/* ═══════════════════════════════════════════════════════════
   Pushp Mahal · vowstory Shubharambh

   ⚠️ REBUILT on 11 September 2026 from the co-founder's redesign.
   The tokens, the typography and every section's treatment are his;
   what this repository adds is the config pipeline, and in this file
   that is only the small block at the very bottom marked
   "config-driven states". Everything above it is the design.

   ⚠️ Two things were corrected on the way in and are marked ⚠️ where
   they occur: the margin borders (fetched by phones that never show
   them) and the dress-code grid (a track held open for a cell that is
   not there). Both are in decision 0047.

   Utsav's designs keep their original stylesheet and take the redesign
   as a three-way merge; this tier's redesigns replace the sheet
   outright, because the pipeline's share of it is three rules.
   ═══════════════════════════════════════════════════════════ */

/* ⚠️ SELF-HOSTED FONTS. The Google Fonts <link> came out of index.html with
   this redesign — an invitation is opened by a guest who never agreed to
   anything, and that stylesheet made their browser announce itself to a third
   party before the first paint. 112 KB of woff2 we serve ourselves instead.
   ⚠️ Every family named anywhere below must have a rule here. A family with
   no @font-face falls back to a system serif silently: the page looks
   slightly wrong rather than broken, which is how it survives review. */
/* ── self-hosted fonts ── */
@font-face {
  font-family: "Gilda Display";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/gilda-display-latin-400-normal.woff2) format("woff2");
}
@font-face {
  font-family: "Parisienne";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/parisienne-latin-400-normal.woff2) format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/cormorant-garamond-latin-400-normal.woff2) format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(assets/fonts/cormorant-garamond-latin-500-normal.woff2) format("woff2");
}
@font-face {
  font-family: "Cormorant Garamond";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(assets/fonts/cormorant-garamond-latin-500-italic.woff2) format("woff2");
}

:root {
  --paper: #fbf5ea;
  --shell: #f1e3d0;
  --blush: #ecdcc5;
  --rose: #b06a54;
  --rose-deep: #8a3e3c;
  --gold: #b4882f;
  --gold-deep: #8e6a24;
  --leaf: #6e8560;
  --leaf-deep: #4e5f44;
  --ink: #4a3a31;
  --ink-soft: #8a7360;
  --col: 480px;
  --pad: 26px;
  --gap: 76px;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --disp: "Gilda Display", Georgia, serif;
  --script: "Parisienne", cursive;
  --body: "Cormorant Garamond", Georgia, serif;
}
* {
  box-sizing: border-box;
}
html {
  -webkit-text-size-adjust: 100%;
}
body {
  margin: 0;
  background: var(--shell);
  color: var(--ink);
  font-family: var(--body);
  font-size: 18px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}
img {
  max-width: 100%;
  display: block;
}
sup {
  font-size: 0.58em;
  vertical-align: 0.5em;
}
body:not(.open) {
  overflow: hidden;
  height: 100%;
}

#page {
  max-width: var(--col);
  margin: 0 auto;
  background: var(--paper);
  overflow: clip;
  box-shadow: 0 0 80px rgba(138, 62, 60, 0.15);
  opacity: 0;
  transition: opacity 0.9s var(--ease);
  position: relative;
  z-index: 2;
}
body.open #page {
  opacity: 1;
}

/* ⚠️ Printed margin borders, shown only from 1180px up. These arrived as two
   <img> tags with display:none below that width. Every browser fetches a
   display:none image, so every phone — which never shows them — paid for
   1.4 MB. They are CSS background-images declared INSIDE the media query
   instead, which is fetched only when the query matches.
   The geometry is unchanged: height:100vh with background-size contain in a
   23vw box resolves to the same painted box as width:auto on an <img> did. */
