Wedding — Hero Landing
An editorial blush-and-gold hero for a boutique wedding planner, pairing a serif headline and a couple portrait with a Plan your day CTA, a three-service teaser, and a scrolling strip of featured real weddings. Thin gold rules, airy spacing and gentle micro-interactions give it a romantic, magazine feel, while a lightweight date-check field, animated stat counters and toast feedback make the page feel genuinely alive and bookable.
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);
--r-sm: 8px;
--r-md: 16px;
--r-lg: 26px;
--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);
line-height: 1.5;
color: var(--ink);
background: var(--bg);
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
img { max-width: 100%; display: block; }
.page { max-width: 1180px; margin: 0 auto; padding: 0 28px; }
/* ---------- Header ---------- */
.site-head {
display: flex;
align-items: center;
gap: 20px;
padding: 26px 0 18px;
}
.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--ink); }
.brand-mark {
display: grid;
place-items: center;
width: 42px; height: 42px;
border: 1px solid var(--gold);
border-radius: 50%;
font-family: var(--serif);
font-size: 1.05rem;
font-weight: 600;
color: var(--gold-d);
letter-spacing: 0.04em;
}
.brand-name { font-family: var(--serif); font-size: 1.5rem; font-weight: 600; letter-spacing: 0.01em; }
.nav { margin-left: auto; display: flex; gap: 28px; }
.nav a {
text-decoration: none;
color: var(--ink-2);
font-size: 0.9rem;
font-weight: 500;
letter-spacing: 0.02em;
position: relative;
padding: 4px 0;
transition: color 0.2s;
}
.nav a::after {
content: "";
position: absolute;
left: 0; bottom: -2px;
width: 0; height: 1px;
background: var(--gold);
transition: width 0.25s ease;
}
.nav a:hover, .nav a:focus-visible { color: var(--ink); }
.nav a:hover::after, .nav a:focus-visible::after { width: 100%; }
/* ---------- Buttons ---------- */
.btn {
--_pad: 13px 24px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: var(--_pad);
border: 1px solid transparent;
border-radius: 999px;
font-family: var(--sans);
font-size: 0.92rem;
font-weight: 600;
letter-spacing: 0.02em;
cursor: pointer;
text-decoration: none;
transition: transform 0.18s ease, box-shadow 0.25s ease, background 0.2s, color 0.2s;
}
.btn:focus-visible { outline: 2px solid var(--gold-d); outline-offset: 3px; }
.btn:active { transform: translateY(1px); }
.btn-primary {
background: var(--ink);
color: var(--cream);
box-shadow: 0 10px 24px -12px rgba(58, 43, 43, 0.6);
}
.btn-primary:hover { background: #2b1f1f; transform: translateY(-2px); box-shadow: 0 16px 30px -14px rgba(58, 43, 43, 0.65); }
.btn-gold {
background: linear-gradient(180deg, var(--gold), var(--gold-d));
color: #fff;
box-shadow: 0 10px 22px -12px rgba(168, 134, 47, 0.8);
}
.btn-gold:hover { transform: translateY(-2px); box-shadow: 0 16px 28px -12px rgba(168, 134, 47, 0.9); }
.btn-ghost {
background: transparent;
border-color: var(--line);
color: var(--ink);
}
.btn-ghost:hover { border-color: var(--gold); color: var(--gold-d); }
.btn-link {
background: transparent;
color: var(--ink-2);
padding: 13px 6px;
}
.btn-link:hover { color: var(--gold-d); }
.head-cta { margin-left: 4px; }
/* ---------- Eyebrow ---------- */
.eyebrow {
display: inline-flex;
align-items: center;
gap: 12px;
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
}
.eyebrow.light { color: rgba(255, 255, 255, 0.75); }
.eyebrow .rule { width: 34px; height: 1px; background: var(--gold); display: inline-block; }
.eyebrow.light .rule { background: rgba(255, 255, 255, 0.6); }
/* ---------- Display type ---------- */
.display {
font-family: var(--serif);
font-weight: 500;
line-height: 1.02;
letter-spacing: -0.01em;
margin: 16px 0 0;
}
.display em { font-style: italic; color: var(--rose); }
h1.display { font-size: clamp(2.6rem, 6vw, 4.4rem); }
.display.sm { font-size: clamp(1.9rem, 4vw, 2.9rem); }
/* ---------- Hero ---------- */
.hero {
display: grid;
grid-template-columns: 1.05fr 0.95fr;
gap: 56px;
align-items: center;
padding: 40px 0 72px;
}
.lede {
max-width: 40ch;
color: var(--ink-2);
font-size: 1.06rem;
margin: 20px 0 26px;
}
.hero-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 30px; }
.date-check {
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-md);
padding: 18px 20px;
max-width: 400px;
box-shadow: 0 20px 40px -30px rgba(58, 43, 43, 0.5);
}
.date-check label {
display: block;
font-size: 0.75rem;
font-weight: 600;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--muted);
margin-bottom: 10px;
}
.date-row { display: flex; gap: 10px; }
.date-row input {
flex: 1;
min-width: 0;
padding: 11px 14px;
border: 1px solid var(--line);
border-radius: var(--r-sm);
font-family: var(--sans);
font-size: 0.92rem;
color: var(--ink);
background: var(--bg);
}
.date-row input:focus-visible { outline: 2px solid var(--gold); outline-offset: 1px; border-color: var(--gold); }
.hint { display: block; margin-top: 10px; font-size: 0.78rem; color: var(--muted); }
.stats {
list-style: none;
display: flex;
gap: 34px;
margin: 34px 0 0;
padding: 26px 0 0;
border-top: 1px solid var(--line);
}
.stat-num {
display: block;
font-family: var(--serif);
font-size: 2.1rem;
font-weight: 600;
color: var(--ink);
line-height: 1;
}
.stat-label { font-size: 0.78rem; color: var(--muted); letter-spacing: 0.03em; }
/* Hero media */
.hero-media { position: relative; }
.frame {
position: relative;
border-radius: var(--r-lg);
overflow: hidden;
padding: 12px;
background: var(--white);
box-shadow: 0 40px 70px -40px rgba(58, 43, 43, 0.45);
}
.frame::after {
content: "";
position: absolute;
inset: 20px;
border: 1px solid rgba(201, 162, 75, 0.55);
border-radius: calc(var(--r-lg) - 14px);
pointer-events: none;
z-index: 2;
}
.frame img {
width: 100%;
height: 520px;
object-fit: cover;
border-radius: calc(var(--r-lg) - 12px);
}
.media-badge {
position: absolute;
left: -18px;
bottom: 42px;
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-md);
padding: 14px 20px;
box-shadow: 0 20px 40px -22px rgba(58, 43, 43, 0.5);
z-index: 3;
}
.badge-kicker { display: block; font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--gold-d); font-weight: 700; }
.badge-main { display: block; font-family: var(--serif); font-size: 1.2rem; color: var(--ink); }
.deco-dot { position: absolute; border-radius: 50%; z-index: 1; }
.deco-1 { width: 120px; height: 120px; background: var(--blush-50); top: -26px; right: -22px; }
.deco-2 { width: 60px; height: 60px; border: 1px solid var(--gold); right: 40px; bottom: -24px; }
/* ---------- Section head ---------- */
.section-head { margin-bottom: 34px; }
.section-head.between { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
/* ---------- Services ---------- */
.services { padding: 30px 0 72px; }
.service-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.card {
position: relative;
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 30px 28px 28px;
transition: transform 0.25s ease, box-shadow 0.3s ease, border-color 0.25s;
outline: none;
}
.card::before {
content: "";
position: absolute;
left: 28px; right: 28px; top: 0;
height: 2px;
background: linear-gradient(90deg, var(--gold), transparent);
transform: scaleX(0);
transform-origin: left;
transition: transform 0.3s ease;
}
.card:hover, .card:focus-visible {
transform: translateY(-6px);
box-shadow: 0 30px 50px -34px rgba(58, 43, 43, 0.5);
border-color: rgba(201, 162, 75, 0.5);
}
.card:hover::before, .card:focus-visible::before { transform: scaleX(1); }
.card-badge {
display: inline-block;
font-size: 0.66rem;
font-weight: 700;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--gold-d);
background: var(--blush-50);
border-radius: 999px;
padding: 5px 12px;
margin-bottom: 16px;
}
.card-badge.alt { color: var(--rose); background: #fbeeec; }
.card h3 { font-family: var(--serif); font-size: 1.7rem; font-weight: 600; margin: 0 0 10px; }
.card p { color: var(--ink-2); font-size: 0.94rem; margin: 0 0 20px; }
.card-foot {
display: inline-block;
font-size: 0.82rem;
font-weight: 600;
color: var(--ink);
padding-top: 14px;
border-top: 1px solid var(--line);
}
/* ---------- Real weddings strip ---------- */
.weddings { padding: 20px 0 76px; }
.strip-controls { display: flex; gap: 10px; }
.strip-nav {
width: 44px; height: 44px;
border: 1px solid var(--line);
background: var(--white);
border-radius: 50%;
font-size: 1.4rem;
line-height: 1;
color: var(--ink);
cursor: pointer;
transition: background 0.2s, border-color 0.2s, transform 0.15s;
}
.strip-nav:hover { border-color: var(--gold); color: var(--gold-d); }
.strip-nav:active { transform: scale(0.94); }
.strip-nav:focus-visible { outline: 2px solid var(--gold-d); outline-offset: 2px; }
.strip {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.wedding {
margin: 0;
border-radius: var(--r-lg);
overflow: hidden;
background: var(--white);
border: 1px solid var(--line);
transition: transform 0.3s ease, box-shadow 0.3s ease, opacity 0.3s;
}
.wedding.is-active {
transform: translateY(-6px);
box-shadow: 0 30px 50px -34px rgba(58, 43, 43, 0.5);
border-color: rgba(201, 162, 75, 0.5);
}
.w-media {
height: 250px;
background-image: var(--img);
background-size: cover;
background-position: center;
filter: saturate(0.95);
transition: transform 0.5s ease;
}
.wedding:hover .w-media { transform: scale(1.05); }
.wedding figcaption { padding: 18px 20px 22px; }
.w-place { font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold-d); font-weight: 700; }
.wedding h3 { font-family: var(--serif); font-size: 1.45rem; font-weight: 600; margin: 6px 0 6px; }
.wedding figcaption p { margin: 0; font-size: 0.88rem; color: var(--ink-2); }
.dots { display: flex; gap: 10px; justify-content: center; margin-top: 26px; }
.dot {
width: 9px; height: 9px;
border-radius: 50%;
border: none;
background: var(--line);
cursor: pointer;
padding: 0;
transition: background 0.25s, transform 0.2s, width 0.25s;
}
.dot.is-active { background: var(--gold); width: 26px; border-radius: 999px; }
.dot:focus-visible { outline: 2px solid var(--gold-d); outline-offset: 3px; }
/* ---------- Enquire ---------- */
.enquire {
margin: 0 0 60px;
border-radius: var(--r-lg);
overflow: hidden;
background:
radial-gradient(120% 120% at 0% 0%, rgba(232, 183, 176, 0.4), transparent 55%),
linear-gradient(135deg, #4a3636, var(--ink));
}
.enquire-inner { padding: 60px 40px; text-align: center; color: var(--cream); }
.enquire-inner .display { color: #fff; }
.enquire-inner .display em { color: var(--blush); }
.enquire-inner p { color: rgba(255, 255, 255, 0.78); margin: 14px 0 28px; }
.enquire-inner .eyebrow { justify-content: center; }
/* ---------- Footer ---------- */
.site-foot {
display: flex;
justify-content: space-between;
gap: 16px;
flex-wrap: wrap;
padding: 26px 0 46px;
border-top: 1px solid var(--line);
color: var(--muted);
font-size: 0.82rem;
}
/* ---------- Toast ---------- */
.toast {
position: fixed;
left: 50%;
bottom: 30px;
transform: translate(-50%, 24px);
background: var(--ink);
color: var(--cream);
padding: 14px 22px;
border-radius: 999px;
font-size: 0.9rem;
font-weight: 500;
box-shadow: 0 20px 40px -18px rgba(58, 43, 43, 0.6);
opacity: 0;
pointer-events: none;
transition: opacity 0.3s ease, transform 0.3s ease;
z-index: 50;
max-width: 90vw;
text-align: center;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }
.toast .accent { color: var(--gold); }
/* ---------- Responsive ---------- */
@media (max-width: 900px) {
.hero { grid-template-columns: 1fr; gap: 44px; }
.strip { grid-template-columns: repeat(2, 1fr); }
.service-grid { grid-template-columns: 1fr; }
.nav { display: none; }
}
@media (max-width: 520px) {
.page { padding: 0 18px; }
.site-head { gap: 12px; }
.head-cta { display: none; }
.brand-name { font-size: 1.3rem; }
.frame img { height: 380px; }
.stats { flex-wrap: wrap; gap: 22px 34px; }
.strip { grid-template-columns: 1fr; }
.strip-controls { display: none; }
.media-badge { left: 8px; bottom: 12px; padding: 11px 15px; }
.enquire-inner { padding: 44px 22px; }
.site-foot { flex-direction: column; gap: 8px; }
.hero-actions { gap: 8px; }
}(function () {
"use strict";
/* ---------- Toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer;
function toast(msg, ms) {
if (!toastEl) return;
toastEl.innerHTML = msg;
toastEl.classList.add("show");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("show");
}, ms || 3200);
}
/* ---------- Smooth scroll for [data-scroll] and header links ---------- */
document.querySelectorAll('a[href^="#"]').forEach(function (a) {
a.addEventListener("click", function (e) {
var id = a.getAttribute("href");
if (id.length < 2) return;
var target = document.querySelector(id);
if (!target) return;
e.preventDefault();
target.scrollIntoView({ behavior: "smooth", block: "start" });
});
});
/* ---------- Date availability check ---------- */
var form = document.getElementById("date-check");
var input = document.getElementById("wdate");
var MONTHS = ["January","February","March","April","May","June","July","August","September","October","November","December"];
if (form && input) {
form.addEventListener("submit", function (e) {
e.preventDefault();
if (!input.value) {
toast("Please choose a date to check.");
input.focus();
return;
}
var picked = new Date(input.value + "T00:00:00");
var today = new Date();
today.setHours(0, 0, 0, 0);
if (picked < today) {
toast("That date has already passed — try a future date.");
return;
}
var label = MONTHS[picked.getMonth()] + " " + picked.getFullYear();
// Peak months (May, Jun, Sep, Oct) are "limited"; others "open".
var peak = [4, 5, 8, 9].indexOf(picked.getMonth()) !== -1;
if (peak) {
toast('<span class="accent">' + label + '</span> is a popular season — a few dates remain.');
} else {
toast('Good news — <span class="accent">' + label + '</span> looks open. Let’s talk.');
}
});
}
/* ---------- Animated stat counters ---------- */
var counters = Array.prototype.slice.call(document.querySelectorAll(".stat-num"));
function animateCount(el) {
var target = parseInt(el.getAttribute("data-count"), 10) || 0;
var suffix = el.getAttribute("data-suffix") || "";
var start = 0;
var dur = 1400;
var t0 = null;
function step(ts) {
if (t0 === null) t0 = ts;
var p = Math.min((ts - t0) / dur, 1);
var eased = 1 - Math.pow(1 - p, 3);
el.textContent = Math.round(start + (target - start) * eased) + suffix;
if (p < 1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
}
if ("IntersectionObserver" in window && counters.length) {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (entry.isIntersecting) {
animateCount(entry.target);
io.unobserve(entry.target);
}
});
}, { threshold: 0.5 });
counters.forEach(function (c) { io.observe(c); });
} else {
counters.forEach(animateCount);
}
/* ---------- Real-wedding strip carousel ---------- */
var strip = document.getElementById("strip");
var slides = strip ? Array.prototype.slice.call(strip.querySelectorAll(".wedding")) : [];
var dotsWrap = document.getElementById("dots");
var current = 0;
var autoTimer;
function setActive(i) {
current = (i + slides.length) % slides.length;
slides.forEach(function (s, idx) { s.classList.toggle("is-active", idx === current); });
if (dotsWrap) {
Array.prototype.slice.call(dotsWrap.children).forEach(function (d, idx) {
d.classList.toggle("is-active", idx === current);
d.setAttribute("aria-selected", idx === current ? "true" : "false");
});
}
}
if (slides.length && dotsWrap) {
slides.forEach(function (s, idx) {
var b = document.createElement("button");
b.className = "dot" + (idx === 0 ? " is-active" : "");
b.setAttribute("role", "tab");
var name = s.querySelector("h3");
b.setAttribute("aria-label", name ? name.textContent : "Wedding " + (idx + 1));
b.addEventListener("click", function () { setActive(idx); restartAuto(); });
dotsWrap.appendChild(b);
});
slides.forEach(function (s, idx) {
s.addEventListener("click", function () { setActive(idx); restartAuto(); });
});
var prev = document.getElementById("prev");
var next = document.getElementById("next");
if (prev) prev.addEventListener("click", function () { setActive(current - 1); restartAuto(); });
if (next) next.addEventListener("click", function () { setActive(current + 1); restartAuto(); });
function startAuto() { autoTimer = setInterval(function () { setActive(current + 1); }, 4200); }
function restartAuto() { clearInterval(autoTimer); startAuto(); }
strip.addEventListener("mouseenter", function () { clearInterval(autoTimer); });
strip.addEventListener("mouseleave", startAuto);
startAuto();
}
/* ---------- Enquire CTA ---------- */
var enquireBtn = document.getElementById("enquire-btn");
if (enquireBtn) {
enquireBtn.addEventListener("click", function () {
toast('Thank you — we’ll be in touch within <span class="accent">two working days</span>.');
});
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Maison Vera — Wedding Planning</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>
<div class="page">
<!-- Header -->
<header class="site-head">
<a class="brand" href="#top" aria-label="Maison Vera home">
<span class="brand-mark">MV</span>
<span class="brand-name">Maison Vera</span>
</a>
<nav class="nav" aria-label="Primary">
<a href="#services">Services</a>
<a href="#weddings">Real Weddings</a>
<a href="#enquire">Contact</a>
</nav>
<a class="btn btn-ghost head-cta" href="#enquire">Enquire</a>
</header>
<!-- Hero -->
<section class="hero" id="top">
<div class="hero-copy">
<span class="eyebrow"><span class="rule"></span>Boutique wedding planning · Est. 2014</span>
<h1 class="display">Your day, <em>quietly</em><br />extraordinary.</h1>
<p class="lede">We design intimate, editorial celebrations across the coast and countryside — from the first mood board to the last dance under the stars.</p>
<div class="hero-actions">
<a class="btn btn-primary" href="#enquire" data-scroll>Plan your day</a>
<a class="btn btn-link" href="#weddings" data-scroll>View real weddings →</a>
</div>
<form class="date-check" id="date-check" novalidate>
<label for="wdate">Check your date</label>
<div class="date-row">
<input type="date" id="wdate" name="wdate" aria-describedby="date-hint" />
<button type="submit" class="btn btn-gold">Check</button>
</div>
<span class="hint" id="date-hint">We take a limited number of weddings each season.</span>
</form>
<ul class="stats" aria-label="Studio at a glance">
<li><span class="stat-num" data-count="210">0</span><span class="stat-label">Weddings planned</span></li>
<li><span class="stat-num" data-count="14">0</span><span class="stat-label">Years crafting days</span></li>
<li><span class="stat-num" data-count="38" data-suffix="+">0</span><span class="stat-label">Trusted venues</span></li>
</ul>
</div>
<div class="hero-media">
<div class="frame">
<img src="https://images.unsplash.com/photo-1519741497674-611481863552?auto=format&fit=crop&w=900&q=80" alt="A couple sharing a quiet moment on their wedding day" />
</div>
<div class="media-badge">
<span class="badge-kicker">Now booking</span>
<span class="badge-main">Spring & Autumn 2027</span>
</div>
<span class="deco-dot deco-1" aria-hidden="true"></span>
<span class="deco-dot deco-2" aria-hidden="true"></span>
</div>
</section>
<!-- Services -->
<section class="services" id="services">
<div class="section-head">
<span class="eyebrow"><span class="rule"></span>What we do</span>
<h2 class="display sm">Three ways to say <em>yes</em>.</h2>
</div>
<div class="service-grid">
<article class="card" tabindex="0">
<span class="card-badge">Signature</span>
<h3>Full Planning</h3>
<p>End-to-end design and logistics — venue, vendors, timeline and styling handled from proposal to send-off.</p>
<span class="card-foot">From $12,000</span>
</article>
<article class="card" tabindex="0">
<span class="card-badge alt">Popular</span>
<h3>Design & Styling</h3>
<p>Palette, florals, tablescapes and paper goods composed into one cohesive, editorial visual story.</p>
<span class="card-foot">From $6,500</span>
</article>
<article class="card" tabindex="0">
<span class="card-badge">Essential</span>
<h3>Day-of Coordination</h3>
<p>You plan the details; we run the day — a calm, invisible hand keeping every moment on cue.</p>
<span class="card-foot">From $2,900</span>
</article>
</div>
</section>
<!-- Real weddings strip -->
<section class="weddings" id="weddings">
<div class="section-head between">
<div>
<span class="eyebrow"><span class="rule"></span>Featured</span>
<h2 class="display sm">Real weddings, real people.</h2>
</div>
<div class="strip-controls" aria-hidden="false">
<button class="strip-nav" id="prev" aria-label="Previous wedding">‹</button>
<button class="strip-nav" id="next" aria-label="Next wedding">›</button>
</div>
</div>
<div class="strip" id="strip" aria-live="polite">
<figure class="wedding is-active">
<div class="w-media" style="--img:url('https://images.unsplash.com/photo-1465495976277-4387d4b0b4c6?auto=format&fit=crop&w=900&q=80')"></div>
<figcaption>
<span class="w-place">Amalfi Coast, Italy</span>
<h3>Elena & Marco</h3>
<p>A cliffside dinner for 60 under strings of warm light.</p>
</figcaption>
</figure>
<figure class="wedding">
<div class="w-media" style="--img:url('https://images.unsplash.com/photo-1511285560929-80b456fea0bc?auto=format&fit=crop&w=900&q=80')"></div>
<figcaption>
<span class="w-place">Cotswolds, England</span>
<h3>Amara & Joel</h3>
<p>An early-autumn barn wedding wrapped in dried grasses.</p>
</figcaption>
</figure>
<figure class="wedding">
<div class="w-media" style="--img:url('https://images.unsplash.com/photo-1520854221256-17451cc331bf?auto=format&fit=crop&w=900&q=80')"></div>
<figcaption>
<span class="w-place">Big Sur, California</span>
<h3>Priya & Noah</h3>
<p>Sea-mist vows and a candlelit long table for close family.</p>
</figcaption>
</figure>
<figure class="wedding">
<div class="w-media" style="--img:url('https://images.unsplash.com/photo-1522673607200-164d1b6ce486?auto=format&fit=crop&w=900&q=80')"></div>
<figcaption>
<span class="w-place">Provence, France</span>
<h3>Sofia & Léa</h3>
<p>Lavender fields, linen suits and a very long lunch.</p>
</figcaption>
</figure>
</div>
<div class="dots" id="dots" role="tablist" aria-label="Choose a wedding"></div>
</section>
<!-- Enquire band -->
<section class="enquire" id="enquire">
<div class="enquire-inner">
<span class="eyebrow light"><span class="rule"></span>Let's begin</span>
<h2 class="display sm">Tell us about your day.</h2>
<p>We reply to every enquiry within two working days with a bespoke proposal.</p>
<button class="btn btn-gold" id="enquire-btn">Start planning</button>
</div>
</section>
<footer class="site-foot">
<span>© 2026 Maison Vera Studio</span>
<span>Handcrafted celebrations · Coast & Countryside</span>
</footer>
</div>
<div class="toast" id="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>A full-width romantic hero for Maison Vera, a boutique wedding planning studio. The left column carries an oversized Cormorant Garamond headline, a short intro line, a primary “Plan your day” call to action and a secondary “View real weddings” link, all above a row of animated trust stats. The right column shows a couple portrait framed with thin gold rules and a small floating “fully planned” badge. Beneath the fold sits a three-card services teaser (Full Planning, Design & Styling, Day-of Coordination) with hover lift and gold accents.
The interactions are all vanilla JS. A compact date-check field lets a visitor enter their wedding date and instantly see a friendly availability message via a toast() helper, while the CTA scrolls smoothly to the enquiry area. The trust stats count up when they scroll into view using an IntersectionObserver, and the featured real-wedding strip auto-advances through couples with clickable dots and pause-on-hover.
The layout is responsive down to ~360px: the hero collapses to a single column, the services grid stacks, and the real-wedding strip stays swipeable. Focus states are visible on every control, buttons are keyboard-usable, and colour contrast follows the blush, gold and ink palette for an elegant, accessible finish.