Job Board — Tech / Startup Landing
A dark, developer-cool landing page for a tech and startup job board. A grid-lit hero pairs animated count-up stats with a live terminal motif that types out a match-and-apply session. Below it sit curated startup roles with salary bands and remote badges, category filters, an interactive salary-transparency card driven by a seniority slider, a tech-stack chip cloud that totals matching roles, a why-us grid for engineers, and an email capture CTA. Built with vanilla JS, scroll reveal, and a toast helper.
MCP
Code
:root {
--bg: #0b0e14;
--bg-2: #0e131c;
--surface: #121826;
--surface-2: #161e2e;
--line: rgba(148, 163, 184, 0.14);
--line-2: rgba(148, 163, 184, 0.26);
--ink: #e7ecf3;
--ink-2: #aab4c4;
--muted: #7c889b;
--brand: #3b82f6;
--brand-d: #2563eb;
--accent: #22d3ee;
--accent-2: #818cf8;
--mono-glow: #5eead4;
--ok: #34d399;
--warn: #fbbf24;
--danger: #f87171;
--new: #38bdf8;
--r-sm: 8px;
--r-md: 14px;
--r-lg: 20px;
--r-xl: 26px;
--shadow: 0 18px 50px -22px rgba(0, 0, 0, 0.8);
--shadow-glow: 0 0 0 1px rgba(59, 130, 246, 0.25), 0 20px 60px -28px rgba(34, 211, 238, 0.35);
--sans: "Inter", system-ui, -apple-system, sans-serif;
--mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", monospace;
--maxw: 1160px;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
margin: 0;
font-family: var(--sans);
background: var(--bg);
color: var(--ink);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
}
h1, h2, h3, h4 { line-height: 1.12; margin: 0; letter-spacing: -0.02em; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; }
.wrap { width: min(var(--maxw), 92%); margin-inline: auto; }
.skip {
position: absolute; left: -999px; top: 8px; z-index: 100;
background: var(--brand); color: #fff; padding: 10px 16px; border-radius: var(--r-sm);
}
.skip:focus { left: 16px; }
.kicker {
display: inline-block; font: 600 12px/1 var(--mono);
letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent);
margin-bottom: 12px;
}
.muted { color: var(--ink-2); }
.grad {
background: linear-gradient(100deg, var(--accent), var(--accent-2));
-webkit-background-clip: text; background-clip: text; color: transparent;
}
/* Buttons */
.btn {
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
font: 600 14px/1 var(--sans); padding: 11px 18px; border-radius: var(--r-sm);
cursor: pointer; border: 1px solid transparent; transition: transform .15s ease, background .2s, box-shadow .2s, border-color .2s;
white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn-solid {
background: linear-gradient(180deg, var(--brand), var(--brand-d)); color: #fff;
box-shadow: 0 8px 24px -10px rgba(59, 130, 246, 0.7);
}
.btn-solid:hover { box-shadow: 0 10px 30px -8px rgba(59, 130, 246, 0.9); transform: translateY(-1px); }
.btn-ghost {
background: rgba(148, 163, 184, 0.06); color: var(--ink); border-color: var(--line-2);
}
.btn-ghost:hover { background: rgba(148, 163, 184, 0.12); border-color: var(--accent); color: #fff; }
/* Nav */
.nav {
position: sticky; top: 0; z-index: 40;
background: rgba(11, 14, 20, 0.78);
backdrop-filter: blur(14px);
border-bottom: 1px solid var(--line);
}
.nav-inner { display: flex; align-items: center; gap: 20px; height: 66px; }
.brand { display: inline-flex; align-items: center; gap: 9px; font-weight: 800; font-size: 18px; }
.brand-mark {
font: 700 14px/1 var(--mono); color: var(--bg);
background: linear-gradient(135deg, var(--accent), var(--accent-2));
padding: 6px 7px; border-radius: 7px;
}
.brand-name { letter-spacing: -0.03em; }
.nav-links { display: flex; gap: 26px; margin-left: 14px; }
.nav-links a { color: var(--ink-2); font-weight: 500; font-size: 14.5px; position: relative; }
.nav-links a:hover { color: #fff; }
.nav-links a::after {
content: ""; position: absolute; left: 0; bottom: -6px; height: 2px; width: 0;
background: var(--accent); transition: width .2s;
}
.nav-links a:hover::after { width: 100%; }
.nav-cta { margin-left: auto; display: flex; gap: 10px; }
.nav-toggle {
display: none; margin-left: auto; flex-direction: column; gap: 5px;
background: none; border: 0; cursor: pointer; padding: 8px;
}
.nav-toggle span { width: 22px; height: 2px; background: var(--ink); border-radius: 2px; transition: .25s; }
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
.mobile-nav {
display: none; flex-direction: column; gap: 4px; padding: 8px 4% 18px;
border-bottom: 1px solid var(--line); background: var(--bg-2);
}
.mobile-nav a { padding: 12px 8px; color: var(--ink-2); font-weight: 500; border-radius: var(--r-sm); }
.mobile-nav a:hover { background: rgba(148,163,184,.07); color: #fff; }
.mobile-nav.open { display: flex; }
/* Hero */
.hero { position: relative; padding: 70px 0 0; overflow: hidden; background: radial-gradient(1100px 540px at 78% -8%, rgba(34,211,238,.12), transparent 60%), radial-gradient(900px 500px at 8% 0%, rgba(129,140,248,.12), transparent 60%); }
.hero-grid {
position: absolute; inset: 0; pointer-events: none; opacity: .5;
background-image: linear-gradient(var(--line) 1px, transparent 1px), linear-gradient(90deg, var(--line) 1px, transparent 1px);
background-size: 52px 52px;
mask-image: radial-gradient(900px 520px at 60% 0%, #000 30%, transparent 75%);
}
.hero-inner {
position: relative; display: grid; grid-template-columns: 1.05fr .95fr; gap: 48px; align-items: center;
}
.hero-copy h1 { font-size: clamp(2.2rem, 5vw, 3.6rem); font-weight: 800; margin: 16px 0 14px; }
.lead { font-size: 1.12rem; color: var(--ink-2); max-width: 30ch; }
.pill {
display: inline-flex; align-items: center; gap: 8px; font: 600 12.5px/1 var(--mono);
padding: 7px 12px; border-radius: 999px; border: 1px solid var(--line-2);
background: rgba(148,163,184,.05); color: var(--ink-2);
}
.pill-live .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 0 rgba(52,211,153,.6); animation: ping 1.8s infinite; }
@keyframes ping { 0% { box-shadow: 0 0 0 0 rgba(52,211,153,.5);} 70% { box-shadow: 0 0 0 7px rgba(52,211,153,0);} 100% { box-shadow: 0 0 0 0 rgba(52,211,153,0);} }
.hero-search {
display: flex; align-items: center; gap: 8px; margin: 26px 0 16px;
background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-md);
padding: 7px 7px 7px 14px; max-width: 480px; transition: border-color .2s, box-shadow .2s;
}
.hero-search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 4px rgba(34,211,238,.14); }
.hero-search-ic { color: var(--muted); font-size: 18px; }
.hero-search input {
flex: 1; background: none; border: 0; outline: none; color: var(--ink);
font: 500 15px/1 var(--sans); min-width: 0;
}
.hero-search input::placeholder { color: var(--muted); }
.hero-tags { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
font: 500 13px/1 var(--mono); color: var(--ink-2);
background: rgba(148,163,184,.06); border: 1px solid var(--line);
padding: 8px 12px; border-radius: 999px; cursor: pointer; transition: .18s;
}
.chip:hover, .chip.on { color: var(--bg); background: var(--accent); border-color: var(--accent); }
/* Terminal */
.hero-term {
background: linear-gradient(180deg, #0d1320, #0a0f1a); border: 1px solid var(--line-2);
border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-glow);
}
.term-bar { display: flex; align-items: center; gap: 7px; padding: 12px 14px; border-bottom: 1px solid var(--line); background: rgba(255,255,255,.02); }
.tb-dot { width: 11px; height: 11px; border-radius: 50%; }
.tb-dot.r { background: #f87171; } .tb-dot.y { background: #fbbf24; } .tb-dot.g { background: #34d399; }
.tb-title { margin-left: 8px; font: 500 12.5px/1 var(--mono); color: var(--muted); }
.term-body { margin: 0; padding: 18px 18px 22px; font: 500 13px/1.85 var(--mono); color: var(--ink-2); overflow-x: auto; }
.c-prompt { color: var(--accent); } .c-dim { color: var(--muted); }
.c-ok { color: var(--ok); } .c-num { color: var(--mono-glow); } .c-str { color: #fcd34d; }
.c-key { color: var(--accent-2); display: inline-block; width: 52px; }
.cursor { color: var(--accent); animation: blink 1s steps(2) infinite; }
@keyframes blink { 50% { opacity: 0; } }
/* Hero stats */
.hero-stats {
position: relative; display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px;
margin: 58px auto 0; padding: 22px 26px; border-top: 1px solid var(--line);
border-bottom: 1px solid var(--line);
}
.hero-stats div { text-align: center; }
.hero-stats strong { display: block; font: 800 1.7rem/1 var(--sans); color: #fff; letter-spacing: -0.03em; }
.hero-stats span { font: 500 12.5px/1 var(--mono); color: var(--muted); text-transform: uppercase; letter-spacing: .08em; }
/* Logos */
.logos { padding: 40px 0 8px; text-align: center; }
.logos-label { font: 500 12px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
.logos-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 30px 42px; margin-top: 20px; }
.logo { font: 700 18px/1 var(--sans); color: var(--ink-2); opacity: .7; transition: .2s; letter-spacing: -.02em; }
.logo:hover { opacity: 1; color: var(--accent); }
/* Sections */
.section { padding: 78px 0; }
.sec-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 34px; flex-wrap: wrap; }
.sec-head h2 { font-size: clamp(1.6rem, 3.4vw, 2.3rem); font-weight: 800; }
.sec-head.center { flex-direction: column; align-items: center; text-align: center; }
/* Filters */
.filters { display: flex; gap: 8px; flex-wrap: wrap; }
.fbtn {
font: 600 13px/1 var(--sans); color: var(--ink-2); background: rgba(148,163,184,.05);
border: 1px solid var(--line); padding: 9px 15px; border-radius: 999px; cursor: pointer; transition: .18s;
}
.fbtn:hover { color: #fff; border-color: var(--line-2); }
.fbtn.is-active { color: var(--bg); background: var(--accent); border-color: var(--accent); }
/* Role list */
.role-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
.role {
position: relative; display: flex; flex-direction: column; gap: 14px;
background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
padding: 20px; transition: transform .2s, border-color .2s, box-shadow .2s;
}
.role:hover { transform: translateY(-3px); border-color: var(--line-2); box-shadow: var(--shadow); }
.role-top { display: flex; align-items: flex-start; gap: 13px; }
.role-logo {
flex: none; width: 44px; height: 44px; display: grid; place-items: center;
border-radius: 11px; font: 700 15px/1 var(--mono); color: var(--bg);
background: var(--lg, linear-gradient(135deg, var(--accent), var(--accent-2)));
}
.role-head { flex: 1; min-width: 0; }
.role-title { font-size: 1.05rem; font-weight: 700; color: #fff; }
.role-company { font: 500 13.5px/1.4 var(--sans); color: var(--ink-2); margin-top: 3px; }
.role-company .stage { color: var(--accent); font-family: var(--mono); font-size: 12px; }
.save {
flex: none; width: 34px; height: 34px; display: grid; place-items: center;
background: rgba(148,163,184,.06); border: 1px solid var(--line); border-radius: 9px;
cursor: pointer; color: var(--muted); font-size: 16px; transition: .18s;
}
.save:hover { color: var(--accent); border-color: var(--line-2); }
.save.saved { color: var(--warn); border-color: var(--warn); background: rgba(251,191,36,.1); }
.role-tags { display: flex; flex-wrap: wrap; gap: 7px; }
.tag {
font: 500 12px/1 var(--mono); color: var(--ink-2); background: rgba(148,163,184,.06);
border: 1px solid var(--line); padding: 6px 9px; border-radius: 7px;
}
.tag.remote { color: var(--ok); border-color: rgba(52,211,153,.3); background: rgba(52,211,153,.08); }
.tag.new { color: var(--new); border-color: rgba(56,189,248,.3); background: rgba(56,189,248,.08); }
.role-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: auto; padding-top: 4px; }
.role-salary { font: 700 14px/1 var(--mono); color: var(--mono-glow); }
.role-salary span { color: var(--muted); font-weight: 400; font-size: 12px; }
.role-apply {
font: 600 13px/1 var(--sans); color: var(--accent); background: rgba(34,211,238,.08);
border: 1px solid rgba(34,211,238,.28); padding: 8px 14px; border-radius: var(--r-sm);
cursor: pointer; transition: .18s;
}
.role-apply:hover { background: var(--accent); color: var(--bg); }
.empty { text-align: center; color: var(--muted); padding: 40px; font-family: var(--mono); }
/* Salary section */
.salary-sec { background: linear-gradient(180deg, var(--bg), var(--bg-2)); border-block: 1px solid var(--line); }
.salary-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 50px; align-items: center; }
.salary-grid h2 { font-size: clamp(1.6rem, 3.2vw, 2.2rem); margin-bottom: 14px; }
.checks { list-style: none; padding: 0; margin: 22px 0 0; display: grid; gap: 12px; }
.checks li { position: relative; padding-left: 30px; color: var(--ink-2); font-size: 15px; }
.checks li::before {
content: "✓"; position: absolute; left: 0; top: -1px; width: 20px; height: 20px;
display: grid; place-items: center; border-radius: 6px; font-size: 12px; font-weight: 700;
color: var(--bg); background: var(--ok);
}
.salary-card {
background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-lg);
padding: 26px; box-shadow: var(--shadow);
}
.sc-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 18px; }
.sc-level { font: 700 1rem/1 var(--sans); color: #fff; }
.sc-range { font: 700 1.4rem/1 var(--mono); color: var(--mono-glow); }
input[type="range"] { width: 100%; accent-color: var(--accent); cursor: pointer; height: 6px; }
.sc-ticks { display: flex; justify-content: space-between; margin: 10px 2px 22px; font: 500 11.5px/1 var(--mono); color: var(--muted); }
.sc-bars { display: grid; gap: 14px; }
.sc-bar { display: grid; grid-template-columns: 64px 1fr 58px; align-items: center; gap: 12px; }
.sc-bar span { font: 500 12.5px/1 var(--mono); color: var(--ink-2); }
.sc-bar b { font: 700 13px/1 var(--mono); color: #fff; text-align: right; }
.bar { height: 9px; background: rgba(148,163,184,.1); border-radius: 99px; overflow: hidden; }
.bar i { display: block; height: 100%; width: var(--w); border-radius: 99px; background: linear-gradient(90deg, var(--brand), var(--accent)); transition: width .5s cubic-bezier(.2,.8,.2,1); }
/* Stacks */
.stack-cloud { display: flex; flex-wrap: wrap; gap: 11px; }
.stack {
position: relative; font: 600 14px/1 var(--mono); color: var(--ink-2);
background: var(--surface); border: 1px solid var(--line-2); padding: 11px 16px;
border-radius: 999px; cursor: pointer; transition: .18s; display: inline-flex; align-items: center; gap: 8px;
}
.stack::after {
content: attr(data-c); font: 600 11px/1 var(--sans); color: var(--muted);
background: rgba(148,163,184,.1); padding: 3px 6px; border-radius: 99px;
}
.stack:hover { border-color: var(--accent); color: #fff; }
.stack.on { color: var(--bg); background: var(--accent); border-color: var(--accent); }
.stack.on::after { color: var(--bg); background: rgba(11,14,20,.18); }
.stack-summary { margin-top: 22px; color: var(--ink-2); font-size: 15px; }
.stack-summary strong { color: var(--mono-glow); font-family: var(--mono); }
/* Why */
.why-sec { background: var(--bg-2); border-block: 1px solid var(--line); }
.why-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.why-card {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md);
padding: 24px 22px; transition: transform .2s, border-color .2s;
}
.why-card:hover { transform: translateY(-4px); border-color: var(--accent); }
.why-ic {
display: inline-grid; place-items: center; width: 44px; height: 44px; font-size: 20px;
border-radius: 12px; background: rgba(34,211,238,.1); border: 1px solid rgba(34,211,238,.25);
color: var(--accent); margin-bottom: 16px;
}
.why-card h3 { font-size: 1.08rem; font-weight: 700; color: #fff; margin-bottom: 8px; }
.why-card p { color: var(--ink-2); font-size: 14.5px; }
/* CTA */
.cta-sec { position: relative; padding: 86px 0; overflow: hidden; background: radial-gradient(900px 460px at 50% 120%, rgba(59,130,246,.22), transparent 60%); border-top: 1px solid var(--line); }
.cta-grid {
position: absolute; inset: 0; opacity: .4;
background-image: linear-gradient(var(--line) 1px, transparent 1px), linear-gradient(90deg, var(--line) 1px, transparent 1px);
background-size: 48px 48px; mask-image: radial-gradient(700px 360px at 50% 100%, #000, transparent 70%);
}
.cta-inner { position: relative; text-align: center; max-width: 620px; }
.cta-inner h2 { font-size: clamp(1.7rem, 3.6vw, 2.5rem); font-weight: 800; margin-bottom: 12px; }
.cta-inner p { color: var(--ink-2); font-size: 1.06rem; }
.cta-form { display: flex; gap: 10px; margin: 26px auto 12px; max-width: 440px; }
.cta-form input {
flex: 1; background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-sm);
padding: 13px 15px; color: var(--ink); font: 500 15px var(--sans); outline: none; min-width: 0;
}
.cta-form input:focus { border-color: var(--accent); box-shadow: 0 0 0 4px rgba(34,211,238,.14); }
.cta-inner small { color: var(--muted); font: 500 13px var(--mono); }
/* Footer */
.footer { border-top: 1px solid var(--line); padding: 56px 0 28px; background: var(--bg-2); }
.foot-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 28px; }
.foot-tag { color: var(--muted); margin-top: 12px; font-size: 14px; max-width: 24ch; }
.foot-col h4 { font: 600 12.5px/1 var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--ink); margin-bottom: 14px; }
.foot-col a { display: block; color: var(--ink-2); font-size: 14px; padding: 5px 0; transition: color .15s; }
.foot-col a:hover { color: var(--accent); }
.foot-bottom { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 40px; padding-top: 22px; border-top: 1px solid var(--line); color: var(--muted); font-size: 13px; }
.foot-mono { font-family: var(--mono); }
/* Toast */
.toast {
position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 20px);
background: var(--surface-2); color: var(--ink); border: 1px solid var(--line-2);
padding: 13px 20px; border-radius: var(--r-md); font: 600 14px var(--sans);
box-shadow: var(--shadow); opacity: 0; pointer-events: none; transition: .3s; z-index: 80;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast b { color: var(--accent); }
/* Reveal */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity .6s ease, transform .6s ease; }
.reveal.in { opacity: 1; transform: none; }
/* Responsive */
@media (max-width: 900px) {
.hero-inner { grid-template-columns: 1fr; gap: 36px; }
.hero-term { order: 2; }
.salary-grid { grid-template-columns: 1fr; gap: 32px; }
.why-grid { grid-template-columns: repeat(2, 1fr); }
.role-list { grid-template-columns: 1fr; }
.foot-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 760px) {
.nav-links, .nav-cta { display: none; }
.nav-toggle { display: flex; }
}
@media (max-width: 520px) {
.section { padding: 56px 0; }
.hero { padding-top: 48px; }
.hero-stats { grid-template-columns: 1fr 1fr; gap: 18px 10px; padding: 22px 8px; }
.why-grid { grid-template-columns: 1fr; }
.foot-grid { grid-template-columns: 1fr; gap: 22px; }
.cta-form, .hero-search { flex-wrap: wrap; }
.cta-form .btn, .hero-search .btn { width: 100%; }
.sec-head { align-items: flex-start; }
.lead { max-width: none; }
.foot-bottom { flex-direction: column; align-items: flex-start; gap: 6px; }
}
@media (prefers-reduced-motion: reduce) {
* { animation: none !important; scroll-behavior: auto; }
.reveal { opacity: 1; transform: none; transition: none; }
}(function () {
"use strict";
/* ---------- Toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer;
function toast(msg) {
if (!toastEl) return;
toastEl.innerHTML = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 2600);
}
/* ---------- Role data ---------- */
var ROLES = [
{ title: "Staff Platform Engineer", company: "Nimbus", stage: "Series B", logo: "◈", lg: "linear-gradient(135deg,#22d3ee,#3b82f6)", salary: "$185k – $230k", remote: true, fresh: true, cats: ["Backend", "Remote"], tags: ["Rust", "Kubernetes", "Go"] },
{ title: "Senior Frontend Engineer", company: "Forge", stage: "Series A", logo: "⬡", lg: "linear-gradient(135deg,#818cf8,#c084fc)", salary: "$155k – $190k", remote: true, fresh: true, cats: ["Frontend", "Remote"], tags: ["React", "TypeScript", "GraphQL"] },
{ title: "ML Research Engineer", company: "Quanta", stage: "Seed", logo: "⟁", lg: "linear-gradient(135deg,#34d399,#22d3ee)", salary: "$170k – $215k", remote: false, fresh: false, cats: ["AI/ML"], tags: ["PyTorch", "Python", "CUDA"] },
{ title: "Backend Engineer, Payments", company: "Loopback", stage: "Series B", logo: "◍", lg: "linear-gradient(135deg,#fbbf24,#f87171)", salary: "$150k – $185k", remote: true, fresh: false, cats: ["Backend", "Remote"], tags: ["Go", "PostgreSQL", "gRPC"] },
{ title: "Full-Stack Engineer", company: "Vectra", stage: "Series A", logo: "⌬", lg: "linear-gradient(135deg,#38bdf8,#818cf8)", salary: "$140k – $175k", remote: true, fresh: true, cats: ["Frontend", "Backend", "Remote"], tags: ["Node.js", "React", "AWS"] },
{ title: "Infrastructure Engineer", company: "Cobalt", stage: "Series C", logo: "✦", lg: "linear-gradient(135deg,#a78bfa,#22d3ee)", salary: "$165k – $200k", remote: false, fresh: false, cats: ["Backend"], tags: ["Terraform", "Kubernetes", "Go"] },
{ title: "Applied AI Engineer", company: "Relay", stage: "Series A", logo: "⊟", lg: "linear-gradient(135deg,#f472b6,#818cf8)", salary: "$160k – $205k", remote: true, fresh: true, cats: ["AI/ML", "Remote"], tags: ["Python", "PyTorch", "LLMs"] },
{ title: "Senior iOS Engineer", company: "Drift", stage: "Series B", logo: "◐", lg: "linear-gradient(135deg,#fbbf24,#34d399)", salary: "$158k – $195k", remote: false, fresh: false, cats: ["Frontend"], tags: ["Swift", "SwiftUI", "Combine"] }
];
var saved = {};
function roleCard(r, i) {
var el = document.createElement("article");
el.className = "role reveal";
el.style.setProperty("--lg", r.lg);
el.dataset.cats = r.cats.join(",");
el.dataset.idx = i;
var tagHtml = "";
if (r.remote) tagHtml += '<span class="tag remote">⬡ Remote</span>';
if (r.fresh) tagHtml += '<span class="tag new">✦ New</span>';
r.tags.forEach(function (t) { tagHtml += '<span class="tag">' + t + "</span>"; });
el.innerHTML =
'<div class="role-top">' +
'<span class="role-logo" style="background:' + r.lg + '">' + r.logo + "</span>" +
'<div class="role-head">' +
'<div class="role-title">' + r.title + "</div>" +
'<div class="role-company">' + r.company + ' · <span class="stage">' + r.stage + "</span></div>" +
"</div>" +
'<button class="save" aria-label="Save ' + r.title + '" aria-pressed="false">♥</button>' +
"</div>" +
'<div class="role-tags">' + tagHtml + "</div>" +
'<div class="role-foot">' +
'<div class="role-salary">' + r.salary + ' <span>/ yr</span></div>' +
'<button class="role-apply">Apply →</button>' +
"</div>";
el.querySelector(".save").addEventListener("click", function () {
saved[i] = !saved[i];
this.classList.toggle("saved", saved[i]);
this.setAttribute("aria-pressed", saved[i] ? "true" : "false");
toast(saved[i] ? "Saved <b>" + r.title + "</b>" : "Removed from saved");
});
el.querySelector(".role-apply").addEventListener("click", function () {
toast("Intro sent to <b>" + r.company + "</b> — good luck!");
});
return el;
}
var roleList = document.getElementById("roleList");
var emptyState = document.getElementById("emptyState");
ROLES.forEach(function (r, i) { roleList.appendChild(roleCard(r, i)); });
/* ---------- Filters ---------- */
var filters = document.getElementById("filters");
if (filters) {
filters.addEventListener("click", function (e) {
var btn = e.target.closest(".fbtn");
if (!btn) return;
filters.querySelectorAll(".fbtn").forEach(function (b) {
b.classList.remove("is-active");
b.setAttribute("aria-selected", "false");
});
btn.classList.add("is-active");
btn.setAttribute("aria-selected", "true");
var f = btn.dataset.filter;
var shown = 0;
roleList.querySelectorAll(".role").forEach(function (card) {
var ok = f === "all" || card.dataset.cats.split(",").indexOf(f) !== -1;
card.style.display = ok ? "" : "none";
if (ok) shown++;
});
emptyState.hidden = shown !== 0;
});
}
/* ---------- Search + quick tags ---------- */
var searchForm = document.getElementById("searchForm");
var searchInput = document.getElementById("searchInput");
if (searchForm) {
searchForm.addEventListener("submit", function (e) {
e.preventDefault();
var q = (searchInput.value || "").trim();
if (!q) { toast("Type a role, stack, or keyword"); return; }
toast("Searching <b>" + q + "</b> across 1,284 roles…");
document.getElementById("roles").scrollIntoView({ behavior: "smooth" });
});
}
var quickTags = document.getElementById("quickTags");
if (quickTags) {
quickTags.addEventListener("click", function (e) {
var c = e.target.closest(".chip");
if (!c) return;
c.classList.toggle("on");
searchInput.value = c.dataset.tag;
toast("Filter: <b>" + c.dataset.tag + "</b>");
});
}
/* ---------- Salary slider ---------- */
var levels = [
{ name: "Junior", range: "$95k – $125k", base: "$110k", eq: "0.08%", bonus: "5%", w: [38, 18, 14] },
{ name: "Mid", range: "$130k – $160k", base: "$145k", eq: "0.18%", bonus: "8%", w: [55, 28, 20] },
{ name: "Senior", range: "$165k – $205k", base: "$185k", eq: "0.35%", bonus: "12%", w: [72, 46, 30] },
{ name: "Staff", range: "$200k – $250k", base: "$225k", eq: "0.55%", bonus: "16%", w: [86, 64, 40] },
{ name: "Principal", range: "$235k – $310k", base: "$272k", eq: "0.85%", bonus: "20%", w: [98, 82, 52] }
];
var range = document.getElementById("salaryRange");
function paintSalary() {
var L = levels[+range.value];
document.getElementById("scLevel").textContent = L.name;
document.getElementById("scRange").textContent = L.range;
document.getElementById("scBase").textContent = L.base;
document.getElementById("scEq").textContent = L.eq;
document.getElementById("scBonus").textContent = L.bonus;
var bars = document.querySelectorAll("#scBars .bar i");
bars[0].style.setProperty("--w", L.w[0] + "%");
bars[1].style.setProperty("--w", L.w[1] + "%");
bars[2].style.setProperty("--w", L.w[2] + "%");
}
if (range) { range.addEventListener("input", paintSalary); paintSalary(); }
/* ---------- Stack picker ---------- */
var stackCloud = document.getElementById("stackCloud");
var stackSummary = document.getElementById("stackSummary");
function updateStacks() {
var on = stackCloud.querySelectorAll(".stack.on");
var total = 0, names = [];
on.forEach(function (s) { total += +s.dataset.c; names.push(s.textContent.trim()); });
if (on.length === 0) {
stackSummary.innerHTML = "Select stacks to preview <strong>0</strong> matching roles.";
} else {
stackSummary.innerHTML = names.join(" + ") + " → <strong>" + total + "</strong> matching roles.";
}
}
if (stackCloud) {
stackCloud.addEventListener("click", function (e) {
var s = e.target.closest(".stack");
if (!s) return;
s.classList.toggle("on");
updateStacks();
});
}
var clearStacks = document.getElementById("clearStacks");
if (clearStacks) {
clearStacks.addEventListener("click", function () {
stackCloud.querySelectorAll(".stack.on").forEach(function (s) { s.classList.remove("on"); });
updateStacks();
toast("Stack filters cleared");
});
}
/* ---------- CTA form ---------- */
var ctaForm = document.getElementById("ctaForm");
if (ctaForm) {
ctaForm.addEventListener("submit", function (e) {
e.preventDefault();
var v = document.getElementById("ctaEmail").value.trim();
if (!v) return;
toast("Welcome aboard — check <b>" + v + "</b> to post your role");
ctaForm.reset();
});
}
/* ---------- Mobile nav ---------- */
var navToggle = document.getElementById("navToggle");
var mobileNav = document.getElementById("mobileNav");
if (navToggle) {
navToggle.addEventListener("click", function () {
var open = mobileNav.classList.toggle("open");
navToggle.setAttribute("aria-expanded", open ? "true" : "false");
});
mobileNav.addEventListener("click", function (e) {
if (e.target.tagName === "A") {
mobileNav.classList.remove("open");
navToggle.setAttribute("aria-expanded", "false");
}
});
}
/* ---------- Count-up stats ---------- */
function countUp(el) {
var target = +el.dataset.count;
var suffix = el.dataset.suffix || "";
var dur = 1100, start = null;
function step(ts) {
if (!start) start = ts;
var p = Math.min((ts - start) / dur, 1);
var eased = 1 - Math.pow(1 - p, 3);
var val = Math.round(target * eased);
el.textContent = val.toLocaleString() + suffix;
if (p < 1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
/* ---------- Scroll reveal ---------- */
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (en) {
if (en.isIntersecting) {
en.target.classList.add("in");
if (en.target.querySelector && en.target.classList.contains("hero-stats")) {
en.target.querySelectorAll("strong[data-count]").forEach(countUp);
}
io.unobserve(en.target);
}
});
}, { threshold: 0.14 });
document.querySelectorAll(".reveal").forEach(function (el) { io.observe(el); });
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Stackr — Tech & Startup Jobs for Engineers</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;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
<header class="nav" id="top">
<div class="wrap nav-inner">
<a class="brand" href="#top" aria-label="Stackr home">
<span class="brand-mark" aria-hidden="true"></></span>
<span class="brand-name">Stackr</span>
</a>
<nav class="nav-links" aria-label="Primary">
<a href="#roles">Roles</a>
<a href="#salary">Salary</a>
<a href="#stacks">Stacks</a>
<a href="#why">Why us</a>
</nav>
<div class="nav-cta">
<a class="btn btn-ghost" href="#roles">Browse jobs</a>
<a class="btn btn-solid" href="#cta">Post a role</a>
</div>
<button class="nav-toggle" id="navToggle" aria-label="Open menu" aria-expanded="false" aria-controls="mobileNav">
<span></span><span></span><span></span>
</button>
</div>
<nav class="mobile-nav" id="mobileNav" aria-label="Mobile">
<a href="#roles">Roles</a>
<a href="#salary">Salary</a>
<a href="#stacks">Stacks</a>
<a href="#why">Why us</a>
<a class="btn btn-solid" href="#cta">Post a role</a>
</nav>
</header>
<main id="main">
<!-- HERO -->
<section class="hero">
<div class="hero-grid"></div>
<div class="wrap hero-inner">
<div class="hero-copy reveal">
<span class="pill pill-live"><span class="dot"></span> 1,284 live roles · updated hourly</span>
<h1>Engineering jobs at startups that <span class="grad">ship fast</span>.</h1>
<p class="lead">Curated roles from funded teams. Transparent salaries, real tech stacks, no recruiter spam. Find your next build.</p>
<form class="hero-search" id="searchForm" role="search">
<span class="hero-search-ic" aria-hidden="true">⌕</span>
<input id="searchInput" type="search" placeholder="Search: Rust, Staff Eng, remote…" aria-label="Search roles" />
<button class="btn btn-solid" type="submit">Find roles</button>
</form>
<div class="hero-tags" id="quickTags">
<button class="chip" data-tag="Remote">Remote</button>
<button class="chip" data-tag="Rust">Rust</button>
<button class="chip" data-tag="React">React</button>
<button class="chip" data-tag="Go">Go</button>
<button class="chip" data-tag="AI/ML">AI/ML</button>
</div>
</div>
<div class="hero-term reveal" aria-hidden="true">
<div class="term-bar">
<span class="tb-dot r"></span><span class="tb-dot y"></span><span class="tb-dot g"></span>
<span class="tb-title">~/stackr — match</span>
</div>
<pre class="term-body"><code><span class="c-prompt">$</span> stackr match --stack=<span class="c-str">"rust,react"</span> --remote
<span class="c-dim">› scanning 1,284 funded roles…</span>
<span class="c-ok">✓</span> 37 strong matches
<span class="c-ok">✓</span> salary visible on <span class="c-num">100%</span>
<span class="c-ok">✓</span> avg response <span class="c-num">2.3</span> days
<span class="c-prompt">$</span> stackr apply --top
<span class="c-key">role</span> Staff Platform Engineer
<span class="c-key">team</span> Nimbus (Series B)
<span class="c-key">comp</span> <span class="c-num">$185k–$230k</span> + <span class="c-num">0.4%</span>
<span class="c-ok">✓</span> intro sent — good luck<span class="cursor">▋</span></code></pre>
</div>
</div>
<div class="hero-stats wrap reveal">
<div><strong data-count="1284">0</strong><span>live roles</span></div>
<div><strong data-count="420">0</strong><span>funded teams</span></div>
<div><strong data-count="100" data-suffix="%">0</strong><span>salaries shown</span></div>
<div><strong data-count="2" data-suffix="d">0</strong><span>avg reply</span></div>
</div>
</section>
<!-- LOGOS -->
<section class="logos reveal" aria-label="Hiring companies">
<p class="logos-label">Trusted by teams hiring right now</p>
<div class="logos-row">
<span class="logo">◈ Nimbus</span>
<span class="logo">⬡ Forge</span>
<span class="logo">⟁ Quanta</span>
<span class="logo">◍ Loopback</span>
<span class="logo">⌬ Vectra</span>
<span class="logo">✦ Cobalt</span>
<span class="logo">⊟ Relay</span>
</div>
</section>
<!-- ROLES -->
<section class="section" id="roles">
<div class="wrap">
<div class="sec-head reveal">
<div>
<span class="kicker">Curated roles</span>
<h2>Fresh from startups that interview fast</h2>
</div>
<div class="filters" id="filters" role="tablist" aria-label="Filter roles">
<button class="fbtn is-active" data-filter="all" role="tab" aria-selected="true">All</button>
<button class="fbtn" data-filter="Remote" role="tab" aria-selected="false">Remote</button>
<button class="fbtn" data-filter="Backend" role="tab" aria-selected="false">Backend</button>
<button class="fbtn" data-filter="Frontend" role="tab" aria-selected="false">Frontend</button>
<button class="fbtn" data-filter="AI/ML" role="tab" aria-selected="false">AI/ML</button>
</div>
</div>
<div class="role-list" id="roleList" aria-live="polite"><!-- injected --></div>
<p class="empty" id="emptyState" hidden>No roles match that filter — try another.</p>
</div>
</section>
<!-- SALARY TRANSPARENCY -->
<section class="section salary-sec" id="salary">
<div class="wrap salary-grid">
<div class="reveal">
<span class="kicker">Salary transparency</span>
<h2>Every role shows the band. No guessing games.</h2>
<p class="muted">We require a real compensation range before a role goes live. Drag the slider to see where roles sit by level.</p>
<ul class="checks">
<li>Base + equity shown on every listing</li>
<li>Filtered by location & remote policy</li>
<li>Reported, not estimated — verified by teams</li>
</ul>
</div>
<div class="salary-card reveal">
<div class="sc-head">
<span class="sc-level" id="scLevel">Senior</span>
<span class="sc-range" id="scRange">$165k – $205k</span>
</div>
<input type="range" id="salaryRange" min="0" max="4" step="1" value="2" aria-label="Seniority level" />
<div class="sc-ticks">
<span>Jr</span><span>Mid</span><span>Senior</span><span>Staff</span><span>Principal</span>
</div>
<div class="sc-bars" id="scBars">
<div class="sc-bar"><span>Base</span><div class="bar"><i style="--w:72%"></i></div><b id="scBase">$185k</b></div>
<div class="sc-bar"><span>Equity</span><div class="bar"><i style="--w:46%"></i></div><b id="scEq">0.35%</b></div>
<div class="sc-bar"><span>Bonus</span><div class="bar"><i style="--w:30%"></i></div><b id="scBonus">12%</b></div>
</div>
</div>
</div>
</section>
<!-- TECH STACKS -->
<section class="section" id="stacks">
<div class="wrap">
<div class="sec-head reveal">
<div>
<span class="kicker">Tech-stack filters</span>
<h2>Pick your stack. We match the rest.</h2>
</div>
<button class="btn btn-ghost" id="clearStacks" type="button">Clear</button>
</div>
<div class="stack-cloud reveal" id="stackCloud">
<button class="stack" data-c="142">Rust</button>
<button class="stack" data-c="318">React</button>
<button class="stack" data-c="205">TypeScript</button>
<button class="stack" data-c="176">Go</button>
<button class="stack" data-c="98">Python</button>
<button class="stack" data-c="64">Elixir</button>
<button class="stack" data-c="120">Kubernetes</button>
<button class="stack" data-c="87">PostgreSQL</button>
<button class="stack" data-c="73">GraphQL</button>
<button class="stack" data-c="156">Node.js</button>
<button class="stack" data-c="52">Swift</button>
<button class="stack" data-c="91">PyTorch</button>
</div>
<div class="stack-summary reveal" id="stackSummary">Select stacks to preview <strong>0</strong> matching roles.</div>
</div>
</section>
<!-- WHY US -->
<section class="section why-sec" id="why">
<div class="wrap">
<div class="sec-head center reveal">
<span class="kicker">Built for engineers</span>
<h2>Why builders pick Stackr</h2>
</div>
<div class="why-grid">
<article class="why-card reveal">
<span class="why-ic">⚡</span>
<h3>No recruiter spam</h3>
<p>You apply when you want. Teams reach out only if there's a real fit — and they show the comp first.</p>
</article>
<article class="why-card reveal">
<span class="why-ic">◎</span>
<h3>Real tech, no fluff</h3>
<p>Every listing names the actual stack, team size, and on-call reality. Read the README before you apply.</p>
</article>
<article class="why-card reveal">
<span class="why-ic">⏱</span>
<h3>Fast loops</h3>
<p>Median first reply is under three days. Most teams here run a tight 2–3 step interview.</p>
</article>
<article class="why-card reveal">
<span class="why-ic">⊞</span>
<h3>Equity you can read</h3>
<p>Percentage, strike, and dilution context where teams share it — so equity is more than a vibe.</p>
</article>
</div>
</div>
</section>
<!-- CTA -->
<section class="cta-sec" id="cta">
<div class="cta-grid" aria-hidden="true"></div>
<div class="wrap cta-inner reveal">
<h2>Hiring engineers? List your role in minutes.</h2>
<p>Post with a real salary band and reach builders who actually read the stack.</p>
<form class="cta-form" id="ctaForm">
<input type="email" id="ctaEmail" placeholder="[email protected]" aria-label="Work email" required />
<button class="btn btn-solid" type="submit">Get started</button>
</form>
<small>Free to post your first role · No card required</small>
</div>
</section>
</main>
<footer class="footer">
<div class="wrap foot-grid">
<div>
<a class="brand" href="#top">
<span class="brand-mark" aria-hidden="true"></></span>
<span class="brand-name">Stackr</span>
</a>
<p class="foot-tag">Tech & startup jobs, salary-first.</p>
</div>
<div class="foot-col">
<h4>Engineers</h4>
<a href="#roles">Browse roles</a>
<a href="#salary">Salary data</a>
<a href="#stacks">By stack</a>
</div>
<div class="foot-col">
<h4>Teams</h4>
<a href="#cta">Post a role</a>
<a href="#why">Why Stackr</a>
<a href="#cta">Pricing</a>
</div>
<div class="foot-col">
<h4>Company</h4>
<a href="#top">About</a>
<a href="#top">Blog</a>
<a href="#top">Careers</a>
</div>
</div>
<div class="wrap foot-bottom">
<span>© 2026 Stackr Labs — illustrative demo, fictional data.</span>
<span class="foot-mono">built with <coffee/></span>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Tech / Startup Landing
A full marketing landing for Stackr, a fictional salary-first job board for engineers. The dark #0b0e14 canvas is lit by a faint grid and dual color glows, with Inter for UI and JetBrains Mono for the developer-cool accents. The hero leads with a live-roles pill, a search field with quick stack chips, and a terminal panel whose blinking cursor sells a stackr match → stackr apply flow. A strip of animated count-up stats and a row of hiring-company logos closes the fold.
The body stacks five working sections. Curated roles render as a two-column card grid with company logos, remote and “new” badges, real salary bands, bookmark toggles, and an apply button — filterable by Remote, Backend, Frontend, and AI/ML. Salary transparency centers on a card whose seniority slider repaints the band plus base, equity, and bonus bars from Junior through Principal. Tech-stack filters are a chip cloud that sums per-stack role counts as you select. A why-us grid and a glowing CTA with email capture round it out, above a four-column footer.
Every interaction is vanilla JS: filtering, the salary slider, stack totals, search, bookmarks, the mobile nav, an IntersectionObserver scroll-reveal that also fires the count-up, and a shared toast() helper for feedback. The layout reflows cleanly from desktop down to ~360px and respects prefers-reduced-motion.
Illustrative UI only — fictional jobs & companies, not a real hiring platform.