@icen.ai/ui 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/base.css +72 -0
- package/dist/behaviors/accordion.mjs +34 -0
- package/dist/behaviors/carousel.mjs +50 -0
- package/dist/behaviors/charts.mjs +267 -0
- package/dist/behaviors/context-menu.mjs +223 -0
- package/dist/behaviors/dropdown.mjs +136 -0
- package/dist/behaviors/input.mjs +102 -0
- package/dist/behaviors/modal.mjs +107 -0
- package/dist/behaviors/nav.mjs +29 -0
- package/dist/behaviors/popover.mjs +164 -0
- package/dist/behaviors/select.mjs +132 -0
- package/dist/behaviors/sidebar.mjs +27 -0
- package/dist/behaviors/slider.mjs +72 -0
- package/dist/behaviors/tag-input.mjs +74 -0
- package/dist/behaviors/tree.mjs +44 -0
- package/dist/behaviors/upload.mjs +55 -0
- package/dist/components/breadcrumb.css +31 -0
- package/dist/components/card.css +56 -0
- package/dist/components/charts.css +95 -0
- package/dist/components/content.css +195 -0
- package/dist/components/empty.css +25 -0
- package/dist/components/feedback.css +106 -0
- package/dist/components/input.css +82 -0
- package/dist/components/layout.css +109 -0
- package/dist/components/media.css +133 -0
- package/dist/components/menu.css +85 -0
- package/dist/components/modal.css +107 -0
- package/dist/components/nav.css +59 -0
- package/dist/components/pagination.css +32 -0
- package/dist/components/popover.css +25 -0
- package/dist/components/segmented.css +112 -0
- package/dist/components/select.css +79 -0
- package/dist/components/sidebar.css +54 -0
- package/dist/components/slider.css +69 -0
- package/dist/components/steps.css +61 -0
- package/dist/components/switch.css +95 -0
- package/dist/components/tag-input.css +48 -0
- package/dist/components/toast.css +1 -1
- package/dist/components/tooltip.css +56 -0
- package/dist/components/upload.css +43 -0
- package/dist/index.mjs +1502 -1
- package/dist/registry.json +41 -3
- package/dist/ui.css +1899 -1
- package/package.json +1 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @icen.ai/ui — Component: feedback(反馈族)
|
|
3
|
+
* 包含:alert(四态内联横幅)/ result(终态页)/ progress(线性进度)/ spinner(加载圈)/ skeleton(占位块)
|
|
4
|
+
* 规格源自 opengal src/presentation/ui/feedback/toast.tsx 的 Alert 与 data/exhibit.tsx 的 Result、
|
|
5
|
+
* data/display.tsx 的 Progress / Spinner / Skeleton。
|
|
6
|
+
* base.css 未提供 spin / skeleton-pulse 关键帧,在本文件自带。
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/* ══════════════ alert · 内联横幅 ══════════════ */
|
|
10
|
+
.alert {
|
|
11
|
+
display: flex; align-items: flex-start; gap: 12px;
|
|
12
|
+
padding: 12px;
|
|
13
|
+
border-radius: var(--radius-lg);
|
|
14
|
+
box-shadow: var(--token-shadow-inset);
|
|
15
|
+
border: 1px solid transparent;
|
|
16
|
+
}
|
|
17
|
+
.alert--info { background: var(--token-info-muted); border-color: color-mix(in srgb, var(--token-info) 15%, transparent); }
|
|
18
|
+
.alert--success { background: var(--token-success-muted); border-color: color-mix(in srgb, var(--token-success) 15%, transparent); }
|
|
19
|
+
.alert--warning { background: var(--token-warning-muted); border-color: color-mix(in srgb, var(--token-warning) 15%, transparent); }
|
|
20
|
+
.alert--error { background: var(--token-error-muted); border-color: color-mix(in srgb, var(--token-error) 15%, transparent); }
|
|
21
|
+
|
|
22
|
+
.alert-icon { flex-shrink: 0; margin-top: 2px; display: flex; }
|
|
23
|
+
.alert-icon svg { width: 16px; height: 16px; }
|
|
24
|
+
.alert--info .alert-icon, .alert--info .alert-title { color: var(--token-info); }
|
|
25
|
+
.alert--success .alert-icon, .alert--success .alert-title { color: var(--token-success); }
|
|
26
|
+
.alert--warning .alert-icon, .alert--warning .alert-title { color: var(--token-warning); }
|
|
27
|
+
.alert--error .alert-icon, .alert--error .alert-title { color: var(--token-error); }
|
|
28
|
+
|
|
29
|
+
.alert-content { flex: 1; min-width: 0; }
|
|
30
|
+
.alert-title { font-size: 13px; font-weight: 500; margin: 0; }
|
|
31
|
+
.alert-body { font-size: 12px; color: var(--token-text-muted); line-height: 1.6; }
|
|
32
|
+
.alert-close {
|
|
33
|
+
margin-left: auto; flex-shrink: 0;
|
|
34
|
+
display: flex; align-items: center; justify-content: center;
|
|
35
|
+
padding: 2px; border: 0; border-radius: var(--radius-xs);
|
|
36
|
+
background: none; color: var(--token-text-faint); cursor: pointer;
|
|
37
|
+
}
|
|
38
|
+
.alert-close:hover { color: var(--token-text); background: color-mix(in srgb, var(--token-text) 6%, transparent); }
|
|
39
|
+
.alert-close svg { width: 14px; height: 14px; }
|
|
40
|
+
|
|
41
|
+
/* ══════════════ result · 终态页 ══════════════ */
|
|
42
|
+
.result {
|
|
43
|
+
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
|
44
|
+
text-align: center;
|
|
45
|
+
padding: 40px 24px;
|
|
46
|
+
}
|
|
47
|
+
.result-icon {
|
|
48
|
+
width: 64px; height: 64px;
|
|
49
|
+
border-radius: var(--radius-full);
|
|
50
|
+
display: flex; align-items: center; justify-content: center;
|
|
51
|
+
box-shadow: var(--token-shadow-inset);
|
|
52
|
+
border: 1px solid transparent;
|
|
53
|
+
margin-bottom: 16px;
|
|
54
|
+
}
|
|
55
|
+
.result-icon svg { width: 28px; height: 28px; }
|
|
56
|
+
.result--success .result-icon { background: var(--token-success-muted); color: var(--token-success); border-color: color-mix(in srgb, var(--token-success) 10%, transparent); }
|
|
57
|
+
.result--error .result-icon { background: var(--token-error-muted); color: var(--token-error); border-color: color-mix(in srgb, var(--token-error) 10%, transparent); }
|
|
58
|
+
.result--warning .result-icon { background: var(--token-warning-muted); color: var(--token-warning); border-color: color-mix(in srgb, var(--token-warning) 10%, transparent); }
|
|
59
|
+
.result--info .result-icon { background: var(--token-info-muted); color: var(--token-info); border-color: color-mix(in srgb, var(--token-info) 10%, transparent); }
|
|
60
|
+
.result-title { font-size: 17px; font-weight: 600; color: var(--token-text); margin: 0; }
|
|
61
|
+
.result-desc { font-size: 13px; color: var(--token-text-muted); margin: 4px 0 0; max-width: 360px; }
|
|
62
|
+
.result-extra { display: flex; align-items: center; gap: 8px; margin-top: 20px; }
|
|
63
|
+
|
|
64
|
+
/* ══════════════ progress · 线性进度 ══════════════ */
|
|
65
|
+
.progress { display: flex; align-items: center; gap: 8px; }
|
|
66
|
+
.progress-track {
|
|
67
|
+
flex: 1; height: 6px; overflow: hidden;
|
|
68
|
+
border-radius: var(--radius-full);
|
|
69
|
+
background: color-mix(in srgb, var(--token-line-soft) 40%, transparent);
|
|
70
|
+
}
|
|
71
|
+
.progress-bar {
|
|
72
|
+
height: 100%;
|
|
73
|
+
border-radius: var(--radius-full);
|
|
74
|
+
background: var(--token-accent);
|
|
75
|
+
transition: width 500ms var(--ease-out);
|
|
76
|
+
}
|
|
77
|
+
.progress--sm .progress-track { height: 4px; }
|
|
78
|
+
.progress-label { font-size: 11px; color: var(--token-text-muted); font-variant-numeric: tabular-nums; }
|
|
79
|
+
|
|
80
|
+
/* ══════════════ spinner · 加载圈 ══════════════ */
|
|
81
|
+
.spinner {
|
|
82
|
+
width: 20px; height: 20px;
|
|
83
|
+
border: 2px solid var(--token-accent);
|
|
84
|
+
border-top-color: transparent;
|
|
85
|
+
border-radius: var(--radius-full);
|
|
86
|
+
animation: icen-spin 1s linear infinite;
|
|
87
|
+
}
|
|
88
|
+
.spinner--sm { width: 16px; height: 16px; }
|
|
89
|
+
.spinner--lg { width: 32px; height: 32px; }
|
|
90
|
+
|
|
91
|
+
@keyframes icen-spin {
|
|
92
|
+
to { transform: rotate(360deg); }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* ══════════════ skeleton · 占位块 ══════════════ */
|
|
96
|
+
.skeleton {
|
|
97
|
+
background: var(--token-control-hover);
|
|
98
|
+
border-radius: var(--radius-sm);
|
|
99
|
+
animation: icen-skeleton-pulse 2s ease-in-out infinite;
|
|
100
|
+
}
|
|
101
|
+
.skeleton--circle { border-radius: var(--radius-full); }
|
|
102
|
+
|
|
103
|
+
@keyframes icen-skeleton-pulse {
|
|
104
|
+
0%, 100% { opacity: 1; }
|
|
105
|
+
50% { opacity: 0.5; }
|
|
106
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @icen.ai/ui — Component: input(wrapper 式输入框 / 多行 / 搜索)
|
|
3
|
+
* 规格源自 opengal primitives/input.tsx;与 behaviors/input.ts 配套。
|
|
4
|
+
*
|
|
5
|
+
* 契约:
|
|
6
|
+
* <div class="input-wrap control [--sm|--lg] [.is-error] [.is-disabled]">
|
|
7
|
+
* <span class="input-leading">…</span> 可选前缀
|
|
8
|
+
* <input class="input" />
|
|
9
|
+
* <button class="input-clear">…</button> 可选清除钮(behavior 清空并聚焦)
|
|
10
|
+
* <button class="input-pw-toggle">…</button> 可选密码可见切换(behavior 驱动)
|
|
11
|
+
* <span class="input-trailing">…</span> 可选后缀
|
|
12
|
+
* </div>
|
|
13
|
+
* 多行:<div class="textarea-wrap control"><textarea class="textarea" data-autosize></textarea></div>
|
|
14
|
+
* 搜索:.input-wrap--search = leading 放大镜 + .input-clear 的结构约定(无额外视觉)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
.input-wrap {
|
|
18
|
+
display: flex; align-items: center; gap: 8px; width: 100%;
|
|
19
|
+
height: 36px; padding: 0 12px; font-size: 13px;
|
|
20
|
+
background: var(--token-control);
|
|
21
|
+
border: 1px solid var(--token-outline-soft);
|
|
22
|
+
border-radius: var(--radius-lg);
|
|
23
|
+
box-shadow: var(--token-shadow-inset);
|
|
24
|
+
}
|
|
25
|
+
.input-wrap:focus-within { border-color: var(--token-accent); }
|
|
26
|
+
.input-wrap.is-error, .input-wrap.is-error:focus-within { border-color: var(--token-error); }
|
|
27
|
+
.input-wrap.is-disabled { opacity: 0.4; }
|
|
28
|
+
.input-wrap.is-disabled .input { cursor: not-allowed; }
|
|
29
|
+
|
|
30
|
+
/* 尺寸三档:高度 / 横向内边距 / 字号 */
|
|
31
|
+
.input-wrap--sm { height: 32px; padding: 0 10px; font-size: 12px; }
|
|
32
|
+
.input-wrap--lg { height: 40px; padding: 0 14px; font-size: 14px; }
|
|
33
|
+
|
|
34
|
+
.input {
|
|
35
|
+
flex: 1; min-width: 0; padding: 0;
|
|
36
|
+
background: transparent; border: none; outline: none;
|
|
37
|
+
color: var(--token-text); font: inherit;
|
|
38
|
+
}
|
|
39
|
+
.input::placeholder { color: color-mix(in srgb, var(--token-text-faint) 60%, transparent); }
|
|
40
|
+
|
|
41
|
+
.input-leading, .input-trailing {
|
|
42
|
+
display: inline-flex; align-items: center; flex-shrink: 0;
|
|
43
|
+
color: var(--token-text-faint);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.input-clear {
|
|
47
|
+
display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
|
|
48
|
+
padding: 2px; border: none; background: transparent; cursor: pointer;
|
|
49
|
+
border-radius: var(--radius-full); color: var(--token-text-faint);
|
|
50
|
+
transition: color var(--duration-normal) var(--ease-out),
|
|
51
|
+
background-color var(--duration-normal) var(--ease-out);
|
|
52
|
+
}
|
|
53
|
+
.input-clear:hover { color: var(--token-text); background: var(--token-surface-hover); }
|
|
54
|
+
|
|
55
|
+
.input-pw-toggle {
|
|
56
|
+
display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
|
|
57
|
+
padding: 2px; border: none; background: transparent; cursor: pointer;
|
|
58
|
+
color: var(--token-text-faint);
|
|
59
|
+
transition: color var(--duration-normal) var(--ease-out);
|
|
60
|
+
}
|
|
61
|
+
.input-pw-toggle:hover { color: var(--token-text); }
|
|
62
|
+
|
|
63
|
+
/* ── 多行:同一 wrapper 视觉,内部 textarea 裸奔 ── */
|
|
64
|
+
.textarea-wrap {
|
|
65
|
+
display: flex; width: 100%;
|
|
66
|
+
background: var(--token-control);
|
|
67
|
+
border: 1px solid var(--token-outline-soft);
|
|
68
|
+
border-radius: var(--radius-lg);
|
|
69
|
+
box-shadow: var(--token-shadow-inset);
|
|
70
|
+
}
|
|
71
|
+
.textarea-wrap:focus-within { border-color: var(--token-accent); }
|
|
72
|
+
.textarea-wrap.is-error, .textarea-wrap.is-error:focus-within { border-color: var(--token-error); }
|
|
73
|
+
.textarea-wrap.is-disabled { opacity: 0.4; }
|
|
74
|
+
.textarea-wrap.is-disabled .textarea { cursor: not-allowed; }
|
|
75
|
+
|
|
76
|
+
.textarea {
|
|
77
|
+
width: 100%; padding: 12px;
|
|
78
|
+
background: transparent; border: none; outline: none; resize: none;
|
|
79
|
+
color: var(--token-text); font: inherit; font-size: 13px; line-height: 1.5;
|
|
80
|
+
min-height: calc(3 * 1.5em + 24px); /* 3 行 + 上下 padding */
|
|
81
|
+
}
|
|
82
|
+
.textarea::placeholder { color: color-mix(in srgb, var(--token-text-faint) 60%, transparent); }
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @icen.ai/ui — Component: layout(布局原语,全部是工具类,无 JS)
|
|
3
|
+
* stack / divider / surface / text / grid / center / container / aspect / visually-hidden
|
|
4
|
+
* 全部消费 --token-*;档位类名与 opengal primitives/layout(-containers) 一一对应。
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/* ── Stack:flex 堆叠(默认列向,gap 8px) ── */
|
|
8
|
+
.stack { display: flex; flex-direction: column; gap: 8px; }
|
|
9
|
+
.stack--row { flex-direction: row; }
|
|
10
|
+
.stack--inline { display: inline-flex; }
|
|
11
|
+
.stack--wrap { flex-wrap: wrap; }
|
|
12
|
+
.stack--gap-0 { gap: 0; }
|
|
13
|
+
.stack--gap-1 { gap: 4px; }
|
|
14
|
+
.stack--gap-2 { gap: 8px; }
|
|
15
|
+
.stack--gap-3 { gap: 12px; }
|
|
16
|
+
.stack--gap-4 { gap: 16px; }
|
|
17
|
+
.stack--gap-6 { gap: 24px; }
|
|
18
|
+
.stack--gap-8 { gap: 32px; }
|
|
19
|
+
.stack--gap-12 { gap: 48px; }
|
|
20
|
+
.stack--gap-16 { gap: 64px; }
|
|
21
|
+
.stack--items-start { align-items: flex-start; }
|
|
22
|
+
.stack--items-center { align-items: center; }
|
|
23
|
+
.stack--items-end { align-items: flex-end; }
|
|
24
|
+
.stack--items-stretch { align-items: stretch; }
|
|
25
|
+
.stack--items-baseline { align-items: baseline; }
|
|
26
|
+
.stack--justify-start { justify-content: flex-start; }
|
|
27
|
+
.stack--justify-center { justify-content: center; }
|
|
28
|
+
.stack--justify-end { justify-content: flex-end; }
|
|
29
|
+
.stack--justify-between { justify-content: space-between; }
|
|
30
|
+
.stack--justify-around { justify-content: space-around; }
|
|
31
|
+
.stack--justify-evenly { justify-content: space-evenly; }
|
|
32
|
+
|
|
33
|
+
/* ── Divider:分隔线 ── */
|
|
34
|
+
.divider { background: var(--token-outline-soft); height: 1px; width: 100%; }
|
|
35
|
+
.divider--vertical { width: 1px; height: 100%; align-self: stretch; }
|
|
36
|
+
|
|
37
|
+
/* ── Surface:卡片容器(默认 inset 阴影 + 16px padding) ── */
|
|
38
|
+
.surface {
|
|
39
|
+
border-radius: var(--radius-lg);
|
|
40
|
+
background: var(--token-card);
|
|
41
|
+
border: 1px solid var(--token-outline-soft);
|
|
42
|
+
box-shadow: var(--token-shadow-inset);
|
|
43
|
+
padding: 16px;
|
|
44
|
+
}
|
|
45
|
+
.surface--elevated { box-shadow: var(--token-shadow-card); }
|
|
46
|
+
.surface--overlay {
|
|
47
|
+
background: var(--token-card-strong);
|
|
48
|
+
border-color: var(--token-outline);
|
|
49
|
+
box-shadow: var(--token-shadow-overlay);
|
|
50
|
+
}
|
|
51
|
+
.surface--p-none { padding: 0; }
|
|
52
|
+
.surface--p-sm { padding: 12px; }
|
|
53
|
+
.surface--p-md { padding: 16px; }
|
|
54
|
+
.surface--p-lg { padding: 20px; }
|
|
55
|
+
|
|
56
|
+
/* ── Text:字号 / 语义色 / 截断 ── */
|
|
57
|
+
.text--xs { font-size: 11px; }
|
|
58
|
+
.text--sm { font-size: 12px; }
|
|
59
|
+
.text--base { font-size: 13px; }
|
|
60
|
+
.text--md { font-size: 14px; }
|
|
61
|
+
.text--lg { font-size: 15px; }
|
|
62
|
+
.text--xl { font-size: 18px; }
|
|
63
|
+
.text--2xl { font-size: 22px; }
|
|
64
|
+
.text--muted { color: var(--token-text-muted); }
|
|
65
|
+
.text--faint { color: var(--token-text-faint); }
|
|
66
|
+
.text--accent { color: var(--token-accent); }
|
|
67
|
+
.text--success { color: var(--token-success); }
|
|
68
|
+
.text--warning { color: var(--token-warning); }
|
|
69
|
+
.text--error { color: var(--token-error); }
|
|
70
|
+
.text--truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
71
|
+
|
|
72
|
+
/* ── Grid:栅格(默认 gap 12px) ── */
|
|
73
|
+
.grid { display: grid; gap: 12px; }
|
|
74
|
+
.grid--cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
|
|
75
|
+
.grid--cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
76
|
+
.grid--cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
|
77
|
+
.grid--cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
|
|
78
|
+
.grid--cols-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
|
|
79
|
+
.grid--cols-12 { grid-template-columns: repeat(12, minmax(0, 1fr)); }
|
|
80
|
+
.grid--gap-0 { gap: 0; }
|
|
81
|
+
.grid--gap-4 { gap: 4px; }
|
|
82
|
+
.grid--gap-8 { gap: 8px; }
|
|
83
|
+
.grid--gap-12 { gap: 12px; }
|
|
84
|
+
.grid--gap-16 { gap: 16px; }
|
|
85
|
+
.grid--gap-24 { gap: 24px; }
|
|
86
|
+
|
|
87
|
+
/* ── Center:flex 居中盒 ── */
|
|
88
|
+
.center { display: flex; align-items: center; justify-content: center; }
|
|
89
|
+
|
|
90
|
+
/* ── Container:限宽容器(默认 960px) ── */
|
|
91
|
+
.container { width: 100%; margin-inline: auto; padding-inline: 16px; max-width: 960px; }
|
|
92
|
+
.container--sm { max-width: 480px; }
|
|
93
|
+
.container--md { max-width: 720px; }
|
|
94
|
+
.container--lg { max-width: 960px; }
|
|
95
|
+
.container--xl { max-width: 1200px; }
|
|
96
|
+
.container--full { max-width: none; }
|
|
97
|
+
|
|
98
|
+
/* ── Aspect:固定比例盒(padding-bottom hack,内容 absolute inset:0) ── */
|
|
99
|
+
.aspect { position: relative; width: 100%; overflow: hidden; padding-bottom: 56.25%; }
|
|
100
|
+
.aspect--square { padding-bottom: 100%; }
|
|
101
|
+
.aspect--4-3 { padding-bottom: 75%; }
|
|
102
|
+
.aspect--2-3 { padding-bottom: 150%; }
|
|
103
|
+
.aspect > * { position: absolute; inset: 0; }
|
|
104
|
+
|
|
105
|
+
/* ── VisuallyHidden:屏幕阅读器专用文本(sr-only 等价) ── */
|
|
106
|
+
.visually-hidden {
|
|
107
|
+
position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
|
|
108
|
+
overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
|
|
109
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @icen.ai/ui — Component: media(媒体族)
|
|
3
|
+
* 包含:avatar(头像)/ media-card(封面卡,滑出 overlay)/ rating(星级评分)/ carousel(轮播,与 behaviors/carousel 配套)
|
|
4
|
+
* carousel 归入本文件(无独立 carousel.css 配额);规格源自 opengal data/display.tsx 的 Avatar、
|
|
5
|
+
* data/cartridge-card.tsx 的 hover overlay、data/exhibit.tsx 的 Carousel 与 Rating。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* ══════════════ avatar · 头像 ══════════════ */
|
|
9
|
+
.avatar {
|
|
10
|
+
position: relative;
|
|
11
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
border-radius: var(--radius-full);
|
|
14
|
+
background: var(--token-accent-subtle);
|
|
15
|
+
color: var(--token-accent);
|
|
16
|
+
font-weight: 600;
|
|
17
|
+
width: 36px; height: 36px; font-size: 12px;
|
|
18
|
+
flex-shrink: 0;
|
|
19
|
+
}
|
|
20
|
+
.avatar--xs { width: 20px; height: 20px; font-size: 9px; }
|
|
21
|
+
.avatar--sm { width: 28px; height: 28px; font-size: 10px; }
|
|
22
|
+
.avatar--lg { width: 48px; height: 48px; font-size: 14px; }
|
|
23
|
+
.avatar img { width: 100%; height: 100%; object-fit: cover; }
|
|
24
|
+
|
|
25
|
+
/* ══════════════ media-card · 封面卡 ══════════════ */
|
|
26
|
+
.media-card {
|
|
27
|
+
position: relative;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
border-radius: var(--radius-lg);
|
|
30
|
+
transition: transform 300ms var(--ease-out), box-shadow 300ms var(--ease-out);
|
|
31
|
+
}
|
|
32
|
+
.media-card:hover {
|
|
33
|
+
transform: translateY(-6px);
|
|
34
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2), 0 0 20px var(--token-accent-glow);
|
|
35
|
+
}
|
|
36
|
+
.media-card-cover {
|
|
37
|
+
display: block;
|
|
38
|
+
width: 100%;
|
|
39
|
+
aspect-ratio: 2 / 3;
|
|
40
|
+
object-fit: cover;
|
|
41
|
+
}
|
|
42
|
+
.media-card-overlay {
|
|
43
|
+
position: absolute; left: 0; right: 0; bottom: 0;
|
|
44
|
+
padding: 32px 12px 10px;
|
|
45
|
+
background: linear-gradient(to top, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0.35) 65%, transparent);
|
|
46
|
+
backdrop-filter: blur(10px);
|
|
47
|
+
-webkit-backdrop-filter: blur(10px);
|
|
48
|
+
color: #fff;
|
|
49
|
+
transform: translateY(100%);
|
|
50
|
+
transition: transform 200ms var(--ease-out);
|
|
51
|
+
pointer-events: none;
|
|
52
|
+
}
|
|
53
|
+
.media-card:hover .media-card-overlay {
|
|
54
|
+
transform: translateY(0);
|
|
55
|
+
transition-delay: 80ms;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* ══════════════ rating · 星级评分 ══════════════ */
|
|
59
|
+
.rating { display: inline-flex; align-items: center; gap: 2px; }
|
|
60
|
+
.rating-star {
|
|
61
|
+
padding: 2px;
|
|
62
|
+
border-radius: var(--radius-xs);
|
|
63
|
+
background: none; border: 0;
|
|
64
|
+
cursor: pointer;
|
|
65
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
66
|
+
}
|
|
67
|
+
.rating-star svg {
|
|
68
|
+
width: 18px; height: 18px; display: block;
|
|
69
|
+
fill: transparent;
|
|
70
|
+
stroke: var(--token-line-strong);
|
|
71
|
+
stroke-width: 1.6;
|
|
72
|
+
transition: fill var(--duration-normal) var(--ease-out), stroke var(--duration-normal) var(--ease-out);
|
|
73
|
+
}
|
|
74
|
+
.rating--sm .rating-star svg { width: 14px; height: 14px; }
|
|
75
|
+
.rating--lg .rating-star svg { width: 22px; height: 22px; }
|
|
76
|
+
.rating-star.is-filled svg { fill: var(--token-warning); stroke: var(--token-warning); }
|
|
77
|
+
.rating-star.is-half svg {
|
|
78
|
+
fill: color-mix(in srgb, var(--token-warning) 50%, transparent);
|
|
79
|
+
stroke: var(--token-warning);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* ══════════════ carousel · 轮播(behaviors/carousel 配套) ══════════════
|
|
83
|
+
* DOM 契约:
|
|
84
|
+
* <div class="carousel">
|
|
85
|
+
* <div class="carousel-track"><div class="carousel-slide">…</div>×n</div>
|
|
86
|
+
* <button class="carousel-arrow carousel-arrow--prev">…</button>
|
|
87
|
+
* <button class="carousel-arrow carousel-arrow--next">…</button>
|
|
88
|
+
* <div class="carousel-dots"></div> <!-- dots 由 behavior 自动生成 -->
|
|
89
|
+
* </div>
|
|
90
|
+
*/
|
|
91
|
+
.carousel {
|
|
92
|
+
position: relative;
|
|
93
|
+
overflow: hidden;
|
|
94
|
+
border-radius: var(--radius-lg);
|
|
95
|
+
background: var(--token-control);
|
|
96
|
+
}
|
|
97
|
+
.carousel-track {
|
|
98
|
+
display: flex;
|
|
99
|
+
transition: transform 300ms var(--ease-out);
|
|
100
|
+
}
|
|
101
|
+
.carousel-slide { width: 100%; flex-shrink: 0; }
|
|
102
|
+
.carousel-arrow {
|
|
103
|
+
position: absolute; top: 50%; transform: translateY(-50%);
|
|
104
|
+
width: 32px; height: 32px;
|
|
105
|
+
border-radius: var(--radius-full);
|
|
106
|
+
background: color-mix(in srgb, var(--token-card) 78%, transparent);
|
|
107
|
+
border: 1px solid var(--token-outline-soft);
|
|
108
|
+
color: var(--token-text);
|
|
109
|
+
display: flex; align-items: center; justify-content: center;
|
|
110
|
+
backdrop-filter: blur(4px);
|
|
111
|
+
-webkit-backdrop-filter: blur(4px);
|
|
112
|
+
box-shadow: var(--token-shadow-card);
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
transition: background-color var(--duration-normal) var(--ease-out), transform var(--duration-normal) var(--ease-out);
|
|
115
|
+
}
|
|
116
|
+
.carousel-arrow:hover { background: var(--token-card-strong); }
|
|
117
|
+
.carousel-arrow:active { transform: translateY(-50%) scale(0.95); }
|
|
118
|
+
.carousel-arrow svg { width: 16px; height: 16px; }
|
|
119
|
+
.carousel-arrow--prev { left: 8px; }
|
|
120
|
+
.carousel-arrow--next { right: 8px; }
|
|
121
|
+
.carousel-dots {
|
|
122
|
+
position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%);
|
|
123
|
+
display: flex; gap: 6px;
|
|
124
|
+
}
|
|
125
|
+
.carousel-dot {
|
|
126
|
+
width: 6px; height: 6px; padding: 0;
|
|
127
|
+
border: 0; border-radius: var(--radius-full);
|
|
128
|
+
background: color-mix(in srgb, var(--token-card) 70%, transparent);
|
|
129
|
+
cursor: pointer;
|
|
130
|
+
transition: width var(--duration-normal) var(--ease-out), background-color var(--duration-normal) var(--ease-out);
|
|
131
|
+
}
|
|
132
|
+
.carousel-dot:hover { background: color-mix(in srgb, var(--token-accent) 70%, transparent); }
|
|
133
|
+
.carousel-dot.active { width: 20px; background: var(--token-accent); }
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @icen.ai/ui — Component: menu(菜单面板,与 behaviors/dropdown、context-menu 配套)
|
|
3
|
+
* 面板由 JS portal 到 document.body 并按 fixed 定位;data-side 决定进场位移方向。
|
|
4
|
+
* 规格源自 opengal overlay/dropdown + overlay/context-menu。
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
.menu {
|
|
8
|
+
position: fixed; z-index: var(--z-popover);
|
|
9
|
+
min-width: 180px; max-height: min(70vh, 420px); overflow-y: auto;
|
|
10
|
+
margin: 0; padding: 4px;
|
|
11
|
+
background: color-mix(in srgb, var(--token-card-strong) 92%, transparent);
|
|
12
|
+
backdrop-filter: blur(24px);
|
|
13
|
+
border: 1px solid var(--token-outline);
|
|
14
|
+
box-shadow: var(--token-shadow-overlay);
|
|
15
|
+
border-radius: var(--radius-lg);
|
|
16
|
+
animation: icen-menu-in 150ms var(--ease-out);
|
|
17
|
+
}
|
|
18
|
+
.menu[data-side='top'] { animation-name: icen-menu-in-top; }
|
|
19
|
+
|
|
20
|
+
/* 右键菜单修正(opengal context-menu:min 218 / max 286 / z 9999 / 入场 100ms) */
|
|
21
|
+
.menu--context {
|
|
22
|
+
min-width: 218px; max-width: 286px; z-index: 9999;
|
|
23
|
+
animation-duration: 100ms;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/* ── 分组标签 / 头(context-menu 的 header 项) ── */
|
|
27
|
+
.menu-label {
|
|
28
|
+
padding: 4px 8px; font-size: 10px; font-weight: 600;
|
|
29
|
+
text-transform: uppercase; letter-spacing: 0.08em;
|
|
30
|
+
color: var(--token-text-faint);
|
|
31
|
+
}
|
|
32
|
+
.menu-header { padding: 8px 10px 6px; }
|
|
33
|
+
.menu-header-label {
|
|
34
|
+
display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
35
|
+
font-size: 11px; font-weight: 500; line-height: 16px; color: var(--token-text);
|
|
36
|
+
}
|
|
37
|
+
.menu-header-desc {
|
|
38
|
+
display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
39
|
+
font-size: 10px; line-height: 14px; color: var(--token-text-faint);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* ── 菜单项 ── */
|
|
43
|
+
.menu-item {
|
|
44
|
+
position: relative; display: flex; align-items: center; gap: 8px;
|
|
45
|
+
width: 100%; padding: 6px 8px;
|
|
46
|
+
background: none; border: 0; font: inherit; font-size: 12px; text-align: left;
|
|
47
|
+
color: var(--token-text);
|
|
48
|
+
border-radius: var(--radius-md); cursor: pointer; user-select: none;
|
|
49
|
+
}
|
|
50
|
+
.menu-item.is-highlighted, .menu-item:focus {
|
|
51
|
+
background: var(--token-surface-hover); color: var(--token-accent); outline: none;
|
|
52
|
+
}
|
|
53
|
+
.menu-item--danger { color: var(--token-error); }
|
|
54
|
+
.menu-item--danger.is-highlighted, .menu-item--danger:focus {
|
|
55
|
+
background: var(--token-error-muted); color: var(--token-error);
|
|
56
|
+
}
|
|
57
|
+
.menu-item.is-disabled, .menu-item:disabled { opacity: 0.5; pointer-events: none; }
|
|
58
|
+
|
|
59
|
+
.menu-item-icon {
|
|
60
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
61
|
+
width: 14px; height: 14px; flex-shrink: 0;
|
|
62
|
+
}
|
|
63
|
+
.menu-item-icon:empty { width: 16px; height: auto; } /* 无图标时 16px 宽占位 */
|
|
64
|
+
.menu-item-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
65
|
+
.menu-item-sub { display: block; font-size: 10px; line-height: 1.2; color: var(--token-text-faint); }
|
|
66
|
+
.menu-item-shortcut { font-size: 10px; color: var(--token-text-faint); }
|
|
67
|
+
|
|
68
|
+
/* 勾选项:左勾 ✓ + 缩进 */
|
|
69
|
+
.menu-item-check {
|
|
70
|
+
position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
|
|
71
|
+
color: var(--token-accent); font-size: 12px; line-height: 1;
|
|
72
|
+
}
|
|
73
|
+
.menu-item--checked { padding-left: 28px; }
|
|
74
|
+
|
|
75
|
+
.menu-separator { margin: 6px 8px; height: 1px; background: var(--token-line-soft); }
|
|
76
|
+
|
|
77
|
+
/* ── 进场:fade + scale(.95→1),bottom 从上方 8px 滑入、top 从下方 8px 滑入 ── */
|
|
78
|
+
@keyframes icen-menu-in {
|
|
79
|
+
from { opacity: 0; transform: scale(0.95) translateY(-8px); }
|
|
80
|
+
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
81
|
+
}
|
|
82
|
+
@keyframes icen-menu-in-top {
|
|
83
|
+
from { opacity: 0; transform: scale(0.95) translateY(8px); }
|
|
84
|
+
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
85
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @icen.ai/ui — Component: modal(对话框 + 贴边 Sheet,与 behaviors/modal 配套)
|
|
3
|
+
* 契约:<div class="modal-backdrop" data-modal="id" hidden> > .modal[role=dialog]
|
|
4
|
+
* 规格源自 opengal overlay/dialog:backdrop fadeIn 150ms、面板 dialogScaleIn
|
|
5
|
+
* 200ms cubic-bezier(.16,1,.3,1)、Sheet 四向 slideIn 200ms 位移 40px。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.modal-backdrop {
|
|
9
|
+
position: fixed; inset: 0; z-index: var(--z-dialog);
|
|
10
|
+
display: flex; align-items: center; justify-content: center; padding: 16px;
|
|
11
|
+
background: rgba(0, 0, 0, 0.45); backdrop-filter: blur(4px);
|
|
12
|
+
animation: icen-modal-fade-in 150ms ease-out;
|
|
13
|
+
}
|
|
14
|
+
.modal-backdrop[hidden] { display: none; }
|
|
15
|
+
|
|
16
|
+
.modal {
|
|
17
|
+
display: flex; flex-direction: column; overflow: hidden;
|
|
18
|
+
width: 100%; max-width: 480px; max-height: calc(100vh - 32px);
|
|
19
|
+
background: var(--token-card-strong); color: var(--token-text);
|
|
20
|
+
border: 1px solid var(--token-outline);
|
|
21
|
+
box-shadow: var(--token-shadow-overlay);
|
|
22
|
+
border-radius: var(--radius-xl);
|
|
23
|
+
animation: icen-modal-scale-in 200ms cubic-bezier(0.16, 1, 0.3, 1);
|
|
24
|
+
}
|
|
25
|
+
.modal:focus { outline: none; }
|
|
26
|
+
|
|
27
|
+
/* ── 尺寸档 ── */
|
|
28
|
+
.modal--sm { max-width: 360px; }
|
|
29
|
+
.modal--lg { max-width: 640px; }
|
|
30
|
+
.modal--xl { max-width: 800px; }
|
|
31
|
+
.modal--full { width: calc(100vw - 32px); max-width: none; height: calc(100vh - 32px); max-height: none; }
|
|
32
|
+
|
|
33
|
+
/* ── 头部 / 主体 / 底栏 ── */
|
|
34
|
+
.modal-header {
|
|
35
|
+
display: flex; align-items: flex-start; justify-content: space-between;
|
|
36
|
+
gap: 16px; padding: 20px 24px 12px;
|
|
37
|
+
}
|
|
38
|
+
.modal-title { margin: 0; font-size: 15px; font-weight: 600; }
|
|
39
|
+
.modal-description { margin: 2px 0 0; font-size: 12px; color: var(--token-text-muted); }
|
|
40
|
+
.modal-close {
|
|
41
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
42
|
+
width: 28px; height: 28px; padding: 0; flex-shrink: 0;
|
|
43
|
+
background: none; border: 0; cursor: pointer;
|
|
44
|
+
color: var(--token-text-faint); font-size: 16px; line-height: 1;
|
|
45
|
+
border-radius: var(--radius-md);
|
|
46
|
+
}
|
|
47
|
+
.modal-close:hover { background: var(--token-surface-hover); color: var(--token-text); }
|
|
48
|
+
|
|
49
|
+
.modal-body { flex: 1; overflow-y: auto; padding: 0 24px 20px; }
|
|
50
|
+
.modal-footer {
|
|
51
|
+
display: flex; justify-content: flex-end; gap: 8px; padding: 16px 24px;
|
|
52
|
+
border-top: 1px solid color-mix(in srgb, var(--token-line-soft) 40%, transparent);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* ── Sheet 变体:面板 fixed 贴边,radius 只保留非贴边侧 ── */
|
|
56
|
+
.modal--sheet-left, .modal--sheet-right, .modal--sheet-top, .modal--sheet-bottom {
|
|
57
|
+
position: fixed; max-width: none; max-height: none; border-radius: 0;
|
|
58
|
+
}
|
|
59
|
+
.modal--sheet-left {
|
|
60
|
+
left: 0; top: 0; bottom: 0; width: 360px; height: 100%;
|
|
61
|
+
border-radius: 0 var(--radius-xl) var(--radius-xl) 0;
|
|
62
|
+
animation-name: icen-modal-slide-left;
|
|
63
|
+
}
|
|
64
|
+
.modal--sheet-right {
|
|
65
|
+
right: 0; top: 0; bottom: 0; width: 360px; height: 100%;
|
|
66
|
+
border-radius: var(--radius-xl) 0 0 var(--radius-xl);
|
|
67
|
+
animation-name: icen-modal-slide-right;
|
|
68
|
+
}
|
|
69
|
+
.modal--sheet-top {
|
|
70
|
+
top: 0; left: 0; right: 0; width: 100%; height: 300px;
|
|
71
|
+
border-radius: 0 0 var(--radius-xl) var(--radius-xl);
|
|
72
|
+
animation-name: icen-modal-slide-top;
|
|
73
|
+
}
|
|
74
|
+
.modal--sheet-bottom {
|
|
75
|
+
bottom: 0; left: 0; right: 0; width: 100%; height: 300px;
|
|
76
|
+
border-radius: var(--radius-xl) var(--radius-xl) 0 0;
|
|
77
|
+
animation-name: icen-modal-slide-bottom;
|
|
78
|
+
}
|
|
79
|
+
.modal--sheet-left.modal--sheet-sm, .modal--sheet-right.modal--sheet-sm { width: 280px; }
|
|
80
|
+
.modal--sheet-left.modal--sheet-lg, .modal--sheet-right.modal--sheet-lg { width: 480px; }
|
|
81
|
+
.modal--sheet-top.modal--sheet-lg, .modal--sheet-bottom.modal--sheet-lg { height: 50vh; }
|
|
82
|
+
|
|
83
|
+
/* ── 进场动画(与 opengal src/index.css 同参数) ── */
|
|
84
|
+
@keyframes icen-modal-fade-in {
|
|
85
|
+
from { opacity: 0; }
|
|
86
|
+
to { opacity: 1; }
|
|
87
|
+
}
|
|
88
|
+
@keyframes icen-modal-scale-in {
|
|
89
|
+
from { opacity: 0; transform: scale(0.96) translateY(8px); }
|
|
90
|
+
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
91
|
+
}
|
|
92
|
+
@keyframes icen-modal-slide-left {
|
|
93
|
+
from { opacity: 0; transform: translateX(-40px); }
|
|
94
|
+
to { opacity: 1; transform: translateX(0); }
|
|
95
|
+
}
|
|
96
|
+
@keyframes icen-modal-slide-right {
|
|
97
|
+
from { opacity: 0; transform: translateX(40px); }
|
|
98
|
+
to { opacity: 1; transform: translateX(0); }
|
|
99
|
+
}
|
|
100
|
+
@keyframes icen-modal-slide-top {
|
|
101
|
+
from { opacity: 0; transform: translateY(-40px); }
|
|
102
|
+
to { opacity: 1; transform: translateY(0); }
|
|
103
|
+
}
|
|
104
|
+
@keyframes icen-modal-slide-bottom {
|
|
105
|
+
from { opacity: 0; transform: translateY(40px); }
|
|
106
|
+
to { opacity: 1; transform: translateY(0); }
|
|
107
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @icen.ai/ui — Component: nav(玻璃顶栏,scroll 收缩配套 behaviors/nav)
|
|
3
|
+
* 用法:<nav class="nav nav--sticky" data-scroll-reactive>
|
|
4
|
+
* <div class="nav-left">…</div><div class="nav-center">…</div><div class="nav-right">…</div>
|
|
5
|
+
* </nav>
|
|
6
|
+
* 三段:.nav-left / .nav-center(flex:1 居中)/ .nav-right,整行补充用 .nav-bottom。
|
|
7
|
+
* 按钮:.nav-btn(HTML 组合 .motion .pressable 基元),.is-active / .is-disabled / .nav-btn--icon。
|
|
8
|
+
* 契约:sticky/fixed 挂 --z-chrome 层;data-scroll-reactive 时 behaviors/nav 依 scrollY>12 切
|
|
9
|
+
* .is-scrolled——未滚动更透且无边线,滚动后底色更实 + blur 16px。
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
.nav {
|
|
13
|
+
display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
|
|
14
|
+
height: 56px; padding: 0 16px;
|
|
15
|
+
background: var(--token-surface-glass);
|
|
16
|
+
backdrop-filter: blur(12px) saturate(1.1);
|
|
17
|
+
-webkit-backdrop-filter: blur(12px) saturate(1.1);
|
|
18
|
+
border-bottom: 1px solid var(--token-outline-soft);
|
|
19
|
+
transition: all var(--duration-slow) var(--ease-out);
|
|
20
|
+
}
|
|
21
|
+
/* 带整行 bottom 时放开固定高度,第一行仍保持 56px */
|
|
22
|
+
.nav:has(.nav-bottom) { height: auto; min-height: 56px; }
|
|
23
|
+
.nav--sticky { position: sticky; top: 0; z-index: var(--z-chrome); }
|
|
24
|
+
.nav--fixed { position: fixed; top: 0; left: 0; right: 0; z-index: var(--z-chrome); }
|
|
25
|
+
|
|
26
|
+
/* scroll-reactive:未滚动更透、底边线透明(滚动后由 .is-scrolled 接管) */
|
|
27
|
+
.nav[data-scroll-reactive]:not(.is-scrolled) {
|
|
28
|
+
background: color-mix(in srgb, var(--token-surface-glass) 70%, transparent);
|
|
29
|
+
backdrop-filter: blur(8px);
|
|
30
|
+
-webkit-backdrop-filter: blur(8px);
|
|
31
|
+
border-bottom-color: transparent;
|
|
32
|
+
}
|
|
33
|
+
.nav.is-scrolled {
|
|
34
|
+
background: color-mix(in srgb, var(--token-surface-glass) 92%, transparent);
|
|
35
|
+
backdrop-filter: blur(16px) saturate(1.2);
|
|
36
|
+
-webkit-backdrop-filter: blur(16px) saturate(1.2);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.nav-left, .nav-right { display: flex; align-items: center; gap: 4px; flex-shrink: 0; }
|
|
40
|
+
.nav-center { flex: 1; display: flex; align-items: center; justify-content: center; gap: 4px; }
|
|
41
|
+
.nav-bottom { width: 100%; }
|
|
42
|
+
|
|
43
|
+
.nav-btn {
|
|
44
|
+
display: inline-flex; align-items: center; gap: 6px;
|
|
45
|
+
border-radius: var(--radius-full); padding: 6px 12px;
|
|
46
|
+
font-size: 13px; color: var(--token-text-muted);
|
|
47
|
+
background: none; border: 0; cursor: pointer;
|
|
48
|
+
}
|
|
49
|
+
.nav-btn > svg { width: 14px; height: 14px; flex-shrink: 0; }
|
|
50
|
+
.nav-btn:not(.is-active):hover { color: var(--token-text); background: var(--token-control-hover); }
|
|
51
|
+
.nav-btn.is-active {
|
|
52
|
+
background: var(--token-accent); color: var(--token-on-accent);
|
|
53
|
+
font-weight: 500; box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
|
|
54
|
+
}
|
|
55
|
+
.nav-btn.is-disabled, .nav-btn:disabled { opacity: .4; pointer-events: none; }
|
|
56
|
+
.nav-btn--icon { padding: 6px 10px; }
|
|
57
|
+
.nav-btn--icon > svg { width: 15px; height: 15px; }
|
|
58
|
+
|
|
59
|
+
.nav-divider { width: 1px; height: 20px; margin: 0 2px; background: var(--token-outline-soft); }
|