master
John Lauer MPN laser etch: etched STEP is the default, plain kept as -unetched.step; hero GLB with footprint and silkscreen; hero… 551f987 20d ago
<!doctype html><html><head><meta charset="utf-8"><title>Hero</title>
<style>
@font-face{font-family:FG;src:url(/_tools/fonts/FamiljenGrotesk-Variable.woff2) format('woff2');font-weight:400 700}
@font-face{font-family:JBM;src:url(/_tools/fonts/JetBrainsMono-Regular.woff2) format('woff2');font-weight:400}
@font-face{font-family:JBM;src:url(/_tools/fonts/JetBrainsMono-Bold.woff2) format('woff2');font-weight:700}
html,body{margin:0;width:1920px;height:1200px;overflow:hidden;background:#0c1117}
body{position:relative;font-family:FG,sans-serif;color:#eef2f6;background:radial-gradient(ellipse 60% 70% at 18% 30%,#121a22 0%,#0c1117 70%)}
.bar{position:absolute;left:0;top:0;right:0;height:8px;background:linear-gradient(90deg,#1fd6c9,#3aa0ff)}
.glow{position:absolute;left:880px;top:80px;width:1100px;height:1060px;border-radius:50%;background:radial-gradient(closest-side,rgba(40,200,190,.20),rgba(40,160,190,.08) 55%,rgba(12,17,23,0) 100%)}
canvas{position:absolute;right:0;top:0;width:1100px;height:1200px;z-index:1}
.left{position:absolute;left:124px;top:150px;width:800px;z-index:2}
.kicker{font-family:JBM;font-size:28px;letter-spacing:.24em;color:#27d3c6;margin-bottom:40px}
h1{font-weight:700;margin:0 0 30px;line-height:1.02;letter-spacing:-.01em;white-space:nowrap}
.mpn{font-family:JBM;font-weight:700;font-size:44px;color:#cfe0ea;margin:-6px 0 26px;letter-spacing:.02em}
.cat{font-size:40px;line-height:1.25;white-space:nowrap;color:#dfe6ec;margin-bottom:22px}
.mfr{font-size:38px;color:#98a4b0}
.pill{display:inline-block;margin-top:44px;padding:14px 30px;border:2px solid rgba(39,211,198,.55);border-radius:999px;font-family:JBM;font-size:24px;letter-spacing:.18em;color:#27d3c6}
.foot{position:absolute;z-index:2;left:124px;bottom:78px;font-family:JBM;font-size:27px;color:#5f6b77;letter-spacing:.02em}
</style>
<script type="importmap">{"imports":{"three":"https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js","three/addons/":"https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/"}}</script>
</head><body>
<div class="bar"></div><div class="glow"></div>
<div class="left">
 <div class="kicker">COMPONENT</div>
 <h1 id="title"></h1>
 <div class="mpn" id="mpn"></div>
 <div class="cat" id="cat"></div>
 <div class="mfr" id="mfr"></div>
 <div id="pillwrap"></div>
</div>
<div class="foot" id="foot"></div>
<script type="module">
import * as THREE from 'three';
import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';
import {RoomEnvironment} from 'three/addons/environments/RoomEnvironment.js';
const C = __CFG__;
const t = document.getElementById('title'); t.textContent = C.title;
document.getElementById('mpn').textContent = C.mpn || ''; if (!C.mpn) document.getElementById('mpn').remove();
document.getElementById('cat').textContent = C.cat; document.getElementById('mfr').textContent = C.mfr;
if (C.pill) document.getElementById('pillwrap').innerHTML = '<div class="pill">' + C.pill + '</div>';
document.getElementById('foot').textContent = C.foot;
await document.fonts.ready;
let fs = 128; t.style.fontSize = fs + 'px'; while (t.scrollWidth > 800 && fs > 60) { fs -= 2; t.style.fontSize = fs + 'px'; }
const W = 1100, H = 1200;
const r = new THREE.WebGLRenderer({antialias: true, alpha: true, preserveDrawingBuffer: true}); r.setPixelRatio(1); r.setSize(W, H);
r.toneMapping = THREE.NeutralToneMapping; r.toneMappingExposure = C.exposure || 1.0; r.setClearColor(0x000000, 0);
document.body.appendChild(r.domElement);
const scene = new THREE.Scene();
scene.environment = new THREE.PMREMGenerator(r).fromScene(new RoomEnvironment(), 0.04).texture;
const key = new THREE.DirectionalLight(0xffffff, 1.6); key.position.set(-2, -3, 6); scene.add(key);
const rim = new THREE.DirectionalLight(0x9fe8ff, 0.6); rim.position.set(3, 4, 2); scene.add(rim);
const g = await new GLTFLoader().loadAsync(C.glb); scene.add(g.scene); g.scene.updateMatrixWorld(true);
const box = new THREE.Box3().setFromObject(g.scene); const c = box.getCenter(new THREE.Vector3()); const s = box.getSize(new THREE.Vector3());
const R = s.length() / 2;
const cam = new THREE.PerspectiveCamera(22, W / H, R / 50, R * 50); cam.up.set(0, 0, 1);
const dir = new THREE.Vector3(...C.dir).normalize();
cam.position.copy(c).addScaledVector(dir, R * (C.dist || 3.3)); cam.lookAt(c);
r.render(scene, cam);
document.body.dataset.ready = 1;
</script></body></html>