/* Blazor validation and error-boundary conventions. Everything visual comes from the
   Aurora tokens in _content/Parrot.SharedComponents/css; page rules below are being
   replaced by scoped, token-driven stylesheets. */
.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}
.invalid {
    outline: 1px solid #e50000;
}
.validation-message {
    color: #e50000;
}
.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}
    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

/* ── Arrivals ─────────────────────────────────────────────────────────────
   A new screen in the dashboard eases up into place instead of snapping in.
   Blazor inserts the new page's root elements into the shell's main column,
   and an animation on those children plays on insertion, so no script is
   involved. Fill mode is "backwards" on purpose: once the animation ends the
   element carries no transform, so fixed-position dialogs inside a page are
   never re-anchored to it. */
@keyframes page-enter {
    from { opacity: 0; transform: translateY(8px); }
}

.app-main > * {
    animation: page-enter 260ms cubic-bezier(0.2, 0.7, 0.2, 1) backwards;
}

@media (prefers-reduced-motion: reduce) {
    .app-main > * { animation: none; }
}

/* ── Switching screens from the sidebar ───────────────────────────────────
   Driven by js/nav-pending.js. The clicked item takes the selected look at
   once, with a soft pulse while the screen is on its way. If the wait is
   long enough to notice, the current screen dims slightly and the top
   hairline (the ActivityBar) runs; a quick switch shows neither. */
/* Selectors are doubled/qualified to outrank the components' scoped rules,
   which load after this file. */
.nav-item.nav-item.is-pending {
    color: var(--colors-interaction-selected-foreground);
    background: var(--colors-interaction-selected);
    animation: nav-pending-pulse 1.2s ease-in-out infinite;
}

@keyframes nav-pending-pulse {
    50% { opacity: 0.6; }
}

/* The rail's own active highlight steps back while another item is pending. */
html.is-navigating .nav-item.is-active:not(.is-pending) {
    background: transparent;
    color: inherit;
}

.app-shell .app-main {
    transition: opacity 200ms ease;
}

html.is-navigating .app-shell .app-main {
    opacity: 0.55;
}

html.is-navigating .activity {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .nav-item.nav-item.is-pending { animation: none; }
}

/* The relay dots over a slow switch, drawn by nav-pending.js: the same three
   dots as CadenceLoader's RelayDots, each hopping in turn and flashing the
   brand's terracotta at the top of its hop, on a small frosted pill so they
   read over any screen. They only appear once a switch has taken 400 ms. */
.nav-loader {
    position: fixed;
    left: var(--nav-loader-x, 50%);
    top: var(--nav-loader-y, 50%);
    z-index: 950;
    display: flex;
    gap: 6px;
    padding: 12px 16px;
    color: var(--colors-text-secondary);
    background: color-mix(in srgb, var(--colors-surface-elevated) 85%, transparent);
    backdrop-filter: blur(6px);
    border: 1px solid var(--colors-surface-border);
    border-radius: 999px;
    box-shadow: 0 4px 16px var(--colors-surface-shadow);
    pointer-events: none;
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.92);
    transition: opacity 220ms var(--cadence-ease), transform 220ms var(--cadence-ease);
}

.nav-loader.is-on {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
}

.nav-loader span {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
    animation: nav-loader-hop 1.5s var(--cadence-ease) infinite;
}

.nav-loader span:nth-child(2) { animation-delay: 0.25s; }
.nav-loader span:nth-child(3) { animation-delay: 0.5s; }

@keyframes nav-loader-hop {
    0%, 40%, 100% { transform: translateY(0); background: currentColor; }
    20%           { transform: translateY(-4px); background: var(--cadence-terracotta); }
}

@media (prefers-reduced-motion: reduce) {
    .nav-loader span { animation: nav-loader-fade 1.5s ease-in-out infinite; }
    .nav-loader span:nth-child(2) { animation-delay: 0.25s; }
    .nav-loader span:nth-child(3) { animation-delay: 0.5s; }
    @keyframes nav-loader-fade { 50% { opacity: 0.35; } }
}
