body {
    font-family: var(--font-stack);
}

.sk-root {
    display: contents;
}

/* View transitions.
   WHEN one runs is decided in routes/login/+page.svelte; these rules only say
   what it looks like. They live here because ::view-transition-* are
   document-level pseudo-elements and cannot be component-scoped.
   The auth card carries view-transition-name: auth-card (AuthShell.svelte), so
   it animates on its own while the root snapshot keeps its default cross-fade —
   the card leaves, the app fades in underneath it. Signing in has no incoming
   card, so only the -old rule matches; /login -> /login/mfa has both. */
@keyframes auth-card-out {
    to {
        opacity: 0;
        transform: translateX(-1.5rem);
    }
}

@keyframes auth-card-in {
    from {
        opacity: 0;
        transform: translateX(1.5rem);
    }
}

/* The UA cross-fade blends captures with plus-lighter, which washes out a
   custom animation. */
::view-transition-old(auth-card),
::view-transition-new(auth-card) {
    mix-blend-mode: normal;
}

::view-transition-old(auth-card) {
    animation: auth-card-out 220ms cubic-bezier(0.4, 0, 1, 1) forwards;
}

::view-transition-new(auth-card) {
    animation: auth-card-in 240ms cubic-bezier(0, 0, 0.2, 1) 40ms backwards;
}

/* The JS hook already skips the transition under reduced motion; this keeps the
   rules self-safe for any future caller that forgets to. */
@media (prefers-reduced-motion: reduce) {
    ::view-transition-old(auth-card),
    ::view-transition-new(auth-card) {
        animation: none;
    }
}
