/* ============================================================================
 * GP Mobile Surface — shared mobile-first surface for portal/app modals
 * ----------------------------------------------------------------------------
 * Replaces desktop-style centered modals on MOBILE with the patterns mandated by
 * docs/MOBILE_DESIGN_SYSTEM.md (§4/§6): a full-screen Push View ("cover") and a
 * Bottom Sheet ("sheet"). DESKTOP keeps the existing centered modal unchanged.
 *
 * Substrate: native <dialog> + showModal() (top layer → renders above the 9999
 * mobile header / 9997 bottom nav with no z-index juggling; free focus-trap,
 * background inert, ::backdrop, ESC). The JS controller is js/gp-surface.js.
 *
 * Adoption: a surface is any element carrying BOTH its legacy modal class (e.g.
 * .gp-modal-overlay) AND `.gp-surface` + `data-gp-surface="cover|sheet"`. The
 * legacy class still drives the DESKTOP look; the rules below take over on mobile.
 *
 * PHASE 1 (pilot): cover mode only, adopted by #addVideoModal on the gymnast
 * profile. Sheet mode is stubbed at the bottom and built in Phase 4 (#6).
 *
 * NOTE (token reconciliation deferred to Phase 5): consumes the wired --gp-*
 * tokens (css/gp-mobile-core.css), not the design-doc --bg-base/--accent-gold
 * names. Do not introduce those here — that is WS-2.5 token-system territory.
 *
 * @package Gymnastics_Plus
 * @since 2.3.47
 * ============================================================================ */

/* ----------------------------------------------------------------------------
 * 1. BASE — make the <dialog> behave like the legacy .gp-modal-overlay
 * ----------------------------------------------------------------------------
 * A <dialog> ships UA styles (border, margin:auto, padding:1em, width/height:
 * fit-content, background:white) that fight the full-bleed overlay. Neutralize
 * only what the .gp-modal-overlay class does NOT already set (it provides
 * position:fixed, inset:0, padding, background dim, blur, z-index, display:none).
 * -------------------------------------------------------------------------- */
dialog.gp-surface {
    max-width: none;
    max-height: none;
    width: auto;
    height: auto;
    margin: 0;
    border: 0;
    color: inherit;
    overflow: visible; /* the inner .gp-modal panel owns scrolling */
}

/* The dialog's own dim (from .gp-modal-overlay background) is the scrim, so the
 * native ::backdrop would double up — keep it transparent. */
dialog.gp-surface::backdrop {
    background: transparent;
}

/* showModal() sets [open] but never the legacy `.active` class, so we must
 * restore the open/visible state the .active rules used to provide:
 *   .gp-modal-overlay        { display:none; opacity:0 }
 *   .gp-modal-overlay.active { display:flex; opacity:1 }
 *   .gp-modal-overlay.active .gp-modal { transform: scale(1) }
 * Specificity dialog.gp-surface[open] (0,2,1) beats .gp-modal-overlay (0,1,0). */
dialog.gp-surface[open] {
    display: flex;
    opacity: 1;
    visibility: visible; /* some surfaces hide via visibility (e.g. .ct-modal) */
}
dialog.gp-surface[open] .gp-modal {
    transform: scale(1);
}

/* The panel is focused on open (js focusPanel) to keep focus inside the dialog
 * without landing on an input (which would pop the keyboard) — it isn't
 * Tab-reachable, so suppress its focus ring (the "blue box"). Real controls
 * keep their own focus rings. */
dialog.gp-surface .gp-modal:focus {
    outline: none;
}

/* When any surface is open, hide the bottom tab nav so a cover is truly the only
 * surface (top-layer already covers it visually; this is belt-and-suspenders and
 * the documented integration hook that replaces mind-lab's per-template override). */
body.gp-surface-open .gp-bottom-nav {
    display: none !important;
}

/* In-surface error banner: hidden everywhere by default. It is only revealed
 * (`.is-visible`) inside the mobile media query, so DESKTOP keeps its existing
 * toast and never shows this unstyled. The controller injects the element. */
