/* ============================================================================
   Circuit recovery UI — what the customer sees when a Blazor Server circuit
   drops or faults. Replaces the unstyled blank purple overlay.

   Brand accent mirrors css/theme/colors.css (--color-primary:#5F368D). The rest
   is a restrained neutral system (slate ink, hairline borders, soft layered
   shadows) so the cards read as product chrome, not a template.
   ============================================================================ */

:root {
    --recovery-primary: #5F368D;        /* brand accent: buttons, links */
    --recovery-primary-hover: #4E2C75;
    --recovery-danger: #C0392B;         /* error glyph */
    --recovery-warning: #B7791F;        /* escalated (looped) glyph */
    --recovery-ink: #1F2430;            /* headings */
    --recovery-body: #5B6472;           /* body copy (>=4.5:1 on white) */
    --recovery-muted: #6B7280;          /* secondary copy (>=4.5:1 on white) */
    --recovery-line: #E6E7EC;           /* hairline borders */
}

/* Shared card chrome ------------------------------------------------------- */
.recovery-card,
.error-card {
    background: #fff;
    border: 1px solid var(--recovery-line);
    border-radius: 16px;
    width: calc(100% - 40px);
    text-align: center;
    box-shadow: 0 1px 3px rgba(16, 24, 40, .08), 0 16px 32px -12px rgba(16, 24, 40, .22);
    font-family: "Poppins", "Segoe UI", system-ui, sans-serif;
    /* margin:auto centers the card in its flex/scroll container and, paired with
       the container's overflow-y:auto, keeps the top reachable when the card is
       taller than a short viewport (e.g. a phone in landscape). */
    margin: auto;
}

.recovery-card h2,
.error-card h2 {
    margin: 0 0 8px;
    font-size: 19px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--recovery-ink);
}

.recovery-card p,
.error-card p {
    margin: 0 0 6px;
    font-size: 14.5px;
    line-height: 1.6;
    color: var(--recovery-body);
}

/* Shared primary action --------------------------------------------------- */
.recovery-btn {
    display: inline-block;
    margin-top: 18px;
    padding: 11px 24px;
    border: 0;
    border-radius: 10px;
    background: var(--recovery-primary);
    color: #fff;
    font-family: inherit;
    font-size: 14.5px;
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(16, 24, 40, .12);
    transition: background-color .15s ease;
}

    .recovery-btn:hover { background: var(--recovery-primary-hover); }

    .recovery-btn:focus-visible {
        outline: 2px solid var(--recovery-primary);
        outline-offset: 2px;
    }

/* ---------------------------------------------------------------------------
   1) RECONNECT MODAL  —  #components-reconnect-modal
   Blazor toggles these classes automatically as the circuit drops/recovers:
     .components-reconnect-show      reconnecting (auto-retrying)
     .components-reconnect-hide      reconnected  (hide)
     .components-reconnect-failed    retries exhausted (offer manual retry)
     .components-reconnect-rejected  server rejected (must reload)
--------------------------------------------------------------------------- */
#components-reconnect-modal {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1070;
    background: rgba(31, 18, 52, .55);
    backdrop-filter: blur(2px);
    align-items: center;
    justify-content: center;
    /* Scroll rather than clip a tall card on a short viewport. */
    overflow-y: auto;
    padding: 20px 0;
}

    #components-reconnect-modal.components-reconnect-show,
    #components-reconnect-modal.components-reconnect-failed,
    #components-reconnect-modal.components-reconnect-rejected {
        display: flex;
    }

    /* Gate the "Reconnecting…" overlay behind a short delay so a sub-second blip
       — e.g. the static→interactive render-mode handoff right after login — fully
       reconnects before the overlay ever becomes visible. The modal is displayed
       immediately (so it captures the page) but stays transparent for ~700ms, then
       fades in only if the circuit is still down. The .failed/.rejected states are
       intentionally excluded: they only fire after retries are exhausted (seconds
       in), so they appear instantly with no delay. */
    #components-reconnect-modal.components-reconnect-show {
        animation: recovery-reconnect-delayed-fade 1s ease-in;
    }

    @keyframes recovery-reconnect-delayed-fade {
        0%, 70% { opacity: 0; }
        100%    { opacity: 1; }
    }

    #components-reconnect-modal.components-reconnect-hide {
        display: none;
    }

