@tiagojct/subsub 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/web/app.css CHANGED
@@ -1,836 +1,807 @@
1
- /* ==========================================================================
2
- Sub-Sub Web View
3
- Vintage & Minimal Bookmaking Aesthetic
4
- Archival Laid Paper • Printer's Inks • Classical Typographic Restraint
5
- ========================================================================== */
1
+ /* Sub-Sub web view.
2
+ Type: IBM Plex Sans for the interface, IBM Plex Serif for replies, IBM Plex Mono for commands.
3
+ The fonts are local: the page's CSP allows no other origin. */
6
4
 
7
- :root {
8
- --mode: var(--gl-accent);
9
- --mode-deep: var(--gl-accent-deep);
10
- --on-mode: var(--gl-on-accent);
11
- --add: #205438;
12
- --rem: #9c281b;
13
- --warn: #946816;
14
- --side-w: 16.5rem;
15
- }
5
+ @font-face { font-family: "IBM Plex Sans"; src: url("/fonts/IBMPlexSans.woff2") format("woff2"); font-weight: 100 700; font-stretch: 75% 100%; font-display: swap; }
6
+ @font-face { font-family: "IBM Plex Serif"; src: url("/fonts/IBMPlexSerif.woff2") format("woff2"); font-weight: 100 700; font-display: swap; }
7
+ @font-face { font-family: "IBM Plex Mono"; src: url("/fonts/IBMPlexMono.woff2") format("woff2"); font-weight: 400; font-display: swap; }
16
8
 
17
- /* Dark Mode Tokens */
18
- @media (prefers-color-scheme: dark) {
19
- :root:not([data-theme="light"]) {
20
- --add: #68aa80;
21
- --rem: #cf663d;
22
- --warn: #cca047;
23
- }
24
- }
9
+ /* ---------------------------------------------------------------- tokens */
25
10
 
