/*
 * Palette tokens. Defaults here; the theme may override them on :root, the "Bingkai Undangan"
 * widget per invitation on body, and each widget's "Warna komponen" section on that widget only.
 * Derived shades use color-mix() inline so they follow whichever level set the base colour.
 *   --inv-bg          page background
 *   --inv-ink         main text
 *   --inv-gold        accent (primary button, dates, countdown digits, dividers)
 *   --inv-on-accent   text placed on the accent colour
 *   --inv-overlay     tint laid over photos and the backdrop
 *   --inv-error       form error text
 *   --inv-radius      button and field corner radius
 */
:root {
  --inv-bg: #0b0b0c;
  --inv-ink: #ffffff;
  --inv-gold: #c8a96a;
  --inv-on-accent: #0b0b0c;
  --inv-overlay: #000000;
  --inv-error: #ffc9c9;
  --inv-radius: 0px;
  --inv-side-ink: #ffffff;
  --inv-font-display: "Cormorant Garamond", Georgia, serif;
  --inv-font-body: "Lora", Georgia, serif;
  --inv-col: 500px;
  --inv-backdrop-overlay: .65;
  --inv-screen: 100vh;
}

@supports (height: 100svh) {
  :root { --inv-screen: 100svh; }
}

.inv-body {
  margin: 0;
  background: var(--inv-bg);
  color: var(--inv-ink);
  font-family: var(--inv-font-body);
  overflow-x: hidden;
}

.inv-locked,
.inv-locked body { overflow: hidden; }

.inv-icon { width: 1em; height: 1em; flex: none; }

/* Component display rules (inline-flex buttons etc.) would otherwise beat the hidden attribute. */
.inv-body [hidden],
.inv-cover [hidden] { display: none !important; }

.inv-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 40px;
  padding: 10px 22px;
  border: 1px solid var(--inv-ink);
  border-radius: var(--inv-radius);
  background: transparent;
  color: var(--inv-ink);
  font: 13px/1 var(--inv-font-body);
  letter-spacing: .02em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color .3s, color .3s, border-color .3s;
}

.inv-btn:hover { background: var(--inv-ink); color: var(--inv-bg); }
.inv-btn:active { transform: translateY(1px); }
.inv-btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }
.inv-btn:disabled:hover { background: transparent; color: var(--inv-ink); }

/* The primary action carries the gold accent. */
.inv-btn--primary { border-color: var(--inv-gold); color: var(--inv-gold); }
.inv-btn--primary:hover { background: var(--inv-gold); color: var(--inv-on-accent); }

.inv-body :focus-visible,
.inv-cover :focus-visible {
  outline: 2px solid var(--inv-gold);
  outline-offset: 3px;
}

.inv-main:focus { outline: none; }

.inv-editor-note {
  margin: 6px 0 0;
  padding: 4px 8px;
  border-left: 2px solid color-mix(in srgb, var(--inv-gold) 60%, transparent);
  font: 11px/1.4 system-ui, sans-serif;
  opacity: .7;
}


/* Frame */
.inv-side { display: none; }

.inv-backdrop {
  position: fixed;
  top: 0;
  right: 0;
  width: 100%;
  height: var(--inv-screen);
  overflow: hidden;
  background: var(--inv-bg) center / cover no-repeat;
}

.inv-backdrop::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--inv-overlay);
  opacity: var(--inv-backdrop-overlay);
}

.inv-backdrop__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Crossfading photos with a slow zoom, shared by the backdrop and the desktop side panel. */
.inv-backdrop__slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1);
  transition: opacity 1.2s ease, transform 7s linear;
}

.inv-backdrop__slide.is-active { opacity: 1; transform: scale(1.12); }
.inv-motion-paused .inv-backdrop__slide.is-active { transform: scale(1); }

.inv-main {
  position: relative;
  width: 100%;
  margin-left: auto;
  overflow-x: hidden;
}

/* Cover */
.inv-cover:not(.e-con) {
  --inv-cover-overlay: .6;
  position: fixed;
  inset: 0;
  z-index: 9990;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 24px;
  background: var(--inv-bg) center / cover no-repeat;
  color: var(--inv-ink);
  font-family: var(--inv-font-body);
  text-align: center;
  transition: transform 1s cubic-bezier(.7, 0, .3, 1), opacity .9s ease;
}

.inv-cover:not(.e-con)::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--inv-overlay);
  opacity: var(--inv-cover-overlay);
}

.inv-cover.is-open { transform: translateY(-100%); opacity: 0; }

