#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
lint_frames.py —— 场景帧静态体检(渲染前跑,比渲完全片再发现问题便宜得多)。
检查项(全部来自 references/frame-contract.md 的八条契约 + 已知踩坑):
1. 画布:html,body 是否声明 1920×1080(或 project.json 的尺寸)
2. 外部字体 / CDN:、fonts.googleapis、@import url(http
3. 色值字面量:#RRGGBB / rgb() / rgba() 出现在 CSS 里(theme.css 变量之外)
—— 例外:纯黑/纯白阴影 rgba(0,0,0,x) 允许(阴影不是"配色")
4. 时间轴注册:window.__tl = (或 window.__timelines)
5. GSAP 本地引用:../assets/gsap.min.js(禁 CDN)
6. 墙钟逻辑:setInterval / setTimeout(数字) / requestAnimationFrame 计数
7. CSS transition 入场
8. B() 兜底:B('x') || 数字
9. 字幕带禁区:CSS 里 bottom < 176px 的规则且带内容属性(启发式,转人工确认)
10. 字体栈:必须含中文字体族(Microsoft YaHei / PingFang 等)
用法:
python lint_frames.py --project . # 全量
python lint_frames.py --project . --only hook,decision
"""
from __future__ import annotations
import argparse
import json
import os
import re
import sys
HEX = re.compile(r"#[0-9a-fA-F]{3,8}\b")
RGBA = re.compile(r"\brgba?\([^)]*\)")
FONT_LINK = re.compile(r"]+href\s*=\s*[\"']https?://", re.I)
IMPORT_HTTP = re.compile(r"@import\s+url\(\s*[\"']?https?://", re.I)
GSAP_CDN = re.compile(r"