/* ══ Invitation templates ═══════════════════════════════════════════════
   The page's own layer. The nav and footer come from the rest of the site
   (styles.css + articles.css) and are not touched here; everything between
   them belongs to this file and is scoped under .tp so it cannot leak into
   the chrome above it. ─────────────────────────────────────────────────── */
.tp {
  --ink: #1A1339; --muted: #666A8C; --iris: #6B3BF2; --iris-deep: #4517C0;
  --paper: #FBFBFE; --line: rgba(26,19,57,.10); --night: #0E0A24;
  background: var(--paper); color: var(--ink);
  font-family: 'Montserrat', system-ui, sans-serif;
  position: relative; overflow-x: clip;
}
/* The preview is a sibling of <main class="tp">, not a child of it -- it
   has to be, so a fixed overlay is not sized by the page's own box. So it
   is named here too: without it every icon in the preview rendered as the
   ligature's own name, and the close button said "close". */
.tp .ms, .tp-modal .ms {
  font-family: 'Material Symbols Rounded'; font-weight: normal; font-style: normal;
  line-height: 1; letter-spacing: normal; text-transform: none; white-space: nowrap;
  font-feature-settings: 'liga'; user-select: none; font-size: 20px;
}
.tp-wrap { max-width: 1240px; margin: 0 auto; padding-inline: clamp(16px,4vw,32px); }
/* styles.css sets `color` on h1-h4 directly, so a heading never inherits the
   colour of the section it is in. On the dark RSVP band that put ink on
   near-black and the headline simply vanished; on the gradient panel it did
   the same. `inherit` hands every heading back to its section. */
.tp h1, .tp h2 { font-family: 'Instrument Serif', Georgia, serif; font-weight: 400; margin: 0;
  color: inherit; }
