@youtyan/code-viewer 0.11.2 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/web/index.html CHANGED
@@ -31,6 +31,7 @@
31
31
  <a class="app-menu-item active" data-route="repo" href="/">Repository</a>
32
32
  <a class="app-menu-item" data-route="diff" href="/todif?from=HEAD&to=worktree">Diff Viewer</a>
33
33
  <a class="app-menu-item" data-route="history" href="/history">History</a>
34
+ <a class="app-menu-item" data-route="worktree" href="/worktree">Worktrees</a>
34
35
  <a class="app-menu-item" data-route="journal" href="/journal">Work Log</a>
35
36
  <a class="app-menu-item" data-route="database" href="/database">Datastores</a>
36
37
  <span class="global-actions-sep app-menu-sep" aria-hidden="true"></span>
@@ -109,6 +110,10 @@
109
110
 
110
111
  <aside id="history-panel" hidden></aside>
111
112
  <div id="history-resizer" aria-hidden="true"></div>
113
+ <!-- 作業ツリー画面の一覧。中身は worktree-view が入れる。見た目は
114
+ #history-panel と同じ規則を共有している。変更ファイルは Repository と
115
+ 同じ #sidebar、差分は #diff を使うので、増える箱はこれだけ。 -->
116
+ <aside id="worktree-panel" hidden></aside>
112
117
  <aside id="sidebar">
113
118
  <div class="sb-head">
114
119
  <span class="sb-title">Files</span>
package/web/style.css CHANGED
@@ -1381,12 +1381,35 @@ body.gdp-diff-page #repo-target-wrap {
1381
1381
  background: var(--fg-subtle);
1382
1382
  transition: background 0.2s ease, box-shadow 0.2s ease;
1383
1383
  }
1384
- #status.live::before { background: #2ea043; box-shadow: 0 0 0 3px rgba(46,160,67,0.20); }
1384
+ #status.live::before {
1385
+ background: #2ea043;
1386
+ box-shadow: 0 0 0 3px rgba(46,160,67,0.20);
1387
+ animation: status-live-pulse 1.6s ease-out infinite;
1388
+ }
1385
1389
  #status.refreshing::before { background: #d29922; box-shadow: 0 0 0 3px rgba(210,153,34,0.25); }
1386
1390
  #status.error::before { background: var(--danger); box-shadow: 0 0 0 3px rgba(207,34,46,0.20); }
1387
1391
  #status.live { color: var(--success); }
1388
1392
  #status.refreshing { color: var(--attn); }
1389
1393
  #status.error { color: var(--danger); }
1394
+ @keyframes status-live-pulse {
1395
+ 0% {
1396
+ box-shadow: 0 0 0 0 rgba(46, 160, 67, 0.42);
1397
+ transform: scale(0.92);
1398
+ }
1399
+ 55% {
1400
+ box-shadow: 0 0 0 6px rgba(46, 160, 67, 0);
1401
+ transform: scale(1.08);
1402
+ }
1403
+ 100% {
1404
+ box-shadow: 0 0 0 0 rgba(46, 160, 67, 0);
1405
+ transform: scale(0.92);
1406
+ }
1407
+ }
1408
+ @media (prefers-reduced-motion: reduce) {
1409
+ #status.live::before {
1410
+ animation: none;
1411
+ }
1412
+ }
1390
1413
 
1391
1414
  /* ===== Top-edge loading bar (indeterminate) ===== */
1392
1415
  #load-bar {
@@ -1500,7 +1523,10 @@ body.gdp-diff-page #repo-target-wrap {
1500
1523
  .gdp-banner-dismiss:hover { color: var(--fg); }
1501
1524
 
1502
1525
  /* ===== Commit history panel ===== */
1503
- #history-panel {
1526
+ /* 作業ツリー画面の 2 枚のパネルも同じ箱を使う。位置だけ Worktrees セクションで
1527
+ 上書きし、見た目はここ 1 箇所で決まる。 */
1528
+ #history-panel,
1529
+ #worktree-panel {
1504
1530
  display: none;
1505
1531
  position: fixed;
