<!DOCTYPE html>
<html>
<head><script>(function(){var n=0;function show(p,m){var el=document.createElement('div');el.style.cssText='position:fixed;left:0;right:0;background:#e04040;color:#fff;padding:6px 12px;z-index:'+(99999-n)+';font:13px/1.4 monospace;white-space:pre-wrap;border-bottom:1px solid #b02020;top:'+n*30+'px';el.textContent=p+m;document.body.appendChild(el);n++}window.onerror=function(msg,src,line){show('ERROR '+(src||'').split('/').pop()+':'+line+' \u2014 ',msg)};window.addEventListener('unhandledrejection',function(e){show('REJECT \u2014 ',e.reason&&e.reason.message||e.reason||'unknown')})})()</script>
<meta charset="utf-8">
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #0d1117; color: #e6edf3; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; overflow: hidden; height: 100vh; }
.scene { position: relative; width: 100%; height: 100%; display: flex; }
.view { flex: 1; position: relative; }
canvas { display: block; width: 100%; height: 100%; }
.toolbar { position: absolute; top: 10px; left: 50%; transform: translateX(-50%); display: flex; gap: 1px; background: #1a1a1a; border: 1px solid #333; border-radius: 6px; padding: 2px; z-index: 10; }
.toolbar button { width: 32px; height: 28px; background: transparent; border: none; border-radius: 4px; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.toolbar button svg { width: 18px; height: 18px; stroke: #666; stroke-width: 1.5; fill: none; }
.toolbar button.active svg { stroke: #00b8b0; }
.badge { position: absolute; top: 10px; right: 10px; background: rgba(0,184,176,0.15); color: #00b8b0; font-size: 11px; font-weight: 600; padding: 3px 8px; border-radius: 4px; border: 1px solid rgba(0,184,176,0.3); z-index: 10; }
.footer { position: absolute; bottom: 8px; left: 50%; transform: translateX(-50%); color: #484f58; font-size: 11px; z-index: 10; }
.dims-panel { width: 320px; background: rgba(13,17,23,0.95); border-left: 1px solid #30363d; overflow-y: auto; padding: 12px; font-size: 12px; }
.dims-panel h3 { color: #00b8b0; font-size: 13px; margin-bottom: 8px; font-weight: 600; }
.dims-panel table { width: 100%; border-collapse: collapse; margin-bottom: 16px; }
.dims-panel th { text-align: left; color: #8b949e; font-weight: 500; padding: 4px 6px; border-bottom: 1px solid #30363d; font-size: 11px; }
.dims-panel td { padding: 4px 6px; border-bottom: 1px solid #21262d; color: #c9d1d9; font-family: 'SF Mono', 'Fira Code', monospace; font-size: 11px; }
.dims-panel .section { margin-bottom: 14px; }
.dims-panel .section-title { color: #8b949e; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; }
.dims-panel .stat { display: flex; justify-content: space-between; padding: 3px 0; }
.dims-panel .stat-label { color: #8b949e; }
.dims-panel .stat-value { color: #e6edf3; font-family: 'SF Mono', 'Fira Code', monospace; }
</style>
</head>
<body>
<div class="scene">
  <div class="view">
    <canvas id="c"></canvas>
    <div class="toolbar">
      <button title="Zoom to fit"><svg viewBox="0 0 24 24"><path d="M4 8V4h4M20 8V4h-4M4 16v4h4M20 16v4h-4"/><circle cx="12" cy="12" r="3"/></svg></button>
      <button class="active" title="Outlines"><svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/></svg></button>
      <button class="active" title="Pad numbers"><svg viewBox="0 0 24 24"><text x="12" y="16" text-anchor="middle" font-size="14" fill="none" stroke="#00b8b0" stroke-width="1.2">#</text></svg></button>
      <button title="Pad names"><svg viewBox="0 0 24 24"><text x="12" y="16" text-anchor="middle" font-size="14" fill="none" stroke="#666" stroke-width="1.2">N</text></svg></button>
      <button title="2D mesh"><svg viewBox="0 0 24 24"><path d="M3 3l18 18M3 12l18 0M12 3l0 18"/></svg></button>
      <button class="active" title="Copper"><svg viewBox="0 0 24 24"><path d="M4 6h16v12H4z"/><path d="M4 6l3-3h10l3 3"/></svg></button>
      <button title="Ground"><svg viewBox="0 0 24 24"><line x1="6" y1="18" x2="18" y2="18"/><line x1="9" y1="21" x2="15" y2="21"/><line x1="12" y1="6" x2="12" y2="18"/></svg></button>
      <button title="Axes"><svg viewBox="0 0 24 24"><line x1="12" y1="12" x2="20" y2="12" stroke="#e74040"/><line x1="12" y1="12" x2="12" y2="4" stroke="#40a0e7"/><line x1="12" y1="12" x2="6" y2="18" stroke="#40e740"/></svg></button>
      <button class="active" title="Dimensions"><svg viewBox="0 0 24 24"><line x1="3" y1="20" x2="21" y2="20"/><line x1="3" y1="18" x2="3" y2="22"/><line x1="21" y1="18" x2="21" y2="22"/><text x="12" y="12" text-anchor="middle" font-size="9" fill="none" stroke="#00b8b0" stroke-width="1.2">mm</text></svg></button>
      <button title="Land pattern"><svg viewBox="0 0 24 24"><rect x="6" y="4" width="12" height="16" rx="1" fill="none"/><rect x="2" y="6" width="4" height="2.5" rx="0.3" fill="none"/><rect x="2" y="10.5" width="4" height="2.5" rx="0.3" fill="none"/><rect x="2" y="15" width="4" height="2.5" rx="0.3" fill="none"/><rect x="18" y="6" width="4" height="2.5" rx="0.3" fill="none"/><rect x="18" y="10.5" width="4" height="2.5" rx="0.3" fill="none"/><rect x="18" y="15" width="4" height="2.5" rx="0.3" fill="none"/></svg></button>
    </div>
    <div class="badge">Fp3dView</div>
    <div class="footer">Demo &mdash; measurements overlay (simulated SOIC-8)</div>
  </div>
  <div class="dims-panel">
    <h3>SOIC-8-1EP 3.9x4.9mm</h3>
    <div class="section">
      <div class="section-title">Pad Details</div>
      <table>
        <thead><tr><th>#</th><th>Name</th><th>Shape</th><th>W</th><th>H</th><th>X</th><th>Y</th></tr></thead>
        <tbody>
          <tr><td>1</td><td>L1</td><td>rrect</td><td>1.95</td><td>0.60</td><td>-2.48</td><td>-1.91</td></tr>
          <tr><td>2</td><td>L2</td><td>rrect</td><td>1.95</td><td>0.60</td><td>-2.48</td><td>-0.64</td></tr>
          <tr><td>3</td><td>L3</td><td>rrect</td><td>1.95</td><td>0.60</td><td>-2.48</td><td>0.64</td></tr>
          <tr><td>4</td><td>L4</td><td>rrect</td><td>1.95</td><td>0.60</td><td>-2.48</td><td>1.91</td></tr>
          <tr><td>5</td><td>R1</td><td>rrect</td><td>1.95</td><td>0.60</td><td>2.48</td><td>1.91</td></tr>
          <tr><td>6</td><td>R2</td><td>rrect</td><td>1.95</td><td>0.60</td><td>2.48</td><td>0.64</td></tr>
          <tr><td>7</td><td>R3</td><td>rrect</td><td>1.95</td><td>0.60</td><td>2.48</td><td>-0.64</td></tr>
          <tr><td>8</td><td>R4</td><td>rrect</td><td>1.95</td><td>0.60</td><td>2.48</td><td>-1.91</td></tr>
          <tr><td>9</td><td>EP</td><td>rect</td><td>2.29</td><td>3.00</td><td>0.00</td><td>0.00</td></tr>
        </tbody>
      </table>
    </div>
    <div class="section">
      <div class="section-title">Pitch</div>
      <div class="stat"><span class="stat-label">Left side (L1-L4)</span><span class="stat-value">1.27 mm</span></div>
      <div class="stat"><span class="stat-label">Right side (R4-R1)</span><span class="stat-value">1.27 mm</span></div>
    </div>
    <div class="section">
      <div class="section-title">Overall Extents</div>
      <div class="stat"><span class="stat-label">Width (X)</span><span class="stat-value">6.90 mm</span></div>
      <div class="stat"><span class="stat-label">Height (Y)</span><span class="stat-value">4.41 mm</span></div>
      <div class="stat"><span class="stat-label">X range</span><span class="stat-value">-3.45 to 3.45</span></div>
      <div class="stat"><span class="stat-label">Y range</span><span class="stat-value">-2.21 to 2.21</span></div>
    </div>
    <div class="section">
      <div class="section-title">Pad-to-Pad</div>
      <div class="stat"><span class="stat-label">Center span (X)</span><span class="stat-value">4.95 mm</span></div>
      <div class="stat"><span class="stat-label">Pad count</span><span class="stat-value">9</span></div>
      <div class="stat"><span class="stat-label">SMD pads</span><span class="stat-value">9</span></div>
      <div class="stat"><span class="stat-label">THT pads</span><span class="stat-value">0</span></div>
    </div>
  </div>
</div>
<script>
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var W, H;
function resize() { W = canvas.width = canvas.offsetWidth; H = canvas.height = canvas.offsetHeight; draw(); }
window.addEventListener('resize', resize);

var pads = [
  {n:'1',x:-2.475,y:-1.905,w:1.95,h:0.6},{n:'2',x:-2.475,y:-0.635,w:1.95,h:0.6},
  {n:'3',x:-2.475,y:0.635,w:1.95,h:0.6},{n:'4',x:-2.475,y:1.905,w:1.95,h:0.6},
  {n:'5',x:2.475,y:1.905,w:1.95,h:0.6},{n:'6',x:2.475,y:0.635,w:1.95,h:0.6},
  {n:'7',x:2.475,y:-0.635,w:1.95,h:0.6},{n:'8',x:2.475,y:-1.905,w:1.95,h:0.6},
  {n:'9',x:0,y:0,w:2.29,h:3}
];

function draw() {
  ctx.fillStyle = '#1a1f26'; ctx.fillRect(0, 0, W, H);
  var scale = Math.min(W, H) / 14;
  var cx = W * 0.48, cy = H * 0.46;
  pads.forEach(function(p) {
    var px = cx + p.x * scale, py = cy + p.y * scale * 0.75;
    var pw = p.w * scale, ph = p.h * scale * 0.75;
    var r = Math.min(pw, ph) * 0.25;
    ctx.fillStyle = '#b8860b'; ctx.strokeStyle = '#3a8fd4'; ctx.lineWidth = 1.5;
    roundRect(ctx, px-pw/2, py-ph/2, pw, ph, r); ctx.fill();
    roundRect(ctx, px-pw/2, py-ph/2, pw, ph, r); ctx.stroke();
    ctx.fillStyle = '#fff'; ctx.font = (scale*0.35)+'px monospace'; ctx.textAlign = 'left'; ctx.textBaseline = 'middle';
    ctx.fillText(p.n, px+pw/2+scale*0.12, py);
  });
}

function roundRect(ctx,x,y,w,h,r) {
  ctx.beginPath(); ctx.moveTo(x+r,y); ctx.lineTo(x+w-r,y);
  ctx.quadraticCurveTo(x+w,y,x+w,y+r); ctx.lineTo(x+w,y+h-r);
  ctx.quadraticCurveTo(x+w,y+h,x+w-r,y+h); ctx.lineTo(x+r,y+h);
  ctx.quadraticCurveTo(x,y+h,x,y+h-r); ctx.lineTo(x,y+r);
  ctx.quadraticCurveTo(x,y,x+r,y); ctx.closePath();
}
resize();
</script>
</body>
</html>