/* ============================================================================
   Golden Journey — Zeel & Nidhi
   ----------------------------------------------------------------------------
   One stylesheet for the whole page, in the order the sections appear:

     1.  Tokens and resets
     2.  Shared pieces        cards, section titles, reveal-on-scroll
     3.  Preloader
     4.  Hero
     5.  Music player
     6.  Invitation
     7.  Scratch card
     8.  Countdown
     9.  Our story
     10. Wedding events
     11. The journey          Ahmedabad to Udaipur
     12. With blessings from
     13. RSVP
     14. Footer

   Sizes follow the original design's own breakpoints rather than scaling
   smoothly, because several of them deliberately go the other way: the tap
   logo, the aeroplane and the revealed date are all *larger* on a phone than
   on a desktop. Each block keeps its media queries at its foot.
   ========================================================================== */


/* ==========================================================================
   1. Tokens and resets
   ========================================================================== */

:root {
  --maroon:      #6e1f2f;
  --gold:        #c9a227;
  --gold-soft:   #e8c978;
  --gold-deep:   #b38728;
  --cream:       #faf5eb;
  --ink:         #2f2f2f;
  --ink-soft:    #6b6b6b;

  --rule-gold:   1px solid rgba(201, 162, 39, .3);
  --shadow:      0 10px 30px rgba(0, 0, 0, .05);
  --shadow-card: 0 10px 40px rgba(0, 0, 0, .05);

  --font-heading: "Cinzel", "Times New Roman", serif;
  --font-body:    "Cormorant Garamond", Georgia, serif;
  --font-names:   "Mussica Swash", "Great Vibes", cursive;
  --font-title:   "Great Vibes", cursive;
  --font-script:  "Parisienne", cursive;
}

*, *::before, *::after { box-sizing: border-box; }

body, h1, h2, h3, h4, p, figure, blockquote { margin: 0; padding: 0; }

html, body {
  width: 100%;
  min-height: 100vh;
  overflow-x: hidden;
  -webkit-tap-highlight-color: transparent;
}

body {
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--cream);
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* The page gradient, held still behind the scroll. A layer of its own rather
   than `background-attachment: fixed`, which makes the browser repaint the
   whole page on every scroll frame; this one is composited once and left. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(135deg, #faf5eb 0%, #f5efe0 100%);
}

/* Set by assets/js/main.js on a section that has scrolled out of view, so its
   looping decorations — sparks, the breathing heart, the bobbing plane — stop
   costing frames while nobody can see them. They carry on from where they
   were when it comes back. */
.is-offscreen,
.is-offscreen *,
.is-offscreen *::before,
.is-offscreen *::after { animation-play-state: paused !important; }

/* Held still while the preloader is up and the opening film is running, so the
   page cannot be scrolled past a cover that is still covering it.

   This has to name the root element as well as the body. The viewport takes
   its scrolling from <html>, and only falls back to <body> when <html> is
   `overflow: visible` — which it is not here, because of the `overflow-x:
   hidden` above. On <body> alone this rule does nothing at all. */
html.is-locked,
body.is-locked { overflow: hidden; }

h1, h2, h3, h4 {
  font-family: var(--font-heading);
  color: var(--maroon);
  font-weight: 500;
}

img, video { max-width: 100%; display: block; }

input, button, textarea { font: inherit; }


/* ==========================================================================
   2. Shared pieces
   ========================================================================== */

/* Every section below the hero sits on the page gradient and breathes the
   same amount. */
.section {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(4rem, 10vw, 8rem) 1.5rem;
}

/* The flowing Great Vibes title over most sections. */
.section__title {
  font-family: var(--font-title);
  font-size: 4rem;
  font-weight: 400;
  color: var(--maroon);
  text-align: center;
  margin-bottom: 3rem;
}

@media (max-width: 768px) {
  .section__title { font-size: 3rem; }
}

/* White card with a gold hairline and a second rule inset inside it — the
   motif the invitation, the family card and the RSVP box all share. */
.card {
  position: relative;
  width: 100%;
  background: #fff;
  border: var(--rule-gold);
  border-radius: 12px;
  box-shadow: var(--shadow);
  text-align: center;
}

.card::before {
  content: "";
  position: absolute;
  inset: 10px;
  border: 1px solid rgba(201, 162, 39, .2);
  border-radius: 8px;
  pointer-events: none;
}

/* Reveal on scroll. assets/js/reveal.js adds .is-in when the element first
   scrolls into view; an inline transition-delay staggers a group. */
[data-reveal] {
  opacity: 0;
  transform: translateY(40px);
  filter: blur(8px);
  transition: opacity .9s ease, transform .9s ease, filter .9s ease;
}

[data-reveal="fade"]  { transform: none; }
[data-reveal="left"]  { transform: translateX(-50px); filter: none; }
[data-reveal="zoom"]  { transform: scale(.95); filter: none; }

[data-reveal].is-in {
  opacity: 1;
  transform: none;
  filter: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; filter: none; transition: none; }
}


/* ==========================================================================
   3. Preloader
   Covers everything until the hero video has a frame to show.
   ========================================================================== */

.preloader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: linear-gradient(135deg, #fdfbf7 0%, #f4eee0 100%);
  transition: opacity .6s ease-out, visibility .6s ease-out;
}

.preloader.is-done { opacity: 0; visibility: hidden; }

/* Taken out of the page once it has faded, so its motes stop animating. */
.preloader[hidden] { display: none; }

.preloader__logo {
  width: 100px;
  height: 100px;
  margin-bottom: 2rem;
  object-fit: contain;
  filter: drop-shadow(0 4px 15px rgba(212, 175, 55, .3));
  animation: float 4s ease-in-out infinite;
}

.preloader__text {
  font-family: var(--font-heading);
  font-size: clamp(1rem, 4vw, 1.5rem);
  letter-spacing: .15em;
  text-transform: uppercase;
  text-align: center;
  color: var(--gold-deep);
  margin-bottom: 3rem;
  animation: pulse-text 2.5s ease-in-out infinite;
}