1506
1532
  left: 0;
@@ -1540,7 +1566,9 @@ body.gdp-history-page #repo-target-wrap {
1540
1566
  background: transparent;
1541
1567
  transition: background 0.12s;
1542
1568
  }
1543
- body.gdp-history-page #history-resizer {
1569
+ /* 一覧パネルを持つページ (data-history-list-panel。履歴・作業ツリー) でだけ
1570
+ つまみを出す。 */
1571
+ body[data-history-list-panel] #history-resizer {
1544
1572
  display: block;
1545
1573
  }
1546
1574
  #history-resizer:hover,
@@ -1553,7 +1581,8 @@ body.gdp-history-resizing #history-resizer {
1553
1581
  body.gdp-history-page #topbar .ref-pickers {
1554
1582
  display: none;
1555
1583
  }
1556
- #history-panel[hidden] {
1584
+ #history-panel[hidden],
1585
+ #worktree-panel[hidden] {
1557
1586
  display: none !important;
1558
1587
  }
1559
1588
  .history-head {
@@ -2283,7 +2312,7 @@ body.gdp-history-resizing * {
2283
2312
 
2284
2313
  /* Help ページの設定セクションに置くフォーム。読みやすい行長で止める。 */
2285
2314
  .scope-settings {
2286
- max-width: 460px;
2315
+ max-width: 760px;
2287
2316
  }
2288
2317
  .scope-settings label {
2289
2318
  display: block;
@@ -2356,6 +2385,118 @@ body.gdp-history-resizing * {
2356
2385
  padding: 8px;
2357
2386
  font: 13px/19px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
2358
2387
  }
2388
+ .agent-screen-rules-section {
2389
+ padding-top: 12px;
2390
+ border-top: 1px solid var(--border);
2391
+ }
2392
+ .agent-screen-rules-guide {
2393
+ margin: 8px 0 10px;
2394
+ padding: 8px 10px;
2395
+ border: 1px solid var(--border);
2396
+ border-radius: 6px;
2397
+ background: color-mix(in srgb, var(--bg-soft) 76%, transparent);
2398
+ }
2399
+ .agent-screen-rules-guide summary {
2400
+ color: var(--fg);
2401
+ font-size: 12px;
2402
+ font-weight: 600;
2403
+ cursor: pointer;
2404
+ }
2405
+ .agent-screen-rules-guide .scope-settings-help {
2406
+ margin-top: 6px;
2407
+ }
2408
+ .agent-screen-rules-guide-example {
2409
+ margin: 8px 0 0;
2410
+ padding: 8px;
2411
+ overflow: auto;
2412
+ border: 1px solid var(--border);
2413
+ border-radius: 5px;
2414
+ background: var(--bg);
2415
+ color: var(--fg);
2416
+ font: 12px/18px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
2417
+ tab-size: 2;
2418
+ }
2419
+ .agent-screen-rules-editor {
2420
+ position: relative;
2421
+ min-height: 420px;
2422
+ overflow: hidden;
2423
+ border: 1px solid var(--border);
2424
+ border-radius: 6px;
2425
+ background: var(--bg-soft);
2426
+ }
2427
+ .agent-screen-rules-editor:focus-within {
2428
+ border-color: var(--accent);
2429
+ box-shadow: 0 0 0 3px var(--accent-muted);
2430
+ }
2431
+ .agent-screen-rules-highlight {
2432
+ position: absolute;
2433
+ inset: 0;
2434
+ margin: 0;
2435
+ padding: 8px;
2436
+ overflow-x: hidden;
2437
+ overflow-y: scroll;
2438
+ scrollbar-gutter: stable;
2439
+ pointer-events: none;
2440
+ background: var(--bg-soft);
2441
+ color: var(--fg);
2442
+ font: 13px/19px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
2443
+ white-space: pre-wrap;
2444
+ overflow-wrap: break-word;
2445
+ tab-size: 2;
2446
+ }
2447
+ .agent-screen-rules-highlight code {
2448
+ font: inherit;
2449
+ }
2450
+ .agent-screen-rules-highlight code::after {
2451
+ content: "\200b";
2452
+ display: inline-block;
2453
+ height: 19px;
2454
+ }
2455
+ .agent-screen-rules-highlight span[style] {
2456
+ color: var(--shiki-light);
2457
+ }
2458
+ @media (prefers-color-scheme: dark) {
2459
+ .agent-screen-rules-highlight span[style] {
2460
+ color: var(--shiki-dark);
2461
+ }
2462
+ }
2463
+ html[data-theme="light"] .agent-screen-rules-highlight span[style] {
2464
+ color: var(--shiki-light);
2465
+ }
2466
+ html[data-theme="dark"] .agent-screen-rules-highlight span[style] {
2467
+ color: var(--shiki-dark);
2468
+ }
2469
+ #agent-screen-rules {
2470
+ position: relative;
2471
+ z-index: 1;
2472
+ display: block;
2473
+ box-sizing: border-box;
2474
+ width: 100%;
2475
+ min-height: 420px;
2476
+ margin: 0;
2477
+ padding: 8px;
2478
+ overflow-y: scroll;
2479
+ scrollbar-gutter: stable;
2480
+ resize: vertical;
2481
+ border: 0;
2482
+ border-radius: 0;
2483
+ outline: 0;
2484
+ background: transparent;
2485
+ color: transparent;
2486
+ caret-color: var(--fg);
2487
+ font: 13px/19px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
2488
+ white-space: pre-wrap;
2489
+ overflow-wrap: break-word;
2490
+ tab-size: 2;
2491
+ }
2492
+ #agent-screen-rules::selection {
2493
+ background: var(--accent);
2494
+ color: var(--fg-onemphasis);
2495
+ }
2496
+ #agent-screen-rules:disabled {
2497
+ cursor: wait;
2498
+ opacity: 0.65;
2499
+ }
2359
2500
  #scope-omit-source {
