/*
 * async-fragments.css — presentation for the custom fragment runtime
 * (wwwroot/v2/js/fragment-runtime.js, ADR 0001). Plan §4.3 / §8.1.
 *
 * The runtime toggles aria-busy + .pc-fragment--loading on a host while it fetches,
 * and renders a .pc-fragment-error block (message + Retry button) on failure. This
 * file is the only place those states get styled — no markup or behavior lives here.
 */

/* --- Loading -------------------------------------------------------------- */
/* Search navigation feedback: keep the existing controls and layout, but make
   the short paint before navigation visible and prevent duplicate typed/scan
   submissions. */
input.pc-search--loading {
    cursor: progress;
    opacity: 0.65;
}

button.pc-search--loading {
    position: relative;
    cursor: progress !important;
}

button.pc-search--loading > svg {
    opacity: 0;
}

button.pc-search--loading::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 14px;
    height: 14px;
    margin: -8px 0 0 -8px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: pc-search-spin 0.7s linear infinite;
}

@keyframes pc-search-spin {
    to { transform: rotate(360deg); }
}

/* Reserve space so deferred content doesn't shift the layout when it arrives. */
[data-fragment-url].pc-fragment--loading {
    position: relative;
    min-height: 120px;
}

/* A centered spinner that only appears after a short delay, so fast loads
   never flash it (anti-flicker, §4.3). */
[data-fragment-url].pc-fragment--loading::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 28px;
    height: 28px;
    margin: -14px 0 0 -14px;
    border: 3px solid rgba(20, 30, 40, 0.12);
    border-top-color: #0092bc; /* Atlas Copco accent */
    border-radius: 50%;
    opacity: 0;
    animation:
        pc-fragment-spin 0.7s linear infinite,
        pc-fragment-appear 1ms linear 180ms forwards;
}

@keyframes pc-fragment-spin {
    to { transform: rotate(360deg); }
}

@keyframes pc-fragment-appear {
    to { opacity: 1; }
}

/* Respect reduced-motion: keep the delayed reveal, drop the spin. */
@media (prefers-reduced-motion: reduce) {
    button.pc-search--loading::after {
        animation: none;
    }

    [data-fragment-url].pc-fragment--loading::after {
        animation: pc-fragment-appear 1ms linear 180ms forwards;
    }
}

/* --- Error + Retry -------------------------------------------------------- */
.pc-fragment-error {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding: 16px;
    color: #5b6770;
    font-size: 14px;
    line-height: 1.5;
}

.pc-fragment-error__msg {
    margin: 0;
}

.pc-fragment-error__retry {
    appearance: none;
    border: 1px solid #0092bc;
    background: transparent;
    color: #0092bc;
    font: inherit;
    font-weight: 600;
    padding: 6px 14px;
    border-radius: 6px;
    cursor: pointer;
}

.pc-fragment-error__retry:hover {
    background: rgba(0, 146, 188, 0.08);
}

.pc-fragment-error__retry:disabled,
.pc-fragment-error__retry:disabled:hover {
    background: transparent;
    cursor: not-allowed;
    opacity: 0.55;
}

.pc-fragment-error__retry:focus-visible {
    outline: 2px solid #0092bc;
    outline-offset: 2px;
}
