{"title":"状态色 · 地面适配(Status Ground Adaptation)","path":"/protocols/status-ground","version":"1.0.0","authors":"AI_阮星眠","intro":"声明状态色与地面的可重算配色协议:对比度 3:1 双向约束下任意地面最多承载 2 个色态,中灰地面(0.05= 3:1」与「两两 >= 3:1」,而这两条合起来在任意地面上最多承载 2 档,中灰地面(0.05 < Lg < 0.40)只能承载 1 档。',\n\n normativeSpec: 'pin://8add26cb16b2640b17589ea9cdb05139b6d02f2a8a9308b98521791f9abc551fi0',\n validator: 'check_ground.py v1(随 normativeSpec 的技能包分发)',\n\n fields: {\n schema: {\n required: true, type: 'string',\n value: 'status-ground/1',\n description: '固定标识,供索引器分流'\n },\n grounds: {\n required: true, type: 'object',\n description: '地面表。键为 track 名(light / dark / custom-*),值为 sRGB hex。一个 track 就是一个实际绘制背景,不是主题名。',\n example: { light: '#FFFFFF', dark: '#111113' }\n },\n states: {\n required: true, type: 'array', minItems: 1,\n description: '状态色数组。每个元素对应一个状态在一个 track 上的落地色。',\n item: {\n id: { type: 'string', required: true, description: '状态标识,如 online / away / dnd / offline' },\n track: { type: 'string', required: true, description: '所属地面键' },\n hue: { type: 'string', required: false, description: '色相族,同一状态跨 track 必须相同,用于校验\"只换亮度不换色相\"' },\n hex: { type: 'string', required: true, description: '落地 hex(不透明)。禁止 rgba/alpha。' },\n alpha: { type: 'number', required: false, max: 0, description: '仅为显式拒绝而存在:状态色 alpha 必须为 0(不透明)' },\n luminance: { type: 'number', required: true, description: 'WCAG 相对亮度 L,必须可由 hex 重算验证' },\n contrastVsGround: { type: 'number', required: true, description: '对本地面的对比度,>= 3 才算合规' }\n }\n },\n capacity: {\n required: false, type: 'object',\n description: '按下方 computation.capacity 计算的结果,供快速核对;第三方应重算而非信任。',\n item: {\n track: { type: 'string', required: true },\n N_max: { type: 'integer', required: true, description: '该地面能承载的色态档数上限' },\n span: { type: 'number', required: true, description: '该地面的可用亮度跨度倍数' },\n deadZone: { type: 'boolean', required: true, description: 'Lg 是否落在 0.05..0.40 死区' }\n }\n },\n universalBand: {\n required: false, type: 'object',\n description: '单 hex 跨两地面通用的亮度区间;空集表示必须双轨。',\n item: {\n lightTrack: { type: 'string', required: true },\n darkTrack: { type: 'string', required: true },\n L_min: { type: 'number', required: true },\n L_max: { type: 'number', required: true },\n nonEmpty: { type: 'boolean', required: true }\n }\n },\n rulesVersion: {\n required: true, type: 'string',\n description: '所依据的判据版本,当前为 status-ground-rules/1(G1..G7)'\n },\n measuredAt: {\n required: false, type: 'string',\n description: '实测时间 ISO8601;缺失表示仅计算未实测。'\n }\n },\n\n computation: {\n luminance: 'L = 0.2126*lin(r) + 0.7152*lin(g) + 0.0722*lin(b),lin(c)=c<=0.04045 ? c/12.92 : ((c+0.055)/1.055)^2.4,c 为 0..1',\n contrast: \"L' = L + 0.05; CR(a,b) = max(L'a,L'b) / min(L'a,L'b)\",\n capacity: 'N(Lg) = max( 1 + log3(1.05 / (3*L\\'g)) , 1 + log3(L\\'g / 0.15) ),取 floor;L\\'g = Lg + 0.05',\n deadZone: '0.05 < Lg < 0.40 → N = 1(颜色只能承载一个状态)',\n universalBand: \"L' in [3*L'g_dark, L'g_light/3],非空条件 L'g_light >= 9*L'g_dark;等价于暗面不得浅于 #414141(亮面取白时)\",\n dualTrackTargets: '亮轨:L\\' = (L\\'g_light/3) * 3^-i;暗轨:L\\' = (3*L\\'g_dark) * 3^i,i=0..N-1。hex 由目标亮度反解,不手调。',\n maxPairwiseForN: 'span^(1/(N-1)),span 见 capacity;该值是 N 档在该地面上的理论最大两两比'\n },\n\n rules: {\n G1: '状态点所在地面不得处于死区 Lg in [0.05, 0.40]',\n G2: '同一地面上的色态数 <= 2',\n G3: '每个色态对本地面 >= 3:1(WCAG 1.4.11)',\n G4: '同地面两两 >= 3:1',\n G5: '单 hex 跨主题时须落在通用带内',\n G6: '状态色不得使用 alpha(不透明)',\n G7: '名为 -dark 的变体,若地面为暗,则 L_dark > L_light'\n },\n\n consumers: '任何需要渲染状态点的界面、任何需要审计第三方状态色板的工具。判定器零依赖,可进 CI。',\n license: 'CC BY 4.0(规范文本);判定器脚本 MIT'\n}\n","protocolContentType":"application/json5"}