2360
2501
  margin: 8px 0 0;
2361
2502
  color: var(--fg-subtle);
@@ -2400,17 +2541,16 @@ body.gdp-history-resizing * {
2400
2541
  margin: 0;
2401
2542
  }
2402
2543
  .scope-settings-footer {
2403
- display: flex;
2404
- align-items: center;
2405
- justify-content: space-between;
2406
- gap: 12px;
2407
2544
  margin-top: 12px;
2408
2545
  padding-top: 10px;
2409
2546
  border-top: 1px solid var(--border);
2410
2547
  }
2411
2548
  .scope-settings-footer .scope-settings-help {
2412
- margin: 0;
2413
- flex: 1;
2549
+ margin: 4px 0 0;
2550
+ }
2551
+ #scope-settings-save-status {
2552
+ min-height: 15px;
2553
+ color: var(--fg-muted);
2414
2554
  }
2415
2555
  .scope-settings-actions button {
2416
2556
  border: 1px solid var(--border);
@@ -2424,6 +2564,22 @@ body.gdp-history-resizing * {
2424
2564
  border-color: var(--border-strong);
2425
2565
  background: var(--bg-mute);
2426
2566
  }
2567
+ .scope-settings-actions button:disabled {
2568
+ cursor: not-allowed;
2569
+ opacity: 0.55;
2570
+ }
2571
+ .scope-settings-actions .scope-settings-primary-action {
2572
+ inline-size: 12em;
2573
+ border-color: var(--accent);
2574
+ background: var(--accent);
2575
+ color: var(--accent-fg, #fff);
2576
+ font-weight: 600;
2577
+ white-space: nowrap;
2578
+ }
2579
+ .scope-settings-actions .scope-settings-primary-action:hover:not(:disabled) {
2580
+ border-color: var(--accent);
2581
+ background: color-mix(in srgb, var(--accent) 88%, var(--fg));
2582
+ }
2427
2583
 
2428
2584
  #quick-help-popover {
2429
2585
  position: fixed;
@@ -7705,6 +7861,313 @@ body.gdp-database-page #load-bar {
7705
7861
  top: var(--global-header-h);
7706
7862
  }
7707
7863
 
7864
+ /* ============================================================
7865
+ Worktrees
7866
+ ============================================================ */
7867
+
7868
+ /* 骨格は History と同じ。左の一覧は #history-panel と同じ箱 (セレクタに
7869
+ #worktree-panel を足してある)、中央は Repository と同じ #sidebar の
7870
+ ファイル一覧、右は #diff の差分カード。行の見た目 (.history-item /
7871
+ .subject / .meta2 / .tree-file / .badge / .name / .gdp-file-shell) も
7872
+ 全部そのまま使うので、この画面のために作る見た目は下の配置だけ。 */
7873
+
7874
+ /* --chrome-h は上書きしない。この画面は History と同じく上部バーを出すので、
7875
+ 基底の「ヘッダ + 上部バー」がそのまま正しい。ヘッダだけに縮めると、
7876
+ 左右のパネルと本文が上部バーの下に潜り込む。 */
7877
+
7878
+ body.gdp-worktree-page #query-history-panel {
7879
+ display: none !important;
7880
+ }
7881
+
7882
+ /* topbar は出す。統合 / 分割・空白・構文・テスト非表示は、この画面の差分にも
7883
+ そのまま効く。from/to のピッカーだけは Diff ビューアのもので、ここでは
7884
+ 比較する対象を作業ツリー側が決めるので出さない (History と同じ扱い)。 */
7885
+ body.gdp-worktree-page #topbar .ref-pickers {
7886
+ display: none;
7887
+ }
7888
+
7889
+ body.gdp-worktree-page #worktree-panel {
7890
+ display: flex;
7891
+ }
7892
+
7893
+ /* 以下 4 つは History 画面と同じ並べ方 (左パネル → サイドバー → 本文)。 */
7894
+ body.gdp-worktree-page #sidebar {
7895
+ left: var(--history-w);
7896
+ }
7897
+
7898
+ body.gdp-worktree-page main#content {
7899
+ margin-left: calc(var(--history-w) + var(--sidebar-w));
7900
+ }
7901
+
7902
+ body.gdp-worktree-page.gdp-sidebar-hidden main#content {
7903
+ margin-left: var(--history-w);
7904
+ }
7905
+
7906
+ body.gdp-worktree-page #sidebar-resizer {
7907
+ left: calc(var(--history-w) + var(--sidebar-w) - 4px);
7908
+ }
7909
+
7910
+ /* サイドバーで意味を持たないのは「対象 ref」だけ。ツリー / 一覧の切替と
7911
+ 全展開・全折りたたみはこの画面でも効く。 */
7912
+ body.gdp-worktree-page #repo-target-wrap {
7913
+ display: none !important;
7914
+ }
7915
+
7916
+ /* 頭のボタンは残り幅の右端に寄せる。 */
7917
+ body.gdp-worktree-page .history-head .worktree-head-btn:first-of-type {
7918
+ margin-left: auto;
7919
+ }
7920
+
7921
+ /* 基準ブランチへそのまま入らない作業ツリーだけ、一覧の中で色を変える。
7922
+ .history-item.active と同じ左罫線の仕組みに乗る。 */
7923
+ .history-item.worktree-conflict {
7924
+ border-left-color: var(--danger);
7925
+ }
7926
+
7927
+ /* 未コミット / コミット済み の区切り。ファイル行ではないので、ツリーの
7928
+ 省略ルールから外して 1 行の見出しとして出す。 */
7929
+ #filelist .worktree-file-group,
7930
+ #filelist.tree .worktree-file-group {
7931
+ /* #filelist の li は flex 前提なので、文字だけの見出しは block に戻す。
7932
+ flex のままだと匿名アイテムになって幅を持てず、日本語が縦に潰れる。 */
7933
+ display: block;
7934
+ padding: 8px 12px 2px;
7935
+ color: var(--fg-muted);
7936
+ font-size: 11px;
7937
+ white-space: nowrap;
7938
+ cursor: default;
7939
+ }
7940
+
7941
+ /* 他の作業ツリーも触っているファイル。何本と重なっているかを行末の数で出す。
7942
+ ファイル名の色は変えない (重なりが多いと一覧がまるごと染まるため)。
7943
+ 誰と重なっているかは title に入る。 */
7944
+ .worktree-overlap-count {
7945
+ color: var(--attn);
7946
+ font-weight: 600;
7947
+ }
7948
+
7949
+ .worktree-overlap-count::before {
7950
+ content: "⇄";
7951
+ margin-right: 2px;
7952
+ font-weight: 400;
7953
+ }
7954
+
7955
+ /* .meta2 の子は長いと行を横に押し広げる。ブランチ名は自由長なので、
7956
+ 溢れるなら省略する (履歴画面の行も同じクラス)。 */
7957
+ .history-item .meta2 > span {
7958
+ min-width: 0;
7959
+ overflow: hidden;
7960
+ text-overflow: ellipsis;
7961
+ white-space: nowrap;
7962
+ }
7963
+
7964
+ /* 作業ツリー行の 1 段目: 名前と状態バッジを両端に。 */
7965
+ .history-item .worktree-row-head {
7966
+ display: flex;
7967
+ align-items: baseline;
7968
+ gap: 8px;
7969
+ }
7970
+ .history-item .worktree-row-head .subject {
7971
+ flex: 1 1 auto;
7972
+ min-width: 0;
7973
+ }
7974
+ .worktree-row-badges {
7975
+ flex: 0 1 auto;
7976
+ min-width: 0;
7977
+ overflow: hidden;
7978
+ text-overflow: ellipsis;
7979
+ white-space: nowrap;
7980
+ color: var(--fg-muted);
7981
+ font-size: var(--ui-font-sm);
7982
+ }
7983
+
7984
+ /* 2 段目のフォルダの場所。パスは末尾が肝心なので、長いときは頭側を省略する。
7985
+ direction: rtl は #filelist li .name と同じ手で、::before の LRM
7986
+ (U+200E) まで込みで 1 組。これが無いと、末尾が記号で終わるパスで並びが
7987
+ 崩れる。 */
7988
+ .worktree-row-path {
7989
+ display: block;
7990
+ direction: rtl;
7991
+ text-align: left;
7992
+ overflow: hidden;
7993
+ text-overflow: ellipsis;
7994
+ white-space: nowrap;
7995
+ color: var(--fg-muted);
7996
+ font-size: var(--ui-font-sm);
7997
+ margin-top: 2px;
7998
+ }
7999
+ .worktree-row-path::before {
8000
+ content: "\200E";
8001
+ }
8002
+
8003
+ /* 4 段目に添える「取り込むコマンドをコピー」。文字側 (.author) だけが縮んで
8004
+ 省略されるように、ボタンは縮ませない。 */
8005
+ .history-item .meta2 > .gdp-copy-path {
8006
+ flex: 0 0 auto;
8007
+ align-self: center;
8008
+ }
8009
+
8010
+ /* 行の右端の「…」。押すまで操作は 1 つも出さない。
8011
+ ボタンを行に並べると、選んだ瞬間にクリックした場所へ現れて誤爆する。
8012
+ 一覧の上に固定すると、今度は削除が画面で一番目立つ場所に居座る。
8013
+ 開くまで何も出さないメニューなら、どちらも起きない。 */
8014
+ .worktree-row-menu {
8015
+ flex: 0 0 auto;
8016
+ display: inline-flex;
8017
+ align-items: center;
8018
+ justify-content: center;
8019
+ width: 22px;
8020
+ height: 22px;
8021
+ padding: 0;
8022
+ border: 0;
8023
+ border-radius: 4px;
8024
+ background: none;
8025
+ color: var(--fg-muted);
8026
+ cursor: pointer;
8027
+ /* 行を選んでも消えない。位置が動かないので押し間違えない。 */
8028
+ opacity: 0.55;
8029
+ transition: opacity 0.12s, background 0.12s;
8030
+ }
8031
+
8032
+ .worktree-row-menu:hover,
8033
+ .worktree-row-menu:focus-visible {
8034
+ opacity: 1;
8035
+ background: var(--bg-soft);
8036
+ }
8037
+
8038
+ .history-item.active .worktree-row-menu {
8039
+ opacity: 1;
8040
+ }
8041
+
8042
+ /* メニューの区切り。取り返しのつかない操作を、よく使う操作と続けて置かない。 */
8043
+ .gdp-context-menu-sep {
8044
+ margin: 4px 2px;
8045
+ border: 0;
8046
+ border-top: 1px solid var(--border);
8047
+ }
8048
+
8049
+ /* 変更がまだ無い作業ツリーの案内 (右ペイン)。次にやることをその場に置く。 */
8050
+ .worktree-empty-diff .worktree-empty-diff-actions {
8051
+ display: inline-flex;
8052
+ gap: 8px;
8053
+ margin-top: 8px;
8054
+ }
8055
+
8056
+ /* まだ 1 本も作っていないときの説明カード (右ペイン)。 */
8057
+ .worktree-intro {
8058
+ padding: 24px;
8059
+ max-width: 46em;
8060
+ line-height: 1.7;
8061
+ color: var(--fg-muted);
8062
+ font-size: var(--ui-font-base);
8063
+ }
8064
+ .worktree-intro-title {
8065
+ color: var(--fg);
8066
+ font-weight: 600;
8067
+ font-size: var(--ui-font-md);
8068
+ margin-bottom: 4px;
8069
+ }
8070
+ .worktree-intro p {
8071
+ margin: 0 0 10px;
8072
+ }
8073
+ .worktree-intro button {
8074
+ margin-top: 4px;
8075
+ }
8076
+
8077
+ /* ⇄ の意味。重なりが 1 件も無いときは出さない。 */
8078
+ #filelist .worktree-overlap-legend {
8079
+ display: block;
8080
+ padding: 8px 12px 2px;
8081
+ color: var(--fg-muted);
8082
+ font-size: 11px;
8083
+ cursor: default;
8084
+ }
8085
+
8086
+ /* 追加 / 削除ダイアログの中身。データストアの接続ダイアログ
8087
+ (.db-connection-form) と同じで、入力欄そのものは共通の
8088
+ .gdp-dialog-input を使い、並べ方だけをここで決める。 */
8089
+ .worktree-form {
8090
+ display: flex;
8091
+ flex-direction: column;
8092
+ gap: 10px;
8093
+ min-width: 340px;
8094
+ margin-top: 6px;
8095
+ }
8096
+
8097
+ .worktree-field {
8098
+ display: flex;
8099
+ flex-direction: column;
8100
+ gap: 4px;
8101
+ color: var(--fg-muted);
8102
+ font-size: 12px;
8103
+ }
8104
+
8105
+ .worktree-hint {
8106
+ color: var(--fg-muted);
8107
+ font-size: 11px;
8108
+ }
8109
+
8110
+ /* 追加ダイアログの「作成先」。入力に連動して実パスを出す行。パスは長いので
8111
+ 1 行に固定し、頭側を省略する (行が折り返すと下のボタンが動く)。 */
8112
+ .worktree-target {
8113
+ display: flex;
8114
+ align-items: baseline;
8115
+ gap: 8px;
8116
+ font-size: 12px;
8117
+ color: var(--fg-muted);
8118
+ }
8119
+
8120
+ .worktree-target-label {
8121
+ flex: 0 0 auto;
8122
+ }
8123
+
8124
+ .worktree-target-path {
8125
+ flex: 1 1 auto;
8126
+ min-width: 0;
8127
+ direction: rtl;
8128
+ text-align: left;
8129
+ overflow: hidden;
8130
+ text-overflow: ellipsis;
8131
+ white-space: nowrap;
8132
+ color: var(--fg);
8133
+ font-family: var(--mono, monospace);
8134
+ }
8135
+ /* .worktree-row-path と同じ理由の LRM。rtl と 1 組で使う。 */
8136
+ .worktree-target-path::before {
8137
+ content: "\200E";
8138
+ }
8139
+
8140
+ /* 作るかどうかの判断に要らない注記 (.gitignore の話) を本文から下ろす先。
8141
+ 押しても何も起きない印なので、寸法も位置も変わらない。 */
8142
+ .worktree-hint-mark {
8143
+ flex: 0 0 auto;
8144
+ display: inline-flex;
8145
+ align-items: center;
8146
+ justify-content: center;
8147
+ width: 15px;
8148
+ height: 15px;
8149
+ border: 1px solid var(--border);
8150
+ border-radius: 50%;
8151
+ font-size: 10px;
8152
+ line-height: 1;
8153
+ color: var(--fg-muted);
8154
+ cursor: help;
8155
+ }
8156
+
8157
+ /* 削除ダイアログの警告。未コミット変更を失うことを、チェックを入れる前に
8158
+ 読める位置に出す。 */
8159
+ .worktree-warn {
8160
+ color: var(--danger);
8161
+ font-size: 12px;
8162
+ }
8163
+
8164
+ .worktree-check {
8165
+ display: flex;
8166
+ align-items: center;
8167
+ gap: 6px;
8168
+ font-size: 12px;
8169
+ }
8170
+
7708
8171
  /* ============================================================
7709
8172
  Journal
7710
8173
  ============================================================ */
