Spaces:
Paused
Paused
Pi Web fork: focus as Claude Code Desktop draws it; sidebar, session info and Settings aligned
Browse files- piweb/hf-design.patch +777 -218
piweb/hf-design.patch
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
diff --git a/AGENTS.md b/AGENTS.md
|
| 2 |
-
index a5c8983..
|
| 3 |
--- a/AGENTS.md
|
| 4 |
+++ b/AGENTS.md
|
| 5 |
@@ -65,8 +65,13 @@ app/api/
|
|
@@ -156,7 +156,7 @@ index a5c8983..749afce 100644
|
|
| 156 |
|
| 157 |
## Pi Session File Format
|
| 158 |
|
| 159 |
-
@@ -274,3 +317,
|
| 160 |
--accent --user-bg --tool-bg
|
| 161 |
--font-mono
|
| 162 |
```
|
|
@@ -179,22 +179,16 @@ index a5c8983..749afce 100644
|
|
| 179 |
+newer parts, menus, tooltips and popovers in `app/ui.css`, the header and tiles in `app/shell.css`)
|
| 180 |
+are styled there too.
|
| 181 |
+`--accent` is a neutral gray in light and dark (no blue anywhere: links are told apart by their
|
| 182 |
-
+underline, focus by
|
| 183 |
+All code (fences, the file viewer, tool inputs and outputs, diffs) is highlighted by Shiki in `lib/diffs-theme.ts`'s neutral themes (`components/highlighting.ts`); the terminal keeps its ANSI hues.
|
| 184 |
-
+Keyboard focus is `app/focus.css`, imported last
|
| 185 |
-
+
|
| 186 |
-
+
|
|
|
|
|
|
|
|
|
|
|
|
|
| 187 |
+focus); closed panels are `inert`; modals use `keepTabInside`.
|
| 188 |
-
+
|
| 189 |
-
+<!-- BEGIN:nextjs-agent-rules -->
|
| 190 |
-
+
|
| 191 |
-
+# This is NOT the Next.js you know
|
| 192 |
-
+
|
| 193 |
-
+This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.
|
| 194 |
-
+
|
| 195 |
-
+This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.
|
| 196 |
-
+
|
| 197 |
-
+<!-- END:nextjs-agent-rules -->
|
| 198 |
diff --git a/app/api/browser/events/route.ts b/app/api/browser/events/route.ts
|
| 199 |
new file mode 100644
|
| 200 |
index 0000000..84aa812
|
|
@@ -1198,34 +1192,54 @@ x=WyK>Q474TgO3Dx+=lt**@4jiTmoXh>QX;DqIUnCXbm^o4n^-mRR&Qm{tL_JHERF>
|
|
| 1198 |
|
| 1199 |
diff --git a/app/focus.css b/app/focus.css
|
| 1200 |
new file mode 100644
|
| 1201 |
-
index 0000000..
|
| 1202 |
--- /dev/null
|
| 1203 |
+++ b/app/focus.css
|
| 1204 |
-
@@ -0,0 +1,
|
| 1205 |
+/* Keyboard focus, one way everywhere (the design system's "Motion and states").
|
| 1206 |
+ Imported last (app/layout.tsx), so these rules win over each component's.
|
| 1207 |
+
|
| 1208 |
-
+ One indicator
|
|
|
|
|
|
|
|
|
|
| 1209 |
+ ring and a second ring, never a box around a row's text:
|
| 1210 |
-
+ -
|
| 1211 |
-
+ not filled with ink: ghost and
|
| 1212 |
-
+ items, fields. A row draws
|
| 1213 |
-
+ draws nothing), so
|
| 1214 |
-
+
|
| 1215 |
-
+
|
| 1216 |
-
+
|
| 1217 |
-
+
|
|
|
|
|
|
|
|
|
|
| 1218 |
+ Mouse focus shows nothing (:focus-visible); text fields show their caret,
|
| 1219 |
+ and other fields the inset ring too, except the composer, which is always
|
| 1220 |
+ where typing goes. */
|
| 1221 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1222 |
+:where(button, summary, [role="button"], [role="tab"], [role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"], [role="option"], [role="switch"], [role="treeitem"], [tabindex]:not(input):not(textarea):not(select)):focus {
|
| 1223 |
+ outline: none;
|
| 1224 |
+}
|
| 1225 |
+
|
| 1226 |
-
+
|
| 1227 |
-
+
|
| 1228 |
-
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1229 |
+}
|
| 1230 |
+
|
| 1231 |
+:where(a[href]):focus {
|
|
@@ -1233,18 +1247,19 @@ index 0000000..f8b1d1c
|
|
| 1233 |
+}
|
| 1234 |
+
|
| 1235 |
+:where(a[href]):focus-visible {
|
| 1236 |
-
+ outline:
|
| 1237 |
+ outline-offset: 2px;
|
| 1238 |
+ border-radius: var(--radius-xs);
|
| 1239 |
+}
|
| 1240 |
+
|
| 1241 |
+:where(input:not([type="range"]):not([type="checkbox"]):not([type="radio"]), select, textarea):focus-visible {
|
| 1242 |
-
+ outline:
|
| 1243 |
-
+ outline-offset: -
|
|
|
|
| 1244 |
+}
|
| 1245 |
+
|
| 1246 |
+:where(input[type="checkbox"], input[type="radio"]):focus-visible {
|
| 1247 |
-
+ outline:
|
| 1248 |
+ outline-offset: 2px;
|
| 1249 |
+}
|
| 1250 |
+
|
|
@@ -1252,12 +1267,14 @@ index 0000000..f8b1d1c
|
|
| 1252 |
+.chat-input-textarea:focus,
|
| 1253 |
+.chat-input-textarea:focus-visible {
|
| 1254 |
+ outline: none;
|
|
|
|
| 1255 |
+}
|
| 1256 |
+
|
| 1257 |
+/* A visually hidden input inside an option (a theme, the send key) leaves the
|
| 1258 |
+ ring to the option. */
|
| 1259 |
+input.sr-only:focus-visible {
|
| 1260 |
+ outline: none;
|
|
|
|
| 1261 |
+}
|
| 1262 |
+
|
| 1263 |
+/* ---------------------------------------------------------------- filled with ink: 2px off */
|
|
@@ -1269,7 +1286,7 @@ index 0000000..f8b1d1c
|
|
| 1269 |
+.web-login-form button:focus-visible,
|
| 1270 |
+.chat-scroll-to-bottom:focus-visible,
|
| 1271 |
+.image-preview-close:focus-visible {
|
| 1272 |
-
+ outline:
|
| 1273 |
+ outline-offset: 2px;
|
| 1274 |
+}
|
| 1275 |
+
|
|
@@ -1298,8 +1315,9 @@ index 0000000..f8b1d1c
|
|
| 1298 |
+.extension-status-command:focus-visible,
|
| 1299 |
+button.extension-widget-trigger:focus-visible,
|
| 1300 |
+.new-session-update:focus-visible {
|
| 1301 |
-
+ outline:
|
| 1302 |
-
+ outline-offset: -
|
|
|
|
| 1303 |
+}
|
| 1304 |
+
|
| 1305 |
+.settings-section-tab:focus-visible,
|
|
@@ -1314,29 +1332,31 @@ index 0000000..f8b1d1c
|
|
| 1314 |
+
|
| 1315 |
+/* A Terminal tab being renamed: the tab is the field, its pill takes the ring (Desktop's
|
| 1316 |
+ has-[:focus-visible] on the tab), the bare input none. */
|
| 1317 |
-
+.terminal-tab-input:focus-visible { outline: none; }
|
| 1318 |
+.terminal-tab:has(.terminal-tab-input:focus-visible) {
|
| 1319 |
-
+ outline:
|
| 1320 |
-
+ outline-offset: -
|
|
|
|
| 1321 |
+}
|
| 1322 |
+
|
| 1323 |
+/* An option whose input is visually hidden: the option is the control. */
|
| 1324 |
+.settings-theme-option:has(input:focus-visible),
|
| 1325 |
+.settings-send-mode-option:has(input:focus-visible) {
|
| 1326 |
-
+ outline:
|
| 1327 |
-
+ outline-offset: -
|
|
|
|
| 1328 |
+}
|
| 1329 |
+
|
| 1330 |
-
+/* Fields, the filled ones too:
|
| 1331 |
+.settings-font-input:focus-visible,
|
| 1332 |
+.sidebar-search-input:focus,
|
| 1333 |
+.sidebar-search-input:focus-visible,
|
| 1334 |
+.sidebar-menu-filter-input:focus-visible,
|
| 1335 |
+.directory-picker-path:focus-visible {
|
| 1336 |
+ border-color: transparent !important;
|
| 1337 |
-
+ box-shadow:
|
| 1338 |
-
+ outline:
|
| 1339 |
-
+ outline-offset: -
|
| 1340 |
+}
|
| 1341 |
+
|
| 1342 |
+.sidebar-search-input:focus:not(:focus-visible) {
|
|
@@ -1345,13 +1365,14 @@ index 0000000..f8b1d1c
|
|
| 1345 |
+
|
| 1346 |
+.web-login-composer:focus-within {
|
| 1347 |
+ border-color: transparent;
|
| 1348 |
-
+ box-shadow:
|
| 1349 |
-
+ outline:
|
| 1350 |
-
+ outline-offset: -
|
| 1351 |
+}
|
| 1352 |
+
|
| 1353 |
+.web-login-composer :is(input, textarea):focus-visible {
|
| 1354 |
+ outline: none;
|
|
|
|
| 1355 |
+}
|
| 1356 |
+
|
| 1357 |
+/* The top bar's 36px edge buttons (the sidebar toggle): a
|
|
@@ -1362,8 +1383,9 @@ index 0000000..f8b1d1c
|
|
| 1362 |
+}
|
| 1363 |
+
|
| 1364 |
+.topbar-edge-button:focus-visible {
|
| 1365 |
-
+ outline:
|
| 1366 |
+ outline-offset: -4px;
|
|
|
|
| 1367 |
+}
|
| 1368 |
+
|
| 1369 |
+/* ---------------------------------------------------------------- rows: the ring is the row's */
|
|
@@ -1372,21 +1394,25 @@ index 0000000..f8b1d1c
|
|
| 1372 |
+.session-tree .session-tree-main:focus-visible,
|
| 1373 |
+.session-tree a.session-tree-main:focus-visible {
|
| 1374 |
+ outline: none;
|
|
|
|
| 1375 |
+}
|
| 1376 |
+
|
| 1377 |
+.session-tree-session:has(> .session-tree-main:focus-visible) {
|
| 1378 |
-
+ outline:
|
| 1379 |
-
+ outline-offset: -
|
|
|
|
| 1380 |
+}
|
| 1381 |
+
|
| 1382 |
+/* A project header: the same, on the header's box (its + and ⋯ ring themselves). */
|
| 1383 |
+.session-tree .session-tree-group-toggle:focus-visible {
|
| 1384 |
+ outline: none;
|
|
|
|
| 1385 |
+}
|
| 1386 |
+
|
| 1387 |
+.session-tree-group:has(> .session-tree-group-toggle:focus-visible) {
|
| 1388 |
-
+ outline:
|
| 1389 |
-
+ outline-offset: -
|
|
|
|
| 1390 |
+}
|
| 1391 |
+
|
| 1392 |
+/* Rows whose control spans the row: the control's own box, with the row's corners. */
|
|
@@ -1395,18 +1421,21 @@ index 0000000..f8b1d1c
|
|
| 1395 |
+.session-tree .session-tree-more-toggle:focus-visible,
|
| 1396 |
+.sidebar-files-section-toggle:focus-visible {
|
| 1397 |
+ border-radius: var(--radius-sm);
|
| 1398 |
-
+ outline:
|
| 1399 |
-
+ outline-offset: -
|
|
|
|
| 1400 |
+}
|
| 1401 |
+
|
| 1402 |
+/* A tool call or a thought: the whole step line, its time included. */
|
| 1403 |
+.tool-call-head:focus-visible {
|
| 1404 |
+ outline: none;
|
|
|
|
| 1405 |
+}
|
| 1406 |
+
|
| 1407 |
+.tool-call-row:has(> .tool-call-head:focus-visible) {
|
| 1408 |
-
+ outline:
|
| 1409 |
-
+ outline-offset: -
|
|
|
|
| 1410 |
+}
|
| 1411 |
+
|
| 1412 |
+/* Browsers without :has() keep the ring on the inner control. */
|
|
@@ -1415,14 +1444,16 @@ index 0000000..f8b1d1c
|
|
| 1415 |
+ .session-tree .session-tree-group-toggle:focus-visible,
|
| 1416 |
+ .tool-call-head:focus-visible {
|
| 1417 |
+ border-radius: var(--radius-sm);
|
| 1418 |
-
+ outline:
|
| 1419 |
-
+ outline-offset: -
|
|
|
|
| 1420 |
+ }
|
| 1421 |
+}
|
| 1422 |
+
|
| 1423 |
-
+/* A resize handle: its line turns into the
|
| 1424 |
+.panel-resize-handle:focus-visible {
|
| 1425 |
+ outline: none;
|
|
|
|
| 1426 |
+}
|
| 1427 |
+
|
| 1428 |
+/* ---------------------------------------------------------------- sliders
|
|
@@ -1439,6 +1470,7 @@ index 0000000..f8b1d1c
|
|
| 1439 |
+input[type="range"]:focus,
|
| 1440 |
+input[type="range"]:focus-visible {
|
| 1441 |
+ outline: none;
|
|
|
|
| 1442 |
+}
|
| 1443 |
+
|
| 1444 |
+input[type="range"]::-webkit-slider-runnable-track {
|
|
@@ -1480,11 +1512,11 @@ index 0000000..f8b1d1c
|
|
| 1480 |
+}
|
| 1481 |
+
|
| 1482 |
+input[type="range"]:focus-visible::-webkit-slider-thumb {
|
| 1483 |
-
+ box-shadow: 0 0 0 2px var(--bg-elevated, var(--bg)), 0 0 0
|
| 1484 |
+}
|
| 1485 |
+
|
| 1486 |
+input[type="range"]:focus-visible::-moz-range-thumb {
|
| 1487 |
-
+ box-shadow: 0 0 0 2px var(--bg-elevated, var(--bg)), 0 0 0
|
| 1488 |
+}
|
| 1489 |
+
|
| 1490 |
+input[type="range"]:disabled {
|
|
@@ -1493,8 +1525,109 @@ index 0000000..f8b1d1c
|
|
| 1493 |
+}
|
| 1494 |
+
|
| 1495 |
+.panel-resize-handle:focus-visible::after {
|
| 1496 |
-
+ background: var(--focus-
|
| 1497 |
+}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1498 |
diff --git a/app/fonts/Geist-Variable.woff2 b/app/fonts/Geist-Variable.woff2
|
| 1499 |
new file mode 100644
|
| 1500 |
index 0000000000000000000000000000000000000000..9983e92a03de482b5708201694101c330b6ae9b8
|
|
@@ -3822,7 +3955,7 @@ index 0000000..8d003fe
|
|
| 3822 |
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
| 3823 |
+OTHER DEALINGS IN THE FONT SOFTWARE.
|
| 3824 |
diff --git a/app/globals.css b/app/globals.css
|
| 3825 |
-
index d6b5535..
|
| 3826 |
--- a/app/globals.css
|
| 3827 |
+++ b/app/globals.css
|
| 3828 |
@@ -24,46 +24,109 @@
|
|
@@ -4120,6 +4253,15 @@ index d6b5535..959b58f 100644
|
|
| 4120 |
background: var(--accent);
|
| 4121 |
color: var(--accent-contrast);
|
| 4122 |
cursor: pointer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4123 |
@@ -332,110 +415,139 @@ html.dark .web-login-error {
|
| 4124 |
cursor: not-allowed;
|
| 4125 |
}
|
|
@@ -4412,7 +4554,19 @@ index d6b5535..959b58f 100644
|
|
| 4412 |
|
| 4413 |
|
| 4414 |
.extension-status-shelf {
|
| 4415 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4416 |
|
| 4417 |
.extension-widget-placement-icon {
|
| 4418 |
display: block;
|
|
@@ -4425,7 +4579,19 @@ index d6b5535..959b58f 100644
|
|
| 4425 |
fill: currentColor;
|
| 4426 |
}
|
| 4427 |
|
| 4428 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4429 |
}
|
| 4430 |
|
| 4431 |
:root {
|
|
@@ -4436,7 +4602,7 @@ index d6b5535..959b58f 100644
|
|
| 4436 |
--font-ui: var(--font-ui-default);
|
| 4437 |
--font-mono: var(--font-mono-default);
|
| 4438 |
--font-ui-weight: 400;
|
| 4439 |
-
@@ -883,11 +
|
| 4440 |
.markdown-body ol > li { list-style-type: decimal; }
|
| 4441 |
.markdown-body li > p { margin: 0; }
|
| 4442 |
.markdown-body li::marker {
|
|
@@ -4451,7 +4617,7 @@ index d6b5535..959b58f 100644
|
|
| 4451 |
font-weight: 700;
|
| 4452 |
}
|
| 4453 |
.markdown-body em { color: var(--text-muted); }
|
| 4454 |
-
@@ -896,24 +
|
| 4455 |
text-decoration: underline;
|
| 4456 |
text-decoration-thickness: 1px;
|
| 4457 |
text-underline-offset: 3px;
|
|
@@ -4480,7 +4646,7 @@ index d6b5535..959b58f 100644
|
|
| 4480 |
}
|
| 4481 |
.markdown-body .contains-task-list {
|
| 4482 |
padding-left: 0;
|
| 4483 |
-
@@ -935,7 +
|
| 4484 |
height: 14px;
|
| 4485 |
margin: 0;
|
| 4486 |
border: 1px solid var(--border);
|
|
@@ -4489,7 +4655,7 @@ index d6b5535..959b58f 100644
|
|
| 4489 |
background: var(--bg);
|
| 4490 |
display: inline-grid;
|
| 4491 |
place-content: center;
|
| 4492 |
-
@@ -967,8 +
|
| 4493 |
margin: 8px 0;
|
| 4494 |
overflow-x: auto;
|
| 4495 |
overflow-y: hidden;
|
|
@@ -4500,7 +4666,7 @@ index d6b5535..959b58f 100644
|
|
| 4500 |
}
|
| 4501 |
.markdown-body table {
|
| 4502 |
border-collapse: separate;
|
| 4503 |
-
@@ -1088,7 +
|
| 4504 |
padding: 7px 8px;
|
| 4505 |
overflow: auto;
|
| 4506 |
border: 1px solid var(--border);
|
|
@@ -4509,7 +4675,7 @@ index d6b5535..959b58f 100644
|
|
| 4509 |
background: var(--bg-panel);
|
| 4510 |
font-family: var(--font-mono);
|
| 4511 |
font-size: 11px;
|
| 4512 |
-
@@ -1108,16 +
|
| 4513 |
min-width: 0;
|
| 4514 |
max-width: 100%;
|
| 4515 |
margin: 6px 0;
|
|
@@ -4529,7 +4695,7 @@ index d6b5535..959b58f 100644
|
|
| 4529 |
color: var(--text-dim);
|
| 4530 |
font-size: 11px;
|
| 4531 |
display: flex;
|
| 4532 |
-
@@ -1137,7 +
|
| 4533 |
}
|
| 4534 |
.markdown-code-action {
|
| 4535 |
border: 1px solid var(--border);
|
|
@@ -4538,7 +4704,19 @@ index d6b5535..959b58f 100644
|
|
| 4538 |
padding: 2px 7px;
|
| 4539 |
background: var(--bg);
|
| 4540 |
color: var(--text-muted);
|
| 4541 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4542 |
max-width: 100%;
|
| 4543 |
max-height: 100%;
|
| 4544 |
object-fit: contain;
|
|
@@ -4547,7 +4725,7 @@ index d6b5535..959b58f 100644
|
|
| 4547 |
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
|
| 4548 |
}
|
| 4549 |
|
| 4550 |
-
@@ -1244,7 +
|
| 4551 |
height: 36px;
|
| 4552 |
padding: 0;
|
| 4553 |
border: 1px solid var(--border);
|
|
@@ -4556,7 +4734,16 @@ index d6b5535..959b58f 100644
|
|
| 4556 |
background: var(--bg-panel);
|
| 4557 |
color: var(--text-muted);
|
| 4558 |
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.28);
|
| 4559 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4560 |
height: 24px;
|
| 4561 |
overflow: hidden;
|
| 4562 |
border: 1px solid var(--border);
|
|
@@ -4565,7 +4752,7 @@ index d6b5535..959b58f 100644
|
|
| 4565 |
background: var(--bg);
|
| 4566 |
}
|
| 4567 |
.mermaid-zoom-stepper button,
|
| 4568 |
-
@@ -1347,7 +
|
| 4569 |
.mermaid-zoom-icon-button {
|
| 4570 |
flex: 0 0 24px;
|
| 4571 |
border: 1px solid var(--border);
|
|
@@ -4574,7 +4761,19 @@ index d6b5535..959b58f 100644
|
|
| 4574 |
}
|
| 4575 |
.mermaid-zoom-stepper button:hover:not(:disabled),
|
| 4576 |
.mermaid-zoom-icon-button:hover {
|
| 4577 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4578 |
.mermaid-zoom-canvas {
|
| 4579 |
padding: 12px;
|
| 4580 |
border: 1px solid var(--border);
|
|
@@ -4583,7 +4782,7 @@ index d6b5535..959b58f 100644
|
|
| 4583 |
background: var(--bg-panel);
|
| 4584 |
margin: 0 auto;
|
| 4585 |
transition: width 0.15s ease;
|
| 4586 |
-
@@ -1460,7 +
|
| 4587 |
height: 24px;
|
| 4588 |
overflow: hidden;
|
| 4589 |
border: 1px solid var(--border);
|
|
@@ -4592,7 +4791,7 @@ index d6b5535..959b58f 100644
|
|
| 4592 |
}
|
| 4593 |
|
| 4594 |
.file-viewer-mode-button {
|
| 4595 |
-
@@ -1503,12 +
|
| 4596 |
height: 32px;
|
| 4597 |
padding: 0;
|
| 4598 |
box-sizing: border-box;
|
|
@@ -4607,7 +4806,16 @@ index d6b5535..959b58f 100644
|
|
| 4607 |
opacity: 0;
|
| 4608 |
visibility: hidden;
|
| 4609 |
pointer-events: none;
|
| 4610 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4611 |
}
|
| 4612 |
}
|
| 4613 |
|
|
@@ -4625,7 +4833,7 @@ index d6b5535..959b58f 100644
|
|
| 4625 |
margin: 0 auto;
|
| 4626 |
}
|
| 4627 |
|
| 4628 |
-
@@ -1584,22 +
|
| 4629 |
|
| 4630 |
.new-session-logo {
|
| 4631 |
flex: none;
|
|
@@ -4654,7 +4862,7 @@ index d6b5535..959b58f 100644
|
|
| 4654 |
line-height: 1.15;
|
| 4655 |
white-space: nowrap;
|
| 4656 |
}
|
| 4657 |
-
@@ -1613,7 +
|
| 4658 |
gap: 6px;
|
| 4659 |
min-width: 0;
|
| 4660 |
color: var(--text-dim);
|
|
@@ -4664,7 +4872,7 @@ index d6b5535..959b58f 100644
|
|
| 4664 |
line-height: 1.4;
|
| 4665 |
white-space: nowrap;
|
| 4666 |
}
|
| 4667 |
-
@@ -1638,7 +
|
| 4668 |
gap: 3px;
|
| 4669 |
margin: -3px -4px;
|
| 4670 |
padding: 3px 4px;
|
|
@@ -4673,16 +4881,18 @@ index d6b5535..959b58f 100644
|
|
| 4673 |
color: var(--accent);
|
| 4674 |
font-weight: 600;
|
| 4675 |
text-decoration: none;
|
| 4676 |
-
@@ -1652,
|
| 4677 |
|
| 4678 |
/* The ring inside the box, clear of the "→" and "·" beside it. */
|
| 4679 |
.new-session-update:focus-visible {
|
| 4680 |
- outline: 2px solid var(--accent);
|
| 4681 |
-
|
| 4682 |
-
|
|
|
|
|
|
|
| 4683 |
}
|
| 4684 |
|
| 4685 |
-
|
| 4686 |
flex: none;
|
| 4687 |
}
|
| 4688 |
|
|
@@ -4716,7 +4926,7 @@ index d6b5535..959b58f 100644
|
|
| 4716 |
}
|
| 4717 |
}
|
| 4718 |
|
| 4719 |
-
@@ -1700,8 +
|
| 4720 |
tab's stacked boxes, the row below the sessions), as the sidebar drew it
|
| 4721 |
on main: two grey boxes in the header buttons' material, 11px, the
|
| 4722 |
project's whole path and the worktree's branch in code type, cut at their
|
|
@@ -4727,7 +4937,7 @@ index d6b5535..959b58f 100644
|
|
| 4727 |
.project-picker {
|
| 4728 |
display: flex;
|
| 4729 |
align-items: center;
|
| 4730 |
-
@@ -1722,52 +
|
| 4731 |
min-width: 0;
|
| 4732 |
height: 29px;
|
| 4733 |
padding: 0 10px;
|
|
@@ -4783,7 +4993,7 @@ index d6b5535..959b58f 100644
|
|
| 4783 |
}
|
| 4784 |
|
| 4785 |
/* The project's name (its display name, else its folder's), cut at its
|
| 4786 |
-
@@ -1781,8 +
|
| 4787 |
max-width: 28ch;
|
| 4788 |
overflow: hidden;
|
| 4789 |
color: var(--text-dim);
|
|
@@ -4794,7 +5004,7 @@ index d6b5535..959b58f 100644
|
|
| 4794 |
}
|
| 4795 |
|
| 4796 |
.project-picker-parent {
|
| 4797 |
-
@@ -1800,10 +
|
| 4798 |
text-overflow: ellipsis;
|
| 4799 |
}
|
| 4800 |
|
|
@@ -4805,7 +5015,19 @@ index d6b5535..959b58f 100644
|
|
| 4805 |
.project-picker-button:hover,
|
| 4806 |
.project-picker-button[aria-expanded="true"] {
|
| 4807 |
background: var(--bg-selected);
|
| 4808 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4809 |
path's color and code type, cut at its end. */
|
| 4810 |
.project-picker-label.is-alias {
|
| 4811 |
color: var(--text);
|
|
@@ -4815,7 +5037,7 @@ index d6b5535..959b58f 100644
|
|
| 4815 |
}
|
| 4816 |
|
| 4817 |
/* A path or a branch, cut at its left (rtl), the text itself kept left to
|
| 4818 |
-
@@ -1901,7 +
|
| 4819 |
border-color: color-mix(in srgb, var(--accent) 40%, transparent);
|
| 4820 |
background: color-mix(in srgb, var(--accent) 6%, transparent);
|
| 4821 |
color: var(--text-dim);
|
|
@@ -4825,7 +5047,7 @@ index d6b5535..959b58f 100644
|
|
| 4825 |
}
|
| 4826 |
|
| 4827 |
/* No worktree list here (the files tab): a box that says why, and does nothing. */
|
| 4828 |
-
@@ -1978,7 +
|
| 4829 |
box-sizing: border-box;
|
| 4830 |
flex: 0 0 24px;
|
| 4831 |
border: 1px solid var(--border);
|
|
@@ -4834,7 +5056,19 @@ index d6b5535..959b58f 100644
|
|
| 4834 |
background: transparent;
|
| 4835 |
color: var(--text-muted);
|
| 4836 |
cursor: pointer;
|
| 4837 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4838 |
.markdown-file-preview pre {
|
| 4839 |
background: var(--bg-panel);
|
| 4840 |
border: 1px solid var(--border);
|
|
@@ -4843,7 +5077,7 @@ index d6b5535..959b58f 100644
|
|
| 4843 |
padding: 12px 16px;
|
| 4844 |
overflow-x: auto;
|
| 4845 |
font-family: var(--font-mono);
|
| 4846 |
-
@@ -2049,7 +
|
| 4847 |
font-size: 0.9em;
|
| 4848 |
background: var(--bg-panel);
|
| 4849 |
padding: 1px 5px;
|
|
@@ -4852,7 +5086,7 @@ index d6b5535..959b58f 100644
|
|
| 4852 |
}
|
| 4853 |
.markdown-file-preview pre code {
|
| 4854 |
background: none;
|
| 4855 |
-
@@ -2061,7 +
|
| 4856 |
margin-bottom: 20px;
|
| 4857 |
padding: 14px 16px 12px;
|
| 4858 |
border: 1px solid var(--border);
|
|
@@ -4861,7 +5095,7 @@ index d6b5535..959b58f 100644
|
|
| 4861 |
background: var(--bg-panel);
|
| 4862 |
}
|
| 4863 |
.markdown-frontmatter-title {
|
| 4864 |
-
@@ -2114,18 +
|
| 4865 |
text-underline-offset: 2px;
|
| 4866 |
}
|
| 4867 |
|
|
@@ -4880,7 +5114,7 @@ index d6b5535..959b58f 100644
|
|
| 4880 |
@keyframes drop-zone-in {
|
| 4881 |
from { opacity: 0; transform: scale(0.97); }
|
| 4882 |
to { opacity: 1; transform: scale(1); }
|
| 4883 |
-
@@ -2230,10 +
|
| 4884 |
.panel-resize-handle.is-resizing::after {
|
| 4885 |
background: color-mix(in srgb, var(--text-muted) 70%, var(--border));
|
| 4886 |
}
|
|
@@ -4891,7 +5125,7 @@ index d6b5535..959b58f 100644
|
|
| 4891 |
/* Desktop sidebar: animate width */
|
| 4892 |
@media (min-width: 641px) {
|
| 4893 |
.sidebar-overlay-backdrop {
|
| 4894 |
-
@@ -2264,119 +
|
| 4895 |
}
|
| 4896 |
}
|
| 4897 |
|
|
@@ -5011,7 +5245,7 @@ index d6b5535..959b58f 100644
|
|
| 5011 |
/* Mobile sidebar: slide in/out as overlay */
|
| 5012 |
@media (max-width: 640px) {
|
| 5013 |
.chat-stats-center {
|
| 5014 |
-
@@ -2401,31 +
|
| 5015 |
box-shadow: none;
|
| 5016 |
}
|
| 5017 |
|
|
@@ -5044,7 +5278,7 @@ index d6b5535..959b58f 100644
|
|
| 5044 |
display: none;
|
| 5045 |
}
|
| 5046 |
.directory-picker-back,
|
| 5047 |
-
@@ -2474,3 +
|
| 5048 |
display: none !important;
|
| 5049 |
}
|
| 5050 |
}
|
|
@@ -5192,7 +5426,7 @@ index d6b5535..959b58f 100644
|
|
| 5192 |
+}
|
| 5193 |
+.user-bubble.is-editing {
|
| 5194 |
+ background: color-mix(in srgb, var(--accent) 14%, var(--user-bg));
|
| 5195 |
-
+ box-shadow: 0 0 0
|
| 5196 |
+}
|
| 5197 |
+/* The actions under a message: icon buttons that show on hover or focus. */
|
| 5198 |
+.message-actions {
|
|
@@ -5447,8 +5681,12 @@ index d6b5535..959b58f 100644
|
|
| 5447 |
+.reply-notice.is-error { background: var(--danger-soft); color: var(--danger); }
|
| 5448 |
+.reply-notice.is-warning { background: color-mix(in srgb, var(--warning) 12%, transparent); color: var(--warning); }
|
| 5449 |
+
|
| 5450 |
-
+/* The sidebar's bottom row (AppShell):
|
| 5451 |
-
+
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5452 |
+.sidebar-footer {
|
| 5453 |
+ display: flex;
|
| 5454 |
+ flex-shrink: 0;
|
|
@@ -5470,11 +5708,11 @@ index d6b5535..959b58f 100644
|
|
| 5470 |
+ display: flex;
|
| 5471 |
+ flex: 1 1 0;
|
| 5472 |
+ align-items: center;
|
| 5473 |
-
+ justify-content:
|
| 5474 |
-
+ gap:
|
| 5475 |
+ min-width: 0;
|
| 5476 |
+ height: var(--size-control-sm);
|
| 5477 |
-
+ padding: 0
|
| 5478 |
+ border: 0;
|
| 5479 |
+ border-radius: var(--radius-sm);
|
| 5480 |
+ background: none;
|
|
@@ -5645,7 +5883,7 @@ index 79c8282..97731f1 100644
|
|
| 5645 |
lang: "en",
|
| 5646 |
icons: [
|
| 5647 |
diff --git a/app/settings.css b/app/settings.css
|
| 5648 |
-
index 0bf21eb..
|
| 5649 |
--- a/app/settings.css
|
| 5650 |
+++ b/app/settings.css
|
| 5651 |
@@ -40,9 +40,9 @@
|
|
@@ -5679,7 +5917,43 @@ index 0bf21eb..e8788d8 100644
|
|
| 5679 |
background: transparent;
|
| 5680 |
color: var(--text-muted);
|
| 5681 |
cursor: pointer;
|
| 5682 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5683 |
}
|
| 5684 |
|
| 5685 |
.config-sidebar-group-count {
|
|
@@ -5690,7 +5964,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5690 |
}
|
| 5691 |
|
| 5692 |
/* Three lines, then scroll: the phone layout gives the whole sidebar 190px. */
|
| 5693 |
-
@@ -188,7 +
|
| 5694 |
height: 30px;
|
| 5695 |
padding: 0 8px;
|
| 5696 |
border: 0;
|
|
@@ -5699,7 +5973,19 @@ index 0bf21eb..e8788d8 100644
|
|
| 5699 |
outline: none;
|
| 5700 |
background: transparent;
|
| 5701 |
color: var(--text);
|
| 5702 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5703 |
.models-sidebar-badge {
|
| 5704 |
flex-shrink: 0;
|
| 5705 |
color: var(--text-dim);
|
|
@@ -5710,7 +5996,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5710 |
}
|
| 5711 |
|
| 5712 |
.oauth-paste-panel {
|
| 5713 |
-
@@ -277,9 +
|
| 5714 |
/* An input's intrinsic width would otherwise push the button out of a narrow pane. */
|
| 5715 |
min-width: 0;
|
| 5716 |
padding: 6px 9px;
|
|
@@ -5722,7 +6008,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5722 |
color: var(--text);
|
| 5723 |
font-family: var(--font-mono);
|
| 5724 |
font-size: 12px;
|
| 5725 |
-
@@ -290,9 +
|
| 5726 |
flex-shrink: 0;
|
| 5727 |
padding: 6px 12px;
|
| 5728 |
border: none;
|
|
@@ -5735,7 +6021,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5735 |
cursor: pointer;
|
| 5736 |
font-size: 12px;
|
| 5737 |
font-weight: 600;
|
| 5738 |
-
@@ -370,8 +
|
| 5739 |
.enabled-models-count {
|
| 5740 |
margin-right: auto;
|
| 5741 |
color: var(--text-dim);
|
|
@@ -5746,7 +6032,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5746 |
}
|
| 5747 |
|
| 5748 |
.enabled-models-note {
|
| 5749 |
-
@@ -383,7 +
|
| 5750 |
.enabled-models-error {
|
| 5751 |
padding: 7px 9px;
|
| 5752 |
border: 1px solid rgba(239, 68, 68, 0.3);
|
|
@@ -5755,7 +6041,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5755 |
color: #ef4444;
|
| 5756 |
font-size: 11px;
|
| 5757 |
line-height: 1.4;
|
| 5758 |
-
@@ -401,10 +
|
| 5759 |
box-sizing: border-box;
|
| 5760 |
height: 30px;
|
| 5761 |
padding: 0 9px;
|
|
@@ -5768,7 +6054,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5768 |
color: var(--text);
|
| 5769 |
font-family: inherit;
|
| 5770 |
font-size: 12px;
|
| 5771 |
-
@@ -413,7 +
|
| 5772 |
.enabled-models-list {
|
| 5773 |
max-height: 360px;
|
| 5774 |
border: 1px solid var(--border);
|
|
@@ -5777,7 +6063,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5777 |
background: var(--bg-panel);
|
| 5778 |
overflow-y: auto;
|
| 5779 |
}
|
| 5780 |
-
@@ -457,9 +
|
| 5781 |
.enabled-models-pin {
|
| 5782 |
flex-shrink: 0;
|
| 5783 |
padding: 1px 4px;
|
|
@@ -5790,7 +6076,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5790 |
font-size: 9px;
|
| 5791 |
}
|
| 5792 |
|
| 5793 |
-
@@ -497,7 +
|
| 5794 |
justify-content: space-between;
|
| 5795 |
gap: 18px;
|
| 5796 |
min-height: 68px;
|
|
@@ -5799,7 +6085,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5799 |
border-bottom: 1px solid var(--border);
|
| 5800 |
background: var(--bg-panel);
|
| 5801 |
}
|
| 5802 |
-
@@ -541,7 +
|
| 5803 |
height: 28px;
|
| 5804 |
padding: 0 6px;
|
| 5805 |
border: 1px solid var(--border);
|
|
@@ -5808,7 +6094,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5808 |
background: var(--bg);
|
| 5809 |
color: var(--text);
|
| 5810 |
font: inherit;
|
| 5811 |
-
@@ -566,7 +
|
| 5812 |
flex: 1;
|
| 5813 |
min-width: 0;
|
| 5814 |
min-height: 0;
|
|
@@ -5817,7 +6103,24 @@ index 0bf21eb..e8788d8 100644
|
|
| 5817 |
overflow-y: auto;
|
| 5818 |
font-family: inherit;
|
| 5819 |
font-size: 12px;
|
| 5820 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5821 |
background: var(--border);
|
| 5822 |
border: 5px solid transparent;
|
| 5823 |
background-clip: padding-box;
|
|
@@ -5826,7 +6129,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5826 |
}
|
| 5827 |
|
| 5828 |
.config-field-label {
|
| 5829 |
-
@@ -697,15 +
|
| 5830 |
.config-scope-tag {
|
| 5831 |
flex-shrink: 0;
|
| 5832 |
padding: 1px 5px;
|
|
@@ -5845,7 +6148,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5845 |
}
|
| 5846 |
|
| 5847 |
.config-scope-switch-field {
|
| 5848 |
-
@@ -730,7 +
|
| 5849 |
height: 30px;
|
| 5850 |
overflow: hidden;
|
| 5851 |
border: 1px solid var(--border);
|
|
@@ -5854,7 +6157,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5854 |
}
|
| 5855 |
|
| 5856 |
.config-scope-switch-option {
|
| 5857 |
-
@@ -760,7 +
|
| 5858 |
.config-scope-switch.is-small {
|
| 5859 |
display: flex;
|
| 5860 |
height: auto;
|
|
@@ -5863,7 +6166,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5863 |
font-size: 12px;
|
| 5864 |
}
|
| 5865 |
|
| 5866 |
-
@@ -891,9 +
|
| 5867 |
width: 100%;
|
| 5868 |
height: 36px;
|
| 5869 |
padding: 0 11px;
|
|
@@ -5875,7 +6178,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5875 |
color: var(--text);
|
| 5876 |
font-family: var(--font-mono);
|
| 5877 |
font-size: 12px;
|
| 5878 |
-
@@ -935,7 +
|
| 5879 |
min-height: 30px;
|
| 5880 |
padding: 6px 9px;
|
| 5881 |
border: 1px solid var(--border);
|
|
@@ -5884,7 +6187,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5884 |
background: var(--bg-panel);
|
| 5885 |
color: var(--text-dim);
|
| 5886 |
cursor: pointer;
|
| 5887 |
-
@@ -976,7 +
|
| 5888 |
}
|
| 5889 |
|
| 5890 |
.config-notice {
|
|
@@ -5893,7 +6196,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5893 |
border-bottom: 1px solid var(--border);
|
| 5894 |
background: var(--bg-panel);
|
| 5895 |
color: var(--text-muted);
|
| 5896 |
-
@@ -1104,7 +
|
| 5897 |
align-items: center;
|
| 5898 |
gap: 8px;
|
| 5899 |
min-height: 52px;
|
|
@@ -5902,7 +6205,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5902 |
border-top: 1px solid var(--border);
|
| 5903 |
}
|
| 5904 |
|
| 5905 |
-
@@ -1159,7 +
|
| 5906 |
gap: 6px;
|
| 5907 |
border-width: 1px;
|
| 5908 |
border-style: solid;
|
|
@@ -5911,7 +6214,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5911 |
cursor: pointer;
|
| 5912 |
font-family: inherit;
|
| 5913 |
letter-spacing: 0;
|
| 5914 |
-
@@ -1168,35 +
|
| 5915 |
transition: background-color 0.14s ease, border-color 0.14s ease, color 0.14s ease, box-shadow 0.14s ease;
|
| 5916 |
}
|
| 5917 |
|
|
@@ -5967,7 +6270,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 5967 |
}
|
| 5968 |
|
| 5969 |
.config-button-ghost {
|
| 5970 |
-
@@ -1206,
|
| 5971 |
}
|
| 5972 |
|
| 5973 |
.config-button-primary:not(:disabled):hover {
|
|
@@ -6002,7 +6305,12 @@ index 0bf21eb..e8788d8 100644
|
|
| 6002 |
}
|
| 6003 |
|
| 6004 |
.config-button:focus-visible {
|
| 6005 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6006 |
width: 32px;
|
| 6007 |
height: 18px;
|
| 6008 |
padding: 0;
|
|
@@ -6014,7 +6322,16 @@ index 0bf21eb..e8788d8 100644
|
|
| 6014 |
cursor: pointer;
|
| 6015 |
transition: background 0.15s, border-color 0.15s;
|
| 6016 |
}
|
| 6017 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6018 |
min-height: 30px;
|
| 6019 |
padding: 0 8px;
|
| 6020 |
border: 0;
|
|
@@ -6023,7 +6340,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6023 |
background: transparent;
|
| 6024 |
color: var(--text-dim);
|
| 6025 |
cursor: pointer;
|
| 6026 |
-
@@ -1358,7 +
|
| 6027 |
|
| 6028 |
.config-list-action-button[aria-current="page"] {
|
| 6029 |
background: var(--bg-selected);
|
|
@@ -6032,7 +6349,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6032 |
}
|
| 6033 |
|
| 6034 |
.config-list-action-button:disabled {
|
| 6035 |
-
@@ -1405,10 +
|
| 6036 |
height: 84vh;
|
| 6037 |
max-height: calc(100dvh - 16px);
|
| 6038 |
overflow: hidden;
|
|
@@ -6046,7 +6363,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6046 |
}
|
| 6047 |
|
| 6048 |
.settings-dialog-header {
|
| 6049 |
-
@@ -1417,7 +
|
| 6050 |
flex-shrink: 0;
|
| 6051 |
align-items: center;
|
| 6052 |
min-height: 50px;
|
|
@@ -6055,7 +6372,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6055 |
border-bottom: 1px solid var(--border);
|
| 6056 |
}
|
| 6057 |
|
| 6058 |
-
@@ -1467,7 +
|
| 6059 |
width: 24px;
|
| 6060 |
height: 2px;
|
| 6061 |
border-radius: 2px 2px 0 0;
|
|
@@ -6064,7 +6381,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6064 |
content: "";
|
| 6065 |
opacity: 0;
|
| 6066 |
transform: translateX(-50%) scaleX(0.5);
|
| 6067 |
-
@@ -1494,7 +
|
| 6068 |
}
|
| 6069 |
|
| 6070 |
.settings-section-tab:focus-visible:not([aria-current="page"]) {
|
|
@@ -6073,16 +6390,23 @@ index 0bf21eb..e8788d8 100644
|
|
| 6073 |
background: var(--bg-hover);
|
| 6074 |
color: var(--text);
|
| 6075 |
}
|
| 6076 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6077 |
.settings-general {
|
| 6078 |
width: 100%;
|
| 6079 |
height: 100%;
|
| 6080 |
- padding: 26px clamp(18px, 4vw, 40px) 40px;
|
| 6081 |
-
+ padding: 18px
|
| 6082 |
overflow-y: auto;
|
| 6083 |
}
|
| 6084 |
|
| 6085 |
-
@@ -1593,21 +
|
| 6086 |
justify-content: center;
|
| 6087 |
gap: 7px;
|
| 6088 |
min-width: 0;
|
|
@@ -6109,7 +6433,19 @@ index 0bf21eb..e8788d8 100644
|
|
| 6109 |
}
|
| 6110 |
|
| 6111 |
.settings-theme-option:not(:has(input:checked)):hover {
|
| 6112 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6113 |
height: 26px;
|
| 6114 |
margin: 0;
|
| 6115 |
padding: 0 8px;
|
|
@@ -6121,7 +6457,19 @@ index 0bf21eb..e8788d8 100644
|
|
| 6121 |
color: var(--text);
|
| 6122 |
font-family: var(--font-ui);
|
| 6123 |
font-weight: var(--font-ui-weight);
|
| 6124 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6125 |
|
| 6126 |
.settings-chat-range-header output {
|
| 6127 |
color: var(--text-muted);
|
|
@@ -6132,7 +6480,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6132 |
}
|
| 6133 |
|
| 6134 |
.settings-send-mode-options {
|
| 6135 |
-
@@ -1732,7 +
|
| 6136 |
gap: 3px;
|
| 6137 |
padding: 3px;
|
| 6138 |
border: 1px solid var(--border);
|
|
@@ -6141,7 +6489,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6141 |
}
|
| 6142 |
|
| 6143 |
.settings-send-mode-option {
|
| 6144 |
-
@@ -1744,7 +
|
| 6145 |
min-height: 26px;
|
| 6146 |
padding: 0 10px;
|
| 6147 |
border: 0;
|
|
@@ -6150,7 +6498,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6150 |
background: transparent;
|
| 6151 |
color: var(--text-muted);
|
| 6152 |
cursor: pointer;
|
| 6153 |
-
@@ -1754,8 +
|
| 6154 |
|
| 6155 |
.settings-send-mode-option:has(input:checked) {
|
| 6156 |
background: var(--bg-selected);
|
|
@@ -6161,7 +6509,19 @@ index 0bf21eb..e8788d8 100644
|
|
| 6161 |
}
|
| 6162 |
|
| 6163 |
.settings-send-mode-option:not(:has(input:checked)):hover {
|
| 6164 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6165 |
display: block;
|
| 6166 |
width: 100%;
|
| 6167 |
margin-top: 2px;
|
|
@@ -6170,7 +6530,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6170 |
}
|
| 6171 |
|
| 6172 |
.settings-language-options {
|
| 6173 |
-
@@ -1799,7 +
|
| 6174 |
height: 44px;
|
| 6175 |
padding: 0 10px;
|
| 6176 |
border: 0;
|
|
@@ -6179,7 +6539,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6179 |
background: transparent;
|
| 6180 |
color: var(--text);
|
| 6181 |
cursor: pointer;
|
| 6182 |
-
@@ -1857,7 +
|
| 6183 |
max-width: 420px;
|
| 6184 |
min-height: 44px;
|
| 6185 |
padding: 0 10px;
|
|
@@ -6188,7 +6548,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6188 |
background: var(--bg-panel);
|
| 6189 |
color: var(--text);
|
| 6190 |
font-size: 12px;
|
| 6191 |
-
@@ -1923,7 +
|
| 6192 |
margin-left: 14px;
|
| 6193 |
padding: 0 9px;
|
| 6194 |
border: 1px solid var(--border);
|
|
@@ -6197,7 +6557,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6197 |
background: var(--bg-panel);
|
| 6198 |
color: var(--text);
|
| 6199 |
font-size: 16px;
|
| 6200 |
-
@@ -2066,7 +
|
| 6201 |
max-width: 100%;
|
| 6202 |
padding: 0 5px;
|
| 6203 |
border: 1px solid var(--border);
|
|
@@ -6206,7 +6566,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6206 |
background: var(--bg-panel);
|
| 6207 |
color: var(--text);
|
| 6208 |
font-family: var(--font-mono);
|
| 6209 |
-
@@ -2085,7 +
|
| 6210 |
padding: 6px 8px;
|
| 6211 |
overflow: auto;
|
| 6212 |
border: 1px solid var(--border);
|
|
@@ -6215,7 +6575,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6215 |
background: var(--bg-panel);
|
| 6216 |
color: var(--text-muted);
|
| 6217 |
font-family: var(--font-mono);
|
| 6218 |
-
@@ -2172,9 +
|
| 6219 |
min-width: 0;
|
| 6220 |
height: 32px;
|
| 6221 |
padding: 0 10px;
|
|
@@ -6227,7 +6587,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6227 |
color: var(--text);
|
| 6228 |
font-family: var(--font-mono);
|
| 6229 |
font-size: 12px;
|
| 6230 |
-
@@ -2266,10 +
|
| 6231 |
max-width: 100%;
|
| 6232 |
max-height: 100%;
|
| 6233 |
overflow: hidden;
|
|
@@ -6241,7 +6601,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6241 |
}
|
| 6242 |
|
| 6243 |
/* Focus moves to the dialog itself when it opens (tabIndex -1); it is not a control, so no ring. */
|
| 6244 |
-
@@ -2282,7 +
|
| 6245 |
flex: 1 1 auto;
|
| 6246 |
gap: 12px;
|
| 6247 |
min-height: 0;
|
|
@@ -6250,7 +6610,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6250 |
overflow: auto;
|
| 6251 |
overscroll-behavior: contain;
|
| 6252 |
}
|
| 6253 |
-
@@ -2315,7 +
|
| 6254 |
margin-top: 10px;
|
| 6255 |
padding: 8px 10px;
|
| 6256 |
border: 1px solid var(--border);
|
|
@@ -6259,7 +6619,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6259 |
background: var(--bg);
|
| 6260 |
color: var(--text);
|
| 6261 |
font-family: var(--font-mono);
|
| 6262 |
-
@@ -2333,7 +
|
| 6263 |
.project-trust-error {
|
| 6264 |
flex-shrink: 0;
|
| 6265 |
max-height: 30vh;
|
|
@@ -6268,7 +6628,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6268 |
overflow: auto;
|
| 6269 |
color: #ef4444;
|
| 6270 |
font-size: 12px;
|
| 6271 |
-
@@ -2353,19 +
|
| 6272 |
flex-shrink: 0;
|
| 6273 |
justify-content: flex-end;
|
| 6274 |
gap: 8px;
|
|
@@ -6296,7 +6656,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6296 |
}
|
| 6297 |
|
| 6298 |
.project-trust-button:disabled {
|
| 6299 |
-
@@ -2373,10 +
|
| 6300 |
}
|
| 6301 |
|
| 6302 |
.project-trust-button.is-primary {
|
|
@@ -6309,7 +6669,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6309 |
}
|
| 6310 |
|
| 6311 |
.project-trust-button.is-primary:disabled {
|
| 6312 |
-
@@ -2450,7 +
|
| 6313 |
min-width: 0;
|
| 6314 |
padding: 8px 10px;
|
| 6315 |
border: 1px solid var(--border);
|
|
@@ -6318,7 +6678,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6318 |
background: var(--bg);
|
| 6319 |
}
|
| 6320 |
|
| 6321 |
-
@@ -2472,7 +
|
| 6322 |
.project-trust-mcp-tag {
|
| 6323 |
flex-shrink: 0;
|
| 6324 |
padding: 1px 5px;
|
|
@@ -6327,7 +6687,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6327 |
background: rgba(120, 120, 120, 0.12);
|
| 6328 |
color: var(--text-dim);
|
| 6329 |
font-size: 10px;
|
| 6330 |
-
@@ -2493,7 +
|
| 6331 |
display: inline-block;
|
| 6332 |
margin: 2px 4px 0 0;
|
| 6333 |
padding: 0 4px;
|
|
@@ -6338,7 +6698,7 @@ index 0bf21eb..e8788d8 100644
|
|
| 6338 |
font-family: var(--font-mono);
|
| 6339 |
diff --git a/app/shell.css b/app/shell.css
|
| 6340 |
new file mode 100644
|
| 6341 |
-
index 0000000..
|
| 6342 |
--- /dev/null
|
| 6343 |
+++ b/app/shell.css
|
| 6344 |
@@ -0,0 +1,720 @@
|
|
@@ -6879,7 +7239,7 @@ index 0000000..7cefafc
|
|
| 6879 |
+ color: var(--text);
|
| 6880 |
+ font: inherit;
|
| 6881 |
+}
|
| 6882 |
-
+.review-comment-input:focus { box-shadow: 0 0 0
|
| 6883 |
+.review-comment-actions { display: flex; align-items: center; justify-content: flex-end; gap: 4px; }
|
| 6884 |
+.review-comment-hint { flex: 1 1 auto; color: var(--text-dim); font-size: 11.5px; }
|
| 6885 |
+
|
|
@@ -6923,7 +7283,7 @@ index 0000000..7cefafc
|
|
| 6923 |
+ font: inherit;
|
| 6924 |
+ font-size: 12.5px;
|
| 6925 |
+}
|
| 6926 |
-
+.browser-address input:focus { box-shadow: 0 0 0
|
| 6927 |
+.browser-error-count { color: var(--danger); font-size: 11.5px; font-variant-numeric: tabular-nums; }
|
| 6928 |
+.browser-tabs {
|
| 6929 |
+ display: flex;
|
|
@@ -6994,7 +7354,7 @@ index 0000000..7cefafc
|
|
| 6994 |
+ background: #fff;
|
| 6995 |
+ cursor: default;
|
| 6996 |
+}
|
| 6997 |
-
+.browser-canvas:focus-visible { box-shadow: inset 0 0 0
|
| 6998 |
+.browser-canvas.is-picking { cursor: crosshair; }
|
| 6999 |
+.browser-agent-pill, .browser-picking-hint {
|
| 7000 |
+ position: absolute;
|
|
@@ -7063,7 +7423,7 @@ index 0000000..7cefafc
|
|
| 7063 |
+.browser-console-text { flex: 1 1 auto; min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
|
| 7064 |
+.browser-console-location { flex: none; max-width: 40%; overflow: hidden; color: var(--text-dim); text-overflow: ellipsis; white-space: nowrap; direction: rtl; }
|
| 7065 |
diff --git a/app/sidebar-menu.css b/app/sidebar-menu.css
|
| 7066 |
-
index 737e7a5..
|
| 7067 |
--- a/app/sidebar-menu.css
|
| 7068 |
+++ b/app/sidebar-menu.css
|
| 7069 |
@@ -19,13 +19,14 @@
|
|
@@ -7553,7 +7913,19 @@ index 737e7a5..d0fd174 100644
|
|
| 7553 |
font-size: 15px;
|
| 7554 |
}
|
| 7555 |
|
| 7556 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7557 |
height: 36px;
|
| 7558 |
padding: 0 4px 0 12px;
|
| 7559 |
box-sizing: border-box;
|
|
@@ -7568,7 +7940,7 @@ index 737e7a5..d0fd174 100644
|
|
| 7568 |
font-size: 12px;
|
| 7569 |
pointer-events: auto;
|
| 7570 |
animation: sidebar-toast-in 0.16s ease-out;
|
| 7571 |
-
@@ -634,7 +
|
| 7572 |
height: 26px;
|
| 7573 |
padding: 0 7px;
|
| 7574 |
border: 0;
|
|
@@ -7577,7 +7949,7 @@ index 737e7a5..d0fd174 100644
|
|
| 7577 |
background: transparent;
|
| 7578 |
color: var(--accent);
|
| 7579 |
font: inherit;
|
| 7580 |
-
@@ -657,7 +
|
| 7581 |
height: 24px;
|
| 7582 |
padding: 0;
|
| 7583 |
border: 0;
|
|
@@ -7586,7 +7958,19 @@ index 737e7a5..d0fd174 100644
|
|
| 7586 |
background: transparent;
|
| 7587 |
color: var(--text-dim);
|
| 7588 |
cursor: pointer;
|
| 7589 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7590 |
/* A worktree menu's "New worktree…" form (a custom menu body; components/WorktreeCreateForm.tsx),
|
| 7591 |
and its removal body. */
|
| 7592 |
.sidebar-worktree-form {
|
|
@@ -7616,7 +8000,7 @@ index 737e7a5..d0fd174 100644
|
|
| 7616 |
user-select: text;
|
| 7617 |
-webkit-user-select: text;
|
| 7618 |
}
|
| 7619 |
-
@@ -747,33 +
|
| 7620 |
.sidebar-worktree-force,
|
| 7621 |
.sidebar-worktree-cancel {
|
| 7622 |
flex: 1;
|
|
@@ -7662,7 +8046,16 @@ index 737e7a5..d0fd174 100644
|
|
| 7662 |
}
|
| 7663 |
|
| 7664 |
.sidebar-worktree-create:disabled,
|
| 7665 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7666 |
|
| 7667 |
/* A worktree menu's removal body (components/ProjectWorktreePicker.tsx): what Force would do. */
|
| 7668 |
.sidebar-worktree-message {
|
|
@@ -7689,7 +8082,7 @@ index 737e7a5..d0fd174 100644
|
|
| 7689 |
}
|
| 7690 |
|
| 7691 |
.sidebar-sheet .sidebar-worktree-input,
|
| 7692 |
-
@@ -820,19 +
|
| 7693 |
/* A project menu's "Delete all sessions" question (a custom menu body;
|
| 7694 |
components/SessionSidebar.tsx): what goes, then Delete and Cancel. */
|
| 7695 |
.sidebar-menu-question {
|
|
@@ -7713,7 +8106,7 @@ index 737e7a5..d0fd174 100644
|
|
| 7713 |
line-height: 1.4;
|
| 7714 |
}
|
| 7715 |
|
| 7716 |
-
@@ -846,26 +
|
| 7717 |
.sidebar-menu-question-cancel {
|
| 7718 |
flex: 1;
|
| 7719 |
min-width: 0;
|
|
@@ -7749,7 +8142,15 @@ index 737e7a5..d0fd174 100644
|
|
| 7749 |
}
|
| 7750 |
|
| 7751 |
.sidebar-menu-question-confirm:disabled {
|
| 7752 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7753 |
}
|
| 7754 |
|
| 7755 |
.sidebar-sheet .sidebar-menu-question {
|
|
@@ -7759,18 +8160,34 @@ index 737e7a5..d0fd174 100644
|
|
| 7759 |
|
| 7760 |
.sidebar-sheet .sidebar-menu-question-text {
|
| 7761 |
diff --git a/app/sidebar.css b/app/sidebar.css
|
| 7762 |
-
index 86728a2..
|
| 7763 |
--- a/app/sidebar.css
|
| 7764 |
+++ b/app/sidebar.css
|
| 7765 |
-
@@ -91,
|
| 7766 |
|
| 7767 |
.session-tree button:focus-visible,
|
| 7768 |
.session-tree a.session-tree-main:focus-visible {
|
| 7769 |
- outline: 2px solid var(--accent);
|
| 7770 |
-
|
| 7771 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7772 |
}
|
| 7773 |
|
|
|
|
| 7774 |
@@ -171,20 +171,22 @@
|
| 7775 |
}
|
| 7776 |
|
|
@@ -8273,18 +8690,20 @@ index 86728a2..98fb8f2 100644
|
|
| 8273 |
}
|
| 8274 |
|
| 8275 |
.sidebar-brand:focus {
|
| 8276 |
-
@@ -1064,8 +1090,
|
| 8277 |
}
|
| 8278 |
|
| 8279 |
.sidebar-brand:focus-visible {
|
| 8280 |
- outline: 2px solid var(--accent);
|
| 8281 |
- outline-offset: 1px;
|
| 8282 |
-
+ outline:
|
|
|
|
|
|
|
| 8283 |
+ outline-offset: 0;
|
| 8284 |
}
|
| 8285 |
|
| 8286 |
.sidebar-header-spacer {
|
| 8287 |
-
@@ -1078,7 +
|
| 8288 |
}
|
| 8289 |
|
| 8290 |
.sidebar-search-toggle {
|
|
@@ -8293,7 +8712,7 @@ index 86728a2..98fb8f2 100644
|
|
| 8293 |
padding: 0;
|
| 8294 |
}
|
| 8295 |
|
| 8296 |
-
@@ -1093,7 +
|
| 8297 |
label is still each one's name. */
|
| 8298 |
.sidebar-header[data-fit="1"] .sidebar-new-button,
|
| 8299 |
.sidebar-header[data-fit="2"] .sidebar-new-button {
|
|
@@ -8302,7 +8721,7 @@ index 86728a2..98fb8f2 100644
|
|
| 8302 |
padding: 0;
|
| 8303 |
}
|
| 8304 |
|
| 8305 |
-
@@ -1105,6 +
|
| 8306 |
font-size: 11px;
|
| 8307 |
}
|
| 8308 |
|
|
@@ -8314,7 +8733,19 @@ index 86728a2..98fb8f2 100644
|
|
| 8314 |
.sidebar-header[data-fit="1"] .sidebar-new-label,
|
| 8315 |
.sidebar-header[data-fit="2"] .sidebar-new-label,
|
| 8316 |
.sidebar-header[data-fit="2"] .sidebar-tab-label {
|
| 8317 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8318 |
the root too), and its time 4px inside the row. The header row's keys and
|
| 8319 |
the picker's boxes end there. */
|
| 8320 |
.session-sidebar.is-files-below {
|
|
@@ -8323,7 +8754,7 @@ index 86728a2..98fb8f2 100644
|
|
| 8323 |
}
|
| 8324 |
|
| 8325 |
/* The files section's header row (files below the sessions only), one row
|
| 8326 |
-
@@ -1246,7 +
|
| 8327 |
padding: 0 5px;
|
| 8328 |
overflow: hidden;
|
| 8329 |
border: 0;
|
|
@@ -8332,7 +8763,19 @@ index 86728a2..98fb8f2 100644
|
|
| 8332 |
background: transparent;
|
| 8333 |
color: var(--text-muted);
|
| 8334 |
font: inherit;
|
| 8335 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8336 |
min-width: 18px;
|
| 8337 |
max-width: 26px;
|
| 8338 |
height: 26px;
|
|
@@ -8341,7 +8784,7 @@ index 86728a2..98fb8f2 100644
|
|
| 8341 |
}
|
| 8342 |
|
| 8343 |
/* Under that row (or the whole files tab): the head, then the tree filling
|
| 8344 |
-
@@ -1329,16 +
|
| 8345 |
height: 29px;
|
| 8346 |
padding: 0 10px;
|
| 8347 |
box-sizing: border-box;
|
|
@@ -8358,12 +8801,13 @@ index 86728a2..98fb8f2 100644
|
|
| 8358 |
-.sidebar-search-input:focus {
|
| 8359 |
- outline: 2px solid var(--accent);
|
| 8360 |
+.sidebar-search-input:focus-visible {
|
| 8361 |
-
+ outline:
|
| 8362 |
-
+ outline-offset: -
|
|
|
|
| 8363 |
}
|
| 8364 |
|
| 8365 |
/* The tree and the archive view under the search, in one cell: the archive
|
| 8366 |
-
@@ -1413,7 +
|
| 8367 |
height: 26px;
|
| 8368 |
padding: 0 6px;
|
| 8369 |
border: 0;
|
|
@@ -8372,7 +8816,7 @@ index 86728a2..98fb8f2 100644
|
|
| 8372 |
background: transparent;
|
| 8373 |
color: var(--text-muted);
|
| 8374 |
font-size: 12px;
|
| 8375 |
-
@@ -1502,7 +
|
| 8376 |
height: 32px;
|
| 8377 |
padding: 0;
|
| 8378 |
border: 0;
|
|
@@ -8383,7 +8827,7 @@ index 86728a2..98fb8f2 100644
|
|
| 8383 |
cursor: pointer;
|
| 8384 |
diff --git a/app/ui.css b/app/ui.css
|
| 8385 |
new file mode 100644
|
| 8386 |
-
index 0000000..
|
| 8387 |
--- /dev/null
|
| 8388 |
+++ b/app/ui.css
|
| 8389 |
@@ -0,0 +1,634 @@
|
|
@@ -8609,7 +9053,7 @@ index 0000000..69db8d7
|
|
| 8609 |
+ white-space: nowrap;
|
| 8610 |
+ cursor: pointer;
|
| 8611 |
+}
|
| 8612 |
-
+.ui-dropdown-row:focus-visible { outline: none; }
|
| 8613 |
+.ui-dropdown-row[aria-selected="true"] { color: var(--text-strong); }
|
| 8614 |
+.ui-dropdown-row.has-gutter { padding-right: calc(var(--popup-row-pad) + 28px); }
|
| 8615 |
+.ui-dropdown-icon { display: inline-flex; flex: none; align-items: center; justify-content: center; width: var(--popup-icon); height: var(--popup-icon); color: var(--text-muted); }
|
|
@@ -9169,7 +9613,7 @@ index e232a55..0000000
|
|
| 9169 |
- assert.deepEqual(saved, { tabs: [{ ...tab, restored: true }], activeId: null, open: false });
|
| 9170 |
-});
|
| 9171 |
diff --git a/components/AppShell.tsx b/components/AppShell.tsx
|
| 9172 |
-
index c8c4ba9..
|
| 9173 |
--- a/components/AppShell.tsx
|
| 9174 |
+++ b/components/AppShell.tsx
|
| 9175 |
@@ -3,6 +3,8 @@
|
|
@@ -10902,7 +11346,16 @@ index c8c4ba9..a7151eb 100644
|
|
| 10902 |
<div style={{ display: "grid", gridTemplateColumns: "auto minmax(0, 1fr) auto", columnGap: 12, rowGap: 8, alignItems: "start" }}>
|
| 10903 |
{sessionRows.map((row) => (
|
| 10904 |
<div key={`session-info:${row.label}`} style={{ display: "contents" }}>
|
| 10905 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10906 |
);
|
| 10907 |
const projectInfoSection = projectRows.length > 0 ? (
|
| 10908 |
<div style={{ minWidth: 0 }}>
|
|
@@ -10911,7 +11364,32 @@ index c8c4ba9..a7151eb 100644
|
|
| 10911 |
<div style={{ display: "grid", gridTemplateColumns: "auto minmax(0, 1fr) auto", columnGap: 12, rowGap: 8, alignItems: "start" }}>
|
| 10912 |
{projectRows.map((row) => (
|
| 10913 |
<div key={`project-info:${row.label}`} style={{ display: "contents" }}>
|
| 10914 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10915 |
{isMobile && renderProjectTrustWarning(true)}
|
| 10916 |
</div>
|
| 10917 |
|
|
@@ -10928,7 +11406,7 @@ index c8c4ba9..a7151eb 100644
|
|
| 10928 |
{showChat ? (
|
| 10929 |
<ChatWindow
|
| 10930 |
key={sessionKey}
|
| 10931 |
-
@@ -2568,7 +
|
| 10932 |
initialPrompt={pendingQuotePrompt?.sessionId === selectedSession?.id ? pendingQuotePrompt?.text : undefined}
|
| 10933 |
onInitialPromptConsumed={() => setPendingQuotePrompt(null)}
|
| 10934 |
soundEnabled={soundEnabled}
|
|
@@ -10936,7 +11414,7 @@ index c8c4ba9..a7151eb 100644
|
|
| 10936 |
playDoneSound={playDoneSound}
|
| 10937 |
unlockAudio={unlockAudio}
|
| 10938 |
holdAudio={holdAudio}
|
| 10939 |
-
@@ -2601,9 +
|
| 10940 |
</div>
|
| 10941 |
) : (
|
| 10942 |
<div style={{ position: "absolute", top: 12, left: 12, display: "flex", alignItems: "flex-start", gap: 8, userSelect: "none", pointerEvents: "none" }}>
|
|
@@ -10947,7 +11425,7 @@ index c8c4ba9..a7151eb 100644
|
|
| 10947 |
<div>
|
| 10948 |
<div style={{ fontSize: 18, fontWeight: 600, color: "var(--text)", marginBottom: 8 }}>{translate("workspace.getStarted")}</div>
|
| 10949 |
<div style={{ fontSize: 12, color: "var(--text-muted)", lineHeight: 1.8 }}>
|
| 10950 |
-
@@ -2614,146 +
|
| 10951 |
</div>
|
| 10952 |
)
|
| 10953 |
) : null}
|
|
@@ -11101,7 +11579,7 @@ index c8c4ba9..a7151eb 100644
|
|
| 11101 |
</div>
|
| 11102 |
</div>
|
| 11103 |
{settingsSection && (
|
| 11104 |
-
@@ -2763,6 +
|
| 11105 |
initialSection={settingsSection}
|
| 11106 |
quoteSelectionEnabled={quoteSelectionEnabled}
|
| 11107 |
onQuoteSelectionChange={handleQuoteSelectionChange}
|
|
@@ -11110,7 +11588,7 @@ index c8c4ba9..a7151eb 100644
|
|
| 11110 |
onClose={() => {
|
| 11111 |
setSettingsSection(null);
|
| 11112 |
setModelsRefreshKey((key) => key + 1);
|
| 11113 |
-
@@ -2786,6 +
|
| 11114 |
onStatus={setProjectTrust}
|
| 11115 |
/>
|
| 11116 |
)}
|
|
@@ -20712,7 +21190,7 @@ index ba912ee..0283a47 100644
|
|
| 20712 |
onSelect={() => choose(option)}
|
| 20713 |
star={onSetDefault ? {
|
| 20714 |
diff --git a/components/ModelsConfig.tsx b/components/ModelsConfig.tsx
|
| 20715 |
-
index 9f6b556..
|
| 20716 |
--- a/components/ModelsConfig.tsx
|
| 20717 |
+++ b/components/ModelsConfig.tsx
|
| 20718 |
@@ -54,6 +54,8 @@ import { providerBadgeLabel } from "./enabled-models-helpers";
|
|
@@ -20892,6 +21370,15 @@ index 9f6b556..470db1f 100644
|
|
| 20892 |
background: "var(--bg-panel)",
|
| 20893 |
color: !model.id.trim() || catalogState.phase === "loading" ? "var(--text-dim)" : "var(--text-muted)",
|
| 20894 |
cursor: !model.id.trim() || catalogState.phase === "loading" ? "not-allowed" : "pointer",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20895 |
@@ -1227,20 +1220,7 @@ function ModelDetail({
|
| 20896 |
{advancedSummary}
|
| 20897 |
</span>
|
|
@@ -20976,7 +21463,16 @@ index 9f6b556..470db1f 100644
|
|
| 20976 |
<input
|
| 20977 |
ref={inputRef}
|
| 20978 |
value={search}
|
| 20979 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20980 |
<div style={{ fontSize: 12, fontWeight: 600, color: "var(--text)", lineHeight: 1.3, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>OpenAI / Anthropic compatible</div>
|
| 20981 |
<div style={{ fontSize: 10, color: "var(--text-dim)", marginTop: 2 }}>{t("i18n.customEndpoint")}</div>
|
| 20982 |
</div>
|
|
@@ -20989,6 +21485,22 @@ index 9f6b556..470db1f 100644
|
|
| 20989 |
</span>
|
| 20990 |
</button>
|
| 20991 |
)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20992 |
@@ -2177,13 +2151,7 @@ export function ModelsConfig({ onClose, embedded = false, cwd = null }: {
|
| 20993 |
onClick={() => setSelection({ type: "provider", name: pName })}
|
| 20994 |
active={isProviderSelected}
|
|
@@ -21242,7 +21754,7 @@ index b9e6dde..1a67841 100644
|
|
| 21242 |
);
|
| 21243 |
}
|
| 21244 |
diff --git a/components/PluginsConfig.tsx b/components/PluginsConfig.tsx
|
| 21245 |
-
index 83fddc9..
|
| 21246 |
--- a/components/PluginsConfig.tsx
|
| 21247 |
+++ b/components/PluginsConfig.tsx
|
| 21248 |
@@ -1,5 +1,6 @@
|
|
@@ -21252,7 +21764,20 @@ index 83fddc9..69cbd44 100644
|
|
| 21252 |
import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
| 21253 |
import { sendAgentCommand } from "@/lib/agent-client";
|
| 21254 |
import type {
|
| 21255 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21256 |
href: "https://pi.dev/packages",
|
| 21257 |
label: "pi.dev/packages",
|
| 21258 |
icon: (
|
|
@@ -21268,7 +21793,7 @@ index 83fddc9..69cbd44 100644
|
|
| 21268 |
),
|
| 21269 |
}]}
|
| 21270 |
target={
|
| 21271 |
-
@@ -370,7 +
|
| 21272 |
style={{
|
| 21273 |
fontSize: 10,
|
| 21274 |
padding: "1px 5px",
|
|
@@ -21277,7 +21802,7 @@ index 83fddc9..69cbd44 100644
|
|
| 21277 |
background: "rgba(120,120,120,0.12)",
|
| 21278 |
color: "var(--text-dim)",
|
| 21279 |
}}
|
| 21280 |
-
@@ -382,7 +
|
| 21281 |
style={{
|
| 21282 |
fontSize: 10,
|
| 21283 |
padding: "1px 5px",
|
|
@@ -25477,7 +26002,7 @@ index 0000000..3d8fca8
|
|
| 25477 |
+});
|
| 25478 |
diff --git a/components/highlighting.ts b/components/highlighting.ts
|
| 25479 |
new file mode 100644
|
| 25480 |
-
index 0000000..
|
| 25481 |
--- /dev/null
|
| 25482 |
+++ b/components/highlighting.ts
|
| 25483 |
@@ -0,0 +1,157 @@
|
|
@@ -25562,7 +26087,7 @@ index 0000000..ae9fdae
|
|
| 25562 |
+[data-separator=line-info-basic] { height: 24px; }
|
| 25563 |
+[data-separator-content] { font-size: 12px; }
|
| 25564 |
+[data-expand-index] [data-separator-wrapper] { grid-template-columns: 28px auto; }
|
| 25565 |
-
+[data-expand-button]:focus-visible { outline:
|
| 25566 |
+`;
|
| 25567 |
+
|
| 25568 |
+// The library's expand controls are role=button divs out of the tab order: give them a place in
|
|
@@ -33727,7 +34252,7 @@ index fa76036..0000000
|
|
| 33727 |
- };
|
| 33728 |
-}
|
| 33729 |
diff --git a/lib/i18n/messages/en.ts b/lib/i18n/messages/en.ts
|
| 33730 |
-
index cd39a31..
|
| 33731 |
--- a/lib/i18n/messages/en.ts
|
| 33732 |
+++ b/lib/i18n/messages/en.ts
|
| 33733 |
@@ -22,8 +22,8 @@ export const enLocale: LocalePlugin = {
|
|
@@ -33768,7 +34293,31 @@ index cd39a31..132c15c 100644
|
|
| 33768 |
"subagent.tabLabel": "Sub-agent {name}",
|
| 33769 |
"subagent.refresh": "Refresh",
|
| 33770 |
"subagent.viewer.starting": "Sub-agent session is starting…",
|
| 33771 |
-
@@ -
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33772 |
"session.copied": "Copied",
|
| 33773 |
"session.title": "Session info",
|
| 33774 |
"session.load": "Send a message or run /session to load session info",
|
|
@@ -33778,7 +34327,17 @@ index cd39a31..132c15c 100644
|
|
| 33778 |
+ "session.projectSection": "Project info",
|
| 33779 |
"session.messages": "Messages",
|
| 33780 |
"session.tokens": "Tokens",
|
| 33781 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33782 |
@@ -269,13 +269,9 @@ export const enLocale: LocalePlugin = {
|
| 33783 |
"workspace.stepModels": "Open Settings at the bottom, then choose Models",
|
| 33784 |
"workspace.newSessionContext": "New session location",
|
|
|
|
| 1 |
diff --git a/AGENTS.md b/AGENTS.md
|
| 2 |
+
index a5c8983..1b769c5 100644
|
| 3 |
--- a/AGENTS.md
|
| 4 |
+++ b/AGENTS.md
|
| 5 |
@@ -65,8 +65,13 @@ app/api/
|
|
|
|
| 156 |
|
| 157 |
## Pi Session File Format
|
| 158 |
|
| 159 |
+
@@ -274,3 +317,32 @@ Location: `~/.pi/agent/sessions/<encoded-cwd>/<timestamp>_<uuid>.jsonl`
|
| 160 |
--accent --user-bg --tool-bg
|
| 161 |
--font-mono
|
| 162 |
```
|
|
|
|
| 179 |
+newer parts, menus, tooltips and popovers in `app/ui.css`, the header and tiles in `app/shell.css`)
|
| 180 |
+are styled there too.
|
| 181 |
+`--accent` is a neutral gray in light and dark (no blue anywhere: links are told apart by their
|
| 182 |
+
+underline, focus by its line and halo), `--accent-soft` its tint; Mist, Rose and Pine keep their own hues.
|
| 183 |
+All code (fences, the file viewer, tool inputs and outputs, diffs) is highlighted by Shiki in `lib/diffs-theme.ts`'s neutral themes (`components/highlighting.ts`); the terminal keeps its ANSI hues.
|
| 184 |
+
+Keyboard focus is `app/focus.css`, imported last, drawn as Claude Code Desktop's (its shadow-focus):
|
| 185 |
+
+a 1px line at 70% of `--focus-ring` (`--focus-line`) with a 3px halo at 16% (`--focus-glow`), never
|
| 186 |
+
+a thick ring. The line sits 1px inside controls, rows and fields with the halo outside (a row draws
|
| 187 |
+
+them on the row; its link or toggle draws nothing, halo included); what is focusable by tabindex
|
| 188 |
+
+alone (a menu's surface, a tile) takes the line only, keeping its shadow; ink-filled controls and
|
| 189 |
+
+text links take the line 2px off, no halo. `app/focus.test.mjs` checks that no 2px ring is left
|
| 190 |
+
+(the gateway's sheets too) and that the line keeps 3:1 on every surface. Hidden row actions fold to width 0 (never `display: none`: Tab would drop
|
| 191 |
+focus); closed panels are `inert`; modals use `keepTabInside`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
diff --git a/app/api/browser/events/route.ts b/app/api/browser/events/route.ts
|
| 193 |
new file mode 100644
|
| 194 |
index 0000000..84aa812
|
|
|
|
| 1192 |
|
| 1193 |
diff --git a/app/focus.css b/app/focus.css
|
| 1194 |
new file mode 100644
|
| 1195 |
+
index 0000000..4aa9f5b
|
| 1196 |
--- /dev/null
|
| 1197 |
+++ b/app/focus.css
|
| 1198 |
+
@@ -0,0 +1,331 @@
|
| 1199 |
+/* Keyboard focus, one way everywhere (the design system's "Motion and states").
|
| 1200 |
+ Imported last (app/layout.tsx), so these rules win over each component's.
|
| 1201 |
+
|
| 1202 |
+
+ One indicator, as Claude Code Desktop draws it (its shadow-focus: a 1px
|
| 1203 |
+
+ ring and a soft glow, no thick outline) in Pi Web's neutral ink: a 1px line
|
| 1204 |
+
+ at 70% of --focus-ring (--focus-line) and a 3px halo at 16% (--focus-glow).
|
| 1205 |
+
+ A 2px ring at full strength drew a heavy white box in dark themes. Never a
|
| 1206 |
+ ring and a second ring, never a box around a row's text:
|
| 1207 |
+
+ - on the edge (the line 1px inside, following the control's own corners;
|
| 1208 |
+
+ the halo outside) on everything that is not filled with ink: ghost and
|
| 1209 |
+
+ icon buttons, pickers, tabs, options, menu items, fields. A row draws it
|
| 1210 |
+
+ on the whole row (its inner control draws nothing), so the line fits the
|
| 1211 |
+
+ row's box and is never clipped;
|
| 1212 |
+
+ - the line 2px off the edge, no halo, on what is filled with ink (primary
|
| 1213 |
+
+ and Send buttons, a switch, floating round buttons), where a line on the
|
| 1214 |
+
+ edge would vanish into the fill;
|
| 1215 |
+
+ - the line 2px off, with small corners, around a link in running text.
|
| 1216 |
+
+ The line keeps at least 3:1 against every surface it sits on (4.5:1 and up
|
| 1217 |
+
+ on canvas and surface in dark, 4:1 in light).
|
| 1218 |
+ Mouse focus shows nothing (:focus-visible); text fields show their caret,
|
| 1219 |
+ and other fields the inset ring too, except the composer, which is always
|
| 1220 |
+ where typing goes. */
|
| 1221 |
+
|
| 1222 |
+
+:root {
|
| 1223 |
+
+ --focus-line: color-mix(in srgb, var(--focus-ring) 70%, transparent);
|
| 1224 |
+
+ --focus-halo: color-mix(in srgb, var(--focus-ring) 16%, transparent);
|
| 1225 |
+
+ --focus-glow: 0 0 0 3px var(--focus-halo);
|
| 1226 |
+
+}
|
| 1227 |
+
+
|
| 1228 |
+:where(button, summary, [role="button"], [role="tab"], [role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"], [role="option"], [role="switch"], [role="treeitem"], [tabindex]:not(input):not(textarea):not(select)):focus {
|
| 1229 |
+ outline: none;
|
| 1230 |
+}
|
| 1231 |
+
|
| 1232 |
+
+/* Anything focusable by tabindex alone (a menu's or a sheet's surface, a tile, a
|
| 1233 |
+
+ scroll region) takes the line only: its own shadow stays. Controls add the halo. */
|
| 1234 |
+
+:where([tabindex]:not(input):not(textarea):not(select)):focus-visible {
|
| 1235 |
+
+ outline: 1px solid var(--focus-line);
|
| 1236 |
+
+ outline-offset: -1px;
|
| 1237 |
+
+}
|
| 1238 |
+
+
|
| 1239 |
+
+:where(button, summary, [role="button"], [role="tab"], [role="menuitem"], [role="menuitemradio"], [role="menuitemcheckbox"], [role="option"], [role="switch"], [role="treeitem"]):focus-visible {
|
| 1240 |
+
+ outline: 1px solid var(--focus-line);
|
| 1241 |
+
+ outline-offset: -1px;
|
| 1242 |
+
+ box-shadow: var(--focus-glow);
|
| 1243 |
+}
|
| 1244 |
+
|
| 1245 |
+:where(a[href]):focus {
|
|
|
|
| 1247 |
+}
|
| 1248 |
+
|
| 1249 |
+:where(a[href]):focus-visible {
|
| 1250 |
+
+ outline: 1px solid var(--focus-line);
|
| 1251 |
+ outline-offset: 2px;
|
| 1252 |
+ border-radius: var(--radius-xs);
|
| 1253 |
+}
|
| 1254 |
+
|
| 1255 |
+:where(input:not([type="range"]):not([type="checkbox"]):not([type="radio"]), select, textarea):focus-visible {
|
| 1256 |
+
+ outline: 1px solid var(--focus-line);
|
| 1257 |
+
+ outline-offset: -1px;
|
| 1258 |
+
+ box-shadow: var(--focus-glow);
|
| 1259 |
+}
|
| 1260 |
+
|
| 1261 |
+:where(input[type="checkbox"], input[type="radio"]):focus-visible {
|
| 1262 |
+
+ outline: 1px solid var(--focus-line);
|
| 1263 |
+ outline-offset: 2px;
|
| 1264 |
+}
|
| 1265 |
+
|
|
|
|
| 1267 |
+.chat-input-textarea:focus,
|
| 1268 |
+.chat-input-textarea:focus-visible {
|
| 1269 |
+ outline: none;
|
| 1270 |
+
+ box-shadow: none;
|
| 1271 |
+}
|
| 1272 |
+
|
| 1273 |
+/* A visually hidden input inside an option (a theme, the send key) leaves the
|
| 1274 |
+ ring to the option. */
|
| 1275 |
+input.sr-only:focus-visible {
|
| 1276 |
+ outline: none;
|
| 1277 |
+
+ box-shadow: none;
|
| 1278 |
+}
|
| 1279 |
+
|
| 1280 |
+/* ---------------------------------------------------------------- filled with ink: 2px off */
|
|
|
|
| 1286 |
+.web-login-form button:focus-visible,
|
| 1287 |
+.chat-scroll-to-bottom:focus-visible,
|
| 1288 |
+.image-preview-close:focus-visible {
|
| 1289 |
+
+ outline: 1px solid var(--focus-line);
|
| 1290 |
+ outline-offset: 2px;
|
| 1291 |
+}
|
| 1292 |
+
|
|
|
|
| 1315 |
+.extension-status-command:focus-visible,
|
| 1316 |
+button.extension-widget-trigger:focus-visible,
|
| 1317 |
+.new-session-update:focus-visible {
|
| 1318 |
+
+ outline: 1px solid var(--focus-line);
|
| 1319 |
+
+ outline-offset: -1px;
|
| 1320 |
+
+ box-shadow: var(--focus-glow);
|
| 1321 |
+}
|
| 1322 |
+
|
| 1323 |
+.settings-section-tab:focus-visible,
|
|
|
|
| 1332 |
+
|
| 1333 |
+/* A Terminal tab being renamed: the tab is the field, its pill takes the ring (Desktop's
|
| 1334 |
+ has-[:focus-visible] on the tab), the bare input none. */
|
| 1335 |
+
+.terminal-tab-input:focus-visible { outline: none; box-shadow: none; }
|
| 1336 |
+.terminal-tab:has(.terminal-tab-input:focus-visible) {
|
| 1337 |
+
+ outline: 1px solid var(--focus-line);
|
| 1338 |
+
+ outline-offset: -1px;
|
| 1339 |
+
+ box-shadow: var(--focus-glow);
|
| 1340 |
+}
|
| 1341 |
+
|
| 1342 |
+/* An option whose input is visually hidden: the option is the control. */
|
| 1343 |
+.settings-theme-option:has(input:focus-visible),
|
| 1344 |
+.settings-send-mode-option:has(input:focus-visible) {
|
| 1345 |
+
+ outline: 1px solid var(--focus-line);
|
| 1346 |
+
+ outline-offset: -1px;
|
| 1347 |
+
+ box-shadow: var(--focus-glow);
|
| 1348 |
+}
|
| 1349 |
+
|
| 1350 |
+
+/* Fields, the filled ones too: the line inside, the halo, no border change. */
|
| 1351 |
+.settings-font-input:focus-visible,
|
| 1352 |
+.sidebar-search-input:focus,
|
| 1353 |
+.sidebar-search-input:focus-visible,
|
| 1354 |
+.sidebar-menu-filter-input:focus-visible,
|
| 1355 |
+.directory-picker-path:focus-visible {
|
| 1356 |
+ border-color: transparent !important;
|
| 1357 |
+
+ box-shadow: var(--focus-glow);
|
| 1358 |
+
+ outline: 1px solid var(--focus-line);
|
| 1359 |
+
+ outline-offset: -1px;
|
| 1360 |
+}
|
| 1361 |
+
|
| 1362 |
+.sidebar-search-input:focus:not(:focus-visible) {
|
|
|
|
| 1365 |
+
|
| 1366 |
+.web-login-composer:focus-within {
|
| 1367 |
+ border-color: transparent;
|
| 1368 |
+
+ box-shadow: var(--focus-glow);
|
| 1369 |
+
+ outline: 1px solid var(--focus-line);
|
| 1370 |
+
+ outline-offset: -1px;
|
| 1371 |
+}
|
| 1372 |
+
|
| 1373 |
+.web-login-composer :is(input, textarea):focus-visible {
|
| 1374 |
+ outline: none;
|
| 1375 |
+
+ box-shadow: none;
|
| 1376 |
+}
|
| 1377 |
+
|
| 1378 |
+/* The top bar's 36px edge buttons (the sidebar toggle): a
|
|
|
|
| 1383 |
+}
|
| 1384 |
+
|
| 1385 |
+.topbar-edge-button:focus-visible {
|
| 1386 |
+
+ outline: 1px solid var(--focus-line);
|
| 1387 |
+ outline-offset: -4px;
|
| 1388 |
+
+ box-shadow: none;
|
| 1389 |
+}
|
| 1390 |
+
|
| 1391 |
+/* ---------------------------------------------------------------- rows: the ring is the row's */
|
|
|
|
| 1394 |
+.session-tree .session-tree-main:focus-visible,
|
| 1395 |
+.session-tree a.session-tree-main:focus-visible {
|
| 1396 |
+ outline: none;
|
| 1397 |
+
+ box-shadow: none;
|
| 1398 |
+}
|
| 1399 |
+
|
| 1400 |
+.session-tree-session:has(> .session-tree-main:focus-visible) {
|
| 1401 |
+
+ outline: 1px solid var(--focus-line);
|
| 1402 |
+
+ outline-offset: -1px;
|
| 1403 |
+
+ box-shadow: var(--focus-glow);
|
| 1404 |
+}
|
| 1405 |
+
|
| 1406 |
+/* A project header: the same, on the header's box (its + and ⋯ ring themselves). */
|
| 1407 |
+.session-tree .session-tree-group-toggle:focus-visible {
|
| 1408 |
+ outline: none;
|
| 1409 |
+
+ box-shadow: none;
|
| 1410 |
+}
|
| 1411 |
+
|
| 1412 |
+.session-tree-group:has(> .session-tree-group-toggle:focus-visible) {
|
| 1413 |
+
+ outline: 1px solid var(--focus-line);
|
| 1414 |
+
+ outline-offset: -1px;
|
| 1415 |
+
+ box-shadow: var(--focus-glow);
|
| 1416 |
+}
|
| 1417 |
+
|
| 1418 |
+/* Rows whose control spans the row: the control's own box, with the row's corners. */
|
|
|
|
| 1421 |
+.session-tree .session-tree-more-toggle:focus-visible,
|
| 1422 |
+.sidebar-files-section-toggle:focus-visible {
|
| 1423 |
+ border-radius: var(--radius-sm);
|
| 1424 |
+
+ outline: 1px solid var(--focus-line);
|
| 1425 |
+
+ outline-offset: -1px;
|
| 1426 |
+
+ box-shadow: var(--focus-glow);
|
| 1427 |
+}
|
| 1428 |
+
|
| 1429 |
+/* A tool call or a thought: the whole step line, its time included. */
|
| 1430 |
+.tool-call-head:focus-visible {
|
| 1431 |
+ outline: none;
|
| 1432 |
+
+ box-shadow: none;
|
| 1433 |
+}
|
| 1434 |
+
|
| 1435 |
+.tool-call-row:has(> .tool-call-head:focus-visible) {
|
| 1436 |
+
+ outline: 1px solid var(--focus-line);
|
| 1437 |
+
+ outline-offset: -1px;
|
| 1438 |
+
+ box-shadow: var(--focus-glow);
|
| 1439 |
+}
|
| 1440 |
+
|
| 1441 |
+/* Browsers without :has() keep the ring on the inner control. */
|
|
|
|
| 1444 |
+ .session-tree .session-tree-group-toggle:focus-visible,
|
| 1445 |
+ .tool-call-head:focus-visible {
|
| 1446 |
+ border-radius: var(--radius-sm);
|
| 1447 |
+
+ outline: 1px solid var(--focus-line);
|
| 1448 |
+
+ outline-offset: -1px;
|
| 1449 |
+
+ box-shadow: var(--focus-glow);
|
| 1450 |
+ }
|
| 1451 |
+}
|
| 1452 |
+
|
| 1453 |
+
+/* A resize handle: its line turns into the focus line's colour, nothing around it. */
|
| 1454 |
+.panel-resize-handle:focus-visible {
|
| 1455 |
+ outline: none;
|
| 1456 |
+
+ box-shadow: none;
|
| 1457 |
+}
|
| 1458 |
+
|
| 1459 |
+/* ---------------------------------------------------------------- sliders
|
|
|
|
| 1470 |
+input[type="range"]:focus,
|
| 1471 |
+input[type="range"]:focus-visible {
|
| 1472 |
+ outline: none;
|
| 1473 |
+
+ box-shadow: none;
|
| 1474 |
+}
|
| 1475 |
+
|
| 1476 |
+input[type="range"]::-webkit-slider-runnable-track {
|
|
|
|
| 1512 |
+}
|
| 1513 |
+
|
| 1514 |
+input[type="range"]:focus-visible::-webkit-slider-thumb {
|
| 1515 |
+
+ box-shadow: 0 0 0 2px var(--bg-elevated, var(--bg)), 0 0 0 3px var(--focus-line), 0 0 0 6px var(--focus-halo);
|
| 1516 |
+}
|
| 1517 |
+
|
| 1518 |
+input[type="range"]:focus-visible::-moz-range-thumb {
|
| 1519 |
+
+ box-shadow: 0 0 0 2px var(--bg-elevated, var(--bg)), 0 0 0 3px var(--focus-line), 0 0 0 6px var(--focus-halo);
|
| 1520 |
+}
|
| 1521 |
+
|
| 1522 |
+input[type="range"]:disabled {
|
|
|
|
| 1525 |
+}
|
| 1526 |
+
|
| 1527 |
+.panel-resize-handle:focus-visible::after {
|
| 1528 |
+
+ background: var(--focus-line);
|
| 1529 |
+}
|
| 1530 |
+
diff --git a/app/focus.test.mjs b/app/focus.test.mjs
|
| 1531 |
+
new file mode 100644
|
| 1532 |
+
index 0000000..0b281f4
|
| 1533 |
+
--- /dev/null
|
| 1534 |
+
+++ b/app/focus.test.mjs
|
| 1535 |
+
@@ -0,0 +1,95 @@
|
| 1536 |
+
+import assert from "node:assert/strict";
|
| 1537 |
+
+import { existsSync, readFileSync, readdirSync } from "node:fs";
|
| 1538 |
+
+import test from "node:test";
|
| 1539 |
+
+
|
| 1540 |
+
+const read = (name) => readFileSync(new URL(name, import.meta.url), "utf8");
|
| 1541 |
+
+const focus = read("./focus.css");
|
| 1542 |
+
+const globals = read("./globals.css");
|
| 1543 |
+
+const sheets = readdirSync(new URL("./", import.meta.url)).filter((name) => name.endsWith(".css")).map((name) => [name, read(`./${name}`)]);
|
| 1544 |
+
+// The Hugging Face gateway's own sheets, where this checkout sits beside them (the Space's folder).
|
| 1545 |
+
+const gatewayDir = new URL("../../space/gateway/static/", import.meta.url);
|
| 1546 |
+
+const gateway = existsSync(gatewayDir) ? ["pi-overlay.css", "app.css"].map((name) => [name, readFileSync(new URL(name, gatewayDir), "utf8")]) : [];
|
| 1547 |
+
+
|
| 1548 |
+
+function rules(css) {
|
| 1549 |
+
+ const clean = css.replace(/\/\*[\s\S]*?\*\//g, "");
|
| 1550 |
+
+ return [...clean.matchAll(/([^{}]+)\{([^{}]*)\}/g)].map(([, selector, body]) => ({ selector: selector.trim(), body }));
|
| 1551 |
+
+}
|
| 1552 |
+
+
|
| 1553 |
+
+test("no focus state draws the thick 2px ring any more: a 1px line and a soft halo, as Desktop's", () => {
|
| 1554 |
+
+ for (const [name, css] of [...sheets, ...gateway]) {
|
| 1555 |
+
+ for (const { selector, body } of rules(css)) {
|
| 1556 |
+
+ if (!selector.includes(":focus")) continue;
|
| 1557 |
+
+ assert.doesNotMatch(body, /outline:\s*2px solid/, `${name}: ${selector}`);
|
| 1558 |
+
+ assert.doesNotMatch(body, /box-shadow:[^;]*\b0 0 0 2px var\(--(focus-ring|accent)\)/, `${name}: ${selector}`);
|
| 1559 |
+
+ }
|
| 1560 |
+
+ }
|
| 1561 |
+
+ assert.match(focus, /--focus-line: color-mix\(in srgb, var\(--focus-ring\) 70%, transparent\);/);
|
| 1562 |
+
+ assert.match(focus, /--focus-glow: 0 0 0 3px var\(--focus-halo\);/);
|
| 1563 |
+
+ // The message being edited was a 2px ring too.
|
| 1564 |
+
+ assert.match(globals, /\.user-bubble\.is-editing \{[^}]*box-shadow: 0 0 0 1px var\(--focus-line\), var\(--focus-glow\);/);
|
| 1565 |
+
+});
|
| 1566 |
+
+
|
| 1567 |
+
+test("controls take the halo; what is focusable by tabindex alone keeps its own shadow", () => {
|
| 1568 |
+
+ const all = rules(focus);
|
| 1569 |
+
+ const containers = all.find(({ selector }) => selector.startsWith(":where([tabindex]"));
|
| 1570 |
+
+ assert.ok(containers && !/box-shadow/.test(containers.body), "a menu's or a tile's surface keeps its shadow");
|
| 1571 |
+
+ const controls = all.find(({ selector }) => selector.startsWith(":where(button, summary") && selector.endsWith(":focus-visible"));
|
| 1572 |
+
+ assert.match(controls.body, /box-shadow: var\(--focus-glow\)/);
|
| 1573 |
+
+ // An inner control whose row draws the ring draws neither the line nor the halo.
|
| 1574 |
+
+ for (const inner of [".session-tree .session-tree-group-toggle:focus-visible", ".tool-call-head:focus-visible", ".chat-input-textarea:focus-visible", ".panel-resize-handle:focus-visible"]) {
|
| 1575 |
+
+ const rule = all.find(({ selector }) => selector.split(",").map((part) => part.trim()).includes(inner));
|
| 1576 |
+
+ assert.ok(rule, inner);
|
| 1577 |
+
+ assert.match(rule.body, /outline: none;[\s\S]*box-shadow: none;/, inner);
|
| 1578 |
+
+ }
|
| 1579 |
+
+});
|
| 1580 |
+
+
|
| 1581 |
+
+function hex(value) {
|
| 1582 |
+
+ const n = Number.parseInt(value.slice(1), 16);
|
| 1583 |
+
+ return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
|
| 1584 |
+
+}
|
| 1585 |
+
+function luminance([r, g, b]) {
|
| 1586 |
+
+ const lin = (c) => { const s = c / 255; return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4; };
|
| 1587 |
+
+ return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
|
| 1588 |
+
+}
|
| 1589 |
+
+function contrast(a, b) {
|
| 1590 |
+
+ const [x, y] = [luminance(a), luminance(b)].sort((p, q) => q - p);
|
| 1591 |
+
+ return (x + 0.05) / (y + 0.05);
|
| 1592 |
+
+}
|
| 1593 |
+
+
|
| 1594 |
+
+test("the focus line keeps 3:1 or more on every surface it sits on, in light and dark", () => {
|
| 1595 |
+
+ const tokens = globals.slice(globals.indexOf("/* tokens:begin */"), globals.indexOf("/* tokens:end */"));
|
| 1596 |
+
+ const blocks = [tokens.slice(0, tokens.indexOf("html.dark")), tokens.slice(tokens.indexOf("html.dark"))];
|
| 1597 |
+
+ for (const block of blocks) {
|
| 1598 |
+
+ const get = (name) => hex(block.match(new RegExp(`--${name}: (#[0-9a-f]{6});`))[1]);
|
| 1599 |
+
+ const ring = get("focus-ring");
|
| 1600 |
+
+ for (const surface of ["bg", "bg-surface", "bg-elevated"]) {
|
| 1601 |
+
+ const under = get(surface);
|
| 1602 |
+
+ const line = ring.map((c, i) => Math.round(c * 0.7 + under[i] * 0.3));
|
| 1603 |
+
+ assert.ok(contrast(line, under) >= 3, `${surface}: ${contrast(line, under).toFixed(2)}:1`);
|
| 1604 |
+
+ }
|
| 1605 |
+
+ }
|
| 1606 |
+
+});
|
| 1607 |
+
+
|
| 1608 |
+
+test("the sidebar's footer rows stand on the brand's columns, and Settings' pages under its title", () => {
|
| 1609 |
+
+ const footer = globals.match(/\.sidebar-footer-button \{([^}]*)\}/)[1];
|
| 1610 |
+
+ assert.match(footer, /justify-content: flex-start;/);
|
| 1611 |
+
+ assert.match(footer, /gap: 9px;/);
|
| 1612 |
+
+ assert.match(footer, /padding: 0 5px;/);
|
| 1613 |
+
+ if (gateway.length) {
|
| 1614 |
+
+ const account = gateway[0][1].match(/\.hfpi-account-button \{([^}]*)\}/)[1];
|
| 1615 |
+
+ assert.match(account, /gap: 9px;/);
|
| 1616 |
+
+ assert.match(account, /padding: 0 5px;/);
|
| 1617 |
+
+ }
|
| 1618 |
+
+ const settings = read("./settings.css");
|
| 1619 |
+
+ const header = settings.match(/\.settings-dialog-header \{[^}]*padding: 0 48px 0 (\d+)px;/)[1];
|
| 1620 |
+
+ const general = settings.match(/\.settings-general \{[^}]*padding: 18px (\d+)px 28px;/)[1];
|
| 1621 |
+
+ assert.equal(general, header);
|
| 1622 |
+
+});
|
| 1623 |
+
+
|
| 1624 |
+
+test("section labels are quiet and in sentence case, never small bold capitals", () => {
|
| 1625 |
+
+ for (const [name, css] of sheets) {
|
| 1626 |
+
+ for (const { selector, body } of rules(css)) {
|
| 1627 |
+
+ if (/text-transform:\s*uppercase/.test(body)) assert.match(selector, /::first-letter/, `${name}: ${selector}`);
|
| 1628 |
+
+ }
|
| 1629 |
+
+ }
|
| 1630 |
+
+});
|
| 1631 |
diff --git a/app/fonts/Geist-Variable.woff2 b/app/fonts/Geist-Variable.woff2
|
| 1632 |
new file mode 100644
|
| 1633 |
index 0000000000000000000000000000000000000000..9983e92a03de482b5708201694101c330b6ae9b8
|
|
|
|
| 3955 |
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
| 3956 |
+OTHER DEALINGS IN THE FONT SOFTWARE.
|
| 3957 |
diff --git a/app/globals.css b/app/globals.css
|
| 3958 |
+
index d6b5535..9f01813 100644
|
| 3959 |
--- a/app/globals.css
|
| 3960 |
+++ b/app/globals.css
|
| 3961 |
@@ -24,46 +24,109 @@
|
|
|
|
| 4253 |
background: var(--accent);
|
| 4254 |
color: var(--accent-contrast);
|
| 4255 |
cursor: pointer;
|
| 4256 |
+
@@ -322,7 +405,7 @@ html.dark .web-login-error {
|
| 4257 |
+
}
|
| 4258 |
+
|
| 4259 |
+
.web-login-form button:focus-visible {
|
| 4260 |
+
- outline: 2px solid var(--accent);
|
| 4261 |
+
+ outline: 1px solid var(--focus-line);
|
| 4262 |
+
outline-offset: 2px;
|
| 4263 |
+
}
|
| 4264 |
+
|
| 4265 |
@@ -332,110 +415,139 @@ html.dark .web-login-error {
|
| 4266 |
cursor: not-allowed;
|
| 4267 |
}
|
|
|
|
| 4554 |
|
| 4555 |
|
| 4556 |
.extension-status-shelf {
|
| 4557 |
+
@@ -686,8 +780,9 @@ button.extension-widget-trigger:hover,
|
| 4558 |
+
}
|
| 4559 |
+
|
| 4560 |
+
button.extension-widget-trigger:focus-visible {
|
| 4561 |
+
- outline: 2px solid var(--accent);
|
| 4562 |
+
- outline-offset: -2px;
|
| 4563 |
+
+ outline: 1px solid var(--focus-line);
|
| 4564 |
+
+ outline-offset: -1px;
|
| 4565 |
+
+ box-shadow: var(--focus-glow);
|
| 4566 |
+
}
|
| 4567 |
+
|
| 4568 |
+
.extension-widget-placement {
|
| 4569 |
+
@@ -703,9 +798,9 @@ button.extension-widget-trigger:focus-visible {
|
| 4570 |
|
| 4571 |
.extension-widget-placement-icon {
|
| 4572 |
display: block;
|
|
|
|
| 4579 |
fill: currentColor;
|
| 4580 |
}
|
| 4581 |
|
| 4582 |
+
@@ -803,8 +898,9 @@ button.extension-widget-trigger:focus-visible {
|
| 4583 |
+
}
|
| 4584 |
+
|
| 4585 |
+
.extension-status-command:focus-visible {
|
| 4586 |
+
- outline: 2px solid var(--accent);
|
| 4587 |
+
- outline-offset: -2px;
|
| 4588 |
+
+ outline: 1px solid var(--focus-line);
|
| 4589 |
+
+ outline-offset: -1px;
|
| 4590 |
+
+ box-shadow: var(--focus-glow);
|
| 4591 |
+
}
|
| 4592 |
+
|
| 4593 |
+
.extension-status-command:disabled {
|
| 4594 |
+
@@ -826,8 +922,8 @@ button.extension-widget-trigger:focus-visible {
|
| 4595 |
}
|
| 4596 |
|
| 4597 |
:root {
|
|
|
|
| 4602 |
--font-ui: var(--font-ui-default);
|
| 4603 |
--font-mono: var(--font-mono-default);
|
| 4604 |
--font-ui-weight: 400;
|
| 4605 |
+
@@ -883,11 +979,11 @@ pre, code {
|
| 4606 |
.markdown-body ol > li { list-style-type: decimal; }
|
| 4607 |
.markdown-body li > p { margin: 0; }
|
| 4608 |
.markdown-body li::marker {
|
|
|
|
| 4617 |
font-weight: 700;
|
| 4618 |
}
|
| 4619 |
.markdown-body em { color: var(--text-muted); }
|
| 4620 |
+
@@ -896,24 +992,23 @@ pre, code {
|
| 4621 |
text-decoration: underline;
|
| 4622 |
text-decoration-thickness: 1px;
|
| 4623 |
text-underline-offset: 3px;
|
|
|
|
| 4646 |
}
|
| 4647 |
.markdown-body .contains-task-list {
|
| 4648 |
padding-left: 0;
|
| 4649 |
+
@@ -935,7 +1030,7 @@ pre, code {
|
| 4650 |
height: 14px;
|
| 4651 |
margin: 0;
|
| 4652 |
border: 1px solid var(--border);
|
|
|
|
| 4655 |
background: var(--bg);
|
| 4656 |
display: inline-grid;
|
| 4657 |
place-content: center;
|
| 4658 |
+
@@ -967,8 +1062,8 @@ pre, code {
|
| 4659 |
margin: 8px 0;
|
| 4660 |
overflow-x: auto;
|
| 4661 |
overflow-y: hidden;
|
|
|
|
| 4666 |
}
|
| 4667 |
.markdown-body table {
|
| 4668 |
border-collapse: separate;
|
| 4669 |
+
@@ -1088,7 +1183,7 @@ pre, code {
|
| 4670 |
padding: 7px 8px;
|
| 4671 |
overflow: auto;
|
| 4672 |
border: 1px solid var(--border);
|
|
|
|
| 4675 |
background: var(--bg-panel);
|
| 4676 |
font-family: var(--font-mono);
|
| 4677 |
font-size: 11px;
|
| 4678 |
+
@@ -1108,16 +1203,13 @@ pre, code {
|
| 4679 |
min-width: 0;
|
| 4680 |
max-width: 100%;
|
| 4681 |
margin: 6px 0;
|
|
|
|
| 4695 |
color: var(--text-dim);
|
| 4696 |
font-size: 11px;
|
| 4697 |
display: flex;
|
| 4698 |
+
@@ -1137,7 +1229,7 @@ pre, code {
|
| 4699 |
}
|
| 4700 |
.markdown-code-action {
|
| 4701 |
border: 1px solid var(--border);
|
|
|
|
| 4704 |
padding: 2px 7px;
|
| 4705 |
background: var(--bg);
|
| 4706 |
color: var(--text-muted);
|
| 4707 |
+
@@ -1191,8 +1283,9 @@ pre, code {
|
| 4708 |
+
opacity: 0.85;
|
| 4709 |
+
}
|
| 4710 |
+
.mermaid-preview-button:focus-visible {
|
| 4711 |
+
- outline: 2px solid var(--accent);
|
| 4712 |
+
- outline-offset: -2px;
|
| 4713 |
+
+ outline: 1px solid var(--focus-line);
|
| 4714 |
+
+ outline-offset: -1px;
|
| 4715 |
+
+ box-shadow: var(--focus-glow);
|
| 4716 |
+
}
|
| 4717 |
+
|
| 4718 |
+
.image-preview-dialog {
|
| 4719 |
+
@@ -1228,7 +1321,7 @@ pre, code {
|
| 4720 |
max-width: 100%;
|
| 4721 |
max-height: 100%;
|
| 4722 |
object-fit: contain;
|
|
|
|
| 4725 |
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
|
| 4726 |
}
|
| 4727 |
|
| 4728 |
+
@@ -1244,7 +1337,7 @@ pre, code {
|
| 4729 |
height: 36px;
|
| 4730 |
padding: 0;
|
| 4731 |
border: 1px solid var(--border);
|
|
|
|
| 4734 |
background: var(--bg-panel);
|
| 4735 |
color: var(--text-muted);
|
| 4736 |
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.28);
|
| 4737 |
+
@@ -1259,7 +1352,7 @@ pre, code {
|
| 4738 |
+
}
|
| 4739 |
+
|
| 4740 |
+
.image-preview-close:focus-visible {
|
| 4741 |
+
- outline: 2px solid var(--accent);
|
| 4742 |
+
+ outline: 1px solid var(--focus-line);
|
| 4743 |
+
outline-offset: 2px;
|
| 4744 |
+
}
|
| 4745 |
+
|
| 4746 |
+
@@ -1320,7 +1413,7 @@ pre, code {
|
| 4747 |
height: 24px;
|
| 4748 |
overflow: hidden;
|
| 4749 |
border: 1px solid var(--border);
|
|
|
|
| 4752 |
background: var(--bg);
|
| 4753 |
}
|
| 4754 |
.mermaid-zoom-stepper button,
|
| 4755 |
+
@@ -1347,7 +1440,7 @@ pre, code {
|
| 4756 |
.mermaid-zoom-icon-button {
|
| 4757 |
flex: 0 0 24px;
|
| 4758 |
border: 1px solid var(--border);
|
|
|
|
| 4761 |
}
|
| 4762 |
.mermaid-zoom-stepper button:hover:not(:disabled),
|
| 4763 |
.mermaid-zoom-icon-button:hover {
|
| 4764 |
+
@@ -1360,8 +1453,9 @@ pre, code {
|
| 4765 |
+
}
|
| 4766 |
+
.mermaid-zoom-stepper button:focus-visible,
|
| 4767 |
+
.mermaid-zoom-icon-button:focus-visible {
|
| 4768 |
+
- outline: 2px solid var(--accent);
|
| 4769 |
+
- outline-offset: -2px;
|
| 4770 |
+
+ outline: 1px solid var(--focus-line);
|
| 4771 |
+
+ outline-offset: -1px;
|
| 4772 |
+
+ box-shadow: var(--focus-glow);
|
| 4773 |
+
}
|
| 4774 |
+
.mermaid-zoom-value {
|
| 4775 |
+
min-width: 48px;
|
| 4776 |
+
@@ -1384,7 +1478,7 @@ pre, code {
|
| 4777 |
.mermaid-zoom-canvas {
|
| 4778 |
padding: 12px;
|
| 4779 |
border: 1px solid var(--border);
|
|
|
|
| 4782 |
background: var(--bg-panel);
|
| 4783 |
margin: 0 auto;
|
| 4784 |
transition: width 0.15s ease;
|
| 4785 |
+
@@ -1460,7 +1554,7 @@ pre, code {
|
| 4786 |
height: 24px;
|
| 4787 |
overflow: hidden;
|
| 4788 |
border: 1px solid var(--border);
|
|
|
|
| 4791 |
}
|
| 4792 |
|
| 4793 |
.file-viewer-mode-button {
|
| 4794 |
+
@@ -1503,12 +1597,11 @@ pre, code {
|
| 4795 |
height: 32px;
|
| 4796 |
padding: 0;
|
| 4797 |
box-sizing: border-box;
|
|
|
|
| 4806 |
opacity: 0;
|
| 4807 |
visibility: hidden;
|
| 4808 |
pointer-events: none;
|
| 4809 |
+
@@ -1542,7 +1635,7 @@ pre, code {
|
| 4810 |
+
}
|
| 4811 |
+
|
| 4812 |
+
.chat-scroll-to-bottom:focus-visible {
|
| 4813 |
+
- outline: 2px solid var(--accent);
|
| 4814 |
+
+ outline: 1px solid var(--focus-line);
|
| 4815 |
+
outline-offset: 2px;
|
| 4816 |
+
}
|
| 4817 |
+
|
| 4818 |
+
@@ -1566,11 +1659,13 @@ pre, code {
|
| 4819 |
}
|
| 4820 |
}
|
| 4821 |
|
|
|
|
| 4833 |
margin: 0 auto;
|
| 4834 |
}
|
| 4835 |
|
| 4836 |
+
@@ -1584,22 +1679,21 @@ pre, code {
|
| 4837 |
|
| 4838 |
.new-session-logo {
|
| 4839 |
flex: none;
|
|
|
|
| 4862 |
line-height: 1.15;
|
| 4863 |
white-space: nowrap;
|
| 4864 |
}
|
| 4865 |
+
@@ -1613,7 +1707,8 @@ pre, code {
|
| 4866 |
gap: 6px;
|
| 4867 |
min-width: 0;
|
| 4868 |
color: var(--text-dim);
|
|
|
|
| 4872 |
line-height: 1.4;
|
| 4873 |
white-space: nowrap;
|
| 4874 |
}
|
| 4875 |
+
@@ -1638,7 +1733,7 @@ pre, code {
|
| 4876 |
gap: 3px;
|
| 4877 |
margin: -3px -4px;
|
| 4878 |
padding: 3px 4px;
|
|
|
|
| 4881 |
color: var(--accent);
|
| 4882 |
font-weight: 600;
|
| 4883 |
text-decoration: none;
|
| 4884 |
+
@@ -1652,38 +1747,27 @@ pre, code {
|
| 4885 |
|
| 4886 |
/* The ring inside the box, clear of the "→" and "·" beside it. */
|
| 4887 |
.new-session-update:focus-visible {
|
| 4888 |
- outline: 2px solid var(--accent);
|
| 4889 |
+
- outline-offset: -2px;
|
| 4890 |
+
+ outline: 1px solid var(--focus-line);
|
| 4891 |
+
+ outline-offset: -1px;
|
| 4892 |
+
+ box-shadow: var(--focus-glow);
|
| 4893 |
}
|
| 4894 |
|
| 4895 |
+
.new-session-update svg {
|
| 4896 |
flex: none;
|
| 4897 |
}
|
| 4898 |
|
|
|
|
| 4926 |
}
|
| 4927 |
}
|
| 4928 |
|
| 4929 |
+
@@ -1700,8 +1784,8 @@ pre, code {
|
| 4930 |
tab's stacked boxes, the row below the sessions), as the sidebar drew it
|
| 4931 |
on main: two grey boxes in the header buttons' material, 11px, the
|
| 4932 |
project's whole path and the worktree's branch in code type, cut at their
|
|
|
|
| 4937 |
.project-picker {
|
| 4938 |
display: flex;
|
| 4939 |
align-items: center;
|
| 4940 |
+
@@ -1722,52 +1806,14 @@ pre, code {
|
| 4941 |
min-width: 0;
|
| 4942 |
height: 29px;
|
| 4943 |
padding: 0 10px;
|
|
|
|
| 4993 |
}
|
| 4994 |
|
| 4995 |
/* The project's name (its display name, else its folder's), cut at its
|
| 4996 |
+
@@ -1781,8 +1827,9 @@ pre, code {
|
| 4997 |
max-width: 28ch;
|
| 4998 |
overflow: hidden;
|
| 4999 |
color: var(--text-dim);
|
|
|
|
| 5004 |
}
|
| 5005 |
|
| 5006 |
.project-picker-parent {
|
| 5007 |
+
@@ -1800,10 +1847,6 @@ pre, code {
|
| 5008 |
text-overflow: ellipsis;
|
| 5009 |
}
|
| 5010 |
|
|
|
|
| 5015 |
.project-picker-button:hover,
|
| 5016 |
.project-picker-button[aria-expanded="true"] {
|
| 5017 |
background: var(--bg-selected);
|
| 5018 |
+
@@ -1811,8 +1854,9 @@ pre, code {
|
| 5019 |
+
}
|
| 5020 |
+
|
| 5021 |
+
.project-picker-button:focus-visible {
|
| 5022 |
+
- outline: 2px solid var(--accent);
|
| 5023 |
+
- outline-offset: 1px;
|
| 5024 |
+
+ outline: 1px solid var(--focus-line);
|
| 5025 |
+
+ outline-offset: -1px;
|
| 5026 |
+
+ box-shadow: var(--focus-glow);
|
| 5027 |
+
}
|
| 5028 |
+
|
| 5029 |
+
.project-picker-icon,
|
| 5030 |
+
@@ -1851,7 +1895,8 @@ pre, code {
|
| 5031 |
path's color and code type, cut at its end. */
|
| 5032 |
.project-picker-label.is-alias {
|
| 5033 |
color: var(--text);
|
|
|
|
| 5037 |
}
|
| 5038 |
|
| 5039 |
/* A path or a branch, cut at its left (rtl), the text itself kept left to
|
| 5040 |
+
@@ -1901,7 +1946,8 @@ pre, code {
|
| 5041 |
border-color: color-mix(in srgb, var(--accent) 40%, transparent);
|
| 5042 |
background: color-mix(in srgb, var(--accent) 6%, transparent);
|
| 5043 |
color: var(--text-dim);
|
|
|
|
| 5047 |
}
|
| 5048 |
|
| 5049 |
/* No worktree list here (the files tab): a box that says why, and does nothing. */
|
| 5050 |
+
@@ -1978,7 +2024,7 @@ pre, code {
|
| 5051 |
box-sizing: border-box;
|
| 5052 |
flex: 0 0 24px;
|
| 5053 |
border: 1px solid var(--border);
|
|
|
|
| 5056 |
background: transparent;
|
| 5057 |
color: var(--text-muted);
|
| 5058 |
cursor: pointer;
|
| 5059 |
+
@@ -2003,8 +2049,9 @@ pre, code {
|
| 5060 |
+
|
| 5061 |
+
.file-viewer-mode-button:focus-visible,
|
| 5062 |
+
.file-viewer-icon-button:focus-visible {
|
| 5063 |
+
- outline: 2px solid var(--accent);
|
| 5064 |
+
- outline-offset: -2px;
|
| 5065 |
+
+ outline: 1px solid var(--focus-line);
|
| 5066 |
+
+ outline-offset: -1px;
|
| 5067 |
+
+ box-shadow: var(--focus-glow);
|
| 5068 |
+
}
|
| 5069 |
+
|
| 5070 |
+
.directory-picker-path:focus-visible {
|
| 5071 |
+
@@ -2037,7 +2084,7 @@ pre, code {
|
| 5072 |
.markdown-file-preview pre {
|
| 5073 |
background: var(--bg-panel);
|
| 5074 |
border: 1px solid var(--border);
|
|
|
|
| 5077 |
padding: 12px 16px;
|
| 5078 |
overflow-x: auto;
|
| 5079 |
font-family: var(--font-mono);
|
| 5080 |
+
@@ -2049,7 +2096,7 @@ pre, code {
|
| 5081 |
font-size: 0.9em;
|
| 5082 |
background: var(--bg-panel);
|
| 5083 |
padding: 1px 5px;
|
|
|
|
| 5086 |
}
|
| 5087 |
.markdown-file-preview pre code {
|
| 5088 |
background: none;
|
| 5089 |
+
@@ -2061,7 +2108,7 @@ pre, code {
|
| 5090 |
margin-bottom: 20px;
|
| 5091 |
padding: 14px 16px 12px;
|
| 5092 |
border: 1px solid var(--border);
|
|
|
|
| 5095 |
background: var(--bg-panel);
|
| 5096 |
}
|
| 5097 |
.markdown-frontmatter-title {
|
| 5098 |
+
@@ -2114,18 +2161,6 @@ pre, code {
|
| 5099 |
text-underline-offset: 2px;
|
| 5100 |
}
|
| 5101 |
|
|
|
|
| 5114 |
@keyframes drop-zone-in {
|
| 5115 |
from { opacity: 0; transform: scale(0.97); }
|
| 5116 |
to { opacity: 1; transform: scale(1); }
|
| 5117 |
+
@@ -2230,10 +2265,6 @@ span.token.table {
|
| 5118 |
.panel-resize-handle.is-resizing::after {
|
| 5119 |
background: color-mix(in srgb, var(--text-muted) 70%, var(--border));
|
| 5120 |
}
|
|
|
|
| 5125 |
/* Desktop sidebar: animate width */
|
| 5126 |
@media (min-width: 641px) {
|
| 5127 |
.sidebar-overlay-backdrop {
|
| 5128 |
+
@@ -2264,119 +2295,6 @@ span.token.table {
|
| 5129 |
}
|
| 5130 |
}
|
| 5131 |
|
|
|
|
| 5245 |
/* Mobile sidebar: slide in/out as overlay */
|
| 5246 |
@media (max-width: 640px) {
|
| 5247 |
.chat-stats-center {
|
| 5248 |
+
@@ -2401,31 +2319,7 @@ span.token.table {
|
| 5249 |
box-shadow: none;
|
| 5250 |
}
|
| 5251 |
|
|
|
|
| 5278 |
display: none;
|
| 5279 |
}
|
| 5280 |
.directory-picker-back,
|
| 5281 |
+
@@ -2474,3 +2368,479 @@ span.token.table {
|
| 5282 |
display: none !important;
|
| 5283 |
}
|
| 5284 |
}
|
|
|
|
| 5426 |
+}
|
| 5427 |
+.user-bubble.is-editing {
|
| 5428 |
+ background: color-mix(in srgb, var(--accent) 14%, var(--user-bg));
|
| 5429 |
+
+ box-shadow: 0 0 0 1px var(--focus-line), var(--focus-glow);
|
| 5430 |
+}
|
| 5431 |
+/* The actions under a message: icon buttons that show on hover or focus. */
|
| 5432 |
+.message-actions {
|
|
|
|
| 5681 |
+.reply-notice.is-error { background: var(--danger-soft); color: var(--danger); }
|
| 5682 |
+.reply-notice.is-warning { background: color-mix(in srgb, var(--warning) 12%, transparent); color: var(--warning); }
|
| 5683 |
+
|
| 5684 |
+
+/* The sidebar's bottom row (AppShell): Settings; under it, the row a host may
|
| 5685 |
+
+ fill ([data-host-slot="sidebar-footer"], the gateway's Workspace row). Both
|
| 5686 |
+
+ on the brand's columns: the icon 11px from the sidebar's edge, the label at
|
| 5687 |
+
+ 34px (the 6px row inset, 5px padding, a 14px icon, a 9px gap), so the
|
| 5688 |
+
+ sidebar's top and bottom line up; a lone centred Settings once floated
|
| 5689 |
+
+ between them. */
|
| 5690 |
+.sidebar-footer {
|
| 5691 |
+ display: flex;
|
| 5692 |
+ flex-shrink: 0;
|
|
|
|
| 5708 |
+ display: flex;
|
| 5709 |
+ flex: 1 1 0;
|
| 5710 |
+ align-items: center;
|
| 5711 |
+
+ justify-content: flex-start;
|
| 5712 |
+
+ gap: 9px;
|
| 5713 |
+ min-width: 0;
|
| 5714 |
+ height: var(--size-control-sm);
|
| 5715 |
+
+ padding: 0 5px;
|
| 5716 |
+ border: 0;
|
| 5717 |
+ border-radius: var(--radius-sm);
|
| 5718 |
+ background: none;
|
|
|
|
| 5883 |
lang: "en",
|
| 5884 |
icons: [
|
| 5885 |
diff --git a/app/settings.css b/app/settings.css
|
| 5886 |
+
index 0bf21eb..11530a5 100644
|
| 5887 |
--- a/app/settings.css
|
| 5888 |
+++ b/app/settings.css
|
| 5889 |
@@ -40,9 +40,9 @@
|
|
|
|
| 5917 |
background: transparent;
|
| 5918 |
color: var(--text-muted);
|
| 5919 |
cursor: pointer;
|
| 5920 |
+
@@ -122,6 +122,7 @@
|
| 5921 |
+
margin-bottom: 6px;
|
| 5922 |
+
}
|
| 5923 |
+
|
| 5924 |
+
+/* A section label as every dropdown's and the design system's: quiet, 12px, sentence case (no small bold capitals). */
|
| 5925 |
+
.config-sidebar-group-label {
|
| 5926 |
+
display: flex;
|
| 5927 |
+
align-items: center;
|
| 5928 |
+
@@ -129,11 +130,10 @@
|
| 5929 |
+
padding: 4px 8px 3px;
|
| 5930 |
+
color: var(--text-dim);
|
| 5931 |
+
font-family: inherit;
|
| 5932 |
+
- font-size: 10px;
|
| 5933 |
+
- font-weight: 600;
|
| 5934 |
+
+ font-size: 12px;
|
| 5935 |
+
+ font-weight: 400;
|
| 5936 |
+
line-height: 1.4;
|
| 5937 |
+
letter-spacing: 0;
|
| 5938 |
+
- text-transform: uppercase;
|
| 5939 |
+
}
|
| 5940 |
+
|
| 5941 |
+
.config-sidebar-group-label-text {
|
| 5942 |
+
@@ -144,6 +144,13 @@
|
| 5943 |
+
white-space: nowrap;
|
| 5944 |
+
}
|
| 5945 |
+
|
| 5946 |
+
+/* Sentence case: the scopes they name are lowercase words elsewhere (a profile's
|
| 5947 |
+
+ "built-in" chip), so the label capitalises its own first letter. */
|
| 5948 |
+
+.config-sidebar-group-label-text::first-letter,
|
| 5949 |
+
+.config-section-title::first-letter {
|
| 5950 |
+
+ text-transform: uppercase;
|
| 5951 |
+
+}
|
| 5952 |
+
+
|
| 5953 |
+
/* Sits in the heading row, so the sidebar gains no height for it. */
|
| 5954 |
+
.config-sidebar-group-switch {
|
| 5955 |
+
display: inline-flex;
|
| 5956 |
+
@@ -153,8 +160,9 @@
|
| 5957 |
}
|
| 5958 |
|
| 5959 |
.config-sidebar-group-count {
|
|
|
|
| 5964 |
}
|
| 5965 |
|
| 5966 |
/* Three lines, then scroll: the phone layout gives the whole sidebar 190px. */
|
| 5967 |
+
@@ -188,7 +196,7 @@
|
| 5968 |
height: 30px;
|
| 5969 |
padding: 0 8px;
|
| 5970 |
border: 0;
|
|
|
|
| 5973 |
outline: none;
|
| 5974 |
background: transparent;
|
| 5975 |
color: var(--text);
|
| 5976 |
+
@@ -206,8 +214,9 @@
|
| 5977 |
+
}
|
| 5978 |
+
|
| 5979 |
+
.config-sidebar-item:focus-visible {
|
| 5980 |
+
- outline: 2px solid var(--accent);
|
| 5981 |
+
- outline-offset: -2px;
|
| 5982 |
+
+ outline: 1px solid var(--focus-line);
|
| 5983 |
+
+ outline-offset: -1px;
|
| 5984 |
+
+ box-shadow: var(--focus-glow);
|
| 5985 |
+
}
|
| 5986 |
+
|
| 5987 |
+
.config-sidebar-item[aria-current="page"] {
|
| 5988 |
+
@@ -236,8 +245,9 @@
|
| 5989 |
.models-sidebar-badge {
|
| 5990 |
flex-shrink: 0;
|
| 5991 |
color: var(--text-dim);
|
|
|
|
| 5996 |
}
|
| 5997 |
|
| 5998 |
.oauth-paste-panel {
|
| 5999 |
+
@@ -277,9 +287,8 @@
|
| 6000 |
/* An input's intrinsic width would otherwise push the button out of a narrow pane. */
|
| 6001 |
min-width: 0;
|
| 6002 |
padding: 6px 9px;
|
|
|
|
| 6008 |
color: var(--text);
|
| 6009 |
font-family: var(--font-mono);
|
| 6010 |
font-size: 12px;
|
| 6011 |
+
@@ -290,9 +299,9 @@
|
| 6012 |
flex-shrink: 0;
|
| 6013 |
padding: 6px 12px;
|
| 6014 |
border: none;
|
|
|
|
| 6021 |
cursor: pointer;
|
| 6022 |
font-size: 12px;
|
| 6023 |
font-weight: 600;
|
| 6024 |
+
@@ -370,8 +379,9 @@
|
| 6025 |
.enabled-models-count {
|
| 6026 |
margin-right: auto;
|
| 6027 |
color: var(--text-dim);
|
|
|
|
| 6032 |
}
|
| 6033 |
|
| 6034 |
.enabled-models-note {
|
| 6035 |
+
@@ -383,7 +393,7 @@
|
| 6036 |
.enabled-models-error {
|
| 6037 |
padding: 7px 9px;
|
| 6038 |
border: 1px solid rgba(239, 68, 68, 0.3);
|
|
|
|
| 6041 |
color: #ef4444;
|
| 6042 |
font-size: 11px;
|
| 6043 |
line-height: 1.4;
|
| 6044 |
+
@@ -401,10 +411,9 @@
|
| 6045 |
box-sizing: border-box;
|
| 6046 |
height: 30px;
|
| 6047 |
padding: 0 9px;
|
|
|
|
| 6054 |
color: var(--text);
|
| 6055 |
font-family: inherit;
|
| 6056 |
font-size: 12px;
|
| 6057 |
+
@@ -413,7 +422,7 @@
|
| 6058 |
.enabled-models-list {
|
| 6059 |
max-height: 360px;
|
| 6060 |
border: 1px solid var(--border);
|
|
|
|
| 6063 |
background: var(--bg-panel);
|
| 6064 |
overflow-y: auto;
|
| 6065 |
}
|
| 6066 |
+
@@ -457,9 +466,9 @@
|
| 6067 |
.enabled-models-pin {
|
| 6068 |
flex-shrink: 0;
|
| 6069 |
padding: 1px 4px;
|
|
|
|
| 6076 |
font-size: 9px;
|
| 6077 |
}
|
| 6078 |
|
| 6079 |
+
@@ -497,7 +506,7 @@
|
| 6080 |
justify-content: space-between;
|
| 6081 |
gap: 18px;
|
| 6082 |
min-height: 68px;
|
|
|
|
| 6085 |
border-bottom: 1px solid var(--border);
|
| 6086 |
background: var(--bg-panel);
|
| 6087 |
}
|
| 6088 |
+
@@ -541,7 +550,7 @@
|
| 6089 |
height: 28px;
|
| 6090 |
padding: 0 6px;
|
| 6091 |
border: 1px solid var(--border);
|
|
|
|
| 6094 |
background: var(--bg);
|
| 6095 |
color: var(--text);
|
| 6096 |
font: inherit;
|
| 6097 |
+
@@ -566,7 +575,7 @@
|
| 6098 |
flex: 1;
|
| 6099 |
min-width: 0;
|
| 6100 |
min-height: 0;
|
|
|
|
| 6103 |
overflow-y: auto;
|
| 6104 |
font-family: inherit;
|
| 6105 |
font-size: 12px;
|
| 6106 |
+
@@ -628,13 +637,13 @@
|
| 6107 |
+
line-height: 1.35;
|
| 6108 |
+
}
|
| 6109 |
+
|
| 6110 |
+
+/* A section label as every dropdown's and the design system's: quiet, 12px, sentence case (no small bold capitals). */
|
| 6111 |
+
.config-section-title {
|
| 6112 |
+
color: var(--text-dim);
|
| 6113 |
+
- font-size: 11px;
|
| 6114 |
+
- font-weight: 600;
|
| 6115 |
+
+ font-size: 12px;
|
| 6116 |
+
+ font-weight: 400;
|
| 6117 |
+
line-height: 1.35;
|
| 6118 |
+
letter-spacing: 0;
|
| 6119 |
+
- text-transform: uppercase;
|
| 6120 |
+
}
|
| 6121 |
+
|
| 6122 |
+
.config-field {
|
| 6123 |
+
@@ -662,7 +671,7 @@
|
| 6124 |
background: var(--border);
|
| 6125 |
border: 5px solid transparent;
|
| 6126 |
background-clip: padding-box;
|
|
|
|
| 6129 |
}
|
| 6130 |
|
| 6131 |
.config-field-label {
|
| 6132 |
+
@@ -697,15 +706,15 @@
|
| 6133 |
.config-scope-tag {
|
| 6134 |
flex-shrink: 0;
|
| 6135 |
padding: 1px 5px;
|
|
|
|
| 6148 |
}
|
| 6149 |
|
| 6150 |
.config-scope-switch-field {
|
| 6151 |
+
@@ -730,7 +739,7 @@
|
| 6152 |
height: 30px;
|
| 6153 |
overflow: hidden;
|
| 6154 |
border: 1px solid var(--border);
|
|
|
|
| 6157 |
}
|
| 6158 |
|
| 6159 |
.config-scope-switch-option {
|
| 6160 |
+
@@ -760,7 +769,7 @@
|
| 6161 |
.config-scope-switch.is-small {
|
| 6162 |
display: flex;
|
| 6163 |
height: auto;
|
|
|
|
| 6166 |
font-size: 12px;
|
| 6167 |
}
|
| 6168 |
|
| 6169 |
+
@@ -891,9 +900,8 @@
|
| 6170 |
width: 100%;
|
| 6171 |
height: 36px;
|
| 6172 |
padding: 0 11px;
|
|
|
|
| 6178 |
color: var(--text);
|
| 6179 |
font-family: var(--font-mono);
|
| 6180 |
font-size: 12px;
|
| 6181 |
+
@@ -935,7 +943,7 @@
|
| 6182 |
min-height: 30px;
|
| 6183 |
padding: 6px 9px;
|
| 6184 |
border: 1px solid var(--border);
|
|
|
|
| 6187 |
background: var(--bg-panel);
|
| 6188 |
color: var(--text-dim);
|
| 6189 |
cursor: pointer;
|
| 6190 |
+
@@ -976,7 +984,7 @@
|
| 6191 |
}
|
| 6192 |
|
| 6193 |
.config-notice {
|
|
|
|
| 6196 |
border-bottom: 1px solid var(--border);
|
| 6197 |
background: var(--bg-panel);
|
| 6198 |
color: var(--text-muted);
|
| 6199 |
+
@@ -1104,7 +1112,7 @@
|
| 6200 |
align-items: center;
|
| 6201 |
gap: 8px;
|
| 6202 |
min-height: 52px;
|
|
|
|
| 6205 |
border-top: 1px solid var(--border);
|
| 6206 |
}
|
| 6207 |
|
| 6208 |
+
@@ -1159,7 +1167,7 @@
|
| 6209 |
gap: 6px;
|
| 6210 |
border-width: 1px;
|
| 6211 |
border-style: solid;
|
|
|
|
| 6214 |
cursor: pointer;
|
| 6215 |
font-family: inherit;
|
| 6216 |
letter-spacing: 0;
|
| 6217 |
+
@@ -1168,35 +1176,39 @@
|
| 6218 |
transition: background-color 0.14s ease, border-color 0.14s ease, color 0.14s ease, box-shadow 0.14s ease;
|
| 6219 |
}
|
| 6220 |
|
|
|
|
| 6270 |
}
|
| 6271 |
|
| 6272 |
.config-button-ghost {
|
| 6273 |
+
@@ -1206,24 +1218,31 @@
|
| 6274 |
}
|
| 6275 |
|
| 6276 |
.config-button-primary:not(:disabled):hover {
|
|
|
|
| 6305 |
}
|
| 6306 |
|
| 6307 |
.config-button:focus-visible {
|
| 6308 |
+
- outline: 2px solid var(--accent);
|
| 6309 |
+
+ outline: 1px solid var(--focus-line);
|
| 6310 |
+
outline-offset: 2px;
|
| 6311 |
+
}
|
| 6312 |
+
|
| 6313 |
+
@@ -1254,9 +1273,9 @@
|
| 6314 |
width: 32px;
|
| 6315 |
height: 18px;
|
| 6316 |
padding: 0;
|
|
|
|
| 6322 |
cursor: pointer;
|
| 6323 |
transition: background 0.15s, border-color 0.15s;
|
| 6324 |
}
|
| 6325 |
+
@@ -1322,7 +1341,7 @@
|
| 6326 |
+
}
|
| 6327 |
+
|
| 6328 |
+
.config-switch:focus-visible {
|
| 6329 |
+
- outline: 2px solid var(--accent);
|
| 6330 |
+
+ outline: 1px solid var(--focus-line);
|
| 6331 |
+
outline-offset: 2px;
|
| 6332 |
+
}
|
| 6333 |
+
|
| 6334 |
+
@@ -1342,7 +1361,7 @@
|
| 6335 |
min-height: 30px;
|
| 6336 |
padding: 0 8px;
|
| 6337 |
border: 0;
|
|
|
|
| 6340 |
background: transparent;
|
| 6341 |
color: var(--text-dim);
|
| 6342 |
cursor: pointer;
|
| 6343 |
+
@@ -1358,7 +1377,7 @@
|
| 6344 |
|
| 6345 |
.config-list-action-button[aria-current="page"] {
|
| 6346 |
background: var(--bg-selected);
|
|
|
|
| 6349 |
}
|
| 6350 |
|
| 6351 |
.config-list-action-button:disabled {
|
| 6352 |
+
@@ -1405,10 +1424,9 @@
|
| 6353 |
height: 84vh;
|
| 6354 |
max-height: calc(100dvh - 16px);
|
| 6355 |
overflow: hidden;
|
|
|
|
| 6363 |
}
|
| 6364 |
|
| 6365 |
.settings-dialog-header {
|
| 6366 |
+
@@ -1417,7 +1435,7 @@
|
| 6367 |
flex-shrink: 0;
|
| 6368 |
align-items: center;
|
| 6369 |
min-height: 50px;
|
|
|
|
| 6372 |
border-bottom: 1px solid var(--border);
|
| 6373 |
}
|
| 6374 |
|
| 6375 |
+
@@ -1467,7 +1485,7 @@
|
| 6376 |
width: 24px;
|
| 6377 |
height: 2px;
|
| 6378 |
border-radius: 2px 2px 0 0;
|
|
|
|
| 6381 |
content: "";
|
| 6382 |
opacity: 0;
|
| 6383 |
transform: translateX(-50%) scaleX(0.5);
|
| 6384 |
+
@@ -1494,7 +1512,7 @@
|
| 6385 |
}
|
| 6386 |
|
| 6387 |
.settings-section-tab:focus-visible:not([aria-current="page"]) {
|
|
|
|
| 6390 |
background: var(--bg-hover);
|
| 6391 |
color: var(--text);
|
| 6392 |
}
|
| 6393 |
+
@@ -1538,11 +1556,13 @@
|
| 6394 |
+
}
|
| 6395 |
+
|
| 6396 |
+
/* The page scrolls across the dialog's full width, so its scrollbar sits at the
|
| 6397 |
+
- dialog's edge; only the content keeps a readable column. */
|
| 6398 |
+
+ dialog's edge; only the content keeps a readable column. Its sides are the
|
| 6399 |
+
+ header's (16px), so the headings stand under "Settings": a 3vw side (28px on
|
| 6400 |
+
+ a desktop) once set them 12px in from the title and the other tabs' lists. */
|
| 6401 |
.settings-general {
|
| 6402 |
width: 100%;
|
| 6403 |
height: 100%;
|
| 6404 |
- padding: 26px clamp(18px, 4vw, 40px) 40px;
|
| 6405 |
+
+ padding: 18px 16px 28px;
|
| 6406 |
overflow-y: auto;
|
| 6407 |
}
|
| 6408 |
|
| 6409 |
+
@@ -1593,21 +1613,21 @@
|
| 6410 |
justify-content: center;
|
| 6411 |
gap: 7px;
|
| 6412 |
min-width: 0;
|
|
|
|
| 6433 |
}
|
| 6434 |
|
| 6435 |
.settings-theme-option:not(:has(input:checked)):hover {
|
| 6436 |
+
@@ -1615,8 +1635,9 @@
|
| 6437 |
+
}
|
| 6438 |
+
|
| 6439 |
+
.settings-theme-option:has(input:focus-visible) {
|
| 6440 |
+
- outline: 2px solid var(--accent);
|
| 6441 |
+
- outline-offset: 1px;
|
| 6442 |
+
+ outline: 1px solid var(--focus-line);
|
| 6443 |
+
+ outline-offset: -1px;
|
| 6444 |
+
+ box-shadow: var(--focus-glow);
|
| 6445 |
+
}
|
| 6446 |
+
|
| 6447 |
+
.settings-theme-option-label {
|
| 6448 |
+
@@ -1657,9 +1678,8 @@
|
| 6449 |
height: 26px;
|
| 6450 |
margin: 0;
|
| 6451 |
padding: 0 8px;
|
|
|
|
| 6457 |
color: var(--text);
|
| 6458 |
font-family: var(--font-ui);
|
| 6459 |
font-weight: var(--font-ui-weight);
|
| 6460 |
+
@@ -1676,8 +1696,9 @@
|
| 6461 |
+
}
|
| 6462 |
+
|
| 6463 |
+
.settings-font-input:focus-visible {
|
| 6464 |
+
- outline: 2px solid var(--accent);
|
| 6465 |
+
- outline-offset: 1px;
|
| 6466 |
+
+ outline: 1px solid var(--focus-line);
|
| 6467 |
+
+ outline-offset: -1px;
|
| 6468 |
+
+ box-shadow: var(--focus-glow);
|
| 6469 |
+
}
|
| 6470 |
+
|
| 6471 |
+
@media (max-width: 640px) {
|
| 6472 |
+
@@ -1722,8 +1743,9 @@
|
| 6473 |
|
| 6474 |
.settings-chat-range-header output {
|
| 6475 |
color: var(--text-muted);
|
|
|
|
| 6480 |
}
|
| 6481 |
|
| 6482 |
.settings-send-mode-options {
|
| 6483 |
+
@@ -1732,7 +1754,7 @@
|
| 6484 |
gap: 3px;
|
| 6485 |
padding: 3px;
|
| 6486 |
border: 1px solid var(--border);
|
|
|
|
| 6489 |
}
|
| 6490 |
|
| 6491 |
.settings-send-mode-option {
|
| 6492 |
+
@@ -1744,7 +1766,7 @@
|
| 6493 |
min-height: 26px;
|
| 6494 |
padding: 0 10px;
|
| 6495 |
border: 0;
|
|
|
|
| 6498 |
background: transparent;
|
| 6499 |
color: var(--text-muted);
|
| 6500 |
cursor: pointer;
|
| 6501 |
+
@@ -1754,8 +1776,8 @@
|
| 6502 |
|
| 6503 |
.settings-send-mode-option:has(input:checked) {
|
| 6504 |
background: var(--bg-selected);
|
|
|
|
| 6509 |
}
|
| 6510 |
|
| 6511 |
.settings-send-mode-option:not(:has(input:checked)):hover {
|
| 6512 |
+
@@ -1763,8 +1785,9 @@
|
| 6513 |
+
}
|
| 6514 |
+
|
| 6515 |
+
.settings-send-mode-option:has(input:focus-visible) {
|
| 6516 |
+
- outline: 2px solid var(--accent);
|
| 6517 |
+
- outline-offset: 1px;
|
| 6518 |
+
+ outline: 1px solid var(--focus-line);
|
| 6519 |
+
+ outline-offset: -1px;
|
| 6520 |
+
+ box-shadow: var(--focus-glow);
|
| 6521 |
+
}
|
| 6522 |
+
|
| 6523 |
+
.settings-send-mode-label {
|
| 6524 |
+
@@ -1781,7 +1804,7 @@
|
| 6525 |
display: block;
|
| 6526 |
width: 100%;
|
| 6527 |
margin-top: 2px;
|
|
|
|
| 6530 |
}
|
| 6531 |
|
| 6532 |
.settings-language-options {
|
| 6533 |
+
@@ -1799,7 +1822,7 @@
|
| 6534 |
height: 44px;
|
| 6535 |
padding: 0 10px;
|
| 6536 |
border: 0;
|
|
|
|
| 6539 |
background: transparent;
|
| 6540 |
color: var(--text);
|
| 6541 |
cursor: pointer;
|
| 6542 |
+
@@ -1857,7 +1880,7 @@
|
| 6543 |
max-width: 420px;
|
| 6544 |
min-height: 44px;
|
| 6545 |
padding: 0 10px;
|
|
|
|
| 6548 |
background: var(--bg-panel);
|
| 6549 |
color: var(--text);
|
| 6550 |
font-size: 12px;
|
| 6551 |
+
@@ -1923,7 +1946,7 @@
|
| 6552 |
margin-left: 14px;
|
| 6553 |
padding: 0 9px;
|
| 6554 |
border: 1px solid var(--border);
|
|
|
|
| 6557 |
background: var(--bg-panel);
|
| 6558 |
color: var(--text);
|
| 6559 |
font-size: 16px;
|
| 6560 |
+
@@ -2066,7 +2089,7 @@
|
| 6561 |
max-width: 100%;
|
| 6562 |
padding: 0 5px;
|
| 6563 |
border: 1px solid var(--border);
|
|
|
|
| 6566 |
background: var(--bg-panel);
|
| 6567 |
color: var(--text);
|
| 6568 |
font-family: var(--font-mono);
|
| 6569 |
+
@@ -2085,7 +2108,7 @@
|
| 6570 |
padding: 6px 8px;
|
| 6571 |
overflow: auto;
|
| 6572 |
border: 1px solid var(--border);
|
|
|
|
| 6575 |
background: var(--bg-panel);
|
| 6576 |
color: var(--text-muted);
|
| 6577 |
font-family: var(--font-mono);
|
| 6578 |
+
@@ -2172,9 +2195,8 @@
|
| 6579 |
min-width: 0;
|
| 6580 |
height: 32px;
|
| 6581 |
padding: 0 10px;
|
|
|
|
| 6587 |
color: var(--text);
|
| 6588 |
font-family: var(--font-mono);
|
| 6589 |
font-size: 12px;
|
| 6590 |
+
@@ -2266,10 +2288,9 @@ select.mcp-add-input {
|
| 6591 |
max-width: 100%;
|
| 6592 |
max-height: 100%;
|
| 6593 |
overflow: hidden;
|
|
|
|
| 6601 |
}
|
| 6602 |
|
| 6603 |
/* Focus moves to the dialog itself when it opens (tabIndex -1); it is not a control, so no ring. */
|
| 6604 |
+
@@ -2282,7 +2303,7 @@ select.mcp-add-input {
|
| 6605 |
flex: 1 1 auto;
|
| 6606 |
gap: 12px;
|
| 6607 |
min-height: 0;
|
|
|
|
| 6610 |
overflow: auto;
|
| 6611 |
overscroll-behavior: contain;
|
| 6612 |
}
|
| 6613 |
+
@@ -2315,7 +2336,7 @@ select.mcp-add-input {
|
| 6614 |
margin-top: 10px;
|
| 6615 |
padding: 8px 10px;
|
| 6616 |
border: 1px solid var(--border);
|
|
|
|
| 6619 |
background: var(--bg);
|
| 6620 |
color: var(--text);
|
| 6621 |
font-family: var(--font-mono);
|
| 6622 |
+
@@ -2333,7 +2354,7 @@ select.mcp-add-input {
|
| 6623 |
.project-trust-error {
|
| 6624 |
flex-shrink: 0;
|
| 6625 |
max-height: 30vh;
|
|
|
|
| 6628 |
overflow: auto;
|
| 6629 |
color: #ef4444;
|
| 6630 |
font-size: 12px;
|
| 6631 |
+
@@ -2353,19 +2374,20 @@ select.mcp-add-input {
|
| 6632 |
flex-shrink: 0;
|
| 6633 |
justify-content: flex-end;
|
| 6634 |
gap: 8px;
|
|
|
|
| 6656 |
}
|
| 6657 |
|
| 6658 |
.project-trust-button:disabled {
|
| 6659 |
+
@@ -2373,10 +2395,8 @@ select.mcp-add-input {
|
| 6660 |
}
|
| 6661 |
|
| 6662 |
.project-trust-button.is-primary {
|
|
|
|
| 6669 |
}
|
| 6670 |
|
| 6671 |
.project-trust-button.is-primary:disabled {
|
| 6672 |
+
@@ -2450,7 +2470,7 @@ select.mcp-add-input {
|
| 6673 |
min-width: 0;
|
| 6674 |
padding: 8px 10px;
|
| 6675 |
border: 1px solid var(--border);
|
|
|
|
| 6678 |
background: var(--bg);
|
| 6679 |
}
|
| 6680 |
|
| 6681 |
+
@@ -2472,7 +2492,7 @@ select.mcp-add-input {
|
| 6682 |
.project-trust-mcp-tag {
|
| 6683 |
flex-shrink: 0;
|
| 6684 |
padding: 1px 5px;
|
|
|
|
| 6687 |
background: rgba(120, 120, 120, 0.12);
|
| 6688 |
color: var(--text-dim);
|
| 6689 |
font-size: 10px;
|
| 6690 |
+
@@ -2493,7 +2513,7 @@ select.mcp-add-input {
|
| 6691 |
display: inline-block;
|
| 6692 |
margin: 2px 4px 0 0;
|
| 6693 |
padding: 0 4px;
|
|
|
|
| 6698 |
font-family: var(--font-mono);
|
| 6699 |
diff --git a/app/shell.css b/app/shell.css
|
| 6700 |
new file mode 100644
|
| 6701 |
+
index 0000000..a3dc745
|
| 6702 |
--- /dev/null
|
| 6703 |
+++ b/app/shell.css
|
| 6704 |
@@ -0,0 +1,720 @@
|
|
|
|
| 7239 |
+ color: var(--text);
|
| 7240 |
+ font: inherit;
|
| 7241 |
+}
|
| 7242 |
+
+.review-comment-input:focus { box-shadow: inset 0 0 0 1px var(--focus-line), var(--focus-glow); }
|
| 7243 |
+.review-comment-actions { display: flex; align-items: center; justify-content: flex-end; gap: 4px; }
|
| 7244 |
+.review-comment-hint { flex: 1 1 auto; color: var(--text-dim); font-size: 11.5px; }
|
| 7245 |
+
|
|
|
|
| 7283 |
+ font: inherit;
|
| 7284 |
+ font-size: 12.5px;
|
| 7285 |
+}
|
| 7286 |
+
+.browser-address input:focus { box-shadow: inset 0 0 0 1px var(--focus-line), var(--focus-glow); }
|
| 7287 |
+.browser-error-count { color: var(--danger); font-size: 11.5px; font-variant-numeric: tabular-nums; }
|
| 7288 |
+.browser-tabs {
|
| 7289 |
+ display: flex;
|
|
|
|
| 7354 |
+ background: #fff;
|
| 7355 |
+ cursor: default;
|
| 7356 |
+}
|
| 7357 |
+
+.browser-canvas:focus-visible { box-shadow: inset 0 0 0 1px var(--focus-line); }
|
| 7358 |
+.browser-canvas.is-picking { cursor: crosshair; }
|
| 7359 |
+.browser-agent-pill, .browser-picking-hint {
|
| 7360 |
+ position: absolute;
|
|
|
|
| 7423 |
+.browser-console-text { flex: 1 1 auto; min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
|
| 7424 |
+.browser-console-location { flex: none; max-width: 40%; overflow: hidden; color: var(--text-dim); text-overflow: ellipsis; white-space: nowrap; direction: rtl; }
|
| 7425 |
diff --git a/app/sidebar-menu.css b/app/sidebar-menu.css
|
| 7426 |
+
index 737e7a5..c098317 100644
|
| 7427 |
--- a/app/sidebar-menu.css
|
| 7428 |
+++ b/app/sidebar-menu.css
|
| 7429 |
@@ -19,13 +19,14 @@
|
|
|
|
| 7913 |
font-size: 15px;
|
| 7914 |
}
|
| 7915 |
|
| 7916 |
+
@@ -562,8 +472,9 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 7917 |
+
}
|
| 7918 |
+
|
| 7919 |
+
.sidebar-sheet-cancel:focus-visible {
|
| 7920 |
+
- outline: 2px solid var(--accent);
|
| 7921 |
+
- outline-offset: -2px;
|
| 7922 |
+
+ outline: 1px solid var(--focus-line);
|
| 7923 |
+
+ outline-offset: -1px;
|
| 7924 |
+
+ box-shadow: var(--focus-glow);
|
| 7925 |
+
}
|
| 7926 |
+
|
| 7927 |
+
/* Undo toast: in place at the bottom of the sidebar root (position: relative). */
|
| 7928 |
+
@@ -583,11 +494,10 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 7929 |
height: 36px;
|
| 7930 |
padding: 0 4px 0 12px;
|
| 7931 |
box-sizing: border-box;
|
|
|
|
| 7940 |
font-size: 12px;
|
| 7941 |
pointer-events: auto;
|
| 7942 |
animation: sidebar-toast-in 0.16s ease-out;
|
| 7943 |
+
@@ -634,7 +544,7 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 7944 |
height: 26px;
|
| 7945 |
padding: 0 7px;
|
| 7946 |
border: 0;
|
|
|
|
| 7949 |
background: transparent;
|
| 7950 |
color: var(--accent);
|
| 7951 |
font: inherit;
|
| 7952 |
+
@@ -657,7 +567,7 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 7953 |
height: 24px;
|
| 7954 |
padding: 0;
|
| 7955 |
border: 0;
|
|
|
|
| 7958 |
background: transparent;
|
| 7959 |
color: var(--text-dim);
|
| 7960 |
cursor: pointer;
|
| 7961 |
+
@@ -670,8 +580,9 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 7962 |
+
|
| 7963 |
+
.sidebar-toast-action:focus-visible,
|
| 7964 |
+
.sidebar-toast-dismiss:focus-visible {
|
| 7965 |
+
- outline: 2px solid var(--accent);
|
| 7966 |
+
- outline-offset: -2px;
|
| 7967 |
+
+ outline: 1px solid var(--focus-line);
|
| 7968 |
+
+ outline-offset: -1px;
|
| 7969 |
+
+ box-shadow: var(--focus-glow);
|
| 7970 |
+
}
|
| 7971 |
+
|
| 7972 |
+
@media (pointer: coarse) {
|
| 7973 |
+
@@ -716,23 +627,23 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 7974 |
/* A worktree menu's "New worktree…" form (a custom menu body; components/WorktreeCreateForm.tsx),
|
| 7975 |
and its removal body. */
|
| 7976 |
.sidebar-worktree-form {
|
|
|
|
| 8000 |
user-select: text;
|
| 8001 |
-webkit-user-select: text;
|
| 8002 |
}
|
| 8003 |
+
@@ -747,33 +658,31 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 8004 |
.sidebar-worktree-force,
|
| 8005 |
.sidebar-worktree-cancel {
|
| 8006 |
flex: 1;
|
|
|
|
| 8046 |
}
|
| 8047 |
|
| 8048 |
.sidebar-worktree-create:disabled,
|
| 8049 |
+
@@ -785,28 +694,28 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 8050 |
+
.sidebar-worktree-create:focus-visible,
|
| 8051 |
+
.sidebar-worktree-force:focus-visible,
|
| 8052 |
+
.sidebar-worktree-cancel:focus-visible {
|
| 8053 |
+
- outline: 2px solid var(--accent);
|
| 8054 |
+
- outline-offset: 1px;
|
| 8055 |
+
+ outline: 1px solid var(--focus-line);
|
| 8056 |
+
+ outline-offset: -1px;
|
| 8057 |
+
+ box-shadow: var(--focus-glow);
|
| 8058 |
+
}
|
| 8059 |
|
| 8060 |
/* A worktree menu's removal body (components/ProjectWorktreePicker.tsx): what Force would do. */
|
| 8061 |
.sidebar-worktree-message {
|
|
|
|
| 8082 |
}
|
| 8083 |
|
| 8084 |
.sidebar-sheet .sidebar-worktree-input,
|
| 8085 |
+
@@ -820,19 +729,18 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 8086 |
/* A project menu's "Delete all sessions" question (a custom menu body;
|
| 8087 |
components/SessionSidebar.tsx): what goes, then Delete and Cancel. */
|
| 8088 |
.sidebar-menu-question {
|
|
|
|
| 8106 |
line-height: 1.4;
|
| 8107 |
}
|
| 8108 |
|
| 8109 |
+
@@ -846,26 +754,25 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 8110 |
.sidebar-menu-question-cancel {
|
| 8111 |
flex: 1;
|
| 8112 |
min-width: 0;
|
|
|
|
| 8142 |
}
|
| 8143 |
|
| 8144 |
.sidebar-menu-question-confirm:disabled {
|
| 8145 |
+
@@ -875,12 +782,13 @@ html[data-keyboard-open] .sidebar-sheet {
|
| 8146 |
+
|
| 8147 |
+
.sidebar-menu-question-confirm:focus-visible,
|
| 8148 |
+
.sidebar-menu-question-cancel:focus-visible {
|
| 8149 |
+
- outline: 2px solid var(--accent);
|
| 8150 |
+
- outline-offset: 1px;
|
| 8151 |
+
+ outline: 1px solid var(--focus-line);
|
| 8152 |
+
+ outline-offset: -1px;
|
| 8153 |
+
+ box-shadow: var(--focus-glow);
|
| 8154 |
}
|
| 8155 |
|
| 8156 |
.sidebar-sheet .sidebar-menu-question {
|
|
|
|
| 8160 |
|
| 8161 |
.sidebar-sheet .sidebar-menu-question-text {
|
| 8162 |
diff --git a/app/sidebar.css b/app/sidebar.css
|
| 8163 |
+
index 86728a2..e2f5bba 100644
|
| 8164 |
--- a/app/sidebar.css
|
| 8165 |
+++ b/app/sidebar.css
|
| 8166 |
+
@@ -91,8 +91,9 @@
|
| 8167 |
|
| 8168 |
.session-tree button:focus-visible,
|
| 8169 |
.session-tree a.session-tree-main:focus-visible {
|
| 8170 |
- outline: 2px solid var(--accent);
|
| 8171 |
+
- outline-offset: -2px;
|
| 8172 |
+
+ outline: 1px solid var(--focus-line);
|
| 8173 |
+
+ outline-offset: -1px;
|
| 8174 |
+
+ box-shadow: var(--focus-glow);
|
| 8175 |
+
}
|
| 8176 |
+
|
| 8177 |
+
/*
|
| 8178 |
+
@@ -146,10 +147,9 @@
|
| 8179 |
+
color: var(--text);
|
| 8180 |
+
}
|
| 8181 |
+
|
| 8182 |
+
+/* Quiet and in sentence case, as every section label is (no small bold capitals). */
|
| 8183 |
+
.session-tree-pinned-label {
|
| 8184 |
+
- font-weight: 600;
|
| 8185 |
+
- letter-spacing: 0.05em;
|
| 8186 |
+
- text-transform: uppercase;
|
| 8187 |
+
+ font-weight: 400;
|
| 8188 |
}
|
| 8189 |
|
| 8190 |
+
.session-tree-pinned-count {
|
| 8191 |
@@ -171,20 +171,22 @@
|
| 8192 |
}
|
| 8193 |
|
|
|
|
| 8690 |
}
|
| 8691 |
|
| 8692 |
.sidebar-brand:focus {
|
| 8693 |
+
@@ -1064,8 +1090,10 @@ a.session-tree-main {
|
| 8694 |
}
|
| 8695 |
|
| 8696 |
.sidebar-brand:focus-visible {
|
| 8697 |
- outline: 2px solid var(--accent);
|
| 8698 |
- outline-offset: 1px;
|
| 8699 |
+
+ outline: 1px solid var(--focus-line);
|
| 8700 |
+
+ outline-offset: -1px;
|
| 8701 |
+
+ box-shadow: var(--focus-glow);
|
| 8702 |
+ outline-offset: 0;
|
| 8703 |
}
|
| 8704 |
|
| 8705 |
.sidebar-header-spacer {
|
| 8706 |
+
@@ -1078,7 +1106,7 @@ a.session-tree-main {
|
| 8707 |
}
|
| 8708 |
|
| 8709 |
.sidebar-search-toggle {
|
|
|
|
| 8712 |
padding: 0;
|
| 8713 |
}
|
| 8714 |
|
| 8715 |
+
@@ -1093,7 +1121,7 @@ a.session-tree-main {
|
| 8716 |
label is still each one's name. */
|
| 8717 |
.sidebar-header[data-fit="1"] .sidebar-new-button,
|
| 8718 |
.sidebar-header[data-fit="2"] .sidebar-new-button {
|
|
|
|
| 8721 |
padding: 0;
|
| 8722 |
}
|
| 8723 |
|
| 8724 |
+
@@ -1105,6 +1133,11 @@ a.session-tree-main {
|
| 8725 |
font-size: 11px;
|
| 8726 |
}
|
| 8727 |
|
|
|
|
| 8733 |
.sidebar-header[data-fit="1"] .sidebar-new-label,
|
| 8734 |
.sidebar-header[data-fit="2"] .sidebar-new-label,
|
| 8735 |
.sidebar-header[data-fit="2"] .sidebar-tab-label {
|
| 8736 |
+
@@ -1122,8 +1155,9 @@ a.session-tree-main {
|
| 8737 |
+
.sidebar-archive-back:focus-visible,
|
| 8738 |
+
.sidebar-tool-button:focus-visible,
|
| 8739 |
+
.sidebar-files-section-toggle:focus-visible {
|
| 8740 |
+
- outline: 2px solid var(--accent);
|
| 8741 |
+
- outline-offset: -2px;
|
| 8742 |
+
+ outline: 1px solid var(--focus-line);
|
| 8743 |
+
+ outline-offset: -1px;
|
| 8744 |
+
+ box-shadow: var(--focus-glow);
|
| 8745 |
+
}
|
| 8746 |
+
|
| 8747 |
+
.sidebar-panel {
|
| 8748 |
+
@@ -1202,7 +1236,7 @@ a.session-tree-main {
|
| 8749 |
the root too), and its time 4px inside the row. The header row's keys and
|
| 8750 |
the picker's boxes end there. */
|
| 8751 |
.session-sidebar.is-files-below {
|
|
|
|
| 8754 |
}
|
| 8755 |
|
| 8756 |
/* The files section's header row (files below the sessions only), one row
|
| 8757 |
+
@@ -1246,7 +1280,7 @@ a.session-tree-main {
|
| 8758 |
padding: 0 5px;
|
| 8759 |
overflow: hidden;
|
| 8760 |
border: 0;
|
|
|
|
| 8763 |
background: transparent;
|
| 8764 |
color: var(--text-muted);
|
| 8765 |
font: inherit;
|
| 8766 |
+
@@ -1272,10 +1306,8 @@ a.session-tree-main {
|
| 8767 |
+
.sidebar-files-section-label {
|
| 8768 |
+
min-width: 0;
|
| 8769 |
+
overflow: hidden;
|
| 8770 |
+
- font-weight: 600;
|
| 8771 |
+
- letter-spacing: 0.05em;
|
| 8772 |
+
+ font-weight: 400;
|
| 8773 |
+
text-overflow: ellipsis;
|
| 8774 |
+
- text-transform: uppercase;
|
| 8775 |
+
}
|
| 8776 |
+
|
| 8777 |
+
/* The changed files' count, as the pinned section's (.session-tree-pinned-count). */
|
| 8778 |
+
@@ -1304,7 +1336,7 @@ a.session-tree-main {
|
| 8779 |
min-width: 18px;
|
| 8780 |
max-width: 26px;
|
| 8781 |
height: 26px;
|
|
|
|
| 8784 |
}
|
| 8785 |
|
| 8786 |
/* Under that row (or the whole files tab): the head, then the tree filling
|
| 8787 |
+
@@ -1329,16 +1361,17 @@ a.session-tree-main {
|
| 8788 |
height: 29px;
|
| 8789 |
padding: 0 10px;
|
| 8790 |
box-sizing: border-box;
|
|
|
|
| 8801 |
-.sidebar-search-input:focus {
|
| 8802 |
- outline: 2px solid var(--accent);
|
| 8803 |
+.sidebar-search-input:focus-visible {
|
| 8804 |
+
+ outline: 1px solid var(--focus-line);
|
| 8805 |
+
+ outline-offset: -1px;
|
| 8806 |
+
+ box-shadow: var(--focus-glow);
|
| 8807 |
}
|
| 8808 |
|
| 8809 |
/* The tree and the archive view under the search, in one cell: the archive
|
| 8810 |
+
@@ -1413,7 +1446,7 @@ a.session-tree-main {
|
| 8811 |
height: 26px;
|
| 8812 |
padding: 0 6px;
|
| 8813 |
border: 0;
|
|
|
|
| 8816 |
background: transparent;
|
| 8817 |
color: var(--text-muted);
|
| 8818 |
font-size: 12px;
|
| 8819 |
+
@@ -1502,7 +1535,7 @@ a.session-tree-main {
|
| 8820 |
height: 32px;
|
| 8821 |
padding: 0;
|
| 8822 |
border: 0;
|
|
|
|
| 8827 |
cursor: pointer;
|
| 8828 |
diff --git a/app/ui.css b/app/ui.css
|
| 8829 |
new file mode 100644
|
| 8830 |
+
index 0000000..b4b8a1d
|
| 8831 |
--- /dev/null
|
| 8832 |
+++ b/app/ui.css
|
| 8833 |
@@ -0,0 +1,634 @@
|
|
|
|
| 9053 |
+ white-space: nowrap;
|
| 9054 |
+ cursor: pointer;
|
| 9055 |
+}
|
| 9056 |
+
+.ui-dropdown-row:focus-visible { outline: none; box-shadow: none; }
|
| 9057 |
+.ui-dropdown-row[aria-selected="true"] { color: var(--text-strong); }
|
| 9058 |
+.ui-dropdown-row.has-gutter { padding-right: calc(var(--popup-row-pad) + 28px); }
|
| 9059 |
+.ui-dropdown-icon { display: inline-flex; flex: none; align-items: center; justify-content: center; width: var(--popup-icon); height: var(--popup-icon); color: var(--text-muted); }
|
|
|
|
| 9613 |
- assert.deepEqual(saved, { tabs: [{ ...tab, restored: true }], activeId: null, open: false });
|
| 9614 |
-});
|
| 9615 |
diff --git a/components/AppShell.tsx b/components/AppShell.tsx
|
| 9616 |
+
index c8c4ba9..51d811c 100644
|
| 9617 |
--- a/components/AppShell.tsx
|
| 9618 |
+++ b/components/AppShell.tsx
|
| 9619 |
@@ -3,6 +3,8 @@
|
|
|
|
| 11346 |
<div style={{ display: "grid", gridTemplateColumns: "auto minmax(0, 1fr) auto", columnGap: 12, rowGap: 8, alignItems: "start" }}>
|
| 11347 |
{sessionRows.map((row) => (
|
| 11348 |
<div key={`session-info:${row.label}`} style={{ display: "contents" }}>
|
| 11349 |
+
@@ -2468,6 +2209,8 @@ export function AppShell() {
|
| 11350 |
+
overflowWrap: "anywhere",
|
| 11351 |
+
wordBreak: "break-word",
|
| 11352 |
+
whiteSpace: "normal",
|
| 11353 |
+
+ // Paths, the ID and the branch are code; a name or a duration is not.
|
| 11354 |
+
+ fontFamily: row.copyField ? "var(--font-mono)" : undefined,
|
| 11355 |
+
}}>{row.value}</div>
|
| 11356 |
+
<div>{row.copyField ? copyButton(row.copyField, row.value) : null}</div>
|
| 11357 |
+
</div>
|
| 11358 |
+
@@ -2477,7 +2220,7 @@ export function AppShell() {
|
| 11359 |
);
|
| 11360 |
const projectInfoSection = projectRows.length > 0 ? (
|
| 11361 |
<div style={{ minWidth: 0 }}>
|
|
|
|
| 11364 |
<div style={{ display: "grid", gridTemplateColumns: "auto minmax(0, 1fr) auto", columnGap: 12, rowGap: 8, alignItems: "start" }}>
|
| 11365 |
{projectRows.map((row) => (
|
| 11366 |
<div key={`project-info:${row.label}`} style={{ display: "contents" }}>
|
| 11367 |
+
@@ -2488,6 +2231,8 @@ export function AppShell() {
|
| 11368 |
+
overflowWrap: "anywhere",
|
| 11369 |
+
wordBreak: "break-word",
|
| 11370 |
+
whiteSpace: "normal",
|
| 11371 |
+
+ // Paths, the ID and the branch are code; a name or a duration is not.
|
| 11372 |
+
+ fontFamily: row.copyField ? "var(--font-mono)" : undefined,
|
| 11373 |
+
}}>{row.value}</div>
|
| 11374 |
+
<div>{row.copyField ? copyButton(row.copyField, row.value) : null}</div>
|
| 11375 |
+
</div>
|
| 11376 |
+
@@ -2505,13 +2250,13 @@ export function AppShell() {
|
| 11377 |
+
gap: isMobile ? 16 : 24,
|
| 11378 |
+
fontSize: 12,
|
| 11379 |
+
lineHeight: 1.5,
|
| 11380 |
+
- fontFamily: "var(--font-mono)",
|
| 11381 |
+
+ fontVariantNumeric: "tabular-nums",
|
| 11382 |
+
}}>
|
| 11383 |
+
<div style={{ display: "flex", flexDirection: "column", gap: isMobile ? 16 : 20 }}>
|
| 11384 |
+
{sessionInfoSection}
|
| 11385 |
+
{projectInfoSection}
|
| 11386 |
+
</div>
|
| 11387 |
+
- {section(translate("session.messages"), messageRows)}
|
| 11388 |
+
+ {section(translate("session.messages"), messageRows, "right", true)}
|
| 11389 |
+
{section(translate("session.tokens"), [...tokenRows, ...extraTokenRows], "right", true)}
|
| 11390 |
+
</div>
|
| 11391 |
+
);
|
| 11392 |
+
@@ -2529,8 +2274,14 @@ export function AppShell() {
|
| 11393 |
{isMobile && renderProjectTrustWarning(true)}
|
| 11394 |
</div>
|
| 11395 |
|
|
|
|
| 11406 |
{showChat ? (
|
| 11407 |
<ChatWindow
|
| 11408 |
key={sessionKey}
|
| 11409 |
+
@@ -2568,7 +2319,6 @@ export function AppShell() {
|
| 11410 |
initialPrompt={pendingQuotePrompt?.sessionId === selectedSession?.id ? pendingQuotePrompt?.text : undefined}
|
| 11411 |
onInitialPromptConsumed={() => setPendingQuotePrompt(null)}
|
| 11412 |
soundEnabled={soundEnabled}
|
|
|
|
| 11414 |
playDoneSound={playDoneSound}
|
| 11415 |
unlockAudio={unlockAudio}
|
| 11416 |
holdAudio={holdAudio}
|
| 11417 |
+
@@ -2601,9 +2351,7 @@ export function AppShell() {
|
| 11418 |
</div>
|
| 11419 |
) : (
|
| 11420 |
<div style={{ position: "absolute", top: 12, left: 12, display: "flex", alignItems: "flex-start", gap: 8, userSelect: "none", pointerEvents: "none" }}>
|
|
|
|
| 11425 |
<div>
|
| 11426 |
<div style={{ fontSize: 18, fontWeight: 600, color: "var(--text)", marginBottom: 8 }}>{translate("workspace.getStarted")}</div>
|
| 11427 |
<div style={{ fontSize: 12, color: "var(--text-muted)", lineHeight: 1.8 }}>
|
| 11428 |
+
@@ -2614,146 +2362,15 @@ export function AppShell() {
|
| 11429 |
</div>
|
| 11430 |
)
|
| 11431 |
) : null}
|
|
|
|
| 11579 |
</div>
|
| 11580 |
</div>
|
| 11581 |
{settingsSection && (
|
| 11582 |
+
@@ -2763,6 +2380,8 @@ export function AppShell() {
|
| 11583 |
initialSection={settingsSection}
|
| 11584 |
quoteSelectionEnabled={quoteSelectionEnabled}
|
| 11585 |
onQuoteSelectionChange={handleQuoteSelectionChange}
|
|
|
|
| 11588 |
onClose={() => {
|
| 11589 |
setSettingsSection(null);
|
| 11590 |
setModelsRefreshKey((key) => key + 1);
|
| 11591 |
+
@@ -2786,6 +2405,6 @@ export function AppShell() {
|
| 11592 |
onStatus={setProjectTrust}
|
| 11593 |
/>
|
| 11594 |
)}
|
|
|
|
| 21190 |
onSelect={() => choose(option)}
|
| 21191 |
star={onSetDefault ? {
|
| 21192 |
diff --git a/components/ModelsConfig.tsx b/components/ModelsConfig.tsx
|
| 21193 |
+
index 9f6b556..c1f7dd6 100644
|
| 21194 |
--- a/components/ModelsConfig.tsx
|
| 21195 |
+++ b/components/ModelsConfig.tsx
|
| 21196 |
@@ -54,6 +54,8 @@ import { providerBadgeLabel } from "./enabled-models-helpers";
|
|
|
|
| 21370 |
background: "var(--bg-panel)",
|
| 21371 |
color: !model.id.trim() || catalogState.phase === "loading" ? "var(--text-dim)" : "var(--text-muted)",
|
| 21372 |
cursor: !model.id.trim() || catalogState.phase === "loading" ? "not-allowed" : "pointer",
|
| 21373 |
+
@@ -1175,7 +1168,7 @@ function ModelDetail({
|
| 21374 |
+
</div>
|
| 21375 |
+
|
| 21376 |
+
<div style={{ marginTop: 16 }}>
|
| 21377 |
+
- <div style={{ fontSize: 10, color: "var(--text-dim)", fontWeight: 600, textTransform: "uppercase" }}>
|
| 21378 |
+
+ <div style={{ fontSize: 12, color: "var(--text-dim)", fontWeight: 400 }}>
|
| 21379 |
+
{t("models.costPerMillion")}
|
| 21380 |
+
</div>
|
| 21381 |
+
{costEditing ? (
|
| 21382 |
@@ -1227,20 +1220,7 @@ function ModelDetail({
|
| 21383 |
{advancedSummary}
|
| 21384 |
</span>
|
|
|
|
| 21463 |
<input
|
| 21464 |
ref={inputRef}
|
| 21465 |
value={search}
|
| 21466 |
+
@@ -1769,7 +1745,7 @@ function AddProviderPicker({
|
| 21467 |
+
) : (
|
| 21468 |
+
<div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(min(240px, 100%), 1fr))", gap: 8 }}>
|
| 21469 |
+
{showCustom && (
|
| 21470 |
+
- <div style={{ gridColumn: "1 / -1", fontSize: 10, fontWeight: 600, color: "var(--text-dim)", textTransform: "uppercase", letterSpacing: "0.07em" }}>{t("i18n.custom")}</div>
|
| 21471 |
+
+ <div style={{ gridColumn: "1 / -1", fontSize: 12, fontWeight: 400, color: "var(--text-dim)" }}>{t("i18n.custom")}</div>
|
| 21472 |
+
)}
|
| 21473 |
+
{showCustom && (
|
| 21474 |
+
<button
|
| 21475 |
+
@@ -1782,16 +1758,14 @@ function AddProviderPicker({
|
| 21476 |
<div style={{ fontSize: 12, fontWeight: 600, color: "var(--text)", lineHeight: 1.3, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>OpenAI / Anthropic compatible</div>
|
| 21477 |
<div style={{ fontSize: 10, color: "var(--text-dim)", marginTop: 2 }}>{t("i18n.customEndpoint")}</div>
|
| 21478 |
</div>
|
|
|
|
| 21485 |
</span>
|
| 21486 |
</button>
|
| 21487 |
)}
|
| 21488 |
+
|
| 21489 |
+
{availableOAuth.length > 0 && (
|
| 21490 |
+
- <div style={{ gridColumn: "1 / -1", paddingTop: showCustom ? 6 : 0, fontSize: 10, fontWeight: 600, color: "var(--text-dim)", textTransform: "uppercase", letterSpacing: "0.07em" }}>{t("i18n.subscriptions")}</div>
|
| 21491 |
+
+ <div style={{ gridColumn: "1 / -1", paddingTop: showCustom ? 6 : 0, fontSize: 12, fontWeight: 400, color: "var(--text-dim)" }}>{t("i18n.subscriptions")}</div>
|
| 21492 |
+
)}
|
| 21493 |
+
{availableOAuth.map((p) => (
|
| 21494 |
+
<button key={p.id} onClick={() => { onSelectOAuth(p.id); onClose(); }}
|
| 21495 |
+
@@ -1808,7 +1782,7 @@ function AddProviderPicker({
|
| 21496 |
+
))}
|
| 21497 |
+
|
| 21498 |
+
{availableApiKey.length > 0 && (
|
| 21499 |
+
- <div style={{ gridColumn: "1 / -1", paddingTop: availableOAuth.length > 0 ? 6 : 0, fontSize: 10, fontWeight: 600, color: "var(--text-dim)", textTransform: "uppercase", letterSpacing: "0.07em" }}>API Key</div>
|
| 21500 |
+
+ <div style={{ gridColumn: "1 / -1", paddingTop: availableOAuth.length > 0 ? 6 : 0, fontSize: 12, fontWeight: 400, color: "var(--text-dim)" }}>API key</div>
|
| 21501 |
+
)}
|
| 21502 |
+
{availableApiKey.map((p) => (
|
| 21503 |
+
<button key={p.id} onClick={() => { onSelectApiKey(p.id); onClose(); }}
|
| 21504 |
@@ -2177,13 +2151,7 @@ export function ModelsConfig({ onClose, embedded = false, cwd = null }: {
|
| 21505 |
onClick={() => setSelection({ type: "provider", name: pName })}
|
| 21506 |
active={isProviderSelected}
|
|
|
|
| 21754 |
);
|
| 21755 |
}
|
| 21756 |
diff --git a/components/PluginsConfig.tsx b/components/PluginsConfig.tsx
|
| 21757 |
+
index 83fddc9..5926818 100644
|
| 21758 |
--- a/components/PluginsConfig.tsx
|
| 21759 |
+++ b/components/PluginsConfig.tsx
|
| 21760 |
@@ -1,5 +1,6 @@
|
|
|
|
| 21764 |
import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
| 21765 |
import { sendAgentCommand } from "@/lib/agent-client";
|
| 21766 |
import type {
|
| 21767 |
+
@@ -197,10 +198,9 @@ function ResourceList({ pkg }: { pkg: PluginPackageInfo }) {
|
| 21768 |
+
>
|
| 21769 |
+
<div
|
| 21770 |
+
style={{
|
| 21771 |
+
- fontSize: 10,
|
| 21772 |
+
- fontWeight: 700,
|
| 21773 |
+
+ fontSize: 12,
|
| 21774 |
+
+ fontWeight: 400,
|
| 21775 |
+
color: "var(--text-dim)",
|
| 21776 |
+
- textTransform: "uppercase",
|
| 21777 |
+
marginBottom: 6,
|
| 21778 |
+
}}
|
| 21779 |
+
>
|
| 21780 |
+
@@ -275,14 +275,7 @@ function AddPluginPanel({
|
| 21781 |
href: "https://pi.dev/packages",
|
| 21782 |
label: "pi.dev/packages",
|
| 21783 |
icon: (
|
|
|
|
| 21793 |
),
|
| 21794 |
}]}
|
| 21795 |
target={
|
| 21796 |
+
@@ -370,7 +363,7 @@ function PackageDetail({
|
| 21797 |
style={{
|
| 21798 |
fontSize: 10,
|
| 21799 |
padding: "1px 5px",
|
|
|
|
| 21802 |
background: "rgba(120,120,120,0.12)",
|
| 21803 |
color: "var(--text-dim)",
|
| 21804 |
}}
|
| 21805 |
+
@@ -382,7 +375,7 @@ function PackageDetail({
|
| 21806 |
style={{
|
| 21807 |
fontSize: 10,
|
| 21808 |
padding: "1px 5px",
|
|
|
|
| 26002 |
+});
|
| 26003 |
diff --git a/components/highlighting.ts b/components/highlighting.ts
|
| 26004 |
new file mode 100644
|
| 26005 |
+
index 0000000..773b858
|
| 26006 |
--- /dev/null
|
| 26007 |
+++ b/components/highlighting.ts
|
| 26008 |
@@ -0,0 +1,157 @@
|
|
|
|
| 26087 |
+[data-separator=line-info-basic] { height: 24px; }
|
| 26088 |
+[data-separator-content] { font-size: 12px; }
|
| 26089 |
+[data-expand-index] [data-separator-wrapper] { grid-template-columns: 28px auto; }
|
| 26090 |
+
+[data-expand-button]:focus-visible { outline: 1px solid var(--focus-line); outline-offset: -1px; box-shadow: var(--focus-glow); }
|
| 26091 |
+`;
|
| 26092 |
+
|
| 26093 |
+// The library's expand controls are role=button divs out of the tab order: give them a place in
|
|
|
|
| 34252 |
- };
|
| 34253 |
-}
|
| 34254 |
diff --git a/lib/i18n/messages/en.ts b/lib/i18n/messages/en.ts
|
| 34255 |
+
index cd39a31..078f061 100644
|
| 34256 |
--- a/lib/i18n/messages/en.ts
|
| 34257 |
+++ b/lib/i18n/messages/en.ts
|
| 34258 |
@@ -22,8 +22,8 @@ export const enLocale: LocalePlugin = {
|
|
|
|
| 34293 |
"subagent.tabLabel": "Sub-agent {name}",
|
| 34294 |
"subagent.refresh": "Refresh",
|
| 34295 |
"subagent.viewer.starting": "Sub-agent session is starting…",
|
| 34296 |
+
@@ -227,18 +227,18 @@ export const enLocale: LocalePlugin = {
|
| 34297 |
+
"tools.guidelines": "Prompt guidelines",
|
| 34298 |
+
"session.info": "Session info",
|
| 34299 |
+
"session.name": "Name",
|
| 34300 |
+
- "session.file": "Session File",
|
| 34301 |
+
+ "session.file": "Session file",
|
| 34302 |
+
"session.inMemory": "In-memory",
|
| 34303 |
+
"session.id": "ID",
|
| 34304 |
+
"session.user": "User",
|
| 34305 |
+
"session.assistant": "Assistant",
|
| 34306 |
+
- "session.toolCalls": "Tool Calls",
|
| 34307 |
+
- "session.toolResults": "Tool Results",
|
| 34308 |
+
+ "session.toolCalls": "Tool calls",
|
| 34309 |
+
+ "session.toolResults": "Tool results",
|
| 34310 |
+
"session.total": "Total",
|
| 34311 |
+
"session.input": "Input",
|
| 34312 |
+
"session.output": "Output",
|
| 34313 |
+
- "session.cacheRead": "Cache Read",
|
| 34314 |
+
- "session.cacheWrite": "Cache Write",
|
| 34315 |
+
+ "session.cacheRead": "Cache read",
|
| 34316 |
+
+ "session.cacheWrite": "Cache write",
|
| 34317 |
+
"session.cost": "Cost",
|
| 34318 |
+
"session.context": "Context",
|
| 34319 |
+
"session.cacheHitRate": "Avg cache hit rate",
|
| 34320 |
+
@@ -246,15 +246,15 @@ export const enLocale: LocalePlugin = {
|
| 34321 |
"session.copied": "Copied",
|
| 34322 |
"session.title": "Session info",
|
| 34323 |
"session.load": "Send a message or run /session to load session info",
|
|
|
|
| 34327 |
+ "session.projectSection": "Project info",
|
| 34328 |
"session.messages": "Messages",
|
| 34329 |
"session.tokens": "Tokens",
|
| 34330 |
+
- "session.totalActive": "Active Time",
|
| 34331 |
+
+ "session.totalActive": "Active time",
|
| 34332 |
+
"session.copyFile": "Copy file path",
|
| 34333 |
+
"session.copyId": "Copy session ID",
|
| 34334 |
+
- "session.projectDir": "Project Dir",
|
| 34335 |
+
- "session.gitBranch": "Git Branch",
|
| 34336 |
+
+ "session.projectDir": "Project folder",
|
| 34337 |
+
+ "session.gitBranch": "Git branch",
|
| 34338 |
+
"session.gitWorktree": "Worktree",
|
| 34339 |
+
"session.copyProjectDir": "Copy project directory",
|
| 34340 |
+
"session.copyGitBranch": "Copy git branch",
|
| 34341 |
@@ -269,13 +269,9 @@ export const enLocale: LocalePlugin = {
|
| 34342 |
"workspace.stepModels": "Open Settings at the bottom, then choose Models",
|
| 34343 |
"workspace.newSessionContext": "New session location",
|