@lemoncat7/dsh-knowledge 1.1.5 → 1.2.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.
Files changed (64) hide show
  1. package/README.md +2 -2
  2. package/docs/architecture.md +3 -3
  3. package/lib/api.d.ts +2 -0
  4. package/lib/api.d.ts.map +1 -1
  5. package/lib/api.js +41 -12
  6. package/lib/api.js.map +1 -1
  7. package/lib/atomic-file.d.ts +16 -0
  8. package/lib/atomic-file.d.ts.map +1 -0
  9. package/lib/atomic-file.js +93 -0
  10. package/lib/atomic-file.js.map +1 -0
  11. package/lib/client.js +1 -1
  12. package/lib/client.js.map +2 -2
  13. package/lib/config.d.ts.map +1 -1
  14. package/lib/config.js +2 -5
  15. package/lib/config.js.map +1 -1
  16. package/lib/connection.d.ts.map +1 -1
  17. package/lib/connection.js +5 -15
  18. package/lib/connection.js.map +1 -1
  19. package/lib/documents/projection-queue.d.ts +10 -0
  20. package/lib/documents/projection-queue.d.ts.map +1 -0
  21. package/lib/documents/projection-queue.js +21 -0
  22. package/lib/documents/projection-queue.js.map +1 -0
  23. package/lib/documents/store.d.ts +4 -2
  24. package/lib/documents/store.d.ts.map +1 -1
  25. package/lib/documents/store.js +54 -73
  26. package/lib/documents/store.js.map +1 -1
  27. package/lib/extraction.d.ts.map +1 -1
  28. package/lib/extraction.js +10 -2
  29. package/lib/extraction.js.map +1 -1
  30. package/lib/index.d.ts.map +1 -1
  31. package/lib/index.js +85 -31
  32. package/lib/index.js.map +1 -1
  33. package/lib/knowledge-merge.d.ts +8 -0
  34. package/lib/knowledge-merge.d.ts.map +1 -0
  35. package/lib/knowledge-merge.js +19 -0
  36. package/lib/knowledge-merge.js.map +1 -0
  37. package/lib/local-provider.d.ts +2 -0
  38. package/lib/local-provider.d.ts.map +1 -1
  39. package/lib/local-provider.js +100 -61
  40. package/lib/local-provider.js.map +1 -1
  41. package/lib/remote-provider.d.ts.map +1 -1
  42. package/lib/remote-provider.js +34 -2
  43. package/lib/remote-provider.js.map +1 -1
  44. package/lib/remote-url.d.ts +2 -0
  45. package/lib/remote-url.d.ts.map +1 -0
  46. package/lib/remote-url.js +14 -0
  47. package/lib/remote-url.js.map +1 -0
  48. package/lib/service-settings.d.ts.map +1 -1
  49. package/lib/service-settings.js +3 -10
  50. package/lib/service-settings.js.map +1 -1
  51. package/lib/tools.js +44 -1
  52. package/lib/tools.js.map +1 -1
  53. package/lib/web-change-review.d.ts +34 -0
  54. package/lib/web-change-review.d.ts.map +1 -0
  55. package/lib/web-change-review.js +147 -0
  56. package/lib/web-change-review.js.map +1 -0
  57. package/lib/web.d.ts.map +1 -1
  58. package/lib/web.js +1 -0
  59. package/lib/web.js.map +1 -1
  60. package/package.json +1 -1
  61. package/web/app.js +287 -81
  62. package/web/change-review.js +5 -0
  63. package/web/index.html +1 -0
  64. package/web/styles.css +100 -23
