Area conversion, checked two ways
HTML for this example
Select the code and use your copy shortcut. Changes in this preview are temporary.
<!doctype html><html lang="en-US"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Area conversion, checked two ways</title><style>*{box-sizing:border-box}:root{--ink:#24333d;--muted:#586872;--line:#cfd9de;--accent:#27627b;--soft:#edf3f5;--paper:white;color-scheme:light}body{margin:0;background:#f2f4f4;color:var(--ink);font:16px/1.5 system-ui,-apple-system,"Segoe UI",sans-serif}main{max-width:1100px;padding:28px 32px 64px;margin:auto}header{margin-bottom:20px}h1{font-size:clamp(1.5rem,3vw,2.1rem);letter-spacing:-.035em;line-height:1.18;margin:0 0 9px}h2{font-size:1.2rem;line-height:1.3;margin:0 0 15px}h3{font-size:1rem;margin:0 0 8px}p{margin:9px 0 16px}header p{margin-bottom:0}.eyebrow{font-size:.75rem;font-weight:750;text-transform:uppercase;letter-spacing:.12em;color:var(--accent);margin-bottom:8px}.muted,small{color:var(--muted)}.panel{background:var(--paper);border:1px solid var(--line);padding:24px;border-radius:12px}.grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:24px}.fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:15px}.triple{display:grid;grid-template-columns:2fr 1fr 1fr;gap:16px}.below{margin-top:24px}label{display:block;font-size:.9rem;font-weight:650}input,select,textarea,button{font:inherit}input,select,textarea{display:block;width:100%;min-width:0;margin-top:6px;padding:10px 12px;border:1px solid #879da8;border-radius:6px;background:white;color:var(--ink)}input,select{min-height:46px}textarea{resize:vertical;line-height:1.6}button{min-height:44px;border:1px solid var(--accent);border-radius:6px;padding:9px 15px;background:var(--accent);color:white;font-weight:650;cursor:pointer}button.secondary{background:white;color:var(--accent)}button:disabled{opacity:.5;cursor:not-allowed}button:hover:enabled{filter:brightness(.95)}:focus-visible{outline:3px solid #bb6b22;outline-offset:3px}.actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px}.result{padding:26px;background:var(--ink);color:white;border-radius:12px}.result .muted{color:#d1e0e7}.big{font-size:clamp(2rem,5vw,3.5rem);line-height:1.15;letter-spacing:-.04em;font-weight:750;font-variant-numeric:tabular-nums;margin:10px 0;overflow-wrap:anywhere}.formula{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;overflow-wrap:anywhere}.error{min-height:24px;color:#a33028;font-weight:650;margin:9px 0 0}.status{font-size:.9rem;color:var(--muted)}.note{padding:12px 16px;background:#fff3de;border-left:3px solid #b67e38;color:#65481d}table{width:100%;border-collapse:collapse;font-size:.92rem}th{text-align:left;color:var(--muted);font-size:.83rem}th,td{padding:10px 8px;border-bottom:1px solid var(--line);vertical-align:top}th:first-child,td:first-child{padding-left:0}details{padding:16px 0;border-top:1px solid var(--line)}summary{font-weight:650;cursor:pointer}pre{white-space:pre-wrap;overflow-wrap:anywhere;font:.87rem/1.6 ui-monospace,Consolas,monospace;background:#edf1f3;border:1px solid #d7e0e4;padding:18px;border-radius:7px}svg{display:block;width:100%;height:auto}.badge{display:inline-block;padding:3px 9px;background:var(--soft);color:var(--accent);font-size:.78rem;font-weight:700;border-radius:25px}.rule{height:1px;background:var(--line);margin:18px 0}[hidden]{display:none!important}a{color:var(--accent)}@media(max-width:720px){main{padding:22px 20px 45px}.grid{grid-template-columns:1fr;gap:18px}.panel{padding:20px}.triple{grid-template-columns:1fr 1fr}.triple>label:first-child{grid-column:1/-1}}@media(max-width:400px){main{padding:18px 16px 36px}.panel{padding:16px}.fields{gap:12px}.result{padding:20px}.big{font-size:2.2rem}th,td{padding:9px 5px}}.area-answer{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);background:#fff;border-top:5px solid #3b7375;padding:25px;gap:24px}.area-answer .big{color:#285b5e}.square-factor{border-left:1px solid var(--line);padding-left:24px;align-self:center}.square-factor p{font-size:.9rem;margin-bottom:0}.rectangle{margin:0}.rectangle figcaption{font-size:.82rem;color:var(--muted);margin-top:12px}@media(max-width:600px){.area-answer{grid-template-columns:1fr;padding:20px;gap:16px}.square-factor{border-left:0;border-top:1px solid var(--line);padding:14px 0 0}}</style></head><body><main><header><h1>Area conversion, checked two ways</h1><p>Convert square units, then compare a rectangle’s separately converted sides.</p></header>
<section class="area-answer" aria-live="polite"><div><span id="entered" class="muted">80 ft²</span><div class="big" id="result">7.4322432 m²</div><span id="rounded">7.43 m² · rounded to two places</span></div><div class="square-factor"><b id="factor">1 ft² = 0.09290304 m²</b><p>1 ft² = 12 in × 12 in = 144 in²</p></div></section>
<section class="panel below"><div class="triple"><label for="amount">Supplied area<input id="amount" value="80" inputmode="decimal" ></label><label for="from">From<select id="from"><option>ft²</option><option>in²</option><option>m²</option></select></label><label for="to">To<select id="to"><option>m²</option><option>ft²</option><option>in²</option></select></label></div><div class="actions"><button type="button" id="convert">Convert</button><button type="button" id="reverse" class="secondary">Show reverse audit</button><button type="button" id="reset" class="secondary">Reset example</button></div><p id="error" class="error" role="status"></p><p id="derive" class="formula"></p><p id="reverseRecord" class="formula"></p></section>
<section class="grid below"><div class="panel"><h2>Rectangle route</h2><div class="fields"><label for="length">First side<input id="length" value="10" inputmode="decimal" ></label><label for="lengthUnit">First side unit<select id="lengthUnit"><option>ft</option><option>in</option><option>m</option></select></label><label for="width">Second side<input id="width" value="8" inputmode="decimal" ></label><label for="widthUnit">Second side unit<select id="widthUnit"><option>ft</option><option>in</option><option>m</option></select></label></div><p id="sideResult" class="formula"></p><p id="agreement" class="status" aria-live="polite"></p></div><figure class="panel rectangle"><svg viewBox="0 0 360 270" role="img" aria-labelledby="gridTitle"><title id="gridTitle">Fictional ten by eight one-square-foot grid</title><defs><pattern id="cells" x="42" y="20" width="28" height="28" patternUnits="userSpaceOnUse"><path d="M28 0H0V28" fill="none" stroke="#8ca6a7" stroke-width="1"/></pattern></defs><rect x="42" y="20" width="280" height="224" fill="url(#cells)" stroke="#36676c" stroke-width="2"/><text x="182" y="265" text-anchor="middle" font-size="16">10 ft · 120 in · 3.048 m</text><text x="12" y="140" transform="rotate(-90 12 140)" text-anchor="middle" font-size="16">8 ft · 2.4384 m</text></svg><figcaption>Fixed fictional grid: 80 one-square-foot cells. Edited side values are calculated in the separate rectangle record.</figcaption></figure></section>
<details class="below"><summary>Factors, precision, and scope</summary><p>Ordinary foot: 1 ft = 0.3048 m. Area squares the linear factor: (0.3048)² = 0.09290304. The converter accepts only ft², in², and m²; rectangle sides separately accept ft, in, and m. Missing sides leave the rectangle route unavailable without invalidating an independently supplied area.</p><p>Nonnegative values up to 1 billion, with at most 12 decimal places. Zero is valid; blank is not. Exact decimal fractions are retained; repeating results retain a fraction. Rounded displays are labeled and never used for reverse checks. This worksheet does not measure property, calculate volume, estimate cost, or save entries.</p></details></main><script>const $=id=>document.getElementById(id),put=(id,s)=>{$(id).textContent=s};
function esc(s){return String(s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));}
function gcd(a,b){a=a<0n?-a:a;b=b<0n?-b:b;while(b){[a,b]=[b,a%b]}return a||1n;}
function R(n,d=1n){n=BigInt(n);d=BigInt(d);if(d===0n)throw Error('Undefined denominator.');if(d<0n){n=-n;d=-d}const g=gcd(n,d);return {n:n/g,d:d/g};}
function mul(a,b){return R(a.n*b.n,a.d*b.d)}function div(a,b){return R(a.n*b.d,a.d*b.n)}function add(a,b){return R(a.n*b.d+b.n*a.d,a.d*b.d)}function sub(a,b){return R(a.n*b.d-b.n*a.d,a.d*b.d)}function cmp(a,b){const x=a.n*b.d-b.n*a.d;return x<0n?-1:x>0n?1:0}
function parse(s,{max=1000000,positive=false,places=6}={}){const t=String(s).trim();if(!t)throw Error('Enter a value; blank is not zero.');const re=new RegExp('^[0-9]+(?:\.[0-9]{1,'+places+'})?$');if(!re.test(t))throw Error('Use digits and a US decimal point, up to '+places+' places; no signs, commas, or exponents.');const v=Number(t);if(!Number.isFinite(v)||v>max||(positive&&v===0))throw Error('Value must be '+(positive?'greater than zero':'nonnegative')+' and at most '+max+'.');const [a,b='']=t.split('.');return R(BigInt(a+b),10n**BigInt(b.length));}
function format(a,places=6){const neg=a.n<0n,n=neg?-a.n:a.n,scale=10n**BigInt(places),v=n*scale,q=v/a.d,rem=v%a.d,k=q+(rem*2n>=a.d?1n:0n);const f=(k%scale).toString().padStart(places,'0').replace(/0+$/,'');return {text:(neg&&k!==0n?'-':'')+(k/scale)+(f?'.'+f:''),approx:rem!==0n};}
function exact(a){let d=a.d;while(d%2n===0n)d/=2n;while(d%5n===0n)d/=5n;if(d!==1n)return a.n+'/'+a.d;let places=0,p=1n;while(p%a.d!==0n&&places<40){p*=10n;places++}return format(a,places).text;}
function display(a,places=6){if(a.n>0n&&cmp(a,R(1n,10n**BigInt(places)))<0)return '< '+format(R(1n,10n**BigInt(places)),places).text;const f=format(a,places);return (f.approx?'≈ ':'')+f.text;}
function listen(ids,fn){ids.forEach(id=>{ $(id).addEventListener('input',fn);$(id).addEventListener('change',fn); });}
const af={'ft²':R(9290304n,100000000n),'in²':R(64516n,100000000n),'m²':R(1n)},lf={ft:R(3048n,10000n),in:R(254n,10000n),m:R(1n)};let current=null;
function convertArea(s,from,to){if(!af[from]||!af[to])throw Error('Choose an area unit: ft², in², or m².');const source=parse(s,{max:1000000000,places:12}),factor=div(af[from],af[to]);return {source,out:mul(source,factor),factor,from,to};}
function rectangle(l,lu,w,wu){if(!lf[lu]||!lf[wu])throw Error('Choose a supported side-length unit.');const a=mul(parse(l,{max:1000000000,places:12}),lf[lu]),b=mul(parse(w,{max:1000000000,places:12}),lf[wu]);return {a,b,area:mul(a,b)};}
function sideUpdate(){try{const r=rectangle($('length').value,$('lengthUnit').value,$('width').value,$('widthUnit').value);put('sideResult',exact(r.a)+' m × '+exact(r.b)+' m = '+exact(r.area)+' m²');put('agreement',current?(cmp(r.area,mul(current.source,af[current.from]))===0?'Both routes agree on the same area.':'The entered rectangle describes a different area from the supplied area above.'):'Rectangle calculation is separate; no valid direct area is available.');}catch(e){put('sideResult','Rectangle check unavailable: '+e.message);put('agreement','Both supplied side lengths are required; none is guessed.');}}
function calculate(){try{current=convertArea($('amount').value,$('from').value,$('to').value);put('entered',$('amount').value+' '+current.from);put('result',(exact(current.out).includes('/')?display(current.out,9):exact(current.out))+' '+current.to);put('rounded',format(current.out,2).text+' '+current.to+' · rounded to two places');put('factor','1 '+current.from+' = '+exact(current.factor)+' '+current.to);put('derive',$('amount').value+' × ('+exact(current.factor)+') = '+exact(current.out)+' '+current.to);put('reverseRecord','');put('error','');$('reverse').disabled=false;}catch(e){current=null;put('result','—');['entered','rounded','factor','derive','reverseRecord'].forEach(id=>put(id,''));put('error',e.message);$('reverse').disabled=true;}sideUpdate();}
listen(['amount','from','to'],calculate);listen(['length','lengthUnit','width','widthUnit'],sideUpdate);$('convert').addEventListener('click',calculate);$('reverse').addEventListener('click',()=>{if(!current)return;put('reverseRecord','Exact reverse: ('+exact(current.out)+') ÷ ('+exact(current.factor)+') = '+exact(current.source)+' '+current.from+'. Rounded display is not used.');});$('reset').addEventListener('click',()=>{$('amount').value='80';$('from').value='ft²';$('to').value='m²';$('length').value='10';$('lengthUnit').value='ft';$('width').value='8';$('widthUnit').value='ft';calculate()});globalThis.Tool={convertArea,rectangle,calculate,exact,cmp,div,mul,R};calculate();</script></body></html>