.gp-surface__error {
    display: none;
}

/* ----------------------------------------------------------------------------
 * 2. COVER (full-screen push view) — MOBILE ONLY
 * ----------------------------------------------------------------------------
 * 1024px matches css/gp-mobile-single.css (single-page mobile breakpoint). These
 * rules must beat the generic ".gp-modal → bottom sheet" morph in
 * gp-mobile-single.css:426 + gp-profile.css:2122, which use !important — so cover
 * overrides carry !important AND higher specificity (the dialog + attribute).
 * Phase 5 deletes those duplicated morphs and most of these !important fall away.
 * -------------------------------------------------------------------------- */
@media (max-width: 1024px) {

    /* The dialog becomes an opaque, full-bleed container (no dim — the cover IS
     * the screen). align-items:stretch beats the bottom-sheet's flex-end. */
    dialog.gp-surface[data-gp-surface="cover"] {
        padding: 0 !important;
        align-items: stretch !important;
        justify-content: stretch !important;
        background: var(--gp-card-bg, #ffffff) !important;
        -webkit-backdrop-filter: none !important;
        backdrop-filter: none !important;
        overflow: hidden !important;  /* lock the frame — only .gp-modal-body scrolls */
    }

    /* Panel fills the dynamic viewport. 100vh first (old browsers), then 100dvh
     * (modern) so the mobile address-bar resize never clips the footer. */
    dialog.gp-surface[data-gp-surface="cover"] .gp-modal {
        max-width: 100% !important;
        max-height: none !important;
        width: 100% !important;
        height: 100vh !important;
        height: 100dvh !important;
        margin: 0 !important;
        border-radius: 0 !important;
        box-shadow: none !important;
        overflow: hidden !important; /* only .gp-modal-body scrolls (self-contained; some panels set their own overflow) */
        display: flex !important;            /* self-contained: body (flex:1) grows, */
        flex-direction: column !important;   /* footer pins to the bottom (panels outside the profile lack this) */
        transform: translateY(0); /* slide-up target; see @starting-style below */
        transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
    }

    /* Native slide-up (bottom → top) where supported; instant + harmless otherwise. */
    @starting-style {
        dialog.gp-surface[data-gp-surface="cover"][open] .gp-modal {
            transform: translateY(100%);
        }
    }

    /* Header = 56px top nav bar. Close control moves to the LEFT (push-view
     * "back" affordance); title sits next to it. Sticky, safe-area aware. */
    dialog.gp-surface[data-gp-surface="cover"] .gp-modal-header {
        position: sticky;
        top: 0;
        z-index: 10;
        display: flex;
        align-items: center;
        justify-content: space-between; /* title left, ✕ right */
        gap: 8px;
        min-height: var(--gp-mobile-header-height, 56px);
        padding: 8px 12px !important;
        padding-top: calc(8px + env(safe-area-inset-top, 0px)) !important;
        background: var(--gp-card-bg, #ffffff);
        border-bottom: 1px solid var(--gp-border-color, rgba(0, 0, 0, 0.08));
    }
    dialog.gp-surface[data-gp-surface="cover"] .gp-modal-close {
        width: 44px;
        height: 44px;
        min-width: 44px;
        min-height: 44px;
    }
    dialog.gp-surface[data-gp-surface="cover"] .gp-modal-title {
        font-size: 17px;
        line-height: 1.3;
    }

    /* Body scrolls in the remaining space; contain scroll so it never chains to
     * the page behind the surface. */
    dialog.gp-surface[data-gp-surface="cover"] .gp-modal-body {
        flex: 1;
        min-height: 0;
        overflow-y: auto;
        overflow-x: hidden;          /* no left/right movement */
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: none;   /* solid scroll — no rubber-band/bounce, no chaining */
        touch-action: pan-y;         /* vertical panning only (blocks horizontal drag + pinch) */
        padding: 16px !important;
    }

    /* Footer = pinned bottom action bar, safe-area aware, thumb-reachable. */
    dialog.gp-surface[data-gp-surface="cover"] .gp-modal-footer {
        position: sticky;
        bottom: 0;
        z-index: 10;
        flex-shrink: 0;
        gap: 10px;
        padding: 12px 16px !important;
        padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px)) !important;
        background: var(--gp-bg-gray, #f5f5f5);
        border-top: 1px solid var(--gp-border-color, rgba(0, 0, 0, 0.08));
    }
    dialog.gp-surface[data-gp-surface="cover"] .gp-modal-footer .gp-btn-cancel,
    dialog.gp-surface[data-gp-surface="cover"] .gp-modal-footer .gp-btn-save {
        min-height: 44px;
    }

    /* 16px+ inputs inside a cover prevent iOS focus auto-zoom. */
    dialog.gp-surface[data-gp-surface="cover"] .gp-form-input,
    dialog.gp-surface[data-gp-surface="cover"] .gp-form-select,
    dialog.gp-surface[data-gp-surface="cover"] .gp-form-textarea {
        font-size: 16px !important;
    }

    /* iOS gives <input type="date"> an intrinsic width that overflows the field
     * and gets clipped on the right (and was the source of sideways drift before
     * overflow-x:hidden). Constrain it to the container so it fits cleanly. */
    dialog.gp-surface[data-gp-surface="cover"] input[type="date"] {
        -webkit-appearance: none;
        appearance: none;
        width: 100% !important;
        min-width: 0 !important;
        max-width: 100% !important;
        box-sizing: border-box !important;
        text-align: center; /* keep the centered "Jun 4, 2026" look you liked */
    }

    /* Keyboard avoidance: js/gp-surface.js sets --gp-kb-inset to the on-screen
     * keyboard height (VisualViewport) so the pinned footer rides above it. */
    dialog.gp-surface[data-gp-surface="cover"][data-gp-kb="1"] .gp-modal {
        height: calc(100dvh - var(--gp-kb-inset, 0px)) !important;
    }

    /* In-surface error banner (data safety: failures never use alert(); the form
     * stays intact and retry-able). Hidden until the controller reveals it. */
    .gp-surface__error {
        display: none;
        margin: 0 0 14px;
        padding: 10px 14px;
        border-radius: 10px;
        background: rgba(239, 68, 68, 0.1);
        border: 1px solid rgba(239, 68, 68, 0.35);
        color: #b91c1c;
        font-size: 14px;
        line-height: 1.4;
    }
    .gp-surface__error.is-visible {
        display: block;
    }
    @media (prefers-reduced-motion: reduce) {
        dialog.gp-surface[data-gp-surface="cover"] .gp-modal {
            transition: none;
        }
    }
}

/* ----------------------------------------------------------------------------
 * 3. SHEET (bottom sheet, large detent) — MOBILE ONLY
 * ----------------------------------------------------------------------------
 * Lifts the proven .rb-modal mobile bottom-sheet (template-parts/recruiting/
 * board-styles.php) into the shared surface: bottom-anchored panel, 20px top
 * radius, drag-pill, slide-up, ~90dvh detent, safe-area footer, contained scroll,
 * 16px inputs. Uses `dvh` (not the board's `vh`) so the mobile address bar never
 * clips. Swipe-down-to-dismiss is layered on by the controller as a follow-up;
 * this is the complete STATIC sheet (open/close/scroll-lock/a11y/back all come
 * from the same js/gp-surface.js controller — sheet vs cover is pure presentation).
 *
 * 1024px breakpoint matches cover (section 2). At ≤768px the board's own .rb-modal
 * mobile rules also match, but these (dialog + attribute, 0,3,1) outrank them and
 * carry !important to beat any generic .gp-modal/.rb-modal morphs — same tactic as
 * cover. Desktop (≥1025px) keeps the legacy centered .rb-modal modal untouched.
 * -------------------------------------------------------------------------- */
@media (max-width: 1024px) {

    /* Transparent, bottom-anchored flex frame; the ::backdrop provides the dim
     * (the page stays visible behind a sheet, unlike the opaque cover). */
    dialog.gp-surface[data-gp-surface="sheet"] {
        padding: 0 !important;
        align-items: flex-end !important;
        justify-content: center !important;
        background: transparent !important;
        -webkit-backdrop-filter: none !important;
        backdrop-filter: none !important;
        overflow: hidden !important; /* lock the frame — only .gp-modal-body scrolls */
    }
    dialog.gp-surface[data-gp-surface="sheet"]::backdrop {
        background: rgba(0, 0, 0, 0.32); /* lighter than cover-dim so the glass panel refracts the page color */
    }

    /* Panel: bottom sheet at the large detent (~90dvh), rounded top, slide-up. */
    dialog.gp-surface[data-gp-surface="sheet"] .gp-modal {
        max-width: 100% !important;
        width: 100% !important;
        max-height: 90vh !important;
        max-height: 90dvh !important;
        margin: 0 !important;
        border-radius: 20px 20px 0 0 !important;
        background: var(--gp-glass-bg, var(--gp-card-bg)) !important;
        -webkit-backdrop-filter: var(--gp-glass-blur, blur(22px) saturate(180%)) !important;
        backdrop-filter: var(--gp-glass-blur, blur(22px) saturate(180%)) !important;
        border-top: 1px solid var(--gp-glass-border, transparent) !important;
        box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.18),
                    inset 0 1px 0 var(--gp-glass-highlight, transparent) !important;
        overflow: hidden !important; /* only .gp-modal-body scrolls */
        display: flex !important;
        flex-direction: column !important;
        transform: translateY(0); /* slide-up target; see @starting-style below */
        transition: transform 0.3s cubic-bezier(0.32, 0.72, 0, 1);
    }
    @starting-style {
        dialog.gp-surface[data-gp-surface="sheet"][open] .gp-modal {
            transform: translateY(100%);
        }
    }

    /* Header: drag-pill affordance on top (the bottom-sheet "grab" cue), title row
     * below it. Sticky so it (and the pill) stay put while the body scrolls. */
    dialog.gp-surface[data-gp-surface="sheet"] .gp-modal-header {
        position: sticky;
        top: 0;
        z-index: 10;
        flex-shrink: 0;
        padding: 20px 16px 12px !important;
        background: transparent; /* the panel glass shows through — uniform frosted header */
    }
    dialog.gp-surface[data-gp-surface="sheet"] .gp-modal-header::before {
        content: '';
        position: absolute;
        top: 8px;
        left: 50%;
        transform: translateX(-50%);
        width: 36px;
        height: 5px;
        border-radius: 3px;
        background: var(--gp-gray-300, #d1d5db);
    }

    /* Body scrolls within the detent; contained so it never chains to the page
     * behind the sheet. Safe-area bottom padding clears the home indicator (the
     * sheet's bottom edge sits on the screen edge). */
    dialog.gp-surface[data-gp-surface="sheet"] .gp-modal-body {
        flex: 1;
        min-height: 0;
        overflow-y: auto;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
        touch-action: pan-y;
        padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px)) !important;
    }

    /* 16px+ inputs prevent iOS focus auto-zoom (board fields use the rb-* family). */
    dialog.gp-surface[data-gp-surface="sheet"] .gp-form-input,
    dialog.gp-surface[data-gp-surface="sheet"] .gp-form-select,
    dialog.gp-surface[data-gp-surface="sheet"] .gp-form-textarea,
    dialog.gp-surface[data-gp-surface="sheet"] .rb-form-input,
    dialog.gp-surface[data-gp-surface="sheet"] .rb-form-select,
    dialog.gp-surface[data-gp-surface="sheet"] .rb-form-textarea,
    dialog.gp-surface[data-gp-surface="sheet"] .rb-inline-select {
        font-size: 16px !important;
    }

    @media (prefers-reduced-motion: reduce) {
        dialog.gp-surface[data-gp-surface="sheet"] .gp-modal {
            transition: none;
        }
    }
}