.edge {
  display: none;
  position: fixed;
  top: 0;
  height: 100vh;
  width: 23vw;
  max-width: 23vw;
  opacity: 0.94;
  pointer-events: none;
  z-index: 1;
  background-repeat: no-repeat;
  background-size: contain;
}
.edge-l {
  left: 0;
  background-position: left center;
}
.edge-r {
  right: 0;
  background-position: right center;
}
@media (min-width: 1180px) {
  .edge {
    display: block;
  }
  .edge-l {
    background-image: url(assets/elements/border-l.webp);
  }
  .edge-r {
    background-image: url(assets/elements/border-r.webp);
  }
}

/* ── cover ── */
#cover {
  position: fixed;
  inset: 0;
  z-index: 90;
  max-width: var(--col);
  margin: 0 auto;
  background: radial-gradient(120% 90% at 50% 32%, var(--blush), #e3cfb4);
  overflow: hidden;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  isolation: isolate;
}
.door {
  position: absolute;
  top: 0;
  height: 100%;
  width: 50.4%;
  background: radial-gradient(140% 120% at 50% 30%, var(--blush), #e3cfb4);
  transition: transform 1.35s var(--ease);
  will-change: transform;
}
.door-l {
  left: 0;
}
.door-r {
  right: 0;
}
.door .panel {
  position: absolute;
  inset: 30px 0;
  border-top: 1px solid rgba(180, 136, 47, 0.5);
  border-bottom: 1px solid rgba(180, 136, 47, 0.5);
}
.door-l .panel {
  left: 30px;
  right: 0;
  border-left: 1px solid rgba(180, 136, 47, 0.5);
}
.door-r .panel {
  right: 30px;
  left: 0;
  border-right: 1px solid rgba(180, 136, 47, 0.5);
}
.seam {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1px;
  background: linear-gradient(
    180deg,
    transparent,
    rgba(180, 136, 47, 0.5) 14%,
    rgba(180, 136, 47, 0.5) 86%,
    transparent
  );
  transform: translateX(-50%);
  transition: opacity 0.5s ease;
}
body.opening .door-l {
  transform: translateX(-101%);
}
body.opening .door-r {
  transform: translateX(101%);
}
body.opening .seam,
body.opening .cover-inner {
  opacity: 0;
}
body.opened #cover {
  display: none;
}
.cover-inner {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  transition: opacity 0.45s ease;
  padding: 20px;
}
.cover-frame {
  position: absolute;
  inset: 16px;
  border: 1px solid rgba(180, 136, 47, 0.7);
  box-shadow:
    inset 0 0 0 5px rgba(236, 220, 197, 0.5),
    inset 0 0 0 6px rgba(180, 136, 47, 0.4);
  z-index: 0;
}
.cover-frame::before,
.cover-frame::after {
  content: "";
  position: absolute;
  left: 50%;
  width: 9px;
  height: 9px;
  background: var(--gold);
  transform: translateX(-50%) rotate(45deg);
}
.cover-frame::before {
  top: -5px;
}
.cover-frame::after {
  bottom: -5px;
}
.tap-open {
  position: relative;
  z-index: 1;
  font-family: var(--disp);
  font-size: clamp(28px, 8vw, 40px);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  background: linear-gradient(
    100deg,
    #8a3e3c 0%,
    #b4882f 30%,
    #ebd9a6 48%,
    #dbc488 56%,
    #8e6a24 74%,
    #8a3e3c 100%
  );
  background-size: 230% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  filter: drop-shadow(0 2px 7px rgba(138, 62, 60, 0.18));
  animation:
    shine 3.2s linear infinite,
    tapbob 2.1s var(--ease) infinite;
}
.tap-hint {
  position: relative;
  z-index: 1;
  color: var(--gold-deep);
  animation: tapbob 2.1s var(--ease) infinite;
  animation-delay: 0.12s;
}
.tap-hint svg {
  width: 24px;
  height: 24px;
  display: block;
}
@keyframes shine {
  to {
    background-position: 230% 0;
  }
}
@keyframes tapbob {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-9px);
  }
}

