/* ============================================================================
   Canonical modal cascade — global enforcement of the CLAUDE.md modal pattern.
   Auto-included on every non-AJAX page via includes/footer.php.

   Target rules: rounded white card, white head with #f1f5f9 divider, white
   foot with same divider, indigo primary buttons (linear #2563eb→#1d4ed8),
   secondary white-with-#e2e8f0 border, 44px min tap targets, no × close
   button (Cancel in the footer is the only dismiss), indigo gradient
   header on mobile.

   This file uses !important deliberately. The codebase has 500+ existing
   modals with their own inline / per-page styles; the cascade has to win.
   For modals that want to stay non-canonical (e.g. the cleaning approval
   destructive red-gradient head), they can opt out with a class on the
   modal root or by being marked `data-modal-unmanaged="1"`.
   ========================================================================= */

/* `data-modal-unmanaged="1"` opt-out:
   Previously this used `all: revert` to drop the modal out of the
   canonical cascade. That was a sledgehammer — `all: revert` reverts
   author CSS too, killing the modal's OWN z-index / position / etc.
   and leaving custom modals (diet plans slot picker, etc.) invisible
   behind the page even though their own .show class added display:flex.

   The canonical selectors below target `.modal-overlay`, `.modal-backdrop`,
   and `.modal[role="dialog"]`. Each one is now qualified with
   :not([data-modal-unmanaged="1"]) so unmanaged modals are excluded
   from the cascade WITHOUT wiping their own author styles. The JS-side
   cascade in modals-canonical.js already honours the same flag.

   For custom modals using brand-new class names (.adb-slot-modal, etc.)
   the canonical selectors don't match anyway — the opt-out flag is only
   strictly needed when a modal carries a canonical class (.modal-overlay
   etc.) but wants to keep its own layout. */

/* ── Backdrop ──────────────────────────────────────────────────────────────
   Slate dim. Pinned with inset:0 (top/right/bottom/left = 0) rather than
   height:100% — on iOS Safari, `position:fixed; height:100%` resolves to
   the LARGER viewport (URL-bar-collapsed), so the backdrop extends
   behind the URL bar and the sticky footer at the bottom of the dialog
   ends up off-screen. `bottom:0` tracks the bottom of the *visible*
   WebView (just above the URL bar) so the backdrop is the dynamic
   viewport automatically. */
.modal-overlay:not([data-modal-unmanaged="1"]),
.modal-backdrop:not([data-modal-unmanaged="1"]),
.modal[role="dialog"]:not([data-modal-unmanaged="1"]) {
    background: rgba(15, 23, 42, 0.55);
}
.modal-overlay.show:not([data-modal-unmanaged="1"]),
.modal-backdrop.show:not([data-modal-unmanaged="1"]),
.modal[role="dialog"].show:not([data-modal-unmanaged="1"]),
.modal.show:not([data-modal-unmanaged="1"]) {
    top: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    left: 0 !important;
    height: auto !important;
    width: auto !important;
}

/* ── Lock the outer wrapper so it can't be the scroll surface ──────────────
   Several legacy modals have inline `overflow-y: auto` on the outer .modal
   element (e.g. feeding/prep.php's recurringModal). That makes the WHOLE
   modal scroll — header, footer, and all — instead of the dialog inside.
   Force the wrapper to centre + clip; the dialog gets max-height + scroll
   of its own (rules below). */
.modal-overlay.show:not([data-modal-unmanaged="1"]),
.modal-backdrop.show:not([data-modal-unmanaged="1"]),
.modal.show:not([data-modal-unmanaged="1"]) {
    align-items: center !important;
    justify-content: center !important;
    padding: 20px !important;
    overflow: hidden !important;
}

/* ── Card shell ────────────────────────────────────────────────────────────
   Rounded 16px, deep shadow, capped height with the container itself as the
   scroll surface. This works regardless of whether the modal has a dedicated
   `.modal-body` inside — head and foot use sticky positioning (rules below)
   to stay anchored while content scrolls. */
