@import url("common.css");
@import url("animation.css");

html {
    scrollbar-width: none !important;
    -ms-overflow-style: none !important;
}

.with-scrollbar {
    scrollbar-width: auto !important;
    -ms-overflow-style: auto !important;
}

.font-esthetic {
    /* Sacramento carries no Arabic, so Arabic headings continue to the chosen
       Arabic face rather than dropping to the browser's default cursive. Every
       section heading on the invitation lives in this class. */
    font-family: 'Sacramento', var(--theme-font-arabic) !important;
}

.font-arabic {
    /* Only the two Qur'anic lines carry this class. They need a naskh face with
       the annotation marks - the modern sans faces draw a missing-glyph box in
       place of a pause mark. */
    font-family: var(--theme-font-quran) !important;
}

.img-center-crop {
    width: 13rem;
    height: 13rem;
    max-width: 100%;
    max-height: 100%;
    object-fit: cover;
}

html[data-bs-theme="dark"] .btn-transparent {
    background-color: rgba(var(--bs-dark-rgb), 0.5) !important;
    backdrop-filter: blur(0.5rem);
}

html[data-bs-theme="light"] .btn-transparent {
    background-color: rgba(var(--bs-light-rgb), 0.5) !important;
    backdrop-filter: blur(0.5rem);
}

.loading-page {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 1056;
}

html[data-bs-theme="light"] .color-theme-svg {
    color: rgb(255, 255, 255);
    background-color: var(--bs-light);
}

html[data-bs-theme="dark"] .color-theme-svg {
    color: rgb(0, 0, 0);
    background-color: var(--bs-dark);
}

html[data-bs-theme="light"] .bg-light-dark {
    background-color: rgb(var(--bs-light-rgb));
}

html[data-bs-theme="dark"] .bg-light-dark {
    background-color: rgb(var(--bs-dark-rgb));
}

html[data-bs-theme="light"] .bg-white-black {
    background-color: rgb(var(--bs-white-rgb));
}

html[data-bs-theme="dark"] .bg-white-black {
    background-color: rgb(var(--bs-black-rgb));
}

.bg-cover-home {
    width: 100%;
    height: 100%;
    object-fit: cover;
    mask-image: linear-gradient(0.5turn, transparent, black 40%, black 60%, transparent);
}

/* Hero background video: full-bleed swan scene behind the home section,
   with a warm veil so the names and date stay readable over it. */
.home-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
    opacity: 0;
    animation: home-video-fade 1.4s ease 0.2s forwards;
}

@keyframes home-video-fade {
    to { opacity: 1; }
}

/* Full-height veil, one flat tint rather than a gradient: the text now sits
   vertically centred in the full-screen hero, which is exactly where a
   gradient that dips in the middle (to stay light at the edges) would leave
   the video untinted right behind the couple's name. A single flat colour
   keeps a little warmth over the whole frame, evenly, wherever the text ends
   up. */
.home-veil {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background: rgba(253, 248, 239, 0.22);
}

/* The home overlay only needs to sit above the video — its backdrop blur
   smears the video, and on a custom theme its background-color (an
   !important rule elsewhere, tinting every other .bg-overlay-auto with the
   theme colour) painted a solid wash over the whole hero, hiding most of
   the footage behind it. Drop both and let the light veil above keep the
   text readable without washing out the footage. */
#home .bg-overlay-auto {
    /* background-color: transparent !important; */
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* The wave divider right after the home section used to blend into the old
   light home background, but now that the home is a video it leaves a light
   strip between the footage and the wave. Pull the wave up over the video's
   bottom edge and make its own background transparent so the video shows
   through above the crest. */
#home + .svg-wrapper {
    position: relative;
    z-index: 3;
    margin-top: -2rem;
}

#home + .svg-wrapper .color-theme-svg {
    background-color: transparent;
}

/* Full-screen hero: give the background video room to breathe and centre the
   invitation text over it. Without a min-height the section collapses to its
   (now shorter) content, leaving the wave to swallow most of the footage. */
#home {
    min-height: 90vh;
    min-height: 80svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.width-loading {
    width: 25%;
}

.cursor-pointer {
    cursor: pointer;
}

@media screen and (max-width: 992px) {
    .width-loading {
        width: 50%;
    }
}

