/*
 * Slice PWA-2 (2026-05-22) — Mobile + PWA enhancements layered on top of
 * admin_theme.css. Loaded automatically on every page by pwa_head.php.
 *
 * Scope:
 *   - iOS safe-area insets (notch, home indicator)
 *   - Prevent iOS zoom-on-focus by enforcing 16px input font size
 *   - Stronger touch targets on already-responsive elements
 *   - Table responsiveness — both horizontal scroll AND opt-in
 *     "card mode" via .table-cards-on-mobile that admin pages can adopt
 *   - PWA standalone tweaks (running from home screen)
 *   - Mobile-friendly modals + offcanvas
 *   - Sticky bottom action bar pattern (.pwa-fab-bar) for primary CTAs
 *
 * Mobile breakpoints follow Bootstrap conventions:
 *   xs  < 576px   phones, portrait
 *   sm  ≥ 576px   phones, landscape
 *   md  ≥ 768px   small tablets
 *   lg  ≥ 992px   tablets
 *   xl  ≥ 1200px  laptops+
 */

/* ===================================================================
   iOS safe-area insets — respect notch + home indicator.
   The viewport-fit=cover lets us paint into those zones, then padding
   pushes UI back inside the safe area.
   =================================================================== */
:root {
    --safe-top:    env(safe-area-inset-top, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);
    --safe-left:   env(safe-area-inset-left, 0px);
    --safe-right:  env(safe-area-inset-right, 0px);
}

@supports (padding: env(safe-area-inset-top)) {
    body.admin-theme .admin-topbar {
        padding-top: calc(18px + var(--safe-top));
        padding-left: calc(28px + var(--safe-left));
        padding-right: calc(28px + var(--safe-right));
    }
    body.admin-theme .admin-content {
        padding-left: calc(18px + var(--safe-left));
        padding-right: calc(18px + var(--safe-right));
    }
}

/* ===================================================================
   Prevent iOS Safari from auto-zooming when focusing inputs.
   The trigger is font-size < 16px. We bump the minimum to 16px on
   small screens for all text inputs.
   =================================================================== */
@media (max-width: 767.98px) {
    .admin-theme input[type="text"],
    .admin-theme input[type="email"],
    .admin-theme input[type="number"],
    .admin-theme input[type="search"],
    .admin-theme input[type="password"],
    .admin-theme input[type="tel"],
    .admin-theme input[type="url"],
    .admin-theme input[type="date"],
    .admin-theme input[type="datetime-local"],
    .admin-theme input[type="time"],
    .admin-theme textarea,
    .admin-theme select,
    .admin-theme .form-control,
    .admin-theme .form-select {
        font-size: 16px !important;  /* defeats iOS zoom */
    }
}

/* ===================================================================
   Touch targets — Apple HIG + Material guidelines both call for 44px
   minimum. Most admin_theme.css elements already hit 42-48px; we just
   nudge the laggards.
   =================================================================== */
@media (max-width: 991.98px) {
    .admin-theme .btn,
    .admin-theme a.btn,
    .admin-theme button:not(.btn-close),
    .admin-theme .nav-link,
    .admin-theme .dropdown-item,
    .admin-theme .pp-actions a,
    .admin-theme .project-context-link {
        min-height: 44px;
    }

    /* Tighter checkboxes/radios are fine, but their click target should
       still be 44px via padding on the label */
    .admin-theme .form-check {
        min-height: 32px;
        padding-top: 6px;
        padding-bottom: 6px;
    }

    /* Topbar links: more padding so taps don't miss */
    .admin-theme .admin-top-links a,
    .admin-theme .admin-top-links span {
        padding: 8px 6px;
    }
}

/* ===================================================================
   Tables — three tiers of responsive behavior:
   1. .table-responsive (Bootstrap default): horizontal scroll
   2. .table-cards-on-mobile: stack each row as a labeled card (opt-in)
   3. .table-priority-cols: hide low-priority columns marked
      data-priority="low"|"medium" depending on viewport
   =================================================================== */