/* A 50px highlight sliding along a 150px track. */
.preloader__bar {
  position: relative;
  width: 150px;
  height: 2px;
  border-radius: 2px;
  background: rgba(183, 140, 59, .2);
  overflow: hidden;
}

.preloader__bar::after {
  content: "";
  position: absolute;
  top: 0;
  left: -50px;
  width: 50px;
  height: 100%;
  background: linear-gradient(90deg, transparent, var(--gold-deep), transparent);
  animation: shimmer 2s cubic-bezier(.65, 0, .35, 1) infinite;
}

/* Gold motes drifting up the screen. Each one's position, size and timing are
   randomised in assets/js/effects.js. */
.motes {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.motes__item {
  position: absolute;
  border-radius: 50%;
  opacity: 0;
  background: radial-gradient(circle, rgba(212, 175, 55, .8) 0%, rgba(212, 175, 55, 0) 70%);
  animation: mote-rise linear infinite;
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}

@keyframes pulse-text {
  0%, 100% { opacity: .6; text-shadow: 0 0 5px rgba(183, 140, 59, .2); }
  50%      { opacity: 1;  text-shadow: 0 0 15px rgba(183, 140, 59, .6); }
}

@keyframes shimmer {
  0%   { left: -50px; }
  100% { left: 100%; }
}

@keyframes mote-rise {
  0%        { opacity: 0; transform: translateY(100vh) scale(.5); }
  20%, 80%  { opacity: .6; }
  100%      { opacity: 0; transform: translateY(-10vh) scale(1.5); }
}


/* ==========================================================================
   4. Hero
   A looping film behind the couple's names. Until it is tapped, a dark
   overlay holds the "Tap to Begin" prompt.
   ========================================================================== */

.hero {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100vh;
  overflow: hidden;
  background: ivory;
}

.hero__video,
.hero__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero__video  { z-index: 1; }

/* The still sits over the video until the video has a frame of its own, so
   the first paint is never a black box. */
.hero__poster {
  z-index: 2;
  pointer-events: none;
  transition: opacity 1s ease-in-out;
}

.hero__poster.is-hidden { opacity: 0; }

.hero__cover {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, .6);
  cursor: pointer;
  transition: opacity 1s ease-out;
}

.hero__cover.is-open { opacity: 0; pointer-events: none; }

/* Gone for good once faded, so the breathing prompt stops animating under
   the film. */
.hero__cover[hidden] { display: none; }

.hero__tap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
}

.hero__tap-text {
  font-family: var(--font-heading);
  font-size: clamp(1.1rem, 4vw, 1.5rem);
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--cream);
  text-shadow: 0 4px 12px rgba(0, 0, 0, .5);
  animation: breathe 2.8s ease-in-out infinite;
}

/* Deliberately larger on a phone, where it is the whole invitation to open
   and the only thing worth tapping. */
.hero__tap-logo {
  width: 70px;
  filter: drop-shadow(0 2px 8px rgba(0, 0, 0, .4));
  animation: breathe 2.8s ease-in-out infinite;
}

@media (max-width: 768px) {
  .hero__tap { margin: 2rem 0; }
  .hero__tap-logo { width: 140px; }
}

@keyframes breathe {
  0%, 100% { opacity: .9; transform: scale(1); }
  50%      { opacity: 1;  transform: scale(1.04); }
}

/* The way past the film, as on template-1. Top right rather than bottom
   right, where the music button lives. Above the names, below the cover. */
.hero__skip {
  position: absolute;
  top: 1.25rem;
  right: 1.25rem;
  z-index: 8;
  padding: .5rem 1.1rem;
  font-family: var(--font-heading);
  font-size: .75rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--gold-soft);
  background: rgba(0, 0, 0, .5);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1px solid rgba(201, 162, 39, .6);
  border-radius: 9999px;
  cursor: pointer;
  animation: skip-in .6s ease both;
  transition: background .25s ease, border-color .25s ease;
}

.hero__skip:hover {
  background: rgba(0, 0, 0, .7);
  border-color: var(--gold);
}

.hero__skip[hidden] { display: none; }

@keyframes skip-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* The names, centred and lifted clear of the lower third of the film. */
.hero__names {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding-bottom: 15vh;
  text-align: center;
  pointer-events: none;
}

/* A dark veil behind the names so they read over any frame of the film. It
   stays clear while the film plays alone and fades in with the names. */
.hero__names::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(ellipse at center, rgba(0, 0, 0, .65) 0%, rgba(0, 0, 0, .45) 55%, rgba(0, 0, 0, .3) 100%);
  opacity: 0;
  transition: opacity 1.5s ease-out;
}

.hero__names.is-in::before { opacity: 1; }

/* Each line starts hidden and is dealt in by assets/js/hero.js: it rises and
   scales up while a clip wipes it open from its own baseline, which is what
   gives the names their curtain-lift rather than a plain fade. */
.hero__names > * {
  opacity: 0;
  transform: translateY(40px) scale(.9);
  clip-path: polygon(-50% 150%, 150% 150%, 150% 150%, -50% 150%);
  transition: opacity 1.5s cubic-bezier(.215, .61, .355, 1),
              transform 1.5s cubic-bezier(.215, .61, .355, 1),
              clip-path 1.5s cubic-bezier(.215, .61, .355, 1);
}

.hero__names.is-in > * {
  opacity: 1;
  transform: none;
  clip-path: polygon(-50% -50%, 150% -50%, 150% 150%, -50% 150%);
}

.hero__name {
  font-family: var(--font-names);
  font-size: 3.2rem;
  font-weight: 700;
  line-height: 1.45;
  letter-spacing: .05em;
  color: var(--cream);
  padding: .15em .5em;
  -webkit-text-stroke: .9px rgba(255, 255, 255, .7);
  text-shadow: 0 0 15px rgba(0, 0, 0, .9), 0 0 30px rgba(0, 0, 0, .7), 0 0 50px rgba(0, 0, 0, .5);
}

