Overview
The wedding website uses TailwindCSS 4.2.1 with a custom design system featuring elegant serif fonts, a warm color palette, and fluid responsive typography. Styling is applied primarily through utility classes, with scoped component styles for specific interactions.
Setup
The styling foundation is minimal and lightweight:
TailwindCSS is imported directly without additional configuration files, relying on default settings enhanced with custom utilities.
Custom Fonts
Two custom fonts define the visual identity:
Amoresa Elegant script font for headings, names, and decorative text
WeddingSerif Serif font (LorenBlakeSerif) for body text and UI elements
Font Loading
Fonts are loaded in Layout.astro using @font-face:
---
import '../styles/global.css' ;
---
< ! doctype html >
< html lang = "es" >
< head >
< meta charset = "UTF-8" />
< link href = "https://fonts.googleapis.com/css2?family=Great+Vibes&family=Playfair+Display:ital@0;1&display=swap" rel = "stylesheet" >
< style is:global >
@font-face {
font-family : 'Amoresa' ;
src : url ( '/src/assets/fonts/amoresa-regular.otf' ) format ( 'truetype' );
font-weight : normal ;
font-style : normal ;
font-display : swap ;
}
@font-face {
font-family : 'WeddingSerif' ;
src : url ( '/src/assets/fonts/LorenBlakeSerif.otf' ) format ( 'truetype' );
font-weight : normal ;
font-style : normal ;
font-display : swap ;
}
html {
overflow-x : hidden ;
}
body {
font-family : 'WeddingSerif' , serif ;
overflow-x : hidden ;
@ apply antialiased text- [#2 c 3 e 50];
}
</ style >
</ head >
< body class = "bg-[#F4EEE7] relative" >
<!-- Content -->
</ body >
</ html >
Font Usage Patterns
Amoresa (Script)
WeddingSerif (Body)
Used for:
Couple names
Section headings
Menu title
Decorative elements
< h1 class = "font-['Amoresa'] text-[#1a1a1a]"
style = "font-size: clamp(3rem, 14vw, 6rem);" >
Alejandra
</ h1 >
< h2 class = "font-['Amoresa'] text-[#1a1a1a]"
style = "font-size: clamp(2.4rem, 10vw, 4rem);" >
Nuestra historia
</ h2 >
Used for:
Body text
Form labels
Navigation links
Buttons
< p class = "font-['WeddingSerif'] text-[#2c3e50]"
style = "font-size: clamp(0.95rem, 3.5vw, 1.2rem);" >
Story content here...
</ p >
< button class = "font-['WeddingSerif'] tracking-[.3em] uppercase" >
Enviar
</ button >
Font families are referenced using Tailwind’s arbitrary value syntax: font-['Amoresa'] and font-['WeddingSerif']
Color Palette
The design uses a warm, elegant color scheme:
Primary Colors
Accent & Border Colors
/* Background */
bg- [# F4EEE7 ] /* Main background - warm off-white */
bg- [# F4E8C5 ] /* Form background - light cream */
bg- [# ede8d8 ] /* Menu panel - soft beige */
/* Text */
text- [#1 a1a1a ] /* Primary headings - near black */
text- [#2 c3e50 ] /* Body text - dark blue-gray */
text- [#333] /* Secondary text - dark gray */
text- [#444] /* Tertiary text */
text- [#888] /* Muted text - medium gray */
Applying Colors
<!-- Background with pattern -->
< body class = "bg-[#F4EEE7] relative" >
<!-- Heading with custom color -->
< h1 class = "text-[#1a1a1a]" >
<!-- Body text with default color -->
< p class = "text-[#2c3e50]" >
<!-- Muted label text -->
< label class = "text-[#888]" >
<!-- Border divider -->
< hr class = "border-t-1 border-[#373737]" >
<!-- Button with hover effect -->
< button class = "bg-[#1a1a1a] text-white hover:bg-[#333]" >
Responsive Typography
The website uses fluid typography with CSS clamp() for smooth scaling:
Font Size Patterns
Element Mobile (min) Viewport-based Desktop (max) Use Case clamp(3rem, 14vw, 6rem)48px 14vw 96px Hero names (h1) clamp(2.4rem, 10vw, 4rem)38.4px 10vw 64px Section headings (h2) clamp(2rem, 9vw, 3.2rem)32px 9vw 51.2px Form title clamp(0.95rem, 3.5vw, 1.2rem)15.2px 3.5vw 19.2px Body text clamp(0.9rem, 4vw, 1.4rem)14.4px 4vw 22.4px Date/location clamp(0.7rem, 2.5vw, 0.9rem)11.2px 2.5vw 14.4px Small text clamp(0.65rem, 2.2vw, 0.82rem)10.4px 2.2vw 13.12px Labels, inputs
Implementation
Fluid typography examples
<!-- Large heading -->
< h1 style = "font-size: clamp(3rem, 14vw, 6rem);" >
Alejandra
</ h1 >
<!-- Section heading -->
< h2 style = "font-size: clamp(2.4rem, 10vw, 4rem);" >
Nuestra historia
</ h2 >
<!-- Body text -->
< p style = "font-size: clamp(0.95rem, 3.5vw, 1.2rem);" >
Story content...
</ p >
<!-- Button text -->
< button style = "font-size: clamp(0.7rem, 2.5vw, 0.9rem);" >
Enviar
</ button >
Fluid typography is applied via inline style attributes rather than Tailwind classes, as Tailwind doesn’t natively support clamp() syntax.
Responsive Breakpoints
Tailwind’s default md: breakpoint (768px) is used throughout:
Layout Adjustments
Element Sizing
Typography
<!-- Padding: mobile 6, desktop 10 -->
< header class = "pt-6 md:pt-10" >
<!-- Width: mobile 350px, desktop 450px -->
< hr class = "w-[350px] md:w-[450px]" >
<!-- Spacing: mobile 8, desktop 24 -->
< div class = "mb-8 md:mb-24" >
Layout Patterns
Centered Content Container
Every section uses a consistent max-width container:
< div class = "w-full max-w-[1000px] mx-auto px-6" >
<!-- Section content -->
</ div >
w-full - Full width on mobile
max-w-[1000px] - Maximum width of 1000px
mx-auto - Center horizontally
px-6 - 1.5rem horizontal padding
Background Pattern Layer
The main layout creates a decorative background:
< body class = "bg-[#F4EEE7] relative" >
<!-- Background pattern layer (z-0) -->
< div class = "absolute inset-0 z-0 flex justify-center pointer-events-none"
aria-hidden = "true" >
< div class = "w-full max-w-[1000px] bg-repeat-y bg-top"
style = { `background-image: url(' ${ fondoWedding . src } '); background-size: contain;` } >
</ div >
</ div >
<!-- Content layer (z-10) -->
< div class = "relative z-10" >
< slot />
</ div >
</ body >
Z-Index Hierarchy
Layer z-index Usage Background pattern z-0Decorative background image Content z-10All main content sections Header z-50Fixed navigation header Menu overlay z-[90]Semi-transparent backdrop Menu panel z-[100]Slide-out navigation menu Menu toggle (open) z-[200]Close button above menu
Spacing & Layout Utilities
Custom Spacing Values
<!-- Hero section -->
< div class = "pt-30 md:pt-42" > <!-- Custom top padding -->
<!-- Section spacing -->
< div class = "mt-28 md:mt-68" > <!-- Custom top margin -->
< div class = "mb-16 md:mb-24" > <!-- Standard bottom margin -->
Common Patterns
Centering
Spacing
Padding
<!-- Horizontal centering -->
< div class = "mx-auto" >
<!-- Flex centering -->
< div class = "flex justify-center items-center" >
<!-- Text centering -->
< div class = "text-center" >
<!-- Section gaps -->
< div class = "mb-8 md:mb-24" > <!-- Large sections -->
< div class = "mb-6" > <!-- Medium spacing -->
< div class = "mb-3" > <!-- Small spacing -->
< div class = "space-y-6" > <!-- Vertical stack spacing -->
< div class = "gap-3" > <!-- Grid/flex gap -->
<!-- Container padding -->
< div class = "px-6" > <!-- Horizontal -->
< div class = "py-2" > <!-- Vertical -->
< div class = "p-2" > <!-- All sides -->
<!-- Responsive padding -->
< div class = "px-2 md:px-8" > <!-- Increase on desktop -->
Interactive States
Hover Effects
<!-- Opacity change -->
< a class = "hover:opacity-60 transition-opacity" >
<!-- Background color change -->
< button class = "bg-[#1a1a1a] hover:bg-[#333] transition-colors" >
< a class = "hover:bg-[#d8cfb8] transition-colors" >
<!-- Text color change -->
< a class = "text-[#666] hover:text-[#333] transition-colors" >
Transitions
All interactive elements use CSS transitions:
<!-- Standard transition -->
class="transition-colors" <!-- Color changes -->
class="transition-opacity" <!-- Opacity changes -->
class="transition-all" <!-- All properties -->
class="transition-transform duration-500 ease-in-out" <!-- Slide animations -->
< div class = "w-full mb-3 relative" >
<!-- Floating label -->
< label class = "absolute -top-2 left-3 bg-[#F4E8C5] px-1
font-['WeddingSerif'] text-[#888]"
style = "font-size: clamp(0.55rem, 1.8vw, 0.7rem);" >
Nombre
</ label >
<!-- Input field -->
< input type = "text"
class = "w-full bg-transparent border border-[#aaa] rounded-full
px-4 py-2 font-['WeddingSerif'] text-[#888]
outline-none focus:border-[#888]"
style = "font-size: clamp(0.65rem, 2.2vw, 0.82rem);" />
</ div >
Primary Button
Menu Link Button
< button class = "bg-[#1a1a1a] text-white rounded-full py-2 px-6
font-['WeddingSerif'] tracking-[.3em] uppercase
hover:bg-[#333] transition-colors
disabled:opacity-50 cursor-pointer"
style = "font-size: clamp(0.7rem, 2.5vw, 0.9rem);" >
Enviar
</ button >
Typography Utilities
Letter Spacing
class="tracking-[.15em]" <!-- Subtle spacing (headings) -->
class="tracking-[.2em]" <!-- Medium spacing (menu links) -->
class="tracking-[.25em]" <!-- Wide spacing (date/location) -->
class="tracking-[.3em]" <!-- Extra wide (buttons) -->
Line Height & Leading
class="leading-tight" <!-- Headings -->
class="leading-snug" <!-- Subtitles -->
class="leading-relaxed" <!-- Body text -->
Text Transform
class="uppercase" <!-- Menu items, buttons -->
class="capitalize" <!-- Not used in this project -->
Animation Patterns
Many headings use an intersection observer pattern:
< h2 class = "reveal-heading font-['Amoresa']" >
Heading text
</ h2 >
< script >
const headings = document . querySelectorAll ( '.reveal-heading' );
// Initial state
headings . forEach ( el => {
( el as HTMLElement ). style . opacity = '0' ;
( el as HTMLElement ). style . filter = 'blur(10px)' ;
( el as HTMLElement ). style . transition = 'opacity 1.2s ease, filter 1.2s ease' ;
});
// Observe and reveal
const observer = new IntersectionObserver (( entries ) => {
entries . forEach ( entry => {
if ( entry . isIntersecting ) {
( entry . target as HTMLElement ). style . opacity = '1' ;
( entry . target as HTMLElement ). style . filter = 'blur(0px)' ;
observer . unobserve ( entry . target );
}
});
}, { threshold: 0.3 });
headings . forEach ( el => observer . observe ( el ));
</ script >
<!-- Panel starts off-screen -->
< div id = "menu-panel"
class = "fixed top-0 right-0 h-full translate-x-full
transition-transform duration-500 ease-in-out" >
</ div >
< script >
function openMenu () {
panel ! . classList . remove ( 'translate-x-full' );
panel ! . classList . add ( 'translate-x-0' );
}
function closeMenu () {
panel ! . classList . add ( 'translate-x-full' );
panel ! . classList . remove ( 'translate-x-0' );
}
</ script >
Best Practices
Use fluid typography
Apply clamp() for all text sizes to ensure smooth scaling across devices.
Maintain consistent spacing
Use standard spacing increments: mb-3, mb-6, mb-8, mb-16, mb-24.
Apply transitions to interactive elements
All hover states should include transition-colors or transition-opacity.
Respect z-index hierarchy
Keep backgrounds at z-0, content at z-10, navigation at z-50+.
Use custom colors consistently
Reference the defined color palette rather than creating new shades.
Performance : The font-display: swap strategy ensures text remains visible during font loading, preventing layout shifts.