/* Tier 1: visual cue when a table scrolls horizontally */
@media (max-width: 767.98px) {
    .admin-theme .table-responsive {
        position: relative;
    }
    .admin-theme .table-responsive::after {
        content: "";
        position: absolute;
        inset-block: 0;
        inset-inline-end: 0;
        width: 30px;
        background: linear-gradient(to left, rgba(255,255,255,.95), transparent);
        pointer-events: none;
        opacity: 0;
        transition: opacity .2s;
    }
    /* JS would toggle .scroll-fading; for now always visible on mobile */
    .admin-theme .table-responsive::after { opacity: .55; }
}

/* Tier 2: stacked cards on phones — opt-in per table.
   The page must add data-label="…" to each <td> so the label shows up
   when the row is rendered as a card. */
@media (max-width: 575.98px) {
    .admin-theme .table-cards-on-mobile {
        display: block;
        width: 100%;
    }
    .admin-theme .table-cards-on-mobile thead {
        display: none;
    }
    .admin-theme .table-cards-on-mobile tbody,
    .admin-theme .table-cards-on-mobile tr {
        display: block;
        width: 100%;
    }
    .admin-theme .table-cards-on-mobile tr {
        border: 1px solid var(--villa-line);
        border-radius: 14px;
        padding: 10px 12px;
        margin-bottom: 10px;
        background: rgba(255,255,255,.94);
        box-shadow: 0 6px 18px rgba(39,84,110,.06);
    }
    .admin-theme .table-cards-on-mobile td {
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        gap: 12px;
        padding: 8px 0;
        border: 0;
        border-bottom: 1px dashed rgba(217,222,227,.6);
        text-align: end;
    }
    .admin-theme .table-cards-on-mobile td:last-child {
        border-bottom: 0;
    }
    .admin-theme .table-cards-on-mobile td[data-label]::before {
        content: attr(data-label);
        font-weight: 700;
        color: var(--villa-muted);
        font-size: .85rem;
        text-align: start;
        flex: 0 0 auto;
        max-width: 45%;
    }
}

/* Tier 3: priority-column hiding via data-priority */
@media (max-width: 991.98px) {
    .admin-theme [data-priority="low"] { display: none !important; }
}
@media (max-width: 575.98px) {
    .admin-theme [data-priority="medium"] { display: none !important; }
}

/* ===================================================================
   Project context nav — horizontal scroll on phones (better than
   wrap-to-2-rows which eats vertical space).
   =================================================================== */
@media (max-width: 575.98px) {
    .admin-theme .project-context-nav {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: thin;
        -webkit-overflow-scrolling: touch;
        padding: 8px;
    }
    .admin-theme .project-context-link {
        flex: 0 0 auto;
        min-width: max-content;
        padding: 10px 14px;
        font-size: .92rem;
    }
}

/* ===================================================================
   PWA standalone mode — when the app is launched from the home screen
   the browser's chrome is hidden. We can:
   - Hide language switcher (mostly noise once installed)
   - Tighten the topbar (no need to compete with browser address bar)
   - Add bottom safe-area padding to scrollable content
   =================================================================== */
@media (display-mode: standalone) {
    body.admin-theme {
        /* extend background under the home indicator */
        padding-bottom: var(--safe-bottom);
    }
    body.admin-theme .admin-topbar {
        padding-top: calc(14px + var(--safe-top));
        padding-bottom: 14px;
    }
    /* Browser back/forward not available in standalone — give the user
       a hint by emphasizing in-app navigation */
    body.admin-theme .pwa-only-installed {
        display: inline-flex !important;
    }
    body.admin-theme .pwa-hide-when-installed {
        display: none !important;
    }
}
.pwa-only-installed { display: none; }

/* ===================================================================
   Install prompt banner — small floating chip shown when the browser
   has captured a beforeinstallprompt. Page code calls
   window.deferredPWAInstall.prompt() when the user clicks it.
   =================================================================== */
