agentcss 0.11.10 → 0.11.12
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/01-tokens/page.css +79 -0
- package/02-primitives/button/demo.html +5 -15
- package/02-primitives/card/demo.html +3 -13
- package/02-primitives/choice/demo.html +1 -0
- package/02-primitives/combobox/demo.html +38 -0
- package/02-primitives/date-range/demo.html +36 -0
- package/02-primitives/input/demo.html +5 -16
- package/02-primitives/popover/README.md +15 -0
- package/02-primitives/popover/demo.html +45 -0
- package/02-primitives/progress/demo.html +25 -0
- package/02-primitives/select/demo.html +46 -0
- package/02-primitives/skeleton/demo.html +28 -0
- package/03-patterns/content/demo.html +20 -0
- package/03-patterns/drawer/demo.html +36 -0
- package/03-patterns/dropdown/demo.html +39 -0
- package/03-patterns/list/demo.html +56 -0
- package/03-patterns/nav/demo.html +38 -1
- package/03-patterns/pagination/demo.html +40 -0
- package/03-patterns/reveal/demo.html +24 -0
- package/03-patterns/states/demo.html +25 -1
- package/03-patterns/tooltip/demo.html +27 -0
- package/03-patterns/tree/demo.html +43 -0
- package/04-recipes/analysis-report/demo.html +38 -0
- package/04-recipes/data-showcase/README.md +1 -0
- package/04-recipes/data-showcase/demo.html +29 -0
- package/04-recipes/detail-page/demo.html +28 -0
- package/04-recipes/report/demo.html +24 -0
- package/04-recipes/table/README.md +22 -0
- package/04-recipes/table/demo.html +39 -0
- package/CHANGELOG.md +131 -0
- package/CONTRIBUTING.md +11 -1
- package/ai/components.json +38 -10
- package/dist/01-tokens/page.css +1 -1
- package/dist/COSTS.md +1 -1
- package/index.html +1 -1
- package/package.json +1 -1
|
@@ -21,6 +21,21 @@
|
|
|
21
21
|
}
|
|
22
22
|
ul.demo-list { padding-left: var(--sp-5); color: var(--text-secondary); }
|
|
23
23
|
ul.demo-list li { margin: var(--sp-1) 0; }
|
|
24
|
+
.dr-bar {
|
|
25
|
+
display: flex; align-items: center; justify-content: space-between;
|
|
26
|
+
gap: var(--sp-3);
|
|
27
|
+
padding: var(--sp-2) var(--sp-3);
|
|
28
|
+
background: var(--surface-raised);
|
|
29
|
+
border: 1px solid var(--border-decor);
|
|
30
|
+
border-radius: var(--r-sm);
|
|
31
|
+
}
|
|
32
|
+
.dr-bar__title { font-size: var(--fs-sm); font-weight: 500; }
|
|
33
|
+
.dr-tiny {
|
|
34
|
+
width: 24px; height: 24px;
|
|
35
|
+
display: flex; align-items: center; justify-content: center;
|
|
36
|
+
background: none; border: 0; border-radius: var(--r-xs);
|
|
37
|
+
color: var(--text-secondary); font-size: 14px; line-height: 1; cursor: pointer;
|
|
38
|
+
}
|
|
24
39
|
</style>
|
|
25
40
|
</head>
|
|
26
41
|
<body class="page page">
|
|
@@ -49,6 +64,27 @@ ul.demo-list li { margin: var(--sp-1) 0; }
|
|
|
49
64
|
<button class="btn btn--primary" id="b2">打开(焦点落在第二个按钮)</button>
|
|
50
65
|
</div>
|
|
51
66
|
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
70
|
+
<div class="cmp">
|
|
71
|
+
<div class="cmp__pane cmp__bad" data-bad="button.dr-tiny|h|<=24">
|
|
72
|
+
<h3>❌ 常见写法:关闭按钮做小</h3>
|
|
73
|
+
<div class="dr-bar" aria-hidden="true">
|
|
74
|
+
<span class="dr-bar__title">筛选</span>
|
|
75
|
+
<button class="dr-tiny" type="button" tabindex="-1" aria-label="关闭">×</button>
|
|
76
|
+
</div>
|
|
77
|
+
<p class="cmp__why">关闭是**独立目标**:抽屉滑进来之后,用户第一件事就是找它。24px 的叉在触屏上要瞄准,点偏了就点到了背后的内容。</p>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="cmp__pane cmp__good" data-good="button.drawer__close|h|>=44">
|
|
80
|
+
<h3>✅ 本库:<code>drawer__close</code> 44px</h3>
|
|
81
|
+
<div class="dr-bar" aria-hidden="true">
|
|
82
|
+
<span class="dr-bar__title">筛选</span>
|
|
83
|
+
<button class="drawer__close" type="button" tabindex="-1" aria-label="关闭">×</button>
|
|
84
|
+
</div>
|
|
85
|
+
<p class="cmp__why">命中区 44px(<code>drawer.css</code> 里写明"关闭按钮是独立目标,用 44")—— 字形还是 20px,只是可点范围大了。</p>
|
|
86
|
+
</div>
|
|
87
|
+
</div>
|
|
52
88
|
</main>
|
|
53
89
|
|
|
54
90
|
<script src="drawer.js"></script>
|
|
@@ -19,6 +19,20 @@
|
|
|
19
19
|
font-family: var(--font-mono, monospace); font-size: var(--fs-xs);
|
|
20
20
|
color: var(--text-secondary); min-height: 2.6em;
|
|
21
21
|
}
|
|
22
|
+
.dd-cap { margin: 0 0 var(--sp-2); font-size: var(--fs-sm); color: var(--text-tertiary); }
|
|
23
|
+
.dd-demo {
|
|
24
|
+
list-style: none; margin: 0; padding: var(--sp-1);
|
|
25
|
+
background: var(--surface-raised);
|
|
26
|
+
border: 1px solid var(--border-decor);
|
|
27
|
+
border-radius: var(--r-sm);
|
|
28
|
+
}
|
|
29
|
+
/* 反例专用:24px 一行(本库把它量出来过,见 dropdown.css 的复盘) */
|
|
30
|
+
.dd-bug {
|
|
31
|
+
display: flex; align-items: center;
|
|
32
|
+
height: 24px; padding: 0 var(--sp-3);
|
|
33
|
+
border-radius: var(--r-xs);
|
|
34
|
+
font-size: var(--fs-sm); cursor: pointer;
|
|
35
|
+
}
|
|
22
36
|
</style>
|
|
23
37
|
</head>
|
|
24
38
|
<body class="page page">
|
|
@@ -73,6 +87,31 @@
|
|
|
73
87
|
</div>
|
|
74
88
|
</div>
|
|
75
89
|
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
93
|
+
<div class="cmp">
|
|
94
|
+
<div class="cmp__pane cmp__bad" data-bad="li.dd-bug|h|<=24">
|
|
95
|
+
<h3>❌ 常见写法:菜单项只有 24px</h3>
|
|
96
|
+
<p class="dd-cap">下拉菜单 · 每项高度</p>
|
|
97
|
+
<ul class="dd-demo" aria-hidden="true">
|
|
98
|
+
<li class="dd-bug">按涨跌幅</li>
|
|
99
|
+
<li class="dd-bug">按市值</li>
|
|
100
|
+
<li class="dd-bug">按成交额</li>
|
|
101
|
+
</ul>
|
|
102
|
+
<p class="cmp__why">24px 一行:手指点下去会压到隔壁,触屏用户每点错一次就得重来。本库在这块踩过更隐蔽的坑 —— 写 <code>min-height: 44px</code>,量出来只有 24px(<code><li></code> 是 <code>display:list-item</code>),所以现在用的是显式 <code>height</code>。</p>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="cmp__pane cmp__good" data-good="li.dd__item|h|>=44">
|
|
105
|
+
<h3>✅ 本库:显式 <code>height: 44px</code></h3>
|
|
106
|
+
<p class="dd-cap">下拉菜单 · 每项高度</p>
|
|
107
|
+
<ul class="dd-demo" aria-hidden="true">
|
|
108
|
+
<li class="dd__item">按涨跌幅</li>
|
|
109
|
+
<li class="dd__item">按市值</li>
|
|
110
|
+
<li class="dd__item">按成交额</li>
|
|
111
|
+
</ul>
|
|
112
|
+
<p class="cmp__why">同一个 44,<code>min-height</code> 与 <code>height</code> 在列表项上是两回事。桌面小屏看不出来,只有量了才发现 —— 所以这里把两种结果并排摆出来。</p>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
76
115
|
</main>
|
|
77
116
|
|
|
78
117
|
<script src="dropdown.js"></script>
|
|
@@ -17,6 +17,17 @@
|
|
|
17
17
|
p { max-width: var(--measure-prose); margin: 0 0 var(--sp-3); }
|
|
18
18
|
p.small { font-size: var(--fs-xs); color: var(--text-tertiary); line-height: 1.65; }
|
|
19
19
|
.bar { display: flex; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-4); }
|
|
20
|
+
.ls-demo { list-style: none; margin: 0; padding: 0; background: var(--surface-raised);
|
|
21
|
+
border: 1px solid var(--border-decor); border-radius: var(--r-sm); }
|
|
22
|
+
.ls-clip { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
23
|
+
/* 🔴 反例栏演示的是"长文本直接换行"。.list__title 自带 ellipsis,
|
|
24
|
+
不把 nowrap 取消掉,两栏就一模一样(实测:这个错犯过)。 */
|
|
25
|
+
.ls-wrap { white-space: normal; }
|
|
26
|
+
/* 🔴 对照块里的列表必须**和栏宽无关**:这一块演示的是"长文本折行",
|
|
27
|
+
而折行取决于行宽 —— 宽屏(1440px,栏约 490px)下它就不折了,
|
|
28
|
+
反例在那种宽度上根本不成立(实测:900px 折成 2 行,1440px 只有 1 行)。
|
|
29
|
+
钉住 300px 之后,任何视口宽度下都是同一个样子。 */
|
|
30
|
+
.cmp .ls-demo { max-width: 300px; }
|
|
20
31
|
</style>
|
|
21
32
|
</head>
|
|
22
33
|
<body class="page page">
|
|
@@ -85,6 +96,51 @@ p.small { font-size: var(--fs-xs); color: var(--text-tertiary); line-height: 1.6
|
|
|
85
96
|
这一点与欧美惯例相反,是刻意的——做反了会被当成数据出错。
|
|
86
97
|
</p>
|
|
87
98
|
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
102
|
+
<div class="cmp">
|
|
103
|
+
<div class="cmp__pane cmp__bad" data-bad="li.list__item|h|>=80">
|
|
104
|
+
<h3>❌ 常见写法:长文本直接换行</h3>
|
|
105
|
+
<ul class="ls-demo" aria-hidden="true">
|
|
106
|
+
<li class="list__item">
|
|
107
|
+
<span class="list__main">
|
|
108
|
+
<span class="list__title ls-wrap">长鑫存储技术有限公司(合肥)2026 年三季报</span>
|
|
109
|
+
<span class="list__meta">12 条记录 · 半导体</span>
|
|
110
|
+
</span>
|
|
111
|
+
<span class="list__value num list__value--up">+3.21%</span>
|
|
112
|
+
</li>
|
|
113
|
+
<li class="list__item">
|
|
114
|
+
<span class="list__main">
|
|
115
|
+
<span class="list__title">中芯国际集成电路制造</span>
|
|
116
|
+
<span class="list__meta">8 条记录 · 半导体</span>
|
|
117
|
+
</span>
|
|
118
|
+
<span class="list__value num list__value--down">−1.05%</span>
|
|
119
|
+
</li>
|
|
120
|
+
</ul>
|
|
121
|
+
<p class="cmp__why">第一行折成两行,行高就不一样了:一屏能扫到的条目从 8 条掉到 5 条,而且"哪一行对应哪个数字"要重新对。</p>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="cmp__pane cmp__good" data-good="li.list__item|h|<=70">
|
|
124
|
+
<h3>✅ 本库:单行省略 + <code>title</code></h3>
|
|
125
|
+
<ul class="ls-demo" aria-hidden="true">
|
|
126
|
+
<li class="list__item">
|
|
127
|
+
<span class="list__main">
|
|
128
|
+
<span class="list__title ls-clip">长鑫存储技术有限公司(合肥)2026 年三季报</span>
|
|
129
|
+
<span class="list__meta">12 条记录 · 半导体</span>
|
|
130
|
+
</span>
|
|
131
|
+
<span class="list__value num list__value--up">+3.21%</span>
|
|
132
|
+
</li>
|
|
133
|
+
<li class="list__item">
|
|
134
|
+
<span class="list__main">
|
|
135
|
+
<span class="list__title ls-clip">中芯国际集成电路制造</span>
|
|
136
|
+
<span class="list__meta">8 条记录 · 半导体</span>
|
|
137
|
+
</span>
|
|
138
|
+
<span class="list__value num list__value--down">−1.05%</span>
|
|
139
|
+
</li>
|
|
140
|
+
</ul>
|
|
141
|
+
<p class="cmp__why">列表是"扫"的不是"读"的:标题单行截断,完整名称放 <code>title</code>,悬停可看。行高一致,眼睛才能顺着往下扫。</p>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
88
144
|
</main>
|
|
89
145
|
|
|
90
146
|
<script src="flip.js"></script>
|
|
@@ -31,6 +31,11 @@ p.small { font-size: var(--fs-xs); color: var(--text-tertiary); line-height: 1.7
|
|
|
31
31
|
.spacer { height: 55vh; }
|
|
32
32
|
|
|
33
33
|
/* 让目录高亮有滚动空间 */
|
|
34
|
+
.toc-clip { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
35
|
+
/* 🔴 反例栏要演示的是"不写 nowrap 会怎样"。.toc__link 自带 nowrap,
|
|
36
|
+
所以只在反例栏里把它取消掉 —— 不取消的话两栏都是 1 行,
|
|
37
|
+
反例就变成"被裁掉",而标题说的是"换行"(实测:这个错犯过)。 */
|
|
38
|
+
.toc-wrap { white-space: normal; }
|
|
34
39
|
</style>
|
|
35
40
|
</head>
|
|
36
41
|
<body class="page page">
|
|
@@ -112,7 +117,39 @@ p.small { font-size: var(--fs-xs); color: var(--text-tertiary); line-height: 1.7
|
|
|
112
117
|
早期版本用的是它 + <code>rootMargin</code>,结果滚到两节之间时观察区里
|
|
113
118
|
一个 section 都没有,高亮卡住不动 —— 现在改成纯计算,任何滚动位置都有答案。
|
|
114
119
|
</p>
|
|
115
|
-
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
123
|
+
<!-- 目录项一律指向本页真实小节(`#mem` / `#sched` / `#sim`):假锚点
|
|
124
|
+
(`href="#x"`)点下去会跳到页面顶部,读者以为"目录坏了"。
|
|
125
|
+
第一条故意写得长 —— 真实文档的长章节名就是这样,能不能单行是这条的判据。 -->
|
|
126
|
+
<div class="cmp">
|
|
127
|
+
<div class="cmp__pane cmp__bad" data-bad="a.toc__link|lines|>=2">
|
|
128
|
+
<h3>❌ 常见写法:目录项允许换行</h3>
|
|
129
|
+
<nav class="toc" aria-label="示例目录" aria-hidden="true">
|
|
130
|
+
<p class="toc__title">本页</p>
|
|
131
|
+
<ul class="toc__list">
|
|
132
|
+
<li><a class="toc__link toc-wrap" href="#mem" tabindex="-1">存储器构成与 2026 年三季度的产能爬坡节奏与毛利口径拆解</a></li>
|
|
133
|
+
<li><a class="toc__link" href="#sched" tabindex="-1">优先级与准入</a></li>
|
|
134
|
+
<li><a class="toc__link" href="#sim" tabindex="-1">把它跑起来</a></li>
|
|
135
|
+
</ul>
|
|
136
|
+
</nav>
|
|
137
|
+
<p class="cmp__why">一条目录折成两行,下面两条就都被推下去了 —— 目录的价值是"一眼看到全文结构",行高一变,结构感就没了。</p>
|
|
138
|
+
</div>
|
|
139
|
+
<div class="cmp__pane cmp__good" data-good="a.toc__link|lines|<=1">
|
|
140
|
+
<h3>✅ 本库:单行、超出省略</h3>
|
|
141
|
+
<nav class="toc" aria-label="示例目录">
|
|
142
|
+
<p class="toc__title">本页</p>
|
|
143
|
+
<ul class="toc__list">
|
|
144
|
+
<li><a class="toc__link toc-clip" href="#mem">存储器构成与 2026 年三季度的产能爬坡节奏与毛利口径拆解</a></li>
|
|
145
|
+
<li><a class="toc__link" href="#sched">优先级与准入</a></li>
|
|
146
|
+
<li><a class="toc__link" href="#sim">把它跑起来</a></li>
|
|
147
|
+
</ul>
|
|
148
|
+
</nav>
|
|
149
|
+
<p class="cmp__why">目录项单行、超出省略:宁可截断,也要保住"三条等高"的节奏。读者扫的是结构,不是一个条目的全名。</p>
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
</main>
|
|
116
153
|
|
|
117
154
|
</div>
|
|
118
155
|
|
|
@@ -30,6 +30,7 @@ th { font-size: var(--fs-xs); color: var(--text-secondary); font-weight: 500; }
|
|
|
30
30
|
.row .v { font-family: var(--mono); font-variant-numeric: tabular-nums; }
|
|
31
31
|
.live-echo { margin: var(--sp-3) 0 0; font-size: var(--fs-xs); color: var(--text-tertiary); }
|
|
32
32
|
.live-echo b { color: var(--text-secondary); font-family: var(--mono); }
|
|
33
|
+
.pagination__list { flex-wrap: wrap; }
|
|
33
34
|
</style>
|
|
34
35
|
</head>
|
|
35
36
|
<body class="page page">
|
|
@@ -118,6 +119,45 @@ th { font-size: var(--fs-xs); color: var(--text-secondary); font-weight: 500; }
|
|
|
118
119
|
⇒ <b>不产生横向溢出</b>。
|
|
119
120
|
</p>
|
|
120
121
|
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
125
|
+
<div class="cmp">
|
|
126
|
+
<div class="cmp__pane cmp__bad" data-bad="li.pagination__item|count|>7">
|
|
127
|
+
<h3>❌ 常见写法:页码全铺开</h3>
|
|
128
|
+
<nav aria-label="分页示例" aria-hidden="true">
|
|
129
|
+
<ul class="pagination__list">
|
|
130
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=1" aria-label="第 1 页" tabindex="-1">1</a></li>
|
|
131
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=2" aria-label="第 2 页" tabindex="-1">2</a></li>
|
|
132
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=3" aria-label="第 3 页" tabindex="-1">3</a></li>
|
|
133
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=4" aria-label="第 4 页" tabindex="-1">4</a></li>
|
|
134
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=5" aria-label="第 5 页" tabindex="-1">5</a></li>
|
|
135
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=6" aria-label="第 6 页" tabindex="-1">6</a></li>
|
|
136
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=7" aria-label="第 7 页" tabindex="-1">7</a></li>
|
|
137
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=8" aria-label="第 8 页" tabindex="-1">8</a></li>
|
|
138
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=9" aria-label="第 9 页" tabindex="-1">9</a></li>
|
|
139
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=10" aria-label="第 10 页" tabindex="-1">10</a></li>
|
|
140
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=11" aria-label="第 11 页" tabindex="-1">11</a></li>
|
|
141
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=12" aria-label="第 12 页" tabindex="-1">12</a></li>
|
|
142
|
+
</ul>
|
|
143
|
+
</nav>
|
|
144
|
+
<p class="cmp__why">12 个页码硬塞进一行,窄屏上要么换行、要么每个都挤到点不中。而 4~10 页其实是读者最不会去点的区间。</p>
|
|
145
|
+
</div>
|
|
146
|
+
<div class="cmp__pane cmp__good" data-good="li.pagination__item|count|<=7">
|
|
147
|
+
<h3>✅ 本库:7 个槽位封顶 + 省略号</h3>
|
|
148
|
+
<nav aria-label="分页示例">
|
|
149
|
+
<ul class="pagination__list">
|
|
150
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=1" aria-label="第 1 页">1</a></li>
|
|
151
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=2" aria-label="第 2 页">2</a></li>
|
|
152
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=3" aria-label="第 3 页">3</a></li>
|
|
153
|
+
<li class="pagination__item"><span class="pagination__ellipsis">…</span></li>
|
|
154
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=11" aria-label="第 11 页">11</a></li>
|
|
155
|
+
<li class="pagination__item"><a class="pagination__link" href="?page=12" aria-label="第 12 页">12</a></li>
|
|
156
|
+
</ul>
|
|
157
|
+
</nav>
|
|
158
|
+
<p class="cmp__why">USWDS 的上限是 7 个槽位:首尾两页 + 当前页邻域,中间用 <code>pagination__ellipsis</code> 收掉。省略号不是装饰,是"这里还有页"的承诺 —— 所以没跳过页码时不许显示它。</p>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
121
161
|
</main>
|
|
122
162
|
|
|
123
163
|
<script src="pagination.js"></script>
|
|
@@ -22,6 +22,12 @@
|
|
|
22
22
|
border: 1px solid var(--border-subtle); font-size: var(--fs-sm); }
|
|
23
23
|
.rv-note { font-size: var(--fs-sm); color: var(--text-secondary); }
|
|
24
24
|
.rv-spacer { height: 40px; }
|
|
25
|
+
.rv-card { padding: var(--sp-3); background: var(--surface-raised);
|
|
26
|
+
border: 1px solid var(--border-decor); border-radius: var(--r-sm); min-height: 64px; }
|
|
27
|
+
.rv-card__t { margin: 0 0 var(--sp-1); font-size: var(--fs-sm); font-weight: 500; }
|
|
28
|
+
.rv-card__d { margin: 0; font-size: var(--fs-xs); color: var(--text-secondary); }
|
|
29
|
+
/* 反例专用:真的藏起来,用来演示"没有兜底"的后果 */
|
|
30
|
+
.rv-hidden { opacity: 0; }
|
|
25
31
|
</style>
|
|
26
32
|
</head>
|
|
27
33
|
<body class="page">
|
|
@@ -81,6 +87,24 @@
|
|
|
81
87
|
② 手动调 <code>Reveal.enable()</code>(本页就是这种,方便截图与演示)。<br>
|
|
82
88
|
都不写 ⇒ 完全不接管:内容可见、位置不偏。<strong>这是刻意的默认值。</strong>
|
|
83
89
|
</p>
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
93
|
+
<div class="cmp">
|
|
94
|
+
<div class="cmp__pane cmp__bad" data-bad=".rv-card|hidden|=1">
|
|
95
|
+
<h3>❌ 常见写法:藏了但没兜底</h3>
|
|
96
|
+
<div class="rv-card rv-hidden" aria-hidden="true"></div>
|
|
97
|
+
<p class="cmp__why">内容真被 <code>opacity: 0</code> 藏着,而脚本没跑起来(被拦、报错、CSP)—— 这一块就永远是空的,读者不知道这里有东西。</p>
|
|
98
|
+
</div>
|
|
99
|
+
<div class="cmp__pane cmp__good" data-good=".rv-card|hidden|=0">
|
|
100
|
+
<h3>✅ 本库:只有 <code>data-reveal-ready</code> 时才藏</h3>
|
|
101
|
+
<div class="rv-card" aria-hidden="true">
|
|
102
|
+
<p class="rv-card__t">2026 年三季度回顾</p>
|
|
103
|
+
<p class="rv-card__d">营收同比 +18%,毛利率 42.1%。</p>
|
|
104
|
+
</div>
|
|
105
|
+
<p class="cmp__why">隐藏只在 <code><html data-reveal-ready></code> 存在时生效:任何一步失败,内容就是全可见的。动画可以有代价,但代价不能是"看不见内容"。</p>
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
84
108
|
</main>
|
|
85
109
|
|
|
86
110
|
<script src="../../03-patterns/reveal/reveal.js"></script>
|
|
@@ -235,6 +235,30 @@ Array.prototype.forEach.call(document.querySelectorAll('.seg button'), function
|
|
|
235
235
|
});
|
|
236
236
|
|
|
237
237
|
show('content');
|
|
238
|
-
</script
|
|
238
|
+
</script>
|
|
239
|
+
|
|
240
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
241
|
+
<div class="cmp">
|
|
242
|
+
<div class="cmp__pane cmp__bad" data-bad=".state__action|count|=0">
|
|
243
|
+
<h3>❌ 常见写法:empty 态没有出口</h3>
|
|
244
|
+
<div class="state state--empty" aria-hidden="true">
|
|
245
|
+
<div class="state__icon">□</div>
|
|
246
|
+
<p class="state__title">这个时间范围下还没有记录</p>
|
|
247
|
+
<p class="state__desc">把范围放宽到 2023 年试试。</p>
|
|
248
|
+
</div>
|
|
249
|
+
<p class="cmp__why">说明写得很清楚,然后呢?用户读完只剩一个动作:刷新,或者退出。一条"没有数据"的提示不构成一个状态,它只是死路。</p>
|
|
250
|
+
</div>
|
|
251
|
+
<div class="cmp__pane cmp__good" data-good=".state__action|count|>=1">
|
|
252
|
+
<h3>✅ 本库:empty 态必须带动作</h3>
|
|
253
|
+
<div class="state state--empty" aria-hidden="true">
|
|
254
|
+
<div class="state__icon">□</div>
|
|
255
|
+
<p class="state__title">这个时间范围下还没有记录</p>
|
|
256
|
+
<p class="state__desc">把范围放宽到 2023 年试试。</p>
|
|
257
|
+
<div class="state__action"><button class="btn btn--sm btn--primary" type="button" tabindex="-1">放宽到 2023</button></div>
|
|
258
|
+
</div>
|
|
259
|
+
<p class="cmp__why"><code>state__action</code> 是 empty 态的一部分:要么给一条能走的路,要么别显示这个空状态。</p>
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
</main>
|
|
239
263
|
</body>
|
|
240
264
|
</html>
|
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
<style>
|
|
15
15
|
.row { display: flex; gap: var(--sp-4); flex-wrap: wrap; align-items: center; }
|
|
16
16
|
.pad { padding: var(--sp-9) 0; }
|
|
17
|
+
.tt-field { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-sm); }
|
|
18
|
+
.tt-label { font-weight: 500; }
|
|
19
|
+
.tt-icon { color: var(--text-tertiary); cursor: help; }
|
|
20
|
+
.tt-real { font-size: var(--fs-xs); color: var(--text-secondary); }
|
|
21
|
+
.tt-hint { margin: var(--sp-2) 0 0; font-size: var(--fs-xs); color: var(--text-tertiary); }
|
|
17
22
|
</style>
|
|
18
23
|
</head>
|
|
19
24
|
<body class="page page">
|
|
@@ -57,6 +62,28 @@
|
|
|
57
62
|
<button class="btn" id="good">导出 CSV</button>
|
|
58
63
|
</div>
|
|
59
64
|
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
68
|
+
<div class="cmp">
|
|
69
|
+
<div class="cmp__pane cmp__bad" data-bad=".tt-real|count|=0">
|
|
70
|
+
<h3>❌ 常见写法:关键信息只放在气泡里</h3>
|
|
71
|
+
<div class="tt-field" aria-hidden="true">
|
|
72
|
+
<span class="tt-label">账期</span>
|
|
73
|
+
<span class="tt-icon" title="按合同约定的账期填写,自然日">ⓘ</span>
|
|
74
|
+
</div>
|
|
75
|
+
<p class="tt-hint">(把鼠标停在那颗 ⓘ 上才看得到说明)</p>
|
|
76
|
+
<p class="cmp__why">触屏没有 hover,键盘用户也未必会停留 —— 这条说明对一半以上的读者等于不存在。判断标准很硬:<b>气泡里的字不能是"必须知道才能填对"的信息</b>。</p>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="cmp__pane cmp__good" data-good=".tt-real|count|>=1">
|
|
79
|
+
<h3>✅ 本库:该看见的写在页面上</h3>
|
|
80
|
+
<div class="tt-field" aria-hidden="true">
|
|
81
|
+
<span class="tt-label">账期</span>
|
|
82
|
+
<span class="tt-real">按合同约定的账期填写(自然日)</span>
|
|
83
|
+
</div>
|
|
84
|
+
<p class="cmp__why">tooltip 只用来<b>补一句</b>(快捷键、单位、来源),不用来补一个字段能不能填对。真的需要解释,就写在它旁边。</p>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
60
87
|
</main>
|
|
61
88
|
|
|
62
89
|
<script src="tooltip.js"></script>
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
color: var(--text-secondary); min-height: 3em;
|
|
25
25
|
}
|
|
26
26
|
.frame { padding: var(--sp-3); border: 1px solid var(--border-decor); border-radius: var(--r-md); }
|
|
27
|
+
.tr-demo { list-style: none; margin: 0; padding: 0; font-size: var(--fs-sm); }
|
|
28
|
+
.tr-demo ul { list-style: none; margin: 0; padding-inline-start: 1.4em; }
|
|
29
|
+
.tr-one { display: inline-block; width: 1em; font-size: .8em;
|
|
30
|
+
color: var(--text-tertiary); text-align: center; }
|
|
27
31
|
</style>
|
|
28
32
|
</head>
|
|
29
33
|
<body class="page page">
|
|
@@ -52,6 +56,45 @@
|
|
|
52
56
|
<div id="t2"></div>
|
|
53
57
|
</div>
|
|
54
58
|
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
62
|
+
<div class="cmp">
|
|
63
|
+
<div class="cmp__pane cmp__bad" data-bad="span.tr-one|uniq|=1">
|
|
64
|
+
<h3>❌ 常见写法:靠"旋转"表示状态</h3>
|
|
65
|
+
<ul class="tr-demo" role="tree" aria-label="文件树示例" aria-hidden="true">
|
|
66
|
+
<li class="tree__item" aria-expanded="true">
|
|
67
|
+
<div class="tree__node"><span class="tr-one">▸</span><span class="tree__label">src</span></div>
|
|
68
|
+
<ul role="group">
|
|
69
|
+
<li class="tree__item" aria-expanded="false">
|
|
70
|
+
<div class="tree__node"><span class="tr-one">▸</span><span class="tree__label">components</span></div>
|
|
71
|
+
</li>
|
|
72
|
+
<li class="tree__item">
|
|
73
|
+
<div class="tree__node"><span class="tr-one">▸</span><span class="tree__label">index.js</span></div>
|
|
74
|
+
</li>
|
|
75
|
+
</ul>
|
|
76
|
+
</li>
|
|
77
|
+
</ul>
|
|
78
|
+
<p class="cmp__why">三个节点长得一模一样:已展开的 src、收起的 components、叶子的 index.js 全是 ▸。旋转只能表达"变过",表达不了"现在是哪一态"。</p>
|
|
79
|
+
</div>
|
|
80
|
+
<div class="cmp__pane cmp__good" data-good="span.tree__marker|uniq|>=3">
|
|
81
|
+
<h3>✅ 本库:三态三种字形</h3>
|
|
82
|
+
<ul class="tr-demo" role="tree" aria-label="文件树示例" aria-hidden="true">
|
|
83
|
+
<li class="tree__item" aria-expanded="true">
|
|
84
|
+
<div class="tree__node"><span class="tree__marker"></span><span class="tree__label">src</span></div>
|
|
85
|
+
<ul role="group">
|
|
86
|
+
<li class="tree__item" aria-expanded="false">
|
|
87
|
+
<div class="tree__node"><span class="tree__marker"></span><span class="tree__label">components</span></div>
|
|
88
|
+
</li>
|
|
89
|
+
<li class="tree__item">
|
|
90
|
+
<div class="tree__node"><span class="tree__marker"></span><span class="tree__label">index.js</span></div>
|
|
91
|
+
</li>
|
|
92
|
+
</ul>
|
|
93
|
+
</li>
|
|
94
|
+
</ul>
|
|
95
|
+
<p class="cmp__why"><code>tree.css</code> 按 <code>aria-expanded</code> 给三种字形:▼ 展开 / ▶ 收起 / · 叶子。形状本身就是信息,不依赖动画。</p>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
55
98
|
</main>
|
|
56
99
|
|
|
57
100
|
<script src="tree.js"></script>
|
|
@@ -18,6 +18,21 @@
|
|
|
18
18
|
<link rel="stylesheet" href="../../09-assets/scientific-plot/scientific-plot.css">
|
|
19
19
|
|
|
20
20
|
<link rel="stylesheet" href="analysis-report.css">
|
|
21
|
+
<style>
|
|
22
|
+
.ar-g { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-2); }
|
|
23
|
+
.ar-g--ok { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
|
|
24
|
+
.ar-cell { padding: var(--sp-2); background: var(--surface-raised);
|
|
25
|
+
border: 1px solid var(--border-decor); border-radius: var(--r-xs);
|
|
26
|
+
font-size: var(--fs-xs); }
|
|
27
|
+
/* 反例的关键:这里**不能**写 overflow:hidden —— 一写,min-content 就变 0,
|
|
28
|
+
那个"列被长内容撑开"的毛病就被自己抹平了(第一版就是这么写坏的) */
|
|
29
|
+
.ar-long { font-family: var(--font-mono, monospace); white-space: nowrap; }
|
|
30
|
+
.ar-g--ok .ar-long { overflow: hidden; text-overflow: ellipsis; }
|
|
31
|
+
/* 🔴 对照块里的栅格宽度钉住:断言量的是"列宽有没有被长串顶开",
|
|
32
|
+
而列宽本身随栏宽变 —— 宽屏下两栏都变宽,绝对阈值就失去意义。
|
|
33
|
+
钉在 360px,任何视口宽度下量的都是同一个东西。 */
|
|
34
|
+
.cmp .ar-g { max-width: 360px; }
|
|
35
|
+
</style>
|
|
21
36
|
</head>
|
|
22
37
|
<body class="page">
|
|
23
38
|
<main class="wrap report">
|
|
@@ -222,6 +237,29 @@
|
|
|
222
237
|
</ol>
|
|
223
238
|
</footer>
|
|
224
239
|
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
243
|
+
<!-- cmp--clip:这一块演示的就是"长串把列撑开",栏内必须允许算得比栏宽更宽;
|
|
244
|
+
越出栏框的部分裁掉(不裁的话 320px 下整页横向溢出 64px,WCAG 1.4.10 红)。 -->
|
|
245
|
+
<div class="cmp cmp--clip">
|
|
246
|
+
<div class="cmp__pane cmp__bad" data-bad=".ar-cell.ar-long|w|>250">
|
|
247
|
+
<h3>❌ 常见写法:栅格列写 <code>1fr</code></h3>
|
|
248
|
+
<div class="ar-g" aria-hidden="true">
|
|
249
|
+
<div class="ar-cell">正文一栏:营收同比 +18%。</div>
|
|
250
|
+
<div class="ar-cell ar-long">SH600519-SH000001-SZ300750-SH601318-SZ000858</div>
|
|
251
|
+
</div>
|
|
252
|
+
<p class="cmp__why">右栏里一串不肯断的长代码把列撑开了:它不换行、也不省略,整页横向溢出 —— 而外层容器并<b>没有</b>写错,错的是列定义。</p>
|
|
253
|
+
</div>
|
|
254
|
+
<div class="cmp__pane cmp__good" data-good=".ar-cell.ar-long|w|<=200">
|
|
255
|
+
<h3>✅ 本库:<code>minmax(0, 1fr)</code></h3>
|
|
256
|
+
<div class="ar-g ar-g--ok" aria-hidden="true">
|
|
257
|
+
<div class="ar-cell">正文一栏:营收同比 +18%。</div>
|
|
258
|
+
<div class="ar-cell ar-long">SH600519-SH000001-SZ300750-SH601318-SZ000858</div>
|
|
259
|
+
</div>
|
|
260
|
+
<p class="cmp__why"><code>1fr</code> 的最小值是 <code>auto</code>(即"内容最小宽度"),所以挡不住长内容。<code>minmax(0, 1fr)</code> 把下限按到 0,列宽才真正受控;再配一句 <code>text-overflow: ellipsis</code>,内容就收在格子里。</p>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
225
263
|
</main>
|
|
226
264
|
|
|
227
265
|
<script src="../../09-assets/scientific-plot/scientific-plot.js"></script>
|
|
@@ -46,6 +46,7 @@ python -m http.server 8000
|
|
|
46
46
|
|
|
47
47
|
## 反例
|
|
48
48
|
|
|
49
|
+
- ❌ **单位与数字同字号同色** —— "1,284.6 亿元" 里"亿元"只是量级标记,却和数字抢同一层注意力;本库把单位降一档(`--fs-sm` + 次级色),数字用 `num` 等宽(纵向才对得齐)
|
|
49
50
|
- ❌ **把这四个当成"同一种图表的四种皮肤"** —— 它们共享令牌与容器,但**不共享**坐标规则与数据格式,
|
|
50
51
|
是四个用途。换皮肤换不来正确的表达
|
|
51
52
|
- ❌ **用 `table` 回答"涨还是跌"** —— 表格给的是具体值,趋势要看形状;
|
|
@@ -34,6 +34,14 @@
|
|
|
34
34
|
屏幕阅读器会把它读成「图 1 的说明」,语义本身就是信息。 */
|
|
35
35
|
.figbox figcaption { margin-top: var(--sp-2); font-size: var(--fs-xs);
|
|
36
36
|
color: var(--text-tertiary); }
|
|
37
|
+
.ds-stat { display: flex; align-items: baseline; gap: var(--sp-2);
|
|
38
|
+
padding: var(--sp-3); background: var(--surface-raised);
|
|
39
|
+
border: 1px solid var(--border-decor); border-radius: var(--r-sm); }
|
|
40
|
+
.ds-k { font-size: var(--fs-xs); color: var(--text-secondary); margin-inline-end: auto; }
|
|
41
|
+
.ds-v { font-size: var(--fs-lg); font-weight: 600; }
|
|
42
|
+
/* 反例专用:单位跟数字同字号同色("抢同一层注意力"就是这个样子) */
|
|
43
|
+
.ds-v .ds-u--flat { font-size: inherit; color: inherit; } /* 特异性要比 .ds-u 高 */
|
|
44
|
+
.ds-u { font-size: var(--fs-sm); color: var(--text-secondary); }
|
|
37
45
|
</style>
|
|
38
46
|
</head>
|
|
39
47
|
<body class="page">
|
|
@@ -215,6 +223,27 @@
|
|
|
215
223
|
</table>
|
|
216
224
|
</div>
|
|
217
225
|
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
229
|
+
<div class="cmp">
|
|
230
|
+
<div class="cmp__pane cmp__bad" data-bad=".ds-u|fs|>=20">
|
|
231
|
+
<h3>❌ 常见写法:单位与数字同字号同色</h3>
|
|
232
|
+
<div class="ds-stat" aria-hidden="true">
|
|
233
|
+
<span class="ds-k">营业收入</span>
|
|
234
|
+
<span class="ds-v"><span class="num">1,284.6</span><span class="ds-u ds-u--flat">亿元</span></span>
|
|
235
|
+
</div>
|
|
236
|
+
<p class="cmp__why">"亿元"只是个量级标记,却和 1,284.6 抢同一层注意力:读者先读到的是四个字,而不是那个数。</p>
|
|
237
|
+
</div>
|
|
238
|
+
<div class="cmp__pane cmp__good" data-good=".ds-u|fs|<=16">
|
|
239
|
+
<h3>✅ 本库:数字当主角,单位退一档</h3>
|
|
240
|
+
<div class="ds-stat" aria-hidden="true">
|
|
241
|
+
<span class="ds-k">营业收入</span>
|
|
242
|
+
<span class="ds-v"><span class="num">1,284.6</span><span class="ds-u">亿元</span></span>
|
|
243
|
+
</div>
|
|
244
|
+
<p class="cmp__why">数字用 <code>num</code>(等宽数字,纵向才对得齐),单位降一档字号与颜色。一屏里有十几个数字时,这个差别决定读者能不能扫。</p>
|
|
245
|
+
</div>
|
|
246
|
+
</div>
|
|
218
247
|
</main>
|
|
219
248
|
|
|
220
249
|
<script src="../../09-assets/sparkline/sparkline.js"></script>
|
|
@@ -18,6 +18,13 @@
|
|
|
18
18
|
.dp-link__t { font-weight: 600; }
|
|
19
19
|
.dp-link__d { display: block; margin-top: 4px; font-size: var(--fs-sm);
|
|
20
20
|
color: var(--text-secondary); }
|
|
21
|
+
.dp-kpi { display: flex; align-items: baseline; gap: var(--sp-2);
|
|
22
|
+
padding: var(--sp-3); background: var(--surface-raised);
|
|
23
|
+
border: 1px solid var(--border-decor); border-radius: var(--r-sm); }
|
|
24
|
+
.dp-kpi__k { font-size: var(--fs-xs); color: var(--text-secondary); }
|
|
25
|
+
.dp-kpi__v { font-size: var(--fs-lg); font-weight: 600; }
|
|
26
|
+
.dp-kpi__u { font-size: var(--fs-xs); color: var(--text-secondary); }
|
|
27
|
+
.detail-null__v { font-size: var(--fs-md); font-weight: 500; color: var(--text-tertiary); }
|
|
21
28
|
</style>
|
|
22
29
|
</head>
|
|
23
30
|
<body class="page">
|
|
@@ -50,6 +57,27 @@
|
|
|
50
57
|
② 皮肤挂在 <code>section</code> 上,不挂 <code>body</code>;<br>
|
|
51
58
|
③ <strong>DOM 不许变</strong>,字段缺失是值缺失,不是节点缺失。
|
|
52
59
|
</p>
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
63
|
+
<div class="cmp">
|
|
64
|
+
<div class="cmp__pane cmp__bad" data-bad=".dp-kpi__v|fs|>=24">
|
|
65
|
+
<h3>❌ 常见写法:缺的字段写 0</h3>
|
|
66
|
+
<div class="dp-kpi" aria-hidden="true">
|
|
67
|
+
<span class="dp-kpi__k">研发投入</span>
|
|
68
|
+
<span class="dp-kpi__v"><span class="num">0</span><span class="dp-kpi__u">亿元</span></span>
|
|
69
|
+
</div>
|
|
70
|
+
<p class="cmp__why"><code>0</code> 是一个真实的值:读者会拿它去算"研发强度 = 0",也会拿它去比同比 —— 而这一格其实<b>没有</b>数据。</p>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="cmp__pane cmp__good" data-good=".detail-null__v|fs|<=22">
|
|
73
|
+
<h3>✅ 本库:写「未披露」+ 弱化色</h3>
|
|
74
|
+
<div class="dp-kpi" aria-hidden="true">
|
|
75
|
+
<span class="dp-kpi__k">研发投入</span>
|
|
76
|
+
<span class="dp-kpi__v"><span class="detail-null__v">未披露</span></span>
|
|
77
|
+
</div>
|
|
78
|
+
<p class="cmp__why">缺就是缺。同一页里三个变体的 DOM 结构必须完全一致(节点数量与嵌套),所以缺数据时是<b>换文案</b>,不是删节点 —— 删了以后这页越改越不像。</p>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
53
81
|
</main>
|
|
54
82
|
</body>
|
|
55
83
|
</html>
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
<link rel="stylesheet" href="report.css">
|
|
14
14
|
<!-- 本页不写内联 <style>:所有版式都来自 report.css。
|
|
15
15
|
内联写成活的那一刻,它就不再是这个系统的一部分了。 -->
|
|
16
|
+
<style>
|
|
17
|
+
.rep-p { margin: 0 0 var(--sp-2); font-size: var(--fs-sm); line-height: 1.7; }
|
|
18
|
+
</style>
|
|
16
19
|
</head>
|
|
17
20
|
<body class="page">
|
|
18
21
|
<main class="wrap">
|
|
@@ -299,6 +302,27 @@
|
|
|
299
302
|
共享基础的六个可变量,以及与 <code>04-recipes/analysis-report</code>(一份具体实例)的分工。
|
|
300
303
|
</p>
|
|
301
304
|
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
<h2 class="rule-bottom">对比:错写法 vs 本库写法</h2>
|
|
308
|
+
<div class="cmp">
|
|
309
|
+
<div class="cmp__pane cmp__bad" data-bad=".rep__cap|count|=0">
|
|
310
|
+
<h3>❌ 常见写法:来源与正文同一副面孔</h3>
|
|
311
|
+
<div class="rep" aria-hidden="true">
|
|
312
|
+
<p class="rep-p">本季度毛利率 42.1%,环比提升 1.3 个百分点。</p>
|
|
313
|
+
<p class="rep-p">数据来源:公司 2026 年三季报,经本库统一口径重算。</p>
|
|
314
|
+
</div>
|
|
315
|
+
<p class="cmp__why">读者读到第二句才知道这是"出处",而它和正文长得一模一样 —— 分不清哪句是结论、哪句是依据。</p>
|
|
316
|
+
</div>
|
|
317
|
+
<div class="cmp__pane cmp__good" data-good=".rep__cap|count|>=1">
|
|
318
|
+
<h3>✅ 本库:来源用 <code>rep__cap</code> 这一档角色</h3>
|
|
319
|
+
<div class="rep" aria-hidden="true">
|
|
320
|
+
<p class="rep-p">本季度毛利率 42.1%,环比提升 1.3 个百分点。</p>
|
|
321
|
+
<p class="rep__cap">数据来源:公司 2026 年三季报,经本库统一口径重算。</p>
|
|
322
|
+
</div>
|
|
323
|
+
<p class="cmp__why">report 的六个字体角色(眉题 / 元信息 / 图表说明 / 来源 / 编者注 / 风险披露)是<b>不多不少</b>的。多造一种,读者就要重新学一遍"这行字是什么身份"。</p>
|
|
324
|
+
</div>
|
|
325
|
+
</div>
|
|
302
326
|
</main>
|
|
303
327
|
|
|
304
328
|
<script src="../../09-assets/scientific-plot/scientific-plot.js"></script>
|