.modal-overlay.show:not([data-modal-unmanaged="1"]) > .modal-container,
.modal-overlay.show:not([data-modal-unmanaged="1"]) > .modal-content,
.modal-overlay.show:not([data-modal-unmanaged="1"]) > .modal-dialog,
.modal-overlay.show:not([data-modal-unmanaged="1"]) > .modal-card,
.modal-overlay.show:not([data-modal-unmanaged="1"]) > .modal-box,
.modal-backdrop.show:not([data-modal-unmanaged="1"]) > .modal-card,
.modal-backdrop.show:not([data-modal-unmanaged="1"]) > .modal-content,
.modal-backdrop.show:not([data-modal-unmanaged="1"]) > .modal-container,
.modal.show:not([data-modal-unmanaged="1"]) > .modal-dialog,
.modal.show:not([data-modal-unmanaged="1"]) > .modal-content,
.modal.show:not([data-modal-unmanaged="1"]) > .modal-card {
    border-radius: 16px !important;
    box-shadow: 0 30px 80px rgba(0, 0, 0, 0.18) !important;
    background: white !important;
    /* dvh tracks the actual visible viewport (excludes Android Chrome's
       dynamic URL bar + the gesture bar), so the modal's bottom edge
       and its sticky footer stay on screen. vh kept as a fallback for
       browsers without dvh support. */
    max-height: 92vh !important;
    max-height: 92dvh !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
}

/* ── Head ──────────────────────────────────────────────────────────────────
   White background, dark text, 1px slate divider. Override any inline
   gradient (green/orange/blue/purple/yellow) the legacy modals applied. */
.modal-container > .modal-header,
.modal-content > .modal-header,
.modal-dialog > .modal-header,
.modal-card > .modal-head,
.modal-box > .modal-hdr,
.modal-overlay .modal-header,
.modal-backdrop .modal-head,
.modal[role="dialog"] .modal-header,
.modal-header[style*="linear-gradient"],
.modal-head[style*="linear-gradient"] {
    background: white !important;
    background-image: none !important;
    color: #0f172a !important;
    padding: 16px 22px !important;
    border-bottom: 1px solid #f1f5f9 !important;
    border-radius: 16px 16px 0 0 !important;
    flex-shrink: 0 !important;
    min-height: 60px !important;
    position: sticky !important;       /* anchor at top of scrolling card */
    top: 0 !important;
    z-index: 2 !important;
}

.modal-overlay .modal-header h1,
.modal-overlay .modal-header h2,
.modal-overlay .modal-header h3,
.modal-overlay .modal-header h4,
.modal-overlay .modal-header h5,
.modal-overlay .modal-header .modal-title,
.modal-backdrop .modal-head h1,
.modal-backdrop .modal-head h2,
.modal-backdrop .modal-head h3,
.modal-backdrop .modal-head h4,
.modal-backdrop .modal-head h5,
.modal-backdrop .modal-head .modal-title,
.modal[role="dialog"] .modal-header .modal-title,
.modal[role="dialog"] .modal-header h1,
.modal[role="dialog"] .modal-header h2,
.modal[role="dialog"] .modal-header h3 {
    color: #0f172a !important;
    background: transparent !important;
    margin: 0 !important;
    font-size: 18px !important;
    font-weight: 700 !important;
}

/* Header icon usually sits in the title — keep it indigo for affordance. */
.modal-overlay .modal-header h1 i,
.modal-overlay .modal-header h2 i,
.modal-overlay .modal-header h3 i,
.modal-overlay .modal-header .modal-title i,
.modal-backdrop .modal-head h3 i,
.modal-backdrop .modal-head .modal-title i {
    color: #2563eb !important;
}

/* Subtitle / supporting copy in the head — softer slate grey on the
   white desktop head, indigo icon for affordance.  Mobile rules below
   flip these to white on the indigo gradient. */
