<!DOCTYPE html>
<!--
     T H E   H O O D E D  .  front door v2
     no framework, no build step, no server. one file, served by a
     contract, reading a mine that lives on another chain. five rooms
     behind one door: terminal, manual, economy, lore, faq.
     the hooded have no timeline; the chain is the timeline.
-->
<html lang="en"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>THE HOODED - on-chain mining collection</title>
<style>
/* HOODCUT - the project's own letterform, welded into the page.
   5x7 terminal glyphs, every corner chamfered like a drawn hood. */
@font-face{font-family:'HOODCUT';src:url(data:font/ttf;base64,AAEAAAAKAIAAAwAgT1MvMkQ4RG4AAAEoAAAAYGNtYXACFALSAAAB7AAAAH5nbHlmzy51zwAAAtAAABwqaGVhZC5e0kIAAACsAAAANmhoZWEEsgJaAAAA5AAAACRobXR4AlgAAAAAAYgAAABibG9jYcA3uLgAAAJsAAAAYm1heHAARABOAAABCAAAACBuYW1lp1KcywAAHvwAAAGJcG9zdMXJytAAACCIAAABnAABAAAAAQAAtKDbNF8PPPUAAQMgAAAAAOarR7cAAAAA5qtHtwAAAAAB9AK8AAAAAwACAAAAAAAAAAEAAAK8/5wAAAJYAAAAZAH0AAEAAAAAAAAAAAAAAAAAAAABAAEAAAAwAEwAEwAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwJYAZAABQAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAPz8/PwAAACAAegK8/5wAAAK8AGQAAAAAAAAAAAAAAAAAAAAgAAACWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAMAAAAUAAMAAQAAABQABABqAAAAFAAQAAMABAAgACUAKQAvADkAOgA9AFoAev//AAAAIAAlACgAKwAwADoAPQBBAGH//wAPAAQAAgAA/+v/8v/q/8D/oAABAAAAAAAAAA4AAAAAAAAAAAAAAAAAJQAtACYALgAoAAAAAAAAAGkA3QEsAZYB9AJBAqkDCANUA5cD4wQYBHYE1QU5BY8F8gZVBq4G6QdDB5EH9Ag7CHQIwQk1CXYJygogCnUK1Qs2C3IL2ww8DHMMlQzTDQANUQ1+DaoN3Q35DhUOFQAAABEAAAAAAfQCvAADAAcACwAPABMAFwAbAB8AIwAnACsALwAzADcAOwA/AEMAABMzNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjFzM1IxczNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjZGRkZGRkZGRk/tRkZAGQZGT+cGRkAZBkZP5wZGRkZGRkZGRkZGRkZGT+cGRkAZBkZP5wZGQBkGRk/nBkZAJYZGRkZGTIZGRkyGRkZMhkZGRkZGRkZGTIZGRkyGRkZMhkABMAAAAAAfQCvAADAAcACwAPABMAFwAbAB8AIwAnACsALwAzADcAOwA/AEMARwBLAAATMzUjFzM1IxczNSMFMzUjBTM1IwUzNSMFMzUjBTM1IxczNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjFzM1IxczNSMXMzUjZGRkZGRkZGRk/tRkZAGQZGT+cGRkAZBkZP5wZGRkZGRkZGRkZGT+1GRkAZBkZP5wZGQBkGRk/nBkZGRkZGRkZGRkZAJYZGRkZGTIZGRkyGRkZMhkZGRkZGRkyGRkZMhkZGTIZGRkZGRkZAANAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAC8AMwAAEzM1IxczNSMXMzUjBTM1IwUzNSMFMzUjFTM1IxUzNSMVMzUjBTM1IwUzNSMXMzUjFzM1I2RkZGRkZGRkZP7UZGQBkGRk/nBkZGRkZGRkZAGQZGT+1GRkZGRkZGRkAlhkZGRkZMhkZGTIZMhkyGTIZGRkyGRkZGRkABEAAAAAAfQCvAADAAcACwAPABMAFwAbAB8AIwAnACsALwAzADcAOwA/AEMAABMzNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjFzM1IxczNSMXMzUjZGRkZGRkZGRk/tRkZAGQZGT+cGRkAZBkZP5wZGQBkGRk/nBkZAGQZGT+cGRkAZBkZP5wZGRkZGRkZGRkZGQCWGRkZGRkyGRkZMhkZGTIZGRkyGRkZMhkZGTIZGRkZGRkZAAAEAAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwA7AD8AABMzNSMXMzUjFzM1IxczNSMFMzUjFTM1IxUzNSMXMzUjFzM1IxczNSMFMzUjFTM1IxUzNSMXMzUjFzM1IxczNSNkZGRkZGRkZGRkZGT+cGRkZGRkZGRkZGRkZGRkZP7UZGRkZGRkZGRkZGRkZGRkAlhkZGRkZGRkyGTIZMhkZGRkZGRkyGTIZMhkZGRkZGRkAAANAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAC8AMwAAEzM1IxczNSMXMzUjFzM1IwUzNSMVMzUjFTM1IxczNSMXMzUjFzM1IwUzNSMVMzUjFTM1I2RkZGRkZGRkZGRkZP5wZGRkZGRkZGRkZGRkZGRk/tRkZGRkZGQCWGRkZGRkZGTIZMhkyGRkZGRkZGTIZMhkyGQAEQAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwA7AD8AQwAAEzM1IxczNSMXMzUjBTM1IwUzNSMFMzUjFTM1IxczNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjFzM1IxczNSNkZGRkZGRkZGT+1GRkAZBkZP5wZGRkZMhkZGRkZGRkZP5wZGQBkGRk/nBkZAGQZGT+1GRkZGRkZGRkAlhkZGRkZMhkZGTIZMhkZGRkZGRkyGRkZMhkZGTIZGRkZGQAAA8AAAAAAfQCvAADAAcACwAPABMAFwAbAB8AIwAnACsALwAzADcAOwAAATM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjFzM1IxczNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjAZBkZP5wZGQBkGRk/nBkZAGQZGT+cGRkZGRkZGRkZGRkZGRk/nBkZAGQZGT+cGRkAZBkZP5wZGQCWGTIZGRkyGRkZMhkZGRkZGRkZGTIZGRkyGRkZMhkAAANAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAC8AMwAAEzM1IxczNSMXMzUjFzM1IwczNSMVMzUjFTM1IxUzNSMVMzUjBzM1IxczNSMXMzUjFzM1I2RkZGRkZGRkZGRkZMhkZGRkZGRkZGRkyGRkZGRkZGRkZGRkAlhkZGRkZGRkyGTIZMhkyGTIZMhkZGRkZGRkAAsAAAAAAfQCvAADAAcACwAPABMAFwAbAB8AIwAnACsAABMzNSMXMzUjFzM1IwczNSMVMzUjFTM1IxUzNSMFMzUjBTM1IwczNSMXMzUjyGRkZGRkZGRkZGRkZGRkZGRk/tRkZAEsZGTIZGRkZGQCWGRkZGRkyGTIZMhkyGTIZGRkyGRkZAAADAAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvAAABMzUjBTM1IwUzNSMFMzUjFzM1IwczNSMXMzUjBzM1IxczNSMHMzUjBTM1IwUzNSMBkGRk/nBkZAEsZGT+1GRkyGRkyGRkZGRkZGRkyGRkyGRkASxkZP7UZGQCWGTIZGRkyGRkZMhkZGTIZGRkyGRkZMhkAAAJAAAAAAGQAlgAAwAHAAsADwATABcAGwAfACMAABEzNSMVMzUjFTM1IxUzNSMVMzUjFTM1IxczNSMXMzUjFzM1I2RkZGRkZGRkZGRkZGRkZGRkZGRkZAH0ZMhkyGTIZMhkyGRkZGRkZGQADwAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwA7AAABMzUjBTM1IxczNSMXMzUjFzM1IwUzNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMBkGRk/nBkZGRkZMhkZGRkZP5wZGTIZGTIZGT+cGRkAZBkZP5wZGQBkGRk/nBkZAGQZGT+cGRkAlhkyGRkZGRkZGTIZGRkZGTIZGRkyGRkZMhkZGTIZAAPAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAC8AMwA3ADsAAAEzNSMFMzUjFzM1IwUzNSMFMzUjFzM1IxczNSMFMzUjBTM1IxczNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwGQZGT+cGRkZGRkASxkZP5wZGTIZGTIZGT+cGRkASxkZGRkZP5wZGQBkGRk/nBkZAGQZGT+cGRkAlhkyGRkZGRkyGRkZGRkyGRkZGRkyGRkZMhkZGTIZAAAEAAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwA7AD8AABMzNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjFzM1IxczNSNkZGRkZGRkZGT+1GRkAZBkZP5wZGQBkGRk/nBkZAGQZGT+cGRkAZBkZP5wZGQBkGRk/tRkZGRkZGRkZAJYZGRkZGTIZGRkyGRkZMhkZGTIZGRkyGRkZMhkZGRkZAAOAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAC8AMwA3AAATMzUjFzM1IxczNSMFMzUjBTM1IwUzNSMFMzUjBTM1IxczNSMXMzUjFzM1IwUzNSMVMzUjFTM1I2RkZGRkZGRkZP7UZGQBkGRk/nBkZAGQZGT+cGRkZGRkZGRkZGRk/tRkZGRkZGQCWGRkZGRkyGRkZMhkZGTIZGRkZGRkZMhkyGTIZAAAEAAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwA7AD8AABMzNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMXMzUjFzM1IwUzNSMFMzUjBzM1IxczNSNkZGRkZGRkZGT+1GRkAZBkZP5wZGQBkGRk/nBkZAGQZGT+cGRkyGRkyGRk/nBkZAEsZGTIZGRkZGQCWGRkZGRkyGRkZMhkZGTIZGRkyGRkZGRkyGRkZMhkZGQAEAAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwA7AD8AABMzNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjFzM1IxczNSMXMzUjBTM1IxczNSMHMzUjBTM1IwUzNSNkZGRkZGRkZGT+1GRkAZBkZP5wZGQBkGRk/nBkZGRkZGRkZGRkZP7UZGTIZGTIZGQBLGRk/tRkZAJYZGRkZGTIZGRkyGRkZMhkZGRkZGRkyGRkZMhkZGTIZAAADwAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwA7AAATMzUjFzM1IxczNSMXMzUjBTM1IxUzNSMXMzUjFzM1IxczNSMXMzUjFTM1IwUzNSMXMzUjFzM1IxczNSNkZGRkZGRkZGRkZGT+cGRkZGRkZGRkZGRkZGRkZGRkZP5wZGRkZGRkZGRkZGQCWGRkZGRkZGTIZMhkyGRkZGRkyGTIZMhkZGRkZGRkAAoAZAAAAfQCvAADAAcACwAPABMAFwAbAB8AIwAnAAATMzUjFzM1IxczNSMXMzUjBzM1IxUzNSMVMzUjFTM1IxUzNSMVMzUjZGRkZGRkZGRkZGRkyGRkZGRkZGRkZGRkZAJYZGRkZGRkZMhkyGTIZMhkyGTIZAAOAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAC8AMwA3AAABMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMXMzUjFzM1IwGQZGT+cGRkAZBkZP5wZGQBkGRk/nBkZAGQZGT+cGRkAZBkZP5wZGQBkGRk/tRkZGRkZGRkZAJYZMhkZGTIZGRkyGRkZMhkZGTIZGRkyGRkZGRkAAAMAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAC8AAAEzNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMXMzUjBzM1IwGQZGT+cGRkAZBkZP5wZGQBkGRk/nBkZAGQZGT+cGRkAZBkZP7UZGTIZGRkZGQCWGTIZGRkyGRkZMhkZGTIZGRkyGRkZMhkAAAQAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAC8AMwA3ADsAPwAAATM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjFzM1IxczNSMFMzUjFzM1IxczNSMFMzUjFzM1IxczNSMXMzUjBTM1IwGQZGT+cGRkAZBkZP5wZGQBkGRk/nBkZMhkZMhkZP5wZGTIZGTIZGT+cGRkZGRkyGRkZGRk/nBkZAJYZMhkZGTIZGRkyGRkZGRkyGRkZGRkyGRkZGRkZGTIZAALAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAAABMzUjBTM1IwUzNSMFMzUjFzM1IwczNSMHMzUjFzM1IwUzNSMFMzUjBTM1IwGQZGT+cGRkAZBkZP7UZGTIZGRkZGRkZGTIZGT+1GRkAZBkZP5wZGQCWGTIZGRkyGRkZMhkyGRkZMhkZGTIZAAACQAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjAAABMzUjBTM1IwUzNSMFMzUjFzM1IwczNSMVMzUjFTM1IxUzNSMBkGRk/nBkZAGQZGT+1GRkyGRkZGRkZGRkZGRkAlhkyGRkZMhkZGTIZMhkyGTIZAAADQAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMAABMzNSMXMzUjFzM1IxczNSMVMzUjBzM1IwczNSMHMzUjBzM1IxUzNSMXMzUjFzM1IxczNSNkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkAlhkZGRkZGRkyGTIZMhkyGTIZMhkZGRkZGRkABMAAAAAAfQCvAADAAcACwAPABMAFwAbAB8AIwAnACsALwAzADcAOwA/AEMARwBLAAATMzUjFzM1IxczNSMFMzUjBTM1IwUzNSMFMzUjFzM1IwUzNSMXMzUjFzM1IwUzNSMXMzUjBTM1IwUzNSMFMzUjBTM1IxczNSMXMzUjZGRkZGRkZGRk/tRkZAGQZGT+cGRkASxkZGRkZP5wZGTIZGTIZGT+cGRkZGRkASxkZP5wZGQBkGRk/tRkZGRkZGRkZAJYZGRkZGTIZGRkyGRkZGRkyGRkZGRkyGRkZGRkyGRkZMhkZGRkZAALAAAAAAGQArwAAwAHAAsADwATABcAGwAfACMAJwArAAATMzUjBzM1IxczNSMVMzUjFTM1IxUzNSMVMzUjBzM1IxczNSMXMzUjFzM1I8hkZGRkZGRkZGRkZGRkZGRkyGRkZGRkZGRkZGRkAlhkyGRkZMhkyGTIZMhkyGRkZGRkZGQADgAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwAAEzM1IxczNSMXMzUjBTM1IwUzNSMVMzUjBzM1IxczNSMHMzUjBzM1IxUzNSMXMzUjFzM1IxczNSNkZGRkZGRkZGT+1GRkAZBkZGRkyGRkZGRkyGRkZGRkZGRkZGRkZGRkZGQCWGRkZGRkyGRkZMhkyGRkZMhkyGTIZGRkZGRkZAAADgAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwAAEzM1IxczNSMXMzUjBTM1IwUzNSMVMzUjBzM1IxczNSMXMzUjBTM1IwUzNSMFMzUjFzM1IxczNSNkZGRkZGRkZGT+1GRkAZBkZGRkyGRkZGRkZGRk/nBkZAGQZGT+1GRkZGRkZGRkAlhkZGRkZMhkZGTIZMhkZGTIZMhkZGTIZGRkZGQAAA4AAAAAAfQCvAADAAcACwAPABMAFwAbAB8AIwAnACsALwAzADcAAAEzNSMHMzUjFzM1IwczNSMXMzUjBTM1IwUzNSMFMzUjFzM1IxczNSMXMzUjFzM1IwczNSMVMzUjASxkZGRkZGRkZMhkZMhkZP7UZGQBLGRk/tRkZGRkZGRkZGRkZGRkZGRkZGRkAlhkyGRkZMhkZGTIZGRkyGRkZGRkZGRkZMhkyGQAEAAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwA7AD8AABMzNSMXMzUjFzM1IxczNSMFMzUjFTM1IxczNSMXMzUjFzM1IxczNSMVMzUjBTM1IwUzNSMFMzUjFzM1IxczNSNkZGRkZGRkZGRkZGT+cGRkZGRkZGRkZGRkZGRkZGRkZP5wZGQBkGRk/tRkZGRkZGRkZAJYZGRkZGRkZMhkyGRkZGRkZGTIZMhkyGRkZMhkZGRkZAAAEAAAAAAB9AK8AAMABwALAA8AEwAXABsAHwAjACcAKwAvADMANwA7AD8AABMzNSMXMzUjFzM1IwUzNSMVMzUjFTM1IxczNSMXMzUjFzM1IwUzNSMFMzUjBTM1IwUzNSMFMzUjFzM1IxczNSNkZGRkZGRkZGT+1GRkZGRkZGRkZGRkZGRkZP7UZGQBkGRk/nBkZAGQZGT+1GRkZGRkZGRkAlhkZGRkZMhkyGTIZGRkZGRkZMhkZGTIZGRkyGRkZGRkAAAKAGQAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwAAEzM1IxczNSMXMzUjFzM1IxUzNSMHMzUjBzM1IwczNSMVMzUjFTM1I2RkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZAJYZGRkZGRkZMhkyGTIZMhkyGTIZAARAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAC8AMwA3ADsAPwBDAAATMzUjFzM1IxczNSMFMzUjBTM1IwUzNSMFMzUjBTM1IxczNSMXMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMXMzUjFzM1I2RkZGRkZGRkZP7UZGQBkGRk/nBkZAGQZGT+1GRkZGRkZGRk/tRkZAGQZGT+cGRkAZBkZP7UZGRkZGRkZGQCWGRkZGRkyGRkZMhkZGTIZGRkZGTIZGRkyGRkZMhkZGRkZAAQAAAAAAH0ArwAAwAHAAsADwATABcAGwAfACMAJwArAC8AMwA3ADsAPwAAEzM1IxczNSMXMzUjBTM1IwUzNSMFMzUjBTM1IwUzNSMXMzUjFzM1IxczNSMVMzUjFTM1IwUzNSMXMzUjFzM1I2RkZGRkZGRkZP7UZGQBkGRk/nBkZAGQZGT+1GRkZGRkZGRkZGRkZGRkZP7UZGRkZGRkZGQCWGRkZGRkyGRkZMhkZGTIZGRkZGRkZMhkyGTIZGRkZGQAAAkAAABkAfQCWAADAAcACwAPABMAFwAbAB8AIwAAEzM1IxUzNSMHMzUjFzM1IxczNSMXMzUjFzM1IwczNSMVMzUjyGRkZGTIZGRkZGRkZGRkZGRkZGTIZGRkZAH0ZMhkyGRkZGRkZGRkZMhkyGQABQAAASwB9AGQAAMABwALAA8AEwAAETM1IxczNSMXMzUjFzM1IxczNSNkZGRkZGRkZGRkZGRkZAEsZGRkZGRkZGRkAAAKAAAAyAH0AfQAAwAHAAsADwATABcAGwAfACMAJwAAETM1Ixcz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) format('truetype');font-display:swap}
:root{--bg:#070907;--panel:#0b0f0c;--panel2:#0d1410;--line:#16201a;--line2:#1e3a2c;--ink:#c9d4cd;--dim:#5f6f66;--acc:#3dff9d;--acc2:#9fd6b0;--warn:#ff7a3c;--void:#000}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--ink);font-family:monospace;line-height:1.5}
.wrap{max-width:1120px;margin:0 auto;padding:0 5vw}
a{color:var(--acc)}
/* -------- nav -------- */
#nav{position:sticky;top:0;z-index:9;background:#070907f2;border-bottom:1px solid var(--line);backdrop-filter:blur(4px)}
#nav .wrap{display:flex;align-items:center;gap:18px;padding-top:12px;padding-bottom:12px;flex-wrap:wrap}
#nav .logo{font-family:'HOODCUT',monospace;letter-spacing:.1em;color:#e8f3ec;white-space:nowrap}
#nav .logo b{color:var(--acc)}
#nav a.tab{font-family:'HOODCUT',monospace;color:var(--dim);text-decoration:none;font-size:12px;letter-spacing:.12em;padding:4px 2px;border-bottom:2px solid transparent}
#nav a.tab.on{color:var(--acc);border-color:var(--acc)}
#nav .right{margin-left:auto;display:flex;gap:10px;align-items:center}
a.mkt{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border:1px solid var(--line2);border-radius:7px;background:#0d1410}
a.mkt:hover{background:#173525}
a.mkt svg{width:16px;height:16px;fill:var(--acc)}
#chainDot{width:8px;height:8px;border-radius:50%;background:#333;display:inline-block}
#chainDot.ok{background:var(--acc);box-shadow:0 0 8px var(--acc)}
/* -------- hero -------- */
#hero{padding:64px 0 40px;border-bottom:1px solid var(--line)}
#hero .cols{display:grid;grid-template-columns:1.3fr 1fr;gap:36px;align-items:center}
@media(max-width:820px){#hero .cols{grid-template-columns:1fr}}
h1{font-family:'HOODCUT',monospace;font-size:clamp(34px,6vw,64px);letter-spacing:.04em;color:#e8f3ec}
h1 b{color:var(--acc)}
.tag{color:var(--dim);letter-spacing:.18em;font-size:13px;margin-top:10px}
.lead{color:#93a49a;margin-top:18px;max-width:560px;font-size:15px;line-height:1.8}
.lead b{color:var(--acc2)}
#heroArt{border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--void);min-height:260px;position:relative}
#heroArt img{width:100%;display:block}
#heroArt .cap{position:absolute;top:0;bottom:auto;left:0;right:0;background:#000000c9;color:var(--dim);font-size:11px;padding:6px 10px;letter-spacing:.1em}
.heroBtns{margin-top:26px;display:flex;gap:12px;flex-wrap:wrap}
/* -------- common -------- */
h2{font-family:'HOODCUT',monospace;font-size:15px;letter-spacing:.18em;color:#e8f3ec;margin:0 0 14px;border-bottom:1px solid var(--line);padding-bottom:9px}
h2 span{color:var(--dim)}
section{padding:44px 0;border-bottom:1px solid var(--line)}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px}
.stat{background:var(--panel);border:1px solid var(--line);padding:12px 14px;border-radius:8px}
.stat b{display:block;font-family:'HOODCUT',monospace;color:var(--acc);font-size:17px;margin-top:4px;word-break:break-all}
.stat span{color:var(--dim);font-size:11px;letter-spacing:.1em}
button{background:#12241b;color:var(--acc);border:1px solid var(--line2);padding:10px 18px;border-radius:7px;font-family:'HOODCUT',monospace;font-size:12px;cursor:pointer;letter-spacing:.05em}
button:hover{background:#173525}
button:disabled{opacity:.35;cursor:default}
button.w{color:var(--warn);border-color:#3a2a1e;background:#241812}
button.big{font-size:15px;padding:13px 24px}
input{background:var(--panel2);border:1px solid var(--line);color:var(--ink);padding:10px;border-radius:7px;font-family:monospace;width:76px}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:12px 0}
.card{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:14px;margin:10px 0;overflow:hidden}
.card img{width:150px;height:150px;border-radius:8px;float:left;margin-right:16px;background:var(--void)}
.dim{color:var(--dim);font-size:12px;line-height:1.7}
.ok{color:var(--acc)} .hot{color:var(--warn)}
.step{background:var(--panel);border:1px solid var(--line);border-left:3px solid var(--acc);border-radius:8px;padding:16px;margin:10px 0}
.step .no{font-family:'HOODCUT',monospace;color:var(--acc);letter-spacing:.16em;font-size:11px}
.step b{color:#e8f3ec}
.step p{color:#93a49a;font-size:13px;margin-top:6px;line-height:1.8}
table{width:100%;border-collapse:collapse;font-size:13px;margin:12px 0}
th,td{border:1px solid var(--line);padding:9px 12px;text-align:left}
th{color:var(--dim);letter-spacing:.12em;font-size:11px;background:var(--panel)}
td b{color:var(--acc2)}
.bar{height:8px;background:var(--panel2);border:1px solid var(--line);border-radius:5px;overflow:hidden;margin-top:6px}
.bar i{display:block;height:100%;background:var(--acc);opacity:.75}
.lore p{color:#93a49a;line-height:2;max-width:680px;margin:14px 0;font-size:14px}
.lore p b{color:var(--acc2)}
.faq{margin:10px 0}
.faq b{display:block;color:#e8f3ec;font-size:14px;margin-top:20px}
.faq p{color:#93a49a;font-size:13px;line-height:1.9;margin-top:6px;max-width:680px}
.mono{background:var(--panel2);border:1px solid var(--line);border-radius:8px;padding:14px;font-size:12px;color:var(--acc2);overflow-x:auto;white-space:pre}
#log{position:fixed;bottom:0;left:0;right:0;background:#0b0f0cee;border-top:1px solid var(--line);padding:8px 5vw;font-size:12px;color:var(--dim);white-space:nowrap;overflow:hidden;z-index:9}
footer{padding:44px 0 84px;color:var(--dim);font-size:12px;line-height:2}
.pgOff{display:none}
.lapchip{display:inline-flex;align-items:center;gap:10px;background:var(--panel);border:1px solid var(--line);border-radius:9px;padding:8px 12px;margin:6px 8px 0 0;cursor:pointer;user-select:none}
.lapchip img{width:56px;height:56px;border-radius:6px;background:var(--void)}
.lapchip.sel{border-color:var(--acc);box-shadow:0 0 8px #3dff9d55}
.lapchip.dead{opacity:.45;cursor:default}
.lapchip .st{font-size:11px}
</style></head>
<body>

<div id="nav"><div class="wrap">
  <span class="logo">THE <b>HOODED</b></span>
  <a class="tab on" href="#terminal" data-pg="terminal">TERMINAL</a>
  <a class="tab" href="#manual" data-pg="manual">MANUAL</a>
  <a class="tab" href="#economy" data-pg="economy">ECONOMY</a>
  <a class="tab" href="#lore" data-pg="lore">LORE</a>
  <a class="tab" href="#faq" data-pg="faq">FAQ</a>
  <span class="right">
    <a class="mkt" id="lnkDex" target="_blank" rel="noopener noreferrer" title="POW on DexScreener"><svg viewBox="0 0 16 16"><rect x="1" y="6" width="3" height="7"/><rect x="2" y="4" width="1" height="2"/><rect x="2" y="13" width="1" height="2"/><rect x="6.5" y="2" width="3" height="8"/><rect x="7.5" y="0" width="1" height="2"/><rect x="7.5" y="10" width="1" height="3"/><rect x="12" y="5" width="3" height="6"/><rect x="13" y="3" width="1" height="2"/><rect x="13" y="11" width="1" height="2"/></svg></a>
    <a class="mkt" id="lnkOs" target="_blank" rel="noopener noreferrer" title="Collection on OpenSea"><svg viewBox="0 0 16 16"><path d="M8 1L3 9h4V4.5L8 1zm1 3.5V9h4L9 4.5zM2 10.5h12L12.5 13h-9L2 10.5z"/><rect x="7.4" y="9" width="1.2" height="2.5"/></svg></a>
    <span id="chainDot"></span><button id="connBtn" onclick="wallet()">CONNECT</button></span>
</div></div>

<!-- ============================ TERMINAL ============================ -->
<div id="pg-terminal">
<div id="hero"><div class="wrap"><div class="cols">
  <div>
    <h1>THE <b>HOODED</b></h1>
    <div class="tag">NO SOCIALS. NO TEAM. ONLY BLOCKS.</div>
    <p class="lead">2,100 rigs mine <b>21,000,000 POW</b> out of an ownerless vault.
    Every room, every picture, every rule lives on the chain - even this page is
    served by a contract. The emission halves every <b>3.5 days</b>. The free class
    overheats and dies. The patient get paid. That is the whole game.</p>
    <div class="heroBtns">
      <button class="big" onclick="mintRig()">MINT RIG - 0.0014 ETH</button>
      <button class="big w" onclick="act('mintLaptop')">FREE LAPTOP</button>
    </div>
    <div class="dim" style="margin-top:12px">cap 10 rigs per wallet - EOA only - genome seals one block after mint</div>
  </div>
  <div id="heroArt"><span class="dim" style="display:block;padding:110px 20px;text-align:center">loading the room from the chain...</span></div>
</div></div></div>

<section><div class="wrap">
  <h2>NETWORK <span>// live from the mine</span></h2>
  <div class="grid" id="stats"><div class="stat"><span>LOADING</span><b>...</b></div></div>
  <div class="dim" id="halvBarWrap" style="margin-top:12px">emission spent this halving<div class="bar"><i id="halvBar" style="width:0%"></i></div></div>
</div></section>

<section><div class="wrap">
  <h2>MINT RIG <span>// the paid class</span></h2>
  <div class="row">
    <input id="mintN" type="number" min="1" max="10" value="1">
    <button onclick="mintRig()">MINT RIG - 0.0014 ETH EACH</button>
    <span class="dim">2,100 total. 100 GH base, 6 upgrade slots, boostable. Each rig gets its own on-chain room.</span>
  </div>
</div></section>

<section><div class="wrap">
  <h2>LAPTOP <span>// the free class</span></h2>
  <div id="lap" class="card"><span class="dim">connect wallet to see your laptop</span></div>
  <div class="dim">Free. 1 GH. Overheats within 12-24h - the room goes dark, the screen dies.
  REBOOT burns it and mints a fresh one. Own three LIVE laptops (mint one, buy or receive more),
  tap them below to select, and feed them to the burn-gate.</div>
  <div class="row">
    <button onclick="scanMine()">SCAN MY LAPTOPS</button>
    <button onclick="burnGate()" id="burnBtn" disabled>BURN 3 SELECTED + 0.0014 ETH = RIG WITH BONUS SLOT</button>
    <span class="dim" id="burnInfo"></span>
  </div>
  <div id="lapList"></div>
</div></section>

<section><div class="wrap">
  <h2>MY UNITS <span>// your side of the mine</span></h2>
  <div id="rigs"><span class="dim">connect wallet</span></div>
</div></section>

<section><div class="wrap">
  <h2>SWEEP <span>// paid janitor work</span></h2>
  <div class="row">
    <button onclick="sweepScan()">SCAN FOR OVERHEATED LAPTOPS</button>
    <button onclick="sweepGo()" id="sweepBtn" disabled>SWEEP (BOUNTY 0.05 POW EACH)</button>
    <span class="dim" id="sweepInfo"></span>
  </div>
  <div class="dim">Anyone may burn dead laptops and collect the bounty. Keeping the mine clean pays.</div>
</div></section>
</div>

<!-- ============================ MANUAL ============================ -->
<div id="pg-manual" class="pgOff">
<section><div class="wrap">
  <h2>HOW THE MINE WORKS <span>// six steps, no trust required</span></h2>
  <div class="step"><span class="no">01 / MINT</span><br><b>Buy a rig for 0.0014 ETH - or start free.</b>
    <p>A rig starts at 100 GH and mines from the very first block. A laptop costs nothing,
    mines 1 GH, and will die within a day. Ten rigs max per wallet, contracts cannot mint.</p></div>
  <div class="step"><span class="no">02 / REVEAL</span><br><b>The genome seals one block after mint.</b>
    <p>Entropy comes from the next block hash - unknowable while your transaction is in flight,
    so nobody can snipe rooms. Anyone can call reveal for anyone; unrevealed rigs still mine at
    full speed. The genome only decides which of the 24 rooms is yours.</p></div>
  <div class="step"><span class="no">03 / MINE</span><br><b>The vault pays out by hashrate share.</b>
    <p>Emission starts at 31.25 POW per second and halves every 3.5 days, integrated exactly across
    every boundary. Your share = your GH / network GH. The laptop class as a whole is capped at 5%
    of emission, so a swarm of free miners can never eat the mine.</p></div>
  <div class="step"><span class="no">04 / CLAIM</span><br><b>Patience is a strategy.</b>
    <p>Claiming within 48h of your last claim is taxed up to 25% - the roast - and the tax is
    redistributed to every rig still mining. Wait the full 48 hours and you keep everything.</p></div>
  <div class="step"><span class="no">05 / REINVEST</span><br><b>Slots and boosts burn the supply.</b>
    <p>A slot costs 1,500 POW and adds +100 GH forever (6 max). A boost costs 193 POW and adds +50%
    for 12-24h. Of every POW spent, 75% is burned forever, 25% goes to the dev address. There is no
    other faucet and no other sink.</p></div>
  <div class="step"><span class="no">06 / SWEEP + BURN-GATE</span><br><b>Even death has a market.</b>
    <p>Dead laptops can be swept by anyone for a 0.05 POW bounty each. Three LIVE laptops plus
    0.0014 ETH can be fed to the burn-gate for a rig with its first slot already filled - 200 GH
    from block one.</p></div>
  <h2 style="margin-top:34px">IRON RULES <span>// what cannot happen</span></h2>
  <div class="mono">no owner keys        - nobody can pause, patch, reprice or refund
no metadata server   - every image is drawn by the chain itself
no hidden mint       - 2,100 rigs, hard cap, wallet cap 10, EOA only
no vault top-up      - 18.9M POW, the series sums to it exactly
no renderer swap     - the art bind is one-shot and welded forever</div>
</div></section>
</div>

<!-- ============================ ECONOMY ============================ -->
<div id="pg-economy" class="pgOff">
<section><div class="wrap">
  <h2>SUPPLY <span>// 21,000,000 POW, not one more</span></h2>
  <table>
    <tr><th>SHARE</th><th>AMOUNT</th><th>WHERE IT LIVES</th></tr>
    <tr><td><b>90%</b> mining vault</td><td>18,900,000 POW</td><td>inside the deck contract - leaves only through mining</td></tr>
    <tr><td><b>10%</b> pool seed</td><td>2,100,000 POW</td><td>one-sided locked liquidity on the DEX</td></tr>
    <tr><td><b>0%</b> team</td><td>0 POW</td><td>nobody keeps a founder allocation</td></tr>
  </table>
  <h2 style="margin-top:34px">EMISSION <span>// R(t) = 31.25 / 2^(t / 3.5d) POW per second</span></h2>
  <table id="emTable">
    <tr><th>WEEK</th><th>RATE / DAY AT START</th><th>SHARE OF ALL POW EVER</th></tr>
    <tr><td>week 1</td><td><b>2,700,000 -&gt; 1,350,000</b></td><td>75% mined by end of week</td></tr>
    <tr><td>week 2</td><td><b>675,000 -&gt; 337,500</b></td><td>93.75% cumulative</td></tr>
    <tr><td>week 3</td><td><b>168,750 -&gt; 84,375</b></td><td>98.4% cumulative</td></tr>
    <tr><td>week 4+</td><td><b>the long tail</b></td><td>the mine dims towards zero, forever</td></tr>
  </table>
  <div class="dim">The asymptotic sum of the halving series equals the vault to the wei: 31.25 x 302,400s x 2 = 18,900,000.</div>
  <h2 style="margin-top:34px">SINKS <span>// where POW goes to die</span></h2>
  <table>
    <tr><th>ACTION</th><th>PRICE</th><th>EFFECT</th><th>SPLIT</th></tr>
    <tr><td>SLOT</td><td><b>1,500 POW</b></td><td>+100 GH permanent, 6 per rig</td><td>75% burned / 25% dev</td></tr>
    <tr><td>BOOST</td><td><b>193 POW</b></td><td>+50% hashrate for 12-24h</td><td>75% burned / 25% dev</td></tr>
    <tr><td>ROAST</td><td><b>up to 25% of claim</b></td><td>early-claim tax, cools to 0 over 48h</td><td>100% to patient miners</td></tr>
    <tr><td>SWEEP</td><td><b>-</b></td><td>0.05 POW bounty per dead laptop</td><td>paid from the vault</td></tr>
  </table>
  <h2 style="margin-top:34px">CLASS MATH <span>// paid vs free</span></h2>
  <table>
    <tr><th></th><th>RIG</th><th>LAPTOP</th></tr>
    <tr><td>price</td><td><b>0.0014 ETH</b></td><td><b>free</b></td></tr>
    <tr><td>hashrate</td><td><b>100 - 700 GH</b> (+50% boosted)</td><td><b>1 GH</b></td></tr>
    <tr><td>lifespan</td><td>forever</td><td>~12-24h, then overheats</td></tr>
    <tr><td>class cap</td><td>2,100 units</td><td>5% of emission, total</td></tr>
    <tr><td>art</td><td>1 of 24 on-chain rooms by genome</td><td>live room / burned-out room</td></tr>
  </table>
</div></section>
</div>

<!-- ============================ LORE ============================ -->
<div id="pg-lore" class="pgOff">
<section><div class="wrap lore">
  <h2>THE LORE <span>// why the hood</span></h2>
  <p>Somewhere under the trader chain, in rooms nobody rents, hooded figures mine a coin
  nobody promised them. They do not speak. They do not post. The face under every hood is
  a <b>void</b>, because identity is the first thing the mine takes as payment.</p>
  <p>When the last human closed the terminal, the machines kept mining. <b>Twenty-one million
  POW</b> and not one more - ninety percent locked in a vault that answers only to hashrate,
  ten percent seeded into a pool whose keys are already gone. Satoshi kept a million coins.
  The Hooded keep nothing.</p>
  <p>The paid ones sit in towers - twenty-four rooms, each sealed by a genome drawn from a
  block hash no one could predict. The free ones get a duct-taped laptop and a day of
  life. When a laptop dies, the screen goes dark, the stool empties, and the smoke is the
  only obituary. <b>Reboot</b> is the free class's whole religion.</p>
  <p>There is no team behind this. There are no keys left. Nobody can pause the mine, patch
  the rules, or top up the vault. Every promise this project makes is enforced by the only
  thing the Hooded trust: <b>the block after this one</b>.</p>
  <p>The emission halves every three and a half days. By the end of the first week, three
  quarters of everything that will ever exist is already out. The mine dims, the rooms stay
  lit a little longer, and then only the patient are left - which was always the point.</p>
  <p class="dim" id="addrs2"></p>
</div></section>
</div>

<!-- ============================ FAQ ============================ -->
<div id="pg-faq" class="pgOff">
<section><div class="wrap faq">
  <h2>FAQ <span>// asked by nobody, answered anyway</span></h2>
  <b>Is anything stored off-chain?</b>
  <p>No. The token images are SVG rooms stored as contract bytecode and assembled by the
  renderer at read time. The metadata is base64 JSON straight from the chain. This page
  itself is stored in a gate contract, chunk by chunk, and sealed.</p>
  <b>What happens if I never reveal my rig?</b>
  <p>Nothing bad - it mines at full speed either way. Reveal only wakes the genome and picks
  your room out of the 24. Anyone can reveal for you; bots usually do it within a minute.</p>
  <b>Why did my claim pay less than pending showed?</b>
  <p>You claimed within 48 hours of your previous claim, so the roast took up to 25% and
  redistributed it to every rig still mining. Wait the full 48h and the tax is zero.</p>
  <b>Can the free class drain the vault?</b>
  <p>No. All laptops together are capped at 5% of emission. The cap is enforced inside the
  accounting, not by trust.</p>
  <b>Why does my laptop die?</b>
  <p>It is a consumable - that is what free costs. It overheats within a day.
  Reboot burns it and mints a fresh one in one transaction, and the mint feed sees every
  reboot. Three live laptops can also be burned at the gate for a 200 GH rig.</p>
  <b>Who gets the 0.0014 ETH and the 25% of sinks?</b>
  <p>The immutable DEV address, fixed at deploy. It has no powers over the protocol - it is
  a beneficiary, not an owner. The other 75% of every sink is burned forever.</p>
  <b>What happens when the vault runs out?</b>
  <p>The mine starves gracefully: payouts are clamped by the vault balance, the emission rate
  reaches zero after the halvings, laptop minting freezes when the rate drops below 1/128 of
  genesis. The collection keeps rendering forever - the rooms do not need the vault.</p>
  <b>Is the site really on-chain?</b>
  <p>Yes. The HTML you are reading is stored in the HoodedGate contract and served via
  web3:// (ERC-4804). The stats above are read from the mine chain directly in your browser.
  If every website on earth went down, this page would still open.</p>
</div></section>
</div>

<footer><div class="wrap">
  <div id="addrs" class="dim"></div>
  <div style="margin-top:10px">THE HOODED - an ownerless mine. No socials. No team. Only blocks.</div>
</div></footer>

<div id="log">ready</div>

<script>
"use strict";
// -- the coordinates of the mine (welded in at deploy) --
const CFG = {
  chainId: "0x1237", chainName: "Robinhood Chain",
  rpc: ["https://rpc.mainnet.chain.robinhood.com"],
  explorer: "https://robinhoodchain.blockscout.com",
  deck: "0xc565d2Cb84B11D6964C2EcE0b82794035A63b6d4",
  pow:  "0x219975C99A40afEee747D6C4fc72BBE04c5c8E91",
  dexSlug: "robinhood", openseaSlug: "the-hooded",
  rigPrice: 1400000000000000n, // the toll at the door: 0.0014 ETH a rig
};
const SEL = { // the knocks the door answers to (selectors from the compiled deck)
  frontStats:"86b0a4f7", rigsOf:"725c6736", pendingRig:"9e6391db", rigInfo:"1d9b6a4f",
  laptopOf:"1217bafd", pendingLaptop:"d77e6375", lapExp:"e0ea5f86", currentEpoch:"76671808",
  START:"ba9a061a", mintRig:"f9528846", mintRigBurning:"562a4e40", reveal:"b93f208a",
  claimRigs:"8de1c065", buySlot:"ab2874cb", boost:"1b55d19e", mintLaptop:"8eb4b28c",
  reboot:"9912815c", claimLaptop:"976fb48e", sweep:"98b02275", rate:"2c4e722e",
  tokenURI:"c87b56dd", ownerOf:"6352211e", rigsMinted:"3b8cfbde", nextLap:"68fb5065", isLaptopLive:"890da48c",
  lapsLive:"945227d5", genome:"d8470576", contractURI:"e8a3d485",
  balanceOf:"70a08231", allowance:"dd62ed3e", approve:"095ea7b3", totalSupply:"18160ddd",
};
// -- reading the chain, one 32-byte word at a time --
const P = (h)=>h.replace(/^0x/,"").padStart(64,"0");
const U = (n)=>P(BigInt(n).toString(16));
const hexToBig = (h)=>BigInt(h);
function encArr(sel, arr){ let d="0x"+sel+U(32)+U(arr.length); for(const x of arr) d+=U(x); return d; }
function enc(sel, ...words){ return "0x"+sel+words.map(U).join(""); }
async function rpc(method, params){
  let lastErr = null;
  for(let pass = 0; pass < 2; pass++){
    for(const url of CFG.rpc){
      try{
        const r = await fetch(url,{method:"POST",headers:{"content-type":"application/json"},
          body:JSON.stringify({jsonrpc:"2.0",id:1,method,params})});
        const j = await r.json();
        if(j.error){ const err = new Error(j.error.message); err.data = j.error.data; throw err; }
        return j.result;
      }catch(e){
        // a real revert carries data - surface it immediately, do not retry
        if(e && e.data) throw e;
        lastErr = e; console.warn(url, e);
      }
    }
    await new Promise(r=>setTimeout(r, 600));
  }
  const err = new Error("rpc unreachable"); err.network = true; throw err;
}
const call = (to,data)=>rpc("eth_call",[{to,data},"latest"]);
function words(res){ const h=res.replace(/^0x/,""); const out=[]; for(let i=0;i<h.length;i+=64) out.push(BigInt("0x"+h.slice(i,i+64))); return out; }
function decArr(res){ const w=words(res); const n=Number(w[1]); return w.slice(2,2+n); }
function decStr(res){ const off=Number(words(res)[0]); const len=Number(BigInt("0x"+res.slice(2+off*2,2+off*2+64)));
  return res.slice(2+off*2+64, 2+off*2+64+len*2).match(/../g).map(h=>String.fromCharCode(parseInt(h,16))).join(""); }
async function tokenImage(id){
  try{ const uri = decStr(await call(CFG.deck, enc(SEL.tokenURI, id)));
    return JSON.parse(atob(uri.split(",")[1])).image; }catch(e){ return ""; }
}
// -- what the mine says when it refuses (custom error selectors -> words) --
const ERR = {
  "0xba092d16":"only wallets can mint - contracts are turned away at the door",
  "0x98d4901c":"wrong ETH amount (0.0014 per rig) or wrong laptop count (exactly 3)",
  "0x52df9fe5":"sold out - all 2,100 rigs are minted",
  "0xd7e991d2":"wallet cap reached - 10 rigs max",
  "0x4a636d30":"that token is not yours",
  "0x085de625":"too early - the genome seals ~15s after mint, try again in a moment",
  "0xa89ac151":"already revealed",
  "0x0fb0d823":"no slot left - 6 max",
  "0x4aabed65":"already boosted - wait for this boost to expire",
  "0xd3230a3f":"you already have a live laptop - reboot it instead",
  "0x8748f1c3":"no laptop on this wallet - mint one first",
  "0xc4b39ef1":"that laptop is overheated - only LIVE ones pass the gate",
  "0x45a96617":"laptop minting is frozen - the emission is too deep in its life",
  "0x351261fc":"nothing to sweep - no overheated laptops in that list",
  "0xb1d04f08":"token does not exist",
  "0xea8e4eb5":"not authorized",
  "0xf4d678b8":"not enough POW",
  "0x13be252b":"POW allowance too low - approve first",
};
function friendly(e){
  const d = (e && e.data ? String(e.data) : "").slice(0, 10);
  return ERR[d] || (e && e.message) || String(e);
}
async function preflight(tx){
  try{ await rpc("eth_call", [tx, "latest"]); return null; }
  catch(e){
    if(e && e.network) return {warn: "rpc is flaky right now - skipping the dry-run, the wallet will check instead"};
    return {block: friendly(e)};
  }
}
const fmt=(x,dp=1)=>{const v=Number(x)/1e18;return v>=1e6?(v/1e6).toFixed(2)+"M":v>=1e3?(v/1e3).toFixed(1)+"k":v.toFixed(dp)};
const log=(m,cls)=>{const el=document.getElementById("log");el.innerHTML=cls?`<span class="${cls}">${m}</span>`:m;};
// -- pages: one file, five rooms --
const PAGES=["terminal","manual","economy","lore","faq"];
function showPage(){
  let pg=(location.hash||"#terminal").slice(1);
  if(!PAGES.includes(pg)) pg="terminal";
  for(const p of PAGES){
    document.getElementById("pg-"+p).className = p===pg?"":"pgOff";
  }
  document.querySelectorAll("#nav a.tab").forEach(a=>{
    a.className = a.dataset.pg===pg?"tab on":"tab";
  });
  window.scrollTo(0,0);
}
window.addEventListener("hashchange",showPage);
// -- the hand that signs --
let me=null;
async function wallet(){
  if(me) return me;
  if(!window.ethereum){ log("no wallet found - install one to act; reading works without","hot"); throw new Error("no wallet"); }
  const acc = await window.ethereum.request({method:"eth_requestAccounts"});
  me = acc[0];
  try{ await window.ethereum.request({method:"wallet_switchEthereumChain",params:[{chainId:CFG.chainId}]}); }
  catch(e){ if(e.code===4902){ await window.ethereum.request({method:"wallet_addEthereumChain",params:[{
    chainId:CFG.chainId, chainName:CFG.chainName, rpcUrls:CFG.rpc,
    nativeCurrency:{name:"Ether",symbol:"ETH",decimals:18}, blockExplorerUrls:[CFG.explorer]}]});}}
  document.getElementById("connBtn").textContent = me.slice(0,6)+"..."+me.slice(-4);
  refresh();
  return me;
}
async function send(data, value){
  const from = await wallet();
  const tx = {from, to: CFG.deck, data};
  if(value) tx.value = "0x"+value.toString(16);
  // dry-run first: never let the wallet sign a doomed transaction
  const why = await preflight(tx);
  if(why && why.block){ log("the mine refused: " + why.block, "hot"); return; }
  if(why && why.warn){ log(why.warn); }
  log("confirm in wallet...");
  const h = await window.ethereum.request({method:"eth_sendTransaction",params:[tx]});
  const txLink = `<a target="_blank" rel="noopener noreferrer" href="${CFG.explorer}/tx/${h}">${h.slice(0,14)}...</a>`;
  log("sent " + txLink + " waiting...");
  for(let i=0;i<120;i++){
    await new Promise(r=>setTimeout(r,1500));
    const rec = await rpc("eth_getTransactionReceipt",[h]);
    if(rec){
      const okTx = rec.status === "0x1";
      log((okTx ? '<span class="ok">confirmed</span> ' : '<span class="hot">REVERTED</span> ') + txLink);
      refresh(); return;
    }
  }
}
async function ensureAllowance(need){
  const from = await wallet();
  const a = hexToBig(await call(CFG.pow, enc(SEL.allowance, from, CFG.deck)));
  if(a >= need) return;
  log("approving POW once...");
  const h = await window.ethereum.request({method:"eth_sendTransaction",params:[{
    from, to: CFG.pow, data: enc(SEL.approve, CFG.deck, (1n<<255n)) }]});
  for(let i=0;i<120;i++){ await new Promise(r=>setTimeout(r,1500));
    if(await rpc("eth_getTransactionReceipt",[h])) return; }
}
// -- what the terminal shows --
let heroDone=false;
async function heroArt(){
  if(heroDone) return;
  try{
    const uri = decStr(await call(CFG.deck,"0x"+SEL.contractURI));
    const img = JSON.parse(atob(uri.split(",")[1])).image;
    document.getElementById("heroArt").innerHTML =
      `<img src="${img}" alt="the mine"><span class="cap">collection banner - rendered by the chain just now</span>`;
    heroDone=true;
  }catch(e){}
}
async function refresh(){
  try{
    const s = words(await call(CFG.deck,"0x"+SEL.frontStats));
    const [rate,halv,ep,nextH,minted,gh,laps,emitted,vault] = s;
    document.getElementById("chainDot").className="ok";
    const supply = hexToBig(await call(CFG.pow,"0x"+SEL.totalSupply));
    const burned = 21000000n*10n**18n - supply;
    const eta = Number(nextH) - Math.floor(Date.now()/1000);
    const box=(l,v)=>`<div class="stat"><span>${l}</span><b>${v}</b></div>`;
    document.getElementById("stats").innerHTML =
      box("EMISSION / DAY", fmt(rate*86400n))+
      box("HALVING IN", eta>0? (Math.floor(eta/3600)+"h "+Math.floor(eta%3600/60)+"m") : "now")+
      box("HALVINGS DONE", halv)+
      box("RIGS", `${minted} / 2100`)+
      box("NETWORK", Number(gh).toLocaleString()+" GH")+
      box("LAPTOPS LIVE", laps)+
      box("MINED", fmt(emitted))+
      box("VAULT", fmt(vault))+
      box("BURNED", fmt(burned));
    const pct = Math.min(100, Math.max(0, 100 - eta/302400*100));
    document.getElementById("halvBar").style.width = pct.toFixed(1)+"%";
    const addrHtml =
      `deck <a target="_blank" rel="noopener noreferrer" href="${CFG.explorer}/address/${CFG.deck}">${CFG.deck}</a><br>pow <a target="_blank" rel="noopener noreferrer" href="${CFG.explorer}/address/${CFG.pow}">${CFG.pow}</a>`;
    document.getElementById("addrs").innerHTML = addrHtml;
    document.getElementById("addrs2").innerHTML = addrHtml;
    heroArt();
    if(me){ renderLaptop(); renderRigs(); }
  }catch(e){ log("read failed: "+e.message,"hot"); }
}
async function renderLaptop(){
  const el = document.getElementById("lap");
  const id = hexToBig(await call(CFG.deck, enc(SEL.laptopOf, me)));
  if(id===0n){ el.innerHTML=`<button onclick="act('mintLaptop')">MINT LAPTOP - FREE</button>
    <span class="dim" style="margin-left:10px">one live laptop per wallet - it gets its own room too</span>`; return; }
  const live = hexToBig(await call(CFG.deck, enc(SEL.isLaptopLive, id)))===1n;
  const pend = hexToBig(await call(CFG.deck, enc(SEL.pendingLaptop, id)));
  const img = await tokenImage(id);
  el.innerHTML = `${img?`<img src="${img}" alt="laptop room">`:""}
    <div><b>LAPTOP 0x${id.toString(16)}</b> - <span class="${live?"ok":"hot"}">${live?"LIVE":"OVERHEATED"}</span>
    <span class="dim">pending ${fmt(pend,4)} POW</span></div>
    <div class="row">
      ${live?`<button onclick="actU('claimLaptop',${id})">CLAIM CRUMBS</button>`:""}
      <button class="w" onclick="act('reboot')">REBOOT (burn + fresh mint)</button>
      <span class="dim">reboot burns this id and mints a NEW one - the number changes, pending resets</span>
    </div><div style="clear:both"></div>`;
}
async function renderRigs(){
  const el = document.getElementById("rigs");
  const ids = decArr(await call(CFG.deck, enc(SEL.rigsOf, me)));
  if(ids.length===0){ el.innerHTML=`<span class="dim">no rigs yet - mint above</span>`; return; }
  let html="";
  for(const id of ids){
    const info = words(await call(CFG.deck, enc(SEL.rigInfo, id)));
    const pend = hexToBig(await call(CFG.deck, enc(SEL.pendingRig, id)));
    const ep = hexToBig(await call(CFG.deck,"0x"+SEL.currentEpoch));
    const slots=Number(info[1]), boosted = info[2]>ep, gen=info[3];
    const img = await tokenImage(id);
    html += `<div class="card">${img?`<img src="${img}" alt="rig room">`:""}
      <div><b>RIG 0x${Number(id).toString(16).padStart(4,"0")}</b>
      <span class="dim">- ${100*(1+slots)}${boosted?"x1.5":""} GH - slots ${slots}/6 ${boosted?'- <span class="hot">BOOSTED</span>':""}</span></div>
      <div class="dim">pending ${fmt(pend,3)} POW ${gen===0n?'- <span class="hot">GENOME SEALED - room wakes on reveal</span>':""}</div>
      <div class="row">
        <button onclick="actArr('claimRigs',[${id}])">CLAIM</button>
        ${gen===0n?`<button onclick="actArr('reveal',[${id}])">REVEAL</button>`:""}
        ${slots<6?`<button onclick="sink('buySlot',${id},1500n*10n**18n)">SLOT +100GH (1500 POW)</button>`:""}
        ${!boosted?`<button class="w" onclick="sink('boost',${id},193n*10n**18n)">BOOST +50% 12-24H (193 POW)</button>`:""}
      </div><div style="clear:both"></div></div>`;
  }
  el.innerHTML = html;
}
// -- what a hooded can do --
async function mintRig(){
  const n = BigInt(document.getElementById("mintN").value||"1");
  await send(enc(SEL.mintRig, n), CFG.rigPrice*n);
}
// -- every laptop this wallet owns, straight from the Transfer logs --
let lapSel = new Set();
async function scanMine(){
  const from = await wallet();
  log("scanning your laptops...");
  const el = document.getElementById("lapList");
  const TRANSFER = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
  let ids = [];
  try{
    const logs = await rpc("eth_getLogs", [{address: CFG.deck, fromBlock: "0x0", toBlock: "latest",
      topics: [TRANSFER, null, "0x" + P(from)]}]);
    ids = [...new Set(logs.map(l => BigInt(l.topics[3])))].filter(i => i > 100000n);
  }catch(e){ log("log scan failed: " + e.message, "hot"); return; }
  const mineNow = [];
  for(const id of ids){
    try{
      const o = BigInt(await call(CFG.deck, enc(SEL.ownerOf, id)));
      if(o === BigInt(from)) mineNow.push(id);
    }catch(e){} // burned/swept ids drop out here
  }
  if(mineNow.length === 0){ el.innerHTML = `<span class="dim">no laptops on this wallet - mint one above</span>`;
    updateBurn(); log("scan done"); return; }
  let html = "";
  for(const id of mineNow.slice(0, 30)){
    const live = hexToBig(await call(CFG.deck, enc(SEL.isLaptopLive, id))) === 1n;
    const img = await tokenImage(id);
    html += `<span class="lapchip ${live?"":"dead"} ${lapSel.has(id.toString())?"sel":""}" data-id="${id}" data-live="${live?1:0}" onclick="toggleLap(this)">
      ${img?`<img src="${img}" alt="">`:""}
      <span><b>0x${id.toString(16)}</b><br><span class="st ${live?"ok":"hot"}">${live?"LIVE":"OVERHEATED"}</span></span></span>`;
  }
  el.innerHTML = html + (mineNow.length>30?`<div class="dim">…and ${mineNow.length-30} more</div>`:"");
  updateBurn(); log("scan done: " + mineNow.length + " laptop(s)");
}
function toggleLap(chip){
  if(chip.dataset.live !== "1"){ log("overheated laptops cannot pass the gate - sweep them instead","hot"); return; }
  const id = chip.dataset.id;
  if(lapSel.has(id)) lapSel.delete(id);
  else { if(lapSel.size >= 3){ log("the gate takes exactly three","hot"); return; } lapSel.add(id); }
  chip.classList.toggle("sel");
  updateBurn();
}
function updateBurn(){
  const n = lapSel.size;
  document.getElementById("burnInfo").textContent = n + " / 3 selected";
  document.getElementById("burnBtn").disabled = n !== 3;
}
async function burnGate(){
  if(lapSel.size !== 3){ log("select exactly 3 LIVE laptops above","hot"); return; }
  const ids = [...lapSel].map(v => BigInt(v));
  await send(encArr(SEL.mintRigBurning, ids), CFG.rigPrice);
  lapSel.clear(); scanMine();
}
const act = async (f)=>send("0x"+SEL[f]);
const actU = async (f,id)=>send(enc(SEL[f], id));
const actArr = async (f,ids)=>send(encArr(SEL[f], ids));
async function sink(f,id,price){ await ensureAllowance(price); await send(enc(SEL[f], id)); }
let sweepIds=[];
async function sweepScan(){
  log("scanning laptops...");
  const next = hexToBig(await call(CFG.deck,"0x"+SEL.nextLap));
  sweepIds=[];
  for(let id=100001n; id<=next && sweepIds.length<200; id++){
    try{
      const live = hexToBig(await call(CFG.deck, enc(SEL.isLaptopLive, id)));
      if(live===0n){
        const exp = hexToBig(await call(CFG.deck, enc(SEL.lapExp, id)));
        if(exp!==0n) sweepIds.push(id); // existed, not yet swept, overheated
      }
    }catch(e){}
  }
  document.getElementById("sweepInfo").textContent = sweepIds.length+" husks found";
  document.getElementById("sweepBtn").disabled = sweepIds.length===0;
  log("scan done");
}
async function sweepGo(){ if(sweepIds.length) await actArr("sweep", sweepIds); }
// -- wake the terminal --
showPage();
// -- market doors: the token and the collection, one click away --
document.getElementById("lnkDex").href = "https://dexscreener.com/" + CFG.dexSlug + "/" + CFG.pow;
document.getElementById("lnkOs").href = "https://opensea.io/collection/" + CFG.openseaSlug;
refresh(); setInterval(refresh, 30000);
if(window.ethereum){
  // silent reconnect: eth_accounts never pops the wallet, it just remembers
  window.ethereum.request({method:"eth_accounts"}).then(acc=>{
    if(acc && acc[0]){ me = acc[0];
      document.getElementById("connBtn").textContent = me.slice(0,6)+"..."+me.slice(-4);
      refresh(); }
  }).catch(()=>{});
  if(window.ethereum.on){
    window.ethereum.on("accountsChanged", acc=>{
      me = (acc && acc[0]) || null;
      document.getElementById("connBtn").textContent = me ? me.slice(0,6)+"..."+me.slice(-4) : "CONNECT";
      lapSel.clear(); refresh();
    });
  }
}
</script>
</body></html>
