/* ═══════════════════════════════════════════════════════════════════════════
   Kai & Andrew — 12 August 2026, Belchite
   Palette and ornaments are lifted from the purchased invitation artwork;
   see tools/dissect.py for how the layers were pulled apart.
   ═══════════════════════════════════════════════════════════════════════════ */

:root {
  --night-900: #01070d;
  --night-800: #030d16;
  --night-700: #0a1420;
  --night-600: #152028;

  --paper:     #e3d8ca;
  --paper-dim: #ddd1c2;
  --cream:     #eee1d0;

  --gold:      #d2ae7a;
  --gold-lit:  #f3ddb6;
  --bronze:    #ab8557;
  --ink:       #241c14;

  --serif:  'Cormorant Garamond', 'Iowan Old Style', Georgia, serif;
  --script: 'Pinyon Script', 'Snell Roundhand', cursive;

  --measure: 62ch;
  --ease: cubic-bezier(.22, .61, .36, 1);
  --tabs-h: 54px;
}

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--night-900);
  color: var(--paper);
  font-family: var(--serif);
  font-weight: 300;
  font-size: clamp(16px, 1rem + .2vw, 19px);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* height:auto matters — these carry width/height attributes for layout
   stability, and without it the attribute height wins and squashes them. */
img { max-width: 100%; display: block; height: auto; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ── starfield ────────────────────────────────────────────────────────────
   These are the invitation's own stars: tools/elements.py detects every point
   in the painted night sky and emits their positions as night-stars.svg. It is
   used as a mask so the stars can be lit in any colour, tiled at two sizes so
   the repeat does not read. */
.starfield {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(ellipse 60% 45% at 78% 12%, rgba(210, 174, 122, .12), transparent 70%),
    radial-gradient(ellipse 70% 50% at 18% 78%, rgba(90, 120, 170, .12), transparent 70%),
    var(--night-900);
}
.starfield::before,
.starfield::after {
  content: '';
  position: absolute; inset: -10%;
  -webkit-mask-image: url(/assets/el/night-stars.svg);
          mask-image: url(/assets/el/night-stars.svg);
  -webkit-mask-repeat: repeat;
          mask-repeat: repeat;
  animation: drift 300s linear infinite;
}
/* Tile sizes hold the 1000:1537 aspect of the sky patch the stars came from. */
.starfield::before {
  -webkit-mask-size: 900px 1383px; mask-size: 900px 1383px;
  background: #fff8e8;
  opacity: .5;
}
.starfield::after {
  -webkit-mask-size: 1480px 2275px; mask-size: 1480px 2275px;
  -webkit-mask-position: 240px 120px; mask-position: 240px 120px;
  background: #cfe0ff;
  opacity: .26;
  animation-duration: 460s;
  animation-direction: reverse;
}
@keyframes drift { to { transform: translate3d(900px, 1383px, 0); } }

/* ═══ tabs ═══════════════════════════════════════════════════════════════ */
.tabs {
  position: sticky; top: 0; z-index: 40;
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  background: rgba(3, 9, 17, .72);
  border-bottom: 1px solid rgba(210, 174, 122, .16);
}
.tabs ul {
  display: flex;
  /* `safe` matters: a plain centred flex row that overflows clips its first
     and last items off both edges, and no amount of scrolling reaches them. */
  justify-content: safe center;
  gap: clamp(.15rem, 1.6vw, 1.4rem);
  margin: 0 auto; padding: 0 .5rem;
  max-width: 1080px;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs ul::-webkit-scrollbar { display: none; }
.tabs a {
  display: block;
  padding: .85rem .7rem;
  white-space: nowrap;
  font-size: clamp(.62rem, 1.7vw, .74rem);
  font-weight: 500;
  letter-spacing: .2em; text-transform: uppercase; text-indent: .2em;
  color: #8f8676;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color .35s var(--ease), border-color .35s var(--ease);
}
.tabs a:hover { color: var(--paper); }
.tabs a.is-here { color: var(--gold-lit); border-bottom-color: var(--gold); }
.tabs a:focus-visible { outline: 2px solid var(--gold); outline-offset: -4px; }

/* Anchored scrolling has to clear the sticky bar. */
:where(.hero, .section) { scroll-margin-top: 3.4rem; }

/* ═══ the hero ═══════════════════════════════════════════════════════════
   The invitation was a fixed 5×7 card; this composes the same scene from the
   extracted elements so it fills any viewport. Percentage placement keeps the
   composition — moon upper left, sun upper right, ranges and water along the
   bottom, arch centred — at every size. */
.hero {
  position: relative;
  min-height: min(100svh, 900px);
  display: grid;
  place-items: center;
  padding: clamp(2rem, 7vh, 5rem) 1rem clamp(3rem, 9vh, 6rem);
  overflow: hidden;
  isolation: isolate;
}

.hero-scene { position: absolute; inset: 0; z-index: 0; pointer-events: none; }

.sky-day {
  position: absolute; inset: 0;
  background: linear-gradient(168deg, #e5dbcd 0%, #e9dbc9 42%, #e4d2b9 72%, #c7b39b 100%);
}
/* The artwork's own torn edge, traced to SVG, dividing the two halves. */
.sky-night {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 70% 50% at 22% 78%, rgba(70, 100, 150, .16), transparent 70%),
    linear-gradient(170deg, #01070d 0%, #030d16 45%, #0a1420 100%);
  /* Wider than the hero so the night half reaches about mid-screen: the seam
     is a 0.7-aspect curve and its dark side only occupies the left third of
     its own box. */
  -webkit-mask: url(/assets/el/seam-night.svg) no-repeat left top / 125% 100%;
          mask: url(/assets/el/seam-night.svg) no-repeat left top / 125% 100%;
}
/* Paper grain, as grain — laid in the background shorthand it is an opaque
   layer and simply covers the gradient underneath it. */
.sky-night::before {
  content: '';
  position: absolute; inset: 0;
  background: url(/assets/el/paper-night.webp) repeat 0 0 / 340px auto;
  opacity: .45;
  mix-blend-mode: overlay;
}
.sky-night::after {
  content: '';
  position: absolute; inset: 0;
  -webkit-mask-image: url(/assets/el/night-stars.svg);
          mask-image: url(/assets/el/night-stars.svg);
  -webkit-mask-size: 760px 1168px; mask-size: 760px 1168px;
  -webkit-mask-repeat: repeat;   mask-repeat: repeat;
  background: #fff8e8;
  opacity: .55;
}

.el { position: absolute; }
.el img { width: 100%; height: auto; }
/* Parallax writes --py; anything with its own transform composes with it. */
.el, .hero-ridge, .deco { transform: translate3d(0, var(--py, 0px), 0); }

/* The day cut-outs are feathered rather than matted, so they carry paper right
   to their edges; multiply at full strength turns that into a brown smear.
   Held low and spread apart, they read as haze instead. */
.el-sun     { top: -8%;   right: 3%;   width: min(34vw, 400px); opacity: .9;  mix-blend-mode: multiply; }
.el-moon    { top: 11%;   left: 8%;    width: min(15vw, 140px); }
.el-cloud-d { top: 30%;   right: 1%;   width: min(30vw, 350px); opacity: .55; mix-blend-mode: multiply; }
.el-cloud-n { top: 26%;   left: -4%;   width: min(32vw, 340px); opacity: .75; }
.el-mtn-n   { bottom: 8%;  left: -2%;  width: min(30vw, 340px); opacity: .8; }
.el-mtn-d   { bottom: 14%; right: 6%;  width: min(26vw, 300px); opacity: .5;  mix-blend-mode: multiply; }
.el-water-d { bottom: 6%;  right: 10%; width: min(15vw, 165px); opacity: .45; mix-blend-mode: multiply; }
.el-water-n { bottom: 2%;  left: 2%;   width: min(26vw, 300px); opacity: .85; }
.el-flora-r { bottom: -8%; right: -6%; width: min(34vw, 380px); opacity: .5;  mix-blend-mode: multiply; }
.el-flora-l { bottom: -8%; left: -6%;  width: min(46vw, 480px); opacity: .95; mix-blend-mode: screen; }

/* Scoped past the base .ridgeline rule, which is position:relative for use as
   a between-sections divider. */
.hero-scene .hero-ridge {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: clamp(90px, 16vh, 220px);
  opacity: .9;
}
/* The horizon crosses both halves, so it is lit across: night rock on the left
   easing into warm rock under the day sky. It stays dark at the warm end on
   purpose — the countdown section starts immediately below, and a bright right
   edge here would meet it as a visible band. */
.hero-scene .hero-ridge .r-far {
  background: linear-gradient(96deg, #0d1a29 34%, #2c2519 66%, #46392479 100%);
}
.hero-scene .hero-ridge .r-near {
  background: linear-gradient(96deg, #040a12 38%, #140f0a 70%, #241c12 100%);
}

/* ── the arch ─────────────────────────────────────────────────────────────
   Built rather than cropped, so it scales freely: a rounded-top panel of the
   paper texture lifted off the plate, with the gold outline as a gradient
   ring. The old card's arch was 448×995 in the original, hence the ratio. */
/* The container lives on the wrapper, not the arch. An element cannot query
   itself: cqi inside .arch's own padding would resolve against the viewport,
   and at these viewport widths that padding swallowed the whole content box,
   leaving every descendant cqi at zero. With the container one level out, cqi
   means "a hundredth of the arch's width", which is what the type wants. */
.arch-wrap {
  position: relative; z-index: 2;
  display: grid; justify-items: center;
  --aw: min(78vw, 42vh, 400px);
  width: var(--aw);
  container-type: inline-size;
}

.arch {
  position: relative;
  width: 100%;
  aspect-ratio: 448 / 760;
  --r: calc(var(--aw) / 2);
  border-radius: var(--r) var(--r) 5px 5px;
  background:
    linear-gradient(180deg, rgba(255, 252, 246, .5), rgba(214, 200, 178, .34)),
    url(/assets/el/paper-cream.webp) repeat 0 0 / 240px auto,
    var(--paper);
  box-shadow:
    0 26px 55px -22px rgba(2, 8, 16, .6),
    0 60px 120px -60px rgba(2, 8, 16, .7);

  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4.6cqi;
  padding: 13% 9% 9%;   /* per cent of the arch's own width, never cqi */
  text-align: center;
  color: var(--ink);
}
/* Gold outline: a gradient ring, masked to just the border. */
.arch::before {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  padding: 1.6px;
  background: linear-gradient(155deg, #f3ddb6, #ab8557 42%, #d2ae7a 70%, #8a6a3c);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  pointer-events: none;
}

.arch-seal {
  width: clamp(58px, 8vw, 86px);
  margin-top: -6%;
  position: relative; z-index: 3;
  filter: drop-shadow(0 8px 18px rgba(2, 8, 16, .5));
}

.eyebrow {
  margin: 0;
  font-size: 3.1cqi;
  font-weight: 500;
  letter-spacing: .24em;
  text-transform: uppercase;
  line-height: 1.75;
  color: #443a2d;
  text-indent: .24em;
}

/* The names need more room than the rest of the stack, and at their height the
   arch is clear right across, so they get their own wider track. */
.arch h1 {
  margin: 0;
  width: 150%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.3cqi;
  font-weight: 400;
  line-height: 1;
}
.name {
  font-size: 17.5cqi;
  letter-spacing: .04em;
  text-indent: .04em;
  color: #1c1610;
}
.amp {
  display: flex;
  align-items: center;
  gap: 3.4cqi;
  width: 62%;
  color: var(--bronze);
}
.amp::before, .amp::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, var(--bronze), transparent);
}
.amp i { font-family: var(--script); font-size: 6.6cqi; font-style: normal; line-height: 1; }

.invite { color: #57493a; }

.facts { margin: 0; display: grid; gap: 3.4cqi; width: 100%; }
.facts div {
  display: grid; gap: .7cqi;
  padding-top: 3.2cqi;
  border-top: 1px solid rgba(122, 96, 60, .34);
}
.facts div:first-child { border-top: 0; padding-top: 0; }
.facts dt {
  font-size: 2.6cqi; font-weight: 500;
  letter-spacing: .24em; text-transform: uppercase; text-indent: .24em;
  color: var(--bronze);
}
.facts dd { margin: 0; font-size: 4.8cqi; letter-spacing: .04em; color: #2b231a; }
.facts time { font-variant-numeric: tabular-nums; }

.arch-countdown {
  margin: 0;
  font-size: 3.2cqi;
  letter-spacing: .2em; text-transform: uppercase; text-indent: .2em;
  color: var(--bronze);
  font-variant-numeric: tabular-nums;
  min-height: 1.2em;
}

/* As totality lands, the card's own ink lifts to gold against the dark. The
   wedding is history now, so body.is-married keeps that lit state permanently
   rather than the page cycling through it as a phase. */
body.is-totality .arch,
body.is-married .arch { color: var(--gold-lit); }
body.is-totality .name,
body.is-married .name { color: #fbeed3; text-shadow: 0 0 24px rgba(243, 221, 182, .45); }
body.is-totality .eyebrow, body.is-totality .invite, body.is-totality .facts dd,
body.is-married .eyebrow, body.is-married .invite, body.is-married .facts dd { color: #e6d3ae; }
body.is-totality .facts dt, body.is-totality .amp, body.is-totality .arch-countdown,
body.is-married .facts dt, body.is-married .amp, body.is-married .arch-countdown { color: var(--gold); }
body.is-totality .facts div,
body.is-married .facts div { border-color: rgba(210, 174, 122, .3); }
.arch, .name, .eyebrow, .facts dd, .facts dt { transition: color 1.4s var(--ease), text-shadow 1.4s var(--ease); }

/* ═══ shared section furniture ═══════════════════════════════════════════ */
.section { position: relative; padding: clamp(4rem, 11vh, 8rem) 1.25rem; overflow: hidden; }
.wrap { max-width: 1080px; margin: 0 auto; position: relative; z-index: 1; }
.wrap.narrow { max-width: 660px; }

.kicker {
  margin: 0 0 .9rem;
  font-size: .74rem; font-weight: 500;
  letter-spacing: .34em; text-transform: uppercase; text-indent: .34em;
  color: var(--gold);
}

.section h2 {
  margin: 0 0 1.6rem;
  font-size: clamp(2rem, 5.2vw, 3.4rem);
  font-weight: 300;
  line-height: 1.12;
  letter-spacing: .01em;
  color: var(--cream);
}

/* Screen blending: these are gold on transparent, and over the night palette a
   plain alpha composite turns the gold to mud. Screening makes it glow. */
/* Screen blending: these are gold on transparent, and over the night palette a
   plain alpha composite turns the gold to mud. Screening makes it glow. */
.deco { position: absolute; pointer-events: none; user-select: none; mix-blend-mode: screen; }
/* Kept clear of the clock: at ~1200px the burst used to cross the seconds. */
.deco-sun    { top: -20%; right: -11%; width: min(38vw, 400px); opacity: .8; }
/* One filigree sweep, mirrored, rather than two crops of the same artwork. */
.deco-bot-l  { bottom: -4%; left: -6%; width: min(54vw, 440px); opacity: .55; }
.deco-leaves { top: -4%; right: -6%;   width: min(44vw, 380px); opacity: .34; }
.deco-cloud  { top: -8%; left: -10%;   width: min(52vw, 460px); opacity: .3; }
.deco-leaf-n { bottom: -4%; right: -3%; width: min(26vw, 230px); opacity: .6; }
.deco-water  { bottom: -6%; right: -8%; width: min(46vw, 400px); opacity: .4; }
.deco-sprig  { bottom: -8%; left: -4%; width: min(34vw, 260px); opacity: .3; }

/* ── ridgeline ───────────────────────────────────────────────────────────
   The two day-side ranges, traced to SVG by tools/elements.py. They fill with
   currentColor, so they are used as masks and painted per placement — the same
   horizon serves the warm sections and the night ones. */
.ridgeline {
  position: relative;
  height: clamp(64px, 9vw, 130px);
  margin-bottom: -1px;   /* no hairline between the ridge and what follows */
  pointer-events: none;
}
.ridgeline i {
  position: absolute; inset: 0;
  display: block;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
}
.ridgeline .r-far {
  -webkit-mask-image: url(/assets/el/ridge-far.svg);
          mask-image: url(/assets/el/ridge-far.svg);
  background: var(--ridge-far, #101d2c);
}
.ridgeline .r-near {
  -webkit-mask-image: url(/assets/el/ridge-near.svg);
          mask-image: url(/assets/el/ridge-near.svg);
  background: var(--ridge-near, #050b13);
}

/* ═══ countdown ══════════════════════════════════════════════════════════ */
.countdown { text-align: center; background: linear-gradient(180deg, var(--night-900), var(--night-800) 60%, var(--night-900)); }

.clock {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(.4rem, 2vw, 1.75rem);
  margin: 1.5rem auto 2rem;
  max-width: 760px;
}
.unit { display: grid; gap: .35rem; justify-items: center; }
.digits {
  font-size: clamp(2.5rem, 11vw, 5.6rem);
  font-weight: 300;
  line-height: 1;
  color: var(--gold-lit);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1;
  text-shadow: 0 0 40px rgba(243, 221, 182, .22);
}
.label {
  font-size: .66rem; letter-spacing: .3em; text-transform: uppercase; text-indent: .3em;
  color: var(--bronze);
}

.phase {
  margin: 0 auto 2.6rem;
  max-width: 46ch;
  font-size: clamp(1.1rem, 2.4vw, 1.45rem);
  font-style: italic;
  color: var(--paper-dim);
}

.contacts {
  list-style: none;
  margin: 0 auto 2.4rem;
  padding: 0;
  max-width: 620px;
  text-align: left;
  counter-reset: c;
}
.contacts li {
  display: grid;
  grid-template-columns: 8.5ch 1fr;
  gap: 1.1rem;
  align-items: baseline;
  padding: .85rem 0 .85rem 1.1rem;
  border-left: 1px solid rgba(210, 174, 122, .22);
  position: relative;
  opacity: .5;
  transition: opacity .7s var(--ease), border-color .7s var(--ease);
}
.contacts li::before {
  content: '';
  position: absolute; left: -3.5px; top: 1.35rem;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--bronze);
  transition: background .7s var(--ease), box-shadow .7s var(--ease);
}
.contacts li.done { opacity: .78; }
.contacts li.now {
  opacity: 1;
  border-color: var(--gold);
}
.contacts li.now::before { background: var(--gold-lit); box-shadow: 0 0 0 4px rgba(243, 221, 182, .16); }
.contacts .t { font-variant-numeric: tabular-nums; letter-spacing: .06em; color: var(--gold); }
.contacts .n { color: var(--paper-dim); }
.contacts em { font-style: italic; color: var(--gold-lit); }

.footnote {
  margin: 0 auto;
  max-width: 56ch;
  font-size: .92rem;
  line-height: 1.75;
  color: #8f8676;
}
.footnote strong { color: var(--gold); font-weight: 400; }

/* ═══ photos & video ═════════════════════════════════════════════════════ */
.media { text-align: center; }
.media-lead {
  margin: 0 auto 2.6rem;
  max-width: 52ch;
  font-size: clamp(1.05rem, 2.2vw, 1.3rem);
  font-style: italic;
  color: var(--paper-dim);
}
.media-h3 {
  margin: 0 0 1.2rem;
  font-size: .76rem; font-weight: 500;
  letter-spacing: .3em; text-transform: uppercase; text-indent: .3em;
  color: var(--gold);
  text-align: left;
}
.media-h3:not(:first-of-type) { margin-top: 3rem; }

.video-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 420px), 1fr));
  gap: 1.5rem;
}
.player {
  position: relative;
  aspect-ratio: 16 / 9;
  border: 1px solid rgba(210, 174, 122, .26);
  border-radius: 3px;
  overflow: hidden;
  background:
    radial-gradient(ellipse 70% 60% at 50% 40%, rgba(21, 32, 40, .9), transparent 70%),
    linear-gradient(160deg, var(--night-800), var(--night-900));
  box-shadow: 0 30px 70px -30px rgba(0, 0, 0, .9);
}
.player iframe { width: 100%; height: 100%; border: 0; display: block; }

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 190px), 1fr));
  gap: .6rem;
}
.gallery-item {
  display: block;
  padding: 0; margin: 0; border: 0;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: 3px;
  background: var(--night-800);
  cursor: pointer;
}
.gallery-item img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform .5s var(--ease);
}
.gallery-item:hover img,
.gallery-item:focus-visible img { transform: scale(1.06); }
.gallery-item:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }

.media-empty {
  grid-column: 1 / -1;
  display: grid; gap: .55rem; justify-items: center;
  padding: clamp(2.5rem, 8vw, 4rem) 2rem;
  border: 1px dashed rgba(210, 174, 122, .26);
  border-radius: 3px;
}
.fallback-lead {
  margin: 0;
  font-size: clamp(1.15rem, 3vw, 1.7rem);
  letter-spacing: .04em;
  color: var(--cream);
}
.fallback-sub { margin: 0; max-width: 42ch; color: #8f8676; font-size: .95rem; }

/* ═══ lightbox ═══════════════════════════════════════════════════════════ */
.lightbox {
  position: fixed; inset: 0; z-index: 50;
  display: grid; place-items: center;
  padding: 4vh 4vw;
  background: rgba(1, 7, 13, .92);
  opacity: 0;
  transition: opacity .2s var(--ease);
}
.lightbox[hidden] { display: none; }
.lightbox.open { opacity: 1; }
.lightbox img {
  max-width: 100%; max-height: 92vh;
  width: auto; height: auto;
  border-radius: 2px;
  box-shadow: 0 30px 80px -20px rgba(0, 0, 0, .9);
}
.lightbox-close {
  position: absolute; top: clamp(.75rem, 3vw, 1.5rem); right: clamp(.75rem, 3vw, 1.5rem);
  width: 2.5rem; height: 2.5rem;
  display: grid; place-items: center;
  border: 1px solid rgba(210, 174, 122, .3);
  border-radius: 50%;
  background: rgba(1, 7, 13, .6);
  color: var(--cream);
  font-size: 1.4rem; line-height: 1;
  cursor: pointer;
}
.lightbox-close:hover, .lightbox-close:focus-visible { border-color: var(--gold); color: var(--gold-lit); }

/* ═══ story ══════════════════════════════════════════════════════════════ */
.story { background: linear-gradient(180deg, var(--night-900), #060e18 50%, var(--night-900)); }
.prose p {
  margin: 0 0 1.35rem;
  font-size: clamp(1.05rem, 2.3vw, 1.28rem);
  line-height: 1.85;
  color: var(--paper-dim);
}
.prose p:first-child::first-letter {
  float: left;
  font-size: 3.2em;
  line-height: .86;
  padding: .04em .05em 0 0;
  color: var(--gold);
  font-weight: 400;
}
.signature {
  margin: 2.4rem 0 0;
  font-size: clamp(1.5rem, 4vw, 2.1rem);
  color: var(--gold-lit);
  letter-spacing: .06em;
}
.signature i { font-family: var(--script); font-style: normal; color: var(--bronze); padding: 0 .2em; }

/* ═══ the day half ═══════════════════════════════════════════════════════
   Cream paper, sampled straight off the artwork's day sky by elements.py, so
   the pale day cut-outs finally have a background they belong on — pale flora
   over night reads as a grey smudge no matter how it is blended. */
.day {
  background: linear-gradient(180deg, #e9dfd0 0%, #e6d9c8 45%, #dccbb2 100%);
  color: #3a3025;
}
.day h2 { color: #241c14; }
.day .kicker { color: #8a6a3c; }
.day .deco { mix-blend-mode: multiply; }
.deco-clouds-day { top: -6%; left: -8%;  width: min(50vw, 460px); opacity: .5; }
.deco-leaves     { top: 2%;  right: -8%; width: min(42vw, 360px); opacity: .55; }
.deco-sprig      { bottom: -6%; left: -3%; width: min(30vw, 240px); opacity: .5; }

.day .cards { background: rgba(122, 96, 60, .3); border-color: rgba(122, 96, 60, .3); }
.day .cards article { background: rgba(252, 248, 240, .58); }
.day .cards h3 { color: #8a6a3c; }
.day .cards p { color: #453a2c; }
.day .cards strong { color: #6b4f26; }

/* ═══ details ════════════════════════════════════════════════════════════ */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
  gap: 1px;
  margin-top: 2rem;
  background: rgba(210, 174, 122, .18);
  border: 1px solid rgba(210, 174, 122, .18);
}
.cards article { padding: clamp(1.5rem, 4vw, 2.25rem); background: var(--night-900); }
.cards h3 {
  margin: 0 0 .7rem;
  font-size: .76rem; font-weight: 500;
  letter-spacing: .3em; text-transform: uppercase; text-indent: .3em;
  color: var(--gold);
}
.cards p { margin: 0; color: var(--paper-dim); line-height: 1.8; }
.cards strong { color: var(--gold-lit); font-weight: 400; font-variant-numeric: tabular-nums; }

/* ═══ footer ═════════════════════════════════════════════════════════════ */
/* Dawn: cream ranges rising out of the night, into the day section below. The
   near range must match that section's first colour exactly, since it is what
   the silhouette fills with. */
.ridgeline-dawn {
  --ridge-far: #f0e5d4;
  --ridge-near: #e9dfd0;
  height: clamp(70px, 10vw, 150px);
}

/* And back into shadow. The sky behind these ranges is the day section they
   rise out of, so this strip carries that colour rather than the page's night. */
.ridgeline-footer {
  --ridge-far: #0a1522;
  --ridge-near: #02070d;
  background: #dccbb2;
  transform: scaleX(-1);
  height: clamp(80px, 11vw, 170px);
}

.footer {
  position: relative;
  padding: clamp(2rem, 5vh, 3.5rem) 1.25rem clamp(3rem, 7vh, 5rem);
  text-align: center;
  background: #02070d;
}
.seal { width: clamp(76px, 13vw, 108px); margin: 0 auto 1.6rem; opacity: .95; }
.vow {
  margin: 0 0 .8rem;
  font-size: clamp(1.05rem, 2.6vw, 1.35rem);
  font-style: italic;
  color: var(--paper-dim);
}
.who {
  margin: 0;
  font-size: .74rem;
  letter-spacing: .28em; text-transform: uppercase; text-indent: .28em;
  color: var(--bronze);
}

/* ═══ drift ══════════════════════════════════════════════════════════════
   Applied to the inner <img> so it composes with the parallax translate on the
   wrapper instead of fighting it. */
@keyframes cloudDrift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(4%, -2%, 0) scale(1.04); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}
.drift      { animation: cloudDrift 90s ease-in-out infinite; }
.drift-slow { animation: cloudDrift 145s ease-in-out infinite reverse; }

/* ═══ reveal on scroll ═══════════════════════════════════════════════════ */
.reveal { opacity: 0; transform: translateY(22px); transition: opacity 1s var(--ease), transform 1s var(--ease); }
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .starfield { animation: none; }
  .reveal { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after { transition-duration: .01ms !important; }
}