.hero__weds {
  font-family: var(--font-heading);
  font-size: 1.2rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--cream);
  margin: 1rem 0;
  text-shadow: 0 4px 12px rgba(0, 0, 0, .8), 0 12px 32px rgba(0, 0, 0, .7);
}

@media (max-width: 480px) {
  .hero__name { font-size: 2.3rem; }
}

/* Appears once the names have finished, and bounces until scrolled past. */
.hero__scroll {
  position: absolute;
  bottom: 5.5rem;
  left: 0;
  z-index: 5;
  display: flex;
  justify-content: center;
  width: 100%;
  opacity: 0;
  pointer-events: none;
  transition: opacity .6s ease-out;
}

.hero__scroll.is-in { opacity: 1; }

/* The bounce animates a glow, which is repainted every frame; there is no
   point running it before the hint appears or after it has gone. */
.hero__scroll:not(.is-in) .hero__scroll-inner { animation-play-state: paused; }

.hero__scroll-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .2rem;
  animation: haptic 1s cubic-bezier(.4, 0, .2, 1) infinite;
}

.hero__scroll-text {
  font-family: var(--font-heading);
  font-size: clamp(1.1rem, 4vw, 1.6rem);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: gold;
  text-shadow: 0 0 10px rgba(255, 215, 0, .6), 0 0 20px rgba(255, 215, 0, .4);
}

.hero__scroll-arrow {
  font-family: var(--font-heading);
  font-size: clamp(2.4rem, 9vw, 3.8rem);
  line-height: 1;
  color: #fff;
  filter: drop-shadow(0 0 8px rgba(255, 215, 0, .9)) drop-shadow(0 0 15px rgba(255, 215, 0, .7));
}

@keyframes haptic {
  0%, 100% { opacity: .8; transform: translateY(0);
             filter: drop-shadow(0 0 5px rgba(201, 162, 39, .4)); }
  50%      { opacity: 1;  transform: translateY(10px);
             filter: drop-shadow(0 0 20px rgba(201, 162, 39, 1)); }
}


/* ==========================================================================
   5. Music player
   A gold record in the corner, spinning while the track plays.
   ========================================================================== */

.music {
  position: fixed;
  right: clamp(16px, 2vw, 28px);
  bottom: clamp(16px, 2vw, 28px);
  z-index: 60;
  width: clamp(58px, 5vw, 74px);
  height: clamp(58px, 5vw, 74px);
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  opacity: 0;
  transform: translateY(60px);
  transition: opacity .8s ease-out, transform .8s ease-out;
}

/* Hidden until the invitation is opened — there is nothing to pause before. */
.music.is-in { opacity: 1; transform: none; }

.music::before {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: 50%;
  filter: blur(10px);
  background: radial-gradient(circle, rgba(255, 208, 85, .55), rgba(255, 208, 85, .18), transparent 72%);
  animation: glow 2.5s ease-in-out infinite;
}

/* No glow behind a button nobody can see yet. */
.music:not(.is-in)::before { animation-play-state: paused; }

.music__record {
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 0 8px rgba(255, 210, 80, .35));
  animation: spin 8s linear infinite;
  animation-play-state: paused;
}

.music.is-playing .music__record { animation-play-state: running; }

@keyframes glow {
  0%, 100% { opacity: .45; transform: scale(.92); }
  50%      { opacity: 1;   transform: scale(1.15); }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}


/* ==========================================================================
   6. Invitation
   ========================================================================== */

.invite__card {
  max-width: 800px;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(3rem, 6vw, 4rem) clamp(1rem, 4vw, 2rem);
  overflow: hidden;
}

.invite__onkar {
  font-size: 2rem;
  color: var(--gold);
  margin-bottom: .5rem;
}

.invite__shabad {
  font-size: .8rem;
  line-height: 2;
  letter-spacing: .1em;
  color: var(--ink);
  opacity: .7;
  margin-bottom: 1.5rem;
}

.invite__heading {
  font-family: var(--font-title);
  font-size: clamp(1.75rem, 6vw, 2.25rem);
  font-weight: 400;
  color: var(--maroon);
  margin-bottom: 1rem;
}

.invite__lead {
  max-width: 600px;
  font-size: clamp(1rem, 3vw, 1.25rem);
  font-weight: 500;
  line-height: 1.8;
  margin-bottom: clamp(1.5rem, 5vw, 4rem);
}

.invite__name {
  font-family: var(--font-names);
  font-size: clamp(1.9rem, 7vw, 2.5rem);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: .05em;
  color: var(--maroon);
  padding: 0 .5em;
  margin-bottom: .5rem;
}

.invite__relation {
  font-size: .9rem;
  font-style: italic;
  opacity: .8;
  margin-bottom: .25rem;
}

.invite__parents {
  font-size: clamp(1rem, 3vw, 1.2rem);
  font-weight: 500;
  letter-spacing: .05em;
  color: var(--gold);
}

.invite__with {
  font-size: 1rem;
  font-style: italic;
  letter-spacing: .2em;
  opacity: .6;
  margin: 1.25rem 0;
}


/* ==========================================================================
   7. Scratch card
   A gold heart scratched away with the pointer to uncover the date.
   ========================================================================== */

