/* Doodle layer for the check-in and alert pages: a greeting plus a subtle
   animation on a handful of Dutch special days.

   Everything here animates transform and opacity only, so the compositor does
   the work and nothing recalculates layout — these pages are opened on cheap
   phones, often on mobile data at five in the morning.

   The overlay is pointer-events:none and sits at z-index -1, behind the page.
   Both pages exist to be tapped: the doodle must never be able to swallow a
   press on the check-in or acknowledge button. */

#festive {
    position: fixed;
    /* Longhands rather than inset: these pages are opened on some genuinely
       old Android browsers. */
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: -1;
    transition: opacity 2s ease-out;
}

/* Set once the effect has had its run: the animation fades out and is removed,
   leaving the greeting behind. No point spinning particles for a whole shift. */
#festive.festive-fade {
    opacity: 0;
}

.festive-greeting {
    text-align: center;
    font-size: 1.15em;
    color: var(--festive-accent, #444);
}

/* --- particle shapes ------------------------------------------------------ */

.festive-particle {
    position: absolute;
    will-change: transform;
}

.festive-dot {
    width: var(--size);
    height: var(--size);
    border-radius: 50%;
    background: var(--color);
}

/* Confetti and streamers: a narrow rectangle reads as a tumbling strip of
   paper once it spins. */
.festive-strip {
    width: calc(var(--size) * 0.4);
    height: var(--size);
    border-radius: 1px;
    background: var(--color);
}

/* Sinterklaas parcels: a wrapped box with a cross ribbon, drawn in CSS rather
   than set as an emoji — the gift emoji is one of the ones that still renders
   as a box on the older Android phones these pages get opened on. */
.festive-parcel {
    width: var(--size);
    height: var(--size);
    border-radius: 2px;
    background:
        linear-gradient(var(--ribbon), var(--ribbon)) no-repeat center / 100% 22%,
        linear-gradient(var(--ribbon), var(--ribbon)) no-repeat center / 22% 100%,
        var(--color);
}

.festive-glyph {
    font-size: var(--size);
    line-height: 1;
    color: var(--color);
}

/* --- falling: snow, parcels, confetti ------------------------------------ */

.festive-fall {
    top: 0;
    left: var(--x);
    animation: festive-fall var(--dur) linear var(--delay) infinite;
}

@keyframes festive-fall {
    from { transform: translate3d(0, -12vh, 0) rotate(0deg); }
    to   { transform: translate3d(var(--drift), 114vh, 0) rotate(var(--spin)); }
}

/* --- rising: hearts, balloons, lanterns ----------------------------------- */

.festive-rise {
    bottom: 0;
    left: var(--x);
    animation: festive-rise var(--dur) linear var(--delay) infinite;
}

@keyframes festive-rise {
    from { transform: translate3d(0, 12vh, 0) rotate(0deg); }
    to   { transform: translate3d(var(--drift), -114vh, 0) rotate(var(--spin)); }
}

/* --- rolling: easter eggs, and bats crossing higher up -------------------- */

.festive-roll {
    bottom: var(--y);
    left: 0;
    animation: festive-roll var(--dur) linear var(--delay) infinite;
}

@keyframes festive-roll {
    from { transform: translate3d(-15vw, 0, 0) rotate(0deg); }
    to   { transform: translate3d(115vw, 0, 0) rotate(var(--spin)); }
}

/* --- vlaggetjes: the Dutch flag on Bevrijdingsdag ------------------------- */

/* Drawn as a gradient rather than the 🇳🇱 emoji, which renders as the letters
   "NL" on a good number of Android builds. Two elements per flag: the outer
   one is carried across the page by the roll animation, the inner one flutters
   on the spot, so the two motions do not have to be folded into one keyframe. */
.festive-flaglet {
    width: var(--size);
    height: calc(var(--size) * 0.667);
}

.festive-cloth {
    width: 100%;
    height: 100%;
    transform-origin: left center;
    background: linear-gradient(
        to bottom,
        #ae1c28 33.33%,
        #ffffff 33.33%,
        #ffffff 66.66%,
        #21468b 66.66%);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
    animation: festive-wave var(--wave) ease-in-out infinite alternate;
}

/* Held on the hoist and left to flutter: a slow skew back and forth reads as
   cloth without the cost of animating a dozen segments. */
@keyframes festive-wave {
    from { transform: rotate(-2deg) skewY(2.5deg) scaleY(0.96); }
    to   { transform: rotate(2deg) skewY(-2.5deg) scaleY(1); }
}

/* --- bursting: fireworks --------------------------------------------------- */

/* Each burst is a point on the page; its dots fly outward along a fixed angle
   handed in as --dx / --dy, all sharing one origin and one delay. */
.festive-burst {
    position: absolute;
    left: var(--x);
    top: var(--y);
}

.festive-spark {
    position: absolute;
    animation: festive-burst var(--dur) ease-out var(--delay) infinite;
}

@keyframes festive-burst {
    0%   { transform: translate3d(0, 0, 0) scale(0.3); opacity: 0; }
    12%  { opacity: 1; }
    100% { transform: translate3d(var(--dx), var(--dy), 0) scale(1); opacity: 0; }
}

/* A driver who has asked the phone to stop animating things gets the greeting
   and nothing else. The script skips building the overlay too; this is the
   backstop for a preference that changes after the page loaded. */
@media (prefers-reduced-motion: reduce) {
    #festive {
        display: none;
    }
}