@@ -0,0 +1,5 @@
1
+ "use strict";var DshKnowledgeReview=(()=>{var g=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var I=(e,t)=>{for(var r in t)g(e,r,{get:t[r],enumerable:!0})},R=(e,t,r,f)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of C(t))!K.call(e,n)&&n!==r&&g(e,n,{get:()=>t[n],enumerable:!(f=v(t,n))||f.enumerable});return e};var A=e=>R(g({},"__esModule",{value:!0}),e);var F={};I(F,{compactDiffLines:()=>y,createLineDiff:()=>w,createReviewChange:()=>$});function D(e,t){let r=L(e),f=L(t);return r===f||r.includes(f)?e.trim():f.includes(r)?t.trim():`${e.trim()}
2
+
3
+ ${t.trim()}`}function L(e){return e.normalize("NFKC").toLocaleLowerCase().replace(/\s+/gu," ").trim()}var _=6e5;function $(e,t,r){let f=e==="create"?"":t,n=e==="create"?r:D(t,r),i=w(f,n);return{before:f,after:n,diff:i,displayLines:y(i.lines)}}function w(e,t){let r=b(e),f=b(t),n=0;for(;n<r.length&&n<f.length&&r[n]===f[n];)n+=1;let i=0;for(;i<r.length-n&&i<f.length-n&&r[r.length-1-i]===f[f.length-1-i];)i+=1;let o=r.slice(n,r.length-i),l=f.slice(n,f.length-i),c=(o.length+1)*(l.length+1)>_,u=c?E(o,l,n+1,n+1):B(o,l,n+1,n+1),a=[];for(let d=0;d<n;d+=1)a.push({kind:"context",text:r[d]??"",oldLine:d+1,newLine:d+1});a.push(...u);for(let d=0;d<i;d+=1){let x=r.length-i+d,M=f.length-i+d;a.push({kind:"context",text:r[x]??"",oldLine:x+1,newLine:M+1})}let h=0,m=0,p=0;for(let d of a)d.kind==="add"?h+=1:d.kind==="remove"?m+=1:p+=1;return{lines:a,additions:h,deletions:m,unchanged:p,simplified:c}}function y(e,t=3){if(e.length===0)return[];let r=e.flatMap((i,o)=>i.kind==="context"?[]:[o]);if(r.length===0)return k(e,[[0,Math.min(e.length,t)],[Math.max(0,e.length-t),e.length]]);let f=r.map(i=>[Math.max(0,i-t),Math.min(e.length,i+t+1)]),n=[];for(let i of f){let o=n.at(-1);o!==void 0&&i[0]<=o[1]?o[1]=Math.max(o[1],i[1]):n.push(i)}return k(e,n)}function b(e){let t=e.replace(/\r\n?/g,`
4
+ `);return t.length===0?[]:t.split(`
5
+ `)}function B(e,t,r,f){let n=t.length+1,i=new Uint32Array((e.length+1)*n);for(let c=e.length-1;c>=0;c-=1)for(let u=t.length-1;u>=0;u-=1){let a=c*n+u;i[a]=e[c]===t[u]?(i[(c+1)*n+u+1]??0)+1:Math.max(i[(c+1)*n+u]??0,i[a+1]??0)}let o=[],l=0,s=0;for(;l<e.length&&s<t.length;)e[l]===t[s]?(o.push({kind:"context",text:e[l]??"",oldLine:r+l,newLine:f+s}),l+=1,s+=1):(i[(l+1)*n+s]??0)>=(i[l*n+s+1]??0)?(o.push({kind:"remove",text:e[l]??"",oldLine:r+l}),l+=1):(o.push({kind:"add",text:t[s]??"",newLine:f+s}),s+=1);for(;l<e.length;)o.push({kind:"remove",text:e[l]??"",oldLine:r+l}),l+=1;for(;s<t.length;)o.push({kind:"add",text:t[s]??"",newLine:f+s}),s+=1;return o}function E(e,t,r,f){return[...e.map((n,i)=>({kind:"remove",text:n,oldLine:r+i})),...t.map((n,i)=>({kind:"add",text:n,newLine:f+i}))]}function k(e,t){let r=[],f=0;for(let[n,i]of t){if(i<=f)continue;let o=Math.max(n,f);o>f&&r.push({kind:"omitted",count:o-f}),r.push(...e.slice(o,i)),f=i}return f<e.length&&r.push({kind:"omitted",count:e.length-f}),r}return A(F);})();
package/web/index.html CHANGED
@@ -11,6 +11,7 @@
11
11
  <title>DSH 知识库</title>
