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 gifts from "../data/gifts.json";
|
||||
import "../styles/global.css";
|
||||
import data from '../data/gift.json';
|
||||
const { couple, heading, message, signature, giftCards, payment } = data;
|
||||
|
||||
const { couple, store, payment } = gifts;
|
||||
import { Image } from 'astro:assets';
|
||||
import birds from '../assets/birds.webp';
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>A gift for {couple.names}</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="bg-shapes" aria-hidden="true">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>{couple.name1} & {couple.name2}</title>
|
||||
|
||||
<!-- Fonts: Cormorant Garamond (display) + Lato (body) -->
|
||||
<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:ital,wght@0,300;0,400;0,600;1,300;1,400&family=Lato:wght@300;400&display=swap" rel="stylesheet" />
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--ivory: #fffdf9; /* body background — warmer than pure white */
|
||||
--ivory-deep: #f9f5ef; /* icon well, emoji backgrounds */
|
||||
--white: #ffffff; /* cards — pure brilliant white */
|
||||
--white-warm: #fefcfa; /* available for hover surfaces */
|
||||
--cream: #f4ede3; /* fallback soft tone */
|
||||
--gold: #c9a96e; /* accent: dates, ampersand, arrows, labels */
|
||||
--gold-light: #e8d5b0; /* divider lines */
|
||||
--gold-faint: #f0e6cf; /* payment emoji background, blurs */
|
||||
--text: #2c2420; /* rich warm dark (not cold black) */
|
||||
--text-muted: #7a6e67; /* hero subtitle, descriptions */
|
||||
--text-faint: #b8aea7; /* tertiary metadata */
|
||||
}
|
||||
|
||||
* {
|
||||
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 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>
|
||||
|
||||
|
||||
<!-- Personal message -->
|
||||
<div class="message-card">
|
||||
<p class="message-text">{message}</p>
|
||||
<p class="message-signature">{signature}</p>
|
||||
</div>
|
||||
|
||||
<!-- Gift cards -->
|
||||
<p class="section-label">Your gifts</p>
|
||||
<div class="gift-list">
|
||||
{giftCards.map((card) => (
|
||||
<a href={card.url} target="_blank" rel="noopener noreferrer" class="gift-card">
|
||||
<div class="gift-card-body">
|
||||
<div class="gift-card-name">{card.name}</div>
|
||||
<div class="gift-card-desc">{card.description}</div>
|
||||
</div>
|
||||
<span class="gift-card-arrow">→</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<!-- Payment link -->
|
||||
<div class="payment-section">
|
||||
<p class="section-label">A little extra</p>
|
||||
<a href={payment.url} target="_blank" rel="noopener noreferrer" class="gift-card">
|
||||
<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>
|
||||
|
||||
<main class="page">
|
||||
<header class="header">
|
||||
<p class="header-eyebrow">{couple.date}</p>
|
||||
</div>
|
||||
|
||||
<h1 class="header-names">{couple.names}</h1>
|
||||
|
||||
<div class="header-divider">
|
||||
<hr />
|
||||
<svg
|
||||
width="14"
|
||||
height="14"
|
||||
viewBox="0 0 24 24"
|
||||
fill="currentColor"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
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"
|
||||
></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} />
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="or-divider" aria-hidden="true">
|
||||
<hr /><span>or</span><hr />
|
||||
</div>
|
||||
|
||||
<section class="payment-card" aria-labelledby="payment-heading">
|
||||
<h2 id="payment-heading" class="payment-title">
|
||||
{payment.label}
|
||||
</h2>
|
||||
<p class="payment-desc">{payment.description}</p>
|
||||
<a
|
||||
href={payment.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="payment-btn"
|
||||
>
|
||||
{payment.buttonText}
|
||||
</a>
|
||||
</section>
|
||||
|
||||
<footer class="footer">
|
||||
<p class="footer-sign">With love, {couple.from}</p>
|
||||
</footer>
|
||||
</main>
|
||||
</body>
|
||||
</body>
|
||||
</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