/*
 * Cover built from a Container with class "inv-cover" (button class "inv-open"). Its look comes
 * from Elementor; here it only covers the screen. The script narrows it to its own column.
 */
body.inv-body:not(.elementor-editor-active) .e-con.inv-cover {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9990;
  width: 100%;
  /*
   * As tall as the screen with the browser bars hidden, so the page never shows below the cover
   * (iOS Safari draws its floating toolbar over the page). The template's own min-height, often
   * 100vh, is ignored. The bottom padding grows by the height the toolbars can take, so the content
   * stays above them (Brave and Safari on iOS keep the address bar at the bottom).
   */
  height: 100vh;
  height: 100lvh;
  min-height: 0;
  padding-bottom: calc(var(--padding-bottom, 0px) + 100lvh - 100svh);
  overflow-y: auto;
  transition: transform 1s cubic-bezier(.7, 0, .3, 1), opacity .9s ease;
}

/* Content settles in as the cover lifts. */
.inv-js .inv-main { transition: opacity .9s ease .25s, transform 1.1s cubic-bezier(.2, .7, .2, 1) .2s; }
.inv-js.inv-locked .inv-main { opacity: 0; transform: translateY(24px); }

/*
 * "Susun sendiri" layout (Bingkai Undangan > Tata letak): the page is built from Containers, e.g. a
 * fixed KIRI panel and a KANAN column. A transform on .inv-main would pin those fixed panels to it.
 */
body.inv-layout-containers .inv-main { width: 100%; }
.inv-js.inv-locked body.inv-layout-containers .inv-main { opacity: 1; transform: none; }

.inv-cover--editor {
  position: relative;
  inset: auto;
  z-index: 1;
  min-height: 640px;
}

.inv-cover__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 420px;
}

.inv-cover__label { margin: 0; font-size: 13px; letter-spacing: .08em; }

.inv-cover__title {
  margin: 14px 0;
  font-family: var(--inv-font-display);
  font-size: 44px;
  font-weight: 500;
  line-height: 1.05;
}

.inv-cover__date { margin: 0; font-size: 13px; }

.inv-cover__to {
  margin-top: clamp(80px, 22vh, 200px);
  padding-top: 18px;
  border-top: 1px solid color-mix(in srgb, var(--inv-gold) 45%, transparent);
}

.inv-cover__greeting { margin: 0; font-size: 13px; }

.inv-cover__guest {
  margin: 10px 0 0;
  font-size: 20px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.inv-cover__open { margin-top: 40px; }

/* Guest name */
.inv-guest-name { margin: 0; overflow-wrap: anywhere; }

/* Countdown */
.inv-timer {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  width: min(100%, 240px);
  margin: 0 auto;
  text-align: center;
}

.inv-timer__digits {
  display: block;
  color: var(--inv-gold);
  font: 600 22px/1 var(--inv-font-body);
}

.inv-timer__label {
  display: block;
  margin-top: 6px;
  font: 10px/1.2 var(--inv-font-body);
  letter-spacing: .04em;
}

.inv-timer__expired {
  grid-column: 1 / -1;
  margin: 12px 0 0;
  font: 13px/1.6 var(--inv-font-body);
}

.inv-timer.is-expired .inv-timer__item { display: none; }

/* Numeric date: day name over 14 · 02 · 2027 */
.inv-date-num {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  color: var(--inv-ink);
  font-family: var(--inv-font-body);
}

.inv-date-num__day { font-size: 12px; letter-spacing: .3em; }

.inv-date-num__digits {
  display: flex;
  align-items: center;
  gap: 10px;
  font: 500 44px/1 var(--inv-font-display);
  font-variant-numeric: lining-nums;
}

.inv-date-num__dot { color: var(--inv-gold); font-size: .7em; }

/* Circular text */
.inv-ring {
  display: block;
  width: 128px;
  height: 128px;
  overflow: visible;
  fill: var(--inv-ink);
  font-family: var(--inv-font-body);
}

.inv-ring--spin {
  animation: inv-spin var(--inv-ring-speed, 24s) linear infinite;
  animation-direction: var(--inv-ring-direction, normal);
}

.inv-motion-paused .inv-ring--spin { animation-play-state: paused; }

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

/* Event date row */
.inv-date-row {
  --inv-date-line: var(--inv-gold);
  display: flex;
  align-items: center;
  font-family: var(--inv-font-body);
}

.inv-date-row__side {
  flex: 1;
  padding: 10px 0;
  border-block: 1px solid var(--inv-date-line);
  font-size: 12px;
  letter-spacing: .12em;
}

.inv-date-row__side--start { padding-right: 12px; text-align: right; }
.inv-date-row__side--end { padding-left: 12px; text-align: left; }

.inv-date-row__center {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 10px;
  line-height: 1;
}

.inv-date-row__day-num {
  color: var(--inv-gold);
  font: 600 38px/1 var(--inv-font-display);
}

.inv-date-row__year { margin-top: 4px; font-size: 12px; font-weight: 600; }

/* Event schedule: layout follows the number of events. */
.inv-events {
  --inv-events-gap: 16px;
  display: grid;
  gap: var(--inv-events-gap);
  font-family: var(--inv-font-body);
  color: var(--inv-ink);
  text-align: center;
}

.inv-events--single { justify-items: center; }
.inv-events--single .inv-event { width: min(100%, 340px); }
.inv-events--pair { grid-template-columns: 1fr 1fr; }

.inv-event {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 0;
  padding: 6px 10px;
}

/* Separators sit between events: vertical in a pair, horizontal when stacked. */
.inv-events--pair.inv-events--sep-line .inv-event + .inv-event,
.inv-events--pair.inv-events--sep-ornament .inv-event + .inv-event { border-inline-start: 1px solid var(--inv-gold); }

.inv-events__sep {
  position: relative;
  justify-self: center;
  width: 40%;
  border-top: 1px solid color-mix(in srgb, var(--inv-gold) 70%, transparent);
}

.inv-events--sep-ornament .inv-events__sep::after {
  content: "";
  position: absolute;
  top: -4px;
  left: 50%;
  width: 7px;
  height: 7px;
  border: 1px solid var(--inv-gold);
  background: var(--inv-bg);
  transform: translateX(-50%) rotate(45deg);
}

/* Rundown: the rule sits halfway through the gap between the time column and the details. */
.inv-events--timeline {
  --inv-tl-time: 86px;
  --inv-tl-gap: 28px;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--inv-events-gap, 26px);
  text-align: left;
}

