Wedding — Services Packages
An editorial blush-and-gold pricing layout for a wedding planning studio, presenting Full Planning, Partial Planning, and Day-of Coordination tiers as elegant cards with itemised inclusions, a featured recommendation ribbon, and hover-lift micro-interactions. A billing toggle reframes each tier by season, inclusion rows reveal on focus, and every enquire button opens a graceful confirmation toast so couples can request their preferred collection in one considered tap.
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 {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
margin: 0;
font-family: var(--sans);
line-height: 1.5;
color: var(--ink);
background:
radial-gradient(1100px 520px at 50% -8%, var(--blush-50), transparent 60%),
var(--bg);
min-height: 100vh;
}
.page {
max-width: 1120px;
margin: 0 auto;
padding: clamp(2.5rem, 6vw, 5rem) clamp(1.1rem, 4vw, 2.5rem) 3.5rem;
}
/* ---------- masthead ---------- */
.masthead {
text-align: center;
margin-bottom: clamp(2rem, 5vw, 3.25rem);
}
.eyebrow {
margin: 0 0 0.9rem;
font-size: 0.72rem;
font-weight: 600;
letter-spacing: 0.28em;
text-transform: uppercase;
color: var(--gold-d);
}
.title {
font-family: var(--serif);
font-weight: 500;
font-size: clamp(2.1rem, 6vw, 3.6rem);
line-height: 1.08;
margin: 0 auto 1rem;
max-width: 15ch;
color: var(--ink);
}
.lede {
margin: 0 auto;
max-width: 52ch;
color: var(--ink-2);
font-size: clamp(0.98rem, 2.4vw, 1.08rem);
}
/* ---------- season toggle ---------- */
.season {
margin: 1.75rem auto 0.5rem;
display: inline-flex;
align-items: center;
gap: 0.85rem;
}
.season__label {
font-size: 0.82rem;
font-weight: 600;
letter-spacing: 0.04em;
color: var(--ink);
transition: color 0.25s ease;
}
.season__label--muted {
color: var(--muted);
}
.switch {
position: relative;
width: 58px;
height: 30px;
border-radius: 999px;
border: 1px solid var(--line);
background: linear-gradient(180deg, var(--white), var(--cream));
cursor: pointer;
padding: 0;
flex: none;
transition: background 0.3s ease, border-color 0.3s ease;
}
.switch__thumb {
position: absolute;
top: 3px;
left: 3px;
width: 22px;
height: 22px;
border-radius: 50%;
background: linear-gradient(160deg, var(--gold), var(--gold-d));
box-shadow: 0 2px 6px rgba(168, 134, 47, 0.4);
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.switch[aria-checked="true"] {
background: linear-gradient(180deg, var(--blush-50), var(--blush));
border-color: var(--rose);
}
.switch[aria-checked="true"] .switch__thumb {
transform: translateX(28px);
}
.season__hint {
margin: 0.65rem 0 0;
font-size: 0.8rem;
color: var(--muted);
font-style: italic;
font-family: var(--serif);
font-size: 0.98rem;
}
/* ---------- tiers ---------- */
.tiers {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: clamp(1rem, 2.5vw, 1.6rem);
align-items: start;
}
.card {
position: relative;
display: flex;
flex-direction: column;
background: var(--white);
border: 1px solid var(--line);
border-radius: var(--r-lg);
padding: 2rem 1.75rem;
outline: none;
transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.3, 1),
box-shadow 0.35s ease, border-color 0.35s ease;
}
.card:hover,
.card:focus-visible {
transform: translateY(-8px);
box-shadow: 0 22px 48px -22px rgba(168, 134, 47, 0.4);
border-color: rgba(201, 162, 75, 0.5);
}
.card:focus-visible {
box-shadow: 0 22px 48px -22px rgba(168, 134, 47, 0.4),
0 0 0 3px var(--blush-50), 0 0 0 4px var(--rose);
}
.card--featured {
background: linear-gradient(180deg, var(--blush-50), var(--white) 55%);
border-color: rgba(201, 138, 134, 0.55);
box-shadow: 0 18px 40px -26px rgba(201, 138, 134, 0.6);
}
.card--featured:hover,
.card--featured:focus-visible {
transform: translateY(-12px);
}
.ribbon {
position: absolute;
top: -13px;
left: 50%;
transform: translateX(-50%);
margin: 0;
padding: 0.4rem 1.1rem;
font-size: 0.66rem;
font-weight: 700;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--white);
background: linear-gradient(135deg, var(--gold), var(--gold-d));
border-radius: 999px;
box-shadow: 0 6px 16px -6px rgba(168, 134, 47, 0.7);
white-space: nowrap;
}
.card__kicker {
margin: 0 0 0.4rem;
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--rose);
}
.card__name {
font-family: var(--serif);
font-weight: 500;
font-size: 2.15rem;
line-height: 1.05;
margin: 0 0 0.6rem;
color: var(--ink);
}
.card__desc {
margin: 0;
font-size: 0.9rem;
color: var(--ink-2);
min-height: 2.7em;
}
/* ---------- price ---------- */
.price {
display: flex;
align-items: baseline;
flex-wrap: wrap;
gap: 0.4rem;
margin: 1.35rem 0;
padding: 1.1rem 0;
border-top: 1px solid var(--line);
border-bottom: 1px solid var(--line);
}
.price__from {
font-size: 0.78rem;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--muted);
}
.price__amount {
font-family: var(--serif);
font-weight: 600;
font-size: 2.6rem;
line-height: 1;
color: var(--ink);
transition: opacity 0.25s ease, transform 0.25s ease;
}
.price__amount.is-swapping {
opacity: 0;
transform: translateY(6px);
}
.price__unit {
font-size: 0.82rem;
color: var(--ink-2);
}
/* ---------- inclusions ---------- */
.incl {
list-style: none;
margin: 0 0 1.75rem;
padding: 0;
display: grid;
gap: 0.15rem;
flex: 1;
}
.incl li {
display: flex;
align-items: flex-start;
gap: 0.7rem;
padding: 0.5rem 0.55rem;
font-size: 0.9rem;
color: var(--ink);
border-radius: var(--r-sm);
transition: background 0.2s ease, transform 0.2s ease;
}
.incl li:hover {
background: var(--blush-50);
transform: translateX(3px);
}
.tick {
flex: none;
display: grid;
place-items: center;
width: 20px;
height: 20px;
margin-top: 1px;
border-radius: 50%;
background: var(--cream);
color: var(--gold-d);
font-size: 0.7rem;
font-weight: 700;
border: 1px solid rgba(201, 162, 75, 0.4);
}
.card--featured .tick {
background: var(--white);
}
/* ---------- buttons ---------- */
.btn {
margin-top: auto;
width: 100%;
padding: 0.9rem 1rem;
border-radius: 999px;
font-family: var(--sans);
font-size: 0.9rem;
font-weight: 600;
letter-spacing: 0.02em;
cursor: pointer;
transition: transform 0.18s ease, box-shadow 0.25s ease,
background 0.25s ease, color 0.25s ease;
}
.btn:active {
transform: scale(0.97);
}
.btn:focus-visible {
outline: none;
box-shadow: 0 0 0 3px var(--blush-50), 0 0 0 4px var(--rose);
}
.btn--solid {
border: 1px solid transparent;
color: var(--white);
background: linear-gradient(135deg, var(--rose), var(--gold-d));
box-shadow: 0 12px 24px -12px rgba(168, 134, 47, 0.7);
}
.btn--solid:hover {
box-shadow: 0 16px 30px -12px rgba(168, 134, 47, 0.85);
transform: translateY(-2px);
}
.btn--ghost {
border: 1px solid var(--line);
color: var(--ink);
background: var(--white);
}
.btn--ghost:hover {
border-color: var(--gold);
color: var(--gold-d);
background: var(--cream);
transform: translateY(-2px);
}
/* ---------- footer note ---------- */
.note {
margin-top: clamp(2.5rem, 5vw, 3.5rem);
text-align: center;
}
.note__rule {
display: block;
width: 70px;
height: 1px;
margin: 0 auto 1.1rem;
background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
.note p {
margin: 0 auto;
max-width: 46ch;
font-family: var(--serif);
font-size: 1.1rem;
color: var(--ink-2);
}
/* ---------- toast ---------- */
.toast {
position: fixed;
left: 50%;
bottom: 28px;
transform: translate(-50%, 140%);
max-width: min(90vw, 380px);
padding: 0.85rem 1.25rem;
border-radius: 999px;
background: var(--ink);
color: var(--white);
font-size: 0.9rem;
font-weight: 500;
box-shadow: 0 18px 40px -14px rgba(58, 43, 43, 0.55);
opacity: 0;
pointer-events: none;
transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.3s ease;
z-index: 50;
}
.toast::before {
content: "❀";
margin-right: 0.55rem;
color: var(--blush);
}
.toast.is-visible {
transform: translate(-50%, 0);
opacity: 1;
}
/* ---------- responsive ---------- */
@media (max-width: 880px) {
.tiers {
grid-template-columns: 1fr;
max-width: 480px;
margin: 0 auto;
}
.card--featured {
order: -1;
}
.card__desc {
min-height: 0;
}
}
@media (max-width: 520px) {
.page {
padding-top: 2.25rem;
}
.card {
padding: 1.6rem 1.35rem;
}
.card__name {
font-size: 1.85rem;
}
.price__amount {
font-size: 2.2rem;
}
.season {
gap: 0.6rem;
}
.toast {
bottom: 18px;
width: calc(100% - 32px);
text-align: center;
}
}
@media (prefers-reduced-motion: reduce) {
* {
transition-duration: 0.01ms !important;
animation-duration: 0.01ms !important;
}
}(function () {
"use strict";
var toggle = document.getElementById("seasonToggle");
var hint = document.getElementById("seasonHint");
var amounts = Array.prototype.slice.call(
document.querySelectorAll(".price__amount")
);
var enquireButtons = Array.prototype.slice.call(
document.querySelectorAll(".enquire")
);
var toastEl = document.getElementById("toast");
var toastTimer = null;
var HINTS = {
peak: "Showing peak-season rates for May–October weddings.",
off: "Showing off-peak rates — save on November–April celebrations.",
};
/* --- toast helper --- */
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("is-visible");
if (toastTimer) clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("is-visible");
}, 3400);
}
/* --- season pricing swap --- */
function applySeason(isOffPeak) {
var key = isOffPeak ? "off" : "peak";
amounts.forEach(function (el) {
var next = "$" + el.getAttribute("data-" + key);
if (el.textContent === next) return;
el.classList.add("is-swapping");
setTimeout(function () {
el.textContent = next;
el.classList.remove("is-swapping");
}, 200);
});
if (hint) hint.textContent = isOffPeak ? HINTS.off : HINTS.peak;
}
if (toggle) {
toggle.addEventListener("click", function () {
var next = toggle.getAttribute("aria-checked") !== "true";
toggle.setAttribute("aria-checked", String(next));
applySeason(next);
});
}
/* --- enquire actions --- */
enquireButtons.forEach(function (btn) {
btn.addEventListener("click", function () {
var pkg = btn.getAttribute("data-package") || "your collection";
var name = pkg.split(" — ")[0];
toast(
"Thank you — your enquiry for " +
name +
" has been noted. We will be in touch within two days."
);
});
});
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Ivory & Vine — Wedding Planning Collections</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>
<main class="page">
<header class="masthead">
<p class="eyebrow">Ivory & Vine · Wedding Atelier</p>
<h1 class="title">Collections for the day you have imagined</h1>
<p class="lede">Three considered ways to plan — from a single graceful afternoon of coordination to a full season of gentle, hands-on guidance.</p>
<div class="season" role="group" aria-label="Choose a pricing season">
<span class="season__label" id="season-peak">Peak season</span>
<button
id="seasonToggle"
class="switch"
role="switch"
aria-checked="false"
aria-labelledby="season-peak season-off"
>
<span class="switch__thumb" aria-hidden="true"></span>
</button>
<span class="season__label season__label--muted" id="season-off">Off-peak</span>
</div>
<p class="season__hint" id="seasonHint">Showing peak-season rates for May–October weddings.</p>
</header>
<section class="tiers" aria-label="Wedding planning packages" aria-live="polite">
<article class="card" tabindex="0" data-tier="Day-of Coordination">
<div class="card__head">
<p class="card__kicker">Day-of Coordination</p>
<h2 class="card__name">The Vow</h2>
<p class="card__desc">For couples who have planned every detail and simply want to be present.</p>
</div>
<p class="price">
<span class="price__from">from</span>
<span class="price__amount" data-peak="1,850" data-off="1,450">$1,850</span>
<span class="price__unit">flat</span>
</p>
<ul class="incl">
<li><span class="tick" aria-hidden="true">✓</span>Two pre-wedding planning consultations</li>
<li><span class="tick" aria-hidden="true">✓</span>Final vendor confirmations & timeline</li>
<li><span class="tick" aria-hidden="true">✓</span>Ceremony rehearsal direction</li>
<li><span class="tick" aria-hidden="true">✓</span>On-site lead coordinator, 10 hours</li>
<li><span class="tick" aria-hidden="true">✓</span>Emergency kit & day-of troubleshooting</li>
</ul>
<button class="btn btn--ghost enquire" data-package="The Vow — Day-of Coordination">Enquire about The Vow</button>
</article>
<article class="card card--featured" tabindex="0" data-tier="Partial Planning">
<p class="ribbon">Most loved</p>
<div class="card__head">
<p class="card__kicker">Partial Planning</p>
<h2 class="card__name">The Bloom</h2>
<p class="card__desc">Guidance from the halfway point — we refine, source, and steward the details.</p>
</div>
<p class="price">
<span class="price__from">from</span>
<span class="price__amount" data-peak="4,600" data-off="3,900">$4,600</span>
<span class="price__unit">collection</span>
</p>
<ul class="incl">
<li><span class="tick" aria-hidden="true">✓</span>Everything in The Vow</li>
<li><span class="tick" aria-hidden="true">✓</span>Curated vendor shortlist & introductions</li>
<li><span class="tick" aria-hidden="true">✓</span>Design direction & mood board</li>
<li><span class="tick" aria-hidden="true">✓</span>Budget stewardship & contract review</li>
<li><span class="tick" aria-hidden="true">✓</span>Monthly planning check-ins</li>
<li><span class="tick" aria-hidden="true">✓</span>Full day-of coordination team of three</li>
</ul>
<button class="btn btn--solid enquire" data-package="The Bloom — Partial Planning">Enquire about The Bloom</button>
</article>
<article class="card" tabindex="0" data-tier="Full Planning">
<div class="card__head">
<p class="card__kicker">Full Planning</p>
<h2 class="card__name">The Everlasting</h2>
<p class="card__desc">A season of complete, hands-on planning — imagined and realised alongside you.</p>
</div>
<p class="price">
<span class="price__from">from</span>
<span class="price__amount" data-peak="9,200" data-off="7,800">$9,200</span>
<span class="price__unit">collection</span>
</p>
<ul class="incl">
<li><span class="tick" aria-hidden="true">✓</span>Everything in The Bloom</li>
<li><span class="tick" aria-hidden="true">✓</span>Full concept & bespoke design</li>
<li><span class="tick" aria-hidden="true">✓</span>End-to-end vendor management</li>
<li><span class="tick" aria-hidden="true">✓</span>Venue sourcing & site visits</li>
<li><span class="tick" aria-hidden="true">✓</span>Guest logistics & travel concierge</li>
<li><span class="tick" aria-hidden="true">✓</span>Unlimited consultations & on-call support</li>
</ul>
<button class="btn btn--ghost enquire" data-package="The Everlasting — Full Planning">Enquire about The Everlasting</button>
</article>
</section>
<footer class="note">
<span class="note__rule" aria-hidden="true"></span>
<p>Every collection includes a complimentary discovery call. Bespoke elopement and multi-day celebration collections available on request.</p>
</footer>
</main>
<div id="toast" class="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>A romantic, editorial services page for a fictional wedding planning studio, Ivory & Vine. Three pricing tiers — Full Planning, Partial Planning, and Day-of Coordination — sit in airy cards separated by thin gold rules. The middle tier carries a “Most loved” ribbon and a soft blush wash to guide the eye, while each card lists real-feeling inclusions with checkmarks and a clear starting price.
A season toggle at the top switches pricing between Peak season and Off-peak, animating the figures and updating a small helper line beneath. Every inclusion row lifts subtly on hover, cards raise on hover and focus with a gold-tinted shadow, and the primary Enquire buttons trigger a graceful toast confirming which collection the couple has requested.
The layout is fully responsive down to about 360px, collapsing the three columns into a single considered stack, and all controls are keyboard-usable with visible focus rings and appropriate aria labelling for the toggle and pricing region.