<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Compare GEO Scores — GEO Optimizer</title>
<meta name="description" content="Compare GEO scores between two websites side by side.">
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
:root{--bg:#06080f;--bg-card:#0d1117;--border:#1b2332;--border-hover:#2d3a4f;
--text:#e2e8f0;--text-dim:#64748b;--text-muted:#475569;--accent:#3b82f6;--accent2:#8b5cf6;
--green:#22c55e;--cyan:#06b6d4;--yellow:#eab308;--red:#ef4444;
--radius:12px;--radius-sm:8px;--font:'DM Sans',system-ui,sans-serif;--mono:'JetBrains Mono',monospace}
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:var(--font);background:var(--bg);color:var(--text);min-height:100vh;overflow-x:hidden}
body::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:9999;opacity:.03;
background:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
a{color:var(--accent);text-decoration:none}
.wrapper{position:relative;z-index:1;max-width:760px;margin:0 auto;padding:2rem 1.5rem}
nav{display:flex;align-items:center;justify-content:center;gap:1.5rem;padding:.75rem 0;margin-bottom:2.5rem;border-bottom:1px solid var(--border)}
nav a{color:var(--text-dim);font-size:.85rem;font-weight:500;transition:color .2s}
nav a:hover,nav a.active{color:var(--text)}
.hero{text-align:center;margin-bottom:2rem}
.hero h1{font-size:2.4rem;font-weight:700;letter-spacing:-.03em;background:linear-gradient(135deg,#60a5fa,#a78bfa);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
.hero p{color:var(--text-dim);margin-top:.4rem}
.form-wrap{margin-bottom:1.5rem}
.form-wrap input{width:100%;padding:.8rem 1rem;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg-card);color:var(--text);font-family:var(--font);font-size:.95rem;outline:none;transition:border-color .2s}
.form-wrap input:focus{border-color:var(--accent)}
.vs{text-align:center;color:var(--text-muted);font-size:.8rem;padding:.4rem 0;letter-spacing:.1em}
.btn{display:block;width:100%;padding:.8rem;border:none;border-radius:var(--radius-sm);background:linear-gradient(135deg,var(--accent),var(--accent2));color:#fff;font-family:var(--font);font-size:1rem;font-weight:600;cursor:pointer;margin-top:.75rem;transition:opacity .2s}
.btn:hover{opacity:.9}
.btn:disabled{opacity:.4;cursor:not-allowed}
.spinner{display:none;text-align:center;padding:1.5rem 0;color:var(--text-dim);font-size:.85rem}
.spinner.active{display:block}
.error{display:none;background:rgba(239,68,68,.08);border:1px solid rgba(239,68,68,.2);border-radius:var(--radius-sm);padding:.75rem 1rem;color:var(--red);font-size:.9rem;margin-bottom:1rem}
.results{display:none;margin-top:1.5rem}
.grid{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
.card{background:var(--bg-card);border:1px solid var(--border);border-radius:var(--radius);padding:1.25rem;text-align:center;transition:border-color .3s}
.card.winner{border-color:var(--green);box-shadow:0 0 20px rgba(34,197,94,.08)}
.card-url{font-size:.75rem;color:var(--text-muted);word-break:break-all;margin-bottom:.75rem;font-family:var(--mono)}
.card-score{font-family:var(--mono);font-size:2.5rem;font-weight:700}
.card-band{font-size:.8rem;font-weight:600;letter-spacing:.05em;margin-top:.25rem;text-transform:uppercase}
.bars{margin-top:1rem}
.bar-row{display:flex;align-items:center;gap:.4rem;padding:.3rem 0;font-size:.75rem}
.bar-lbl{width:65px;text-align:right;color:var(--text-dim);flex-shrink:0}
.bar-track{flex:1;height:5px;background:var(--border);border-radius:3px;overflow:hidden}
.bar-fill{height:100%;border-radius:3px;transition:width .8s cubic-bezier(.4,0,.2,1)}
.bar-val{width:24px;font-family:var(--mono);color:var(--text-dim);font-size:.7rem}
footer{text-align:center;padding:2rem 0 1rem;border-top:1px solid var(--border);margin-top:2rem;color:var(--text-muted);font-size:.8rem}
footer a{color:var(--text-muted)}
@media(max-width:600px){.grid{grid-template-columns:1fr}.wrapper{padding:1.25rem 1rem}.hero h1{font-size:1.8rem}}
</style>
</head>
<body>
<div class="wrapper">
  <nav>
    <a href="/">Audit</a>
    <a href="/compare" class="active">Compare</a>
    <a href="/roadmap">Roadmap</a>
    <a href="/research">Research</a>
    <a href="/docs/">Docs</a>
  </nav>
  <div class="hero"><h1>Compare GEO Scores</h1><p>Side-by-side — see who's more visible to AI</p></div>
  <div class="form-wrap">
    <input type="url" id="url1" placeholder="https://site-a.com" required>
    <div class="vs">VS</div>
    <input type="url" id="url2" placeholder="https://site-b.com" required>
    <button class="btn" id="btn">Compare</button>
  </div>
  <div class="spinner" id="spinner">Analyzing both sites... this may take up to 60 seconds.</div>
  <div class="error" id="error"></div>
  <div class="results" id="results"><div class="grid" id="grid"></div></div>
  <footer>
    <a href="https://github.com/auriti-labs/geo-optimizer-skill">GitHub</a> &middot;
    <a href="/docs/">Docs</a> &middot;
    <a href="https://pypi.org/project/geo-optimizer-skill/">PyPI</a>
  </footer>
</div>
<script__NONCE_ATTR__>
const BANDS={excellent:'#22c55e',good:'#06b6d4',foundation:'#eab308',critical:'#ef4444'};
const CATS=[{k:'robots',l:'Robots',m:18},{k:'llms',l:'llms.txt',m:18},{k:'schema',l:'Schema',m:22},{k:'meta',l:'Meta',m:14},{k:'content',l:'Content',m:14},{k:'signals',l:'Signals',m:8},{k:'ai_discovery',l:'AI Disc.',m:6}];
const $=id=>document.getElementById(id);

$('btn').addEventListener('click',run);
$('url2').addEventListener('keypress',e=>{if(e.key==='Enter')run()});

async function run(){
  const u1=$('url1').value,u2=$('url2').value;
  if(!u1||!u2)return;
  $('btn').disabled=true;$('spinner').classList.add('active');$('error').style.display='none';$('results').style.display='none';
  try{
    const [r1,r2]=await Promise.all([fetch('/api/audit?url='+encodeURIComponent(u1)),fetch('/api/audit?url='+encodeURIComponent(u2))]);
    const [d1,d2]=await Promise.all([r1.json(),r2.json()]);
    if(!r1.ok)throw new Error('Site A: '+(d1.detail||'Error'));
    if(!r2.ok)throw new Error('Site B: '+(d2.detail||'Error'));
    render(d1,d2);$('results').style.display='block';
  }catch(e){$('error').textContent=e.message;$('error').style.display='block'}
  finally{$('btn').disabled=false;$('spinner').classList.remove('active')}
}

function render(a,b){
  const g=$('grid');g.textContent='';
  [a,b].forEach((d,i)=>{
    const win=(i===0?a.score>b.score:b.score>a.score);
    const c=document.createElement('div');c.className='card'+(win?' winner':'');
    const color=BANDS[d.band]||'#888';
    const url=document.createElement('div');url.className='card-url';url.textContent=d.url||(i===0?$('url1').value:$('url2').value);c.appendChild(url);
    const sc=document.createElement('div');sc.className='card-score';sc.style.color=color;sc.textContent=d.score+'/100';c.appendChild(sc);
    const bd=document.createElement('div');bd.className='card-band';bd.style.color=color;bd.textContent=(d.band||'').toUpperCase();c.appendChild(bd);
    const bars=document.createElement('div');bars.className='bars';
    const br=d.score_breakdown||{};
    for(const cat of CATS){
      const v=br[cat.k]||0;const pct=Math.min(v/cat.m*100,100);
      const row=document.createElement('div');row.className='bar-row';
      const lbl=document.createElement('span');lbl.className='bar-lbl';lbl.textContent=cat.l;
      const track=document.createElement('div');track.className='bar-track';
      const fill=document.createElement('div');fill.className='bar-fill';fill.style.width='0%';fill.style.background=color;
      track.appendChild(fill);
      const val=document.createElement('span');val.className='bar-val';val.textContent=v;
      row.appendChild(lbl);row.appendChild(track);row.appendChild(val);bars.appendChild(row);
      requestAnimationFrame(()=>{requestAnimationFrame(()=>{fill.style.width=pct+'%'})});
    }
    c.appendChild(bars);g.appendChild(c);
  });
}
</script>
</body>
</html>