.inv-events--timeline::before {
  content: "";
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: calc(var(--inv-tl-time) + var(--inv-tl-gap) / 2);
  border-left: 1px solid var(--inv-gold);
}

.inv-event--tl {
  display: grid;
  grid-template-columns: var(--inv-tl-time) minmax(0, 1fr);
  column-gap: var(--inv-tl-gap);
  align-items: start;
  padding: 0;
}

.inv-event--tl .inv-event__when {
  margin: 0;
  color: var(--inv-gold);
  font: 500 22px/1.15 var(--inv-font-display);
  text-align: right;
  overflow-wrap: anywhere;
}

.inv-event--tl .inv-event__body {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
}

.inv-event--tl .inv-event__body::before {
  content: "";
  position: absolute;
  top: 6px;
  left: calc(var(--inv-tl-gap) / -2 - 5px);
  width: 9px;
  height: 9px;
  border: 1px solid var(--inv-gold);
  background: var(--inv-bg);
  transform: rotate(45deg);
}

.inv-event__title { margin: 0; font: 600 20px/1.15 var(--inv-font-display); }
.inv-event__date,
.inv-event__time,
.inv-event__place { margin: 0; font-size: 13px; line-height: 1.5; overflow-wrap: anywhere; }
.inv-event__maps { margin-top: 8px; }

/* Love story timeline */
/* Moments are spaced by gap, so a moment given its own box padding still keeps its distance. */
.inv-story {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 28px;
  margin: 0;
  padding: 0 0 0 24px;
  list-style: none;
  color: var(--inv-ink);
  font-family: var(--inv-font-body);
}

.inv-story::before {
  content: "";
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: 5px;
  border-left: 1px solid color-mix(in srgb, var(--inv-gold) 70%, transparent);
}

.inv-moment { position: relative; }

.inv-moment::before {
  content: "";
  position: absolute;
  top: 5px;
  left: -24px;
  width: 11px;
  height: 11px;
  border: 1px solid var(--inv-gold);
  border-radius: 50%;
  background: var(--inv-bg);
}

.inv-moment__label { margin: 0; color: var(--inv-gold); font-size: 12px; letter-spacing: .08em; }
.inv-moment__title { margin: 2px 0 8px; font: 500 22px/1.2 var(--inv-font-display); }
.inv-moment__photo {
  display: block;
  width: 100%;
  height: auto;
  margin-bottom: 10px;
  aspect-ratio: 4 / 3;
  border-radius: var(--inv-photo-radius, 10px);
  object-fit: cover;
}
.inv-moment__text { margin: 0; font-size: 13px; line-height: 1.7; }