.scratch {
  position: relative;
  overflow: hidden;
  background-color: #fcfbf9;
  background-image: radial-gradient(circle at 10% 10%, #fff8e7 0%, transparent 60%);
}

/* Gold flecks drifting up through the whole section, behind the heart. Built
   in assets/js/effects.js because every one of them is placed at random. */
.sparks {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

.sparks__item {
  position: absolute;
  border-radius: 50%;
  box-shadow: 0 0 4px rgba(255, 255, 255, .8);
  animation: spark-rise linear infinite;
}

/* The travel is in viewport units, not percentages: a percentage here would be
   a share of each 2-6px speck rather than of the section it drifts through. */
@keyframes spark-rise {
  0%       { opacity: 0; transform: translateY(100vh) rotate(0); }
  10%, 90% { opacity: 1; }
  100%     { opacity: 0; transform: translateY(-20vh) rotate(360deg); }
}

.scratch__head { position: relative; z-index: 10; text-align: center; margin-bottom: clamp(2rem, 6vw, 4rem); }

.scratch__eyebrow {
  font-size: .9rem;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 1rem;
}

.scratch__title {
  font-family: var(--font-heading);
  font-size: clamp(1.5rem, 5vw, 2.2rem);
  letter-spacing: .05em;
  color: #6e2c2c;
}

.scratch__stage {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 460px;
}

/* The heart is square; the clip-path does the shaping. */
.scratch__card {
  position: relative;
  width: 100%;
  max-width: 400px;
  aspect-ratio: 1;
  margin: 0 auto;
  transition: transform .5s cubic-bezier(.25, 1, .5, 1);
  animation: hover-heart 4s ease-in-out infinite;
}

.scratch__card:hover { transform: scale(1.02); }
.scratch__card:hover .scratch__heart-line { filter: drop-shadow(0 0 15px rgba(201, 162, 39, .6)); }

.scratch__heart-bg,
.scratch__heart-line,
.scratch__foil-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* White fill behind the foil, so a scratched patch shows paper not page. */
.scratch__heart-bg {
  z-index: 0;
  filter: drop-shadow(0 15px 25px rgba(0, 0, 0, .08));
}

/* The foil canvas, clipped to the heart. */
.scratch__foil-wrap {
  z-index: 2;
  clip-path: url(#heart-clip);
}

.scratch__foil {
  width: 100%;
  height: 100%;
  cursor: crosshair;
  transition: opacity 1.2s ease-in-out;
}

.scratch__foil.is-cleared { opacity: 0; pointer-events: none; }

/* A single sweep of light across the foil, fired once the guest has scratched
   enough to show they have understood the idea — it draws the eye back to the
   heart just before it gives way. */
.scratch__shimmer {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  mix-blend-mode: overlay;
  background: linear-gradient(110deg, transparent 0% 40%, rgba(255, 255, 255, .7) 50%, transparent 60% 100%) 0 0 / 200% 100%;
  animation: shimmer-sweep 1.5s ease-in-out forwards;
}

.scratch__shimmer[hidden] { display: none; }

@keyframes shimmer-sweep {
  0%   { opacity: 0; background-position: 200% 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { opacity: 0; background-position: -200% 0; }
}

/* The gold outline, drawn over the foil and left behind after the reveal. */
.scratch__heart-line {
  z-index: 3;
  pointer-events: none;
  filter: drop-shadow(0 0 8px rgba(201, 162, 39, .3));
  animation: heart-breathe 4s ease-in-out infinite;
}

.scratch__date {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 1;
  width: 80%;
  transform: translate(-50%, -50%) scale(.95);
  opacity: 0;
  text-align: center;
  font-family: var(--font-heading);
  font-size: 1.8rem;
  line-height: 1.7;
  text-transform: uppercase;
  color: var(--gold-deep);
  text-shadow: 1px 1px 2px rgba(255, 255, 255, .8);
  transition: opacity 1s ease-out, transform 1s cubic-bezier(.2, 1.4, .4, 1);
}

.scratch__date.is-in { opacity: 1; transform: translate(-50%, -50%) scale(1); }

/* Confetti fired on reveal; sized generously so pieces can fall in from
   outside the card. */
.scratch__confetti {
  position: absolute;
  top: -50%;
  left: -50%;
  z-index: 10;
  width: 200%;
  height: 200%;
  pointer-events: none;
}

.scratch__hint {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-top: 2.5rem;
  transition: opacity .5s;
}

.scratch__hint.is-done { opacity: 0; }

.scratch__hint-text {
  font-family: var(--font-heading);
  font-size: clamp(1rem, 3vw, 1.1rem);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--maroon);
  opacity: .7;
  margin-bottom: .8rem;
}

.scratch__hand {
  width: 32px;
  height: 32px;
  color: var(--gold);
  opacity: .8;
  animation: swipe 2s ease-in-out infinite;
}

@keyframes hover-heart {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px); }
}

@keyframes heart-breathe {
  0%, 100% { filter: drop-shadow(0 0 8px rgba(201, 162, 39, .3)); }
  50%      { filter: drop-shadow(0 0 12px rgba(201, 162, 39, .5)); }
}

@keyframes swipe {
  0%, 100% { transform: translateX(15px) rotate(10deg); }
  50%      { transform: translateX(-15px) rotate(-10deg); }
}

@media (max-width: 480px) {
  .scratch            { padding: 40px 10px; }
  .scratch__card      { max-width: 320px; }
  .scratch__date      { font-size: 2rem; }
  .scratch__hint-text { font-size: 1rem; }
}


/* ==========================================================================
   8. Countdown
   ========================================================================== */

.countdown__grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(8px, 3vw, 2rem);
}

.countdown__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(8px, 2vw, 16px);
}

.countdown__box {
  display: flex;
  align-items: center;
  justify-content: center;
  width: clamp(65px, 18vw, 130px);
  height: clamp(65px, 18vw, 130px);
  background: var(--cream);
  border: 1px solid rgba(201, 161, 74, .25);
  border-radius: 8px;
  box-shadow: var(--shadow);
}

/* Swapped out and back by assets/js/countdown.js as each number changes: the
   old number leaves upwards, the new one rises into its place. */
.countdown__value {
  font-family: var(--font-heading);
  font-size: clamp(24px, 7vw, 52px);
  font-weight: 500;
  line-height: 1;
  color: var(--gold);
  transition: transform .35s cubic-bezier(.215, .61, .355, 1), opacity .35s ease-out;
}