@media screen and (max-width: 576px) {
    .width-loading {
        width: 75%;
    }
}

svg {
    display: block;
    line-height: 0;
    shape-rendering: geometricPrecision;
    backface-visibility: hidden;
}

.svg-wrapper {
    overflow: hidden !important;
    transform: translateZ(0) !important;
}

.no-gap-bottom {
    margin-bottom: -0.75rem !important;
}

/* Fixed custom theme: see common.css for the base rules this extends. */
html.custom-theme-active .btn-transparent {
    background-color: color-mix(in srgb, var(--theme-background) 50%, transparent) !important;
    backdrop-filter: blur(0.5rem);
}

html.custom-theme-active .color-theme-svg {
    color: var(--theme-divider);
    background-color: var(--theme-background);
}

html.custom-theme-active .bg-white-black {
    background-color: var(--theme-background) !important;
}

/* The template alternates two shades between sections, and that alternation is
   what separates them. Pointing both at the background colour collapsed the
   whole page to one flat tone, so the second shade is derived instead - which
   works for a light or a dark palette without another setting to get wrong. */
html.custom-theme-active .bg-light-dark {
    background-color: color-mix(in srgb, var(--theme-background) 95%, var(--theme-text)) !important;
}

/* Bootstrap's left-to-right build compiles the logical spacing utilities down
   to physical properties, so the ones this page uses need mirroring by hand.
   Loading the whole RTL stylesheet instead would cost a second 230 kB download
   for the sake of seven rules. */
/* Bootstrap's .navbar-nav only resets padding-left; in RTL the list's default
   40px padding lands on the right instead, leaving a gap before the first
   (rightmost) nav item. */
html[dir="rtl"] .navbar-nav {
    padding-right: 0;
}

html[dir="rtl"] .me-1 {
    margin-right: 0 !important;
    margin-left: 0.25rem !important;
}

html[dir="rtl"] .me-2 {
    margin-right: 0 !important;
    margin-left: 0.5rem !important;
}

html[dir="rtl"] .ms-1 {
    margin-left: 0 !important;
    margin-right: 0.25rem !important;
}

html[dir="rtl"] .text-start {
    text-align: right !important;
}

html[dir="rtl"] .end-0 {
    right: auto !important;
    left: 0 !important;
}

/* Used on the Love Story timeline: the text column butts up against the
   numbered circle with no gap on its near side. In RTL the row's flex order
   reverses so that near side is physically the right, not the left. */
html[dir="rtl"] .ps-0 {
    padding-left: calc(var(--bs-gutter-x, 1.5rem) * 0.5) !important;
    padding-right: 0 !important;
}
/* Countdown. Both parts take the text colour rather than the accent: an accent
   is free to be pale, and unreadable digits are worse than plain ones. Size and
   weight carry the hierarchy instead. */