26
- [data-theme="dark"], html[data-theme="dark"] {
27
- --add: #68aa80;
28
- --rem: #cf663d;
29
- --warn: #cca047;
11
+ :root {
12
+ --sans: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
13
+ --serif: "IBM Plex Serif", Georgia, serif;
14
+ --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
15
+
16
+ --bg: #f7f6f2;
17
+ --surface: #efede7;
18
+ --raised: #ffffff;
19
+ --text: #1c1b19;
20
+ --muted: #5f5c55;
21
+ --faint: #8a867d;
22
+ --rule: #e0ddd4;
23
+ --rule-strong: #c8c3b8;
24
+ --shadow: 0 1px 2px rgb(28 27 25 / 0.05), 0 8px 24px -12px rgb(28 27 25 / 0.18);
25
+
26
+ --researcher: #1d4f7c;
27
+ --researcher-soft: #e3ebf3;
28
+ --librarian: #a33b14;
29
+ --librarian-soft: #f5e6de;
30
+ --on-accent: #ffffff;
31
+
32
+ --add: #256b3b;
33
+ --add-soft: #e2f0e5;
34
+ --rem: #a8321d;
35
+ --rem-soft: #f7e3de;
36
+ --warn: #946412;
37
+
38
+ --radius: 6px;
39
+ --radius-lg: 10px;
40
+ --side-w: 17rem;
41
+ --measure: 46rem;
30
42
  }
31
43
 
32
- /* Mode-specific signature accents */
33
- /* Researcher: Prussian Library Blue / Nautical Slate */
34
- body[data-mode="researcher"] {
35
- --mode: #234b6e;
36
- --mode-deep: #163650;
37
- --on-mode: #f8f6f0;
38
- }
39
44
  @media (prefers-color-scheme: dark) {
40
- :root:not([data-theme="light"]) body[data-mode="researcher"] {
41
- --mode: #6ea3cc;
42
- --mode-deep: #8bb9dc;
43
- --on-mode: #141210;
45
+ :root:not([data-theme="light"]) {
46
+ --bg: #141413;
47
+ --surface: #1c1c1a;
48
+ --raised: #232320;
49
+ --text: #ebe8e1;
50
+ --muted: #a7a399;
51
+ --faint: #7b776f;
52
+ --rule: #2e2d2a;
53
+ --rule-strong: #45433e;
54
+ --shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 12px 32px -12px rgb(0 0 0 / 0.6);
55
+ --researcher: #7fb0de;
56
+ --researcher-soft: #1b2733;
57
+ --librarian: #e48a5f;
58
+ --librarian-soft: #33221a;
59
+ --on-accent: #141413;
60
+ --add: #7cc493;
61
+ --add-soft: #1a2c20;
62
+ --rem: #ec8a70;
63
+ --rem-soft: #36201b;
64
+ --warn: #d6a84e;
44
65
  }
45
66
  }
46
- [data-theme="dark"] body[data-mode="researcher"], html[data-theme="dark"] body[data-mode="researcher"] {
47
- --mode: #6ea3cc;
48
- --mode-deep: #8bb9dc;
49
- --on-mode: #141210;
50
- }
51
67
 
52
- /* Librarian: Venetian Vermilion / Warm Terracotta */
53
- body[data-mode="librarian"] {
54
- --mode: #8b2500;
55
- --mode-deep: #5c1800;
56
- --on-mode: #f8f6f0;
57
- }
58
- @media (prefers-color-scheme: dark) {
59
- :root:not([data-theme="light"]) body[data-mode="librarian"] {
60
- --mode: #cf663d;
61
- --mode-deep: #eb7c52;
62
- --on-mode: #141210;
63
- }
64
- }
65
- [data-theme="dark"] body[data-mode="librarian"], html[data-theme="dark"] body[data-mode="librarian"] {
66
- --mode: #cf663d;
67
- --mode-deep: #eb7c52;
68
- --on-mode: #141210;
69
- }
68
+ :root[data-theme="dark"] {
69
+ --bg: #141413;
70
+ --surface: #1c1c1a;
71
+ --raised: #232320;
72
+ --text: #ebe8e1;
73
+ --muted: #a7a399;
74
+ --faint: #7b776f;
75
+ --rule: #2e2d2a;
76
+ --rule-strong: #45433e;
77
+ --shadow: 0 1px 2px rgb(0 0 0 / 0.3), 0 12px 32px -12px rgb(0 0 0 / 0.6);
78
+ --researcher: #7fb0de;
79
+ --researcher-soft: #1b2733;
80
+ --librarian: #e48a5f;
81
+ --librarian-soft: #33221a;
82
+ --on-accent: #141413;
83
+ --add: #7cc493;
84
+ --add-soft: #1a2c20;
85
+ --rem: #ec8a70;
86
+ --rem-soft: #36201b;
87
+ --warn: #d6a84e;
88
+ }
89
+
90
+ /* The mode sets the accent: blue for the researcher, rust for the librarian. */
91
+ body { --accent: var(--researcher); --accent-soft: var(--researcher-soft); }
92
+ body[data-mode="librarian"] { --accent: var(--librarian); --accent-soft: var(--librarian-soft); }
93
+
94
+ /* ---------------------------------------------------------------- base */
70
95
 
71
96
  *, *::before, *::after { box-sizing: border-box; }
72
97
  html, body { height: 100%; }
73
98
 
74
99
  body {
75
100
  margin: 0;
76
- background: var(--gl-bg);
77
- color: var(--gl-text);
78
- font-family: var(--gl-font-reading);
79
- font-size: 1.1rem;
80
- line-height: 1.65;
81
- transition: background-color 0.2s ease, color 0.2s ease;
101
+ background: var(--bg);
102
+ color: var(--text);
103
+ font-family: var(--sans);
104
+ font-size: 15px;
105
+ line-height: 1.5;
82
106
  -webkit-font-smoothing: antialiased;
107
+ -moz-osx-font-smoothing: grayscale;
108
+ text-rendering: optimizeLegibility;
83
109
  }
84
110
 
85
111
  button, input, select, textarea { font: inherit; color: inherit; }
86
- a { color: var(--mode); text-decoration: underline; text-underline-offset: 3px; }
87
- a:hover { color: var(--mode-deep); }
112
+ a { color: var(--accent); text-underline-offset: 0.18em; text-decoration-thickness: 1px; }
113
+ a:hover { text-decoration-thickness: 2px; }
114
+ svg { flex: none; }
88
115
 
89
116
  .visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
90
117
  [hidden] { display: none !important; }
91
- :focus-visible { outline: 1px solid var(--mode); outline-offset: 2px; }
118
+ :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
119
+ ::selection { background: var(--accent-soft); }
92
120
 
93
- /* ---- Buttons ---- */
94
- button {
95
- cursor: pointer;
96
- border-radius: var(--gl-radius-sm);
97
- border: 1px solid transparent;
98
- padding: 0.35rem 0.85rem;
99
- background: none;
100
- font-family: var(--gl-font-serif);
101
- transition: all 0.15s ease;
121
+ /* Icons drawn with strokes, at the size of the text. */
122
+ .icon-btn svg, .new-btn svg, .brand .mark, .icon {
123
+ width: 18px;
124
+ height: 18px;
125
+ fill: none;
126
+ stroke: currentColor;
127
+ stroke-width: 1.6;
128
+ stroke-linecap: round;
129
+ stroke-linejoin: round;
102
130
  }
131
+
132
+ /* ---------------------------------------------------------------- buttons */
133
+
134
+ button { cursor: pointer; background: none; border: 1px solid transparent; border-radius: var(--radius); padding: 0.4rem 0.85rem; line-height: 1.3; }
103
135
  button:disabled { opacity: 0.45; cursor: default; }
104
- .primary {
105
- background: var(--mode);
106
- color: var(--on-mode);
107
- font-weight: 600;
108
- border: 1px solid var(--mode);
109
- }
110
- .primary:hover:not(:disabled) {
111
- background: var(--mode-deep);
112
- border-color: var(--mode-deep);
113
- }
114
- .secondary {
115
- border-color: var(--gl-border);
116
- background: var(--gl-surface-raised);
117
- color: var(--gl-text);
136
+
137
+ .primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 550; }
138
+ .primary:hover:not(:disabled) { filter: brightness(1.08); }
139
+ .secondary { background: var(--raised); border-color: var(--rule-strong); }
140
+ .secondary:hover:not(:disabled) { border-color: var(--text); }
141
+ .ghost { color: var(--muted); }
142
+ .ghost:hover { color: var(--text); background: var(--surface); }
143
+ .link-btn { padding: 0.1rem 0.2rem; color: var(--muted); font-size: 0.82rem; }
144
+ .link-btn:hover { color: var(--text); text-decoration: underline; text-underline-offset: 0.18em; }
145
+ .small { font-size: 0.85rem; }
146
+ .primary.small, .secondary.small { padding: 0.25rem 0.6rem; }
147
+ .muted { color: var(--muted); }
148
+
149
+ .icon-btn {
150
+ display: inline-grid;
151
+ place-items: center;
152
+ width: 34px;
153
+ height: 34px;
154
+ padding: 0;
155
+ color: var(--muted);
156
+ border-radius: var(--radius);
118
157
  }
119
- .secondary:hover:not(:disabled) {
120
- border-color: var(--gl-text);
158
+ .icon-btn:hover { color: var(--text); background: var(--surface); }
159
+ .icon-btn[aria-pressed="true"] { color: var(--accent); background: var(--accent-soft); }
160
+
161
+ .chip-btn {
162
+ max-width: 16rem;
163
+ overflow: hidden;
164
+ text-overflow: ellipsis;
165
+ white-space: nowrap;
166
+ font-family: var(--mono);
167
+ font-size: 0.78rem;
168
+ color: var(--muted);
169
+ border-color: var(--rule);
170
+ background: var(--raised);
171
+ padding: 0.35rem 0.65rem;
172
+ }
173
+ .chip-btn:hover { color: var(--text); border-color: var(--rule-strong); }
174
+
175
+ select {
176
+ appearance: none;
177
+ border: 1px solid var(--rule);
178
+ border-radius: var(--radius);
179
+ background: var(--raised) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 4.5l3 3 3-3' fill='none' stroke='%23888' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat right 0.5rem center / 12px;
180
+ padding: 0.35rem 1.8rem 0.35rem 0.65rem;
181
+ font-size: 0.85rem;
182
+ cursor: pointer;
121
183
  }
122
- .ghost { color: var(--gl-text-muted); }
123
- .ghost:hover { color: var(--gl-text); background: var(--gl-surface); }
124
- .small { font-size: 0.88rem; padding: 0.2rem 0.55rem; }
125
- .muted { color: var(--gl-text-muted); }
126
- .block { width: 100%; }
184
+ select:hover { border-color: var(--rule-strong); }
185
+
186
+ /* ---------------------------------------------------------------- layout */
127
187
 
128
- /* ---- Application Layout ---- */
129
188
  .app {
130
189
  display: grid;
131
190
  grid-template-columns: var(--side-w) minmax(0, 1fr);
132
191
  grid-template-rows: auto minmax(0, 1fr);
133
192
  height: 100vh;
134
193
  height: 100dvh;
135
- transition: grid-template-columns 0.2s ease;
136
194
  }
195
+ .app.side-collapsed { grid-template-columns: 0 minmax(0, 1fr); }
196
+ .app.side-collapsed .side { display: none; }
137
197
 
138
- .app.side-collapsed {
139
- grid-template-columns: 0 minmax(0, 1fr);
140
- }
141
- .app.side-collapsed .side {
142
- display: none;
143
- }
198
+ /* ---------------------------------------------------------------- top bar */
144
199
 
145
- /* ---- Top Header ---- */
146
200
  .top {
147
201
  grid-column: 1 / -1;
148
202
  display: flex;
149
203
  align-items: center;
150
- gap: 0.75rem 1.25rem;
151
- flex-wrap: wrap;
152
- padding: 0.65rem 1.25rem;
153
- border-bottom: 1px solid var(--gl-border);
154
- background: var(--gl-bg);
204
+ gap: 0.5rem 1rem;
205
+ padding: 0.55rem 1rem;
206
+ border-top: 3px solid var(--accent);
207
+ border-bottom: 1px solid var(--rule);
208
+ background: var(--bg);
155
209
  }
156
210
 
157
211
  .brand {
158
- font-family: var(--gl-font-serif);
159
- font-weight: 700;
160
- font-size: 1.3rem;
161
- letter-spacing: -0.01em;
162
212
  display: flex;
163
- align-items: baseline;
164
- gap: 0.45rem;
165
- }
166
-
167
- .mark {
168
- font-family: var(--gl-font-serif);
169
- font-size: 0.85rem;
170
- font-style: italic;
171
- font-weight: 700;
172
- border: 1px solid var(--gl-border);
173
- background: var(--gl-surface);
174
- color: var(--mode);
175
- padding: 0.1rem 0.4rem;
176
- border-radius: var(--gl-radius-sm);
177
- }
178
-
179
- .menu-btn {
180
- display: inline-flex;
181
213
  align-items: center;
182
- gap: 0.35rem;
183
- border: 1px solid var(--gl-border);
184
- padding: 0.25rem 0.65rem;
185
- border-radius: var(--gl-radius-sm);
186
- font-size: 0.88rem;
214
+ gap: 0.45rem;
215
+ font-weight: 600;
216
+ font-size: 1.02rem;
217
+ letter-spacing: -0.01em;
218
+ margin-right: 0.25rem;
187
219
  }
220
+ .brand .mark { color: var(--accent); }
221
+ .brand .hyphen { color: var(--accent); }
188
222
 
189
223
  .modes {
190
224
  display: inline-flex;
191
- border: 1px solid var(--gl-border);
192
- border-radius: var(--gl-radius-sm);
193
- padding: 1px;
194
- background: var(--gl-surface);
225
+ padding: 3px;
226
+ border-radius: 8px;
227
+ background: var(--surface);
228
+ border: 1px solid var(--rule);
195
229
  }
196
230
  .modes button {
197
- border-radius: var(--gl-radius-sm);
198
- padding: 0.25rem 0.75rem;
199
- font-size: 0.92rem;
200
- color: var(--gl-text-muted);
201
- border: none;
231
+ padding: 0.28rem 0.8rem;
232
+ border-radius: 5px;
233
+ font-size: 0.86rem;
234
+ color: var(--muted);
235
+ border: 0;
202
236
  }
237
+ .modes button:hover { color: var(--text); }
203
238
  .modes button[aria-pressed="true"] {
204
- background: var(--mode);
205
- color: var(--on-mode);
239
+ background: var(--raised);
240
+ color: var(--accent);
206
241
  font-weight: 600;
242
+ box-shadow: 0 1px 2px rgb(0 0 0 / 0.08), 0 0 0 1px var(--rule);
207
243
  }
208
244
 
209
245
  .status {
210
246
  margin-left: auto;
211
247
  display: flex;
212
248
  align-items: center;
213
- gap: 0.65rem 1rem;
214
- flex-wrap: wrap;
215
- font-size: 0.9rem;
249
+ gap: 0.5rem;
250
+ min-width: 0;
216
251
  }
217
252
 
218
253
  .library {
219
254
  display: inline-flex;
220
255
  align-items: center;
221
256
  gap: 0.45rem;
222
- color: var(--gl-text-muted);
223
- font-size: 0.9rem;
224
- }
225
- .library-dot {
226
- width: 0.45rem;
227
- height: 0.45rem;
228
- border-radius: 50%;
229
- background: var(--gl-border);
230
- flex: none;
231
- transition: background 0.2s ease;
257
+ padding: 0.3rem 0.7rem;
258
+ border-radius: 999px;
259
+ font-size: 0.8rem;
260
+ color: var(--muted);
261
+ white-space: nowrap;
262
+ overflow: hidden;
263
+ text-overflow: ellipsis;
264
+ min-width: 0;
265
+ font-variant-numeric: tabular-nums;
232
266
  }
233
- .library.reachable .library-dot { background: var(--add); }
267
+ .library-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--rule-strong); flex: none; }
268
+ .library.reachable .library-dot { background: var(--add); box-shadow: 0 0 0 3px var(--add-soft); }
269
+ .library.down { color: var(--rem); background: var(--rem-soft); font-weight: 550; }
234
270
  .library.down .library-dot { background: var(--rem); }
235
- .library.down { color: var(--rem); font-weight: 600; }
236
271
  .library.checking .library-dot { background: var(--warn); animation: pulse 1.2s ease-in-out infinite; }
237
272
 
238
- .status select {
239
- border: 1px solid var(--gl-border);
240
- border-radius: var(--gl-radius-sm);
241
- background: var(--gl-surface-raised);
242
- padding: 0.25rem 0.5rem;
243
- font-family: var(--gl-font-serif);
244
- font-size: 0.9rem;
245
- }
273
+ /* ---------------------------------------------------------------- side panel */
246
274
 
247
- .model-btn, .width-btn, .theme-btn {
248
- font-family: var(--gl-font-serif);
249
- font-size: 0.88rem;
250
- border: 1px solid var(--gl-border);
251
- padding: 0.25rem 0.65rem;
252
- border-radius: var(--gl-radius-sm);
253
- display: inline-flex;
254
- align-items: center;
255
- gap: 0.35rem;
256
- }
257
- body.layout-full .width-btn {
258
- background: var(--gl-surface);
259
- border-color: var(--mode);
260
- color: var(--mode);
261
- font-weight: 600;
262
- }
263
-
264
- /* ---- Sidebar (Catalog & Conversations) ---- */
265
275
  .side {
266
- border-right: 1px solid var(--gl-border);
267
- background: var(--gl-surface);
268
- padding: 1rem;
276
+ border-right: 1px solid var(--rule);
277
+ background: var(--surface);
278
+ padding: 0.9rem 0.75rem 0.75rem;
269
279
  display: flex;
270
280
  flex-direction: column;
271
- gap: 1.25rem;
281
+ gap: 1.1rem;
272
282
  overflow-y: auto;
283
+ min-height: 0;
273
284
  }
274
285
 
275
286
  .side h2 {
276
- font-family: var(--gl-font-serif);
277
- font-size: 0.8rem;
278
- letter-spacing: 0.1em;
287
+ font-size: 0.7rem;
288
+ font-weight: 600;
289
+ letter-spacing: 0.08em;
279
290
  text-transform: uppercase;
280
- color: var(--gl-text-dim);
281
- margin: 0 0 0.4rem;
282
- font-weight: 700;
291
+ color: var(--faint);
292
+ margin: 0 0 0.35rem;
293
+ padding: 0 0.5rem;
283
294
  }
284
295
 
285
- .side .grow { flex: 1; display: flex; flex-direction: column; min-height: 0; }
286
- .side-subhead { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 0.4rem; }
287
- .side-subhead h2 { margin: 0; }
288
-
289
- .search-wrap { margin-bottom: 0.6rem; }
290
- .search-wrap input {
296
+ .new-btn {
297
+ display: flex;
298
+ align-items: center;
299
+ gap: 0.5rem;
291
300
  width: 100%;
292
- font-size: 0.88rem;
293
- padding: 0.35rem 0.6rem;
294
- border: 1px solid var(--gl-border);
295
- border-radius: var(--gl-radius-sm);
296
- background: var(--gl-surface-raised);
297
- color: var(--gl-text);
298
- font-family: var(--gl-font-serif);
299
- }
300
- .search-wrap input:focus {
301
- outline: none;
302
- border-color: var(--mode);
301
+ padding: 0.5rem 0.7rem;
302
+ background: var(--raised);
303
+ border: 1px solid var(--rule);
304
+ font-weight: 550;
305
+ box-shadow: 0 1px 1px rgb(0 0 0 / 0.03);
303
306
  }
307
+ .new-btn:hover { border-color: var(--rule-strong); }
308
+ .new-btn svg { width: 16px; height: 16px; color: var(--accent); }
304
309
 
305
- .actions { display: flex; flex-direction: column; gap: 0.2rem; }
310
+ .actions { display: flex; flex-direction: column; }
306
311
  .actions button {
307
312
  text-align: left;
308
- padding: 0.35rem 0.6rem;
309
- border-radius: var(--gl-radius-sm);
310
- font-size: 0.95rem;
313
+ padding: 0.32rem 0.5rem;
314
+ font-size: 0.88rem;
315
+ color: var(--text);
316
+ border-radius: 5px;
311
317
  }
312
- .actions button:hover { background: var(--gl-bg); }
313
- .actions hr { border: 0; border-top: 1px solid var(--gl-border); margin: 0.4rem 0; width: 100%; }
318
+ .actions button:hover { background: var(--bg); }
319
+ .actions hr { border: 0; border-top: 1px solid var(--rule); margin: 0.4rem 0.5rem; }
314
320
 
315
- .sessions {
316
- list-style: none;
317
- margin: 0;
318
- padding: 0;
319
- display: flex;
320
- flex-direction: column;
321
- gap: 0.2rem;
322
- overflow-y: auto;
323
- flex: 1;
321
+ .side .grow { flex: 1; display: flex; flex-direction: column; min-height: 8rem; }
322
+ .side-subhead { display: flex; justify-content: space-between; align-items: baseline; padding-right: 0.3rem; }
323
+
324
+ .search {
325
+ width: 100%;
326
+ margin: 0.15rem 0 0.4rem;
327
+ font-size: 0.84rem;
328
+ padding: 0.38rem 0.6rem;
329
+ border: 1px solid var(--rule);
330
+ border-radius: var(--radius);
331
+ background: var(--raised);
324
332
  }
333
+ .search:focus { outline: none; border-color: var(--accent); }
334
+
335
+ .sessions { list-style: none; margin: 0; padding: 0; overflow-y: auto; flex: 1; }
336
+ .sessions > li.muted { padding: 0.3rem 0.5rem; }
325
337
  .sessions button {
326
338
  width: 100%;
327
339
  text-align: left;
328
- padding: 0.45rem 0.6rem;
340
+ padding: 0.42rem 0.5rem;
329
341
  display: block;
330
- border-radius: var(--gl-radius-sm);
331
- border: 1px solid transparent;
332
- }
333
- .sessions button:hover {
334
- background: var(--gl-bg);
335
- border-color: var(--gl-border);
336
- }
337
- .sessions .current button {
338
- background: var(--gl-bg);
339
- border-color: var(--gl-border);
340
- font-weight: 600;
341
- }
342
- .sessions .when {
343
- display: flex;
344
- justify-content: space-between;
345
- font-size: 0.8rem;
346
- color: var(--gl-text-muted);
347
- margin-top: 0.15rem;
348
- font-style: italic;
349
- }
350
- .sessions .badge {
351
- font-family: var(--gl-font-mono);
352
- font-size: 0.72rem;
353
- background: var(--gl-surface-raised);
354
- border: 1px solid var(--gl-border);
355
- border-radius: var(--gl-radius-sm);
356
- padding: 0 0.3rem;
342
+ border-radius: 5px;
357
343
  }
344
+ .sessions button:hover { background: var(--bg); }
345
+ .sessions .current button { background: var(--raised); box-shadow: inset 2px 0 0 var(--accent), 0 0 0 1px var(--rule); }
358
346
  .sessions .what {
359
347
  display: -webkit-box;
360
348
  -webkit-line-clamp: 2;
361
349
  -webkit-box-orient: vertical;
362
350
  overflow: hidden;
363
- font-size: 0.95rem;
364
- line-height: 1.4;
351
+ font-size: 0.86rem;
352
+ line-height: 1.35;
365
353
  }
366
-
367
- .side-foot {
354
+ .sessions .when {
368
355
  display: flex;
369
356
  justify-content: space-between;
370
- align-items: center;
371
- gap: 0.5rem;
372
- border-top: 1px solid var(--gl-border);
373
- padding-top: 0.75rem;
357
+ font-size: 0.72rem;
358
+ color: var(--faint);
359
+ margin-top: 0.15rem;
360
+ font-variant-numeric: tabular-nums;
374
361
  }
375
- .version {
376
- font-size: 0.8rem;
377
- color: var(--gl-text-muted);
378
- font-style: italic;
362
+ .sessions .badge { font-family: var(--mono); font-size: 0.68rem; }
363
+
364
+ .side-foot {
365
+ display: grid;
366
+ gap: 0.55rem;
367
+ border-top: 1px solid var(--rule);
368
+ padding: 0.7rem 0.5rem 0;
379
369
  }
370
+ .side-foot-row { display: flex; justify-content: space-between; align-items: center; }
371
+ .version { font-family: var(--mono); font-size: 0.7rem; color: var(--faint); }
380
372
 
381
- /* ---- Conversation Main Area ---- */
382
- .chat { display: flex; flex-direction: column; min-height: 0; }
373
+ /* A switch built on a checkbox. */
374
+ .switch { display: flex; align-items: center; gap: 0.55rem; font-size: 0.84rem; cursor: pointer; line-height: 1.3; }
375
+ .switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
376
+ .switch .track {
377
+ position: relative;
378
+ flex: none;
379
+ width: 28px;
380
+ height: 16px;
381
+ border-radius: 999px;
382
+ background: var(--rule-strong);
383
+ transition: background-color 0.15s ease;
384
+ }
385
+ .switch .track::after {
386
+ content: "";
387
+ position: absolute;
388
+ top: 2px;
389
+ left: 2px;
390
+ width: 12px;
391
+ height: 12px;
392
+ border-radius: 50%;
393
+ background: #fff;
394
+ box-shadow: 0 1px 2px rgb(0 0 0 / 0.25);
395
+ transition: transform 0.15s ease;
396
+ }
397
+ .switch input:checked + .track { background: var(--accent); }
398
+ .switch input:checked + .track::after { transform: translateX(12px); }
399
+ .switch input:focus-visible + .track { outline: 2px solid var(--accent); outline-offset: 2px; }
400
+ .switch input:disabled + .track { opacity: 0.5; }
401
+
402
+ /* ---------------------------------------------------------------- conversation */
403
+
404
+ .chat { display: flex; flex-direction: column; min-height: 0; background: var(--bg); }
405
+
406
+ body.layout-full { --measure: 72rem; }
383
407
 
384
408
  .banner {
385
- margin: 0.75rem max(1.5rem, calc((100% - 84rem) / 2 + 1.5rem)) 0;
386
- padding: 0.6rem 0.9rem;
387
- border: 1px solid var(--gl-border);
409
+ width: min(calc(100% - 2.5rem), var(--measure));
410
+ margin: 0.9rem auto 0;
411
+ padding: 0.6rem 0.6rem 0.6rem 0.9rem;
412
+ border: 1px solid var(--rule);
388
413
  border-left: 3px solid var(--warn);
389
- background: var(--gl-surface);
414
+ border-radius: var(--radius);
415
+ background: var(--raised);
390
416
  display: flex;
391
417
  gap: 0.75rem;
392
418
  align-items: center;
393
- flex-wrap: wrap;
394
- font-size: 0.95rem;
419
+ justify-content: space-between;
420
+ font-size: 0.9rem;
395
421
  }
396
422
 
397
423
  .log {
398
424
  flex: 1;
399
425
  overflow-y: auto;
400
- padding: 1.5rem max(1.5rem, calc((100% - 84rem) / 2 + 1.5rem)) 2.5rem;
401
- }
402
- .log > * {
403
- max-width: 100%;
404
- width: 100%;
405
- margin-left: auto;
406
- margin-right: auto;
426
+ padding: 1.75rem 1.25rem 2rem;
427
+ scrollbar-gutter: stable;
407
428
  }
429
+ .log > * { width: min(100%, var(--measure)); margin-inline: auto; }
408
430
 
409
- /* Wide / Edge-to-Edge Layout */
410
- body.layout-full .log {
411
- padding: 1.5rem 2rem 2.5rem;
412
- }
413
- body.layout-full .banner {
414
- margin: 0.75rem 2rem 0;
415
- }
416
- body.layout-full .composer {
417
- padding: 0.85rem 2rem 1.15rem;
418
- }
419
- body.layout-full .msg.assistant .md > p,
420
- body.layout-full .msg.assistant .md > ul,
421
- body.layout-full .msg.assistant .md > ol,
422
- body.layout-full .msg.assistant .md > blockquote,
423
- body.layout-full .msg.assistant .md > h1,
424
- body.layout-full .msg.assistant .md > h2,
425
- body.layout-full .msg.assistant .md > h3,
426
- body.layout-full .msg.assistant .md > h4 {
427
- max-width: 100%;
428
- }
429
- body.layout-full .msg.user .bubble {
430
- max-width: 90%;
431
- }
431
+ .msg { margin-top: 1.6rem; }
432
+ .msg:first-child { margin-top: 0; }
432
433
 
433
- .msg { margin-top: 1.25rem; width: 100%; }
434
434
  .msg.user { display: flex; justify-content: flex-end; }
435
435
  .msg.user .bubble {
436
- background: var(--gl-surface);
437
- border: 1px solid var(--gl-border);
438
- border-radius: var(--gl-radius-md);
439
- padding: 0.65rem 1.1rem;
440
- max-width: min(52rem, 85%);
436
+ background: var(--raised);
437
+ border: 1px solid var(--rule);
438
+ border-radius: var(--radius-lg) var(--radius-lg) 3px var(--radius-lg);
439
+ padding: 0.6rem 0.95rem;
440
+ max-width: min(36rem, 88%);
441
441
  white-space: pre-wrap;
442
442
  overflow-wrap: anywhere;
443
- font-size: 1.05rem;
444
- line-height: 1.6;
443
+ font-size: 0.95rem;
445
444
  }
445
+ .msg.user details.bubble summary { cursor: pointer; color: var(--muted); }
446
+ .msg.user details.bubble[open] summary { margin-bottom: 0.4rem; }
446
447
 
447
- .msg.assistant { width: 100%; }
448
- .msg.assistant .md {
449
- width: 100%;
448
+ /* Replies read as text, in the serif. */
449
+ .md {
450
+ font-family: var(--serif);
451
+ font-size: 1.02rem;
452
+ line-height: 1.68;
450
453
  overflow-wrap: anywhere;
451
- font-size: 1.1rem;
452
- line-height: 1.7;
453
454
  }
454
-
455
455
  .md > :first-child { margin-top: 0; }
456
456
  .md > :last-child { margin-bottom: 0; }
457
-
458
- /* Continuous prose reading measure */
459
- .msg.assistant .md > p,
460
- .msg.assistant .md > ul,
461
- .msg.assistant .md > ol,
462
- .msg.assistant .md > blockquote {
463
- max-width: 52rem;
464
- margin: 0.75rem 0;
465
- }
466
- .msg.assistant .md > h1,
467
- .msg.assistant .md > h2,
468
- .msg.assistant .md > h3,
469
- .msg.assistant .md > h4 {
470
- max-width: 58rem;
471
- font-family: var(--gl-font-serif);
472
- line-height: 1.25;
473
- margin: 1.4rem 0 0.5rem;
457
+ .md p, .md ul, .md ol { margin: 0.7rem 0; }
458
+ .md li { margin: 0.2rem 0; }
459
+ .md li::marker { color: var(--faint); }
460
+ .md h1, .md h2, .md h3, .md h4 {
461
+ font-family: var(--sans);
462
+ line-height: 1.3;
474
463
  letter-spacing: -0.01em;
464
+ margin: 1.6rem 0 0.5rem;
465
+ font-weight: 600;
466
+ }
467
+ .md h1 { font-size: 1.3rem; }
468
+ .md h2 { font-size: 1.12rem; }
469
+ .md h3 { font-size: 1rem; }
470
+ .md h4 { font-size: 0.92rem; color: var(--muted); }
471
+ .md strong { font-weight: 600; }
472
+ .md hr { border: 0; border-top: 1px solid var(--rule); margin: 1.5rem 0; }
473
+ .msg.assistant + .msg.assistant { margin-top: 0.9rem; }
474
+ .msg.assistant .md + .md { margin-top: 0.9rem; }
475
+
476
+ .md blockquote {
477
+ margin: 1rem 0;
478
+ padding: 0.1rem 0 0.1rem 1rem;
479
+ border-left: 2px solid var(--accent);
480
+ color: var(--muted);
475
481
  }
476
- .md h1 { font-size: 1.55rem; }
477
- .md h2 { font-size: 1.35rem; }
478
- .md h3 { font-size: 1.15rem; }
479
482
 
480
- /* Inline code optically balanced against classical serif x-height */
481
483
  .md code {
482
- font-family: var(--gl-font-mono);
483
- font-size: 0.79em;
484
- letter-spacing: -0.01em;
485
- background: var(--gl-surface);
486
- border: 1px solid var(--gl-border);
487
- border-radius: var(--gl-radius-sm);
488
- padding: 0.12em 0.38em;
489
- vertical-align: 0.04em;
484
+ font-family: var(--mono);
485
+ font-size: 0.84em;
486
+ background: var(--surface);
487
+ border: 1px solid var(--rule);
488
+ border-radius: 4px;
489
+ padding: 0.05em 0.32em;
490
490
  }
491
491
 
492
492
  .md pre {
493
- background: var(--gl-surface);
494
- border: 1px solid var(--gl-border);
495
- border-radius: var(--gl-radius-sm);
493
+ margin: 0;
494
+ background: var(--surface);
495
+ border: 1px solid var(--rule);
496
+ border-radius: var(--radius);
496
497
  padding: 0.85rem 1rem;
497
498
  overflow-x: auto;
498
- font-family: var(--gl-font-mono);
499
- font-size: 0.82rem;
500
- line-height: 1.5;
501
- width: 100%;
499
+ font-family: var(--mono);
500
+ font-size: 0.8rem;
501
+ line-height: 1.55;
502
502
  }
503
- .md pre code { background: none; border: 0; padding: 0; font-size: inherit; vertical-align: baseline; }
503
+ .md pre code { background: none; border: 0; padding: 0; font-size: inherit; }
504
504
 
505
- .pre-wrap { position: relative; margin: 0.85rem 0; width: 100%; }
506
- .pre-wrap pre { margin: 0; }
505
+ .pre-wrap { position: relative; margin: 0.9rem 0; }
507
506
  .copy-btn {
508
507
  position: absolute;
509
508
  top: 0.4rem;
510
509
  right: 0.4rem;
511
- font-family: var(--gl-font-serif);
512
- font-size: 0.78rem;
513
- background: var(--gl-surface-raised);
514
- border: 1px solid var(--gl-border);
515
- border-radius: var(--gl-radius-sm);
510
+ font-family: var(--sans);
511
+ font-size: 0.74rem;
512
+ background: var(--raised);
513
+ border: 1px solid var(--rule);
516
514
  padding: 0.15rem 0.5rem;
517
- color: var(--gl-text-muted);
518
- cursor: pointer;
515
+ color: var(--muted);
519
516
  opacity: 0;
520
- transition: opacity 0.15s ease;
521
- z-index: 2;
517
+ transition: opacity 0.12s ease;
522
518
  }
523
519
  .pre-wrap:hover .copy-btn, .copy-btn:focus-visible { opacity: 1; }
524
- .copy-btn:hover { color: var(--gl-text); border-color: var(--gl-border-dark, var(--gl-text)); }
520
+ .copy-btn:hover { color: var(--text); border-color: var(--rule-strong); }
525
521
  .copy-btn.copied { opacity: 1; color: var(--add); border-color: var(--add); }
526
522
 
527
- .msg-actions {
528
- display: flex;
529
- gap: 0.4rem;
530
- margin-top: 0.5rem;
531
- opacity: 0;
532
- transition: opacity 0.15s ease;
533
- }
534
- .msg.assistant:hover .msg-actions, .msg-actions:focus-within { opacity: 1; }
535
- .msg-action-btn {
536
- font-size: 0.8rem;
537
- padding: 0.15rem 0.5rem;
538
- border-radius: var(--gl-radius-sm);
539
- color: var(--gl-text-muted);
540
- border: 1px solid transparent;
541
- background: none;
542
- }
543
- .msg-action-btn:hover { color: var(--gl-text); background: var(--gl-surface); border-color: var(--gl-border); }
544
- .msg-action-btn.copied { color: var(--add); border-color: var(--add); }
545
-
546
- .md blockquote {
547
- margin: 1rem 0;
548
- padding-left: 1.1rem;
549
- border-left: 2px solid var(--mode);
550
- color: var(--gl-text-muted);
551
- font-style: italic;
552
- }
553
-
554
- /* Wide Bibliographic & Data Tables */
523
+ /* Tables: citekeys, screening logs, evidence. */
555
524
  .md-table-wrap {
556
- width: 100%;
557
525
  overflow-x: auto;
558
- margin: 1.35rem 0;
559
- border-top: 1px solid var(--gl-border);
560
- border-bottom: 1px solid var(--gl-border);
561
- scrollbar-width: thin;
526
+ margin: 1.1rem 0;
527
+ border: 1px solid var(--rule);
528
+ border-radius: var(--radius);
529
+ background: var(--raised);
562
530
  }
563
-
564
531
  .md table {
565
532
  border-collapse: collapse;
566
533
  width: 100%;
567
- max-width: 100%;
568
- display: table;
569
- font-size: 0.93rem;
570
- line-height: 1.5;
571
- margin: 1.35rem 0;
572
- border-top: 1px solid var(--gl-border);
573
- border-bottom: 1px solid var(--gl-border);
574
- }
575
-
576
- .md-table-wrap table {
577
- margin: 0;
578
- border-top: none;
579
- border-bottom: none;
580
- }
581
-
582
- .md th, .md td {
583
- border-bottom: 1px solid var(--gl-border);
584
- padding: 0.55rem 0.85rem;
585
- text-align: left;
586
- vertical-align: top;
534
+ font-family: var(--sans);
535
+ font-size: 0.86rem;
536
+ line-height: 1.45;
537
+ font-variant-numeric: tabular-nums;
587
538
  }
588
-
539
+ .md th, .md td { padding: 0.5rem 0.75rem; text-align: left; vertical-align: top; border-bottom: 1px solid var(--rule); }
540
+ .md tr:last-child td { border-bottom: 0; }
589
541
  .md th {
590
- font-size: 0.78rem;
591
- font-weight: 700;
542
+ font-size: 0.72rem;
543
+ font-weight: 600;
544
+ letter-spacing: 0.04em;
592
545
  text-transform: uppercase;
593
- letter-spacing: 0.06em;
594
- color: var(--gl-text-muted);
595
- white-space: nowrap;
596
- background: var(--gl-surface);
597
- }
598
-
599
- .md th:first-child,
600
- .md td:first-child {
601
- width: 1%;
602
- white-space: nowrap;
603
- text-align: center;
604
- font-family: var(--gl-font-mono);
605
- font-size: 0.80rem;
606
- color: var(--gl-text-muted);
607
- }
608
-
609
- .md td code {
610
- white-space: nowrap;
611
- }
612
-
613
- .md td:nth-child(3) {
546
+ color: var(--muted);
614
547
  white-space: nowrap;
548
+ background: var(--surface);
615
549
  }
550
+ .md td:first-child { white-space: nowrap; }
551
+ .md td code { white-space: nowrap; }
552
+ .md tbody tr:hover td { background: var(--bg); }
616
553
 
617
- .md tr:hover td {
618
- background: var(--gl-surface);
619
- }
620
-
621
- /* Tool execution items */
622
- .tool { margin-top: 0.5rem; font-size: 0.9rem; color: var(--gl-text-muted); width: 100%; }
554
+ .msg-actions { display: flex; gap: 0.25rem; margin-top: 0.4rem; opacity: 0; transition: opacity 0.12s ease; }
555
+ .msg.assistant:hover .msg-actions, .msg-actions:focus-within { opacity: 1; }
556
+ .msg-action-btn { font-size: 0.75rem; padding: 0.15rem 0.45rem; color: var(--faint); }
557
+ .msg-action-btn:hover { color: var(--text); background: var(--surface); }
558
+ .msg-action-btn.copied { color: var(--add); }
559
+
560
+ /* Tool calls: one quiet line each; the result opens below. */
561
+ .tool { margin: 0.35rem 0; font-size: 0.82rem; color: var(--muted); }
562
+ .msg.assistant > .tool:first-child { margin-top: 0; }
563
+ .tool + .md, .md + .tool { margin-top: 0.8rem; }
623
564
  .tool summary {
624
565
  cursor: pointer;
625
566
  list-style: none;
626
567
  display: flex;
627
- gap: 0.5rem;
568
+ gap: 0.55rem;
628
569
  align-items: baseline;
629
- flex-wrap: wrap;
570
+ padding: 0.28rem 0.55rem;
571
+ margin-left: -0.55rem;
572
+ border-radius: 5px;
573
+ width: fit-content;
574
+ max-width: calc(100% + 0.55rem);
630
575
  }
576
+ .tool summary:hover { background: var(--surface); }
631
577
  .tool summary::-webkit-details-marker { display: none; }
632
578
  .tool summary::before {
633
579
  content: "";
634
- width: 0.45rem;
635
- height: 0.45rem;
580
+ width: 6px;
581
+ height: 6px;
636
582
  border-radius: 50%;
637
- background: var(--gl-border);
583
+ background: var(--rule-strong);
638
584
  flex: none;
639
585
  align-self: center;
640
586
  }
641
- .tool.running summary::before { background: var(--mode); animation: pulse 1.2s ease-in-out infinite; }
587
+ .tool .label { color: var(--text); white-space: nowrap; }
588
+ .tool.running summary::before { background: var(--accent); animation: pulse 1.1s ease-in-out infinite; }
642
589
  .tool.done summary::before { background: var(--add); }
643
590
  .tool.error summary::before { background: var(--rem); }
644
- .tool .args { font-family: var(--gl-font-mono); font-size: 0.78rem; overflow-wrap: anywhere; }
591
+ .tool.error .label { color: var(--rem); }
592
+ .tool .args { font-family: var(--mono); font-size: 0.74rem; color: var(--faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
593
+ .tool[open] .args { white-space: normal; overflow-wrap: anywhere; }
645
594
  .tool pre {
595
+ margin: 0.35rem 0 0.6rem 0.6rem;
646
596
  white-space: pre-wrap;
647
597
  overflow-wrap: anywhere;
648
- font-family: var(--gl-font-mono);
649
- font-size: 0.80rem;
598
+ font-family: var(--mono);
599
+ font-size: 0.75rem;
600
+ line-height: 1.5;
650
601
  max-height: 18rem;
651
602
  overflow-y: auto;
652
- background: var(--gl-surface);
653
- border: 1px solid var(--gl-border);
654
- border-radius: var(--gl-radius-sm);
655
- padding: 0.65rem;
656
- color: var(--gl-text);
603
+ background: var(--surface);
604
+ border: 1px solid var(--rule);
605
+ border-radius: var(--radius);
606
+ padding: 0.65rem 0.8rem;
607
+ color: var(--text);
608
+ }
609
+ .tool .open {
610
+ font-size: 0.74rem;
611
+ padding: 0.05rem 0.45rem;
612
+ border: 1px solid var(--rule-strong);
613
+ background: var(--raised);
614
+ color: var(--text);
657
615
  }
658
- .tool .open { margin-left: 0.25rem; padding: 0.1rem 0.5rem; border: 1px solid var(--gl-border); font-size: 0.8rem; }
659
616
 
660
617
  .note {
661
618
  margin-top: 1rem;
662
- padding: 0.65rem 1rem;
663
- border-radius: var(--gl-radius-sm);
664
- background: var(--gl-surface);
665
- border: 1px solid var(--gl-border);
666
- font-size: 0.95rem;
619
+ padding: 0.6rem 0.9rem;
620
+ border-radius: var(--radius);
621
+ background: var(--surface);
622
+ border: 1px solid var(--rule);
623
+ font-size: 0.88rem;
667
624
  white-space: pre-wrap;
668
625
  overflow-wrap: anywhere;
669
626
  }
670
627
  .note.warning { border-left: 3px solid var(--warn); }
671
628
  .note.error { border-left: 3px solid var(--rem); }
672
- .note.mono { font-family: var(--gl-font-mono); font-size: 0.80rem; }
629
+ .note.mono { font-family: var(--mono); font-size: 0.76rem; line-height: 1.55; }
630
+ .note pre { font-family: var(--mono); font-size: 0.74rem; white-space: pre-wrap; }
631
+ .note button { margin-top: 0.5rem; }
673
632
 
674
633
  .working {
675
- margin-top: 0.75rem;
676
- color: var(--gl-text-muted);
677
- font-size: 0.92rem;
634
+ margin-top: 1rem;
635
+ color: var(--muted);
636
+ font-size: 0.85rem;
678
637
  display: flex;
679
- gap: 0.5rem;
638
+ gap: 0.55rem;
680
639
  align-items: center;
681
- font-style: italic;
682
640
  }
683
641
  .working::before {
684
642
  content: "";
685
- width: 0.45rem;
686
- height: 0.45rem;
687
- border-radius: 50%;
688
- background: var(--mode);
689
- animation: pulse 1.2s ease-in-out infinite;
690
- }
643
+ width: 28px;
644
+ height: 3px;
645
+ border-radius: 2px;
646
+ background: linear-gradient(90deg, var(--accent) 0 40%, var(--rule) 40% 100%);
647
+ background-size: 250% 100%;
648
+ animation: sweep 1.3s ease-in-out infinite alternate;
649
+ }
650
+ @keyframes sweep { from { background-position: 100% 0; } to { background-position: 0 0; } }
691
651
  @keyframes pulse { 50% { opacity: 0.3; } }
692
- @media (prefers-reduced-motion: reduce) { .working::before, .tool.running summary::before { animation: none; } }
693
652
 
694
- .empty { text-align: center; padding-top: 12vh; }
695
- .empty h1 {
696
- font-family: var(--gl-font-serif);
697
- font-weight: 700;
698
- font-size: 1.85rem;
699
- letter-spacing: -0.01em;
700
- margin: 0 0 1rem;
653
+ /* Empty conversation. */
654
+ .empty { padding-top: 11vh; }
655
+ .empty .kicker {
656
+ font-size: 0.72rem;
657
+ font-weight: 600;
658
+ letter-spacing: 0.08em;
659
+ text-transform: uppercase;
660
+ color: var(--accent);
661
+ margin: 0 0 0.6rem;
701
662
  }
702
- .chips { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; }
663
+ .empty h1 {
664
+ font-family: var(--serif);
665
+ font-weight: 500;
666
+ font-size: clamp(1.6rem, 3.2vw, 2.15rem);
667
+ line-height: 1.2;
668
+ letter-spacing: -0.015em;
669
+ margin: 0 0 0.6rem;
670
+ }
671
+ .empty .lede { color: var(--muted); max-width: 34rem; margin: 0 0 1.75rem; }
672
+ .chips { display: grid; gap: 0.5rem; grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); }
703
673
  .chips button {
704
- border: 1px solid var(--gl-border);
705
- border-radius: var(--gl-radius-sm);
706
- background: var(--gl-surface-raised);
707
- padding: 0.4rem 0.9rem;
708
- font-size: 0.95rem;
674
+ text-align: left;
675
+ border: 1px solid var(--rule);
676
+ border-radius: var(--radius-lg);
677
+ background: var(--raised);
678
+ padding: 0.75rem 0.9rem;
679
+ font-size: 0.9rem;
680
+ line-height: 1.4;
709
681
  }
710
- .chips button:hover { border-color: var(--mode); }
682
+ .chips button:hover { border-color: var(--accent); }
711
683
 
712
- /* ---- Composer ---- */
713
- .composer {
714
- position: relative;
715
- display: flex;
716
- gap: 0.6rem;
717
- align-items: flex-end;
718
- padding: 0.85rem max(1.5rem, calc((100% - 84rem) / 2 + 1.5rem)) 1.15rem;
719
- border-top: 1px solid var(--gl-border);
720
- background: var(--gl-bg);
684
+ body > p.empty { text-align: center; color: var(--muted); padding: 30vh 1rem 0; margin: 0; }
685
+
686
+ /* ---------------------------------------------------------------- composer */
687
+
688
+ .composer { position: relative; padding: 0 1.25rem 1.1rem; }
689
+ .composer-box {
690
+ width: min(100%, var(--measure));
691
+ margin-inline: auto;
692
+ border: 1px solid var(--rule-strong);
693
+ border-radius: 12px;
694
+ background: var(--raised);
695
+ box-shadow: var(--shadow);
696
+ transition: border-color 0.12s ease, box-shadow 0.12s ease;
721
697
  }
698
+ .composer-box:focus-within { border-color: var(--accent); box-shadow: var(--shadow), 0 0 0 3px var(--accent-soft); }
722
699
  .composer textarea {
723
- flex: 1;
700
+ display: block;
701
+ width: 100%;
724
702
  resize: none;
725
703
  max-height: 40vh;
726
- min-height: 2.85rem;
727
- padding: 0.65rem 0.85rem;
728
- border: 1px solid var(--gl-border);
729
- border-radius: var(--gl-radius-sm);
730
- background: var(--gl-surface-raised);
731
- font-family: var(--gl-font-reading);
732
- font-size: 1.05rem;
704
+ min-height: 3rem;
705
+ padding: 0.8rem 0.95rem 0.2rem;
706
+ border: 0;
707
+ background: transparent;
708
+ font-size: 0.98rem;
733
709
  line-height: 1.5;
734
710
  }
735
- .composer textarea:focus {
736
- outline: none;
737
- border-color: var(--mode);
738
- }
739
- .composer-buttons { display: flex; gap: 0.4rem; }
711
+ .composer textarea:focus { outline: none; }
712
+ .composer textarea::placeholder { color: var(--faint); }
713
+ .composer-row { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; padding: 0.35rem 0.5rem 0.5rem 0.95rem; }
714
+ .composer-hint { font-size: 0.74rem; color: var(--faint); }
715
+ .composer-buttons { display: flex; gap: 0.4rem; margin-left: auto; }
716
+ .composer-buttons button { padding: 0.38rem 0.95rem; font-size: 0.88rem; }
740
717
 
741
718
  .suggest {
742
719
  position: absolute;
743
- left: 1rem;
744
- right: 1rem;
745
- bottom: calc(100% - 0.25rem);
746
- max-width: 30rem;
747
- max-height: 16rem;
720
+ left: max(1.25rem, calc((100% - var(--measure)) / 2));
721
+ bottom: calc(100% - 0.4rem);
722
+ width: min(32rem, calc(100% - 2.5rem));
723
+ max-height: 18rem;
748
724
  overflow-y: auto;
749
- background: var(--gl-surface-raised);
750
- border: 1px solid var(--gl-border);
751
- border-radius: var(--gl-radius-sm);
752
- box-shadow: 0 8px 24px -12px rgba(0,0,0,0.25);
753
- padding: 0.25rem;
754
- }
755
- .suggest button { display: block; width: 100%; text-align: left; padding: 0.35rem 0.6rem; }
756
- .suggest button[aria-selected="true"], .suggest button:hover { background: var(--gl-bg); }
757
- .suggest .name { font-family: var(--gl-font-mono); font-size: 0.80rem; }
758
- .suggest .desc { color: var(--gl-text-muted); font-size: 0.85rem; margin-left: 0.5rem; font-style: italic; }
759
-
760
- /* ---- Dialogs & Modals ---- */
725
+ background: var(--raised);
726
+ border: 1px solid var(--rule-strong);
727
+ border-radius: var(--radius-lg);
728
+ box-shadow: var(--shadow);
729
+ padding: 0.3rem;
730
+ z-index: 5;
731
+ }
732
+ .suggest button { display: flex; align-items: baseline; gap: 0.6rem; width: 100%; text-align: left; padding: 0.38rem 0.55rem; border-radius: 5px; }
733
+ .suggest button[aria-selected="true"], .suggest button:hover { background: var(--accent-soft); }
734
+ .suggest .name { font-family: var(--mono); font-size: 0.8rem; color: var(--accent); white-space: nowrap; }
735
+ .suggest .desc { color: var(--muted); font-size: 0.82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
736
+
737
+ /* ---------------------------------------------------------------- dialogs */
738
+
761
739
  .modal {
762
- border: 1px solid var(--gl-border);
763
- border-radius: var(--gl-radius-sm);
764
- background: var(--gl-surface-raised);
765
- color: var(--gl-text);
766
- padding: 1.5rem;
767
- width: min(38rem, calc(100vw - 2rem));
740
+ border: 1px solid var(--rule-strong);
741
+ border-radius: 12px;
742
+ background: var(--raised);
743
+ color: var(--text);
744
+ padding: 1.4rem 1.5rem 1.25rem;
745
+ width: min(40rem, calc(100vw - 2rem));
768
746
  max-height: calc(100dvh - 2rem);
769
747
  overflow-y: auto;
770
- box-shadow: 0 16px 40px -10px rgba(0,0,0,0.35);
748
+ box-shadow: 0 24px 60px -16px rgb(0 0 0 / 0.45);
771
749
  }
772
750
  .modal.wide { width: min(44rem, calc(100vw - 2rem)); }
773
- .modal::backdrop { background: rgba(20, 18, 16, 0.6); }
751
+ .modal::backdrop { background: rgb(20 20 19 / 0.45); backdrop-filter: blur(2px); }
752
+ .modal[open] { animation: rise 0.16s ease-out; }
753
+ @keyframes rise { from { opacity: 0; transform: translateY(6px); } }
774
754
 
775
- .modal h2 {
776
- font-family: var(--gl-font-serif);
777
- font-size: 1.4rem;
778
- letter-spacing: -0.01em;
779
- margin: 0 0 0.35rem;
755
+ .modal-kicker {
756
+ margin: 0 0 0.3rem;
757
+ font-size: 0.7rem;
758
+ font-weight: 600;
759
+ letter-spacing: 0.08em;
760
+ text-transform: uppercase;
761
+ color: var(--accent);
780
762
  }
781
- .modal h3 { font-size: 1.05rem; margin: 1.25rem 0 0.5rem; }
782
- .modal .hint { color: var(--gl-text-muted); margin: 0 0 0.85rem; font-size: 0.95rem; font-style: italic; }
763
+ .modal-kicker:empty { display: none; }
764
+ .modal h2 { font-size: 1.2rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.3; margin: 0 0 0.3rem; overflow-wrap: anywhere; }
765
+ .modal h3 { font-size: 0.72rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--faint); margin: 1.4rem 0 0.5rem; }
766
+ .modal .hint { color: var(--muted); margin: 0 0 1rem; font-size: 0.88rem; }
783
767
 
784
768
  .preview {
785
- font-family: var(--gl-font-mono);
786
- font-size: 0.80rem;
787
- line-height: 1.5;
769
+ font-family: var(--mono);
770
+ font-size: 0.78rem;
771
+ line-height: 1.7;
788
772
  white-space: pre-wrap;
789
773
  overflow-wrap: anywhere;
790
- background: var(--gl-surface);
791
- border: 1px solid var(--gl-border);
792
- border-radius: var(--gl-radius-sm);
793
- padding: 0.85rem;
774
+ background: var(--bg);
775
+ border: 1px solid var(--rule);
776
+ border-radius: var(--radius);
777
+ padding: 0.8rem 0.95rem;
794
778
  max-height: 55vh;
795
779
  overflow-y: auto;
796
- margin: 0 0 1.25rem;
797
- }
798
- .preview .add {
799
- color: var(--add);
800
- font-weight: 700;
801
- }
802
- .preview .rem {
803
- color: var(--rem);
804
- font-weight: 700;
780
+ margin: 0 0 1.1rem;
805
781
  }
782
+ .preview .add, .preview .rem { border-radius: 3px; padding: 0.1em 0.3em; }
783
+ .preview .add { color: var(--add); background: var(--add-soft); }
784
+ .preview .rem { color: var(--rem); background: var(--rem-soft); }
806
785
 
807
- .modal-buttons {
808
- display: flex;
809
- justify-content: flex-end;
810
- align-items: center;
811
- gap: 0.75rem;
812
- flex-wrap: wrap;
813
- margin-top: 0.75rem;
814
- }
815
- .modal-shortcut-hint {
816
- font-size: 0.82rem;
817
- color: var(--gl-text-muted);
818
- font-style: italic;
819
- margin-right: auto;
820
- }
786
+ .modal-buttons { display: flex; justify-content: flex-end; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.75rem; }
787
+ .modal-buttons button { min-width: 5.5rem; }
788
+ .modal-shortcut-hint { font-size: 0.78rem; color: var(--faint); margin-right: auto; }
821
789
  .modal-head { display: flex; justify-content: space-between; align-items: center; }
822
790
  .modal input[type="text"], .modal input[type="password"], .modal textarea, .modal select {
823
791
  width: 100%;
824
- padding: 0.5rem 0.6rem;
825
- border: 1px solid var(--gl-border);
826
- border-radius: var(--gl-radius-sm);
827
- background: var(--gl-bg);
828
- }
829
- .modal textarea { min-height: 12rem; font-family: var(--gl-font-mono); font-size: 0.82rem; }
830
- .login { display: grid; gap: 0.6rem; }
831
- .login label { display: grid; gap: 0.25rem; font-size: 0.95rem; }
792
+ padding: 0.5rem 0.65rem;
793
+ border: 1px solid var(--rule-strong);
794
+ border-radius: var(--radius);
795
+ background-color: var(--bg);
796
+ }
797
+ .modal select { padding-right: 1.8rem; }
798
+ .modal input:focus, .modal textarea:focus { outline: none; border-color: var(--accent); }
799
+ .modal textarea { min-height: 12rem; font-family: var(--mono); font-size: 0.8rem; }
800
+ .login { display: grid; gap: 0.7rem; }
801
+ .login label { display: grid; gap: 0.3rem; font-size: 0.86rem; font-weight: 500; }
832
802
  .login p { margin: 0; }
833
- .check { display: flex; gap: 0.4rem; align-items: center; font-size: 0.92rem; margin-bottom: 0.5rem; }
803
+ .check { display: flex; gap: 0.45rem; align-items: center; font-size: 0.88rem; margin-bottom: 0.6rem; }
804
+ .check input { accent-color: var(--accent); }
834
805
 
835
806
  .models {
836
807
  list-style: none;
@@ -838,56 +809,62 @@ body.layout-full .msg.user .bubble {
838
809
  padding: 0;
839
810
  max-height: 16rem;
840
811
  overflow-y: auto;
841
- border: 1px solid var(--gl-border);
842
- border-radius: var(--gl-radius-sm);
812
+ border: 1px solid var(--rule);
813
+ border-radius: var(--radius);
843
814
  }
844
- .models li + li { border-top: 1px solid var(--gl-border); }
815
+ .models li + li { border-top: 1px solid var(--rule); }
845
816
  .models button {
846
817
  width: 100%;
847
818
  text-align: left;
848
819
  border-radius: 0;
849
- font-family: var(--gl-font-mono);
850
- font-size: 0.80rem;
851
- padding: 0.45rem 0.75rem;
820
+ font-family: var(--mono);
821
+ font-size: 0.78rem;
822
+ padding: 0.5rem 0.8rem;
852
823
  }
853
- .models button:hover { background: var(--gl-bg); }
854
- .models .current { font-weight: 700; color: var(--mode); }
855
- .models .empty-models { padding: 0.6rem 0.75rem; color: var(--gl-text-muted); font-size: 0.95rem; }
824
+ .models button:hover { background: var(--bg); }
825
+ .models .current { color: var(--accent); font-weight: 600; background: var(--accent-soft); }
826
+ .models .empty-models { padding: 0.65rem 0.8rem; color: var(--muted); font-size: 0.88rem; }
827
+
828
+ /* ---------------------------------------------------------------- narrow screens */
856
829
 
857
830
  .side .phone-only { display: none; }
858
- .settings { display: grid; gap: 0.6rem; }
859
- .settings label { display: grid; gap: 0.25rem; font-size: 0.88rem; color: var(--gl-text-muted); }
860
- .settings select {
861
- border: 1px solid var(--gl-border);
862
- border-radius: var(--gl-radius-sm);
863
- background: var(--gl-surface-raised);
864
- padding: 0.4rem 0.5rem;
865
- color: var(--gl-text);
866
- }
867
- .settings .model-btn { text-align: left; color: var(--gl-text); }
868
-
869
- /* ---- Responsive (Mobile) ---- */
831
+ .settings { display: grid; gap: 0.6rem; padding: 0 0.3rem; }
832
+ .settings label { display: grid; gap: 0.25rem; font-size: 0.78rem; color: var(--muted); }
833
+ .settings select, .settings button { width: 100%; text-align: left; color: var(--text); }
834
+ .settings .model-btn { font-family: var(--mono); font-size: 0.78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
835
+
836
+ @media (max-width: 64rem) {
837
+ .composer-hint { display: none; }
838
+ }
839
+
870
840
  @media (max-width: 52rem) {
871
- .app { grid-template-columns: minmax(0, 1fr); }
872
- .menu-btn { display: inline-block; border: 1px solid var(--gl-border); }
841
+ .app, .app.side-collapsed { grid-template-columns: minmax(0, 1fr); }
842
+ .app.side-collapsed .side { display: flex; }
873
843
  .side {
874
844
  position: fixed;
875
845
  z-index: 20;
876
- top: 0;
877
- bottom: 0;
878
- left: 0;
879
- width: min(20rem, 85vw);
846
+ inset: 0 auto 0 0;
847
+ width: min(19rem, 86vw);
880
848
  transform: translateX(-100%);
881
849
  transition: transform 0.2s ease;
882
- box-shadow: 0 0 30px rgba(0,0,0,0.3);
850
+ box-shadow: var(--shadow);
883
851
  }
884
852
  .side.open { transform: none; }
885
- .status { margin-left: 0; width: 100%; }
886
- .status .profile, .status .model-btn { display: none; }
853
+ .top { padding: 0.5rem 0.75rem; gap: 0.5rem; }
854
+ .wide-only { display: none !important; }
855
+ .library .library-text { display: none; }
856
+ .library { padding: 0.3rem; }
887
857
  .side .phone-only { display: grid; }
888
- .top { gap: 0.5rem 0.75rem; }
889
- .log { padding: 1rem 0.85rem 1.5rem; }
890
- .composer { padding: 0.65rem 0.85rem 0.85rem; }
891
- .composer-buttons { flex-direction: column; }
858
+ .log { padding: 1.25rem 0.9rem 1.5rem; }
859
+ .composer { padding: 0 0.75rem 0.75rem; }
860
+ .empty { padding-top: 5vh; }
861
+ }
862
+
863
+ @media (max-width: 30rem) {
864
+ .brand > span { display: none; }
865
+ .modes button { padding: 0.28rem 0.6rem; }
866
+ }
867
+
868
+ @media (prefers-reduced-motion: reduce) {
869
+ *, *::before, *::after { animation: none !important; transition: none !important; }
892
870
  }
893
- @media (prefers-reduced-motion: reduce) { .side { transition: none; } }