.countdown__value.is-turning {
  opacity: 0;
  transform: translateY(-20px);
  transition: transform .25s ease-in, opacity .25s ease-in;
}

/* Where the incoming number waits, for one frame, before it rises. */
.countdown__value.is-below   { opacity: 0; transform: translateY(20px); }
.countdown__value.is-instant { transition: none; }

.countdown__label {
  font-family: var(--font-heading);
  font-size: clamp(8px, 2vw, 11px);
  letter-spacing: clamp(1px, .5vw, 3px);
  text-transform: uppercase;
  color: var(--ink);
}


/* ==========================================================================
   9. Our story
   A three-photo carousel beside the text.
   ========================================================================== */

.story__grid {
  display: flex;
  align-items: center;
  gap: clamp(2rem, 5vw, 4rem);
  width: 100%;
  max-width: 1100px;
}

.story__col { flex: 1; width: 100%; }

/* The three frames are stacked in one spot; .is-prev / .is-next slide the
   neighbours out to either side. */
.carousel {
  /* How far the two neighbouring photos sit out from the middle one. */
  --offset: 120px;

  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 600px;
  perspective: 1000px;
  touch-action: pan-y;
  user-select: none;
}

.carousel__slide {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 320px;
  height: 480px;
  padding: 14px;
  background: var(--cream);
  border: var(--rule-gold);
  border-radius: 12px;
  box-shadow: var(--shadow);
  cursor: grab;
  opacity: 0;
  z-index: 1;
  transform: scale(.5);
  transition: transform .6s cubic-bezier(.22, 1, .36, 1),
              opacity .6s cubic-bezier(.22, 1, .36, 1);
}

.carousel__slide:active { cursor: grabbing; }

.carousel__slide::after {
  content: "";
  position: absolute;
  inset: 6px;
  z-index: 10;
  border: 1px solid rgba(201, 162, 39, .3);
  border-radius: 8px;
  pointer-events: none;
}

.carousel__slide.is-current { opacity: 1; z-index: 3; transform: translateX(0) scale(1); }
.carousel__slide.is-next    { opacity: .5; z-index: 2; transform: translateX(var(--offset)) scale(.85); }
.carousel__slide.is-prev    { opacity: .5; z-index: 2; transform: translateX(calc(var(--offset) * -1)) scale(.85); }


.carousel__slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 4px;
  pointer-events: none;
}

.story__text {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 1.5rem;
}

.story__title {
  font-family: var(--font-title);
  font-size: clamp(3rem, 9vw, 4rem);
  font-weight: 400;
  color: var(--maroon);
  margin-bottom: 1rem;
}

.story__text p {
  font-size: clamp(1rem, 3vw, 1.1rem);
  font-weight: 500;
  line-height: 1.8;
  opacity: .9;
}

@media (max-width: 900px) {
  .story__grid     { flex-direction: column; text-align: center; }
  .carousel        { --offset: 60px; height: 450px; }
  .carousel__slide { width: 260px; height: 390px; }
}


/* ==========================================================================
   10. Wedding events
   ========================================================================== */

.events { background-color: var(--cream); }

.events__list {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4rem;
  width: 100%;
  max-width: 600px;
}

.event {
  display: flex;
  flex-direction: column;
  gap: 2rem;
  width: 100%;
  padding: clamp(1.5rem, 5vw, 2.5rem);
  background: #fff;
  border-radius: 20px;
  box-shadow: var(--shadow-card);
  text-align: center;
}

.event__name {
  font-family: var(--font-title);
  font-size: clamp(2.5rem, 9vw, 3.5rem);
  line-height: 1.2;
  color: var(--gold);
  margin-bottom: 1rem;
}

.event__date {
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  opacity: .7;
}

.event__time {
  font-family: var(--font-heading);
  font-size: 1.1rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: var(--gold);
  margin-top: .5rem;
}

/* The event films are portrait (9:16) and fill the card's width, as the
   photos did. The gold wash shows until the first frame arrives. */
.event__video {
  display: block;
  width: 100%;
  aspect-ratio: 9 / 16;
  object-fit: cover;
  border-radius: 16px;
  background: linear-gradient(160deg, #f6ead2, #e9d3a8);
  cursor: pointer;
  /* Its own compositor layer, so a playing film is not repainted with the
     page on every scroll frame. */
  transform: translateZ(0);
  backface-visibility: hidden;
}

/* The event cards rise in without the blur the other reveals use: a blur
   filter over a playing film forces the phone to re-filter every frame. */
.event[data-reveal] {
  filter: none;
  transition: opacity .9s ease, transform .9s ease;
}

.event__venue {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .6rem;
}

.event__venue-label {
  font-family: var(--font-heading);
  font-size: 13px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: #2f2e2d;
}

.event__venue-name {
  font-family: var(--font-heading);
  font-size: clamp(1.5rem, 5vw, 2rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 3px;
  text-transform: uppercase;
  background: linear-gradient(90deg, var(--gold), var(--gold-soft));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.event__street {
  font-family: var(--font-heading);
  font-size: 1.2rem;
  color: var(--ink-soft);
}

.event__country {
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: 500;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: #6e2c2c;
}

/* Shared by the four event cards; the only link out of the page. */
.map-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 1rem;
  padding: 12px 24px;
  font-family: var(--font-heading);
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--gold);
  background: var(--cream);
  border: 1px solid rgba(201, 161, 74, .35);
  border-radius: 100px;
  box-shadow: 0 4px 20px rgba(0, 0, 0, .06);
  transition: transform .3s, box-shadow .3s;
}

.map-link:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 28px rgba(201, 161, 74, .15);
}

.map-link svg { width: 16px; height: 16px; }


/* ==========================================================================
   11. The journey — Ahmedabad to Udaipur
   The plane flies down the dashed line as the section is scrolled.
   ========================================================================== */

