From 77c7f1261a6f5d2f715ff24751e442741570ed1f Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Mon, 8 Jun 2026 19:55:43 -0500 Subject: feat(theme-studio): show OKLCH and APCA readouts in the picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Perceptual-metrics Phase 2. The picker now shows a second readout row under the WCAG ratio: the OKLCH coordinates (L, C, hue°) and the signed APCA Lc against the ground color. WCAG and all three contrast tables are untouched, so APCA stays picker-only for v1. APCA Lc carries its sign convention in a tooltip and in the README: positive is dark text on a light background, negative is light text on a dark background, so a light color on dupre's dark ground reads negative. pkReadout drives the new spans from the inlined colormath functions, and a #readouttest headless guard loads dupre-blue and asserts the spans match both the live computation and the known OKLCH reference, with WCAG unchanged. --- scripts/theme-studio/generate.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'scripts/theme-studio/generate.py') diff --git a/scripts/theme-studio/generate.py b/scripts/theme-studio/generate.py index c73a78f5..0aa12892 100644 --- a/scripts/theme-studio/generate.py +++ b/scripts/theme-studio/generate.py @@ -413,7 +413,9 @@ HTML = """theme-studio .svcur{position:absolute;width:16px;height:16px;border:2px solid #fff;border-radius:50%;transform:translate(-50%,-50%);box-shadow:0 0 0 1px #0008;pointer-events:none} .hue{position:relative;width:34px;height:320px;border-radius:4px;cursor:ns-resize;background:linear-gradient(to bottom,#f00,#ff0,#0f0,#0ff,#00f,#f0f,#f00)} .huecur{position:absolute;left:-2px;right:-2px;height:4px;background:#fff;border:1px solid #0008;transform:translateY(-50%);pointer-events:none} - .pinfo{display:flex;justify-content:space-between;margin:10px 2px 8px;font:12pt monospace;color:#cdced1} + .pinfo{display:flex;justify-content:space-between;margin:10px 2px 4px;font:12pt monospace;color:#cdced1} + .pinfo2{margin:0 2px 9px;font:10pt monospace;color:#9aa3ad} + .pinfo2 span{cursor:default} .pkchips{display:flex;flex-wrap:wrap;gap:5px} .pkchips .pc{width:28px;height:28px;border-radius:3px;border:1px solid #555;cursor:pointer} .palctl button,.filebar button,.fbtn{background:#252321;color:#e8bd30;border:1px solid #3a3a3a;border-radius:4px;padding:6px 12px;font:10pt monospace;cursor:pointer} #palmsg{font:10pt monospace;opacity:0;transition:opacity .35s;margin-left:6px} @@ -457,6 +459,7 @@ HTML = """theme-studio
#888888
+
limit
@@ -616,7 +619,9 @@ let pkMode='any'; function pkThresh(){return pkMode==='aa'?4.5:pkMode==='aaa'?7:0;} function drawMask(){const cv=document.getElementById('svmask');if(!cv)return;const sv=document.getElementById('sv'),w=cv.width=sv.clientWidth,h=cv.height=sv.clientHeight,ctx=cv.getContext('2d');ctx.clearRect(0,0,w,h);const T=pkThresh();if(!T)return;ctx.fillStyle='rgba(8,7,6,0.66)';const step=4;for(let x=0;x1&&T>1&&H>1;document.title='CURSORTEST '+(ok?'PASS':'FAIL');const d=document.createElement('div');d.id='cursortest';d.textContent='CURSORTEST '+(ok?'PASS':'FAIL')+' left='+sc.style.left+' top='+sc.style.top+' hue='+hc.style.top;document.body.appendChild(d);} if(location.hash.startsWith('#app')){const ap=location.hash.slice(4),s=document.getElementById('appsel');if(s&&ap){s.value=ap;pkgChanged();}} +if(location.hash==='#readouttest'){const hex='#67809c';document.getElementById('newhexstr').value=hex;openPicker();pkReadout(hex); + const o=document.getElementById('pkoklch').textContent,a=document.getElementById('pkapca').textContent,w=document.getElementById('pkcon').textContent; + const lch=oklab2oklch(srgb2oklab(hex)); + const expO='OKLCH '+lch.L.toFixed(3)+' '+lch.C.toFixed(3)+' '+Math.round(lch.H)+'\\u00b0'; + const expA='APCA Lc '+apca(hex,MAP['bg']).toFixed(0); + const r=contrast(hex,MAP['bg']),expW=r.toFixed(1)+' '+rating(r); + const wired=o===expO&&a===expA&&w===expW; + const sane=Math.abs(lch.L-0.591)<0.01&&Math.abs(lch.C-0.052)<0.01&&Math.abs(lch.H-251.6)<2; + const ok=wired&&sane;document.title='READOUTTEST '+(ok?'PASS':'FAIL'); + const d=document.createElement('div');d.id='readouttest';d.textContent='READOUTTEST '+(ok?'PASS':'FAIL')+' oklch='+o+' | apca='+a+' | wcag='+w;document.body.appendChild(d);} """ HTML=(HTML.replace("COLORMATH_J",COLORMATH_BODY) .replace("SAMPLES_J",json.dumps(SAMPLES)) -- cgit v1.2.3