@keyframes typewriter {
    from {
        width: 0;
    }
    to {
        width: 100%;
    }
}

@keyframes blink-caret {
    from, to {
        border-color: transparent;
    }
}

.typewriter-animation {
    overflow: hidden;
    border-right: .15em solid var(--text-color-primary); /* Adjust the caret color */
    white-space: nowrap;
    animation:
            typewriter 2s steps(80, end),
            blink-caret .1s step-end infinite;
}

/* The reveal animates width on a single unwrapped line, so on narrow screens
   it would clip the heading. Let the text wrap and drop the effect instead. */
@media (max-width: 600px) {
    .typewriter-animation {
        overflow: visible;
        white-space: normal;
        border-right: 0;
        animation: none;
    }
}

/* ============ PAGE TRANSITIONS ============ */
/* Every page does a real navigation (no SPA router), so the "loading" lag is
   the browser fetching header/sidebar/theme.js again. Revealing the shell in
   stages - box first, content after - hides that instead of fighting it. */

.site-header,
#sidebar-container,
main {
    opacity: 0;
    transition: opacity 0.25s ease, transform 0.25s ease;
}

.site-header {
    transform: translateY(-10px);
}

#sidebar-container {
    transform: translateX(-10px);
}

main {
    transform: translateY(14px) scale(0.98);
}

.site-header.is-visible,
#sidebar-container.is-visible,
main.is-visible {
    opacity: 1;
    transform: none;
}

/* Main's direct children (title, content blocks) reveal one at a time,
   staggered from JS, once the main box itself is visible. */
main > * {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 0.25s ease, transform 0.25s ease;
}

main > *.is-visible {
    opacity: 1;
    transform: none;
}

/* Played on the outgoing page right before navigating away. */
body.is-leaving {
    opacity: 0;
    transition: opacity 0.12s ease;
}