12
12
  <link rel="stylesheet" href="__DSH_KNOWLEDGE_WEB_PATH__/styles.css?v=__DSH_KNOWLEDGE_ASSET_VERSION__">
13
13
  <script src="__DSH_KNOWLEDGE_WEB_PATH__/markdown-preview.js?v=__DSH_KNOWLEDGE_ASSET_VERSION__"></script>
14
+ <script src="__DSH_KNOWLEDGE_WEB_PATH__/change-review.js?v=__DSH_KNOWLEDGE_ASSET_VERSION__"></script>
14
15
  <script type="module" src="__DSH_KNOWLEDGE_WEB_PATH__/app.js?v=__DSH_KNOWLEDGE_ASSET_VERSION__"></script>
15
16
  </head>
16
17
  <body>
package/web/styles.css CHANGED
@@ -172,23 +172,23 @@ html,
172
172
  .note-editor-scroll,
173
173
  .markdown-preview pre,
174
174
  .markdown-table-scroll,
175
- .candidate-comparison pre,
175
+ .diff-viewer,
176
176
  .dialog-body,
177
177
  .textarea {
178
178
  scrollbar-width: thin;
179
179
  scrollbar-color: var(--scrollbar-thumb) transparent;
180
180
  }
181
181
 
182
- :where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar {
182
+ :where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .diff-viewer, .dialog-body, .textarea)::-webkit-scrollbar {
183
183
  width: 8px;
184
184
  height: 8px;
185
185
  }
186
186
 
187
- :where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar-track {
187
+ :where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .diff-viewer, .dialog-body, .textarea)::-webkit-scrollbar-track {
188
188
  background: transparent;
189
189
  }
190
190
 
191
- :where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar-thumb {
191
+ :where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .diff-viewer, .dialog-body, .textarea)::-webkit-scrollbar-thumb {
192
192
  min-width: 28px;
193
193
  min-height: 28px;
194
194
  border: 2px solid transparent;
@@ -197,7 +197,7 @@ html,
197
197
  background-clip: padding-box;
198
198
  }
199
199
 
200
- :where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar-thumb:hover {
200
+ :where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .diff-viewer, .dialog-body, .textarea)::-webkit-scrollbar-thumb:hover {
201
201
  background: var(--scrollbar-thumb-hover);
202
202
  background-clip: padding-box;
203
203
  }
@@ -660,7 +660,16 @@ html,
660
660
  background: var(--surface);
661
661
  box-shadow: 0 14px 38px color-mix(in srgb, var(--text) 5%, transparent);
662
662
  }
663
- .note-tree-panel { min-width: 0; display: grid; grid-template-rows: auto auto minmax(0, 1fr) auto; border-right: 1px solid var(--border); background: color-mix(in srgb, var(--surface-soft) 55%, var(--surface)); }
663
+ .note-tree-panel {
664
+ min-width: 0;
665
+ min-height: 0;
666
+ height: 100%;
667
+ display: grid;
668
+ grid-template-rows: auto auto minmax(0, 1fr) auto;
669
+ overflow: hidden;
670
+ border-right: 1px solid var(--border);
671
+ background: color-mix(in srgb, var(--surface-soft) 55%, var(--surface));
672
+ }
664
673
  .note-tree-scrim { display: none; }
665
674
  .note-tree-header { min-height: 58px; display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 11px 12px 8px 16px; }
666
675
  .note-tree-header h2 { margin: 0; font-size: 14px; letter-spacing: -.01em; }
@@ -670,7 +679,13 @@ html,
670
679
  .note-tree-search-wrap .search-symbol { left: 20px; }