/* ── music ── */
.music {
  position: fixed;
  top: 16px;
  z-index: 80;
  right: max(16px, calc(50vw - var(--col) / 2 + 16px));
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: rgba(251, 245, 234, 0.9);
  border: 1px solid rgba(180, 136, 47, 0.5);
  backdrop-filter: blur(6px);
  display: none;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  color: var(--rose);
  transition: transform 0.25s var(--ease);
}
body.open .music {
  display: flex;
  animation: fadein 0.8s 0.5s backwards;
}
.music:hover {
  transform: scale(1.07);
}
.music svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
  stroke: currentColor;
}
.music .ic-off {
  display: none;
}
.music[aria-pressed="false"] .ic-on {
  display: none;
}
.music[aria-pressed="false"] .ic-off {
  display: block;
}
@keyframes fadein {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* ── hero ── */
.hero {
  position: relative;
}
.hero-art {
  position: relative;
  min-height: 100svh;
  background: url(assets/hero.webp) center top/cover no-repeat;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 64px 38px 140px;
}
.hero-art::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse 78% 40% at 50% 43%,
      rgba(251, 245, 234, 0.46) 0%,
      rgba(251, 245, 234, 0.24) 55%,
      rgba(251, 245, 234, 0) 78%
    ),
    linear-gradient(
      180deg,
      rgba(251, 245, 234, 0) 58%,
      rgba(251, 245, 234, 0.42) 82%,
      rgba(251, 245, 234, 0) 97%
    );
}
.hero-body {
  position: relative;
  text-align: center;
  width: 100%;
  max-width: 520px;
}
.ganesh {
  width: clamp(104px, 28%, 152px);
  margin: 0 auto 4px;
  filter: drop-shadow(0 6px 16px rgba(138, 62, 60, 0.12));
}
.invocation {
  margin: 0 0 16px;
  font-size: 14px;
  letter-spacing: 0.06em;
  color: var(--gold-deep);
}
.hero-eyebrow {
  margin: 0 0 12px;
  font-family: var(--disp);
  font-size: 11px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--leaf-deep);
}
.hero-names {
  margin: 0;
  font-family: var(--disp);
  font-weight: 400;
  font-size: clamp(46px, 13vw, 84px);
  line-height: 1.04;
  letter-spacing: 0.01em;
}
.hero-names span {
  display: block;
  background: linear-gradient(
    96deg,
    var(--rose-deep) 24%,
    var(--gold) 50%,
    var(--rose-deep) 76%
  );
  background-size: 230% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
  animation: shine 6.5s linear infinite;
}
.hero-names em {
  display: block;
  font-family: var(--script);
  font-style: normal;
  font-size: 0.66em;
  color: var(--gold);
  margin: -4px 0;
  line-height: 1;
}
.rule {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: min(200px, 58%);
  margin: 18px auto 18px;
}
.rule i {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(180, 136, 47, 0.85));
}
.rule i:last-child {
  background: linear-gradient(90deg, rgba(180, 136, 47, 0.85), transparent);
}
.rule b {
  width: 7px;
  height: 7px;
  transform: rotate(45deg);
  background: var(--gold);
  flex: none;
}
.hero-date {
  margin: 0 0 12px;
  font-family: var(--disp);
  font-size: clamp(14.5px, 3.5vw, 19px);
  letter-spacing: 0.16em;
  color: var(--rose);
  text-transform: uppercase;
}
.hero-venue {
  margin: 0;
  font-size: clamp(16px, 3.4vw, 20px);
  font-style: italic;
  color: var(--ink-soft);
  line-height: 1.5;
}
.hero-venue span {
  display: inline-block;
  font-style: normal;
  font-size: 0.82em;
  letter-spacing: 0.07em;
  color: var(--ink-soft);
  margin-top: 2px;
}

