@icen.ai/ui 0.5.0 → 0.8.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/AGENTS.md +256 -0
- package/README.md +47 -13
- package/dist/base.css +31 -4
- package/dist/behaviors/accordion.d.mts +4 -0
- package/dist/behaviors/accordion.mjs +4 -3
- package/dist/behaviors/ai-chat.d.mts +57 -0
- package/dist/behaviors/ai-chat.mjs +557 -0
- package/dist/behaviors/ai-composer.d.mts +112 -0
- package/dist/behaviors/ai-composer.mjs +2032 -0
- package/dist/behaviors/ai-core.d.mts +151 -0
- package/dist/behaviors/ai-core.mjs +491 -0
- package/dist/behaviors/ai-diff.d.mts +53 -0
- package/dist/behaviors/ai-diff.mjs +282 -0
- package/dist/behaviors/ai-panel.d.mts +98 -0
- package/dist/behaviors/ai-panel.mjs +1012 -0
- package/dist/behaviors/ai-provider.d.mts +198 -0
- package/dist/behaviors/ai-provider.mjs +1055 -0
- package/dist/behaviors/ai-tool.d.mts +18 -0
- package/dist/behaviors/ai-tool.mjs +2125 -0
- package/dist/behaviors/ai-tools.d.mts +81 -0
- package/dist/behaviors/ai-tools.mjs +1658 -0
- package/dist/behaviors/back-top.d.mts +20 -0
- package/dist/behaviors/back-top.mjs +49 -32
- package/dist/behaviors/carousel.d.mts +4 -0
- package/dist/behaviors/carousel.mjs +34 -16
- package/dist/behaviors/charts.d.mts +250 -0
- package/dist/behaviors/charts.mjs +1301 -448
- package/dist/behaviors/command-palette.d.mts +8 -0
- package/dist/behaviors/command-palette.mjs +24 -12
- package/dist/behaviors/context-menu.d.mts +36 -0
- package/dist/behaviors/context-menu.mjs +6 -2
- package/dist/behaviors/copy.d.mts +4 -0
- package/dist/behaviors/copy.mjs +7 -6
- package/dist/behaviors/datatable.d.mts +78 -0
- package/dist/behaviors/datatable.mjs +54 -11
- package/dist/behaviors/date-picker.d.mts +4 -0
- package/dist/behaviors/date-picker.mjs +104 -36
- package/dist/behaviors/dropdown.d.mts +4 -0
- package/dist/behaviors/dropdown.mjs +7 -3
- package/dist/behaviors/input.d.mts +4 -0
- package/dist/behaviors/input.mjs +29 -22
- package/dist/behaviors/modal.d.mts +11 -0
- package/dist/behaviors/modal.mjs +11 -6
- package/dist/behaviors/nav.d.mts +7 -0
- package/dist/behaviors/nav.mjs +25 -9
- package/dist/behaviors/notification.d.mts +172 -0
- package/dist/behaviors/notification.mjs +243 -89
- package/dist/behaviors/popover.d.mts +46 -0
- package/dist/behaviors/popover.mjs +2 -1
- package/dist/behaviors/select.d.mts +4 -0
- package/dist/behaviors/select.mjs +131 -26
- package/dist/behaviors/sidebar.d.mts +4 -0
- package/dist/behaviors/sidebar.mjs +4 -3
- package/dist/behaviors/slider.d.mts +4 -0
- package/dist/behaviors/slider.mjs +4 -3
- package/dist/behaviors/split-pane.d.mts +4 -0
- package/dist/behaviors/split-pane.mjs +13 -13
- package/dist/behaviors/tabs.d.mts +8 -0
- package/dist/behaviors/tabs.mjs +44 -19
- package/dist/behaviors/tag-input.d.mts +4 -0
- package/dist/behaviors/tag-input.mjs +12 -3
- package/dist/behaviors/theme.d.mts +25 -0
- package/dist/behaviors/theme.mjs +3 -1
- package/dist/behaviors/toast.d.mts +26 -0
- package/dist/behaviors/toast.mjs +24 -18
- package/dist/behaviors/tree.d.mts +4 -0
- package/dist/behaviors/tree.mjs +4 -3
- package/dist/behaviors/upload.d.mts +4 -0
- package/dist/behaviors/upload.mjs +63 -26
- package/dist/components/ai-chat.css +1037 -0
- package/dist/components/ai-chat.mjs +3 -0
- package/dist/components/ai-composer.mjs +3 -0
- package/dist/components/ai-context.mjs +2 -0
- package/dist/components/ai-diff.css +311 -0
- package/dist/components/ai-diff.mjs +3 -0
- package/dist/components/ai-files.mjs +3 -0
- package/dist/components/ai-message.mjs +3 -0
- package/dist/components/ai-panel.css +682 -0
- package/dist/components/ai-reasoning.mjs +3 -0
- package/dist/components/ai-subagent.mjs +2 -0
- package/dist/components/ai-todo.mjs +2 -0
- package/dist/components/ai-tool-call.mjs +2 -0
- package/dist/components/ai-tool.css +532 -0
- package/dist/components/ai-usage.mjs +3 -0
- package/dist/components/badge.css +4 -8
- package/dist/components/breadcrumb.css +1 -5
- package/dist/components/btn.css +4 -7
- package/dist/components/card.css +3 -6
- package/dist/components/chart-bar.css +10 -0
- package/dist/components/chart-calendar.mjs +5 -0
- package/dist/components/chart-gauge.css +1 -1
- package/dist/components/chart-heatmap.css +40 -0
- package/dist/components/chart-scatter.css +24 -0
- package/dist/components/chart-scatter.mjs +4 -0
- package/dist/components/charts.css +86 -1
- package/dist/components/charts.mjs +1 -0
- package/dist/components/command-palette.css +2 -2
- package/dist/components/content.css +8 -9
- package/dist/components/copy.css +8 -8
- package/dist/components/datatable.css +4 -8
- package/dist/components/date-picker.css +3 -7
- package/dist/components/empty.css +0 -4
- package/dist/components/feedback.css +10 -17
- package/dist/components/form.css +13 -14
- package/dist/components/input.css +2 -2
- package/dist/components/layout.css +36 -36
- package/dist/components/media.css +12 -8
- package/dist/components/menu.css +2 -2
- package/dist/components/modal.css +1 -1
- package/dist/components/nav.css +11 -6
- package/dist/components/notification.css +28 -28
- package/dist/components/pagination.css +1 -1
- package/dist/components/panel.css +16 -16
- package/dist/components/pill.css +15 -15
- package/dist/components/segmented.css +5 -5
- package/dist/components/segmented.mjs +1 -0
- package/dist/components/select.css +12 -20
- package/dist/components/sidebar.css +1 -1
- package/dist/components/split-pane.css +0 -1
- package/dist/components/stat.css +14 -18
- package/dist/components/steps.css +2 -2
- package/dist/components/switch.css +8 -12
- package/dist/components/table.css +46 -47
- package/dist/components/tabs.css +35 -46
- package/dist/components/tag-input.css +4 -4
- package/dist/components/toast.css +16 -13
- package/dist/components/tooltip.css +2 -2
- package/dist/index.d.mts +37 -0
- package/dist/index.mjs +7890 -1199
- package/dist/registry.json +113 -4
- package/dist/retro-effects.css +21 -17
- package/dist/tokens/colors.css +4 -1
- package/dist/tokens/retro-effects.css +21 -17
- package/dist/tokens/style-profiles.css +21 -0
- package/dist/tokens.css +25 -1
- package/dist/ui.css +3168 -433
- package/docs/spec/ai-native.md +659 -0
- package/package.json +15 -5
package/dist/ui.css
CHANGED
|
@@ -507,6 +507,8 @@
|
|
|
507
507
|
--token-accent-glow: color-mix(in srgb, var(--token-accent) 8%, transparent);
|
|
508
508
|
--token-line-dashed: color-mix(in srgb, var(--token-line-soft) 60%, transparent);
|
|
509
509
|
--token-overlay-bg: color-mix(in srgb, var(--token-bg) 92%, transparent);
|
|
510
|
+
/* 睡莲粉 accent 上的文字色:深绿灰(白字在 #d59ab1 上对比度不达标) */
|
|
511
|
+
--token-on-accent: #26302b;
|
|
510
512
|
|
|
511
513
|
--token-shadow-elevated: 0 1px 2px rgba(0,0,0,.18), 0 8px 22px rgba(0,0,0,.24);
|
|
512
514
|
--token-shadow-overlay: 0 2px 5px rgba(0,0,0,.24), 0 14px 36px rgba(0,0,0,.32);
|
|
@@ -844,7 +846,8 @@
|
|
|
844
846
|
--token-accent-glow: color-mix(in srgb, var(--token-accent) 6%, transparent);
|
|
845
847
|
--token-line-dashed: color-mix(in srgb, var(--token-line-soft) 60%, transparent);
|
|
846
848
|
--token-overlay-bg: color-mix(in srgb, var(--token-bg) 94%, transparent);
|
|
847
|
-
|
|
849
|
+
/* 松烟绿 accent 上的文字色:深墨(白字在 #7AA87E 上对比度不达标) */
|
|
850
|
+
--token-on-accent: #1a2018;
|
|
848
851
|
|
|
849
852
|
--token-shadow-elevated: 0 1px 2px rgba(0,0,0,.2), 0 4px 14px rgba(0,0,0,.22);
|
|
850
853
|
--token-shadow-overlay: 0 2px 4px rgba(0,0,0,.28), 0 10px 30px rgba(0,0,0,.34);
|
|
@@ -1312,13 +1315,20 @@
|
|
|
1312
1315
|
--density-space-sm: 0.5rem;
|
|
1313
1316
|
--density-space-md: 0.75rem;
|
|
1314
1317
|
--density-space-lg: 1rem;
|
|
1318
|
+
--density-space-xl: 1.5rem;
|
|
1319
|
+
--density-space-2xl: 2rem;
|
|
1320
|
+
--density-space-3xl: 3rem;
|
|
1321
|
+
--density-space-4xl: 4rem;
|
|
1315
1322
|
--density-input-height-sm: 28px;
|
|
1316
1323
|
--density-input-height-md: 36px;
|
|
1317
1324
|
--density-input-height-lg: 44px;
|
|
1325
|
+
--density-font-size-2xs: 10px;
|
|
1318
1326
|
--density-font-size-xs: 11px;
|
|
1319
1327
|
--density-font-size-sm: 12px;
|
|
1320
1328
|
--density-font-size-md: 13px;
|
|
1321
1329
|
--density-font-size-lg: 14px;
|
|
1330
|
+
--density-font-size-xl: 18px;
|
|
1331
|
+
--density-font-size-2xl: 22px;
|
|
1322
1332
|
|
|
1323
1333
|
/* ── Motion 动效 ── */
|
|
1324
1334
|
--duration-instant: 0ms;
|
|
@@ -1350,13 +1360,20 @@
|
|
|
1350
1360
|
--density-space-sm: 0.5rem;
|
|
1351
1361
|
--density-space-md: 0.75rem;
|
|
1352
1362
|
--density-space-lg: 1rem;
|
|
1363
|
+
--density-space-xl: 1.5rem;
|
|
1364
|
+
--density-space-2xl: 2rem;
|
|
1365
|
+
--density-space-3xl: 3rem;
|
|
1366
|
+
--density-space-4xl: 4rem;
|
|
1353
1367
|
--density-input-height-sm: 28px;
|
|
1354
1368
|
--density-input-height-md: 36px;
|
|
1355
1369
|
--density-input-height-lg: 44px;
|
|
1370
|
+
--density-font-size-2xs: 10px;
|
|
1356
1371
|
--density-font-size-xs: 11px;
|
|
1357
1372
|
--density-font-size-sm: 12px;
|
|
1358
1373
|
--density-font-size-md: 13px;
|
|
1359
1374
|
--density-font-size-lg: 14px;
|
|
1375
|
+
--density-font-size-xl: 18px;
|
|
1376
|
+
--density-font-size-2xl: 22px;
|
|
1360
1377
|
|
|
1361
1378
|
/* ── Motion ── */
|
|
1362
1379
|
--duration-fast: 150ms;
|
|
@@ -1385,13 +1402,20 @@
|
|
|
1385
1402
|
--density-space-sm: 0.25rem;
|
|
1386
1403
|
--density-space-md: 0.5rem;
|
|
1387
1404
|
--density-space-lg: 0.75rem;
|
|
1405
|
+
--density-space-xl: 1rem;
|
|
1406
|
+
--density-space-2xl: 1.5rem;
|
|
1407
|
+
--density-space-3xl: 2rem;
|
|
1408
|
+
--density-space-4xl: 3rem;
|
|
1388
1409
|
--density-input-height-sm: 24px;
|
|
1389
1410
|
--density-input-height-md: 32px;
|
|
1390
1411
|
--density-input-height-lg: 40px;
|
|
1412
|
+
--density-font-size-2xs: 9px;
|
|
1391
1413
|
--density-font-size-xs: 9px;
|
|
1392
1414
|
--density-font-size-sm: 10px;
|
|
1393
1415
|
--density-font-size-md: 11px;
|
|
1394
1416
|
--density-font-size-lg: 12px;
|
|
1417
|
+
--density-font-size-xl: 14px;
|
|
1418
|
+
--density-font-size-2xl: 16px;
|
|
1395
1419
|
|
|
1396
1420
|
/* ── Motion:像素风瞬间切换 ── */
|
|
1397
1421
|
--duration-fast: 0ms;
|
|
@@ -1854,10 +1878,11 @@ h1, h2, h3, h4, h5, h6 {
|
|
|
1854
1878
|
* ════════════════════════════════════════════════════════════════════════
|
|
1855
1879
|
* icen 组件契约(统一抽象)
|
|
1856
1880
|
* ════════════════════════════════════════════════════════════════════════
|
|
1857
|
-
* 所有
|
|
1881
|
+
* 所有 51 个组件遵循同一套抽象,由两层共同支撑:
|
|
1858
1882
|
*
|
|
1859
1883
|
* ── 层 1:--icen-* 原语 token(所有组件自洽消费)
|
|
1860
|
-
* --icen-ring / --icen-ring-soft / --icen-ring-error
|
|
1884
|
+
* --icen-ring / --icen-ring-soft / --icen-ring-error /
|
|
1885
|
+
* --icen-ring-warning / --icen-ring-inset ← 聚焦环
|
|
1861
1886
|
* --icen-hover-border ← 悬停边框过渡
|
|
1862
1887
|
* --icen-disabled-opacity ← 禁用透明度
|
|
1863
1888
|
* --icen-press ← 按下形变
|
|
@@ -1903,6 +1928,7 @@ h1, h2, h3, h4, h5, h6 {
|
|
|
1903
1928
|
* - 滚动条:贴 --token-scrollbar-*(retro profile 另有硬覆盖)
|
|
1904
1929
|
* - 工具类:.mono / .dim / .faint / .sr-only / .skip-link
|
|
1905
1930
|
* - z-index 标尺:--z-* (浮层一律 portal 到 body)
|
|
1931
|
+
* - 共享 keyframes:icen-pop-in(弹层进场)/ icen-spin(旋转)/ icen-skeleton-pulse(骨架脉冲)
|
|
1906
1932
|
* - 交互基元 class:.pressable / .control / .field / .lift / .surface-elevated / .focus-ring / .motion
|
|
1907
1933
|
* - 状态约定:[aria-disabled] / [aria-busy] / [data-loading] / [data-disabled] / [data-invalid]
|
|
1908
1934
|
*/
|
|
@@ -1912,7 +1938,7 @@ h1, h2, h3, h4, h5, h6 {
|
|
|
1912
1938
|
───────────────────────────────────────────────────────────────
|
|
1913
1939
|
所有组件消费的"原语级"变量:聚焦环、悬停、按下、禁用、过渡。
|
|
1914
1940
|
风格 profile(如 .style-retro)只需覆盖这里的少数变量,
|
|
1915
|
-
即可让
|
|
1941
|
+
即可让 51 个组件整体换肤;组件自身无需感知风格切换。
|
|
1916
1942
|
══════════════════════════════════════════════════════════════ */
|
|
1917
1943
|
:root {
|
|
1918
1944
|
/* ── 聚焦环(focus-visible) ── */
|
|
@@ -1920,6 +1946,9 @@ h1, h2, h3, h4, h5, h6 {
|
|
|
1920
1946
|
--icen-ring-soft: 0 0 0 3px color-mix(in srgb, var(--token-accent) 16%, transparent);
|
|
1921
1947
|
--icen-ring-error: 0 0 0 2px var(--token-bg), 0 0 0 4px color-mix(in srgb, var(--token-error) 50%, transparent);
|
|
1922
1948
|
--icen-ring-success: 0 0 0 2px var(--token-bg), 0 0 0 4px color-mix(in srgb, var(--token-success) 50%, transparent);
|
|
1949
|
+
--icen-ring-warning: 0 0 0 2px var(--token-bg), 0 0 0 4px color-mix(in srgb, var(--token-warning) 50%, transparent);
|
|
1950
|
+
/* inset 聚焦环:空间受限的网格/表头单元格用内阴影聚焦(2px 内描边 + 3px 内光晕) */
|
|
1951
|
+
--icen-ring-inset: inset 0 0 0 2px color-mix(in srgb, var(--token-accent) 50%, transparent), inset 0 0 0 5px color-mix(in srgb, var(--token-accent) 14%, transparent);
|
|
1923
1952
|
|
|
1924
1953
|
/* ── 悬停 / 按下 / 禁用 ── */
|
|
1925
1954
|
--icen-hover-border: color-mix(in srgb, var(--token-accent) 30%, var(--token-line));
|
|
@@ -2098,7 +2127,8 @@ html {
|
|
|
2098
2127
|
banner → 全屏横幅(紧急公告,高于 toast)
|
|
2099
2128
|
dialog → 模态对话框 + backdrop
|
|
2100
2129
|
popover → 弹出层/下拉菜单(高于 dialog 因为常常 portal 出去)
|
|
2101
|
-
tooltip →
|
|
2130
|
+
tooltip → 工具提示
|
|
2131
|
+
fx → 效果层(retro 扫描线/噪点等,永远在最上)
|
|
2102
2132
|
══════════════════════════════════════════════════════════════ */
|
|
2103
2133
|
:root {
|
|
2104
2134
|
--z-base: 0;
|
|
@@ -2110,6 +2140,27 @@ html {
|
|
|
2110
2140
|
--z-dialog: 500;
|
|
2111
2141
|
--z-popover: 620;
|
|
2112
2142
|
--z-tooltip: 700;
|
|
2143
|
+
--z-fx: 1000;
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
/* ══════════════════════════════════════════════════════════════
|
|
2147
|
+
共享 keyframes(组件统一引用,不再各自重复定义)
|
|
2148
|
+
icen-pop-in → 弹层进场(scale .96 + translateY -4px)
|
|
2149
|
+
icen-spin → 旋转(spinner / 加载态)
|
|
2150
|
+
icen-skeleton-pulse → 骨架脉冲
|
|
2151
|
+
注:menu.css / popover.css 保留自己的 scale(.95)±8px 四方向版
|
|
2152
|
+
(方向语义不同:按 data-side 反向位移),不并入 icen-pop-in。
|
|
2153
|
+
══════════════════════════════════════════════════════════════ */
|
|
2154
|
+
@keyframes icen-pop-in {
|
|
2155
|
+
from { opacity: 0; transform: scale(0.96) translateY(-4px); }
|
|
2156
|
+
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
2157
|
+
}
|
|
2158
|
+
@keyframes icen-spin {
|
|
2159
|
+
to { transform: rotate(360deg); }
|
|
2160
|
+
}
|
|
2161
|
+
@keyframes icen-skeleton-pulse {
|
|
2162
|
+
0%, 100% { opacity: 1; }
|
|
2163
|
+
50% { opacity: 0.5; }
|
|
2113
2164
|
}
|
|
2114
2165
|
|
|
2115
2166
|
/* ══════════════════════════════════════════════════════════════
|
|
@@ -2260,58 +2311,2632 @@ html {
|
|
|
2260
2311
|
outline: none;
|
|
2261
2312
|
box-shadow: var(--icen-ring);
|
|
2262
2313
|
}
|
|
2263
|
-
|
|
2264
|
-
/* ── .motion — 显式动画工具类(仅在 prefers-reduced-motion: no-preference 时生效) */
|
|
2265
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
2266
|
-
.motion { transition: all var(--icen-tx-normal); }
|
|
2314
|
+
|
|
2315
|
+
/* ── .motion — 显式动画工具类(仅在 prefers-reduced-motion: no-preference 时生效) */
|
|
2316
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
2317
|
+
.motion { transition: all var(--icen-tx-normal); }
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
/* ══════════════════════════════════════════════════════════════
|
|
2321
|
+
动效与无障碍兜底
|
|
2322
|
+
══════════════════════════════════════════════════════════════ */
|
|
2323
|
+
|
|
2324
|
+
/* reduced-motion:所有动画/过渡压缩到 ~0ms(保留可访问性最小可视信号) */
|
|
2325
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2326
|
+
*, *::before, *::after {
|
|
2327
|
+
animation-duration: 0.01ms !important;
|
|
2328
|
+
animation-iteration-count: 1 !important;
|
|
2329
|
+
transition-duration: 0.01ms !important;
|
|
2330
|
+
scroll-behavior: auto !important;
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
|
|
2334
|
+
/* 触屏设备(无精细指针):关闭 hover 抬升、压低 pressable scale */
|
|
2335
|
+
@media (pointer: coarse) {
|
|
2336
|
+
.lift:hover { transform: none; }
|
|
2337
|
+
.pressable:active { transform: translateY(0) scale(0.99); }
|
|
2338
|
+
}
|
|
2339
|
+
|
|
2340
|
+
/* 高对比度模式(Windows High Contrast / 强制 colors) */
|
|
2341
|
+
@media (forced-colors: active) {
|
|
2342
|
+
.pressable, .control, .lift, .surface-elevated, .focus-ring:focus-visible {
|
|
2343
|
+
forced-color-adjust: none;
|
|
2344
|
+
}
|
|
2345
|
+
.focus-ring:focus-visible,
|
|
2346
|
+
.pressable:focus-visible {
|
|
2347
|
+
outline: 2px solid Highlight;
|
|
2348
|
+
outline-offset: 2px;
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
/* 打印:去掉阴影/背景/动效,节约墨水并避免打印截断 */
|
|
2353
|
+
@media print {
|
|
2354
|
+
*, *::before, *::after {
|
|
2355
|
+
background: transparent !important;
|
|
2356
|
+
color: #000 !important;
|
|
2357
|
+
box-shadow: none !important;
|
|
2358
|
+
text-shadow: none !important;
|
|
2359
|
+
}
|
|
2360
|
+
body { font-size: 12pt; line-height: 1.4; }
|
|
2361
|
+
a, a:visited { text-decoration: underline; }
|
|
2362
|
+
a[href]::after { content: ' (' attr(href) ')'; font-size: 90%; }
|
|
2363
|
+
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
|
|
2364
|
+
h1, h2, h3 { page-break-after: avoid; }
|
|
2365
|
+
.pressable, .lift, .surface-elevated { box-shadow: none !important; transform: none !important; }
|
|
2366
|
+
}
|
|
2367
|
+
|
|
2368
|
+
|
|
2369
|
+
/* ── components/ai-chat.css ── */
|
|
2370
|
+
/*
|
|
2371
|
+
* @icen.ai/ui — Component: ai-chat(AI 原生组件族:ai-chat / ai-message / ai-reasoning / ai-composer)
|
|
2372
|
+
*
|
|
2373
|
+
* 完整契约:
|
|
2374
|
+
* <div class="ai-chat" data-density="normal"> ← verbose|normal|summary 三档
|
|
2375
|
+
* <div class="ai-chat-scroll">
|
|
2376
|
+
* <div class="ai-msg ai-msg--user|ai-msg--assistant|ai-msg--system|ai-msg--tool">
|
|
2377
|
+
* <span class="ai-msg-avatar"></span>
|
|
2378
|
+
* <div class="ai-msg-body">…消费方自行渲染 markdown…</div>
|
|
2379
|
+
* <div class="ai-msg-actions"><button data-ai-msg-action="copy|retry">…</button></div>
|
|
2380
|
+
* <div class="ai-msg-meta">12:04 · 1.2k tok</div>
|
|
2381
|
+
* </div>
|
|
2382
|
+
* </div>
|
|
2383
|
+
* <button class="ai-chat-jump" hidden>回到底部 · N 条新消息</button>
|
|
2384
|
+
* </div>
|
|
2385
|
+
*
|
|
2386
|
+
* <div class="ai-reasoning [.is-streaming|.is-done]">
|
|
2387
|
+
* <button class="ai-reasoning-head" aria-expanded="false">
|
|
2388
|
+
* <span class="ai-reasoning-label">思考过程</span><span class="ai-reasoning-time">3s</span>
|
|
2389
|
+
* </button>
|
|
2390
|
+
* <div class="ai-reasoning-body" hidden>…</div>
|
|
2391
|
+
* </div>
|
|
2392
|
+
*
|
|
2393
|
+
* <div class="ai-composer" data-ai-composer [.is-running]>
|
|
2394
|
+
* <div class="ai-composer-queue" hidden><span class="ai-composer-chip">
|
|
2395
|
+
* <span class="ai-composer-chip-text">…</span>
|
|
2396
|
+
* <button class="ai-composer-chip-remove" aria-label="移除">×</button>
|
|
2397
|
+
* </span></div>
|
|
2398
|
+
* <div class="ai-composer-refs" hidden><!-- @ 引用 chips,结构同上(v2 setComposerRefs) --></div>
|
|
2399
|
+
* <div class="ai-composer-attach" hidden><!-- 附件 chips,结构同上 --></div>
|
|
2400
|
+
* <div class="ai-composer-box control">
|
|
2401
|
+
* <textarea class="ai-composer-input" rows="1" placeholder="…"></textarea>
|
|
2402
|
+
* <div class="ai-composer-actions"><!-- v1 旧结构(无 toolbar 配置时保留): -->
|
|
2403
|
+
* <button class="ai-composer-btn" data-ai-attach aria-label="附件"></button>
|
|
2404
|
+
* <button class="ai-composer-send" data-ai-send aria-label="发送"></button> ← 运行态 .is-stop
|
|
2405
|
+
* </div>
|
|
2406
|
+
* <div class="ai-composer-toolbar"><!-- v2 工具条(setComposerModels/Usage 配置时 JS 装配):
|
|
2407
|
+
* <button class="ai-composer-model" data-ai-model-open>provider 图标/首字母章 + 模型名 + chevron</button>
|
|
2408
|
+
* <span class="ai-composer-spacer"></span>
|
|
2409
|
+
* <span class="ai-composer-usage" data-ai-usage></span> ← 用量环挂载点(renderAiUsageRing)
|
|
2410
|
+
* <button class="ai-composer-btn" data-ai-attach></button>
|
|
2411
|
+
* <button class="ai-composer-send" data-ai-send></button> ← 运行态 .is-stop
|
|
2412
|
+
* </div>
|
|
2413
|
+
* </div>
|
|
2414
|
+
* </div>
|
|
2415
|
+
* 弹层 .ai-composer-popup(portal body,JS 动态创建):模型切换 / 斜杠命令 / @ 引用
|
|
2416
|
+
* 三模式共用基座——.ai-composer-popup-search 搜索框、.ai-composer-popup-list(listbox)
|
|
2417
|
+
* > .ai-composer-popup-group > .ai-composer-popup-group-label + .ai-composer-popup-option(role=option),
|
|
2418
|
+
* .ai-composer-popup-empty 空态、.ai-composer-popup-foot 底部提示。
|
|
2419
|
+
*
|
|
2420
|
+
* 配套 behaviors:behaviors/ai-chat.ts(initAiChat / createAiStream)
|
|
2421
|
+
* + behaviors/ai-composer.ts(initAiComposer / setComposerRunning
|
|
2422
|
+
* + v2:setComposerModels / setComposerCommands / setComposerRefs / setComposerUsage)。
|
|
2423
|
+
* 状态机 7 态 .is-* 中的 streaming/done 在本文件消费;running 脉冲点等条目态见 ai-tool.css(.ai-item 基元)。
|
|
2424
|
+
* data-density:summary 档隐藏 meta、默认折叠 reasoning(纯 CSS);
|
|
2425
|
+
* tool/system 类次要消息在 summary 档压淡。verbose 与 normal 目前同视觉(透明度两档生效)。
|
|
2426
|
+
* 流式光标复用 tokens 的 blink keyframes(.animate-blink 同款);reasoning shimmer 时长走
|
|
2427
|
+
* --ai-shimmer-duration 局部变量(默认值 1.6s)。
|
|
2428
|
+
*/
|
|
2429
|
+
|
|
2430
|
+
/* ══════════════ ai-chat(滚动容器 + 钉底) ══════════════ */
|
|
2431
|
+
|
|
2432
|
+
/* 输出容器宽度自稳定契约:即使宿主是 flex/grid 居中上下文(shrink-wrap 陷阱),
|
|
2433
|
+
也不随内容多少改变宽度——流式内容只允许纵向生长。
|
|
2434
|
+
(用 align-self 而非 width:100%——width 在 shrink-wrap 父级下会塌成 min-content) */
|
|
2435
|
+
.ai-chat,
|
|
2436
|
+
.ai-reasoning,
|
|
2437
|
+
.ai-composer {
|
|
2438
|
+
align-self: stretch;
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
.ai-chat {
|
|
2442
|
+
position: relative;
|
|
2443
|
+
display: flex;
|
|
2444
|
+
flex-direction: column;
|
|
2445
|
+
height: 100%;
|
|
2446
|
+
min-height: 0;
|
|
2447
|
+
gap: var(--density-space-sm);
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
.ai-chat-scroll {
|
|
2451
|
+
flex: 1;
|
|
2452
|
+
min-height: 0;
|
|
2453
|
+
overflow-y: auto;
|
|
2454
|
+
display: flex;
|
|
2455
|
+
flex-direction: column;
|
|
2456
|
+
gap: var(--density-space-md);
|
|
2457
|
+
padding: var(--density-space-xs) var(--density-space-2xs, 2px);
|
|
2458
|
+
scroll-behavior: smooth;
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
/* 「回到底部 · N 条新消息」浮动钮(用户上滚暂停跟随时出现,initAiChat 驱动) */
|
|
2462
|
+
.ai-chat-jump {
|
|
2463
|
+
position: absolute;
|
|
2464
|
+
left: 50%;
|
|
2465
|
+
bottom: var(--density-space-md);
|
|
2466
|
+
transform: translateX(-50%);
|
|
2467
|
+
z-index: var(--z-raised);
|
|
2468
|
+
display: inline-flex;
|
|
2469
|
+
align-items: center;
|
|
2470
|
+
gap: var(--density-space-xs);
|
|
2471
|
+
padding: var(--density-space-xs) var(--density-space-md);
|
|
2472
|
+
border: 1px solid var(--token-line-soft);
|
|
2473
|
+
border-radius: var(--radius-full);
|
|
2474
|
+
background: var(--token-surface);
|
|
2475
|
+
box-shadow: var(--token-shadow-card);
|
|
2476
|
+
color: var(--token-text-muted);
|
|
2477
|
+
font-family: var(--font-mono);
|
|
2478
|
+
font-size: var(--density-font-size-xs);
|
|
2479
|
+
letter-spacing: 0.02em;
|
|
2480
|
+
white-space: nowrap;
|
|
2481
|
+
cursor: pointer;
|
|
2482
|
+
animation: icen-pop-in var(--ai-jump-enter-duration, var(--duration-normal)) var(--ease-out);
|
|
2483
|
+
transition:
|
|
2484
|
+
color var(--icen-tx-fast),
|
|
2485
|
+
border-color var(--icen-tx-fast),
|
|
2486
|
+
box-shadow var(--icen-tx-fast);
|
|
2487
|
+
}
|
|
2488
|
+
.ai-chat-jump:hover {
|
|
2489
|
+
color: var(--token-accent);
|
|
2490
|
+
border-color: var(--icen-hover-border);
|
|
2491
|
+
}
|
|
2492
|
+
.ai-chat-jump:focus-visible {
|
|
2493
|
+
outline: none;
|
|
2494
|
+
box-shadow: var(--icen-ring);
|
|
2495
|
+
}
|
|
2496
|
+
.ai-chat-jump[hidden] {
|
|
2497
|
+
display: none;
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2500
|
+
/* ══════════════ ai-message ══════════════ */
|
|
2501
|
+
|
|
2502
|
+
.ai-msg {
|
|
2503
|
+
position: relative;
|
|
2504
|
+
display: grid;
|
|
2505
|
+
grid-template-columns: auto 1fr;
|
|
2506
|
+
gap: var(--density-space-sm);
|
|
2507
|
+
padding: var(--density-space-sm) var(--density-space-md);
|
|
2508
|
+
border-radius: var(--radius-md);
|
|
2509
|
+
animation: icen-pop-in var(--ai-msg-enter-duration, var(--duration-normal)) var(--ease-out);
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2512
|
+
.ai-msg-avatar {
|
|
2513
|
+
width: 28px;
|
|
2514
|
+
height: 28px;
|
|
2515
|
+
flex-shrink: 0;
|
|
2516
|
+
display: inline-flex;
|
|
2517
|
+
align-items: center;
|
|
2518
|
+
justify-content: center;
|
|
2519
|
+
border-radius: var(--radius-sm);
|
|
2520
|
+
background: var(--token-fill-2);
|
|
2521
|
+
color: var(--token-text-muted);
|
|
2522
|
+
font-family: var(--font-mono);
|
|
2523
|
+
font-size: var(--density-font-size-2xs);
|
|
2524
|
+
letter-spacing: 0.04em;
|
|
2525
|
+
user-select: none;
|
|
2526
|
+
}
|
|
2527
|
+
.ai-msg--user .ai-msg-avatar {
|
|
2528
|
+
background: color-mix(in srgb, var(--token-accent) 14%, transparent);
|
|
2529
|
+
color: var(--token-accent);
|
|
2530
|
+
}
|
|
2531
|
+
.ai-msg--assistant .ai-msg-avatar {
|
|
2532
|
+
background: color-mix(in srgb, var(--token-success) 12%, transparent);
|
|
2533
|
+
color: var(--token-success);
|
|
2534
|
+
}
|
|
2535
|
+
.ai-msg--system .ai-msg-avatar {
|
|
2536
|
+
background: color-mix(in srgb, var(--token-warning) 12%, transparent);
|
|
2537
|
+
color: var(--token-warning);
|
|
2538
|
+
}
|
|
2539
|
+
.ai-msg--tool .ai-msg-avatar {
|
|
2540
|
+
background: color-mix(in srgb, var(--token-info) 12%, transparent);
|
|
2541
|
+
color: var(--token-info);
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
.ai-msg-body {
|
|
2545
|
+
min-width: 0;
|
|
2546
|
+
min-height: 1.6em; /* 流式从空开始时占住一行高度,不塌 */
|
|
2547
|
+
font-size: var(--density-font-size-md);
|
|
2548
|
+
line-height: 1.6;
|
|
2549
|
+
white-space: pre-wrap;
|
|
2550
|
+
word-break: break-word;
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
/* 流式光标(▍闪烁,复用 tokens 的 blink keyframes,同 .animate-blink) */
|
|
2554
|
+
.ai-msg-body.is-streaming::after,
|
|
2555
|
+
.ai-reasoning-body.is-streaming::after {
|
|
2556
|
+
content: '▍';
|
|
2557
|
+
margin-left: 1px;
|
|
2558
|
+
color: var(--token-accent);
|
|
2559
|
+
animation: blink 1s step-end infinite;
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
/* 消息操作:hover / focus-within 才出现(键盘可达等价) */
|
|
2563
|
+
.ai-msg-actions {
|
|
2564
|
+
position: absolute;
|
|
2565
|
+
top: var(--density-space-xs);
|
|
2566
|
+
right: var(--density-space-xs);
|
|
2567
|
+
display: flex;
|
|
2568
|
+
gap: 2px;
|
|
2569
|
+
padding: 2px;
|
|
2570
|
+
border-radius: var(--radius-sm);
|
|
2571
|
+
background: var(--token-surface);
|
|
2572
|
+
border: 1px solid var(--token-line-soft);
|
|
2573
|
+
opacity: 0;
|
|
2574
|
+
visibility: hidden;
|
|
2575
|
+
transform: translateY(-2px);
|
|
2576
|
+
transition:
|
|
2577
|
+
opacity var(--icen-tx-fast),
|
|
2578
|
+
transform var(--icen-tx-fast),
|
|
2579
|
+
visibility var(--icen-tx-fast);
|
|
2580
|
+
}
|
|
2581
|
+
.ai-msg:hover .ai-msg-actions,
|
|
2582
|
+
.ai-msg:focus-within .ai-msg-actions {
|
|
2583
|
+
opacity: 1;
|
|
2584
|
+
visibility: visible;
|
|
2585
|
+
transform: translateY(0);
|
|
2586
|
+
}
|
|
2587
|
+
.ai-msg-actions [data-ai-msg-action] {
|
|
2588
|
+
display: inline-flex;
|
|
2589
|
+
align-items: center;
|
|
2590
|
+
justify-content: center;
|
|
2591
|
+
width: 22px;
|
|
2592
|
+
height: 22px;
|
|
2593
|
+
padding: 0;
|
|
2594
|
+
border: 0;
|
|
2595
|
+
border-radius: var(--radius-xs);
|
|
2596
|
+
background: transparent;
|
|
2597
|
+
color: var(--token-text-muted);
|
|
2598
|
+
cursor: pointer;
|
|
2599
|
+
transition:
|
|
2600
|
+
color var(--icen-tx-fast),
|
|
2601
|
+
background-color var(--icen-tx-fast);
|
|
2602
|
+
}
|
|
2603
|
+
.ai-msg-actions [data-ai-msg-action]:hover {
|
|
2604
|
+
color: var(--token-accent);
|
|
2605
|
+
background: var(--token-fill-2);
|
|
2606
|
+
}
|
|
2607
|
+
.ai-msg-actions [data-ai-msg-action]:focus-visible {
|
|
2608
|
+
outline: none;
|
|
2609
|
+
box-shadow: var(--icen-ring);
|
|
2610
|
+
}
|
|
2611
|
+
.ai-msg-actions [data-ai-msg-action] svg {
|
|
2612
|
+
width: 12px;
|
|
2613
|
+
height: 12px;
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
/* meta:时间 · token 数(summary 档隐藏) */
|
|
2617
|
+
.ai-msg-meta {
|
|
2618
|
+
margin-top: 2px;
|
|
2619
|
+
font-family: var(--font-mono);
|
|
2620
|
+
font-size: var(--density-font-size-2xs);
|
|
2621
|
+
color: var(--token-text-faint);
|
|
2622
|
+
font-variant-numeric: tabular-nums;
|
|
2623
|
+
}
|
|
2624
|
+
|
|
2625
|
+
/* ── 多模态消息部件(renderAiMessage,spec §10)── */
|
|
2626
|
+
|
|
2627
|
+
.ai-msg-text {
|
|
2628
|
+
display: block;
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
/* 图片 / 音频 / 视频:宽度自稳定(不超正文列),纵向生长 */
|
|
2632
|
+
.ai-msg-media {
|
|
2633
|
+
display: block;
|
|
2634
|
+
max-width: min(100%, 360px);
|
|
2635
|
+
margin: var(--density-space-xs) 0;
|
|
2636
|
+
border: 1px solid var(--token-line-soft);
|
|
2637
|
+
border-radius: var(--radius-md);
|
|
2638
|
+
background: var(--token-surface);
|
|
2639
|
+
}
|
|
2640
|
+
.ai-msg-media--image {
|
|
2641
|
+
max-height: 320px;
|
|
2642
|
+
object-fit: contain;
|
|
2643
|
+
}
|
|
2644
|
+
.ai-msg-media--audio {
|
|
2645
|
+
width: min(100%, 300px);
|
|
2646
|
+
height: 40px;
|
|
2647
|
+
}
|
|
2648
|
+
.ai-msg-media--video {
|
|
2649
|
+
max-width: min(100%, 480px);
|
|
2650
|
+
max-height: 300px;
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2653
|
+
/* 文件 chip(含可选下载链接) */
|
|
2654
|
+
.ai-msg-file {
|
|
2655
|
+
display: inline-flex;
|
|
2656
|
+
align-items: center;
|
|
2657
|
+
gap: var(--density-space-xs);
|
|
2658
|
+
margin: 2px var(--density-space-xs) 2px 0;
|
|
2659
|
+
padding: 2px var(--density-space-sm);
|
|
2660
|
+
border: 1px solid var(--token-line);
|
|
2661
|
+
border-radius: var(--radius-sm);
|
|
2662
|
+
background: var(--token-surface);
|
|
2663
|
+
font-family: var(--font-mono);
|
|
2664
|
+
font-size: var(--density-font-size-xs);
|
|
2665
|
+
color: var(--token-text);
|
|
2666
|
+
}
|
|
2667
|
+
.ai-msg-file-link {
|
|
2668
|
+
color: var(--token-accent);
|
|
2669
|
+
text-decoration: none;
|
|
2670
|
+
}
|
|
2671
|
+
.ai-msg-file-link:hover {
|
|
2672
|
+
text-decoration: underline;
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2675
|
+
/* MCP ResourceLink 等资源引用 */
|
|
2676
|
+
.ai-msg-link {
|
|
2677
|
+
color: var(--token-accent);
|
|
2678
|
+
}
|
|
2679
|
+
|
|
2680
|
+
/* assistant 消息的模型名标签 */
|
|
2681
|
+
.ai-msg-model {
|
|
2682
|
+
display: inline-block;
|
|
2683
|
+
margin-left: var(--density-space-xs);
|
|
2684
|
+
padding: 0 6px;
|
|
2685
|
+
border-radius: var(--radius-xs);
|
|
2686
|
+
background: var(--token-fill-1);
|
|
2687
|
+
color: var(--token-text-faint);
|
|
2688
|
+
font-family: var(--font-mono);
|
|
2689
|
+
font-size: var(--density-font-size-2xs);
|
|
2690
|
+
vertical-align: middle;
|
|
2691
|
+
}
|
|
2692
|
+
|
|
2693
|
+
/* ── 错误变体(renderAiMessage.setError / createAiStream.fail)── */
|
|
2694
|
+
|
|
2695
|
+
.ai-msg--error .ai-msg-body {
|
|
2696
|
+
border-left: 2px solid var(--token-error);
|
|
2697
|
+
padding-left: var(--density-space-sm);
|
|
2698
|
+
}
|
|
2699
|
+
.ai-msg-error-text {
|
|
2700
|
+
display: block;
|
|
2701
|
+
margin-top: var(--density-space-xs);
|
|
2702
|
+
color: var(--token-error);
|
|
2703
|
+
font-size: var(--density-font-size-xs);
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
/* ══════════════ ai-reasoning ══════════════ */
|
|
2707
|
+
|
|
2708
|
+
.ai-reasoning {
|
|
2709
|
+
margin: var(--density-space-xs) 0;
|
|
2710
|
+
padding-left: var(--density-space-md);
|
|
2711
|
+
border-left: 2px solid var(--token-line-soft);
|
|
2712
|
+
}
|
|
2713
|
+
|
|
2714
|
+
.ai-reasoning-head {
|
|
2715
|
+
display: flex;
|
|
2716
|
+
align-items: center;
|
|
2717
|
+
gap: var(--density-space-sm);
|
|
2718
|
+
width: 100%;
|
|
2719
|
+
padding: var(--density-space-xs) 0;
|
|
2720
|
+
border: 0;
|
|
2721
|
+
background: none;
|
|
2722
|
+
color: var(--token-text-muted);
|
|
2723
|
+
font-family: var(--font-mono);
|
|
2724
|
+
font-size: var(--density-font-size-sm);
|
|
2725
|
+
letter-spacing: 0.02em;
|
|
2726
|
+
cursor: pointer;
|
|
2727
|
+
text-align: left;
|
|
2728
|
+
}
|
|
2729
|
+
.ai-reasoning-head:hover {
|
|
2730
|
+
color: var(--token-text);
|
|
2731
|
+
}
|
|
2732
|
+
.ai-reasoning-head:focus-visible {
|
|
2733
|
+
outline: none;
|
|
2734
|
+
box-shadow: var(--icen-ring);
|
|
2735
|
+
border-radius: var(--radius-xs);
|
|
2736
|
+
}
|
|
2737
|
+
|
|
2738
|
+
/* 折叠指示 chevron(CSS 三角,展开时旋转) */
|
|
2739
|
+
.ai-reasoning-head::before {
|
|
2740
|
+
content: '';
|
|
2741
|
+
flex-shrink: 0;
|
|
2742
|
+
width: 6px;
|
|
2743
|
+
height: 6px;
|
|
2744
|
+
border-right: 1.5px solid currentColor;
|
|
2745
|
+
border-bottom: 1.5px solid currentColor;
|
|
2746
|
+
transform: rotate(-45deg);
|
|
2747
|
+
transition: transform var(--icen-tx-fast);
|
|
2748
|
+
}
|
|
2749
|
+
.ai-reasoning:has(.ai-reasoning-head[aria-expanded='true']) .ai-reasoning-head::before {
|
|
2750
|
+
transform: rotate(45deg);
|
|
2751
|
+
}
|
|
2752
|
+
|
|
2753
|
+
.ai-reasoning-label {
|
|
2754
|
+
overflow: hidden;
|
|
2755
|
+
text-overflow: ellipsis;
|
|
2756
|
+
white-space: nowrap;
|
|
2757
|
+
}
|
|
2758
|
+
|
|
2759
|
+
.ai-reasoning-time {
|
|
2760
|
+
margin-left: auto;
|
|
2761
|
+
font-size: var(--density-font-size-2xs);
|
|
2762
|
+
color: var(--token-text-faint);
|
|
2763
|
+
font-variant-numeric: tabular-nums;
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2766
|
+
/* 流式中:耗时位换成 shimmer「正在思考…」(时长走局部变量) */
|
|
2767
|
+
.ai-reasoning.is-streaming .ai-reasoning-time {
|
|
2768
|
+
display: none;
|
|
2769
|
+
}
|
|
2770
|
+
.ai-reasoning.is-streaming .ai-reasoning-head::after {
|
|
2771
|
+
content: '正在思考…';
|
|
2772
|
+
margin-left: auto;
|
|
2773
|
+
font-size: var(--density-font-size-2xs);
|
|
2774
|
+
background: linear-gradient(
|
|
2775
|
+
90deg,
|
|
2776
|
+
var(--token-text-faint) 25%,
|
|
2777
|
+
var(--token-text) 50%,
|
|
2778
|
+
var(--token-text-faint) 75%
|
|
2779
|
+
);
|
|
2780
|
+
background-size: 200% 100%;
|
|
2781
|
+
-webkit-background-clip: text;
|
|
2782
|
+
background-clip: text;
|
|
2783
|
+
-webkit-text-fill-color: transparent;
|
|
2784
|
+
color: transparent;
|
|
2785
|
+
animation: ai-shimmer var(--ai-shimmer-duration, 1.6s) linear infinite;
|
|
2786
|
+
}
|
|
2787
|
+
|
|
2788
|
+
.ai-reasoning-body {
|
|
2789
|
+
padding: var(--density-space-xs) 0 var(--density-space-sm);
|
|
2790
|
+
color: var(--token-text-muted);
|
|
2791
|
+
font-size: var(--density-font-size-sm);
|
|
2792
|
+
line-height: 1.6;
|
|
2793
|
+
white-space: pre-wrap;
|
|
2794
|
+
word-break: break-word;
|
|
2795
|
+
}
|
|
2796
|
+
.ai-reasoning-body[hidden] {
|
|
2797
|
+
display: none;
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
/* ══════════════ ai-composer ══════════════ */
|
|
2801
|
+
|
|
2802
|
+
.ai-composer {
|
|
2803
|
+
display: flex;
|
|
2804
|
+
flex-direction: column;
|
|
2805
|
+
gap: var(--density-space-xs);
|
|
2806
|
+
padding: var(--density-space-sm);
|
|
2807
|
+
border: 1px solid var(--token-line-soft);
|
|
2808
|
+
border-radius: var(--radius-lg);
|
|
2809
|
+
background: var(--token-surface);
|
|
2810
|
+
box-shadow: var(--token-shadow-card);
|
|
2811
|
+
}
|
|
2812
|
+
.ai-composer:focus-within {
|
|
2813
|
+
border-color: var(--icen-hover-border);
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
/* 排队 / 引用 / 附件 chips 行 */
|
|
2817
|
+
.ai-composer-queue,
|
|
2818
|
+
.ai-composer-refs,
|
|
2819
|
+
.ai-composer-attach {
|
|
2820
|
+
display: flex;
|
|
2821
|
+
flex-wrap: wrap;
|
|
2822
|
+
gap: var(--density-space-xs);
|
|
2823
|
+
}
|
|
2824
|
+
.ai-composer-queue[hidden],
|
|
2825
|
+
.ai-composer-refs[hidden],
|
|
2826
|
+
.ai-composer-attach[hidden] {
|
|
2827
|
+
display: none;
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
.ai-composer-chip {
|
|
2831
|
+
display: inline-flex;
|
|
2832
|
+
align-items: center;
|
|
2833
|
+
gap: 4px;
|
|
2834
|
+
max-width: 240px;
|
|
2835
|
+
padding: 2px var(--density-space-xs);
|
|
2836
|
+
border: 1px solid var(--token-line-soft);
|
|
2837
|
+
border-radius: var(--radius-full);
|
|
2838
|
+
background: var(--token-surface-strong);
|
|
2839
|
+
color: var(--token-text-muted);
|
|
2840
|
+
font-size: var(--density-font-size-xs);
|
|
2841
|
+
line-height: 1.4;
|
|
2842
|
+
}
|
|
2843
|
+
.ai-composer-chip-text {
|
|
2844
|
+
overflow: hidden;
|
|
2845
|
+
text-overflow: ellipsis;
|
|
2846
|
+
white-space: nowrap;
|
|
2847
|
+
}
|
|
2848
|
+
.ai-composer-chip-remove {
|
|
2849
|
+
display: inline-flex;
|
|
2850
|
+
align-items: center;
|
|
2851
|
+
justify-content: center;
|
|
2852
|
+
width: 14px;
|
|
2853
|
+
height: 14px;
|
|
2854
|
+
padding: 0;
|
|
2855
|
+
border: 0;
|
|
2856
|
+
border-radius: var(--radius-full);
|
|
2857
|
+
background: transparent;
|
|
2858
|
+
color: var(--token-text-faint);
|
|
2859
|
+
font-size: 12px;
|
|
2860
|
+
line-height: 1;
|
|
2861
|
+
cursor: pointer;
|
|
2862
|
+
transition:
|
|
2863
|
+
color var(--icen-tx-fast),
|
|
2864
|
+
background-color var(--icen-tx-fast);
|
|
2865
|
+
}
|
|
2866
|
+
.ai-composer-chip-remove:hover {
|
|
2867
|
+
color: var(--token-error);
|
|
2868
|
+
background: var(--token-error-muted);
|
|
2869
|
+
}
|
|
2870
|
+
.ai-composer-chip-remove:focus-visible {
|
|
2871
|
+
outline: none;
|
|
2872
|
+
box-shadow: var(--icen-ring);
|
|
2873
|
+
}
|
|
2874
|
+
|
|
2875
|
+
/* 输入框(.control 基元提供 hover/focus 边框与光晕);flex-wrap 让工具条独占下一行 */
|
|
2876
|
+
.ai-composer-box {
|
|
2877
|
+
display: flex;
|
|
2878
|
+
flex-wrap: wrap;
|
|
2879
|
+
align-items: flex-end;
|
|
2880
|
+
gap: var(--density-space-sm);
|
|
2881
|
+
padding: var(--density-space-xs) var(--density-space-sm);
|
|
2882
|
+
border: 1px solid var(--token-line-soft);
|
|
2883
|
+
border-radius: var(--radius-md);
|
|
2884
|
+
background: var(--token-panel);
|
|
2885
|
+
box-shadow: var(--token-shadow-inset);
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2888
|
+
.ai-composer-input {
|
|
2889
|
+
flex: 1;
|
|
2890
|
+
min-width: 0;
|
|
2891
|
+
padding: var(--density-space-xs) 0;
|
|
2892
|
+
border: 0;
|
|
2893
|
+
outline: none;
|
|
2894
|
+
background: transparent;
|
|
2895
|
+
resize: none;
|
|
2896
|
+
font-family: inherit;
|
|
2897
|
+
font-size: var(--density-font-size-md);
|
|
2898
|
+
line-height: 1.5;
|
|
2899
|
+
max-height: 12em;
|
|
2900
|
+
overflow-y: auto;
|
|
2901
|
+
}
|
|
2902
|
+
|
|
2903
|
+
/* v1 旧结构按钮行(无 toolbar 配置时保留);v2 中按钮被移入工具条后此容器由 JS 移除 */
|
|
2904
|
+
.ai-composer-actions {
|
|
2905
|
+
display: flex;
|
|
2906
|
+
align-items: center;
|
|
2907
|
+
gap: var(--density-space-xs);
|
|
2908
|
+
flex-shrink: 0;
|
|
2909
|
+
}
|
|
2910
|
+
|
|
2911
|
+
/* ── v2 工具条(composer-box 内底部,业界主流形态)── */
|
|
2912
|
+
|
|
2913
|
+
.ai-composer-toolbar {
|
|
2914
|
+
flex: 0 0 100%;
|
|
2915
|
+
display: flex;
|
|
2916
|
+
align-items: center;
|
|
2917
|
+
gap: var(--density-space-xs);
|
|
2918
|
+
padding-top: var(--density-space-xs);
|
|
2919
|
+
border-top: 1px solid var(--token-line-soft);
|
|
2920
|
+
}
|
|
2921
|
+
.ai-composer-toolbar[hidden] {
|
|
2922
|
+
display: none;
|
|
2923
|
+
}
|
|
2924
|
+
|
|
2925
|
+
.ai-composer-spacer {
|
|
2926
|
+
flex: 1;
|
|
2927
|
+
}
|
|
2928
|
+
|
|
2929
|
+
/* 模型切换钮:provider 图标/首字母章 + 模型名 + chevron */
|
|
2930
|
+
.ai-composer-model {
|
|
2931
|
+
display: inline-flex;
|
|
2932
|
+
align-items: center;
|
|
2933
|
+
gap: 4px;
|
|
2934
|
+
max-width: 180px;
|
|
2935
|
+
height: 28px;
|
|
2936
|
+
padding: 0 var(--density-space-xs);
|
|
2937
|
+
border: 1px solid transparent;
|
|
2938
|
+
border-radius: var(--radius-sm);
|
|
2939
|
+
background: transparent;
|
|
2940
|
+
color: var(--token-text-muted);
|
|
2941
|
+
font-size: var(--density-font-size-xs);
|
|
2942
|
+
cursor: pointer;
|
|
2943
|
+
transition:
|
|
2944
|
+
color var(--icen-tx-fast),
|
|
2945
|
+
background-color var(--icen-tx-fast);
|
|
2946
|
+
}
|
|
2947
|
+
.ai-composer-model:hover {
|
|
2948
|
+
color: var(--token-text);
|
|
2949
|
+
background: var(--token-fill-2);
|
|
2950
|
+
}
|
|
2951
|
+
.ai-composer-model:focus-visible {
|
|
2952
|
+
outline: none;
|
|
2953
|
+
box-shadow: var(--icen-ring);
|
|
2954
|
+
}
|
|
2955
|
+
.ai-composer-model-icon,
|
|
2956
|
+
.ai-composer-model-provider-icon {
|
|
2957
|
+
display: inline-flex;
|
|
2958
|
+
align-items: center;
|
|
2959
|
+
justify-content: center;
|
|
2960
|
+
flex-shrink: 0;
|
|
2961
|
+
}
|
|
2962
|
+
.ai-composer-model-provider-icon svg {
|
|
2963
|
+
width: 14px;
|
|
2964
|
+
height: 14px;
|
|
2965
|
+
}
|
|
2966
|
+
.ai-composer-model-name {
|
|
2967
|
+
overflow: hidden;
|
|
2968
|
+
text-overflow: ellipsis;
|
|
2969
|
+
white-space: nowrap;
|
|
2970
|
+
}
|
|
2971
|
+
.ai-composer-model-chevron {
|
|
2972
|
+
display: inline-flex;
|
|
2973
|
+
align-items: center;
|
|
2974
|
+
justify-content: center;
|
|
2975
|
+
flex-shrink: 0;
|
|
2976
|
+
color: var(--token-text-faint);
|
|
2977
|
+
transition: transform var(--icen-tx-fast);
|
|
2978
|
+
}
|
|
2979
|
+
.ai-composer-model-chevron svg {
|
|
2980
|
+
width: 12px;
|
|
2981
|
+
height: 12px;
|
|
2982
|
+
}
|
|
2983
|
+
.ai-composer-model[aria-expanded='true'] .ai-composer-model-chevron {
|
|
2984
|
+
transform: rotate(180deg);
|
|
2985
|
+
}
|
|
2986
|
+
|
|
2987
|
+
/* provider 图标缺失时的首字母圆形章(token 色) */
|
|
2988
|
+
.ai-composer-model-badge {
|
|
2989
|
+
display: inline-flex;
|
|
2990
|
+
align-items: center;
|
|
2991
|
+
justify-content: center;
|
|
2992
|
+
width: 16px;
|
|
2993
|
+
height: 16px;
|
|
2994
|
+
border-radius: var(--radius-full);
|
|
2995
|
+
background: color-mix(in srgb, var(--token-accent) 15%, transparent);
|
|
2996
|
+
color: var(--token-accent);
|
|
2997
|
+
font-size: 10px;
|
|
2998
|
+
font-weight: 600;
|
|
2999
|
+
line-height: 1;
|
|
3000
|
+
user-select: none;
|
|
3001
|
+
}
|
|
3002
|
+
.ai-composer-model-icon .ai-composer-model-badge {
|
|
3003
|
+
width: 14px;
|
|
3004
|
+
height: 14px;
|
|
3005
|
+
font-size: 9px;
|
|
3006
|
+
}
|
|
3007
|
+
|
|
3008
|
+
/* 用量环挂载点(环本体 .ai-usage-ring 在 ai-panel.css) */
|
|
3009
|
+
.ai-composer-usage {
|
|
3010
|
+
display: inline-flex;
|
|
3011
|
+
align-items: center;
|
|
3012
|
+
flex-shrink: 0;
|
|
3013
|
+
}
|
|
3014
|
+
.ai-composer-usage:empty {
|
|
3015
|
+
display: none;
|
|
3016
|
+
}
|
|
3017
|
+
|
|
3018
|
+
/* ── v2 弹层(portal body,模型/命令/引用三模式共用基座;定位 inline 由 behavior 写入)── */
|
|
3019
|
+
|
|
3020
|
+
.ai-composer-popup {
|
|
3021
|
+
position: fixed;
|
|
3022
|
+
z-index: var(--z-popover);
|
|
3023
|
+
display: flex;
|
|
3024
|
+
flex-direction: column;
|
|
3025
|
+
padding: var(--density-space-2xs);
|
|
3026
|
+
border: 1px solid var(--token-line-soft);
|
|
3027
|
+
border-radius: var(--radius-md);
|
|
3028
|
+
background: var(--token-card-strong);
|
|
3029
|
+
box-shadow: var(--token-shadow-popover, var(--token-shadow-card));
|
|
3030
|
+
overflow: hidden;
|
|
3031
|
+
animation: icen-pop-in var(--ai-composer-popup-enter-duration, var(--duration-normal)) var(--ease-out);
|
|
3032
|
+
}
|
|
3033
|
+
|
|
3034
|
+
/* 搜索框(模型/引用过滤) */
|
|
3035
|
+
.ai-composer-popup-search {
|
|
3036
|
+
flex-shrink: 0;
|
|
3037
|
+
padding: var(--density-space-2xs);
|
|
3038
|
+
border-bottom: 1px solid var(--token-line-soft);
|
|
3039
|
+
}
|
|
3040
|
+
.ai-composer-popup-search-input {
|
|
3041
|
+
width: 100%;
|
|
3042
|
+
padding: var(--density-space-2xs) var(--density-space-xs);
|
|
3043
|
+
border: 1px solid var(--token-line-soft);
|
|
3044
|
+
border-radius: var(--radius-sm);
|
|
3045
|
+
background: var(--token-panel);
|
|
3046
|
+
color: var(--token-text);
|
|
3047
|
+
font-size: var(--density-font-size-sm);
|
|
3048
|
+
outline: none;
|
|
3049
|
+
transition: border-color var(--icen-tx-fast);
|
|
3050
|
+
}
|
|
3051
|
+
.ai-composer-popup-search-input:focus {
|
|
3052
|
+
border-color: var(--token-accent);
|
|
3053
|
+
}
|
|
3054
|
+
.ai-composer-popup-search-input::placeholder {
|
|
3055
|
+
color: var(--token-text-faint);
|
|
3056
|
+
}
|
|
3057
|
+
|
|
3058
|
+
/* 列表(max-height inline 由 behavior 按 computePopoverLayout 写入) */
|
|
3059
|
+
.ai-composer-popup-list {
|
|
3060
|
+
flex: 1;
|
|
3061
|
+
min-height: 0;
|
|
3062
|
+
overflow-y: auto;
|
|
3063
|
+
overscroll-behavior: contain;
|
|
3064
|
+
padding: var(--density-space-2xs);
|
|
3065
|
+
}
|
|
3066
|
+
|
|
3067
|
+
/* 分组(provider / ref kind) */
|
|
3068
|
+
.ai-composer-popup-group[hidden] {
|
|
3069
|
+
display: none;
|
|
3070
|
+
}
|
|
3071
|
+
.ai-composer-popup-group-label {
|
|
3072
|
+
display: flex;
|
|
3073
|
+
align-items: center;
|
|
3074
|
+
gap: 4px;
|
|
3075
|
+
padding: var(--density-space-xs) var(--density-space-xs) var(--density-space-2xs);
|
|
3076
|
+
font-size: var(--density-font-size-2xs);
|
|
3077
|
+
color: var(--token-text-faint);
|
|
3078
|
+
letter-spacing: 0.02em;
|
|
3079
|
+
}
|
|
3080
|
+
.ai-composer-popup-group-icon {
|
|
3081
|
+
display: inline-flex;
|
|
3082
|
+
align-items: center;
|
|
3083
|
+
justify-content: center;
|
|
3084
|
+
flex-shrink: 0;
|
|
3085
|
+
color: var(--token-text-muted);
|
|
3086
|
+
}
|
|
3087
|
+
.ai-composer-popup-group-icon svg {
|
|
3088
|
+
width: 12px;
|
|
3089
|
+
height: 12px;
|
|
3090
|
+
}
|
|
3091
|
+
.ai-composer-popup-group-icon .ai-composer-model-badge {
|
|
3092
|
+
width: 12px;
|
|
3093
|
+
height: 12px;
|
|
3094
|
+
font-size: 8px;
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
/* 选项行(label + meta + check) */
|
|
3098
|
+
.ai-composer-popup-option {
|
|
3099
|
+
display: flex;
|
|
3100
|
+
align-items: center;
|
|
3101
|
+
gap: var(--density-space-xs);
|
|
3102
|
+
width: 100%;
|
|
3103
|
+
padding: var(--density-space-xs);
|
|
3104
|
+
border: 0;
|
|
3105
|
+
border-radius: var(--radius-sm);
|
|
3106
|
+
background: transparent;
|
|
3107
|
+
color: var(--token-text);
|
|
3108
|
+
font-size: var(--density-font-size-sm);
|
|
3109
|
+
text-align: left;
|
|
3110
|
+
cursor: pointer;
|
|
3111
|
+
transition: background-color var(--icen-tx-fast);
|
|
3112
|
+
}
|
|
3113
|
+
.ai-composer-popup-option:hover {
|
|
3114
|
+
background: var(--token-fill-2);
|
|
3115
|
+
}
|
|
3116
|
+
.ai-composer-popup-option.is-focused {
|
|
3117
|
+
background: var(--token-fill-2);
|
|
3118
|
+
}
|
|
3119
|
+
.ai-composer-popup-option:focus-visible {
|
|
3120
|
+
outline: none;
|
|
3121
|
+
box-shadow: var(--icen-ring);
|
|
3122
|
+
}
|
|
3123
|
+
.ai-composer-popup-option-icon {
|
|
3124
|
+
display: inline-flex;
|
|
3125
|
+
align-items: center;
|
|
3126
|
+
justify-content: center;
|
|
3127
|
+
flex-shrink: 0;
|
|
3128
|
+
color: var(--token-text-muted);
|
|
3129
|
+
}
|
|
3130
|
+
.ai-composer-popup-option-icon svg {
|
|
3131
|
+
width: 14px;
|
|
3132
|
+
height: 14px;
|
|
3133
|
+
}
|
|
3134
|
+
.ai-composer-popup-option-icon .ai-composer-model-badge {
|
|
3135
|
+
width: 14px;
|
|
3136
|
+
height: 14px;
|
|
3137
|
+
font-size: 9px;
|
|
3138
|
+
}
|
|
3139
|
+
.ai-composer-popup-option-label {
|
|
3140
|
+
overflow: hidden;
|
|
3141
|
+
text-overflow: ellipsis;
|
|
3142
|
+
white-space: nowrap;
|
|
3143
|
+
}
|
|
3144
|
+
.ai-composer-popup-option-sub {
|
|
3145
|
+
margin-left: 6px;
|
|
3146
|
+
font-size: var(--density-font-size-2xs);
|
|
3147
|
+
color: var(--token-text-faint);
|
|
3148
|
+
}
|
|
3149
|
+
.ai-composer-popup-option-meta {
|
|
3150
|
+
margin-left: auto;
|
|
3151
|
+
flex-shrink: 0;
|
|
3152
|
+
font-family: var(--font-mono);
|
|
3153
|
+
font-size: var(--density-font-size-2xs);
|
|
3154
|
+
color: var(--token-text-faint);
|
|
3155
|
+
font-variant-numeric: tabular-nums;
|
|
3156
|
+
}
|
|
3157
|
+
.ai-composer-popup-option-check {
|
|
3158
|
+
display: none;
|
|
3159
|
+
flex-shrink: 0;
|
|
3160
|
+
color: var(--token-accent);
|
|
3161
|
+
}
|
|
3162
|
+
.ai-composer-popup-option-check svg {
|
|
3163
|
+
width: 12px;
|
|
3164
|
+
height: 12px;
|
|
3165
|
+
}
|
|
3166
|
+
.ai-composer-popup-option[aria-selected='true'] .ai-composer-popup-option-check {
|
|
3167
|
+
display: inline-flex;
|
|
3168
|
+
}
|
|
3169
|
+
|
|
3170
|
+
/* 命令行:/name <argsHint> + 描述 */
|
|
3171
|
+
.ai-composer-popup-cmd {
|
|
3172
|
+
flex-direction: column;
|
|
3173
|
+
align-items: flex-start;
|
|
3174
|
+
gap: 1px;
|
|
3175
|
+
}
|
|
3176
|
+
.ai-composer-popup-cmd-line {
|
|
3177
|
+
display: flex;
|
|
3178
|
+
align-items: baseline;
|
|
3179
|
+
gap: 6px;
|
|
3180
|
+
max-width: 100%;
|
|
3181
|
+
}
|
|
3182
|
+
.ai-composer-popup-cmd-name {
|
|
3183
|
+
font-family: var(--font-mono);
|
|
3184
|
+
color: var(--token-accent);
|
|
3185
|
+
}
|
|
3186
|
+
.ai-composer-popup-cmd-args {
|
|
3187
|
+
font-family: var(--font-mono);
|
|
3188
|
+
font-size: var(--density-font-size-2xs);
|
|
3189
|
+
color: var(--token-text-faint);
|
|
3190
|
+
}
|
|
3191
|
+
.ai-composer-popup-cmd-desc {
|
|
3192
|
+
font-size: var(--density-font-size-2xs);
|
|
3193
|
+
color: var(--token-text-muted);
|
|
3194
|
+
}
|
|
3195
|
+
|
|
3196
|
+
/* 空态 */
|
|
3197
|
+
.ai-composer-popup-empty {
|
|
3198
|
+
flex-shrink: 0;
|
|
3199
|
+
padding: var(--density-space-md);
|
|
3200
|
+
text-align: center;
|
|
3201
|
+
font-size: var(--density-font-size-sm);
|
|
3202
|
+
color: var(--token-text-faint);
|
|
3203
|
+
}
|
|
3204
|
+
.ai-composer-popup-empty[hidden] {
|
|
3205
|
+
display: none;
|
|
3206
|
+
}
|
|
3207
|
+
|
|
3208
|
+
/* 底部提示(模型弹层:切换模型会使 prompt 缓存失效;cacheRead 占比高时 warning 色) */
|
|
3209
|
+
.ai-composer-popup-foot {
|
|
3210
|
+
flex-shrink: 0;
|
|
3211
|
+
display: flex;
|
|
3212
|
+
align-items: center;
|
|
3213
|
+
gap: 4px;
|
|
3214
|
+
padding: var(--density-space-xs);
|
|
3215
|
+
border-top: 1px solid var(--token-line-soft);
|
|
3216
|
+
font-size: var(--density-font-size-2xs);
|
|
3217
|
+
color: var(--token-text-faint);
|
|
3218
|
+
}
|
|
3219
|
+
.ai-composer-popup-foot svg {
|
|
3220
|
+
width: 12px;
|
|
3221
|
+
height: 12px;
|
|
3222
|
+
flex-shrink: 0;
|
|
3223
|
+
}
|
|
3224
|
+
.ai-composer-popup-foot.is-warn {
|
|
3225
|
+
color: var(--token-warning);
|
|
3226
|
+
}
|
|
3227
|
+
|
|
3228
|
+
/* ── 工具条按钮统一 28px 方形、svg 14px 居中(v1 旧结构按钮同样收敛)── */
|
|
3229
|
+
|
|
3230
|
+
.ai-composer-btn {
|
|
3231
|
+
display: inline-flex;
|
|
3232
|
+
align-items: center;
|
|
3233
|
+
justify-content: center;
|
|
3234
|
+
width: 28px;
|
|
3235
|
+
height: 28px;
|
|
3236
|
+
padding: 0;
|
|
3237
|
+
border: 1px solid transparent;
|
|
3238
|
+
border-radius: var(--radius-sm);
|
|
3239
|
+
background: transparent;
|
|
3240
|
+
color: var(--token-text-muted);
|
|
3241
|
+
cursor: pointer;
|
|
3242
|
+
transition:
|
|
3243
|
+
color var(--icen-tx-fast),
|
|
3244
|
+
background-color var(--icen-tx-fast);
|
|
3245
|
+
}
|
|
3246
|
+
.ai-composer-btn:hover {
|
|
3247
|
+
color: var(--token-text);
|
|
3248
|
+
background: var(--token-fill-2);
|
|
3249
|
+
}
|
|
3250
|
+
.ai-composer-btn:focus-visible {
|
|
3251
|
+
outline: none;
|
|
3252
|
+
box-shadow: var(--icen-ring);
|
|
3253
|
+
}
|
|
3254
|
+
.ai-composer-btn svg {
|
|
3255
|
+
width: 14px;
|
|
3256
|
+
height: 14px;
|
|
3257
|
+
}
|
|
3258
|
+
|
|
3259
|
+
/* 发送钮:accent 实底;运行态 .is-stop 变停止钮(中性底 + error 色方标,停语气但不整钮铺红) */
|
|
3260
|
+
.ai-composer-send {
|
|
3261
|
+
display: inline-flex;
|
|
3262
|
+
align-items: center;
|
|
3263
|
+
justify-content: center;
|
|
3264
|
+
width: 28px;
|
|
3265
|
+
height: 28px;
|
|
3266
|
+
padding: 0;
|
|
3267
|
+
border: 1px solid transparent;
|
|
3268
|
+
border-radius: var(--radius-sm);
|
|
3269
|
+
background: var(--token-accent);
|
|
3270
|
+
color: var(--token-on-accent);
|
|
3271
|
+
cursor: pointer;
|
|
3272
|
+
transition:
|
|
3273
|
+
background-color var(--icen-tx-fast),
|
|
3274
|
+
color var(--icen-tx-fast),
|
|
3275
|
+
border-color var(--icen-tx-fast);
|
|
3276
|
+
}
|
|
3277
|
+
.ai-composer-send:hover {
|
|
3278
|
+
background: var(--token-accent-deep, var(--token-accent));
|
|
3279
|
+
}
|
|
3280
|
+
.ai-composer-send:focus-visible {
|
|
3281
|
+
outline: none;
|
|
3282
|
+
box-shadow: var(--icen-ring);
|
|
3283
|
+
}
|
|
3284
|
+
.ai-composer-send svg {
|
|
3285
|
+
width: 14px;
|
|
3286
|
+
height: 14px;
|
|
3287
|
+
}
|
|
3288
|
+
.ai-composer-send .ai-composer-send-icon[hidden] {
|
|
3289
|
+
display: none;
|
|
3290
|
+
}
|
|
3291
|
+
.ai-composer-send.is-stop {
|
|
3292
|
+
background: var(--token-surface-strong);
|
|
3293
|
+
color: var(--token-error);
|
|
3294
|
+
border-color: color-mix(in srgb, var(--token-error) 35%, transparent);
|
|
3295
|
+
}
|
|
3296
|
+
.ai-composer-send.is-stop:hover {
|
|
3297
|
+
background: var(--token-error-muted);
|
|
3298
|
+
}
|
|
3299
|
+
|
|
3300
|
+
/* 运行态:输入台整体 busy 标记(aria-busy 等价,状态机语言) */
|
|
3301
|
+
.ai-composer.is-running .ai-composer-box {
|
|
3302
|
+
border-color: color-mix(in srgb, var(--token-accent) 30%, var(--token-line-soft));
|
|
3303
|
+
}
|
|
3304
|
+
|
|
3305
|
+
/* 拖放文件高亮(粘贴/拖放附件入口,spec §11) */
|
|
3306
|
+
.ai-composer-box.is-dragover {
|
|
3307
|
+
border-color: var(--token-accent);
|
|
3308
|
+
box-shadow: var(--icen-ring);
|
|
3309
|
+
}
|
|
3310
|
+
|
|
3311
|
+
/* ══════════════ data-density 三档(summary 纯 CSS 降噪) ══════════════ */
|
|
3312
|
+
|
|
3313
|
+
/* summary:隐藏 meta、默认折叠 reasoning(head 展开仍可看)、次要消息压淡 */
|
|
3314
|
+
.ai-chat[data-density='summary'] .ai-msg-meta {
|
|
3315
|
+
display: none;
|
|
3316
|
+
}
|
|
3317
|
+
.ai-chat[data-density='summary'] .ai-reasoning-body {
|
|
3318
|
+
display: none;
|
|
3319
|
+
}
|
|
3320
|
+
.ai-chat[data-density='summary'] .ai-reasoning:has(.ai-reasoning-head[aria-expanded='true']) .ai-reasoning-body {
|
|
3321
|
+
display: block;
|
|
3322
|
+
}
|
|
3323
|
+
.ai-chat[data-density='summary'] .ai-msg--tool,
|
|
3324
|
+
.ai-chat[data-density='summary'] .ai-msg--system {
|
|
3325
|
+
opacity: 0.72;
|
|
3326
|
+
}
|
|
3327
|
+
|
|
3328
|
+
/* verbose:当前与 normal 同视觉(透明度三档中两档生效;verbose 预留全显档位) */
|
|
3329
|
+
|
|
3330
|
+
/* ══════════════ keyframes(本文件局部) ══════════════ */
|
|
3331
|
+
|
|
3332
|
+
@keyframes ai-shimmer {
|
|
3333
|
+
from {
|
|
3334
|
+
background-position: 200% 0;
|
|
3335
|
+
}
|
|
3336
|
+
to {
|
|
3337
|
+
background-position: -200% 0;
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
|
|
3341
|
+
/* ══════════════ 动效守卫 ══════════════ */
|
|
3342
|
+
|
|
3343
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3344
|
+
.ai-msg,
|
|
3345
|
+
.ai-chat-jump,
|
|
3346
|
+
.ai-composer-popup {
|
|
3347
|
+
animation: none;
|
|
3348
|
+
}
|
|
3349
|
+
.ai-chat-jump,
|
|
3350
|
+
.ai-msg-actions,
|
|
3351
|
+
.ai-composer-chip-remove,
|
|
3352
|
+
.ai-composer-btn,
|
|
3353
|
+
.ai-composer-send,
|
|
3354
|
+
.ai-composer-model,
|
|
3355
|
+
.ai-composer-model-chevron,
|
|
3356
|
+
.ai-composer-popup-option,
|
|
3357
|
+
.ai-composer-popup-search-input,
|
|
3358
|
+
.ai-reasoning-head,
|
|
3359
|
+
.ai-reasoning-head::before {
|
|
3360
|
+
transition: none;
|
|
3361
|
+
}
|
|
3362
|
+
.ai-reasoning.is-streaming .ai-reasoning-head::after {
|
|
3363
|
+
animation: none;
|
|
3364
|
+
background: none;
|
|
3365
|
+
-webkit-text-fill-color: currentColor;
|
|
3366
|
+
color: var(--token-text-faint);
|
|
3367
|
+
}
|
|
3368
|
+
.ai-msg-body.is-streaming::after,
|
|
3369
|
+
.ai-reasoning-body.is-streaming::after {
|
|
3370
|
+
animation: none;
|
|
3371
|
+
}
|
|
3372
|
+
}
|
|
3373
|
+
|
|
3374
|
+
/* 触屏无 hover:消息操作常显(否则不可达) */
|
|
3375
|
+
@media (pointer: coarse) {
|
|
3376
|
+
.ai-msg-actions {
|
|
3377
|
+
opacity: 1;
|
|
3378
|
+
visibility: visible;
|
|
3379
|
+
transform: none;
|
|
3380
|
+
}
|
|
3381
|
+
}
|
|
3382
|
+
|
|
3383
|
+
/* 实时待办 chip(setComposerTodo:业界模式——plan 状态挂输入区,不进对话流) */
|
|
3384
|
+
.ai-composer-todo {
|
|
3385
|
+
display: inline-flex;
|
|
3386
|
+
align-items: center;
|
|
3387
|
+
gap: 5px;
|
|
3388
|
+
height: 28px;
|
|
3389
|
+
padding: 0 8px;
|
|
3390
|
+
border: 1px solid var(--token-line-soft);
|
|
3391
|
+
border-radius: var(--radius-full);
|
|
3392
|
+
background: var(--token-surface);
|
|
3393
|
+
color: var(--token-text-muted);
|
|
3394
|
+
font-family: var(--font-mono);
|
|
3395
|
+
font-size: var(--density-font-size-2xs);
|
|
3396
|
+
font-variant-numeric: tabular-nums;
|
|
3397
|
+
cursor: pointer;
|
|
3398
|
+
transition: color var(--icen-tx-fast), border-color var(--icen-tx-fast);
|
|
3399
|
+
}
|
|
3400
|
+
.ai-composer-todo svg { width: 13px; height: 13px; color: var(--token-accent); }
|
|
3401
|
+
.ai-composer-todo:hover { border-color: var(--icen-hover-border, var(--token-line)); color: var(--token-text); }
|
|
3402
|
+
.ai-composer-todo:focus-visible { outline: none; box-shadow: var(--icen-ring); }
|
|
3403
|
+
.ai-composer-todo.is-done svg { color: var(--token-success); }
|
|
3404
|
+
.ai-composer-todo.is-error svg { color: var(--token-warning); }
|
|
3405
|
+
.ai-composer-todo-pop { min-width: 240px; max-width: 320px; }
|
|
3406
|
+
.ai-composer-todo-pop .ai-todo { padding: 0; }
|
|
3407
|
+
|
|
3408
|
+
|
|
3409
|
+
/* ── components/ai-diff.css ── */
|
|
3410
|
+
/*
|
|
3411
|
+
* @icen.ai/ui — Component: ai-diff(AI 差异审阅 + 文件 chips,与 behaviors/ai-diff.ts 配套)
|
|
3412
|
+
*
|
|
3413
|
+
* 完整 DOM 契约(类名与规格 §4.6/§4.7 一致):
|
|
3414
|
+
* <div class="ai-diff">
|
|
3415
|
+
* <div class="ai-diff-file is-added|is-modified|is-deleted|is-renamed
|
|
3416
|
+
* [.is-accepted|.is-rejected]" data-path="src/foo.ts">
|
|
3417
|
+
* <div class="ai-diff-head" role="button" tabindex="0" aria-expanded="false">
|
|
3418
|
+
* <span class="ai-diff-path">src/foo.ts</span> <!-- renamed:旧路径 → 新路径 -->
|
|
3419
|
+
* <span class="ai-diff-stat"><b class="ai-diff-add">+12</b> <b class="ai-diff-del">−4</b></span>
|
|
3420
|
+
* <span class="ai-diff-actions">
|
|
3421
|
+
* <button type="button" data-ai-diff-accept>接受</button>
|
|
3422
|
+
* <button type="button" data-ai-diff-reject>拒绝</button>
|
|
3423
|
+
* </span>
|
|
3424
|
+
* <span class="ai-diff-verdict" hidden>已接受|已拒绝</span> <!-- 状态章(JS 决策后显示) -->
|
|
3425
|
+
* </div>
|
|
3426
|
+
* <div class="ai-diff-body" hidden>
|
|
3427
|
+
* <table class="ai-diff-table">
|
|
3428
|
+
* <tr class="ai-diff-line--hunk"><td colspan="3">@@ -10,6 +10,8 @@ …</td></tr>
|
|
3429
|
+
* <tr class="ai-diff-line--ctx|ai-diff-line--add|ai-diff-line--del">
|
|
3430
|
+
* <td class="ai-diff-ln" aria-hidden="true">10</td>
|
|
3431
|
+
* <td class="ai-diff-ln" aria-hidden="true">10</td>
|
|
3432
|
+
* <td class="ai-diff-code">内容(行首符号由 ::before 提供)</td>
|
|
3433
|
+
* </tr>
|
|
3434
|
+
* </table>
|
|
3435
|
+
* </div>
|
|
3436
|
+
* </div>
|
|
3437
|
+
* </div>
|
|
3438
|
+
*
|
|
3439
|
+
* 文件 chips(纯 CSS 族,无 behavior;文件图标由消费方/ai-panel.ts 注入 svg):
|
|
3440
|
+
* <div class="ai-files">
|
|
3441
|
+
* <span class="ai-file-chip is-added|is-modified|is-deleted
|
|
3442
|
+
* ai-file-chip--ts|js|css|json|md|img|other">
|
|
3443
|
+
* <span class="ai-file-icon">…svg…</span>src/foo.ts
|
|
3444
|
+
* </span>
|
|
3445
|
+
* </div>
|
|
3446
|
+
*
|
|
3447
|
+
* 状态视觉:
|
|
3448
|
+
* add 行 = success 底 / del 行 = error 底 / hunk 行 = info 文字(bg-soft 底)
|
|
3449
|
+
* 文件头状态色边(inset 左色条):added=success / modified=accent / deleted=error / renamed=info
|
|
3450
|
+
* .is-accepted / .is-rejected = 整体淡化 + .ai-diff-verdict 状态章,actions 由 JS hidden
|
|
3451
|
+
*
|
|
3452
|
+
* 依赖:base.css(--icen-tx-* / --icen-ring / keyframes icen-pop-in)。
|
|
3453
|
+
* 只消费 --token-* / --density-* / --radius-*;动画时长全部走组件局部变量。
|
|
3454
|
+
*/
|
|
3455
|
+
|
|
3456
|
+
/* ══════════════ ai-diff · 差异审阅 ══════════════ */
|
|
3457
|
+
|
|
3458
|
+
.ai-diff {
|
|
3459
|
+
display: flex;
|
|
3460
|
+
flex-direction: column;
|
|
3461
|
+
gap: var(--density-space-sm);
|
|
3462
|
+
font-size: var(--density-font-size-sm);
|
|
3463
|
+
min-width: 0;
|
|
3464
|
+
align-self: stretch; /* 输出容器宽度自稳定:宿主 flex/grid 居中时不 shrink-wrap */
|
|
3465
|
+
}
|
|
3466
|
+
|
|
3467
|
+
.ai-diff-file {
|
|
3468
|
+
border: 1px solid var(--token-line-soft);
|
|
3469
|
+
border-radius: var(--radius-md);
|
|
3470
|
+
background: var(--token-surface);
|
|
3471
|
+
overflow: hidden;
|
|
3472
|
+
min-width: 0;
|
|
3473
|
+
animation: icen-pop-in var(--ai-diff-pop-duration, var(--icen-tx-fast));
|
|
3474
|
+
}
|
|
3475
|
+
|
|
3476
|
+
/* 文件头状态色边(inset 色条避免 border 宽差导致布局抖动) */
|
|
3477
|
+
.ai-diff-file.is-added { box-shadow: inset 3px 0 0 var(--token-success); }
|
|
3478
|
+
.ai-diff-file.is-modified { box-shadow: inset 3px 0 0 var(--token-accent); }
|
|
3479
|
+
.ai-diff-file.is-deleted { box-shadow: inset 3px 0 0 var(--token-error); }
|
|
3480
|
+
.ai-diff-file.is-renamed { box-shadow: inset 3px 0 0 var(--token-info); }
|
|
3481
|
+
|
|
3482
|
+
/* 决策后淡化(状态章配色见 .ai-diff-verdict) */
|
|
3483
|
+
.ai-diff-file.is-accepted,
|
|
3484
|
+
.ai-diff-file.is-rejected {
|
|
3485
|
+
opacity: 0.66;
|
|
3486
|
+
transition: opacity var(--ai-diff-fade-duration, var(--icen-tx-normal));
|
|
3487
|
+
}
|
|
3488
|
+
|
|
3489
|
+
/* ── head ── */
|
|
3490
|
+
|
|
3491
|
+
.ai-diff-head {
|
|
3492
|
+
display: flex;
|
|
3493
|
+
align-items: center;
|
|
3494
|
+
gap: var(--density-space-sm);
|
|
3495
|
+
padding: var(--density-space-xs) var(--density-space-sm);
|
|
3496
|
+
min-width: 0;
|
|
3497
|
+
cursor: pointer;
|
|
3498
|
+
user-select: none;
|
|
3499
|
+
transition: background-color var(--icen-tx-fast);
|
|
3500
|
+
}
|
|
3501
|
+
.ai-diff-head:hover {
|
|
3502
|
+
background: var(--token-fill-1);
|
|
3503
|
+
}
|
|
3504
|
+
.ai-diff-head:focus-visible {
|
|
3505
|
+
outline: none;
|
|
3506
|
+
box-shadow: var(--icen-ring);
|
|
3507
|
+
}
|
|
3508
|
+
|
|
3509
|
+
.ai-diff-path {
|
|
3510
|
+
flex: 1;
|
|
3511
|
+
min-width: 0;
|
|
3512
|
+
overflow: hidden;
|
|
3513
|
+
text-overflow: ellipsis;
|
|
3514
|
+
white-space: nowrap;
|
|
3515
|
+
font-family: var(--font-mono);
|
|
3516
|
+
font-size: var(--density-font-size-xs);
|
|
3517
|
+
color: var(--token-text);
|
|
3518
|
+
}
|
|
3519
|
+
|
|
3520
|
+
.ai-diff-stat {
|
|
3521
|
+
flex-shrink: 0;
|
|
3522
|
+
display: inline-flex;
|
|
3523
|
+
gap: var(--density-space-xs);
|
|
3524
|
+
font-size: var(--density-font-size-xs);
|
|
3525
|
+
font-variant-numeric: tabular-nums;
|
|
3526
|
+
}
|
|
3527
|
+
.ai-diff-add { color: var(--token-success); font-weight: 600; }
|
|
3528
|
+
.ai-diff-del { color: var(--token-error); font-weight: 600; }
|
|
3529
|
+
|
|
3530
|
+
/* accept / reject 行内小钮(DOM 无固定类,按 data 属性定位) */
|
|
3531
|
+
.ai-diff-actions {
|
|
3532
|
+
flex-shrink: 0;
|
|
3533
|
+
display: inline-flex;
|
|
3534
|
+
gap: var(--density-space-xs);
|
|
3535
|
+
}
|
|
3536
|
+
.ai-diff-actions button {
|
|
3537
|
+
padding: 3px 10px;
|
|
3538
|
+
border: 1px solid var(--token-line-soft);
|
|
3539
|
+
border-radius: var(--radius-full);
|
|
3540
|
+
background: var(--token-surface);
|
|
3541
|
+
color: var(--token-text-muted);
|
|
3542
|
+
font-size: var(--density-font-size-xs);
|
|
3543
|
+
line-height: 1.4;
|
|
3544
|
+
cursor: pointer;
|
|
3545
|
+
transition:
|
|
3546
|
+
background-color var(--icen-tx-fast),
|
|
3547
|
+
border-color var(--icen-tx-fast),
|
|
3548
|
+
color var(--icen-tx-fast);
|
|
3549
|
+
}
|
|
3550
|
+
.ai-diff-actions button:focus-visible {
|
|
3551
|
+
outline: none;
|
|
3552
|
+
box-shadow: var(--icen-ring);
|
|
3553
|
+
}
|
|
3554
|
+
.ai-diff-actions [data-ai-diff-accept]:hover {
|
|
3555
|
+
color: var(--token-success);
|
|
3556
|
+
border-color: color-mix(in srgb, var(--token-success) 45%, transparent);
|
|
3557
|
+
background: var(--token-success-muted);
|
|
3558
|
+
}
|
|
3559
|
+
.ai-diff-actions [data-ai-diff-reject]:hover {
|
|
3560
|
+
color: var(--token-error);
|
|
3561
|
+
border-color: color-mix(in srgb, var(--token-error) 45%, transparent);
|
|
3562
|
+
background: var(--token-error-muted);
|
|
3563
|
+
}
|
|
3564
|
+
|
|
3565
|
+
/* 状态章:决策后 JS 置 text + 去 hidden */
|
|
3566
|
+
.ai-diff-verdict {
|
|
3567
|
+
flex-shrink: 0;
|
|
3568
|
+
padding: 2px 8px;
|
|
3569
|
+
border: 1px solid currentColor;
|
|
3570
|
+
border-radius: var(--radius-full);
|
|
3571
|
+
font-size: var(--density-font-size-xs);
|
|
3572
|
+
font-weight: 500;
|
|
3573
|
+
line-height: 1.4;
|
|
3574
|
+
}
|
|
3575
|
+
.ai-diff-file.is-accepted .ai-diff-verdict { color: var(--token-success); background: var(--token-success-muted); }
|
|
3576
|
+
.ai-diff-file.is-rejected .ai-diff-verdict { color: var(--token-error); background: var(--token-error-muted); }
|
|
3577
|
+
|
|
3578
|
+
/* ── body / 表格 ── */
|
|
3579
|
+
|
|
3580
|
+
.ai-diff-body {
|
|
3581
|
+
border-top: 1px solid var(--token-line-soft);
|
|
3582
|
+
overflow-x: auto;
|
|
3583
|
+
}
|
|
3584
|
+
|
|
3585
|
+
.ai-diff-table {
|
|
3586
|
+
width: 100%;
|
|
3587
|
+
border-collapse: collapse;
|
|
3588
|
+
font-family: var(--font-mono);
|
|
3589
|
+
font-size: var(--density-font-size-xs);
|
|
3590
|
+
line-height: 1.6;
|
|
3591
|
+
}
|
|
3592
|
+
.ai-diff-table td {
|
|
3593
|
+
padding: 0 var(--density-space-xs);
|
|
3594
|
+
vertical-align: top;
|
|
3595
|
+
}
|
|
3596
|
+
|
|
3597
|
+
/* hunk 头:info 文字 */
|
|
3598
|
+
.ai-diff-line--hunk td {
|
|
3599
|
+
padding: 2px var(--density-space-sm);
|
|
3600
|
+
background: var(--token-bg-soft);
|
|
3601
|
+
color: var(--token-info);
|
|
3602
|
+
user-select: none;
|
|
3603
|
+
white-space: nowrap;
|
|
3604
|
+
}
|
|
3605
|
+
|
|
3606
|
+
.ai-diff-ln {
|
|
3607
|
+
width: 1%;
|
|
3608
|
+
min-width: 3.5ch;
|
|
3609
|
+
text-align: right;
|
|
3610
|
+
color: var(--token-text-faint);
|
|
3611
|
+
font-variant-numeric: tabular-nums;
|
|
3612
|
+
user-select: none;
|
|
3613
|
+
}
|
|
3614
|
+
/* 行号区与代码区的分隔线画在第二列右侧 */
|
|
3615
|
+
.ai-diff-ln + .ai-diff-ln {
|
|
3616
|
+
border-right: 1px solid var(--token-line-soft);
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3619
|
+
/* add = success 底 / del = error 底 */
|
|
3620
|
+
.ai-diff-line--add { background: var(--token-success-muted); }
|
|
3621
|
+
.ai-diff-line--del { background: var(--token-error-muted); }
|
|
3622
|
+
|
|
3623
|
+
.ai-diff-code {
|
|
3624
|
+
white-space: pre-wrap;
|
|
3625
|
+
word-break: break-all;
|
|
3626
|
+
padding-left: var(--density-space-sm);
|
|
3627
|
+
}
|
|
3628
|
+
/* 行首符号(选择 diff 内容时不带符号) */
|
|
3629
|
+
.ai-diff-code::before {
|
|
3630
|
+
user-select: none;
|
|
3631
|
+
}
|
|
3632
|
+
.ai-diff-line--add .ai-diff-code::before {
|
|
3633
|
+
content: '+ ';
|
|
3634
|
+
color: var(--token-success);
|
|
3635
|
+
}
|
|
3636
|
+
.ai-diff-line--del .ai-diff-code::before {
|
|
3637
|
+
content: '− ';
|
|
3638
|
+
color: var(--token-error);
|
|
3639
|
+
}
|
|
3640
|
+
.ai-diff-line--ctx .ai-diff-code::before {
|
|
3641
|
+
content: ' ';
|
|
3642
|
+
}
|
|
3643
|
+
|
|
3644
|
+
/* ══════════════ ai-files · 文件 chips(纯 CSS 族) ══════════════ */
|
|
3645
|
+
|
|
3646
|
+
.ai-files {
|
|
3647
|
+
display: flex;
|
|
3648
|
+
flex-wrap: wrap;
|
|
3649
|
+
gap: var(--density-space-xs);
|
|
3650
|
+
align-self: stretch; /* 容器自稳定;chip 自身保持内容宽 */
|
|
3651
|
+
}
|
|
3652
|
+
|
|
3653
|
+
.ai-file-chip {
|
|
3654
|
+
display: inline-flex;
|
|
3655
|
+
align-items: center;
|
|
3656
|
+
gap: 5px;
|
|
3657
|
+
max-width: 100%;
|
|
3658
|
+
padding: 2px 8px;
|
|
3659
|
+
border: 1px solid var(--token-line-soft);
|
|
3660
|
+
border-radius: var(--radius-full);
|
|
3661
|
+
background: var(--token-surface);
|
|
3662
|
+
color: var(--token-text-muted);
|
|
3663
|
+
font-family: var(--font-mono);
|
|
3664
|
+
font-size: var(--density-font-size-xs);
|
|
3665
|
+
line-height: 1.6;
|
|
3666
|
+
overflow: hidden;
|
|
3667
|
+
text-overflow: ellipsis;
|
|
3668
|
+
white-space: nowrap;
|
|
3669
|
+
transition:
|
|
3670
|
+
background-color var(--icen-tx-fast),
|
|
3671
|
+
border-color var(--icen-tx-fast);
|
|
3672
|
+
}
|
|
3673
|
+
.ai-file-chip:hover {
|
|
3674
|
+
background: var(--token-fill-1);
|
|
3675
|
+
border-color: var(--token-line);
|
|
3676
|
+
}
|
|
3677
|
+
|
|
3678
|
+
/* 状态色点(尾点,纯 CSS) */
|
|
3679
|
+
.ai-file-chip::after {
|
|
3680
|
+
content: '';
|
|
3681
|
+
flex-shrink: 0;
|
|
3682
|
+
width: 6px;
|
|
3683
|
+
height: 6px;
|
|
3684
|
+
border-radius: var(--radius-full);
|
|
3685
|
+
background: var(--token-text-faint);
|
|
3686
|
+
}
|
|
3687
|
+
.ai-file-chip.is-added::after { background: var(--token-success); }
|
|
3688
|
+
.ai-file-chip.is-modified::after { background: var(--token-accent); }
|
|
3689
|
+
.ai-file-chip.is-deleted::after { background: var(--token-error); }
|
|
3690
|
+
|
|
3691
|
+
.ai-file-chip.is-deleted {
|
|
3692
|
+
text-decoration: line-through;
|
|
3693
|
+
opacity: 0.75;
|
|
3694
|
+
}
|
|
3695
|
+
|
|
3696
|
+
.ai-file-icon {
|
|
3697
|
+
flex-shrink: 0;
|
|
3698
|
+
display: inline-flex;
|
|
3699
|
+
color: var(--token-text-faint);
|
|
3700
|
+
}
|
|
3701
|
+
.ai-file-icon svg {
|
|
3702
|
+
width: 13px;
|
|
3703
|
+
height: 13px;
|
|
3704
|
+
}
|
|
3705
|
+
|
|
3706
|
+
/* 文件类型色(语义 token):ts/js=冷调 accent-cold,css=accent,json=warning,md=info,img=success */
|
|
3707
|
+
.ai-file-chip--ts .ai-file-icon,
|
|
3708
|
+
.ai-file-chip--js .ai-file-icon { color: var(--token-accent-cold); }
|
|
3709
|
+
.ai-file-chip--css .ai-file-icon { color: var(--token-accent); }
|
|
3710
|
+
.ai-file-chip--json .ai-file-icon { color: var(--token-warning); }
|
|
3711
|
+
.ai-file-chip--md .ai-file-icon { color: var(--token-info); }
|
|
3712
|
+
.ai-file-chip--img .ai-file-icon { color: var(--token-success); }
|
|
3713
|
+
|
|
3714
|
+
/* ── 动效守卫 ── */
|
|
3715
|
+
|
|
3716
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3717
|
+
.ai-diff-file { animation: none; }
|
|
3718
|
+
.ai-diff-file.is-accepted,
|
|
3719
|
+
.ai-diff-file.is-rejected { transition: none; }
|
|
3720
|
+
}
|
|
3721
|
+
|
|
3722
|
+
|
|
3723
|
+
/* ── components/ai-panel.css ── */
|
|
3724
|
+
/*
|
|
3725
|
+
* @icen.ai/ui — Component: ai-panel(AI 任务面板族:todo / context / usage,与 behaviors/ai-panel.ts 配套)
|
|
3726
|
+
*
|
|
3727
|
+
* 完整 DOM 契约(类名与规格 §4.8/§4.9/§4.10 一致):
|
|
3728
|
+
* <div class="ai-todo" [.is-complete] [data-ai-todo-interactive]>
|
|
3729
|
+
* <div class="ai-todo-head">
|
|
3730
|
+
* <span class="ai-todo-progress">2/5</span>
|
|
3731
|
+
* <div class="ai-todo-bar" role="progressbar" …><i style="width:40%"></i></div>
|
|
3732
|
+
* </div>
|
|
3733
|
+
* <div class="ai-todo-item is-pending|running|streaming|approval|done|error|cancelled
|
|
3734
|
+
* [role="button" tabindex="0"]" data-index="0">
|
|
3735
|
+
* <span class="ai-item-status"></span> <!-- 状态点,纯 CSS 由 .is-* 驱动 -->
|
|
3736
|
+
* <span class="ai-todo-text">实现登录页</span>
|
|
3737
|
+
* <span class="ai-todo-active">正在实现登录页…</span> <!-- is-running 时替换 text(CSS 驱动) -->
|
|
3738
|
+
* </div>
|
|
3739
|
+
* </div>
|
|
3740
|
+
*
|
|
3741
|
+
* <div class="ai-usage">
|
|
3742
|
+
* <div class="ai-usage-bar" role="img" aria-label="…">
|
|
3743
|
+
* <i class="ai-usage-seg ai-usage-seg--input|output|cache-read|cache-write|reasoning" style="width:35%"></i>…
|
|
3744
|
+
* </div>
|
|
3745
|
+
* <div class="ai-usage-legend">
|
|
3746
|
+
* <span class="ai-usage-legend-item">
|
|
3747
|
+
* <i class="ai-usage-dot ai-usage-seg--input"></i>
|
|
3748
|
+
* <span class="ai-usage-legend-label">输入</span> <span class="ai-usage-legend-value">35k</span>
|
|
3749
|
+
* </span>…
|
|
3750
|
+
* </div>
|
|
3751
|
+
* <div class="ai-usage-total">82k / 200k · 41%</div>
|
|
3752
|
+
* </div>
|
|
3753
|
+
*
|
|
3754
|
+
* <aside class="ai-context [.ai-context--inline]" hidden role="dialog" aria-label="上下文">
|
|
3755
|
+
* <div class="ai-context-head"><span>上下文</span>
|
|
3756
|
+
* <button type="button" data-ai-context-close aria-label="关闭">×</button></div>
|
|
3757
|
+
* <section class="ai-context-section"><h3>…</h3>
|
|
3758
|
+
* <div class="ai-context-section-body">…renderAiContext 产物…</div> <!-- 可选包裹,亦可直接放内容 -->
|
|
3759
|
+
* </section>…
|
|
3760
|
+
* </aside>
|
|
3761
|
+
*
|
|
3762
|
+
* .ai-item 行(MCP / Skills,规格 §2 基元):
|
|
3763
|
+
* <div class="ai-item is-done|is-error" style="--ai-item-tint: var(--token-accent)">
|
|
3764
|
+
* <span class="ai-item-icon">…svg…</span>
|
|
3765
|
+
* <span class="ai-item-main">
|
|
3766
|
+
* <span class="ai-item-title">github</span><span class="ai-item-sub">…</span>
|
|
3767
|
+
* </span>
|
|
3768
|
+
* <span class="ai-item-side"><span class="ai-item-status"></span><span class="ai-item-meta">12 工具</span></span>
|
|
3769
|
+
* </div>
|
|
3770
|
+
*
|
|
3771
|
+
* 依赖说明:
|
|
3772
|
+
* - .ai-item 完整版在 ai-tool.css(S2)。此处按任务约定重新声明最小骨架(含 --ai-item-tint
|
|
3773
|
+
* 局部变量与状态点),保证 ai-panel.css 单独引入时 todo/context 可用;两边类名/语义一致,
|
|
3774
|
+
* 同页面共存时后加载者覆盖同款属性,视觉不冲突。
|
|
3775
|
+
* - keyframes ai-status-pulse 为组件局部定义(等同 pill.css 的 pill-pulse),
|
|
3776
|
+
* 时长走 var(--pill-pulse-duration, 1.5s):pill.css 在场时与其同步,否则自洽。
|
|
3777
|
+
* - blink keyframes 来自 tokens/colors.css(.animate-blink 同款,共享复用)。
|
|
3778
|
+
* - base.css:--z-chrome / --icen-tx-* / --icen-ring。只消费 --token-* / --density-* / --radius-*。
|
|
3779
|
+
*/
|
|
3780
|
+
|
|
3781
|
+
/* ══════════════ .ai-item 最小基元(自包含,兼容 ai-tool.css 完整版) ══════════════ */
|
|
3782
|
+
|
|
3783
|
+
.ai-item {
|
|
3784
|
+
--ai-item-tint: var(--token-accent);
|
|
3785
|
+
display: flex;
|
|
3786
|
+
align-items: center;
|
|
3787
|
+
gap: var(--density-space-sm);
|
|
3788
|
+
padding: var(--density-space-xs) var(--density-space-sm);
|
|
3789
|
+
border-radius: var(--radius-sm);
|
|
3790
|
+
font-size: var(--density-font-size-sm);
|
|
3791
|
+
min-width: 0;
|
|
3792
|
+
align-self: stretch; /* 宽度自稳定:宿主 flex/grid 居中时不 shrink-wrap */
|
|
3793
|
+
}
|
|
3794
|
+
|
|
3795
|
+
.ai-item-icon {
|
|
3796
|
+
flex-shrink: 0;
|
|
3797
|
+
display: inline-flex;
|
|
3798
|
+
color: var(--ai-item-tint);
|
|
3799
|
+
}
|
|
3800
|
+
.ai-item-icon svg {
|
|
3801
|
+
width: 15px;
|
|
3802
|
+
height: 15px;
|
|
3803
|
+
}
|
|
3804
|
+
|
|
3805
|
+
.ai-item-main {
|
|
3806
|
+
flex: 1;
|
|
3807
|
+
min-width: 0;
|
|
3808
|
+
display: flex;
|
|
3809
|
+
flex-direction: column;
|
|
3810
|
+
gap: 1px;
|
|
3811
|
+
}
|
|
3812
|
+
.ai-item-title {
|
|
3813
|
+
color: var(--token-text);
|
|
3814
|
+
line-height: 1.4;
|
|
3815
|
+
overflow: hidden;
|
|
3816
|
+
text-overflow: ellipsis;
|
|
3817
|
+
white-space: nowrap;
|
|
3818
|
+
}
|
|
3819
|
+
.ai-item-sub {
|
|
3820
|
+
font-size: var(--density-font-size-xs);
|
|
3821
|
+
color: var(--token-text-muted);
|
|
3822
|
+
overflow: hidden;
|
|
3823
|
+
text-overflow: ellipsis;
|
|
3824
|
+
white-space: nowrap;
|
|
3825
|
+
}
|
|
3826
|
+
|
|
3827
|
+
.ai-item-side {
|
|
3828
|
+
flex-shrink: 0;
|
|
3829
|
+
display: inline-flex;
|
|
3830
|
+
align-items: center;
|
|
3831
|
+
gap: var(--density-space-xs);
|
|
3832
|
+
}
|
|
3833
|
+
.ai-item-meta {
|
|
3834
|
+
font-size: var(--density-font-size-xs);
|
|
3835
|
+
color: var(--token-text-faint);
|
|
3836
|
+
font-variant-numeric: tabular-nums;
|
|
3837
|
+
}
|
|
3838
|
+
|
|
3839
|
+
/* ── 状态点 .ai-item-status:纯 CSS 圆点,由 .is-* 驱动(ai-item 与 ai-todo-item 共用) ── */
|
|
3840
|
+
|
|
3841
|
+
.ai-item-status {
|
|
3842
|
+
flex-shrink: 0;
|
|
3843
|
+
width: 8px;
|
|
3844
|
+
height: 8px;
|
|
3845
|
+
border-radius: var(--radius-full);
|
|
3846
|
+
border: 1.5px solid var(--token-text-faint);
|
|
3847
|
+
background: transparent;
|
|
3848
|
+
}
|
|
3849
|
+
|
|
3850
|
+
/* pending:faint 空心点(默认态即空心) */
|
|
3851
|
+
.ai-item.is-pending > .ai-item-status,
|
|
3852
|
+
.ai-todo-item.is-pending > .ai-item-status { }
|
|
3853
|
+
|
|
3854
|
+
/* running / streaming:accent 脉冲点 */
|
|
3855
|
+
.ai-item.is-running > .ai-item-status,
|
|
3856
|
+
.ai-todo-item.is-running > .ai-item-status,
|
|
3857
|
+
.ai-item.is-streaming > .ai-item-status,
|
|
3858
|
+
.ai-todo-item.is-streaming > .ai-item-status {
|
|
3859
|
+
border-color: var(--token-accent);
|
|
3860
|
+
background: var(--token-accent);
|
|
3861
|
+
animation: ai-status-pulse var(--pill-pulse-duration, 1.5s) ease-in-out infinite;
|
|
3862
|
+
}
|
|
3863
|
+
|
|
3864
|
+
/* approval:warning 点 */
|
|
3865
|
+
.ai-item.is-approval > .ai-item-status,
|
|
3866
|
+
.ai-todo-item.is-approval > .ai-item-status {
|
|
3867
|
+
border-color: var(--token-warning);
|
|
3868
|
+
background: var(--token-warning);
|
|
3869
|
+
}
|
|
3870
|
+
|
|
3871
|
+
/* done:success 点 */
|
|
3872
|
+
.ai-item.is-done > .ai-item-status,
|
|
3873
|
+
.ai-todo-item.is-done > .ai-item-status {
|
|
3874
|
+
border-color: var(--token-success);
|
|
3875
|
+
background: var(--token-success);
|
|
3876
|
+
}
|
|
3877
|
+
|
|
3878
|
+
/* error:error 点 */
|
|
3879
|
+
.ai-item.is-error > .ai-item-status,
|
|
3880
|
+
.ai-todo-item.is-error > .ai-item-status {
|
|
3881
|
+
border-color: var(--token-error);
|
|
3882
|
+
background: var(--token-error);
|
|
3883
|
+
}
|
|
3884
|
+
|
|
3885
|
+
/* cancelled:faint 实心点 + 标题删除线(规格 §1) */
|
|
3886
|
+
.ai-item.is-cancelled > .ai-item-status,
|
|
3887
|
+
.ai-todo-item.is-cancelled > .ai-item-status {
|
|
3888
|
+
border-color: var(--token-text-faint);
|
|
3889
|
+
background: var(--token-text-faint);
|
|
3890
|
+
}
|
|
3891
|
+
.ai-item.is-cancelled .ai-item-title,
|
|
3892
|
+
.ai-todo-item.is-cancelled .ai-todo-text {
|
|
3893
|
+
text-decoration: line-through;
|
|
3894
|
+
}
|
|
3895
|
+
|
|
3896
|
+
/* 组件局部 keyframes(等同 pill-pulse,避免硬依赖 pill.css) */
|
|
3897
|
+
@keyframes ai-status-pulse {
|
|
3898
|
+
0%, 100% { opacity: 1; transform: scale(1); }
|
|
3899
|
+
50% { opacity: 0.4; transform: scale(0.7); }
|
|
3900
|
+
}
|
|
3901
|
+
|
|
3902
|
+
/* ══════════════ ai-todo · 任务清单(§4.8) ══════════════ */
|
|
3903
|
+
|
|
3904
|
+
.ai-todo {
|
|
3905
|
+
display: flex;
|
|
3906
|
+
flex-direction: column;
|
|
3907
|
+
gap: var(--density-space-xs);
|
|
3908
|
+
font-size: var(--density-font-size-sm);
|
|
3909
|
+
min-width: 0;
|
|
3910
|
+
align-self: stretch; /* 输出容器宽度自稳定 */
|
|
3911
|
+
}
|
|
3912
|
+
|
|
3913
|
+
.ai-todo-head {
|
|
3914
|
+
display: flex;
|
|
3915
|
+
align-items: center;
|
|
3916
|
+
gap: var(--density-space-sm);
|
|
3917
|
+
min-width: 0;
|
|
3918
|
+
}
|
|
3919
|
+
|
|
3920
|
+
.ai-todo-progress {
|
|
3921
|
+
flex-shrink: 0;
|
|
3922
|
+
font-size: var(--density-font-size-xs);
|
|
3923
|
+
color: var(--token-text-muted);
|
|
3924
|
+
font-variant-numeric: tabular-nums;
|
|
3925
|
+
}
|
|
3926
|
+
|
|
3927
|
+
/* 进度条:feedback progress 视觉(token 消费) */
|
|
3928
|
+
.ai-todo-bar {
|
|
3929
|
+
flex: 1;
|
|
3930
|
+
height: 4px;
|
|
3931
|
+
border-radius: var(--radius-full);
|
|
3932
|
+
overflow: hidden;
|
|
3933
|
+
background: color-mix(in srgb, var(--token-line-soft) 40%, transparent);
|
|
3934
|
+
}
|
|
3935
|
+
.ai-todo-bar > i {
|
|
3936
|
+
display: block;
|
|
3937
|
+
height: 100%;
|
|
3938
|
+
border-radius: var(--radius-full);
|
|
3939
|
+
background: var(--token-accent);
|
|
3940
|
+
transition: width var(--icen-tx-slow);
|
|
3941
|
+
}
|
|
3942
|
+
.ai-todo.is-complete .ai-todo-bar > i {
|
|
3943
|
+
background: var(--token-success);
|
|
3944
|
+
}
|
|
3945
|
+
|
|
3946
|
+
.ai-todo-item {
|
|
3947
|
+
display: flex;
|
|
3948
|
+
align-items: center;
|
|
3949
|
+
gap: var(--density-space-sm);
|
|
3950
|
+
padding: 3px var(--density-space-xs);
|
|
3951
|
+
border-radius: var(--radius-xs);
|
|
3952
|
+
min-width: 0;
|
|
3953
|
+
}
|
|
3954
|
+
|
|
3955
|
+
/* 交互模式(initAiTodo 升级 role=button) */
|
|
3956
|
+
.ai-todo-item[role='button'] {
|
|
3957
|
+
cursor: pointer;
|
|
3958
|
+
transition: background-color var(--icen-tx-fast);
|
|
3959
|
+
}
|
|
3960
|
+
.ai-todo-item[role='button']:hover {
|
|
3961
|
+
background: var(--token-fill-1);
|
|
3962
|
+
}
|
|
3963
|
+
.ai-todo-item:focus-visible {
|
|
3964
|
+
outline: none;
|
|
3965
|
+
box-shadow: var(--icen-ring);
|
|
3966
|
+
}
|
|
3967
|
+
|
|
3968
|
+
.ai-todo-text {
|
|
3969
|
+
min-width: 0;
|
|
3970
|
+
overflow: hidden;
|
|
3971
|
+
text-overflow: ellipsis;
|
|
3972
|
+
white-space: nowrap;
|
|
3973
|
+
}
|
|
3974
|
+
|
|
3975
|
+
/* activeForm:运行中替换式强调(Claude Code 模式) */
|
|
3976
|
+
.ai-todo-active {
|
|
3977
|
+
display: none;
|
|
3978
|
+
min-width: 0;
|
|
3979
|
+
overflow: hidden;
|
|
3980
|
+
text-overflow: ellipsis;
|
|
3981
|
+
white-space: nowrap;
|
|
3982
|
+
color: var(--token-accent-deep);
|
|
3983
|
+
}
|
|
3984
|
+
.ai-todo-item.is-running .ai-todo-text { display: none; }
|
|
3985
|
+
.ai-todo-item.is-running .ai-todo-active { display: inline; }
|
|
3986
|
+
|
|
3987
|
+
/* done/cancelled:淡化 + 删除线 */
|
|
3988
|
+
.ai-todo-item.is-done .ai-todo-text,
|
|
3989
|
+
.ai-todo-item.is-cancelled .ai-todo-text {
|
|
3990
|
+
color: var(--token-text-faint);
|
|
3991
|
+
text-decoration: line-through;
|
|
3992
|
+
}
|
|
3993
|
+
|
|
3994
|
+
/* ══════════════ ai-usage · 用量条(§4.9) ══════════════ */
|
|
3995
|
+
|
|
3996
|
+
.ai-usage {
|
|
3997
|
+
display: flex;
|
|
3998
|
+
flex-direction: column;
|
|
3999
|
+
gap: var(--density-space-xs);
|
|
4000
|
+
font-size: var(--density-font-size-xs);
|
|
4001
|
+
color: var(--token-text-muted);
|
|
4002
|
+
min-width: 0;
|
|
4003
|
+
align-self: stretch; /* 输出容器宽度自稳定 */
|
|
4004
|
+
}
|
|
4005
|
+
|
|
4006
|
+
.ai-usage-bar {
|
|
4007
|
+
display: flex;
|
|
4008
|
+
height: 6px;
|
|
4009
|
+
border-radius: var(--radius-full);
|
|
4010
|
+
overflow: hidden;
|
|
4011
|
+
background: color-mix(in srgb, var(--token-line-soft) 40%, transparent);
|
|
4012
|
+
}
|
|
4013
|
+
|
|
4014
|
+
.ai-usage-seg {
|
|
4015
|
+
display: block;
|
|
4016
|
+
height: 100%;
|
|
4017
|
+
min-width: 0;
|
|
4018
|
+
transition: width var(--icen-tx-slow);
|
|
4019
|
+
}
|
|
4020
|
+
|
|
4021
|
+
/* 配色契约:input=accent / output=success / cacheRead=info / cacheWrite=warning / reasoning=faint */
|
|
4022
|
+
.ai-usage-seg--input { background: var(--token-accent); }
|
|
4023
|
+
.ai-usage-seg--output { background: var(--token-success); }
|
|
4024
|
+
.ai-usage-seg--cache-read { background: var(--token-info); }
|
|
4025
|
+
.ai-usage-seg--cache-write { background: var(--token-warning); }
|
|
4026
|
+
.ai-usage-seg--reasoning { background: var(--token-text-faint); }
|
|
4027
|
+
|
|
4028
|
+
/* 图例:色点 + 标签 + 数值(缓存分列,计费诚实) */
|
|
4029
|
+
.ai-usage-legend {
|
|
4030
|
+
display: flex;
|
|
4031
|
+
flex-wrap: wrap;
|
|
4032
|
+
gap: var(--density-space-xs) var(--density-space-sm);
|
|
4033
|
+
}
|
|
4034
|
+
.ai-usage-legend-item {
|
|
4035
|
+
display: inline-flex;
|
|
4036
|
+
align-items: center;
|
|
4037
|
+
gap: 5px;
|
|
4038
|
+
font-variant-numeric: tabular-nums;
|
|
4039
|
+
}
|
|
4040
|
+
.ai-usage-dot {
|
|
4041
|
+
flex-shrink: 0;
|
|
4042
|
+
width: 8px;
|
|
4043
|
+
height: 8px;
|
|
4044
|
+
border-radius: var(--radius-full);
|
|
4045
|
+
}
|
|
4046
|
+
.ai-usage-legend-label { color: var(--token-text-muted); }
|
|
4047
|
+
.ai-usage-legend-value { color: var(--token-text); font-weight: 500; }
|
|
4048
|
+
|
|
4049
|
+
.ai-usage-total {
|
|
4050
|
+
font-variant-numeric: tabular-nums;
|
|
4051
|
+
color: var(--token-text-muted);
|
|
4052
|
+
}
|
|
4053
|
+
|
|
4054
|
+
/* ══════════════ ai-usage-ring · 上下文窗口环形指示器(点击弹出完整分解) ══════════════ */
|
|
4055
|
+
|
|
4056
|
+
.ai-usage-ring {
|
|
4057
|
+
position: relative;
|
|
4058
|
+
display: inline-flex;
|
|
4059
|
+
align-items: center;
|
|
4060
|
+
justify-content: center;
|
|
4061
|
+
width: 36px;
|
|
4062
|
+
height: 36px;
|
|
4063
|
+
padding: 0;
|
|
4064
|
+
border: 0;
|
|
4065
|
+
background: transparent;
|
|
4066
|
+
border-radius: var(--radius-full);
|
|
4067
|
+
color: var(--token-text-muted);
|
|
4068
|
+
cursor: pointer;
|
|
4069
|
+
flex-shrink: 0;
|
|
4070
|
+
transition:
|
|
4071
|
+
color var(--icen-tx-fast),
|
|
4072
|
+
background-color var(--icen-tx-fast);
|
|
4073
|
+
}
|
|
4074
|
+
.ai-usage-ring:hover {
|
|
4075
|
+
background: var(--token-fill-1);
|
|
4076
|
+
color: var(--token-text);
|
|
4077
|
+
}
|
|
4078
|
+
.ai-usage-ring:focus-visible {
|
|
4079
|
+
outline: none;
|
|
4080
|
+
box-shadow: var(--icen-ring);
|
|
4081
|
+
}
|
|
4082
|
+
|
|
4083
|
+
.ai-usage-ring > svg {
|
|
4084
|
+
position: absolute;
|
|
4085
|
+
inset: 0;
|
|
4086
|
+
width: 100%;
|
|
4087
|
+
height: 100%;
|
|
4088
|
+
transform: rotate(-90deg); /* 12 点起笔 */
|
|
4089
|
+
}
|
|
4090
|
+
.ai-usage-ring-track {
|
|
4091
|
+
fill: none;
|
|
4092
|
+
stroke: var(--token-fill-2);
|
|
4093
|
+
stroke-width: 3;
|
|
4094
|
+
}
|
|
4095
|
+
.ai-usage-ring-fill {
|
|
4096
|
+
fill: none;
|
|
4097
|
+
stroke: var(--token-accent);
|
|
4098
|
+
stroke-width: 3;
|
|
4099
|
+
stroke-linecap: round;
|
|
4100
|
+
transition:
|
|
4101
|
+
stroke-dasharray var(--icen-tx-slow),
|
|
4102
|
+
stroke var(--icen-tx-fast);
|
|
4103
|
+
}
|
|
4104
|
+
/* 状态档:<60% ok(accent)/ 60–85% warn / >85% hot */
|
|
4105
|
+
.ai-usage-ring.is-warn .ai-usage-ring-fill { stroke: var(--token-warning); }
|
|
4106
|
+
.ai-usage-ring.is-hot .ai-usage-ring-fill { stroke: var(--token-error); }
|
|
4107
|
+
.ai-usage-ring.is-hot {
|
|
4108
|
+
animation: ai-usage-ring-pulse var(--ai-usage-ring-pulse-duration, 1.6s) ease-in-out infinite;
|
|
4109
|
+
}
|
|
4110
|
+
@keyframes ai-usage-ring-pulse {
|
|
4111
|
+
0%, 100% { opacity: 1; }
|
|
4112
|
+
50% { opacity: 0.55; }
|
|
4113
|
+
}
|
|
4114
|
+
|
|
4115
|
+
.ai-usage-ring-pct {
|
|
4116
|
+
position: relative;
|
|
4117
|
+
font-family: var(--font-mono);
|
|
4118
|
+
font-size: 9px;
|
|
4119
|
+
font-weight: 600;
|
|
4120
|
+
letter-spacing: -0.02em;
|
|
4121
|
+
font-variant-numeric: tabular-nums;
|
|
4122
|
+
user-select: none;
|
|
4123
|
+
}
|
|
4124
|
+
|
|
4125
|
+
/* 大号变体(常驻工具栏/头部用) */
|
|
4126
|
+
.ai-usage-ring--lg {
|
|
4127
|
+
width: 44px;
|
|
4128
|
+
height: 44px;
|
|
4129
|
+
}
|
|
4130
|
+
.ai-usage-ring--lg .ai-usage-ring-pct { font-size: 10px; }
|
|
4131
|
+
|
|
4132
|
+
/* 弹层(复用 .popover 基座,内容区只补间距) */
|
|
4133
|
+
.ai-usage-popover {
|
|
4134
|
+
display: flex;
|
|
4135
|
+
flex-direction: column;
|
|
4136
|
+
gap: var(--density-space-sm);
|
|
4137
|
+
padding: var(--density-space-md);
|
|
4138
|
+
}
|
|
4139
|
+
.ai-usage-popover-title {
|
|
4140
|
+
font-size: var(--density-font-size-sm);
|
|
4141
|
+
font-weight: 600;
|
|
4142
|
+
color: var(--token-text);
|
|
4143
|
+
}
|
|
4144
|
+
|
|
4145
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4146
|
+
.ai-usage-ring.is-hot { animation: none; }
|
|
4147
|
+
.ai-usage-ring-fill { transition: none; }
|
|
4148
|
+
}
|
|
4149
|
+
|
|
4150
|
+
/* ══════════════ ai-context · 上下文抽屉(§4.10) ══════════════ */
|
|
4151
|
+
|
|
4152
|
+
.ai-context {
|
|
4153
|
+
position: fixed;
|
|
4154
|
+
inset: 0 0 0 auto;
|
|
4155
|
+
width: min(360px, 92vw);
|
|
4156
|
+
z-index: var(--z-chrome);
|
|
4157
|
+
display: flex;
|
|
4158
|
+
flex-direction: column;
|
|
4159
|
+
background: var(--token-surface);
|
|
4160
|
+
border-left: 1px solid var(--token-line-soft);
|
|
4161
|
+
box-shadow: var(--token-shadow-overlay);
|
|
4162
|
+
transform: translateX(100%);
|
|
4163
|
+
transition: transform var(--ai-context-duration, var(--duration-normal)) var(--ease-out);
|
|
4164
|
+
overflow-y: auto;
|
|
4165
|
+
}
|
|
4166
|
+
.ai-context[hidden] {
|
|
4167
|
+
display: none;
|
|
4168
|
+
}
|
|
4169
|
+
.ai-context.is-open {
|
|
4170
|
+
transform: translateX(0);
|
|
4171
|
+
}
|
|
4172
|
+
|
|
4173
|
+
/* 页面流内嵌变体:不做 fixed、不滑入 */
|
|
4174
|
+
.ai-context--inline {
|
|
4175
|
+
position: static;
|
|
4176
|
+
inset: auto;
|
|
4177
|
+
width: auto;
|
|
4178
|
+
z-index: auto;
|
|
4179
|
+
transform: none;
|
|
4180
|
+
transition: none;
|
|
4181
|
+
border: 1px solid var(--token-line-soft);
|
|
4182
|
+
border-radius: var(--radius-md);
|
|
4183
|
+
box-shadow: var(--token-shadow-elevated);
|
|
4184
|
+
overflow-y: visible;
|
|
4185
|
+
}
|
|
4186
|
+
|
|
4187
|
+
.ai-context-head {
|
|
4188
|
+
position: sticky;
|
|
4189
|
+
top: 0;
|
|
4190
|
+
z-index: 1;
|
|
4191
|
+
display: flex;
|
|
4192
|
+
align-items: center;
|
|
4193
|
+
justify-content: space-between;
|
|
4194
|
+
gap: var(--density-space-sm);
|
|
4195
|
+
padding: var(--density-space-sm) var(--density-space-md);
|
|
4196
|
+
background: var(--token-surface);
|
|
4197
|
+
border-bottom: 1px solid var(--token-line-soft);
|
|
4198
|
+
font-size: var(--density-font-size-sm);
|
|
4199
|
+
font-weight: 600;
|
|
4200
|
+
color: var(--token-text);
|
|
4201
|
+
}
|
|
4202
|
+
|
|
4203
|
+
.ai-context-head [data-ai-context-close] {
|
|
4204
|
+
flex-shrink: 0;
|
|
4205
|
+
display: inline-flex;
|
|
4206
|
+
align-items: center;
|
|
4207
|
+
justify-content: center;
|
|
4208
|
+
width: 26px;
|
|
4209
|
+
height: 26px;
|
|
4210
|
+
padding: 0;
|
|
4211
|
+
border: 0;
|
|
4212
|
+
border-radius: var(--radius-xs);
|
|
4213
|
+
background: none;
|
|
4214
|
+
color: var(--token-text-faint);
|
|
4215
|
+
font-size: 16px;
|
|
4216
|
+
line-height: 1;
|
|
4217
|
+
cursor: pointer;
|
|
4218
|
+
transition:
|
|
4219
|
+
background-color var(--icen-tx-fast),
|
|
4220
|
+
color var(--icen-tx-fast);
|
|
4221
|
+
}
|
|
4222
|
+
.ai-context-head [data-ai-context-close]:hover {
|
|
4223
|
+
color: var(--token-text);
|
|
4224
|
+
background: var(--token-fill-1);
|
|
4225
|
+
}
|
|
4226
|
+
.ai-context-head [data-ai-context-close]:focus-visible {
|
|
4227
|
+
outline: none;
|
|
4228
|
+
box-shadow: var(--icen-ring);
|
|
4229
|
+
}
|
|
4230
|
+
|
|
4231
|
+
.ai-context-section {
|
|
4232
|
+
display: flex;
|
|
4233
|
+
flex-direction: column;
|
|
4234
|
+
gap: var(--density-space-xs);
|
|
4235
|
+
padding: var(--density-space-sm) var(--density-space-md);
|
|
4236
|
+
min-width: 0;
|
|
4237
|
+
}
|
|
4238
|
+
.ai-context-section ~ .ai-context-section {
|
|
4239
|
+
border-top: 1px solid var(--token-line-soft);
|
|
4240
|
+
}
|
|
4241
|
+
.ai-context-section h3 {
|
|
4242
|
+
margin: 0;
|
|
4243
|
+
font-size: var(--density-font-size-xs);
|
|
4244
|
+
font-weight: 600;
|
|
4245
|
+
color: var(--token-text-muted);
|
|
4246
|
+
}
|
|
4247
|
+
.ai-context-section-body {
|
|
4248
|
+
display: flex;
|
|
4249
|
+
flex-direction: column;
|
|
4250
|
+
gap: var(--density-space-xs);
|
|
4251
|
+
min-width: 0;
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4254
|
+
/* ══════════════ ai-audit(renderAiAudit,规格 §12.2) ══════════════ */
|
|
4255
|
+
|
|
4256
|
+
/*
|
|
4257
|
+
* <div class="ai-audit">
|
|
4258
|
+
* <div class="ai-audit-totals"><span class="ai-audit-totals-text">12 次请求 · 1 失败 · 1.2M tok · $0.42 · TTFT 240ms</span></div>
|
|
4259
|
+
* <div class="ai-audit-models">
|
|
4260
|
+
* <div class="ai-audit-model-row"><span class="ai-audit-model-name">kimi/kimi-k3</span>
|
|
4261
|
+
* <span class="ai-audit-model-meta">8 次 · 900k tok · $0.31</span></div>…
|
|
4262
|
+
* </div>
|
|
4263
|
+
* <div class="ai-audit-list">
|
|
4264
|
+
* <div class="ai-audit-item is-done|is-error">
|
|
4265
|
+
* <span class="ai-audit-dot"></span>
|
|
4266
|
+
* <span class="ai-audit-item-main"><span class="ai-audit-item-model">kimi · kimi-k3</span>
|
|
4267
|
+
* <span class="ai-audit-item-meta">14:03 · 1.2s · TTFT 240ms · 12.3k tok</span></span>
|
|
4268
|
+
* <span class="ai-audit-item-error">网络请求失败:…</span> <!-- 仅 is-error -->
|
|
4269
|
+
* </div>…
|
|
4270
|
+
* </div>
|
|
4271
|
+
* <button class="btn btn-sm ai-audit-clear">清除审计</button>
|
|
4272
|
+
* </div>
|
|
4273
|
+
*/
|
|
4274
|
+
|
|
4275
|
+
.ai-audit {
|
|
4276
|
+
display: flex;
|
|
4277
|
+
flex-direction: column;
|
|
4278
|
+
gap: var(--density-space-sm);
|
|
4279
|
+
align-self: stretch;
|
|
4280
|
+
min-width: 0;
|
|
4281
|
+
font-size: var(--density-font-size-sm);
|
|
4282
|
+
}
|
|
4283
|
+
.ai-audit-empty {
|
|
4284
|
+
padding: var(--density-space-md);
|
|
4285
|
+
text-align: center;
|
|
4286
|
+
color: var(--token-text-faint);
|
|
4287
|
+
font-size: var(--density-font-size-xs);
|
|
4288
|
+
}
|
|
4289
|
+
|
|
4290
|
+
/* totals 行:等宽数字,faint 汇总 */
|
|
4291
|
+
.ai-audit-totals-text {
|
|
4292
|
+
display: block;
|
|
4293
|
+
font-family: var(--font-mono);
|
|
4294
|
+
font-size: var(--density-font-size-xs);
|
|
4295
|
+
color: var(--token-text-faint);
|
|
4296
|
+
font-variant-numeric: tabular-nums;
|
|
4297
|
+
}
|
|
4298
|
+
|
|
4299
|
+
/* byModel 分组行 */
|
|
4300
|
+
.ai-audit-models {
|
|
4301
|
+
display: flex;
|
|
4302
|
+
flex-direction: column;
|
|
4303
|
+
gap: 2px;
|
|
4304
|
+
}
|
|
4305
|
+
.ai-audit-model-row {
|
|
4306
|
+
display: flex;
|
|
4307
|
+
align-items: baseline;
|
|
4308
|
+
justify-content: space-between;
|
|
4309
|
+
gap: var(--density-space-sm);
|
|
4310
|
+
min-width: 0;
|
|
4311
|
+
}
|
|
4312
|
+
.ai-audit-model-name {
|
|
4313
|
+
font-family: var(--font-mono);
|
|
4314
|
+
font-size: var(--density-font-size-xs);
|
|
4315
|
+
color: var(--token-text);
|
|
4316
|
+
overflow: hidden;
|
|
4317
|
+
text-overflow: ellipsis;
|
|
4318
|
+
white-space: nowrap;
|
|
4319
|
+
}
|
|
4320
|
+
.ai-audit-model-meta {
|
|
4321
|
+
flex-shrink: 0;
|
|
4322
|
+
font-family: var(--font-mono);
|
|
4323
|
+
font-size: var(--density-font-size-2xs);
|
|
4324
|
+
color: var(--token-text-faint);
|
|
4325
|
+
font-variant-numeric: tabular-nums;
|
|
4326
|
+
}
|
|
4327
|
+
|
|
4328
|
+
/* 最近条目(最新在前) */
|
|
4329
|
+
.ai-audit-list {
|
|
4330
|
+
display: flex;
|
|
4331
|
+
flex-direction: column;
|
|
4332
|
+
gap: 2px;
|
|
4333
|
+
max-height: 280px;
|
|
4334
|
+
overflow-y: auto;
|
|
4335
|
+
}
|
|
4336
|
+
.ai-audit-item {
|
|
4337
|
+
display: flex;
|
|
4338
|
+
align-items: baseline;
|
|
4339
|
+
gap: var(--density-space-xs);
|
|
4340
|
+
padding: 2px var(--density-space-xs);
|
|
4341
|
+
border-radius: var(--radius-xs);
|
|
4342
|
+
min-width: 0;
|
|
4343
|
+
}
|
|
4344
|
+
.ai-audit-item:hover {
|
|
4345
|
+
background: var(--token-fill-1);
|
|
4346
|
+
}
|
|
4347
|
+
.ai-audit-dot {
|
|
4348
|
+
flex-shrink: 0;
|
|
4349
|
+
width: 6px;
|
|
4350
|
+
height: 6px;
|
|
4351
|
+
border-radius: 50%;
|
|
4352
|
+
background: var(--token-text-faint);
|
|
4353
|
+
}
|
|
4354
|
+
.ai-audit-item.is-done .ai-audit-dot {
|
|
4355
|
+
background: var(--token-success);
|
|
4356
|
+
}
|
|
4357
|
+
.ai-audit-item.is-error .ai-audit-dot {
|
|
4358
|
+
background: var(--token-error);
|
|
4359
|
+
}
|
|
4360
|
+
.ai-audit-item-main {
|
|
4361
|
+
display: flex;
|
|
4362
|
+
flex-direction: column;
|
|
4363
|
+
min-width: 0;
|
|
4364
|
+
flex: 1;
|
|
4365
|
+
}
|
|
4366
|
+
.ai-audit-item-model {
|
|
4367
|
+
font-family: var(--font-mono);
|
|
4368
|
+
font-size: var(--density-font-size-2xs);
|
|
4369
|
+
color: var(--token-text);
|
|
4370
|
+
overflow: hidden;
|
|
4371
|
+
text-overflow: ellipsis;
|
|
4372
|
+
white-space: nowrap;
|
|
4373
|
+
}
|
|
4374
|
+
.ai-audit-item-meta {
|
|
4375
|
+
font-family: var(--font-mono);
|
|
4376
|
+
font-size: var(--density-font-size-2xs);
|
|
4377
|
+
color: var(--token-text-faint);
|
|
4378
|
+
font-variant-numeric: tabular-nums;
|
|
4379
|
+
}
|
|
4380
|
+
.ai-audit-item-error {
|
|
4381
|
+
flex-shrink: 0;
|
|
4382
|
+
max-width: 45%;
|
|
4383
|
+
font-size: var(--density-font-size-2xs);
|
|
4384
|
+
color: var(--token-error);
|
|
4385
|
+
overflow: hidden;
|
|
4386
|
+
text-overflow: ellipsis;
|
|
4387
|
+
white-space: nowrap;
|
|
4388
|
+
}
|
|
4389
|
+
.ai-audit-item.is-error .ai-audit-item-model {
|
|
4390
|
+
color: var(--token-error);
|
|
4391
|
+
}
|
|
4392
|
+
|
|
4393
|
+
/* 清除钮(右对齐;视觉复用 .btn .btn-sm) */
|
|
4394
|
+
.ai-audit-clear {
|
|
4395
|
+
align-self: flex-end;
|
|
4396
|
+
}
|
|
4397
|
+
|
|
4398
|
+
/* ── 动效守卫 ── */
|
|
4399
|
+
|
|
4400
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4401
|
+
.ai-todo-bar > i,
|
|
4402
|
+
.ai-usage-seg { transition: none; }
|
|
4403
|
+
.ai-context { transition: none; }
|
|
4404
|
+
.ai-item-status { animation: none; }
|
|
4405
|
+
}
|
|
4406
|
+
|
|
4407
|
+
|
|
4408
|
+
/* ── components/ai-tool.css ── */
|
|
4409
|
+
/*
|
|
4410
|
+
* @icen.ai/ui — Component: ai-tool(AI 工具调用卡 + 子智能体卡;含 .ai-item 条目基元完整定义)
|
|
4411
|
+
*
|
|
4412
|
+
* 完整契约:
|
|
4413
|
+
* ── 条目基元 .ai-item(规格 §2 骨架:所有行式 AI 条目的"基类",todo/panel 亦复用)──
|
|
4414
|
+
* <div class="ai-item is-running" style="--ai-item-tint: var(--token-accent)">
|
|
4415
|
+
* <span class="ai-item-icon"><!-- svg --></span>
|
|
4416
|
+
* <div class="ai-item-main">
|
|
4417
|
+
* <div class="ai-item-title">一行摘要</div>
|
|
4418
|
+
* <div class="ai-item-sub">次要信息(路径/参数)</div>
|
|
4419
|
+
* </div>
|
|
4420
|
+
* <div class="ai-item-side">
|
|
4421
|
+
* <span class="ai-item-status"></span> ← 状态点,纯 CSS 由 .is-* 驱动
|
|
4422
|
+
* <span class="ai-item-meta">1.2s</span>
|
|
4423
|
+
* </div>
|
|
4424
|
+
* <div class="ai-item-detail" hidden>展开详情</div>
|
|
4425
|
+
* </div>
|
|
4426
|
+
*
|
|
4427
|
+
* ── 工具调用卡(.ai-tool-head 复用 .ai-item-* 零件,不带 .ai-item 壳)──
|
|
4428
|
+
* <div class="ai-tool ai-tool--shell is-done" data-ai-id="…" data-ai-kind="shell">
|
|
4429
|
+
* <button class="ai-tool-head" type="button" aria-expanded="false">
|
|
4430
|
+
* <span class="ai-item-icon" aria-hidden="true">…svg…</span>
|
|
4431
|
+
* <span class="ai-item-main">
|
|
4432
|
+
* <span class="ai-item-title">Read</span>
|
|
4433
|
+
* <span class="ai-item-sub">src/foo.ts:1-50</span>
|
|
4434
|
+
* </span>
|
|
4435
|
+
* <span class="ai-item-status" role="img" aria-label="完成"></span>
|
|
4436
|
+
* <span class="ai-item-meta">0.4s</span>
|
|
4437
|
+
* </button>
|
|
4438
|
+
* <div class="ai-tool-body" hidden>
|
|
4439
|
+
* <div class="ai-tool-io"><div class="ai-tool-io-label">输入</div><pre class="ai-tool-io-content">…</pre></div>
|
|
4440
|
+
* <div class="ai-tool-io"><div class="ai-tool-io-label">输出</div><pre class="ai-tool-io-content">…</pre></div>
|
|
4441
|
+
* <div class="ai-tool-approval"> ← 仅 .is-approval 显示(纯 CSS 驱动)
|
|
4442
|
+
* <div class="ai-tool-approval-reason" hidden>审批原因</div> ← 可选(model.approval.reason)
|
|
4443
|
+
* <button class="btn btn-sm btn-primary" data-ai-approve type="button">允许</button>
|
|
4444
|
+
* <button class="btn btn-sm" data-ai-reject type="button">拒绝</button>
|
|
4445
|
+
* </div>
|
|
4446
|
+
* </div>
|
|
4447
|
+
* </div>
|
|
4448
|
+
*
|
|
4449
|
+
* ── 子智能体卡 ──
|
|
4450
|
+
* <div class="ai-subagent is-running" data-ai-id="…" data-ai-kind="subagent">
|
|
4451
|
+
* <button class="ai-subagent-head" type="button" aria-expanded="false">…head 结构同上…</button>
|
|
4452
|
+
* <div class="ai-subagent-body" hidden>
|
|
4453
|
+
* <div class="ai-subagent-stream"> ← 嵌套 .ai-tool / .ai-subagent;
|
|
4454
|
+
* … 行间 style="--ai-activity-index:i" 驱动渐入 stagger
|
|
4455
|
+
* </div>
|
|
4456
|
+
* <div class="ai-subagent-result">完成回执摘要</div>
|
|
4457
|
+
* </div>
|
|
4458
|
+
* </div>
|
|
4459
|
+
*
|
|
4460
|
+
* 状态机 7 态(全条目共享,规格 §1):
|
|
4461
|
+
* .is-pending faint 空心点
|
|
4462
|
+
* .is-running tint 脉冲点(--ai-item-pulse-duration 变量化时长)
|
|
4463
|
+
* .is-streaming ▍流式光标(colors.css blink keyframes,--ai-item-blink-duration 变量化)
|
|
4464
|
+
* .is-approval warning 点 + 外环;卡片边框 warning;显示审批按钮
|
|
4465
|
+
* .is-done success 纯 CSS 对勾
|
|
4466
|
+
* .is-error error 点 + 外环;失败条目由 behavior 首次渲染自动展开
|
|
4467
|
+
* .is-cancelled faint 点 + 标题删除线
|
|
4468
|
+
*
|
|
4469
|
+
* kind 修饰类 ai-tool--<kind> 只覆盖 --ai-item-tint(继承 = 变量级联,不改结构):
|
|
4470
|
+
* read/search/grep/glob=info · edit/write=accent · rm=error · shell=muted · mcp/skill=success
|
|
4471
|
+
* browser/fetch/todo/plan/subagent/note = 默认 accent(不写规则)
|
|
4472
|
+
* 第三方 registerAiKind 的 tint 由 behavior 内联 --ai-item-tint 兜底。
|
|
4473
|
+
*/
|
|
4474
|
+
|
|
4475
|
+
/* ══════════════════════════════════════════════════════════════
|
|
4476
|
+
条目基元 .ai-item(行式条目"基类")
|
|
4477
|
+
══════════════════════════════════════════════════════════════ */
|
|
4478
|
+
|
|
4479
|
+
.ai-item {
|
|
4480
|
+
/* 局部变量槽:kind/变体只覆盖这些变量(--btn-* 同款继承模式) */
|
|
4481
|
+
--ai-item-tint: var(--token-accent);
|
|
4482
|
+
--ai-item-pulse-duration: 1.5s; /* running 脉冲(pill --pill-pulse-duration 同款变量化) */
|
|
4483
|
+
--ai-item-blink-duration: 1s; /* streaming 光标闪烁 */
|
|
4484
|
+
|
|
4485
|
+
display: flex;
|
|
4486
|
+
flex-wrap: wrap;
|
|
4487
|
+
align-items: center;
|
|
4488
|
+
gap: var(--density-space-sm);
|
|
4489
|
+
min-width: 0;
|
|
4490
|
+
align-self: stretch; /* 宽度自稳定:宿主 flex/grid 居中时不 shrink-wrap(width:100% 会塌成 min-content,禁用) */
|
|
4491
|
+
}
|
|
4492
|
+
|
|
4493
|
+
.ai-item-icon {
|
|
4494
|
+
display: inline-flex;
|
|
4495
|
+
align-items: center;
|
|
4496
|
+
justify-content: center;
|
|
4497
|
+
flex-shrink: 0;
|
|
4498
|
+
width: 20px;
|
|
4499
|
+
height: 20px;
|
|
4500
|
+
color: var(--ai-item-tint);
|
|
4501
|
+
transition: color var(--icen-tx-fast);
|
|
4502
|
+
}
|
|
4503
|
+
.ai-item-icon > svg {
|
|
4504
|
+
width: 16px;
|
|
4505
|
+
height: 16px;
|
|
4506
|
+
}
|
|
4507
|
+
|
|
4508
|
+
.ai-item-main {
|
|
4509
|
+
flex: 1 1 auto;
|
|
4510
|
+
min-width: 0;
|
|
4511
|
+
display: flex;
|
|
4512
|
+
flex-direction: column;
|
|
4513
|
+
gap: 1px;
|
|
4514
|
+
}
|
|
4515
|
+
.ai-item-title {
|
|
4516
|
+
font-size: var(--density-font-size-md);
|
|
4517
|
+
line-height: 1.4;
|
|
4518
|
+
color: var(--token-text);
|
|
4519
|
+
overflow: hidden;
|
|
4520
|
+
text-overflow: ellipsis;
|
|
4521
|
+
white-space: nowrap;
|
|
4522
|
+
}
|
|
4523
|
+
.ai-item-sub {
|
|
4524
|
+
font-size: var(--density-font-size-xs);
|
|
4525
|
+
line-height: 1.4;
|
|
4526
|
+
color: var(--token-text-muted);
|
|
4527
|
+
overflow: hidden;
|
|
4528
|
+
text-overflow: ellipsis;
|
|
4529
|
+
white-space: nowrap;
|
|
4530
|
+
}
|
|
4531
|
+
.ai-item-side {
|
|
4532
|
+
display: inline-flex;
|
|
4533
|
+
align-items: center;
|
|
4534
|
+
gap: var(--density-space-xs);
|
|
4535
|
+
margin-left: auto;
|
|
4536
|
+
flex-shrink: 0;
|
|
4537
|
+
}
|
|
4538
|
+
/* head 直排结构(无 .ai-item-side 包裹)时,状态点顶到右侧 */
|
|
4539
|
+
.ai-tool-head > .ai-item-status,
|
|
4540
|
+
.ai-subagent-head > .ai-item-status {
|
|
4541
|
+
margin-left: auto;
|
|
4542
|
+
}
|
|
4543
|
+
|
|
4544
|
+
.ai-item-meta {
|
|
4545
|
+
font-size: var(--density-font-size-xs);
|
|
4546
|
+
color: var(--token-text-faint);
|
|
4547
|
+
font-variant-numeric: tabular-nums;
|
|
4548
|
+
flex-shrink: 0;
|
|
4549
|
+
}
|
|
4550
|
+
|
|
4551
|
+
.ai-item-detail {
|
|
4552
|
+
flex-basis: 100%;
|
|
4553
|
+
min-width: 100%;
|
|
4554
|
+
}
|
|
4555
|
+
|
|
4556
|
+
/* ── 状态点 .ai-item-status(纯 CSS 圆点,由 .is-* 决定颜色与动效) ── */
|
|
4557
|
+
.ai-item-status {
|
|
4558
|
+
position: relative;
|
|
4559
|
+
flex-shrink: 0;
|
|
4560
|
+
width: 8px;
|
|
4561
|
+
height: 8px;
|
|
4562
|
+
border-radius: 50%;
|
|
4563
|
+
}
|
|
4564
|
+
|
|
4565
|
+
/* 等待:faint 空心点(.ai-subagent 与 .ai-item 共享同一状态语言) */
|
|
4566
|
+
:is(.ai-item, .ai-tool, .ai-subagent).is-pending .ai-item-status {
|
|
4567
|
+
border: 1.5px solid var(--token-text-faint);
|
|
4568
|
+
}
|
|
4569
|
+
|
|
4570
|
+
/* 执行中:tint 脉冲点 */
|
|
4571
|
+
:is(.ai-item, .ai-tool, .ai-subagent).is-running .ai-item-status {
|
|
4572
|
+
background: var(--ai-item-tint);
|
|
4573
|
+
animation: ai-item-pulse var(--ai-item-pulse-duration) ease-in-out infinite;
|
|
4574
|
+
}
|
|
4575
|
+
@keyframes ai-item-pulse {
|
|
4576
|
+
0%, 100% { opacity: 1; transform: scale(1); }
|
|
4577
|
+
50% { opacity: 0.4; transform: scale(0.7); }
|
|
4578
|
+
}
|
|
4579
|
+
|
|
4580
|
+
/* 流式中:▍光标闪烁(复用 colors.css 的 blink keyframes,animate-blink 同款) */
|
|
4581
|
+
:is(.ai-item, .ai-tool, .ai-subagent).is-streaming .ai-item-status {
|
|
4582
|
+
width: 3px;
|
|
4583
|
+
height: 12px;
|
|
4584
|
+
border-radius: 1px;
|
|
4585
|
+
background: var(--ai-item-tint);
|
|
4586
|
+
animation: blink var(--ai-item-blink-duration) step-end infinite;
|
|
4587
|
+
}
|
|
4588
|
+
|
|
4589
|
+
/* 待人确认:warning 点 + 外环 */
|
|
4590
|
+
:is(.ai-item, .ai-tool, .ai-subagent).is-approval .ai-item-status {
|
|
4591
|
+
background: var(--token-warning);
|
|
4592
|
+
box-shadow: 0 0 0 3px var(--token-warning-muted);
|
|
4593
|
+
}
|
|
4594
|
+
|
|
4595
|
+
/* 完成:success 对勾(纯 CSS,无 SVG) */
|
|
4596
|
+
:is(.ai-item, .ai-tool, .ai-subagent).is-done .ai-item-status::after {
|
|
4597
|
+
content: "";
|
|
4598
|
+
position: absolute;
|
|
4599
|
+
left: 1px;
|
|
4600
|
+
top: -1px;
|
|
4601
|
+
width: 5px;
|
|
4602
|
+
height: 9px;
|
|
4603
|
+
border-right: 1.5px solid var(--token-success);
|
|
4604
|
+
border-bottom: 1.5px solid var(--token-success);
|
|
4605
|
+
transform: rotate(45deg);
|
|
4606
|
+
}
|
|
4607
|
+
|
|
4608
|
+
/* 失败:error 点 + 外环 */
|
|
4609
|
+
:is(.ai-item, .ai-tool, .ai-subagent).is-error .ai-item-status {
|
|
4610
|
+
background: var(--token-error);
|
|
4611
|
+
box-shadow: 0 0 0 3px var(--token-error-muted);
|
|
4612
|
+
}
|
|
4613
|
+
|
|
4614
|
+
/* 已取消:faint 点 + 标题删除线 */
|
|
4615
|
+
:is(.ai-item, .ai-tool, .ai-subagent).is-cancelled .ai-item-status {
|
|
4616
|
+
background: var(--token-text-faint);
|
|
4617
|
+
opacity: 0.6;
|
|
4618
|
+
}
|
|
4619
|
+
:is(.ai-item, .ai-tool, .ai-subagent).is-cancelled .ai-item-title {
|
|
4620
|
+
color: var(--token-text-faint);
|
|
4621
|
+
text-decoration: line-through;
|
|
4622
|
+
}
|
|
4623
|
+
|
|
4624
|
+
/* ══════════════════════════════════════════════════════════════
|
|
4625
|
+
工具调用卡 .ai-tool
|
|
4626
|
+
══════════════════════════════════════════════════════════════ */
|
|
4627
|
+
|
|
4628
|
+
.ai-tool {
|
|
4629
|
+
--ai-item-tint: var(--token-accent);
|
|
4630
|
+
align-self: stretch; /* 宽度自稳定:宿主 flex/grid 居中时不 shrink-wrap */
|
|
4631
|
+
border: 1px solid var(--token-line-soft);
|
|
4632
|
+
border-radius: var(--radius-md);
|
|
4633
|
+
background: var(--token-surface);
|
|
4634
|
+
}
|
|
4635
|
+
|
|
4636
|
+
/* ── kind 修饰类:只覆盖 --ai-item-tint ──
|
|
4637
|
+
browser/fetch/todo/plan/subagent/note 用默认 accent,不写规则 */
|
|
4638
|
+
.ai-tool--read,
|
|
4639
|
+
.ai-tool--search,
|
|
4640
|
+
.ai-tool--grep,
|
|
4641
|
+
.ai-tool--glob {
|
|
4642
|
+
--ai-item-tint: var(--token-info);
|
|
4643
|
+
}
|
|
4644
|
+
.ai-tool--edit,
|
|
4645
|
+
.ai-tool--write {
|
|
4646
|
+
--ai-item-tint: var(--token-accent);
|
|
4647
|
+
}
|
|
4648
|
+
.ai-tool--rm {
|
|
4649
|
+
--ai-item-tint: var(--token-error);
|
|
4650
|
+
}
|
|
4651
|
+
.ai-tool--shell {
|
|
4652
|
+
--ai-item-tint: var(--token-text-muted);
|
|
4653
|
+
}
|
|
4654
|
+
.ai-tool--mcp,
|
|
4655
|
+
.ai-tool--skill {
|
|
4656
|
+
--ai-item-tint: var(--token-success);
|
|
4657
|
+
}
|
|
4658
|
+
|
|
4659
|
+
/* ── head ── */
|
|
4660
|
+
.ai-tool-head,
|
|
4661
|
+
.ai-subagent-head {
|
|
4662
|
+
display: flex;
|
|
4663
|
+
align-items: center;
|
|
4664
|
+
gap: var(--density-space-sm);
|
|
4665
|
+
width: 100%;
|
|
4666
|
+
padding: var(--density-space-xs) var(--density-space-sm);
|
|
4667
|
+
border: none;
|
|
4668
|
+
border-radius: inherit; /* hover 底色不戳破卡片圆角 */
|
|
4669
|
+
background: transparent;
|
|
4670
|
+
color: inherit;
|
|
4671
|
+
font: inherit;
|
|
4672
|
+
text-align: left;
|
|
4673
|
+
cursor: pointer;
|
|
4674
|
+
-webkit-tap-highlight-color: transparent;
|
|
4675
|
+
transition: background-color var(--icen-tx-fast);
|
|
4676
|
+
}
|
|
4677
|
+
.ai-tool-head:hover,
|
|
4678
|
+
.ai-subagent-head:hover {
|
|
4679
|
+
background: var(--token-fill-1);
|
|
4680
|
+
}
|
|
4681
|
+
.ai-tool-head:focus-visible,
|
|
4682
|
+
.ai-subagent-head:focus-visible {
|
|
4683
|
+
outline: none;
|
|
4684
|
+
box-shadow: var(--icen-ring);
|
|
4685
|
+
}
|
|
4686
|
+
|
|
4687
|
+
/* ── body ── */
|
|
4688
|
+
.ai-tool-body {
|
|
4689
|
+
display: flex;
|
|
4690
|
+
flex-direction: column;
|
|
4691
|
+
gap: var(--density-space-sm);
|
|
4692
|
+
padding: var(--density-space-sm);
|
|
4693
|
+
border-top: 1px solid var(--token-line-soft);
|
|
4694
|
+
animation: icen-pop-in var(--icen-tx-fast);
|
|
4695
|
+
}
|
|
4696
|
+
.ai-tool-body[hidden],
|
|
4697
|
+
.ai-subagent-body[hidden],
|
|
4698
|
+
.ai-tool-io[hidden],
|
|
4699
|
+
.ai-subagent-result[hidden] {
|
|
4700
|
+
display: none;
|
|
4701
|
+
}
|
|
4702
|
+
|
|
4703
|
+
/* ── 输入/输出区块(pre 等宽、可滚、max-height 收敛) ── */
|
|
4704
|
+
.ai-tool-io {
|
|
4705
|
+
display: flex;
|
|
4706
|
+
flex-direction: column;
|
|
4707
|
+
gap: 4px;
|
|
4708
|
+
min-width: 0;
|
|
4709
|
+
}
|
|
4710
|
+
.ai-tool-io-label {
|
|
4711
|
+
font-size: var(--density-font-size-2xs);
|
|
4712
|
+
font-weight: 600;
|
|
4713
|
+
letter-spacing: 0.08em;
|
|
4714
|
+
text-transform: uppercase;
|
|
4715
|
+
color: var(--token-text-faint);
|
|
4716
|
+
}
|
|
4717
|
+
.ai-tool-io-content {
|
|
4718
|
+
--ai-tool-io-max: 12rem; /* 收敛上限(组件局部变量) */
|
|
4719
|
+
margin: 0;
|
|
4720
|
+
padding: var(--density-space-xs) var(--density-space-sm);
|
|
4721
|
+
max-height: var(--ai-tool-io-max);
|
|
4722
|
+
overflow: auto;
|
|
4723
|
+
background: var(--token-bg-soft);
|
|
4724
|
+
border: 1px solid var(--token-line-soft);
|
|
4725
|
+
border-radius: var(--radius-sm);
|
|
4726
|
+
font-family: var(--font-mono);
|
|
4727
|
+
font-size: var(--density-font-size-sm);
|
|
4728
|
+
line-height: 1.5;
|
|
4729
|
+
color: var(--token-text);
|
|
4730
|
+
white-space: pre-wrap;
|
|
4731
|
+
word-break: break-word;
|
|
4732
|
+
}
|
|
4733
|
+
|
|
4734
|
+
/* 多模态回执(MCP content 数组 → 媒体/链接,spec §10.3):
|
|
4735
|
+
容器纵向排布;媒体本体复用 ai-chat.css 的 .ai-msg-media 全局样式 */
|
|
4736
|
+
.ai-tool-io-media {
|
|
4737
|
+
display: flex;
|
|
4738
|
+
flex-direction: column;
|
|
4739
|
+
gap: var(--density-space-xs);
|
|
4740
|
+
min-width: 0;
|
|
4741
|
+
}
|
|
4742
|
+
|
|
4743
|
+
/* ── 审批区(仅 .is-approval 显示,纯 CSS 驱动) ── */
|
|
4744
|
+
.ai-tool-approval {
|
|
4745
|
+
display: none;
|
|
4746
|
+
align-items: center;
|
|
4747
|
+
gap: var(--density-space-sm);
|
|
4748
|
+
padding-top: var(--density-space-xs);
|
|
4749
|
+
border-top: 1px dashed var(--token-line-soft);
|
|
4750
|
+
}
|
|
4751
|
+
.ai-tool.is-approval .ai-tool-approval {
|
|
4752
|
+
display: flex;
|
|
4753
|
+
}
|
|
4754
|
+
.ai-tool-approval-reason {
|
|
4755
|
+
flex: 1 1 auto;
|
|
4756
|
+
min-width: 0;
|
|
4757
|
+
font-size: var(--density-font-size-xs);
|
|
4758
|
+
line-height: 1.5;
|
|
4759
|
+
color: var(--token-text-muted);
|
|
4760
|
+
}
|
|
4761
|
+
.ai-tool.is-approval {
|
|
4762
|
+
border-color: color-mix(in srgb, var(--token-warning) 40%, transparent);
|
|
4763
|
+
}
|
|
4764
|
+
.ai-tool.is-error {
|
|
4765
|
+
border-color: color-mix(in srgb, var(--token-error) 40%, transparent);
|
|
4766
|
+
}
|
|
4767
|
+
|
|
4768
|
+
/* ══════════════════════════════════════════════════════════════
|
|
4769
|
+
子智能体卡 .ai-subagent(嵌套活动流 = 缩进 + 左侧引导线,可递归)
|
|
4770
|
+
══════════════════════════════════════════════════════════════ */
|
|
4771
|
+
|
|
4772
|
+
.ai-subagent {
|
|
4773
|
+
--ai-item-tint: var(--token-accent);
|
|
4774
|
+
align-self: stretch; /* 宽度自稳定:宿主 flex/grid 居中时不 shrink-wrap */
|
|
4775
|
+
border: 1px solid var(--token-line-soft);
|
|
4776
|
+
border-left: 3px solid var(--ai-item-tint); /* 代理卡身份:tint 左边条 */
|
|
4777
|
+
border-radius: var(--radius-md);
|
|
4778
|
+
background: var(--token-surface);
|
|
4779
|
+
}
|
|
4780
|
+
.ai-subagent.is-error {
|
|
4781
|
+
border-left-color: var(--token-error);
|
|
4782
|
+
}
|
|
4783
|
+
.ai-subagent.is-done {
|
|
4784
|
+
border-left-color: var(--token-success);
|
|
4785
|
+
}
|
|
4786
|
+
|
|
4787
|
+
.ai-subagent-body {
|
|
4788
|
+
display: flex;
|
|
4789
|
+
flex-direction: column;
|
|
4790
|
+
gap: var(--density-space-sm);
|
|
4791
|
+
padding: var(--density-space-sm);
|
|
4792
|
+
border-top: 1px solid var(--token-line-soft);
|
|
4793
|
+
}
|
|
4794
|
+
|
|
4795
|
+
/* 嵌套流:缩进 + 引导线;行间渐入 stagger 由 --ai-activity-index(render 写入)驱动 */
|
|
4796
|
+
.ai-subagent-stream {
|
|
4797
|
+
--ai-stagger-step: 40ms; /* 活动项渐入步长(组件局部变量) */
|
|
4798
|
+
position: relative;
|
|
4799
|
+
display: flex;
|
|
4800
|
+
flex-direction: column;
|
|
4801
|
+
gap: var(--density-space-xs);
|
|
4802
|
+
padding-left: var(--density-space-md);
|
|
4803
|
+
}
|
|
4804
|
+
.ai-subagent-stream::before {
|
|
4805
|
+
content: "";
|
|
4806
|
+
position: absolute;
|
|
4807
|
+
left: 5px;
|
|
4808
|
+
top: var(--density-space-xs);
|
|
4809
|
+
bottom: var(--density-space-xs);
|
|
4810
|
+
width: 1px;
|
|
4811
|
+
background: var(--token-line-soft);
|
|
4812
|
+
}
|
|
4813
|
+
/* 展开(body 从 hidden 解除)时,活动项逐条 icen-pop-in 渐入 */
|
|
4814
|
+
.ai-subagent-stream > * {
|
|
4815
|
+
animation: icen-pop-in var(--icen-tx-fast) backwards;
|
|
4816
|
+
animation-delay: calc(var(--ai-activity-index, 0) * var(--ai-stagger-step));
|
|
4817
|
+
}
|
|
4818
|
+
|
|
4819
|
+
/* 完成回执 */
|
|
4820
|
+
.ai-subagent-result {
|
|
4821
|
+
padding: var(--density-space-xs) var(--density-space-sm);
|
|
4822
|
+
background: var(--token-bg-soft);
|
|
4823
|
+
border: 1px solid var(--token-line-soft);
|
|
4824
|
+
border-radius: var(--radius-sm);
|
|
4825
|
+
font-size: var(--density-font-size-sm);
|
|
4826
|
+
line-height: 1.5;
|
|
4827
|
+
color: var(--token-text-muted);
|
|
4828
|
+
}
|
|
4829
|
+
.ai-subagent.is-done .ai-subagent-result {
|
|
4830
|
+
color: var(--token-text);
|
|
4831
|
+
border-color: color-mix(in srgb, var(--token-success) 30%, transparent);
|
|
4832
|
+
}
|
|
4833
|
+
|
|
4834
|
+
/* ══════════════════════════════════════════════════════════════
|
|
4835
|
+
动效守卫
|
|
4836
|
+
══════════════════════════════════════════════════════════════ */
|
|
4837
|
+
@media (prefers-reduced-motion: reduce) {
|
|
4838
|
+
:is(.ai-item, .ai-tool, .ai-subagent).is-running .ai-item-status,
|
|
4839
|
+
:is(.ai-item, .ai-tool, .ai-subagent).is-streaming .ai-item-status {
|
|
4840
|
+
animation: none;
|
|
4841
|
+
}
|
|
4842
|
+
.ai-tool-body,
|
|
4843
|
+
.ai-subagent-stream > * {
|
|
4844
|
+
animation: none;
|
|
4845
|
+
}
|
|
4846
|
+
.ai-tool-head,
|
|
4847
|
+
.ai-subagent-head {
|
|
4848
|
+
transition: none;
|
|
4849
|
+
}
|
|
4850
|
+
}
|
|
4851
|
+
|
|
4852
|
+
/* ═══ 工具卡内嵌图表(回执 = ChartSpec 时 setIo 走 renderChart,§13)═══ */
|
|
4853
|
+
.ai-tool-io-chart {
|
|
4854
|
+
width: 100%;
|
|
4855
|
+
min-width: 0;
|
|
4856
|
+
}
|
|
4857
|
+
|
|
4858
|
+
/* ═══ AI 工具挂载区(ai-tools.ts 的 createAiToolArea,§13)═══
|
|
4859
|
+
* .ai-tools-mount > .ai-tools-item > head(名/时间/×)+ body(工具自渲染) */
|
|
4860
|
+
.ai-tools-mount {
|
|
4861
|
+
display: grid;
|
|
4862
|
+
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
|
4863
|
+
gap: var(--density-space-md);
|
|
4864
|
+
align-items: start;
|
|
4865
|
+
}
|
|
4866
|
+
.ai-tools-item {
|
|
4867
|
+
display: flex;
|
|
4868
|
+
flex-direction: column;
|
|
4869
|
+
min-width: 0;
|
|
4870
|
+
border: 1px solid var(--token-line-soft);
|
|
4871
|
+
border-radius: var(--radius-md);
|
|
4872
|
+
background: var(--token-surface);
|
|
4873
|
+
animation: icen-pop-in var(--duration-normal) var(--ease-out);
|
|
4874
|
+
}
|
|
4875
|
+
.ai-tools-item-head {
|
|
4876
|
+
display: flex;
|
|
4877
|
+
align-items: center;
|
|
4878
|
+
gap: var(--density-space-sm);
|
|
4879
|
+
padding: var(--density-space-xs) var(--density-space-sm);
|
|
4880
|
+
border-bottom: 1px solid var(--token-line-soft);
|
|
4881
|
+
}
|
|
4882
|
+
.ai-tools-item-name {
|
|
4883
|
+
font-family: var(--font-mono);
|
|
4884
|
+
font-size: var(--density-font-size-xs);
|
|
4885
|
+
color: var(--token-text);
|
|
4886
|
+
}
|
|
4887
|
+
.ai-tools-item-meta {
|
|
4888
|
+
flex: 1;
|
|
4889
|
+
font-family: var(--font-mono);
|
|
4890
|
+
font-size: var(--density-font-size-2xs);
|
|
4891
|
+
color: var(--token-text-faint);
|
|
4892
|
+
font-variant-numeric: tabular-nums;
|
|
4893
|
+
}
|
|
4894
|
+
.ai-tools-item-remove {
|
|
4895
|
+
border: 0;
|
|
4896
|
+
background: transparent;
|
|
4897
|
+
color: var(--token-text-faint);
|
|
4898
|
+
cursor: pointer;
|
|
4899
|
+
border-radius: var(--radius-xs);
|
|
4900
|
+
font-size: var(--density-font-size-sm);
|
|
4901
|
+
line-height: 1;
|
|
4902
|
+
padding: 2px 6px;
|
|
4903
|
+
transition: color var(--icen-tx-fast), background-color var(--icen-tx-fast);
|
|
4904
|
+
}
|
|
4905
|
+
.ai-tools-item-remove:hover { color: var(--token-error); background: var(--token-fill-1); }
|
|
4906
|
+
.ai-tools-item-remove:focus-visible { outline: none; box-shadow: var(--icen-ring); }
|
|
4907
|
+
.ai-tools-item-body {
|
|
4908
|
+
padding: var(--density-space-sm);
|
|
4909
|
+
min-width: 0;
|
|
2267
4910
|
}
|
|
2268
4911
|
|
|
2269
|
-
/* ══════════════════════════════════════════════════════════════
|
|
2270
|
-
动效与无障碍兜底
|
|
2271
|
-
══════════════════════════════════════════════════════════════ */
|
|
2272
|
-
|
|
2273
|
-
/* reduced-motion:所有动画/过渡压缩到 ~0ms(保留可访问性最小可视信号) */
|
|
2274
4912
|
@media (prefers-reduced-motion: reduce) {
|
|
2275
|
-
|
|
2276
|
-
animation-duration: 0.01ms !important;
|
|
2277
|
-
animation-iteration-count: 1 !important;
|
|
2278
|
-
transition-duration: 0.01ms !important;
|
|
2279
|
-
scroll-behavior: auto !important;
|
|
2280
|
-
}
|
|
4913
|
+
.ai-tools-item { animation: none; }
|
|
2281
4914
|
}
|
|
2282
4915
|
|
|
2283
|
-
/*
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
4916
|
+
/* 挂载项折叠态:head 为 button(chevron + 名/时间 + ×) */
|
|
4917
|
+
.ai-tools-item-head {
|
|
4918
|
+
cursor: pointer;
|
|
4919
|
+
border: 0;
|
|
4920
|
+
background: transparent;
|
|
4921
|
+
text-align: left;
|
|
4922
|
+
width: 100%;
|
|
4923
|
+
font: inherit;
|
|
2287
4924
|
}
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
}
|
|
2294
|
-
.focus-ring:focus-visible,
|
|
2295
|
-
.pressable:focus-visible {
|
|
2296
|
-
outline: 2px solid Highlight;
|
|
2297
|
-
outline-offset: 2px;
|
|
2298
|
-
}
|
|
4925
|
+
.ai-tools-item-chevron {
|
|
4926
|
+
flex-shrink: 0;
|
|
4927
|
+
color: var(--token-text-faint);
|
|
4928
|
+
font-size: var(--density-font-size-xs);
|
|
4929
|
+
transition: transform var(--icen-tx-fast);
|
|
2299
4930
|
}
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
body { font-size: 12pt; line-height: 1.4; }
|
|
2310
|
-
a, a:visited { text-decoration: underline; }
|
|
2311
|
-
a[href]::after { content: ' (' attr(href) ')'; font-size: 90%; }
|
|
2312
|
-
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
|
|
2313
|
-
h1, h2, h3 { page-break-after: avoid; }
|
|
2314
|
-
.pressable, .lift, .surface-elevated { box-shadow: none !important; transform: none !important; }
|
|
4931
|
+
.ai-tools-item-head[aria-expanded='false'] .ai-tools-item-chevron {
|
|
4932
|
+
transform: rotate(-90deg);
|
|
4933
|
+
}
|
|
4934
|
+
.ai-tools-item.is-collapsed .ai-tools-item-body {
|
|
4935
|
+
display: none;
|
|
4936
|
+
}
|
|
4937
|
+
.ai-tools-item-head:focus-visible {
|
|
4938
|
+
outline: none;
|
|
4939
|
+
box-shadow: var(--icen-ring);
|
|
2315
4940
|
}
|
|
2316
4941
|
|
|
2317
4942
|
|
|
@@ -2454,11 +5079,11 @@ html {
|
|
|
2454
5079
|
height: 16px;
|
|
2455
5080
|
padding: 0 4px;
|
|
2456
5081
|
font: inherit;
|
|
2457
|
-
font-size:
|
|
5082
|
+
font-size: var(--density-font-size-2xs);
|
|
2458
5083
|
font-weight: 600;
|
|
2459
5084
|
line-height: 1;
|
|
2460
5085
|
font-variant-numeric: tabular-nums;
|
|
2461
|
-
color: var(--token-on-accent
|
|
5086
|
+
color: var(--token-on-accent);
|
|
2462
5087
|
background: var(--token-error);
|
|
2463
5088
|
border: 2px solid var(--token-surface);
|
|
2464
5089
|
border-radius: var(--radius-full);
|
|
@@ -2481,7 +5106,7 @@ html {
|
|
|
2481
5106
|
.badge--sm {
|
|
2482
5107
|
min-width: 14px;
|
|
2483
5108
|
height: 14px;
|
|
2484
|
-
font-size:
|
|
5109
|
+
font-size: var(--density-font-size-2xs);
|
|
2485
5110
|
padding: 0 3px;
|
|
2486
5111
|
}
|
|
2487
5112
|
.badge--sm.badge--dot {
|
|
@@ -2526,7 +5151,7 @@ html {
|
|
|
2526
5151
|
/* 挂在实底色按钮上时用更浅的边框 */
|
|
2527
5152
|
.btn-primary .badge,
|
|
2528
5153
|
.btn-danger .badge {
|
|
2529
|
-
border-color: var(--token-on-accent
|
|
5154
|
+
border-color: var(--token-on-accent);
|
|
2530
5155
|
}
|
|
2531
5156
|
|
|
2532
5157
|
/* 数字超过 99 显示 99+(消费方决定是否使用,这里只保证宽度容纳) */
|
|
@@ -2535,10 +5160,6 @@ html {
|
|
|
2535
5160
|
padding: 0 5px;
|
|
2536
5161
|
}
|
|
2537
5162
|
|
|
2538
|
-
@media (prefers-reduced-motion: reduce) {
|
|
2539
|
-
.badge { transition: none; }
|
|
2540
|
-
}
|
|
2541
|
-
|
|
2542
5163
|
|
|
2543
5164
|
/* ── components/breadcrumb.css ── */
|
|
2544
5165
|
/*
|
|
@@ -2663,7 +5284,7 @@ html {
|
|
|
2663
5284
|
border-radius: var(--radius-md);
|
|
2664
5285
|
box-shadow: var(--token-shadow-overlay);
|
|
2665
5286
|
z-index: var(--z-popover);
|
|
2666
|
-
animation:
|
|
5287
|
+
animation: icen-pop-in var(--icen-tx-fast);
|
|
2667
5288
|
}
|
|
2668
5289
|
.breadcrumb-dropdown-menu[hidden] { display: none; }
|
|
2669
5290
|
.breadcrumb-dropdown-menu a {
|
|
@@ -2679,10 +5300,6 @@ html {
|
|
|
2679
5300
|
background: var(--token-fill-1);
|
|
2680
5301
|
color: var(--token-text);
|
|
2681
5302
|
}
|
|
2682
|
-
@keyframes breadcrumb-drop-in {
|
|
2683
|
-
from { opacity: 0; transform: scale(0.96) translateY(-4px); }
|
|
2684
|
-
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
2685
|
-
}
|
|
2686
5303
|
|
|
2687
5304
|
/* ── 面包屑分隔符变体 ── */
|
|
2688
5305
|
.breadcrumb--slash .breadcrumb-sep::after { content: '/'; }
|
|
@@ -2782,7 +5399,7 @@ html {
|
|
|
2782
5399
|
/* ── 变体 ── */
|
|
2783
5400
|
.btn-primary {
|
|
2784
5401
|
--btn-bg: var(--token-accent);
|
|
2785
|
-
--btn-fg: var(--token-on-accent
|
|
5402
|
+
--btn-fg: var(--token-on-accent);
|
|
2786
5403
|
--btn-border: var(--token-accent);
|
|
2787
5404
|
--btn-bg-hover: var(--token-accent-deep, color-mix(in srgb, var(--token-accent) 85%, black));
|
|
2788
5405
|
--btn-border-hover: var(--token-accent-deep, var(--token-accent));
|
|
@@ -2798,7 +5415,7 @@ html {
|
|
|
2798
5415
|
--btn-bg-hover: var(--token-error);
|
|
2799
5416
|
--btn-border-hover: var(--token-error);
|
|
2800
5417
|
}
|
|
2801
|
-
.btn-danger:hover { color: var(--token-on-accent
|
|
5418
|
+
.btn-danger:hover { color: var(--token-on-accent); }
|
|
2802
5419
|
|
|
2803
5420
|
.btn-ghost {
|
|
2804
5421
|
--btn-bg: transparent;
|
|
@@ -2869,14 +5486,11 @@ html {
|
|
|
2869
5486
|
border: 2px solid color-mix(in srgb, currentColor 35%, transparent);
|
|
2870
5487
|
border-top-color: currentColor;
|
|
2871
5488
|
border-radius: 50%;
|
|
2872
|
-
animation: btn-spin var(--duration-slow) linear infinite;
|
|
5489
|
+
animation: icen-spin var(--btn-spin-duration, var(--duration-slow)) linear infinite;
|
|
2873
5490
|
opacity: 1; /* 覆盖 .pressable::after 渐变(若与 .pressable 同用) */
|
|
2874
5491
|
background: none;
|
|
2875
5492
|
pointer-events: none;
|
|
2876
5493
|
}
|
|
2877
|
-
@keyframes btn-spin {
|
|
2878
|
-
to { transform: rotate(360deg); }
|
|
2879
|
-
}
|
|
2880
5494
|
|
|
2881
5495
|
/* 图标按钮内部 svg 默认尺寸对齐字号 */
|
|
2882
5496
|
.btn-icon-start, .btn-icon-end {
|
|
@@ -2886,7 +5500,7 @@ html {
|
|
|
2886
5500
|
}
|
|
2887
5501
|
|
|
2888
5502
|
@media (prefers-reduced-motion: reduce) {
|
|
2889
|
-
.btn.is-loading::after {
|
|
5503
|
+
.btn.is-loading::after { --btn-spin-duration: 1.2s; }
|
|
2890
5504
|
}
|
|
2891
5505
|
|
|
2892
5506
|
|
|
@@ -2918,6 +5532,7 @@ html {
|
|
|
2918
5532
|
*/
|
|
2919
5533
|
|
|
2920
5534
|
.card {
|
|
5535
|
+
position: relative;
|
|
2921
5536
|
background: var(--token-card);
|
|
2922
5537
|
border: 1px solid var(--token-outline-soft);
|
|
2923
5538
|
box-shadow: var(--token-shadow-inset);
|
|
@@ -2984,14 +5599,11 @@ html {
|
|
|
2984
5599
|
transform: scale(1.04);
|
|
2985
5600
|
}
|
|
2986
5601
|
.card-media > img,
|
|
2987
|
-
.card-media > video {
|
|
2988
|
-
transition: transform var(--icen-tx-slow) var(--ease-out);
|
|
2989
|
-
}
|
|
2990
|
-
.card-media > img,
|
|
2991
5602
|
.card-media > video {
|
|
2992
5603
|
width: 100%;
|
|
2993
5604
|
height: 100%;
|
|
2994
5605
|
object-fit: cover;
|
|
5606
|
+
transition: transform var(--icen-tx-slow) var(--ease-out);
|
|
2995
5607
|
}
|
|
2996
5608
|
.card-tag {
|
|
2997
5609
|
position: absolute;
|
|
@@ -3000,7 +5612,7 @@ html {
|
|
|
3000
5612
|
padding: 2px var(--density-space-xs);
|
|
3001
5613
|
font-size: var(--density-font-size-xs);
|
|
3002
5614
|
font-weight: 600;
|
|
3003
|
-
color: var(--token-on-accent
|
|
5615
|
+
color: var(--token-on-accent);
|
|
3004
5616
|
background: color-mix(in srgb, var(--token-text) 70%, transparent);
|
|
3005
5617
|
border-radius: var(--radius-xs);
|
|
3006
5618
|
backdrop-filter: blur(8px);
|
|
@@ -3114,7 +5726,6 @@ html {
|
|
|
3114
5726
|
right: var(--density-space-sm);
|
|
3115
5727
|
z-index: 1;
|
|
3116
5728
|
}
|
|
3117
|
-
.card { position: relative; }
|
|
3118
5729
|
|
|
3119
5730
|
|
|
3120
5731
|
/* ── components/chart-area.css ── */
|
|
@@ -3216,6 +5827,16 @@ html {
|
|
|
3216
5827
|
.chart-vbar-bar, .chart-hbar-bar { transition: none; }
|
|
3217
5828
|
}
|
|
3218
5829
|
|
|
5830
|
+
/* ── 多系列:分组(簇内并排)与堆叠(列内向上叠)── */
|
|
5831
|
+
.chart-vbar-track--multi { gap: 2px; }
|
|
5832
|
+
.chart-vbar-track--multi > .chart-vbar-bar { flex: 1; min-width: 0; width: auto; }
|
|
5833
|
+
.chart-vbar-track--multi.chart-vbar-track--stacked {
|
|
5834
|
+
flex-direction: column;
|
|
5835
|
+
justify-content: flex-end;
|
|
5836
|
+
gap: 0;
|
|
5837
|
+
}
|
|
5838
|
+
.chart-vbar-track--multi.chart-vbar-track--stacked > .chart-vbar-bar { flex: none; width: 100%; }
|
|
5839
|
+
|
|
3219
5840
|
|
|
3220
5841
|
/* ── components/chart-gauge.css ── */
|
|
3221
5842
|
/*
|
|
@@ -3247,7 +5868,7 @@ html {
|
|
|
3247
5868
|
gap: 1px;
|
|
3248
5869
|
}
|
|
3249
5870
|
.chart-gauge-value {
|
|
3250
|
-
font-size:
|
|
5871
|
+
font-size: var(--density-font-size-2xl);
|
|
3251
5872
|
font-weight: 700;
|
|
3252
5873
|
font-variant-numeric: tabular-nums;
|
|
3253
5874
|
color: var(--token-text);
|
|
@@ -3312,6 +5933,46 @@ html {
|
|
|
3312
5933
|
.chart-heatmap-legend > span:first-child { margin-right: 2px; }
|
|
3313
5934
|
.chart-heatmap-legend > span:last-child { margin-left: 2px; }
|
|
3314
5935
|
|
|
5936
|
+
/* ── 贡献日历(renderCalendar):月份标签 + 星期列 + 周格 ──
|
|
5937
|
+
* 布局 grid:左列星期标签(一/三/五/日),右列自上而下 月份行 / 周格 / 图例。
|
|
5938
|
+
* 月份标签按周列定位:left = col / columns * 100%。 */
|
|
5939
|
+
.chart-calendar {
|
|
5940
|
+
display: grid;
|
|
5941
|
+
grid-template-columns: 14px 1fr;
|
|
5942
|
+
grid-template-rows: 14px auto auto;
|
|
5943
|
+
column-gap: 4px;
|
|
5944
|
+
row-gap: 3px;
|
|
5945
|
+
}
|
|
5946
|
+
.chart-calendar-months {
|
|
5947
|
+
grid-column: 2;
|
|
5948
|
+
position: relative;
|
|
5949
|
+
font-size: var(--density-font-size-2xs);
|
|
5950
|
+
color: var(--token-text-faint);
|
|
5951
|
+
}
|
|
5952
|
+
.chart-calendar-month {
|
|
5953
|
+
position: absolute;
|
|
5954
|
+
top: 0;
|
|
5955
|
+
left: calc(var(--col, 0) / var(--columns, 1) * 100%);
|
|
5956
|
+
white-space: nowrap;
|
|
5957
|
+
}
|
|
5958
|
+
.chart-calendar-weekdays {
|
|
5959
|
+
grid-column: 1;
|
|
5960
|
+
grid-row: 2;
|
|
5961
|
+
display: grid;
|
|
5962
|
+
grid-template-rows: repeat(7, 1fr);
|
|
5963
|
+
font-size: var(--density-font-size-2xs);
|
|
5964
|
+
color: var(--token-text-faint);
|
|
5965
|
+
line-height: 1;
|
|
5966
|
+
}
|
|
5967
|
+
.chart-calendar .chart-heatmap-grid {
|
|
5968
|
+
grid-column: 2;
|
|
5969
|
+
grid-row: 2;
|
|
5970
|
+
}
|
|
5971
|
+
.chart-calendar .chart-heatmap-legend {
|
|
5972
|
+
grid-column: 2;
|
|
5973
|
+
grid-row: 3;
|
|
5974
|
+
}
|
|
5975
|
+
|
|
3315
5976
|
|
|
3316
5977
|
/* ── components/chart-line.css ── */
|
|
3317
5978
|
/*
|
|
@@ -3382,6 +6043,33 @@ html {
|
|
|
3382
6043
|
.chart-radar { gap: var(--density-space-md); }
|
|
3383
6044
|
|
|
3384
6045
|
|
|
6046
|
+
/* ── components/chart-scatter.css ── */
|
|
6047
|
+
/*
|
|
6048
|
+
* @icen.ai/ui — Component: chart-scatter(散点/气泡图专属样式)
|
|
6049
|
+
* 依赖:charts.css(基座 .chart / tooltip / [data-chart-mark] 交互态)
|
|
6050
|
+
*
|
|
6051
|
+
* DOM 由 behaviors/charts.ts 的 renderScatter 构建:
|
|
6052
|
+
* .chart-scatter > svg(360×220 viewBox,网格 + 刻度 + circle[data-chart-mark])
|
|
6053
|
+
* 气泡第三维:points[].size 映射半径 3–10;hover/点击/右键走通用层委托。
|
|
6054
|
+
*/
|
|
6055
|
+
|
|
6056
|
+
.chart-scatter svg {
|
|
6057
|
+
width: 100%;
|
|
6058
|
+
height: auto;
|
|
6059
|
+
display: block;
|
|
6060
|
+
}
|
|
6061
|
+
.chart-scatter circle[data-chart-mark] {
|
|
6062
|
+
transition: fill-opacity var(--icen-tx-fast);
|
|
6063
|
+
}
|
|
6064
|
+
.chart-scatter circle[data-chart-mark]:hover {
|
|
6065
|
+
fill-opacity: 0.85;
|
|
6066
|
+
}
|
|
6067
|
+
|
|
6068
|
+
@media (prefers-reduced-motion: reduce) {
|
|
6069
|
+
.chart-scatter circle[data-chart-mark] { transition: none; }
|
|
6070
|
+
}
|
|
6071
|
+
|
|
6072
|
+
|
|
3385
6073
|
/* ── components/chart-sparkline.css ── */
|
|
3386
6074
|
/*
|
|
3387
6075
|
* @icen.ai/ui — Component: chart-sparkline(迷你趋势线专属样式)
|
|
@@ -3505,7 +6193,7 @@ html {
|
|
|
3505
6193
|
flex: 1;
|
|
3506
6194
|
min-width: 0;
|
|
3507
6195
|
text-align: center;
|
|
3508
|
-
font-size:
|
|
6196
|
+
font-size: var(--density-font-size-2xs);
|
|
3509
6197
|
color: var(--token-text-faint);
|
|
3510
6198
|
overflow: hidden;
|
|
3511
6199
|
text-overflow: ellipsis;
|
|
@@ -3521,6 +6209,91 @@ html {
|
|
|
3521
6209
|
.chart-tone-5 { --chart-tone: var(--token-info); }
|
|
3522
6210
|
.chart-tone-6 { --chart-tone: color-mix(in srgb, var(--token-text) 50%, transparent); }
|
|
3523
6211
|
|
|
6212
|
+
/* ═══ 通用层(renderChart):标题 / 内置 tooltip / 标记交互 / 图例切换 ═══ */
|
|
6213
|
+
|
|
6214
|
+
/* 标题(spec.title 有值时渲染) */
|
|
6215
|
+
.chart-title {
|
|
6216
|
+
font-size: var(--density-font-size-sm);
|
|
6217
|
+
font-weight: 600;
|
|
6218
|
+
color: var(--token-text);
|
|
6219
|
+
}
|
|
6220
|
+
|
|
6221
|
+
/* 头部行(renderChart 渲染):标题 + 图例可见性小眼睛 */
|
|
6222
|
+
.chart-head {
|
|
6223
|
+
display: flex;
|
|
6224
|
+
align-items: center;
|
|
6225
|
+
justify-content: space-between;
|
|
6226
|
+
gap: var(--density-space-sm);
|
|
6227
|
+
min-height: 24px;
|
|
6228
|
+
}
|
|
6229
|
+
.chart-legend-eye {
|
|
6230
|
+
display: inline-flex;
|
|
6231
|
+
align-items: center;
|
|
6232
|
+
justify-content: center;
|
|
6233
|
+
width: 22px;
|
|
6234
|
+
height: 22px;
|
|
6235
|
+
padding: 0;
|
|
6236
|
+
border: 0;
|
|
6237
|
+
border-radius: var(--radius-xs);
|
|
6238
|
+
background: transparent;
|
|
6239
|
+
color: var(--token-text-faint);
|
|
6240
|
+
cursor: pointer;
|
|
6241
|
+
transition: color var(--icen-tx-fast), background-color var(--icen-tx-fast);
|
|
6242
|
+
}
|
|
6243
|
+
.chart-legend-eye:hover { color: var(--token-text); background: var(--token-fill-1); }
|
|
6244
|
+
.chart-legend-eye:focus-visible { outline: none; box-shadow: var(--icen-ring); }
|
|
6245
|
+
.chart-legend-eye svg { width: 13px; height: 13px; }
|
|
6246
|
+
|
|
6247
|
+
/* 图例统一隐藏:容器级继承——data-legend-hidden 一条选择器覆盖全部图型的图例 */
|
|
6248
|
+
[data-legend-hidden='true'] .chart-legend,
|
|
6249
|
+
[data-legend-hidden='true'] .chart-legend--toggle,
|
|
6250
|
+
[data-legend-hidden='true'] .chart-heatmap-legend {
|
|
6251
|
+
display: none;
|
|
6252
|
+
}
|
|
6253
|
+
|
|
6254
|
+
/* 内置 tooltip:portal 到 body 的单例,position: fixed 跟随指针 */
|
|
6255
|
+
.chart-tooltip {
|
|
6256
|
+
position: fixed;
|
|
6257
|
+
z-index: var(--z-tooltip);
|
|
6258
|
+
max-width: 280px;
|
|
6259
|
+
padding: 3px 8px;
|
|
6260
|
+
border-radius: var(--radius-sm);
|
|
6261
|
+
background: var(--token-card-strong);
|
|
6262
|
+
border: 1px solid var(--token-line);
|
|
6263
|
+
box-shadow: var(--token-shadow-elevated);
|
|
6264
|
+
font-size: var(--density-font-size-xs);
|
|
6265
|
+
font-variant-numeric: tabular-nums;
|
|
6266
|
+
color: var(--token-text);
|
|
6267
|
+
pointer-events: none;
|
|
6268
|
+
}
|
|
6269
|
+
.chart-tooltip[hidden] { display: none; }
|
|
6270
|
+
|
|
6271
|
+
/* 数据标记(各图型的条/点/段/格):交互态由委托层挂 .is-hover,图例切换挂 .is-off */
|
|
6272
|
+
[data-chart-mark] { cursor: pointer; }
|
|
6273
|
+
[data-chart-mark].is-hover { filter: brightness(1.12); }
|
|
6274
|
+
[data-chart-mark].is-off { opacity: 0.16; pointer-events: none; }
|
|
6275
|
+
svg circle[data-chart-mark].is-hover { stroke-width: 3; }
|
|
6276
|
+
|
|
6277
|
+
/* 可切换图例:行可点(Enter/Space 等价),.is-off 划线淡化 */
|
|
6278
|
+
.chart-legend--toggle .chart-legend-toggle-item {
|
|
6279
|
+
cursor: pointer;
|
|
6280
|
+
border-radius: var(--radius-xs);
|
|
6281
|
+
padding: 2px 4px;
|
|
6282
|
+
margin: -2px -4px;
|
|
6283
|
+
transition: background-color var(--icen-tx-fast);
|
|
6284
|
+
}
|
|
6285
|
+
.chart-legend--toggle .chart-legend-toggle-item:hover { background: var(--token-fill-1); }
|
|
6286
|
+
.chart-legend--toggle .chart-legend-toggle-item:focus-visible {
|
|
6287
|
+
outline: none;
|
|
6288
|
+
box-shadow: var(--icen-ring);
|
|
6289
|
+
}
|
|
6290
|
+
.chart-legend--toggle .is-off .chart-legend-label,
|
|
6291
|
+
.chart-legend--toggle .is-off .chart-legend-value {
|
|
6292
|
+
color: var(--token-text-faint);
|
|
6293
|
+
text-decoration: line-through;
|
|
6294
|
+
}
|
|
6295
|
+
.chart-legend--toggle .is-off .chart-legend-dot { opacity: 0.3; }
|
|
6296
|
+
|
|
3524
6297
|
|
|
3525
6298
|
/* ── components/command-palette.css ── */
|
|
3526
6299
|
/*
|
|
@@ -3713,7 +6486,7 @@ html {
|
|
|
3713
6486
|
|
|
3714
6487
|
.command-palette-item-kbd {
|
|
3715
6488
|
font-family: var(--font-mono);
|
|
3716
|
-
font-size:
|
|
6489
|
+
font-size: var(--density-font-size-2xs);
|
|
3717
6490
|
color: var(--token-text-faint);
|
|
3718
6491
|
padding: 1px 5px;
|
|
3719
6492
|
border: 1px solid var(--token-line-soft);
|
|
@@ -3744,7 +6517,7 @@ html {
|
|
|
3744
6517
|
}
|
|
3745
6518
|
.command-palette-foot-hint kbd {
|
|
3746
6519
|
font-family: var(--font-mono);
|
|
3747
|
-
font-size:
|
|
6520
|
+
font-size: var(--density-font-size-2xs);
|
|
3748
6521
|
padding: 1px 4px;
|
|
3749
6522
|
border: 1px solid var(--token-line-soft);
|
|
3750
6523
|
border-radius: var(--radius-xs);
|
|
@@ -3802,7 +6575,7 @@ html {
|
|
|
3802
6575
|
height: 16px;
|
|
3803
6576
|
min-width: 16px;
|
|
3804
6577
|
padding: 0 4px;
|
|
3805
|
-
font-size:
|
|
6578
|
+
font-size: var(--density-font-size-2xs);
|
|
3806
6579
|
}
|
|
3807
6580
|
.kbd-group {
|
|
3808
6581
|
display: inline-flex;
|
|
@@ -3966,11 +6739,11 @@ html {
|
|
|
3966
6739
|
z-index: 1;
|
|
3967
6740
|
}
|
|
3968
6741
|
.timeline-dot svg { width: 13px; height: 13px; }
|
|
3969
|
-
.timeline-dot--accent { background: var(--token-accent); color: var(--token-on-accent
|
|
3970
|
-
.timeline-dot--success { background: var(--token-success); color: var(--token-on-accent
|
|
3971
|
-
.timeline-dot--warning { background: var(--token-warning); color: var(--token-on-accent
|
|
3972
|
-
.timeline-dot--error { background: var(--token-error); color: var(--token-on-accent
|
|
3973
|
-
.timeline-dot--info { background: var(--token-info); color: var(--token-on-accent
|
|
6742
|
+
.timeline-dot--accent { background: var(--token-accent); color: var(--token-on-accent); border-color: transparent; }
|
|
6743
|
+
.timeline-dot--success { background: var(--token-success); color: var(--token-on-accent); border-color: transparent; }
|
|
6744
|
+
.timeline-dot--warning { background: var(--token-warning); color: var(--token-on-accent); border-color: transparent; }
|
|
6745
|
+
.timeline-dot--error { background: var(--token-error); color: var(--token-on-accent); border-color: transparent; }
|
|
6746
|
+
.timeline-dot--info { background: var(--token-info); color: var(--token-on-accent); border-color: transparent; }
|
|
3974
6747
|
|
|
3975
6748
|
.timeline-body { flex: 1; min-width: 0; }
|
|
3976
6749
|
.timeline-head {
|
|
@@ -4136,9 +6909,9 @@ html {
|
|
|
4136
6909
|
min-width: 16px;
|
|
4137
6910
|
height: 16px;
|
|
4138
6911
|
padding: 0 4px;
|
|
4139
|
-
font-size:
|
|
6912
|
+
font-size: var(--density-font-size-2xs);
|
|
4140
6913
|
font-weight: 600;
|
|
4141
|
-
color: var(--token-on-accent
|
|
6914
|
+
color: var(--token-on-accent);
|
|
4142
6915
|
background: var(--token-accent);
|
|
4143
6916
|
border-radius: var(--radius-full);
|
|
4144
6917
|
flex-shrink: 0;
|
|
@@ -4228,7 +7001,6 @@ html {
|
|
|
4228
7001
|
/* 自定义 dot 尺寸 */
|
|
4229
7002
|
.timeline-dot--sm { width: 20px; height: 20px; }
|
|
4230
7003
|
.timeline-dot--sm svg { width: 10px; height: 10px; }
|
|
4231
|
-
.timeline-dot--sm ~ .timeline-item:not(:last-child)::after,
|
|
4232
7004
|
.timeline--sm .timeline-item:not(:last-child)::after { left: 10px; top: 24px; }
|
|
4233
7005
|
|
|
4234
7006
|
/* 时间线自定义内容槽(放标签、卡片等) */
|
|
@@ -4374,17 +7146,17 @@ html {
|
|
|
4374
7146
|
* <button class="copy-btn" data-copy="复制的文本">复制</button>
|
|
4375
7147
|
* <button class="copy-btn copy-btn--ghost" data-copy="…">复制链接</button>
|
|
4376
7148
|
*
|
|
4377
|
-
* 图标变体(带 data-copy-icon,仅加 .done 类;由 CSS 显隐子 svg):
|
|
7149
|
+
* 图标变体(带 data-copy-icon,仅加 .is-done 类;由 CSS 显隐子 svg):
|
|
4378
7150
|
* <button class="copy-btn copy-btn--icon" data-copy="…" data-copy-icon aria-label="复制">
|
|
4379
7151
|
* <svg class="copy-icon-clipboard">…</svg>
|
|
4380
7152
|
* <svg class="copy-icon-check" hidden>…</svg>
|
|
4381
7153
|
* </button>
|
|
4382
7154
|
*
|
|
4383
7155
|
* behavior 自动处理:
|
|
4384
|
-
* - 文本变体:成功后 textContent = '已复制' + 加 .done 类,1.4s 后还原
|
|
4385
|
-
* - 图标变体(带 data-copy-icon):仅加 .done 类(不改文本),由 CSS 切换 svg 显隐
|
|
7156
|
+
* - 文本变体:成功后 textContent = '已复制' + 加 .is-done 类,1.4s 后还原
|
|
7157
|
+
* - 图标变体(带 data-copy-icon):仅加 .is-done 类(不改文本),由 CSS 切换 svg 显隐
|
|
4386
7158
|
*
|
|
4387
|
-
* 与 toast.
|
|
7159
|
+
* 与 toast.toast--success 区别:copy 是"原地反馈"(按钮自身闪烁),toast 是"全局通知"。
|
|
4388
7160
|
*/
|
|
4389
7161
|
|
|
4390
7162
|
.copy-btn {
|
|
@@ -4433,7 +7205,7 @@ html {
|
|
|
4433
7205
|
}
|
|
4434
7206
|
|
|
4435
7207
|
/* ── 成功闪烁态(behavior 1.4s 后移除)── */
|
|
4436
|
-
.copy-btn.done {
|
|
7208
|
+
.copy-btn.is-done {
|
|
4437
7209
|
color: var(--token-success);
|
|
4438
7210
|
border-color: color-mix(in srgb, var(--token-success) 40%, transparent);
|
|
4439
7211
|
background: color-mix(in srgb, var(--token-success) 10%, transparent);
|
|
@@ -4451,10 +7223,10 @@ html {
|
|
|
4451
7223
|
flex-shrink: 0;
|
|
4452
7224
|
}
|
|
4453
7225
|
|
|
4454
|
-
/* .done 时显隐切换:剪贴板 → 对勾 */
|
|
7226
|
+
/* .is-done 时显隐切换:剪贴板 → 对勾 */
|
|
4455
7227
|
.copy-btn[data-copy-icon] .copy-icon-check { display: none; }
|
|
4456
|
-
.copy-btn[data-copy-icon].done .copy-icon-clipboard { display: none; }
|
|
4457
|
-
.copy-btn[data-copy-icon].done .copy-icon-check { display: inline-block; }
|
|
7228
|
+
.copy-btn[data-copy-icon].is-done .copy-icon-clipboard { display: none; }
|
|
7229
|
+
.copy-btn[data-copy-icon].is-done .copy-icon-check { display: inline-block; }
|
|
4458
7230
|
|
|
4459
7231
|
@media (prefers-reduced-motion: reduce) {
|
|
4460
7232
|
.copy-btn { transition: none; }
|
|
@@ -4589,11 +7361,11 @@ html {
|
|
|
4589
7361
|
.dt-cell--head.is-sortable:hover { color: var(--token-text); }
|
|
4590
7362
|
.dt-cell--head:focus-visible {
|
|
4591
7363
|
outline: none;
|
|
4592
|
-
box-shadow:
|
|
7364
|
+
box-shadow: var(--icen-ring-inset);
|
|
4593
7365
|
}
|
|
4594
7366
|
.dt-head-title { overflow: hidden; text-overflow: ellipsis; }
|
|
4595
7367
|
.dt-sort {
|
|
4596
|
-
font-size:
|
|
7368
|
+
font-size: var(--density-font-size-2xs);
|
|
4597
7369
|
color: var(--token-text-faint);
|
|
4598
7370
|
flex-shrink: 0;
|
|
4599
7371
|
}
|
|
@@ -4629,11 +7401,7 @@ html {
|
|
|
4629
7401
|
border-radius: var(--radius-md);
|
|
4630
7402
|
box-shadow: var(--token-shadow-overlay);
|
|
4631
7403
|
font-weight: 400;
|
|
4632
|
-
animation:
|
|
4633
|
-
}
|
|
4634
|
-
@keyframes dt-panel-in {
|
|
4635
|
-
from { opacity: 0; transform: scale(0.96) translateY(-4px); }
|
|
4636
|
-
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
7404
|
+
animation: icen-pop-in var(--icen-tx-fast);
|
|
4637
7405
|
}
|
|
4638
7406
|
.dt-filter-list {
|
|
4639
7407
|
max-height: 220px;
|
|
@@ -4864,7 +7632,7 @@ html {
|
|
|
4864
7632
|
.dt-resize:active::after {
|
|
4865
7633
|
background: var(--token-accent);
|
|
4866
7634
|
}
|
|
4867
|
-
.dt-cell--head
|
|
7635
|
+
/* .dt-cell--head 已在主规则 position: relative,供 resize 手柄绝对定位 */
|
|
4868
7636
|
|
|
4869
7637
|
/* ── 冻结列(左固定 sticky) ── */
|
|
4870
7638
|
.datatable--frozen .dt-cell--frozen {
|
|
@@ -4997,11 +7765,7 @@ html {
|
|
|
4997
7765
|
border-radius: var(--radius-md);
|
|
4998
7766
|
box-shadow: var(--token-shadow-overlay);
|
|
4999
7767
|
font-size: var(--density-font-size-sm);
|
|
5000
|
-
animation: icen-
|
|
5001
|
-
}
|
|
5002
|
-
@keyframes icen-dp-in {
|
|
5003
|
-
from { opacity: 0; transform: scale(0.96) translateY(-4px); }
|
|
5004
|
-
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
7768
|
+
animation: icen-pop-in var(--icen-tx-fast);
|
|
5005
7769
|
}
|
|
5006
7770
|
|
|
5007
7771
|
.date-picker-head {
|
|
@@ -5085,10 +7849,10 @@ html {
|
|
|
5085
7849
|
}
|
|
5086
7850
|
.date-picker-cell.is-selected {
|
|
5087
7851
|
background: var(--token-accent);
|
|
5088
|
-
color: var(--token-on-accent
|
|
7852
|
+
color: var(--token-on-accent);
|
|
5089
7853
|
font-weight: 600;
|
|
5090
7854
|
}
|
|
5091
|
-
.date-picker-cell.is-selected.is-today { border-color: var(--token-on-accent
|
|
7855
|
+
.date-picker-cell.is-selected.is-today { border-color: var(--token-on-accent); }
|
|
5092
7856
|
.date-picker-cell.is-outside {
|
|
5093
7857
|
color: var(--token-text-faint);
|
|
5094
7858
|
opacity: 0.55;
|
|
@@ -5273,10 +8037,6 @@ html {
|
|
|
5273
8037
|
.empty--404 .empty-title { font-size: 56px; }
|
|
5274
8038
|
}
|
|
5275
8039
|
|
|
5276
|
-
@media (prefers-reduced-motion: reduce) {
|
|
5277
|
-
.empty { animation: none; }
|
|
5278
|
-
}
|
|
5279
|
-
|
|
5280
8040
|
|
|
5281
8041
|
/* ── components/feedback.css ── */
|
|
5282
8042
|
/*
|
|
@@ -5430,7 +8190,7 @@ html {
|
|
|
5430
8190
|
/* 不定进度(spinner 替代品):bar 来回扫动 */
|
|
5431
8191
|
.progress--indeterminate .progress-bar {
|
|
5432
8192
|
width: 35% !important;
|
|
5433
|
-
animation: progress-sweep 1.4s var(--ease-in-out, var(--ease-out)) infinite;
|
|
8193
|
+
animation: progress-sweep var(--progress-sweep-duration, 1.4s) var(--ease-in-out, var(--ease-out)) infinite;
|
|
5434
8194
|
}
|
|
5435
8195
|
@keyframes progress-sweep {
|
|
5436
8196
|
0% { transform: translateX(-100%); }
|
|
@@ -5454,7 +8214,7 @@ html {
|
|
|
5454
8214
|
border: 2px solid color-mix(in srgb, var(--token-accent) 30%, transparent);
|
|
5455
8215
|
border-top-color: var(--token-accent);
|
|
5456
8216
|
border-radius: var(--radius-full);
|
|
5457
|
-
animation: icen-spin 0.8s linear infinite;
|
|
8217
|
+
animation: icen-spin var(--spinner-duration, 0.8s) linear infinite;
|
|
5458
8218
|
}
|
|
5459
8219
|
.spinner--sm { width: 14px; height: 14px; border-width: 2px; }
|
|
5460
8220
|
.spinner--lg { width: 32px; height: 32px; border-width: 3px; }
|
|
@@ -5462,8 +8222,6 @@ html {
|
|
|
5462
8222
|
.spinner--error { border-color: color-mix(in srgb, var(--token-error) 30%, transparent); border-top-color: var(--token-error); }
|
|
5463
8223
|
.spinner--muted { border-color: color-mix(in srgb, var(--token-text-faint) 30%, transparent); border-top-color: var(--token-text-faint); }
|
|
5464
8224
|
|
|
5465
|
-
@keyframes icen-spin { to { transform: rotate(360deg); } }
|
|
5466
|
-
|
|
5467
8225
|
/* 文字+spinner 组合 */
|
|
5468
8226
|
.spinner-wrap {
|
|
5469
8227
|
display: inline-flex;
|
|
@@ -5478,7 +8236,7 @@ html {
|
|
|
5478
8236
|
display: block;
|
|
5479
8237
|
background: color-mix(in srgb, var(--token-text) 8%, transparent);
|
|
5480
8238
|
border-radius: var(--radius-sm);
|
|
5481
|
-
animation: icen-skeleton-pulse 2s ease-in-out infinite;
|
|
8239
|
+
animation: icen-skeleton-pulse var(--skeleton-duration, 2s) ease-in-out infinite;
|
|
5482
8240
|
}
|
|
5483
8241
|
.skeleton--circle { border-radius: var(--radius-full); }
|
|
5484
8242
|
.skeleton--text {
|
|
@@ -5487,11 +8245,6 @@ html {
|
|
|
5487
8245
|
}
|
|
5488
8246
|
.skeleton--text:last-child { width: 60%; }
|
|
5489
8247
|
|
|
5490
|
-
@keyframes icen-skeleton-pulse {
|
|
5491
|
-
0%, 100% { opacity: 1; }
|
|
5492
|
-
50% { opacity: 0.5; }
|
|
5493
|
-
}
|
|
5494
|
-
|
|
5495
8248
|
/* ── alert 增强 ── */
|
|
5496
8249
|
|
|
5497
8250
|
/* 可操作横幅(含按钮) */
|
|
@@ -5585,7 +8338,7 @@ html {
|
|
|
5585
8338
|
transparent
|
|
5586
8339
|
);
|
|
5587
8340
|
background-size: 20px 20px;
|
|
5588
|
-
animation: progress-stripe 1s linear infinite;
|
|
8341
|
+
animation: progress-stripe var(--progress-stripe-duration, 1s) linear infinite;
|
|
5589
8342
|
}
|
|
5590
8343
|
@keyframes progress-stripe {
|
|
5591
8344
|
from { background-position: 0 0; }
|
|
@@ -5617,7 +8370,7 @@ html {
|
|
|
5617
8370
|
height: 6px;
|
|
5618
8371
|
border-radius: var(--radius-full);
|
|
5619
8372
|
background: var(--token-accent);
|
|
5620
|
-
animation: spinner-dot 1.4s ease-in-out infinite;
|
|
8373
|
+
animation: spinner-dot var(--spinner-dots-duration, 1.4s) ease-in-out infinite;
|
|
5621
8374
|
}
|
|
5622
8375
|
.spinner--dots span:nth-child(2) { animation-delay: 0.2s; }
|
|
5623
8376
|
.spinner--dots span:nth-child(3) { animation-delay: 0.4s; }
|
|
@@ -5643,7 +8396,7 @@ html {
|
|
|
5643
8396
|
height: 100%;
|
|
5644
8397
|
background: var(--token-accent);
|
|
5645
8398
|
border-radius: 1px;
|
|
5646
|
-
animation: spinner-bar 1s ease-in-out infinite;
|
|
8399
|
+
animation: spinner-bar var(--spinner-bars-duration, 1s) ease-in-out infinite;
|
|
5647
8400
|
}
|
|
5648
8401
|
.spinner--bars span:nth-child(2) { animation-delay: 0.1s; }
|
|
5649
8402
|
.spinner--bars span:nth-child(3) { animation-delay: 0.2s; }
|
|
@@ -5657,7 +8410,7 @@ html {
|
|
|
5657
8410
|
.spinner-overlay {
|
|
5658
8411
|
position: fixed;
|
|
5659
8412
|
inset: 0;
|
|
5660
|
-
z-index: var(--z-
|
|
8413
|
+
z-index: var(--z-dialog);
|
|
5661
8414
|
display: flex;
|
|
5662
8415
|
align-items: center;
|
|
5663
8416
|
justify-content: center;
|
|
@@ -5703,7 +8456,7 @@ html {
|
|
|
5703
8456
|
height: 12px;
|
|
5704
8457
|
border-radius: var(--radius-xs);
|
|
5705
8458
|
background: color-mix(in srgb, var(--token-text) 8%, transparent);
|
|
5706
|
-
animation: icen-skeleton-pulse 2s ease-in-out infinite;
|
|
8459
|
+
animation: icen-skeleton-pulse var(--skeleton-duration, 2s) ease-in-out infinite;
|
|
5707
8460
|
}
|
|
5708
8461
|
|
|
5709
8462
|
/* 骨架波纹变体(shimmer,区别于 pulse) */
|
|
@@ -5715,7 +8468,7 @@ html {
|
|
|
5715
8468
|
color-mix(in srgb, var(--token-text) 6%, transparent) 100%
|
|
5716
8469
|
);
|
|
5717
8470
|
background-size: 200% 100%;
|
|
5718
|
-
animation: skeleton-shimmer 1.5s ease-in-out infinite;
|
|
8471
|
+
animation: skeleton-shimmer var(--skeleton-shimmer-duration, 1.5s) ease-in-out infinite;
|
|
5719
8472
|
}
|
|
5720
8473
|
@keyframes skeleton-shimmer {
|
|
5721
8474
|
from { background-position: 200% 0; }
|
|
@@ -5727,7 +8480,7 @@ html {
|
|
|
5727
8480
|
.progress--indeterminate .progress-bar { animation: none; width: 100% !important; }
|
|
5728
8481
|
.progress--striped .progress-bar { animation: none; }
|
|
5729
8482
|
.progress-ring-fill { transition: none; }
|
|
5730
|
-
.spinner {
|
|
8483
|
+
.spinner { --spinner-duration: 2s; }
|
|
5731
8484
|
.spinner--dots span,
|
|
5732
8485
|
.spinner--bars span { animation: none; }
|
|
5733
8486
|
.skeleton,
|
|
@@ -5887,7 +8640,7 @@ html {
|
|
|
5887
8640
|
|
|
5888
8641
|
/* label 带可选标记 */
|
|
5889
8642
|
.form-label-optional {
|
|
5890
|
-
font-size:
|
|
8643
|
+
font-size: var(--density-font-size-2xs);
|
|
5891
8644
|
font-weight: 400;
|
|
5892
8645
|
color: var(--token-text-faint);
|
|
5893
8646
|
margin-left: 4px;
|
|
@@ -5968,11 +8721,11 @@ html {
|
|
|
5968
8721
|
border: 2px solid color-mix(in srgb, var(--token-accent) 30%, transparent);
|
|
5969
8722
|
border-top-color: var(--token-accent);
|
|
5970
8723
|
border-radius: 50%;
|
|
5971
|
-
animation: form-loading-
|
|
8724
|
+
animation: icen-spin var(--form-loading-duration, 0.8s) linear infinite;
|
|
5972
8725
|
}
|
|
5973
|
-
@keyframes form-loading-spin { to { transform: rotate(360deg); } }
|
|
5974
8726
|
|
|
5975
|
-
/* ── 页面级横幅:操作结果 / 引导提示 ──
|
|
8727
|
+
/* ── 页面级横幅:操作结果 / 引导提示 ──
|
|
8728
|
+
与 feedback.css 的 alert 共享同一套视觉 token(--banner-* 仅在底色/文字/描边上分流) */
|
|
5976
8729
|
.banner-ok,
|
|
5977
8730
|
.banner-err {
|
|
5978
8731
|
display: flex;
|
|
@@ -5984,16 +8737,19 @@ html {
|
|
|
5984
8737
|
font-size: var(--density-font-size-sm);
|
|
5985
8738
|
line-height: 1.5;
|
|
5986
8739
|
border: 1px solid transparent;
|
|
8740
|
+
background: var(--banner-bg);
|
|
8741
|
+
color: var(--banner-fg);
|
|
8742
|
+
border-color: var(--banner-border);
|
|
5987
8743
|
}
|
|
5988
8744
|
.banner-ok {
|
|
5989
|
-
|
|
5990
|
-
|
|
5991
|
-
border
|
|
8745
|
+
--banner-bg: var(--token-success-muted);
|
|
8746
|
+
--banner-fg: var(--token-success);
|
|
8747
|
+
--banner-border: color-mix(in srgb, var(--token-success) 25%, transparent);
|
|
5992
8748
|
}
|
|
5993
8749
|
.banner-err {
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
border
|
|
8750
|
+
--banner-bg: var(--token-error-muted);
|
|
8751
|
+
--banner-fg: var(--token-error);
|
|
8752
|
+
--banner-border: color-mix(in srgb, var(--token-error) 25%, transparent);
|
|
5997
8753
|
}
|
|
5998
8754
|
/* block 模式:横向占满,带图标位 */
|
|
5999
8755
|
.banner-block {
|
|
@@ -6001,10 +8757,6 @@ html {
|
|
|
6001
8757
|
padding: var(--density-space-md);
|
|
6002
8758
|
}
|
|
6003
8759
|
|
|
6004
|
-
@media (prefers-reduced-motion: reduce) {
|
|
6005
|
-
.banner-ok, .banner-err { transition: none; }
|
|
6006
|
-
}
|
|
6007
|
-
|
|
6008
8760
|
|
|
6009
8761
|
/* ── components/input.css ── */
|
|
6010
8762
|
/*
|
|
@@ -6028,6 +8780,7 @@ html {
|
|
|
6028
8780
|
|
|
6029
8781
|
/* ── 单行 ── */
|
|
6030
8782
|
.input-wrap {
|
|
8783
|
+
position: relative;
|
|
6031
8784
|
display: flex;
|
|
6032
8785
|
align-items: center;
|
|
6033
8786
|
gap: var(--density-space-xs);
|
|
@@ -6149,6 +8902,7 @@ html {
|
|
|
6149
8902
|
|
|
6150
8903
|
/* ── 多行:同一 wrapper 视觉,内部 textarea 裸奔 ── */
|
|
6151
8904
|
.textarea-wrap {
|
|
8905
|
+
position: relative;
|
|
6152
8906
|
display: flex;
|
|
6153
8907
|
width: 100%;
|
|
6154
8908
|
background: var(--token-control);
|
|
@@ -6198,7 +8952,6 @@ html {
|
|
|
6198
8952
|
}
|
|
6199
8953
|
|
|
6200
8954
|
/* 字符计数(behavior 可挂到 .input-wrap 或 .textarea-wrap 内尾部) */
|
|
6201
|
-
.input-wrap { position: relative; }
|
|
6202
8955
|
.input-wrap--has-counter { padding-right: calc(var(--density-space-sm) + 48px); }
|
|
6203
8956
|
.input-wrap--has-counter .input-counter {
|
|
6204
8957
|
position: absolute;
|
|
@@ -6223,7 +8976,6 @@ html {
|
|
|
6223
8976
|
.input-counter.is-warn { color: var(--token-warning); }
|
|
6224
8977
|
.input-counter.is-error { color: var(--token-error); font-weight: 600; }
|
|
6225
8978
|
|
|
6226
|
-
.textarea-wrap { position: relative; }
|
|
6227
8979
|
.textarea-wrap .textarea { padding-bottom: 24px; }
|
|
6228
8980
|
|
|
6229
8981
|
/* 有计数器时的 textarea 底部留空 */
|
|
@@ -6238,23 +8990,23 @@ html {
|
|
|
6238
8990
|
/*
|
|
6239
8991
|
* @icen.ai/ui — Component: layout(布局原语,全部是工具类,无 JS)
|
|
6240
8992
|
* stack / divider / surface / text / grid / center / container / aspect / visually-hidden
|
|
6241
|
-
* 全部消费 --token-*;档位类名与 opengal primitives/layout(-containers) 一一对应。
|
|
8993
|
+
* 全部消费 --token-* 与 --density-*;档位类名与 opengal primitives/layout(-containers) 一一对应。
|
|
6242
8994
|
*/
|
|
6243
8995
|
|
|
6244
|
-
/* ── Stack:flex 堆叠(默认列向,gap
|
|
6245
|
-
.stack { display: flex; flex-direction: column; gap:
|
|
8996
|
+
/* ── Stack:flex 堆叠(默认列向,gap = density-space-sm) ── */
|
|
8997
|
+
.stack { display: flex; flex-direction: column; gap: var(--density-space-sm); }
|
|
6246
8998
|
.stack--row { flex-direction: row; }
|
|
6247
8999
|
.stack--inline { display: inline-flex; }
|
|
6248
9000
|
.stack--wrap { flex-wrap: wrap; }
|
|
6249
9001
|
.stack--gap-0 { gap: 0; }
|
|
6250
|
-
.stack--gap-1 { gap:
|
|
6251
|
-
.stack--gap-2 { gap:
|
|
6252
|
-
.stack--gap-3 { gap:
|
|
6253
|
-
.stack--gap-4 { gap:
|
|
6254
|
-
.stack--gap-6 { gap:
|
|
6255
|
-
.stack--gap-8 { gap:
|
|
6256
|
-
.stack--gap-12 { gap:
|
|
6257
|
-
.stack--gap-16 { gap:
|
|
9002
|
+
.stack--gap-1 { gap: var(--density-space-xs); }
|
|
9003
|
+
.stack--gap-2 { gap: var(--density-space-sm); }
|
|
9004
|
+
.stack--gap-3 { gap: var(--density-space-md); }
|
|
9005
|
+
.stack--gap-4 { gap: var(--density-space-lg); }
|
|
9006
|
+
.stack--gap-6 { gap: var(--density-space-xl); }
|
|
9007
|
+
.stack--gap-8 { gap: var(--density-space-2xl); }
|
|
9008
|
+
.stack--gap-12 { gap: var(--density-space-3xl); }
|
|
9009
|
+
.stack--gap-16 { gap: var(--density-space-4xl); }
|
|
6258
9010
|
.stack--items-start { align-items: flex-start; }
|
|
6259
9011
|
.stack--items-center { align-items: center; }
|
|
6260
9012
|
.stack--items-end { align-items: flex-end; }
|
|
@@ -6271,13 +9023,13 @@ html {
|
|
|
6271
9023
|
.divider { background: var(--token-outline-soft); height: 1px; width: 100%; }
|
|
6272
9024
|
.divider--vertical { width: 1px; height: 100%; align-self: stretch; }
|
|
6273
9025
|
|
|
6274
|
-
/* ── Surface:卡片容器(默认 inset 阴影 +
|
|
9026
|
+
/* ── Surface:卡片容器(默认 inset 阴影 + density-space-lg padding) ── */
|
|
6275
9027
|
.surface {
|
|
6276
9028
|
border-radius: var(--radius-lg);
|
|
6277
9029
|
background: var(--token-card);
|
|
6278
9030
|
border: 1px solid var(--token-outline-soft);
|
|
6279
9031
|
box-shadow: var(--token-shadow-inset);
|
|
6280
|
-
padding:
|
|
9032
|
+
padding: var(--density-space-lg);
|
|
6281
9033
|
}
|
|
6282
9034
|
.surface--elevated { box-shadow: var(--token-shadow-card); }
|
|
6283
9035
|
.surface--overlay {
|
|
@@ -6286,18 +9038,18 @@ html {
|
|
|
6286
9038
|
box-shadow: var(--token-shadow-overlay);
|
|
6287
9039
|
}
|
|
6288
9040
|
.surface--p-none { padding: 0; }
|
|
6289
|
-
.surface--p-sm { padding:
|
|
6290
|
-
.surface--p-md { padding:
|
|
6291
|
-
.surface--p-lg { padding:
|
|
9041
|
+
.surface--p-sm { padding: var(--density-space-md); }
|
|
9042
|
+
.surface--p-md { padding: var(--density-space-lg); }
|
|
9043
|
+
.surface--p-lg { padding: calc(var(--density-space-lg) + var(--density-space-xs)); }
|
|
6292
9044
|
|
|
6293
9045
|
/* ── Text:字号 / 语义色 / 截断 ── */
|
|
6294
|
-
.text--xs { font-size:
|
|
6295
|
-
.text--sm { font-size:
|
|
6296
|
-
.text--base { font-size:
|
|
6297
|
-
.text--md { font-size:
|
|
6298
|
-
.text--lg { font-size:
|
|
6299
|
-
.text--xl { font-size:
|
|
6300
|
-
.text--2xl { font-size:
|
|
9046
|
+
.text--xs { font-size: var(--density-font-size-xs); }
|
|
9047
|
+
.text--sm { font-size: var(--density-font-size-sm); }
|
|
9048
|
+
.text--base { font-size: var(--density-font-size-md); }
|
|
9049
|
+
.text--md { font-size: var(--density-font-size-lg); }
|
|
9050
|
+
.text--lg { font-size: var(--density-font-size-lg); }
|
|
9051
|
+
.text--xl { font-size: var(--density-font-size-xl); }
|
|
9052
|
+
.text--2xl { font-size: var(--density-font-size-2xl); }
|
|
6301
9053
|
.text--muted { color: var(--token-text-muted); }
|
|
6302
9054
|
.text--faint { color: var(--token-text-faint); }
|
|
6303
9055
|
.text--accent { color: var(--token-accent); }
|
|
@@ -6306,8 +9058,8 @@ html {
|
|
|
6306
9058
|
.text--error { color: var(--token-error); }
|
|
6307
9059
|
.text--truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
6308
9060
|
|
|
6309
|
-
/* ── Grid:栅格(默认 gap
|
|
6310
|
-
.grid { display: grid; gap:
|
|
9061
|
+
/* ── Grid:栅格(默认 gap = density-space-md) ── */
|
|
9062
|
+
.grid { display: grid; gap: var(--density-space-md); }
|
|
6311
9063
|
.grid--cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
|
|
6312
9064
|
.grid--cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
6313
9065
|
.grid--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
|
@@ -6315,28 +9067,28 @@ html {
|
|
|
6315
9067
|
.grid--cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
|
|
6316
9068
|
.grid--cols-12 { grid-template-columns: repeat(12, minmax(0, 1fr)); }
|
|
6317
9069
|
.grid--gap-0 { gap: 0; }
|
|
6318
|
-
.grid--gap-4 { gap:
|
|
6319
|
-
.grid--gap-8 { gap:
|
|
6320
|
-
.grid--gap-12 { gap:
|
|
6321
|
-
.grid--gap-16 { gap:
|
|
6322
|
-
.grid--gap-24 { gap:
|
|
9070
|
+
.grid--gap-4 { gap: var(--density-space-xs); }
|
|
9071
|
+
.grid--gap-8 { gap: var(--density-space-sm); }
|
|
9072
|
+
.grid--gap-12 { gap: var(--density-space-md); }
|
|
9073
|
+
.grid--gap-16 { gap: var(--density-space-lg); }
|
|
9074
|
+
.grid--gap-24 { gap: var(--density-space-xl); }
|
|
6323
9075
|
|
|
6324
9076
|
/* ── Center:flex 居中盒 ── */
|
|
6325
9077
|
.center { display: flex; align-items: center; justify-content: center; }
|
|
6326
9078
|
|
|
6327
9079
|
/* ── Container:限宽容器(默认 960px) ── */
|
|
6328
|
-
.container { width: 100%; margin-inline: auto; padding-inline:
|
|
9080
|
+
.container { width: 100%; margin-inline: auto; padding-inline: var(--density-space-lg); max-width: 960px; }
|
|
6329
9081
|
.container--sm { max-width: 480px; }
|
|
6330
9082
|
.container--md { max-width: 720px; }
|
|
6331
9083
|
.container--lg { max-width: 960px; }
|
|
6332
9084
|
.container--xl { max-width: 1200px; }
|
|
6333
9085
|
.container--full { max-width: none; }
|
|
6334
9086
|
|
|
6335
|
-
/* ── Aspect:固定比例盒(
|
|
6336
|
-
.aspect { position: relative; width: 100%; overflow: hidden;
|
|
6337
|
-
.aspect--square {
|
|
6338
|
-
.aspect--4-3 {
|
|
6339
|
-
.aspect--2-3 {
|
|
9087
|
+
/* ── Aspect:固定比例盒(aspect-ratio,内容 absolute inset:0 铺满) ── */
|
|
9088
|
+
.aspect { position: relative; width: 100%; overflow: hidden; aspect-ratio: 16 / 9; }
|
|
9089
|
+
.aspect--square { aspect-ratio: 1 / 1; }
|
|
9090
|
+
.aspect--4-3 { aspect-ratio: 4 / 3; }
|
|
9091
|
+
.aspect--2-3 { aspect-ratio: 2 / 3; }
|
|
6340
9092
|
.aspect > * { position: absolute; inset: 0; }
|
|
6341
9093
|
|
|
6342
9094
|
/* ── VisuallyHidden:屏幕阅读器专用文本(sr-only 等价) ── */
|
|
@@ -6353,6 +9105,10 @@ html {
|
|
|
6353
9105
|
* 包含:avatar(头像)/ media-card(封面卡,滑出 overlay)/ rating(星级评分)/ carousel(轮播,与 behaviors/carousel 配套)
|
|
6354
9106
|
* 规格源自 opengal data/display.tsx 的 Avatar、data/cartridge-card.tsx 的 hover overlay、
|
|
6355
9107
|
* data/exhibit.tsx 的 Carousel 与 Rating。
|
|
9108
|
+
*
|
|
9109
|
+
* 例外声明(deliberate exception):carousel-thumbs 隐藏滚动条是有意设计
|
|
9110
|
+
* (缩略图条视觉纯净,滚动仍可用)。违反「组件不写滚动条样式」纪律仅此处,
|
|
9111
|
+
* 先例参照 scroll-area.css 的尺寸变体。
|
|
6356
9112
|
*/
|
|
6357
9113
|
|
|
6358
9114
|
/* ══════════════ avatar · 头像 ══════════════ */
|
|
@@ -6372,8 +9128,8 @@ html {
|
|
|
6372
9128
|
flex-shrink: 0;
|
|
6373
9129
|
user-select: none;
|
|
6374
9130
|
}
|
|
6375
|
-
.avatar--xs { width: 20px; height: 20px; font-size:
|
|
6376
|
-
.avatar--sm { width: 28px; height: 28px; font-size:
|
|
9131
|
+
.avatar--xs { width: 20px; height: 20px; font-size: var(--density-font-size-2xs); }
|
|
9132
|
+
.avatar--sm { width: 28px; height: 28px; font-size: var(--density-font-size-2xs); }
|
|
6377
9133
|
.avatar--lg { width: 48px; height: 48px; font-size: var(--density-font-size-md); }
|
|
6378
9134
|
.avatar--xl { width: 80px; height: 80px; font-size: var(--density-font-size-lg); }
|
|
6379
9135
|
.avatar img {
|
|
@@ -6417,7 +9173,7 @@ html {
|
|
|
6417
9173
|
/* 渐变底头像 */
|
|
6418
9174
|
.avatar--gradient {
|
|
6419
9175
|
background: linear-gradient(135deg, var(--token-accent), var(--token-accent-deep, var(--token-accent)));
|
|
6420
|
-
color: var(--token-on-accent
|
|
9176
|
+
color: var(--token-on-accent);
|
|
6421
9177
|
}
|
|
6422
9178
|
|
|
6423
9179
|
/* 方形头像 */
|
|
@@ -6435,7 +9191,7 @@ html {
|
|
|
6435
9191
|
justify-content: center;
|
|
6436
9192
|
width: 28px;
|
|
6437
9193
|
height: 28px;
|
|
6438
|
-
font-size:
|
|
9194
|
+
font-size: var(--density-font-size-2xs);
|
|
6439
9195
|
font-weight: 600;
|
|
6440
9196
|
color: var(--token-text-muted);
|
|
6441
9197
|
background: var(--token-fill-2);
|
|
@@ -6457,7 +9213,7 @@ html {
|
|
|
6457
9213
|
.media-card:hover {
|
|
6458
9214
|
transform: translateY(-6px);
|
|
6459
9215
|
box-shadow:
|
|
6460
|
-
|
|
9216
|
+
var(--token-shadow-overlay),
|
|
6461
9217
|
0 0 20px var(--token-accent-glow);
|
|
6462
9218
|
}
|
|
6463
9219
|
.media-card-cover {
|
|
@@ -6485,7 +9241,7 @@ html {
|
|
|
6485
9241
|
}
|
|
6486
9242
|
.media-card:hover .media-card-overlay {
|
|
6487
9243
|
transform: translateY(0);
|
|
6488
|
-
transition-delay: 80ms;
|
|
9244
|
+
transition-delay: var(--media-overlay-delay, 80ms);
|
|
6489
9245
|
}
|
|
6490
9246
|
.media-card-overlay-title {
|
|
6491
9247
|
font-size: var(--density-font-size-md);
|
|
@@ -6690,7 +9446,7 @@ html {
|
|
|
6690
9446
|
outline: none;
|
|
6691
9447
|
box-shadow: var(--icen-ring);
|
|
6692
9448
|
}
|
|
6693
|
-
.carousel-dot.active,
|
|
9449
|
+
.carousel-dot.is-active,
|
|
6694
9450
|
.carousel-dot[aria-current='true'] {
|
|
6695
9451
|
width: 20px;
|
|
6696
9452
|
background: var(--token-accent);
|
|
@@ -6706,7 +9462,7 @@ html {
|
|
|
6706
9462
|
transition: width var(--icen-tx-slow);
|
|
6707
9463
|
}
|
|
6708
9464
|
|
|
6709
|
-
/*
|
|
9465
|
+
/* 缩略图导航条(deliberate exception:隐藏滚动条是设计意图,见文件头注释) */
|
|
6710
9466
|
.carousel-thumbs {
|
|
6711
9467
|
display: flex;
|
|
6712
9468
|
gap: var(--density-space-xs);
|
|
@@ -6816,7 +9572,7 @@ html {
|
|
|
6816
9572
|
border: 1px solid var(--token-outline);
|
|
6817
9573
|
box-shadow: var(--token-shadow-overlay);
|
|
6818
9574
|
border-radius: var(--radius-lg);
|
|
6819
|
-
animation: icen-menu-in var(--icen-tx-fast);
|
|
9575
|
+
animation: icen-menu-in var(--menu-in-duration, var(--icen-tx-fast));
|
|
6820
9576
|
}
|
|
6821
9577
|
.menu[data-side='top'] { animation-name: icen-menu-in-top; }
|
|
6822
9578
|
.menu[data-side='left'] { animation-name: icen-menu-in-left; }
|
|
@@ -6827,7 +9583,7 @@ html {
|
|
|
6827
9583
|
min-width: 218px;
|
|
6828
9584
|
max-width: 286px;
|
|
6829
9585
|
z-index: var(--z-tooltip); /* 上下文菜单高于普通 popover,与 tooltip 平齐 */
|
|
6830
|
-
|
|
9586
|
+
--menu-in-duration: 100ms;
|
|
6831
9587
|
}
|
|
6832
9588
|
|
|
6833
9589
|
/* ── 分组标签 / 头(context-menu 的 header 项) ── */
|
|
@@ -7092,7 +9848,7 @@ html {
|
|
|
7092
9848
|
border: 0;
|
|
7093
9849
|
cursor: pointer;
|
|
7094
9850
|
color: var(--token-text-faint);
|
|
7095
|
-
font-size:
|
|
9851
|
+
font-size: var(--density-font-size-lg);
|
|
7096
9852
|
line-height: 1;
|
|
7097
9853
|
border-radius: var(--radius-sm);
|
|
7098
9854
|
transition:
|
|
@@ -7231,7 +9987,12 @@ html {
|
|
|
7231
9987
|
backdrop-filter: blur(12px) saturate(1.1);
|
|
7232
9988
|
-webkit-backdrop-filter: blur(12px) saturate(1.1);
|
|
7233
9989
|
border-bottom: 1px solid var(--token-outline-soft);
|
|
7234
|
-
transition:
|
|
9990
|
+
transition:
|
|
9991
|
+
background-color var(--icen-tx-slow),
|
|
9992
|
+
border-color var(--icen-tx-slow),
|
|
9993
|
+
box-shadow var(--icen-tx-slow),
|
|
9994
|
+
transform var(--icen-tx-slow),
|
|
9995
|
+
backdrop-filter var(--icen-tx-slow);
|
|
7235
9996
|
}
|
|
7236
9997
|
.nav:has(.nav-bottom) {
|
|
7237
9998
|
height: auto;
|
|
@@ -7288,6 +10049,7 @@ html {
|
|
|
7288
10049
|
.nav-bottom { width: 100%; padding-top: var(--density-space-xs); }
|
|
7289
10050
|
|
|
7290
10051
|
.nav-btn {
|
|
10052
|
+
position: relative;
|
|
7291
10053
|
display: inline-flex;
|
|
7292
10054
|
align-items: center;
|
|
7293
10055
|
gap: var(--density-space-xs);
|
|
@@ -7319,7 +10081,7 @@ html {
|
|
|
7319
10081
|
.nav-btn.is-active,
|
|
7320
10082
|
.nav-btn[aria-current='page'] {
|
|
7321
10083
|
background: var(--token-accent);
|
|
7322
|
-
color: var(--token-on-accent
|
|
10084
|
+
color: var(--token-on-accent);
|
|
7323
10085
|
font-weight: 500;
|
|
7324
10086
|
box-shadow: var(--token-shadow-elevated);
|
|
7325
10087
|
}
|
|
@@ -7389,7 +10151,7 @@ html {
|
|
|
7389
10151
|
.nav-search-kbd {
|
|
7390
10152
|
margin-left: auto;
|
|
7391
10153
|
padding: 1px 5px;
|
|
7392
|
-
font-size:
|
|
10154
|
+
font-size: var(--density-font-size-2xs);
|
|
7393
10155
|
font-family: var(--font-mono);
|
|
7394
10156
|
color: var(--token-text-faint);
|
|
7395
10157
|
background: var(--token-fill-2);
|
|
@@ -7409,14 +10171,13 @@ html {
|
|
|
7409
10171
|
border-radius: var(--radius-full);
|
|
7410
10172
|
pointer-events: none;
|
|
7411
10173
|
}
|
|
7412
|
-
.nav-btn { position: relative; }
|
|
7413
10174
|
.nav-btn-badge--count {
|
|
7414
10175
|
min-width: 16px;
|
|
7415
10176
|
height: 16px;
|
|
7416
10177
|
padding: 0 4px;
|
|
7417
|
-
font-size:
|
|
10178
|
+
font-size: var(--density-font-size-2xs);
|
|
7418
10179
|
font-weight: 700;
|
|
7419
|
-
color: var(--token-on-accent
|
|
10180
|
+
color: var(--token-on-accent);
|
|
7420
10181
|
display: inline-flex;
|
|
7421
10182
|
align-items: center;
|
|
7422
10183
|
justify-content: center;
|
|
@@ -7478,7 +10239,7 @@ html {
|
|
|
7478
10239
|
*
|
|
7479
10240
|
* 完整契约(由 behavior 渲染):
|
|
7480
10241
|
* <div class="notification-container" role="region" aria-label="通知" data-position="top-right">
|
|
7481
|
-
* <div class="notification [
|
|
10242
|
+
* <div class="notification [notification--success|warning|error|info]
|
|
7482
10243
|
* [.is-priority] [.is-unread] [.is-progress] [.is-clickable] [.is-paused]
|
|
7483
10244
|
* [.has-avatar]" role="alert|button">
|
|
7484
10245
|
* <span class="notification-icon">…svg 或 img.notification-avatar…</span>
|
|
@@ -7547,19 +10308,19 @@ html {
|
|
|
7547
10308
|
overflow: hidden; /* 倒计时进度条贴底 */
|
|
7548
10309
|
animation: icen-notif-in var(--icen-tx-normal);
|
|
7549
10310
|
}
|
|
7550
|
-
.notification.
|
|
7551
|
-
.notification.
|
|
7552
|
-
.notification.
|
|
7553
|
-
.notification.
|
|
10311
|
+
.notification.notification--success { border-left-color: var(--token-success); }
|
|
10312
|
+
.notification.notification--warning { border-left-color: var(--token-warning); }
|
|
10313
|
+
.notification.notification--error { border-left-color: var(--token-error); }
|
|
10314
|
+
.notification.notification--info { border-left-color: var(--token-info); }
|
|
7554
10315
|
|
|
7555
10316
|
/* ── 优先级:高优先级强调(左侧加粗 + 更强阴影)── */
|
|
7556
10317
|
.notification.is-priority {
|
|
7557
10318
|
border-left-width: 4px;
|
|
7558
10319
|
box-shadow: var(--token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--token-accent) 24%, transparent);
|
|
7559
10320
|
}
|
|
7560
|
-
.notification.is-priority.
|
|
7561
|
-
.notification.is-priority.
|
|
7562
|
-
.notification.is-priority.
|
|
10321
|
+
.notification.is-priority.notification--success { box-shadow: var(--token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--token-success) 28%, transparent); }
|
|
10322
|
+
.notification.is-priority.notification--warning { box-shadow: var(--token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--token-warning) 28%, transparent); }
|
|
10323
|
+
.notification.is-priority.notification--error { box-shadow: var(--token-shadow-overlay), 0 0 0 1px color-mix(in srgb, var(--token-error) 28%, transparent); }
|
|
7563
10324
|
|
|
7564
10325
|
/* ── 未读:标题左侧 4px 强调点 + 加粗 ── */
|
|
7565
10326
|
.notification.is-unread .notification-title::before {
|
|
@@ -7574,9 +10335,9 @@ html {
|
|
|
7574
10335
|
background: var(--token-accent);
|
|
7575
10336
|
flex-shrink: 0;
|
|
7576
10337
|
}
|
|
7577
|
-
.notification.is-unread.
|
|
7578
|
-
.notification.is-unread.
|
|
7579
|
-
.notification.is-unread.
|
|
10338
|
+
.notification.is-unread.notification--success .notification-title::before { background: var(--token-success); }
|
|
10339
|
+
.notification.is-unread.notification--warning .notification-title::before { background: var(--token-warning); }
|
|
10340
|
+
.notification.is-unread.notification--error .notification-title::before { background: var(--token-error); }
|
|
7580
10341
|
|
|
7581
10342
|
/* ── 可点击:整条 hover 抬升 ── */
|
|
7582
10343
|
.notification.is-clickable {
|
|
@@ -7604,10 +10365,10 @@ html {
|
|
|
7604
10365
|
color: var(--token-text-faint);
|
|
7605
10366
|
}
|
|
7606
10367
|
.notification-icon svg { width: 16px; height: 16px; }
|
|
7607
|
-
.
|
|
7608
|
-
.
|
|
7609
|
-
.
|
|
7610
|
-
.
|
|
10368
|
+
.notification--success .notification-icon { color: var(--token-success); }
|
|
10369
|
+
.notification--warning .notification-icon { color: var(--token-warning); }
|
|
10370
|
+
.notification--error .notification-icon { color: var(--token-error); }
|
|
10371
|
+
.notification--info .notification-icon { color: var(--token-info); }
|
|
7611
10372
|
|
|
7612
10373
|
/* 头像(圆形图) */
|
|
7613
10374
|
.notification-avatar {
|
|
@@ -7624,7 +10385,7 @@ html {
|
|
|
7624
10385
|
}
|
|
7625
10386
|
|
|
7626
10387
|
/* 进度通知的图标默认走品牌色 */
|
|
7627
|
-
.notification.is-progress:not(.
|
|
10388
|
+
.notification.is-progress:not(.notification--success):not(.notification--warning):not(.notification--error) .notification-icon {
|
|
7628
10389
|
color: var(--token-accent);
|
|
7629
10390
|
}
|
|
7630
10391
|
|
|
@@ -7690,23 +10451,23 @@ html {
|
|
|
7690
10451
|
/* primary:实底 accent */
|
|
7691
10452
|
.notification-action--primary {
|
|
7692
10453
|
background: var(--token-accent);
|
|
7693
|
-
color: var(--token-on-accent
|
|
10454
|
+
color: var(--token-on-accent);
|
|
7694
10455
|
border-color: var(--token-accent);
|
|
7695
10456
|
}
|
|
7696
10457
|
.notification-action--primary:hover {
|
|
7697
10458
|
background: var(--token-accent-deep, var(--token-accent));
|
|
7698
|
-
color: var(--token-on-accent
|
|
10459
|
+
color: var(--token-on-accent);
|
|
7699
10460
|
border-color: var(--token-accent-deep, var(--token-accent));
|
|
7700
10461
|
}
|
|
7701
10462
|
/* danger:实底 error */
|
|
7702
10463
|
.notification-action--danger {
|
|
7703
10464
|
background: var(--token-error);
|
|
7704
|
-
color: var(--token-on-accent
|
|
10465
|
+
color: var(--token-on-accent);
|
|
7705
10466
|
border-color: var(--token-error);
|
|
7706
10467
|
}
|
|
7707
10468
|
.notification-action--danger:hover {
|
|
7708
10469
|
filter: brightness(0.92);
|
|
7709
|
-
color: var(--token-on-accent
|
|
10470
|
+
color: var(--token-on-accent);
|
|
7710
10471
|
border-color: var(--token-error);
|
|
7711
10472
|
}
|
|
7712
10473
|
|
|
@@ -7751,9 +10512,9 @@ html {
|
|
|
7751
10512
|
border-radius: var(--radius-full);
|
|
7752
10513
|
transition: width var(--icen-tx-normal) var(--ease-out);
|
|
7753
10514
|
}
|
|
7754
|
-
.notification.
|
|
7755
|
-
.notification.
|
|
7756
|
-
.notification.
|
|
10515
|
+
.notification.notification--success .notification-progress-bar { background: var(--token-success); }
|
|
10516
|
+
.notification.notification--warning .notification-progress-bar { background: var(--token-warning); }
|
|
10517
|
+
.notification.notification--error .notification-progress-bar { background: var(--token-error); }
|
|
7757
10518
|
.notification-progress-label {
|
|
7758
10519
|
flex: 0 0 auto;
|
|
7759
10520
|
font-size: var(--density-font-size-xs);
|
|
@@ -7809,9 +10570,9 @@ html {
|
|
|
7809
10570
|
animation-fill-mode: forwards;
|
|
7810
10571
|
animation-play-state: running;
|
|
7811
10572
|
}
|
|
7812
|
-
.notification.
|
|
7813
|
-
.notification.
|
|
7814
|
-
.notification.
|
|
10573
|
+
.notification.notification--success .notification-countdown-fill { background: var(--token-success); opacity: 0.6; }
|
|
10574
|
+
.notification.notification--warning .notification-countdown-fill { background: var(--token-warning); opacity: 0.6; }
|
|
10575
|
+
.notification.notification--error .notification-countdown-fill { background: var(--token-error); opacity: 0.6; }
|
|
7815
10576
|
.notification.is-paused .notification-countdown-fill {
|
|
7816
10577
|
animation-play-state: paused;
|
|
7817
10578
|
}
|
|
@@ -7826,7 +10587,7 @@ html {
|
|
|
7826
10587
|
}
|
|
7827
10588
|
|
|
7828
10589
|
/* ── 退场动画 ── */
|
|
7829
|
-
.notification.leaving {
|
|
10590
|
+
.notification.is-leaving {
|
|
7830
10591
|
opacity: 0;
|
|
7831
10592
|
transform: translateX(20px);
|
|
7832
10593
|
transition:
|
|
@@ -7850,7 +10611,7 @@ html {
|
|
|
7850
10611
|
|
|
7851
10612
|
@media (prefers-reduced-motion: reduce) {
|
|
7852
10613
|
.notification { animation: none; }
|
|
7853
|
-
.notification.leaving { transform: none; }
|
|
10614
|
+
.notification.is-leaving { transform: none; }
|
|
7854
10615
|
.notification-countdown-fill { animation: none; transform-origin: left; }
|
|
7855
10616
|
.notification-progress-bar { transition: none; }
|
|
7856
10617
|
}
|
|
@@ -7907,7 +10668,7 @@ html {
|
|
|
7907
10668
|
.page-btn.is-active,
|
|
7908
10669
|
.page-btn[aria-current='page'] {
|
|
7909
10670
|
background: var(--token-accent);
|
|
7910
|
-
color: var(--token-on-accent
|
|
10671
|
+
color: var(--token-on-accent);
|
|
7911
10672
|
font-weight: 500;
|
|
7912
10673
|
box-shadow: var(--token-shadow-elevated);
|
|
7913
10674
|
}
|
|
@@ -7982,8 +10743,8 @@ html {
|
|
|
7982
10743
|
* @icen.ai/ui — Component: panel(白卡片容器 + 标题栏 + 可选 footer)
|
|
7983
10744
|
*
|
|
7984
10745
|
* 完整契约:
|
|
7985
|
-
* <div class="panel
|
|
7986
|
-
* [panel
|
|
10746
|
+
* <div class="panel [panel--flush] [panel--accent]
|
|
10747
|
+
* [panel--collapsible] [.is-collapsed]">
|
|
7987
10748
|
* <div class="panel-title">
|
|
7988
10749
|
* <div class="panel-title-text">
|
|
7989
10750
|
* <span>标题</span>
|
|
@@ -8004,10 +10765,10 @@ html {
|
|
|
8004
10765
|
* --collapsible:标题栏出现展开/折叠钮(behavior 可选,也可靠纯 CSS details/summary)。
|
|
8005
10766
|
* --accent:强调色标题边。
|
|
8006
10767
|
* .panel-subtitle:标题下方的副标题/描述文字。
|
|
8007
|
-
* .panel
|
|
10768
|
+
* .panel.is-collapsed:折叠态——隐藏 body + foot。
|
|
8008
10769
|
*/
|
|
8009
10770
|
|
|
8010
|
-
.panel
|
|
10771
|
+
.panel {
|
|
8011
10772
|
background: var(--token-surface);
|
|
8012
10773
|
border: 1px solid var(--token-line-soft);
|
|
8013
10774
|
border-radius: var(--radius-lg);
|
|
@@ -8043,7 +10804,7 @@ html {
|
|
|
8043
10804
|
white-space: nowrap;
|
|
8044
10805
|
}
|
|
8045
10806
|
.panel-subtitle {
|
|
8046
|
-
font-size:
|
|
10807
|
+
font-size: var(--density-font-size-xs);
|
|
8047
10808
|
font-weight: 400;
|
|
8048
10809
|
letter-spacing: 0;
|
|
8049
10810
|
text-transform: none;
|
|
@@ -8087,19 +10848,19 @@ html {
|
|
|
8087
10848
|
height: 14px;
|
|
8088
10849
|
transition: transform var(--icen-tx-fast);
|
|
8089
10850
|
}
|
|
8090
|
-
.panel
|
|
10851
|
+
.panel.is-collapsed .panel-toggle-icon {
|
|
8091
10852
|
transform: rotate(-90deg);
|
|
8092
10853
|
}
|
|
8093
10854
|
|
|
8094
10855
|
/* ── 折叠态:隐藏 body + foot,去掉标题栏底边 ── */
|
|
8095
|
-
.panel
|
|
8096
|
-
.panel
|
|
10856
|
+
.panel.is-collapsed .panel-body,
|
|
10857
|
+
.panel.is-collapsed .panel-foot {
|
|
8097
10858
|
display: none;
|
|
8098
10859
|
}
|
|
8099
|
-
.panel
|
|
10860
|
+
.panel.is-collapsed .panel-title {
|
|
8100
10861
|
border-bottom-color: transparent;
|
|
8101
10862
|
}
|
|
8102
|
-
.panel
|
|
10863
|
+
.panel--collapsible .panel-body {
|
|
8103
10864
|
animation: panel-expand var(--icen-tx-normal) var(--ease-out);
|
|
8104
10865
|
}
|
|
8105
10866
|
@keyframes panel-expand {
|
|
@@ -8113,7 +10874,7 @@ html {
|
|
|
8113
10874
|
font-size: var(--density-font-size-md);
|
|
8114
10875
|
line-height: 1.6;
|
|
8115
10876
|
}
|
|
8116
|
-
.panel
|
|
10877
|
+
.panel--flush .panel-body { padding: 0; }
|
|
8117
10878
|
|
|
8118
10879
|
.panel-foot {
|
|
8119
10880
|
display: flex;
|
|
@@ -8126,26 +10887,26 @@ html {
|
|
|
8126
10887
|
}
|
|
8127
10888
|
|
|
8128
10889
|
/* ── 强调变体 ── */
|
|
8129
|
-
.panel
|
|
8130
|
-
.panel
|
|
10890
|
+
.panel--accent { border-color: color-mix(in srgb, var(--token-accent) 30%, transparent); }
|
|
10891
|
+
.panel--accent .panel-title {
|
|
8131
10892
|
color: var(--token-accent);
|
|
8132
10893
|
background: var(--token-accent-subtle);
|
|
8133
10894
|
}
|
|
8134
10895
|
|
|
8135
10896
|
/* ── 平面变体(无阴影,嵌套时用) ── */
|
|
8136
|
-
.panel
|
|
10897
|
+
.panel--flat {
|
|
8137
10898
|
box-shadow: none;
|
|
8138
10899
|
background: var(--token-bg-soft);
|
|
8139
10900
|
}
|
|
8140
10901
|
|
|
8141
10902
|
/* ── 可折叠模式:标题栏可点(纯 CSS 方案用 details/summary) ── */
|
|
8142
|
-
.panel
|
|
10903
|
+
.panel--collapsible .panel-title {
|
|
8143
10904
|
cursor: pointer;
|
|
8144
10905
|
}
|
|
8145
10906
|
|
|
8146
10907
|
@media (prefers-reduced-motion: reduce) {
|
|
8147
10908
|
.panel-toggle-icon { transition: none; }
|
|
8148
|
-
.panel
|
|
10909
|
+
.panel--collapsible .panel-body { animation: none; }
|
|
8149
10910
|
}
|
|
8150
10911
|
|
|
8151
10912
|
|
|
@@ -8154,7 +10915,7 @@ html {
|
|
|
8154
10915
|
* @icen.ai/ui — Component: pill(状态徽章 / tag)
|
|
8155
10916
|
*
|
|
8156
10917
|
* 完整契约:
|
|
8157
|
-
* <span class="pill [
|
|
10918
|
+
* <span class="pill [pill--success|pill--warning|pill--error|pill--info|pill--accent] [.pill--dot|pill--outline|pill--sm]">文本</span>
|
|
8158
10919
|
*
|
|
8159
10920
|
* 语义色纪律:仅绿/黄/红/信息 + 品牌 accent。
|
|
8160
10921
|
* --dot:左侧加状态色圆点;--outline:透明底、纯描边;--sm:紧凑尺寸。
|
|
@@ -8176,27 +10937,27 @@ html {
|
|
|
8176
10937
|
vertical-align: middle;
|
|
8177
10938
|
}
|
|
8178
10939
|
|
|
8179
|
-
.pill
|
|
10940
|
+
.pill--success {
|
|
8180
10941
|
color: var(--token-success);
|
|
8181
10942
|
border-color: color-mix(in srgb, var(--token-success) 35%, transparent);
|
|
8182
10943
|
background: color-mix(in srgb, var(--token-success) 9%, transparent);
|
|
8183
10944
|
}
|
|
8184
|
-
.pill
|
|
10945
|
+
.pill--warning {
|
|
8185
10946
|
color: var(--token-warning);
|
|
8186
10947
|
border-color: color-mix(in srgb, var(--token-warning) 35%, transparent);
|
|
8187
10948
|
background: color-mix(in srgb, var(--token-warning) 9%, transparent);
|
|
8188
10949
|
}
|
|
8189
|
-
.pill
|
|
10950
|
+
.pill--error {
|
|
8190
10951
|
color: var(--token-error);
|
|
8191
10952
|
border-color: color-mix(in srgb, var(--token-error) 35%, transparent);
|
|
8192
10953
|
background: color-mix(in srgb, var(--token-error) 9%, transparent);
|
|
8193
10954
|
}
|
|
8194
|
-
.pill
|
|
10955
|
+
.pill--accent {
|
|
8195
10956
|
color: var(--token-accent-deep, var(--token-accent));
|
|
8196
10957
|
border-color: color-mix(in srgb, var(--token-accent) 40%, transparent);
|
|
8197
10958
|
background: color-mix(in srgb, var(--token-accent) 9%, transparent);
|
|
8198
10959
|
}
|
|
8199
|
-
.pill
|
|
10960
|
+
.pill--info {
|
|
8200
10961
|
color: var(--token-info);
|
|
8201
10962
|
border-color: color-mix(in srgb, var(--token-info) 35%, transparent);
|
|
8202
10963
|
background: color-mix(in srgb, var(--token-info) 9%, transparent);
|
|
@@ -8221,7 +10982,7 @@ html {
|
|
|
8221
10982
|
/* 尺寸变体 */
|
|
8222
10983
|
.pill--sm {
|
|
8223
10984
|
padding: 1px var(--density-space-xs);
|
|
8224
|
-
font-size:
|
|
10985
|
+
font-size: var(--density-font-size-2xs);
|
|
8225
10986
|
}
|
|
8226
10987
|
.pill--lg {
|
|
8227
10988
|
padding: 4px calc(var(--density-space-sm) + 2px);
|
|
@@ -8231,13 +10992,13 @@ html {
|
|
|
8231
10992
|
/* 实色变体:accent 实底(用于 count、活跃状态等强调场景) */
|
|
8232
10993
|
.pill--solid {
|
|
8233
10994
|
background: var(--token-accent);
|
|
8234
|
-
color: var(--token-on-accent
|
|
10995
|
+
color: var(--token-on-accent);
|
|
8235
10996
|
border-color: var(--token-accent);
|
|
8236
10997
|
}
|
|
8237
|
-
.pill--solid.
|
|
8238
|
-
.pill--solid.
|
|
8239
|
-
.pill--solid.
|
|
8240
|
-
.pill--solid.info
|
|
10998
|
+
.pill--solid.pill--success { background: var(--token-success); border-color: var(--token-success); }
|
|
10999
|
+
.pill--solid.pill--warning { background: var(--token-warning); border-color: var(--token-warning); }
|
|
11000
|
+
.pill--solid.pill--error { background: var(--token-error); border-color: var(--token-error); }
|
|
11001
|
+
.pill--solid.pill--info { background: var(--token-info); border-color: var(--token-info); }
|
|
8241
11002
|
|
|
8242
11003
|
/* ── 增强 ── */
|
|
8243
11004
|
|
|
@@ -8278,7 +11039,7 @@ html {
|
|
|
8278
11039
|
border-radius: var(--radius-full);
|
|
8279
11040
|
background: currentColor;
|
|
8280
11041
|
margin-right: 2px;
|
|
8281
|
-
animation: pill-pulse 1.5s ease-in-out infinite;
|
|
11042
|
+
animation: pill-pulse var(--pill-pulse-duration, 1.5s) ease-in-out infinite;
|
|
8282
11043
|
}
|
|
8283
11044
|
@keyframes pill-pulse {
|
|
8284
11045
|
0%, 100% { opacity: 1; transform: scale(1); }
|
|
@@ -8291,7 +11052,7 @@ html {
|
|
|
8291
11052
|
height: 18px;
|
|
8292
11053
|
padding: 0 5px;
|
|
8293
11054
|
justify-content: center;
|
|
8294
|
-
font-size:
|
|
11055
|
+
font-size: var(--density-font-size-2xs);
|
|
8295
11056
|
font-weight: 700;
|
|
8296
11057
|
font-variant-numeric: tabular-nums;
|
|
8297
11058
|
line-height: 1;
|
|
@@ -8300,7 +11061,7 @@ html {
|
|
|
8300
11061
|
/* 渐变变体 */
|
|
8301
11062
|
.pill--gradient {
|
|
8302
11063
|
background: linear-gradient(135deg, var(--token-accent), var(--token-accent-deep, var(--token-accent)));
|
|
8303
|
-
color: var(--token-on-accent
|
|
11064
|
+
color: var(--token-on-accent);
|
|
8304
11065
|
border-color: transparent;
|
|
8305
11066
|
}
|
|
8306
11067
|
|
|
@@ -8630,7 +11391,7 @@ html {
|
|
|
8630
11391
|
.segmented-item.is-active,
|
|
8631
11392
|
.segmented-item[aria-checked='true'] {
|
|
8632
11393
|
background: var(--token-accent);
|
|
8633
|
-
color: var(--token-on-accent
|
|
11394
|
+
color: var(--token-on-accent);
|
|
8634
11395
|
box-shadow: var(--token-shadow-elevated);
|
|
8635
11396
|
}
|
|
8636
11397
|
.segmented-item:disabled,
|
|
@@ -8688,7 +11449,7 @@ html {
|
|
|
8688
11449
|
.toggle-item.is-active,
|
|
8689
11450
|
.toggle-item[aria-checked='true'] {
|
|
8690
11451
|
background: var(--token-accent);
|
|
8691
|
-
color: var(--token-on-accent
|
|
11452
|
+
color: var(--token-on-accent);
|
|
8692
11453
|
box-shadow: var(--token-shadow-card);
|
|
8693
11454
|
}
|
|
8694
11455
|
.toggle-item:disabled,
|
|
@@ -8739,7 +11500,7 @@ html {
|
|
|
8739
11500
|
}
|
|
8740
11501
|
.stepper-btn:focus-visible {
|
|
8741
11502
|
outline: none;
|
|
8742
|
-
box-shadow:
|
|
11503
|
+
box-shadow: var(--icen-ring-inset);
|
|
8743
11504
|
}
|
|
8744
11505
|
.stepper-btn:disabled,
|
|
8745
11506
|
.stepper-btn[aria-disabled='true'] {
|
|
@@ -8783,7 +11544,7 @@ html {
|
|
|
8783
11544
|
height: 48px;
|
|
8784
11545
|
padding: 0;
|
|
8785
11546
|
text-align: center;
|
|
8786
|
-
font-size:
|
|
11547
|
+
font-size: var(--density-font-size-xl);
|
|
8787
11548
|
font-weight: 600;
|
|
8788
11549
|
font-family: var(--font-mono);
|
|
8789
11550
|
color: var(--token-text);
|
|
@@ -8812,7 +11573,7 @@ html {
|
|
|
8812
11573
|
cursor: not-allowed;
|
|
8813
11574
|
}
|
|
8814
11575
|
.otp--sm .otp-cell { width: 32px; height: 40px; font-size: var(--density-font-size-lg); }
|
|
8815
|
-
.otp--lg .otp-cell { width: 48px; height: 56px; font-size:
|
|
11576
|
+
.otp--lg .otp-cell { width: 48px; height: 56px; font-size: var(--density-font-size-2xl); }
|
|
8816
11577
|
|
|
8817
11578
|
@media (prefers-reduced-motion: reduce) {
|
|
8818
11579
|
.segmented-item, .toggle-item, .stepper-btn, .stepper, .otp-cell { transition: none; }
|
|
@@ -8923,7 +11684,8 @@ html {
|
|
|
8923
11684
|
* </div>
|
|
8924
11685
|
*
|
|
8925
11686
|
* behavior 维护:
|
|
8926
|
-
* - .select.is-open ↔ aria-expanded;panel
|
|
11687
|
+
* - .select.is-open ↔ aria-expanded;panel portal 到 body(inline left/top/width/max-height,
|
|
11688
|
+
* 带 data-side="top|bottom";多选时带 data-select-multiple);ESC/外部点击关闭
|
|
8927
11689
|
* - 选项 .is-focused 跟随键盘箭头;Enter 选中 → 写回 .select-value / .is-selected
|
|
8928
11690
|
* - data-select-search:面板顶部自动插入搜索框,实时过滤(含 data-keywords),空分组自动隐藏
|
|
8929
11691
|
* - data-select-multiple:点击切选不关面板,trigger 显示计数,hidden input 同步逗号分隔值
|
|
@@ -8932,7 +11694,6 @@ html {
|
|
|
8932
11694
|
.select {
|
|
8933
11695
|
position: relative;
|
|
8934
11696
|
width: 100%;
|
|
8935
|
-
isolation: isolate; /* panel 不被后面兄弟节点的层叠遮挡 */
|
|
8936
11697
|
}
|
|
8937
11698
|
|
|
8938
11699
|
.select-trigger {
|
|
@@ -9002,12 +11763,11 @@ html {
|
|
|
9002
11763
|
}
|
|
9003
11764
|
.select.is-open .select-chevron { transform: rotate(180deg); }
|
|
9004
11765
|
|
|
11766
|
+
/* 面板由 behavior portal 到 body:left/top/width/max-height 由 JS 按 trigger rect inline 写入;
|
|
11767
|
+
data-side="top|bottom" 标记翻侧方向;多选时 panel 带 data-select-multiple 属性。 */
|
|
9005
11768
|
.select-panel {
|
|
9006
11769
|
position: absolute;
|
|
9007
|
-
|
|
9008
|
-
left: 0;
|
|
9009
|
-
min-width: 100%;
|
|
9010
|
-
max-height: 240px;
|
|
11770
|
+
z-index: var(--z-popover);
|
|
9011
11771
|
overflow-y: auto;
|
|
9012
11772
|
overscroll-behavior: contain;
|
|
9013
11773
|
padding: 4px;
|
|
@@ -9015,17 +11775,10 @@ html {
|
|
|
9015
11775
|
border: 1px solid var(--token-outline);
|
|
9016
11776
|
border-radius: var(--radius-md);
|
|
9017
11777
|
box-shadow: var(--token-shadow-overlay);
|
|
9018
|
-
z-index: var(--z-popover);
|
|
9019
11778
|
transform-origin: top center;
|
|
9020
|
-
animation:
|
|
9021
|
-
}
|
|
9022
|
-
@keyframes select-panel-in {
|
|
9023
|
-
from { opacity: 0; transform: scale(0.96) translateY(-4px); }
|
|
9024
|
-
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
9025
|
-
}
|
|
9026
|
-
@media (prefers-reduced-motion: reduce) {
|
|
9027
|
-
.select-panel { animation: none; }
|
|
11779
|
+
animation: icen-pop-in var(--icen-tx-fast);
|
|
9028
11780
|
}
|
|
11781
|
+
.select-panel[data-side='top'] { transform-origin: bottom center; }
|
|
9029
11782
|
|
|
9030
11783
|
/* 选项 */
|
|
9031
11784
|
.select-option {
|
|
@@ -9127,7 +11880,7 @@ html {
|
|
|
9127
11880
|
border-radius: var(--radius-xs);
|
|
9128
11881
|
background: transparent;
|
|
9129
11882
|
color: var(--token-text-faint);
|
|
9130
|
-
font-size:
|
|
11883
|
+
font-size: var(--density-font-size-lg);
|
|
9131
11884
|
line-height: 1;
|
|
9132
11885
|
cursor: pointer;
|
|
9133
11886
|
transition: color var(--icen-tx-fast), background-color var(--icen-tx-fast);
|
|
@@ -9146,8 +11899,8 @@ html {
|
|
|
9146
11899
|
flex-wrap: wrap;
|
|
9147
11900
|
}
|
|
9148
11901
|
|
|
9149
|
-
/* 多选项 checkbox
|
|
9150
|
-
.select[data-select-multiple] .select-option::before {
|
|
11902
|
+
/* 多选项 checkbox 指示器(选项左侧;panel portal 到 body,属性在 panel 上) */
|
|
11903
|
+
.select-panel[data-select-multiple] .select-option::before {
|
|
9151
11904
|
content: '';
|
|
9152
11905
|
width: 14px;
|
|
9153
11906
|
height: 14px;
|
|
@@ -9156,11 +11909,11 @@ html {
|
|
|
9156
11909
|
border-radius: var(--radius-xs);
|
|
9157
11910
|
transition: background-color var(--icen-tx-fast), border-color var(--icen-tx-fast);
|
|
9158
11911
|
}
|
|
9159
|
-
.select[data-select-multiple] .select-option.is-selected::before {
|
|
11912
|
+
.select-panel[data-select-multiple] .select-option.is-selected::before {
|
|
9160
11913
|
background: var(--token-accent);
|
|
9161
11914
|
border-color: var(--token-accent);
|
|
9162
11915
|
}
|
|
9163
|
-
.select[data-select-multiple] .select-option.is-selected::after {
|
|
11916
|
+
.select-panel[data-select-multiple] .select-option.is-selected::after {
|
|
9164
11917
|
content: '✓';
|
|
9165
11918
|
margin-left: auto;
|
|
9166
11919
|
}
|
|
@@ -9345,7 +12098,7 @@ html {
|
|
|
9345
12098
|
padding: 0 5px;
|
|
9346
12099
|
font-size: var(--density-font-size-xs);
|
|
9347
12100
|
font-weight: 600;
|
|
9348
|
-
color: var(--token-on-accent
|
|
12101
|
+
color: var(--token-on-accent);
|
|
9349
12102
|
background: var(--token-accent);
|
|
9350
12103
|
border-radius: var(--radius-full);
|
|
9351
12104
|
font-variant-numeric: tabular-nums;
|
|
@@ -9883,7 +12636,6 @@ html {
|
|
|
9883
12636
|
}
|
|
9884
12637
|
.split-pane--vertical .split-pane-first {
|
|
9885
12638
|
flex: 0 0 var(--split, 50%);
|
|
9886
|
-
flex-basis: var(--split, 50%);
|
|
9887
12639
|
min-height: 0;
|
|
9888
12640
|
}
|
|
9889
12641
|
.split-pane--vertical .split-pane-second {
|
|
@@ -9922,10 +12674,10 @@ html {
|
|
|
9922
12674
|
* <div class="stat-card [.stat-card--interactive] [.stat-card--horizontal]">
|
|
9923
12675
|
* <div class="stat-head">
|
|
9924
12676
|
* <span class="stat-label">用户总数</span>
|
|
9925
|
-
* <span class="stat-icon [.icon--
|
|
12677
|
+
* <span class="stat-icon [.icon--success|.icon--warning|.icon--error|.icon--info]>…svg…</span>
|
|
9926
12678
|
* </div>
|
|
9927
12679
|
* <div class="stat-body">
|
|
9928
|
-
* <div class="stat-num [
|
|
12680
|
+
* <div class="stat-num [--accent|--warning|--error|--info]">0</div>
|
|
9929
12681
|
* <div class="stat-delta [.up|.down|.flat]"> ← 可选趋势
|
|
9930
12682
|
* <svg>…arrow…</svg> +12.4%
|
|
9931
12683
|
* <span class="stat-period">比上周</span>
|
|
@@ -10001,10 +12753,10 @@ html {
|
|
|
10001
12753
|
background: var(--token-accent-subtle);
|
|
10002
12754
|
color: var(--token-accent);
|
|
10003
12755
|
}
|
|
10004
|
-
.stat-icon.icon--
|
|
10005
|
-
.stat-icon.icon--
|
|
10006
|
-
.stat-icon.icon--
|
|
10007
|
-
.stat-icon.icon--info
|
|
12756
|
+
.stat-icon.icon--success { background: color-mix(in srgb, var(--token-success) 14%, transparent); color: var(--token-success); }
|
|
12757
|
+
.stat-icon.icon--warning { background: color-mix(in srgb, var(--token-warning) 14%, transparent); color: var(--token-warning); }
|
|
12758
|
+
.stat-icon.icon--error { background: color-mix(in srgb, var(--token-error) 14%, transparent); color: var(--token-error); }
|
|
12759
|
+
.stat-icon.icon--info { background: color-mix(in srgb, var(--token-info) 14%, transparent); color: var(--token-info); }
|
|
10008
12760
|
.stat-icon svg { width: 14px; height: 14px; }
|
|
10009
12761
|
|
|
10010
12762
|
/* ── 内容体(数字 + 趋势) ── */
|
|
@@ -10015,17 +12767,17 @@ html {
|
|
|
10015
12767
|
}
|
|
10016
12768
|
|
|
10017
12769
|
.stat-num {
|
|
10018
|
-
font-size:
|
|
12770
|
+
font-size: var(--density-font-size-2xl);
|
|
10019
12771
|
font-weight: 700;
|
|
10020
12772
|
line-height: 1.2;
|
|
10021
12773
|
font-variant-numeric: tabular-nums lining-nums;
|
|
10022
12774
|
color: var(--token-text);
|
|
10023
12775
|
word-break: break-all;
|
|
10024
12776
|
}
|
|
10025
|
-
.stat-num
|
|
10026
|
-
.stat-num
|
|
10027
|
-
.stat-num
|
|
10028
|
-
.stat-num
|
|
12777
|
+
.stat-num--accent { color: var(--token-accent); }
|
|
12778
|
+
.stat-num--warning { color: var(--token-warning); }
|
|
12779
|
+
.stat-num--error { color: var(--token-error); }
|
|
12780
|
+
.stat-num--info { color: var(--token-info); }
|
|
10029
12781
|
|
|
10030
12782
|
.stat-delta {
|
|
10031
12783
|
display: inline-flex;
|
|
@@ -10050,7 +12802,7 @@ html {
|
|
|
10050
12802
|
gap: 2px;
|
|
10051
12803
|
}
|
|
10052
12804
|
.stat-card--sm .stat-num { font-size: var(--density-font-size-lg); }
|
|
10053
|
-
.stat-card--sm .stat-label { font-size:
|
|
12805
|
+
.stat-card--sm .stat-label { font-size: var(--density-font-size-2xs); }
|
|
10054
12806
|
|
|
10055
12807
|
/* ── 横向布局(dashboard 顶栏:标签左 + 数字右) ── */
|
|
10056
12808
|
.stat-card--horizontal {
|
|
@@ -10131,20 +12883,16 @@ html {
|
|
|
10131
12883
|
margin: 0 1px;
|
|
10132
12884
|
}
|
|
10133
12885
|
|
|
10134
|
-
/* ──
|
|
12886
|
+
/* ── 加载态骨架(脉冲 keyframes 见 base.css 的 icen-skeleton-pulse) ── */
|
|
10135
12887
|
.stat-card.is-loading .stat-num,
|
|
10136
12888
|
.stat-card.is-loading .stat-delta {
|
|
10137
12889
|
color: transparent;
|
|
10138
12890
|
background: var(--token-fill-2);
|
|
10139
12891
|
border-radius: var(--radius-xs);
|
|
10140
|
-
animation: stat-skeleton 1.5s ease-in-out infinite;
|
|
12892
|
+
animation: icen-skeleton-pulse var(--stat-skeleton-duration, 1.5s) ease-in-out infinite;
|
|
10141
12893
|
}
|
|
10142
12894
|
.stat-card.is-loading .stat-num { height: 28px; }
|
|
10143
12895
|
.stat-card.is-loading .stat-delta { height: 14px; width: 60%; }
|
|
10144
|
-
@keyframes stat-skeleton {
|
|
10145
|
-
0%, 100% { opacity: 1; }
|
|
10146
|
-
50% { opacity: 0.5; }
|
|
10147
|
-
}
|
|
10148
12896
|
@media (prefers-reduced-motion: reduce) {
|
|
10149
12897
|
.stat-card.is-loading .stat-num,
|
|
10150
12898
|
.stat-card.is-loading .stat-delta { animation: none; }
|
|
@@ -10216,7 +12964,7 @@ html {
|
|
|
10216
12964
|
}
|
|
10217
12965
|
.step--finish .step-dot {
|
|
10218
12966
|
background: var(--token-accent);
|
|
10219
|
-
color: var(--token-on-accent
|
|
12967
|
+
color: var(--token-on-accent);
|
|
10220
12968
|
}
|
|
10221
12969
|
.step--process .step-dot {
|
|
10222
12970
|
background: var(--token-accent-subtle);
|
|
@@ -10307,7 +13055,7 @@ html {
|
|
|
10307
13055
|
width: 16px;
|
|
10308
13056
|
height: 16px;
|
|
10309
13057
|
}
|
|
10310
|
-
.step--finish .step-dot-icon { color: var(--token-on-accent
|
|
13058
|
+
.step--finish .step-dot-icon { color: var(--token-on-accent); }
|
|
10311
13059
|
.step--process .step-dot-icon { color: var(--token-accent); }
|
|
10312
13060
|
.step--wait .step-dot-icon { color: var(--token-text-faint); }
|
|
10313
13061
|
.step--error .step-dot-icon { color: var(--token-error); }
|
|
@@ -10449,8 +13197,8 @@ html {
|
|
|
10449
13197
|
width: var(--switch-thumb);
|
|
10450
13198
|
height: var(--switch-thumb);
|
|
10451
13199
|
border-radius: var(--radius-full);
|
|
10452
|
-
background: var(--token-on-accent
|
|
10453
|
-
box-shadow: 0 1px 2px
|
|
13200
|
+
background: var(--token-on-accent);
|
|
13201
|
+
box-shadow: 0 1px 2px color-mix(in srgb, var(--token-text) 15%, transparent);
|
|
10454
13202
|
transition: transform var(--icen-tx-bounce);
|
|
10455
13203
|
}
|
|
10456
13204
|
.switch[aria-checked='true'] .switch-thumb {
|
|
@@ -10461,10 +13209,6 @@ html {
|
|
|
10461
13209
|
.switch--sm { --switch-w: 36px; --switch-h: 20px; --switch-thumb: 16px; }
|
|
10462
13210
|
.switch--lg { --switch-w: 56px; --switch-h: 28px; --switch-thumb: 24px; }
|
|
10463
13211
|
|
|
10464
|
-
@media (prefers-reduced-motion: reduce) {
|
|
10465
|
-
.switch-thumb { transition: none; }
|
|
10466
|
-
}
|
|
10467
|
-
|
|
10468
13212
|
/* ── 勾选框(✓ 与半选横条均 ::before 自绘) ── */
|
|
10469
13213
|
.checkbox {
|
|
10470
13214
|
--checkbox-size: 16px;
|
|
@@ -10494,7 +13238,7 @@ html {
|
|
|
10494
13238
|
.checkbox[aria-checked='mixed'] {
|
|
10495
13239
|
background: var(--token-accent);
|
|
10496
13240
|
border-color: var(--token-accent);
|
|
10497
|
-
color: var(--token-on-accent
|
|
13241
|
+
color: var(--token-on-accent);
|
|
10498
13242
|
}
|
|
10499
13243
|
.checkbox::before {
|
|
10500
13244
|
content: '';
|
|
@@ -10614,7 +13358,7 @@ html {
|
|
|
10614
13358
|
display: flex;
|
|
10615
13359
|
align-items: center;
|
|
10616
13360
|
justify-content: center;
|
|
10617
|
-
font-size:
|
|
13361
|
+
font-size: var(--density-font-size-2xs);
|
|
10618
13362
|
font-weight: 700;
|
|
10619
13363
|
color: transparent;
|
|
10620
13364
|
}
|
|
@@ -10624,9 +13368,9 @@ html {
|
|
|
10624
13368
|
left: 6px;
|
|
10625
13369
|
top: 50%;
|
|
10626
13370
|
transform: translateY(-50%);
|
|
10627
|
-
font-size:
|
|
13371
|
+
font-size: var(--density-font-size-2xs);
|
|
10628
13372
|
font-weight: 700;
|
|
10629
|
-
color: var(--token-on-accent
|
|
13373
|
+
color: var(--token-on-accent);
|
|
10630
13374
|
}
|
|
10631
13375
|
.switch--text[aria-checked='false']::before {
|
|
10632
13376
|
content: 'OFF';
|
|
@@ -10634,7 +13378,7 @@ html {
|
|
|
10634
13378
|
right: 6px;
|
|
10635
13379
|
top: 50%;
|
|
10636
13380
|
transform: translateY(-50%);
|
|
10637
|
-
font-size:
|
|
13381
|
+
font-size: var(--density-font-size-2xs);
|
|
10638
13382
|
font-weight: 700;
|
|
10639
13383
|
color: var(--token-text-faint);
|
|
10640
13384
|
}
|
|
@@ -10694,7 +13438,7 @@ html {
|
|
|
10694
13438
|
background-color var(--icen-tx-fast);
|
|
10695
13439
|
}
|
|
10696
13440
|
.radio-card:hover {
|
|
10697
|
-
border-color: var(--
|
|
13441
|
+
border-color: var(--icen-hover-border);
|
|
10698
13442
|
}
|
|
10699
13443
|
.radio-card-head {
|
|
10700
13444
|
display: flex;
|
|
@@ -10750,7 +13494,7 @@ html {
|
|
|
10750
13494
|
*
|
|
10751
13495
|
* 完整契约:
|
|
10752
13496
|
* <div class="table-wrap [table-wrap--bordered]">
|
|
10753
|
-
* <table class="
|
|
13497
|
+
* <table class="table [--zebra|--compact|--dense] [--sticky-col]">
|
|
10754
13498
|
* <caption class="table-caption">标题说明</caption> ← 可选
|
|
10755
13499
|
* <thead>
|
|
10756
13500
|
* <tr><th [colspan=rowspan] [data-sort]>列名</th>…</tr>
|
|
@@ -10770,9 +13514,9 @@ html {
|
|
|
10770
13514
|
* </div>
|
|
10771
13515
|
*
|
|
10772
13516
|
* .table-wrap:窄屏横向滚动(滚动条样式见 base.css);--bordered 加外边框。
|
|
10773
|
-
* .
|
|
10774
|
-
* .
|
|
10775
|
-
* .
|
|
13517
|
+
* .table--zebra:斑马纹(奇数行底色)。
|
|
13518
|
+
* .table--compact:紧凑(cell padding 缩小);--dense:极紧凑(行高更紧)。
|
|
13519
|
+
* .table--sticky-col:首列水平粘滞(配合 td/th .col-fixed,长表横向滚动时保持可见)。
|
|
10776
13520
|
* .row-expand[hidden]:配合 .row-link.is-expanded 控制展开行显隐。
|
|
10777
13521
|
*/
|
|
10778
13522
|
|
|
@@ -10785,18 +13529,18 @@ html {
|
|
|
10785
13529
|
border: 1px solid var(--token-line-soft);
|
|
10786
13530
|
}
|
|
10787
13531
|
|
|
10788
|
-
.
|
|
13532
|
+
.table {
|
|
10789
13533
|
width: 100%;
|
|
10790
13534
|
border-collapse: collapse;
|
|
10791
13535
|
font-size: var(--density-font-size-md);
|
|
10792
13536
|
font-variant-numeric: tabular-nums;
|
|
10793
13537
|
}
|
|
10794
|
-
.
|
|
10795
|
-
.
|
|
13538
|
+
.table th,
|
|
13539
|
+
.table td {
|
|
10796
13540
|
padding: var(--density-space-sm) calc(var(--density-space-md) + 2px);
|
|
10797
13541
|
text-align: left;
|
|
10798
13542
|
}
|
|
10799
|
-
.
|
|
13543
|
+
.table th {
|
|
10800
13544
|
font-weight: 600;
|
|
10801
13545
|
font-size: var(--density-font-size-xs);
|
|
10802
13546
|
letter-spacing: 0.05em;
|
|
@@ -10807,27 +13551,27 @@ html {
|
|
|
10807
13551
|
background: var(--token-bg-soft);
|
|
10808
13552
|
position: sticky;
|
|
10809
13553
|
top: 0;
|
|
10810
|
-
z-index:
|
|
13554
|
+
z-index: var(--z-raised);
|
|
10811
13555
|
}
|
|
10812
|
-
.
|
|
13556
|
+
.table td {
|
|
10813
13557
|
border-bottom: 1px solid var(--token-line-soft);
|
|
10814
13558
|
vertical-align: middle;
|
|
10815
13559
|
color: var(--token-text);
|
|
10816
13560
|
}
|
|
10817
|
-
.
|
|
10818
|
-
.
|
|
13561
|
+
.table tbody tr:last-child td { border-bottom: 0; }
|
|
13562
|
+
.table tbody tr {
|
|
10819
13563
|
transition: background-color var(--icen-tx-fast);
|
|
10820
13564
|
}
|
|
10821
|
-
.
|
|
13565
|
+
.table tbody tr:hover {
|
|
10822
13566
|
background: var(--token-surface-strong);
|
|
10823
13567
|
}
|
|
10824
|
-
.
|
|
13568
|
+
.table tbody tr.row-link {
|
|
10825
13569
|
cursor: pointer;
|
|
10826
13570
|
}
|
|
10827
|
-
.
|
|
13571
|
+
.table tbody tr.is-selected {
|
|
10828
13572
|
background: var(--token-accent-subtle);
|
|
10829
13573
|
}
|
|
10830
|
-
.
|
|
13574
|
+
.table tfoot td {
|
|
10831
13575
|
border-top: 1px solid var(--token-line);
|
|
10832
13576
|
border-bottom: 0;
|
|
10833
13577
|
font-weight: 500;
|
|
@@ -10835,51 +13579,50 @@ html {
|
|
|
10835
13579
|
}
|
|
10836
13580
|
|
|
10837
13581
|
/* 紧凑变体 */
|
|
10838
|
-
.
|
|
10839
|
-
.
|
|
13582
|
+
.table--compact th,
|
|
13583
|
+
.table--compact td {
|
|
10840
13584
|
padding: var(--density-space-xs) var(--density-space-sm);
|
|
10841
13585
|
}
|
|
10842
|
-
.
|
|
10843
|
-
.
|
|
13586
|
+
.table--dense th,
|
|
13587
|
+
.table--dense td {
|
|
10844
13588
|
padding: 4px var(--density-space-xs);
|
|
10845
13589
|
font-size: var(--density-font-size-sm);
|
|
10846
13590
|
}
|
|
10847
13591
|
|
|
10848
13592
|
/* 右对齐数字列 */
|
|
10849
|
-
.
|
|
13593
|
+
.table td.num {
|
|
10850
13594
|
text-align: right;
|
|
10851
13595
|
font-variant-numeric: tabular-nums lining-nums;
|
|
10852
13596
|
}
|
|
10853
13597
|
|
|
10854
|
-
/*
|
|
10855
|
-
.
|
|
13598
|
+
/* 操作列(.btn-sm 必伴 .btn,无需单独列) */
|
|
13599
|
+
.table .ops {
|
|
10856
13600
|
white-space: nowrap;
|
|
10857
13601
|
text-align: right;
|
|
10858
13602
|
}
|
|
10859
|
-
.
|
|
10860
|
-
.admin-table .ops .btn-sm {
|
|
13603
|
+
.table .ops .btn {
|
|
10861
13604
|
margin-left: var(--density-space-xs);
|
|
10862
13605
|
}
|
|
10863
13606
|
|
|
10864
13607
|
/* 可排序表头(使用方 data-sort 指示) */
|
|
10865
|
-
.
|
|
13608
|
+
.table th[data-sort] {
|
|
10866
13609
|
cursor: pointer;
|
|
10867
13610
|
user-select: none;
|
|
10868
13611
|
}
|
|
10869
|
-
.
|
|
13612
|
+
.table th[data-sort]::after {
|
|
10870
13613
|
content: '↕';
|
|
10871
13614
|
margin-left: var(--density-space-xs);
|
|
10872
13615
|
color: var(--token-text-faint);
|
|
10873
13616
|
opacity: 0.6;
|
|
10874
13617
|
}
|
|
10875
|
-
.
|
|
10876
|
-
.
|
|
13618
|
+
.table th[data-sort='asc']::after { content: '↑'; opacity: 1; color: var(--token-accent); }
|
|
13619
|
+
.table th[data-sort='desc']::after { content: '↓'; opacity: 1; color: var(--token-accent); }
|
|
10877
13620
|
|
|
10878
13621
|
/* ── 斑马纹 ── */
|
|
10879
|
-
.
|
|
13622
|
+
.table--zebra tbody tr:nth-child(odd) {
|
|
10880
13623
|
background: color-mix(in srgb, var(--token-bg-soft) 50%, transparent);
|
|
10881
13624
|
}
|
|
10882
|
-
.
|
|
13625
|
+
.table--zebra tbody tr:hover {
|
|
10883
13626
|
background: var(--token-surface-strong);
|
|
10884
13627
|
}
|
|
10885
13628
|
|
|
@@ -10894,30 +13637,30 @@ html {
|
|
|
10894
13637
|
}
|
|
10895
13638
|
|
|
10896
13639
|
/* ── 首列粘滞(长表横向滚动时保持可见) ── */
|
|
10897
|
-
.
|
|
10898
|
-
.
|
|
13640
|
+
.table--sticky-col th:first-child,
|
|
13641
|
+
.table--sticky-col .col-fixed {
|
|
10899
13642
|
position: sticky;
|
|
10900
13643
|
left: 0;
|
|
10901
|
-
z-index:
|
|
13644
|
+
z-index: calc(var(--z-raised) + 1);
|
|
10902
13645
|
background: var(--token-bg-soft);
|
|
10903
|
-
box-shadow: 2px 0 4px color-mix(in srgb, var(--token-
|
|
13646
|
+
box-shadow: 2px 0 4px color-mix(in srgb, var(--token-text) 5%, transparent);
|
|
10904
13647
|
}
|
|
10905
|
-
.
|
|
13648
|
+
.table--sticky-col tbody td.col-fixed {
|
|
10906
13649
|
background: var(--token-surface);
|
|
10907
13650
|
}
|
|
10908
|
-
.
|
|
13651
|
+
.table--sticky-col tbody tr:hover td.col-fixed {
|
|
10909
13652
|
background: var(--token-surface-strong);
|
|
10910
13653
|
}
|
|
10911
13654
|
|
|
10912
13655
|
/* ── 展开行 ── */
|
|
10913
|
-
.
|
|
13656
|
+
.table .row-expand > td {
|
|
10914
13657
|
padding: 0 var(--density-space-md);
|
|
10915
13658
|
background: var(--token-bg-soft);
|
|
10916
13659
|
border-bottom: 1px solid var(--token-line-soft);
|
|
10917
13660
|
font-size: var(--density-font-size-sm);
|
|
10918
13661
|
color: var(--token-text-muted);
|
|
10919
13662
|
}
|
|
10920
|
-
.
|
|
13663
|
+
.table .row-expand[hidden] { display: none; }
|
|
10921
13664
|
/* 展开行的内容容器(使用方可加 padding/动画) */
|
|
10922
13665
|
.row-expand-content {
|
|
10923
13666
|
padding: var(--density-space-sm) 0;
|
|
@@ -10929,22 +13672,22 @@ html {
|
|
|
10929
13672
|
}
|
|
10930
13673
|
|
|
10931
13674
|
/* ── 列宽工具类 ── */
|
|
10932
|
-
.
|
|
10933
|
-
.
|
|
10934
|
-
.
|
|
13675
|
+
.table .col-narrow { width: 80px; }
|
|
13676
|
+
.table .col-wide { width: 240px; }
|
|
13677
|
+
.table .col-action { width: 1%; white-space: nowrap; }
|
|
10935
13678
|
|
|
10936
13679
|
/* ── 行状态色 ── */
|
|
10937
|
-
.
|
|
10938
|
-
.
|
|
10939
|
-
.
|
|
13680
|
+
.table tbody tr.row-success { background: color-mix(in srgb, var(--token-success) 6%, transparent); }
|
|
13681
|
+
.table tbody tr.row-warning { background: color-mix(in srgb, var(--token-warning) 6%, transparent); }
|
|
13682
|
+
.table tbody tr.row-error { background: color-mix(in srgb, var(--token-error) 6%, transparent); }
|
|
10940
13683
|
|
|
10941
13684
|
/* ── 粘滞表头阴影提示 ── */
|
|
10942
|
-
.
|
|
13685
|
+
.table thead th {
|
|
10943
13686
|
box-shadow: 0 1px 0 var(--token-line);
|
|
10944
13687
|
}
|
|
10945
13688
|
|
|
10946
13689
|
/* ── 表头分组(rowspan/colspan 样式) ── */
|
|
10947
|
-
.
|
|
13690
|
+
.table th[rowspan] { vertical-align: bottom; }
|
|
10948
13691
|
|
|
10949
13692
|
@media (prefers-reduced-motion: reduce) {
|
|
10950
13693
|
.row-expand-content { animation: none; }
|
|
@@ -10956,20 +13699,19 @@ html {
|
|
|
10956
13699
|
* @icen.ai/ui — Component: tabs(分区导航 / 子导航)
|
|
10957
13700
|
*
|
|
10958
13701
|
* 完整契约:
|
|
10959
|
-
* <div class="
|
|
10960
|
-
* <button class="page-tab [.active]" role="tab" [aria-selected="true"]>…</button>
|
|
13702
|
+
* <div class="tabs" role="tablist"> ← 页面内分区
|
|
13703
|
+
* <button class="page-tab [.is-active]" role="tab" [aria-selected="true"]>…</button>
|
|
10961
13704
|
* </div>
|
|
10962
13705
|
*
|
|
10963
|
-
* <nav class="
|
|
10964
|
-
* <a class="[.active]" [aria-current="page"] href="…">…</a>
|
|
13706
|
+
* <nav class="tabs" role="navigation"> ← 顶部子导航(a 链接)
|
|
13707
|
+
* <a class="[.is-active]" [aria-current="page"] href="…">…</a>
|
|
10965
13708
|
* </nav>
|
|
10966
13709
|
*
|
|
10967
13710
|
* 与 behaviors/tabs 配套:[data-tabs] > [data-tab] + [data-tab-panel],行为层维护 aria。
|
|
10968
|
-
*
|
|
13711
|
+
* 窄屏换行不滚动(纪律:tab 条永不出现滚动条,一律 flex-wrap: wrap)。
|
|
10969
13712
|
*/
|
|
10970
13713
|
|
|
10971
|
-
.
|
|
10972
|
-
.admin-tabs {
|
|
13714
|
+
.tabs {
|
|
10973
13715
|
display: flex;
|
|
10974
13716
|
gap: 2px;
|
|
10975
13717
|
flex-wrap: wrap;
|
|
@@ -11001,14 +13743,14 @@ html {
|
|
|
11001
13743
|
border-radius: var(--radius-sm);
|
|
11002
13744
|
box-shadow: var(--icen-ring);
|
|
11003
13745
|
}
|
|
11004
|
-
.page-tab.active,
|
|
13746
|
+
.page-tab.is-active,
|
|
11005
13747
|
.page-tab[aria-selected='true'] {
|
|
11006
13748
|
color: var(--token-accent);
|
|
11007
13749
|
border-bottom-color: var(--token-accent);
|
|
11008
13750
|
font-weight: 700;
|
|
11009
13751
|
}
|
|
11010
13752
|
|
|
11011
|
-
.
|
|
13753
|
+
.tabs a {
|
|
11012
13754
|
padding: var(--density-space-sm) var(--density-space-md);
|
|
11013
13755
|
font-size: var(--density-font-size-md);
|
|
11014
13756
|
color: var(--token-text-muted);
|
|
@@ -11020,44 +13762,44 @@ html {
|
|
|
11020
13762
|
color var(--icen-tx-fast),
|
|
11021
13763
|
border-color var(--icen-tx-fast);
|
|
11022
13764
|
}
|
|
11023
|
-
.
|
|
13765
|
+
.tabs a:hover {
|
|
11024
13766
|
color: var(--token-accent);
|
|
11025
13767
|
text-decoration: none;
|
|
11026
13768
|
}
|
|
11027
|
-
.
|
|
13769
|
+
.tabs a:focus-visible {
|
|
11028
13770
|
outline: none;
|
|
11029
13771
|
border-radius: var(--radius-sm);
|
|
11030
13772
|
box-shadow: var(--icen-ring);
|
|
11031
13773
|
}
|
|
11032
|
-
.
|
|
11033
|
-
.
|
|
13774
|
+
.tabs a.is-active,
|
|
13775
|
+
.tabs a[aria-current='page'] {
|
|
11034
13776
|
color: var(--token-accent);
|
|
11035
13777
|
border-bottom-color: var(--token-accent);
|
|
11036
13778
|
}
|
|
11037
13779
|
|
|
11038
|
-
/* 卡片变体(可选 .
|
|
11039
|
-
.
|
|
13780
|
+
/* 卡片变体(可选 .tabs--cards):tab 变成 pill,没有底边线 */
|
|
13781
|
+
.tabs--cards {
|
|
11040
13782
|
border-bottom: 0;
|
|
11041
13783
|
gap: var(--density-space-xs);
|
|
11042
13784
|
margin-bottom: var(--density-space-md);
|
|
11043
13785
|
}
|
|
11044
|
-
.
|
|
13786
|
+
.tabs--cards .page-tab {
|
|
11045
13787
|
padding: var(--density-space-xs) var(--density-space-md);
|
|
11046
13788
|
border: 1px solid var(--token-outline-soft);
|
|
11047
13789
|
border-radius: var(--radius-full);
|
|
11048
13790
|
margin-bottom: 0;
|
|
11049
13791
|
}
|
|
11050
|
-
.
|
|
11051
|
-
.
|
|
13792
|
+
.tabs--cards .page-tab.is-active,
|
|
13793
|
+
.tabs--cards .page-tab[aria-selected='true'] {
|
|
11052
13794
|
background: var(--token-accent);
|
|
11053
|
-
color: var(--token-on-accent
|
|
13795
|
+
color: var(--token-on-accent);
|
|
11054
13796
|
border-color: var(--token-accent);
|
|
11055
13797
|
font-weight: 500;
|
|
11056
13798
|
}
|
|
11057
13799
|
|
|
11058
13800
|
/* 等宽变体:tab 平均占满容器 */
|
|
11059
|
-
.
|
|
11060
|
-
.
|
|
13801
|
+
.tabs--equal .page-tab,
|
|
13802
|
+
.tabs--equal a {
|
|
11061
13803
|
flex: 1;
|
|
11062
13804
|
text-align: center;
|
|
11063
13805
|
}
|
|
@@ -11065,11 +13807,11 @@ html {
|
|
|
11065
13807
|
/* ── 增强 ── */
|
|
11066
13808
|
|
|
11067
13809
|
/* 尺寸变体 */
|
|
11068
|
-
.
|
|
13810
|
+
.tabs--sm .page-tab {
|
|
11069
13811
|
padding: var(--density-space-xs) var(--density-space-sm);
|
|
11070
13812
|
font-size: var(--density-font-size-sm);
|
|
11071
13813
|
}
|
|
11072
|
-
.
|
|
13814
|
+
.tabs--lg .page-tab {
|
|
11073
13815
|
padding: var(--density-space-md) calc(var(--density-space-md) + 4px);
|
|
11074
13816
|
font-size: var(--density-font-size-lg);
|
|
11075
13817
|
}
|
|
@@ -11091,7 +13833,7 @@ html {
|
|
|
11091
13833
|
height: 18px;
|
|
11092
13834
|
padding: 0 5px;
|
|
11093
13835
|
margin-left: var(--density-space-xs);
|
|
11094
|
-
font-size:
|
|
13836
|
+
font-size: var(--density-font-size-2xs);
|
|
11095
13837
|
font-weight: 600;
|
|
11096
13838
|
color: var(--token-text-faint);
|
|
11097
13839
|
background: var(--token-fill-2);
|
|
@@ -11099,10 +13841,10 @@ html {
|
|
|
11099
13841
|
font-variant-numeric: tabular-nums;
|
|
11100
13842
|
line-height: 1;
|
|
11101
13843
|
}
|
|
11102
|
-
.page-tab.active .page-tab-badge,
|
|
13844
|
+
.page-tab.is-active .page-tab-badge,
|
|
11103
13845
|
.page-tab[aria-selected='true'] .page-tab-badge {
|
|
11104
13846
|
background: var(--token-accent);
|
|
11105
|
-
color: var(--token-on-accent
|
|
13847
|
+
color: var(--token-on-accent);
|
|
11106
13848
|
}
|
|
11107
13849
|
|
|
11108
13850
|
/* 可关闭 tab */
|
|
@@ -11129,7 +13871,7 @@ html {
|
|
|
11129
13871
|
.page-tab-close svg { width: 10px; height: 10px; }
|
|
11130
13872
|
|
|
11131
13873
|
/* 分段式 tab(替代底边线,用 segmented 视觉) */
|
|
11132
|
-
.
|
|
13874
|
+
.tabs--segment {
|
|
11133
13875
|
display: inline-flex;
|
|
11134
13876
|
border-bottom: none;
|
|
11135
13877
|
gap: 2px;
|
|
@@ -11139,52 +13881,42 @@ html {
|
|
|
11139
13881
|
border-radius: var(--radius-md);
|
|
11140
13882
|
box-shadow: var(--token-shadow-inset);
|
|
11141
13883
|
}
|
|
11142
|
-
.
|
|
13884
|
+
.tabs--segment .page-tab {
|
|
11143
13885
|
border-bottom: none;
|
|
11144
13886
|
margin-bottom: 0;
|
|
11145
13887
|
padding: var(--density-space-xs) var(--density-space-md);
|
|
11146
13888
|
border-radius: var(--radius-sm);
|
|
11147
13889
|
}
|
|
11148
|
-
.
|
|
11149
|
-
.
|
|
13890
|
+
.tabs--segment .page-tab.is-active,
|
|
13891
|
+
.tabs--segment .page-tab[aria-selected='true'] {
|
|
11150
13892
|
background: var(--token-accent);
|
|
11151
|
-
color: var(--token-on-accent
|
|
13893
|
+
color: var(--token-on-accent);
|
|
11152
13894
|
border-bottom-color: transparent;
|
|
11153
13895
|
font-weight: 500;
|
|
11154
13896
|
}
|
|
11155
13897
|
|
|
11156
13898
|
/* 垂直 tab(侧栏式) */
|
|
11157
|
-
.
|
|
13899
|
+
.tabs--vertical {
|
|
11158
13900
|
flex-direction: column;
|
|
11159
13901
|
border-bottom: none;
|
|
11160
13902
|
border-right: 1px solid var(--token-line-soft);
|
|
11161
13903
|
margin-bottom: 0;
|
|
11162
13904
|
min-width: 160px;
|
|
11163
13905
|
}
|
|
11164
|
-
.
|
|
13906
|
+
.tabs--vertical .page-tab {
|
|
11165
13907
|
border-bottom: none;
|
|
11166
13908
|
border-right: 2px solid transparent;
|
|
11167
13909
|
margin-bottom: 0;
|
|
11168
13910
|
margin-right: -1px;
|
|
11169
13911
|
}
|
|
11170
|
-
.
|
|
11171
|
-
.
|
|
13912
|
+
.tabs--vertical .page-tab.is-active,
|
|
13913
|
+
.tabs--vertical .page-tab[aria-selected='true'] {
|
|
11172
13914
|
border-right-color: var(--token-accent);
|
|
11173
13915
|
border-bottom-color: transparent;
|
|
11174
13916
|
}
|
|
11175
13917
|
|
|
11176
|
-
/* tab 溢出渐变提示(窄屏溢出时右侧渐变遮罩——纯视觉提示,不违反"不滚动"纪律,仍 flex-wrap) */
|
|
11177
|
-
.page-tabs--scroll {
|
|
11178
|
-
flex-wrap: nowrap;
|
|
11179
|
-
overflow-x: auto;
|
|
11180
|
-
overflow-y: hidden;
|
|
11181
|
-
scrollbar-width: none;
|
|
11182
|
-
-ms-overflow-style: none;
|
|
11183
|
-
}
|
|
11184
|
-
.page-tabs--scroll::-webkit-scrollbar { display: none; }
|
|
11185
|
-
|
|
11186
13918
|
@media (prefers-reduced-motion: reduce) {
|
|
11187
|
-
.page-tab, .
|
|
13919
|
+
.page-tab, .tabs a, .page-tab-close { transition: none; }
|
|
11188
13920
|
}
|
|
11189
13921
|
|
|
11190
13922
|
|
|
@@ -11231,7 +13963,7 @@ html {
|
|
|
11231
13963
|
.tag-input.is-max,
|
|
11232
13964
|
.tag-input.is-max:focus-within {
|
|
11233
13965
|
border-color: color-mix(in srgb, var(--token-warning) 60%, transparent);
|
|
11234
|
-
box-shadow:
|
|
13966
|
+
box-shadow: var(--icen-ring-warning);
|
|
11235
13967
|
}
|
|
11236
13968
|
.tag-input.is-disabled,
|
|
11237
13969
|
.tag-input[aria-disabled='true'],
|
|
@@ -11289,7 +14021,7 @@ html {
|
|
|
11289
14021
|
cursor: pointer;
|
|
11290
14022
|
border-radius: var(--radius-full);
|
|
11291
14023
|
color: inherit;
|
|
11292
|
-
font-size:
|
|
14024
|
+
font-size: var(--density-font-size-xs);
|
|
11293
14025
|
line-height: 1;
|
|
11294
14026
|
opacity: 0.7;
|
|
11295
14027
|
transition:
|
|
@@ -11300,7 +14032,7 @@ html {
|
|
|
11300
14032
|
.tag-chip-x:hover {
|
|
11301
14033
|
opacity: 1;
|
|
11302
14034
|
background: color-mix(in srgb, currentColor 18%, transparent);
|
|
11303
|
-
color: var(--token-on-accent
|
|
14035
|
+
color: var(--token-on-accent);
|
|
11304
14036
|
}
|
|
11305
14037
|
.tag-chip-x:focus-visible {
|
|
11306
14038
|
outline: none;
|
|
@@ -11326,7 +14058,7 @@ html {
|
|
|
11326
14058
|
|
|
11327
14059
|
/* 重复值抖动反馈(behavior 短暂挂 is-shake) */
|
|
11328
14060
|
.tag-input.is-shake {
|
|
11329
|
-
animation: tag-shake 0.32s var(--ease-out);
|
|
14061
|
+
animation: tag-shake var(--tag-shake-duration, 0.32s) var(--ease-out);
|
|
11330
14062
|
}
|
|
11331
14063
|
@keyframes tag-shake {
|
|
11332
14064
|
0%, 100% { transform: translateX(0); }
|
|
@@ -11510,7 +14242,7 @@ button.tag,
|
|
|
11510
14242
|
*
|
|
11511
14243
|
* 完整契约:
|
|
11512
14244
|
* <div class="toast-container" role="status" aria-live="polite">
|
|
11513
|
-
* <div class="toast [
|
|
14245
|
+
* <div class="toast [toast--success|toast--error|toast--warning|toast--info]" role="status|alert">
|
|
11514
14246
|
* <span class="toast-msg">文本</span>
|
|
11515
14247
|
* <button class="toast-action">撤销</button> ← 可选 action
|
|
11516
14248
|
* </div>
|
|
@@ -11533,6 +14265,8 @@ button.tag,
|
|
|
11533
14265
|
|
|
11534
14266
|
.toast {
|
|
11535
14267
|
pointer-events: auto;
|
|
14268
|
+
position: relative;
|
|
14269
|
+
overflow: hidden;
|
|
11536
14270
|
display: inline-flex;
|
|
11537
14271
|
align-items: center;
|
|
11538
14272
|
gap: var(--density-space-sm);
|
|
@@ -11550,9 +14284,10 @@ button.tag,
|
|
|
11550
14284
|
}
|
|
11551
14285
|
|
|
11552
14286
|
/* 语义色:左缘 3px 强调 */
|
|
11553
|
-
.toast
|
|
11554
|
-
.toast
|
|
11555
|
-
.toast
|
|
14287
|
+
.toast--success { border-left-color: var(--token-success); }
|
|
14288
|
+
.toast--error { border-left-color: var(--token-error); }
|
|
14289
|
+
.toast--warning { border-left-color: var(--token-warning); }
|
|
14290
|
+
.toast--info { border-left-color: var(--token-info); }
|
|
11556
14291
|
|
|
11557
14292
|
.toast-msg {
|
|
11558
14293
|
flex: 1;
|
|
@@ -11593,9 +14328,10 @@ button.tag,
|
|
|
11593
14328
|
color: var(--token-text-faint);
|
|
11594
14329
|
}
|
|
11595
14330
|
.toast-icon svg { width: 16px; height: 16px; }
|
|
11596
|
-
.toast
|
|
11597
|
-
.toast.
|
|
11598
|
-
.toast
|
|
14331
|
+
.toast--success .toast-icon { color: var(--token-success); }
|
|
14332
|
+
.toast--error .toast-icon { color: var(--token-error); }
|
|
14333
|
+
.toast--warning .toast-icon { color: var(--token-warning); }
|
|
14334
|
+
.toast--info .toast-icon { color: var(--token-info); }
|
|
11599
14335
|
|
|
11600
14336
|
/* 关闭按钮 */
|
|
11601
14337
|
.toast-close {
|
|
@@ -11654,16 +14390,15 @@ button.tag,
|
|
|
11654
14390
|
transform-origin: left;
|
|
11655
14391
|
animation: toast-countdown linear forwards;
|
|
11656
14392
|
}
|
|
11657
|
-
.toast
|
|
11658
|
-
.toast.
|
|
11659
|
-
.toast
|
|
14393
|
+
.toast--success .toast-progress-fill { background: var(--token-success); }
|
|
14394
|
+
.toast--error .toast-progress-fill { background: var(--token-error); }
|
|
14395
|
+
.toast--warning .toast-progress-fill { background: var(--token-warning); }
|
|
14396
|
+
.toast--info .toast-progress-fill { background: var(--token-info); }
|
|
11660
14397
|
@keyframes toast-countdown {
|
|
11661
14398
|
from { transform: scaleX(1); }
|
|
11662
14399
|
to { transform: scaleX(0); }
|
|
11663
14400
|
}
|
|
11664
14401
|
|
|
11665
|
-
.toast { position: relative; overflow: hidden; }
|
|
11666
|
-
|
|
11667
14402
|
/* 容器定位变体 */
|
|
11668
14403
|
.toast-container[data-position='top-left'] {
|
|
11669
14404
|
right: auto;
|
|
@@ -11696,7 +14431,7 @@ button.tag,
|
|
|
11696
14431
|
align-items: center;
|
|
11697
14432
|
}
|
|
11698
14433
|
|
|
11699
|
-
.toast.leaving {
|
|
14434
|
+
.toast.is-leaving {
|
|
11700
14435
|
opacity: 0;
|
|
11701
14436
|
transform: translateY(8px);
|
|
11702
14437
|
transition:
|
|
@@ -11833,7 +14568,7 @@ button.tag,
|
|
|
11833
14568
|
* 无障碍:键盘 :focus-visible 立即出现(无延迟),鼠标 hover 延迟 400ms。
|
|
11834
14569
|
*/
|
|
11835
14570
|
|
|
11836
|
-
[data-tooltip] { position: relative; }
|
|
14571
|
+
[data-tooltip] { position: relative; --tooltip-delay: 400ms; }
|
|
11837
14572
|
|
|
11838
14573
|
[data-tooltip]::after {
|
|
11839
14574
|
content: attr(data-tooltip);
|
|
@@ -11858,7 +14593,7 @@ button.tag,
|
|
|
11858
14593
|
transition:
|
|
11859
14594
|
opacity var(--icen-tx-fast),
|
|
11860
14595
|
transform var(--icen-tx-fast);
|
|
11861
|
-
transition-delay:
|
|
14596
|
+
transition-delay: var(--tooltip-delay);
|
|
11862
14597
|
|
|
11863
14598
|
/* 默认:上方、水平居中 */
|
|
11864
14599
|
bottom: calc(100% + 6px);
|