/* Native-feeling open/close motion for the platform's modals.
 *
 * Every page follows the same shape -- a fixed `.modal` backdrop that is
 * `display: none` until JS sets `display: flex` (or `block`), wrapping a
 * `.modal-content` box -- but nothing animated the transition, so a modal
 * snapped into existence. On a phone, inside the app's WebView, that snap is
 * the single clearest tell that a screen is a web page rather than a view.
 *
 * Opening needs no JS at all: a CSS animation restarts whenever an element goes
 * from `display: none` to displayed, so declaring the keyframes here animates
 * all ~40 existing modals without touching a single page's code.
 *
 * Closing does need help -- an element being hidden cannot animate itself out
 * of existence -- and that is what js/utlis/modal-motion.js adds, by way of the
 * `.mm-closing` class below.
 *
 * Load AFTER the page stylesheet: these rules deliberately override whatever
 * transition a page already declared for its own modal.
 */

/* Easing: a strong deceleration, so the box arrives quickly and settles. The
   overshoot-free curve is intentional -- a bouncy modal is charming once and
   irritating by the tenth time a student submits an exam. */
:root {
    --mm-ease-out: cubic-bezier(.16, 1, .3, 1);
    --mm-ease-in: cubic-bezier(.4, 0, 1, 1);
    --mm-in: 260ms;
    --mm-out: 180ms;
}

@keyframes mm-backdrop-in {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes mm-backdrop-out {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
    }
}

/* Rises and scales up from just under full size. Starting at 0.96 rather than
   something smaller keeps it feeling like the panel was already there and is
   coming forward, instead of growing from nothing. */