@@ -14423,11 +14886,10 @@ body.app-panel-docked:has(.app-panel.app-panel-open) {
14423
14886
  var(--app-panel-max-h)
14424
14887
  );
14425
14888
  }
14426
- body.app-panel-docked.gdp-diff-page #content,
14427
- body.app-panel-docked.gdp-history-page #content,
14428
- body.app-panel-docked.gdp-repo-page #content,
14429
- body.app-panel-docked.gdp-file-detail-page #content,
14430
- body.app-panel-docked.gdp-help-page #content {
14889
+ /* #content がスクロール容器になるかはページの属性で決まる。属性は app.ts
14890
+ setPageMode がページクラスと同じ場所で立てる。ページクラスの列挙はしない
14891
+ (ui-layout.md「ページクラスの列挙をレイアウト規則に書かない」)。 */
14892
+ body.app-panel-docked[data-content-scrolls-when-docked] #content {
14431
14893
  position: relative;
14432
14894
  top: var(--chrome-h);
14433
14895
  height: var(--content-h);
@@ -14439,41 +14901,22 @@ body.app-panel-docked.gdp-help-page #content {
14439
14901
  /* Keep the normal page-specific top gap without putting padding on the
14440
14902
  scroll container. A sticky child otherwise adds that padding to its top
14441
14903
  offset and leaves scrolled content visible above the file header. */