.countdown-days {
    font-size: 2rem;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.countdown-clock {
    font-size: 1.5rem;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

/* Decorative only - the digits carry the meaning, so a quieter colon is safe. */
.countdown-sep {
    opacity: 0.55;
    padding: 0 0.1rem;
}

/* The one word on the countdown. It sits after the number, which is the right
   order in Arabic as well as English, and it is sized off the number so the two
   stay in proportion whatever the theme font is. */
.countdown-unit {
    font-size: 0.5em;
    margin-inline-start: 0.3rem;
    opacity: 0.8;
}

/* ---------- Envelope opening ----------
   The welcome screen is an addressed envelope: the guest's own name sits on the
   front, and breaking the wax seal opens the invitation. Every colour is taken
   from the theme so it follows whatever palette the owner picks - nothing here
   is a fixed cream-and-gold. */
.envelope {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background: var(--theme-background, #fff);
    /* Gives all four flaps one shared vanishing point, so they read as panels of
       the same envelope hinging away in space rather than four unrelated planes. */
    perspective: 1400px;
}

/* Four triangles meeting in the middle, the way a paper envelope folds. Each
   gets a slightly different shade so the folds read as folds, and each hinges
   from its own outer edge - real paper folds along a crease, it does not slide
   off screen flat. */
.envelope-flap {
    position: absolute;
    inset: 0;
    backface-visibility: hidden;
    transition: transform 0.85s cubic-bezier(0.6, 0, 0.25, 1), opacity 0.6s ease 0.35s;
    will-change: transform, opacity;
}

.envelope-flap-top {
    clip-path: polygon(0 0, 100% 0, 50% 50%);
    background: var(--theme-background);
    transform-origin: 50% 0%;
}

.envelope-flap-bottom {
    clip-path: polygon(0 100%, 100% 100%, 50% 50%);
    background: linear-gradient(0deg, color-mix(in srgb, var(--theme-background) 94%, var(--theme-text)), var(--theme-background));
    transform-origin: 50% 100%;
}

.envelope-flap-left {
    clip-path: polygon(0 0, 0 100%, 50% 50%);
    background: linear-gradient(90deg, color-mix(in srgb, var(--theme-background) 97%, var(--theme-text)), var(--theme-background));
    transform-origin: 0% 50%;
}

.envelope-flap-right {
    clip-path: polygon(100% 0, 100% 100%, 50% 50%);
    background: linear-gradient(270deg, color-mix(in srgb, var(--theme-background) 97%, var(--theme-text)), var(--theme-background));
    transform-origin: 100% 50%;
}

/* Staggered so the folds peel rather than vanish together. Rotated past 90deg
   so each flap swings behind the envelope rather than stopping edge-on; opacity
   still finishes the job a beat later, both because backface-visibility can
   leave a sliver visible at extreme angles under real-world rounding, and so a
   reduced-motion swap - which skips the transition and jumps straight to these
   end values - still hides the flap outright rather than leaving it edge-on. */
.envelope-open .envelope-flap-top {
    transform: rotateX(-124deg);
    opacity: 0;
    transition-delay: 0.02s;
}

.envelope-open .envelope-flap-left {
    transform: rotateY(124deg);
    opacity: 0;
    transition-delay: 0.09s;
}

.envelope-open .envelope-flap-right {
    transform: rotateY(-124deg);
    opacity: 0;
    transition-delay: 0.16s;
}

.envelope-open .envelope-flap-bottom {
    transform: rotateX(124deg);
    opacity: 0;
    transition-delay: 0.23s;
}

/* The address panel and the seal ride above the flaps and leave with them. */
/* Three rows put the middle one - the seal - on the point where the four folds
   converge. minmax(0, 1fr) rather than 1fr: a plain 1fr is minmax(auto, 1fr), so
   a tall address block grows the first row and shoves the seal down the screen.
   Forcing the outer rows equal keeps the wax centred however much text sits
   above it, and in whatever order. */
.envelope-face {
    position: relative;
    z-index: 5;
    height: 100%;
    display: grid;
    grid-template-rows: minmax(0, 1fr) auto minmax(0, 1fr);
    justify-items: center;
    text-align: center;
    padding: 6vh 8vw;
    transition: opacity 0.4s ease, transform 0.5s ease;
}

.envelope-address {
    align-self: end;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    padding-bottom: 1.6rem;
}

.envelope-open .envelope-face {
    opacity: 0;
    transform: scale(0.97);
}

.envelope-seal {
    position: relative;
    width: min(32vw, 138px);
    height: min(32vw, 138px);
    border: 0;
    padding: 0;
    background: none;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    /* Wax is matte, so the shadow is close and soft rather than a glossy pool. */
    filter: drop-shadow(0 6px 10px color-mix(in srgb, var(--theme-text) 30%, transparent));
    transition: transform 0.55s cubic-bezier(0.6, 0, 0.25, 1), opacity 0.45s ease;
}

.envelope-seal-wax {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
}

/* The poured body. Lit from the upper left, deepening towards the rim, and
   mixed toward the page's own text colour rather than black so a dark palette
   is not lit as though the wax were sitting on white paper. */
.wax-body {
    fill: url("#waxDome");
}

/* Gradient stops live here so the wax still follows the theme. Mixing toward
   --theme-background and --theme-text rather than white and black is what keeps
   a dark palette from looking lit off a sheet of paper. */
.wax-lit {
    stop-color: color-mix(in srgb, var(--theme-primary) 82%, var(--theme-background));
}

.wax-mid {
    stop-color: var(--theme-primary);
}

.wax-deep {
    stop-color: color-mix(in srgb, var(--theme-primary) 68%, var(--theme-text));
}

.wax-rim {
    fill: none;
    stroke: color-mix(in srgb, var(--theme-primary) 62%, var(--theme-text));
    stroke-width: 1.4;
    opacity: 0.55;
}

/* The die pressed into the wax: a ring standing slightly proud of the middle. */
.wax-stamp {
    fill: color-mix(in srgb, var(--theme-primary) 93%, var(--theme-text));
    stroke: color-mix(in srgb, var(--theme-primary) 74%, var(--theme-background));
    stroke-width: 1;
    opacity: 0.75;
}

.envelope-seal:focus-visible {
    outline: 2px solid var(--theme-text);
    outline-offset: 6px;
}


.envelope-seal .envelope-seal-monogram {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: color-mix(in srgb, var(--theme-on-primary) 88%, transparent);
    font-size: min(8vw, 2.2rem);
    line-height: 1;
    pointer-events: none;
    /* Struck into the wax: a dark edge below, a catch of light above. */
    text-shadow:
        0 1px 0 color-mix(in srgb, var(--theme-primary) 55%, var(--theme-text)),
        0 -1px 0 color-mix(in srgb, var(--theme-primary) 60%, var(--theme-background));
}

.envelope-open .envelope-seal {
    transform: scale(0.35) rotate(12deg);
    opacity: 0;
}

.envelope-breaking .envelope-seal {
    animation: envelope-jitter 0.32s ease;
}

.envelope-crack {
    position: absolute;
    inset: 0;
    opacity: 0;
    pointer-events: none;
    color: color-mix(in srgb, var(--theme-on-primary) 70%, transparent);
}

.envelope-breaking .envelope-crack {
    animation: envelope-crack 0.32s ease forwards;
}

@keyframes envelope-jitter {
    0% { transform: translate(0, 0) rotate(0); }
    20% { transform: translate(-1.5px, 1px) rotate(-1deg); }
    40% { transform: translate(1.5px, -1px) rotate(1deg); }
    60% { transform: translate(-1px, -1px) rotate(-0.5deg); }
    80% { transform: translate(1px, 1px) rotate(0.5deg); }
    100% { transform: translate(0, 0) rotate(0); }
}

@keyframes envelope-crack {
    0% { opacity: 0; }
    100% { opacity: 1; }
}

.envelope-prompt {
    align-self: start;
    padding-top: 1.4rem;
    font-size: 0.68rem;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--theme-text) 70%, transparent);
    animation: envelope-pulse 2.4s ease-in-out infinite;
}

@keyframes envelope-pulse {
    0%, 100% { opacity: 0.5; }
    50% { opacity: 1; }
}

.envelope-eyebrow {
    font-size: 0.72rem;
    letter-spacing: 0.32em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--theme-text) 65%, transparent);
}

