cardbuddy 0.6.0 → 0.7.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/dist/preview-editor/assets/{index-BYB0hngG.js → index-BlscexDE.js} +18 -11
- package/dist/preview-editor/assets/index-dlbSPb5W.css +1 -0
- package/dist/preview-editor/index.html +2 -2
- package/dist/server-core/cardFiles.js +9 -4
- package/dist/server-core/index.js +6 -0
- package/dist/server-core/sliceUpload.js +97 -0
- package/dist/vendored/App.vue +263 -44
- package/dist/vendored/assets/svgIcons/icons.svg +5 -0
- package/dist/vendored/components/ApiCallPanel.vue +115 -0
- package/dist/vendored/components/CardGallery.vue +2 -0
- package/dist/vendored/components/CardSelect.vue +6 -0
- package/dist/vendored/components/ConfirmDialog.vue +20 -5
- package/dist/vendored/components/DebugPanel.vue +22 -88
- package/dist/vendored/components/JsonTree.vue +35 -4
- package/dist/vendored/components/StructureTree.vue +53 -2
- package/dist/vendored/styles/app.css +142 -51
- package/dist/vendored/styles/card-gallery.css +20 -0
- package/dist/vendored/styles/card-select.css +15 -0
- package/dist/vendored/styles/json-tree.css +1 -1
- package/dist/vendored/styles/structure-tree.css +135 -5
- package/package.json +1 -1
- package/dist/preview-editor/assets/index-CpBZEQDy.css +0 -1
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
说明:设备模拟 UI(.dlg / .dtoast / .pk-* 等原生弹框白底)模拟真机外观,不随主题变化,保持固定。 */
|
|
4
4
|
/* 配色 Token 与《深浅主题配色规范手册》映射(语义单一 / 双主题同义词切换):
|
|
5
5
|
--accent/-2/-soft/-border/-hover = 主色 color-primary(及 hover/active 变体)
|
|
6
|
-
--ok/-soft/-border/-strong
|
|
7
|
-
--
|
|
6
|
+
--ok/-soft/-border/-strong/-solid = 成功 success(深色提亮 #34D399 / 浅色 #10B981)
|
|
7
|
+
--on-ok = 成功实心填充(--ok-solid)上的文字
|
|
8
|
+
--warn/-soft/-border/-hover = 警告 warning(琥珀);--on-warn = 警告实心填充上的深色文字
|
|
8
9
|
--danger/-soft/-hover = 错误 / 危险 error(红)
|
|
9
10
|
--info/-soft/-border = 信息 info(与主色同源,均为蓝)
|
|
10
11
|
--on-accent = 主色填充上的文字(深色 #0F1115 / 浅色 #fff)
|
|
@@ -38,10 +39,16 @@
|
|
|
38
39
|
--warn: #FBBF24;
|
|
39
40
|
--warn-soft: rgba(251, 191, 36, 0.14);
|
|
40
41
|
--warn-border: rgba(251, 191, 36, 0.4);
|
|
42
|
+
--warn-hover: #F59E0B;
|
|
43
|
+
--on-warn: #0F1115;
|
|
41
44
|
--ok: #34D399;
|
|
42
45
|
--ok-soft: rgba(52, 211, 153, 0.16);
|
|
43
46
|
--ok-border: rgba(52, 211, 153, 0.45);
|
|
44
47
|
--ok-strong: #34D399;
|
|
48
|
+
/* 成功态「实心填充」徽标(标签 / 角标浮在任意底色上时用):--ok-solid 为底、--on-ok 为其上文字。
|
|
49
|
+
与 --ok-soft(半透明,仅适合压在已知面板色上)区分:实心版不透明,浮在白色缩略图上仍达 WCAG AA。 */
|
|
50
|
+
--ok-solid: #17734A;
|
|
51
|
+
--on-ok: #ffffff;
|
|
45
52
|
--info: #6B83F7;
|
|
46
53
|
--info-soft: rgba(107, 131, 247, 0.14);
|
|
47
54
|
--info-border: rgba(107, 131, 247, 0.45);
|
|
@@ -192,10 +199,14 @@
|
|
|
192
199
|
--warn: #F59E0B;
|
|
193
200
|
--warn-soft: rgba(245, 158, 11, 0.14);
|
|
194
201
|
--warn-border: rgba(245, 158, 11, 0.4);
|
|
202
|
+
--warn-hover: #D97706;
|
|
203
|
+
--on-warn: #0F1115;
|
|
195
204
|
--ok: #10B981;
|
|
196
205
|
--ok-soft: rgba(16, 185, 129, 0.14);
|
|
197
206
|
--ok-border: rgba(16, 185, 129, 0.4);
|
|
198
207
|
--ok-strong: #166534;
|
|
208
|
+
--ok-solid: #166534;
|
|
209
|
+
--on-ok: #ffffff;
|
|
199
210
|
--info: #4F6BF2;
|
|
200
211
|
--info-soft: rgba(79, 107, 242, 0.12);
|
|
201
212
|
--info-border: rgba(79, 107, 242, 0.4);
|
|
@@ -382,6 +393,12 @@ body {
|
|
|
382
393
|
height: var(--ctrl-md);
|
|
383
394
|
padding: 0 8px;
|
|
384
395
|
}
|
|
396
|
+
/* 开关型图标按钮的「开启」态(如右侧接口调用面板开关):用主题色标示当前已展开 */
|
|
397
|
+
.app__btn--active {
|
|
398
|
+
background: var(--accent-soft);
|
|
399
|
+
color: var(--accent);
|
|
400
|
+
border-color: var(--accent-border);
|
|
401
|
+
}
|
|
385
402
|
/* 顶栏图标按钮(刷新 / 连接)与远端、op-group 统一为 28px(--ctrl-sm),不再高 32px */
|
|
386
403
|
.app__bar .app__btn--icon {
|
|
387
404
|
height: var(--ctrl-sm);
|
|
@@ -423,11 +440,16 @@ body {
|
|
|
423
440
|
.app__icon--chev {
|
|
424
441
|
transition: transform 0.15s;
|
|
425
442
|
}
|
|
426
|
-
/*
|
|
443
|
+
/* 下拉项:保存/上传类 hover 蓝色与琥珀、同步类 hover 绿色(基础布局见 dropdown.css .app__remote-item) */
|
|
427
444
|
.app__remote-item--save:hover {
|
|
428
445
|
background: var(--accent-soft);
|
|
429
446
|
color: var(--accent);
|
|
430
447
|
}
|
|
448
|
+
/* 切图上传:琥珀色,与「版本推送」(蓝)、「同步」(绿)区分——传的是素材不是版本 */
|
|
449
|
+
.app__remote-item--upload:hover {
|
|
450
|
+
background: var(--warn-soft);
|
|
451
|
+
color: var(--warn);
|
|
452
|
+
}
|
|
431
453
|
.app__remote-item--sync:hover {
|
|
432
454
|
background: var(--ok-soft);
|
|
433
455
|
color: var(--ok);
|
|
@@ -845,6 +867,27 @@ body {
|
|
|
845
867
|
position: relative; /* 作为绝对定位 splitter 的定位上下文 */
|
|
846
868
|
}
|
|
847
869
|
|
|
870
|
+
/* 中右工作区:纵向 flex——上为「调试面板 + 接口调用面板」两栏,下为贯穿两栏的共同状态栏。
|
|
871
|
+
状态栏由 DebugPanel 内 Teleport 注入 .workside__bar;该目标在 DOM 中先于两栏容器
|
|
872
|
+
(Teleport 挂载要求目标已存在),故用 order 把它视觉置底。 */
|
|
873
|
+
.workside {
|
|
874
|
+
flex: 1 1 auto;
|
|
875
|
+
display: flex;
|
|
876
|
+
flex-direction: column;
|
|
877
|
+
min-width: 0;
|
|
878
|
+
min-height: 0;
|
|
879
|
+
}
|
|
880
|
+
.workside__bar {
|
|
881
|
+
flex: 0 0 auto;
|
|
882
|
+
order: 1;
|
|
883
|
+
}
|
|
884
|
+
.workside__cols {
|
|
885
|
+
flex: 1 1 auto;
|
|
886
|
+
display: flex;
|
|
887
|
+
min-width: 0;
|
|
888
|
+
min-height: 0;
|
|
889
|
+
}
|
|
890
|
+
|
|
848
891
|
.phone {
|
|
849
892
|
flex: 0 0 auto;
|
|
850
893
|
display: flex;
|
|
@@ -889,6 +932,11 @@ body {
|
|
|
889
932
|
z-index: var(--z-sticky);
|
|
890
933
|
transition: background 0.15s ease;
|
|
891
934
|
}
|
|
935
|
+
/* 中右分隔条:以右侧「接口调用」面板右缘(即舞台右缘)回推面板宽度定位接缝 */
|
|
936
|
+
.splitter--api {
|
|
937
|
+
left: auto;
|
|
938
|
+
right: calc(var(--api-panel-width, 360px) - 3px);
|
|
939
|
+
}
|
|
892
940
|
.splitter:hover,
|
|
893
941
|
.splitter.is-dragging {
|
|
894
942
|
background: var(--splitter);
|
|
@@ -1082,17 +1130,84 @@ body {
|
|
|
1082
1130
|
flex: 1 1 auto;
|
|
1083
1131
|
display: flex;
|
|
1084
1132
|
flex-direction: column;
|
|
1085
|
-
|
|
1133
|
+
/* 中栏最小宽度:不得小于三分之一屏幕宽度(与中右分隔条 startApiDrag 的夹取一致) */
|
|
1134
|
+
min-width: 33.333vw;
|
|
1135
|
+
background: var(--bg-panel);
|
|
1136
|
+
border-left: 1px solid var(--border);
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
/* 右侧常驻「接口调用」面板:默认 360px 宽,可经中右分隔条拖拽调节(最小 320px,
|
|
1140
|
+
宽度由 App 以 --api-panel-width CSS 变量下发),与预览列 / 调试面板呈左中右布局。
|
|
1141
|
+
展开/收起由顶栏按钮与面板内 ✕ 控制(v-if 整体挂载/卸载)。 */
|
|
1142
|
+
.apipanel {
|
|
1143
|
+
flex: 0 0 auto;
|
|
1144
|
+
width: var(--api-panel-width, 360px);
|
|
1145
|
+
min-width: 320px;
|
|
1146
|
+
display: flex;
|
|
1147
|
+
flex-direction: column;
|
|
1148
|
+
min-height: 0;
|
|
1086
1149
|
background: var(--bg-panel);
|
|
1087
1150
|
border-left: 1px solid var(--border);
|
|
1088
1151
|
}
|
|
1152
|
+
.apipanel__head {
|
|
1153
|
+
flex: 0 0 auto;
|
|
1154
|
+
display: flex;
|
|
1155
|
+
align-items: center;
|
|
1156
|
+
gap: 8px;
|
|
1157
|
+
/* 与调试面板 tab 条同高(12px 上下 padding + 13px 字号 ≈ 42px),保证三条栏顶线对齐 */
|
|
1158
|
+
height: 40px;
|
|
1159
|
+
padding: 0 12px;
|
|
1160
|
+
border-bottom: 1px solid var(--border);
|
|
1161
|
+
}
|
|
1162
|
+
.apipanel__title {
|
|
1163
|
+
font-size: 13px;
|
|
1164
|
+
font-weight: 600;
|
|
1165
|
+
color: var(--text);
|
|
1166
|
+
white-space: nowrap;
|
|
1167
|
+
}
|
|
1168
|
+
.apipanel__spacer {
|
|
1169
|
+
flex: 1 1 auto;
|
|
1170
|
+
}
|
|
1171
|
+
.apipanel__btn {
|
|
1172
|
+
flex: 0 0 auto;
|
|
1173
|
+
display: inline-flex;
|
|
1174
|
+
align-items: center;
|
|
1175
|
+
justify-content: center;
|
|
1176
|
+
width: 28px;
|
|
1177
|
+
height: 28px;
|
|
1178
|
+
padding: 0;
|
|
1179
|
+
background: transparent;
|
|
1180
|
+
color: var(--text-dim);
|
|
1181
|
+
border: 1px solid transparent;
|
|
1182
|
+
border-radius: 8px;
|
|
1183
|
+
cursor: pointer;
|
|
1184
|
+
transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.05s;
|
|
1185
|
+
}
|
|
1186
|
+
.apipanel__btn:hover:not(:disabled) {
|
|
1187
|
+
background: var(--bg-hover);
|
|
1188
|
+
border-color: var(--border);
|
|
1189
|
+
color: var(--text);
|
|
1190
|
+
}
|
|
1191
|
+
.apipanel__btn:active:not(:disabled) {
|
|
1192
|
+
transform: translateY(1px);
|
|
1193
|
+
}
|
|
1194
|
+
.apipanel__btn:disabled {
|
|
1195
|
+
opacity: 0.5;
|
|
1196
|
+
cursor: default;
|
|
1197
|
+
}
|
|
1198
|
+
.apipanel__body {
|
|
1199
|
+
flex: 1 1 auto;
|
|
1200
|
+
overflow: auto;
|
|
1201
|
+
padding: 8px 12px;
|
|
1202
|
+
}
|
|
1089
1203
|
.debug__tabs {
|
|
1090
1204
|
display: flex;
|
|
1091
1205
|
border-bottom: 1px solid var(--border);
|
|
1092
1206
|
}
|
|
1093
1207
|
.debug__tab {
|
|
1094
1208
|
flex: 1;
|
|
1095
|
-
padding:
|
|
1209
|
+
padding: 10px 8px;
|
|
1210
|
+
height: 39px;
|
|
1096
1211
|
background: transparent;
|
|
1097
1212
|
border: none;
|
|
1098
1213
|
color: var(--text-dim);
|
|
@@ -1133,12 +1248,11 @@ body {
|
|
|
1133
1248
|
position: relative;
|
|
1134
1249
|
flex: 1 1 auto;
|
|
1135
1250
|
overflow: auto;
|
|
1136
|
-
padding: 12px 16px;
|
|
1251
|
+
/* padding: 12px 16px; */
|
|
1137
1252
|
}
|
|
1138
|
-
.
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
height: 38px;
|
|
1253
|
+
.debug__meta {
|
|
1254
|
+
margin: 0;
|
|
1255
|
+
padding: 8px 12px;
|
|
1142
1256
|
}
|
|
1143
1257
|
.debug__empty {
|
|
1144
1258
|
color: var(--text-faint);
|
|
@@ -1282,42 +1396,6 @@ body {
|
|
|
1282
1396
|
color: var(--danger);
|
|
1283
1397
|
background: var(--danger-soft);
|
|
1284
1398
|
}
|
|
1285
|
-
/* 接口调用标签页工具条(仿 Chrome 控制台) */
|
|
1286
|
-
.debug__clear {
|
|
1287
|
-
/* 通用带边框按钮:固定在接口调用 tab 右上角、不随滚动,方便随时清空日志 */
|
|
1288
|
-
position: sticky;
|
|
1289
|
-
top: 0;
|
|
1290
|
-
float: right;
|
|
1291
|
-
z-index: var(--z-sticky);
|
|
1292
|
-
display: inline-flex;
|
|
1293
|
-
align-items: center;
|
|
1294
|
-
justify-content: center;
|
|
1295
|
-
width: 28px;
|
|
1296
|
-
height: 28px;
|
|
1297
|
-
padding: 0;
|
|
1298
|
-
background: var(--bg-input);
|
|
1299
|
-
color: var(--text);
|
|
1300
|
-
border: 1px solid var(--border-strong);
|
|
1301
|
-
border-radius: 8px;
|
|
1302
|
-
cursor: pointer;
|
|
1303
|
-
box-shadow: -10px 0 10px var(--bg-panel);
|
|
1304
|
-
transition: background 0.15s, border-color 0.15s, transform 0.05s;
|
|
1305
|
-
}
|
|
1306
|
-
.debug__clear:hover:not(:disabled) {
|
|
1307
|
-
background: var(--bg-hover);
|
|
1308
|
-
border-color: var(--accent-border);
|
|
1309
|
-
}
|
|
1310
|
-
.debug__clear:active:not(:disabled) {
|
|
1311
|
-
transform: translateY(1px);
|
|
1312
|
-
}
|
|
1313
|
-
.debug__clear:disabled {
|
|
1314
|
-
opacity: 0.5;
|
|
1315
|
-
cursor: default;
|
|
1316
|
-
}
|
|
1317
|
-
/* 接口调用列表顶部留白,避免首行被右上角浮动的清空按钮遮挡 */
|
|
1318
|
-
.debug__list--api {
|
|
1319
|
-
padding-top: 34px;
|
|
1320
|
-
}
|
|
1321
1399
|
.debug__list {
|
|
1322
1400
|
list-style: none;
|
|
1323
1401
|
margin: 0;
|
|
@@ -1456,7 +1534,7 @@ body {
|
|
|
1456
1534
|
/* right:0 让 JSON 树滚动条紧贴面板最右边(与其他 tab 用 body padding 作
|
|
1457
1535
|
16px 滚动框不同,本 tab 滚动交给内部 .debug__scope-tree,需要贴边);
|
|
1458
1536
|
left:16px 与 body 的 16px 内边距对齐,让树内容左缘与其他 tab 一致。 */
|
|
1459
|
-
inset:
|
|
1537
|
+
inset: 0;
|
|
1460
1538
|
display: flex;
|
|
1461
1539
|
flex-direction: column;
|
|
1462
1540
|
min-height: 0;
|
|
@@ -1521,8 +1599,8 @@ body {
|
|
|
1521
1599
|
padding: 12px 14px;
|
|
1522
1600
|
background: var(--bg-input);
|
|
1523
1601
|
color: var(--text);
|
|
1524
|
-
border: 1px solid var(--border-strong);
|
|
1525
|
-
border-radius: 8px;
|
|
1602
|
+
/* border: 1px solid var(--border-strong); */
|
|
1603
|
+
/* border-radius: 8px; */
|
|
1526
1604
|
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
1527
1605
|
font-size: 12px;
|
|
1528
1606
|
line-height: 1.6;
|
|
@@ -1531,9 +1609,9 @@ body {
|
|
|
1531
1609
|
overflow: auto;
|
|
1532
1610
|
outline: none;
|
|
1533
1611
|
}
|
|
1534
|
-
.debug__raw-editor:focus {
|
|
1612
|
+
/* .debug__raw-editor:focus {
|
|
1535
1613
|
border-color: var(--accent-border);
|
|
1536
|
-
}
|
|
1614
|
+
} */
|
|
1537
1615
|
/* CodeJar 托管的原始 JSON 编辑器:Prism(json) 语法高亮配色(与 SetCode 暗色面板一致) */
|
|
1538
1616
|
.debug__raw-editor .token.property,
|
|
1539
1617
|
.debug__raw-editor .token.tag,
|
|
@@ -2503,6 +2581,10 @@ body {
|
|
|
2503
2581
|
.confirm-modal__title.is-danger {
|
|
2504
2582
|
color: var(--danger);
|
|
2505
2583
|
}
|
|
2584
|
+
/* 警告级(warn):覆盖推送类操作(版本推送等)——标题与图标取琥珀警告色,见配色规范 §2.7 / §3.4 */
|
|
2585
|
+
.confirm-modal__title.is-warn {
|
|
2586
|
+
color: var(--warn);
|
|
2587
|
+
}
|
|
2506
2588
|
.confirm-modal__icon {
|
|
2507
2589
|
width: 18px;
|
|
2508
2590
|
height: 18px;
|
|
@@ -2555,6 +2637,15 @@ body {
|
|
|
2555
2637
|
.confirm-modal__btn--danger:hover {
|
|
2556
2638
|
background: var(--danger-hover);
|
|
2557
2639
|
}
|
|
2640
|
+
/* 警告级确认按钮:琥珀实心 + 深色文字(琥珀底白字对比度不足,双主题统一深色 ink) */
|
|
2641
|
+
.confirm-modal__btn--warn {
|
|
2642
|
+
border-color: var(--warn);
|
|
2643
|
+
background: var(--warn);
|
|
2644
|
+
color: var(--on-warn);
|
|
2645
|
+
}
|
|
2646
|
+
.confirm-modal__btn--warn:hover {
|
|
2647
|
+
background: var(--warn-hover);
|
|
2648
|
+
}
|
|
2558
2649
|
.confirm-fade-enter-active,
|
|
2559
2650
|
.confirm-fade-leave-active {
|
|
2560
2651
|
transition: opacity 0.15s ease;
|
|
@@ -170,6 +170,26 @@
|
|
|
170
170
|
background: #fff;
|
|
171
171
|
border-bottom: 1px solid var(--border);
|
|
172
172
|
}
|
|
173
|
+
/* 导入角标:悬浮在缩略图右上角,仅「有 .import-meta.json 侧车」的导入卡显示。
|
|
174
|
+
配色用成功态「实心」token(--ok-solid 底 + --on-ok 白字 + --ok-solid 同色描边):
|
|
175
|
+
缩略图恒为白底,半透明的 --ok-soft 压上去会被吃成 ~2:1,实心深绿才达 WCAG AA,
|
|
176
|
+
且与顶栏 .app__badge--ok 同属 success 语义、不引入新色相。圆角取 --radius-xs(方形小标),无阴影。 */
|
|
177
|
+
.cg-tile__tag {
|
|
178
|
+
position: absolute;
|
|
179
|
+
top: 6px;
|
|
180
|
+
right: 6px;
|
|
181
|
+
z-index: 1;
|
|
182
|
+
padding: 2px 8px;
|
|
183
|
+
border-radius: var(--radius-xs);
|
|
184
|
+
background: var(--ok-strong);
|
|
185
|
+
color: var(--on-ok);
|
|
186
|
+
font-size: var(--fs-xs);
|
|
187
|
+
font-weight: 600;
|
|
188
|
+
line-height: 1.5;
|
|
189
|
+
white-space: nowrap;
|
|
190
|
+
user-select: none;
|
|
191
|
+
pointer-events: none;
|
|
192
|
+
}
|
|
173
193
|
.cg-tile__img {
|
|
174
194
|
width: 100%;
|
|
175
195
|
height: 100%;
|
|
@@ -121,6 +121,21 @@
|
|
|
121
121
|
.csel__item--selected .csel__item-id {
|
|
122
122
|
color: var(--accent);
|
|
123
123
|
}
|
|
124
|
+
/* 卡片来源圆点(6x6):绿色 = 导入卡(有 .import-meta.json),灰色 = 本地卡(无来源信息)。
|
|
125
|
+
align-self:center + 固定行高保证与右侧 id/name 文本视觉居中对齐(不受行高影响)。 */
|
|
126
|
+
.csel__dot {
|
|
127
|
+
flex: 0 0 auto;
|
|
128
|
+
align-self: center;
|
|
129
|
+
width: 6px;
|
|
130
|
+
height: 6px;
|
|
131
|
+
border-radius: 50%;
|
|
132
|
+
background: var(--text-faint);
|
|
133
|
+
opacity: 0.75;
|
|
134
|
+
}
|
|
135
|
+
.csel__dot--imported {
|
|
136
|
+
background: var(--ok);
|
|
137
|
+
opacity: 1;
|
|
138
|
+
}
|
|
124
139
|
.csel__item-id {
|
|
125
140
|
font-weight: 600;
|
|
126
141
|
color: var(--text);
|
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
.st {
|
|
9
9
|
position: relative;
|
|
10
10
|
min-height: 100%;
|
|
11
|
+
/* flex 列布局 + 底部帮助按钮 margin-top:auto:内容不足一屏时按钮仍吸附面板底部 */
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
/* 顶部工具条:与 JsonTree 的 .jt__toolbar 同款(sticky 顶部),
|
|
@@ -16,7 +19,7 @@
|
|
|
16
19
|
display: flex;
|
|
17
20
|
justify-content: flex-start;
|
|
18
21
|
gap: 12px;
|
|
19
|
-
padding:
|
|
22
|
+
padding: 8px 12px;
|
|
20
23
|
position: sticky;
|
|
21
24
|
top: 0;
|
|
22
25
|
z-index: var(--z-sticky);
|
|
@@ -86,14 +89,141 @@
|
|
|
86
89
|
list-style: none;
|
|
87
90
|
}
|
|
88
91
|
|
|
89
|
-
/*
|
|
90
|
-
|
|
92
|
+
/* 帮助悬浮按钮容器:零高度 sticky 吸附在滚动视口底部(滚动容器为外层 .debug__body),
|
|
93
|
+
内容过长时按钮仍固定于面板左下角可见,且不占用固定布局区域 */
|
|
94
|
+
.st__help-wrap {
|
|
95
|
+
position: sticky;
|
|
96
|
+
bottom: 10px;
|
|
97
|
+
height: 0;
|
|
98
|
+
z-index: var(--z-pop);
|
|
99
|
+
/* 内容较短时把按钮推到 .st 底部(即面板可见区底部);内容较长时由 sticky 吸附兜底 */
|
|
100
|
+
margin-top: auto;
|
|
101
|
+
}
|
|
102
|
+
.st__help {
|
|
103
|
+
position: absolute;
|
|
104
|
+
left: 10px;
|
|
105
|
+
bottom: 0;
|
|
106
|
+
display: inline-flex;
|
|
107
|
+
align-items: center;
|
|
108
|
+
justify-content: center;
|
|
109
|
+
width: 28px;
|
|
110
|
+
height: 28px;
|
|
111
|
+
padding: 0;
|
|
112
|
+
background: var(--bg-input);
|
|
113
|
+
color: var(--text-dim);
|
|
114
|
+
border: 1px solid var(--border-strong);
|
|
115
|
+
border-radius: 50%;
|
|
116
|
+
cursor: pointer;
|
|
117
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
|
|
118
|
+
transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.05s;
|
|
119
|
+
}
|
|
120
|
+
.st__help:hover {
|
|
121
|
+
background: var(--bg-hover);
|
|
122
|
+
border-color: var(--accent-border);
|
|
123
|
+
color: var(--accent);
|
|
124
|
+
}
|
|
125
|
+
.st__help:active {
|
|
126
|
+
transform: translateY(1px);
|
|
127
|
+
}
|
|
128
|
+
/* 气泡展开时按钮保持激活态配色 */
|
|
129
|
+
.st__help--open {
|
|
130
|
+
background: var(--accent-soft);
|
|
131
|
+
border-color: var(--accent-border);
|
|
132
|
+
color: var(--accent);
|
|
133
|
+
}
|
|
134
|
+
/* 使用说明气泡:自左下角按钮向上弹出 */
|
|
135
|
+
.st__help-pop {
|
|
136
|
+
position: absolute;
|
|
137
|
+
left: 10px;
|
|
138
|
+
bottom: 36px;
|
|
139
|
+
width: 300px;
|
|
140
|
+
background: var(--bg-panel);
|
|
141
|
+
border: 1px solid var(--border-strong);
|
|
142
|
+
border-radius: 10px;
|
|
143
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
|
|
144
|
+
}
|
|
145
|
+
.st__help-pop-head {
|
|
146
|
+
display: flex;
|
|
147
|
+
align-items: center;
|
|
148
|
+
justify-content: space-between;
|
|
149
|
+
padding: 8px 12px;
|
|
150
|
+
border-bottom: 1px solid var(--border);
|
|
151
|
+
}
|
|
152
|
+
.st__help-pop-title {
|
|
153
|
+
font-size: 12px;
|
|
154
|
+
font-weight: 600;
|
|
155
|
+
color: var(--text);
|
|
156
|
+
}
|
|
157
|
+
.st__help-pop-close {
|
|
158
|
+
display: inline-flex;
|
|
159
|
+
align-items: center;
|
|
160
|
+
justify-content: center;
|
|
161
|
+
width: 18px;
|
|
162
|
+
height: 18px;
|
|
163
|
+
padding: 0;
|
|
164
|
+
background: none;
|
|
165
|
+
border: none;
|
|
166
|
+
color: var(--text-faint);
|
|
167
|
+
font-size: 12px;
|
|
168
|
+
cursor: pointer;
|
|
169
|
+
border-radius: 4px;
|
|
170
|
+
transition: background 0.15s, color 0.15s;
|
|
171
|
+
}
|
|
172
|
+
.st__help-pop-close:hover {
|
|
173
|
+
background: var(--bg-hover);
|
|
174
|
+
color: var(--text);
|
|
175
|
+
}
|
|
176
|
+
.st__help-pop-body {
|
|
91
177
|
margin: 0;
|
|
92
|
-
padding:
|
|
178
|
+
padding: 10px 12px;
|
|
179
|
+
color: var(--text-dim);
|
|
180
|
+
font-size: 12px;
|
|
181
|
+
line-height: 1.6;
|
|
182
|
+
}
|
|
183
|
+
/* 快捷键清单:左列按键示意(kbd 芯片),右列一句话说明 */
|
|
184
|
+
.st__keys {
|
|
185
|
+
list-style: none;
|
|
186
|
+
display: flex;
|
|
187
|
+
flex-direction: column;
|
|
188
|
+
gap: 8px;
|
|
189
|
+
}
|
|
190
|
+
.st__keys-row {
|
|
191
|
+
display: flex;
|
|
192
|
+
align-items: center;
|
|
193
|
+
gap: 10px;
|
|
194
|
+
}
|
|
195
|
+
.st__keys-combo {
|
|
196
|
+
flex: 0 0 108px; /* 左列固定宽度,组合键纵向对齐 */
|
|
197
|
+
display: inline-flex;
|
|
198
|
+
align-items: center;
|
|
199
|
+
gap: 3px;
|
|
200
|
+
white-space: nowrap;
|
|
201
|
+
}
|
|
202
|
+
.st__kbd {
|
|
203
|
+
display: inline-flex;
|
|
204
|
+
align-items: center;
|
|
205
|
+
justify-content: center;
|
|
206
|
+
min-width: 20px;
|
|
207
|
+
height: 20px;
|
|
208
|
+
padding: 0 5px;
|
|
209
|
+
background: var(--bg-input);
|
|
210
|
+
color: var(--text);
|
|
211
|
+
border: 1px solid var(--border-strong);
|
|
212
|
+
border-bottom-width: 2px; /* 键帽底部加厚,模拟按键立体感 */
|
|
213
|
+
border-radius: 5px;
|
|
214
|
+
font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace);
|
|
215
|
+
font-size: 11px;
|
|
216
|
+
line-height: 1;
|
|
217
|
+
}
|
|
218
|
+
.st__kbd-plus {
|
|
93
219
|
color: var(--text-faint);
|
|
94
220
|
font-size: 11px;
|
|
221
|
+
}
|
|
222
|
+
.st__keys-desc {
|
|
223
|
+
flex: 1 1 auto;
|
|
224
|
+
color: var(--text-dim);
|
|
225
|
+
font-size: 12px;
|
|
95
226
|
line-height: 1.5;
|
|
96
|
-
border-bottom: 1px solid var(--border);
|
|
97
227
|
}
|
|
98
228
|
|
|
99
229
|
.st__node {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cardbuddy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Local dev service for the CardBuddy card editor — decouples card CRUD (sync/save/validate/render-status/screenshot) from the static public editor, so the editor can be deployed to any static host while each developer runs a local service against their own card source.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|