Hopefully final
This commit is contained in:
BIN
public/images/wedding-bg.jpg
Normal file
BIN
public/images/wedding-bg.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 923 KiB |
BIN
src/assets/birds.png
Normal file
BIN
src/assets/birds.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
BIN
src/assets/birds.webp
Normal file
BIN
src/assets/birds.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 148 KiB |
@@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
interface Props {
|
|
||||||
code: string;
|
|
||||||
index: number;
|
|
||||||
}
|
|
||||||
const { code, index } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<div class="gift-card" style={`animation-delay: ${index * 80}ms`}>
|
|
||||||
<div>
|
|
||||||
<p class="gift-card-label">Gift code {index + 1}</p>
|
|
||||||
<p class="gift-card-code">{code}</p>
|
|
||||||
</div>
|
|
||||||
<button class="copy-btn" data-code={code} aria-label={`Copy code ${code}`}
|
|
||||||
>Copy</button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
document.querySelectorAll<HTMLButtonElement>(".copy-btn").forEach((btn) => {
|
|
||||||
btn.addEventListener("click", async () => {
|
|
||||||
const code = btn.dataset.code ?? "";
|
|
||||||
try {
|
|
||||||
await navigator.clipboard.writeText(code);
|
|
||||||
btn.textContent = "Copied";
|
|
||||||
btn.classList.add("copied");
|
|
||||||
setTimeout(() => {
|
|
||||||
btn.textContent = "Copy";
|
|
||||||
btn.classList.remove("copied");
|
|
||||||
}, 2000);
|
|
||||||
} catch {
|
|
||||||
btn.textContent = "Error";
|
|
||||||
setTimeout(() => {
|
|
||||||
btn.textContent = "Copy";
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
39
src/data/gift.json
Normal file
39
src/data/gift.json
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
"couple": {
|
||||||
|
"name1": "Elza",
|
||||||
|
"name2": "Ainārs",
|
||||||
|
"weddingDate": "2026.05.25"
|
||||||
|
},
|
||||||
|
"heading": "With love, on your special day",
|
||||||
|
"message": "Wishing you a lifetime of joy, laughter, and adventure together. May your home be filled with warmth and your hearts with happiness. This small gift comes with all our love.",
|
||||||
|
"signature": "With love, from us",
|
||||||
|
"giftCards": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "IKEA Gift Card",
|
||||||
|
"description": "For your new home together",
|
||||||
|
"emoji": "🏡",
|
||||||
|
"url": "https://example.com/ikea-gift"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "Booking.com",
|
||||||
|
"description": "Your first trip as a married couple",
|
||||||
|
"emoji": "✈️",
|
||||||
|
"url": "https://example.com/booking-gift"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"name": "Amazon Gift Card",
|
||||||
|
"description": "Whatever your hearts desire",
|
||||||
|
"emoji": "🎁",
|
||||||
|
"url": "https://example.com/amazon-gift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payment": {
|
||||||
|
"label": "Or a little something extra",
|
||||||
|
"description": "Straight to you, with love",
|
||||||
|
"emoji": "💸",
|
||||||
|
"url": "https://revolut.me/example"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"couple": {
|
|
||||||
"names": "Anna & Tomas",
|
|
||||||
"date": "July 19, 2025",
|
|
||||||
"from": "Armands"
|
|
||||||
},
|
|
||||||
"store": {
|
|
||||||
"name": "ZARA Home",
|
|
||||||
"url": "https://www.zarahome.com",
|
|
||||||
"codes": [
|
|
||||||
{ "id": 1, "code": "GIFT-A1B2-C3D4" },
|
|
||||||
{ "id": 2, "code": "GIFT-E5F6-G7H8" },
|
|
||||||
{ "id": 3, "code": "GIFT-I9J0-K1L2" }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"payment": {
|
|
||||||
"label": "A little extra, with love",
|
|
||||||
"description": "If you'd prefer something personal, here's a direct contribution.",
|
|
||||||
"url": "https://revolut.me/example",
|
|
||||||
"buttonText": "Send via Revolut"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
src/env.d.ts
vendored
1
src/env.d.ts
vendored
@@ -1 +0,0 @@
|
|||||||
/// <reference path="../.astro/types.d.ts" />
|
|
||||||
@@ -1,99 +1,445 @@
|
|||||||
---
|
---
|
||||||
import GiftCard from "../components/GiftCard.astro";
|
import data from '../data/gift.json';
|
||||||
import gifts from "../data/gifts.json";
|
const { couple, heading, message, signature, giftCards, payment } = data;
|
||||||
import "../styles/global.css";
|
|
||||||
|
|
||||||
const { couple, store, payment } = gifts;
|
import { Image } from 'astro:assets';
|
||||||
|
import birds from '../assets/birds.webp';
|
||||||
---
|
---
|
||||||
|
|
||||||
<!doctype html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>A gift for {couple.names}</title>
|
<title>{couple.name1} & {couple.name2}</title>
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="bg-shapes" aria-hidden="true">
|
|
||||||
<span></span>
|
|
||||||
<span></span>
|
|
||||||
<span></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<main class="page">
|
<!-- Fonts: Cormorant Garamond (display) + Lato (body) -->
|
||||||
<header class="header">
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<p class="header-eyebrow">{couple.date}</p>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;1,300;1,400&family=Lato:wght@300;400&display=swap" rel="stylesheet" />
|
||||||
|
|
||||||
<h1 class="header-names">{couple.names}</h1>
|
<style>
|
||||||
|
:root {
|
||||||
<div class="header-divider">
|
--ivory: #fffdf9; /* body background — warmer than pure white */
|
||||||
<hr />
|
--ivory-deep: #f9f5ef; /* icon well, emoji backgrounds */
|
||||||
<svg
|
--white: #ffffff; /* cards — pure brilliant white */
|
||||||
width="14"
|
--white-warm: #fefcfa; /* available for hover surfaces */
|
||||||
height="14"
|
--cream: #f4ede3; /* fallback soft tone */
|
||||||
viewBox="0 0 24 24"
|
--gold: #c9a96e; /* accent: dates, ampersand, arrows, labels */
|
||||||
fill="currentColor"
|
--gold-light: #e8d5b0; /* divider lines */
|
||||||
aria-hidden="true"
|
--gold-faint: #f0e6cf; /* payment emoji background, blurs */
|
||||||
>
|
--text: #2c2420; /* rich warm dark (not cold black) */
|
||||||
<path
|
--text-muted: #7a6e67; /* hero subtitle, descriptions */
|
||||||
d="M12 21.593c-5.63-5.539-11-10.297-11-14.402 0-3.791 3.068-5.191 5.281-5.191 1.312 0 4.151.501 5.719 4.457 1.59-3.968 4.464-4.447 5.726-4.447 2.54 0 5.274 1.621 5.274 5.181 0 4.069-5.136 8.625-11 14.402z"
|
--text-faint: #b8aea7; /* tertiary metadata */
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
<hr />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="header-message">
|
|
||||||
A small gift from {couple.from}, with all my love for your
|
|
||||||
new beginning.
|
|
||||||
</p>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<section aria-labelledby="codes-heading">
|
|
||||||
<div class="section-header">
|
|
||||||
<h2 id="codes-heading" class="section-title">
|
|
||||||
{store.name}
|
|
||||||
</h2>
|
|
||||||
<a
|
|
||||||
href={store.url}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
class="section-link"
|
|
||||||
>
|
|
||||||
Visit store
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="codes-list">
|
|
||||||
{
|
|
||||||
store.codes.map((item, i) => (
|
|
||||||
<GiftCard code={item.code} index={i} />
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--beige);
|
||||||
|
color: var(--black);
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
min-height: 100vh;
|
||||||
|
overflow-x: hidden;
|
||||||
|
background-color: var(--ivory);
|
||||||
|
background-image: url('/images/wedding-bg.jpg');
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-attachment: fixed; /* parallax-like scroll */
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Watercolor SVG background blobs ── */
|
||||||
|
.wc-bg {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-bg svg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Page wrapper ── */
|
||||||
|
.page {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
max-width: 480px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 20px 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Hero section ── */
|
||||||
|
.hero {
|
||||||
|
text-align: center;
|
||||||
|
padding: 64px 0 48px;
|
||||||
|
animation: fadeUp 0.9s ease both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-date {
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
letter-spacing: 0.25em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--black);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-names {
|
||||||
|
font-family: 'Cormorant Garamond', serif;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: clamp(2.6rem, 12vw, 3.6rem);
|
||||||
|
line-height: 1.05;
|
||||||
|
color: var(--black);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-names .amp {
|
||||||
|
font-style: italic;
|
||||||
|
color: var(--beige-dark);
|
||||||
|
font-size: 0.85em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-divider {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10px;
|
||||||
|
margin: 24px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-divider-line {
|
||||||
|
flex: 1;
|
||||||
|
max-width: 60px;
|
||||||
|
height: 1px;
|
||||||
|
background: linear-gradient(to right, transparent, var(--beige-dark));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-divider-line.right {
|
||||||
|
background: linear-gradient(to left, transparent, var(--beige-dark));
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-divider-icon {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-heading {
|
||||||
|
font-family: 'Cormorant Garamond', serif;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: clamp(1.1rem, 5vw, 1.35rem);
|
||||||
|
color: var(--black);
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Message card ── */
|
||||||
|
.message-card {
|
||||||
|
background: var(--white);
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 32px 28px;
|
||||||
|
margin-bottom: 36px;
|
||||||
|
position: relative;
|
||||||
|
box-shadow:
|
||||||
|
0 2px 12px rgba(217, 210, 200, 0.1),
|
||||||
|
0 0 0 1px rgba(237, 223, 200, 0.3);
|
||||||
|
animation: fadeUp 0.9s 0.15s ease both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Corner watercolor smudge accents */
|
||||||
|
.message-card::before,
|
||||||
|
.message-card::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 70px;
|
||||||
|
height: 70px;
|
||||||
|
border-radius: 50%;
|
||||||
|
opacity: 0.18;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-card::before {
|
||||||
|
background: var(--beige-light);
|
||||||
|
top: -16px;
|
||||||
|
left: -16px;
|
||||||
|
filter: blur(18px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-card::after {
|
||||||
|
background: var(--beige-dark);
|
||||||
|
bottom: -16px;
|
||||||
|
right: -16px;
|
||||||
|
filter: blur(22px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-text {
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
line-height: 1.85;
|
||||||
|
color: var(--black);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-signature {
|
||||||
|
font-family: 'Cormorant Garamond', serif;
|
||||||
|
font-style: italic;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: var(--beige-dark);
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Section label ── */
|
||||||
|
.section-label {
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
letter-spacing: 0.22em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--black);
|
||||||
|
margin-bottom: 16px;
|
||||||
|
padding-left: 2px;
|
||||||
|
animation: fadeUp 0.9s 0.25s ease both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Gift card list ── */
|
||||||
|
.gift-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 14px;
|
||||||
|
margin-bottom: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
background: var(--white);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 18px 20px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--black);
|
||||||
|
box-shadow: 0 2px 10px rgba(217, 210, 200, 0.08), 0 0 0 1px rgba(237, 223, 200, 0.25);
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
animation: fadeUp 0.9s ease both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card:nth-child(1) { animation-delay: 0.3s; }
|
||||||
|
.gift-card:nth-child(2) { animation-delay: 0.4s; }
|
||||||
|
.gift-card:nth-child(3) { animation-delay: 0.5s; }
|
||||||
|
|
||||||
|
.gift-card:active {
|
||||||
|
transform: scale(0.98);
|
||||||
|
box-shadow: 0 1px 6px rgba(217, 210, 200, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card-emoji {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: var(--beige-light);
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card-body {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card-name {
|
||||||
|
font-family: 'Cormorant Garamond', serif;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card-desc {
|
||||||
|
font-size: 0.78rem;
|
||||||
|
color: var(--black);
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-card-arrow {
|
||||||
|
color: var(--beige-dark);
|
||||||
|
font-size: 1.1rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Payment link ── */
|
||||||
|
.payment-section {
|
||||||
|
animation: fadeUp 0.9s 0.55s ease both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.payment-link {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
background: var(--beige-light);
|
||||||
|
border-radius: 16px;
|
||||||
|
padding: 22px 20px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--black);
|
||||||
|
border: 1px solid rgba(237, 223, 200, 0.5);
|
||||||
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
box-shadow: 0 4px 20px rgba(217, 210, 200, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.payment-link:active {
|
||||||
|
transform: scale(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
.payment-emoji {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: rgba(255,255,255,0.5);
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.payment-body {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.payment-label {
|
||||||
|
font-family: 'Cormorant Garamond', serif;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.payment-desc {
|
||||||
|
font-size: 0.78rem;
|
||||||
|
color: var(--black);
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wc-bg-img {
|
||||||
|
margin: 12px auto 0;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
opacity: 0.9;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Animation ── */
|
||||||
|
@keyframes fadeUp {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(22px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- Watercolor background blobs -->
|
||||||
|
<div class="wc-bg">
|
||||||
|
<svg viewBox="0 0 400 800" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<filter id="blur1"><feGaussianBlur stdDeviation="28"/></filter>
|
||||||
|
<filter id="blur2"><feGaussianBlur stdDeviation="40"/></filter>
|
||||||
|
<filter id="blur3"><feGaussianBlur stdDeviation="22"/></filter>
|
||||||
|
</defs>
|
||||||
|
<!-- Top-left beige blob -->
|
||||||
|
<ellipse cx="60" cy="80" rx="130" ry="110" fill="#eddfc8" opacity="0.28" filter="url(#blur1)"/>
|
||||||
|
<!-- Top-right beige blob -->
|
||||||
|
<ellipse cx="370" cy="140" rx="100" ry="140" fill="#f5ede0" opacity="0.4" filter="url(#blur2)"/>
|
||||||
|
<!-- Mid beige blob -->
|
||||||
|
<ellipse cx="320" cy="420" rx="120" ry="90" fill="#f9f3e8" opacity="0.35" filter="url(#blur1)"/>
|
||||||
|
<!-- Mid-left blob -->
|
||||||
|
<ellipse cx="30" cy="500" rx="90" ry="110" fill="#eddfc8" opacity="0.22" filter="url(#blur3)"/>
|
||||||
|
<!-- Bottom center -->
|
||||||
|
<ellipse cx="200" cy="730" rx="160" ry="100" fill="#f5ede0" opacity="0.3" filter="url(#blur2)"/>
|
||||||
|
<!-- Bottom right beige -->
|
||||||
|
<ellipse cx="390" cy="780" rx="100" ry="80" fill="#d4c4a8" opacity="0.15" filter="url(#blur1)"/>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="page">
|
||||||
|
|
||||||
|
<!-- Hero -->
|
||||||
|
<section class="hero">
|
||||||
|
<p class="hero-date">{couple.weddingDate}</p>
|
||||||
|
<h1 class="hero-names">
|
||||||
|
{couple.name1}<br/>
|
||||||
|
<span class="amp">&</span><br/>
|
||||||
|
{couple.name2}
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="hero-divider">
|
||||||
|
<div class="hero-divider-line"></div>
|
||||||
|
<div class="hero-divider-line right"></div>
|
||||||
|
</div>
|
||||||
|
<p class="hero-heading">{heading}</p>
|
||||||
|
|
||||||
|
<Image
|
||||||
|
src={birds}
|
||||||
|
alt=""
|
||||||
|
class="wc-bg-img"
|
||||||
|
widths={[768, 1280, 1920]}
|
||||||
|
sizes="100vw"
|
||||||
|
loading="eager"
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="or-divider" aria-hidden="true">
|
|
||||||
<hr /><span>or</span><hr />
|
<!-- Personal message -->
|
||||||
|
<div class="message-card">
|
||||||
|
<p class="message-text">{message}</p>
|
||||||
|
<p class="message-signature">{signature}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<section class="payment-card" aria-labelledby="payment-heading">
|
<!-- Gift cards -->
|
||||||
<h2 id="payment-heading" class="payment-title">
|
<p class="section-label">Your gifts</p>
|
||||||
{payment.label}
|
<div class="gift-list">
|
||||||
</h2>
|
{giftCards.map((card) => (
|
||||||
<p class="payment-desc">{payment.description}</p>
|
<a href={card.url} target="_blank" rel="noopener noreferrer" class="gift-card">
|
||||||
<a
|
<div class="gift-card-body">
|
||||||
href={payment.url}
|
<div class="gift-card-name">{card.name}</div>
|
||||||
target="_blank"
|
<div class="gift-card-desc">{card.description}</div>
|
||||||
rel="noopener noreferrer"
|
</div>
|
||||||
class="payment-btn"
|
<span class="gift-card-arrow">→</span>
|
||||||
>
|
|
||||||
{payment.buttonText}
|
|
||||||
</a>
|
</a>
|
||||||
</section>
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
<footer class="footer">
|
<!-- Payment link -->
|
||||||
<p class="footer-sign">With love, {couple.from}</p>
|
<div class="payment-section">
|
||||||
</footer>
|
<p class="section-label">A little extra</p>
|
||||||
</main>
|
<a href={payment.url} target="_blank" rel="noopener noreferrer" class="gift-card">
|
||||||
</body>
|
<div class="payment-body">
|
||||||
|
<div class="payment-label">{payment.label}</div>
|
||||||
|
<div class="payment-desc">{payment.description}</div>
|
||||||
|
</div>
|
||||||
|
<span class="gift-card-arrow">→</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,384 +0,0 @@
|
|||||||
@import url("https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,500;0,600;1,400;1,500&family=Dancing+Script:wght@600&family=Jost:wght@300;400;500&display=swap");
|
|
||||||
@import "tailwindcss";
|
|
||||||
|
|
||||||
/* ── Reset & base ───────────────────────────────────────── */
|
|
||||||
*,
|
|
||||||
*::before,
|
|
||||||
*::after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
min-height: 100svh;
|
|
||||||
background-color: #faf6f1;
|
|
||||||
color: #3a2e2b;
|
|
||||||
font-family: "Jost", sans-serif;
|
|
||||||
font-weight: 300;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Grain overlay ──────────────────────────────────────── */
|
|
||||||
body::before {
|
|
||||||
content: "";
|
|
||||||
position: fixed;
|
|
||||||
inset: 0;
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 100;
|
|
||||||
opacity: 0.04;
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
|
|
||||||
background-size: 128px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Background shapes ──────────────────────────────────── */
|
|
||||||
.bg-shapes {
|
|
||||||
position: fixed;
|
|
||||||
inset: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-shapes span {
|
|
||||||
position: absolute;
|
|
||||||
border-radius: 50% 0 50% 0;
|
|
||||||
opacity: 0.15;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-shapes span:nth-child(1) {
|
|
||||||
width: 360px;
|
|
||||||
height: 360px;
|
|
||||||
background: #e8c4b8;
|
|
||||||
top: -100px;
|
|
||||||
right: -120px;
|
|
||||||
transform: rotate(20deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-shapes span:nth-child(2) {
|
|
||||||
width: 280px;
|
|
||||||
height: 280px;
|
|
||||||
background: #8fa89e;
|
|
||||||
bottom: -80px;
|
|
||||||
left: -90px;
|
|
||||||
transform: rotate(-15deg);
|
|
||||||
border-radius: 0 50% 0 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-shapes span:nth-child(3) {
|
|
||||||
width: 160px;
|
|
||||||
height: 160px;
|
|
||||||
background: #c9857a;
|
|
||||||
top: 42%;
|
|
||||||
left: 62%;
|
|
||||||
transform: rotate(35deg);
|
|
||||||
opacity: 0.08;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Layout ─────────────────────────────────────────────── */
|
|
||||||
.page {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
max-width: 420px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 56px 20px 72px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Header ─────────────────────────────────────────────── */
|
|
||||||
.header {
|
|
||||||
text-align: center;
|
|
||||||
margin-bottom: 48px;
|
|
||||||
animation: fade-in 0.8s ease both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-eyebrow {
|
|
||||||
font-family: "Jost", sans-serif;
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 400;
|
|
||||||
letter-spacing: 0.22em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: #8fa89e;
|
|
||||||
margin-bottom: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-names {
|
|
||||||
font-family: "Dancing Script", cursive;
|
|
||||||
font-size: 52px;
|
|
||||||
color: #7d4f47;
|
|
||||||
line-height: 1.15;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-divider {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
margin: 18px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-divider hr {
|
|
||||||
flex: 1;
|
|
||||||
border: none;
|
|
||||||
border-top: 1px solid #e8c4b8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-divider svg {
|
|
||||||
color: #c9857a;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-message {
|
|
||||||
font-family: "Cormorant Garamond", serif;
|
|
||||||
font-size: 16px;
|
|
||||||
font-style: italic;
|
|
||||||
line-height: 1.7;
|
|
||||||
color: rgba(58, 46, 43, 0.65);
|
|
||||||
max-width: 340px;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Section heading row ────────────────────────────────── */
|
|
||||||
.section-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
animation: fade-up 0.7s 0.15s ease both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-title {
|
|
||||||
font-family: "Cormorant Garamond", serif;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #3a2e2b;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-link {
|
|
||||||
font-family: "Jost", sans-serif;
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 400;
|
|
||||||
letter-spacing: 0.2em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: #8fa89e;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: color 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-link:hover {
|
|
||||||
color: #c9857a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Gift cards list ────────────────────────────────────── */
|
|
||||||
.codes-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Single gift card ───────────────────────────────────── */
|
|
||||||
.gift-card {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
gap: 16px;
|
|
||||||
background: rgba(255, 255, 255, 0.6);
|
|
||||||
border: 1px solid rgba(232, 196, 184, 0.6);
|
|
||||||
border-radius: 16px;
|
|
||||||
padding: 16px 20px;
|
|
||||||
box-shadow: 0 1px 4px rgba(58, 46, 43, 0.06);
|
|
||||||
backdrop-filter: blur(6px);
|
|
||||||
transition: box-shadow 0.3s;
|
|
||||||
animation: fade-up 0.5s ease both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gift-card:hover {
|
|
||||||
box-shadow: 0 4px 16px rgba(58, 46, 43, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.gift-card::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
width: 3px;
|
|
||||||
height: 32px;
|
|
||||||
background: rgba(201, 133, 122, 0.5);
|
|
||||||
border-radius: 0 2px 2px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gift-card-label {
|
|
||||||
font-family: "Jost", sans-serif;
|
|
||||||
font-size: 10px;
|
|
||||||
font-weight: 400;
|
|
||||||
letter-spacing: 0.22em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: #8fa89e;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.gift-card-code {
|
|
||||||
font-family: "Cormorant Garamond", serif;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
letter-spacing: 0.05em;
|
|
||||||
color: #3a2e2b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Copy button ────────────────────────────────────────── */
|
|
||||||
.copy-btn {
|
|
||||||
flex-shrink: 0;
|
|
||||||
font-family: "Jost", sans-serif;
|
|
||||||
font-size: 11px;
|
|
||||||
font-weight: 500;
|
|
||||||
letter-spacing: 0.2em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: #7d4f47;
|
|
||||||
background: #faf6f1;
|
|
||||||
border: 1px solid #e8c4b8;
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 8px 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition:
|
|
||||||
background 0.2s,
|
|
||||||
border-color 0.2s,
|
|
||||||
color 0.2s,
|
|
||||||
transform 0.1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-btn:hover {
|
|
||||||
background: rgba(232, 196, 184, 0.4);
|
|
||||||
border-color: #c9857a;
|
|
||||||
color: #c9857a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-btn:active {
|
|
||||||
transform: scale(0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
.copy-btn.copied {
|
|
||||||
background: rgba(143, 168, 158, 0.12);
|
|
||||||
border-color: #8fa89e;
|
|
||||||
color: #8fa89e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Or divider ─────────────────────────────────────────── */
|
|
||||||
.or-divider {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 14px;
|
|
||||||
margin: 8px 0 28px;
|
|
||||||
animation: fade-up 0.7s 0.28s ease both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.or-divider hr {
|
|
||||||
flex: 1;
|
|
||||||
border: none;
|
|
||||||
border-top: 1px solid rgba(232, 196, 184, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.or-divider span {
|
|
||||||
font-family: "Jost", sans-serif;
|
|
||||||
font-size: 10px;
|
|
||||||
font-weight: 400;
|
|
||||||
letter-spacing: 0.22em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: #e8c4b8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Payment card ───────────────────────────────────────── */
|
|
||||||
.payment-card {
|
|
||||||
background: rgba(255, 255, 255, 0.5);
|
|
||||||
border: 1px solid rgba(232, 196, 184, 0.6);
|
|
||||||
border-radius: 16px;
|
|
||||||
padding: 28px 24px;
|
|
||||||
text-align: center;
|
|
||||||
box-shadow: 0 1px 4px rgba(58, 46, 43, 0.06);
|
|
||||||
backdrop-filter: blur(6px);
|
|
||||||
animation: fade-up 0.7s 0.32s ease both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.payment-title {
|
|
||||||
font-family: "Cormorant Garamond", serif;
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #3a2e2b;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.payment-desc {
|
|
||||||
font-family: "Cormorant Garamond", serif;
|
|
||||||
font-size: 15px;
|
|
||||||
font-style: italic;
|
|
||||||
color: rgba(58, 46, 43, 0.6);
|
|
||||||
margin-bottom: 22px;
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.payment-btn {
|
|
||||||
display: inline-block;
|
|
||||||
font-family: "Jost", sans-serif;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
letter-spacing: 0.2em;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: #fff;
|
|
||||||
background: #c9857a;
|
|
||||||
border: none;
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 14px 32px;
|
|
||||||
text-decoration: none;
|
|
||||||
box-shadow: 0 2px 8px rgba(201, 133, 122, 0.35);
|
|
||||||
transition:
|
|
||||||
background 0.2s,
|
|
||||||
box-shadow 0.2s,
|
|
||||||
transform 0.1s;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.payment-btn:hover {
|
|
||||||
background: #7d4f47;
|
|
||||||
box-shadow: 0 4px 16px rgba(125, 79, 71, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.payment-btn:active {
|
|
||||||
transform: scale(0.96);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Footer ─────────────────────────────────────────────── */
|
|
||||||
.footer {
|
|
||||||
margin-top: 56px;
|
|
||||||
text-align: center;
|
|
||||||
animation: fade-in 1s 0.5s ease both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-sign {
|
|
||||||
font-family: "Dancing Script", cursive;
|
|
||||||
font-size: 28px;
|
|
||||||
color: rgba(201, 133, 122, 0.65);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ── Animations ─────────────────────────────────────────── */
|
|
||||||
@keyframes fade-in {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade-up {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(14px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user