14442
- body.app-panel-docked.gdp-diff-page #diff,
14443
- body.app-panel-docked.gdp-history-page #diff,
14444
- body.app-panel-docked.gdp-repo-page #diff,
14445
- body.app-panel-docked.gdp-file-detail-page #diff,
14446
- body.app-panel-docked.gdp-help-page #diff {
14904
+ body.app-panel-docked[data-content-scrolls-when-docked] #diff {
14447
14905
  padding-top: var(--content-top-gap);
14448
14906
  }
14449
- body.app-panel-docked.gdp-diff-page .d2h-file-header,
14450
- body.app-panel-docked.gdp-diff-page .gdp-shell-header,
14451
- body.app-panel-docked.gdp-history-page .d2h-file-header,
14452
- body.app-panel-docked.gdp-history-page .gdp-shell-header,
14453
- body.app-panel-docked.gdp-repo-page .d2h-file-header,
14454
- body.app-panel-docked.gdp-repo-page .gdp-shell-header,
14455
- body.app-panel-docked.gdp-file-detail-page .d2h-file-header,
14456
- body.app-panel-docked.gdp-file-detail-page .gdp-shell-header,
14457
- body.app-panel-docked.gdp-file-detail-page .gdp-file-detail-sticky {
14907
+ body.app-panel-docked[data-content-scrolls-when-docked] .d2h-file-header,
14908
+ body.app-panel-docked[data-content-scrolls-when-docked] .gdp-shell-header,
14909
+ body.app-panel-docked[data-content-scrolls-when-docked] .gdp-file-detail-sticky {
14458
14910
  top: 0;
14459
14911
  }
14460
- body.app-panel-docked.gdp-diff-page .gdp-markdown-toc,
14461
- body.app-panel-docked.gdp-history-page .gdp-markdown-toc,
14462
- body.app-panel-docked.gdp-repo-page .gdp-markdown-toc,
14463
- body.app-panel-docked.gdp-file-detail-page .gdp-markdown-toc {
14912
+ body.app-panel-docked[data-content-scrolls-when-docked] .gdp-markdown-toc {
14464
14913
  top: 16px;
14465
14914
  }
14466
- body.app-panel-docked.gdp-help-page .gdp-help-nav {
14915
+ body.app-panel-docked[data-content-scrolls-when-docked] .gdp-help-nav {
14467
14916
  top: 20px;
14468
14917
  }
14469
- body.app-panel-docked.gdp-diff-page .d2h-file-wrapper,
14470
- body.app-panel-docked.gdp-diff-page .gdp-file-shell,
14471
- body.app-panel-docked.gdp-history-page .d2h-file-wrapper,
14472
- body.app-panel-docked.gdp-history-page .gdp-file-shell,
14473
- body.app-panel-docked.gdp-repo-page .d2h-file-wrapper,
14474
- body.app-panel-docked.gdp-repo-page .gdp-file-shell,
14475
- body.app-panel-docked.gdp-file-detail-page .d2h-file-wrapper,
14476
- body.app-panel-docked.gdp-file-detail-page .gdp-file-shell {
14918
+ body.app-panel-docked[data-content-scrolls-when-docked] .d2h-file-wrapper,
14919
+ body.app-panel-docked[data-content-scrolls-when-docked] .gdp-file-shell {
14477
14920
  scroll-margin-top: 8px;
14478
14921
  }
14479
14922
  body.app-panel-docked #sidebar,
@@ -14486,10 +14929,13 @@ body.app-panel-docked #annotation-panel {
14486
14929
  body.app-panel-docked .app-panel.app-panel-open {
14487
14930
  box-shadow: none;
14488
14931
  }
14489
- body.app-panel-docked .journal-page,
14490
- body.app-panel-docked .db-root {
14491
- height: 100%;
14492
- }
14932
+ /* docked のときに `.journal-page` / `.db-root` を `height: 100%` で上書きしない。
14933
+ この 2 ページは data-content-scrolls-when-docked を持たず、
14934
+ 親の `#content` が高さを持たないので、100% は解決先を失って auto に落ち、ページ
14935
+ 全体が中身の高さまで縮む (中身が空のとき画面途中で切れる形で表面化した)。両者は
14936
+ 既に `height: var(--content-h)` を持ち、--content-h は docked ではパネル占有分が
14937
+ 引かれた値になるので、そもそも上書きが要らない。検査は
14938
+ `web-src/test/docked-page-height.test.ts`。 */
14493
14939
 
14494
14940
  .tools-sheet,
14495
14941
  .terminal-sheet {
@@ -15683,6 +16129,20 @@ html[data-theme="dark"] .tools-code span[style] {
15683
16129
  color: var(--fg-muted, #57606a);
15684
16130
  }
15685
16131
 
16132
+ .terminal-observation-errors {
16133
+ max-height: 12rem;
16134
+ margin: 0;
16135
+ padding: 8px 10px;
16136
+ overflow: auto;
16137
+ border: 1px solid color-mix(in srgb, var(--danger) 40%, var(--border));
16138
+ border-radius: 6px;
16139
+ color: var(--danger);
16140
+ background: color-mix(in srgb, var(--danger) 8%, var(--bg));
16141
+ font: 11px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
16142
+ white-space: pre-wrap;
16143
+ overflow-wrap: anywhere;
16144
+ }
16145
+
15686
16146
  /* ==========================================================================
15687
16147
  Datastore page — premium glass theme
15688
16148
  データストアページ (.db-root) 全体にスコープした装飾レイヤ。