.modal-overlay .modal-header small,
.modal-overlay .modal-header .modal-subtitle,
.modal-overlay .modal-header p,
.modal-backdrop .modal-head small,
.modal-backdrop .modal-head .modal-subtitle,
.modal-backdrop .modal-head p,
.modal[role="dialog"] .modal-header small,
.modal[role="dialog"] .modal-header .modal-subtitle,
.modal[role="dialog"] .modal-header p {
    display: block !important;
    margin-top: 4px !important;
    font-size: 12px !important;
    line-height: 1.45 !important;
    color: #64748b !important;
}
.modal-overlay .modal-header small i,
.modal-overlay .modal-header .modal-subtitle i,
.modal-overlay .modal-header p i,
.modal-backdrop .modal-head small i,
.modal-backdrop .modal-head .modal-subtitle i,
.modal[role="dialog"] .modal-header small i,
.modal[role="dialog"] .modal-header .modal-subtitle i {
    color: #4f46e5 !important;
    margin-right: 5px !important;
}

/* ── Hide × close buttons globally ─────────────────────────────────────────
   CLAUDE.md: "No × close button in the head. The footer Cancel button is
   the only dismiss." Catches every common close-button class plus aria-
   labelled close buttons that don't follow naming. */
.modal-overlay .modal-close,
.modal-overlay .close-btn,
.modal-overlay .btn-close,
.modal-overlay .modal-header .close,
.modal-overlay [aria-label="Close"],
.modal-backdrop .modal-close,
.modal-backdrop .close-btn,
.modal-backdrop .btn-close,
.modal-backdrop .modal-header .close,
.modal-backdrop [aria-label="Close"],
.modal[role="dialog"] .modal-close,
.modal[role="dialog"] .close-btn,
.modal[role="dialog"] .btn-close,
.modal[role="dialog"] .modal-header .close,
.modal[role="dialog"] [aria-label="Close"] {
    display: none !important;
}

/* (Body region intentionally not overridden — legacy modals all set their
   own padding and scroll, and forcing flex:1 / overflow-y here breaks any
   modal whose container isn't already flex-column. The visual shim sticks
   to head + foot + button styling.) */

/* ── Foot ──────────────────────────────────────────────────────────────────
   Sticky bottom strip, primary action right-aligned. */
.modal-overlay .modal-footer,
.modal-backdrop .modal-footer,
.modal[role="dialog"] .modal-footer,
.modal-card .modal-foot,
.modal-content .modal-footer,
.modal-dialog .modal-footer {
    background: #fafbfd !important;
    border-top: 1px solid #f1f5f9 !important;
    /* Bottom padding uses max() so we always get ≥72px of buffer above
       the system nav / gesture bar / mobile-browser URL bar. Tested
       progressively: 28px wasn't enough (Samsung 3-button nav), 56px
       wasn't enough (iOS Safari bottom URL bar covered Cancel), 72px
       gives Cancel/Submit clear airspace above the OS chrome on both.
       env(safe-area-inset-bottom) is 0 in regular Android Chrome tabs
       so we can't rely on it alone. */
    padding: 14px 22px max(72px, calc(14px + env(safe-area-inset-bottom, 0px))) 22px !important;
    flex-shrink: 0 !important;
    border-radius: 0 0 16px 16px !important;
    display: flex !important;
    gap: 10px !important;
    justify-content: flex-end !important;
    flex-wrap: wrap !important;
    position: sticky !important;       /* anchor at bottom of scrolling card */
    bottom: 0 !important;
    z-index: 2 !important;
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.04) !important;
}

