Ticketing — Conference Landing
A clean, modern landing page for the fictional DevHorizon 2026 engineering conference. An indigo gridded hero pairs the event name, dates and San Francisco venue with a live early-bird countdown, headline stats and dual register calls to action. Below it sit a speakers grid with keynote badges, a four-track agenda built from accessible tabs, three pricing tiers with strikethrough early-bird rates, a stylized venue and travel block, a sponsor wall and a register form. Vanilla JS handles the tabs, countdown, scroll reveal and toast feedback.
MCP
Code
:root {
--brand: #4f46e5;
--brand-d: #4338ca;
--brand-l: #6366f1;
--ink: #0f172a;
--ink-2: #334155;
--muted: #64748b;
--bg: #ffffff;
--bg-alt: #f8fafc;
--surface: #ffffff;
--line: rgba(15, 23, 42, 0.1);
--line-2: rgba(15, 23, 42, 0.06);
--ok: #16a34a;
--warn: #d97706;
--danger: #dc2626;
--accent: #6366f1;
--r-sm: 8px;
--r-md: 14px;
--r-lg: 20px;
--shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.08);
--shadow-md: 0 8px 24px rgba(15, 23, 42, 0.1);
--shadow-lg: 0 24px 60px rgba(79, 70, 229, 0.22);
--maxw: 1120px;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: "Inter", system-ui, -apple-system, sans-serif;
font-size: 16px;
line-height: 1.5;
color: var(--ink);
background: var(--bg);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3 { line-height: 1.15; letter-spacing: -0.02em; margin: 0; }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; }
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
.sr-only {
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
position: absolute; left: 16px; top: -48px; z-index: 100;
background: var(--brand); color: #fff; padding: 10px 16px; border-radius: var(--r-sm);
transition: top 0.2s ease;
}
.skip-link:focus { top: 16px; }
:focus-visible { outline: 3px solid var(--brand-l); outline-offset: 2px; border-radius: 6px; }
/* ---------- Buttons ---------- */
.btn {
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
font: inherit; font-weight: 600; cursor: pointer; border: 1px solid transparent;
padding: 11px 20px; border-radius: var(--r-md); transition: transform 0.12s ease,
box-shadow 0.2s ease, background 0.2s ease, border-color 0.2s ease; white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn-lg { padding: 15px 28px; font-size: 1.02rem; }
.btn-block { width: 100%; }
.btn-primary { background: var(--brand); color: #fff; box-shadow: 0 6px 18px rgba(79, 70, 229, 0.32); }
.btn-primary:hover { background: var(--brand-d); box-shadow: 0 10px 26px rgba(79, 70, 229, 0.42); }
.btn-ghost { background: #fff; color: var(--ink); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--brand); color: var(--brand); }
/* ---------- Badges ---------- */
.badge {
display: inline-flex; align-items: center; gap: 5px;
font-size: 0.72rem; font-weight: 700; letter-spacing: 0.02em;
padding: 4px 9px; border-radius: 999px;
background: #eef2ff; color: var(--brand-d); border: 1px solid rgba(79, 70, 229, 0.18);
}
.badge-keynote { background: var(--brand); color: #fff; border-color: transparent; }
.badge-work { background: #ecfdf5; color: #047857; border-color: rgba(4, 120, 87, 0.2); }
.badge-low { background: #fff7ed; color: var(--warn); border-color: rgba(217, 119, 6, 0.22); }
/* ---------- Nav ---------- */
.nav {
position: sticky; top: 0; z-index: 50;
background: rgba(255, 255, 255, 0.82);
backdrop-filter: saturate(180%) blur(12px);
border-bottom: 1px solid var(--line-2);
}
.nav-inner { display: flex; align-items: center; gap: 20px; height: 66px; }
.brand { display: inline-flex; align-items: center; gap: 10px; font-weight: 800; font-size: 1.12rem; }
.brand-mark {
display: grid; place-items: center; width: 34px; height: 34px; border-radius: 9px;
background: linear-gradient(135deg, var(--brand-l), var(--brand-d));
color: #fff; font-weight: 800; font-size: 0.85rem; letter-spacing: 0.02em;
}
.brand-yr { color: var(--brand); }
.nav-links { display: flex; gap: 22px; margin-left: auto; font-weight: 500; color: var(--ink-2); }
.nav-links a { position: relative; padding: 4px 0; }
.nav-links a::after {
content: ""; position: absolute; left: 0; bottom: -2px; height: 2px; width: 0;
background: var(--brand); transition: width 0.2s ease;
}
.nav-links a:hover { color: var(--ink); }
.nav-links a:hover::after { width: 100%; }
.nav-cta { margin-left: 4px; }
.nav-toggle {
display: none; flex-direction: column; gap: 5px; background: none; border: 0;
padding: 8px; cursor: pointer; margin-left: auto;
}
.nav-toggle span { width: 22px; height: 2px; background: var(--ink); border-radius: 2px; transition: 0.2s ease; }
.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: flex; flex-direction: column; gap: 4px; padding: 12px 24px 20px;
border-bottom: 1px solid var(--line-2); background: #fff;
}
.mobile-nav a { padding: 12px 8px; border-radius: var(--r-sm); font-weight: 600; color: var(--ink-2); }
.mobile-nav a:hover { background: var(--bg-alt); color: var(--ink); }
.mobile-nav .btn { margin-top: 6px; }
/* ---------- Hero ---------- */
.hero { position: relative; overflow: hidden; color: #fff; }
.hero-bg {
position: absolute; inset: 0; z-index: 0;
background:
radial-gradient(60% 80% at 80% 10%, rgba(99, 102, 241, 0.55), transparent 60%),
radial-gradient(50% 60% at 10% 90%, rgba(129, 140, 248, 0.45), transparent 60%),
linear-gradient(135deg, #1e1b4b 0%, #312e81 45%, #4338ca 100%);
}
.hero-bg::after {
content: ""; position: absolute; inset: 0;
background-image: linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
background-size: 44px 44px; mask-image: radial-gradient(70% 70% at 50% 30%, #000, transparent);
}
.hero-inner { position: relative; z-index: 1; padding: 84px 24px 92px; max-width: 880px; }
.eyebrow {
display: inline-flex; align-items: center; gap: 8px; margin: 0 0 18px;
font-weight: 600; font-size: 0.86rem; padding: 7px 14px; border-radius: 999px;
background: rgba(255, 255, 255, 0.12); border: 1px solid rgba(255, 255, 255, 0.2);
}
.pulse { width: 8px; height: 8px; border-radius: 50%; background: #a5b4fc; box-shadow: 0 0 0 0 rgba(165, 180, 252, 0.7); animation: pulse 2s infinite; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(165, 180, 252, 0.6); } 70% { box-shadow: 0 0 0 10px rgba(165, 180, 252, 0); } 100% { box-shadow: 0 0 0 0 rgba(165, 180, 252, 0); } }
.hero h1 { font-size: clamp(2.6rem, 6.5vw, 4.6rem); font-weight: 800; }
.hero-sub { display: inline-block; margin-top: 8px; font-size: clamp(1.05rem, 2.4vw, 1.6rem); font-weight: 600; color: #c7d2fe; letter-spacing: -0.01em; }
.hero-meta { display: flex; flex-wrap: wrap; gap: 10px; margin: 22px 0 0; }
.meta-pill {
padding: 8px 14px; border-radius: var(--r-md); font-size: 0.92rem;
background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.16);
}
.meta-pill strong { font-weight: 700; }
.hero-lede { max-width: 560px; margin: 22px 0 0; font-size: 1.1rem; color: #dde3fb; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin: 30px 0 0; }
.countdown {
margin: 38px 0 0; padding: 18px 20px; border-radius: var(--r-lg);
background: rgba(255, 255, 255, 0.08); border: 1px solid rgba(255, 255, 255, 0.16);
backdrop-filter: blur(6px); max-width: 480px;
}
.cd-label { margin: 0 0 12px; font-weight: 600; font-size: 0.84rem; color: #c7d2fe; display: flex; align-items: center; gap: 8px; }
.cd-label .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--warn); }
.cd-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.cd-cell {
display: flex; flex-direction: column; align-items: center; gap: 4px;
padding: 12px 6px; border-radius: var(--r-md); background: rgba(255, 255, 255, 0.1);
}
.cd-num { font-size: 1.85rem; font-weight: 800; font-variant-numeric: tabular-nums; letter-spacing: -0.02em; }
.cd-unit { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: #c7d2fe; }
.hero-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin: 40px 0 0; max-width: 560px; }
.hero-stats div { padding: 0; }
.hero-stats dt { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; color: #c7d2fe; }
.hero-stats dd { margin: 4px 0 0; font-size: 1.7rem; font-weight: 800; }
/* ---------- Sections ---------- */
.section { padding: 84px 0; }
.section-alt { background: var(--bg-alt); border-top: 1px solid var(--line-2); border-bottom: 1px solid var(--line-2); }
.section-head { max-width: 640px; margin: 0 0 40px; }
.kicker { margin: 0 0 10px; font-weight: 700; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--brand); }
.kicker-light { color: #c7d2fe; }
.section-head h2 { font-size: clamp(1.9rem, 4vw, 2.7rem); font-weight: 800; }
.section-lede { margin: 14px 0 0; color: var(--muted); font-size: 1.08rem; }
/* ---------- Speakers ---------- */
.speakers-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.speaker {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
overflow: hidden; box-shadow: var(--shadow-sm); transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.speaker:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: rgba(79, 70, 229, 0.3); }
.speaker-photo {
height: 168px; display: grid; place-items: center; color: rgba(255, 255, 255, 0.9);
font-size: 2.4rem; font-weight: 800; letter-spacing: 0.02em; position: relative;
}
.speaker-photo[data-grad="a"] { background: linear-gradient(135deg, #6366f1, #8b5cf6); }
.speaker-photo[data-grad="b"] { background: linear-gradient(135deg, #4338ca, #0ea5e9); }
.speaker-photo[data-grad="c"] { background: linear-gradient(135deg, #7c3aed, #ec4899); }
.speaker-photo[data-grad="d"] { background: linear-gradient(135deg, #0f766e, #4f46e5); }
.speaker-photo[data-grad="e"] { background: linear-gradient(135deg, #f59e0b, #4f46e5); }
.speaker-photo[data-grad="f"] { background: linear-gradient(135deg, #1e293b, #6366f1); }
.speaker-body { padding: 16px 18px 20px; }
.speaker-body h3 { font-size: 1.18rem; margin: 10px 0 2px; }
.speaker-role { margin: 0 0 8px; color: var(--brand-d); font-weight: 600; font-size: 0.88rem; }
.speaker-topic { margin: 0; color: var(--muted); font-size: 0.94rem; }
.speakers-more { margin: 32px 0 0; text-align: center; color: var(--muted); }
.speakers-more a { color: var(--brand); font-weight: 600; }
/* ---------- Tabs / Agenda ---------- */
.tabs { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; box-shadow: var(--shadow-sm); }
.tablist { display: flex; gap: 2px; overflow-x: auto; padding: 8px; background: var(--bg-alt); border-bottom: 1px solid var(--line-2); }
.tab {
font: inherit; font-weight: 600; color: var(--ink-2); background: transparent; border: 0; cursor: pointer;
padding: 10px 18px; border-radius: var(--r-md); white-space: nowrap; transition: background 0.18s ease, color 0.18s ease;
}
.tab:hover { color: var(--ink); background: rgba(79, 70, 229, 0.08); }
.tab[aria-selected="true"] { background: var(--brand); color: #fff; box-shadow: 0 4px 12px rgba(79, 70, 229, 0.3); }
.tabpanel { padding: 8px 8px 14px; }
.tabpanel[hidden] { display: none; }
.agenda-list { list-style: none; margin: 0; padding: 0; }
.agenda-row {
display: flex; align-items: center; gap: 18px; padding: 16px 14px;
border-bottom: 1px solid var(--line-2); transition: background 0.15s ease;
}
.agenda-row:last-child { border-bottom: 0; }
.agenda-row:hover { background: var(--bg-alt); }
.ag-time { font-weight: 800; font-variant-numeric: tabular-nums; color: var(--brand-d); width: 56px; flex: none; }
.ag-body { flex: 1; min-width: 0; }
.ag-body h3 { font-size: 1.02rem; }
.ag-body p { margin: 3px 0 0; color: var(--muted); font-size: 0.88rem; }
/* ---------- Pricing ---------- */
.pricing-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; align-items: start; }
.price-card {
background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
padding: 26px 24px; box-shadow: var(--shadow-sm); transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.price-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.price-feat { border-color: var(--brand); box-shadow: var(--shadow-lg); position: relative; }
.price-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0 0 14px; }
.price-top h3 { font-size: 1.3rem; }
.price { margin: 0 0 18px; display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px; }
.price .was { color: var(--muted); text-decoration: line-through; font-size: 1.05rem; font-weight: 600; }
.price .now { font-size: 2.4rem; font-weight: 800; letter-spacing: -0.02em; }
.price .per { color: var(--muted); font-size: 0.86rem; font-weight: 500; width: 100%; }
.price-feats { list-style: none; margin: 0 0 22px; padding: 0; display: grid; gap: 10px; }
.price-feats li { position: relative; padding-left: 26px; color: var(--ink-2); font-size: 0.95rem; }
.price-feats li::before {
content: ""; position: absolute; left: 0; top: 3px; width: 16px; height: 16px; border-radius: 50%;
background: #ecfdf5 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%2316a34a'%3E%3Cpath d='M6.5 11.2 3.3 8l1.1-1.1 2.1 2.1 4.9-4.9L12.6 5.2z'/%3E%3C/svg%3E") center/14px no-repeat;
border: 1px solid rgba(22, 163, 74, 0.25);
}
/* ---------- Venue ---------- */
.venue-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: center; }
.venue-list { list-style: none; margin: 24px 0; padding: 0; display: grid; gap: 14px; }
.venue-list li { display: flex; align-items: baseline; gap: 14px; padding-bottom: 14px; border-bottom: 1px solid var(--line-2); color: var(--ink-2); }
.venue-list li:last-child { border-bottom: 0; }
.vt { flex: none; width: 76px; font-weight: 700; color: var(--brand-d); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; }
.venue-map {
position: relative; aspect-ratio: 4 / 3; border-radius: var(--r-lg); overflow: hidden;
background: linear-gradient(135deg, #eef2ff, #e0e7ff); border: 1px solid var(--line); box-shadow: var(--shadow-md);
}
.map-grid {
position: absolute; inset: 0;
background-image: linear-gradient(rgba(79, 70, 229, 0.14) 1px, transparent 1px),
linear-gradient(90deg, rgba(79, 70, 229, 0.14) 1px, transparent 1px);
background-size: 36px 36px;
}
.map-pin {
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
display: inline-flex; align-items: center; gap: 8px; background: #fff; color: var(--ink);
padding: 8px 14px; border-radius: 999px; font-weight: 700; font-size: 0.9rem; box-shadow: var(--shadow-md);
}
.pin-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 5px rgba(79, 70, 229, 0.2); }
/* ---------- Sponsors ---------- */
.sponsor-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.sponsor {
display: grid; place-items: center; height: 84px; border-radius: var(--r-md);
background: var(--surface); border: 1px solid var(--line); font-weight: 700; color: var(--ink-2);
letter-spacing: -0.01em; transition: transform 0.16s ease, color 0.16s ease, border-color 0.16s ease;
}
.sponsor:hover { transform: translateY(-3px); color: var(--brand); border-color: rgba(79, 70, 229, 0.35); }
/* ---------- Register CTA ---------- */
.register { padding: 72px 0; color: #fff; position: relative; overflow: hidden;
background: radial-gradient(60% 100% at 80% 0%, rgba(99, 102, 241, 0.6), transparent 60%), linear-gradient(135deg, #312e81, #4338ca); }
.register-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: center; }
.register-copy h2 { font-size: clamp(1.7rem, 3.4vw, 2.4rem); font-weight: 800; }
.register-copy p { margin: 14px 0 0; color: #dde3fb; max-width: 420px; }
.register-form {
display: grid; gap: 12px; background: rgba(255, 255, 255, 0.1); border: 1px solid rgba(255, 255, 255, 0.18);
padding: 22px; border-radius: var(--r-lg); backdrop-filter: blur(6px);
}
.register-form input, .register-form select {
font: inherit; padding: 13px 15px; border-radius: var(--r-md); border: 1px solid rgba(255, 255, 255, 0.25);
background: rgba(255, 255, 255, 0.95); color: var(--ink); width: 100%;
}
.register-form input::placeholder { color: var(--muted); }
.register-form .btn { margin-top: 2px; }
/* ---------- Footer ---------- */
.footer { background: #0f172a; color: #cbd5e1; padding: 48px 0; }
.footer-inner { display: flex; flex-wrap: wrap; align-items: center; gap: 18px 32px; }
.footer-brand { display: flex; align-items: center; gap: 12px; }
.footer-brand p { margin: 0; font-size: 0.9rem; }
.footer-nav { display: flex; gap: 20px; margin-left: auto; font-weight: 500; font-size: 0.92rem; }
.footer-nav a:hover { color: #fff; }
.footer-fine { width: 100%; margin: 8px 0 0; padding-top: 18px; border-top: 1px solid rgba(255, 255, 255, 0.1); font-size: 0.82rem; color: #94a3b8; }
/* ---------- Reveal ---------- */
.reveal { opacity: 0; transform: translateY(18px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.in { opacity: 1; transform: none; }
/* ---------- Toast ---------- */
.toast-host { position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%); z-index: 200; display: grid; gap: 10px; width: min(92vw, 380px); }
.toast {
background: var(--ink); color: #fff; padding: 13px 18px; border-radius: var(--r-md);
box-shadow: var(--shadow-md); font-weight: 500; display: flex; align-items: center; gap: 10px;
opacity: 0; transform: translateY(12px); transition: opacity 0.25s ease, transform 0.25s ease;
}
.toast.in { opacity: 1; transform: none; }
.toast::before { content: ""; width: 9px; height: 9px; border-radius: 50%; background: var(--brand-l); flex: none; }
/* ---------- Responsive ---------- */
@media (max-width: 900px) {
.speakers-grid { grid-template-columns: repeat(2, 1fr); }
.pricing-grid { grid-template-columns: 1fr; max-width: 460px; }
.venue-grid, .register-inner { grid-template-columns: 1fr; }
.sponsor-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 760px) {
.nav-links, .nav-cta { display: none; }
.nav-toggle { display: flex; }
}
@media (max-width: 520px) {
.wrap { padding: 0 18px; }
.section { padding: 56px 0; }
.hero-inner { padding: 60px 18px 64px; }
.speakers-grid { grid-template-columns: 1fr; }
.sponsor-grid { grid-template-columns: repeat(2, 1fr); }
.hero-stats { grid-template-columns: repeat(2, 1fr); gap: 18px; }
.cd-num { font-size: 1.5rem; }
.hero-actions .btn { flex: 1; }
.agenda-row { gap: 12px; flex-wrap: wrap; }
.footer-nav { margin-left: 0; }
}
@media (prefers-reduced-motion: reduce) {
* { scroll-behavior: auto; }
.reveal { opacity: 1; transform: none; transition: none; }
.pulse { animation: none; }
}(function () {
"use strict";
/* ---------- Toast helper ---------- */
var host = document.getElementById("toastHost");
function toast(msg) {
if (!host) return;
var el = document.createElement("div");
el.className = "toast";
el.setAttribute("role", "status");
el.textContent = msg;
host.appendChild(el);
requestAnimationFrame(function () { el.classList.add("in"); });
setTimeout(function () {
el.classList.remove("in");
setTimeout(function () { el.remove(); }, 280);
}, 3200);
}
/* ---------- Mobile nav ---------- */
var toggle = document.getElementById("navToggle");
var mobileNav = document.getElementById("mobileNav");
function closeNav() {
if (!toggle || !mobileNav) return;
toggle.setAttribute("aria-expanded", "false");
toggle.setAttribute("aria-label", "Open menu");
mobileNav.hidden = true;
}
if (toggle && mobileNav) {
toggle.addEventListener("click", function () {
var open = toggle.getAttribute("aria-expanded") === "true";
toggle.setAttribute("aria-expanded", String(!open));
toggle.setAttribute("aria-label", open ? "Open menu" : "Close menu");
mobileNav.hidden = open;
});
mobileNav.querySelectorAll("a").forEach(function (a) {
a.addEventListener("click", closeNav);
});
document.addEventListener("keydown", function (e) {
if (e.key === "Escape") closeNav();
});
}
/* ---------- Agenda tabs ---------- */
var tablist = document.querySelector(".tablist");
if (tablist) {
var tabs = Array.prototype.slice.call(tablist.querySelectorAll(".tab"));
function selectTab(tab) {
tabs.forEach(function (t) {
var selected = t === tab;
t.setAttribute("aria-selected", String(selected));
t.tabIndex = selected ? 0 : -1;
var panel = document.getElementById(t.getAttribute("aria-controls"));
if (panel) panel.hidden = !selected;
});
}
tabs.forEach(function (tab, i) {
tab.addEventListener("click", function () { selectTab(tab); });
tab.addEventListener("keydown", function (e) {
var next;
if (e.key === "ArrowRight") next = tabs[(i + 1) % tabs.length];
else if (e.key === "ArrowLeft") next = tabs[(i - 1 + tabs.length) % tabs.length];
else if (e.key === "Home") next = tabs[0];
else if (e.key === "End") next = tabs[tabs.length - 1];
if (next) { e.preventDefault(); selectTab(next); next.focus(); }
});
});
}
/* ---------- Countdown to early-bird deadline ---------- */
var cdGrid = document.getElementById("cdGrid");
if (cdGrid) {
// Deadline: 21 days from first load (stable per page view).
var deadline = new Date(Date.now() + 21 * 24 * 60 * 60 * 1000);
deadline.setHours(23, 59, 59, 0);
var cells = {
days: cdGrid.querySelector('[data-unit="days"]'),
hours: cdGrid.querySelector('[data-unit="hours"]'),
minutes: cdGrid.querySelector('[data-unit="minutes"]'),
seconds: cdGrid.querySelector('[data-unit="seconds"]')
};
function pad(n) { return String(n).padStart(2, "0"); }
function tick() {
var diff = deadline - Date.now();
if (diff <= 0) {
cells.days.textContent = cells.hours.textContent = cells.minutes.textContent = cells.seconds.textContent = "00";
clearInterval(timer);
return;
}
var s = Math.floor(diff / 1000);
cells.days.textContent = pad(Math.floor(s / 86400));
cells.hours.textContent = pad(Math.floor((s % 86400) / 3600));
cells.minutes.textContent = pad(Math.floor((s % 3600) / 60));
cells.seconds.textContent = pad(s % 60);
}
tick();
var timer = setInterval(tick, 1000);
}
/* ---------- Scroll reveal ---------- */
var reveals = document.querySelectorAll(".reveal");
if ("IntersectionObserver" in window) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
entry.target.classList.add("in");
io.unobserve(entry.target);
}
});
}, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
reveals.forEach(function (el) { io.observe(el); });
} else {
reveals.forEach(function (el) { el.classList.add("in"); });
}
/* ---------- Pricing buttons ---------- */
document.querySelectorAll(".price-card .btn").forEach(function (btn) {
btn.addEventListener("click", function () {
var card = btn.closest(".price-card");
var name = card ? card.querySelector("h3").textContent : "pass";
var select = document.getElementById("regTier");
if (select) {
for (var i = 0; i < select.options.length; i++) {
if (select.options[i].value.toLowerCase() === name.split(" ")[0].toLowerCase()) {
select.selectedIndex = i;
break;
}
}
}
toast(name + " pass selected — finish below to reserve.");
});
});
/* ---------- Register form ---------- */
var form = document.getElementById("registerForm");
if (form) {
form.addEventListener("submit", function (e) {
e.preventDefault();
var email = document.getElementById("regEmail");
var tier = document.getElementById("regTier");
var value = (email.value || "").trim();
if (!value || !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(value)) {
email.focus();
toast("Enter a valid work email to reserve.");
return;
}
toast("Seat reserved · " + tier.value + " · confirmation sent to " + value);
form.reset();
tier.value = "Conference";
});
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>DevHorizon 2026 — The Frontier Engineering Conference</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&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#register">Skip to registration</a>
<header class="nav" id="top">
<div class="wrap nav-inner">
<a class="brand" href="#top" aria-label="DevHorizon 2026 home">
<span class="brand-mark" aria-hidden="true">DH</span>
<span class="brand-text">DevHorizon<span class="brand-yr">26</span></span>
</a>
<nav class="nav-links" aria-label="Primary">
<a href="#speakers">Speakers</a>
<a href="#agenda">Agenda</a>
<a href="#pricing">Pricing</a>
<a href="#venue">Venue</a>
<a href="#sponsors">Sponsors</a>
</nav>
<a class="btn btn-primary nav-cta" href="#register">Register</a>
<button class="nav-toggle" id="navToggle" aria-expanded="false" aria-controls="mobileNav" aria-label="Open menu">
<span></span><span></span><span></span>
</button>
</div>
<nav class="mobile-nav" id="mobileNav" aria-label="Mobile" hidden>
<a href="#speakers">Speakers</a>
<a href="#agenda">Agenda</a>
<a href="#pricing">Pricing</a>
<a href="#venue">Venue</a>
<a href="#sponsors">Sponsors</a>
<a class="btn btn-primary" href="#register">Register</a>
</nav>
</header>
<main>
<!-- HERO -->
<section class="hero" aria-labelledby="hero-title">
<div class="hero-bg" aria-hidden="true"></div>
<div class="wrap hero-inner">
<p class="eyebrow reveal"><span class="pulse" aria-hidden="true"></span> 3-day flagship event · in-person + livestream</p>
<h1 id="hero-title" class="reveal">DevHorizon 2026<br /><span class="hero-sub">The Frontier Engineering Conference</span></h1>
<p class="hero-meta reveal">
<span class="meta-pill"><strong>Sep 22–24, 2026</strong></span>
<span class="meta-pill">Moscone West · San Francisco, CA</span>
</p>
<p class="hero-lede reveal">Two thousand builders. Five tracks. One weekend on the frontier of platform engineering, AI systems, and developer experience.</p>
<div class="hero-actions reveal">
<a class="btn btn-primary btn-lg" href="#register">Get your ticket</a>
<a class="btn btn-ghost btn-lg" href="#agenda">Explore the agenda</a>
</div>
<div class="countdown reveal" id="countdown" aria-label="Early-bird pricing countdown">
<p class="cd-label"><span class="dot" aria-hidden="true"></span> Early-bird pricing ends in</p>
<div class="cd-grid" id="cdGrid" role="timer" aria-live="polite">
<div class="cd-cell"><span class="cd-num" data-unit="days">00</span><span class="cd-unit">days</span></div>
<div class="cd-cell"><span class="cd-num" data-unit="hours">00</span><span class="cd-unit">hrs</span></div>
<div class="cd-cell"><span class="cd-num" data-unit="minutes">00</span><span class="cd-unit">min</span></div>
<div class="cd-cell"><span class="cd-num" data-unit="seconds">00</span><span class="cd-unit">sec</span></div>
</div>
</div>
<dl class="hero-stats reveal">
<div><dt>Speakers</dt><dd>64</dd></div>
<div><dt>Tracks</dt><dd>5</dd></div>
<div><dt>Workshops</dt><dd>18</dd></div>
<div><dt>Attendees</dt><dd>2,000</dd></div>
</dl>
</div>
</section>
<!-- SPEAKERS -->
<section class="section" id="speakers" aria-labelledby="speakers-title">
<div class="wrap">
<header class="section-head reveal">
<p class="kicker">Keynotes & sessions</p>
<h2 id="speakers-title">Speakers on the frontier</h2>
<p class="section-lede">Engineers and researchers shipping the tools the next decade runs on.</p>
</header>
<ul class="speakers-grid" role="list">
<li class="speaker reveal">
<div class="speaker-photo" data-grad="a" aria-hidden="true"><span>AR</span></div>
<div class="speaker-body">
<span class="badge badge-keynote">Keynote</span>
<h3>Ada Reyes</h3>
<p class="speaker-role">VP Platform · Northwind Cloud</p>
<p class="speaker-topic">Scaling internal developer platforms past 10k engineers.</p>
</div>
</li>
<li class="speaker reveal">
<div class="speaker-photo" data-grad="b" aria-hidden="true"><span>KO</span></div>
<div class="speaker-body">
<span class="badge badge-keynote">Keynote</span>
<h3>Kenji Ozawa</h3>
<p class="speaker-role">Principal Eng · Meridian AI</p>
<p class="speaker-topic">Inference at the edge: latency budgets that hold up.</p>
</div>
</li>
<li class="speaker reveal">
<div class="speaker-photo" data-grad="c" aria-hidden="true"><span>SM</span></div>
<div class="speaker-body">
<span class="badge">Session</span>
<h3>Sofia Marchetti</h3>
<p class="speaker-role">Staff DX Eng · Loomstack</p>
<p class="speaker-topic">Designing CLIs people actually keep using.</p>
</div>
</li>
<li class="speaker reveal">
<div class="speaker-photo" data-grad="d" aria-hidden="true"><span>TN</span></div>
<div class="speaker-body">
<span class="badge">Session</span>
<h3>Tomas Novak</h3>
<p class="speaker-role">Eng Director · Cinderpath</p>
<p class="speaker-topic">Zero-downtime migrations for stateful systems.</p>
</div>
</li>
<li class="speaker reveal">
<div class="speaker-photo" data-grad="e" aria-hidden="true"><span>PI</span></div>
<div class="speaker-body">
<span class="badge">Session</span>
<h3>Priya Iyer</h3>
<p class="speaker-role">Sec Lead · Vault & Vine</p>
<p class="speaker-topic">Supply-chain trust without slowing the team down.</p>
</div>
</li>
<li class="speaker reveal">
<div class="speaker-photo" data-grad="f" aria-hidden="true"><span>LB</span></div>
<div class="speaker-body">
<span class="badge">Session</span>
<h3>Leon Brandt</h3>
<p class="speaker-role">Open Source · Driftwood Labs</p>
<p class="speaker-topic">Maintaining a project read by a million developers.</p>
</div>
</li>
</ul>
<p class="speakers-more reveal">+ 58 more across five tracks. <a href="#agenda">See the full agenda →</a></p>
</div>
</section>
<!-- AGENDA -->
<section class="section section-alt" id="agenda" aria-labelledby="agenda-title">
<div class="wrap">
<header class="section-head reveal">
<p class="kicker">Three days, five tracks</p>
<h2 id="agenda-title">Agenda</h2>
<p class="section-lede">Switch tracks to see how each day flows.</p>
</header>
<div class="tabs reveal">
<div class="tablist" role="tablist" aria-label="Agenda tracks">
<button class="tab" role="tab" id="tab-platform" aria-controls="panel-platform" aria-selected="true">Platform</button>
<button class="tab" role="tab" id="tab-ai" aria-controls="panel-ai" aria-selected="false" tabindex="-1">AI Systems</button>
<button class="tab" role="tab" id="tab-dx" aria-controls="panel-dx" aria-selected="false" tabindex="-1">Developer XP</button>
<button class="tab" role="tab" id="tab-security" aria-controls="panel-security" aria-selected="false" tabindex="-1">Security</button>
</div>
<div class="tabpanel" role="tabpanel" id="panel-platform" aria-labelledby="tab-platform">
<ol class="agenda-list" role="list">
<li class="agenda-row"><span class="ag-time">09:00</span><div class="ag-body"><h3>Opening keynote: Platforms at scale</h3><p>Ada Reyes · Grand Hall</p></div><span class="badge badge-keynote">Keynote</span></li>
<li class="agenda-row"><span class="ag-time">10:30</span><div class="ag-body"><h3>Golden paths without golden cages</h3><p>Marcus Hale · West 2002</p></div><span class="badge">Talk</span></li>
<li class="agenda-row"><span class="ag-time">13:00</span><div class="ag-body"><h3>Workshop: Building an internal platform API</h3><p>Hands-on · West 2010</p></div><span class="badge badge-work">Workshop</span></li>
<li class="agenda-row"><span class="ag-time">15:30</span><div class="ag-body"><h3>Panel: Buy, build, or borrow your IDP</h3><p>Five leads · Grand Hall</p></div><span class="badge">Panel</span></li>
</ol>
</div>
<div class="tabpanel" role="tabpanel" id="panel-ai" aria-labelledby="tab-ai" hidden>
<ol class="agenda-list" role="list">
<li class="agenda-row"><span class="ag-time">09:00</span><div class="ag-body"><h3>Keynote: Inference at the edge</h3><p>Kenji Ozawa · Grand Hall</p></div><span class="badge badge-keynote">Keynote</span></li>
<li class="agenda-row"><span class="ag-time">11:00</span><div class="ag-body"><h3>Evaluating LLM agents in production</h3><p>Dana Whitfield · West 2004</p></div><span class="badge">Talk</span></li>
<li class="agenda-row"><span class="ag-time">13:30</span><div class="ag-body"><h3>Workshop: RAG pipelines that don't drift</h3><p>Hands-on · West 2012</p></div><span class="badge badge-work">Workshop</span></li>
<li class="agenda-row"><span class="ag-time">16:00</span><div class="ag-body"><h3>Cost-aware model routing</h3><p>Owen Pratt · West 2004</p></div><span class="badge">Talk</span></li>
</ol>
</div>
<div class="tabpanel" role="tabpanel" id="panel-dx" aria-labelledby="tab-dx" hidden>
<ol class="agenda-list" role="list">
<li class="agenda-row"><span class="ag-time">09:30</span><div class="ag-body"><h3>CLIs people keep using</h3><p>Sofia Marchetti · West 2006</p></div><span class="badge">Talk</span></li>
<li class="agenda-row"><span class="ag-time">11:15</span><div class="ag-body"><h3>Docs as a first-class product</h3><p>Riley Cohen · West 2006</p></div><span class="badge">Talk</span></li>
<li class="agenda-row"><span class="ag-time">14:00</span><div class="ag-body"><h3>Workshop: Build-time speed audits</h3><p>Hands-on · West 2014</p></div><span class="badge badge-work">Workshop</span></li>
<li class="agenda-row"><span class="ag-time">16:30</span><div class="ag-body"><h3>Onboarding in under a day</h3><p>Grace Lin · West 2006</p></div><span class="badge">Talk</span></li>
</ol>
</div>
<div class="tabpanel" role="tabpanel" id="panel-security" aria-labelledby="tab-security" hidden>
<ol class="agenda-list" role="list">
<li class="agenda-row"><span class="ag-time">09:30</span><div class="ag-body"><h3>Supply-chain trust at speed</h3><p>Priya Iyer · West 2008</p></div><span class="badge">Talk</span></li>
<li class="agenda-row"><span class="ag-time">11:00</span><div class="ag-body"><h3>Secrets that never touch disk</h3><p>Noah Berg · West 2008</p></div><span class="badge">Talk</span></li>
<li class="agenda-row"><span class="ag-time">13:30</span><div class="ag-body"><h3>Workshop: Threat-modeling a CI pipeline</h3><p>Hands-on · West 2016</p></div><span class="badge badge-work">Workshop</span></li>
<li class="agenda-row"><span class="ag-time">15:45</span><div class="ag-body"><h3>Zero-trust for internal tools</h3><p>Mara Quinn · West 2008</p></div><span class="badge">Talk</span></li>
</ol>
</div>
</div>
</div>
</section>
<!-- PRICING -->
<section class="section" id="pricing" aria-labelledby="pricing-title">
<div class="wrap">
<header class="section-head reveal">
<p class="kicker">Passes</p>
<h2 id="pricing-title">Pricing tiers</h2>
<p class="section-lede">Early-bird rates locked until the countdown hits zero.</p>
</header>
<ul class="pricing-grid" role="list">
<li class="price-card reveal">
<div class="price-top">
<h3>Community</h3>
<span class="badge badge-low">Limited</span>
</div>
<p class="price"><span class="was">$399</span><span class="now">$249</span><span class="per">early-bird</span></p>
<ul class="price-feats" role="list">
<li>All keynotes & talks</li>
<li>Hallway track & expo</li>
<li>Session recordings</li>
</ul>
<a class="btn btn-ghost btn-block" href="#register">Choose Community</a>
</li>
<li class="price-card price-feat reveal">
<div class="price-top">
<h3>Conference</h3>
<span class="badge badge-keynote">Most popular</span>
</div>
<p class="price"><span class="was">$899</span><span class="now">$649</span><span class="per">early-bird</span></p>
<ul class="price-feats" role="list">
<li>Everything in Community</li>
<li>All 18 hands-on workshops</li>
<li>Speaker dinner & afterparty</li>
<li>Reserved keynote seating</li>
</ul>
<a class="btn btn-primary btn-block" href="#register">Choose Conference</a>
</li>
<li class="price-card reveal">
<div class="price-top">
<h3>Team (5+)</h3>
<span class="badge">Best value</span>
</div>
<p class="price"><span class="was">$799</span><span class="now">$549</span><span class="per">per seat</span></p>
<ul class="price-feats" role="list">
<li>Everything in Conference</li>
<li>Dedicated team lounge</li>
<li>Priority workshop booking</li>
</ul>
<a class="btn btn-ghost btn-block" href="#register">Choose Team</a>
</li>
</ul>
</div>
</section>
<!-- VENUE -->
<section class="section section-alt" id="venue" aria-labelledby="venue-title">
<div class="wrap venue-grid">
<div class="venue-copy reveal">
<p class="kicker">Getting there</p>
<h2 id="venue-title">Venue & travel</h2>
<p class="section-lede">In the heart of downtown San Francisco, steps from transit and hotels.</p>
<ul class="venue-list" role="list">
<li><span class="vt">Venue</span> Moscone West · 800 Howard St</li>
<li><span class="vt">Transit</span> Powell St BART · 6-min walk</li>
<li><span class="vt">Airport</span> SFO · 20 min via BART</li>
<li><span class="vt">Hotels</span> 12% attendee block at 4 partners</li>
</ul>
<a class="btn btn-ghost" href="#register">Book a hotel block</a>
</div>
<div class="venue-map reveal" aria-hidden="true">
<div class="map-grid"></div>
<span class="map-pin"><span class="pin-dot"></span> Moscone West</span>
</div>
</div>
</section>
<!-- SPONSORS -->
<section class="section" id="sponsors" aria-labelledby="sponsors-title">
<div class="wrap">
<header class="section-head reveal">
<p class="kicker">Backed by</p>
<h2 id="sponsors-title">Sponsors</h2>
<p class="section-lede">The teams making DevHorizon possible.</p>
</header>
<ul class="sponsor-grid" role="list">
<li class="sponsor reveal">Northwind</li>
<li class="sponsor reveal">Meridian AI</li>
<li class="sponsor reveal">Loomstack</li>
<li class="sponsor reveal">Cinderpath</li>
<li class="sponsor reveal">Vault & Vine</li>
<li class="sponsor reveal">Driftwood</li>
<li class="sponsor reveal">Atlas Forge</li>
<li class="sponsor reveal">Brightline</li>
</ul>
</div>
</section>
<!-- REGISTER CTA -->
<section class="register" id="register" aria-labelledby="register-title">
<div class="wrap register-inner reveal">
<div class="register-copy">
<p class="kicker kicker-light">Lock in early-bird</p>
<h2 id="register-title">Join 2,000 engineers on the frontier</h2>
<p>Seats are released in waves. Reserve before the countdown ends to keep the early-bird rate.</p>
</div>
<form class="register-form" id="registerForm" novalidate>
<label class="sr-only" for="regEmail">Work email</label>
<input id="regEmail" name="email" type="email" placeholder="you@company.com" autocomplete="email" required />
<label class="sr-only" for="regTier">Pass tier</label>
<select id="regTier" name="tier">
<option value="Community">Community · $249</option>
<option value="Conference" selected>Conference · $649</option>
<option value="Team">Team · $549/seat</option>
</select>
<button class="btn btn-primary" type="submit">Reserve my seat</button>
</form>
</div>
</section>
</main>
<footer class="footer">
<div class="wrap footer-inner">
<div class="footer-brand">
<span class="brand-mark" aria-hidden="true">DH</span>
<p>DevHorizon 2026 · Sep 22–24 · San Francisco</p>
</div>
<nav class="footer-nav" aria-label="Footer">
<a href="#speakers">Speakers</a>
<a href="#agenda">Agenda</a>
<a href="#pricing">Pricing</a>
<a href="#venue">Venue</a>
<a href="#register">Register</a>
</nav>
<p class="footer-fine">Fictional event for UI demonstration. © 2026 DevHorizon.</p>
</div>
</footer>
<div class="toast-host" id="toastHost" aria-live="polite" aria-atomic="true"></div>
<script src="script.js"></script>
</body>
</html>Conference Landing
A polished, professional landing page for the fictional DevHorizon 2026 conference, built on a white-and-indigo system with slate text. The hero sits on a deep indigo gradient with a faint grid, leading with the event name, the September 22–24 dates and the Moscone West venue, a pulsing “early-bird” eyebrow, dual register and agenda calls to action, a live countdown to the early-bird deadline, and a four-up stat strip.
The body flows through a speakers grid with gradient photo placeholders and keynote badges, a track-based agenda powered by an accessible tab list (click or arrow-key navigation across Platform, AI Systems, Developer XP and Security), three pricing tiers with struck-through original prices and a highlighted “most popular” card, and a venue and travel block beside a stylized pinned map. A sponsor wall, an indigo register CTA with an email-and-tier form, and a footer round it out.
Everything runs on vanilla JS: an IntersectionObserver reveals sections on scroll, the countdown ticks every second, choosing a pricing tier syncs the register form’s select, and a small toast helper confirms selections and validates the email before “reserving” a seat. The layout reflows from multi-column desktop down to a single column near 360px, with a collapsing mobile nav.
Illustrative UI only — fictional events, not a real ticketing service.