.envelope-rule {
    width: 3.5rem;
    height: 1px;
    margin: 1.1rem 0;
    background: linear-gradient(90deg, transparent, var(--theme-divider, var(--theme-text)), transparent);
    opacity: 0.6;
}

.envelope-skip {
    position: absolute;
    z-index: 6;
    top: max(1rem, env(safe-area-inset-top));
    inset-inline-end: max(1rem, env(safe-area-inset-right));
    background: none;
    border: 0;
    font-size: 0.65rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--theme-text) 65%, transparent);
    cursor: pointer;
    padding: 0.5rem;
    transition: opacity 0.3s ease, color 0.3s ease;
}

.envelope-skip:hover,
.envelope-skip:focus-visible {
    color: var(--theme-text);
}

.envelope-open .envelope-skip {
    opacity: 0;
    pointer-events: none;
}

/* The whole point of the animation is the flourish; without it, just leave. */
@media (prefers-reduced-motion: reduce) {
    .envelope-flap,
    .envelope-seal,
    .envelope-face,
    .envelope-prompt,
    .envelope-skip {
        transition: none !important;
        animation: none !important;
    }
}

/* Uppercase and wide letter-spacing are Latin typographic habits; Arabic is
   cursive and joins, so both would damage it. */
html[dir="rtl"] .envelope-prompt,
html[dir="rtl"] .envelope-eyebrow,
html[dir="rtl"] .envelope-skip {
    text-transform: none;
    letter-spacing: normal;
    font-size: 0.8rem;
}