body.open .hero-body > * {
  animation: heroIn 1.1s var(--ease) backwards;
}
body.open .hero-body > *:nth-child(1) {
  animation-delay: 0.45s;
}
body.open .hero-body > *:nth-child(2) {
  animation-delay: 0.57s;
}
body.open .hero-body > *:nth-child(3) {
  animation-delay: 0.69s;
}
body.open .hero-body > *:nth-child(4) {
  animation-delay: 0.81s;
}
body.open .hero-body > *:nth-child(5) {
  animation-delay: 0.93s;
}
body.open .hero-body > *:nth-child(6) {
  animation-delay: 1.05s;
}
body.open .hero-body > *:nth-child(7) {
  animation-delay: 1.17s;
}
@keyframes heroIn {
  from {
    opacity: 0;
    transform: translateY(24px);
    filter: blur(6px);
  }
  to {
    opacity: 1;
    transform: none;
    filter: none;
  }
}
.scroll-cue {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 24px;
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  transition:
    opacity 0.5s ease,
    transform 0.5s ease;
  pointer-events: none;
}
.cue-word {
  font-family: var(--disp);
  font-size: 11px;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--rose-deep);
}
.cue-chev {
  color: var(--rose-deep);
  animation: bob 1.6s ease-in-out infinite;
}
.cue-chev svg {
  width: 30px;
  height: 30px;
  display: block;
  filter: drop-shadow(0 2px 5px rgba(251, 245, 234, 0.95));
}
@keyframes bob {
  0%,
  100% {
    transform: translateY(0);
    opacity: 0.55;
  }
  50% {
    transform: translateY(7px);
    opacity: 1;
  }
}
.scroll-cue.gone {
  opacity: 0;
  transform: translateY(10px);
}

