DIY — Hacker Blog Landing
A brutalist landing page for SOLDER & SMOKE, a fictional hardware-hacking blog. Pure black canvas, bone-white slab headlines and a single acid-green accent drive a dense reverse-chronological article river, a duotone featured teardown, and a sticky sidebar holding a project of the day, a live contest countdown, a weighted tag cloud and a most-commented list. Hover inverts each card to acid on black, a top progress bar tracks reading depth, and a load-more button appends staggered batches until the archive runs out.
MCP
Code
:root{
--black:#0b0b0b;
--black-2:#141414;
--black-3:#1c1c1c;
--bone:#f5f2eb;
--bone-dim:#b9b4a9;
--bone-faint:#7a766e;
--acid:#9dff3d;
--acid-d:#7fd42c;
--amber:#ffb300;
--danger:#ff4d3d;
--line:#f5f2eb;
--line-soft:#3a3a37;
--bw:2px;
--maxw:1240px;
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
margin:0;
background:var(--black);
color:var(--bone);
font-family:Inter,system-ui,-apple-system,"Segoe UI",sans-serif;
line-height:1.5;
-webkit-font-smoothing:antialiased;
text-rendering:optimizeLegibility;
background-image:
repeating-linear-gradient(0deg,rgba(245,242,235,.028) 0 1px,transparent 1px 3px);
}
img,svg{max-width:100%}
h1,h2,h3{margin:0;line-height:1.03;letter-spacing:-.015em}
p{margin:0}
a{color:var(--acid);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
.mono{font-family:"JetBrains Mono",ui-monospace,Menlo,Consolas,monospace}
:focus-visible{outline:3px solid var(--acid);outline-offset:2px}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 20px}
.skip{position:absolute;left:-9999px;top:0;z-index:60;background:var(--acid);color:#0b0b0b;
padding:10px 16px;font-weight:800;letter-spacing:.08em}
.skip:focus{left:8px;top:8px}
/* ---------- progress ---------- */
.progress{position:fixed;top:0;left:0;right:0;height:5px;background:#000;z-index:50;
border-bottom:1px solid var(--line-soft)}
.progress__bar{height:100%;width:0;background:var(--acid);transition:width .08s linear}
/* ---------- masthead ---------- */
.masthead{position:sticky;top:5px;z-index:40;background:var(--black);
border-bottom:var(--bw) solid var(--line)}
.masthead__inner{display:flex;flex-wrap:wrap;align-items:center;gap:16px;padding-top:16px;padding-bottom:0}
.brand{display:flex;align-items:center;gap:14px;color:var(--bone);text-decoration:none;padding-bottom:14px}
.brand:hover{text-decoration:none}
.brand__mark{width:52px;height:52px;flex:none;color:var(--acid);
border:var(--bw) solid var(--acid);padding:3px;background:#000}
.brand:hover .brand__mark{background:var(--acid);color:#000}
.brand__name{display:block;font-size:clamp(28px,5vw,42px);font-weight:800;letter-spacing:-.04em;
text-transform:uppercase;line-height:.92}
.brand__name em{font-style:normal;color:var(--acid);padding:0 2px}
.brand__tag{display:block;font-family:"JetBrains Mono",monospace;font-size:11px;
color:var(--bone-faint);letter-spacing:.1em;text-transform:uppercase;margin-top:4px}
.navtoggle{display:none;margin-left:auto;border:var(--bw) solid var(--line);padding:8px 14px;
font-weight:700;letter-spacing:.12em;font-size:13px}
.navtoggle[aria-expanded="true"]{background:var(--acid);color:#000;border-color:var(--acid)}
.navbar{display:flex;flex-wrap:wrap;gap:0;width:100%;border-top:var(--bw) solid var(--line)}
.navbar a{display:block;padding:12px 16px;color:var(--bone);font-weight:700;font-size:13px;
letter-spacing:.13em;text-transform:uppercase;border-right:var(--bw) solid var(--line-soft)}
.navbar a:first-child{padding-left:0}
.navbar a:hover{background:var(--acid);color:#000;text-decoration:none}
.navbar a.is-current{color:var(--acid)}
.navbar a.is-current:hover{color:#000}
.navbar .nav-hot{margin-left:auto;border-right:0;color:var(--amber)}
.navbar .nav-hot:hover{background:var(--amber);color:#000}
/* ---------- layout ---------- */
.layout{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:0 34px;
padding-top:34px;padding-bottom:60px;align-items:start}
.col-side{border-left:var(--bw) solid var(--line-soft);padding-left:24px;
position:sticky;top:96px}
/* ---------- feature ---------- */
.feature{border:var(--bw) solid var(--line);background:var(--black-2)}
.feature__art{position:relative;border-bottom:var(--bw) solid var(--line);overflow:hidden}
.duotone{color:var(--acid);background:
linear-gradient(135deg,#0b0b0b 0%,#132a05 55%,#1f4a06 100%);
position:relative;display:block;height:clamp(180px,26vw,300px)}
.duotone svg{display:block;width:100%;height:100%;opacity:.9;
filter:drop-shadow(3px 3px 0 rgba(0,0,0,.6))}
.duo-scan{position:absolute;inset:0;pointer-events:none;
background:repeating-linear-gradient(0deg,rgba(0,0,0,.55) 0 2px,transparent 2px 5px);
mix-blend-mode:multiply}
.feature__stamp{position:absolute;left:0;top:0;background:var(--amber);color:#000;
font-family:"JetBrains Mono",monospace;font-weight:700;font-size:11px;letter-spacing:.2em;
padding:6px 12px;border-right:var(--bw) solid #000;border-bottom:var(--bw) solid #000}
.feature__body{padding:26px 26px 30px}
.kicker{font-family:"JetBrains Mono",monospace;font-size:11px;letter-spacing:.22em;
color:var(--amber);text-transform:uppercase;margin-bottom:12px}
.feature__title{font-size:clamp(30px,4.6vw,52px);font-weight:800;text-transform:uppercase;
letter-spacing:-.035em;margin-bottom:14px}
.dek{color:var(--bone-dim);font-size:16px;max-width:62ch;margin-bottom:16px}
.byline{font-family:"JetBrains Mono",monospace;font-size:12px;letter-spacing:.1em;
color:var(--bone-faint);text-transform:uppercase}
.byline__who{color:var(--acid)}
/* ---------- rule ---------- */
.rule{display:flex;align-items:center;gap:14px;margin:36px 0 20px;
color:var(--acid);font-family:"JetBrains Mono",monospace;font-size:12px;letter-spacing:.24em}
.rule::before,.rule::after{content:"";height:var(--bw);background:var(--acid);flex:1}
.rule::before{flex:0 0 30px}
/* ---------- river ---------- */
.river{display:grid;grid-template-columns:1fr 1fr;gap:0;
border-top:var(--bw) solid var(--line);border-left:var(--bw) solid var(--line)}
.post{display:flex;gap:14px;padding:16px;
border-right:var(--bw) solid var(--line);border-bottom:var(--bw) solid var(--line);
background:var(--black);transition:background .12s linear,color .12s linear}
.post:hover,.post:focus-visible{background:var(--acid);color:#000;outline-offset:-3px}
.post:hover .post__dek,.post:focus-visible .post__dek,
.post:hover .post__meta,.post:focus-visible .post__meta{color:#123000}
.post:hover .tag,.post:focus-visible .tag{background:#000;color:var(--acid);border-color:#000}
.post:hover .post__thumb,.post:focus-visible .post__thumb{border-color:#000;color:#000;
background-color:rgba(0,0,0,.12)}
.post__thumb{flex:none;width:88px;height:88px;border:var(--bw) solid var(--line-soft);
color:var(--acid);background-color:#000;background-size:10px 10px}
.post__body{min-width:0}
.tag{display:inline-block;font-family:"JetBrains Mono",monospace;font-size:10px;font-weight:700;
letter-spacing:.16em;padding:3px 7px;border:1px solid var(--acid);color:var(--acid);
margin-bottom:8px}
.post__title{font-size:19px;font-weight:800;text-transform:uppercase;letter-spacing:-.02em;
margin-bottom:7px}
.post__dek{font-size:13.5px;color:var(--bone-dim);margin-bottom:9px}
.post__meta{display:flex;flex-wrap:wrap;gap:8px;font-family:"JetBrains Mono",monospace;
font-size:11px;letter-spacing:.08em;color:var(--bone-faint);text-transform:uppercase}
/* thumbnails, all CSS-drawn */
.thumb--chip{background-image:
linear-gradient(90deg,currentColor 2px,transparent 2px),
linear-gradient(0deg,currentColor 2px,transparent 2px);
background-size:14px 14px;opacity:.95}
.thumb--wave{background-image:radial-gradient(circle at 50% 100%,transparent 26%,currentColor 27%,transparent 29%),
radial-gradient(circle at 50% 100%,transparent 46%,currentColor 47%,transparent 49%),
radial-gradient(circle at 50% 100%,transparent 66%,currentColor 67%,transparent 69%);
background-size:100% 100%}
.thumb--grid{background-image:repeating-linear-gradient(45deg,currentColor 0 2px,transparent 2px 9px)}
.thumb--scope{background-image:linear-gradient(currentColor 2px,transparent 2px),
linear-gradient(90deg,currentColor 2px,transparent 2px);
background-size:22px 22px;background-position:center}
.thumb--bot{background-image:radial-gradient(circle,currentColor 3px,transparent 4px);
background-size:16px 16px}
.thumb--solder{background-image:repeating-linear-gradient(-45deg,currentColor 0 4px,transparent 4px 12px)}
.thumb--power{background-image:linear-gradient(180deg,currentColor 0 6px,transparent 6px 16px)}
.thumb--pcb{background-image:linear-gradient(90deg,currentColor 0 3px,transparent 3px 11px),
linear-gradient(180deg,currentColor 0 3px,transparent 3px 26px)}
.thumb--laser{background-image:conic-gradient(from 0deg,currentColor 0 8deg,transparent 8deg 45deg)}
.thumb--audio{background-image:linear-gradient(90deg,currentColor 0 4px,transparent 4px 10px);
background-size:10px 100%;background-position:0 50%}
.thumb--net{background-image:repeating-linear-gradient(90deg,currentColor 0 1px,transparent 1px 8px),
repeating-linear-gradient(0deg,currentColor 0 1px,transparent 1px 8px)}
.thumb--key{background-image:linear-gradient(currentColor 2px,transparent 2px),
linear-gradient(90deg,currentColor 2px,transparent 2px);background-size:18px 26px}
/* stagger-in for appended posts */
.post--in{opacity:0;transform:translateY(14px)}
.post--in.is-on{opacity:1;transform:none;transition:opacity .3s ease,transform .3s ease}
/* ---------- load more ---------- */
.loadwrap{margin-top:28px;text-align:center}
.btn-load{display:inline-block;border:var(--bw) solid var(--acid);color:var(--acid);
background:#000;padding:15px 30px;font-weight:800;letter-spacing:.16em;text-transform:uppercase;
font-size:14px}
.btn-load:hover{background:var(--acid);color:#000}
.btn-load[disabled]{opacity:.45;cursor:not-allowed;border-color:var(--line-soft);color:var(--bone-faint);background:#000}
.btn-load.is-busy{color:var(--amber);border-color:var(--amber)}
.loadwrap__note{margin-top:12px;font-size:11px;letter-spacing:.1em;color:var(--bone-faint);
text-transform:uppercase}
/* ---------- sidebar panels ---------- */
.panel{border:var(--bw) solid var(--line);padding:16px;margin-bottom:22px;background:var(--black-2)}
.panel__head{font-size:13px;font-weight:800;letter-spacing:.18em;text-transform:uppercase;
background:var(--bone);color:#000;margin:-16px -16px 14px;padding:8px 12px}
.panel--contest .panel__head{background:var(--amber)}
.panel--potd .panel__head{background:var(--acid)}
.potd__art{border:var(--bw) solid var(--line-soft);color:var(--acid);background:#000;padding:8px;margin-bottom:12px}
.potd__art svg{display:block;width:100%;height:auto}
.potd__title{font-size:16px;font-weight:800;text-transform:uppercase;margin-bottom:8px}
.potd__dek{font-size:13px;color:var(--bone-dim);margin-bottom:10px}
.potd__meta{font-size:11px;letter-spacing:.1em;color:var(--bone-faint);margin-bottom:12px}
.potd__meta b{color:var(--bone)}
.btn-ghost,.btn-amber{display:block;width:100%;text-align:center;padding:11px;font-weight:800;
letter-spacing:.14em;font-size:12.5px;text-transform:uppercase;border:var(--bw) solid var(--acid);
color:var(--acid);background:#000}
.btn-ghost:hover{background:var(--acid);color:#000}
.btn-ghost.is-on{background:var(--acid);color:#000}
.btn-amber{border-color:var(--amber);color:#000;background:var(--amber)}
.btn-amber:hover{background:#000;color:var(--amber)}
.contest__name{font-size:22px;font-weight:800;text-transform:uppercase;letter-spacing:-.02em;
line-height:1.05;margin-bottom:8px}
.contest__dek{font-size:13px;color:var(--bone-dim);margin-bottom:14px}
.contest__label{font-size:10.5px;letter-spacing:.2em;color:var(--amber);margin-bottom:8px}
.countdown{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin-bottom:12px}
.cd{border:var(--bw) solid var(--line-soft);background:#000;text-align:center;padding:8px 2px}
.cd b{display:block;font-family:"JetBrains Mono",monospace;font-size:22px;font-weight:700;
color:var(--amber);font-variant-numeric:tabular-nums}
.cd i{display:block;font-family:"JetBrains Mono",monospace;font-style:normal;font-size:9px;
letter-spacing:.14em;color:var(--bone-faint);margin-top:2px}
.contest__entries{font-size:11px;letter-spacing:.12em;color:var(--bone-faint);margin-bottom:12px}
.contest__entries span{color:var(--bone)}
.cloud{display:flex;flex-wrap:wrap;gap:7px}
.cl{font-family:"JetBrains Mono",monospace;border:1px solid var(--line-soft);padding:3px 8px;
color:var(--bone-dim);line-height:1.3}
.cl:hover{border-color:var(--acid);color:var(--acid)}
.cl.is-on{background:var(--acid);border-color:var(--acid);color:#000}
.cl--1{font-size:11px}
.cl--2{font-size:13px}
.cl--3{font-size:15px;color:var(--bone)}
.cl--4{font-size:18px;color:var(--bone);font-weight:600}
.cl--5{font-size:22px;color:var(--acid);font-weight:700}
.mostcom{list-style:none;margin:0;padding:0;counter-reset:mc}
.mostcom li{display:flex;gap:10px;align-items:baseline;padding:9px 0;
border-bottom:1px solid var(--line-soft)}
.mostcom li:last-child{border-bottom:0}
.mostcom .num{color:var(--acid);font-size:12px;flex:none}
.mostcom a{display:block;color:var(--bone);font-weight:600;font-size:14px;line-height:1.28}
.mostcom a:hover{color:var(--acid)}
.mostcom a b{display:block;font-weight:700;font-size:11px;color:var(--bone-faint);
letter-spacing:.12em;margin-top:3px}
/* ---------- footer ---------- */
.foot{border-top:var(--bw) solid var(--line);background:#000;padding:22px 0}
.foot__inner{display:flex;flex-wrap:wrap;gap:12px;justify-content:space-between;
font-size:11px;letter-spacing:.1em;color:var(--bone-faint);text-transform:uppercase}
/* ---------- toast ---------- */
.toast{position:fixed;left:50%;bottom:24px;transform:translate(-50%,20px);
background:var(--acid);color:#000;border:var(--bw) solid #000;
font-family:"JetBrains Mono",monospace;font-weight:700;font-size:12px;letter-spacing:.12em;
text-transform:uppercase;padding:11px 18px;opacity:0;pointer-events:none;z-index:70;
transition:opacity .18s ease,transform .18s ease;max-width:90vw;text-align:center}
.toast.is-on{opacity:1;transform:translate(-50%,0)}
/* ---------- responsive ---------- */
@media (max-width:1040px){
.layout{grid-template-columns:1fr}
.col-side{border-left:0;padding-left:0;position:static;margin-top:36px;
border-top:var(--bw) solid var(--line);padding-top:26px}
}
@media (max-width:760px){
.river{grid-template-columns:1fr}
}
@media (max-width:520px){
.wrap{padding:0 14px}
.masthead{position:static}
.brand__mark{width:42px;height:42px}
.brand__name{font-size:28px}
.navtoggle{display:block}
.navbar{display:none;flex-direction:column}
.navbar.is-open{display:flex}
.navbar a{border-right:0;border-bottom:var(--bw) solid var(--line-soft);padding-left:0}
.navbar .nav-hot{margin-left:0}
.feature__body{padding:18px 16px 22px}
.post{flex-direction:column}
.post__thumb{width:100%;height:64px}
.countdown{grid-template-columns:repeat(2,1fr)}
.btn-load{width:100%;padding:14px 10px;font-size:12.5px}
.foot__inner{flex-direction:column}
}
@media (prefers-reduced-motion:reduce){
*{animation:none!important;transition:none!important}
}(function () {
"use strict";
/* ---------- toast ---------- */
var toastEl = document.getElementById("toast");
var toastTimer = null;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("is-on");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("is-on");
}, 2200);
}
/* ---------- reading progress ---------- */
var bar = document.getElementById("progressBar");
var progressBox = bar ? bar.parentElement : null;
var ticking = false;
function updateProgress() {
var doc = document.documentElement;
var max = doc.scrollHeight - window.innerHeight;
var pct = max > 0 ? Math.min(100, Math.max(0, (window.scrollY / max) * 100)) : 0;
if (bar) bar.style.width = pct.toFixed(2) + "%";
if (progressBox) progressBox.setAttribute("aria-valuenow", Math.round(pct));
ticking = false;
}
window.addEventListener(
"scroll",
function () {
if (!ticking) {
ticking = true;
window.requestAnimationFrame(updateProgress);
}
},
{ passive: true }
);
window.addEventListener("resize", updateProgress);
updateProgress();
/* ---------- mobile nav ---------- */
var navToggle = document.getElementById("navToggle");
var navbar = document.getElementById("navbar");
if (navToggle && navbar) {
navToggle.addEventListener("click", function () {
var open = navbar.classList.toggle("is-open");
navToggle.setAttribute("aria-expanded", String(open));
navToggle.textContent = open ? "CLOSE" : "MENU";
});
navbar.addEventListener("click", function (e) {
if (e.target.tagName === "A" && navbar.classList.contains("is-open")) {
navbar.classList.remove("is-open");
navToggle.setAttribute("aria-expanded", "false");
navToggle.textContent = "MENU";
}
});
}
/* nav current state */
Array.prototype.forEach.call(navbar ? navbar.querySelectorAll("a") : [], function (a) {
a.addEventListener("click", function () {
Array.prototype.forEach.call(navbar.querySelectorAll("a"), function (x) {
x.classList.remove("is-current");
x.removeAttribute("aria-current");
});
a.classList.add("is-current");
a.setAttribute("aria-current", "page");
});
});
/* ---------- countdown ---------- */
var deadline = new Date();
deadline.setDate(deadline.getDate() + 9);
deadline.setHours(23, 59, 0, 0);
var pads = {
d: document.getElementById("cdD"),
h: document.getElementById("cdH"),
m: document.getElementById("cdM"),
s: document.getElementById("cdS")
};
function pad2(n) {
return (n < 10 ? "0" : "") + n;
}
function tick() {
var diff = Math.max(0, deadline.getTime() - Date.now());
var s = Math.floor(diff / 1000);
var d = Math.floor(s / 86400);
var h = Math.floor((s % 86400) / 3600);
var m = Math.floor((s % 3600) / 60);
var sec = s % 60;
if (pads.d) pads.d.textContent = pad2(d);
if (pads.h) pads.h.textContent = pad2(h);
if (pads.m) pads.m.textContent = pad2(m);
if (pads.s) pads.s.textContent = pad2(sec);
}
tick();
setInterval(tick, 1000);
/* ---------- skull / upvote ---------- */
var skullBtn = document.querySelector(".js-skull");
if (skullBtn) {
skullBtn.addEventListener("click", function () {
var n = parseInt(skullBtn.getAttribute("data-count"), 10) || 0;
var on = skullBtn.classList.toggle("is-on");
n += on ? 1 : -1;
skullBtn.setAttribute("data-count", String(n));
skullBtn.textContent = on ? "SKULL GIVEN ✓" : "GIVE IT A SKULL";
var meta = document.querySelector(".potd__meta");
if (meta) meta.innerHTML = "BY <b>K. ABERNATHY</b> · " + n + " SKULLS";
toast(on ? "Skull registered — " + n + " total" : "Skull withdrawn");
});
}
/* ---------- contest enter ---------- */
var enterBtn = document.querySelector(".js-enter");
var entryCount = document.getElementById("entryCount");
if (enterBtn) {
enterBtn.addEventListener("click", function () {
if (enterBtn.disabled) return;
enterBtn.disabled = true;
enterBtn.textContent = "ENTRY LOGGED ✓";
if (entryCount) entryCount.textContent = "1,285";
toast("Entry #1285 logged — demo only");
});
}
/* ---------- tag cloud ---------- */
var cloud = document.getElementById("cloud");
if (cloud) {
cloud.addEventListener("click", function (e) {
var b = e.target.closest(".cl");
if (!b) return;
var on = b.classList.toggle("is-on");
var active = cloud.querySelectorAll(".cl.is-on").length;
toast(
(on ? "Filtering by #" : "Removed #") + b.textContent + " — " + active + " tag(s) active"
);
});
}
/* ---------- article river: load more ---------- */
var river = document.getElementById("river");
var loadBtn = document.getElementById("loadMore");
var loadCount = document.getElementById("loadCount");
var loadNote = document.getElementById("loadNote");
var TOTAL = 34;
var BATCHES = [
[
["NETWORKING", "thumb--net", "We Put A Whole Mesh Network In A Fire Extinguisher Cabinet", "Eleven nodes, solar buffered, LoRa backhaul. It has survived two winters and one very curious raccoon.", "NKECHI HARLOW", "1d", 74],
["KEYBOARDS", "thumb--key", "Hand-Wiring 68 Switches Taught Me To Hate Diode Orientation", "A full build log with the three mistakes everyone makes and the continuity test that catches all of them.", "TOMÁS RIEDEL", "1d", 96],
["REVERSE ENG", "thumb--chip", "The Undocumented Opcode That Unlocks A Discontinued Motor Driver", "Fuzzing the SPI register map for six hours turned a bricked drawer of chips into working stock.", "HANS DELACROIX", "2d", 143],
["CNC", "thumb--grid", "Cutting Aluminium On A Machine Designed For Foam", "Chip load, rigidity and a lot of coolant. Feeds and speeds table included, plus the parts that snapped.", "ISOBEL FRIEND", "2d", 39],
["SENSORS", "thumb--wave", "A Load Cell In A Doormat Knows Exactly Who Is Home", "Four strain gauges, one instrumentation amp, and a gait signature classifier that runs on a microcontroller.", "MARLA OKONKWO", "2d", 68],
["POWER", "thumb--power", "Building A Bench Supply That Refuses To Blow Up Your Prototype", "Programmable current limit with a hardware latch, because software foldback is always half a millisecond late.", "DEV OYELARAN", "3d", 112]
],
[
["LASERS", "thumb--laser", "Engraving Anodised Aluminium With A Diode That Should Not Manage It", "Focus stacking on the Z axis and a paint mask that turns 5 W into something surprisingly crisp.", "PRIYA VANTERPOOL", "3d", 47],
["RETROCOMPUTING", "thumb--scope", "Restoring A Terminal Whose Flyback Died In 1987", "Rewinding the transformer by hand, plus the safe discharge procedure we should all be following.", "TOMÁS RIEDEL", "3d", 85],
["AUDIO", "thumb--audio", "A Reverb Tank Made From A Radiator And Two Contact Mics", "Impulse responses measured, files released, and yes it does sound like a haunted plumbing system.", "NKECHI HARLOW", "4d", 52],
["SHOP TALK", "thumb--solder", "The Cheapest Fume Extractor That Actually Moves Air", "We tested six builds with an anemometer. The winner is a computer fan and a carbon filter, correctly ducted.", "HANS DELACROIX", "4d", 133],
["PCB DESIGN", "thumb--pcb", "Silkscreen Art That Survives The Fab House Design Rule Check", "Halftone dithering, minimum feature sizes, and the exact gerber layer stack that made ours print clean.", "ISOBEL FRIEND", "5d", 61],
["ROBOTS", "thumb--bot", "A Delta Arm That Sorts Resistors Faster Than You Can Read Them", "Machine vision on a colour band, 900 ms per part, and a hopper printed from the leftovers of another project.", "MARLA OKONKWO", "5d", 104]
]
];
var batchIndex = 0;
var shown = 10;
function buildPost(d) {
var art = document.createElement("article");
art.className = "post post--in";
art.tabIndex = 0;
art.innerHTML =
'<div class="post__thumb ' + d[1] + '" aria-hidden="true"></div>' +
'<div class="post__body">' +
'<span class="tag">' + d[0] + "</span>" +
'<h3 class="post__title">' + d[2] + "</h3>" +
'<p class="post__dek">' + d[3] + "</p>" +
'<p class="post__meta"><span>' + d[4] + "</span>" +
'<span class="mono">· ' + d[5] + " · " + d[6] + " COMMENTS</span></p>" +
"</div>";
return art;
}
function appendBatch() {
if (!river || batchIndex >= BATCHES.length) return;
var batch = BATCHES[batchIndex++];
var nodes = [];
batch.forEach(function (d) {
var el = buildPost(d);
river.appendChild(el);
nodes.push(el);
});
shown += batch.length;
nodes.forEach(function (el, i) {
setTimeout(function () {
el.classList.add("is-on");
}, 60 * i + 30);
});
if (loadCount) loadCount.textContent = "[" + shown + " / " + TOTAL + "]";
if (batchIndex >= BATCHES.length) {
loadBtn.disabled = true;
loadBtn.textContent = "THAT IS THE WHOLE ARCHIVE ";
loadBtn.appendChild(loadCount || document.createTextNode(""));
if (loadNote) loadNote.textContent = "End of the river. Go build something.";
toast("All " + shown + " posts loaded");
} else {
toast("+" + batch.length + " posts appended");
}
if (nodes[0]) nodes[0].focus({ preventScroll: true });
updateProgress();
}
if (loadBtn) {
loadBtn.addEventListener("click", function () {
if (loadBtn.disabled) return;
loadBtn.classList.add("is-busy");
var original = loadBtn.firstChild;
if (original && original.nodeType === 3) original.nodeValue = "FETCHING… ";
setTimeout(function () {
loadBtn.classList.remove("is-busy");
if (original && original.nodeType === 3 && batchIndex + 1 < BATCHES.length + 1) {
original.nodeValue = "LOAD MORE POSTS ";
}
appendBatch();
}, 420);
});
}
/* ---------- reveal existing posts on scroll ---------- */
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(
function (entries) {
entries.forEach(function (en) {
if (en.isIntersecting) {
en.target.classList.add("is-on");
io.unobserve(en.target);
}
});
},
{ rootMargin: "0px 0px -40px 0px" }
);
Array.prototype.forEach.call(document.querySelectorAll(".post--in"), function (el) {
io.observe(el);
});
}
/* ---------- posts are keyboard-activatable ---------- */
document.addEventListener("keydown", function (e) {
if ((e.key === "Enter" || e.key === " ") && e.target.classList && e.target.classList.contains("post")) {
e.preventDefault();
var t = e.target.querySelector(".post__title");
toast("Opening: " + (t ? t.textContent.slice(0, 44) : "post"));
}
});
if (river) {
river.addEventListener("click", function (e) {
var p = e.target.closest(".post");
if (!p) return;
var t = p.querySelector(".post__title");
toast("Opening: " + (t ? t.textContent.slice(0, 44) : "post"));
});
}
toast("SOLDER & SMOKE — front page loaded");
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SOLDER & SMOKE — hardware hacking, badly soldered</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="progress" role="progressbar" aria-label="Reading progress" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div class="progress__bar" id="progressBar"></div>
</div>
<a class="skip" href="#river">Skip to articles</a>
<header class="masthead">
<div class="wrap masthead__inner">
<a class="brand" href="#" aria-label="SOLDER and SMOKE, home">
<svg class="brand__mark" viewBox="0 0 64 64" role="img" aria-hidden="true" focusable="false">
<g fill="none" stroke="currentColor" stroke-width="3.4" stroke-linecap="square" stroke-linejoin="miter">
<path d="M20 12h24l6 10v14c0 8-6 12-10 14v8H24v-8c-4-2-10-6-10-14V22z"/>
<path d="M22 30h8M34 30h8"/>
<path d="M26 44h12"/>
<path d="M28 48v6M36 48v6"/>
</g>
<g fill="currentColor">
<rect x="23" y="26" width="6" height="6"/>
<rect x="35" y="26" width="6" height="6"/>
</g>
<path d="M6 54l10-6 4 6" fill="none" stroke="currentColor" stroke-width="3.4" stroke-linecap="square"/>
<path d="M58 54l-10-6-4 6" fill="none" stroke="currentColor" stroke-width="3.4" stroke-linecap="square"/>
</svg>
<span class="brand__text">
<span class="brand__name">SOLDER<em>&</em>SMOKE</span>
<span class="brand__tag">hardware hacking, badly soldered — since 2011</span>
</span>
</a>
<button class="navtoggle" id="navToggle" aria-expanded="false" aria-controls="navbar">MENU</button>
<nav class="navbar" id="navbar" aria-label="Primary">
<a href="#river" class="is-current" aria-current="page">FRONT PAGE</a>
<a href="#river">TEARDOWNS</a>
<a href="#river">RETRO</a>
<a href="#river">RF & RADIO</a>
<a href="#sidebar">CONTESTS</a>
<a href="#river">SHOP TALK</a>
<a href="#river" class="nav-hot">SUBMIT A TIP</a>
</nav>
</div>
</header>
<main class="wrap layout">
<div class="col-main">
<!-- FEATURED -->
<article class="feature" aria-labelledby="featTitle">
<div class="feature__art" aria-hidden="true">
<div class="duotone">
<span class="duo-scan"></span>
<svg viewBox="0 0 480 260" preserveAspectRatio="xMidYMid slice" role="presentation">
<g stroke="currentColor" fill="none" stroke-width="2">
<rect x="40" y="40" width="400" height="180"/>
<rect x="66" y="66" width="120" height="80"/>
<rect x="212" y="66" width="60" height="40"/>
<rect x="300" y="66" width="112" height="128"/>
<path d="M66 170h120M66 186h96M212 122h60M212 138h40M212 154h60"/>
<path d="M300 96h112M300 126h112M300 156h112"/>
<circle cx="126" cy="106" r="26"/>
<path d="M126 80v52M100 106h52"/>
</g>
<g fill="currentColor">
<rect x="216" y="70" width="8" height="8"/>
<rect x="232" y="70" width="8" height="8"/>
<rect x="248" y="70" width="8" height="8"/>
<rect x="70" y="196" width="46" height="10"/>
<rect x="126" y="196" width="24" height="10"/>
</g>
</svg>
</div>
<span class="feature__stamp">FRONT PAGE</span>
</div>
<div class="feature__body">
<p class="kicker">TEARDOWN / 40 MINUTES OF SMOKE</p>
<h1 class="feature__title" id="featTitle">We Cracked Open A $9 Thermal Camera And Found A Whole Linux Box Inside</h1>
<p class="dek">The bill of materials says toy. The bootlog says otherwise: a 400 MHz SoC, 32 MB of DRAM and a UART header nobody bothered to depopulate. Two hours with a logic analyser and a bent paperclip got us a root shell — here is the whole map, pad by pad.</p>
<p class="byline"><span class="byline__who">MARLA OKONKWO</span> · 12 HOURS AGO · <span class="mono">36 COMMENTS</span></p>
</div>
</article>
<div class="rule" role="separator" aria-hidden="true"><span>LATEST FROM THE BENCH</span></div>
<!-- ARTICLE RIVER -->
<section class="river" id="river" aria-label="Latest articles">
<article class="post" tabindex="0">
<div class="post__thumb thumb--chip" aria-hidden="true"></div>
<div class="post__body">
<span class="tag">RETROCOMPUTING</span>
<h3 class="post__title">A Z80 Laptop That Boots In 40 Milliseconds And Runs For A Week</h3>
<p class="post__dek">No BIOS, no init, no excuses. Just a masked ROM, a 4 MHz clock and an e-paper panel driven straight off the bus.</p>
<p class="post__meta"><span>DEV OYELARAN</span><span class="mono">· 4h · 61 COMMENTS</span></p>
</div>
</article>
<article class="post" tabindex="0">
<div class="post__thumb thumb--wave" aria-hidden="true"></div>
<div class="post__body">
<span class="tag">RF & RADIO</span>
<h3 class="post__title">Bouncing Packets Off The Moon With A Rooftop Yagi And Too Much Patience</h3>
<p class="post__dek">2.4 seconds of round trip, 12 dB of path loss you cannot argue with, and a homebrew LNA in a biscuit tin.</p>
<p class="post__meta"><span>PRIYA VANTERPOOL</span><span class="mono">· 7h · 44 COMMENTS</span></p>
</div>
</article>
<article class="post" tabindex="0">
<div class="post__thumb thumb--grid" aria-hidden="true"></div>
<div class="post__body">
<span class="tag">3D PRINTING</span>
<h3 class="post__title">Printing In Ceramic Slip On A Machine That Cost Less Than The Kiln</h3>
<p class="post__dek">A syringe pump, a stepper, and a firmware fork that finally stops treating extrusion as a temperature problem.</p>
<p class="post__meta"><span>ISOBEL FRIEND</span><span class="mono">· 9h · 18 COMMENTS</span></p>
</div>
</article>
<article class="post" tabindex="0">
<div class="post__thumb thumb--scope" aria-hidden="true"></div>
<div class="post__body">
<span class="tag">TEST GEAR</span>
<h3 class="post__title">Your $30 Logic Analyser Is Lying About Its Sample Rate — Here Is The Proof</h3>
<p class="post__dek">We fed eight clones a known 24 MHz square wave. Only two survived the first division. Full trace dumps inside.</p>
<p class="post__meta"><span>HANS DELACROIX</span><span class="mono">· 11h · 129 COMMENTS</span></p>
</div>
</article>
<article class="post" tabindex="0">
<div class="post__thumb thumb--bot" aria-hidden="true"></div>
<div class="post__body">
<span class="tag">ROBOTS</span>
<h3 class="post__title">This Walking Table Uses Zero Microcontrollers And One Very Angry Cam</h3>
<p class="post__dek">Pure mechanical gait sequencing, cut on a hand router from 12 mm ply. It walks. Slowly. It walks.</p>
<p class="post__meta"><span>TOMÁS RIEDEL</span><span class="mono">· 14h · 27 COMMENTS</span></p>
</div>
</article>
<article class="post" tabindex="0">
<div class="post__thumb thumb--solder" aria-hidden="true"></div>
<div class="post__body">
<span class="tag">SHOP TALK</span>
<h3 class="post__title">Stop Buying Flux Pens: Rosin, Alcohol And A Jam Jar Do It Better</h3>
<p class="post__dek">We measured wetting time across nine mixtures. The cheapest one won, and it does not eat your soldermask.</p>
<p class="post__meta"><span>MARLA OKONKWO</span><span class="mono">· 16h · 88 COMMENTS</span></p>
</div>
</article>
<article class="post" tabindex="0">
<div class="post__thumb thumb--power" aria-hidden="true"></div>
<div class="post__body">
<span class="tag">POWER</span>
<h3 class="post__title">Reviving Eleven Dead Laptop Cells With A Bench Supply And A Fire Blanket</h3>
<p class="post__dek">Six came back. Three stayed dead. Two vented. We logged every millivolt so you do not have to repeat it.</p>
<p class="post__meta"><span>NKECHI HARLOW</span><span class="mono">· 19h · 152 COMMENTS</span></p>
</div>
</article>
<article class="post" tabindex="0">
<div class="post__thumb thumb--pcb" aria-hidden="true"></div>
<div class="post__body">
<span class="tag">PCB DESIGN</span>
<h3 class="post__title">Four-Layer Boards For The Price Of Two If You Panelise Like A Goblin</h3>
<p class="post__dek">Mouse bites, shared rails and a tab layout that fabs will actually accept without an engineering query.</p>
<p class="post__meta"><span>DEV OYELARAN</span><span class="mono">· 21h · 33 COMMENTS</span></p>
</div>
</article>
<article class="post" tabindex="0">
<div class="post__thumb thumb--laser" aria-hidden="true"></div>
<div class="post__body">
<span class="tag">LASERS</span>
<h3 class="post__title">A Galvo Scanner Built From Two Hard Drive Voice Coils</h3>
<p class="post__dek">Bandwidth is terrible, linearity is worse, and the projected Lissajous figures are gorgeous anyway.</p>
<p class="post__meta"><span>ISOBEL FRIEND</span><span class="mono">· 1d · 21 COMMENTS</span></p>
</div>
</article>
<article class="post" tabindex="0">
<div class="post__thumb thumb--audio" aria-hidden="true"></div>
<div class="post__body">
<span class="tag">AUDIO</span>
<h3 class="post__title">Sampling A Cassette Deck At 192 kHz Just To Hear The Motor Whine</h3>
<p class="post__dek">Wow and flutter turned into a control signal. The tape becomes the LFO. Schematics and firmware included.</p>
<p class="post__meta"><span>PRIYA VANTERPOOL</span><span class="mono">· 1d · 57 COMMENTS</span></p>
</div>
</article>
</section>
<div class="loadwrap">
<button class="btn-load" id="loadMore" aria-controls="river">LOAD MORE POSTS <span class="mono" id="loadCount">[10 / 34]</span></button>
<p class="loadwrap__note mono" id="loadNote">Scroll depth logged locally. No trackers, no cookies, no newsletter modal.</p>
</div>
</div>
<!-- SIDEBAR -->
<aside class="col-side" id="sidebar" aria-label="Sidebar">
<section class="panel panel--potd">
<h2 class="panel__head">PROJECT OF THE DAY</h2>
<div class="potd__art" aria-hidden="true">
<svg viewBox="0 0 240 130" role="presentation">
<g stroke="currentColor" fill="none" stroke-width="2">
<rect x="18" y="20" width="204" height="90"/>
<path d="M18 44h204M60 20v90M60 68h162"/>
<circle cx="39" cy="86" r="14"/>
<path d="M96 56l24 24 26-34 30 40"/>
</g>
<g fill="currentColor"><rect x="150" y="28" width="10" height="10"/><rect x="168" y="28" width="10" height="10"/><rect x="186" y="28" width="10" height="10"/></g>
</svg>
</div>
<h3 class="potd__title">GEIGER-COUNTER WEATHER STATION, SOLAR, NO NETWORK</h3>
<p class="potd__dek">Stores 18 months of counts on a single FRAM chip and dumps them over IR when you point a TV remote at it.</p>
<p class="mono potd__meta">BY <b>K. ABERNATHY</b> · 412 SKULLS</p>
<button class="btn-ghost js-skull" data-count="412">GIVE IT A SKULL</button>
</section>
<section class="panel panel--contest">
<h2 class="panel__head">RUNNING CONTEST</h2>
<p class="contest__name">THE ONE-CHIP CHALLENGE</p>
<p class="contest__dek">Build anything. One active component. Show the schematic or it did not happen. $2,000 in bench gear across three prizes.</p>
<p class="mono contest__label">ENTRIES CLOSE IN</p>
<div class="countdown" id="countdown" role="timer" aria-live="off">
<div class="cd"><b id="cdD">00</b><i>DAYS</i></div>
<div class="cd"><b id="cdH">00</b><i>HRS</i></div>
<div class="cd"><b id="cdM">00</b><i>MIN</i></div>
<div class="cd"><b id="cdS">00</b><i>SEC</i></div>
</div>
<p class="mono contest__entries"><span id="entryCount">1,284</span> ENTRIES LOGGED</p>
<button class="btn-amber js-enter">ENTER THE CONTEST</button>
</section>
<section class="panel">
<h2 class="panel__head">TAG CLOUD</h2>
<div class="cloud" id="cloud">
<button class="cl cl--5">soldering</button>
<button class="cl cl--3">esp32</button>
<button class="cl cl--4">teardown</button>
<button class="cl cl--2">cnc</button>
<button class="cl cl--5">retro</button>
<button class="cl cl--1">plotter</button>
<button class="cl cl--3">fpga</button>
<button class="cl cl--4">radio</button>
<button class="cl cl--2">nixie</button>
<button class="cl cl--3">3d-printing</button>
<button class="cl cl--1">pcb-art</button>
<button class="cl cl--4">reverse-eng</button>
<button class="cl cl--2">lasers</button>
<button class="cl cl--3">batteries</button>
<button class="cl cl--1">keyboards</button>
</div>
</section>
<section class="panel">
<h2 class="panel__head">MOST COMMENTED / 7 DAYS</h2>
<ol class="mostcom">
<li><span class="mono num">01</span><a href="#river">Everyone Is Wrong About Decoupling Caps<b class="mono">311</b></a></li>
<li><span class="mono num">02</span><a href="#river">I Ran My Whole Shop Off A Car Battery For A Month<b class="mono">264</b></a></li>
<li><span class="mono num">03</span><a href="#river">Lead-Free Solder Is Fine, Your Iron Is Not<b class="mono">240</b></a></li>
<li><span class="mono num">04</span><a href="#river">A Bootloader In 212 Bytes, Written On A Train<b class="mono">198</b></a></li>
<li><span class="mono num">05</span><a href="#river">Why Your Bench PSU Reads 30 mV Too High<b class="mono">176</b></a></li>
</ol>
</section>
</aside>
</main>
<footer class="foot">
<div class="wrap foot__inner">
<p class="mono">SOLDER & SMOKE — a fictional hardware blog. All projects, bylines and comment counts are invented.</p>
<p class="mono">SUBMIT A TIP · RSS · MASTODON · SHOP RULES</p>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Hacker Blog Landing
SOLDER & SMOKE is a fictional hardware-hacking publication rendered as a fanzine printed on a broken laser printer. The masthead pairs a chunky uppercase wordmark with an original hand-drawn SVG mark — a boxy skull whose jaw is a pair of soldering tips — over a stark uppercase nav bar with 2px hard borders and no rounded corners anywhere. Below it a full-width featured teardown uses a CSS duotone illustration area: a green-to-black gradient wash, an inline SVG board schematic and a multiply-blended scanline overlay, stamped with an amber corner badge.
The article river runs 10 posts in a dense two-column grid, each with a CSS-drawn thumbnail block (chips, waveforms, halftones, conic laser sweeps — no image files anywhere), a category tag, a slab headline, a dek, a byline and a comment count. Hovering or focusing a card inverts it entirely to black-on-acid, flipping the tag and thumbnail colors with it. Cards are keyboard reachable and respond to Enter and Space.
The sidebar sticks alongside the river with a project-of-the-day card whose skull button toggles and recounts, a running contest block with a live day/hour/minute/second countdown, a weighted tag cloud whose five size classes double as multi-select filters, and a most-commented top five. A sticky progress bar at the very top tracks reading depth, and the load-more button pulls two more batches of six posts with a per-card stagger before declaring the archive exhausted.
How this look is built
The layout takes its information architecture from Hackaday-style hardware blogs — dense article
river plus contest sidebar — but everything here is CSS grid rather than the float-and-clear tables
that era of blog actually used. A single grid-template-columns: minmax(0,1fr) 320px drives the
whole page and collapses at 1040px, while the river is its own two-up grid whose shared 2px borders
come from border-left/top on the container plus right/bottom on each cell, so no double lines
appear and no gap hacks are needed. The paper-noise and thumbnail art are all repeating linear,
radial and conic gradients on currentColor, which means the hover inversion recolors every
illustration for free with one color change instead of swapping assets. position: sticky handles
both the masthead and the sidebar without a scroll listener, and an IntersectionObserver reveals
appended cards on entry rather than firing a layout-thrashing scroll handler per frame.
Illustrative UI only — always follow real safety guidance when working with tools, electronics, or repairs.