1313 * —— 批 6 的动效 token 真源落地后删 `motion.css` 的变量块即生效。
1414 * ③ 与其它原语同向的纪律:类名 ↔ CSS 规则一致 · 零颜色字面量 · 零 `z-index`(层级是 TS 标尺的
1515 * 职责)· `--ed-stamp` 不进任何 `background` 声明(规格 §4.1「绝不用于按钮」)。
16+ * ④ **退场时长的两个真源对拍**(T9 评审 I-3):`Toast.tsx` 的 `EXIT_MS` 与 `motion.css` 的
17+ * `--ed-dur-toast-out` 必须同值 —— 前者还决定 `usePresence` 的兜底窗口(+80ms),两者脱钩会让
18+ * "退场中途被兜底摘掉"成为无判据可抓的静默缺陷。
1619 *
1720 * 副作用:只读磁盘(同目录两个文件),不修改任何文件。
1821 * 边界:判据前先**剥注释**(注释里会提到反例串);EOL 归一(本仓无 `.gitattributes` 且
@@ -29,6 +32,7 @@ const stripComments = (s: string): string => s.replace(/\/\*[\s\S]*?\*\//g, "");
2932
3033const CLEAN = stripComments ( read ( "Toast.css" ) ) ;
3134const TSX = read ( "Toast.tsx" ) ;
35+ const MOTION_CSS = read ( "motion.css" ) ;
3236
3337/** 颜色字面量(与 `style-seams.test.ts` 同一口径:本层不得出现,颜色只经 `var(--ed-*)`) */
3438const COLOR_LITERAL = / # [ 0 - 9 a - f A - F ] { 3 , 8 } \b | \b (?: r g b | h s l ) a ? \( / ;
@@ -106,3 +110,23 @@ describe("③ 纪律判据(与批 0-D 其它原语同向)", () => {
106110 expect ( TSX , "不 import 自己的 CSS ⇒ 全部类静默无样式" ) . toContain ( 'import "./Toast.css";' ) ;
107111 } ) ;
108112} ) ;
113+
114+ describe ( "④ 退场时长的两个真源对拍(T9 评审 I-3)" , ( ) => {
115+ /**
116+ * `Toast.tsx` 的 `EXIT_MS` 与 `motion.css` 的 `--ed-dur-toast-out` 是**并列的真源**:前者还是
117+ * `usePresence` 兜底窗口的一半(`EXIT_MS + timeoutSlackMs(80)` = 220ms)。若将来有人只把 token
118+ * 调大(如 260ms)而 `EXIT_MS` 不动 ⇒ 名义过渡比兜底还长,**退场演到一半就被兜底计时器摘掉**,
119+ * 而没有任何断言会红。故把两者钉成同一个数字。
120+ *
121+ * 边界(本条**不覆盖**):① 只判"两个数字相等",不判 CSS 是否真的引用了该变量(那是 ② 的职责);
122+ * ② `usePresence` 的 slack 默认值(80)不在此判据内 —— 改它须连 `usePresence.test.tsx` 一起改;
123+ * ③ 若批 6 把时长搬进 token 真源并删掉 `motion.css` 的变量块,本条会红,届时按新的唯一真源改写。
124+ */
125+ it ( "`const EXIT_MS` == `--ed-dur-toast-out`(否则兜底窗口会把退场中途摘掉)" , ( ) => {
126+ const exitMs = / c o n s t E X I T _ M S = ( \d + ) ; / . exec ( TSX ) ?. [ 1 ] ;
127+ const tokenMs = / - - e d - d u r - t o a s t - o u t : \s * ( \d + ) m s ; / . exec ( MOTION_CSS ) ?. [ 1 ] ;
128+ expect ( exitMs , "Toast.tsx 缺 `const EXIT_MS = <n>;`" ) . toBeDefined ( ) ;
129+ expect ( tokenMs , "motion.css 缺 `--ed-dur-toast-out: <n>ms;`" ) . toBeDefined ( ) ;
130+ expect ( Number ( exitMs ) , "退场名义时长必须与 --ed-dur-toast-out 同值(兜底窗口 = EXIT_MS + 80)" ) . toBe ( Number ( tokenMs ) ) ;
131+ } ) ;
132+ } ) ;
0 commit comments