/* ── shared ── */
.sec {
  padding: var(--gap) var(--pad);
  position: relative;
  text-align: center;
  overflow: clip;
  isolation: isolate;
  background: var(--paper);
}
.eyebrow {
  margin: 0 0 12px;
  font-family: var(--disp);
  font-size: 11px;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.h2 {
  margin: 0 0 20px;
  font-family: var(--disp);
  font-weight: 400;
  font-size: clamp(29px, 6.8vw, 46px);
  line-height: 1.2;
  color: var(--rose-deep);
}
.h2-sm {
  font-size: clamp(26px, 5.8vw, 38px);
}
.prose {
  margin: 0 auto 16px;
  max-width: 36ch;
  color: var(--ink);
}
.tag {
  margin: 26px 0 0;
  font-family: var(--disp);
  font-size: clamp(13px, 2.6vw, 16px);
  letter-spacing: 0.2em;
  color: var(--rose);
}
.tag-sm {
  font-size: 12px;
  letter-spacing: 0.26em;
  margin-top: 14px;
}
.rule-sm {
  width: min(150px, 56%);
  margin: 12px auto 12px;
}

.reveal {
  opacity: 0;
  transform: translateY(32px) scale(0.987);
  filter: blur(6px);
  transition:
    opacity 1.05s var(--ease),
    transform 1.05s var(--ease),
    filter 1.05s var(--ease);
}
.reveal.in {
  opacity: 1;
  transform: none;
  filter: none;
}

.deco {
  position: absolute;
  pointer-events: none;
  z-index: 0;
}

/* ── plates ── */
.plate {
  position: relative;
  isolation: isolate;
}
.plate-invite {
  background: url(assets/plate-lake.webp) center top/cover no-repeat;
}
/* ⚠️ THE VEIL IS THE ONLY THING HOLDING THIS SECTION'S COPY ABOVE
   THRESHOLD, and these are not the stops the redesign shipped. Those peaked
   low and fell away fast — measured on the two family columns at 834px, where
   they sit at the outer edges of the plate and the veil has almost run out,
   the parents' line came back well under the 4.5:1 small text needs.
   ⚠️ Widening a veil is not the same as strengthening it: peak opacity is the
   limit, not extent. These stops were set by measurement and still reach zero
   at the edge so the painted border reads.
   ⚠️ Re-export the artwork and they have to be measured again. */
.plate::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    ellipse 106% 96% at 50% 48%,
    rgba(251, 245, 234, 0.95) 0%,
    rgba(251, 245, 234, 0.9) 44%,
    rgba(251, 245, 234, 0.7) 72%,
    rgba(251, 245, 234, 0.24) 88%,
    rgba(251, 245, 234, 0) 100%
  );
}
.plate-body {
  position: relative;
  padding: var(--gap) var(--pad);
  text-align: center;
  min-height: clamp(440px, 72vw, 600px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.eyebrow-on-plate {
  color: var(--rose);
}

/* seal (couple logo in gold ring) */
.seal-wrap {
  position: relative;
  width: min(150px, 40%);
  margin: 0 auto 22px;
  aspect-ratio: 1;
}
.seal-wrap::before {
  content: "";
  position: absolute;
  inset: -24px;
  border-radius: 50%;
  background: radial-gradient(
    circle,
    rgba(251, 245, 234, 0.92) 55%,
    rgba(251, 245, 234, 0) 74%
  );
  z-index: 0;
}
.seal-ring {
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  border: 1px solid rgba(180, 136, 47, 0.6);
  box-shadow:
    0 0 0 5px var(--paper),
    0 0 0 6px rgba(180, 136, 47, 0.3);
  z-index: 1;
}
.seal {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 10px 24px rgba(138, 62, 60, 0.16);
}

.sec-count {
  background: var(--paper);
}
.deco-gazebo-c {
  width: min(260px, 64%);
  left: 50%;
  transform: translateX(-50%);
  top: -6px;
  opacity: 0.14;
}
.clock {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  max-width: 400px;
  margin: 26px auto 0;
  width: 100%;
}
.unit {
  padding: 18px 4px 14px;
  background: rgba(251, 245, 234, 0.82);
  border: 1px solid rgba(180, 136, 47, 0.4);
  backdrop-filter: blur(2px);
}
.unit b {
  display: block;
  font-family: var(--disp);
  font-weight: 400;
  font-size: clamp(23px, 6vw, 34px);
  color: var(--rose-deep);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.unit i {
  display: block;
  margin-top: 8px;
  font-style: normal;
  font-size: 9.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* ── union block ── */
.weds {
  margin: 34px auto 0;
  max-width: 560px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-family: var(--disp);
  font-size: clamp(21px, 4.8vw, 30px);
  line-height: 1.25;
  color: var(--rose-deep);
  text-align: center;
}
.weds em {
  font-family: var(--disp);
  font-style: normal;
  font-size: 0.42em;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--gold-deep);
  display: flex;
  align-items: center;
  gap: 12px;
  text-indent: 0.34em;
}
.weds em::before,
.weds em::after {
  content: "";
  width: 32px;
  height: 1px;
  background: rgba(180, 136, 47, 0.55);
}
.side {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
.side-name {
  margin: 0 0 9px;
  line-height: 1.2;
}
.side-role {
  margin: 0 0 6px;
  font-family: var(--disp);
  font-size: 10px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.side-parents {
  margin: 0;
  font-family: var(--body);
  font-size: 16px;
  font-weight: 400;
  line-height: 1.55;
  color: var(--ink);
  max-width: 26ch;
}
@media (min-width: 600px) {
  .weds {
    flex-direction: row;
    justify-content: center;
    gap: clamp(20px, 4vw, 38px);
    align-items: flex-start;
  }
  .side {
    flex: 1;
    max-width: 300px;
  }
  .weds em {
    margin-top: 12px;
    flex: none;
  }
}

/* ── events ── */
.sec-head {
  padding-bottom: 26px;
}
.event {
  background: var(--paper);
  isolation: isolate;
}
.event-art {
  aspect-ratio: 1/1;
  background-size: cover;
  background-position: center 28%;
}
.event-title {
  margin: 18px 0 0;
  font-family: var(--disp);
  font-weight: 400;
  font-size: clamp(32px, 8vw, 54px);
  color: var(--rose-deep);
  line-height: 1;
}
.event-when {
  margin: 0 0 3px;
  font-family: var(--disp);
  font-size: clamp(13px, 3vw, 17px);
  letter-spacing: 0.11em;
  color: var(--rose);
  text-transform: uppercase;
}
.event-time {
  margin: 0 0 14px;
  font-style: italic;
  color: var(--ink-soft);
}
.event-foot {
  padding: 8px var(--pad) 46px;
  text-align: center;
  background: var(--paper);
}
.event-venue {
  margin: 0 0 16px;
  line-height: 1.5;
}
.event-venue span {
  font-size: 0.85em;
  color: var(--ink-soft);
}
/* Dress code and note, two labelled cells under an event. New with the
   redesign; there was one italic line before it.
   ⚠️ The columns are generated per cell, NOT declared as `1fr 1fr` as they
   arrived. Most couples fill in one of the two, and a declared pair of tracks
   stays open whether or not anything is in it — the lone cell would sit at
   half width beside a hole. `grid-auto-flow: column` with
   `grid-auto-columns: 1fr` makes one track per cell that exists. */
.card-meta {
  margin: 0 auto 20px;
  max-width: 420px;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 10px;
}
.card-meta > div {
  background: var(--shell);
  border: 1px solid rgba(180, 136, 47, 0.32);
  padding: 8px 12px;
  min-width: 0;
}
.card-meta dt {
  font-family: var(--disp);
  font-size: 9px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.card-meta dd {
  margin: 3px 0 0;
  font-size: 14px;
  color: var(--ink);
}
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  border: 1px solid rgba(180, 136, 47, 0.65);
  font-family: var(--disp);
  font-size: 11.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--rose-deep);
  text-decoration: none;
  background: var(--paper);
  transition:
    background 0.3s ease,
    color 0.3s ease,
    border-color 0.3s ease;
}
.btn:hover {
  background: var(--rose-deep);
  color: var(--paper);
  border-color: var(--rose-deep);
}
.btn svg {
  width: 15px;
  height: 15px;
  stroke: currentColor;
  fill: none;
}

/* ── gallery ── */
.sec-gallery {
  background: var(--shell);
}
.deco-lanterns {
  width: clamp(60px, 16vw, 104px);
  top: -10px;
  right: 6px;
  opacity: 0.9;
}
.frame-wrap {
  position: relative;
  width: min(430px, 94%);
  margin: 28px auto 0;
  aspect-ratio: 1;
}
.photo-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 3;
  filter: drop-shadow(0 12px 26px rgba(138, 62, 60, 0.14));
}
.slides {
  position: absolute;
  inset: 6.4% 6% 8% 6%;
  overflow: hidden;
  z-index: 1;
  background: var(--paper);
  border-radius: 6px;
}
.slide-track {
  display: flex;
  height: 100%;
  transition: transform 0.6s var(--ease);
}
.slide {
  margin: 0;
  flex: 0 0 100%;
  height: 100%;
  position: relative;
}
.slide img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ph {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--disp);
  font-size: 9.5px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold-deep);
  border: 1px solid rgba(180, 136, 47, 0.45);
  padding: 4px 12px;
  background: rgba(251, 245, 234, 0.9);
  white-space: nowrap;
  z-index: 2;
}
.nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  background: rgba(251, 245, 234, 0.92);
  border: 1px solid rgba(180, 136, 47, 0.45);
  color: var(--rose);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 4;
}
.nav svg {
  width: 15px;
  height: 15px;
  stroke: currentColor;
  fill: none;
}
.prev {
  left: calc(6% - 17px);
}
.next {
  right: calc(6% - 17px);
}
.dots {
  display: flex;
  justify-content: center;
  gap: 7px;
  margin-top: 20px;
}
.dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  background: transparent;
  border: 1px solid var(--gold);
  transition: background 0.3s ease;
}
.dot[aria-current="true"] {
  background: var(--gold);
}

