/* Preloader styles */
#preloader {
    position: fixed;
    inset: 0;
    z-index: 9998;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background-color: #FAF8F5;
    transition: opacity 450ms ease-in-out;
}

/* Reading progress */
#reading-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 2px;
    width: 0%;
    background: #8B7355;
    z-index: 9999;
    transition: width 0.1s linear;
    pointer-events: none;
}

/* Animation keyframes */
@keyframes jump-utensil {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-10px); }
}
@keyframes jump-plate {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-6px); }
}

/* Kitchen preloader — utensils jumping in place, staggered */
.fork-anim {
    animation: jump-utensil 0.9s ease-in-out infinite;
}
.plate-anim {
    animation: jump-plate 0.9s ease-in-out infinite;
    animation-delay: 0.1s;
}
.spoon-anim {
    animation: jump-utensil 0.9s ease-in-out infinite;
    animation-delay: 0.2s;
}

/* Coffee preloader — steam wisps drawn along their own path.
   Animating stroke-dashoffset (rather than fading a static shape) makes each
   wisp appear to rise and dissipate, which reads far more organically.
   pathLength="1" on the SVG paths normalises length so these values are exact. */
@keyframes steam-drift {
    0% {
        stroke-dashoffset: 0.55;
        opacity: 0;
        transform: translate3d(0, 3px, 0);
    }
    20% {
        opacity: 0.95;
    }
    65% {
        opacity: 0.55;
    }
    100% {
        stroke-dashoffset: -1;
        opacity: 0;
        transform: translate3d(var(--drift, 0px), -8px, 0);
    }
}

#preloader .s1,
#preloader .s2,
#preloader .s3 {
    stroke-dasharray: 0.55 1;
    stroke-dashoffset: 0.55;
    opacity: 0;
    transform-box: fill-box;
    transform-origin: center bottom;
    will-change: stroke-dashoffset, opacity, transform;
    /* soft ease-out: rises briskly, then slows as it disperses */
    animation: steam-drift 1.7s cubic-bezier(0.33, 0, 0.3, 1) infinite;
}

/* Each wisp drifts a little differently and runs at a slightly different
   duration, so the three never re-sync into a mechanical-looking pulse. */
#preloader .s1 {
    --drift: -2px;
    animation-duration: 1.7s;
    animation-delay: 0s;
}
#preloader .s2 {
    --drift: 0.5px;
    animation-duration: 1.9s;
    animation-delay: 0.28s;
}
#preloader .s3 {
    --drift: 2px;
    animation-duration: 1.8s;
    animation-delay: 0.56s;
}

/* Loading caption breathes gently in time with the steam */
@keyframes caption-breathe {
    0%, 100% { opacity: 0.55; }
    50%      { opacity: 1; }
}
#preloader p {
    animation: caption-breathe 2.4s ease-in-out infinite;
}

/* Utility classes */
.fade-in-up {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.8s ease-out, transform 0.8s ease-out;
    will-change: opacity, transform;
}
.fade-in-up.visible {
    opacity: 1;
    transform: translateY(0);
}
.scroll-reveal {
    opacity: 0;
    transform: scale(0.98);
    transition: all 1.2s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.scroll-reveal.visible {
    opacity: 1;
    transform: scale(1);
}
/* Respect OS-level reduced-motion preference: kill looping/decorative
   animations and scroll transitions for users who've asked for them off */
@media (prefers-reduced-motion: reduce) {
    .fork-anim,
    .plate-anim,
    .spoon-anim,
    #preloader p {
        animation: none !important;
        opacity: 1 !important;
    }
    /* Steam must also have its dash pattern cleared, otherwise stopping the
       animation would leave the dash sitting off the path and the wisps
       would disappear entirely. Show them as complete static strokes. */
    #preloader .s1,
    #preloader .s2,
    #preloader .s3 {
        animation: none !important;
        opacity: 0.8 !important;
        stroke-dasharray: none !important;
        stroke-dashoffset: 0 !important;
        transform: none !important;
    }
    .fade-in-up,
    .scroll-reveal {
        transition: none !important;
        opacity: 1 !important;
        transform: none !important;
    }
}