.recovery-card {
    max-width: 380px;
    padding: 32px 32px 30px;
}

.recovery-spinner {
    width: 38px;
    height: 38px;
    margin: 0 auto 18px;
    border-radius: 50%;
    border: 2.5px solid #ECEAF1;
    border-top-color: var(--recovery-primary);
    animation: recovery-spin .8s linear infinite;
}

@keyframes recovery-spin {
    to { transform: rotate(360deg); }
}

/* Swap the message block based on circuit state. "reconnecting" shows while
   .components-reconnect-show; "failed" text shows once retries are exhausted. */
.recovery-failed-block { display: none; }

.components-reconnect-failed .recovery-reconnecting-block,
.components-reconnect-rejected .recovery-reconnecting-block { display: none; }

.components-reconnect-failed .recovery-failed-block,
.components-reconnect-rejected .recovery-failed-block { display: block; }

/* ---------------------------------------------------------------------------
   2) FATAL ERROR UI  —  #blazor-error-ui
   Blazor sets style="display:block" on this element when an unhandled
   exception escapes (circuit-fatal). Hidden by default.
--------------------------------------------------------------------------- */
#blazor-error-ui {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1080;
    background: rgba(248, 249, 251, .98);
    /* The framework forces display:block here, so flex centering can't apply;
       overflow-y:auto + the card's vertical margin handle short-viewport scroll. */
    overflow-y: auto;
}

.error-card {
    max-width: 440px;
    padding: 34px 34px 30px;
}

#blazor-error-ui .error-card {
    margin: 8vh auto;
}

/* Alert glyph in a soft tinted disc, far calmer than the old emoji + red bar. */
.error-icon {
    width: 52px;
    height: 52px;
    margin: 0 auto 16px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: #FBEAEA;
    color: var(--recovery-danger);
}

    .error-icon svg { width: 26px; height: 26px; display: block; }

.error-card .error-support { margin-top: 16px; font-size: 13px; color: var(--recovery-muted); }
.error-card .error-support a { color: var(--recovery-primary); text-decoration: none; }
.error-card .error-support a:hover { text-decoration: underline; }

/* Loop-guard escalation: after repeated reloads, JS adds .recovery-looped so we
   stop offering reload (which would loop) and give a clear way out (home + email). */
.error-card .error-looped-msg { display: none; }
.error-card .error-looped-actions { display: none; }

/* Secondary escape, shown only once reload is exhausted so the full-screen
   overlay is never a dead end. */
.recovery-btn-link {
    display: inline-block;
    margin-top: 16px;
    padding: 10px 22px;
    border: 1px solid var(--recovery-line);
    border-radius: 10px;
    background: #fff;
    color: var(--recovery-ink);
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    transition: background-color .15s ease;
}

    .recovery-btn-link:hover { background: #F6F5F9; }

    .recovery-btn-link:focus-visible {
        outline: 2px solid var(--recovery-primary);
        outline-offset: 2px;
    }

.error-card.recovery-looped .error-icon { background: #FBF1DA; color: var(--recovery-warning); }

    .error-card.recovery-looped .recovery-btn { display: none; }

    /* The looped message already gives the support address, so drop the duplicate line. */
    .error-card.recovery-looped .error-support { display: none; }

    .error-card.recovery-looped .error-looped-actions { display: block; }

    .error-card.recovery-looped .error-looped-msg {
        display: block;
        background: #FBF7EC;
        border: 1px solid #ECDCB0;
        border-radius: 10px;
        padding: 11px 14px;
        margin-top: 16px;
        font-size: 13px;
        line-height: 1.5;
        color: #7A5B12;
    }

        .error-card.recovery-looped .error-looped-msg a { color: #7A5B12; font-weight: 600; }
