/* MODAL GLOW - the same border shimmer every popup menu wears
 * (client/css/popup-focus.css), scaled up for a larger surface (issue
 * #918: Adam (Adoom666), "all popup modals need the glow shimmer around
 * the borders like a popup menu does. a tad more glod though since
 * theyre larger" - glod meaning glow).
 *
 * WHY A NEW FILE INSTEAD OF EDITING `.modal-content` IN styles.css.
 * `.modal-content` (client/css/styles.css) is the shared chassis every
 * centered dialog in both front-end trees borrows: 13 vanilla dialogs plus
 * every Svelte modal built on `web/src/lib/dialog-frame/ModalShell.svelte`,
 * which carries no `<style>` of its own and reads this class by name (see
 * that file's own header comment: "twenty two dialogs across both
 * front-end trees"). `styles.css` is already past this repo's file-size
 * cap (CLAUDE.md), so the glow is declared here, once, and reaches every
 * one of those dialogs with NO markup change anywhere: a restart, a
 * confirm, a text prompt, a folder pick, a session restore offer, the "?"
 * help panel, and every blueprint/catalog/launchpad/layout modal in
 * `web/`.
 *
 * ONE MORE SURFACE IS A CENTERED CARD OVER A BACKDROP BUT DOES NOT USE
 * `.modal-content` (it predates the shared chassis or needs its own
 * sizing): the help panel's media lightbox
 * (`.sidebar-help__lightbox-body`, media-lightbox.css). Only its travelling
 * ring (the `.mg-sheen` below) comes from this file; its position and its 1px
 * inset hairline box-shadow are its own (media-lightbox.css, in
 * `@layer legacy`, #1961), and the outer glow is not drawn on it.
 *
 * NOT IN SCOPE, ON THE REQUEST'S OWN TERMS ("a backdrop plus a centered
 * card"): `.config-editor-modal-content` (config-editor-modal.css) goes
 * full screen the moment a file is open and explicitly draws no border to
 * glow around ("a full-screen surface has no edge to draw"); the file
 * picker drawer, `.config-editor-picker-content` (config-drawer.css,
 * right-drawer.css), is a right-edge drawer "part of the frame, not a
 * card floating in it" with no radius and, when docked, no shadow at all
 * by its own explicit rule. A glow on either would contradict a
 * documented design decision about a surface that isn't a centered card
 * in the first place.
 *
 * THE SCALE, AS A MULTIPLIER ON THE MENU'S OWN VALUES (`--pf-glow` and its
 * two flat drop shadows in popup-focus.css), not a new effect: roughly
 * 1.3x the blur/offset and about ten more points of color-mix intensity.
 * If the menu's glow is retuned, apply the same ratio here by hand - there
 * is no live CSS binding between the two files, only this documented
 * relationship, because `--pf-glow` is scoped to `.popup-focus` rather
 * than declared on `:root`.
 *
 * THE SHIMMER TURNS ON THE COMPOSITOR (Joe, 2026-10-28, "modalring"; finding
 * u001-05). It used to animate a registered `@property` angle on
 * `.modal-content::after`, which re-resolves style and repaints the card every
 * frame while a dialog is open. It is now the popup-focus-turn recipe
 * (popup-focus.css, issue #1809): a conic square that ROTATES with `transform`
 * inside a masked 1px host. A pseudo-element cannot be host and rotating child
 * at once, so the card carries one real child, `<span class="mg-sheen"
 * aria-hidden="true">`, appended by client/js/modal-ring.js for every card
 * (the one place that owns it, so no builder edits it in). Same duration (6s),
 * easing (linear), direction (clockwise) and conic span (130deg to 230deg) as
 * the menus; this file keeps its own keyframes name so popup-focus.css stays
 * the only file that declares `popup-focus-turn`.
 *
 * THE RING RIDES THE CARD'S OWN BORDER, IT DOES NOT REPLACE THE BOX. Each
 * target keeps its real `border` from its own file; the `.mg-sheen` here is
 * `position: absolute; inset: 0`, the same footprint as that border, so
 * the travelling sheen and the static top-down gradient paint over it
 * with no layout cost and no change to any panel's size. `position:
 * relative` is added only where the target had no positioning context of
 * its own (`.modal-content`); the lightbox body
 * already declares it.
 *
 * REDUCED MOTION (prefers-reduced-motion, and `data-motion="off"`) drops the
 * sheen to transparent and stops the turn, exactly as popup-focus.css does for
 * menus, leaving the plain glow and
 * the static gradient border with no motion at all.
 *
 * EVERY COLOUR IS AN --oc-* TOKEN, re-derived from the active theme by
 * web/src/opscenter/tokens.css, so this glow repaints under every theme
 * and holds no literal of its own except the two flat black drop shadows,
 * which are black on purpose (see popup-focus.css's own header): they must
 * still read as a lift on a light theme, where every accent token is
 * itself light.
 */

@keyframes modal-glow-turn {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

.modal-content {
    position: relative;
}

.modal-content {
    --mg-glow: color-mix(in srgb, var(--oc-orange) 55%, transparent);
    box-shadow:
        0 4px 3px var(--mg-glow),
        0 10px 32px rgba(0, 0, 0, 0.6),
        0 3px 8px rgba(0, 0, 0, 0.4);
}

/* The media lightbox body (`.sidebar-help__lightbox-body`) sets its own position and hairline box-shadow in
 * media-lightbox.css, which now sits in `@layer legacy` (the unlayered-sheet ratchet, #1961). This unlayered file
 * would beat it, so it no longer restates either property for that box; only the travelling ring below applies to it. */

.modal-content > .mg-sheen,
.sidebar-help__lightbox-body > .mg-sheen {
    --mg-sheen: color-mix(in srgb, color-mix(in srgb, var(--oc-orange) 55%, var(--oc-text-bright)) 85%, transparent);
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    container-type: size;
    padding: 1px;
    border-radius: inherit;
    background: linear-gradient(to bottom, var(--oc-line-panel), var(--oc-strip-edge));
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
    mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    mask-composite: exclude;
}

/* The turning square: larger than the card's diagonal so the arc reaches every edge, measured off the host's own box
 * with container units. Only `transform` animates. */
.modal-content > .mg-sheen::before,
.sidebar-help__lightbox-body > .mg-sheen::before {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: calc(100cqw + 100cqh);
    height: calc(100cqw + 100cqh);
    margin: calc((100cqw + 100cqh) / -2) 0 0 calc((100cqw + 100cqh) / -2);
    background: conic-gradient(
        from 0deg,
        transparent 0deg,
        transparent 130deg,
        var(--mg-sheen) 180deg,
        transparent 230deg,
        transparent 360deg
    );
    will-change: transform;
    animation: modal-glow-turn 6s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
    .modal-content > .mg-sheen,
    .sidebar-help__lightbox-body > .mg-sheen {
        --mg-sheen: transparent;
    }

    .modal-content > .mg-sheen::before,
    .sidebar-help__lightbox-body > .mg-sheen::before {
        animation: none;
    }
}

/* ANIMATIONS SETTING (issue #1617): `html[data-motion="off"]` wears the reduced-motion look above, whatever the OS says;
 * the animation itself is stopped by the one rule in animation-pause.css. */
:root[data-motion="off"] .modal-content > .mg-sheen,
:root[data-motion="off"] .sidebar-help__lightbox-body > .mg-sheen {
    --mg-sheen: transparent;
}