.journey {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 600px;
  margin: clamp(4rem, 10vw, 6rem) 0;
}

.journey__stop {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  z-index: 5;
}

.journey__stop img {
  width: 300px;
  max-height: 250px;
  object-fit: contain;
}

/* journey-2.webp is square with clear space above and below the palace;
   trimmed to the same 3:2-ish frame as journey-1 so the two read as a pair. */
.journey__stop img.journey__img--trim {
  aspect-ratio: 300 / 220;
  height: auto;
  object-fit: cover;
  object-position: 50% 64%;
}

.journey__place {
  font-family: var(--font-heading);
  font-size: clamp(1.8rem, 6vw, 2.2rem);
  font-weight: 800;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--maroon);
  margin-top: .5rem;
}

.journey__track {
  position: relative;
  width: 100%;
  height: 350px;
  margin: 3rem 0;
}

.journey__line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  transform: translateX(-50%);
  background-image: linear-gradient(transparent 50%, rgba(0, 0, 0, .25) 50%);
  background-size: 100% 16px;
}

/* Nose-down at the top of the track; assets/js/journey.js drives --progress
   from 0 to 1 as the section passes the viewport, and writes the track's
   height in pixels to --track — a percentage translate would only ever move
   the plane its own height.

   The travel is the `translate` property rather than `top`, so following the
   scroll is a compositor move instead of a layout on every frame. It is kept
   apart from `transform` so that only the turn and the swell are eased: the
   plane tracks the scroll exactly and banks around rather than snapping. */
.journey__plane {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 10;
  width: 40px;
  height: 40px;
  translate: 0 calc(var(--progress, 0) * var(--track, 0px));
  transform: translate(-50%, -50%) rotate(var(--facing, 180deg)) scale(var(--climb, 1));
  transition: transform .5s ease-out;
  will-change: translate, transform;
}

/* Browsers without the separate `translate` property fall back to `top`. */
@supports not (translate: 0) {
  .journey__plane { top: calc(var(--progress, 0) * 100%); }
}

.journey__plane svg {
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  color: var(--maroon);
  animation: float 1.6s ease-in-out infinite;
}

/* The ground shadow under the plane. It shrinks and fades as the plane climbs
   away at the start of the flight, and settles again as it comes back down —
   assets/js/journey.js drives both off the same --progress. */
.journey__plane-shadow {
  position: absolute;
  top: 10%;
  left: 10%;
  z-index: 1;
  width: 80%;
  height: 80%;
  border-radius: 50%;
  background: radial-gradient(rgba(0, 0, 0, .4) 0%, transparent 70%);
  transform: translateY(5px) scale(var(--shadow-scale, 1));
  opacity: var(--shadow-alpha, .5);
}

/* The track tightens on a phone but the plane itself gets bigger, so it still
   reads as an aircraft rather than a speck on the line. */
@media (max-width: 768px) {
  .journey__track     { height: 300px; }
  .journey__plane     { width: 60px; height: 60px; }
  .journey__stop img  { width: 240px; max-height: 180px; }
}


/* ==========================================================================
   12. With blessings from
   ========================================================================== */

.family__card {
  max-width: 850px;
  padding: clamp(2rem, 6vw, 3rem) clamp(.5rem, 3vw, 1rem);
}

.family__group { margin-bottom: 1.5rem; }
.family__group:last-child { margin-bottom: 0; }

.family__group h4 {
  font-size: .9rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--maroon);
  margin-bottom: .25rem;
}

.family__group p {
  font-size: 1.3rem;
  font-weight: 600;
}

@media (max-width: 768px) {
  .family__group p { font-size: 1.15rem; }
}


/* ==========================================================================
   13. RSVP
   A boarding pass for the journey the events section has just flown: the
   guest fills it in, and sending it stamps it. See assets/js/rsvp.js.
   ========================================================================== */

.rsvp__lead {
  max-width: 34rem;
  margin: -1.5rem auto 2.5rem;
  font-size: 1.3rem;
  font-weight: 600;
  line-height: 1.5;
  text-align: center;
  color: var(--ink-soft);
}

.pass {
  position: relative;
  width: 100%;
  max-width: 560px;
  overflow: hidden;
  background: #fff;
  border-radius: 18px;
  box-shadow: 0 25px 60px -20px rgba(110, 31, 47, .35),
              0 0 0 1px rgba(201, 162, 39, .35);
}

/* The airline strip across the top. */
.pass__band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.5rem;
  font-family: var(--font-heading);
  font-size: .72rem;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--cream);
  background: var(--maroon);
}

.pass__airline {
  display: flex;
  align-items: center;
  gap: .6rem;
  color: var(--gold-soft);
}

/* The plane is drawn nose-up; turned to fly east, Ahmedabad to Udaipur. */
.pass__airline svg,
.pass__path svg {
  flex: none;
  width: 18px;
  height: 18px;
  transform: rotate(90deg);
}

/* AMD ✈ UDR. */
.pass__route {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1rem;
  padding: 1.75rem 1.5rem 1.5rem;
  border-bottom: 1px dashed rgba(201, 162, 39, .45);
}

.pass__city {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .2rem;
}

.pass__city--to { align-items: flex-end; text-align: right; }

.pass__code {
  font-family: var(--font-heading);
  font-size: clamp(2rem, 8vw, 2.75rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: .05em;
  color: var(--maroon);
}

.pass__place {
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink-soft);
}

