base-paint 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blocks.d.ts +141 -4
- package/dist/blocks.d.ts.map +1 -1
- package/dist/blocks.js +1015 -25
- package/dist/blocks.js.map +1 -1
- package/dist/charts.d.ts +6 -4
- package/dist/charts.d.ts.map +1 -1
- package/dist/charts.js +378 -64
- package/dist/charts.js.map +1 -1
- package/dist/controls.d.ts +20 -5
- package/dist/controls.d.ts.map +1 -1
- package/dist/controls.js +246 -34
- package/dist/controls.js.map +1 -1
- package/dist/font.d.ts +3 -3
- package/dist/font.js +3 -3
- package/dist/help.d.ts +3 -3
- package/dist/help.js +12 -12
- package/dist/help.js.map +1 -1
- package/dist/helpShell.d.ts.map +1 -1
- package/dist/helpShell.js +2 -2
- package/dist/helpShell.js.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/injector.d.ts +1 -1
- package/dist/output/saveHtml.d.ts +37 -2
- package/dist/output/saveHtml.d.ts.map +1 -1
- package/dist/output/saveHtml.js +125 -15
- package/dist/output/saveHtml.js.map +1 -1
- package/dist/pageShapes.d.ts +117 -0
- package/dist/pageShapes.d.ts.map +1 -0
- package/dist/pageShapes.js +366 -0
- package/dist/pageShapes.js.map +1 -0
- package/dist/pageUi.d.ts +37 -0
- package/dist/pageUi.d.ts.map +1 -0
- package/dist/pageUi.js +237 -0
- package/dist/pageUi.js.map +1 -0
- package/dist/spec/charts.d.ts +12 -3
- package/dist/spec/charts.d.ts.map +1 -1
- package/dist/spec/charts.js +1 -1
- package/dist/spec/charts.js.map +1 -1
- package/dist/spec/controls.d.ts +30 -5
- package/dist/spec/controls.d.ts.map +1 -1
- package/dist/spec/controls.js +14 -3
- package/dist/spec/controls.js.map +1 -1
- package/dist/spec/help.d.ts +4 -4
- package/dist/spec/help.d.ts.map +1 -1
- package/dist/spec/help.js +2 -2
- package/dist/spec/index.d.ts +6 -3
- package/dist/spec/index.d.ts.map +1 -1
- package/dist/spec/index.js +27 -2
- package/dist/spec/index.js.map +1 -1
- package/dist/style.d.ts.map +1 -1
- package/dist/style.js +265 -47
- package/dist/style.js.map +1 -1
- package/package.json +1 -1
package/dist/style.js
CHANGED
|
@@ -60,7 +60,7 @@ function rootBlock() {
|
|
|
60
60
|
lines.push('}');
|
|
61
61
|
return lines.join(LF);
|
|
62
62
|
}
|
|
63
|
-
/**
|
|
63
|
+
/** 页级基础(非控件区):**本票不产**。
|
|
64
64
|
* 裁定 R7/施工单 B-D2(a):共享页面模板/KPI/表格/回到顶部等**无闭集归属**的样式归 #104
|
|
65
65
|
* (区块组件 owner),#75 只产 11 token + 8 个闭集样式区;`extraCss` 语义被
|
|
66
66
|
* 契约 doc:299-300 限死(只许技能作用域 token 覆盖块),**不得**塞共享页面模板的样式。 */
|
|
@@ -95,6 +95,13 @@ const SECTION_BUILDERS = {
|
|
|
95
95
|
// 时靠换行分层,代价是把关闭按钮挤到第三行)。根因已由 `controls.ts` 的结构对齐修掉
|
|
96
96
|
// (helpers 与静态产出器/旧层同构:`icon? + .toast-body(> .toast-title-row + detail) + .toast-close`),
|
|
97
97
|
// 补丁一并删除 → 关闭按钮与标题恒同行。
|
|
98
|
+
// 卡面色(2026-09-12 用户裁定改用**老技能**版):深色毛玻璃,逐值取自
|
|
99
|
+
// 老仓 `公共组件/assets/base.js:75` 的 `.hm-toast` 串——底色 rgba(28,28,30,.94)、
|
|
100
|
+
// 毛玻璃 blur(20px) saturate(180%)、主字 #f0f0f0、投影 0 10px 32px rgba(0,0,0,.32)
|
|
101
|
+
// + 0 0 0 .5px rgba(255,255,255,.08) inset(原样的「无描边、靠内影收边」)。
|
|
102
|
+
// 几何(圆角 14px/内距 13-14-16/min 300/max 480/gap 12)与老仓逐值相同,本次不动。
|
|
103
|
+
// 取字面量而非 token:本卡是**深色面**,不随浅色 token 变——这是本次的唯一例外,记账见
|
|
104
|
+
// `docs/visual-spec-blocks.md` §B-12 的 2026-09-12 裁定行。
|
|
98
105
|
'.' + p + 'toast {',
|
|
99
106
|
' display: flex;',
|
|
100
107
|
' align-items: flex-start;',
|
|
@@ -103,12 +110,14 @@ const SECTION_BUILDERS = {
|
|
|
103
110
|
' min-width: 300px;',
|
|
104
111
|
' max-width: 480px;',
|
|
105
112
|
' padding: 13px 14px 13px 16px;',
|
|
106
|
-
' border: 1px solid var(--line);',
|
|
107
113
|
' border-radius: 14px;',
|
|
108
|
-
' background:
|
|
109
|
-
'
|
|
110
|
-
'
|
|
111
|
-
'
|
|
114
|
+
' background: rgba(28, 28, 30, .94);',
|
|
115
|
+
' -webkit-backdrop-filter: blur(20px) saturate(180%);',
|
|
116
|
+
' backdrop-filter: blur(20px) saturate(180%);',
|
|
117
|
+
' color: #f0f0f0;',
|
|
118
|
+
' box-shadow: 0 10px 32px rgba(0, 0, 0, .32), 0 0 0 .5px rgba(255, 255, 255, .08) inset;',
|
|
119
|
+
// #567 J4(§5.2 正文 13 吸收 13/12.5)。
|
|
120
|
+
' font-size: 13px;',
|
|
112
121
|
' line-height: 1.4;',
|
|
113
122
|
' font-feature-settings: "tnum";',
|
|
114
123
|
' pointer-events: auto;',
|
|
@@ -127,13 +136,16 @@ const SECTION_BUILDERS = {
|
|
|
127
136
|
' transform: none;',
|
|
128
137
|
' }',
|
|
129
138
|
'}',
|
|
139
|
+
// 失败态:老仓没有卡面描边,失败由「❌ 图标 + danger 徽章」承担;深色面上改由
|
|
140
|
+
// **内影那条 0.5px 细线换成功色系的红**来点一句(不新增描边、不改底色)。
|
|
130
141
|
'.' + p + 'toast-danger {',
|
|
131
|
-
'
|
|
142
|
+
' box-shadow: 0 10px 32px rgba(0, 0, 0, .32), 0 0 0 .5px rgba(255, 59, 48, .45) inset;',
|
|
132
143
|
'}',
|
|
133
144
|
'.' + p + 'toast-icon {',
|
|
134
145
|
' flex: 0 0 auto;',
|
|
135
146
|
' padding-top: 1px;',
|
|
136
|
-
|
|
147
|
+
// #567 J4(§5.2 标题 18 吸收 17/18/20/22):装饰字形 20→18。
|
|
148
|
+
' font-size: 18px;',
|
|
137
149
|
' line-height: 1;',
|
|
138
150
|
'}',
|
|
139
151
|
// body 是 toast 的**唯一**内容列(静态产出器与 helpers 运行时同构,见 `controls.ts`
|
|
@@ -151,15 +163,16 @@ const SECTION_BUILDERS = {
|
|
|
151
163
|
'}',
|
|
152
164
|
'.' + p + 'toast-title {',
|
|
153
165
|
' margin-bottom: 2px;',
|
|
154
|
-
' color:
|
|
155
|
-
|
|
166
|
+
' color: #fff;',
|
|
167
|
+
// #567 J4(§5.2 正文 13 吸收 13/12.5)。
|
|
168
|
+
' font-size: 13px;',
|
|
156
169
|
' font-weight: 600;',
|
|
157
170
|
' line-height: 1.4;',
|
|
158
171
|
'}',
|
|
159
172
|
// 运行时详情(helpers 产出 `.ilife-toast-title-detail`,在 `.ilife-toast-body` 内):
|
|
160
173
|
// 与静态侧 `.ilife-toast-detail` **同排版**;此前的 `flex: 1 1 100%` 权宜补丁已随结构对齐删除。
|
|
161
174
|
'.' + p + 'toast-title-detail {',
|
|
162
|
-
' color:
|
|
175
|
+
' color: #c8c8cc;',
|
|
163
176
|
' font-size: 11px;',
|
|
164
177
|
' font-weight: 400;',
|
|
165
178
|
' line-height: 1.5;',
|
|
@@ -168,41 +181,44 @@ const SECTION_BUILDERS = {
|
|
|
168
181
|
' flex-shrink: 0;',
|
|
169
182
|
' padding: 2px 8px;',
|
|
170
183
|
' border-radius: 999px;',
|
|
171
|
-
' background:
|
|
172
|
-
' color:
|
|
173
|
-
|
|
184
|
+
' background: rgba(255, 255, 255, .12);',
|
|
185
|
+
' color: #c8c8cc;',
|
|
186
|
+
// #567 J4(§5.2 下限 11:10/10.5/11 一律抬到 11)。
|
|
187
|
+
' font-size: 11px;',
|
|
174
188
|
' font-weight: 700;',
|
|
175
189
|
' letter-spacing: .02em;',
|
|
176
190
|
' line-height: 1.6;',
|
|
177
191
|
'}',
|
|
178
192
|
'.' + p + 'toast-chip-ok {',
|
|
179
|
-
' background: rgba(52, 199, 89, .
|
|
180
|
-
' color: #
|
|
193
|
+
' background: rgba(52, 199, 89, .18);',
|
|
194
|
+
' color: #4dd96b;',
|
|
181
195
|
'}',
|
|
182
196
|
'.' + p + 'toast-chip-warn {',
|
|
183
|
-
' background: rgba(255, 149, 0, .
|
|
184
|
-
' color: #
|
|
197
|
+
' background: rgba(255, 149, 0, .18);',
|
|
198
|
+
' color: #ffb340;',
|
|
185
199
|
'}',
|
|
186
200
|
'.' + p + 'toast-chip-danger {',
|
|
187
|
-
' background: rgba(255, 59, 48, .
|
|
188
|
-
' color: #
|
|
201
|
+
' background: rgba(255, 59, 48, .18);',
|
|
202
|
+
' color: #ff6961;',
|
|
189
203
|
'}',
|
|
190
204
|
'.' + p + 'toast-count {',
|
|
191
205
|
' flex-shrink: 0;',
|
|
192
206
|
' padding: 2px 8px;',
|
|
193
207
|
' border-radius: 8px;',
|
|
194
|
-
'
|
|
195
|
-
'
|
|
208
|
+
' background: rgba(255, 255, 255, .08);',
|
|
209
|
+
' color: #c8c8cc;',
|
|
210
|
+
// #567 J4(§5.2 下限 11)。
|
|
211
|
+
' font-size: 11px;',
|
|
196
212
|
' font-weight: 700;',
|
|
197
213
|
' font-variant-numeric: tabular-nums;',
|
|
198
214
|
'}',
|
|
199
215
|
'.' + p + 'toast-detail {',
|
|
200
|
-
' color:
|
|
216
|
+
' color: #c8c8cc;',
|
|
201
217
|
' font-size: 11px;',
|
|
202
218
|
' line-height: 1.5;',
|
|
203
219
|
'}',
|
|
204
220
|
'.' + p + 'toast-lines {',
|
|
205
|
-
' color:
|
|
221
|
+
' color: #c8c8cc;',
|
|
206
222
|
' font-size: 11px;',
|
|
207
223
|
' line-height: 1.55;',
|
|
208
224
|
' white-space: pre-wrap;',
|
|
@@ -211,10 +227,11 @@ const SECTION_BUILDERS = {
|
|
|
211
227
|
' margin: 6px 0 0;',
|
|
212
228
|
' padding: 8px 10px;',
|
|
213
229
|
' border-radius: 8px;',
|
|
214
|
-
' background:
|
|
215
|
-
' color:
|
|
230
|
+
' background: rgba(0, 0, 0, .32);',
|
|
231
|
+
' color: #aeb0b8;',
|
|
216
232
|
' font-family: "SF Mono", monospace;',
|
|
217
|
-
|
|
233
|
+
// #567 J4(§5.2 下限 11)。
|
|
234
|
+
' font-size: 11px;',
|
|
218
235
|
' line-height: 1.5;',
|
|
219
236
|
' white-space: pre-wrap;',
|
|
220
237
|
' max-height: 140px;',
|
|
@@ -225,11 +242,13 @@ const SECTION_BUILDERS = {
|
|
|
225
242
|
' padding: 2px 4px;',
|
|
226
243
|
' border: 0;',
|
|
227
244
|
' background: none;',
|
|
228
|
-
' color:
|
|
245
|
+
' color: #4dd96b;',
|
|
229
246
|
' font-family: inherit;',
|
|
230
247
|
' font-size: 11px;',
|
|
231
248
|
' font-weight: 600;',
|
|
232
249
|
' cursor: pointer;',
|
|
250
|
+
' -webkit-tap-highlight-color: transparent;',
|
|
251
|
+
' touch-action: manipulation;',
|
|
233
252
|
'}',
|
|
234
253
|
'.' + p + 'toast-act:active {',
|
|
235
254
|
' opacity: .7;',
|
|
@@ -240,13 +259,16 @@ const SECTION_BUILDERS = {
|
|
|
240
259
|
' padding: 5px 9px;',
|
|
241
260
|
' border: 0;',
|
|
242
261
|
' border-radius: 8px;',
|
|
243
|
-
' background:
|
|
244
|
-
' color:
|
|
262
|
+
' background: rgba(255, 255, 255, .10);',
|
|
263
|
+
' color: #34c759;',
|
|
245
264
|
' font-family: inherit;',
|
|
246
|
-
|
|
265
|
+
// #567 J4(§5.2 下限 11)。
|
|
266
|
+
' font-size: 11px;',
|
|
247
267
|
' font-weight: 500;',
|
|
248
268
|
' white-space: nowrap;',
|
|
249
269
|
' cursor: pointer;',
|
|
270
|
+
' -webkit-tap-highlight-color: transparent;',
|
|
271
|
+
' touch-action: manipulation;',
|
|
250
272
|
'}',
|
|
251
273
|
focusRing('.' + p + 'toast-act'),
|
|
252
274
|
focusRing('.' + p + 'toast-close'),
|
|
@@ -272,9 +294,18 @@ const SECTION_BUILDERS = {
|
|
|
272
294
|
' gap: 8px;',
|
|
273
295
|
' box-sizing: border-box;',
|
|
274
296
|
' margin: 12px 0;',
|
|
297
|
+
// 旧层冻结值(旧 `base.css:81-91`)。它只在**窄档**用得上:窄屏内容列本来就不到 520px,这条不生效;
|
|
298
|
+
// 桌面档由下方那条媒体查询放开到内容列宽(#238 用户 2026-09-13 二次裁定)。
|
|
275
299
|
' max-width: 520px;',
|
|
276
|
-
'
|
|
277
|
-
|
|
300
|
+
'}',
|
|
301
|
+
// #238(用户 2026-09-13 二次裁定「两个按钮平分宽度」):桌面档**铺满内容列**,动作条里的整行
|
|
302
|
+
// (`.action-row-ghost` 的 `repeat(2, minmax(0, 1fr))`)随之按内容列平分——两颗按钮各占一半。
|
|
303
|
+
// 断点用样式表里既有的移动档分界 `TOAST_DEFAULTS.mobileMaxPx`(与 #249 那两处同源),
|
|
304
|
+
// 故 ≤820 的窄档逐像素不动。
|
|
305
|
+
'@media (min-width: ' + (TOAST_DEFAULTS.mobileMaxPx + 1) + 'px) {',
|
|
306
|
+
' .' + p + 'action-bar {',
|
|
307
|
+
' max-width: none;',
|
|
308
|
+
' }',
|
|
278
309
|
'}',
|
|
279
310
|
'.' + p + 'action-row {',
|
|
280
311
|
' display: grid;',
|
|
@@ -282,7 +313,18 @@ const SECTION_BUILDERS = {
|
|
|
282
313
|
' gap: 8px;',
|
|
283
314
|
'}',
|
|
284
315
|
'.' + p + 'action-row-ghost {',
|
|
285
|
-
|
|
316
|
+
// 复制按钮那一行**平分整行**(#247 用户 2026-09-12 返修):两列而不是单列——单列只在「一行一颗」时
|
|
317
|
+
// 才好看,一旦有第二颗(复制数据 + 复制日志)就变成「一颗铺满、一颗缩成内容宽」。列数取冻结
|
|
318
|
+
// `ACTION_BAR_DEFAULTS.evenRowPairs`(既有「偶数一行 2 个」的口径,不是新拍的数字)。
|
|
319
|
+
' grid-template-columns: repeat(' + ACTION_BAR_DEFAULTS.evenRowPairs + ', minmax(0, 1fr));',
|
|
320
|
+
'}',
|
|
321
|
+
// #249:窄屏那档菜单**以整行做锚点**(同档 `copyButton` 区把包裹层改成 `position: static`)——
|
|
322
|
+
// 行盒=内容宽,菜单 `left:0; right:0` 落进去就恒在视口内,与那颗按钮落在左格还是右格无关。
|
|
323
|
+
// 只在窄屏挂,桌面档的锚点仍是包裹层(菜单贴按钮右缘,用户已验收的样子不动)。
|
|
324
|
+
'@media (max-width: ' + TOAST_DEFAULTS.mobileMaxPx + 'px) {',
|
|
325
|
+
' .' + p + 'action-row-ghost {',
|
|
326
|
+
' position: relative;',
|
|
327
|
+
' }',
|
|
286
328
|
'}',
|
|
287
329
|
'.' + p + 'action-btn {',
|
|
288
330
|
' display: inline-flex;',
|
|
@@ -299,6 +341,8 @@ const SECTION_BUILDERS = {
|
|
|
299
341
|
' font-weight: ' + ACTION_BAR_DEFAULTS.fontWeight + ';',
|
|
300
342
|
' line-height: 1;',
|
|
301
343
|
' cursor: pointer;',
|
|
344
|
+
' -webkit-tap-highlight-color: transparent;',
|
|
345
|
+
' touch-action: manipulation;',
|
|
302
346
|
'}',
|
|
303
347
|
'.' + p + 'action-btn-primary {',
|
|
304
348
|
' background: var(--blue);',
|
|
@@ -313,7 +357,8 @@ const SECTION_BUILDERS = {
|
|
|
313
357
|
' background: var(--card);',
|
|
314
358
|
' color: var(--blue2);',
|
|
315
359
|
'}',
|
|
316
|
-
// #179 触控目标:窄屏按钮抬到 44px
|
|
360
|
+
// #179 触控目标:窄屏按钮抬到 44px。**#525 起两个宽档同值**(`minHeightPx` 40 → 44,见
|
|
361
|
+
// `spec/controls.ts`);本条留在这里只为不动既有选择器与既有媒体查询。
|
|
317
362
|
'@media (max-width: ' + TOAST_DEFAULTS.mobileMaxPx + 'px) {',
|
|
318
363
|
' .' + p + 'action-btn {',
|
|
319
364
|
' min-height: 44px;',
|
|
@@ -338,6 +383,8 @@ const SECTION_BUILDERS = {
|
|
|
338
383
|
' font-weight: ' + ACTION_BAR_DEFAULTS.fontWeight + ';',
|
|
339
384
|
' line-height: 1;',
|
|
340
385
|
' cursor: pointer;',
|
|
386
|
+
' -webkit-tap-highlight-color: transparent;',
|
|
387
|
+
' touch-action: manipulation;',
|
|
341
388
|
' transition: transform .45s cubic-bezier(.34, 1.56, .64, 1), background-color .2s ease;',
|
|
342
389
|
'}',
|
|
343
390
|
'.' + p + 'copy-btn-primary {',
|
|
@@ -358,7 +405,7 @@ const SECTION_BUILDERS = {
|
|
|
358
405
|
' transform: scale(.96);',
|
|
359
406
|
'}',
|
|
360
407
|
// W3(H-16 双反馈的 CSS 侧):复制成功态变绿。规格 `docs/visual-spec-help.md:195,197`
|
|
361
|
-
// 「按钮变绿进入 `copied` 态并跑 450ms 弹簧动画」;弹簧 =
|
|
408
|
+
// 「按钮变绿进入 `copied` 态并跑 450ms 弹簧动画」;弹簧 = 基础 `transition: transform .45s
|
|
362
409
|
// cubic-bezier(.34, 1.56, .64, 1)`(B1 `benchmark-visual-spec.md:279,645`),本节只补**变绿**。
|
|
363
410
|
// 类名由**运行时**添加(`copied`,非 `ilife-` 前缀 → 不占样式区命名空间);
|
|
364
411
|
// 本票**不改** helpers 的复制反馈行为,移交落点见契约 §8.11.1 FX-75-11。
|
|
@@ -367,12 +414,172 @@ const SECTION_BUILDERS = {
|
|
|
367
414
|
' background: var(--ok);',
|
|
368
415
|
' color: var(--card);',
|
|
369
416
|
'}',
|
|
370
|
-
//
|
|
417
|
+
// **禁用态必须看得出来**(#525 收口 · 两处公共债之一):读页面没有写库日志,复制区按 #336
|
|
418
|
+
// 自动补的那颗「复制日志」带 `disabled` 属性、可**从 #336 起就没有任何置灰规则**——看着与
|
|
419
|
+
// 旁边那颗能点的按钮一模一样(`t524-改前读数.md` §7.1 第 3 条只核了属性、没核观感)。
|
|
420
|
+
//
|
|
421
|
+
// **#525 第二轮返修(禁用态只看得见、读不清)**:上一版照 HELP 页 `button.copy:disabled`
|
|
422
|
+
// 取 `opacity:.45` 压**整颗**按钮,实测有效文字色被混成 `#91b9e9` 压白底,对比度只有
|
|
423
|
+
// **2.03:1**(`.scratch/t525c/before.json`;读法=把 opacity 混进底色后按 WCAG 相对亮度算)——
|
|
424
|
+
// 连 AA 大字的 3:1 都不到,等于把「禁用」写成了「看不清」。
|
|
425
|
+
// 改法=**不压整颗**,改三处、各自都是一个信号:① 文字色换 `--fg3`;② 底压成 `--soft`;
|
|
426
|
+
// ③ 描边降到 `--line`(「蓝=可点」这条信号只留在可点态)。`opacity` 恒 1(不继承、不叠乘)。
|
|
427
|
+
// 2.03 → 3.47 的两行读数落 `.scratch/t525c/disabled-contrast.json`,探针 `.scratch/t525c/probe.mjs` 可复跑。
|
|
428
|
+
'.' + p + 'copy-btn[disabled],',
|
|
429
|
+
'.' + p + 'copy-btn:disabled {',
|
|
430
|
+
' opacity: 1;',
|
|
431
|
+
' border-color: var(--line);',
|
|
432
|
+
' background: var(--soft);',
|
|
433
|
+
' color: var(--fg3);',
|
|
434
|
+
' cursor: not-allowed;',
|
|
435
|
+
'}',
|
|
436
|
+
'.' + p + 'copy-btn[disabled]:active,',
|
|
437
|
+
'.' + p + 'copy-btn:disabled:active {',
|
|
438
|
+
' transform: none;',
|
|
439
|
+
'}',
|
|
440
|
+
// #179 触控目标:窄屏按钮抬到 44px。**#525 起这条在两个宽档上是同一个值**(`minHeightPx`
|
|
441
|
+
// 由 40 提到 44,见 `spec/controls.ts`)——留在这里是为了不动既有选择器与既有媒体查询;
|
|
442
|
+
// 桌面档不再是 40px。
|
|
371
443
|
'@media (max-width: ' + TOAST_DEFAULTS.mobileMaxPx + 'px) {',
|
|
372
444
|
' .' + p + 'copy-btn {',
|
|
373
445
|
' min-height: 44px;',
|
|
374
446
|
' }',
|
|
375
447
|
'}',
|
|
448
|
+
// ── 复制数据的三格式菜单(#247,2026-09-12 用户裁定「恢复老仓原样」)───────────────
|
|
449
|
+
// 逐值取自老仓 `卡路里/templates/crud_receipt.html`(可点版本 `2262fee1~1`)的 `.fmt-menu`/
|
|
450
|
+
// `.fmt-item`/`.fmt-item:hover`/`.fmt-item span` 四串;老仓的 `--border`/`--soft` 分别
|
|
451
|
+
// 对到本仓的 `--line`/`--soft`。**复用本区命名空间**(`CONTROL_STYLE_SECTIONS` 是冻结闭集,
|
|
452
|
+
// 不新增第 9 个区);类名不对 `copy-btn` 用前缀相似的名字(`.copy-menu-btn` 会被
|
|
453
|
+
// `.copy-btn` 的规则一并命中,多出一圈胶囊底),故开合器只带 `copy-btn copy-btn-ghost` 两颗类。
|
|
454
|
+
// **偏离 1 处(记账)**:菜单圆角取 **14px**(老仓是 12px)——#89 R-9 的 H-10 把
|
|
455
|
+
// 全部非图表 CSS 的 `border-radius` 钉在 `{8px,14px,20px,999px,50%}`,12px 会让你越出闭集;
|
|
456
|
+
// 14px 是本仓既有卡片圆角(toast 同值),几何其余逐值不动(`bottom`/`right`/`min-width`/
|
|
457
|
+
// `max-width`/`padding`/投影/项内距与字号全取老仓)。
|
|
458
|
+
'.' + p + 'copy-menu-wrap {',
|
|
459
|
+
// 宽度**跟着轨道走**(#247 用户 2026-09-12 返修):复制数据与复制日志在 ghost 行里**平分整行**
|
|
460
|
+
// (各占一格,见 `.action-row-ghost` 的两列),两颗宽高一致——不再出现「一颗铺满一行、一颗缩成
|
|
461
|
+
// 内容宽」的一胖一瘦。故这里**不写** `justify-self: start`(那会让本层缩成内容宽、连带按钮也缩)。
|
|
462
|
+
' position: relative;',
|
|
463
|
+
' display: flex;',
|
|
464
|
+
' align-items: center;',
|
|
465
|
+
' width: 100%;',
|
|
466
|
+
'}',
|
|
467
|
+
// 开合器按钮铺满自己那一格:菜单的 `right: 0` 才贴着按钮右缘(== 格子右缘),两格时居中偏右。
|
|
468
|
+
'.' + p + 'copy-menu-wrap > .' + p + 'copy-btn {',
|
|
469
|
+
' width: 100%;',
|
|
470
|
+
'}',
|
|
471
|
+
// **#525 第二轮·三角用 CSS 画**(用户裁定第 5 条:符号顶替了设计):
|
|
472
|
+
// 可见文字里的 `▾` 已从 `controls.ts` 的 `copyMenuHtml` 删掉(那句「可以选格式」改住 `aria-label`),
|
|
473
|
+
// 这里用 `border` 拼一个向下的小三角 + `rotate(180deg)` 做开合态——**一个字符都不打**,
|
|
474
|
+
// 也就不会被字体/读屏/抓取器当成内容。画的规矩:零宽零高的盒子靠 `border-top` 出形,
|
|
475
|
+
// `margin-left: 6px` 与基础的 `gap: 6px` 同值(文字与三角的间距连两处取值都不新造)。
|
|
476
|
+
// 开合态由运行时加的 `.copy-menu-open` 落色(与菜单同一个类,不新增第二个开关)。
|
|
477
|
+
'.' + p + 'copy-menu-wrap > .' + p + 'copy-btn::after {',
|
|
478
|
+
' content: "";',
|
|
479
|
+
' width: 0;',
|
|
480
|
+
' height: 0;',
|
|
481
|
+
' margin-left: 6px;',
|
|
482
|
+
' border-left: 4px solid transparent;',
|
|
483
|
+
' border-right: 4px solid transparent;',
|
|
484
|
+
' border-top: 5px solid currentColor;',
|
|
485
|
+
' transition: transform .16s ease-out;',
|
|
486
|
+
'}',
|
|
487
|
+
'.copy-menu-open.' + p + 'copy-menu-wrap > .' + p + 'copy-btn::after {',
|
|
488
|
+
' transform: rotate(180deg);',
|
|
489
|
+
'}',
|
|
490
|
+
'.' + p + 'copy-menu {',
|
|
491
|
+
' position: absolute;',
|
|
492
|
+
' bottom: calc(100% + 8px);',
|
|
493
|
+
' right: 0;',
|
|
494
|
+
' z-index: 20;',
|
|
495
|
+
' min-width: 200px;',
|
|
496
|
+
// 浮层开合走 opacity(不是 `display`/`hidden`):一是 CSS 过渡不被跳过,二是开合不重排整页。
|
|
497
|
+
// 关着时同时收掉命中,免得看不见的菜单项还能被点到;`visibility` 可过渡 ⇒ 收起仍有淡出。
|
|
498
|
+
' box-sizing: border-box;',
|
|
499
|
+
' max-width: calc(100vw - 32px);',
|
|
500
|
+
' padding: 6px;',
|
|
501
|
+
' border: 1px solid var(--line);',
|
|
502
|
+
' border-radius: 14px;',
|
|
503
|
+
' background: var(--card);',
|
|
504
|
+
' box-shadow: 0 8px 24px rgba(0, 0, 0, .14);',
|
|
505
|
+
' opacity: 0;',
|
|
506
|
+
' visibility: hidden;',
|
|
507
|
+
' pointer-events: none;',
|
|
508
|
+
' transition: opacity .16s ease-out, visibility .16s ease-out;',
|
|
509
|
+
'}',
|
|
510
|
+
// 开着的那条:`copy-menu-open` 是**运行时**加的类(与 #121 的 `copied` 同口径——类名不加
|
|
511
|
+
// `ilife-` 前缀,故不占样式区命名空间,也不作为 `ilife-` 类名进跨文件检查);选择器把裸类
|
|
512
|
+
// 排在**前**面,这样从 CSS 里扫出来的 `ilife-` 类名仍只有 `ilife-copy-menu`(T10 ② 认得出产出者)。
|
|
513
|
+
'.copy-menu-open.' + p + 'copy-menu {',
|
|
514
|
+
' opacity: 1;',
|
|
515
|
+
' visibility: visible;',
|
|
516
|
+
' pointer-events: auto;',
|
|
517
|
+
'}',
|
|
518
|
+
'.' + p + 'copy-menu-item {',
|
|
519
|
+
// #152 返修:补最小高——老仓 `.fmt-item` 只写 `padding:10px 12px` + 13px 字,算出来 37px,
|
|
520
|
+
// 低于本仓同区复制按钮的冻结最小值(`spec/controls.ts:297` 的 40px)。40 不另写一个数,
|
|
521
|
+
// 引用同一个定义地;窄屏那档仍由下面的 `min-height:44px` 抬起(老仓 `.fmt-item` 是 36px)。
|
|
522
|
+
' min-height: ' + ACTION_BAR_DEFAULTS.minHeightPx + 'px;',
|
|
523
|
+
' display: flex;',
|
|
524
|
+
' justify-content: space-between;',
|
|
525
|
+
' gap: 14px;',
|
|
526
|
+
' width: 100%;',
|
|
527
|
+
' padding: 10px 12px;',
|
|
528
|
+
' border: none;',
|
|
529
|
+
' border-radius: 8px;',
|
|
530
|
+
' background: none;',
|
|
531
|
+
' color: var(--fg);',
|
|
532
|
+
' font-family: inherit;',
|
|
533
|
+
' font-size: 13px;',
|
|
534
|
+
' text-align: left;',
|
|
535
|
+
' cursor: pointer;',
|
|
536
|
+
' -webkit-tap-highlight-color: transparent;',
|
|
537
|
+
' touch-action: manipulation;',
|
|
538
|
+
'}',
|
|
539
|
+
'.' + p + 'copy-menu-item:hover {',
|
|
540
|
+
' background: var(--soft);',
|
|
541
|
+
'}',
|
|
542
|
+
// 标签(格式键):显式一条——省得继承菜单项的既有值,也让「CSS 里每个类名都有产出者、
|
|
543
|
+
// 每个产出类名都有 CSS」这条跨文件检查两面都成立(`style.test.mjs` T10)。
|
|
544
|
+
'.' + p + 'copy-menu-item > .' + p + 'copy-menu-label {',
|
|
545
|
+
' color: var(--fg);',
|
|
546
|
+
' font-size: 13px;',
|
|
547
|
+
'}',
|
|
548
|
+
// 用途提示:老仓是 `.fmt-item span`(后代选择器,两项 span 都染 11px 灰);本仓显式给类名,
|
|
549
|
+
// 标签那半仍取 13px/`--fg`(上一条)。选择器用 `>` ——本仓跨文件交叉检查按**整段选择器**比对。
|
|
550
|
+
// **返修**:字色由 `--fg3`(#86868b)改为 `--fg2`(#6e6e73)——11px 属正文,AA 要 4.5:1,
|
|
551
|
+
// 前者对白卡片仅 3.62:1、后者 5.07:1;与同批「12px + `--fg3`」那 7 处改用的是同一个做法(#152)。
|
|
552
|
+
'.' + p + 'copy-menu-item > .' + p + 'copy-menu-hint {',
|
|
553
|
+
' color: var(--fg2);',
|
|
554
|
+
' font-size: 11px;',
|
|
555
|
+
' white-space: nowrap;',
|
|
556
|
+
'}',
|
|
557
|
+
// #179 触控目标:窄屏菜单项抬到 44px(与复制按钮同一口径;老仓 `.fmt-item` 是 36px 上下)。
|
|
558
|
+
'@media (max-width: ' + TOAST_DEFAULTS.mobileMaxPx + 'px) {',
|
|
559
|
+
' .' + p + 'copy-menu-item {',
|
|
560
|
+
' min-height: 44px;',
|
|
561
|
+
' }',
|
|
562
|
+
// 窄屏改**贴按钮算**(老仓那句「右对齐视口内,手机不超界」的落法):桌面档按钮靠左,200px 的菜单
|
|
563
|
+
// 贴按钮会有一半越到屏幕左外;窄屏按钮在右半格,故改成
|
|
564
|
+
// 「宽 = 视口 − 左右各 16px、右缘贴按钮右缘」——既恒在视口内,又跟着按钮(滚动时不漂、不挡按钮),
|
|
565
|
+
// 也不会像 `position: fixed` 那样把浮层钉在视口底、压住别的正文。
|
|
566
|
+
//
|
|
567
|
+
// **#249 修正**:原先「宽 = 视口 − 32px + 右缘贴按钮」只在按钮位于**右格**时成立;复制数据排在
|
|
568
|
+
// 复制日志前头(`renderActionBar` 的 ghost 行顺序),窄屏上它在**左格**,菜单右缘贴左格右缘 ⇒
|
|
569
|
+
// 菜单左缘跑到视口外 167px(390 实测 x=-167,三项的格式名全看不见)。修法:窄屏把锚点从**包裹层**
|
|
570
|
+
// 换成**整行**(行在这一档挂 `position: relative`,见 `actionBar` 区);菜单 `left:0; right:0`
|
|
571
|
+
// 就落在行盒(=内容宽 358)里,按钮在哪一格都在视口内,且仍是「跟着按钮走」的绝对定位浮层。
|
|
572
|
+
' .' + p + 'copy-menu-wrap {',
|
|
573
|
+
' position: static;',
|
|
574
|
+
' }',
|
|
575
|
+
' .' + p + 'copy-menu {',
|
|
576
|
+
' left: 0;',
|
|
577
|
+
' right: 0;',
|
|
578
|
+
' width: auto;',
|
|
579
|
+
' min-width: 0;',
|
|
580
|
+
' max-width: none;',
|
|
581
|
+
' }',
|
|
582
|
+
'}',
|
|
376
583
|
focusRing('.' + p + 'copy-btn'),
|
|
377
584
|
].join(LF),
|
|
378
585
|
/** statusBadge —— 类名产出者 `controls.ts:702-707`。
|
|
@@ -382,7 +589,7 @@ const SECTION_BUILDERS = {
|
|
|
382
589
|
* ok `#e6f7ec`/`#1f8c3d`、warn `#fff5e0`/`#a25b00`、danger `#fff0ee`/`#a83228`、
|
|
383
590
|
* empty `#f0f0f3`/`var(--fg2)`(empty 字色旧层 `base.css:228` 为 `#6e6e73`=`--fg2` 解析值,底色为实色 `#f0f0f3`)。
|
|
384
591
|
* **返修 W2**:上一轮误用 `#1f8f3d`/`#b25000`(全仓无出处)+ 12% alpha 底色,且注释谎称「沿用旧值」
|
|
385
|
-
* → 已改回旧逐值,注释与实现一致(非 token 硬编码色按 D-5 以 CSS
|
|
592
|
+
* → 已改回旧逐值,注释与实现一致(非 token 硬编码色按 D-5 以 CSS 常量实施,不新增 token 名)。 */
|
|
386
593
|
statusBadge: (p) => [
|
|
387
594
|
'.' + p + 'status-badge {',
|
|
388
595
|
' display: inline-flex;',
|
|
@@ -424,14 +631,16 @@ const SECTION_BUILDERS = {
|
|
|
424
631
|
' color: var(--fg2);',
|
|
425
632
|
'}',
|
|
426
633
|
'.' + p + 'empty-icon {',
|
|
427
|
-
|
|
634
|
+
// #567 J4(§5.2 大数 28 吸收 26/28/32/40):装饰图标 40→28。
|
|
635
|
+
' font-size: 28px;',
|
|
428
636
|
' line-height: 1.2;',
|
|
429
637
|
' opacity: .5;',
|
|
430
638
|
'}',
|
|
431
639
|
'.' + p + 'empty-text {',
|
|
432
640
|
' margin-top: 8px;',
|
|
433
641
|
' color: var(--fg);',
|
|
434
|
-
|
|
642
|
+
// #567 J4(§5.2 标题 18 吸收 17/18/20/22)。
|
|
643
|
+
' font-size: 18px;',
|
|
435
644
|
' font-weight: 600;',
|
|
436
645
|
'}',
|
|
437
646
|
'.' + p + 'empty-hint {',
|
|
@@ -590,6 +799,7 @@ const SECTION_BUILDERS = {
|
|
|
590
799
|
' font-size: 13px;',
|
|
591
800
|
' font-weight: 600;',
|
|
592
801
|
' cursor: pointer;',
|
|
802
|
+
' touch-action: manipulation;',
|
|
593
803
|
'}',
|
|
594
804
|
'.' + p + 'help-shell-tab-icon {',
|
|
595
805
|
' font-size: 14px;',
|
|
@@ -712,6 +922,7 @@ const SECTION_BUILDERS = {
|
|
|
712
922
|
' font-size: 13px;',
|
|
713
923
|
' font-weight: 600;',
|
|
714
924
|
' cursor: pointer;',
|
|
925
|
+
' touch-action: manipulation;',
|
|
715
926
|
' list-style: none;',
|
|
716
927
|
'}',
|
|
717
928
|
'.' + p + 'help-shell-sheet-summary::-webkit-details-marker {',
|
|
@@ -761,11 +972,13 @@ const SECTION_BUILDERS = {
|
|
|
761
972
|
' font-size: ' + ACTION_BAR_DEFAULTS.fontSizePx + 'px;',
|
|
762
973
|
' font-weight: ' + ACTION_BAR_DEFAULTS.fontWeight + ';',
|
|
763
974
|
' line-height: 1;',
|
|
764
|
-
// #121:H-16「跑 450ms 弹簧动画」——弹簧口径**逐字复用** `copyButton`
|
|
975
|
+
// #121:H-16「跑 450ms 弹簧动画」——弹簧口径**逐字复用** `copyButton` 基础(B1
|
|
765
976
|
// `benchmark-visual-spec.md:279,645`:`transform .45s cubic-bezier(.34,1.56,.64,1)`),
|
|
766
977
|
// 不新增机制、不新增关键帧;按下态同 `.ilife-copy-btn:active`(scale .96)。
|
|
767
978
|
' transition: transform .45s cubic-bezier(.34, 1.56, .64, 1), background-color .2s ease;',
|
|
768
979
|
' cursor: pointer;',
|
|
980
|
+
' -webkit-tap-highlight-color: transparent;',
|
|
981
|
+
' touch-action: manipulation;',
|
|
769
982
|
'}',
|
|
770
983
|
'.' + p + 'help-shell-btn:active {',
|
|
771
984
|
' transform: scale(.96);',
|
|
@@ -801,6 +1014,7 @@ const SECTION_BUILDERS = {
|
|
|
801
1014
|
' font-size: 14px;',
|
|
802
1015
|
' font-weight: 600;',
|
|
803
1016
|
' cursor: pointer;',
|
|
1017
|
+
' touch-action: manipulation;',
|
|
804
1018
|
'}',
|
|
805
1019
|
'.' + p + 'help-shell-count {',
|
|
806
1020
|
' color: var(--fg3);',
|
|
@@ -899,6 +1113,7 @@ const SECTION_BUILDERS = {
|
|
|
899
1113
|
' font-size: 12px;',
|
|
900
1114
|
' line-height: 1;',
|
|
901
1115
|
' cursor: pointer;',
|
|
1116
|
+
' touch-action: manipulation;',
|
|
902
1117
|
'}',
|
|
903
1118
|
focusRing('.' + p + 'help-shell-tab-search-clear'),
|
|
904
1119
|
'.' + p + 'help-shell-page-hitcount {',
|
|
@@ -921,9 +1136,11 @@ const SECTION_BUILDERS = {
|
|
|
921
1136
|
' font-size: 12px;',
|
|
922
1137
|
' font-weight: 600;',
|
|
923
1138
|
' line-height: 1;',
|
|
924
|
-
// #121:弹簧口径同 `copyButton`
|
|
1139
|
+
// #121:弹簧口径同 `copyButton` 基础(H-16「450ms 弹簧」),成功态 `.copied` 见上方 helpShell 区。
|
|
925
1140
|
' transition: transform .45s cubic-bezier(.34, 1.56, .64, 1), background-color .2s ease;',
|
|
926
1141
|
' cursor: pointer;',
|
|
1142
|
+
' -webkit-tap-highlight-color: transparent;',
|
|
1143
|
+
' touch-action: manipulation;',
|
|
927
1144
|
'}',
|
|
928
1145
|
'.' + p + 'help-shell-card-copy:active {',
|
|
929
1146
|
' transform: scale(.96);',
|
|
@@ -984,6 +1201,7 @@ const SECTION_BUILDERS = {
|
|
|
984
1201
|
' transition: opacity .2s ease;',
|
|
985
1202
|
' z-index: 9998;',
|
|
986
1203
|
' cursor: pointer;',
|
|
1204
|
+
' touch-action: manipulation;',
|
|
987
1205
|
'}',
|
|
988
1206
|
'.' + p + 'help-shell-btn-backtop-show {',
|
|
989
1207
|
' opacity: 1;',
|
|
@@ -1048,7 +1266,7 @@ function normalizePrefix(input) {
|
|
|
1048
1266
|
/** `extraCss` 违规错误:**不导出**(与 #74 `TemplateError`/#76 `bad-input` 同口径——
|
|
1049
1267
|
* 冻结面 `SPEC_FROZEN_SURFACE` 无该运行时条目,调用方按 `name`/`code` 判定)。
|
|
1050
1268
|
* code 三值 = 契约 doc:299-300 三条「不得」的落点:
|
|
1051
|
-
* `extra-css-root
|
|
1269
|
+
* `extra-css-root`(改写基础 `:root`)/`extra-css-forbidden-token`(Q14 禁入项)/
|
|
1052
1270
|
* `extra-css-dark-scheme`(深色区选择器,doc:292)。 */
|
|
1053
1271
|
class StyleSheetExtraCssError extends Error {
|
|
1054
1272
|
code;
|
|
@@ -1059,7 +1277,7 @@ class StyleSheetExtraCssError extends Error {
|
|
|
1059
1277
|
}
|
|
1060
1278
|
}
|
|
1061
1279
|
/** CSS 块注释剥除(`/* … *\/` → 空格):**判定前先剥注释**——注释里的 `:root`/`--pink` 只是说明文字,
|
|
1062
|
-
*
|
|
1280
|
+
* 不是「改写基础/引入禁入项」;反之注释**不能**藏住真实声明(`/*c*\/:root{}` 剥后仍命中)。 */
|
|
1063
1281
|
function stripCssComments(css) {
|
|
1064
1282
|
return css.replace(/\/\*[\s\S]*?\*\//g, ' ');
|
|
1065
1283
|
}
|
|
@@ -1072,9 +1290,9 @@ function hasBoundedToken(text, token) {
|
|
|
1072
1290
|
}
|
|
1073
1291
|
/** `extraCss` 三禁强制(**编排者返修裁定:D3 修订**,见契约 §8.11)。
|
|
1074
1292
|
*
|
|
1075
|
-
* 理由:契约 doc:299-300
|
|
1293
|
+
* 理由:契约 doc:299-300 的三条「不得」(不得改写基础值/不得引入 Q14 禁入项/不得引入深色区)
|
|
1076
1294
|
* 此前**无任何落点**(D3 原裁定「不校验、纯调用方责任」)→ 本票补最小强制:
|
|
1077
|
-
* - (a) 含 `:root` 选择器 →
|
|
1295
|
+
* - (a) 含 `:root` 选择器 → 改写基础;
|
|
1078
1296
|
* - (b) 含 `STYLE_FORBIDDEN_TOKENS`(`--r-xl`/`--pink`);
|
|
1079
1297
|
* - (c) 含深色区选择器(`[data-theme`/`prefers-color-scheme: dark`)。
|
|
1080
1298
|
* 命中**任一**即抛错;**合法技能作用域覆盖块**(`.ilife-<skill>{--blue:…}`)照常通过。
|
|
@@ -1088,7 +1306,7 @@ function assertExtraCss(extraCss) {
|
|
|
1088
1306
|
const code = stripCssComments(extraCss);
|
|
1089
1307
|
// `:root` 是伪类名(CSS 伪类名大小写不敏感)→ 用 `/i` 拦住 `:ROOT` 之类的等价写法。
|
|
1090
1308
|
if (/:root(?![A-Za-z0-9_-])/i.test(code)) {
|
|
1091
|
-
throw new StyleSheetExtraCssError('extra-css-root', 'buildStyleSheet: extraCss
|
|
1309
|
+
throw new StyleSheetExtraCssError('extra-css-root', 'buildStyleSheet: extraCss 不得改写基础(命中 `:root` 选择器);技能主题只许用 `.ilife-<skill>` 作用域覆盖块(契约 doc:299)');
|
|
1092
1310
|
}
|
|
1093
1311
|
for (const forbidden of STYLE_FORBIDDEN_TOKENS) {
|
|
1094
1312
|
if (hasBoundedToken(code, forbidden)) {
|