collabmd 0.1.21 → 0.1.23

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 (99) hide show
  1. package/README.md +94 -7
  2. package/bin/collabmd.js +3 -2
  3. package/docker-compose.yml +13 -1
  4. package/package.json +2 -1
  5. package/public/assets/css/style.css +1 -1
  6. package/public/assets/js/chunks/{chunk-HEWVH67U.js → chunk-CYK7KO7W.js} +8 -8
  7. package/public/assets/js/chunks/editor-session-S5AT7BMV.js +22 -0
  8. package/public/assets/js/{excalidraw-editor-TCIH6GJL.js → excalidraw-editor-5YWMGLKF.js} +145 -62
  9. package/public/assets/js/excalidraw-editor.js +1 -1
  10. package/public/assets/js/main.js +503 -182
  11. package/public/index.html +104 -84
  12. package/src/client/application/app-shell/git-feature.js +247 -9
  13. package/src/client/application/app-shell/ui-feature.js +65 -7
  14. package/src/client/application/app-shell/workspace-feature.js +46 -0
  15. package/src/client/application/app-shell-elements.js +2 -0
  16. package/src/client/application/mermaid-preview-hydrator.js +1 -1
  17. package/src/client/application/plantuml-preview-hydrator.js +1 -1
  18. package/src/client/application/workspace-coordinator.js +147 -18
  19. package/src/client/application/workspace-preview-controller.js +34 -0
  20. package/src/client/application/workspace-route-controller.js +104 -0
  21. package/src/client/bootstrap/collabmd-app-shell.js +95 -0
  22. package/src/client/domain/runtime-paths.js +5 -0
  23. package/src/client/excalidraw-editor.js +50 -2
  24. package/src/client/infrastructure/auth-client.js +219 -52
  25. package/src/client/infrastructure/browser-navigation-port.js +20 -0
  26. package/src/client/infrastructure/editor-collaboration-client.js +4 -0
  27. package/src/client/infrastructure/editor-session.js +47 -7
  28. package/src/client/infrastructure/editor-view-adapter.js +122 -58
  29. package/src/client/infrastructure/runtime-config.js +66 -0
  30. package/src/client/presentation/comment-ui-controller.js +82 -26
  31. package/src/client/presentation/comments-panel.js +2 -2
  32. package/src/client/presentation/excalidraw-embed-controller.js +60 -2
  33. package/src/client/presentation/file-history-view-controller.js +806 -0
  34. package/src/client/presentation/git-diff-view-controller.js +718 -121
  35. package/src/client/presentation/git-panel-controller.js +458 -66
  36. package/src/client/presentation/layout-controller.js +1 -1
  37. package/src/client/styles/components/actions.css +89 -0
  38. package/src/client/styles/components/feedback.css +43 -0
  39. package/src/client/styles/components/navigation.css +68 -0
  40. package/src/client/styles/components/scrollbars.css +104 -0
  41. package/src/client/styles/components/states.css +289 -0
  42. package/src/client/styles/components/surfaces.css +155 -0
  43. package/src/client/styles/features/backlinks.css +213 -0
  44. package/src/client/styles/features/collaboration-chat.css +228 -0
  45. package/src/client/styles/features/collaboration-dialogs.css +154 -0
  46. package/src/client/styles/features/collaboration-presence.css +103 -0
  47. package/src/client/styles/features/collaboration-ui.css +3 -0
  48. package/src/client/styles/features/comment-card.css +236 -0
  49. package/src/client/styles/features/comment-markdown.css +127 -0
  50. package/src/client/styles/features/comment-overlays.css +60 -0
  51. package/src/client/styles/features/comments-drawer.css +120 -0
  52. package/src/client/styles/features/comments.css +4 -0
  53. package/src/client/styles/features/diagram-preview.css +227 -0
  54. package/src/client/styles/features/diff-commit.css +268 -0
  55. package/src/client/styles/features/diff-lines.css +160 -0
  56. package/src/client/styles/features/diff-toolbar.css +98 -0
  57. package/src/client/styles/features/diff.css +3 -0
  58. package/src/client/styles/features/embedded-preview.css +218 -0
  59. package/src/client/styles/features/git-branch.css +155 -0
  60. package/src/client/styles/features/git-files.css +105 -0
  61. package/src/client/styles/features/git-history.css +339 -0
  62. package/src/client/styles/features/git.css +3 -0
  63. package/src/client/styles/features/media-lightbox.css +157 -0
  64. package/src/client/styles/features/outline.css +115 -0
  65. package/src/client/styles/features/preview-content.css +3 -0
  66. package/src/client/styles/features/preview-markdown.css +201 -0
  67. package/src/client/styles/features/preview-sidebars.css +2 -0
  68. package/src/client/styles/features/quick-switcher.css +167 -0
  69. package/src/client/styles/foundation/themes.css +347 -0
  70. package/src/client/styles/foundation/tokens.css +66 -0
  71. package/src/client/styles/foundation/utilities.css +36 -0
  72. package/src/client/styles/layout/editor-page.css +203 -0
  73. package/src/client/styles/layout/overlays.css +132 -0
  74. package/src/client/styles/layout/responsive.css +251 -0
  75. package/src/client/styles/layout/shell.css +314 -0
  76. package/src/client/styles/layout/sidebar.css +176 -0
  77. package/src/client/styles/layout/view-modes.css +92 -0
  78. package/src/client/styles/overrides/codemirror.css +53 -0
  79. package/src/client/styles/overrides/highlightjs.css +7 -0
  80. package/src/client/styles/overrides/vendor.css +2 -0
  81. package/src/client/styles/primitives/controls.css +276 -0
  82. package/src/client/styles/style.css +25 -4945
  83. package/src/server/auth/create-auth-service.js +373 -15
  84. package/src/server/auth/session-cookie.js +30 -4
  85. package/src/server/config/env.js +121 -5
  86. package/src/server/create-app-server.js +8 -0
  87. package/src/server/domain/collaboration/collaboration-room.js +90 -47
  88. package/src/server/index.js +3 -1
  89. package/src/server/infrastructure/git/command-runner.js +2 -1
  90. package/src/server/infrastructure/git/git-service.js +48 -2
  91. package/src/server/infrastructure/git/history-service.js +683 -0
  92. package/src/server/infrastructure/git/parsers.js +30 -0
  93. package/src/server/infrastructure/git/responses.js +73 -0
  94. package/src/server/infrastructure/http/create-auth-api-handler.js +30 -2
  95. package/src/server/infrastructure/http/create-git-api-command-handler.js +2 -0
  96. package/src/server/infrastructure/http/create-git-api-handler.js +2 -0
  97. package/src/server/infrastructure/http/create-git-api-query-handler.js +61 -0
  98. package/src/server/infrastructure/http/create-request-handler.js +15 -0
  99. package/public/assets/js/chunks/editor-session-EAUBJCHH.js +0 -22
