更新技术美术明亮教具室版:字体、指路、教学与庆祝效果
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"tool": "built-in image_gen",
|
||||
"purpose": "原创竖屏美术概念效果图,非最终生产素材",
|
||||
"directions": [
|
||||
"Use case: ui-mockup. Create ONE polished portrait mobile puzzle game screenshot, 9:16 composition, edge-to-edge UI, no phone hardware, no surrounding presentation board. Original game inspired by the cheerful approachable educational toy design principles of Big Brain Academy Brain vs Brain, NOT copying its logo, mascot or exact UI. Simplified charming console-quality art direction, moderately richer than minimalist wireframes, not elaborate scenery. Perfectly top-down readable puzzle with shallow 3D bevels and short soft shadows, no perspective distortion. Exact central board geometry on a 4 column x 5 row invisible square grid: row1 only col2 single tile; row2 only col2 single tile; rows3 and4 col1 andcol4 are separate single tiles, while cols2+3 across BOTH rows are ONE seamless 2x2 large square tile; row5 four separate single tiles. Total 11 logical tiles. No internal seam in the large square. Top two tiles and large central tile are purple/blue visited, connected down their shared edges by small matching color bridges. White digits 1 in top tile, 2 in second tile, 3 anchored in TOP LEFT unit of large square. One dark fixed digit 8 in row5 col2. All other tiles blank. No other numeric labels inside board. Large board occupies main central area with spacious margins. Chinese text exact and legible: top title \"数字一笔\", small level label \"关卡 1-8\", compact status \"已走 3 步 · 还剩 8 块\"; below board small instruction \"每块只走一次\"; bottom exactly three generous buttons labeled \"重开\" \"补数字\" \"指路\" with simple appropriate icons above words. Consistent typographic hierarchy. Do not add timer, currency, ads, heart lives, sidebars or scores. No hands, no device, no watermarks. DIRECTION: 明亮教具室. Warm butter yellow full page background with extremely faint oversized outline doodles of simple geometry only outside board, cream softly rounded central teaching mat. Matte ivory resin unvisited blocks with substantial but subtle pale beige side faces, blueberry purple visited blocks and path, small coral accent on level tab and reset icon. Bold rounded friendly Chinese title, tidy readable functional type. Slightly handmade polished educational toy character; no mascot. Bottom buttons three chunky cream rounded keycaps, right hint key purple. One small scalloped coral chapter tag at top, small sparse geometric marks outside play area only. Warm cheerful daytime studio lighting. Restrained coherent palette, crisp high quality game art, not glossy candy. Clearly visible toy bevels and clean structural borders.",
|
||||
"Use case: ui-mockup. Create ONE polished portrait mobile puzzle game screenshot, 9:16 composition, edge-to-edge UI, no phone hardware, no surrounding presentation board. Original game inspired by the cheerful approachable educational toy design principles of Big Brain Academy Brain vs Brain, NOT copying its logo, mascot or exact UI. Simplified charming console-quality art direction, moderately richer than minimalist wireframes, not elaborate scenery. Perfectly top-down readable puzzle with shallow 3D bevels and short soft shadows, no perspective distortion. Exact central board geometry on a 4 column x 5 row invisible square grid: row1 only col2 single tile; row2 only col2 single tile; rows3 and4 col1 andcol4 are separate single tiles, while cols2+3 across BOTH rows are ONE seamless 2x2 large square tile; row5 four separate single tiles. Total 11 logical tiles. No internal seam in the large square. Top two tiles and large central tile are purple/blue visited, connected down their shared edges by small matching color bridges. White digits 1 in top tile, 2 in second tile, 3 anchored in TOP LEFT unit of large square. One dark fixed digit 8 in row5 col2. All other tiles blank. No other numeric labels inside board. Large board occupies main central area with spacious margins. Chinese text exact and legible: top title \"数字一笔\", small level label \"关卡 1-8\", compact status \"已走 3 步 · 还剩 8 块\"; below board small instruction \"每块只走一次\"; bottom exactly three generous buttons labeled \"重开\" \"补数字\" \"指路\" with simple appropriate icons above words. Consistent typographic hierarchy. Do not add timer, currency, ads, heart lives, sidebars or scores. No hands, no device, no watermarks. DIRECTION: 桌游题卡. Mint sage desktop-color backdrop, a tall large cream card with generous elegant margins centered nearly filling screen, rounded clipped card corners, subtle paper thickness and short shadow, navy ink typography. Header within card uses a clean orderly editorial title, small coral rectangular chapter tab and delicate dividing rule. Puzzle blocks are matte pastel ivory board game pieces, active path muted saturated cobalt blue; unvisited edges subtle blue grey. Background very sparse, only one or two simplified offset card corners visible behind main card near top; no desk objects. Bottom three orderly rectangular tactile buttons integrated into lower card, hint cobalt. Small printed circular completion-stamp motif empty near footer but not distracting. Family-friendly mature refined board game style, richer than flat UI, calm balanced composition.",
|
||||
"Use case: ui-mockup. Create ONE polished portrait mobile puzzle game screenshot, 9:16 composition, edge-to-edge UI, no phone hardware, no surrounding presentation board. Original game inspired by the cheerful approachable educational toy design principles of Big Brain Academy Brain vs Brain, NOT copying its logo, mascot or exact UI. Simplified charming console-quality art direction, moderately richer than minimalist wireframes, not elaborate scenery. Perfectly top-down readable puzzle with shallow 3D bevels and short soft shadows, no perspective distortion. Exact central board geometry on a 4 column x 5 row invisible square grid: row1 only col2 single tile; row2 only col2 single tile; rows3 and4 col1 andcol4 are separate single tiles, while cols2+3 across BOTH rows are ONE seamless 2x2 large square tile; row5 four separate single tiles. Total 11 logical tiles. No internal seam in the large square. Top two tiles and large central tile are purple/blue visited, connected down their shared edges by small matching color bridges. White digits 1 in top tile, 2 in second tile, 3 anchored in TOP LEFT unit of large square. One dark fixed digit 8 in row5 col2. All other tiles blank. No other numeric labels inside board. Large board occupies main central area with spacious margins. Chinese text exact and legible: top title \"数字一笔\", small level label \"关卡 1-8\", compact status \"已走 3 步 · 还剩 8 块\"; below board small instruction \"每块只走一次\"; bottom exactly three generous buttons labeled \"重开\" \"补数字\" \"指路\" with simple appropriate icons above words. Consistent typographic hierarchy. Do not add timer, currency, ads, heart lives, sidebars or scores. No hands, no device, no watermarks. DIRECTION: 几何游乐场. Soft coral pink background, pale apricot large rounded asymmetric stage behind board. Original cheerful geometric brand system: sparse large cropped circle, arch and triangle at outer margins, never touching or resembling board cells; no character. Active path deep teal blue, unvisited tiles warm cream with smooth small bevels and subtle warm side faces. Playful rounded Chinese heading slightly dynamic but all numeric clues upright and precise. Top level label small cobalt pill. Bottom three rounded physical buttons, hint teal, one small mustard accent on reset. Richer playful rhythm in spacing and composition, but restrained total decorative shapes and no scenery. Premium simplified game UI, strong coherent shapes, crisp readability, no excessive confetti."
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
@@ -0,0 +1,34 @@
|
||||
import {readFileSync,writeFileSync} from 'node:fs';
|
||||
import {createHash} from 'node:crypto';
|
||||
const local=p=>new URL(p,import.meta.url);
|
||||
const tokens=JSON.parse(readFileSync(local('tokens.json'),'utf8'));
|
||||
function luminance(hex){
|
||||
if(!/^#[0-9a-f]{6}$/i.test(hex))throw Error('Expected opaque sRGB: '+hex);
|
||||
const c=[1,3,5].map(i=>parseInt(hex.slice(i,i+2),16)/255).map(v=>v<=.04045?v/12.92:((v+.055)/1.055)**2.4);
|
||||
return c[0]*.2126+c[1]*.7152+c[2]*.0722;
|
||||
}
|
||||
const resolve=k=>tokens.color[k]??k;
|
||||
const rows=tokens.contrastPairs.map(p=>{const foreground=resolve(p.fg),background=resolve(p.bg),a=luminance(foreground),b=luminance(background),ratio=(Math.max(a,b)+.05)/(Math.min(a,b)+.05);return {...p,foreground,background,ratio,pass:p.minimum===null?null:ratio>=p.minimum};});
|
||||
writeFileSync(local('contrast-audit.json'),JSON.stringify({method:'WCAG relative luminance; opaque sRGB; unrounded thresholds; static token pairs only, not complete UI compliance',rows},null,2)+'\n');
|
||||
console.table(rows.map(p=>({pair:p.name,ratio:p.ratio.toFixed(3),minimum:p.minimum,result:p.pass===null?'diagnostic':p.pass?'pass':'FAIL'})));
|
||||
const tracked=[
|
||||
'../../../README.md',
|
||||
'../../../wechat-campaign-200-r2/README.md',
|
||||
'../../../wechat-campaign-200-r2/src/upstream/levels.json',
|
||||
'../../../wechat-campaign-200-r2/src/upstream/rules.mjs',
|
||||
'../../../wechat-campaign-200-r2/src/main.mjs',
|
||||
'../../../wechat-campaign-200-r2/src/hints.mjs',
|
||||
'../../../modes/01-number-stroke/src/board.ts',
|
||||
'../../../modes/01-number-stroke/src/game.ts',
|
||||
'../../../modes/03-hex-walls/src/board.ts'
|
||||
];
|
||||
// Paths above resolve from docs/design/bright-classroom/ to repository root.
|
||||
const sources=tracked.map(path=>{const bytes=readFileSync(local(path));return {path,sha256:createHash('sha256').update(bytes).digest('hex')};});
|
||||
const p=JSON.parse(readFileSync(local('../../../wechat-campaign-200-r2/src/upstream/levels.json'),'utf8'));
|
||||
const countBy=fn=>p.levels.reduce((out,l)=>{const k=fn(l);out[k]=(out[k]??0)+1;return out;},{});
|
||||
const extent=l=>{if(l.geometry==='hex')return null;const points=l.cells.flatMap(c=>c.shape?c.shape.map(([x,y])=>[c.x+x,c.y+y]):Array.from({length:(c.w??1)*(c.h??1)},(_,i)=>[c.x+i%(c.w??1),c.y+Math.floor(i/(c.w??1))]));return {cols:Math.max(...points.map(p=>p[0]))-Math.min(...points.map(p=>p[0]))+1,rows:Math.max(...points.map(p=>p[1]))-Math.min(...points.map(p=>p[1]))+1};};
|
||||
const examples=p.levels.map(l=>({id:l.id,chapter:l.chapter,geometry:l.geometry,features:l.features,cells:l.cells.length,...extent(l)}));
|
||||
const audit={date:'2026-10-21',scope:'Read-only design inventory; not solver validation',sources,campaign:{levels:p.levels.length,chapters:p.chapters.length,playOrder:p.playOrder.length,geometry:countBy(l=>l.geometry),featureCounts:Object.fromEntries([...new Set(p.levels.flatMap(l=>l.features))].map(f=>[f,p.levels.filter(l=>l.features.includes(f)).length])),minCells:Math.min(...p.levels.map(l=>l.cells.length)),maxCells:Math.max(...p.levels.map(l=>l.cells.length)),nonemptyConstraintCounts:Object.fromEntries(['relations','orderChains','windows','walls','doors','gates'].map(k=>[k,p.levels.filter(l=>l[k]?.length).length]))},examples};
|
||||
writeFileSync(local('project-audit.json'),JSON.stringify(audit,null,2)+'\n');
|
||||
console.log(JSON.stringify(audit.campaign,null,2));
|
||||
if(rows.some(p=>p.pass===false))process.exitCode=1;
|
||||
@@ -0,0 +1,305 @@
|
||||
{
|
||||
"method": "WCAG relative luminance; opaque sRGB; unrounded thresholds; static token pairs only, not complete UI compliance",
|
||||
"rows": [
|
||||
{
|
||||
"name": "标题/黄底",
|
||||
"fg": "ink",
|
||||
"bg": "background",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#43382F",
|
||||
"background": "#FFE69A",
|
||||
"ratio": 9.232457114035482,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "辅助文字/黄底",
|
||||
"fg": "inkSecondary",
|
||||
"bg": "background",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#71604F",
|
||||
"background": "#FFE69A",
|
||||
"ratio": 4.884289301747754,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "正文/舞台",
|
||||
"fg": "ink",
|
||||
"bg": "stage",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#43382F",
|
||||
"background": "#FFF6DF",
|
||||
"ratio": 10.566877010581722,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "辅助文字/舞台",
|
||||
"fg": "inkSecondary",
|
||||
"bg": "stage",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#71604F",
|
||||
"background": "#FFF6DF",
|
||||
"ratio": 5.590243604512046,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "数字/未走块",
|
||||
"fg": "ink",
|
||||
"bg": "cellFace",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#43382F",
|
||||
"background": "#FFF8EA",
|
||||
"ratio": 10.765868439756863,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "白数字/路径",
|
||||
"fg": "onPrimary",
|
||||
"bg": "primary",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#FFFFFF",
|
||||
"background": "#6552D9",
|
||||
"ratio": 5.581827872446398,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "白字/按压紫",
|
||||
"fg": "onPrimary",
|
||||
"bg": "primaryPressed",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#FFFFFF",
|
||||
"background": "#5140B7",
|
||||
"ratio": 7.589436402107891,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "白数字/错误",
|
||||
"fg": "onPrimary",
|
||||
"bg": "danger",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#FFFFFF",
|
||||
"background": "#B93B46",
|
||||
"ratio": 5.56014089796343,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "错误说明/淡红",
|
||||
"fg": "dangerInk",
|
||||
"bg": "dangerSoft",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#862735",
|
||||
"background": "#FBE4E5",
|
||||
"ratio": 7.358198572071083,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "珊瑚标签文字",
|
||||
"fg": "coralInk",
|
||||
"bg": "coral",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#4F2418",
|
||||
"background": "#F57950",
|
||||
"ratio": 4.839371438999691,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "淡紫选中文字",
|
||||
"fg": "primaryPressed",
|
||||
"bg": "primarySoft",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#5140B7",
|
||||
"background": "#ECE7FF",
|
||||
"ratio": 6.303185573751691,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "提示文字/淡黄",
|
||||
"fg": "hint",
|
||||
"bg": "hintSoft",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#8B5E00",
|
||||
"background": "#FFF0B8",
|
||||
"ratio": 4.976695326004001,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "成功文字/淡绿",
|
||||
"fg": "success",
|
||||
"bg": "successSoft",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#2E6B52",
|
||||
"background": "#DEEFDC",
|
||||
"ratio": 5.233622489592483,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "蓝类别标记",
|
||||
"fg": "categoryBlueInk",
|
||||
"bg": "categoryBlueFace",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#245A92",
|
||||
"background": "#CEE4FF",
|
||||
"ratio": 5.4751847239513065,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "橙类别标记",
|
||||
"fg": "categoryOrangeInk",
|
||||
"bg": "categoryOrangeFace",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#8A470E",
|
||||
"background": "#FFE0B2",
|
||||
"ratio": 5.54066890035091,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "数字/蓝类别面",
|
||||
"fg": "ink",
|
||||
"bg": "categoryBlueFace",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#43382F",
|
||||
"background": "#CEE4FF",
|
||||
"ratio": 8.760129662894578,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "数字/橙类别面",
|
||||
"fg": "ink",
|
||||
"bg": "categoryOrangeFace",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#43382F",
|
||||
"background": "#FFE0B2",
|
||||
"ratio": 8.972232377643234,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "格边/格面",
|
||||
"fg": "cellBoundary",
|
||||
"bg": "cellFace",
|
||||
"minimum": 3,
|
||||
"foreground": "#8A7660",
|
||||
"background": "#FFF8EA",
|
||||
"ratio": 4.10397343242954,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "格边/舞台",
|
||||
"fg": "cellBoundary",
|
||||
"bg": "stage",
|
||||
"minimum": 3,
|
||||
"foreground": "#8A7660",
|
||||
"background": "#FFF6DF",
|
||||
"ratio": 4.0281174489400735,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "路径/未走格",
|
||||
"fg": "primary",
|
||||
"bg": "cellFace",
|
||||
"minimum": 3,
|
||||
"foreground": "#6552D9",
|
||||
"background": "#FFF8EA",
|
||||
"ratio": 5.280691791017535,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "提示描边/舞台",
|
||||
"fg": "hintCasing",
|
||||
"bg": "stage",
|
||||
"minimum": 3,
|
||||
"foreground": "#43382F",
|
||||
"background": "#FFF6DF",
|
||||
"ratio": 10.566877010581722,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "提示白芯/描边",
|
||||
"fg": "hintCore",
|
||||
"bg": "hintCasing",
|
||||
"minimum": 3,
|
||||
"foreground": "#FFFFFF",
|
||||
"background": "#43382F",
|
||||
"ratio": 11.379801530993449,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "墙/黄色条纹",
|
||||
"fg": "wallInk",
|
||||
"bg": "wallStripe",
|
||||
"minimum": 3,
|
||||
"foreground": "#43382F",
|
||||
"background": "#F7C74D",
|
||||
"ratio": 7.1700148267761294,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "墙/舞台",
|
||||
"fg": "wallInk",
|
||||
"bg": "stage",
|
||||
"minimum": 3,
|
||||
"foreground": "#43382F",
|
||||
"background": "#FFF6DF",
|
||||
"ratio": 10.566877010581722,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "开门标记/舞台",
|
||||
"fg": "doorOpen",
|
||||
"bg": "stage",
|
||||
"minimum": 3,
|
||||
"foreground": "#2E6B52",
|
||||
"background": "#FFF6DF",
|
||||
"ratio": 5.836381119577005,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "关门标记/舞台",
|
||||
"fg": "doorClosed",
|
||||
"bg": "stage",
|
||||
"minimum": 3,
|
||||
"foreground": "#8B4B29",
|
||||
"background": "#FFF6DF",
|
||||
"ratio": 6.217581699869901,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "焦点/黄底",
|
||||
"fg": "focus",
|
||||
"bg": "background",
|
||||
"minimum": 3,
|
||||
"foreground": "#5140B7",
|
||||
"background": "#FFE69A",
|
||||
"ratio": 6.15732584714453,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "白字/珊瑚(仅诊断,不采用)",
|
||||
"fg": "onPrimary",
|
||||
"bg": "coral",
|
||||
"minimum": null,
|
||||
"foreground": "#FFFFFF",
|
||||
"background": "#F57950",
|
||||
"ratio": 2.715535351933964,
|
||||
"pass": null
|
||||
},
|
||||
{
|
||||
"name": "格面/舞台(仅诊断,格边承担识别)",
|
||||
"fg": "cellFace",
|
||||
"bg": "stage",
|
||||
"minimum": null,
|
||||
"foreground": "#FFF8EA",
|
||||
"background": "#FFF6DF",
|
||||
"ratio": 1.0188316215827884,
|
||||
"pass": null
|
||||
},
|
||||
{
|
||||
"name": "蓝类别面/橙类别面(仅诊断,另配形状)",
|
||||
"fg": "categoryBlueFace",
|
||||
"bg": "categoryOrangeFace",
|
||||
"minimum": null,
|
||||
"foreground": "#CEE4FF",
|
||||
"background": "#FFE0B2",
|
||||
"ratio": 1.0242122802870215,
|
||||
"pass": null
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"meta":{"name":"NumberSwipe 明亮教具室","version":"1.0-proposal","date":"2026-10-21","status":"Design specification; not applied to runtime","unit":"logical layout unit, not physical pixel","reference":[375,812]},
|
||||
"color":{
|
||||
"background":"#FFE69A","backgroundBottom":"#FFDE79","pattern":"#E8BE54","stage":"#FFF6DF","surface":"#FFFBF2","surfaceMuted":"#F1E6D0","cellFace":"#FFF8EA","cellDepth":"#D8C4A0","cellBoundary":"#8A7660","cellBevel":"#FFFFFF",
|
||||
"ink":"#43382F","inkSecondary":"#71604F","primary":"#6552D9","primaryPressed":"#5140B7","primaryDepth":"#49379E","primarySoft":"#ECE7FF","primaryEdge":"#ADA0F1","onPrimary":"#FFFFFF",
|
||||
"coral":"#F57950","coralInk":"#4F2418","coralSoft":"#FFE0CF","danger":"#B93B46","dangerDepth":"#8D2934","dangerSoft":"#FBE4E5","dangerInk":"#862735",
|
||||
"hint":"#8B5E00","hintSoft":"#FFF0B8","hintCore":"#FFFFFF","hintCasing":"#43382F","hintRibbon":"#F49B75","hintRibbonDepth":"#C96E48","hintRibbonLight":"#FFF5DD","hintSpark":"#FFFDF0","success":"#2E6B52","successSoft":"#DEEFDC",
|
||||
"categoryBlueFace":"#CEE4FF","categoryBlueInk":"#245A92","categoryOrangeFace":"#FFE0B2","categoryOrangeInk":"#8A470E","wallInk":"#43382F","wallStripe":"#F7C74D","doorClosed":"#8B4B29","doorOpen":"#2E6B52","disabledFace":"#E9E1D3","disabledInk":"#7A7064","focus":"#5140B7","overlay":"#43382F"
|
||||
},
|
||||
"referenceMatch":{
|
||||
"version":"2-reference-cushion","authority":"User-supplied reference image; overrides earlier flat production proposal",
|
||||
"color":{"background":"#FFE383","backgroundBottom":"#FFDA68","pattern":"#EFBF4D","stage":"#FAEED6","surface":"#FBEFD9","cellFace":"#F9EDD5","cellDepth":"#CDB590","ink":"#51452E","inkSecondary":"#796644","primary":"#8178F4","primaryPressed":"#7369DF","primaryDepth":"#5750BA","primaryEdge":"#B7AAFF","coral":"#FF7946"},
|
||||
"pitchMax":104,"bridgeRatio":0.25,"cellDepthRatio":0.085,"cellDepthMax":7,"bevelRatio":0.085,"stageMargin":12,"buttonRadiusRatio":0.32,
|
||||
"conditionFrames":false,"endpointCorners":false,"categoryVisitedFrames":false
|
||||
},
|
||||
"font":{"numeric":"Nunito","cjk":"Noto Sans SC","fallback":"system-ui, -apple-system, Segoe UI, Microsoft YaHei, sans-serif","numericWeight":800,"bodyWeight":500,"labelWeight":600,"headingWeight":700},
|
||||
"type":{"display":{"size":32,"line":40,"weight":800},"pageTitle":{"size":24,"line":32,"weight":700},"section":{"size":18,"line":26,"weight":700},"body":{"size":16,"line":24,"weight":500},"button":{"size":16,"line":22,"weight":700},"label":{"size":14,"line":20,"weight":600},"caption":{"size":13,"line":18,"weight":500},"micro":{"size":12,"line":16,"weight":500}},
|
||||
"spacing":[4,8,12,16,20,24,32,40,48],
|
||||
"layout":{"referenceWidth":375,"referenceHeight":812,"margin":20,"compactMargin":16,"topbarHeight":48,"headerHeight":40,"statusHeight":28,"playfieldHeight":464,"feedbackHeight":40,"actionHeight":64,"actionGap":10,"tapTarget":48,"pitchPreferred":56,"pitchTargetMin":44,"pitchReviewBelow":44,"tileInsetRatio":0.045,"bridgeThicknessRatio":0.42,"stagePadding":16},
|
||||
"radius":{"small":8,"label":12,"button":18,"stage":28,"card":24,"sheet":28,"dialog":24,"cellRatio":0.18,"cellMin":6,"cellMax":12,"concaveMaxRatio":0.06,"hexMaxRatio":0.11},
|
||||
"material":{"light":"upper-left","cellDepthRatio":0.055,"cellDepthMin":2,"cellDepthMax":4,"pressedDepth":1,"cellBoundary":1.25,"bevelWidth":1,"gradientChannelDeltaMax":6,"cellShadow":{"x":0,"y":3,"blur":5,"alpha":0.10},"stageShadow":{"x":0,"y":4,"blur":10,"alpha":0.08},"buttonShadow":{"x":0,"y":3,"blur":5,"alpha":0.12},"dialogShadow":{"x":0,"y":12,"blur":28,"alpha":0.16}},
|
||||
"motionMs":{"fast":120,"base":200,"slow":320,"hold":500,"buttonPress":80,"buttonRelease":120,"step":140,"bridge":120,"undo":100,"conflict":200,"hintAttention":2400,"hintSegmentCycleMin":1200,"door":160,"spinner":160,"clearSweep":320,"clearHold":500,"entryStagger":12,"entryStaggerCap":120},
|
||||
"motion":{"easeOut":[0.22,1,0.36,1],"stepPeak":1.015,"stepPressed":0.985,"buttonPressed":0.98,"conflictTravelMax":1.5,"spinnerDegrees":120,"ambientAnimation":false,"reducedMotionHint":"static dashed path; keep all hint information"},
|
||||
"contrastPairs":[
|
||||
{"name":"标题/黄底","fg":"ink","bg":"background","minimum":4.5},
|
||||
{"name":"辅助文字/黄底","fg":"inkSecondary","bg":"background","minimum":4.5},
|
||||
{"name":"正文/舞台","fg":"ink","bg":"stage","minimum":4.5},
|
||||
{"name":"辅助文字/舞台","fg":"inkSecondary","bg":"stage","minimum":4.5},
|
||||
{"name":"数字/未走块","fg":"ink","bg":"cellFace","minimum":4.5},
|
||||
{"name":"白数字/路径","fg":"onPrimary","bg":"primary","minimum":4.5},
|
||||
{"name":"白字/按压紫","fg":"onPrimary","bg":"primaryPressed","minimum":4.5},
|
||||
{"name":"白数字/错误","fg":"onPrimary","bg":"danger","minimum":4.5},
|
||||
{"name":"错误说明/淡红","fg":"dangerInk","bg":"dangerSoft","minimum":4.5},
|
||||
{"name":"珊瑚标签文字","fg":"coralInk","bg":"coral","minimum":4.5},
|
||||
{"name":"淡紫选中文字","fg":"primaryPressed","bg":"primarySoft","minimum":4.5},
|
||||
{"name":"提示文字/淡黄","fg":"hint","bg":"hintSoft","minimum":4.5},
|
||||
{"name":"成功文字/淡绿","fg":"success","bg":"successSoft","minimum":4.5},
|
||||
{"name":"蓝类别标记","fg":"categoryBlueInk","bg":"categoryBlueFace","minimum":4.5},
|
||||
{"name":"橙类别标记","fg":"categoryOrangeInk","bg":"categoryOrangeFace","minimum":4.5},
|
||||
{"name":"数字/蓝类别面","fg":"ink","bg":"categoryBlueFace","minimum":4.5},
|
||||
{"name":"数字/橙类别面","fg":"ink","bg":"categoryOrangeFace","minimum":4.5},
|
||||
{"name":"格边/格面","fg":"cellBoundary","bg":"cellFace","minimum":3},
|
||||
{"name":"格边/舞台","fg":"cellBoundary","bg":"stage","minimum":3},
|
||||
{"name":"路径/未走格","fg":"primary","bg":"cellFace","minimum":3},
|
||||
{"name":"提示描边/舞台","fg":"hintCasing","bg":"stage","minimum":3},
|
||||
{"name":"提示白芯/描边","fg":"hintCore","bg":"hintCasing","minimum":3},
|
||||
{"name":"墙/黄色条纹","fg":"wallInk","bg":"wallStripe","minimum":3},
|
||||
{"name":"墙/舞台","fg":"wallInk","bg":"stage","minimum":3},
|
||||
{"name":"开门标记/舞台","fg":"doorOpen","bg":"stage","minimum":3},
|
||||
{"name":"关门标记/舞台","fg":"doorClosed","bg":"stage","minimum":3},
|
||||
{"name":"焦点/黄底","fg":"focus","bg":"background","minimum":3},
|
||||
{"name":"白字/珊瑚(仅诊断,不采用)","fg":"onPrimary","bg":"coral","minimum":null},
|
||||
{"name":"格面/舞台(仅诊断,格边承担识别)","fg":"cellFace","bg":"stage","minimum":null},
|
||||
{"name":"蓝类别面/橙类别面(仅诊断,另配形状)","fg":"categoryBlueFace","bg":"categoryOrangeFace","minimum":null}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,16 @@
|
||||
import {readFileSync,writeFileSync} from 'node:fs';
|
||||
const tokens=JSON.parse(readFileSync(new URL('tokens.json',import.meta.url),'utf8'));
|
||||
function luminance(hex){
|
||||
if(!/^#[0-9a-f]{6}$/i.test(hex))throw new Error(`Expected opaque sRGB hex: ${hex}`);
|
||||
const c=[1,3,5].map(i=>parseInt(hex.slice(i,i+2),16)/255).map(v=>v<=0.04045?v/12.92:((v+0.055)/1.055)**2.4);
|
||||
return .2126*c[0]+.7152*c[1]+.0722*c[2];
|
||||
}
|
||||
const resolve=k=>tokens.color[k]??k;
|
||||
const rows=tokens.contrastPairs.map(p=>{
|
||||
const foreground=resolve(p.fg),background=resolve(p.bg),a=luminance(foreground),b=luminance(background);
|
||||
const ratio=(Math.max(a,b)+.05)/(Math.min(a,b)+.05);
|
||||
return {...p,foreground,background,ratio,pass:p.minimum===null?null:ratio>=p.minimum};
|
||||
});
|
||||
writeFileSync(new URL('contrast-audit.json',import.meta.url),JSON.stringify({method:'WCAG relative luminance, opaque sRGB; threshold checked without rounding; does not validate all composed/animated UI states',rows},null,2)+'\n');
|
||||
console.table(rows.map(r=>({pair:r.name,foreground:r.foreground,background:r.background,ratio:r.ratio.toFixed(3),minimum:r.minimum,result:r.pass===null?'diagnostic':r.pass?'pass':'FAIL'})));
|
||||
if(rows.some(r=>r.pass===false))process.exitCode=1;
|
||||
@@ -0,0 +1,225 @@
|
||||
{
|
||||
"method": "WCAG relative luminance, opaque sRGB; threshold checked without rounding; does not validate all composed/animated UI states",
|
||||
"rows": [
|
||||
{
|
||||
"name": "主文字/背景",
|
||||
"fg": "ink",
|
||||
"bg": "background",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#292638",
|
||||
"background": "#F7F5F1",
|
||||
"ratio": 13.499592723055425,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "辅助文字/背景",
|
||||
"fg": "inkSecondary",
|
||||
"bg": "background",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#66616F",
|
||||
"background": "#F7F5F1",
|
||||
"ratio": 5.50340046530515,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "三级文字/背景",
|
||||
"fg": "inkTertiary",
|
||||
"bg": "background",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#716A78",
|
||||
"background": "#F7F5F1",
|
||||
"ratio": 4.7797069926956475,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "线索数字/未走格",
|
||||
"fg": "ink",
|
||||
"bg": "cellFace",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#292638",
|
||||
"background": "#E5E3E1",
|
||||
"ratio": 11.484041400281836,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "路径数字/紫面",
|
||||
"fg": "onPrimary",
|
||||
"bg": "primary",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#FFFFFF",
|
||||
"background": "#6558F5",
|
||||
"ratio": 4.920632349356288,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "路径数字/按压紫面",
|
||||
"fg": "onPrimary",
|
||||
"bg": "primaryPressed",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#FFFFFF",
|
||||
"background": "#5245D6",
|
||||
"ratio": 6.601647105487607,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "错误数字/错误面",
|
||||
"fg": "onPrimary",
|
||||
"bg": "danger",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#FFFFFF",
|
||||
"background": "#C74350",
|
||||
"ratio": 4.830782166769728,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "错误说明/淡红底",
|
||||
"fg": "dangerInk",
|
||||
"bg": "dangerSoft",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#8B2632",
|
||||
"background": "#FBEAED",
|
||||
"ratio": 7.473414279853196,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "提示文字/淡琥珀底",
|
||||
"fg": "hintInk",
|
||||
"bg": "hintSoft",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#664400",
|
||||
"background": "#FFF0D2",
|
||||
"ratio": 7.79606369057448,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "格边/格面",
|
||||
"fg": "cellBoundary",
|
||||
"bg": "cellFace",
|
||||
"minimum": 3,
|
||||
"foreground": "#817B88",
|
||||
"background": "#E5E3E1",
|
||||
"ratio": 3.2030630920005154,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "格边/背景",
|
||||
"fg": "cellBoundary",
|
||||
"bg": "background",
|
||||
"minimum": 3,
|
||||
"foreground": "#817B88",
|
||||
"background": "#F7F5F1",
|
||||
"ratio": 3.765229129807595,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "提示环/背景",
|
||||
"fg": "hint",
|
||||
"bg": "background",
|
||||
"minimum": 3,
|
||||
"foreground": "#966000",
|
||||
"background": "#F7F5F1",
|
||||
"ratio": 4.857982445311365,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "提示环/未走格",
|
||||
"fg": "hint",
|
||||
"bg": "cellFace",
|
||||
"minimum": 3,
|
||||
"foreground": "#966000",
|
||||
"background": "#E5E3E1",
|
||||
"ratio": 4.132663308317279,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "墙身/墙条纹",
|
||||
"fg": "wallInk",
|
||||
"bg": "wallStripe",
|
||||
"minimum": 3,
|
||||
"foreground": "#3B3547",
|
||||
"background": "#D7B35B",
|
||||
"ratio": 5.872010474102764,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "墙身/未走格",
|
||||
"fg": "wallInk",
|
||||
"bg": "cellFace",
|
||||
"minimum": 3,
|
||||
"foreground": "#3B3547",
|
||||
"background": "#E5E3E1",
|
||||
"ratio": 9.1851898632995,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "焦点/表面",
|
||||
"fg": "focus",
|
||||
"bg": "surface",
|
||||
"minimum": 3,
|
||||
"foreground": "#6558F5",
|
||||
"background": "#FFFEFC",
|
||||
"ratio": 4.881824820806739,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "选中项文字/淡紫底",
|
||||
"fg": "selectedInk",
|
||||
"bg": "primarySoft",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#5245D6",
|
||||
"background": "#EDEAFF",
|
||||
"ratio": 5.600093119280275,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "辅助文字/二级面",
|
||||
"fg": "inkSecondary",
|
||||
"bg": "surfaceMuted",
|
||||
"minimum": 4.5,
|
||||
"foreground": "#66616F",
|
||||
"background": "#EEEBE6",
|
||||
"ratio": 5.039815678579112,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "已走线索环/路径面",
|
||||
"fg": "primarySoft",
|
||||
"bg": "primary",
|
||||
"minimum": 3,
|
||||
"foreground": "#EDEAFF",
|
||||
"background": "#6558F5",
|
||||
"ratio": 4.174109721683276,
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "未走格面/背景(诊断,边界另保证)",
|
||||
"fg": "cellFace",
|
||||
"bg": "background",
|
||||
"minimum": null,
|
||||
"foreground": "#E5E3E1",
|
||||
"background": "#F7F5F1",
|
||||
"ratio": 1.1755088868561658,
|
||||
"pass": null
|
||||
},
|
||||
{
|
||||
"name": "旧错误色白字(诊断)",
|
||||
"fg": "#FFFFFF",
|
||||
"bg": "#E5484D",
|
||||
"minimum": null,
|
||||
"foreground": "#FFFFFF",
|
||||
"background": "#E5484D",
|
||||
"ratio": 3.913738950339162,
|
||||
"pass": null
|
||||
},
|
||||
{
|
||||
"name": "旧过关亮面白字(诊断)",
|
||||
"fg": "#FFFFFF",
|
||||
"bg": "#7D72FF",
|
||||
"minimum": null,
|
||||
"foreground": "#FFFFFF",
|
||||
"background": "#7D72FF",
|
||||
"ratio": 3.6694552685051627,
|
||||
"pass": null
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"meta": {"name":"NumberSwipe Soft Blocks", "version":"1.0-proposal", "date":"2026-10-21", "status":"Design proposal; not applied to runtime", "unit":"logical design unit; map per platform, not physical pixel"},
|
||||
"color": {
|
||||
"background":"#F7F5F1", "surface":"#FFFEFC", "surfaceRaised":"#FFFFFF", "surfaceMuted":"#EEEBE6",
|
||||
"divider":"#D5D0C9", "cellFace":"#E5E3E1", "cellDepth":"#C5C0CB", "cellBoundary":"#817B88",
|
||||
"ink":"#292638", "inkSecondary":"#66616F", "inkTertiary":"#716A78", "onPrimary":"#FFFFFF",
|
||||
"primary":"#6558F5", "primaryPressed":"#5245D6", "primaryDepth":"#4B3AC8", "primarySoft":"#EDEAFF", "selectedInk":"#5245D6", "primaryEdgeLight":"#A49BFF",
|
||||
"danger":"#C74350", "dangerDepth":"#9E2F3A", "dangerSoft":"#FBEAED", "dangerInk":"#8B2632",
|
||||
"hint":"#966000", "hintSoft":"#FFF0D2", "hintInk":"#664400",
|
||||
"wallInk":"#3B3547", "wallStripe":"#D7B35B", "focus":"#6558F5", "overlay":"#292638"
|
||||
},
|
||||
"font": {"numericPreferred":"Nunito", "cjkPreferred":"Noto Sans SC", "fallback":"ui-rounded, system-ui, -apple-system, Segoe UI, sans-serif", "numericWeight":800, "bodyWeight":500, "labelWeight":600, "headingWeight":700},
|
||||
"type": {
|
||||
"display":{"size":30,"line":38,"weight":800}, "pageTitle":{"size":24,"line":32,"weight":700}, "section":{"size":18,"line":26,"weight":700},
|
||||
"body":{"size":16,"line":24,"weight":500}, "button":{"size":16,"line":24,"weight":700}, "label":{"size":14,"line":20,"weight":600},
|
||||
"caption":{"size":13,"line":18,"weight":500}, "micro":{"size":12,"line":16,"weight":500}
|
||||
},
|
||||
"boardType":{"startRatio":0.60,"singleRatio":0.52,"doubleRatio":0.46,"parityRatio":0.44,"paritySubMin":12,"doubleMin":22,"singleMin":24,"numberMax":46},
|
||||
"spacing":[4,8,12,16,20,24,32,40,48],
|
||||
"radius":{"small":8,"control":16,"card":20,"sheet":24,"cellRatio":0.18,"cellMin":7,"cellMax":14},
|
||||
"layout":{"referenceWidth":375,"referenceHeight":812,"contentPadding":20,"tapMin":48,"topbarHeight":56,"actionHeight":56,"actionGap":8,"boardOuterMargin":12,"boardPitchMin":48,"boardPitchPreferred":56,"tileInsetRatio":0.05,"bridgeThicknessRatio":0.46},
|
||||
"material":{"lightDirection":"upper-left","cellDepth":2,"cellDepthMax":3,"pressedDepth":1,"boundaryWidth":1.25,"shadowBlurMax":6,"shadowOpacityMax":0.08,"gradientLuminanceDeltaMax":0.02},
|
||||
"motionMs":{"fast":120,"base":200,"slow":320,"hold":500,"hintVisible":2400,"entryStagger":12,"entryStaggerCap":120},
|
||||
"motion":{"easeOut":[0.22,1,0.36,1],"easeIn":[0.4,0,1,1],"easeInOut":[0.65,0,0.35,1],"stepScalePeak":1.02,"buttonScaleMin":0.98,"shakeAmplitudeMax":2,"rotationDegrees":120},
|
||||
"contrastPairs":[
|
||||
{"name":"主文字/背景","fg":"ink","bg":"background","minimum":4.5},
|
||||
{"name":"辅助文字/背景","fg":"inkSecondary","bg":"background","minimum":4.5},
|
||||
{"name":"三级文字/背景","fg":"inkTertiary","bg":"background","minimum":4.5},
|
||||
{"name":"线索数字/未走格","fg":"ink","bg":"cellFace","minimum":4.5},
|
||||
{"name":"路径数字/紫面","fg":"onPrimary","bg":"primary","minimum":4.5},
|
||||
{"name":"路径数字/按压紫面","fg":"onPrimary","bg":"primaryPressed","minimum":4.5},
|
||||
{"name":"错误数字/错误面","fg":"onPrimary","bg":"danger","minimum":4.5},
|
||||
{"name":"错误说明/淡红底","fg":"dangerInk","bg":"dangerSoft","minimum":4.5},
|
||||
{"name":"提示文字/淡琥珀底","fg":"hintInk","bg":"hintSoft","minimum":4.5},
|
||||
{"name":"格边/格面","fg":"cellBoundary","bg":"cellFace","minimum":3},
|
||||
{"name":"格边/背景","fg":"cellBoundary","bg":"background","minimum":3},
|
||||
{"name":"提示环/背景","fg":"hint","bg":"background","minimum":3},
|
||||
{"name":"提示环/未走格","fg":"hint","bg":"cellFace","minimum":3},
|
||||
{"name":"墙身/墙条纹","fg":"wallInk","bg":"wallStripe","minimum":3},
|
||||
{"name":"墙身/未走格","fg":"wallInk","bg":"cellFace","minimum":3},
|
||||
{"name":"焦点/表面","fg":"focus","bg":"surface","minimum":3},
|
||||
{"name":"选中项文字/淡紫底","fg":"selectedInk","bg":"primarySoft","minimum":4.5},
|
||||
{"name":"辅助文字/二级面","fg":"inkSecondary","bg":"surfaceMuted","minimum":4.5},
|
||||
{"name":"已走线索环/路径面","fg":"primarySoft","bg":"primary","minimum":3},
|
||||
{"name":"未走格面/背景(诊断,边界另保证)","fg":"cellFace","bg":"background","minimum":null},
|
||||
{"name":"旧错误色白字(诊断)","fg":"#FFFFFF","bg":"#E5484D","minimum":null},
|
||||
{"name":"旧过关亮面白字(诊断)","fg":"#FFFFFF","bg":"#7D72FF","minimum":null}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user