671
680
  .note-tree-search { width: 100%; height: 34px; border: 1px solid transparent; border-radius: 8px; padding: 6px 10px 6px 34px; background: color-mix(in srgb, var(--surface) 72%, transparent); color: var(--text); outline: none; }
672
681
  .note-tree-search:focus { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); background: var(--surface); }
673
- .note-tree { min-height: 0; overflow: auto; padding: 3px 8px 12px; }
682
+ .note-tree {
683
+ min-height: 0;
684
+ overflow-x: hidden;
685
+ overflow-y: auto;
686
+ overscroll-behavior: contain;
687
+ padding: 3px 8px 12px;
688
+ }
674
689
  .note-tree-group + .note-tree-group { margin-top: 3px; }
675
690
  .note-tree-base, .note-tree-document, .note-tree-new { width: 100%; display: flex; align-items: center; border: 0; background: transparent; color: var(--text-secondary); text-align: left; }
676
691
  .note-tree-base { min-height: 34px; gap: 7px; border-radius: 7px; padding: 5px 7px; font-weight: 620; }
@@ -717,8 +732,10 @@ html,
717
732
  .note-editor {
718
733
  min-width: 0;
719
734
  min-height: 0;
735
+ height: 100%;
720
736
  display: grid;
721
737
  grid-template-rows: auto minmax(0, 1fr) auto;
738
+ overflow: hidden;
722
739
  background: var(--surface);
723
740
  container-name: note-editor;
724
741
  container-type: inline-size;
@@ -728,7 +745,18 @@ html,
728
745
  .note-empty-content h3 { margin: 16px 0 5px; font-size: 17px; }
729
746
  .note-empty-content p { margin: 0 0 18px; color: var(--text-tertiary); }
730
747
  .empty-document-mark { display: inline-block; width: 38px; height: 47px; border: 1.5px solid var(--border-strong); border-radius: 5px; background: linear-gradient(var(--border), var(--border)) 9px 13px / 19px 1px no-repeat, linear-gradient(var(--border), var(--border)) 9px 20px / 15px 1px no-repeat; }
731
- .note-editor-toolbar { min-height: 58px; display: flex; align-items: center; justify-content: space-between; gap: 14px; border-bottom: 1px solid var(--border); padding: 9px 14px 9px 20px; }
748
+ .note-editor-toolbar {
749
+ position: relative;
750
+ z-index: 2;
751
+ min-height: 58px;
752
+ display: flex;
753
+ align-items: center;
754
+ justify-content: space-between;
755
+ gap: 14px;
756
+ border-bottom: 1px solid var(--border);
757
+ padding: 9px 14px 9px 20px;
758
+ background: var(--surface);
759
+ }
732
760
  .note-breadcrumb { min-width: 0; display: flex; align-items: center; gap: 7px; overflow: hidden; color: var(--text-tertiary); font-size: 11px; white-space: nowrap; }
733
761
  .note-breadcrumb strong { overflow: hidden; color: var(--text-secondary); font-weight: 560; text-overflow: ellipsis; }
734
762
  .note-editor-actions { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; }
@@ -737,7 +765,12 @@ html,
737
765
  .note-mode-switch button { min-width: 48px; min-height: 28px; border: 0; border-radius: 6px; padding: 4px 9px; background: transparent; color: var(--text-tertiary); font-size: 11px; font-weight: 600; }
738
766
  .note-mode-switch button:hover { color: var(--text); }
739
767
  .note-mode-switch button[aria-selected="true"] { background: var(--surface-raised); color: var(--text); box-shadow: 0 1px 3px color-mix(in srgb, var(--text) 10%, transparent); }
740
- .note-editor-scroll { min-height: 0; overflow: auto; container-type: inline-size; }
768
+ .note-editor-scroll {
769
+ min-height: 0;
770
+ overflow: auto;
771
+ overscroll-behavior: contain;
772
+ container-type: inline-size;
773
+ }
741
774
  .document-finalized-banner {
742
775
  display: grid;
743
776
  grid-template-columns: auto minmax(0, 1fr) auto;
@@ -892,22 +925,51 @@ html,
892
925
  .tab[aria-selected="true"] { background: var(--surface); color: var(--text); box-shadow: 0 1px 4px rgb(0 0 0 / 7%); }
893
926
 
894
927
  .candidate-list { display: grid; gap: 13px; }
895
- .candidate { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
928
+ .candidate { overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
896
929
  .candidate-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; padding: 17px 18px 12px; }
897
930
  .candidate-header h3 { margin: 8px 0 0; font-size: 15px; }
898
- .candidate-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(240px, .55fr); gap: 20px; padding: 0 18px 17px; }
899
- .candidate-content { margin: 0; color: var(--text-secondary); white-space: pre-wrap; }
900
- .candidate-body.is-conflict { grid-template-columns: 1fr; }
901
- .candidate-comparison { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
902
- .candidate-comparison section { min-width: 0; border: 1px solid var(--border); border-radius: 9px; padding: 12px; background: var(--surface-soft); }
903
- .candidate-comparison strong { display: block; margin-bottom: 8px; color: var(--text); font-size: 12px; }
904
- .candidate-comparison pre { overflow: auto; max-height: 280px; margin: 0; color: var(--text-secondary); font: inherit; line-height: 1.65; white-space: pre-wrap; overflow-wrap: anywhere; }
905
- .candidate-reason { border-left: 2px solid var(--border-strong); padding-left: 13px; color: var(--text-secondary); font-size: 12px; }
906
- .candidate-reason strong { display: block; margin-bottom: 5px; color: var(--text-tertiary); font-size: 10px; text-transform: uppercase; letter-spacing: .08em; }
907
- .candidate-target { display: block; margin-bottom: 13px; border-radius: 7px; padding: 7px 9px; background: var(--accent-soft); color: var(--accent); font-weight: 600; }
931
+ .candidate-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(210px, .34fr); gap: 16px; padding: 0 18px 17px; }
932
+ .candidate-change { min-width: 0; overflow: hidden; border: 1px solid var(--border); border-radius: 11px; background: var(--surface); }
933
+ .candidate-change.is-conflict { border-color: color-mix(in srgb, var(--warning) 24%, var(--border)); }
934
+ .candidate-change-heading { min-height: 53px; display: flex; align-items: center; justify-content: space-between; gap: 14px; border-bottom: 1px solid var(--border); padding: 9px 12px; background: color-mix(in srgb, var(--surface-soft) 74%, var(--surface)); }
935
+ .candidate-change-heading > div:first-child { min-width: 0; }
936
+ .candidate-change-heading strong, .candidate-change-heading small { display: block; }
937
+ .candidate-change-heading strong { color: var(--text); font-size: 12px; }
938
+ .candidate-change-heading small { overflow: hidden; margin-top: 2px; color: var(--text-tertiary); font-size: 11px; text-overflow: ellipsis; white-space: nowrap; }
939
+ .diff-summary { display: flex; flex: none; align-items: center; gap: 4px; font: 600 11px/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
940
+ .diff-stat { border-radius: 5px; padding: 4px 6px; background: var(--surface); color: var(--text-tertiary); }
941
+ .diff-stat.additions { background: var(--success-soft); color: var(--success); }
942
+ .diff-stat.deletions { background: var(--danger-soft); color: var(--danger); }
943
+ .diff-notice { border-bottom: 1px solid var(--border); padding: 7px 12px; background: var(--warning-soft); color: var(--warning); font-size: 11px; }
944
+ .diff-viewer { overflow: auto; max-height: 390px; overscroll-behavior: contain; background: var(--surface); scrollbar-width: thin; scrollbar-color: var(--scrollbar-thumb) transparent; }
945
+ .diff-column-headings, .diff-line { display: grid; grid-template-columns: 42px 42px 22px minmax(0, 1fr); }
946
+ .diff-column-headings { position: sticky; top: 0; z-index: 1; border-bottom: 1px solid var(--border); background: var(--surface-raised); color: var(--text-tertiary); font-size: 10px; }
947
+ .diff-column-headings span { min-width: 0; padding: 4px 7px; }
948
+ .diff-column-headings span:nth-child(-n + 3) { border-right: 1px solid var(--border); text-align: right; }
949
+ .diff-line { min-height: 24px; color: var(--text-secondary); font: 12px/1.55 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
950
+ .diff-line + .diff-line { border-top: 1px solid color-mix(in srgb, var(--border) 45%, transparent); }
951
+ .diff-line-number, .diff-marker { min-width: 0; border-right: 1px solid color-mix(in srgb, var(--border) 72%, transparent); padding: 2px 7px; color: var(--text-tertiary); text-align: right; user-select: none; }
952
+ .diff-marker { padding-inline: 5px; text-align: center; }
953
+ .diff-code { min-width: 0; padding: 2px 9px; color: inherit; font: inherit; white-space: pre-wrap; overflow-wrap: anywhere; }
954
+ .diff-line.is-add { background: color-mix(in srgb, var(--success-soft) 72%, var(--surface)); color: color-mix(in srgb, var(--success) 72%, var(--text)); }
955
+ .diff-line.is-remove { background: color-mix(in srgb, var(--danger-soft) 68%, var(--surface)); color: color-mix(in srgb, var(--danger) 68%, var(--text)); }
956
+ .diff-line.is-add .diff-marker { color: var(--success); font-weight: 700; }
957
+ .diff-line.is-remove .diff-marker { color: var(--danger); font-weight: 700; }
958
+ .diff-line.is-omitted { background: color-mix(in srgb, var(--accent-soft) 42%, var(--surface)); color: var(--text-tertiary); }
959
+ .diff-omitted-copy { padding: 3px 9px; font-family: ui-sans-serif, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", sans-serif; font-size: 11px; }
960
+ .diff-empty { padding: 22px; color: var(--text-tertiary); text-align: center; }
961
+ .candidate-change-unavailable { padding: 20px; background: var(--warning-soft); color: var(--warning); }
962
+ .candidate-change-unavailable p { margin: 5px 0 0; }
963
+ .candidate-reason { display: grid; align-content: start; gap: 14px; border-left: 1px solid var(--border); padding-left: 15px; color: var(--text-secondary); font-size: 12px; }
964
+ .candidate-reason section { min-width: 0; }
965
+ .candidate-reason strong { display: block; margin-bottom: 5px; color: var(--text-tertiary); font-size: 11px; font-weight: 600; }
966
+ .candidate-reason p { margin: 0; line-height: 1.6; overflow-wrap: anywhere; }
967
+ .candidate-target { display: block; border-radius: 7px; padding: 7px 9px; background: var(--accent-soft); color: var(--accent); font-weight: 600; overflow-wrap: anywhere; }
968
+ .candidate-metadata ul { display: grid; gap: 4px; margin: 0; padding-left: 17px; }
969
+ .candidate-metadata li { overflow-wrap: anywhere; }
908
970
  .candidate-footer { display: flex; align-items: center; justify-content: space-between; gap: 14px; border-top: 1px solid var(--border); padding: 11px 18px; background: var(--surface-hover); }
909
971
  .candidate-footer small { color: var(--text-tertiary); }
910
- .candidate-footer div { display: flex; gap: 7px; }
972
+ .candidate-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 7px; }
911
973
 
912
974
  .empty-state { display: grid; place-items: center; min-height: 230px; border: 1px dashed var(--border-strong); border-radius: var(--radius); padding: 28px; text-align: center; }
913
975
  .empty-state strong { font-size: 15px; }
@@ -1013,7 +1075,9 @@ html,
1013
1075
  .secret-value code { min-width: 0; flex: 1; overflow-wrap: anywhere; border-radius: 7px; padding: 8px; background: var(--surface); color: var(--text); }
1014
1076
 
1015
1077
  .toast-region { position: fixed; right: 20px; bottom: 20px; z-index: 200; display: grid; gap: 8px; pointer-events: none; }
1016
- .toast { max-width: 360px; border: 1px solid var(--border-strong); border-radius: 11px; padding: 11px 14px; background: var(--surface-raised); color: var(--text); box-shadow: var(--shadow); animation: toast-in .18s ease-out; }
1078
+ .toast { max-width: 420px; display: flex; align-items: flex-start; gap: 10px; border: 1px solid var(--border-strong); border-radius: 11px; padding: 11px 12px 11px 14px; background: var(--surface-raised); color: var(--text); box-shadow: var(--shadow); animation: toast-in .18s ease-out; pointer-events: auto; }
1079
+ .toast > span { min-width: 0; flex: 1; overflow-wrap: anywhere; }
1080
+ .toast-close { flex: none; min-height: 28px; }
1017
1081
  .toast.error { border-color: color-mix(in srgb, var(--danger) 45%, var(--border)); color: var(--danger); }
1018
1082
  @keyframes toast-in { from { opacity: 0; transform: translateY(7px); } }
1019
1083
 
@@ -1021,6 +1085,7 @@ html,
1021
1085
  .metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
1022
1086
  .dashboard-grid { grid-template-columns: 1fr; }
1023
1087
  .candidate-body { grid-template-columns: 1fr; }
1088
+ .candidate-reason { border-top: 1px solid var(--border); border-left: 0; padding-top: 14px; padding-left: 0; }
1024
1089
  .mount-manager-toolbar .tabs { width: 100%; }
1025
1090
  .note-workspace { grid-template-columns: minmax(210px, 30%) minmax(0, 1fr); }
1026
1091
  .note-paper { padding-inline: clamp(28px, 6cqi, 62px); }
@@ -1044,7 +1109,6 @@ html,
1044
1109
  }
1045
1110
 
1046
1111
  @media (max-width: 760px) {
1047
- .candidate-comparison { grid-template-columns: 1fr; }
1048
1112
  :root { --sidebar-width: 0px; }
1049
1113
  .app-shell { display: block; }
1050
1114
  .app-sidebar-resizer { display: none; }
@@ -1113,6 +1177,12 @@ html,
1113
1177
  .mount-bulk-actions .button { flex: 1 1 auto; }
1114
1178
  .candidate-header, .candidate-footer { align-items: flex-start; flex-direction: column; }
1115
1179
  .candidate-footer { gap: 9px; }
1180
+ .candidate-actions { width: 100%; justify-content: flex-start; }
1181
+ .button, .tab, .nav-button, .note-tree-base, .note-tree-document, .note-tree-new { min-height: 44px; }
1182
+ .note-add-button, .pane-toggle-button, .mobile-menu { width: 44px; min-width: 44px; min-height: 44px; }
1183
+ .note-mode-switch button { min-height: 38px; }
1184
+ .toast-region { right: 12px; bottom: 12px; left: 12px; }
1185
+ .toast { max-width: none; }
1116
1186
  }
1117
1187
 
1118
1188
  @media (max-width: 520px) {
@@ -1146,6 +1216,13 @@ html,
1146
1216
  .secret-value { flex-direction: column; }
1147
1217
  .reader-actions .badge { display: none; }
1148
1218
  .reader-footer { flex-direction: column; gap: 2px; }
1219
+ .candidate-header { padding-inline: 14px; }
1220
+ .candidate-body { padding-inline: 14px; }
1221
+ .candidate-footer { padding-inline: 14px; }
1222
+ .candidate-change-heading { align-items: flex-start; flex-direction: column; }
1223
+ .diff-column-headings, .diff-line { grid-template-columns: 30px 30px 20px minmax(0, 1fr); }
1224
+ .diff-column-headings span, .diff-line-number { padding-inline: 4px; }
1225
+ .candidate-actions .button { flex: 1 1 auto; }
1149
1226
  }
1150
1227
 
1151
1228
  @media (prefers-reduced-motion: reduce) {