/* Wedding gift: accounts drawn as payment cards (ISO ID-1 proportions, 85.6 x 54 mm). */
.inv-gift { color: var(--inv-ink); font-family: var(--inv-font-body); text-align: center; }
/*
 * Inside a Container, Elementor leaves widgets without a definite width. The browser then sizes the
 * aspect-ratio cards before their width is known, the widget comes out shorter than its content on
 * phones, and the next section covers the last item (the address). A full width fixes the height.
 */
.e-con > .elementor-widget-inv-gift { width: 100%; }
.inv-gift__toggle-wrap { margin: 0 0 16px; }
/* Collapsible panel: rows animate from 0fr to 1fr so the height follows the content. */
.inv-gift__panel {
  display: grid;
  grid-template-rows: 1fr;
  opacity: 1;
  transition: grid-template-rows .7s cubic-bezier(.2, .7, .2, 1), opacity .5s ease;
}

.inv-gift__panel[data-closed] { grid-template-rows: 0fr; opacity: 0; }

/* Flex, not grid: grid sizes rows before an aspect-ratio card knows its width, so cards overlapped. */
.inv-gift__panel-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  min-height: 0;
  overflow: hidden;
  padding: 6px 4px 18px;
}

.inv-gift__panel-inner > * { flex: none; }

/* Cards rise in one after another when the guest opens the panel. */
.inv-gift__panel.is-opening .inv-card,
.inv-gift__panel.is-opening .inv-gift__address {
  animation: inv-card-in .7s cubic-bezier(.2, .7, .2, 1) both;
  animation-delay: calc(var(--i, 0) * 130ms + 120ms);
}

@keyframes inv-card-in {
  from { opacity: 0; transform: translateY(24px) scale(.97); }
  to { opacity: 1; transform: none; }
}

.inv-card {
  --inv-card-from: #3a342d;
  --inv-card-to: #121110;
  --inv-card-ink: #f4efe6;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  width: 100%;
  max-width: 360px;
  aspect-ratio: 85.6 / 54;
  padding: 16px 18px;
  overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--inv-gold) 55%, transparent);
  border-radius: 14px;
  background: linear-gradient(135deg, var(--inv-card-from), var(--inv-card-to));
  color: var(--inv-card-ink);
  text-align: left;
  box-shadow: 0 10px 24px rgba(0, 0, 0, .28);
}

/* Faint sheen so the surface reads as a card, not a flat box. */
.inv-card::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 80% at 100% 0%, rgba(255, 255, 255, .12), transparent 55%);
  pointer-events: none;
}

.inv-card > * { position: relative; z-index: 1; }

.inv-card__top { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; }