@keyframes mm-box-in {
    from {
        opacity: 0;
        transform: translateY(12px) scale(.96);
    }

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

@keyframes mm-box-out {
    from {
        opacity: 1;
        transform: translateY(0) scale(1);
    }

    to {
        opacity: 0;
        transform: translateY(6px) scale(.98);
    }
}

.modal,
.modal-overlay {
    animation: mm-backdrop-in var(--mm-in) ease both;
}

.modal > .modal-content,
.modal > .modal-dialog,
.modal-overlay > .modal-content {
    animation: mm-box-in var(--mm-in) var(--mm-ease-out) both;
}

/* Exit, driven by modal-motion.js. Faster than the entrance: a dismissal that
   lingers feels unresponsive, while an arrival that is too quick feels abrupt. */
.modal.mm-closing,
.modal-overlay.mm-closing {
    animation: mm-backdrop-out var(--mm-out) var(--mm-ease-in) both;
    /* The modal is on its way out; a stray click must not reopen anything. */
    pointer-events: none;
}

.modal.mm-closing > .modal-content,
.modal.mm-closing > .modal-dialog,
.modal-overlay.mm-closing > .modal-content {
    animation: mm-box-out var(--mm-out) var(--mm-ease-in) both;
}

/* ---- snappy variant (`data-modal-snap` on <body>) ----
 *
 * The exact motion of the video player's watch-stats modal
 * (.watch-stats-content in css/video-player.css): the same duration, but a
 * curve that overshoots, so the box is at full size well before the animation
 * ends and reads as arriving instantly rather than settling into place. The
 * default above is deliberately overshoot-free for modals a student meets
 * dozens of times; these pages are the teacher's own, opened a few times a
 * session, where the snap is worth it.
 *
 * Keep this in sync with wsContentIn / wsBackdropIn -- the point of the variant
 * is that the two are indistinguishable.
 */
@keyframes mm-box-in-snap {
    from {
        opacity: 0;
        transform: scale(.9) translateY(24px);
    }

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

body[data-modal-snap] .modal,
body[data-modal-snap] .modal-overlay {
    animation-duration: 250ms;
}

body[data-modal-snap] .modal > .modal-content,
body[data-modal-snap] .modal > .modal-dialog,
body[data-modal-snap] .modal-overlay > .modal-content {
    animation: mm-box-in-snap 300ms cubic-bezier(.34, 1.4, .64, 1) both;
}

/* The exit stays the default one: an overshoot on the way out just delays the
   dismissal. Restated only to outrank the entrance rule above. */
body[data-modal-snap] .modal.mm-closing > .modal-content,
body[data-modal-snap] .modal.mm-closing > .modal-dialog,
body[data-modal-snap] .modal-overlay.mm-closing > .modal-content {
    animation: mm-box-out var(--mm-out) var(--mm-ease-in) both;
}

/* ---- confirm dialog ----
 *
 * The whole component, appearance included -- not just its motion. It used to
 * live only in base.css, which take-exam.html does not load, so the exam submit
 * confirmation rendered as unstyled markup dumped at the bottom of the page:
 * no backdrop, no box, no centring. Defining it here and loading this file
 * wherever confirmDialog() is used is what makes it a dialog everywhere.
 *
 * base.css still carries the original rules; this file loads after it, so these
 * win on the pages that have both.
 */

.confirm-overlay {
    position: fixed;
    inset: 0;
    /* Darkened from .45 to keep the same visual weight now that the blur below
       is desktop-only. */
    background: rgba(0, 0, 0, .55);
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 20px;
    z-index: 20000;
    opacity: 0;
    /* Deliberately not `visibility`, which base.css also transitioned: it steps
       instead of fading, so it snapped the dialog away before the fade ended.
       The overlay node only exists while the dialog is open, so there is
       nothing to hide from the pointer in between. */
    visibility: visible;
    transition: opacity var(--mm-out) var(--mm-ease-in);
}

/* Desktop-only blur; see the .video-modal blur-gating comment in
   teacer-video.css for why a full-viewport blur is skipped on phones. */
@media (min-width: 900px) {
    .confirm-overlay {
        backdrop-filter: blur(3px);
        -webkit-backdrop-filter: blur(3px);
    }
}

.confirm-overlay.active {
    opacity: 1;
    transition: opacity var(--mm-in) ease;
}

.confirm-dialog {
    background: var(--background-color, #fff);
    color: var(--text-color, #14262a);
    border-radius: var(--border-radius, 14px);
    padding: 25px 30px;
    width: 100%;
    max-width: 400px;
    box-shadow: var(--shadow, 0 12px 40px rgba(0, 0, 0, .25));
    text-align: center;
    transform: translateY(12px) scale(.96);
    opacity: 0;
    transition: transform var(--mm-out) var(--mm-ease-in),
                opacity var(--mm-out) var(--mm-ease-in);
}

.confirm-overlay.active .confirm-dialog {
    transform: translateY(0) scale(1);
    opacity: 1;
    transition: transform var(--mm-in) var(--mm-ease-out),
                opacity var(--mm-in) var(--mm-ease-out);
}

.confirm-message {
    font-size: 1.1rem;
    font-weight: 500;
    line-height: 1.6;
    margin-bottom: 20px;
}

.confirm-actions {
    display: flex;
    justify-content: center;
    gap: 15px;
}

.confirm-actions .btn-confirm,
.confirm-actions .btn-cancel {
    padding: 10px 22px;
    border: none;
    border-radius: 10px;
    font-family: inherit;
    font-size: .95rem;
    font-weight: 600;
    cursor: pointer;
    transition: background .2s ease, color .2s ease, transform .1s ease;
}

.confirm-actions .btn-confirm:active,
.confirm-actions .btn-cancel:active {
    transform: scale(.97);
}

.confirm-actions .btn-confirm {
    background: var(--accent-color, #137980);
    color: var(--white, #fff);
}

.confirm-actions .btn-cancel {
    background: var(--dark-gray, #e2e8f0);
    color: var(--black, #14262a);
}

[data-theme="dark"] .confirm-actions .btn-cancel {
    background: #444;
    color: #e0e0e0;
}

/* Motion is decoration here -- the modal must still appear and disappear. */
@media (prefers-reduced-motion: reduce) {

    .modal,
    .modal-overlay,
    .modal > .modal-content,
    .modal > .modal-dialog,
    .modal-overlay > .modal-content,
    .modal.mm-closing,
    .modal-overlay.mm-closing,
    .modal.mm-closing > .modal-content,
    .modal.mm-closing > .modal-dialog,
    .modal-overlay.mm-closing > .modal-content {
        animation-duration: 1ms;
    }

    .confirm-overlay,
    .confirm-overlay.active,
    .confirm-dialog,
    .confirm-overlay.active .confirm-dialog {
        transition-duration: 1ms;
    }
}