.pass__when {
  font-family: var(--font-heading);
  font-size: .7rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.pass__path {
  display: flex;
  align-items: center;
  gap: .5rem;
  color: var(--gold);
}

.pass__path svg { width: 24px; height: 24px; }

.pass__dash {
  flex: 1;
  height: 2px;
  background: linear-gradient(90deg, rgba(201, 162, 39, .7) 50%, transparent 50%) 0 0 / 10px 2px;
}

/* ---- The form ------------------------------------------------------------ */

.pass__body { padding: 1.75rem 1.5rem .25rem; text-align: left; }

.pass__field {
  min-width: 0;
  margin: 0 0 1.6rem;
  padding: 0;
  border: 0;
}

.pass__label {
  display: block;
  margin-bottom: .45rem;
  padding: 0;
  font-family: var(--font-heading);
  font-size: .7rem;
  letter-spacing: .25em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

/* Written on the pass rather than typed into a box: a single rule to write
   along. */
.pass__input {
  width: 100%;
  padding: .3rem 0 .5rem;
  font-family: var(--font-body);
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1.5px solid rgba(110, 31, 47, .25);
  border-radius: 0;
  transition: border-color .3s;
}

.pass__input::placeholder { color: rgba(47, 47, 47, .35); font-weight: 500; }
.pass__input:focus        { outline: none; border-bottom-color: var(--maroon); }
.pass__input.is-bad       { border-bottom-color: #d9534f; }

textarea.pass__input {
  min-height: 64px;
  font-size: 1.2rem;
  line-height: 1.5;
  resize: vertical;
}

.pass__value {
  font-family: var(--font-heading);
  font-size: 1.15rem;
  color: var(--maroon);
}

.error {
  font-size: .9rem;
  color: #d9534f;
  margin-top: .35rem;
}

.error[hidden] { display: none; }

/* Joyfully yes / Regretfully no — two tiles side by side, the chosen one
   filled: maroon for yes, grey for no. They are radio buttons underneath. */
.choices {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: .6rem;
}

.choice {
  position: relative;
  cursor: pointer;
}

.choice input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.choice__card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: .15rem;
  height: 100%;
  padding: .75rem 2.2rem .75rem .95rem;
  border: 1px solid rgba(201, 162, 39, .5);
  border-radius: 10px;
  transition: background .25s, border-color .25s, transform .25s;
}

.choice:hover .choice__card { border-color: var(--maroon); transform: translateY(-1px); }

.choice__name {
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--maroon);
  transition: color .25s;
}

/* A tick in the corner, drawn once the tile is chosen. */
.choice__card::after {
  content: "";
  position: absolute;
  top: 50%;
  right: .95rem;
  width: 6px;
  height: 11px;
  border: solid var(--gold-soft);
  border-width: 0 2px 2px 0;
  opacity: 0;
  transform: translateY(-65%) rotate(45deg) scale(.4);
  transition: opacity .25s, transform .25s;
}

.choice input:checked + .choice__card {
  background: var(--maroon);
  border-color: var(--maroon);
}

.choice input:checked + .choice__card .choice__name { color: var(--cream); }

.choice input:checked + .choice__card::after {
  opacity: 1;
  transform: translateY(-65%) rotate(45deg) scale(1);
}

.choice--regret input:checked + .choice__card {
  background: var(--ink-soft);
  border-color: var(--ink-soft);
}

.choice input:focus-visible + .choice__card {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

.counter {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.counter button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  font-family: var(--font-heading);
  font-size: 1.1rem;
  color: var(--maroon);
  background: transparent;
  border: 1px solid var(--maroon);
  border-radius: 50%;
  cursor: pointer;
  transition: background .25s, color .25s;
}

.counter button:hover { background: var(--maroon); color: var(--cream); }

.counter output {
  min-width: 24px;
  font-family: var(--font-heading);
  font-size: 1.2rem;
  text-align: center;
  color: var(--maroon);
}

/* ---- The tear line and the stub ------------------------------------------ */

/* Dashes across, and a round bite out of each edge of the pass where it would
   be torn. The bites are the page's own cream. */
.pass__tear {
  position: relative;
  margin: 0 18px;
  border-top: 2px dashed rgba(201, 162, 39, .5);
}

.pass__tear::before,
.pass__tear::after {
  content: "";
  position: absolute;
  top: -15px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: #f8f2e6;
}

.pass__tear::before { left: -32px; }
.pass__tear::after  { right: -32px; }

.pass__stub {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: 1.5rem;
}

.pass__barcode {
  flex: none;
  width: 84px;
  height: 46px;
  opacity: .75;
  background: repeating-linear-gradient(90deg,
    var(--ink) 0 2px, transparent 2px 4px,
    var(--ink) 4px 5px, transparent 5px 8px,
    var(--ink) 8px 11px, transparent 11px 12px,
    var(--ink) 12px 13px, transparent 13px 16px);
}

.pass__send {
  flex: 1;
  padding: 1rem 1.5rem;
  font-family: var(--font-heading);
  font-size: .85rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--cream);
  background: var(--maroon);
  border: none;
  border-radius: 999px;
  cursor: pointer;
  transition: background .3s, transform .3s, box-shadow .3s;
}

.pass__send:hover {
  background: var(--ink);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .15);
}

.pass__send:disabled { opacity: .7; cursor: not-allowed; transform: none; }

/* ---- The issued pass ----------------------------------------------------- */

.pass__issued {
  padding: 2rem 1.5rem 2.25rem;
  text-align: center;
  outline: none;
}

.pass__issued[hidden] { display: none; }

/* Inked onto the pass as it is issued: dropped from above, a little crooked. */
.pass__stamp {
  display: inline-block;
  margin-bottom: 1.5rem;
  padding: .4rem 1rem;
  font-family: var(--font-heading);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--maroon);
  border: 3px double var(--maroon);
  border-radius: 8px;
  opacity: .85;
  transform: rotate(-8deg);
}

.pass.is-issued .pass__stamp { animation: stamp .55s cubic-bezier(.2, 1.3, .4, 1) both; }
.pass.is-regret .pass__stamp { color: var(--ink-soft); border-color: var(--ink-soft); }

.pass__guest {
  font-family: var(--font-title);
  font-size: clamp(2.4rem, 9vw, 3rem);
  line-height: 1.2;
  color: var(--maroon);
  overflow-wrap: anywhere;
}