.inv-card__chip {
  width: 40px;
  height: 30px;
  fill: color-mix(in srgb, var(--inv-gold) 85%, #fff);
  stroke: color-mix(in srgb, var(--inv-gold) 55%, #000);
  stroke-width: 1;
}

.inv-card__logo {
  display: block;
  width: auto;
  max-width: 45%;
  height: 26px;
  margin-left: auto;
  object-fit: contain;
  object-position: right top;
}

.inv-card__bank {
  margin-left: auto;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.inv-card__number {
  margin: 0;
  font: 600 clamp(17px, 5.4vw, 22px)/1.2 var(--inv-font-body);
  font-variant-numeric: tabular-nums;
  letter-spacing: .08em;
  overflow-wrap: anywhere;
}

.inv-card__bottom { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; }

.inv-card__holder {
  min-width: 0;
  margin: 0;
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}

.inv-card__copy {
  flex: none;
  min-height: 34px;
  padding: 6px 14px;
  border-color: var(--inv-card-ink);
  color: var(--inv-card-ink);
  font-size: 12px;
}

.inv-card__copy:hover { background: var(--inv-card-ink); color: var(--inv-card-to); }
.inv-card__copy.is-copied { border-color: var(--inv-gold); background: var(--inv-gold); color: var(--inv-on-accent); }

.inv-gift__address { display: grid; gap: 6px; justify-items: center; max-width: 360px; }
.inv-gift__address-title { margin: 8px 0 0; font: 500 20px/1.2 var(--inv-font-display); }
.inv-gift__address-name { margin: 0; font-weight: 600; }
.inv-gift__address-text { margin: 0 0 6px; font-size: 13px; line-height: 1.6; }

.inv-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Maps button */
.inv-maps {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* RSVP */
.inv-rsvp {
  display: flex;
  flex-direction: column;
  gap: 16px;
  font: 13px/1.6 var(--inv-font-body);
  color: var(--inv-ink);
}

.inv-rsvp__guest { margin: 0; }
.inv-rsvp__guest-label { display: block; font-size: 12px; opacity: .85; }
.inv-rsvp__guest strong { font-size: 16px; font-weight: 600; }

.inv-field { display: flex; flex-direction: column; gap: 4px; margin: 0; padding: 0; border: 0; min-width: 0; }
.inv-field[hidden] { display: none; }
.inv-field > label,
.inv-field > legend { padding: 0; font-size: 12px; }

.inv-field select,
.inv-field textarea {
  width: 100%;
  padding: 8px 0;
  border: 0;
  border-bottom: 1px solid var(--inv-ink);
  border-radius: 0;
  background: transparent;
  color: var(--inv-ink);
  font: 13px/1.5 var(--inv-font-body);
}

.inv-field textarea { resize: vertical; }
.inv-field textarea::placeholder { color: color-mix(in srgb, var(--inv-ink) 72%, transparent); }
.inv-field select option { color: #1f1f24; }

.inv-field select:focus-visible,
.inv-field textarea:focus-visible {
  outline: none;
  border-bottom: 2px solid var(--inv-gold);
  margin-bottom: -1px;
}

.inv-checks { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 6px; }

.inv-check {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 36px;
  cursor: pointer;
}

.inv-check input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--inv-gold);
  cursor: pointer;
}

.inv-check input:focus-visible { outline: 2px solid var(--inv-gold); outline-offset: 3px; }

.inv-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.inv-rsvp__status { min-height: 1.6em; margin: 0; }
.inv-rsvp__status.is-error { color: var(--inv-error); }
.inv-rsvp .inv-btn { align-self: flex-start; }
.inv-rsvp__note { margin: 0; font-size: 12px; opacity: .85; }

/* Wishes */
.inv-wishes { font: 13px/1.6 var(--inv-font-body); color: var(--inv-ink); }

.inv-wishes__counts {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
  margin: 0 0 8px;
  padding-bottom: 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--inv-gold) 45%, transparent);
  font-size: 12px;
}

.inv-wishes__counts strong { color: var(--inv-gold); font-weight: 600; }

.inv-wishes__list {
  max-height: 420px;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.inv-wish { padding: 12px 4px; border-bottom: 1px solid color-mix(in srgb, var(--inv-ink) 25%, transparent); }
.inv-wish__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; margin: 0; }
.inv-wish__name { font-size: 14px; font-weight: 600; overflow-wrap: anywhere; }
.inv-wish__badge { font-size: 11px; opacity: .85; }
.inv-wish__badge--hadir { color: var(--inv-gold); opacity: 1; }
.inv-wish__text { margin: 4px 0 0; white-space: pre-line; overflow-wrap: anywhere; }
.inv-wish__time { margin: 4px 0 0; font-size: 11px; opacity: .8; }
.inv-wishes__empty { padding: 12px 4px; font-size: 15px; line-height: 1.6; }
.inv-wishes__more { margin-top: 12px; }

/* Gallery */
.inv-gallery {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}

.inv-gallery--featured .inv-gallery__item:first-child {
  grid-column: 1 / -1;
  aspect-ratio: 4 / 3;
}

.inv-gallery__item {
  position: relative;
  aspect-ratio: 9 / 16;
  padding: 0;
  border: 0;
  overflow: hidden;
  border-radius: var(--inv-gallery-radius, 0px);
  background: color-mix(in srgb, var(--inv-ink) 12%, var(--inv-bg));
  cursor: zoom-in;
}

.inv-gallery__item img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform .8s;
}

.inv-gallery__item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--inv-overlay);
  opacity: 0;
  transition: opacity .6s;
}

.inv-gallery__item:hover::after,
.inv-gallery__item:focus-visible::after { opacity: .4; }
.inv-gallery__item:focus-visible { outline: 2px solid var(--inv-gold); outline-offset: -3px; }

.inv-lightbox {
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: rgba(0, 0, 0, .94);
  color: #fff;
}

.inv-lightbox[open] { display: flex; justify-content: center; align-items: center; }
.inv-lightbox::backdrop { background: transparent; }

.inv-lightbox__img {
  max-width: calc(100% - 32px);
  max-height: calc(100% - 120px);
  object-fit: contain;
}

.inv-lightbox__btn {
  position: absolute;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: rgba(0, 0, 0, .45);
  color: #fff;
  font-size: 20px;
  cursor: pointer;
}