.pwa-install-banner {
    position: fixed;
    inset-block-end: calc(14px + var(--safe-bottom));
    inset-inline-end: 14px;
    z-index: 1080;
    display: none;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    border-radius: 14px;
    background: linear-gradient(135deg, #2d607c, #427691);
    color: #fff;
    box-shadow: 0 14px 30px rgba(31,88,116,.32);
    font-weight: 700;
    font-size: .95rem;
    cursor: pointer;
    user-select: none;
    border: 0;
    max-width: calc(100vw - 28px);
}

html.pwa-installable .pwa-install-banner {
    display: inline-flex;
}

.pwa-install-banner:hover {
    transform: translateY(-1px);
    box-shadow: 0 18px 36px rgba(31,88,116,.36);
}

.pwa-install-banner .pwa-install-icon {
    font-size: 1.2rem;
    line-height: 1;
}

.pwa-install-banner .pwa-install-close {
    background: transparent;
    border: 0;
    color: rgba(255,255,255,.8);
    font-size: 1.1rem;
    padding: 0 4px;
    cursor: pointer;
}

/* ===================================================================
   Offline indicator — chip appears when navigator.onLine is false.
   Toggled by a tiny inline script in pwa_head.php.
   =================================================================== */
.pwa-offline-chip {
    position: fixed;
    inset-block-start: calc(8px + var(--safe-top));
    inset-inline-start: 50%;
    transform: translateX(-50%);
    z-index: 1090;
    display: none;
    padding: 6px 14px;
    border-radius: 999px;
    background: #f97316;
    color: #fff;
    font-weight: 700;
    font-size: .85rem;
    box-shadow: 0 8px 20px rgba(249,115,22,.35);
    pointer-events: none;
    direction: rtl;
}

html.pwa-offline .pwa-offline-chip {
    display: inline-block;
}

/* ===================================================================
   Bootstrap modals + offcanvas on phones — fill the screen for easier
   reading + tapping.
   =================================================================== */
@media (max-width: 575.98px) {
    .modal-dialog {
        margin: 8px;
        max-width: calc(100vw - 16px);
    }
    .modal-content {
        border-radius: 14px;
    }
    .modal-fullscreen-mobile .modal-dialog,
    .modal-fullscreen-mobile .modal-content {
        margin: 0;
        max-width: 100%;
        height: 100vh;
        border-radius: 0;
    }
    .offcanvas {
        max-width: 88vw;
    }
}

/* ===================================================================
   KPI grid + dashboard cards — better stacking on phones. The base
   admin_theme.css already collapses to 1 column at 767.98px; we add
   2-column intermediate at 576–767 for a denser layout on landscape
   phones.
   =================================================================== */
@media (min-width: 576px) and (max-width: 767.98px) {
    .admin-theme .kpi-grid,
    .admin-theme .pp-kpi-grid,
    .admin-theme .admin-stats-grid,
    .admin-theme .admin-form-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    }
}

/* ===================================================================
   Forms — make required-field markers, error states, and help text
   easier to read on phones.
   =================================================================== */
@media (max-width: 575.98px) {
    .admin-theme .form-label {
        margin-bottom: 4px;
        font-size: .92rem;
    }
    .admin-theme .invalid-feedback,
    .admin-theme .form-text {
        font-size: .85rem;
    }
    /* File inputs: stretch full width */
    .admin-theme input[type="file"] {
        width: 100%;
    }
}

/* ===================================================================
   Mobile-first floating action bar at the bottom of long forms.
   Pages opt-in by wrapping primary CTAs in <div class="pwa-fab-bar">.
   On desktop, behaves like a normal inline container.
   =================================================================== */
.pwa-fab-bar {
    display: flex;
    gap: 10px;
    align-items: center;
    justify-content: flex-end;
    flex-wrap: wrap;
}

@media (max-width: 767.98px) {
    .pwa-fab-bar {
        position: sticky;
        inset-block-end: 0;
        margin-inline: -14px;
        margin-block-start: 18px;
        padding: 12px 14px calc(12px + var(--safe-bottom));
        background: rgba(255,255,255,.97);
        backdrop-filter: blur(8px);
        border-top: 1px solid var(--villa-line);
        box-shadow: 0 -8px 24px rgba(31,88,116,.08);
        z-index: 30;
    }
    .pwa-fab-bar .btn {
        flex: 1 1 auto;
    }
}