/* ── venue ── */
.sec-venue {
  background: var(--paper);
}
.deco-gazebo {
  width: min(230px, 58%);
  left: 50%;
  transform: translateX(-50%);
  top: -4px;
  opacity: 0.16;
}
.venue-name {
  margin: 0 0 6px;
  font-family: var(--disp);
  font-size: clamp(17px, 3.6vw, 21px);
  color: var(--rose-deep);
}
.venue-addr {
  margin: 0 0 24px;
  color: var(--ink-soft);
}
.mapcard {
  display: flex;
  align-items: center;
  gap: 16px;
  text-decoration: none;
  color: var(--ink);
  padding: 18px 20px;
  background: var(--shell);
  border: 1px solid rgba(180, 136, 47, 0.45);
  max-width: 520px;
  margin: 6px auto 0;
  text-align: left;
  transition:
    border-color 0.3s ease,
    transform 0.3s var(--ease);
}
.mapcard:hover {
  border-color: var(--gold);
  transform: translateY(-2px);
}
.mapcard-pin,
.mapcard-go {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gold-deep);
}
.mapcard-pin svg {
  width: 26px;
  height: 26px;
  stroke: currentColor;
  fill: none;
}
.mapcard-go svg {
  width: 17px;
  height: 17px;
  stroke: currentColor;
  fill: none;
}
.mapcard-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  font-family: var(--body);
  font-size: 14px;
  color: var(--ink-soft);
  line-height: 1.5;
}
.mapcard-text b {
  font-family: var(--disp);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--rose-deep);
  margin-bottom: 3px;
}
.route {
  margin: 30px auto 2px;
  width: min(330px, 86%);
}
.route-svg {
  width: 100%;
  height: auto;
  display: block;
  overflow: visible;
}

