/*
    PWA surface for the hand-written install/offline layer.

    Loaded after the v7 stylesheets (Components/App.razor) and borrows their tokens unchanged:
    everything here either sits outside the shell's content (notices, reconnection overlay) or is a
    single topbar control, so no page styling is rewritten.

    Sources of the class names:
      .pwa-notices / .pwa-notice*  built by js/pwa.js showNotice()
      .pwa-install                 markup in Components/Layout/InstallApp.razor, shown only while
                                   js/pwa.js publishes an install state on <html>
      #components-reconnect-modal  markup in Components/App.razor; Blazor toggles the
                                   components-reconnect-* state classes on it
*/

/* --------------------------------------------------------------------- notices */

.pwa-notices {
    position: fixed;
    left: 50%;
    bottom: 22px;
    transform: translateX(-50%);
    display: grid;
    gap: 10px;
    width: min(440px, calc(100vw - 32px));
    z-index: 90;
    pointer-events: none;
}

.pwa-notice {
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 13px 15px;
    background: var(--u-paper, #fff);
    border: 1px solid var(--u-line, #e8e7ef);
    border-radius: 14px;
    color: var(--u-ink, #292840);
    box-shadow: 0 12px 34px #35304d1f;
}

.pwa-notice-body {
    display: grid;
    gap: 3px;
    min-width: 0;
}

.pwa-notice-body b {
    font-size: 12px;
    font-weight: 700;
    line-height: 1.35;
}

.pwa-notice-body span {
    font-size: 11px;
    line-height: 1.5;
    color: var(--u-muted, #77768c);
}

.pwa-notice-actions {
    display: flex;
    gap: 7px;
    margin-left: auto;
    flex-shrink: 0;
}

.pwa-notice-btn {
    padding: 8px 13px;
    border: 1px solid var(--u-line, #e8e7ef);
    border-radius: 10px;
    background: #fff;
    color: var(--u-brand-dark, #433965);
    font-size: 11px;
    font-weight: 650;
    white-space: nowrap;
}

.pwa-notice-btn.is-primary {
    background: var(--u-brand, #5c508e);
    border-color: var(--u-brand, #5c508e);
    color: #fff;
}

.pwa-notice-btn:disabled {
    opacity: .6;
}

.pwa-notice--offline {
    background: var(--u-peach, #fff0e3);
    border-color: #f2d7b4;
}

.pwa-notice--update {
    background: var(--u-lilac, #eeebf8);
    border-color: #d3c9e9;
}

.pwa-notice--info {
    background: var(--u-blue, #e9f2fb);
    border-color: #cfdcf1;
}

@media (max-width: 760px) {
    /* Above the fixed bottom navigation, which the shell reserves 105px for. */
    .pwa-notices {
        left: 12px;
        right: 12px;
        bottom: 78px;
        transform: none;
        width: auto;
    }

    .pwa-notice {
        flex-wrap: wrap;
    }

    .pwa-notice-actions {
        margin-left: 0;
        width: 100%;
    }

    .pwa-notice-actions .pwa-notice-btn {
        flex: 1;
    }
}

/* -------------------------------------------------------------- install button */

/*
    Hidden until js/pwa.js publishes the state on <html>, so a browser that offers no prompt
    (Firefox, desktop Safari) never shows a button that cannot do anything. Inside an installed
    window the button stays hidden for good.
*/
.pwa-install {
    display: none;
    align-items: center;
    gap: 7px;
    padding: 9px 14px;
    border: 1px solid #d8d0ea;
    border-radius: 12px;
    background: var(--u-lilac, #eeebf8);
    color: var(--u-brand-dark, #433965);
    font-size: 12px;
    font-weight: 650;
    white-space: nowrap;
}

html[data-pwa-installed="false"][data-pwa-installable="true"] .pwa-install,
html[data-pwa-installed="false"][data-pwa-ios="true"] .pwa-install {
    display: inline-flex;
}

/*
    An insecure origin (http://<lan-ip>:<port>) can never install: Chrome and Edge never fire
    beforeinstallprompt there, and Android's own "Install app" menu answers "This app cannot be
    installed". Leaving the button hidden makes that the only feedback the user gets, so on such an
    address the button is shown, relabelled by js/pwa.js, and its click names the HTTPS requirement.
*/
html[data-pwa-installed="false"][data-pwa-secure="false"] .pwa-install {
    display: inline-flex;
}

.pwa-install:hover {
    background: #e4dff4;
    border-color: #c8bce2;
}

/* Same 24px art set as the other topbar control (bell.svg), scaled down to fit the pill. */
.pwa-install .u-icon {
    width: 18px;
    height: 18px;
}

@media (max-width: 760px) {
    .pwa-install {
        justify-content: center;
        width: 34px;
        height: 34px;
        min-width: 34px;
        padding: 0;
    }

    .pwa-install span {
        display: none;
    }
}

/* --------------------------------------------------------- push badge opt-in */

/*
    The notifications popover's row (Components/Layout/MainLayout.razor) that turns the installed app's
    icon badge on for this device. Nothing is shown until js/push.js publishes a state on <html> that can
    actually badge the icon, so a browser without the Badging API, an iPhone whose app is not on the Home
    Screen, or a server without a VAPID key never offers a control that cannot do anything. A blocked
    permission stays visible: the row then says how to undo it, and the button is disabled by the script.
*/
.pwa-push {
    display: none;
    align-items: center;
    gap: 9px;
    padding: 2px 4px 10px;
    margin-bottom: 8px;
    border-bottom: 1px solid #f2f4f7;
    text-align: left;
}

html[data-push-supported="true"] .pwa-push {
    display: flex;
}

.pwa-push-copy {
    display: grid;
    gap: 2px;
    min-width: 0;
    flex: 1;
}

.pwa-push-copy b {
    font-size: 10px;
    color: var(--text, #172b4d);
}

.pwa-push-copy small {
    font-size: 8px;
    line-height: 1.45;
    color: var(--muted, #667085);
}

.pwa-push-btn {
    flex-shrink: 0;
    padding: 6px 11px;
    border: 1px solid var(--line, #e4e7ec);
    border-radius: 8px;
    background: #fff;
    color: var(--blue, #2563eb);
    font-size: 9px;
    font-weight: 800;
    white-space: nowrap;
}

.pwa-push-btn:hover:not(:disabled) {
    background: var(--blue2, #eff6ff);
    border-color: #93b4ff;
}

/* Once the device is subscribed the button only turns the badge off, so it reads as secondary. */
html[data-push="on"] .pwa-push-btn {
    color: #475467;
}

.pwa-push-btn:disabled {
    opacity: .6;
    cursor: default;
}

/* ------------------------------------------------------ reconnection overlay */

/*
    Blazor's reconnection handler looks for #components-reconnect-modal and only toggles the
    components-reconnect-show / -hide / -retrying / -failed / -rejected / -paused / -resume-failed
    classes on it, so the element has to hide itself when no class says otherwise (the E2E suite
    asserts it is not visible before it acts). The paused pair comes from the .NET 10 circuit
    pause: a hidden tab suspends the circuit, and -resume-failed means it did not come back.
*/
#components-reconnect-modal {
    position: fixed;
    inset: 0;
    z-index: 120;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: #29284080;
}

#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-paused,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-resume-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: flex;
}

.pwa-reconnect-card {
    display: grid;
    gap: 10px;
    width: min(400px, 100%);
    padding: 24px;
    background: var(--u-paper, #fff);
    border-radius: 20px;
    box-shadow: 0 24px 60px #35304d33;
    text-align: center;
}

.pwa-reconnect-card h2 {
    margin: 0;
    font-size: 17px;
    color: var(--u-ink, #292840);
}

.pwa-reconnect-card p {
    margin: 0;
    font-size: 12px;
    line-height: 1.55;
    color: var(--u-muted, #77768c);
}

.pwa-reconnect-actions {
    display: flex;
    justify-content: center;
    margin-top: 4px;
}

/* One sentence per state: the retrying copy is the norm, the paused copy covers a circuit the
   runtime suspended while the tab was hidden, and the three failure states share the failed
   sentence. All of them are in the markup so the overlay reads correctly before js/pwa.js has run. */
.pwa-reconnect-paused,
.pwa-reconnect-failed,
.pwa-reconnect-error {
    display: none;
}

/* Attempt counters the framework fills in (components-seconds-to-next-attempt,
   components-reconnect-current-attempt): only shown once an automatic retry has failed, which is
   exactly when Blazor adds components-reconnect-retrying. */
.pwa-reconnect-progress {
    display: none;
}

#components-reconnect-modal.components-reconnect-retrying .pwa-reconnect-progress {
    display: block;
    color: var(--u-brand-dark, #433965);
}

#components-reconnect-modal.components-reconnect-paused .pwa-reconnect-paused,
#components-reconnect-modal.components-reconnect-failed .pwa-reconnect-failed,
#components-reconnect-modal.components-reconnect-resume-failed .pwa-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected .pwa-reconnect-failed {
    display: block;
}

#components-reconnect-modal.components-reconnect-paused .pwa-reconnect-retrying,
#components-reconnect-modal.components-reconnect-failed .pwa-reconnect-retrying,
#components-reconnect-modal.components-reconnect-resume-failed .pwa-reconnect-retrying,
#components-reconnect-modal.components-reconnect-rejected .pwa-reconnect-retrying {
    display: none;
}

#components-reconnect-modal[data-pwa-reconnect-error="true"] .pwa-reconnect-error {
    display: block;
    color: #9a4034;
}