Agency — Design Studio Landing
A polished, single-page landing for a fictional independent design studio, Foundry and Field. Editorial serif headlines on warm off-white with an electric coral accent carry an oversized hero, a selected-works case grid with hover reveals, a numbered services list, a dark studio and team section, an awards and clients strip, four process steps, an auto-rotating testimonial carousel, and a validating contact form. Built with semantic HTML, CSS variables and vanilla JavaScript only.
MCP
Code
/* ============================================================
Foundry & Field — Design Studio Landing
============================================================ */
:root {
--bg: #f6f4ef;
--bg-2: #efece4;
--ink: #14110d;
--ink-soft: #4a443b;
--line: #ddd6c8;
--accent: #ff5a3c; /* electric coral */
--accent-dk: #e2421f;
--card: #ffffff;
--serif: "Fraunces", Georgia, "Times New Roman", serif;
--sans: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--mono: "JetBrains Mono", ui-monospace, "SFMono-Regular", monospace;
--maxw: 1180px;
--r: 18px;
--ease: cubic-bezier(.22,.61,.36,1);
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
margin: 0;
background: var(--bg);
color: var(--ink);
font-family: var(--sans);
font-size: 17px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow-x: hidden;
}
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
* { animation: none !important; transition: none !important; }
}
img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
h1,h2,h3,h4 { margin: 0; font-family: var(--serif); font-weight: 500; letter-spacing: -.02em; }
p { margin: 0; }
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: 28px; }
.skip-link {
position: absolute; left: 12px; top: -60px; z-index: 200;
background: var(--ink); color: var(--bg); padding: 10px 16px; border-radius: 8px;
transition: top .2s var(--ease);
}
.skip-link:focus { top: 12px; }
.eyebrow {
font-family: var(--mono); font-size: 12px; letter-spacing: .14em;
text-transform: uppercase; color: var(--accent); margin: 0 0 18px;
}
/* ---------- buttons ---------- */
.btn {
display: inline-flex; align-items: center; gap: .4em;
font-family: var(--sans); font-weight: 600; font-size: 15px;
padding: 13px 22px; border-radius: 100px; border: 1.5px solid transparent;
cursor: pointer; transition: transform .25s var(--ease), background .25s var(--ease), color .25s var(--ease), box-shadow .25s var(--ease);
white-space: nowrap;
}
.btn--solid { background: var(--accent); color: #fff; box-shadow: 0 10px 24px -10px var(--accent); }
.btn--solid:hover { background: var(--accent-dk); transform: translateY(-2px); box-shadow: 0 16px 30px -12px var(--accent); }
.btn--ghost { border-color: var(--ink); color: var(--ink); }
.btn--ghost:hover { background: var(--ink); color: var(--bg); transform: translateY(-2px); }
.btn--lg { padding: 16px 28px; font-size: 16px; }
.btn:focus-visible, a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible {
outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 8px;
}
/* ============================================================
NAV
============================================================ */
.nav {
position: sticky; top: 0; z-index: 100;
background: color-mix(in srgb, var(--bg) 78%, transparent);
backdrop-filter: saturate(140%) blur(12px);
border-bottom: 1px solid transparent;
transition: border-color .3s var(--ease), background .3s var(--ease);
}
.nav.is-stuck { border-color: var(--line); background: color-mix(in srgb, var(--bg) 92%, transparent); }
.nav__inner { display: flex; align-items: center; justify-content: space-between; height: 76px; }
.logo { display: inline-flex; align-items: center; gap: 12px; font-weight: 600; }
.logo__mark {
display: grid; place-items: center; width: 38px; height: 38px;
background: var(--ink); color: var(--bg); border-radius: 10px;
font-family: var(--serif); font-size: 17px;
}
.logo__word { font-family: var(--serif); font-size: 18px; letter-spacing: -.01em; }
.nav__links { display: flex; align-items: center; gap: 30px; }
.nav__links a { font-size: 15px; font-weight: 500; color: var(--ink-soft); transition: color .2s; }
.nav__links a:hover { color: var(--ink); }
.nav__cta {
background: var(--ink); color: var(--bg) !important; padding: 10px 18px; border-radius: 100px;
transition: transform .2s var(--ease), background .2s;
}
.nav__cta:hover { transform: translateY(-2px); }
.nav__toggle {
display: none; flex-direction: column; gap: 5px; background: none; border: 0;
padding: 10px; cursor: pointer;
}
.nav__toggle span { width: 24px; height: 2px; background: var(--ink); transition: transform .3s var(--ease), opacity .2s; }
.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-menu {
display: flex; flex-direction: column; gap: 6px; padding: 14px 28px 24px;
border-top: 1px solid var(--line); background: var(--bg);
}
.mobile-menu a { padding: 12px 0; font-size: 18px; font-family: var(--serif); border-bottom: 1px solid var(--line); }
.mobile-menu a:last-child { border-bottom: 0; }
.mobile-menu__cta { color: var(--accent); }
/* ============================================================
HERO
============================================================ */
.hero { padding: 80px 0 40px; }
.hero__title {
font-size: clamp(48px, 11vw, 148px);
line-height: .92; letter-spacing: -.04em; margin: 6px 0 0;
}
.hero__title span { display: block; }
.hero__title em { font-style: italic; color: var(--accent); }
.hero__row {
display: grid; grid-template-columns: 1.2fr 1fr; gap: 40px; align-items: end;
margin-top: 42px; padding-top: 30px; border-top: 1px solid var(--line);
}
.hero__sub { font-size: clamp(17px, 2vw, 20px); color: var(--ink-soft); max-width: 46ch; }
.hero__cta { display: flex; flex-wrap: wrap; gap: 14px; justify-self: end; }
.hero__visual {
display: grid; grid-template-columns: 1.3fr .7fr 1fr; gap: 18px;
margin-top: 56px; height: 260px;
}
.hero__panel {
border-radius: var(--r); padding: 20px; position: relative; overflow: hidden;
border: 1px solid var(--line); transition: transform .4s var(--ease);
}
.hero__panel:hover { transform: translateY(-6px); }
.hero__panel--a { background: var(--card); display: flex; flex-direction: column; justify-content: space-between; }
.hero__panel--b {
background: var(--accent); color: #fff; display: grid; place-items: center;
font-family: var(--serif); font-size: clamp(60px, 9vw, 110px); font-style: italic;
}
.hero__panel--c { background: var(--ink); color: var(--bg); display: flex; flex-direction: column; justify-content: space-between; }
.tag { font-family: var(--mono); font-size: 11px; letter-spacing: .12em; text-transform: uppercase; }
.hero__panel--c .tag { color: var(--accent); }
.hero__swatches { display: flex; gap: 10px; }
.hero__swatches i { width: 32px; height: 32px; border-radius: 50%; background: var(--c); display: block; }
.hero__bars { display: flex; align-items: flex-end; gap: 10px; height: 70px; }
.hero__bars span { width: 18px; background: var(--accent); border-radius: 6px; }
.hero__bars span:nth-child(1) { height: 40%; }
.hero__bars span:nth-child(2) { height: 100%; }
.hero__bars span:nth-child(3) { height: 65%; }
/* ============================================================
CLIENTS MARQUEE
============================================================ */
.clients { padding: 28px 0; border-block: 1px solid var(--line); background: var(--bg-2); overflow: hidden; }
.marquee { display: flex; gap: 0; width: max-content; }
.marquee__track {
display: flex; align-items: center; gap: 28px; padding-right: 28px;
animation: scroll 32s linear infinite; flex: none;
}
.marquee:hover .marquee__track { animation-play-state: paused; }
.marquee__track span {
font-family: var(--serif); font-size: clamp(22px, 3vw, 34px); color: var(--ink-soft);
font-style: italic; white-space: nowrap;
}
.marquee__track span:nth-child(even) { color: var(--line); font-style: normal; }
@keyframes scroll { to { transform: translateX(-50%); } }
/* ============================================================
SECTION SHELL
============================================================ */
.section { padding: clamp(70px, 9vw, 130px) 0; }
.section__head {
display: grid; grid-template-columns: 1fr 1fr; gap: 30px; align-items: end;
margin-bottom: 56px;
}
.section__title { font-size: clamp(38px, 6vw, 84px); line-height: .95; }
.section__lede { font-size: 19px; color: var(--ink-soft); max-width: 42ch; justify-self: end; }
/* ============================================================
WORK / CASES
============================================================ */
.cases { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; }
.case { cursor: pointer; }
.case__media {
position: relative; aspect-ratio: 4/3; border-radius: var(--r); overflow: hidden;
background: var(--ca); display: grid; place-items: center;
border: 1px solid var(--line);
}
.case__art {
font-family: var(--serif); font-size: clamp(60px, 9vw, 120px); font-style: italic;
color: var(--cb); opacity: .9; transition: transform .5s var(--ease);
}
.case:hover .case__art { transform: scale(1.08) rotate(-3deg); }
.case__hover {
position: absolute; inset: 0; display: grid; place-items: center;
background: color-mix(in srgb, var(--ink) 82%, transparent); color: var(--bg);
font-family: var(--mono); font-size: 14px; letter-spacing: .06em;
opacity: 0; transition: opacity .35s var(--ease); z-index: 2;
}
.case:hover .case__hover, .case:focus-within .case__hover { opacity: 1; }
.case__meta {
display: flex; align-items: baseline; gap: 14px; padding: 18px 4px 0;
border-top: 1px solid transparent; transition: border-color .3s;
}
.case:hover .case__meta { border-color: var(--ink); }
.case__meta h3 { font-size: 24px; }
.case__meta p { color: var(--ink-soft); font-size: 14px; }
.case__year { margin-left: auto; font-family: var(--mono); font-size: 13px; color: var(--ink-soft); }
/* ============================================================
SERVICES
============================================================ */
.svc { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.svc__row {
display: grid; grid-template-columns: 80px 1.1fr 1.3fr 40px; align-items: center;
gap: 24px; padding: 34px 8px; border-bottom: 1px solid var(--line);
transition: padding-left .35s var(--ease), background .35s var(--ease);
}
.svc__row:hover { padding-left: 22px; background: var(--bg-2); }
.svc__num { font-family: var(--mono); font-size: 14px; color: var(--accent); }
.svc__name { font-size: clamp(26px, 3.4vw, 42px); }
.svc__desc { color: var(--ink-soft); font-size: 16px; }
.svc__plus { font-family: var(--serif); font-size: 32px; color: var(--ink-soft); text-align: right; transition: transform .35s var(--ease), color .35s; }
.svc__row:hover .svc__plus { transform: rotate(90deg); color: var(--accent); }
/* ============================================================
STUDIO + TEAM
============================================================ */
.studio { background: var(--ink); color: var(--bg); border-radius: 0; }
.studio .eyebrow { color: var(--accent); }
.studio__grid { display: grid; grid-template-columns: 1.05fr 1fr; gap: 64px; align-items: start; }
.studio__title { font-size: clamp(34px, 5vw, 62px); line-height: 1; margin-bottom: 26px; color: var(--bg); }
.studio__copy p { color: color-mix(in srgb, var(--bg) 76%, var(--ink)); font-size: 18px; max-width: 48ch; }
.stats { display: flex; gap: 40px; margin-top: 40px; flex-wrap: wrap; }
.stat { display: flex; flex-direction: column; }
.stat strong { font-family: var(--serif); font-size: 46px; line-height: 1; color: var(--accent); }
.stat span { font-size: 14px; color: color-mix(in srgb, var(--bg) 70%, var(--ink)); margin-top: 6px; }
.team { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.member { margin: 0; }
.member__photo {
aspect-ratio: 1; border-radius: 14px;
background: linear-gradient(150deg, #2a241c, #3a322833);
border: 1px solid color-mix(in srgb, var(--bg) 18%, transparent);
display: grid; place-items: center; position: relative; overflow: hidden;
transition: transform .4s var(--ease);
}
.member__photo::after {
content: attr(data-init); font-family: var(--serif); font-style: italic;
font-size: 40px; color: var(--accent);
}
.member:hover .member__photo { transform: translateY(-6px) scale(1.02); }
.member figcaption { display: flex; flex-direction: column; padding-top: 12px; }
.member figcaption strong { font-size: 16px; }
.member figcaption span { font-size: 13px; color: color-mix(in srgb, var(--bg) 65%, var(--ink)); }
/* ============================================================
AWARDS
============================================================ */
.awards { padding: clamp(50px, 6vw, 80px) 0; background: var(--bg-2); border-bottom: 1px solid var(--line); }
.awards__list {
list-style: none; margin: 0; padding: 0;
display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px;
}
.awards__list li { display: flex; flex-direction: column; gap: 6px; padding-right: 18px; border-left: 2px solid var(--accent); padding-left: 18px; }
.awards__list strong { font-family: var(--serif); font-size: 24px; }
.awards__list span { font-size: 14px; color: var(--ink-soft); }
/* ============================================================
PROCESS STEPS
============================================================ */
.steps { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4,1fr); gap: 22px; counter-reset: s; }
.step {
background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
padding: 28px 24px 30px; transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.step:hover { transform: translateY(-8px); box-shadow: 0 24px 40px -28px rgba(20,17,13,.45); }
.step__n { font-family: var(--mono); font-size: 13px; color: var(--accent); }
.step h3 { font-size: 26px; margin: 26px 0 10px; }
.step p { color: var(--ink-soft); font-size: 15px; }
/* ============================================================
TESTIMONIALS
============================================================ */
.quotes { background: var(--accent); color: #fff; text-align: center; }
.quote-stage { position: relative; min-height: 220px; max-width: 880px; margin-inline: auto; }
.quote {
margin: 0; position: absolute; inset: 0;
opacity: 0; transform: translateY(16px); pointer-events: none;
transition: opacity .5s var(--ease), transform .5s var(--ease);
}
.quote.is-active { opacity: 1; transform: none; pointer-events: auto; position: relative; }
.quote p { font-family: var(--serif); font-size: clamp(24px, 4vw, 44px); line-height: 1.18; letter-spacing: -.02em; }
.quote footer { margin-top: 28px; font-family: var(--mono); font-size: 13px; letter-spacing: .04em; }
.quote footer strong { font-weight: 500; }
.quote-dots { display: flex; gap: 10px; justify-content: center; margin-top: 44px; }
.quote-dots button {
width: 10px; height: 10px; border-radius: 50%; border: 0; cursor: pointer;
background: rgba(255,255,255,.4); transition: transform .2s, background .2s; padding: 0;
}
.quote-dots button.is-active { background: #fff; transform: scale(1.4); }
/* ============================================================
CONTACT
============================================================ */
.contact { text-align: center; }
.contact__inner { max-width: 720px; margin-inline: auto; }
.contact__title { font-size: clamp(40px, 7vw, 88px); line-height: .96; margin-bottom: 18px; }
.contact__sub { color: var(--ink-soft); font-size: 19px; max-width: 44ch; margin: 0 auto 40px; }
.contact__form {
display: grid; grid-template-columns: 1fr 1fr; gap: 16px; text-align: left;
background: var(--card); border: 1px solid var(--line); border-radius: var(--r);
padding: 28px; box-shadow: 0 30px 60px -40px rgba(20,17,13,.4);
}
.field { display: flex; flex-direction: column; gap: 7px; }
.field--full { grid-column: 1 / -1; }
.field label { font-family: var(--mono); font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--ink-soft); }
.field input, .field textarea {
font: inherit; font-size: 16px; padding: 13px 14px; border: 1.5px solid var(--line);
border-radius: 12px; background: var(--bg); color: var(--ink); resize: vertical;
transition: border-color .2s, background .2s;
}
.field input:focus, .field textarea:focus { border-color: var(--accent); background: #fff; outline: none; }
.contact__form .btn { grid-column: 1 / -1; justify-content: center; }
.field input.invalid, .field textarea.invalid { border-color: var(--accent-dk); }
.contact__alt { margin-top: 22px; font-size: 15px; color: var(--ink-soft); }
.contact__alt a { color: var(--accent); text-decoration: underline; text-underline-offset: 3px; }
/* ============================================================
FOOTER
============================================================ */
.footer { background: var(--ink); color: var(--bg); padding: 70px 0 32px; }
.footer__grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1.3fr; gap: 40px; padding-bottom: 50px; border-bottom: 1px solid color-mix(in srgb, var(--bg) 16%, transparent); }
.footer__brand p { color: color-mix(in srgb, var(--bg) 68%, var(--ink)); font-size: 15px; max-width: 32ch; margin-top: 16px; }
.footer__col { display: flex; flex-direction: column; gap: 10px; }
.footer__col h4 { font-family: var(--mono); font-weight: 500; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); margin-bottom: 6px; }
.footer__col a { color: color-mix(in srgb, var(--bg) 80%, var(--ink)); font-size: 15px; transition: color .2s; }
.footer__col a:hover { color: var(--bg); }
.footer__addr { color: color-mix(in srgb, var(--bg) 55%, var(--ink)); font-size: 14px; margin-top: 4px; }
.footer__base { display: flex; align-items: center; justify-content: space-between; padding-top: 26px; font-size: 13px; color: color-mix(in srgb, var(--bg) 60%, var(--ink)); }
.footer__top { background: none; border: 0; color: inherit; font: inherit; cursor: pointer; transition: color .2s; }
.footer__top:hover { color: var(--accent); }
/* ============================================================
TOAST
============================================================ */
.toast {
position: fixed; left: 50%; bottom: 28px; transform: translate(-50%, 140%);
background: var(--ink); color: var(--bg); padding: 14px 22px; border-radius: 100px;
font-size: 15px; z-index: 300; box-shadow: 0 18px 40px -16px rgba(20,17,13,.6);
transition: transform .4s var(--ease); max-width: 90vw;
}
.toast.show { transform: translate(-50%, 0); }
/* ============================================================
SCROLL REVEAL
============================================================ */
.reveal { opacity: 0; transform: translateY(26px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.reveal.in { opacity: 1; transform: none; }
/* ============================================================
RESPONSIVE
============================================================ */
@media (max-width: 920px) {
.studio__grid { grid-template-columns: 1fr; gap: 44px; }
.footer__grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 720px) {
body { font-size: 16px; }
.nav__links { display: none; }
.nav__toggle { display: flex; }
.hero { padding: 48px 0 30px; }
.hero__row { grid-template-columns: 1fr; gap: 26px; align-items: start; }
.hero__cta { justify-self: start; }
.hero__visual { grid-template-columns: 1fr 1fr; grid-template-rows: auto auto; height: auto; }
.hero__panel { min-height: 150px; }
.hero__panel--b { grid-column: 1 / -1; min-height: 110px; }
.section__head { grid-template-columns: 1fr; gap: 18px; margin-bottom: 40px; }
.section__lede { justify-self: start; }
.cases { grid-template-columns: 1fr; }
.svc__row { grid-template-columns: 50px 1fr; grid-template-areas: "num name" "desc desc"; gap: 8px 16px; }
.svc__num { grid-area: num; }
.svc__name { grid-area: name; }
.svc__desc { grid-area: desc; }
.svc__plus { display: none; }
.awards__list { grid-template-columns: 1fr 1fr; }
.steps { grid-template-columns: 1fr 1fr; }
.contact__form { grid-template-columns: 1fr; }
.footer__grid { grid-template-columns: 1fr; }
.footer__base { flex-direction: column; gap: 14px; }
}
@media (max-width: 520px) {
.wrap { padding-inline: 18px; }
.team { grid-template-columns: 1fr 1fr; }
.awards__list { grid-template-columns: 1fr; }
.steps { grid-template-columns: 1fr; }
.stats { gap: 26px; }
}/* ============================================================
Foundry & Field — landing interactions (vanilla JS)
============================================================ */
(function () {
"use strict";
/* ---------- toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 3200);
}
/* ---------- sticky nav shadow ---------- */
var nav = document.getElementById("nav");
function onScroll() {
if (!nav) return;
nav.classList.toggle("is-stuck", window.scrollY > 12);
}
window.addEventListener("scroll", onScroll, { passive: true });
onScroll();
/* ---------- mobile menu ---------- */
var toggle = document.getElementById("navToggle");
var menu = document.getElementById("mobileMenu");
function setMenu(open) {
if (!toggle || !menu) return;
toggle.setAttribute("aria-expanded", String(open));
toggle.setAttribute("aria-label", open ? "Close menu" : "Open menu");
menu.hidden = !open;
}
if (toggle && menu) {
toggle.addEventListener("click", function () {
setMenu(toggle.getAttribute("aria-expanded") !== "true");
});
menu.querySelectorAll("a").forEach(function (a) {
a.addEventListener("click", function () { setMenu(false); });
});
document.addEventListener("keydown", function (e) {
if (e.key === "Escape") setMenu(false);
});
}
/* ---------- smooth scroll (with reduced-motion respect) ---------- */
var reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
document.querySelectorAll('a[href^="#"]').forEach(function (link) {
link.addEventListener("click", function (e) {
var id = link.getAttribute("href");
if (id.length < 2) return;
var target = document.querySelector(id);
if (!target) return;
e.preventDefault();
target.scrollIntoView({ behavior: reduce ? "auto" : "smooth", block: "start" });
});
});
/* ---------- back to top ---------- */
var toTop = document.getElementById("toTop");
if (toTop) {
toTop.addEventListener("click", function () {
window.scrollTo({ top: 0, behavior: reduce ? "auto" : "smooth" });
});
}
/* ---------- scroll reveal ---------- */
var revealEls = Array.prototype.slice.call(document.querySelectorAll("[data-reveal]"));
if ("IntersectionObserver" in window && !reduce) {
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" });
revealEls.forEach(function (el) { io.observe(el); });
} else {
revealEls.forEach(function (el) { el.classList.add("in"); });
}
/* ---------- case studies → toast ---------- */
document.querySelectorAll(".case").forEach(function (c) {
var name = (c.querySelector("h3") || {}).textContent || "this project";
c.setAttribute("tabindex", "0");
c.setAttribute("role", "button");
c.setAttribute("aria-label", "View case study: " + name);
function open() { toast("Case study for " + name + " — coming soon."); }
c.addEventListener("click", open);
c.addEventListener("keydown", function (e) {
if (e.key === "Enter" || e.key === " ") { e.preventDefault(); open(); }
});
});
/* ---------- testimonial carousel (auto + dots) ---------- */
var quotes = Array.prototype.slice.call(document.querySelectorAll("[data-quote]"));
var dots = Array.prototype.slice.call(document.querySelectorAll("[data-dot]"));
var qi = 0, qTimer;
function showQuote(i) {
qi = (i + quotes.length) % quotes.length;
quotes.forEach(function (q, n) { q.classList.toggle("is-active", n === qi); });
dots.forEach(function (d, n) {
d.classList.toggle("is-active", n === qi);
d.setAttribute("aria-selected", String(n === qi));
});
}
function startQuotes() {
if (reduce || quotes.length < 2) return;
clearInterval(qTimer);
qTimer = setInterval(function () { showQuote(qi + 1); }, 5200);
}
dots.forEach(function (d, n) {
d.addEventListener("click", function () { showQuote(n); startQuotes(); });
});
if (quotes.length) { showQuote(0); startQuotes(); }
/* ---------- contact form ---------- */
var form = document.getElementById("contactForm");
if (form) {
form.addEventListener("submit", function (e) {
e.preventDefault();
var ok = true;
["name", "email", "brief"].forEach(function (id) {
var f = form.querySelector("#" + id);
if (!f) return;
var bad = !f.value.trim() || (id === "email" && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(f.value));
f.classList.toggle("invalid", bad);
if (bad) ok = false;
});
if (!ok) { toast("Add your name, a valid email and a quick brief."); return; }
var who = (form.querySelector("#name").value || "").trim().split(" ")[0];
form.reset();
toast("Thanks" + (who ? ", " + who : "") + "! We'll reply within two business days.");
});
form.querySelectorAll("input, textarea").forEach(function (f) {
f.addEventListener("input", function () { f.classList.remove("invalid"); });
});
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Foundry & Field — Independent Design Studio</title>
<meta name="description" content="Foundry & Field is an independent design studio building brands, products and digital experiences with intention." />
<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=Fraunces:opsz,[email protected],400;9..144,500;9..144,600&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<a class="skip-link" href="#main">Skip to content</a>
<!-- ===== NAV ===== -->
<header class="nav" id="nav">
<div class="wrap nav__inner">
<a class="logo" href="#top" aria-label="Foundry and Field home">
<span class="logo__mark" aria-hidden="true">F&</span>
<span class="logo__word">Foundry & Field</span>
</a>
<nav class="nav__links" aria-label="Primary">
<a href="#work">Work</a>
<a href="#services">Services</a>
<a href="#studio">Studio</a>
<a href="#process">Process</a>
<a href="#contact" class="nav__cta">Start a project</a>
</nav>
<button class="nav__toggle" id="navToggle" aria-expanded="false" aria-controls="mobileMenu" aria-label="Open menu">
<span></span><span></span><span></span>
</button>
</div>
<div class="mobile-menu" id="mobileMenu" hidden>
<a href="#work">Work</a>
<a href="#services">Services</a>
<a href="#studio">Studio</a>
<a href="#process">Process</a>
<a href="#contact" class="mobile-menu__cta">Start a project</a>
</div>
</header>
<main id="main">
<span id="top"></span>
<!-- ===== HERO ===== -->
<section class="hero">
<div class="wrap">
<p class="eyebrow reveal" data-reveal>Independent design studio — est. 2016</p>
<h1 class="hero__title">
<span class="reveal" data-reveal>We design brands</span>
<span class="reveal" data-reveal>that <em>refuse</em> to</span>
<span class="reveal" data-reveal>blend in.</span>
</h1>
<div class="hero__row">
<p class="hero__sub reveal" data-reveal>
Foundry & Field is a small team of strategists, designers and makers
crafting identities, products and stories for ambitious, curious companies.
</p>
<div class="hero__cta reveal" data-reveal>
<a href="#contact" class="btn btn--solid">Start a project</a>
<a href="#work" class="btn btn--ghost">See selected work →</a>
</div>
</div>
<div class="hero__visual reveal" data-reveal>
<div class="hero__panel hero__panel--a">
<span class="tag">Identity</span>
<div class="hero__swatches" aria-hidden="true">
<i style="--c:var(--accent)"></i><i style="--c:var(--ink)"></i><i style="--c:#d9c9b0"></i><i style="--c:#5b8c7e"></i>
</div>
</div>
<div class="hero__panel hero__panel--b" aria-hidden="true">Aa</div>
<div class="hero__panel hero__panel--c">
<span class="tag">Product</span>
<div class="hero__bars" aria-hidden="true"><span></span><span></span><span></span></div>
</div>
</div>
</div>
</section>
<!-- ===== CLIENTS / MARQUEE ===== -->
<section class="clients" aria-label="Selected clients">
<div class="marquee" id="marquee">
<div class="marquee__track">
<span>Halcyon</span><span aria-hidden="true">·</span>
<span>Northwind</span><span aria-hidden="true">·</span>
<span>Persona Labs</span><span aria-hidden="true">·</span>
<span>Tidewell</span><span aria-hidden="true">·</span>
<span>Maison Clé</span><span aria-hidden="true">·</span>
<span>Orbital</span><span aria-hidden="true">·</span>
<span>Field Notes Co.</span><span aria-hidden="true">·</span>
<span>Quartz Bank</span><span aria-hidden="true">·</span>
</div>
<div class="marquee__track" aria-hidden="true">
<span>Halcyon</span><span>·</span>
<span>Northwind</span><span>·</span>
<span>Persona Labs</span><span>·</span>
<span>Tidewell</span><span>·</span>
<span>Maison Clé</span><span>·</span>
<span>Orbital</span><span>·</span>
<span>Field Notes Co.</span><span>·</span>
<span>Quartz Bank</span><span>·</span>
</div>
</div>
</section>
<!-- ===== WORK ===== -->
<section class="work section" id="work">
<div class="wrap">
<header class="section__head reveal" data-reveal>
<h2 class="section__title">Selected<br />works</h2>
<p class="section__lede">A short list, chosen on purpose. Brand systems, digital
products and editorial work shipped with teams who sweat the details.</p>
</header>
<div class="cases">
<article class="case reveal" data-reveal style="--ca:#e7ded0;--cb:#14110d">
<div class="case__media">
<div class="case__hover">View case study →</div>
<span class="case__art" aria-hidden="true">Hl</span>
</div>
<div class="case__meta">
<h3>Halcyon</h3>
<p>Brand identity · Web</p>
<span class="case__year">2025</span>
</div>
</article>
<article class="case reveal" data-reveal style="--ca:#ff5a3c;--cb:#fff">
<div class="case__media">
<div class="case__hover">View case study →</div>
<span class="case__art" aria-hidden="true">Pl</span>
</div>
<div class="case__meta">
<h3>Persona Labs</h3>
<p>Product design · Design system</p>
<span class="case__year">2025</span>
</div>
</article>
<article class="case reveal" data-reveal style="--ca:#1f3a34;--cb:#f6f4ef">
<div class="case__media">
<div class="case__hover">View case study →</div>
<span class="case__art" aria-hidden="true">Td</span>
</div>
<div class="case__meta">
<h3>Tidewell</h3>
<p>Strategy · Naming · Identity</p>
<span class="case__year">2024</span>
</div>
</article>
<article class="case reveal" data-reveal style="--ca:#14110d;--cb:#d9c9b0">
<div class="case__media">
<div class="case__hover">View case study →</div>
<span class="case__art" aria-hidden="true">Mc</span>
</div>
<div class="case__meta">
<h3>Maison Clé</h3>
<p>Editorial · Art direction</p>
<span class="case__year">2024</span>
</div>
</article>
</div>
</div>
</section>
<!-- ===== SERVICES ===== -->
<section class="services section" id="services">
<div class="wrap">
<header class="section__head reveal" data-reveal>
<h2 class="section__title">What we<br />do</h2>
<p class="section__lede">Three practices, one team. We embed early and stay
through launch — strategy and craft never live in separate rooms here.</p>
</header>
<ul class="svc">
<li class="svc__row reveal" data-reveal>
<span class="svc__num">01</span>
<h3 class="svc__name">Brand & Identity</h3>
<p class="svc__desc">Positioning, naming, visual systems, voice and the
guidelines that keep it all coherent as you grow.</p>
<span class="svc__plus" aria-hidden="true">+</span>
</li>
<li class="svc__row reveal" data-reveal>
<span class="svc__num">02</span>
<h3 class="svc__name">Product & Web</h3>
<p class="svc__desc">Interface design, design systems, prototypes and
production-ready front-end for sites and apps.</p>
<span class="svc__plus" aria-hidden="true">+</span>
</li>
<li class="svc__row reveal" data-reveal>
<span class="svc__num">03</span>
<h3 class="svc__name">Editorial & Motion</h3>
<p class="svc__desc">Art direction, campaign systems, print, and motion that
carries the brand into the moving image.</p>
<span class="svc__plus" aria-hidden="true">+</span>
</li>
</ul>
</div>
</section>
<!-- ===== STUDIO / ABOUT + TEAM ===== -->
<section class="studio section" id="studio">
<div class="wrap studio__grid">
<div class="studio__copy reveal" data-reveal>
<p class="eyebrow">The studio</p>
<h2 class="studio__title">Small by design.<br />Sharp on purpose.</h2>
<p>We stayed small so the people you meet are the people who do the work.
No layers, no handoffs to a team you never see — just a tight crew that
cares loudly about the details no one notices and everyone feels.</p>
<div class="stats">
<div class="stat"><strong>40+</strong><span>brands shipped</span></div>
<div class="stat"><strong>9</strong><span>years independent</span></div>
<div class="stat"><strong>3</strong><span>core disciplines</span></div>
</div>
</div>
<div class="team reveal" data-reveal>
<figure class="member">
<div class="member__photo" data-init="ME" aria-hidden="true"></div>
<figcaption><strong>Mara Eilish</strong><span>Founder · Creative Director</span></figcaption>
</figure>
<figure class="member">
<div class="member__photo" data-init="JO" aria-hidden="true"></div>
<figcaption><strong>Jonah Okafor</strong><span>Design Lead</span></figcaption>
</figure>
<figure class="member">
<div class="member__photo" data-init="SR" aria-hidden="true"></div>
<figcaption><strong>Saoirse Renn</strong><span>Strategy</span></figcaption>
</figure>
<figure class="member">
<div class="member__photo" data-init="TV" aria-hidden="true"></div>
<figcaption><strong>Tomás Vidal</strong><span>Engineer</span></figcaption>
</figure>
</div>
</div>
</section>
<!-- ===== AWARDS ===== -->
<section class="awards section" aria-label="Awards and recognition">
<div class="wrap">
<ul class="awards__list">
<li class="reveal" data-reveal><strong>Awwwards</strong><span>Site of the Day ×4</span></li>
<li class="reveal" data-reveal><strong>D&AD</strong><span>Yellow Pencil 2024</span></li>
<li class="reveal" data-reveal><strong>Type Directors</strong><span>Excellence 2023</span></li>
<li class="reveal" data-reveal><strong>FWA</strong><span>Of the Day ×7</span></li>
</ul>
</div>
</section>
<!-- ===== PROCESS ===== -->
<section class="process section" id="process">
<div class="wrap">
<header class="section__head reveal" data-reveal>
<h2 class="section__title">How we<br />work</h2>
<p class="section__lede">A clear path from first call to launch. Predictable
where it should be, open where the interesting things happen.</p>
</header>
<ol class="steps">
<li class="step reveal" data-reveal>
<span class="step__n">01</span>
<h3>Discover</h3>
<p>Workshops, interviews and audits to find the truest, sharpest version of the story.</p>
</li>
<li class="step reveal" data-reveal>
<span class="step__n">02</span>
<h3>Define</h3>
<p>Strategy, positioning and the creative territory we'll build everything on.</p>
</li>
<li class="step reveal" data-reveal>
<span class="step__n">03</span>
<h3>Design</h3>
<p>Identity, interface and content — iterated in the open, decided together.</p>
</li>
<li class="step reveal" data-reveal>
<span class="step__n">04</span>
<h3>Deliver</h3>
<p>Production, handoff and the guidelines that let it live on without us.</p>
</li>
</ol>
</div>
</section>
<!-- ===== TESTIMONIALS ===== -->
<section class="quotes section" aria-label="Client testimonials">
<div class="wrap">
<div class="quote-stage">
<blockquote class="quote is-active" data-quote>
<p>“Foundry & Field gave us a brand that finally felt like us — and a
team that argued for the right answer, not the easy one.”</p>
<footer><strong>Priya Anand</strong> — CEO, Northwind</footer>
</blockquote>
<blockquote class="quote" data-quote>
<p>“The most considered design partner we've worked with. Every detail had a
reason, and the launch numbers backed it up.”</p>
<footer><strong>Daniel Ross</strong> — Founder, Persona Labs</footer>
</blockquote>
<blockquote class="quote" data-quote>
<p>“Small studio, enormous craft. They moved fast without ever cutting a corner
that mattered.”</p>
<footer><strong>Lena Voss</strong> — VP Brand, Quartz Bank</footer>
</blockquote>
</div>
<div class="quote-dots" role="tablist" aria-label="Choose testimonial">
<button role="tab" class="is-active" aria-label="Testimonial 1" data-dot></button>
<button role="tab" aria-label="Testimonial 2" data-dot></button>
<button role="tab" aria-label="Testimonial 3" data-dot></button>
</div>
</div>
</section>
<!-- ===== CONTACT CTA ===== -->
<section class="contact section" id="contact">
<div class="wrap contact__inner reveal" data-reveal>
<p class="eyebrow">Start a project</p>
<h2 class="contact__title">Got something<br />worth making?</h2>
<p class="contact__sub">Tell us what you're building. We'll come back within two
business days with first thoughts and next steps.</p>
<form class="contact__form" id="contactForm" novalidate>
<div class="field">
<label for="name">Name</label>
<input id="name" name="name" type="text" placeholder="Your name" required />
</div>
<div class="field">
<label for="email">Email</label>
<input id="email" name="email" type="email" placeholder="[email protected]" required />
</div>
<div class="field field--full">
<label for="brief">What's the project?</label>
<textarea id="brief" name="brief" rows="3" placeholder="A sentence or two is plenty." required></textarea>
</div>
<button type="submit" class="btn btn--solid btn--lg">Send the brief →</button>
</form>
<p class="contact__alt">Prefer email? <a href="#contact">[email protected]</a></p>
</div>
</section>
</main>
<!-- ===== FOOTER ===== -->
<footer class="footer">
<div class="wrap footer__grid">
<div class="footer__brand">
<span class="logo__mark" aria-hidden="true">F&</span>
<p>An independent design studio building brands that refuse to blend in.</p>
</div>
<nav class="footer__col" aria-label="Footer — studio">
<h4>Studio</h4>
<a href="#work">Work</a>
<a href="#services">Services</a>
<a href="#studio">About</a>
<a href="#process">Process</a>
</nav>
<nav class="footer__col" aria-label="Footer — social">
<h4>Elsewhere</h4>
<a href="#contact">Instagram</a>
<a href="#contact">Dribbble</a>
<a href="#contact">LinkedIn</a>
<a href="#contact">Newsletter</a>
</nav>
<div class="footer__col">
<h4>Say hello</h4>
<a href="#contact">[email protected]</a>
<a href="#contact">+1 (555) 014-2210</a>
<p class="footer__addr">Lisbon · Berlin · Remote</p>
</div>
</div>
<div class="wrap footer__base">
<span>© 2026 Foundry & Field. Fictional studio.</span>
<button class="footer__top" id="toTop">Back to top ↑</button>
</div>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Design Studio Landing
A complete marketing landing page for Foundry & Field, a fictional independent design studio. It leads with an editorial, oversized serif hero — “We design brands that refuse to blend in” — set in warm off-white ink with an electric coral accent, followed by a layered visual of identity, typography and product panels. A sticky, blur-backed nav collapses into an animated hamburger menu on small screens.
The page moves through a curated set of sections: an infinite client marquee, a two-up selected works grid where each case reveals a “View case study” overlay and a scaling monogram on hover, a numbered services list that slides and rotates a plus glyph on interaction, a dark studio + team block with headline stats and monogram team cards, an awards strip, a four-card process sequence, an auto-rotating testimonial carousel with clickable dots, and a validating contact form with a toast confirmation.
Everything is hand-built with semantic landmarks, CSS custom properties, fluid clamp() type,
and vanilla JavaScript — an IntersectionObserver drives the scroll reveals, and a toast()
helper handles CTA feedback. It is fully responsive down to ~360px and respects
prefers-reduced-motion.
Illustrative UI only — fictional brand, not a real product.