/* ── rsvp (paper, distinct) ── */
.sec-rsvp {
  background: var(--shell);
}
.urli {
  width: clamp(96px, 24vw, 132px);
  margin: 6px auto 10px;
  opacity: 0.96;
  filter: drop-shadow(0 8px 18px rgba(138, 62, 60, 0.1));
}
.rsvp {
  display: grid;
  gap: 12px;
  margin-top: 18px;
  max-width: 520px;
  margin-inline: auto;
  width: 100%;
}
.chip {
  display: flex;
  align-items: center;
  gap: 14px;
  text-align: left;
  padding: 14px 20px;
  background: rgba(251, 245, 234, 0.92);
  border: 1px solid rgba(180, 136, 47, 0.4);
  text-decoration: none;
  color: var(--ink);
  transition:
    border-color 0.3s ease,
    transform 0.3s var(--ease);
}
.chip:hover {
  border-color: var(--rose);
  transform: translateY(-2px);
}
.chip svg {
  width: 23px;
  height: 23px;
  flex: none;
  stroke: var(--leaf);
  fill: var(--leaf);
}
.chip span {
  display: flex;
  flex-direction: column;
  font-size: 0.85em;
  color: var(--ink-soft);
}
.chip b {
  font-family: var(--disp);
  font-weight: 400;
  font-size: 1.15em;
  color: var(--rose-deep);
}

