/* Entrances begin after the envelope has left the screen. */
.js .reveal,.js .animated-heading{--enter-delay:0s;--entry-tilt:0deg;opacity:0;filter:blur(8px);transform:translate3d(0,44px,0) rotate(var(--entry-tilt));transition:opacity 1.15s ease var(--enter-delay),filter 1.35s ease var(--enter-delay),transform 1.45s cubic-bezier(.16,1,.3,1) var(--enter-delay)}
.js .reveal.is-visible,.js .animated-heading.is-visible{opacity:1;filter:blur(0);transform:translate3d(0,0,0) rotate(var(--entry-tilt))}
.js .section-heading{filter:none;transform:none;transition:opacity .65s ease var(--enter-delay)}
.js .animated-heading{filter:none;transform:none;transition:opacity .5s ease var(--enter-delay)}
.word-sequence .reveal-word{display:inline-block;white-space:nowrap;transform-origin:50% 100%}
.js .reveal:not(.is-visible) .reveal-word,.js .animated-heading:not(.is-visible) .reveal-word{opacity:0;filter:blur(11px);transform:translate3d(0,38px,0) rotate(4deg)}
.js .is-visible .reveal-word{animation:word-emerge 1.25s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--enter-delay,0s) + var(--word-order,0)*.09s)}
.names.is-visible>span{animation:none}.names.is-visible>span:last-child .reveal-word{animation-delay:calc(var(--enter-delay,0s) + .38s + var(--word-order,0)*.09s)}
.animated-heading.is-visible em{animation:none}.section-heading h2 em .reveal-word{animation-delay:calc(var(--enter-delay,0s) + .3s + var(--word-order,0)*.09s)}
.js .section-heading:not(.is-visible) .kicker{opacity:0;transform:translateY(15px);filter:blur(4px)}
.js .section-heading.is-visible .kicker{animation:kicker-arrive 1s ease var(--enter-delay) both}
.js .hero-art{filter:none;transform:translateY(45px);transition:opacity 1.25s ease var(--enter-delay),transform 1.7s cubic-bezier(.16,1,.3,1) var(--enter-delay)}
.js .hero-art .hero-photo{clip-path:inset(49% 15% 49% 15% round 160px);filter:blur(9px);transition:clip-path 1.85s cubic-bezier(.16,1,.3,1) var(--enter-delay),filter 1.7s ease var(--enter-delay)}
.js .hero-art.is-visible .hero-photo{clip-path:inset(0 0 0 0 round 0);filter:blur(0)}
.js .hero-art .portrait-outline{opacity:0;transform:rotate(-10deg) scale(.9);transition:opacity 1.6s ease .55s,transform 2s cubic-bezier(.16,1,.3,1) .4s}
.js .hero-art.is-visible .portrait-outline{opacity:.75;transform:rotate(-2deg) scale(1)}
.hero-art.is-visible{animation:portrait-drift 9s ease-in-out 2.4s infinite}
.js .reveal-portrait:not(.is-visible) .family-photo{clip-path:inset(0 0 100% 0);filter:blur(7px)}
.js .family-photo{transition:clip-path 1.75s cubic-bezier(.16,1,.3,1) var(--enter-delay),filter 1.5s ease var(--enter-delay);clip-path:inset(0);filter:blur(0)}
.js .family-card.is-visible .family-copy{animation:soft-arrive 1.2s ease calc(var(--enter-delay) + .4s) both}
.js .album-photo{--entry-tilt:var(--tilt,-2deg);transform:translate3d(0,65px,0) rotate(calc(var(--entry-tilt) - 5deg)) scale(.94);filter:blur(8px);transition:opacity 1.25s ease var(--enter-delay),filter 1.4s ease var(--enter-delay),transform 1.7s cubic-bezier(.16,1,.3,1) var(--enter-delay)}
.js .album-photo.is-visible{transform:translate3d(0,0,0) rotate(var(--entry-tilt)) scale(1);filter:blur(0)}
.js .album-photo img{clip-path:inset(8% 8% 8% 8%);transition:clip-path 1.8s cubic-bezier(.16,1,.3,1) var(--enter-delay)}
.js .album-photo.is-visible img{clip-path:inset(0);animation:photo-focus 1.9s cubic-bezier(.16,1,.3,1) var(--enter-delay) both,photo-breathe 12s ease-in-out calc(var(--enter-delay) + 2s) infinite alternate}
.js .album-photo.is-visible .photo-caption{animation:soft-arrive 1s ease calc(var(--enter-delay) + .65s) both}
.js .album-photo.is-visible:hover{transform:rotate(0deg) translateY(-6px)}
.js .month-calendar{--entry-tilt:-1.5deg}.js .month-calendar.is-visible{transform:translate3d(0,0,0) rotate(-1.5deg)}
.js .gift-card{filter:none;transform:translateY(25px);transition:opacity 1s ease var(--enter-delay),transform 1.2s cubic-bezier(.16,1,.3,1) var(--enter-delay)}
.js .gift-card.is-visible{transform:none;filter:none}.gift-qr-viewport,.gift-qr-viewport img{animation:none!important;filter:none!important}
.js .event-card.is-visible .event-time{animation:soft-arrive 1.25s ease calc(var(--enter-delay) + .25s) both}
.js .location-layout.is-visible .location-info{animation:soft-arrive 1.3s ease calc(var(--enter-delay) + .15s) both}
@keyframes word-emerge{0%{opacity:0;filter:blur(11px);transform:translate3d(0,38px,0) rotate(4deg)}60%{opacity:1;filter:blur(1px)}100%{opacity:1;filter:blur(0);transform:none}}
@keyframes kicker-arrive{from{opacity:0;filter:blur(4px);transform:translateY(15px)}to{opacity:1;filter:blur(0);transform:none}}
@keyframes soft-arrive{from{opacity:0;filter:blur(5px);transform:translateY(20px)}to{opacity:1;filter:blur(0);transform:none}}
@keyframes photo-focus{from{transform:scale(1.16);filter:blur(6px)}to{transform:scale(1);filter:blur(0)}}
/* Switching effects off or requesting reduced motion leaves every paragraph readable. */
.motion-disabled .reveal,.motion-disabled .animated-heading,.motion-disabled .reveal-word,.motion-disabled .family-copy,.motion-disabled .photo-caption,.motion-disabled .kicker{opacity:1!important;filter:none!important;transform:none!important;animation:none!important;transition:none!important}
.motion-disabled .hero-photo,.motion-disabled .family-photo,.motion-disabled .album-photo img{clip-path:none!important;filter:none!important;animation:none!important;transition:none!important}
.motion-disabled .portrait-outline{opacity:.75!important;transform:rotate(-2deg)!important}
@media(prefers-reduced-motion:reduce){.js .reveal,.js .animated-heading,.js .reveal-word{opacity:1!important;filter:none!important;transform:none!important;animation:none!important;transition:none!important}.js .hero-photo,.js .family-photo,.js .album-photo img{clip-path:none!important;filter:none!important}.js .is-visible .reveal-word,.js .family-copy,.js .photo-caption,.js .kicker{animation:none!important;opacity:1!important;filter:none!important;transform:none!important}.js .portrait-outline{opacity:.75!important}}
/* The album keeps its tilted paper edges; its hover glint stays inside the photograph. */
.album-photo::after{inset:9px 9px 44px;transform:none;background:linear-gradient(115deg,transparent 25%,#ffffff45 50%,transparent 75%);background-size:250% 100%;background-position:130% 0;opacity:0;transition:opacity .4s,background-position 1.2s}
.album-photo:hover::after{transform:none;background-position:-30% 0;opacity:.7}
