refactor(ui): unify semantic presentation and table hierarchy
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
"""Focused normal/reduced-motion and predicted-ghost text proof; no screenshot loop."""
|
||||
import json,re
|
||||
from pathlib import Path
|
||||
from playwright.sync_api import sync_playwright
|
||||
|
||||
def rgb(s):return [float(v) for v in re.findall(r'[\d.]+',s)][:3]
|
||||
def mix(f,b,a):return [f[i]*a+b[i]*(1-a) for i in range(3)]
|
||||
def ratio(a,b):
|
||||
def lum(v):
|
||||
v=[x/255 for x in v];v=[x/12.92 if x<=.04045 else ((x+.055)/1.055)**2.4 for x in v];return sum(x*y for x,y in zip(v,[.2126,.7152,.0722]))
|
||||
lo,hi=sorted([lum(a),lum(b)]);return round((hi+.05)/(lo+.05),3)
|
||||
results=[]
|
||||
with sync_playwright() as p:
|
||||
browser=p.chromium.launch(channel='chromium')
|
||||
for scheme in ['light','dark']:
|
||||
for motion in ['no-preference','reduce']:
|
||||
page=browser.new_page(reduced_motion=motion);page.goto('http://127.0.0.1:5201/presentation',wait_until='networkidle');page.evaluate('s=>window.sbTheme.set(s)',scheme)
|
||||
record=page.evaluate('''()=>{const p=document.querySelector('.fg-node.pending .fg-pill'),g=document.querySelector('.fg-node.ghost'),r=g.querySelector('.fg-node-box'),lane=document.querySelector('.fg-lane-bg.alt');const pc=getComputedStyle(p),gc=getComputedStyle(g),rc=getComputedStyle(r),lc=getComputedStyle(lane);return {pending:{opacity:pc.opacity,animations:p.getAnimations().length,color:pc.color,background:pc.backgroundColor},ghost:{opacity:gc.opacity,titleColor:getComputedStyle(g.querySelector('.fg-title')).color,captionColor:getComputedStyle(g.querySelector('.fg-eyebrow')).color,boxFill:rc.fill,boxFillOpacity:rc.fillOpacity,strokeDasharray:rc.strokeDasharray,laneFill:lc.fill,laneFillOpacity:lc.fillOpacity,wrapBackground:getComputedStyle(document.querySelector('.fg-wrap')).backgroundColor}};}''');record.update({'scheme':scheme,'motion':motion});ghost=record['ghost'];base=mix(rgb(ghost['laneFill']),rgb(ghost['wrapBackground']),float(ghost['laneFillOpacity']));background=mix(rgb(ghost['boxFill']),base,float(ghost['boxFillOpacity']));ghost['effectiveBackground']=background;ghost['titleContrast']=ratio(rgb(ghost['titleColor']),background);ghost['captionContrast']=ratio(rgb(ghost['captionColor']),background);record['pending']['contrast']=ratio(rgb(record['pending']['color']),rgb(record['pending']['background']));record['passed']=record['pending']['opacity']=='1' and record['pending']['animations']==0 and ghost['opacity']=='1' and min(ghost['titleContrast'],ghost['captionContrast'],record['pending']['contrast'])>=4.5;results.append(record);page.close()
|
||||
browser.close()
|
||||
Path('docs/ui-consistency/evidence/sb07-09/flow-text-opacity-after.json').write_text(json.dumps({'results':results,'passed':all(r['passed'] for r in results)},indent=2)+'\n');print([(r['scheme'],r['motion'],r['passed'],r['ghost']['titleContrast'],r['ghost']['captionContrast']) for r in results])
|
||||
Reference in New Issue
Block a user