Shop — Order Confirmation
A reassuring e-commerce order confirmation page with an animated success check and a celebratory confetti burst on load. It pairs a copy-to-clipboard order number with an estimated-delivery card and a four-stage step tracker (Confirmed, Packed, Shipped, Delivered), an expandable itemized summary with totals and payment method, a shipping address block with a CSS map illustration, and clear track-order and continue-shopping calls to action. Fully responsive, keyboard friendly, and built with vanilla JavaScript.
MCP
Code
:root {
--bg: #f6f7fb;
--surface: #ffffff;
--ink: #16181d;
--muted: #6b7280;
--faint: #9aa1ad;
--brand: #3457ff;
--brand-d: #2742d6;
--brand-tint: #eef1ff;
--sale: #e0245e;
--ok: #1f9d55;
--ok-tint: #e7f6ed;
--line: rgba(16, 18, 29, 0.1);
--line-2: rgba(16, 18, 29, 0.06);
--shadow: 0 1px 2px rgba(16, 18, 29, 0.04), 0 12px 30px -18px rgba(16, 18, 29, 0.22);
--radius: 18px;
--radius-sm: 12px;
--maxw: 940px;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
font-family: "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
background:
radial-gradient(1200px 480px at 50% -8%, var(--brand-tint), transparent 60%),
var(--bg);
color: var(--ink);
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
min-height: 100vh;
}
#confetti {
position: fixed;
inset: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 60;
}
/* ---------- Header ---------- */
.site-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
max-width: var(--maxw);
margin: 0 auto;
padding: 18px 20px;
}
.brand {
display: inline-flex;
align-items: center;
gap: 10px;
text-decoration: none;
color: var(--ink);
}
.brand__mark {
display: grid;
place-items: center;
width: 36px;
height: 36px;
border-radius: 10px;
background: var(--brand);
color: #fff;
box-shadow: 0 6px 16px -6px rgba(52, 87, 255, 0.7);
}
.brand__name {
font-weight: 800;
letter-spacing: -0.02em;
font-size: 1.05rem;
}
.brand__name span {
color: var(--brand);
}
.header-trust {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 0.82rem;
font-weight: 600;
color: var(--ok);
background: var(--ok-tint);
padding: 7px 12px;
border-radius: 999px;
}
/* ---------- Layout ---------- */
.content {
max-width: var(--maxw);
margin: 0 auto;
padding: 8px 20px 64px;
}
.card {
background: var(--surface);
border: 1px solid var(--line);
border-radius: var(--radius);
box-shadow: var(--shadow);
padding: 24px;
}
.content h2 {
font-size: 1.08rem;
margin: 0 0 4px;
letter-spacing: -0.01em;
}
/* ---------- Hero ---------- */
.hero {
text-align: center;
padding: 22px 12px 30px;
}
.success-icon {
width: 84px;
height: 84px;
margin: 0 auto 18px;
}
.checkmark {
width: 84px;
height: 84px;
}
.checkmark .circle {
fill: var(--ok-tint);
stroke: var(--ok);
stroke-width: 3;
stroke-dasharray: 244;
stroke-dashoffset: 244;
animation: draw-circle 0.6s ease-out forwards;
}
.checkmark .check {
fill: none;
stroke: var(--ok);
stroke-width: 4;
stroke-linecap: round;
stroke-linejoin: round;
stroke-dasharray: 60;
stroke-dashoffset: 60;
animation: draw-check 0.4s 0.55s ease-out forwards;
}
@keyframes draw-circle {
to {
stroke-dashoffset: 0;
}
}
@keyframes draw-check {
to {
stroke-dashoffset: 0;
}
}
.eyebrow {
text-transform: uppercase;
letter-spacing: 0.12em;
font-size: 0.72rem;
font-weight: 700;
color: var(--ok);
margin: 0 0 6px;
}
.hero h1 {
font-size: clamp(1.5rem, 4.4vw, 2.1rem);
line-height: 1.18;
letter-spacing: -0.025em;
margin: 0 auto 12px;
max-width: 18ch;
}
.lede {
color: var(--muted);
max-width: 46ch;
margin: 0 auto 22px;
font-size: 0.96rem;
}
.lede strong {
color: var(--ink);
font-weight: 600;
}
.order-pill {
display: inline-flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
justify-content: center;
background: var(--surface);
border: 1px solid var(--line);
border-radius: 999px;
padding: 8px 8px 8px 18px;
box-shadow: var(--shadow);
}
.order-pill__label {
font-size: 0.8rem;
color: var(--muted);
}
.order-pill__num {
font-weight: 700;
letter-spacing: -0.01em;
font-variant-numeric: tabular-nums;
}
.copy-btn {
display: inline-flex;
align-items: center;
gap: 6px;
border: 0;
border-radius: 999px;
padding: 8px 14px;
font: inherit;
font-size: 0.82rem;
font-weight: 600;
color: var(--brand);
background: var(--brand-tint);
cursor: pointer;
transition: background 0.15s, color 0.15s, transform 0.08s;
}
.copy-btn:hover {
background: #e3e8ff;
}
.copy-btn:active {
transform: scale(0.96);
}
.copy-btn .ic-check {
display: none;
}
.copy-btn.is-copied {
color: var(--ok);
background: var(--ok-tint);
}
.copy-btn.is-copied .ic-copy {
display: none;
}
.copy-btn.is-copied .ic-check {
display: inline;
}
/* ---------- Delivery + tracker ---------- */
.delivery {
margin-top: 12px;
}
.delivery__top {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 14px;
margin-bottom: 22px;
}
.delivery__date {
margin: 2px 0 2px;
font-size: 1.18rem;
letter-spacing: -0.01em;
}
.delivery__meta {
margin: 0;
color: var(--muted);
font-size: 0.88rem;
}
.ship-chip {
flex: none;
display: inline-flex;
align-items: center;
gap: 7px;
font-size: 0.8rem;
font-weight: 600;
color: var(--ok);
background: var(--ok-tint);
padding: 6px 12px;
border-radius: 999px;
}
.ship-chip__dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: var(--ok);
box-shadow: 0 0 0 0 rgba(31, 157, 85, 0.5);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
box-shadow: 0 0 0 0 rgba(31, 157, 85, 0.45);
}
70% {
box-shadow: 0 0 0 8px rgba(31, 157, 85, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(31, 157, 85, 0);
}
}
.tracker {
list-style: none;
margin: 0;
padding: 0;
display: grid;
grid-template-columns: repeat(4, 1fr);
position: relative;
}
.tracker__step {
position: relative;
text-align: center;
padding-top: 30px;
}
/* connector line */
.tracker__step::before {
content: "";
position: absolute;
top: 10px;
left: 50%;
width: 100%;
height: 3px;
background: var(--line);
z-index: 0;
}
.tracker__step:last-child::before {
display: none;
}
.tracker__step.is-done::before {
background: var(--ok);
}
.tracker__dot {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 22px;
height: 22px;
border-radius: 50%;
background: var(--surface);
border: 3px solid var(--line);
display: grid;
place-items: center;
color: #fff;
z-index: 1;
}
.tracker__step.is-done .tracker__dot {
background: var(--ok);
border-color: var(--ok);
}
.tracker__step.is-active .tracker__dot {
border-color: var(--brand);
background: var(--brand);
box-shadow: 0 0 0 5px var(--brand-tint);
animation: pulse-brand 2s infinite;
}
@keyframes pulse-brand {
0% {
box-shadow: 0 0 0 0 rgba(52, 87, 255, 0.35);
}
70% {
box-shadow: 0 0 0 9px rgba(52, 87, 255, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(52, 87, 255, 0);
}
}
.tracker__label {
display: block;
font-size: 0.86rem;
font-weight: 600;
}
.tracker__step.is-active .tracker__label {
color: var(--brand);
}
.tracker__sub {
display: block;
font-size: 0.74rem;
color: var(--faint);
margin-top: 1px;
}
/* ---------- Grid (summary + address) ---------- */
.grid {
display: grid;
grid-template-columns: 1.35fr 1fr;
gap: 16px;
margin-top: 16px;
}
/* ---------- Summary ---------- */
.summary__head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 6px;
}
.toggle-items {
display: inline-flex;
align-items: center;
gap: 6px;
border: 1px solid var(--line);
background: var(--surface);
border-radius: 999px;
padding: 6px 12px;
font: inherit;
font-size: 0.82rem;
font-weight: 600;
color: var(--muted);
cursor: pointer;
transition: background 0.15s, color 0.15s;
}
.toggle-items:hover {
background: var(--bg);
color: var(--ink);
}
.toggle-items .chev {
transition: transform 0.25s ease;
}
.toggle-items[aria-expanded="false"] .chev {
transform: rotate(-90deg);
}
.items {
list-style: none;
margin: 14px 0 0;
padding: 0;
display: grid;
gap: 14px;
overflow: hidden;
transition: max-height 0.3s ease, opacity 0.25s ease, margin 0.3s ease;
max-height: 800px;
opacity: 1;
}
.items.is-collapsed {
max-height: 0;
opacity: 0;
margin-top: 0;
}
.item {
display: grid;
grid-template-columns: auto 1fr auto;
gap: 14px;
align-items: center;
}
.item__thumb {
width: 60px;
height: 60px;
border-radius: 14px;
display: grid;
place-items: center;
}
.thumb--lamp {
background: linear-gradient(135deg, #fff1da, #ffe1b0);
color: #b06a00;
}
.thumb--mug {
background: linear-gradient(135deg, #e6f3ec, #cfe9d9);
color: #2f7a52;
}
.thumb--candle {
background: linear-gradient(135deg, #f1ecff, #e0d6ff);
color: #6b4bd0;
}
.item__info {
display: flex;
flex-direction: column;
gap: 1px;
min-width: 0;
}
.item__info strong {
font-size: 0.95rem;
letter-spacing: -0.01em;
}
.item__opts {
font-size: 0.82rem;
color: var(--muted);
}
.item__qty {
font-size: 0.78rem;
color: var(--faint);
}
.item__price {
font-weight: 700;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.totals {
margin: 18px 0 0;
padding-top: 16px;
border-top: 1px solid var(--line);
display: grid;
gap: 9px;
}
.totals__row {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0;
font-size: 0.92rem;
color: var(--muted);
}
.totals__row dt {
margin: 0;
}
.totals__row dd {
margin: 0;
font-variant-numeric: tabular-nums;
color: var(--ink);
font-weight: 500;
}
.totals__row .free {
color: var(--ok);
font-weight: 600;
}
.totals__row--grand {
margin-top: 6px;
padding-top: 12px;
border-top: 1px dashed var(--line);
font-size: 1.05rem;
}
.totals__row--grand dt {
color: var(--ink);
font-weight: 700;
}
.totals__row--grand dd {
font-weight: 800;
font-size: 1.15rem;
}
.paid-with {
display: inline-flex;
align-items: center;
gap: 9px;
margin: 16px 0 0;
font-size: 0.85rem;
color: var(--muted);
}
.card-glyph {
color: var(--faint);
display: inline-flex;
}
/* ---------- Address ---------- */
.address__block {
font-style: normal;
line-height: 1.7;
font-size: 0.92rem;
color: var(--muted);
margin: 8px 0 16px;
}
.address__block strong {
display: block;
color: var(--ink);
font-size: 0.98rem;
margin-bottom: 2px;
}
.address__phone {
color: var(--faint);
font-size: 0.85rem;
}
.map {
height: 120px;
border-radius: var(--radius-sm);
overflow: hidden;
background:
radial-gradient(120px 90px at 74% 50%, rgba(52, 87, 255, 0.12), transparent 70%),
linear-gradient(135deg, #eef1f6, #e3e8f2);
border: 1px solid var(--line-2);
}
.map svg {
width: 100%;
height: 100%;
}
.map-road {
fill: none;
stroke: #fff;
stroke-width: 7;
stroke-linecap: round;
opacity: 0.85;
}
.map-road--thin {
stroke-width: 4;
opacity: 0.7;
}
.map-pin-ring {
fill: rgba(52, 87, 255, 0.18);
}
.map-pin {
fill: var(--brand);
}
.help {
margin-top: 18px;
padding-top: 16px;
border-top: 1px solid var(--line);
}
.help h3 {
margin: 0 0 4px;
font-size: 0.92rem;
}
.help p {
margin: 0 0 10px;
font-size: 0.85rem;
color: var(--muted);
}
.help__links {
display: flex;
flex-wrap: wrap;
gap: 8px 18px;
}
.help__link {
font-size: 0.86rem;
font-weight: 600;
color: var(--brand);
text-decoration: none;
}
.help__link:hover {
text-decoration: underline;
}
/* ---------- CTAs ---------- */
.cta-row {
display: flex;
gap: 12px;
margin-top: 24px;
}
.btn {
flex: 1;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 15px 20px;
border-radius: 14px;
font-weight: 700;
font-size: 0.96rem;
text-decoration: none;
cursor: pointer;
border: 1px solid transparent;
transition: background 0.15s, transform 0.08s, box-shadow 0.15s, border-color 0.15s;
}
.btn:active {
transform: translateY(1px);
}
.btn--primary {
background: var(--brand);
color: #fff;
box-shadow: 0 12px 26px -12px rgba(52, 87, 255, 0.85);
}
.btn--primary:hover {
background: var(--brand-d);
}
.btn--ghost {
background: var(--surface);
color: var(--ink);
border-color: var(--line);
}
.btn--ghost:hover {
background: var(--bg);
border-color: rgba(16, 18, 29, 0.18);
}
.footnote {
text-align: center;
color: var(--faint);
font-size: 0.82rem;
margin: 22px 0 0;
}
/* ---------- Focus ---------- */
:focus-visible {
outline: 3px solid rgba(52, 87, 255, 0.45);
outline-offset: 2px;
border-radius: 6px;
}
/* ---------- Toast ---------- */
.toast {
position: fixed;
left: 50%;
bottom: 26px;
transform: translate(-50%, 140%);
background: var(--ink);
color: #fff;
padding: 12px 18px;
border-radius: 12px;
font-size: 0.88rem;
font-weight: 600;
box-shadow: 0 14px 34px -12px rgba(0, 0, 0, 0.5);
z-index: 80;
opacity: 0;
transition: transform 0.32s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.3s;
max-width: calc(100vw - 32px);
}
.toast.is-visible {
transform: translate(-50%, 0);
opacity: 1;
}
/* ---------- Responsive ---------- */
@media (max-width: 760px) {
.grid {
grid-template-columns: 1fr;
}
}
@media (max-width: 520px) {
.content {
padding: 4px 16px 56px;
}
.card {
padding: 20px;
}
.delivery__top {
flex-direction: column;
}
.tracker__label {
font-size: 0.78rem;
}
.tracker__sub {
display: none;
}
.cta-row {
flex-direction: column;
}
.header-trust {
display: none;
}
}
@media (max-width: 380px) {
.hero h1 {
font-size: 1.4rem;
}
.item__thumb {
width: 50px;
height: 50px;
}
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.001ms !important;
}
.checkmark .circle,
.checkmark .check {
stroke-dashoffset: 0;
}
}(function () {
"use strict";
var prefersReduced =
window.matchMedia &&
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
/* ---------- Toast helper ---------- */
var toastEl = document.getElementById("toast");
var toastTimer;
function toast(msg) {
if (!toastEl) return;
toastEl.textContent = msg;
toastEl.classList.add("is-visible");
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.classList.remove("is-visible");
}, 2600);
}
/* ---------- Copy order number ---------- */
var copyBtn = document.getElementById("copy-btn");
var orderNumEl = document.getElementById("order-number");
if (copyBtn && orderNumEl) {
var revertTimer;
var labelEl = copyBtn.querySelector(".copy-btn__text");
copyBtn.addEventListener("click", function () {
var text = orderNumEl.textContent.trim();
var done = function () {
copyBtn.classList.add("is-copied");
if (labelEl) labelEl.textContent = "Copied";
copyBtn.setAttribute("aria-label", "Order number copied");
toast("Order number copied to clipboard");
clearTimeout(revertTimer);
revertTimer = setTimeout(function () {
copyBtn.classList.remove("is-copied");
if (labelEl) labelEl.textContent = "Copy";
copyBtn.setAttribute("aria-label", "Copy order number");
}, 2000);
};
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(done, fallbackCopy);
} else {
fallbackCopy();
}
function fallbackCopy() {
try {
var ta = document.createElement("textarea");
ta.value = text;
ta.setAttribute("readonly", "");
ta.style.position = "absolute";
ta.style.left = "-9999px";
document.body.appendChild(ta);
ta.select();
document.execCommand("copy");
document.body.removeChild(ta);
done();
} catch (e) {
toast("Press Ctrl/Cmd + C to copy");
}
}
});
}
/* ---------- Expandable item list ---------- */
var toggle = document.getElementById("toggle-items");
var list = document.getElementById("item-list");
if (toggle && list) {
toggle.addEventListener("click", function () {
var expanded = toggle.getAttribute("aria-expanded") === "true";
toggle.setAttribute("aria-expanded", String(!expanded));
list.classList.toggle("is-collapsed", expanded);
});
}
/* ---------- Track order CTA (demo) ---------- */
var trackBtn = document.getElementById("track-btn");
if (trackBtn) {
trackBtn.addEventListener("click", function (e) {
e.preventDefault();
toast("Tracking opens once your order ships — we'll email you the link.");
});
}
/* ---------- Confetti burst on load ---------- */
var canvas = document.getElementById("confetti");
if (canvas && canvas.getContext && !prefersReduced) {
var ctx = canvas.getContext("2d");
var dpr = Math.min(window.devicePixelRatio || 1, 2);
var W = 0;
var H = 0;
function resize() {
W = canvas.clientWidth = window.innerWidth;
H = canvas.clientHeight = window.innerHeight;
canvas.width = W * dpr;
canvas.height = H * dpr;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
}
resize();
window.addEventListener("resize", resize);
var colors = ["#3457ff", "#1f9d55", "#e0245e", "#ffb020", "#7c5cff"];
var pieces = [];
var originX = W / 2;
var originY = H * 0.26;
var count = W < 480 ? 70 : 130;
for (var i = 0; i < count; i++) {
var angle = Math.random() * Math.PI * 2;
var speed = 4 + Math.random() * 8;
pieces.push({
x: originX + (Math.random() - 0.5) * 60,
y: originY,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed - (3 + Math.random() * 4),
size: 5 + Math.random() * 6,
color: colors[(Math.random() * colors.length) | 0],
rot: Math.random() * Math.PI,
vr: (Math.random() - 0.5) * 0.3,
shape: Math.random() < 0.5 ? "rect" : "circle",
life: 0
});
}
var gravity = 0.32;
var maxLife = 170;
function frame() {
ctx.clearRect(0, 0, W, H);
var alive = false;
for (var j = 0; j < pieces.length; j++) {
var p = pieces[j];
if (p.life > maxLife) continue;
alive = true;
p.life++;
p.vy += gravity;
p.vx *= 0.99;
p.x += p.vx;
p.y += p.vy;
p.rot += p.vr;
var fade = p.life > maxLife - 40 ? (maxLife - p.life) / 40 : 1;
ctx.save();
ctx.globalAlpha = Math.max(0, fade);
ctx.translate(p.x, p.y);
ctx.rotate(p.rot);
ctx.fillStyle = p.color;
if (p.shape === "rect") {
ctx.fillRect(-p.size / 2, -p.size / 2, p.size, p.size * 0.62);
} else {
ctx.beginPath();
ctx.arc(0, 0, p.size / 2, 0, Math.PI * 2);
ctx.fill();
}
ctx.restore();
}
if (alive) {
requestAnimationFrame(frame);
} else {
ctx.clearRect(0, 0, W, H);
}
}
// small delay so it lands with the check animation
setTimeout(function () {
requestAnimationFrame(frame);
}, 350);
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css" />
<title>Order Confirmed — Nimbus Goods Co.</title>
</head>
<body>
<canvas id="confetti" aria-hidden="true"></canvas>
<header class="site-header" role="banner">
<a href="#main" class="brand" aria-label="Nimbus Goods Co. home">
<span class="brand__mark" aria-hidden="true">
<svg viewBox="0 0 24 24" width="22" height="22" fill="none">
<path
d="M5 16a4 4 0 0 1 .6-7.95A5.5 5.5 0 0 1 16.5 7 4.5 4.5 0 0 1 18 15.8"
stroke="currentColor"
stroke-width="1.8"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</span>
<span class="brand__name">Nimbus<span>Goods</span></span>
</a>
<span class="header-trust">
<svg viewBox="0 0 24 24" width="15" height="15" fill="none" aria-hidden="true">
<path d="M12 3l7 3v5c0 4.5-3 8.2-7 10-4-1.8-7-5.5-7-10V6l7-3z" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/>
<path d="M9 12l2 2 4-4" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Secure checkout
</span>
</header>
<main class="content" id="main" role="main">
<!-- Success hero -->
<section class="hero" aria-labelledby="hero-title">
<div class="success-icon" aria-hidden="true">
<svg class="checkmark" viewBox="0 0 84 84" fill="none">
<circle class="circle" cx="42" cy="42" r="38" />
<polyline class="check" points="26,44 38,56 60,30" />
</svg>
</div>
<p class="eyebrow">Order placed</p>
<h1 id="hero-title">Thank you, Maya! Your order is confirmed.</h1>
<p class="lede">
A receipt is on its way to <strong>[email protected]</strong>. We'll email you
tracking details the moment your package ships.
</p>
<div class="order-pill">
<span class="order-pill__label">Order number</span>
<span class="order-pill__num" id="order-number">#NG-2026-48172</span>
<button type="button" class="copy-btn" id="copy-btn" aria-label="Copy order number">
<svg class="ic-copy" viewBox="0 0 24 24" width="16" height="16" fill="none" aria-hidden="true">
<rect x="9" y="9" width="11" height="11" rx="2" stroke="currentColor" stroke-width="1.7"/>
<path d="M5 15V6a2 2 0 0 1 2-2h9" stroke="currentColor" stroke-width="1.7" stroke-linecap="round"/>
</svg>
<svg class="ic-check" viewBox="0 0 24 24" width="16" height="16" fill="none" aria-hidden="true">
<path d="M5 12l5 5 9-10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span class="copy-btn__text">Copy</span>
</button>
</div>
</section>
<!-- Estimated delivery + step tracker -->
<section class="card delivery" aria-labelledby="delivery-title">
<div class="delivery__top">
<div>
<h2 id="delivery-title">Estimated delivery</h2>
<p class="delivery__date">
<strong>Tue, Jun 17 – Thu, Jun 19</strong>
</p>
<p class="delivery__meta">Standard shipping · Free · 3–5 business days</p>
</div>
<span class="ship-chip">
<span class="ship-chip__dot" aria-hidden="true"></span> On schedule
</span>
</div>
<ol class="tracker" aria-label="Order progress">
<li class="tracker__step is-done">
<span class="tracker__dot" aria-hidden="true">
<svg viewBox="0 0 24 24" width="13" height="13" fill="none"><path d="M5 12l5 5 9-10" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/></svg>
</span>
<span class="tracker__label">Confirmed</span>
<span class="tracker__sub">Today</span>
</li>
<li class="tracker__step is-active">
<span class="tracker__dot" aria-hidden="true"></span>
<span class="tracker__label">Packed</span>
<span class="tracker__sub">In progress</span>
</li>
<li class="tracker__step">
<span class="tracker__dot" aria-hidden="true"></span>
<span class="tracker__label">Shipped</span>
<span class="tracker__sub">Est. Jun 16</span>
</li>
<li class="tracker__step">
<span class="tracker__dot" aria-hidden="true"></span>
<span class="tracker__label">Delivered</span>
<span class="tracker__sub">Est. Jun 17–19</span>
</li>
</ol>
</section>
<div class="grid">
<!-- Order summary -->
<section class="card summary" aria-labelledby="summary-title">
<div class="summary__head">
<h2 id="summary-title">Order summary</h2>
<button
type="button"
class="toggle-items"
id="toggle-items"
aria-expanded="true"
aria-controls="item-list"
>
<span class="toggle-items__count">3 items</span>
<svg class="chev" viewBox="0 0 24 24" width="18" height="18" fill="none" aria-hidden="true">
<path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
</div>
<ul class="items" id="item-list">
<li class="item">
<span class="item__thumb thumb--lamp" aria-hidden="true">
<svg viewBox="0 0 48 48" width="40" height="40" fill="none">
<path d="M18 8h12l5 12H13l5-12z" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
<path d="M24 20v14M16 38h16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
</span>
<span class="item__info">
<strong>Halo Arc Desk Lamp</strong>
<span class="item__opts">Warm Brass · Dimmable</span>
<span class="item__qty">Qty 1</span>
</span>
<span class="item__price">$148.00</span>
</li>
<li class="item">
<span class="item__thumb thumb--mug" aria-hidden="true">
<svg viewBox="0 0 48 48" width="40" height="40" fill="none">
<path d="M13 16h20v13a7 7 0 0 1-7 7h-6a7 7 0 0 1-7-7V16z" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
<path d="M33 19h4a4 4 0 0 1 0 8h-4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>
</svg>
</span>
<span class="item__info">
<strong>Stoneware Mug Set</strong>
<span class="item__opts">Set of 4 · Sage</span>
<span class="item__qty">Qty 2</span>
</span>
<span class="item__price">$72.00</span>
</li>
<li class="item">
<span class="item__thumb thumb--candle" aria-hidden="true">
<svg viewBox="0 0 48 48" width="40" height="40" fill="none">
<path d="M24 10c3 3 3 6 0 8-3-2-3-5 0-8z" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>
<rect x="16" y="20" width="16" height="18" rx="2" stroke="currentColor" stroke-width="2"/>
</svg>
</span>
<span class="item__info">
<strong>Cedar & Fig Candle</strong>
<span class="item__opts">9 oz · 60h burn</span>
<span class="item__qty">Qty 1</span>
</span>
<span class="item__price">$34.00</span>
</li>
</ul>
<dl class="totals">
<div class="totals__row"><dt>Subtotal</dt><dd>$254.00</dd></div>
<div class="totals__row"><dt>Shipping</dt><dd class="free">Free</dd></div>
<div class="totals__row"><dt>Tax (estimated)</dt><dd>$20.32</dd></div>
<div class="totals__row totals__row--grand"><dt>Total paid</dt><dd>$274.32</dd></div>
</dl>
<p class="paid-with">
<span class="card-glyph" aria-hidden="true">
<svg viewBox="0 0 32 22" width="30" height="20" fill="none">
<rect x="1" y="1" width="30" height="20" rx="3" stroke="currentColor" stroke-width="1.6"/>
<rect x="1" y="5" width="30" height="4" fill="currentColor"/>
<rect x="5" y="14" width="9" height="2.5" rx="1.25" fill="currentColor"/>
</svg>
</span>
Paid with Visa ending •• 4242
</p>
</section>
<!-- Shipping address + support -->
<section class="card address" aria-labelledby="address-title">
<h2 id="address-title">Shipping to</h2>
<address class="address__block">
<strong>Maya Rivera</strong>
418 Magnolia Court, Apt 12<br />
Portland, OR 97214<br />
United States<br />
<span class="address__phone">+1 (503) 555-0148</span>
</address>
<div class="map" role="img" aria-label="Map illustration of the delivery area">
<svg viewBox="0 0 240 120" preserveAspectRatio="none" aria-hidden="true">
<path class="map-road" d="M-10 30 H120 V90 H260" />
<path class="map-road" d="M70 -10 V60 H180 V130" />
<path class="map-road map-road--thin" d="M-10 78 H90 V110" />
<circle class="map-pin-ring" cx="178" cy="60" r="13" />
<path
class="map-pin"
d="M178 47c5 0 8 4 8 9 0 6-8 14-8 14s-8-8-8-14c0-5 3-9 8-9z"
/>
<circle cx="178" cy="56" r="3" fill="#fff" />
</svg>
</div>
<div class="help">
<h3>Need a hand?</h3>
<p>Changes to your address are possible until the order ships.</p>
<div class="help__links">
<a href="#" class="help__link">Edit shipping</a>
<a href="#" class="help__link">Contact support</a>
</div>
</div>
</section>
</div>
<!-- CTAs -->
<section class="cta-row" aria-label="Next steps">
<a href="#" class="btn btn--primary" id="track-btn">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" aria-hidden="true">
<circle cx="11" cy="11" r="7" stroke="currentColor" stroke-width="1.8"/>
<path d="M16.5 16.5L21 21" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
</svg>
Track order
</a>
<a href="#" class="btn btn--ghost">Continue shopping</a>
</section>
<p class="footnote">
Order placed on Jun 14, 2026. You can view this confirmation anytime from your account.
</p>
</main>
<div id="toast" class="toast" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>Order Confirmation
A polished thank-you page for the fictional “Nimbus Goods Co.” It opens with an SVG checkmark that draws itself in and a one-shot confetti burst, then leads with a friendly success headline, the customer email, and an order-number pill with a working copy-to-clipboard button. An estimated-delivery card states the window, shipping method, and an “on schedule” chip, above a four-stage step tracker that marks the order Confirmed (done) and Packed (active) with the remaining Shipped and Delivered steps still ahead.
The order summary lists each line item on a softly tinted tile with inline-SVG product silhouettes, options, and quantities, and a collapsible header lets shoppers expand or hide the items. Totals break down subtotal, free shipping, estimated tax, and the grand total, finished with a masked payment method. A side card shows the shipping address over a pure-CSS map illustration with a route and pin, plus quick links to edit shipping or contact support. Track-order and continue-shopping CTAs round out the page.
Every interaction is real: the order number copies to the clipboard with a confirming toast and icon swap, the item list expands and collapses via an accessible aria-expanded toggle, and the track CTA explains next steps. The layout collapses to a single column on tablets and stacks cleanly down to ~360px, with landmark roles, visible focus rings, AA-contrast text, and full reduced-motion support that skips the confetti and check animation.
Illustrative storefront UI only — fictional products, prices, and reviews. No real checkout.