/* Reconnect dialog (markup in App.razor, behaviour in customjs/blazor-reconnect-custom.js).
   The script sets data-state (connecting, retrying, failed, paused, resume-failed) and data-offline on the dialog;
   an element with data-for="a b" only shows in those states. The dialog lives outside MainLayout, so dark mode
   follows html[data-theme] (set before the first paint, kept in step by theme.js), not .pn-dark. */

.pn-reconnect {
    --pn-rc-tone: var(--mud-palette-primary, #6646f0);
    /* MudBlazor's reset zeroes every margin, which drops a modal <dialog> in the top-left corner. */
    position: fixed;
    inset: 0;
    margin: auto;
    width: min(420px, calc(100vw - 32px));
    height: fit-content;
    max-height: calc(100dvh - 32px);
    border: 0;
    padding: 0;
    background: transparent;
    color: var(--mud-palette-text-primary, #15151c);
    overflow: visible
}

/* The dialog takes focus when nothing inside can; the card is the visible element, not its box. */
.pn-reconnect:focus,
.pn-reconnect:focus-visible {
    outline: none
}

.pn-reconnect[data-state="failed"],
.pn-reconnect[data-state="resume-failed"] {
    --pn-rc-tone: var(--mud-palette-error, #c62828)
}

.pn-reconnect[data-state="paused"] {
    --pn-rc-tone: var(--mud-palette-warning, #b45309)
}

/* One state at a time (no data-state yet reads as connecting). */
.pn-reconnect:not([data-state]) [data-for]:not([data-for~="connecting"]),
.pn-reconnect[data-state="connecting"] [data-for]:not([data-for~="connecting"]),
.pn-reconnect[data-state="retrying"] [data-for]:not([data-for~="retrying"]),
.pn-reconnect[data-state="failed"] [data-for]:not([data-for~="failed"]),
.pn-reconnect[data-state="paused"] [data-for]:not([data-for~="paused"]),
.pn-reconnect[data-state="resume-failed"] [data-for]:not([data-for~="resume-failed"]) {
    display: none
}

/* Blips usually heal within a second: the backdrop and the card wait before showing so they never flash. The open
   dialog still blocks the page meanwhile (clicks would be lost anyway). */
.pn-reconnect::backdrop {
    background: rgba(11, 11, 16, .42);
    backdrop-filter: blur(6px) saturate(.85);
    -webkit-backdrop-filter: blur(6px) saturate(.85);
    animation: pn-rc-fade .3s ease .5s both
}

.pn-reconnect[open] .pn-rc-card {
    animation: pn-rc-in .36s var(--pn-ease-out, cubic-bezier(.23, 1, .32, 1)) .5s both
}

@keyframes pn-rc-fade {
    from { opacity: 0 }
    to { opacity: 1 }
}

@keyframes pn-rc-in {
    from { opacity: 0; transform: translateY(10px) scale(.97) }
    to { opacity: 1; transform: none }
}

.pn-rc-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    padding: 32px 28px 26px;
    text-align: center;
    border-radius: calc(var(--pn-radius, 14px) + 4px);
    border: 1px solid var(--pn-line);
    background: var(--mud-palette-surface, #fff);
    box-shadow: 0 1px 2px rgba(11, 11, 16, .06), 0 24px 60px -12px rgba(11, 11, 16, .35);
    font-family: "Outfit", system-ui, sans-serif;
    overflow: hidden
}

/* A thin bar of the state's colour along the top edge. */
.pn-rc-card::before {
    content: "";
    position: absolute;
    inset: 0 0 auto;
    height: 3px;
    background: var(--pn-rc-tone);
    transition: background-color var(--pn-dur, 240ms) ease
}

html[data-theme="dark"] .pn-rc-card {
    border-color: rgba(237, 237, 242, .10);
    box-shadow: 0 1px 0 rgba(255, 255, 255, .04) inset, 0 28px 70px -10px rgba(0, 0, 0, .65)
}

html[data-theme="dark"] .pn-reconnect::backdrop {
    background: rgba(5, 5, 8, .6)
}

/* ---------- Icon ---------- */

.pn-rc-visual {
    position: relative;
    display: grid;
    place-items: center;
    width: 76px;
    height: 76px;
    margin-bottom: 2px
}

.pn-rc-icon {
    position: relative;
    z-index: 1;
    display: grid;
    place-items: center;
    width: 64px;
    height: 64px;
    border-radius: 50%;
    color: var(--pn-rc-tone);
    background: color-mix(in srgb, var(--pn-rc-tone) 13%, transparent);
    transition: color var(--pn-dur, 240ms) ease, background-color var(--pn-dur, 240ms) ease
}

.pn-rc-icon svg {
    width: 30px;
    height: 30px
}

.pn-rc-ring {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    border: 2px solid var(--pn-rc-tone);
    opacity: 0;
    pointer-events: none
}

.pn-reconnect:is(:not([data-state]), [data-state="connecting"], [data-state="retrying"]) .pn-rc-ring {
    animation: pn-rc-ping 2s cubic-bezier(.2, .6, .35, 1) infinite
}

.pn-rc-ring:nth-child(2) {
    animation-delay: 1s !important
}

@keyframes pn-rc-ping {
    from { transform: scale(.82); opacity: .55 }
    to { transform: scale(1.35); opacity: 0 }
}

/* The signal arcs light up from the inside out, like a search. */
.pn-rc-wave {
    animation: pn-rc-wave 1.6s ease-in-out infinite
}

.pn-rc-wave-2 { animation-delay: .2s }
.pn-rc-wave-3 { animation-delay: .4s }

@keyframes pn-rc-wave {
    0%, 100% { opacity: .25 }
    40% { opacity: 1 }
}

/* Waiting for the next attempt: the signal rests. */
.pn-reconnect[data-state="retrying"] .pn-rc-wave {
    animation: none;
    opacity: .35
}

.pn-reconnect[data-state="retrying"] .pn-rc-wave-1 {
    opacity: 1
}

/* ---------- Text ---------- */

.pn-rc-text {
    display: flex;
    flex-direction: column;
    gap: 6px
}

.pn-rc-title {
    margin: 0;
    font-family: var(--pn-font-display);
    font-size: 1.2rem;
    font-weight: 700;
    letter-spacing: -.01em;
    line-height: 1.3;
    text-wrap: balance
}

.pn-rc-desc {
    margin: 0;
    font-size: .95rem;
    line-height: 1.5;
    color: var(--mud-palette-text-secondary, #5d5d6e);
    text-wrap: pretty
}

.pn-rc-desc strong {
    color: var(--mud-palette-text-primary, #15151c);
    font-weight: 600;
    font-variant-numeric: tabular-nums
}

.pn-rc-meta {
    margin: -6px 0 0;
    font-size: .8rem;
    color: var(--mud-palette-text-secondary, #5d5d6e);
    font-variant-numeric: tabular-nums;
    opacity: .85
}


/* ---------- Progress ---------- */

.pn-rc-progress {
    position: relative;
    width: 100%;
    max-width: 260px;
    height: 4px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--pn-rc-tone) 14%, transparent);
    overflow: hidden
}

.pn-rc-progress span {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: var(--pn-rc-tone);
    transform-origin: left center
}

/* Trying right now: indeterminate. */
.pn-reconnect:is(:not([data-state]), [data-state="connecting"]) .pn-rc-progress span {
    width: 40%;
    animation: pn-rc-slide 1.3s cubic-bezier(.65, 0, .35, 1) infinite
}

@keyframes pn-rc-slide {
    from { transform: translateX(-100%) }
    to { transform: translateX(250%) }
}

/* Waiting: the bar empties as the countdown runs (--pn-rc-fill, 1 → 0, set by the script every second). */
.pn-reconnect[data-state="retrying"] .pn-rc-progress span {
    transform: scaleX(var(--pn-rc-fill, 1));
    transition: transform 1s linear
}

/* ---------- Offline hint ---------- */

.pn-rc-offline {
    display: none;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 8px 12px;
    border-radius: var(--pn-radius-md);
    font-size: .85rem;
    font-weight: 500;
    color: var(--mud-palette-warning-darken, #b45309);
    background: color-mix(in srgb, var(--mud-palette-warning, #b45309) 12%, transparent)
}

html[data-theme="dark"] .pn-rc-offline {
    color: var(--mud-palette-warning-lighten, #fbbf24)
}

.pn-rc-offline svg {
    flex: none;
    width: 16px;
    height: 16px
}

.pn-reconnect[data-offline] .pn-rc-offline {
    display: flex
}

/* ---------- Actions ---------- */

.pn-rc-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    width: 100%
}

.pn-rc-btn {
    flex: 1 1 140px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 10px 18px;
    border: 1px solid var(--pn-line);
    border-radius: var(--pn-radius-md);
    background: transparent;
    color: var(--mud-palette-text-primary, #15151c);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background-color var(--pn-dur-fast, 180ms) ease, filter var(--pn-dur-fast, 180ms) ease,
    transform var(--pn-dur-press, 140ms) var(--pn-ease-out, ease)
}

.pn-rc-btn--primary,
.pn-reconnect[data-state="resume-failed"] #components-reload-button {
    border-color: transparent;
    background: var(--mud-palette-primary, #6646f0);
    color: var(--mud-palette-primary-text, #fff)
}

.pn-rc-btn:focus-visible {
    outline: 2px solid var(--mud-palette-primary, #6646f0);
    outline-offset: 2px
}

.pn-rc-btn:active {
    transform: scale(.97)
}

.pn-rc-btn:disabled {
    opacity: .6;
    cursor: progress
}

@media (hover: hover) and (pointer: fine) {
    .pn-rc-btn:hover {
        background: color-mix(in srgb, var(--mud-palette-text-primary, #15151c) 6%, transparent)
    }

    .pn-rc-btn--primary:hover,
    .pn-reconnect[data-state="resume-failed"] #components-reload-button:hover {
        background: var(--mud-palette-primary, #6646f0);
        filter: brightness(1.08)
    }
}

.pn-rc-note {
    margin: -4px 0 0;
    font-size: .78rem;
    line-height: 1.45;
    color: var(--mud-palette-text-secondary, #5d5d6e);
    opacity: .85
}

/* ---------- Phones: a sheet at the bottom, within reach of the thumb ---------- */

@media (max-width: 599.98px) {
    .pn-reconnect {
        width: calc(100vw - 24px);
        margin: auto auto max(12px, env(safe-area-inset-bottom))
    }

    .pn-rc-card {
        padding: 26px 20px 20px
    }

    .pn-rc-btn {
        flex-basis: 100%
    }
}

@media (prefers-reduced-motion: reduce) {
    .pn-rc-ring,
    .pn-rc-wave,
    .pn-rc-progress span {
        animation: none !important
    }

    .pn-rc-wave { opacity: 1 }

    .pn-reconnect:is(:not([data-state]), [data-state="connecting"]) .pn-rc-progress span {
        width: 100%;
        opacity: .45
    }

    .pn-reconnect[data-state="retrying"] .pn-rc-progress span {
        transition: none
    }

    .pn-reconnect[open] .pn-rc-card {
        animation-name: pn-rc-fade;
        animation-duration: .15s
    }
}