.inv-lightbox__btn:hover { background: rgba(255, 255, 255, .2); }
.inv-lightbox__btn:focus-visible { outline: 2px solid var(--inv-gold); outline-offset: 2px; }
.inv-lightbox__close { top: 12px; right: 12px; }
.inv-lightbox__prev { top: 50%; left: 8px; transform: translateY(-50%); }
.inv-lightbox__next { top: 50%; right: 8px; transform: translateY(-50%); }

.inv-lightbox__count {
  position: absolute;
  right: 0;
  bottom: 16px;
  left: 0;
  margin: 0;
  font: 12px/1 var(--inv-font-body);
  text-align: center;
}

/* Floating controls */
.inv-controls {
  position: fixed;
  bottom: 40px;
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

.inv-controls[hidden] { display: none; }
.inv-controls--right { right: 16px; }
.inv-controls--left { left: 16px; }
.inv-controls--editor { position: static; flex-direction: row; }

.inv-control {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--inv-bg) 55%, transparent);
  color: var(--inv-ink);
  font-size: 28px;
  cursor: pointer;
  transition: background-color .3s, color .3s;
}

.inv-control--small { font-size: 14px; }
.inv-control:hover { background: color-mix(in srgb, var(--inv-bg) 85%, transparent); color: var(--inv-gold); }
.inv-control:focus-visible { outline: 2px solid var(--inv-gold); outline-offset: 2px; }
.inv-control [hidden] { display: none; }
.inv-control > span { display: grid; place-items: center; }

/*
 * Elementor's own widgets follow the palette unless the widget sets its own colour or font
 * (widget settings are more specific and win). Elementor globals map to the palette too.
 */
body.inv-body {
  /* Elementor gives headings "Primary" and buttons "Accent" by default. */
  --e-global-color-primary: var(--inv-ink);
  --e-global-color-secondary: var(--inv-ink);
  --e-global-color-text: var(--inv-ink);
  --e-global-color-accent: var(--inv-gold);
  --e-global-typography-primary-font-family: var(--inv-font-display);
  --e-global-typography-secondary-font-family: var(--inv-font-body);
  --e-global-typography-text-font-family: var(--inv-font-body);
  --e-global-typography-accent-font-family: var(--inv-font-body);
}

.inv-body .elementor-widget-heading .elementor-heading-title {
  color: var(--inv-ink);
  font-family: var(--inv-font-display);
}

.inv-body .elementor-widget-text-editor {
  color: var(--inv-ink);
  font-family: var(--inv-font-body);
}

/*
 * Elementor wraps edited text in <p>. Browser margins are 1em, so at a 50px script size a name
 * gained 50px gaps after editing. Keep paragraph spacing small and independent of the font size.
 */
.inv-body .elementor-widget-text-editor p { margin: 0 0 .75rem; }
.inv-body .elementor-widget-text-editor p:last-child { margin-bottom: 0; }

.inv-body .elementor-widget-divider { --divider-color: var(--inv-gold); }
.inv-body .elementor-widget-text-path { --text-color: var(--inv-ink); font-family: var(--inv-font-body); }

/* Utility classes for template authors (Advanced > CSS Classes). */
.inv-body .inv-font-display :is(.elementor-heading-title, p, span),
.inv-body .inv-font-display.elementor-widget-text-editor { font-family: var(--inv-font-display); }
.inv-body .inv-font-body :is(.elementor-heading-title, p, span),
.inv-body .inv-font-body.elementor-widget-text-editor { font-family: var(--inv-font-body); }
.inv-body .inv-font-script :is(.elementor-heading-title, p, span),
.inv-body .inv-font-script.elementor-widget-text-editor { font-family: var(--inv-font-script, cursive); font-weight: 400; }
.inv-body .inv-color-accent :is(.elementor-heading-title, p, span),
.inv-body .inv-color-accent.elementor-widget-text-editor { color: var(--inv-gold); }

.inv-body .inv-photo-frame img,
.inv-body .e-con.inv-photo-frame {
  border: 1px solid var(--inv-gold);
  border-radius: var(--inv-photo-radius, 10px);
}

.inv-body .e-con.inv-divide-end { border-inline-end: 1px solid var(--inv-gold); }

/*
 * Shape classes. The double ring (background-coloured gap, then an accent hairline) is drawn with
 * box-shadow so it follows the rounded shape.
 */
.inv-body .inv-photo-arch img,
.inv-body .e-con.inv-photo-arch {
  border-radius: 999px 999px var(--inv-photo-radius, 10px) var(--inv-photo-radius, 10px);
  box-shadow: 0 0 0 6px var(--inv-bg), 0 0 0 7px var(--inv-gold);
}