.tp em { font-style: italic; }
.tp-grad {
  background: linear-gradient(120deg,#A22FE2 0%,#6B3BF2 48%,#1F6BEC 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* A line that is revealed by sliding up out of its own clipped box. */
.tp-mask { display: block; overflow: hidden; padding-bottom: .12em; margin-bottom: -.12em; }
.tp-mask > span { display: block; }

/* ── Hero ────────────────────────────────────────────────────────────── */
.tp-hero { position: relative; overflow: hidden; padding-top: 86px; }
.tp-aur { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.tp-aur i { position: absolute; border-radius: 50%; display: block; will-change: transform; }
.tp-aur i:nth-child(1) { width: 640px; height: 640px; right: -160px; top: -200px; opacity: .95;
  background: radial-gradient(closest-side,#DCCFFF,rgba(220,207,255,0)); }
.tp-aur i:nth-child(2) { width: 520px; height: 520px; right: 24%; bottom: -260px; opacity: .9;
  background: radial-gradient(closest-side,#CFE0FF,rgba(207,224,255,0)); }
.tp-aur i:nth-child(3) { width: 460px; height: 460px; left: -180px; top: 80px; opacity: .85;
  background: radial-gradient(closest-side,#F6DDF6,rgba(246,221,246,0)); }
.tp-aur i:nth-child(4) { width: 380px; height: 380px; right: 12%; top: 38%;
  background: radial-gradient(closest-side,rgba(255,226,200,.75),rgba(255,226,200,0)); }
/* A film of noise over the washes, so the gradients read as paper, not as CSS. */
.tp-grain { position: absolute; inset: 0; opacity: .07; mix-blend-mode: multiply; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }

.tp-hero-in { position: relative; display: grid;
  grid-template-columns: repeat(auto-fit,minmax(min(440px,100%),1fr));
  gap: clamp(32px,5vw,64px); align-items: center;
  padding-block: clamp(32px,6vw,80px) clamp(48px,7vw,96px); }
.tp-hero-copy { display: flex; flex-direction: column; gap: 22px; align-items: flex-start; }
.tp-badge { display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px 7px 8px;
  border-radius: 999px; background: #fff; border: 1px solid var(--line);
  font-size: 13px; font-weight: 600; color: var(--iris-deep); }
.tp-badge b { padding: 3px 9px; border-radius: 999px; background: #F2EEFE; font-size: 11px;
  letter-spacing: .08em; text-transform: uppercase; font-weight: 700; }
.tp-hero h1 { font-size: clamp(44px,7.4vw,96px); line-height: .98; letter-spacing: -.02em; }
.tp-line1 { display: flex; flex-wrap: wrap; column-gap: .22em; }
.tp-w { display: inline-block; overflow: hidden; padding: 0 .04em .14em 0; margin-bottom: -.14em; }
.tp-w > span { display: inline-block; transform-origin: 0 100%; }
.tp-l2 { position: relative; display: inline-block; font-style: italic; padding: 0 .08em .06em 0; }
/* The light that travels across the gradient line once it has landed. */
.tp-sweep { position: absolute; inset: 0; padding: 0 .08em .06em 0; color: transparent; opacity: 0;
  pointer-events: none; background-size: 260% 100%; background-position: 100% 0;
  background-image: linear-gradient(100deg,rgba(255,255,255,0) 40%,rgba(255,255,255,.9) 50%,rgba(255,255,255,0) 60%);
  -webkit-background-clip: text; background-clip: text; }
.tp-lede { margin: 0; max-width: 520px; font-size: 17px; line-height: 1.7; color: var(--muted); text-wrap: pretty; }
.tp-ctas { display: flex; gap: 12px; flex-wrap: wrap; }
.tp-btn { display: inline-flex; align-items: center; gap: 8px; padding: 15px 26px; border-radius: 999px;
  font-weight: 700; font-size: 15px; text-decoration: none; cursor: pointer; border: 0;
  font-family: inherit; line-height: 1;
  transition: box-shadow .4s cubic-bezier(0.16,1,0.3,1), background-color .25s, color .25s, border-color .3s, transform .2s; }
.tp-btn:active { transform: scale(.97); }
.tp-btn.solid { background: var(--iris); color: #fff; box-shadow: 0 14px 30px -12px rgba(107,59,242,.6); }
.tp-btn.solid:hover { background: #5A2BE6; color: #fff; box-shadow: 0 20px 40px -12px rgba(107,59,242,.75); }
.tp-btn.ghost { background: #fff; color: var(--ink); border: 1px solid rgba(26,19,57,.12); }
.tp-btn.ghost:hover { color: var(--iris); border-color: var(--iris); }
.tp-btn.white { background: #fff; color: var(--iris-deep); box-shadow: 0 16px 34px -14px rgba(14,10,36,.55); }
.tp-btn.white:hover { color: var(--ink); box-shadow: 0 24px 44px -14px rgba(14,10,36,.7); }
.tp-btn.tp-clear { border-color: var(--iris); color: var(--iris); }
.tp-bens { display: flex; gap: 22px; flex-wrap: wrap; font-size: 13px; color: var(--muted); font-weight: 500; }
.tp-bens span { display: flex; align-items: center; gap: 6px; }
.tp-bens .ms { font-size: 18px; color: var(--iris); }

/* The fanned stack: perspective on the stage, depth on each card. */
.tp-stage { position: relative; height: clamp(420px,46vw,580px); perspective: 1400px; }
.tp-scene { position: absolute; inset: 0; transform-style: preserve-3d; }
/* A fraction of the stage, so the spread between the cards and the cards
   themselves stay in proportion at every width. */
.tp-fan { position: absolute; left: 50%; top: 50%; width: min(38%,240px); transform-style: preserve-3d; }
.tp-fan .dep { will-change: transform; transform-style: preserve-3d; }
.tp-face { position: relative; border-radius: 6px; overflow: hidden;
  box-shadow: 0 2px 4px rgba(26,19,57,.08), 0 30px 60px -20px rgba(26,19,57,.45); }
.tp-face img { display: block; width: 100%; height: auto; }
.tp-spec { position: absolute; inset: 0; pointer-events: none; opacity: 0; mix-blend-mode: soft-light;
  background: radial-gradient(circle at var(--mx,50%) var(--my,30%),rgba(255,255,255,.42),rgba(255,255,255,0) 52%);
  transition: opacity .6s cubic-bezier(0.16,1,0.3,1); }

/* ── The collection ──────────────────────────────────────────────────── */
.tp-coll { padding-block: clamp(48px,8vw,104px) clamp(48px,6vw,80px); scroll-margin-top: 70px; }
.tp-coll-h { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px;
  flex-wrap: wrap; margin-bottom: 28px; }
.tp-coll-t { display: flex; flex-direction: column; gap: 10px; max-width: 620px; }
.tp-eyebrow { font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--iris); }
.tp-coll-h h2 { font-size: clamp(32px,5vw,60px); line-height: 1.02; letter-spacing: -.01em; }
.tp-search { display: flex; align-items: center; gap: 10px; padding: 0 16px; height: 48px; border-radius: 999px;
  background: #fff; border: 1px solid var(--line); min-width: min(280px,100%); box-sizing: border-box;
  flex: 0 1 320px; transition: border-color .3s, box-shadow .4s cubic-bezier(0.16,1,0.3,1); }
.tp-search:focus-within { border-color: var(--iris); box-shadow: 0 0 0 4px rgba(107,59,242,.14); }
.tp-search .ms { color: #8F92B0; transition: transform .45s cubic-bezier(0.16,1,0.3,1), color .3s; }
.tp-search:focus-within .ms { color: var(--iris); transform: scale(1.1) rotate(-8deg); }
.tp-search input { border: 0; outline: 0; background: transparent; font-size: 14px; color: var(--ink);
  flex: 1; min-width: 0; height: 100%; font-family: inherit; }
.tp-search input::-webkit-search-cancel-button { -webkit-appearance: none; }

.tp-filters { display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-bottom: 28px; padding-bottom: 20px; border-bottom: 1px solid var(--line); }
.tp-chips { position: relative; display: flex; gap: 8px; flex-wrap: wrap; }
/* One travelling pill behind the chips, rather than a background on each. */
.tp-chip-ind { position: absolute; left: 0; top: 0; width: 0; height: 0; border-radius: 999px;
  background: var(--ink); z-index: 0; pointer-events: none; box-shadow: 0 8px 20px -10px rgba(26,19,57,.6); }
.tp-chip { position: relative; z-index: 1; display: flex; align-items: center; gap: 8px; padding: 10px 16px;
  border-radius: 999px; border: 1px solid var(--line); background: #fff; color: var(--ink); font-family: inherit;
  font-size: 14px; font-weight: 600; cursor: pointer; min-height: 44px;
  transition: color .35s ease, border-color .35s ease, background-color .35s ease; }
.tp-chip small { font-size: 12px; font-weight: 600; opacity: .7; font-variant-numeric: tabular-nums; }
.tp-chip.on { color: #fff; border-color: transparent; background: transparent; }
.tp-toggle { display: flex; align-items: center; gap: 10px; padding: 8px 6px 8px 14px; border-radius: 999px;
  border: 0; background: transparent; font-family: inherit; font-size: 14px; font-weight: 600;
  color: var(--ink); cursor: pointer; min-height: 44px; }
.tp-toggle .ms { font-size: 19px; color: var(--iris); }
.tp-sw { width: 40px; height: 24px; border-radius: 12px; background: #DDD8EA; position: relative; display: block;
  transition: background-color .35s ease; }
.tp-sw::after { content: ''; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%;
  background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: transform .45s cubic-bezier(0.34,1.4,0.5,1); }
.tp-toggle.on .tp-sw { background: var(--iris); }
.tp-toggle.on .tp-sw::after { transform: translateX(16px); }

.tp-grid { display: grid; grid-template-columns: repeat(auto-fill,minmax(210px,1fr));
  gap: clamp(18px,2.4vw,32px) clamp(14px,2vw,26px); align-items: start; }
.tp-tile { display: flex; flex-direction: column; gap: 12px; padding: 0; border: 0; background: transparent;
  text-align: left; cursor: pointer; color: var(--ink); font-family: inherit; }
.tp-lift { display: block; position: relative; width: 100%; border-radius: 6px; overflow: hidden;
  box-shadow: 0 1px 2px rgba(26,19,57,.06), 0 14px 30px -16px rgba(26,19,57,.35);
  transition: transform .6s cubic-bezier(0.16,1,0.3,1), box-shadow .6s cubic-bezier(0.16,1,0.3,1); }
.tp-lift img { display: block; width: 100%; height: auto; background: #EFEDF6; }
.tp-tile:hover .tp-lift { transform: translateY(-6px) scale(1.012);
  box-shadow: 0 1px 2px rgba(26,19,57,.06), 0 30px 60px -20px rgba(26,19,57,.45); }
.tp-tile:hover .tp-spec { opacity: 1; }
.tp-tile:focus-visible { outline: 2px solid var(--iris); outline-offset: 4px; border-radius: 10px; }
.tp-tile-meta { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; padding: 0 2px; }
.tp-tile-meta b { font-size: 14px; font-weight: 700; line-height: 1.3; }
.tp-tile-meta span { font-size: 12px; font-weight: 500; color: var(--muted); white-space: nowrap; }
.tp-empty { padding: 64px 16px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.tp-empty b { font-family: 'Instrument Serif', Georgia, serif; font-size: 32px; font-weight: 400; }

/* ── How it works ────────────────────────────────────────────────────── */
.tp-how { background: var(--paper); scroll-margin-top: 70px; }
.tp-steps { display: grid; grid-template-columns: repeat(auto-fit,minmax(min(280px,100%),1fr));
  gap: clamp(24px,3vw,40px); padding-block: clamp(24px,4vw,48px) clamp(40px,6vw,72px); will-change: transform; }
.tp-step { position: relative; display: flex; flex-direction: column; gap: 12px; padding-top: 22px; }
.tp-step i.rule { position: absolute; left: 0; right: 0; top: 0; height: 2px; background: var(--ink);
  transform-origin: 0 50%; display: block; }
.tp-num-mask { display: block; overflow: hidden; }
.tp-step .n { display: block; font-family: 'Instrument Serif', Georgia, serif; font-size: 56px;
  line-height: 1; color: var(--iris); }
.tp-step b { font-size: 20px; font-weight: 700; }
.tp-step p { margin: 0; font-size: 15px; line-height: 1.65; color: var(--muted); text-wrap: pretty; }

/* ── The horizon into the night section ──────────────────────────────── */
.tp-horizon { position: relative; height: clamp(90px,13vw,190px); background: var(--paper);
  overflow-x: clip; overflow-y: visible; margin-bottom: -1px; }
.tp-horizon > i { position: absolute; left: -30%; right: -30%; top: 46%; height: 400%; border-radius: 50%;
  background: var(--night); transform-origin: 50% 0; will-change: transform; display: block;
  box-shadow: 0 -1px 0 rgba(162,47,226,.55), 0 -24px 60px -6px rgba(107,59,242,.32), 0 -60px 120px -10px rgba(162,47,226,.16); }
.tp-horizon > i::after { content: ''; position: absolute; left: 38%; right: 38%; top: -1px; height: 2px;
  border-radius: 2px; box-shadow: 0 0 18px 2px rgba(107,59,242,.45);
  background: linear-gradient(90deg,rgba(162,47,226,0),#A22FE2 30%,#6B3BF2 50%,#1F6BEC 70%,rgba(31,107,236,0)); }

/* ── Try the RSVP ────────────────────────────────────────────────────── */
.tp-rsvp { position: relative; overflow: hidden; background: var(--night); color: #F2F1FA; scroll-margin-top: 70px; }
.tp-rsvp-glow { position: absolute; left: 0; right: 0; top: 0; height: 1000px; pointer-events: none; opacity: .4;
  will-change: transform, opacity;
  background: radial-gradient(ellipse 50% 42% at 50% 34%,rgba(107,59,242,.4),rgba(107,59,242,.1) 50%,rgba(107,59,242,0) 80%); }
.tp-rsvp-aur { position: absolute; width: 700px; height: 700px; right: -240px; top: 38%; border-radius: 50%;
  pointer-events: none; will-change: transform;
  background: radial-gradient(closest-side,rgba(31,107,236,.22),rgba(31,107,236,0)); }
.tp-rsvp-in { position: relative; padding-block: clamp(40px,6vw,80px) clamp(56px,8vw,104px); }
.tp-rsvp-head { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 14px;
  margin-bottom: clamp(36px,6vw,64px); }
.tp-rsvp-eyebrow { color: #B9A8F7; }
.tp-rsvp-head h2 { font-size: clamp(32px,5.4vw,68px); line-height: 1.02; max-width: 820px; text-wrap: balance; }
.tp-rsvp-head p { margin: 0; max-width: 560px; font-size: 16px; line-height: 1.7; color: #A7A1BF; text-wrap: pretty; }
.tp-rsvp-grid { display: grid; grid-template-columns: repeat(auto-fit,minmax(min(360px,100%),1fr));
  gap: clamp(28px,4vw,56px); align-items: center; }

.tp-phone-wrap { display: flex; justify-content: center; will-change: transform; }
.tp-phone { width: 100%; max-width: 360px; border-radius: 44px; padding: 10px; background: #0E0A24;
  box-shadow: 0 0 0 1px rgba(255,255,255,.08), 0 50px 90px -30px rgba(0,0,0,.6); }
.tp-phone-screen { border-radius: 34px; overflow: hidden; background: #fff; color: var(--ink); }
.tp-phone-card { position: relative; height: 210px; overflow: hidden; background: #fafaf7; }
.tp-phone-card img { display: block; width: 100%; height: auto; margin-top: -8%; }
.tp-phone-fade { position: absolute; inset: auto 0 0 0; height: 8%; display: block;
  background: linear-gradient(rgba(255,255,255,0) 0%,rgba(255,255,255,.35) 30%,rgba(255,255,255,.8) 62%,#fff 92%); }
.tp-phone-body { display: flex; flex-direction: column; }
.tp-form { padding: 6px 18px 20px; display: flex; flex-direction: column; gap: 12px; }
.tp-form-h { display: flex; flex-direction: column; gap: 2px; }
.tp-form-h b { font-family: 'Instrument Serif', Georgia, serif; font-size: 26px; font-weight: 400; line-height: 1.1; }
.tp-form-h span { font-size: 12px; color: var(--muted); }
.tp-fns { display: flex; flex-direction: column; gap: 8px; }
.tp-fn { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 8px 8px 12px; border-radius: 14px; background: #F6F6FC; }
.tp-fn-t { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.tp-fn-t b { font-size: 14px; font-weight: 700; }
.tp-fn-t span { font-size: 11px; color: var(--muted); }
.tp-fn-b { display: flex; gap: 4px; flex: none; }
.tp-fn-b button { min-width: 52px; height: 36px; border-radius: 10px; border: 1px solid #E4E2F0;
  background: #fff; color: var(--ink); font-family: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  transition: transform .25s cubic-bezier(0.16,1,0.3,1), box-shadow .25s, border-color .2s, background-color .2s, color .2s; }
.tp-fn-b button:hover { border-color: var(--iris); box-shadow: 0 0 0 3px rgba(107,59,242,.16); transform: translateY(-1px); }
.tp-fn-b button.on[data-ans="yes"] { background: #EEF9F2; border-color: #4F9D69; color: #2F6B45; }
.tp-fn-b button.on[data-ans="no"] { background: #FBEFF0; border-color: #C9637A; color: #8E3A4D; }
.tp-row { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 8px 8px 12px; border-radius: 14px; background: #F6F6FC; }
.tp-row-t b { font-size: 14px; font-weight: 700; }
.tp-step-n { display: flex; align-items: center; gap: 4px; }
.tp-step-n button { width: 34px; height: 34px; border-radius: 10px; border: 1px solid #E4E2F0; background: #fff;
  color: var(--ink); cursor: pointer; display: grid; place-items: center; }
.tp-step-n button .ms { font-size: 17px; }
.tp-step-n i { width: 30px; text-align: center; font-style: normal; font-family: 'Instrument Serif', Georgia, serif;
  font-size: 24px; }
.tp-meals { display: flex; gap: 4px; }
.tp-meals button { padding: 7px 10px; border-radius: 10px; border: 1px solid #E4E2F0; background: #fff;
  color: var(--ink); font-family: inherit; font-size: 12px; font-weight: 700; cursor: pointer;
  transition: border-color .2s, background-color .2s, color .2s; }
.tp-meals button.on { background: #F2EEFE; border-color: var(--iris); color: var(--iris-deep); }
.tp-send { margin-top: 2px; display: flex; align-items: center; justify-content: center; gap: 8px; padding: 13px;
  border: 0; border-radius: 14px; background: var(--iris); color: #fff; font-family: inherit; font-size: 15px;
  font-weight: 700; cursor: pointer; transition: background-color .2s, transform .18s; }
.tp-send:hover { background: #5A2BE6; }
.tp-send:active { transform: scale(.985); }
/* The panel keeps the height the form had, so that it does not jump when
   the two swap. That leaves the thank-you stranded against the top of a
   tall empty box, so it takes the whole of it and sits in the middle --
   a little above true centre, which reads as placed rather than floating. */
.tp-done { padding: 40px 22px 76px; display: flex; flex-direction: column; align-items: center;
  justify-content: center; flex: 1 1 auto; text-align: center; gap: 12px; }
/* The two buttons sit on one row inside a 360px phone, which they only do
   if the panel stops taking 22px off each side for them. */
.tp-done { padding-inline: 14px; }
.tp-tick { width: 64px; height: 64px; border-radius: 50%; background: #E7F4EC; display: grid;
  place-items: center; margin-bottom: 6px; }
.tp-done b { font-family: 'Instrument Serif', Georgia, serif; font-size: 32px; font-weight: 400;
  line-height: 1.1; }
.tp-done > span { font-size: 14px; line-height: 1.65; color: var(--muted); max-width: 250px;
  text-wrap: pretty; }
.tp-done-btns { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 8px; }
.tp-cal, .tp-again { display: inline-flex; align-items: center; gap: 6px; padding: 11px 13px;
  border-radius: 999px; font-family: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer;
  white-space: nowrap;
  border: 1px solid transparent; line-height: 1;
  transition: background-color .2s, border-color .2s, color .2s, transform .18s; }
.tp-cal { background: #F2EEFE; color: var(--iris-deep); }
.tp-cal:hover { background: #E8E0FD; }
.tp-cal .ms { font-size: 17px; }
.tp-again { background: #fff; color: var(--ink); border-color: var(--line); }
.tp-again:hover { border-color: var(--iris); color: var(--iris); }
.tp-cal:active, .tp-again:active { transform: scale(.97); }

/* The host's side */
.tp-dash { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.10); border-radius: 24px;
  padding: clamp(18px,2.4vw,26px); display: flex; flex-direction: column; gap: 16px;
  box-shadow: 0 40px 90px -40px rgba(0,0,0,.7); }
.tp-dash-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.tp-live { display: inline-flex; align-items: center; gap: 7px; padding: 4px 11px; border-radius: 999px;
  background: rgba(79,157,105,.16); color: #8FE0AE; font-size: 12px; font-weight: 700; }
.tp-live i { width: 7px; height: 7px; border-radius: 50%; background: #4F9D69; display: block;
  animation: tpLive 1.8s ease-out infinite; }
@keyframes tpLive { 0% { box-shadow: 0 0 0 0 rgba(79,157,105,.55); } 100% { box-shadow: 0 0 0 8px rgba(79,157,105,0); } }
.tp-dash-ev { font-size: 13px; color: #A7A1BF; }
.tp-dash-fns { display: flex; flex-direction: column; gap: 10px; }
.tp-dfn { display: flex; flex-direction: column; gap: 6px; }
.tp-dfn-top { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-size: 13px; }
.tp-dfn-top b { font-weight: 700; }
.tp-dfn-top span { color: #A7A1BF; font-variant-numeric: tabular-nums; }
.tp-dfn-bar { height: 7px; border-radius: 4px; background: rgba(255,255,255,.09); overflow: hidden; }
/* scaleX rather than width: the bar moves on the compositor, so a function changing
   from 40% to 70% costs no layout. */
.tp-dfn-bar i { display: block; height: 100%; width: 100%; border-radius: 4px;
  background: linear-gradient(90deg,#A22FE2,#6B3BF2);
  transform-origin: left; transform: scaleX(0);
  transition: transform .7s cubic-bezier(0.16,1,0.3,1); }
.tp-dash-note { margin: 0; font-size: 12.5px; line-height: 1.6; color: #8E88AC; text-wrap: pretty; }

.tp-cta { margin-top: clamp(48px,7vw,88px); display: flex; flex-direction: column; align-items: center;
  text-align: center; gap: 14px; }
.tp-cta h2 { font-size: clamp(30px,4.6vw,56px); line-height: 1.04; }
.tp-cta p { margin: 0; font-size: 15px; color: #A7A1BF; }

/* ── A card, up close ────────────────────────────────────────────────── */
.tp-modal { position: fixed; inset: 0; z-index: 400; display: grid; place-items: center; padding: 20px;
  background: rgba(10,7,26,.62); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.tp-modal[hidden] { display: none; }
/* Vertical scrolling only. Stepping to the next design slides the card in
   from +28px, and in an `overflow:auto` box that is 28px of scrollable
   width: a scrollbar appeared and the panel jumped sideways. Stepping back
   slides from -28px, which creates no scroll at all, which is why only one
   of the two arrows looked broken. */
.tp-modal-in { position: relative; width: 100%; max-width: 920px; max-height: calc(100vh - 40px);
  overflow-x: hidden; overflow-y: auto;
  background: #fff; border-radius: 24px; padding: clamp(18px,2.6vw,30px);
  display: grid; grid-template-columns: minmax(0,1fr) minmax(0,.9fr); gap: clamp(18px,3vw,34px);
  align-items: center; box-shadow: 0 50px 100px -30px rgba(10,7,26,.65); }
.tp-modal-x { position: absolute; top: 14px; right: 14px; width: 38px; height: 38px; border: 0; border-radius: 50%;
  background: #F3F1F9; color: var(--ink); cursor: pointer; display: grid; place-items: center; z-index: 2; }
/* `width:100%` and `justify-self`, never `margin:0 auto`. An auto inline
   margin turns OFF a grid item's stretch, so the card was sized by its
   content -- and its content is a .iv-card at width:100%, which against an
   auto-width parent resolves to nothing. The card was in the DOM, correct,
   and 0x0. */
.tp-modal-card { width: 100%; justify-self: center; border-radius: 8px; overflow: hidden;
  box-shadow: 0 30px 60px -24px rgba(26,19,57,.5); }
.tp-modal-card img { display: block; width: 100%; height: auto; background: #EFEDF6; }
.tp-modal-meta { display: flex; flex-direction: column; gap: 10px; color: var(--ink); }
.tp-modal-meta b { font-family: 'Instrument Serif', Georgia, serif; font-weight: 400; font-size: clamp(28px,3.4vw,40px); line-height: 1.05; }
.tp-modal-meta > span:last-of-type { font-size: 14.5px; line-height: 1.65; color: var(--muted); }
.tp-modal-cta { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 6px; }

@media (max-width: 860px) {
  .tp-modal-in { grid-template-columns: 1fr; }
  .tp-modal-card { max-width: 320px; }
}
@media (max-width: 760px) {
  .tp-hero { padding-top: 74px; }
  .tp-stage { height: clamp(290px,72vw,420px); order: -1; }
}
@media (max-width: 480px) {
  .tp-grid { grid-template-columns: repeat(auto-fill,minmax(150px,1fr)); }
  .tp-filters { gap: 10px; }
}
@media (prefers-reduced-motion: reduce) {
  .tp-aur i, .tp-lift, .tp-spec, .tp-dfn-bar i, .tp-live i { transition: none !important; animation: none !important; }
}

/* ── The bar above this page ─────────────────────────────────────────────
   The nav is shared with the article pages, and articles.css paints it
   white-on-dark because those pages are dark. This one is light, so it
   takes the dark-on-light treatment the homepage only reaches after you
   have scrolled past its dark hero. */
body.tp-page .rd-nav {
  color: #1A1339; background: rgba(251,251,254,.80);
  backdrop-filter: saturate(1.4) blur(14px); -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-bottom: 1px solid rgba(26,19,57,.08); box-shadow: none;
}
body.tp-page .rd-nav.scrolled { background: rgba(255,255,255,.92);
  border-bottom-color: rgba(26,19,57,.10); box-shadow: 0 6px 30px -18px rgba(26,19,57,.45); }
body.tp-page .rd-nav a, body.tp-page .rd-brand, body.tp-page .rd-brand span { color: #1A1339; }
body.tp-page .rd-links a:hover, body.tp-page .rd-nav a[aria-current="page"] { color: #6B3BF2; }
body.tp-page .rd-nav a[aria-current="page"] { font-weight: 700; }
body.tp-page .rd-btn-ghost { border-color: rgba(26,19,57,.22); color: #1A1339; }
body.tp-page .rd-btn-solid { background: #6B3BF2; color: #fff; }
body.tp-page .rd-menu-btn { color: #1A1339; border-color: rgba(26,19,57,.22); }

/* ── The [hidden] attribute has to win ───────────────────────────────────
   A class carrying display:flex outranks the UA rule for [hidden], so every
   block this page toggles by the attribute — the empty state, the RSVP form,
   its thank-you panel, the preview — would stay on screen. One rule rather
   than four, because the next one added would have the same fault. */
.tp [hidden], .tp-modal[hidden] { display: none !important; }

/* ══ The handoff's remaining furniture ══════════════════════════════════
   Everything below arrived with the second pass: real rendered cards in
   place of bare artwork, the hero's toast and running count, the host's
   panel as the design actually draws it, and the gradient panel the page
   ends on. ───────────────────────────────────────────────────────────── */

/* ── A rendered invitation, wherever one is placed ───────────────────────
   js/invites.js returns a <div> wrapping .iv-card, which carries its own
   aspect-ratio, its own container-type and font sizes in cqw. It only needs
   a width: one string of HTML is then right at 170px in the fan and at
   440px in the preview. */
.tp .iv-card, .tp-modal .iv-card { width: 100%; display: block; }
.tp-art, .tp-fan-art { display: block; position: relative; }
.tp-art > div, .tp-fan-art > div, .tp-modal-card > div,
#tpPhoneCard > div, .tp-cta-card [data-sc-idle] > div { display: block; }

/* The shadow that grows under a lifted card must not be clipped, so the
   radius and the overflow move inward, off [data-face] and onto the art. */
.tp-face { position: relative; border-radius: 0; overflow: visible; box-shadow: none; }
.tp-fan-art { border-radius: 6px; overflow: hidden;
  box-shadow: 0 2px 4px rgba(26,19,57,.08), 0 30px 60px -20px rgba(26,19,57,.45); }
.tp-fan-shadow { position: absolute; inset: 0; display: block; border-radius: 6px;
  box-shadow: 0 40px 70px -24px rgba(26,19,57,.6); opacity: 0; pointer-events: none; }

/* ── A number that rolls to its new value ───────────────────────────────
   The outgoing digits leave upward from the same box the incoming ones
   arrive into, so a count that changes reads as one movement. */
.tp-roll { position: relative; display: inline-block; clip-path: inset(-.1em -.3em);
  font-variant-numeric: tabular-nums; }
.tp-roll > [data-cur] { display: inline-block; }
.tp-roll > [data-ghost] { position: absolute; left: 0; top: 0; opacity: 0; }
.tp-roll.big { font-family: 'Instrument Serif', Georgia, serif; font-size: 30px; line-height: 1; }

/* ── The hero's toast: a reply, landing ─────────────────────────────── */
.tp-toast { position: absolute; left: -2%; bottom: 4%; z-index: 30; width: min(330px,86%);
  will-change: transform; }
.tp-toast > i { position: absolute; display: block; border-radius: 20px; }
.tp-toast-b2 { left: 8%; right: 8%; top: 22px; bottom: -14px; background: rgba(255,255,255,.55);
  box-shadow: 0 12px 30px -16px rgba(26,19,57,.35); }
.tp-toast-b1 { left: 4%; right: 4%; top: 12px; bottom: -7px; background: rgba(255,255,255,.8);
  box-shadow: 0 12px 30px -16px rgba(26,19,57,.3); }
.tp-toast-card { position: relative; border-radius: 20px; background: #fff;
  border: 1px solid rgba(26,19,57,.06);
  box-shadow: 0 1px 2px rgba(26,19,57,.05), 0 24px 50px -18px rgba(26,19,57,.45); }
.tp-toast-in { padding: 14px 16px 14px 14px; display: flex; flex-direction: column; gap: 11px;
  color: var(--ink); }
.tp-toast-row { display: flex; align-items: center; gap: 12px; }
.tp-av { position: relative; display: block; width: 42px; height: 42px; flex: none; }
.tp-av > i { position: absolute; font-style: normal; }
.tp-av [data-avring] { inset: 0; border-radius: 50%; border: 2px solid #4F9D69; opacity: 0; }
.tp-av-in { inset: 0; border-radius: 50%; color: #fff; display: grid; place-items: center;
  font-weight: 700; font-size: 14px; letter-spacing: .02em; }
.tp-av-b { right: -2px; bottom: -2px; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid #fff; color: #fff; display: grid; place-items: center; }
.tp-av-b .ms { font-size: 12px; }
.tp-toast-who { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.tp-toast-who b { font-size: 14px; font-weight: 700; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
.tp-toast-who span { font-size: 12px; color: var(--muted); }
.tp-toast-st { flex: none; padding: 5px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; }
.tp-toast-chips { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.tp-toast-chips > span { padding: 5px 10px; border-radius: 8px; background: #F2EEFE;
  color: var(--iris-deep); font-size: 12px; font-weight: 600; }
.tp-toast-chips > span.tp-toast-x { background: transparent; color: var(--muted);
  font-weight: 500; padding: 0 0 0 2px; }

/* The running count the replies add up to. */
.tp-hbadge { position: absolute; right: 0; top: 3%; z-index: 30; display: flex; align-items: center;
  gap: 10px; padding: 10px 16px; border-radius: 999px; background: var(--ink); color: #fff;
  font-size: 13px; font-weight: 600; will-change: transform;
  box-shadow: 0 16px 36px -14px rgba(26,19,57,.6); }
.tp-hdot { position: relative; display: block; width: 8px; height: 8px; flex: none; }
.tp-hdot > i { position: absolute; inset: 0; border-radius: 50%; }
.tp-hdot [data-dotring] { background: #7FD39B; opacity: 0; }
.tp-hdot-live { background: #4F9D69; animation: tpLive 2.4s ease-out infinite; }
.tp-hbadge-t { display: flex; align-items: baseline; white-space: nowrap; }
.tp-hbadge-t .tp-roll { font-weight: 700; }

/* The dot that carries one reply across a section. */
.tp-pulse, .tp-pulse-t { position: absolute; left: 0; top: 0; display: block; border-radius: 50%;
  opacity: 0; pointer-events: none; }
.tp-pulse-t { width: 10px; height: 10px; margin: -5px 0 0 -5px; z-index: 40;
  background: radial-gradient(circle,#E9E2FF 0,#8D6BFF 45%,rgba(107,59,242,0) 72%); }
.tp-pulse { width: 16px; height: 16px; margin: -8px 0 0 -8px; z-index: 41;
  background: radial-gradient(circle,#fff 0,#C9BBFF 30%,#6B3BF2 55%,rgba(31,107,236,0) 72%);
  box-shadow: 0 0 22px 8px rgba(107,59,242,.35); }

/* ── The guest's side ───────────────────────────────────────────────── */
/* The window onto the card, and where the card sits inside it. Both are
   ratios rather than pixels, because the card is sized by the phone's width
   -- a fixed window crops a different amount of it at every screen size,
   which is how the couple's names ended up half under the fade.
   350/258 is the design's own proportion. The card is then pulled up until
   the printed wording, the names and the date all sit in the clear part of
   the window, above the fade. */
.tp-phone-card { height: auto; aspect-ratio: 350 / 258; border-bottom: 1px solid #ECEAF4; }
#tpPhoneCard { position: relative; margin-top: -29%; }
.tp-send { position: relative; }
.tp-sendring { position: absolute; inset: 0; display: block; border-radius: 14px;
  border: 2px solid var(--iris); opacity: 0; pointer-events: none; }

/* ── The host's side, as the design draws it ────────────────────────── */
.tp-dash-depth { position: relative; display: flex; flex-direction: column; gap: 18px;
  will-change: transform; }
.tp-halo { position: absolute; left: -40px; right: -40px; top: -40px; height: 420px;
  border-radius: 50%; display: block; opacity: 0; pointer-events: none;
  background: radial-gradient(closest-side,rgba(107,59,242,.5),rgba(107,59,242,0)); }
.tp-dash { position: relative; gap: 20px; }
.tp-live { letter-spacing: .06em; text-transform: uppercase; }
.tp-dash-ev .tp-roll { color: #F2F1FA; font-weight: 700; }
.tp-dash-fns { gap: 16px; }
.tp-dfn { position: relative; gap: 8px; }
/* A function that just took a reply lights up behind its row. */
.tp-dfn-flash { position: absolute; left: -12px; right: -12px; top: -7px; bottom: -7px;
  display: block; border-radius: 12px; background: rgba(141,107,255,.16); opacity: 0;
  pointer-events: none; }
.tp-dfn-top { position: relative; font-size: 15px; }
.tp-dfn-top > .tp-dfn-n { display: flex; align-items: baseline; gap: 6px; color: #F2F1FA; }
.tp-dfn-u { font-size: 12px; color: #A7A1BF; }
.tp-delta { display: inline-block; min-width: 26px; font-style: normal; font-size: 12px;
  font-weight: 700; color: #7FD39B; }
.tp-dfn-bar { height: 10px; border-radius: 5px; }
.tp-dfn-bar i { background: linear-gradient(90deg,#A22FE2,#6B3BF2 50%,#1F6BEC); border-radius: 5px;
  transition: transform .9s linear(0, 0.012, 0.047 2.5%, 0.18 5.3%, 0.674 13.8%, 0.86 18.8%, 0.966 24.5%, 1.012 31.4%, 1.018 37%, 1.008 46.5%, 1); }

.tp-meals-blk { display: flex; flex-direction: column; gap: 10px; padding-top: 18px;
  border-top: 1px solid rgba(255,255,255,.10); }
.tp-meals-h { font-size: 13px; font-weight: 700; }
.tp-mealbar { display: flex; height: 10px; border-radius: 5px; overflow: hidden; gap: 3px; }
.tp-mealbar > i { display: block; transition: flex .8s cubic-bezier(0.16,1,0.3,1); }
.tp-meal-legend { display: flex; gap: 18px; flex-wrap: wrap; font-size: 13px; color: #A7A1BF; }
.tp-meal-legend > span { display: flex; align-items: center; gap: 6px; }
.tp-meal-legend > span > i { width: 8px; height: 8px; border-radius: 2px; display: block; }
.tp-meal-legend .tp-roll { color: #F2F1FA; font-weight: 700; }

/* The replies as they land, newest first. */
.tp-feed { display: flex; flex-direction: column; gap: 8px; }
.tp-feed-row { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-radius: 16px;
  background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.10); }
.tp-feed-av { width: 34px; height: 34px; flex: none; border-radius: 50%; color: #fff;
  display: grid; place-items: center; font-size: 12px; font-weight: 700; }
.tp-feed-t { flex: 1; min-width: 0; font-size: 13px; line-height: 1.45; }
.tp-feed-t b { font-weight: 700; }
.tp-feed-t span { color: #A7A1BF; }
.tp-feed-w { font-size: 12px; color: #A7A1BF; white-space: nowrap; }

/* ── What it does, said once ────────────────────────────────────────── */
.tp-feats { margin-top: clamp(48px,7vw,88px); display: grid;
  grid-template-columns: repeat(auto-fit,minmax(min(300px,100%),1fr));
  gap: clamp(26px,3vw,38px) clamp(24px,3vw,48px); }
.tp-feat { display: flex; gap: 16px; align-items: flex-start; }
.tp-feat-i { width: 44px; height: 44px; flex: none; border-radius: 14px; display: grid;
  place-items: center; background: rgba(255,255,255,.08); color: #C9BBFF; }
.tp-feat-i .ms { font-size: 22px; }
.tp-feat-t { display: flex; flex-direction: column; gap: 6px; }
.tp-feat-t b { font-size: 16px; font-weight: 700; }
.tp-feat-t > span { font-size: 14px; line-height: 1.65; color: #A7A1BF; text-wrap: pretty; }

/* ── The panel the page ends on ─────────────────────────────────────── */
.tp-ctap { position: relative; margin-top: clamp(52px,8vw,96px); border-radius: 32px;
  overflow: hidden; padding: clamp(28px,4vw,56px); color: #fff;
  background: linear-gradient(120deg,#A22FE2 0%,#6B3BF2 48%,#1F6BEC 100%);
  box-shadow: 0 50px 100px -40px rgba(107,59,242,.75); }
/* Two lights inside the gradient: a white one that comes up as the panel
   arrives, and a fixed cyan one in the far corner, so a flat 120deg ramp
   reads as a lit surface rather than as a swatch. */
.tp-ctap-illum { position: absolute; left: -12%; top: -70%; width: 72%; height: 220%; display: block;
  opacity: 0; pointer-events: none;
  background: radial-gradient(closest-side,rgba(255,255,255,.5),rgba(255,255,255,0)); }
.tp-ctap-light { position: absolute; right: -16%; bottom: -80%; width: 64%; height: 200%; display: block;
  pointer-events: none;
  background: radial-gradient(closest-side,rgba(38,207,239,.55),rgba(38,207,239,0)); }
.tp-ctap-in { position: relative; display: grid;
  grid-template-columns: minmax(0,1.05fr) minmax(0,.95fr); gap: clamp(24px,4vw,48px);
  align-items: center; }
.tp-ctap-copy { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; }
.tp-ctap-copy h2 { font-size: clamp(32px,4.4vw,56px); line-height: 1.04; letter-spacing: -.01em; }
.tp-ctap-copy p { margin: 0; max-width: 460px; font-size: 16px; line-height: 1.7;
  color: rgba(255,255,255,.86); text-wrap: pretty; }
.tp-ctap-btns { display: flex; gap: 12px; flex-wrap: wrap; }
.tp-btn.outline { background: transparent; color: #fff; border: 1px solid rgba(255,255,255,.55); }
.tp-btn.outline:hover { background: rgba(255,255,255,.14); border-color: #fff; color: #fff; }
.tp-ctap-stage { position: relative; height: 290px; perspective: 900px; }
.tp-ctap-stack { position: absolute; inset: 0; transform-style: preserve-3d; }
.tp-cta-card { position: absolute; left: 50%; top: 50%; width: clamp(128px,15vw,168px); }
.tp-cta-card [data-sc-idle] { display: block; border-radius: 5px; overflow: hidden;
  box-shadow: 0 2px 4px rgba(10,7,26,.22), 0 28px 56px -18px rgba(10,7,26,.65); }

/* ── The preview ────────────────────────────────────────────────────── */
.tp-modal-back { position: absolute; inset: 0; background: rgba(10,7,26,.62);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.tp-modal { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; }
.tp-modal-card.land { max-width: 520px; }
/* Stepping back and stepping on are one control, so they wrap as one
   rather than leaving the back arrow stranded on the row above. */
.tp-modal-nav { display: flex; gap: 10px; }
.tp-modal-cta #tpModalPrev { padding-inline: 18px; }

@media (max-width: 980px) {
  .tp-ctap-in { grid-template-columns: 1fr; }
  .tp-ctap-stage { height: 240px; order: -1; }
  .tp-ctap-copy { align-items: center; text-align: center; }
  .tp-ctap-copy p { max-width: 540px; }
  .tp-ctap-btns { justify-content: center; }
}
@media (max-width: 760px) {
  .tp-stage { height: clamp(400px,96vw,500px); }
  .tp-fan { width: min(40%,190px); }
  .tp-toast { width: min(300px,96%); left: 0; bottom: 0; }
  .tp-toast-in { padding: 12px 13px; gap: 9px; }
  .tp-hbadge { right: 0; top: 0; padding: 8px 13px; font-size: 12px; }
  .tp-roll.big { font-size: 26px; }
  .tp-feed-w { display: none; }
}
@media (max-width: 480px) {
  /* A narrower phone leaves the two buttons 8px short of one row, and two
     rows of pills reads as a mistake rather than a choice. */
  .tp-done { padding-inline: 8px; }
  .tp-cal, .tp-again { padding: 11px 12px; }
}
@media (max-width: 420px) {
  .tp-toast-st { display: none; }
  .tp-ctap { border-radius: 24px; }
}
@media (prefers-reduced-motion: reduce) {
  .tp-hdot-live, .tp-mealbar > i, .tp-dfn-bar i { animation: none !important; transition: none !important; }
  .tp-ctap-illum { opacity: .24; }
}