/* ── footer ── */
.foot {
  background: var(--paper);
  padding: calc(var(--gap) + 10px) var(--pad) 32px;
  text-align: center;
  position: relative;
  overflow: clip;
  isolation: isolate;
}
.foot-bg {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: min(760px, 150%);
  max-width: none;
  opacity: 0.16;
  pointer-events: none;
  z-index: 0;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 52%);
  mask-image: linear-gradient(180deg, transparent 0, #000 52%);
}
.foot > *:not(.foot-bg) {
  position: relative;
  z-index: 1;
}
.foot-orn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: min(216px, 58%);
  margin: 0 auto 22px;
}
.foot-orn i {
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(180, 136, 47, 0.85));
}
.foot-orn i:last-child {
  background: linear-gradient(90deg, rgba(180, 136, 47, 0.85), transparent);
}
.foot-orn b {
  width: 7px;
  height: 7px;
  transform: rotate(45deg);
  background: var(--gold);
  flex: none;
}
.foot-line {
  margin: 0 0 6px;
  font-style: italic;
  color: var(--ink-soft);
}
.foot-names {
  margin: 0;
  font-family: var(--disp);
  font-size: clamp(34px, 7.4vw, 48px);
  color: var(--rose-deep);
}
.ig {
  display: flex;
  width: max-content;
  align-items: center;
  gap: 8px;
  margin: 20px auto 0;
  text-decoration: none;
  color: var(--ink-soft);
  font-size: 0.85em;
  letter-spacing: 0.04em;
  transition: color 0.3s ease;
}
.ig:hover {
  color: var(--rose);
}
.ig svg {
  width: 19px;
  height: 19px;
  stroke: currentColor;
  fill: currentColor;
}
.made {
  display: flex;
  width: max-content;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin: 38px auto 0;
  text-decoration: none;
  opacity: 0.9;
  transition: opacity 0.3s ease;
}
.made:hover {
  opacity: 1;
}
.made span {
  font-family: var(--disp);
  font-size: 10px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.made img {
  width: 100px;
}

/* ── scale up ── */
@media (min-width: 600px) {
  :root {
    --col: 620px;
    --pad: 46px;
    --gap: 92px;
  }
  body {
    font-size: 19px;
  }
  .hero-art {
    padding: 88px 58px 130px;
  }
  .event-art {
    aspect-ratio: 5/4;
  }
}
@media (min-width: 960px) {
  :root {
    --col: 800px;
    --pad: 66px;
    --gap: 108px;
  }
  body {
    font-size: 20px;
  }
  .music {
    width: 46px;
    height: 46px;
    top: 22px;
  }
  .event-art {
    aspect-ratio: 4/3;
    background-position: center 28%;
  }
  .hero-art {
    background-position: center 24%;
  }
}
@media (min-width: 1400px) {
  :root {
    --col: 880px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .reveal {
    opacity: 1;
    transform: none;
    filter: none;
  }
  .hero-names span,
  .tap-open {
    -webkit-text-fill-color: initial;
    color: var(--rose-deep);
  }
  .tap-open {
    color: var(--gold-deep);
  }
}
:focus-visible {
  outline: 2px solid var(--rose);
  outline-offset: 3px;
}

/* ── hosted by ── */
.hosted {
  margin: 32px auto 0;
  text-align: center;
  max-width: 440px;
}
.hosted-rule {
  display: block;
  width: 46px;
  height: 1px;
  margin: 0 auto 14px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
.hosted-label {
  margin: 0 0 6px;
  font-family: var(--disp);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold-deep);
}
.hosted-names {
  margin: 0;
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink);
}

/* ══ config-driven states ══════════════════════════════════════════════════
   Everything below this line belongs to the repository's rendering pipeline,
   not to the design. It is what has to be re-applied whenever a redesign
   replaces this sheet. */

/* Slots the config left empty are hidden with [hidden]; several of them are
   flex or grid, so the attribute needs to win over the class. */
[hidden] {
  display: none !important;
}

/* Blessings with no artwork of their own fall back to their glyph, set at the
   same weight as the Ganesha crop it replaces.
   ⚠️ Since 11 September 2026 (decision 0048) every blessing in the catalogue
   ships its own drawing, so the config sends `symbol: null` and NOTHING lands
   here any more. The rule stays as the fallback for a blessing added later
   with no artwork drawn for it yet — without it that one would print at the
   browser's default size in a system serif. */
.glyph {
  margin: 0 0 8px;
  font-family: var(--disp);
  font-size: clamp(40px, 10vw, 58px);
  line-height: 1;
  color: var(--gold-deep);
}

/* The reply chip's second line is an <i> because the blueprint has two text
   slots and only one of them is ever a name. */
.chip i {
  font-style: normal;
}