@@ -0,0 +1,160 @@
1
+ /* ===== DIFF / LINES ===== */
2
+
3
+ .diff-hunk-header,
4
+ .diff-split-hunk {
5
+ padding: 4px 14px 4px 84px;
6
+ background: var(--diff-hunk-bg);
7
+ color: var(--diff-hunk-text);
8
+ font-family: var(--font-mono);
9
+ font-size: var(--text-label);
10
+ }
11
+
12
+ .diff-line {
13
+ display: flex;
14
+ align-items: stretch;
15
+ min-height: 20px;
16
+ font-family: var(--font-mono);
17
+ font-size: var(--text-ui-sm);
18
+ line-height: 20px;
19
+ }
20
+
21
+ .diff-line-numbers {
22
+ display: flex;
23
+ flex-shrink: 0;
24
+ user-select: none;
25
+ }
26
+
27
+ .diff-line-num {
28
+ width: 40px;
29
+ padding: 0 8px;
30
+ border-right: 1px solid var(--color-divider);
31
+ color: var(--diff-gutter);
32
+ text-align: right;
33
+ font-size: var(--text-label);
34
+ }
35
+
36
+ .diff-line-num:first-child {
37
+ border-right: none;
38
+ }
39
+
40
+ .diff-line-prefix {
41
+ width: 20px;
42
+ padding-left: 8px;
43
+ flex-shrink: 0;
44
+ font-weight: 500;
45
+ user-select: none;
46
+ }
47
+
48
+ .diff-line-content {
49
+ flex: 1;
50
+ padding: 0 10px;
51
+ white-space: pre;
52
+ tab-size: 4;
53
+ }
54
+
55
+ .diff-line.addition {
56
+ background: var(--diff-add-bg);
57
+ }
58
+
59
+ .diff-line.addition .diff-line-num {
60
+ background: var(--diff-add-line-bg);
61
+ color: var(--diff-add-text);
62
+ }
63
+
64
+ .diff-line.addition .diff-line-prefix {
65
+ color: var(--diff-add-text);
66
+ }
67
+
68
+ .diff-line.deletion {
69
+ background: var(--diff-del-bg);
70
+ }
71
+
72
+ .diff-line.deletion .diff-line-num {
73
+ background: var(--diff-del-line-bg);
74
+ color: var(--diff-del-text);
75
+ }
76
+
77
+ .diff-line.deletion .diff-line-prefix {
78
+ color: var(--diff-del-text);
79
+ }
80
+
81
+ .diff-line.note {
82
+ background: var(--color-surface-offset);
83
+ color: var(--color-text-faint);
84
+ }
85
+
86
+ .diff-highlight-add {
87
+ padding: 0 1px;
88
+ border-radius: var(--radius-2xs);
89
+ background: var(--diff-add-line-bg);
90
+ }
91
+
92
+ .diff-highlight-del {
93
+ padding: 0 1px;
94
+ border-radius: var(--radius-2xs);
95
+ background: var(--diff-del-line-bg);
96
+ }
97
+
98
+ .diff-split {
99
+ display: block;
100
+ }
101
+
102
+ .diff-split-row {
103
+ display: grid;
104
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
105
+ }
106
+
107
+ .diff-split-pane-header {
108
+ display: none;
109
+ }
110
+
111
+ .diff-split-line {
112
+ display: flex;
113
+ min-height: 20px;
114
+ font-family: var(--font-mono);
115
+ font-size: var(--text-ui-sm);
116
+ line-height: 20px;
117
+ }
118
+
119
+ .diff-split-line:first-child {
120
+ border-right: 1px solid var(--color-divider);
121
+ }
122
+
123
+ .diff-split-num {
124
+ width: 44px;
125
+ padding: 0 8px;
126
+ border-right: 1px solid var(--color-divider);
127
+ color: var(--diff-gutter);
128
+ text-align: right;
129
+ font-size: var(--text-label);
130
+ }
131
+
132
+ .diff-split-content {
133
+ flex: 1;
134
+ padding: 0 10px;
135
+ white-space: pre;
136
+ tab-size: 4;
137
+ }
138
+
139
+ .diff-split-line.addition {
140
+ background: var(--diff-add-bg);
141
+ }
142
+
143
+ .diff-split-line.addition .diff-split-num {
144
+ background: var(--diff-add-line-bg);
145
+ color: var(--diff-add-text);
146
+ }
147
+
148
+ .diff-split-line.deletion {
149
+ background: var(--diff-del-bg);
150
+ }
151
+
152
+ .diff-split-line.deletion .diff-split-num {
153
+ background: var(--diff-del-line-bg);
154
+ color: var(--diff-del-text);
155
+ }
156
+
157
+ .diff-split-line.empty {
158
+ background: var(--color-surface-offset);
159
+ opacity: 0.45;
160
+ }
@@ -0,0 +1,98 @@
1
+ /* ===== DIFF / TOOLBAR ===== */
2
+
3
+ .diff-toolbar {
4
+ display: flex;
5
+ align-items: center;
6
+ justify-content: space-between;
7
+ gap: var(--space-3);
8
+ padding: var(--space-2) var(--space-4);
9
+ background: var(--color-surface-2);
10
+ border-bottom: 1px solid var(--color-divider);
11
+ }
12
+
13
+ .diff-toolbar-left,
14
+ .diff-toolbar-right {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: var(--space-3);
18
+ }
19
+
20
+ .diff-toolbar-actions {
21
+ display: inline-flex;
22
+ align-items: center;
23
+ gap: var(--space-2);
24
+ }
25
+
26
+ .diff-toolbar-actions-group {
27
+ display: inline-flex;
28
+ align-items: center;
29
+ gap: var(--space-2);
30
+ }
31
+
32
+ .diff-toolbar-actions-group-git {
33
+ padding: var(--space-1);
34
+ border: 1px solid var(--color-divider);
35
+ border-radius: var(--radius-lg);
36
+ background: var(--surface-overlay);
37
+ box-shadow: var(--shadow-sheet-inset);
38
+ }
39
+
40
+ .diff-toolbar-actions-divider {
41
+ width: 1px;
42
+ height: var(--control-h-xs);
43
+ background: var(--color-divider);
44
+ opacity: 0.9;
45
+ }
46
+
47
+ .diff-open-editor-btn {
48
+ min-width: 116px;
49
+ }
50
+
51
+ .diff-open-editor-btn:disabled {
52
+ opacity: 0.45;
53
+ cursor: not-allowed;
54
+ }
55
+
56
+ .diff-back-btn {
57
+ min-width: 130px;
58
+ }
59
+
60
+ .diff-file-nav {
61
+ display: flex;
62
+ align-items: center;
63
+ gap: var(--space-2);
64
+ }
65
+
66
+ .diff-file-nav .ui-action-icon:disabled {
67
+ opacity: 0.3;
68
+ }
69
+
70
+ .diff-file-indicator {
71
+ color: var(--color-text-muted);
72
+ font-size: var(--text-xs);
73
+ font-variant-numeric: tabular-nums;
74
+ }
75
+
76
+ .diff-stats {
77
+ display: inline-flex;
78
+ align-items: center;
79
+ gap: var(--space-2);
80
+ white-space: nowrap;
81
+ }
82
+
83
+ .diff-scroll {
84
+ flex: 1;
85
+ overflow: auto;
86
+ }
87
+
88
+ .diff-content {
89
+ min-width: fit-content;
90
+ min-height: 100%;
91
+ }
92
+
93
+ .diff-content--history {
94
+ display: flex;
95
+ min-width: 0;
96
+ min-height: 100%;
97
+ width: 100%;
98
+ }
@@ -0,0 +1,3 @@
1
+ @import './diff-toolbar.css';
2
+ @import './diff-commit.css';
3
+ @import './diff-lines.css';
@@ -0,0 +1,218 @@
1
+ /* ===== PREVIEW / EMBEDDED MEDIA ===== */
2
+
3
+ .preview-content .video-embed-shell {
4
+ display: block;
5
+ background: var(--surface-media-canvas);
6
+ }
7
+
8
+ .preview-content .video-embed,
9
+ .preview-content .video-embed-placeholder {
10
+ display: block;
11
+ transition: box-shadow 0.18s ease;
12
+ }
13
+
14
+ .preview-content .video-embed-placeholder.is-hydrated {
15
+ visibility: hidden;
16
+ }
17
+
18
+ .video-embed-overlay-root {
19
+ position: absolute;
20
+ inset: 0;
21
+ z-index: 1;
22
+ pointer-events: none;
23
+ }
24
+
25
+ .preview-content .video-embed-frame,
26
+ .preview-content .video-embed,
27
+ .preview-content .video-embed-placeholder {
28
+ width: 100%;
29
+ max-width: 100%;
30
+ min-width: 0;
31
+ }
32
+
33
+ .preview-content .video-embed-frame {
34
+ height: 100%;
35
+ }
36
+
37
+ .preview-content .video-embed-placeholder-card {
38
+ min-height: 100%;
39
+ border-radius: 0;
40
+ }
41
+
42
+ .preview-content .video-embed-placeholder-copy {
43
+ display: grid;
44
+ gap: 2px;
45
+ }
46
+
47
+ .preview-content .video-embed-iframe,
48
+ .preview-content .video-embed-player {
49
+ display: block;
50
+ width: 100%;
51
+ height: 100%;
52
+ max-width: 100%;
53
+ border: none;
54
+ background: var(--surface-media-canvas);
55
+ }
56
+
57
+ .preview-content .video-embed-player {
58
+ object-fit: contain;
59
+ }
60
+
61
+ .preview-content .mermaid-shell {
62
+ display: grid;
63
+ gap: 0;
64
+ }
65
+
66
+ .preview-content .mermaid-placeholder-card {
67
+ border-radius: 0;
68
+ }
69
+
70
+ .preview-content .mermaid-toolbar {
71
+ justify-content: flex-end;
72
+ }
73
+
74
+ .preview-content .mermaid-zoom-btn {
75
+ min-width: 32px;
76
+ line-height: 1.5;
77
+ }
78
+
79
+ .preview-content .mermaid-zoom-btn:disabled {
80
+ opacity: 0.5;
81
+ cursor: not-allowed;
82
+ }
83
+
84
+ .preview-content .mermaid-frame {
85
+ max-width: none;
86
+ }
87
+
88
+ .preview-content .mermaid-frame.is-pannable {
89
+ cursor: grab;
90
+ }
91
+
92
+ .preview-content .mermaid-frame.is-dragging {
93
+ cursor: grabbing;
94
+ user-select: none;
95
+ }
96
+
97
+ .preview-content .mermaid-frame svg {
98
+ display: block;
99
+ }
100
+
101
+ body.mermaid-maximized-open {
102
+ overflow: hidden;
103
+ }
104
+
105
+ body.mermaid-maximized-open::before {
106
+ content: '';
107
+ position: fixed;
108
+ inset: 0;
109
+ z-index: 170;
110
+ background: var(--surface-scrim);
111
+ backdrop-filter: blur(2px);
112
+ }
113
+
114
+ .preview-content .mermaid-shell.is-maximized {
115
+ position: fixed;
116
+ inset: var(--space-4);
117
+ z-index: 171;
118
+ width: auto;
119
+ max-width: none;
120
+ margin: 0;
121
+ box-shadow: var(--shadow-lg);
122
+ grid-template-rows: auto minmax(0, 1fr);
123
+ }
124
+
125
+ .preview-content .mermaid-shell.is-maximized .mermaid-frame {
126
+ max-height: none;
127
+ height: 100%;
128
+ }
129
+
130
+ .preview-content .plantuml-shell,
131
+ .plantuml-maximized-root .plantuml-shell {
132
+ display: grid;
133
+ gap: 0;
134
+ min-width: 0;
135
+ width: 100%;
136
+ }
137
+
138
+ .preview-content .plantuml-placeholder-card,
139
+ .plantuml-maximized-root .plantuml-placeholder-card {
140
+ border-radius: 0;
141
+ }
142
+
143
+ .preview-content .plantuml-tool-btn:disabled,
144
+ .plantuml-maximized-root .plantuml-tool-btn:disabled {
145
+ opacity: 0.5;
146
+ cursor: not-allowed;
147
+ }
148
+
149
+ .preview-content .plantuml-toolbar,
150
+ .plantuml-maximized-root .plantuml-toolbar {
151
+ justify-content: flex-end;
152
+ }
153
+
154
+ .preview-content .plantuml-tool-btn,
155
+ .plantuml-maximized-root .plantuml-tool-btn {
156
+ min-width: 32px;
157
+ line-height: 1.5;
158
+ }
159
+
160
+ .preview-content .plantuml-frame,
161
+ .plantuml-maximized-root .plantuml-frame {
162
+ max-width: 100%;
163
+ }
164
+
165
+ .preview-content .plantuml-frame.is-pannable,
166
+ .plantuml-maximized-root .plantuml-frame.is-pannable {
167
+ cursor: grab;
168
+ }
169
+
170
+ .preview-content .plantuml-frame.is-dragging,
171
+ .plantuml-maximized-root .plantuml-frame.is-dragging {
172
+ cursor: grabbing;
173
+ user-select: none;
174
+ }
175
+
176
+ .preview-content .plantuml-frame svg,
177
+ .plantuml-maximized-root .plantuml-frame svg {
178
+ display: block;
179
+ }
180
+
181
+ body.plantuml-maximized-open {
182
+ overflow: hidden;
183
+ }
184
+
185
+ body.plantuml-maximized-open::before {
186
+ content: '';
187
+ position: fixed;
188
+ inset: 0;
189
+ z-index: 170;
190
+ background: var(--surface-scrim);
191
+ backdrop-filter: blur(2px);
192
+ }
193
+
194
+ .plantuml-maximized-root {
195
+ position: fixed;
196
+ inset: 0;
197
+ z-index: 171;
198
+ pointer-events: none;
199
+ }
200
+
201
+ .preview-content .plantuml-shell.is-maximized,
202
+ .plantuml-maximized-root .plantuml-shell.is-maximized {
203
+ position: fixed;
204
+ inset: var(--space-4);
205
+ z-index: 171;
206
+ width: auto;
207
+ max-width: none;
208
+ margin: 0;
209
+ box-shadow: var(--shadow-lg);
210
+ pointer-events: auto;
211
+ grid-template-rows: auto minmax(0, 1fr);
212
+ }
213
+
214
+ .preview-content .plantuml-shell.is-maximized .plantuml-frame,
215
+ .plantuml-maximized-root .plantuml-shell.is-maximized .plantuml-frame {
216
+ max-height: none;
217
+ height: 100%;
218
+ }
@@ -0,0 +1,155 @@
1
+ /* ===== GIT / BRANCH ===== */
2
+
3
+ .git-panel {
4
+ flex: 1;
5
+ display: flex;
6
+ flex-direction: column;
7
+ overflow-y: auto;
8
+ }
9
+
10
+ .git-panel.active {
11
+ display: flex;
12
+ }
13
+
14
+ .git-branch-bar {
15
+ display: flex;
16
+ flex-direction: column;
17
+ align-items: stretch;
18
+ gap: var(--space-2);
19
+ padding: var(--space-3);
20
+ border-bottom: 1px solid var(--color-divider);
21
+ font-size: var(--text-xs);
22
+ }
23
+
24
+ .git-branch-meta {
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: space-between;
28
+ gap: var(--space-3);
29
+ min-width: 0;
30
+ width: 100%;
31
+ }
32
+
33
+ .git-branch-name {
34
+ display: inline-flex;
35
+ align-items: center;
36
+ gap: 6px;
37
+ min-width: 0;
38
+ max-width: 100%;
39
+ padding: 3px 8px;
40
+ border-radius: var(--radius-sm);
41
+ background: var(--color-surface-offset);
42
+ color: var(--color-text);
43
+ font-family: var(--font-mono);
44
+ font-size: var(--text-label);
45
+ font-weight: 500;
46
+ }
47
+
48
+ .git-branch-name svg {
49
+ flex-shrink: 0;
50
+ color: var(--color-primary);
51
+ }
52
+
53
+ .git-sync-info {
54
+ display: inline-flex;
55
+ align-items: center;
56
+ gap: var(--space-2);
57
+ font-family: var(--font-mono);
58
+ font-size: var(--text-meta);
59
+ flex-shrink: 0;
60
+ }
61
+
62
+ .git-sync-metric {
63
+ display: inline-flex;
64
+ align-items: center;
65
+ gap: 2px;
66
+ }
67
+
68
+ .git-sync-metric--ahead {
69
+ color: var(--color-success);
70
+ }
71
+
72
+ .git-sync-metric--behind {
73
+ color: var(--color-text-faint);
74
+ }
75
+
76
+ .git-sync-info-muted {
77
+ color: var(--color-text-faint);
78
+ }
79
+
80
+ .git-change-stats {
81
+ display: inline-flex;
82
+ align-items: center;
83
+ gap: var(--space-2);
84
+ font-family: var(--font-mono);
85
+ font-size: var(--text-meta);
86
+ font-weight: 600;
87
+ flex-shrink: 0;
88
+ }
89
+
90
+ .git-branch-actions {
91
+ display: grid;
92
+ grid-template-columns: repeat(2, minmax(0, 1fr));
93
+ gap: 6px;
94
+ width: 100%;
95
+ }
96
+
97
+ .git-panel-mode-switch {
98
+ display: inline-grid;
99
+ grid-template-columns: repeat(2, minmax(0, 1fr));
100
+ }
101
+
102
+ .git-panel-mode-btn {
103
+ min-width: 0;
104
+ }
105
+
106
+ .git-branch-actions .ui-action-pill {
107
+ width: 100%;
108
+ justify-content: center;
109
+ }
110
+
111
+ .git-branch-actions .ui-action-pill svg {
112
+ flex-shrink: 0;
113
+ }
114
+
115
+ .git-change-add {
116
+ color: var(--diff-add-text);
117
+ }
118
+
119
+ .git-change-del {
120
+ color: var(--diff-del-text);
121
+ }
122
+
123
+ .git-panel-footer {
124
+ margin-top: auto;
125
+ padding: var(--space-3);
126
+ border-top: 1px solid var(--color-divider);
127
+ }
128
+
129
+ .git-panel-footer-actions {
130
+ display: flex;
131
+ flex-direction: column;
132
+ gap: var(--space-2);
133
+ }
134
+
135
+ .git-panel-footer-actions .ui-action-button {
136
+ width: 100%;
137
+ }
138
+
139
+ .git-footer-commit-btn {
140
+ width: 100%;
141
+ border: 1px solid var(--border-accent-soft);
142
+ background: var(--surface-accent-soft);
143
+ color: var(--color-primary);
144
+ }
145
+
146
+ .git-footer-commit-btn:hover:not(:disabled) {
147
+ background: var(--surface-accent-strong);
148
+ }
149
+
150
+ .git-panel-empty {
151
+ padding: var(--space-4);
152
+ color: var(--color-text-faint);
153
+ text-align: center;
154
+ font-size: var(--text-xs);
155
+ }