/*
 * SIS kit global rules that CSS isolation cannot reach (enrollment redesign, 2026-09-28).
 * MudDialogProvider / MudSnackbarProvider render outside any component's scope, so the dialog/bottom-sheet container
 * and the toast host are styled here by class. Everything else belongs in a component's .razor.css.
 * Owner: SisKit dialog/sheet shell (Wave 1 task H). Tokens: sis-tokens.css.
 * Loads after _content/MudBlazor/MudBlazor.min.css (see Components/App.razor), so equal-specificity rules here win
 * without needing !important.
 */

/*
 * Dialog / bottom-sheet shell (task H — SisDialogOptions + SisDialogLayout).
 *
 * MudBlazor 7.15's DialogOptions has no Class/ClassBackground — only BackgroundClass, which MudDialogInstance
 * applies to the *sibling* MudOverlay element, not to the dialog box itself (verified by decompiling
 * MudDialogInstance.BuildRenderTree: the overlay and the role="dialog" div are adjacent children of
 * .mud-dialog-container, in that order, with only a whitespace text node between them). SisDialogOptions sets
 * BackgroundClass to "sis-dialog-scrim" (+ "sis-dialog-scrim--narrow"/"--alert"), so the rules below reach the real
 * .mud-dialog box with an adjacent-sibling selector instead of touching every dialog call site's own <MudDialog
 * Class="…">. SisDialogLayout.razor.css owns the padding/gap/typography *inside* the box; this file only owns the
 * box itself (size/position/elevation) and the scrim tint.
 *
 * The gallery's static specimens (no MudOverlay/MudDialog present, just a bare <SisDialogLayout> in a box) use
 * .sis-dialog-frame / .sis-dialog-frame--narrow instead of the .sis-dialog-scrim(-…) + .mud-dialog pair, sharing
 * every rule below so a static specimen can never visually drift from what DialogService actually renders.
 */

.mud-overlay.sis-dialog-scrim .mud-overlay-scrim {
    background-color: var(--sis-scrim);
    border-color: transparent;
}

.sis-dialog-scrim + .mud-dialog,
.sis-dialog-frame {
    width: min(540px, calc(100vw - 32px));
    border-radius: var(--sis-radius-dialog);
    background-color: var(--sis-surface);
    box-shadow: var(--sis-shadow-dialog);
    animation: sis-dialog-in var(--sis-duration) var(--sis-ease) both;
    /* Boards use browser-default text metrics; MudBlazor's own body rule sets line-height:1.43 and
       letter-spacing:.01071em, which .mud-dialog inherits. Reset here too (SisDialogLayout.razor.css resets again
       at its own root) so the box is "normal" even before SisDialogLayout's content mounts. */
    line-height: normal;
    letter-spacing: normal;
}

.sis-dialog-scrim--narrow + .mud-dialog,
.sis-dialog-frame--narrow {
    width: min(500px, calc(100vw - 32px));
}

/* Alert is narrower than Default but not as narrow as Narrow — CartFailed_v2's own alertdialog is 520px (vs
   EnrolledWithdraw_v2's 500px alertdialog, which Narrow matches). Comes after the --narrow rule above so it wins
   despite equal selector specificity: Alert's BackgroundClass carries both marker classes. */
.sis-dialog-scrim--alert + .mud-dialog,
.sis-dialog-frame--alert {
    width: min(520px, calc(100vw - 32px));
}

/* Result (SisResultDialog): an icon, a title, one line and its buttons -- at 500px+ the short text floats in a wide box
   under oversized buttons, so it gets a compact width. Below 960px the bottom-sheet rules further down still win. */
.sis-dialog-scrim--result + .mud-dialog {
    width: min(400px, calc(100vw - 32px));
}

/* Mud's own DialogContent wrapper adds padding/margin (0 24px / 8px 0); SisDialogLayout.razor.css owns spacing
   instead, so neutralize Mud's here rather than depending on every dialog author remembering Gutters="false". */
.sis-dialog-scrim + .mud-dialog .mud-dialog-content {
    padding: 0;
    margin: 0;
}

@keyframes sis-dialog-in {
    from {
        opacity: 0;
        transform: translateY(8px) scale(0.98);
    }

    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

@keyframes sis-sheet-in {
    from {
        transform: translateY(100%);
    }

    to {
        transform: translateY(0);
    }
}

/* <960px: full-width bottom sheet, slid up from the bottom edge instead of the desktop centered dialog. Only the
   real dialog box gets position:fixed (pinning it to the viewport, out of .mud-dialog-container's flex layout
   entirely — no Position override needed, the container's center/top/bottom alignment classes stop mattering once
   the box is out of flow). The gallery's static .sis-dialog-frame specimen stays in normal flow inside its own
   GalleryFrame stage box — only a real dialog should escape to the viewport — but still gets the same visual
   treatment (radius, shadow, max-height, slide-up) so it reads as "this is what the sheet looks like" without
   fighting the gallery page's own layout. */
@media (max-width: 959.98px) {
    .sis-dialog-scrim + .mud-dialog,
    .sis-dialog-scrim--narrow + .mud-dialog {
        position: fixed;
        inset: auto 0 0 0;
        width: 100%;
        max-width: 100%;
        margin: 0;
    }

    .sis-dialog-frame,
    .sis-dialog-frame--narrow {
        width: 100%;
    }

    .sis-dialog-scrim + .mud-dialog,
    .sis-dialog-scrim--narrow + .mud-dialog,
    .sis-dialog-frame,
    .sis-dialog-frame--narrow {
        border-radius: var(--sis-radius-sheet) var(--sis-radius-sheet) 0 0;
        box-shadow: var(--sis-shadow-sheet);
        max-height: 92dvh;
        overflow-y: auto;
        overscroll-behavior: contain;
        animation: sis-sheet-in var(--sis-duration) var(--sis-ease) both;
    }
}

/* After the <960px block above so it wins there too (equal specificity, source order decides) — without this
   ordering, a reduced-motion user at a mobile width would still get the sheet's slide-up animation. */
@media (prefers-reduced-motion: reduce) {
    .sis-dialog-scrim + .mud-dialog,
    .sis-dialog-frame {
        animation: none;
    }
}

/* Content that replaces a loading skeleton: a short fade + 6px rise so it lands instead of popping in. Applied from
   the owning component's CSS (animation: var(--sis-enter-animation)) so inner elements keep data-slot styling.
   Opacity and transform only; fill-mode "backwards" means the end state is the element's plain style, so nothing
   depends on the animation having run. Reduced motion turns it into "none". */
:root {
    --sis-enter-animation: sis-enter 280ms cubic-bezier(0.22, 0.61, 0.36, 1) backwards;
}

@media (prefers-reduced-motion: reduce) {
    :root {
        --sis-enter-animation: none;
    }
}

@keyframes sis-enter {
    from {
        opacity: 0;
        transform: translateY(6px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}