/* ── Universal modal-footer bottom-buffer ──────────────────────────────────
   The canonical selectors above only catch .modal-footer / .modal-foot.
   Many pages across the codebase use variant class names for their
   footer strip — modal-ftr, modal-actions, search-modal-footer,
   add-med-modal-footer, settings-modal-footer, etc. They each carry
   their own background / border / layout but were missing the
   bottom-buffer fix, so on Samsung Android and iOS Safari their
   Cancel/Submit buttons sat behind the system nav.

   This attribute-selector rule adds JUST the bottom padding to any
   element whose class name contains a modal-footer-like substring,
   without overriding any other style. New per-page footer classes
   pick up the fix automatically. */
[class*="modal-footer"],
[class*="modal-foot"],
[class*="modal-ftr"],
[class*="modal-actions"],
[class*="modal-buttons"],
[class*="modal-bottom"] {
    padding-bottom: max(72px, calc(14px + env(safe-area-inset-bottom, 0px))) !important;
}

/* ── Buttons inside modal foot ─────────────────────────────────────────────
   44px min tap target, indigo gradient for primary, white for secondary. */
.modal-overlay .modal-footer button,
.modal-overlay .modal-footer .btn,
.modal-overlay .modal-footer a.btn,
.modal-backdrop .modal-footer button,
.modal-backdrop .modal-footer .btn,
.modal[role="dialog"] .modal-footer button,
.modal[role="dialog"] .modal-footer .btn,
.modal-card .modal-foot button,
.modal-card .modal-foot .btn {
    min-height: 44px !important;
    padding: 10px 18px !important;
    border-radius: 8px !important;
    font-size: 14px !important;
    font-weight: 600 !important;
    font-family: inherit !important;
    cursor: pointer !important;
    touch-action: manipulation !important;
    -webkit-tap-highlight-color: rgba(99, 102, 241, 0.15) !important;
    border: 1px solid #e2e8f0 !important;
    background: white !important;
    color: #475569 !important;
    transition: box-shadow .15s, background .15s, transform .04s !important;
}

