/* TAILORBLEND's loading shimmer (ShimmerBar and PageShimmer): classic silver, for the few places with nothing to show yet.
   Grey bars, with one soft band of light crossing them all together: the gradient is fixed to the window, so neighbouring
   bars show neighbouring parts of the same band. Browsers that ignore a fixed background (iOS Safari) sweep each bar on its
   own instead. */

.tb-shimmer-bar {
    display: block;
    flex: none;
    width: var(--tb-shimmer-width, 100%);
    max-width: 100%;
    height: var(--tb-shimmer-height, var(--type-body-sm));
    background-color: var(--slate-200);
    background-image: linear-gradient(105deg, transparent 34%, var(--slate-100) 44%, var(--slate-50) 50%, var(--slate-100) 56%, transparent 66%);
    background-attachment: fixed;
    background-repeat: no-repeat;
    background-size: 100vw 100vh;
    border-radius: var(--radius-xs);
    /* Three passes, about 5 seconds: motion that never ends looks busy when something is stuck. "forwards" leaves the band
       off the bar, so what stays is a still bar. */
    animation: tb-shimmer-wave calc(var(--dur-slower) * 2.5) linear 3 forwards;
}

.tb-shimmer-bar.is-pill {
    border-radius: var(--radius-pill);
}

@keyframes tb-shimmer-wave {
    from {
        background-position: -100vw 0;
    }

    /* The wave rests for the last part of each pass, so it reads as a pulse of light rather than a conveyor belt. */
    70%,
    to {
        background-position: 100vw 0;
    }
}

/* Held back for the first 300 ms, so a quick answer shows nothing at all, then a slow fade, so an answer soon after replaces
   bars that have only begun to show rather than flashing them at full strength (measured: at 450-600 ms a quick fade flashed
   them for 90-240 ms). Only its opacity changes: the space stays taken, and the server's shimmer on the Create page is the
   same element until the builder replaces it, so it appears only once. */
.tb-shimmer {
    display: flex;
    flex-direction: column;
    gap: var(--space-group);
    animation: tb-shimmer-appear var(--dur-base) ease-in 300ms backwards;
}

@keyframes tb-shimmer-appear {
    from {
        opacity: 0;
    }
}

.tb-shimmer-label {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--fg-muted);
    font-family: var(--font-sans);
    font-size: var(--type-micro);
    font-weight: 700;
    letter-spacing: var(--track-widest);
    line-height: 1.3;
    text-transform: uppercase;
}

.tb-shimmer-label::before {
    width: 0.375rem;
    height: 0.375rem;
    flex: none;
    background: var(--slate-400);
    border-radius: 50%;
    content: "";
    animation: tb-shimmer-pulse calc(var(--dur-slower) * 2.5) ease-in-out 3;
}

@keyframes tb-shimmer-pulse {
    50% {
        opacity: 0.35;
    }
}

.tb-shimmer-stack {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 0;
}

/* The status a page keeps for screen readers while a shimmer shows: on the page, but not on the screen. */
.tb-shimmer-status {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Reduced motion, or a page that has failed (Blazor has shown its error bar): still, quiet bars. The wait before they appear
   stays, without the fade. */
@media (prefers-reduced-motion: reduce) {
    .tb-shimmer {
        animation-duration: 1ms;
    }

    .tb-shimmer-bar,
    .tb-shimmer-label::before {
        background-image: none;
        animation: none;
    }
}

body:has(#blazor-error-ui[style*="block"]) .tb-shimmer-bar,
body:has(#blazor-error-ui[style*="block"]) .tb-shimmer-label::before {
    animation: none;
}

body:has(#blazor-error-ui[style*="block"]) .tb-shimmer-bar {
    background-image: none;
}
