Wedding — Landing Rustic
A warm rustic wedding landing page that pairs the blush-and-gold palette with earthy barn tones, an animated countdown to the big day, a scrolling love story, venue and schedule details, a gallery, and a working RSVP form with guest count, meal choice, and live confirmation toast.
MCP
Code
:root {
--blush: #e8b7b0;
--blush-50: #fbeeec;
--rose: #c98a86;
--gold: #c9a24b;
--gold-d: #a8862f;
--ink: #3a2b2b;
--ink-2: #6b5555;
--muted: #9a8585;
--bg: #fbf7f4;
--cream: #f4ece4;
--white: #fff;
--line: rgba(58, 43, 43, 0.12);
/* rustic earth accents layered over the wedding palette */
--bark: #6b4f3a;
--clay: #a86b4c;
--sage: #8a936b;
--r-sm: 8px;
--r-md: 16px;
--r-lg: 26px;
--shadow: 0 18px 40px -22px rgba(58, 43, 43, 0.4);
--serif: "Cormorant Garamond", Georgia, serif;
--sans: "Inter", system-ui, -apple-system, sans-serif;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
margin: 0;
font-family: var(--sans);
color: var(--ink);
background: var(--bg);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3 { font-family: var(--serif); font-weight: 500; margin: 0; letter-spacing: 0.01em; }
a { color: inherit; }
img { max-width: 100%; display: block; }
:focus-visible {
outline: 2px solid var(--gold-d);
outline-offset: 3px;
border-radius: 4px;
}
/* ---------- NAV ---------- */
.nav {
position: sticky;
top: 0;
z-index: 40;
display: flex;
align-items: center;
justify-content: space-between;
padding: 14px clamp(18px, 5vw, 56px);
background: rgba(251, 247, 244, 0.82);
backdrop-filter: blur(10px);
border-bottom: 1px solid var(--line);
}
.nav__brand {
font-family: var(--serif);
font-size: 26px;
font-weight: 600;
text-decoration: none;
letter-spacing: 0.04em;
}
.nav__brand span { color: var(--gold-d); }
.nav__links { display: flex; align-items: center; gap: clamp(10px, 2.6vw, 30px); }
.nav__links a {
text-decoration: none;
font-size: 13px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--ink-2);
transition: color 0.2s;
}
.nav__links a:hover { color: var(--gold-d); }
.nav__cta {
padding: 8px 18px;
border: 1px solid var(--gold);
border-radius: 999px;
color: var(--gold-d) !important;
transition: background 0.2s, color 0.2s;
}
.nav__cta:hover { background: var(--gold); color: var(--white) !important; }
/* ---------- HERO ---------- */
.hero {
position: relative;
min-height: 92vh;
display: grid;
place-items: center;
text-align: center;
padding: 80px 20px;
overflow: hidden;
}
.hero__photo {
position: absolute;
inset: 0;
background:
linear-gradient(180deg, rgba(107, 79, 58, 0.28), rgba(168, 107, 76, 0.22)),
url("https://images.unsplash.com/photo-1519741497674-611481863552?auto=format&fit=crop&w=1600&q=60") center/cover;
transform: scale(1.05);
}
.hero__wash {
position: absolute;
inset: 0;
background:
radial-gradient(120% 90% at 50% 20%, rgba(251, 238, 236, 0.6), transparent 60%),
linear-gradient(180deg, rgba(251, 247, 244, 0.55), rgba(251, 247, 244, 0.9));
}
.hero__inner { position: relative; max-width: 720px; }
.hero__eyebrow {
text-transform: uppercase;
letter-spacing: 0.28em;
font-size: 12px;
font-weight: 600;
color: var(--clay);
margin: 0 0 14px;
}
.hero__names {
font-size: clamp(56px, 12vw, 116px);
line-height: 0.95;
color: var(--ink);
}
.hero__names span { display: block; font-size: 0.42em; color: var(--gold-d); font-style: italic; margin: 4px 0; }
.hero__sub {
font-family: var(--serif);
font-size: clamp(20px, 3.4vw, 30px);
color: var(--ink-2);
margin: 10px 0 22px;
}
.hero__meta {
display: inline-flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 12px;
font-size: 13px;
letter-spacing: 0.14em;
text-transform: uppercase;
font-weight: 600;
color: var(--ink-2);
}
.dot { width: 5px; height: 5px; border-radius: 50%; background: var(--gold); }
.countdown {
display: flex;
justify-content: center;
gap: clamp(10px, 3vw, 26px);
margin: 34px 0;
}
.cd {
min-width: 76px;
padding: 16px 10px;
background: rgba(255, 255, 255, 0.72);
border: 1px solid var(--line);
border-top: 2px solid var(--gold);
border-radius: var(--r-md);
box-shadow: var(--shadow);
}
.cd b {
display: block;
font-family: var(--serif);
font-size: clamp(28px, 6vw, 44px);
font-weight: 600;
line-height: 1;
color: var(--ink);
font-variant-numeric: tabular-nums;
}
.cd small {
display: block;
margin-top: 6px;
font-size: 10px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
}
/* ---------- BUTTONS ---------- */
.btn {
display: inline-block;
font-family: var(--sans);
font-size: 13px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
text-decoration: none;
cursor: pointer;
border: 0;
padding: 14px 32px;
border-radius: 999px;
transition: transform 0.15s, box-shadow 0.2s, background 0.2s;
}
.btn--gold {
background: linear-gradient(135deg, var(--gold), var(--gold-d));
color: var(--white);
box-shadow: 0 12px 26px -12px rgba(168, 134, 47, 0.8);
}
.btn--gold:hover { transform: translateY(-2px); box-shadow: 0 18px 32px -14px rgba(168, 134, 47, 0.9); }
.btn--gold:active { transform: translateY(0); }
.btn--block { width: 100%; }
.btn--ghost {
background: transparent;
color: var(--gold-d);
border: 1px solid var(--gold);
}
.btn--ghost:hover { background: var(--blush-50); }
/* ---------- SECTION SHELL ---------- */
.section { padding: clamp(56px, 9vw, 104px) clamp(18px, 6vw, 64px); max-width: 1080px; margin: 0 auto; }
.section__head { text-align: center; max-width: 640px; margin: 0 auto 44px; }
.kicker {
display: inline-block;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--clay);
margin-bottom: 10px;
}
.section__head h2 { font-size: clamp(34px, 6vw, 54px); position: relative; display: inline-block; padding-bottom: 16px; }
.section__head h2::after {
content: "";
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
width: 64px;
height: 1px;
background: var(--gold);
}
.lead { font-family: var(--serif); font-size: clamp(17px, 2.6vw, 21px); color: var(--ink-2); margin: 14px 0 0; }
/* ---------- STORY ---------- */
.story__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.story__card {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 30px 26px;
transition: transform 0.2s, box-shadow 0.2s;
}
.story__card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.story__year {
font-family: var(--serif);
font-size: 30px;
color: var(--gold-d);
font-style: italic;
}
.story__card h3 { font-size: 24px; margin: 8px 0 10px; }
.story__card p { margin: 0; color: var(--ink-2); font-size: 15px; }
/* ---------- SCHEDULE / TIMELINE ---------- */
.schedule { background: var(--cream); max-width: none; }
.schedule .section__head, .timeline { max-width: 680px; margin-left: auto; margin-right: auto; }
.timeline { list-style: none; padding: 0; margin: 0; position: relative; }
.timeline::before {
content: "";
position: absolute;
left: 66px;
top: 6px;
bottom: 6px;
width: 1px;
background: var(--gold);
opacity: 0.5;
}
.timeline li {
display: grid;
grid-template-columns: 66px 1fr;
gap: 24px;
padding: 18px 0;
position: relative;
}
.timeline li::before {
content: "";
position: absolute;
left: 61px;
top: 26px;
width: 11px;
height: 11px;
border-radius: 50%;
background: var(--white);
border: 2px solid var(--gold-d);
}
.timeline__time { font-family: var(--serif); font-size: 26px; color: var(--clay); text-align: right; }
.timeline h3 { font-size: 22px; }
.timeline p { margin: 4px 0 0; color: var(--ink-2); font-size: 15px; }
/* ---------- VENUE CARDS ---------- */
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.card {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 30px 26px;
transition: transform 0.2s, box-shadow 0.2s;
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow); }
.card__badge {
display: inline-block;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--gold-d);
background: var(--blush-50);
border: 1px solid rgba(201, 162, 75, 0.4);
padding: 5px 12px;
border-radius: 999px;
}
.card h3 { font-size: 24px; margin: 14px 0 10px; }
.card p { margin: 0 0 8px; color: var(--ink-2); font-size: 15px; }
.card__note { font-style: italic; color: var(--muted); font-size: 13.5px; }
/* ---------- GALLERY ---------- */
.gallery__grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: 150px;
gap: 14px;
}
.g { margin: 0; border-radius: var(--r-md); background-size: cover; background-position: center; position: relative; overflow: hidden; }
.g::after {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(180deg, transparent 55%, rgba(107, 79, 58, 0.35));
opacity: 0;
transition: opacity 0.25s;
}
.g:hover::after { opacity: 1; }
.g:hover { transform: scale(1.01); }
.g { transition: transform 0.25s; }
.g--1 { grid-column: span 2; grid-row: span 2; background-image: linear-gradient(rgba(168,107,76,0.12),rgba(168,107,76,0.12)), url("https://images.unsplash.com/photo-1465495976277-4387d4b0b4c6?auto=format&fit=crop&w=800&q=60"); }
.g--2 { grid-column: span 2; background-image: url("https://images.unsplash.com/photo-1519225421980-715cb0215aed?auto=format&fit=crop&w=800&q=60"); }
.g--3 { background-image: url("https://images.unsplash.com/photo-1490750967868-88aa4486c946?auto=format&fit=crop&w=600&q=60"); }
.g--4 { background-image: url("https://images.unsplash.com/photo-1478146896981-b80fe463b330?auto=format&fit=crop&w=600&q=60"); }
.g--5 { grid-column: span 2; background-image: url("https://images.unsplash.com/photo-1510076857177-7470076d4098?auto=format&fit=crop&w=800&q=60"); }
/* ---------- RSVP ---------- */
.rsvp { max-width: 640px; }
.rsvp__panel {
background: var(--white);
border: 1px solid var(--line);
border-top: 3px solid var(--gold);
border-radius: var(--r-lg);
padding: clamp(28px, 5vw, 48px);
box-shadow: var(--shadow);
}
.form { display: grid; gap: 20px; margin-top: 8px; }
.field { border: 0; padding: 0; margin: 0; display: grid; gap: 8px; }
.field label, .field legend {
font-size: 12px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--ink-2);
padding: 0;
}
.opt { color: var(--muted); font-weight: 500; text-transform: none; letter-spacing: 0; }
.field input, .field textarea {
font-family: var(--sans);
font-size: 15px;
color: var(--ink);
background: var(--bg);
border: 1px solid var(--line);
border-radius: var(--r-sm);
padding: 12px 14px;
transition: border-color 0.2s, box-shadow 0.2s;
}
.field input:focus, .field textarea:focus {
outline: none;
border-color: var(--gold);
box-shadow: 0 0 0 3px rgba(201, 162, 75, 0.18);
}
.field input.invalid { border-color: var(--rose); }
.err { color: var(--rose); font-size: 12.5px; min-height: 1em; }
.segmented { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.seg {
font-family: var(--sans);
font-size: 13px;
font-weight: 600;
letter-spacing: 0.04em;
padding: 13px 10px;
border: 1px solid var(--line);
background: var(--bg);
border-radius: var(--r-sm);
color: var(--ink-2);
cursor: pointer;
transition: all 0.18s;
}
.seg:hover { border-color: var(--gold); }
.seg.is-active {
background: var(--ink);
border-color: var(--ink);
color: var(--white);
}
.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
font-family: var(--sans);
font-size: 13px;
font-weight: 600;
padding: 10px 16px;
border: 1px solid var(--line);
background: var(--bg);
border-radius: 999px;
color: var(--ink-2);
cursor: pointer;
transition: all 0.18s;
}
.chip:hover { border-color: var(--gold); color: var(--gold-d); }
.chip.is-active {
background: var(--blush-50);
border-color: var(--gold);
color: var(--gold-d);
box-shadow: inset 0 0 0 1px var(--gold);
}
.attend-only { display: grid; gap: 20px; }
.attend-only.hidden { display: none; }
/* success panel */
.success { text-align: center; padding: 20px 6px; display: grid; gap: 14px; justify-items: center; }
.success__seal {
width: 76px;
height: 76px;
display: grid;
place-items: center;
border-radius: 50%;
border: 2px solid var(--gold);
font-family: var(--serif);
font-size: 26px;
color: var(--gold-d);
background: var(--blush-50);
animation: pop 0.4s ease;
}
@keyframes pop { 0% { transform: scale(0.5); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }
.success h3 { font-size: 30px; }
.success p { margin: 0; color: var(--ink-2); max-width: 400px; }
/* ---------- FOOTER ---------- */
.foot {
text-align: center;
padding: 60px 20px 48px;
background: var(--ink);
color: var(--cream);
}
.foot__mono { font-family: var(--serif); font-size: 40px; margin: 0 0 12px; }
.foot__mono span { color: var(--gold); font-style: italic; }
.foot p { margin: 4px 0; font-size: 14px; color: rgba(244, 236, 228, 0.75); }
.foot__tag { letter-spacing: 0.18em; text-transform: uppercase; font-size: 12px !important; color: var(--gold) !important; margin-top: 14px !important; }
/* ---------- TOAST ---------- */
.toast {
position: fixed;
left: 50%;
bottom: 28px;
transform: translate(-50%, 140%);
background: var(--ink);
color: var(--white);
padding: 14px 22px;
border-radius: 999px;
font-size: 14px;
font-weight: 500;
box-shadow: var(--shadow);
border-left: 3px solid var(--gold);
z-index: 60;
transition: transform 0.35s cubic-bezier(0.2, 0.9, 0.3, 1.2);
max-width: 90vw;
}
.toast.show { transform: translate(-50%, 0); }
/* ---------- REVEAL ---------- */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.6s ease, transform 0.6s ease; }
.reveal.in { opacity: 1; transform: none; }
/* ---------- RESPONSIVE ---------- */
@media (max-width: 860px) {
.story__grid, .cards { grid-template-columns: 1fr; }
.gallery__grid { grid-template-columns: repeat(2, 1fr); }
.g--1, .g--2, .g--5 { grid-column: span 2; }
}
@media (max-width: 520px) {
.nav { padding: 12px 16px; }
.nav__links a:not(.nav__cta) { display: none; }
.hero { min-height: 88vh; padding: 60px 16px; }
.countdown { gap: 8px; }
.cd { min-width: 0; flex: 1; padding: 12px 4px; }
.gallery__grid { grid-template-columns: 1fr; grid-auto-rows: 180px; }
.g--1, .g--2, .g--5 { grid-column: span 1; grid-row: span 1; }
.timeline::before { left: 52px; }
.timeline li { grid-template-columns: 52px 1fr; gap: 16px; }
.timeline li::before { left: 47px; }
.timeline__time { font-size: 21px; }
.segmented { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
html { 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.textContent = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, 3400);
}
/* ---------- Countdown ---------- */
var target = new Date("2026-09-19T15:30:00").getTime();
var elDays = document.getElementById("cd-days");
var elHours = document.getElementById("cd-hours");
var elMins = document.getElementById("cd-mins");
var elSecs = document.getElementById("cd-secs");
function pad(n) { return (n < 10 ? "0" : "") + n; }
function tick() {
var diff = target - Date.now();
if (diff <= 0) {
elDays.textContent = elHours.textContent = elMins.textContent = elSecs.textContent = "00";
var cd = document.getElementById("countdown");
if (cd && !cd.dataset.done) {
cd.dataset.done = "1";
cd.setAttribute("aria-label", "The celebration has begun");
}
return;
}
var d = Math.floor(diff / 86400000);
var h = Math.floor((diff % 86400000) / 3600000);
var m = Math.floor((diff % 3600000) / 60000);
var s = Math.floor((diff % 60000) / 1000);
elDays.textContent = pad(d);
elHours.textContent = pad(h);
elMins.textContent = pad(m);
elSecs.textContent = pad(s);
}
tick();
setInterval(tick, 1000);
/* ---------- Scroll reveal ---------- */
var revealEls = 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 -40px 0px" });
revealEls.forEach(function (el) { io.observe(el); });
} else {
revealEls.forEach(function (el) { el.classList.add("in"); });
}
/* ---------- Generic single-select chip group ---------- */
function bindRadioGroup(container, onChange) {
if (!container) return;
var items = container.querySelectorAll("[role='radio']");
items.forEach(function (btn) {
btn.addEventListener("click", function () {
items.forEach(function (b) {
b.classList.remove("is-active");
b.setAttribute("aria-checked", "false");
});
btn.classList.add("is-active");
btn.setAttribute("aria-checked", "true");
if (onChange) onChange(btn);
});
btn.addEventListener("keydown", function (e) {
if (e.key === "ArrowRight" || e.key === "ArrowDown" || e.key === "ArrowLeft" || e.key === "ArrowUp") {
e.preventDefault();
var list = Array.prototype.slice.call(items);
var i = list.indexOf(btn);
var next = (e.key === "ArrowRight" || e.key === "ArrowDown")
? list[(i + 1) % list.length]
: list[(i - 1 + list.length) % list.length];
next.focus();
next.click();
}
});
});
}
/* ---------- Form state ---------- */
var state = { attend: "yes", guests: "1", meal: "Harvest chicken" };
var attendGroup = document.querySelector(".segmented");
var attendOnly = document.querySelector(".attend-only");
bindRadioGroup(attendGroup, function (btn) {
state.attend = btn.getAttribute("data-attend");
var declining = state.attend === "no";
attendOnly.classList.toggle("hidden", declining);
toast(declining ? "We'll miss you dearly." : "Yay! Fill in your details below.");
});
bindRadioGroup(document.getElementById("guestChips"), function (btn) {
state.guests = btn.getAttribute("data-guests");
});
bindRadioGroup(document.getElementById("mealChips"), function (btn) {
state.meal = btn.getAttribute("data-meal");
});
/* ---------- Validation + submit ---------- */
var form = document.getElementById("rsvpForm");
var successEl = document.getElementById("success");
var successMsg = document.getElementById("successMsg");
var successTitle = document.getElementById("successTitle");
function setError(name, msg) {
var input = form.elements[name];
var slot = form.querySelector("[data-err='" + name + "']");
if (input) input.classList.toggle("invalid", !!msg);
if (slot) slot.textContent = msg || "";
}
function validEmail(v) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v);
}
form.addEventListener("submit", function (e) {
e.preventDefault();
var name = form.elements.fullName.value.trim();
var email = form.elements.email.value.trim();
var ok = true;
if (name.length < 2) { setError("fullName", "Please tell us your name."); ok = false; }
else setError("fullName", "");
if (!validEmail(email)) { setError("email", "Enter a valid email so we can confirm."); ok = false; }
else setError("email", "");
if (!ok) {
toast("Please check the highlighted fields.");
var firstBad = form.querySelector(".invalid");
if (firstBad) firstBad.focus();
return;
}
var firstName = name.split(" ")[0];
if (state.attend === "yes") {
var guestWord = state.guests === "1" ? "1 seat" : state.guests + " seats";
successTitle.textContent = "See you at the barn, " + firstName + "!";
successMsg.textContent = "We've reserved " + guestWord + " for you, with " +
state.meal.toLowerCase() + " on the menu. A confirmation is on its way to " + email + ".";
toast("RSVP received — " + guestWord + " reserved.");
} else {
successTitle.textContent = "Thank you, " + firstName;
successMsg.textContent = "We're sorry you can't make it, but we're grateful you let us know. We'll raise a glass to you.";
toast("Thanks for letting us know.");
}
form.hidden = true;
successEl.hidden = false;
successEl.scrollIntoView({ behavior: "smooth", block: "center" });
});
/* live-clear errors while typing */
["fullName", "email"].forEach(function (n) {
form.elements[n].addEventListener("input", function () { setError(n, ""); });
});
/* ---------- Edit response ---------- */
document.getElementById("editRsvp").addEventListener("click", function () {
successEl.hidden = true;
form.hidden = false;
form.scrollIntoView({ behavior: "smooth", block: "center" });
form.elements.fullName.focus();
});
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Amelia & Rowan — Rustic Wedding</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=Cormorant+Garamond:wght@400;500;600&family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header class="nav" id="top">
<a class="nav__brand" href="#top" aria-label="Amelia and Rowan, home">A <span>&</span> R</a>
<nav class="nav__links" aria-label="Primary">
<a href="#story">Our Story</a>
<a href="#schedule">Schedule</a>
<a href="#venue">Venue</a>
<a href="#gallery">Gallery</a>
<a href="#rsvp" class="nav__cta">RSVP</a>
</nav>
</header>
<main>
<!-- HERO -->
<section class="hero" id="hero">
<div class="hero__photo" aria-hidden="true"></div>
<div class="hero__wash" aria-hidden="true"></div>
<div class="hero__inner reveal">
<p class="hero__eyebrow">Together with their families</p>
<h1 class="hero__names">Amelia <span>&</span> Rowan</h1>
<p class="hero__sub">are getting married at Wildflower Barn</p>
<div class="hero__meta">
<span>Saturday</span>
<span class="dot" aria-hidden="true"></span>
<span>September 19, 2026</span>
<span class="dot" aria-hidden="true"></span>
<span>Hollow Creek, Vermont</span>
</div>
<div class="countdown" id="countdown" role="timer" aria-live="polite" aria-label="Countdown to the wedding">
<div class="cd"><b id="cd-days">00</b><small>Days</small></div>
<div class="cd"><b id="cd-hours">00</b><small>Hours</small></div>
<div class="cd"><b id="cd-mins">00</b><small>Minutes</small></div>
<div class="cd"><b id="cd-secs">00</b><small>Seconds</small></div>
</div>
<a href="#rsvp" class="btn btn--gold">Reserve your seat</a>
</div>
</section>
<!-- STORY -->
<section class="section story" id="story">
<div class="section__head reveal">
<span class="kicker">Est. 2019</span>
<h2>Our Story</h2>
<p class="lead">Two city planners who met over a shared table at a countryside market and never stopped building things together.</p>
</div>
<div class="story__grid">
<article class="story__card reveal">
<span class="story__year">2019</span>
<h3>The Farmers' Market</h3>
<p>Amelia reached for the last jar of wildflower honey. Rowan reached at the same moment. They split it, shared a bench, and talked until the stalls packed up.</p>
</article>
<article class="story__card reveal">
<span class="story__year">2022</span>
<h3>The Old Farmhouse</h3>
<p>They restored a leaning porch on a rented plot outside town, learning that a good partnership is mostly patience, coffee, and a level.</p>
</article>
<article class="story__card reveal">
<span class="story__year">2025</span>
<h3>The Proposal</h3>
<p>Under a string of café lights at the same barn where they'll marry, Rowan asked. Amelia said yes before he finished the sentence.</p>
</article>
</div>
</section>
<!-- SCHEDULE -->
<section class="section schedule" id="schedule">
<div class="section__head reveal">
<span class="kicker">September 19</span>
<h2>The Day</h2>
<p class="lead">A slow, sun-warmed celebration from ceremony to last dance.</p>
</div>
<ol class="timeline">
<li class="reveal"><span class="timeline__time">3:30</span><div><h3>Ceremony</h3><p>Under the oak by the meadow. Grab a fan and a seat.</p></div></li>
<li class="reveal"><span class="timeline__time">4:15</span><div><h3>Cocktail Hour</h3><p>Barrel bar, lawn games, and live acoustic sets.</p></div></li>
<li class="reveal"><span class="timeline__time">5:30</span><div><h3>Dinner</h3><p>Farm-to-table feast in the string-lit barn.</p></div></li>
<li class="reveal"><span class="timeline__time">7:00</span><div><h3>Toasts & Cake</h3><p>Warning: happy tears likely.</p></div></li>
<li class="reveal"><span class="timeline__time">8:00</span><div><h3>Dancing</h3><p>Until the sparklers send us off.</p></div></li>
</ol>
</section>
<!-- VENUE -->
<section class="section venue" id="venue">
<div class="section__head reveal">
<span class="kicker">Getting there</span>
<h2>Venue & Travel</h2>
</div>
<div class="cards">
<article class="card reveal">
<span class="card__badge">The Barn</span>
<h3>Wildflower Barn</h3>
<p>412 Hollow Creek Road<br />Hollow Creek, VT 05301</p>
<p class="card__note">Gravel lot on-site. Flats recommended — it's a working farm.</p>
</article>
<article class="card reveal">
<span class="card__badge">Stay</span>
<h3>Where to Sleep</h3>
<p>The Maple Inn — 12 min drive<br />Creekside Cabins — 8 min drive</p>
<p class="card__note">Ask for the "Hart–Vance" block for a discounted rate.</p>
</article>
<article class="card reveal">
<span class="card__badge">Shuttle</span>
<h3>Rides</h3>
<p>Shuttles run from The Maple Inn at 3:00 & 3:15 PM, returning at 9:00 & 10:30 PM.</p>
<p class="card__note">Rideshare is spotty out here — plan ahead.</p>
</article>
</div>
</section>
<!-- GALLERY -->
<section class="section gallery" id="gallery">
<div class="section__head reveal">
<span class="kicker">Moments</span>
<h2>Gallery</h2>
</div>
<div class="gallery__grid">
<figure class="g g--1 reveal" aria-label="Meadow at golden hour"></figure>
<figure class="g g--2 reveal" aria-label="String lights in the barn"></figure>
<figure class="g g--3 reveal" aria-label="Wildflower bouquet"></figure>
<figure class="g g--4 reveal" aria-label="Vintage farm table setting"></figure>
<figure class="g g--5 reveal" aria-label="Two chairs under the oak"></figure>
</div>
</section>
<!-- RSVP -->
<section class="section rsvp" id="rsvp">
<div class="rsvp__panel reveal">
<div class="section__head">
<span class="kicker">Kindly reply by August 15</span>
<h2>RSVP</h2>
<p class="lead">We can't wait to celebrate with you.</p>
</div>
<form class="form" id="rsvpForm" novalidate>
<div class="field">
<label for="fullName">Full name</label>
<input id="fullName" name="fullName" type="text" autocomplete="name" placeholder="Jamie Rivera" required />
<small class="err" data-err="fullName"></small>
</div>
<div class="field">
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" placeholder="[email protected]" required />
<small class="err" data-err="email"></small>
</div>
<fieldset class="field">
<legend>Will you attend?</legend>
<div class="segmented" role="radiogroup" aria-label="Attendance">
<button type="button" class="seg is-active" data-attend="yes" role="radio" aria-checked="true">Joyfully accept</button>
<button type="button" class="seg" data-attend="no" role="radio" aria-checked="false">Regretfully decline</button>
</div>
</fieldset>
<div class="attend-only">
<fieldset class="field">
<legend>Guests in your party</legend>
<div class="chips" id="guestChips" role="radiogroup" aria-label="Guest count">
<button type="button" class="chip is-active" data-guests="1" role="radio" aria-checked="true">1</button>
<button type="button" class="chip" data-guests="2" role="radio" aria-checked="false">2</button>
<button type="button" class="chip" data-guests="3" role="radio" aria-checked="false">3</button>
<button type="button" class="chip" data-guests="4" role="radio" aria-checked="false">4</button>
</div>
</fieldset>
<fieldset class="field">
<legend>Meal preference</legend>
<div class="chips" id="mealChips" role="radiogroup" aria-label="Meal preference">
<button type="button" class="chip is-active" data-meal="Harvest chicken" role="radio" aria-checked="true">Harvest chicken</button>
<button type="button" class="chip" data-meal="Maple-glazed short rib" role="radio" aria-checked="false">Short rib</button>
<button type="button" class="chip" data-meal="Garden risotto" role="radio" aria-checked="false">Garden risotto (v)</button>
</div>
</fieldset>
</div>
<div class="field">
<label for="note">A note for the couple <span class="opt">(optional)</span></label>
<textarea id="note" name="note" rows="3" placeholder="Song request, dietary needs, or a little love…"></textarea>
</div>
<button type="submit" class="btn btn--gold btn--block">Send RSVP</button>
</form>
<div class="success" id="success" hidden>
<div class="success__seal" aria-hidden="true">A&R</div>
<h3 id="successTitle">You're on the list!</h3>
<p id="successMsg"></p>
<button type="button" class="btn btn--ghost" id="editRsvp">Edit response</button>
</div>
</div>
</section>
</main>
<footer class="foot">
<p class="foot__mono">A <span>&</span> R</p>
<p>Amelia Hart & Rowan Vance · September 19, 2026 · Wildflower Barn</p>
<p class="foot__tag">#HartToVance</p>
</footer>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>A single-page rustic wedding celebration site for Amelia and Rowan, set at a countryside barn. The hero layers a soft blush-and-cream wash over an earthy outdoor photo, with a serif monogram, the date, and a live countdown that ticks down days, hours, minutes, and seconds to the ceremony. Thin gold rules and Cormorant Garamond headings keep the mood editorial and romantic while warm barn tones ground it in the rustic theme.
Below the fold, guests read a two-column love story, browse a timeline of the day’s schedule, and see venue and travel details in tidy cards with hover lift. A gallery strip and a details grid cover dress code, registry, and lodging. Everything scales down cleanly to a single column on small screens.
The RSVP form is fully interactive in vanilla JS: guests toggle attending or declining, pick a guest count and meal preference via custom chips, add a note, and submit to receive an inline success panel plus a toast confirmation. The countdown updates every second, nav links smooth-scroll, and a scroll-reveal fades sections in as they enter the viewport.