.pass__summary {
  max-width: 260px;
  margin: 1.5rem auto 0;
  padding-top: 1.25rem;
  border-top: 1px dashed rgba(201, 162, 39, .45);
}

.pass__summary[hidden] { display: none; }

.pass__note {
  max-width: 26rem;
  margin: 1.5rem auto 2rem;
  font-size: 1.2rem;
  line-height: 1.6;
}

.rsvp__again {
  padding: .75rem 2.5rem;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--maroon);
  background: transparent;
  border: 1px solid var(--maroon);
  border-radius: 30px;
  cursor: pointer;
  transition: background .3s, color .3s;
}

.rsvp__again:hover { background: var(--maroon); color: var(--cream); }

.rsvp__sample {
  max-width: 30rem;
  margin-top: 2rem;
  font-size: 1rem;
  font-style: italic;
  line-height: 1.5;
  text-align: center;
  color: var(--ink-soft);
}

@media (max-width: 480px) {
  .rsvp__lead  { font-size: 1.15rem; }
  .pass__band  { padding: .9rem 1.1rem; font-size: .62rem; letter-spacing: .16em; }
  .pass__route { padding: 1.5rem 1.1rem 1.25rem; gap: .6rem; }
  .pass__place { font-size: .9rem; }
  .pass__body  { padding: 1.5rem 1.1rem .25rem; }
  .choice__card { padding: .7rem 1.6rem .7rem .8rem; }
  .choice__card::after { right: .7rem; }
  .choice__name { font-size: 1.1rem; }
  .pass__stub  { padding: 1.25rem 1.1rem; gap: .9rem; }
  .pass__barcode { width: 60px; }
  .pass__send  { padding: .95rem 1rem; font-size: .75rem; letter-spacing: .14em; }
}

@keyframes stamp {
  from { opacity: 0; transform: rotate(-8deg) scale(2.2); }
  to   { opacity: .85; transform: rotate(-8deg) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .pass.is-issued .pass__stamp { animation: none; }
}


/* ==========================================================================
   14. Footer
   A postcard home — airmail border, the monogram for a stamp and a postmark
   from the wedding — on the maroon ground.
   ========================================================================== */

.footer {
  padding: 5rem 1.5rem 2rem;
  text-align: center;
  color: var(--cream);
  background: var(--maroon);
}

/* The airmail stripes are the postcard's own background, showing as a
   border around the paper laid over it. */
.postcard {
  max-width: 820px;
  margin: 0 auto 2.5rem;
  padding: 10px;
  border-radius: 6px;
  background: repeating-linear-gradient(135deg,
    var(--gold)  0 14px,  #fdf9f0 14px 22px,
    #b8475a      22px 36px, #fdf9f0 36px 44px);
  box-shadow: 0 30px 60px -25px rgba(0, 0, 0, .5);
}

.postcard__paper {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 2rem;
  padding: 2rem;
  text-align: left;
  color: var(--ink);
  background: #fdf9f0;
  border-radius: 2px;
}

.postcard__message {
  padding-right: 2rem;
  border-right: 1px solid rgba(110, 31, 47, .2);
}

.postcard__thanks {
  margin-bottom: .75rem;
  font-family: var(--font-script);
  font-size: clamp(2.8rem, 9vw, 3.6rem);
  line-height: 1.1;
  color: var(--maroon);
}

.postcard__text {
  font-size: 1.2rem;
  font-weight: 500;
  line-height: 1.6;
}

.postcard__sign {
  margin-top: 1.25rem;
  font-size: 1.1rem;
  font-style: italic;
}

.postcard__sign span {
  display: block;
  font-family: var(--font-title);
  font-size: 2rem;
  font-style: normal;
  word-spacing: .2em;
  color: var(--maroon);
}

.postcard__address { display: flex; flex-direction: column; }

.postcard__marks {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  margin-bottom: 1.75rem;
}

/* Inked over the stamp's corner, as a real one would be. */
.postcard__postmark {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 92px;
  height: 92px;
  margin-right: -12px;
  font-family: var(--font-heading);
  font-size: .56rem;
  letter-spacing: .15em;
  text-transform: uppercase;
  color: rgba(110, 31, 47, .7);
  border: 2px solid rgba(110, 31, 47, .55);
  border-radius: 50%;
  transform: rotate(-14deg);
}

.postcard__postmark strong {
  margin: .2rem 0;
  font-size: .78rem;
  letter-spacing: .05em;
}

/* The perforated edge is a dotted border in the paper's colour, drawn over
   the stamp's white. */
.postcard__stamp {
  width: 88px;
  height: 104px;
  padding: 5px;
  background: #fff;
  border: 5px dotted #fdf9f0;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, .15));
}

.postcard__stamp img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: var(--cream);
}

.postcard__to {
  margin-bottom: .25rem;
  font-family: var(--font-heading);
  font-size: .7rem;
  letter-spacing: .25em;
  text-transform: uppercase;
  color: var(--gold-deep);
}

.postcard__lines {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The address, handwritten along ruled lines. */
.postcard__lines li {
  padding: .35rem 0 .1rem .75rem;
  font-family: var(--font-title);
  font-size: 1.9rem;
  line-height: 1.4;
  color: var(--maroon);
  border-bottom: 1px solid rgba(110, 31, 47, .25);
}

.footer__credit {
  font-size: .75rem;
  letter-spacing: .05em;
  color: rgba(250, 245, 235, .7);
}

.footer__credit a { color: var(--gold); text-decoration: none; }

@media (max-width: 680px) {
  .footer { padding-top: 4rem; }

  .postcard__paper {
    grid-template-columns: 1fr;
    gap: 1.5rem;
    padding: 1.5rem;
  }

  .postcard__message {
    padding: 0 0 1.5rem;
    border-right: 0;
    border-bottom: 1px solid rgba(110, 31, 47, .2);
  }

  /* On a phone the stamp leads the address side, so it sits at the left. */
  .postcard__marks { justify-content: flex-start; }
}