.inv-body .inv-photo-circle img,
.inv-body .e-con.inv-photo-circle {
  aspect-ratio: 1;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 0 6px var(--inv-bg), 0 0 0 7px var(--inv-gold);
}

/*
 * Soft edges: the element fades out towards one side, so a photo blends into the backdrop instead
 * of ending on a hard line. Use on a Container whose photo is its background (image or slideshow).
 */
.inv-body .inv-fade-top {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--inv-fade, 30%));
  mask-image: linear-gradient(to bottom, transparent 0, #000 var(--inv-fade, 30%));
}

.inv-body .inv-fade-bottom {
  -webkit-mask-image: linear-gradient(to top, transparent 0, #000 var(--inv-fade, 30%));
  mask-image: linear-gradient(to top, transparent 0, #000 var(--inv-fade, 30%));
}

.inv-body .inv-fade-top.inv-fade-bottom {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--inv-fade, 30%), #000 calc(100% - var(--inv-fade, 30%)), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 var(--inv-fade, 30%), #000 calc(100% - var(--inv-fade, 30%)), transparent 100%);
}

/* A mask also hides box-shadow, so a fading arch draws its outline as a border, which fades with it. */
.inv-body .e-con.inv-photo-arch { overflow: hidden; }
.inv-body .e-con.inv-photo-arch:is(.inv-fade-top, .inv-fade-bottom) {
  border: 1px solid var(--inv-gold);
  box-shadow: none;
}

/* "Ornamen" widget: an image from the Media Library. */
.inv-motif {
  display: flex;
  justify-content: center;
  line-height: 0;
}

.inv-motif img {
  display: block;
  width: var(--inv-motif-size, 90px);
  max-width: 100%;
  height: auto;
  transform: rotate(var(--inv-motif-rot, 0deg)) scaleX(var(--inv-motif-flip, 1));
}

/* Four corners: the widget stretches over its parent container and mirrors the motif per corner. */
.inv-body .e-con > .inv-motif-mode-corners,
.elementor-editor-active .e-con > .inv-motif-mode-corners {
  position: absolute !important;
  inset: var(--inv-motif-inset, 12px);
  z-index: 1;
  width: auto !important;
  max-width: none !important;
  margin: 0 !important;
  pointer-events: none;
}

.inv-motif-mode-corners > .elementor-widget-container,
.inv-motif--corners { position: absolute; inset: 0; }

.inv-motif__corner { position: absolute; width: var(--inv-motif-size, 90px); }
.inv-motif__corner img { width: 100%; transform: none; }
.inv-motif__corner--tl { top: 0; left: 0; }
.inv-motif__corner--tr { top: 0; right: 0; transform: scaleX(-1); }
.inv-motif__corner--bl { bottom: 0; left: 0; transform: scaleY(-1); }
.inv-motif__corner--br { right: 0; bottom: 0; transform: scale(-1, -1); }

/* In the editor the corners stay clickable so the widget can be selected. */
.elementor-editor-active .inv-motif__corner { pointer-events: auto; }

/*
 * Two-tone sections. A Container with inv-tone-light gets a solid light background and swaps the
 * palette to the "Palet terang" values of Bingkai Undangan; inv-tone-dark restores the main palette
 * (e.g. a dark card inside a light section). Everything inside follows: text, accent, buttons.
 */
body.inv-body {
  --inv-dark-bg: var(--inv-bg);
  --inv-dark-ink: var(--inv-ink);
  --inv-dark-gold: var(--inv-gold);
  --inv-dark-on-accent: var(--inv-on-accent);
}

.inv-body .e-con.inv-tone-light {
  --inv-bg: var(--inv-light-bg, #fbf6ee);
  --inv-ink: var(--inv-light-ink, #3b2a1e);
  --inv-gold: var(--inv-light-gold, #8a5a2b);
  --inv-on-accent: var(--inv-light-on-accent, #ffffff);
}

.inv-body .e-con.inv-tone-dark {
  --inv-bg: var(--inv-dark-bg);
  --inv-ink: var(--inv-dark-ink);
  --inv-gold: var(--inv-dark-gold);
  --inv-on-accent: var(--inv-dark-on-accent);
}

.inv-body .e-con:is(.inv-tone-light, .inv-tone-dark) {
  --e-global-color-primary: var(--inv-ink);
  --e-global-color-secondary: var(--inv-ink);
  --e-global-color-text: var(--inv-ink);
  --e-global-color-accent: var(--inv-gold);
  background-color: var(--inv-bg);
  color: var(--inv-ink);
}

/* Solid buttons: class on a widget to fill its buttons with the accent colour. */
.inv-body .inv-btn-solid .inv-btn,
.inv-body .inv-btn-solid .inv-btn--primary {
  border-color: var(--inv-gold);
  background: var(--inv-gold);
  color: var(--inv-on-accent);
}

.inv-body .inv-btn-solid .inv-btn:hover {
  border-color: var(--inv-ink);
  background: var(--inv-ink);
  color: var(--inv-bg);
}

/* Ornament: a Divider widget with a small accent diamond at its centre. */
.inv-body .inv-ornament .elementor-divider { position: relative; }
.inv-body .inv-ornament .elementor-divider::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 7px;
  height: 7px;
  border: 1px solid var(--inv-gold);
  background: var(--inv-bg);
  transform: translate(-50%, -50%) rotate(45deg);
}

/* Orbit: a "Teks Melingkar" widget wrapped around its parent container (e.g. a round photo). */
/* Elementor sizes container children itself, so the orbit's box is forced here. */
.inv-body .e-con > .inv-ring-orbit {
  position: absolute;
  top: calc(var(--inv-orbit-gap, 34px) * -1);
  left: calc(var(--inv-orbit-gap, 34px) * -1);
  z-index: 2;
  width: calc(100% + var(--inv-orbit-gap, 34px) * 2) !important;
  max-width: none !important;
  height: calc(100% + var(--inv-orbit-gap, 34px) * 2);
  margin: 0;
  pointer-events: none;
}

.inv-body .inv-ring-orbit > .elementor-widget-container,
.inv-body .inv-ring-orbit .inv-ring {
  width: 100% !important;
  height: 100% !important;
}
.inv-body .e-con.inv-surface { background-color: color-mix(in srgb, var(--inv-bg) 55%, transparent); }

/* "Animasi berulang" */
.inv-js .inv-reveal { opacity: 0; transition: opacity 1s, transform 1.5s; }
.inv-js .inv-reveal--up { transform: translateY(30px); }
.inv-js .inv-reveal--left { transform: translateX(-80px); }
.inv-js .inv-reveal--right { transform: translateX(80px); }
.inv-js .inv-reveal--fade { transform: scale(.85); }
.inv-js .inv-reveal--rotate { transform: scale(.5) rotate(-20deg); transition: opacity .5s, transform 1.5s; }
.inv-js .inv-reveal.in-view,
.elementor-editor-active .inv-reveal { opacity: 1; transform: none; }

@media (min-width: 768px) {
  .inv-side {
    position: fixed;
    top: 0;
    right: var(--inv-col);
    left: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    height: var(--inv-screen);
    padding: 0 24px 18vh;
    overflow: hidden;
    background: var(--inv-overlay);
    color: var(--inv-side-ink);
    text-align: center;
  }

  .inv-side::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, color-mix(in srgb, var(--inv-overlay) 75%, transparent), color-mix(in srgb, var(--inv-overlay) 25%, transparent) 60%);
  }

  .inv-side__slide {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transform: scale(1);
    transition: opacity 1.2s ease, transform 6s linear;
  }

  .inv-side__slide.is-active { opacity: 1; transform: scale(1.12); }
  .inv-motion-paused .inv-side__slide.is-active { transform: scale(1); }

  .inv-side__title,
  .inv-side__subtitle { position: relative; z-index: 1; margin: 0; }

  .inv-side__title {
    font: 500 44px/1.05 var(--inv-font-display);
  }

  .inv-side__subtitle {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--inv-gold);
    font: 13px/1.4 var(--inv-font-body);
    letter-spacing: .06em;
  }

  .inv-backdrop { width: var(--inv-col); }
  .inv-main { width: var(--inv-col); }

  /* The side panel stays visible; the cover only closes the invitation column. */
  .inv-cover:not(.inv-cover--editor):not(.e-con) {
    left: auto;
    width: var(--inv-col);
  }
  .inv-cover__title { font-size: 52px; }
  .inv-controls { bottom: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .inv-js .inv-main,
  .inv-cover,
  .inv-side__slide,
  .inv-backdrop__slide,
  .inv-gallery__item img,
  .inv-js .inv-reveal { transition: none; }
  .inv-js .inv-reveal { opacity: 1; transform: none; }
  .inv-ring--spin,
  .inv-gift__panel.is-opening .inv-card,
  .inv-gift__panel.is-opening .inv-gift__address { animation: none; }
  .inv-gift__panel { transition: none; }
  .inv-side__slide.is-active,
  .inv-backdrop__slide.is-active { transform: none; }
}