.modal-overlay .modal-footer .btn-primary,
.modal-overlay .modal-footer button.primary,
.modal-overlay .modal-footer button[type="submit"]:not(.btn-secondary):not(.btn-cancel):not(.btn-danger),
.modal-backdrop .modal-footer .btn-primary,
.modal[role="dialog"] .modal-footer .btn-primary,
.modal-card .modal-foot .btn-primary,
.modal-card .modal-foot button.primary {
    background: linear-gradient(135deg, #2563eb, #1d4ed8) !important;
    color: white !important;
    border-color: transparent !important;
}

.modal-overlay .modal-footer .btn-success,
.modal-overlay .modal-footer button.success {
    background: linear-gradient(135deg, #10b981, #059669) !important;
    color: white !important;
    border-color: transparent !important;
}

.modal-overlay .modal-footer .btn-danger,
.modal-overlay .modal-footer .btn-delete,
.modal-overlay .modal-footer button.danger {
    background: linear-gradient(135deg, #dc2626, #b91c1c) !important;
    color: white !important;
    border-color: transparent !important;
}

.modal-overlay .modal-footer .btn-secondary,
.modal-overlay .modal-footer .btn-cancel,
.modal-overlay .modal-footer button.secondary,
.modal-overlay .modal-footer button.cancel,
.modal-backdrop .modal-footer .btn-secondary,
.modal-backdrop .modal-footer .btn-cancel,
.modal-card .modal-foot .btn-secondary {
    background: white !important;
    color: #475569 !important;
    border: 1px solid #e2e8f0 !important;
}

@media (hover: hover) {
    .modal-overlay .modal-footer button:hover,
    .modal-overlay .modal-footer .btn:hover,
    .modal-backdrop .modal-footer button:hover {
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06) !important;
    }
}

/* ── Mobile sheet ──────────────────────────────────────────────────────────
   Edge-to-edge, indigo gradient header, full-width buttons. */
@media (max-width: 768px) {
    .modal-overlay.show,
    .modal-backdrop.show,
    .modal.show {
        padding: 0 !important;
        align-items: stretch !important;
    }

    .modal-overlay.show > .modal-container,
    .modal-overlay.show > .modal-content,
    .modal-overlay.show > .modal-dialog,
    .modal-overlay.show > .modal-card,
    .modal-overlay.show > .modal-box,
    .modal-backdrop.show > .modal-card,
    .modal.show > .modal-dialog,
    .modal.show > .modal-content {
        max-width: 100% !important;
        width: 100% !important;
        /* `100vh` on iOS Safari = the larger viewport (URL bar collapsed),
           so the sticky footer at the bottom of the dialog can sit below
           the URL bar when it's showing. `100dvh` is the dynamic viewport
           height — equals the current visible area. Falls through to the
           vh value on browsers without dvh support. */
        max-height: 100vh !important;
        max-height: 100dvh !important;
        border-radius: 0 !important;
        margin: 0 !important;
        overflow-y: auto !important;       /* fall-through scroll if inner */
        -webkit-overflow-scrolling: touch !important;
    }

    .modal-overlay .modal-header,
    .modal-backdrop .modal-head,
    .modal[role="dialog"] .modal-header {
        background: linear-gradient(135deg, #6366f1, #4f46e5) !important;
        color: white !important;
        border-radius: 0 !important;
        border-bottom: 0 !important;
    }
    .modal-overlay .modal-header h1,
    .modal-overlay .modal-header h2,
    .modal-overlay .modal-header h3,
    .modal-overlay .modal-header h4,
    .modal-overlay .modal-header h5,
    .modal-overlay .modal-header .modal-title,
    .modal-backdrop .modal-head h3,
    .modal-backdrop .modal-head .modal-title,
    .modal[role="dialog"] .modal-header h3,
    .modal[role="dialog"] .modal-header .modal-title {
        color: white !important;
    }
    .modal-overlay .modal-header h1 i,
    .modal-overlay .modal-header h2 i,
    .modal-overlay .modal-header h3 i,
    .modal-overlay .modal-header .modal-title i,
    .modal-backdrop .modal-head h3 i,
    .modal-backdrop .modal-head .modal-title i,
    .modal[role="dialog"] .modal-header h3 i {
        color: white !important;
    }
    /* Subtitle / supporting copy in the head — when the head goes
       indigo on mobile, anything not in the h1-h5/.modal-title set
       (typically a <small> or .modal-subtitle byline) needs to flip
       white too, otherwise grey-on-indigo is unreadable. */
    .modal-overlay .modal-header small,
    .modal-overlay .modal-header .modal-subtitle,
    .modal-overlay .modal-header p,
    .modal-backdrop .modal-head small,
    .modal-backdrop .modal-head .modal-subtitle,
    .modal-backdrop .modal-head p,
    .modal[role="dialog"] .modal-header small,
    .modal[role="dialog"] .modal-header .modal-subtitle,
    .modal[role="dialog"] .modal-header p {
        color: rgba(255, 255, 255, 0.92) !important;
    }
    .modal-overlay .modal-header small i,
    .modal-overlay .modal-header .modal-subtitle i,
    .modal-overlay .modal-header p i,
    .modal-backdrop .modal-head small i,
    .modal-backdrop .modal-head .modal-subtitle i,
    .modal[role="dialog"] .modal-header small i,
    .modal[role="dialog"] .modal-header .modal-subtitle i {
        color: rgba(255, 255, 255, 0.92) !important;
        margin-right: 5px !important;
    }
    .modal-overlay .modal-footer button,
    .modal-overlay .modal-footer .btn,
    .modal-backdrop .modal-footer button,
    .modal[role="dialog"] .modal-footer button,
    .modal-card .modal-foot button {
        flex: 1 !important;
        justify-content: center !important;
    }
    .modal-overlay .modal-footer,
    .modal-backdrop .modal-footer,
    .modal[role="dialog"] .modal-footer,
    .modal-card .modal-foot {
        border-radius: 0 !important;
    }
}
