DIY — 3D Print Community Landing
A dark, workshop-grade landing page for SPOOLYARD, a fictional 3D model community. Isometric SVG render plates sit on radial-gradient turntables, a sticky filter rail live-filters printer type, material chips and a max print-time slider against a running results counter, and hover tilts each tile in 3D to reveal a download button with fake progress. Rounded out by a contest band with a live countdown, a fresh-makes row of community prints, and a points leaderboard.
MCP
Code
:root {
--bg: #151a21;
--bg-2: #11151b;
--card: #1e242d;
--card-2: #232a34;
--orange: #ff7a1a;
--orange-deep: #e06510;
--orange-soft: rgba(255, 122, 26, 0.14);
--cyan: #22c8d8;
--cyan-soft: rgba(34, 200, 216, 0.14);
--text: #e8edf3;
--text-2: #b3bfcd;
--muted: #7f8c9c;
--line: rgba(232, 237, 243, 0.1);
--line-2: rgba(232, 237, 243, 0.18);
--ok: #2f9e6f;
--warn: #d98a2b;
--danger: #d4503e;
--r-sm: 6px;
--r-md: 12px;
--r-lg: 18px;
--sh-1: 0 1px 2px rgba(0, 0, 0, 0.4);
--sh-2: 0 10px 30px rgba(0, 0, 0, 0.45);
--sh-3: 0 22px 50px rgba(0, 0, 0, 0.55);
--mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
background:
radial-gradient(900px 480px at 82% -6%, rgba(34, 200, 216, 0.1), transparent 62%),
radial-gradient(760px 460px at 8% 0%, rgba(255, 122, 26, 0.12), transparent 60%),
var(--bg);
color: var(--text);
font-family: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
img, svg { max-width: 100%; display: block; }
button, input { font: inherit; color: inherit; }
a { color: inherit; }
.mono { font-family: var(--mono); font-variant-ligatures: none; }
.muted { color: var(--muted); }
.wrap { width: min(1200px, 100% - 2.5rem); margin-inline: auto; }
.sr-only {
position: absolute; width: 1px; height: 1px; overflow: hidden;
clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.skip {
position: absolute; left: -999px; top: 0; z-index: 60;
background: var(--orange); color: #14181d; padding: .6rem 1rem;
border-radius: 0 0 var(--r-sm) 0; font-weight: 700;
}
.skip:focus { left: 0; }
:where(a, button, input, [tabindex]):focus-visible {
outline: 2px solid var(--cyan);
outline-offset: 2px;
border-radius: var(--r-sm);
}
/* ---------- header ---------- */
.site-head {
position: sticky; top: 0; z-index: 40;
background: rgba(17, 21, 27, 0.82);
backdrop-filter: blur(14px);
border-bottom: 1px solid var(--line);
}
.head-inner {
display: flex; align-items: center; gap: 1rem;
min-height: 68px; padding-block: .7rem;
}
.brand { display: flex; align-items: center; gap: .6rem; text-decoration: none; flex: none; }
.brand-mark { width: 34px; height: 34px; }
.brand-name { font-weight: 800; letter-spacing: -.02em; font-size: 1.12rem; }
.brand-name span { color: var(--orange); }
.search {
flex: 1 1 auto; position: relative; display: flex; align-items: center;
max-width: 520px; margin-inline: auto;
}
.search-ico {
position: absolute; left: .7rem; width: 18px; height: 18px; color: var(--muted);
}
.search input {
width: 100%; padding: .62rem 2.6rem .62rem 2.4rem;
background: var(--card); border: 1px solid var(--line);
border-radius: 999px; color: var(--text);
}
.search input::placeholder { color: var(--muted); }
.search input:focus { border-color: var(--cyan); outline: none; box-shadow: 0 0 0 3px var(--cyan-soft); }
.search kbd {
position: absolute; right: .6rem; font-family: var(--mono); font-size: .72rem;
color: var(--muted); border: 1px solid var(--line-2); border-radius: 5px;
padding: .05rem .4rem; background: var(--bg-2);
}
.head-actions { display: flex; align-items: center; gap: .6rem; flex: none; }
.chip-points {
display: inline-flex; align-items: center; gap: .4rem;
background: var(--card); border: 1px solid var(--line-2);
border-radius: 999px; padding: .4rem .75rem; font-size: .85rem;
color: var(--text-2); cursor: pointer; transition: border-color .18s, transform .18s;
}
.chip-points:hover { border-color: var(--orange); transform: translateY(-1px); }
.chip-points .dot {
width: 8px; height: 8px; border-radius: 50%;
background: var(--cyan); box-shadow: 0 0 0 3px var(--cyan-soft);
}
.chip-points .mono { color: var(--text); font-weight: 700; }
.btn {
display: inline-flex; align-items: center; gap: .45rem; cursor: pointer;
border-radius: 999px; border: 1px solid transparent; padding: .55rem 1rem;
font-weight: 600; font-size: .9rem;
transition: transform .15s ease, background .18s, border-color .18s, box-shadow .18s;
}
.btn svg { width: 17px; height: 17px; }
.btn:active { transform: translateY(1px) scale(.99); }
.btn-primary {
background: linear-gradient(180deg, var(--orange), var(--orange-deep));
color: #17110a; box-shadow: 0 6px 18px rgba(255, 122, 26, 0.28);
}
.btn-primary:hover { box-shadow: 0 10px 26px rgba(255, 122, 26, 0.38); }
.btn-ghost { background: transparent; border-color: var(--line-2); color: var(--text-2); }
.btn-ghost:hover { border-color: var(--cyan); color: var(--text); }
.btn.wide { width: 100%; justify-content: center; }
/* ---------- hero ---------- */
.hero {
display: grid; grid-template-columns: 1.25fr .85fr; gap: 2rem; align-items: center;
padding: 3rem 0 2.2rem;
}
.eyebrow { font-size: .72rem; letter-spacing: .16em; color: var(--cyan); margin: 0 0 .6rem; }
.hero h1 {
margin: 0 0 .7rem; font-size: clamp(2rem, 4.6vw, 3.15rem);
line-height: 1.06; letter-spacing: -.03em; font-weight: 800;
}
.hero h1 em { font-style: normal; color: var(--orange); }
.lede { margin: 0 0 1.4rem; color: var(--text-2); max-width: 52ch; }
.hero-stats { display: flex; gap: 2rem; flex-wrap: wrap; }
.hero-stats div { display: flex; flex-direction: column; }
.hero-stats strong { font-size: 1.35rem; letter-spacing: -.02em; }
.hero-stats span { font-size: .78rem; color: var(--muted); }
.hero-plate {
border-radius: var(--r-lg); overflow: hidden;
border: 1px solid var(--line-2); box-shadow: var(--sh-3);
}
/* ---------- filters ---------- */
.filters {
position: sticky; top: 68px; z-index: 30;
background: rgba(21, 26, 33, 0.9); backdrop-filter: blur(10px);
padding: .9rem 0 .6rem;
}
.filter-row {
display: flex; flex-wrap: wrap; gap: 1rem 1.6rem; align-items: flex-end;
background: var(--card); border: 1px solid var(--line);
border-radius: var(--r-lg); padding: .9rem 1.1rem; box-shadow: var(--sh-2);
}
.fgroup { display: flex; flex-direction: column; gap: .45rem; }
.fgroup.grow { flex: 1 1 220px; min-width: 200px; }
.flabel { font-size: .68rem; letter-spacing: .14em; color: var(--muted); }
.flabel .val { color: var(--cyan); }
.pills { display: flex; gap: .4rem; flex-wrap: wrap; }
.pill {
cursor: pointer; border-radius: 999px; padding: .34rem .8rem;
background: var(--bg-2); border: 1px solid var(--line-2);
color: var(--text-2); font-size: .84rem; font-weight: 500;
transition: all .16s ease;
}
.pill:hover { border-color: var(--cyan); color: var(--text); }
.pill.is-on {
background: var(--orange-soft); border-color: var(--orange);
color: var(--orange); font-weight: 600;
}
.pill.mat.is-on { background: var(--cyan-soft); border-color: var(--cyan); color: var(--cyan); }
.range {
-webkit-appearance: none; appearance: none; width: 100%; height: 5px;
border-radius: 999px; background: var(--line-2); cursor: pointer;
}
.range::-webkit-slider-thumb {
-webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%;
background: var(--orange); border: 3px solid #17110a;
box-shadow: 0 0 0 3px var(--orange-soft);
}
.range::-moz-range-thumb {
width: 18px; height: 18px; border-radius: 50%; border: 3px solid #17110a;
background: var(--orange); box-shadow: 0 0 0 3px var(--orange-soft);
}
.results { margin: .7rem 0 0; font-size: .82rem; color: var(--muted); }
/* ---------- model grid ---------- */
.grid {
display: grid; gap: 1.1rem; padding: 1rem 0 2.4rem;
grid-template-columns: repeat(auto-fill, minmax(238px, 1fr));
}
.card {
position: relative; background: var(--card); border: 1px solid var(--line);
border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--sh-1);
transition: transform .3s cubic-bezier(.2,.7,.3,1), box-shadow .3s, border-color .3s;
transform-style: preserve-3d;
opacity: 0; translate: 0 14px;
}
.card.in { opacity: 1; translate: 0 0; transition: opacity .5s ease, translate .5s ease, transform .3s cubic-bezier(.2,.7,.3,1), box-shadow .3s, border-color .3s; }
.card:hover, .card:focus-within {
transform: perspective(900px) rotateX(4deg) rotateY(-5deg) translateY(-6px);
box-shadow: var(--sh-3); border-color: var(--orange);
}
.plate { position: relative; aspect-ratio: 4 / 3; background: #10141a; }
.plate svg { width: 100%; height: 100%; }
.plate-badges {
position: absolute; top: .55rem; left: .55rem; display: flex; gap: .35rem;
}
.tag {
font-family: var(--mono); font-size: .64rem; letter-spacing: .06em;
padding: .18rem .42rem; border-radius: var(--r-sm);
background: rgba(17, 21, 27, .78); border: 1px solid var(--line-2); color: var(--text-2);
}
.tag.fdm { color: var(--orange); border-color: rgba(255,122,26,.5); }
.tag.resin { color: var(--cyan); border-color: rgba(34,200,216,.5); }
.dl-layer {
position: absolute; inset: auto 0 0 0; padding: .6rem;
background: linear-gradient(180deg, transparent, rgba(16, 20, 26, .95));
display: flex; justify-content: center;
opacity: 0; translate: 0 8px; transition: opacity .22s ease, translate .22s ease;
}
.card:hover .dl-layer, .card:focus-within .dl-layer { opacity: 1; translate: 0 0; }
.dl-btn {
cursor: pointer; border: none; border-radius: 999px; padding: .42rem 1rem;
background: var(--orange); color: #17110a; font-weight: 700; font-size: .82rem;
display: inline-flex; align-items: center; gap: .4rem;
}
.dl-btn[disabled] { opacity: .8; cursor: progress; }
.prog {
position: absolute; left: 0; bottom: 0; height: 3px; width: 0%;
background: var(--cyan); transition: width .2s linear;
}
.card-body { padding: .8rem .85rem .9rem; }
.card-title {
margin: 0 0 .5rem; font-size: .96rem; font-weight: 700; letter-spacing: -.01em;
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.author { display: flex; align-items: center; gap: .4rem; margin-bottom: .6rem; }
.avatar {
width: 22px; height: 22px; border-radius: 50%; flex: none;
display: grid; place-items: center; font-size: .62rem; font-weight: 700; color: #14181d;
font-family: var(--mono);
}
.author-name { font-size: .78rem; color: var(--text-2); }
.metrics {
display: flex; align-items: center; gap: .8rem; font-size: .76rem; color: var(--muted);
border-top: 1px solid var(--line); padding-top: .55rem;
}
.metrics span { display: inline-flex; align-items: center; gap: .28rem; }
.metrics svg { width: 13px; height: 13px; }
.metrics .spec { margin-left: auto; font-family: var(--mono); font-size: .66rem; color: var(--text-2); }
.like { cursor: pointer; background: none; border: none; padding: 0; transition: color .15s; }
.like:hover { color: var(--orange); }
.like.on { color: var(--orange); }
.empty { text-align: center; color: var(--muted); padding: 2.5rem 0 3rem; }
/* ---------- contest ---------- */
.contest { padding: 1rem 0 2.6rem; }
.contest-inner {
display: grid; grid-template-columns: 1.4fr .8fr; gap: 2rem;
border-radius: var(--r-lg); padding: 1.8rem;
border: 1px solid rgba(255, 122, 26, .35);
background:
radial-gradient(600px 300px at 12% 0%, rgba(255,122,26,.16), transparent 65%),
radial-gradient(520px 280px at 96% 100%, rgba(34,200,216,.14), transparent 62%),
var(--card);
box-shadow: var(--sh-2);
}
.contest h2 { margin: 0 0 .5rem; font-size: clamp(1.4rem, 2.6vw, 2rem); letter-spacing: -.02em; }
.contest p { color: var(--text-2); margin: 0 0 1rem; max-width: 56ch; }
.prizes { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.prizes li { display: flex; align-items: center; gap: .6rem; font-size: .88rem; color: var(--text-2); }
.medal {
width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
font-size: .72rem; font-weight: 700; color: #17110a; flex: none;
}
.gold { background: linear-gradient(160deg, #ffd777, #e0a11a); }
.silver { background: linear-gradient(160deg, #dfe6ee, #9aa8b8); }
.bronze { background: linear-gradient(160deg, #e8a877, #b26a34); }
.countdown {
background: var(--bg-2); border: 1px solid var(--line-2); border-radius: var(--r-md);
padding: 1.1rem; align-self: center;
}
.cd-label { font-size: .66rem; letter-spacing: .16em; color: var(--muted); margin: 0 0 .7rem; }
.cd { display: grid; grid-template-columns: repeat(4, 1fr); gap: .4rem; margin-bottom: .9rem; }
.cd div {
background: var(--card-2); border-radius: var(--r-sm); padding: .5rem .2rem; text-align: center;
}
.cd strong { display: block; font-size: 1.25rem; color: var(--orange); letter-spacing: -.02em; }
.cd span { font-size: .62rem; color: var(--muted); text-transform: uppercase; letter-spacing: .1em; }
.cd-note { font-size: .68rem; color: var(--muted); text-align: center; margin: .7rem 0 0; letter-spacing: .1em; }
/* ---------- makes ---------- */
.sec-head {
display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
margin-bottom: 1rem;
}
.sec-head h2 { margin: 0; font-size: 1.35rem; letter-spacing: -.02em; }
.link { color: var(--cyan); font-size: .86rem; text-decoration: none; font-weight: 600; }
.link:hover { text-decoration: underline; }
.makes { padding-bottom: 2.6rem; }
.makes-row {
display: grid; gap: 1rem;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.make {
display: flex; gap: .8rem; background: var(--card); border: 1px solid var(--line);
border-radius: var(--r-md); padding: .8rem; transition: border-color .2s, transform .2s;
}
.make:hover { border-color: var(--cyan); transform: translateY(-3px); }
.make-plate {
width: 78px; height: 78px; flex: none; border-radius: var(--r-sm); overflow: hidden;
border: 1px solid var(--line-2);
}
.make-body { min-width: 0; }
.make h3 { margin: 0 0 .2rem; font-size: .88rem; }
.make .who { font-size: .72rem; color: var(--cyan); font-family: var(--mono); margin: 0 0 .35rem; }
.make .cmt { margin: 0; font-size: .8rem; color: var(--text-2); }
.make .meta { margin: .45rem 0 0; font-size: .66rem; color: var(--muted); font-family: var(--mono); }
/* ---------- leaderboard ---------- */
.board { padding-bottom: 3.4rem; }
.leaders {
list-style: none; margin: 0; padding: .4rem; display: grid; gap: .3rem;
background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg);
}
.leader {
display: flex; align-items: center; gap: .8rem; padding: .6rem .8rem;
border-radius: var(--r-md); transition: background .18s;
}
.leader:hover { background: var(--card-2); }
.rank { width: 26px; text-align: center; font-family: var(--mono); font-weight: 700; color: var(--muted); }
.leader .avatar { width: 30px; height: 30px; font-size: .72rem; }
.lname { font-weight: 600; font-size: .92rem; }
.lmeta { font-size: .72rem; color: var(--muted); font-family: var(--mono); }
.lpts { margin-left: auto; text-align: right; }
.lpts strong { display: block; font-family: var(--mono); color: var(--orange); }
.lpts span { font-size: .66rem; color: var(--muted); letter-spacing: .1em; }
.bar {
height: 4px; border-radius: 999px; background: var(--line-2); overflow: hidden;
width: 110px; flex: none;
}
.bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--cyan), var(--orange)); }
/* ---------- footer / toast ---------- */
.site-foot { border-top: 1px solid var(--line); background: var(--bg-2); padding: 1.4rem 0; }
.foot-inner {
display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
color: var(--muted); font-size: .76rem;
}
.foot-inner nav { display: flex; gap: 1.1rem; }
.foot-inner a { text-decoration: none; }
.foot-inner a:hover { color: var(--cyan); }
.toast-wrap {
position: fixed; right: 1rem; bottom: 1rem; z-index: 80;
display: flex; flex-direction: column; gap: .5rem; align-items: flex-end;
}
.toast {
background: var(--card-2); border: 1px solid var(--line-2); border-left: 3px solid var(--orange);
color: var(--text); padding: .6rem .9rem; border-radius: var(--r-sm);
box-shadow: var(--sh-2); font-size: .85rem; max-width: 300px;
animation: pop .28s cubic-bezier(.2,.9,.3,1);
}
.toast.ok { border-left-color: var(--ok); }
.toast.cy { border-left-color: var(--cyan); }
@keyframes pop { from { opacity: 0; transform: translateY(10px) scale(.97); } }
@media (prefers-reduced-motion: reduce) {
* { animation-duration: .01ms !important; transition-duration: .01ms !important; }
.card { opacity: 1; translate: none; }
}
@media (max-width: 900px) {
.hero { grid-template-columns: 1fr; }
.hero-plate { order: -1; }
.contest-inner { grid-template-columns: 1fr; }
.search { order: 3; max-width: none; flex-basis: 100%; margin: .2rem 0 0; }
.head-inner { flex-wrap: wrap; }
}
@media (max-width: 520px) {
.wrap { width: min(1200px, 100% - 1.5rem); }
.filters { position: static; }
.grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: .7rem; }
.card-title { font-size: .84rem; }
.metrics { font-size: .68rem; gap: .5rem; }
.metrics .spec { display: none; }
.hero { padding-top: 1.6rem; }
.hero-stats { gap: 1.1rem; }
.contest-inner { padding: 1.1rem; }
.filter-row { padding: .8rem; gap: .8rem; }
.bar { display: none; }
.head-actions .btn-primary { padding: .55rem .8rem; font-size: .82rem; }
.chip-points { padding: .4rem .6rem; font-size: .78rem; }
.make-plate { width: 62px; height: 62px; }
.toast-wrap { left: 1rem; right: 1rem; align-items: stretch; }
.toast { max-width: none; }
}/* SPOOLYARD — fictional 3D model community landing. Vanilla JS only. */
(function () {
"use strict";
/* ---------------- toast helper ---------------- */
var toastWrap = document.getElementById("toasts");
function toast(msg, kind) {
var el = document.createElement("div");
el.className = "toast" + (kind ? " " + kind : "");
el.setAttribute("role", "status");
el.textContent = msg;
toastWrap.appendChild(el);
setTimeout(function () {
el.style.transition = "opacity .3s, transform .3s";
el.style.opacity = "0";
el.style.transform = "translateY(8px)";
setTimeout(function () { el.remove(); }, 320);
}, 2600);
}
/* ---------------- data ---------------- */
var MODELS = [
{ t: "Hex Cable Tray — modular 60 mm", a: "voxelwren", p: "fdm", m: "PETG", likes: 4820, dl: 18240, lh: 0.20, hrs: 3.5, shape: "hex" },
{ t: "Turntable Camera Rig, geared", a: "orbitmill", p: "fdm", m: "PLA", likes: 3110, dl: 9820, lh: 0.16, hrs: 7, shape: "gear" },
{ t: "Flex Wrist Rest, honeycomb infill", a: "softshellco", p: "fdm", m: "TPU", likes: 2740, dl: 7410, lh: 0.24, hrs: 5, shape: "wave" },
{ t: "Miniature Lighthouse, 32 mm scale", a: "tidecast", p: "resin", m: "Resin", likes: 6190, dl: 21400, lh: 0.04, hrs: 9, shape: "tower" },
{ t: "Filament Dry Box Latch Kit", a: "spoolsmith", p: "fdm", m: "PETG", likes: 1890, dl: 12030, lh: 0.20, hrs: 2, shape: "box" },
{ t: "Planetary Pen Silo, 4 slots", a: "gearpocket", p: "fdm", m: "PLA", likes: 5310, dl: 16880, lh: 0.16, hrs: 6, shape: "gear" },
{ t: "Vase-mode Lantern, twist shell", a: "lumenlathe", p: "fdm", m: "PLA", likes: 7420, dl: 26510, lh: 0.28, hrs: 4, shape: "vase" },
{ t: "Articulated Desk Dragon, print-in-place", a: "scalesmith", p: "fdm", m: "PLA", likes: 9840, dl: 41220, lh: 0.20, hrs: 11, shape: "chain" },
{ t: "Resin Bust — Wanderer, hollowed", a: "tidecast", p: "resin", m: "Resin", likes: 4460, dl: 13750, lh: 0.03, hrs: 14, shape: "tower" },
{ t: "TPU Camera Bumper, 3 mm shell", a: "softshellco", p: "fdm", m: "TPU", likes: 1320, dl: 4980, lh: 0.24, hrs: 3, shape: "box" },
{ t: "Headphone Arm, clamp mount", a: "voxelwren", p: "fdm", m: "PETG", likes: 3980, dl: 15640, lh: 0.20, hrs: 4, shape: "arm" },
{ t: "Micro Terrain Tiles, 24-pack", a: "orbitmill", p: "resin", m: "Resin", likes: 2210, dl: 8110, lh: 0.05, hrs: 8, shape: "hex" },
{ t: "Snap-fit Drawer Grid, 42 mm", a: "gearpocket", p: "fdm", m: "PLA", likes: 5620, dl: 29310, lh: 0.20, hrs: 2, shape: "box" },
{ t: "Bearing-free Fidget Spinner", a: "spoolsmith", p: "fdm", m: "PLA", likes: 2870, dl: 10240, lh: 0.16, hrs: 1, shape: "gear" },
{ t: "Wall Spool Cradle, 1 kg rated", a: "lumenlathe", p: "fdm", m: "PETG", likes: 3340, dl: 11760, lh: 0.24, hrs: 6, shape: "arm" }
];
var PALETTES = {
hex: ["#ff7a1a", "#ffb066"], gear: ["#22c8d8", "#7ae4ee"],
wave: ["#ff9d4d", "#ffd0a3"], tower: ["#8fd6ff", "#d5efff"],
box: ["#ff7a1a", "#ffcf9e"], vase: ["#22c8d8", "#b6f2f8"],
chain: ["#ffa04d", "#ffd9b3"], arm: ["#5fd8e4", "#c9f4f8"]
};
var uid = 0;
function plateSVG(shape, seed) {
var pal = PALETTES[shape] || PALETTES.box;
var id = "g" + (++uid);
var body = {
hex: '<path d="M0 -34 L30 -17 L30 17 L0 34 L-30 17 L-30 -17 Z" fill="url(#f' + id + ')" stroke="' + pal[0] + '" stroke-width="1.6"/><path d="M0 -34 L0 0 L-30 17 M0 0 L30 17" stroke="' + pal[1] + '" stroke-width="1.2" fill="none" opacity=".8"/>',
gear: '<circle r="30" fill="url(#f' + id + ')" stroke="' + pal[0] + '" stroke-width="1.8"/><circle r="12" fill="none" stroke="' + pal[1] + '" stroke-width="1.6"/><g stroke="' + pal[0] + '" stroke-width="3">' +
[0, 45, 90, 135, 180, 225, 270, 315].map(function (d) {
var r = d * Math.PI / 180;
return '<line x1="' + (Math.cos(r) * 30).toFixed(1) + '" y1="' + (Math.sin(r) * 30 * 0.55).toFixed(1) + '" x2="' + (Math.cos(r) * 38).toFixed(1) + '" y2="' + (Math.sin(r) * 38 * 0.55).toFixed(1) + '"/>';
}).join("") + "</g>",
wave: '<path d="M-38 12 C-20 -22 -6 26 8 -8 C20 -34 32 6 40 -6 L40 24 L-38 24 Z" fill="url(#f' + id + ')" stroke="' + pal[0] + '" stroke-width="1.6"/>',
tower: '<path d="M-14 34 L-8 -30 L8 -30 L14 34 Z" fill="url(#f' + id + ')" stroke="' + pal[0] + '" stroke-width="1.6"/><path d="M-11 6 H11 M-9 -12 H9" stroke="' + pal[1] + '" stroke-width="1.4"/><circle cy="-36" r="7" fill="none" stroke="' + pal[1] + '" stroke-width="1.6"/>',
box: '<path d="M0 -30 L34 -12 L34 16 L0 34 L-34 16 L-34 -12 Z" fill="url(#f' + id + ')" stroke="' + pal[0] + '" stroke-width="1.6"/><path d="M-34 -12 L0 6 L34 -12 M0 6 L0 34" stroke="' + pal[1] + '" stroke-width="1.3" fill="none"/>',
vase: '<path d="M-16 34 C-30 6 -6 -6 -12 -32 L12 -32 C6 -6 30 6 16 34 Z" fill="url(#f' + id + ')" stroke="' + pal[0] + '" stroke-width="1.6"/><path d="M-18 18 H18 M-14 2 H14" stroke="' + pal[1] + '" stroke-width="1.1" opacity=".8"/>',
chain: [0, 1, 2, 3].map(function (i) {
return '<ellipse cx="' + (-27 + i * 18) + '" cy="' + (10 - i * 8) + '" rx="12" ry="8" fill="url(#f' + id + ')" stroke="' + pal[0] + '" stroke-width="1.5"/>';
}).join(""),
arm: '<path d="M-30 30 L-30 16 L-4 -6 L-4 -26" fill="none" stroke="' + pal[0] + '" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"/><path d="M-4 -26 L26 -26" stroke="' + pal[1] + '" stroke-width="5" stroke-linecap="round"/><rect x="-38" y="28" width="20" height="8" rx="3" fill="url(#f' + id + ')" stroke="' + pal[0] + '" stroke-width="1.4"/>'
}[shape];
return '<svg viewBox="0 0 200 150" role="img" aria-label="Isometric render of the model">' +
'<defs>' +
'<radialGradient id="p' + id + '" cx="50%" cy="42%" r="62%"><stop offset="0" stop-color="#2b3542"/><stop offset="1" stop-color="#10141a"/></radialGradient>' +
'<linearGradient id="f' + id + '" x1="0" y1="0" x2="0.6" y2="1"><stop offset="0" stop-color="' + pal[1] + '" stop-opacity=".5"/><stop offset="1" stop-color="' + pal[0] + '" stop-opacity=".18"/></linearGradient>' +
'</defs>' +
'<rect width="200" height="150" fill="url(#p' + id + ')"/>' +
'<g opacity=".35" stroke="#22c8d8" stroke-width=".5">' +
'<path d="M0 108 L100 150 L200 108 M0 96 L100 138 L200 96 M0 120 L100 162 L200 120"/></g>' +
'<ellipse cx="100" cy="112" rx="56" ry="16" fill="#000" opacity=".45"/>' +
'<g transform="translate(100 ' + (72 + (seed % 5)) + ')">' + body + "</g>" +
"</svg>";
}
function fmt(n) {
return n >= 1000 ? (n / 1000).toFixed(n >= 10000 ? 0 : 1).replace(/\.0$/, "") + "k" : String(n);
}
function hue(name) {
var h = 0;
for (var i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) % 360;
return h;
}
function avatar(name, cls) {
return '<span class="avatar ' + (cls || "") + '" aria-hidden="true" style="background:linear-gradient(150deg,hsl(' +
hue(name) + ' 78% 62%),hsl(' + ((hue(name) + 48) % 360) + ' 78% 52%))">' +
name.slice(0, 2).toUpperCase() + "</span>";
}
/* ---------------- render grid ---------------- */
var grid = document.getElementById("grid");
var emptyEl = document.getElementById("empty");
var resultsEl = document.getElementById("results");
MODELS.forEach(function (m, i) {
var card = document.createElement("article");
card.className = "card";
card.dataset.printer = m.p;
card.dataset.mat = m.m;
card.dataset.hrs = String(m.hrs);
card.dataset.title = m.t.toLowerCase() + " " + m.a.toLowerCase();
card.innerHTML =
'<div class="plate">' + plateSVG(m.shape, i) +
'<div class="plate-badges"><span class="tag ' + m.p + '">' + m.p.toUpperCase() + '</span>' +
'<span class="tag">' + m.m + "</span></div>" +
'<div class="dl-layer"><button class="dl-btn" type="button">Download STL</button></div>' +
'<i class="prog" aria-hidden="true"></i>' +
"</div>" +
'<div class="card-body">' +
'<h3 class="card-title">' + m.t + "</h3>" +
'<div class="author">' + avatar(m.a) + '<span class="author-name">@' + m.a + "</span></div>" +
'<div class="metrics">' +
'<button class="like" type="button" aria-pressed="false" aria-label="Like ' + m.t + '">' +
'<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 20s-7-4.35-7-9a4 4 0 0 1 7-2.6A4 4 0 0 1 19 11c0 4.65-7 9-7 9z" fill="none" stroke="currentColor" stroke-width="2"/></svg>' +
'<b class="mono" style="font-weight:600">' + fmt(m.likes) + "</b></button>" +
'<span><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 4v11m0 0-4-4m4 4 4-4M5 20h14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>' +
'<span class="mono">' + fmt(m.dl) + "</span></span>" +
'<span class="spec">' + m.lh.toFixed(2) + "mm · " + m.hrs + "h</span>" +
"</div>" +
"</div>";
grid.appendChild(card);
});
/* reveal on scroll */
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (e) {
if (e.isIntersecting) { e.target.classList.add("in"); io.unobserve(e.target); }
});
}, { rootMargin: "0px 0px -40px 0px" });
grid.querySelectorAll(".card").forEach(function (c) { io.observe(c); });
} else {
grid.querySelectorAll(".card").forEach(function (c) { c.classList.add("in"); });
}
/* ---------------- filtering ---------------- */
var state = { printer: "all", mats: ["PLA", "PETG", "TPU", "Resin"], maxHrs: 24, q: "" };
function apply() {
var shown = 0;
grid.querySelectorAll(".card").forEach(function (c) {
var ok =
(state.printer === "all" || c.dataset.printer === state.printer) &&
state.mats.indexOf(c.dataset.mat) !== -1 &&
Number(c.dataset.hrs) <= state.maxHrs &&
(!state.q || c.dataset.title.indexOf(state.q) !== -1);
c.hidden = !ok;
if (ok) shown++;
});
resultsEl.textContent = "Showing " + shown + " of " + MODELS.length + " models";
emptyEl.hidden = shown !== 0;
}
document.getElementById("printerPills").addEventListener("click", function (e) {
var b = e.target.closest(".pill");
if (!b) return;
this.querySelectorAll(".pill").forEach(function (p) {
p.classList.toggle("is-on", p === b);
p.setAttribute("aria-pressed", String(p === b));
});
state.printer = b.dataset.printer;
apply();
});
document.getElementById("matPills").addEventListener("click", function (e) {
var b = e.target.closest(".pill");
if (!b) return;
var on = !b.classList.contains("is-on");
b.classList.toggle("is-on", on);
b.setAttribute("aria-pressed", String(on));
state.mats = Array.prototype.map.call(this.querySelectorAll(".pill.is-on"), function (p) { return p.dataset.mat; });
apply();
});
var range = document.getElementById("timeRange");
var timeVal = document.getElementById("timeVal");
range.addEventListener("input", function () {
state.maxHrs = Number(this.value);
timeVal.textContent = state.maxHrs >= 24 ? "24 h" : state.maxHrs + " h";
apply();
});
var q = document.getElementById("q");
q.addEventListener("input", function () { state.q = this.value.trim().toLowerCase(); apply(); });
document.addEventListener("keydown", function (e) {
if (e.key === "/" && document.activeElement !== q) { e.preventDefault(); q.focus(); }
});
document.getElementById("resetBtn").addEventListener("click", function () {
state = { printer: "all", mats: ["PLA", "PETG", "TPU", "Resin"], maxHrs: 24, q: "" };
q.value = ""; range.value = 24; timeVal.textContent = "24 h";
document.querySelectorAll("#printerPills .pill").forEach(function (p) {
var on = p.dataset.printer === "all";
p.classList.toggle("is-on", on); p.setAttribute("aria-pressed", String(on));
});
document.querySelectorAll("#matPills .pill").forEach(function (p) {
p.classList.add("is-on"); p.setAttribute("aria-pressed", "true");
});
apply();
toast("Filters reset — all 15 models visible.", "cy");
});
/* ---------------- likes + downloads ---------------- */
grid.addEventListener("click", function (e) {
var like = e.target.closest(".like");
if (like) {
var b = like.querySelector("b");
if (!b.dataset.orig) b.dataset.orig = b.textContent;
var on = !like.classList.contains("on");
like.classList.toggle("on", on);
like.setAttribute("aria-pressed", String(on));
b.textContent = on ? b.dataset.orig + " +1" : b.dataset.orig;
if (on) toast("Saved to your likes.", "ok");
return;
}
var dl = e.target.closest(".dl-btn");
if (!dl) return;
var card = dl.closest(".card");
var bar = card.querySelector(".prog");
if (dl.disabled) return;
dl.disabled = true;
var label = dl.textContent;
var pct = 0;
var tick = setInterval(function () {
pct = Math.min(100, pct + 8 + Math.random() * 14);
bar.style.width = pct + "%";
dl.textContent = "Downloading " + Math.round(pct) + "%";
if (pct >= 100) {
clearInterval(tick);
dl.textContent = "Done ✓";
toast('"' + card.querySelector(".card-title").textContent + '" added to your plate queue.', "ok");
setTimeout(function () {
bar.style.width = "0%"; dl.textContent = label; dl.disabled = false;
}, 1400);
}
}, 160);
});
document.getElementById("uploadBtn").addEventListener("click", function () {
toast("Upload wizard is a demo stub — drop your STL and slicer profile here.", "cy");
});
document.querySelector(".chip-points").addEventListener("click", function () {
toast("4,820 maker points · 180 more unlocks the Resin badge.", "cy");
});
document.getElementById("enterBtn").addEventListener("click", function () {
toast("Entry slot reserved for the Desk Ecosystem Challenge.", "ok");
});
/* ---------------- countdown ---------------- */
var deadline = Date.now() + (6 * 24 + 9) * 3600e3 + 42 * 60e3 + 18e3;
var cd = document.getElementById("countdown");
function pad(n) { return String(n).padStart(2, "0"); }
function tickCd() {
var ms = Math.max(0, deadline - Date.now());
var s = Math.floor(ms / 1000);
cd.querySelector('[data-cd="d"]').textContent = pad(Math.floor(s / 86400));
cd.querySelector('[data-cd="h"]').textContent = pad(Math.floor(s / 3600) % 24);
cd.querySelector('[data-cd="m"]').textContent = pad(Math.floor(s / 60) % 60);
cd.querySelector('[data-cd="s"]').textContent = pad(s % 60);
}
tickCd();
setInterval(tickCd, 1000);
/* ---------------- fresh makes ---------------- */
var MAKES = [
{ model: "Vase-mode Lantern", who: "printhaus_ana", cmt: "Ran it at 0.28 mm in translucent PLA — the twist catches an LED puck beautifully. Zero supports.", shape: "vase", meta: "PLA · 4h 12m · 2 h AGO" },
{ model: "Articulated Desk Dragon", who: "benchy_bram", cmt: "Print-in-place joints freed up with a gentle twist. Scaled to 140% and it still moves.", shape: "chain", meta: "PLA · 13h 40m · 5 h AGO" },
{ model: "Hex Cable Tray", who: "wattnest", cmt: "Six tiles under the desk, snapped together dry. PETG survived a hot room all summer.", shape: "hex", meta: "PETG · 3h 30m · 9 h AGO" },
{ model: "Micro Terrain Tiles", who: "tabletop_ivy", cmt: "Resin caught every chisel mark. Washed 6 min, cured 3 — no warping on the thin edges.", shape: "hex", meta: "RESIN · 8h 05m · 1 d AGO" }
];
var makesRow = document.getElementById("makesRow");
MAKES.forEach(function (mk, i) {
var el = document.createElement("article");
el.className = "make";
el.innerHTML =
'<div class="make-plate">' + plateSVG(mk.shape, i + 3) + "</div>" +
'<div class="make-body"><h3>' + mk.model + "</h3>" +
'<p class="who">@' + mk.who + "</p>" +
'<p class="cmt">' + mk.cmt + "</p>" +
'<p class="meta">' + mk.meta + "</p></div>";
makesRow.appendChild(el);
});
/* ---------------- leaderboard ---------------- */
var LEADERS = [
{ n: "voxelwren", pts: 42180, models: 96, makes: 3120 },
{ n: "gearpocket", pts: 38640, models: 74, makes: 2810 },
{ n: "tidecast", pts: 35110, models: 58, makes: 2440 },
{ n: "lumenlathe", pts: 29870, models: 61, makes: 1990 },
{ n: "softshellco", pts: 24350, models: 44, makes: 1520 },
{ n: "spoolsmith", pts: 21090, models: 39, makes: 1310 }
];
var leaders = document.getElementById("leaders");
var top = LEADERS[0].pts;
LEADERS.forEach(function (l, i) {
var medal = i < 3 ? ["gold", "silver", "bronze"][i] : "";
var li = document.createElement("li");
li.className = "leader";
li.innerHTML =
(medal
? '<span class="medal ' + medal + ' mono rank" style="width:26px;height:26px">' + (i + 1) + "</span>"
: '<span class="rank">' + (i + 1) + "</span>") +
avatar(l.n) +
'<span><span class="lname">@' + l.n + '</span><br><span class="lmeta">' + l.models + " models · " + fmt(l.makes) + " makes</span></span>" +
'<span class="bar" aria-hidden="true"><i style="width:' + Math.round((l.pts / top) * 100) + '%"></i></span>' +
'<span class="lpts"><strong>' + l.pts.toLocaleString("en-US") + "</strong><span>PTS</span></span>";
leaders.appendChild(li);
});
apply();
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>SPOOLYARD — 3D model community</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>
<a class="skip" href="#models">Skip to models</a>
<header class="site-head">
<div class="wrap head-inner">
<a class="brand" href="#" aria-label="SPOOLYARD home">
<svg class="brand-mark" viewBox="0 0 40 40" aria-hidden="true">
<defs>
<linearGradient id="bm" x1="0" y1="0" x2="1" y2="1">
<stop offset="0" stop-color="#ff7a1a"/><stop offset="1" stop-color="#22c8d8"/>
</linearGradient>
</defs>
<circle cx="20" cy="20" r="18" fill="none" stroke="url(#bm)" stroke-width="3"/>
<path d="M20 8 L31 14.2 L31 25.8 L20 32 L9 25.8 L9 14.2 Z" fill="none" stroke="#ff7a1a" stroke-width="2"/>
<path d="M20 8 L20 20 L9 25.8 M20 20 L31 25.8" fill="none" stroke="#22c8d8" stroke-width="1.6" opacity=".85"/>
</svg>
<span class="brand-name">SPOOL<span>YARD</span></span>
</a>
<form class="search" role="search" onsubmit="return false">
<label class="sr-only" for="q">Search models</label>
<svg viewBox="0 0 24 24" aria-hidden="true" class="search-ico"><circle cx="11" cy="11" r="7" fill="none" stroke="currentColor" stroke-width="2"/><path d="M16.5 16.5 L21 21" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
<input id="q" type="search" placeholder="Search 84,120 printable models…" autocomplete="off" />
<kbd>/</kbd>
</form>
<div class="head-actions">
<button class="chip-points" type="button" aria-label="Your maker points: 4,820">
<span class="dot" aria-hidden="true"></span>
<span class="mono">4,820</span> pts
</button>
<button class="btn btn-primary" id="uploadBtn" type="button">
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M12 19V6M12 6l-5 5M12 6l5 5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M4 20h16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
Upload model
</button>
</div>
</div>
</header>
<main>
<section class="hero wrap">
<div class="hero-copy">
<p class="eyebrow mono">OPEN LIBRARY · CC-BY-SA</p>
<h1>Print it, remix it, share the <em>make</em>.</h1>
<p class="lede">Eighty-four thousand community models with tested slicer profiles, real print times and photo proof from makers who actually ran the job.</p>
<div class="hero-stats">
<div><strong class="mono">84,120</strong><span>models</span></div>
<div><strong class="mono">312k</strong><span>makes posted</span></div>
<div><strong class="mono">1,940</strong><span>designers</span></div>
</div>
</div>
<div class="hero-plate" aria-hidden="true">
<svg viewBox="0 0 260 200">
<defs>
<radialGradient id="hp" cx="50%" cy="45%" r="60%">
<stop offset="0" stop-color="#2b3542"/><stop offset="1" stop-color="#151a21"/>
</radialGradient>
</defs>
<rect width="260" height="200" fill="url(#hp)"/>
<g opacity=".5" stroke="#22c8d8" stroke-width=".5">
<path d="M0 140 L130 200 L260 140 M0 120 L130 180 L260 120"/>
</g>
<g transform="translate(130 108)">
<path d="M0 -62 L54 -31 L54 31 L0 62 L-54 31 L-54 -31 Z" fill="#1e242d" stroke="#ff7a1a" stroke-width="2"/>
<path d="M0 -62 L0 0 L-54 31 M0 0 L54 31" fill="none" stroke="#ff7a1a" stroke-width="1.4" opacity=".7"/>
<path d="M0 -34 L30 -17 L30 17 L0 34 L-30 17 L-30 -17 Z" fill="none" stroke="#22c8d8" stroke-width="1.6"/>
</g>
</svg>
</div>
</section>
<section class="filters wrap" aria-label="Model filters">
<div class="filter-row">
<div class="fgroup" role="group" aria-label="Printer type">
<span class="flabel mono">PRINTER</span>
<div class="pills" id="printerPills">
<button class="pill is-on" type="button" data-printer="all" aria-pressed="true">All</button>
<button class="pill" type="button" data-printer="fdm" aria-pressed="false">FDM</button>
<button class="pill" type="button" data-printer="resin" aria-pressed="false">Resin</button>
</div>
</div>
<div class="fgroup" role="group" aria-label="Material">
<span class="flabel mono">MATERIAL</span>
<div class="pills" id="matPills">
<button class="pill mat is-on" type="button" data-mat="PLA" aria-pressed="true">PLA</button>
<button class="pill mat is-on" type="button" data-mat="PETG" aria-pressed="true">PETG</button>
<button class="pill mat is-on" type="button" data-mat="TPU" aria-pressed="true">TPU</button>
<button class="pill mat is-on" type="button" data-mat="Resin" aria-pressed="true">Resin</button>
</div>
</div>
<div class="fgroup grow">
<label class="flabel mono" for="timeRange">MAX PRINT TIME · <span class="mono val" id="timeVal">24 h</span></label>
<input id="timeRange" class="range" type="range" min="1" max="24" step="1" value="24" />
</div>
<div class="fgroup">
<button class="btn btn-ghost" id="resetBtn" type="button">Reset</button>
</div>
</div>
<p class="results" id="results" role="status" aria-live="polite">Showing 15 of 15 models</p>
</section>
<section class="wrap" id="models" aria-label="Model grid">
<div class="grid" id="grid"></div>
<p class="empty" id="empty" hidden>No models match those filters. Widen the print time or re-enable a material.</p>
</section>
<section class="contest wrap" aria-label="Design contest">
<div class="contest-inner">
<div class="contest-copy">
<p class="eyebrow mono">CONTEST · ROUND 14</p>
<h2>Desk Ecosystem Challenge</h2>
<p>Design a print that tames one square foot of desk. Cable trays, headphone arms, pen silos — anything that ships as a single-plate print under four hours.</p>
<ul class="prizes">
<li><span class="medal gold mono">1</span> 6 spools + a 0.2 mm nozzle kit</li>
<li><span class="medal silver mono">2</span> 3 spools + resin sampler</li>
<li><span class="medal bronze mono">3</span> 1 spool + 2,000 pts</li>
</ul>
</div>
<div class="countdown" aria-label="Time remaining to enter">
<p class="mono cd-label">ENTRIES CLOSE IN</p>
<div class="cd" id="countdown">
<div><strong class="mono" data-cd="d">00</strong><span>days</span></div>
<div><strong class="mono" data-cd="h">00</strong><span>hrs</span></div>
<div><strong class="mono" data-cd="m">00</strong><span>min</span></div>
<div><strong class="mono" data-cd="s">00</strong><span>sec</span></div>
</div>
<button class="btn btn-primary wide" type="button" id="enterBtn">Enter the contest</button>
<p class="cd-note mono">412 ENTRIES SO FAR</p>
</div>
</div>
</section>
<section class="wrap makes" aria-label="Fresh makes from the community">
<div class="sec-head">
<h2>Fresh makes</h2>
<a class="link" href="#">Browse all makes</a>
</div>
<div class="makes-row" id="makesRow"></div>
</section>
<section class="wrap board" aria-label="Top designers leaderboard">
<div class="sec-head">
<h2>Top designers this month</h2>
<span class="mono muted">UPDATED HOURLY</span>
</div>
<ol class="leaders" id="leaders"></ol>
</section>
</main>
<footer class="site-foot">
<div class="wrap foot-inner">
<p class="mono">SPOOLYARD · fictional community · illustrative UI</p>
<nav aria-label="Footer"><a href="#">Guidelines</a><a href="#">Licensing</a><a href="#">Print farm</a><a href="#">API</a></nav>
</div>
</footer>
<div class="toast-wrap" id="toasts" aria-live="polite" aria-atomic="false"></div>
<script src="script.js"></script>
</body>
</html>3D Print Community Landing
SPOOLYARD is a fictional model-sharing community rendered in a deep slate workshop palette: filament orange for primary actions, cyan for secondary signals and build-plate lines, and elevated cards floating on a soft two-source radial glow. The header stays sticky with a wordmark, a slash-focusable search field, a maker-points chip and an upload CTA, so browsing never loses its navigation.
Under it sits a filter rail that is the real engine of the page. Printer pills (All / FDM / Resin) behave as a radio group, material chips (PLA, PETG, TPU, Resin) toggle independently, and a max print-time slider clamps the grid from 1 to 24 hours. All three combine with the search query and update a polite live-region counter — “Showing N of 15 models” — with an empty state that tells you exactly which control to loosen.
Every one of the fifteen tiles draws its model as inline isometric SVG on a radial-gradient plate with build-plate guide lines and a soft contact shadow, so each card reads like a turntable shot without a single image request. Hovering tilts the card in 3D and slides up a download button that runs a fake progress bar and fires a toast; likes toggle with an aria-pressed state. Below, a contest band counts down to entry close in real time, a fresh-makes row pairs mini plates with maker comments, and a leaderboard ranks top designers with medal chips and proportional points bars.
How this look is built
The information architecture is in the spirit of Printables/Thingiverse-style model communities, but everything here is original and drawn from scratch. CSS Grid with repeat(auto-fill, minmax()) handles the render grid at every width without a single breakpoint for the columns themselves; position: sticky layers the header at top: 0 and the filter rail at top: 68px so both stay reachable while scrolling; the turntable plates are pure radial gradients plus inline SVG generated in JS, which keeps the page zero-request and infinitely recolorable; and an IntersectionObserver staggers card reveals instead of a scroll listener, so the browser does the throttling. The 3D hover is a single perspective() + rotateX/rotateY transform on a transform-style: preserve-3d card — compositor-only work, unlike the old margin/top hover tricks that forced layout on every frame. Filtering toggles the hidden attribute rather than rebuilding the DOM, so grid positions animate smoothly and the observer state survives.
Illustrative UI only — always follow real safety guidance when working with tools, electronics, or repairs.