// Circle geometry: sun marker orbit, horizon line, center text block — all inside 466px circle. const fs = require('node:fs'); const assert = require('node:assert/strict'); const ux = fs.readFileSync('src/pages/index/index.ux', 'utf8'); const num = (re) => { const m = ux.match(re); assert.ok(m, 'missing: '+re); return Number(m[1]); }; const SCREEN = 466, R = 233; const skyD = num(/\.sky\s*{[^}]*width:\s*(\d+)px/); assert.ok(skyD <= SCREEN - 40, 'sky dial should leave bezel margin: ' + skyD); // horizon line spans within circle at y=233 (widest point) → width <= 466 const hzW = num(/\.horizon\s*{[^}]*width:\s*(\d+)px/); assert.ok(hzW <= SCREEN, 'horizon width fits'); // Actual template-bound coordinates are exercised in marker.cjs. const orbit = num(/orbitR:\s*(\d+)/); assert.ok(orbit <= skyD / 2 - 30, `sun orbit ${orbit} must stay within sky dial ${skyD/2} minus marker radius`); // center text block vertical span inside circle const cTop = num(/\.center\s*{[^}]*top:\s*(\d+)px/); const bigH = num(/\.big\s*{[^}]*height:\s*(\d+)px/); const phaseH = num(/\.phase\s*{[^}]*height:\s*(\d+)px/); const countH = num(/\.count\s*{[^}]*height:\s*(\d+)px/); const cBot = cTop + bigH + phaseH + countH; // text content is centered and narrow (~240px wide worst case = clock at 66px font); check half-width 120px fits chord const TEXT_HALF = 120; for (const y of [cTop, cBot]) { const halfW = Math.sqrt(Math.max(0, R*R - Math.abs(y-R)**2)); assert.ok(TEXT_HALF <= halfW, `center text at y=${y} exceeds chord: needs ${TEXT_HALF}, has ${halfW.toFixed(0)}`); } // contrast const lum = h => { const c=h.match(/\w\w/g).map(x=>parseInt(x,16)/255).map(v=>v<=0.03928?v/12.92:((v+0.055)/1.055)**2.4); return .2126*c[0]+.7152*c[1]+.0722*c[2]; }; const ratio = (a,b)=>(Math.max(lum(a),lum(b))+.05)/(Math.min(lum(a),lum(b))+.05); assert.ok(ratio('#ffffff','#000000') >= 4.5, 'clock contrast'); assert.ok(ratio('#f3a633','#000000') >= 4.5, 'phase contrast'); assert.ok(ratio('#9aa0aa','#000000') >= 4.5, 'count contrast'); console.log('GEOMETRY ESTIMATES PASS (not renderer validation): dial', skyD, 'orbit', orbit, 'center block y', cTop, '-', cBot);