/* ===================================================================
   Charts / Gantt / Network — allow horizontal scroll on phones rather
   than crushing into 320px width. Specific pages can override.
   =================================================================== */
@media (max-width: 767.98px) {
    .pp-chart-wrap,
    .gantt-canvas-wrap,
    .network-canvas-wrap,
    .svg-canvas-wrap {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    .pp-chart-wrap > svg,
    .gantt-canvas-wrap > svg,
    .network-canvas-wrap > svg {
        min-width: 720px; /* let it scroll */
    }
}

/* ===================================================================
 * MOBILE-SHELL (2026-05-22) — fixed top bar + bottom nav for phones.
 * Injected by includes/pwa_head.php → injectMobileShellIntoHtml().
 * Brand: navy #427691 (--villa-top-dark).
 * =================================================================== */

/* Hidden on desktop */
.pwa-mtop, .pwa-mbottom { display: none; }

@media (max-width: 991.98px) {
    /* === Mobile top bar === */
    .pwa-mtop {
        position: fixed;
        inset-block-start: 0;
        inset-inline: 0;
        z-index: 1055;
        display: flex;
        align-items: center;
        gap: 10px;
        height: 56px;
        padding: 0 12px;
        padding-top: max(0px, var(--safe-top));
        padding-inline-start: max(12px, var(--safe-left));
        padding-inline-end:   max(12px, var(--safe-right));
        background: linear-gradient(135deg, #2d607c, #427691);
        color: #fff;
        box-shadow: 0 4px 14px rgba(31, 88, 116, .18);
        font-family: var(--villa-font-family, "Tahoma","Segoe UI",sans-serif);
    }
    .pwa-mtop-btn {
        appearance: none;
        background: rgba(255,255,255,.14);
        border: 0;
        color: #fff;
        width: 40px;
        height: 40px;
        border-radius: 10px;
        font-size: 20px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        text-decoration: none;
        position: relative;
    }
    .pwa-mtop-btn:hover { background: rgba(255,255,255,.22); color: #fff; }
    .pwa-mtop-title {
        flex: 1 1 auto;
        font-weight: 700;
        font-size: 1.05rem;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .pwa-mtop-bell [data-unread-count] {
        position: absolute;
        top: 2px;
        inset-inline-end: 2px;
        min-width: 16px;
        height: 16px;
        font-size: 10px;
        background: #f3d25d;
        color: #5b3b00;
    }

    /* === Mobile bottom navigation === */
    .pwa-mbottom {
        position: fixed;
        inset-block-end: 0;
        inset-inline: 0;
        z-index: 1055;
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        background: #fff;
        border-top: 1px solid var(--villa-line, #d9dee3);
        box-shadow: 0 -6px 20px rgba(31, 88, 116, .12);
        padding-bottom: var(--safe-bottom);
        font-family: var(--villa-font-family, "Tahoma","Segoe UI",sans-serif);
    }
    .pwa-mb-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 2px;
        padding: 8px 4px;
        text-decoration: none !important;
        color: var(--villa-muted, #6c7f8d);
        font-size: 11px;
        font-weight: 700;
        position: relative;
        min-height: 56px;
    }
    .pwa-mb-icon { font-size: 22px; line-height: 1; }
    .pwa-mb-label {
        font-size: 11px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        max-width: 100%;
    }
    .pwa-mb-item.is-active {
        color: var(--villa-top-dark, #427691);
    }
    .pwa-mb-item.is-active::before {
        content: '';
        position: absolute;
        inset-block-start: 0;
        inset-inline-start: 25%;
        inset-inline-end: 25%;
        height: 3px;
        background: var(--villa-top-dark, #427691);
        border-radius: 0 0 3px 3px;
    }
    .pwa-mb-dot {
        position: absolute;
        top: 4px;
        inset-inline-end: calc(50% - 18px);
        min-width: 16px;
        height: 16px;
        font-size: 10px;
        background: #dc2626;
        color: #fff;
        border: 2px solid #fff;
    }

    /* === Hide the existing villa-app desktop topbar + subbar on mobile === */
    body.admin-theme .admin-topbar,
    body.admin-theme .admin-subbar {
        display: none !important;
    }

    /* === Pad the main content for the mobile shells === */
    body.admin-theme {
        padding-top: calc(56px + var(--safe-top));
        padding-bottom: calc(56px + var(--safe-bottom));
    }
    body.admin-theme .admin-page-wrap {
        grid-template-columns: 1fr !important;
    }
    body.admin-theme .admin-content {
        padding: 14px 12px 18px !important;
        min-height: auto !important;
    }

    /* === Sidebar becomes a slide-in drawer === */
    body.admin-theme .admin-sidebar {
        position: fixed !important;
        inset-block-start: 0 !important;
        inset-inline-start: 0 !important;
        height: 100vh !important;
        width: min(86vw, 320px) !important;
        z-index: 1060 !important;
        transform: translateX(-100%);
        transition: transform .22s ease;
        background: #fff !important;
        box-shadow: 0 18px 40px rgba(31, 88, 116, .22) !important;
        padding: calc(56px + var(--safe-top)) 0 20px !important;
        overflow-y: auto !important;
        border-left: 0 !important;
        border-bottom: 0 !important;
        margin: 0 !important;
        backdrop-filter: none !important;
    }
    body.admin-theme.rtl-layout .admin-sidebar,
    body.admin-theme[dir="rtl"] .admin-sidebar,
    html[dir="rtl"] body.admin-theme .admin-sidebar {
        inset-inline-start: auto !important;
        inset-inline-end: 0 !important;
        transform: translateX(100%);
    }
    body.admin-theme.pwa-nav-open .admin-sidebar {
        transform: translateX(0) !important;
    }
    body.admin-theme.pwa-nav-open::before {
        content: '';
        position: fixed; inset: 0; z-index: 1058;
        background: rgba(15,23,42,.5);
    }
    /* The drawer must look like a vertical sidebar even though the
       desktop CSS overrides it to a horizontal scroll-strip at ≤1199px. */
    body.admin-theme.pwa-nav-open .admin-menu-group {
        flex-direction: column !important;
        flex-wrap: wrap !important;
        overflow: visible !important;
        gap: 4px !important;
        padding: 0 !important;
    }
    body.admin-theme.pwa-nav-open .admin-menu-item {
        width: 100% !important;
        min-width: 0 !important;
        border-radius: 0 !important;
        border: 0 !important;
        border-bottom: 1px solid var(--villa-line, #d9dee3) !important;
        box-shadow: none !important;
        background: #fff !important;
        padding: 14px 18px !important;
    }
    body.admin-theme.pwa-nav-open .admin-menu-group-title {
        display: block !important;
    }
    body.admin-theme.pwa-nav-open .admin-menu-item small {
        display: inline-block !important;
    }

    /* Install banner sits above the bottom nav */
    .pwa-install-banner {
        inset-block-end: calc(70px + var(--safe-bottom)) !important;
    }
    #pwa-queue-badge {
        inset-block-end: calc(70px + var(--safe-bottom)) !important;
    }
    .pwa-offline-chip {
        inset-block-start: calc(60px + var(--safe-top)) !important;
    }
}

/* ===================================================================
   Environment badge (2026-05-25): always-visible chip in the corner
   that tells the user whether the running app instance is connected
   to LOCAL XAMPP or to the LIVE host. Survives PWA install since the
   PWA inherits the page DOM.

   Default position: top-left on desktop (clear of the admin topbar).
   On mobile: pushed below the fixed top bar so it doesn't overlap
   the hamburger.
   =================================================================== */
.pwa-env-badge {
    position: fixed;
    top: 8px;
    inset-inline-start: 8px;
    z-index: 1100;
    color: #fff;
    padding: 4px 10px;
    border-radius: 999px;
    font: 700 11px "Tahoma", system-ui, -apple-system, sans-serif;
    box-shadow: 0 4px 12px rgba(0,0,0,.25);
    opacity: .92;
    user-select: none;
    letter-spacing: .04em;
    pointer-events: auto;
    max-width: 60vw;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pwa-env-badge:hover { opacity: 1; }

@media (max-width: 991.98px) {
    /* Below the mobile fixed top bar */
    .pwa-env-badge {
        top: calc(60px + var(--safe-top));
        font-size: 10px;
        padding: 3px 8px;
    }
}

@media print {
    .pwa-env-badge { display: none !important; }
}

/* ===================================================================
   Global Search overlay (Ctrl+K) — VA-32 #1
   =================================================================== */
#gs-overlay {
    position: fixed; inset: 0; z-index: 1500;
    background: rgba(15, 23, 42, .55);
    display: none;
    align-items: flex-start;
    justify-content: center;
    padding-top: 12vh;
    backdrop-filter: blur(2px);
}
#gs-overlay.is-open { display: flex; }
.gs-card {
    width: min(640px, 92vw);
    background: #fff;
    border-radius: 14px;
    box-shadow: 0 24px 60px rgba(15, 23, 42, .30);
    overflow: hidden;
    font-family: "Tahoma", system-ui, sans-serif;
}
#gs-input {
    width: 100%;
    border: 0;
    padding: 18px 22px;
    font-size: 17px;
    outline: none;
    border-bottom: 1px solid #eef3f7;
}
.gs-hint {
    background: #f8fbfd;
    color: #6c7f8d;
    padding: 6px 22px;
    font-size: 11px;
    text-align: center;
    border-bottom: 1px solid #eef3f7;
}
.gs-results { max-height: 56vh; overflow-y: auto; }
.gs-group {
    padding: 10px 22px 4px;
    font-size: 11px;
    font-weight: 800;
    color: #427691;
    text-transform: uppercase;
    letter-spacing: .06em;
    background: #fff;
}
.gs-item {
    display: block;
    padding: 10px 22px;
    color: #25485c;
    text-decoration: none !important;
    border-inline-start: 3px solid transparent;
}
.gs-item:hover, .gs-item.is-sel {
    background: #eef5f9;
    border-inline-start-color: #427691;
}
.gs-label { font-weight: 700; }
.gs-meta { font-size: 12px; color: #6c7f8d; margin-top: 2px; }
.gs-empty { padding: 30px 22px; text-align: center; color: #6c7f8d; }

@media print { #gs-overlay { display: none !important; } }

/* Unread badge mirror — used by the topbar bell + bottom-nav Inbox dot. */
[data-unread-count] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 999px;
    background: #dc2626;
    color: #fff;
    font-size: 11px;
    font-weight: 800;
    line-height: 1;
}
[data-unread-count]:not(.has-unread) { display: none; }

/* ===================================================================
   Print — keep mobile rules from leaking into print stylesheets used
   by schedule_report.php etc.
   =================================================================== */
@media print {
    .pwa-install-banner,
    .pwa-offline-chip,
    .pwa-fab-bar,
    .pwa-mtop,
    .pwa-mbottom {
        display: none !important;
    }
}

/* Quick-actions FAB (VA-32 #3) — mobile only */
.qf-fab-wrap {
    position: fixed;
    inset-block-end: calc(70px + var(--safe-bottom));
    inset-inline-end: 18px;
    z-index: 1090;
    display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
}
.qf-fab {
    width: 56px; height: 56px; border-radius: 50%;
    background: linear-gradient(135deg, #2d607c, #427691);
    color: #fff; border: 0;
    font-size: 28px; font-weight: 800; line-height: 1;
    box-shadow: 0 12px 28px rgba(31, 88, 116, .35);
    cursor: pointer;
}
.qf-fab.is-open { background: linear-gradient(135deg, #b45309, #d97706); }
.qf-menu { display: flex; flex-direction: column; gap: 8px; align-items: flex-end; }
.qf-menu[hidden] { display: none; }
.qf-action {
    width: 48px; height: 48px; border-radius: 50%;
    background: #fff; color: #25485c;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 22px; text-decoration: none !important;
    box-shadow: 0 8px 20px rgba(31, 88, 116, .25);
    border: 1px solid #d9dee3;
    animation: qfPop .18s ease;
}
@keyframes qfPop { from { transform: scale(.6); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@media print, (min-width: 992px) { .qf-fab-wrap { display: none !important; } }
