/* ================================================================
   RESPONSIVE / SMALL VIEWPORT SAFEGUARDS
   Prevent fixed-height dropdowns, modals and sidebars from cutting
   off content on short or narrow screens.
   ================================================================ */

/* Viewport-relative max-height for tall dropdowns so they never extend
   past the visible viewport on short devices. */
.navbar-nav > li > .dropdown-menu.notifications,
.mobile-menu .dropdown-menu.notifications,
ul.search-results,
.started-timers-top,
._filter_data .dropdown-menu,
._filter_data .dropdown-menu.height500 {
    /* Older browsers that don't support min() fall back to 600px. */
    max-height: 600px !important;
    max-height: min(600px, calc(100vh - 70px)) !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
}

/* On very short viewports keep the dropdown from touching the edges. */
@media (max-height: 500px) {
    .navbar-nav > li > .dropdown-menu.notifications,
    .mobile-menu .dropdown-menu.notifications,
    ul.search-results,
    .started-timers-top {
        max-height: calc(100vh - 60px) !important;
    }
}

/* Sidebar popover: never exceed the viewport bounds horizontally or
   vertically; keep its own scrollbar if content is long. */
.sidebar-popover-menu {
    max-width: calc(100vw - var(--slim-sidebar-width) - 10px) !important;
    max-height: calc(100vh - 20px) !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
}

/* Mobile / small screens: make sure the off-canvas sidebar drawer is
   independently scrollable even when body scroll is locked. */
@media (max-width: 1024px) {
    #menu.sidebar {
        overflow-y: auto !important;
        -webkit-overflow-scrolling: touch !important;
    }

    /* Content should not force a wider page than the device. */
    .content {
        min-width: auto !important;
    }
}

/* Short viewports: reduce modal top margin so the footer/buttons remain
   reachable without excessive scrolling. */
@media (max-height: 600px) {
    .modal-dialog {
        margin-top: 10px !important;
        margin-bottom: 10px !important;
    }
}

/* ============================================================
   JomCore Ultra-Slim Modern Sidebar
   Icon-based 60px sidebar toggled by hamburger button
   ============================================================ */

/* ---------- CSS Variables ---------- */
:root {
    --slim-sidebar-width: 60px;
    --sidebar-expanded-width: 240px;
    --sidebar-accent: #0ac5a8;       /* JomCore Teal/Cyan */
    --sidebar-accent-light: rgba(10, 197, 168, 0.12);
    --sidebar-brand-navy: #002561;   /* JomCore Deep Navy */
    --sidebar-bg: #f8fafc;
    --sidebar-hover-bg: #f1f5f9;
    --sidebar-text: #64748b;
    --sidebar-text-active: #002561;  /* Navy for active text */
    --sidebar-transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ===============================================================
   JOMCORE DESIGN DNA TOKENS
   Canonical spec: /JOMCORE_DESIGN_DNA.md

   These tokens are the source of truth for the JomCore design system.
   New components and modules MUST prefer --dna-* tokens. Existing
   components remain on legacy --sidebar-*, --stat-card-*, etc.
   tokens for now; their migration is tracked in the DNA doc's
   "Migration Roadmap" section.
   =============================================================== */
:root {
    /* Brand */
    --dna-primary:        #0EA5E9;
    --dna-primary-hover:  #0284C7;
    --dna-primary-light:  #E0F2FE;

    /* Status */
    --dna-success:        #10B981;
    --dna-warning:        #F59E0B;
    --dna-danger:         #EF4444;
    --dna-purple:         #7C3AED;

    /* Neutrals */
    --dna-text:           #0F172A;
    --dna-text-secondary: #64748B;
    --dna-border:         #E2E8F0;
    --dna-bg:             #F8FAFC;
    --dna-card:           #FFFFFF;

    /* Radius */
    --dna-radius-card:    20px;
    --dna-radius-button:  14px;
    --dna-radius-input:   14px;
    --dna-radius-modal:   24px;
    --dna-radius-pill:    999px;

    /* Shadow */
    --dna-shadow-1:       0 10px 40px rgba(2, 8, 20, .06);
    --dna-shadow-1-hover: 0 18px 50px rgba(2, 8, 20, .08);

    /* Spacing (8-point system: 4 · 8 · 12 · 16 · 20 · 24 · 32 · 40 · 48 · 64) */
    --dna-sp-1:  4px;
    --dna-sp-2:  8px;
    --dna-sp-3:  12px;
    --dna-sp-4:  16px;
    --dna-sp-5:  20px;
    --dna-sp-6:  24px;
    --dna-sp-8:  32px;
    --dna-sp-10: 40px;
    --dna-sp-12: 48px;
    --dna-sp-16: 64px;

    /* Animation */
    --dna-anim-fast:   150ms;
    --dna-anim-ease:   cubic-bezier(0.16, 1, 0.3, 1);
    --dna-lift-hover:  translateY(-1px);
}

/* ===============================================================
   FLICKER FIX — Perfex dropdown fadeIn is 1 second.
   The default keyframe `animation-duration: 1s` on `.animated .fadeIn`
   means every dropdown open (profile menu, notifications, timers,
   quick-create, language selector, etc.) does a 1-second opacity
   oscillation that briefly scrapes the sidebar's snapshot. Override
   globally so Perfex's animated dropdowns snap open instead of fading
   for a full second. Visual impact: barely perceptible loss of a slow
   entrance; gain: zero 1-second pause.
   =============================================================== */
.animated,
.animated.fadeIn,
.dropdown-menu.animated.fadeIn {
    animation-duration: 0.15s !important;
}

/* Default state: Deep Navy icons */
#menu.sidebar .material-symbols-outlined {
    color: var(--sidebar-brand-navy);
    transition: color var(--sidebar-transition);
    font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}

/* Hover/active state: Teal/Cyan icons
   NOTE: Use exact class match (.tw-text-secondary / .tw-border-secondary),
   NOT substring match [class*="text-secondary"] which incorrectly matches the
   static "hover:tw-text-secondary" utility class on every submenu item. */
#menu.sidebar [class*="menu-item-wrapper-"] > a:hover .material-symbols-outlined,
#menu.sidebar .menu-item-wrapper-setup > a:hover .material-symbols-outlined,
#menu.sidebar [class*="menu-item-wrapper-"] > a.tw-text-secondary .material-symbols-outlined,
#menu.sidebar [class*="menu-item-wrapper-"] > a.tw-border-secondary .material-symbols-outlined,
#menu.sidebar .submenu-children a:hover .material-symbols-outlined,
#menu.sidebar .submenu-children a.tw-text-secondary .material-symbols-outlined {
    color: var(--sidebar-accent);
    font-variation-settings: 'FILL' 1, 'wght' 500, 'GRAD' 0, 'opsz' 24;
}

/* ================================================================
   DEFAULT STATE — Sidebar EXPANDED (240px, icons + text visible)
   ================================================================ */
#menu.sidebar {
    position: fixed !important;
    left: 0 !important;
    top: 0 !important;
    width: var(--sidebar-expanded-width) !important;
    overflow-x: hidden;
    overflow-y: auto;
    /* FLICKER FIX:
       - Explicit `width` transition (no `all`).
       - GPU layer: transform: translateZ(0) promotes `#menu` to its own
         composited layer, so its collapse animation doesn't repaint the
         adjacent <main>/<wrapper> region even though `width` itself is
         still layout-promoting. `will-change` reinforces the same hint.
       - `contain: layout` keeps the sidebar's internal layout from
         leaking into the rest of the document (skips recomputing the
         outer DOM on internal reflows like submenu expand).
       - `z-index: 60` lifted above #header so the dark backdrop and
         popover dropdowns render on top. */
    transition: width var(--sidebar-transition);
    transform: translateZ(0);
    will-change: width;
    contain: layout;
    z-index: 60;
    padding-left: 0 !important;
    padding-right: 0 !important;
    /* Preserve scroll position between page loads: persist `<aside>#menu`
       scrollTop to localStorage and the global handler in header.php
       restores it AFTER the synchronous sidebar-collapsed class is
       applied (preventing FOUC). */
}

#menu.sidebar nav {
    padding-left: 0 !important;
    padding-right: 0 !important;
}

/* Menu item wrappers */
#menu.sidebar .menu-item-wrapper-setup,
#menu.sidebar [class*="menu-item-wrapper-"] {
    position: relative;
    margin: 2px 0;
}

/* Menu links — default expanded look */
#menu.sidebar [class*="menu-item-wrapper-"] > a,
#menu.sidebar .menu-item-wrapper-setup > a {
    display: flex !important;
    align-items: center !important;
    gap: 0 !important;
    padding: 10px 16px !important;
    border-radius: 0 !important;
    white-space: nowrap;
    overflow: hidden;
    /* FLICKER FIX: never use `transition: all`. Listing only the props
       that actually animate prevents the browser from also transitioning
       layout-promoting props (padding, border-radius, etc.) on hover →
       avoids the per-frame reflow that paints the sidebar twice. */
    transition:
        background-color var(--sidebar-transition),
        border-left-color var(--sidebar-transition),
        color var(--sidebar-transition);
    border: none !important;
    border-left: 3px solid transparent !important;
    position: relative;
}

#menu.sidebar [class*="menu-item-wrapper-"] > a.tw-border-r-4 {
    border-right: none !important;
}

#menu.sidebar [class*="menu-item-wrapper-"] > a.tw-bg-surface-container-high {
    background: var(--sidebar-accent-light) !important;
}

/* Icons in expanded state — with margin */
#menu.sidebar [class*="menu-item-wrapper-"] > a > i,
#menu.sidebar [class*="menu-item-wrapper-"] > a > .material-symbols-outlined,
#menu.sidebar .menu-item-wrapper-setup > a > i,
#menu.sidebar .menu-item-wrapper-setup > a > .material-symbols-outlined {
    font-size: 22px !important;
    width: 24px !important;
    height: 24px !important;
    display: flex !important;
    align-items: center;
    justify-content: center;
    flex-shrink: 0 !important;
    margin-right: 14px !important;
    /* FLICKER FIX: explicit props only (color + opacity for collapse fade).
       Was: transition: all — fired on layout props too. */
    transition:
        color var(--sidebar-transition),
        opacity var(--sidebar-transition),
        margin-right var(--sidebar-transition);
}

#menu.sidebar [class*="menu-item-wrapper-"] > a > i {
    color: var(--sidebar-text);
}

/* Text labels — visible in expanded state */
#menu.sidebar [class*="menu-item-wrapper-"] > a > span:not(.badge):not(.material-symbols-outlined),
#menu.sidebar .menu-item-wrapper-setup > a > span:not(.badge):not(.material-symbols-outlined) {
    opacity: 1;
    width: auto;
    flex: 1;
    overflow: hidden;
    font-size: 14px !important;
    font-weight: 500;
    color: var(--sidebar-text);
    /* FLICKER FIX: only animate the props that change on collapse.
       Was: transition: all — fired on font-size/flex which shouldn't move. */
    transition:
        opacity var(--sidebar-transition),
        width var(--sidebar-transition),
        color var(--sidebar-transition);
    flex-shrink: 1;
}

/* Chevron — visible in expanded state */
#menu.sidebar .submenu-chevron {
    display: inline-block !important;
    font-size: 16px !important;
    flex-shrink: 0;
    margin-left: auto;
}

/* Badges — inline in expanded state */
#menu.sidebar [class*="menu-item-wrapper-"] > a > .badge,
#menu.sidebar .menu-item-wrapper-setup > a > .badge {
    position: relative;
    top: auto;
    right: auto;
    margin-left: 8px;
    font-size: 10px !important;
    min-width: 18px;
    height: 18px;
    line-height: 18px;
    padding: 0 5px !important;
    border-radius: 9px !important;
    z-index: 2;
    /* FLICKER FIX: only animate the props that change between expanded
       and collapsed (top/right/margin-left/position). Was: transition: all. */
    transition:
        top var(--sidebar-transition),
        right var(--sidebar-transition),
        margin-left var(--sidebar-transition),
        background-color 0.15s ease;
}

/* Active state — exact class match to avoid false positives on hover utility classes */
#menu.sidebar [class*="menu-item-wrapper-"] > a.tw-border-secondary,
#menu.sidebar [class*="menu-item-wrapper-"] > a.tw-text-secondary {
    border-left: 4px solid var(--sidebar-accent) !important;
    border-right: none !important;
    background: var(--sidebar-accent-light) !important;
}

#menu.sidebar [class*="menu-item-wrapper-"] > a.tw-border-secondary > span,
#menu.sidebar [class*="menu-item-wrapper-"] > a.tw-text-secondary > span {
    color: var(--sidebar-accent) !important;
    font-weight: 600;
}

/* Hover state */
#menu.sidebar [class*="menu-item-wrapper-"] > a:hover,
#menu.sidebar .menu-item-wrapper-setup > a:hover {
    background: var(--sidebar-hover-bg) !important;
    border-left-color: color-mix(in srgb, var(--sidebar-accent) 50%, transparent) !important;
}

/* Collapsed: prevent border-left hover/active from causing layout shift.
   The collapsed rule sets `border-left: none` (no reserved space). The
   hover rule above changes `border-left-color` to a non-transparent value,
   which, combined with `transition: all`, causes a 0→3px animated border
   width change. That 3px shift moves the link content and fires
   mouseout/mouseover in a loop → popover flicker. Override both the
   hover and active border-left to stay `none` in collapsed mode. */
body.sidebar-collapsed #menu.sidebar [class*="menu-item-wrapper-"] > a:hover,
body.sidebar-collapsed #menu.sidebar .menu-item-wrapper-setup > a:hover,
body.sidebar-collapsed #menu.sidebar [class*="menu-item-wrapper-"] > a.tw-border-secondary:hover,
body.sidebar-collapsed #menu.sidebar [class*="menu-item-wrapper-"] > a.tw-text-secondary:hover {
    border-left: none !important;
    border-right: none !important;
}

/* Submenu children animation comes from assets/css/style.css
   (max-height + opacity + visibility + transition). DO NOT override
   with `display:none` or `transition:none` here or animation breaks.
   JomCore-specific visuals only live in the OPEN state below. */

/* ── Submenu container (open state) ──
   Only JomCore-specific visual additions; let the framework drive the
   show/hide via max-height/opacity/visibility (so it animates). */
#menu.sidebar .submenu-children.submenu-open,
#menu.sidebar .menu-item-wrapper-setup .submenu-children.submenu-open {
    background: rgba(241, 245, 249, 0.65) !important;
    margin-bottom: 4px;
    border-radius: 8px !important;
}

/* ── Submenu item links — flex row, icons aligned with parent icons ── */
#menu.sidebar .submenu-children a,
#menu.sidebar .menu-item-wrapper-setup .submenu-children a {
    display: flex !important;
    align-items: center !important;
    gap: 14px !important;
    padding: 6px 14px !important;
    margin: 1px 0 !important;
    font-size: 13px !important;
    font-weight: 400 !important;
    line-height: 1.4;
    color: var(--sidebar-text) !important;
    white-space: nowrap;
    border-radius: 6px !important;
    overflow: hidden;
    transition: color 0.15s ease, background 0.15s ease;
}

#menu.sidebar .submenu-children a:hover,
#menu.sidebar .menu-item-wrapper-setup .submenu-children a:hover {
    color: var(--sidebar-accent) !important;
    background: var(--sidebar-accent-light) !important;
}

/* Active submenu text — exact class match so only the truly-active
   submenu item gets the accent color/bold, not every submenu link. */
#menu.sidebar .submenu-children a.tw-text-secondary,
#menu.sidebar .menu-item-wrapper-setup .submenu-children a.tw-text-secondary {
    color: var(--sidebar-accent) !important;
    font-weight: 600;
    gap: 8px !important;  /* tighter gap so dot sits close to text */
}

/* ── Active submenu dot indicator (replaces removed icon) ── */
#menu.sidebar .submenu-children a.tw-text-secondary::before,
#menu.sidebar .menu-item-wrapper-setup .submenu-children a.tw-text-secondary::before {
    content: '';
    width: 4px;
    height: 4px;
    min-width: 4px;
    border-radius: 50%;
    background: var(--sidebar-accent);
    flex-shrink: 0;
}

/* ── Submenu icons — hidden, not shown on submenu items ── */
#menu.sidebar .submenu-children a .material-symbols-outlined,
#menu.sidebar .submenu-children a > i,
#menu.sidebar .menu-item-wrapper-setup .submenu-children a .material-symbols-outlined,
#menu.sidebar .menu-item-wrapper-setup .submenu-children a > i {
    display: none !important;
}

/* ── Submenu text — single line, no wrap ── */
#menu.sidebar .submenu-children a > span:not(.badge):not(.material-symbols-outlined),
#menu.sidebar .menu-item-wrapper-setup .submenu-children a > span:not(.badge):not(.material-symbols-outlined) {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
}

/* Pinned projects */
#menu.sidebar .pinned-projects {
    display: block;
}

/* ================================================================
   ICON TOOLTIPS — shown on hover when sidebar is collapsed
   ================================================================ */
#sidebar-icon-tooltip {
    position: fixed;
    pointer-events: none;
    z-index: 1100;
    background: var(--sidebar-brand-navy);
    color: #fff;
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
    padding: 7px 12px;
    border-radius: 6px;
    white-space: nowrap;
    opacity: 0;
    transform: translateY(-50%) translateX(4px);
    transition: opacity 0.15s ease, transform 0.15s ease;
    box-shadow: 0 4px 12px rgba(0, 37, 97, 0.25);
}

#sidebar-icon-tooltip::before {
    content: '';
    position: absolute;
    left: -5px;
    top: 50%;
    transform: translateY(-50%);
    width: 0;
    height: 0;
    border-top: 5px solid transparent;
    border-bottom: 5px solid transparent;
    border-right: 5px solid var(--sidebar-brand-navy);
}

#sidebar-icon-tooltip.visible {
    opacity: 1;
    transform: translateY(-50%) translateX(0);
}

/* Hide tooltip on touch devices (no hover) */
@media (hover: none) and (pointer: coarse) {
    #sidebar-icon-tooltip {
        display: none !important;
    }
}

/* RTL: arrow points right instead of left, slide from left */
[dir="rtl"] #sidebar-icon-tooltip {
    transform: translateY(-50%) translateX(-4px);
}

[dir="rtl"] #sidebar-icon-tooltip.visible {
    transform: translateY(-50%) translateX(0);
}

[dir="rtl"] #sidebar-icon-tooltip::before {
    left: auto;
    right: -5px;
    border-right: none;
    border-left: 5px solid var(--sidebar-brand-navy);
}

/* ================================================================
   COLLAPSED STATE — Sidebar SLIM (60px, icons only, text hidden)
   ================================================================ */
body.sidebar-collapsed #menu.sidebar {
    width: var(--slim-sidebar-width) !important;
}

/* Collapsed: center icons, remove padding and margin */
body.sidebar-collapsed #menu.sidebar [class*="menu-item-wrapper-"] > a,
body.sidebar-collapsed #menu.sidebar .menu-item-wrapper-setup > a {
    padding: 10px 0 !important;
    justify-content: center;
    border-left: none !important;
}

body.sidebar-collapsed #menu.sidebar [class*="menu-item-wrapper-"] > a > i,
body.sidebar-collapsed #menu.sidebar [class*="menu-item-wrapper-"] > a > .material-symbols-outlined,
body.sidebar-collapsed #menu.sidebar .menu-item-wrapper-setup > a > i,
body.sidebar-collapsed #menu.sidebar .menu-item-wrapper-setup > a > .material-symbols-outlined {
    margin-right: 0 !important;
}

/* Collapsed: hide text */
body.sidebar-collapsed #menu.sidebar [class*="menu-item-wrapper-"] > a > span:not(.badge):not(.material-symbols-outlined),
body.sidebar-collapsed #menu.sidebar .menu-item-wrapper-setup > a > span:not(.badge):not(.material-symbols-outlined) {
    opacity: 0;
    width: 0;
    flex: 0;
}

/* Collapsed: hide chevron */
body.sidebar-collapsed #menu.sidebar .submenu-chevron {
    display: none !important;
}

/* Collapsed: badge overlay on icon corner */
body.sidebar-collapsed #menu.sidebar [class*="menu-item-wrapper-"] > a > .badge,
body.sidebar-collapsed #menu.sidebar .menu-item-wrapper-setup > a > .badge {
    position: absolute;
    top: 4px;
    right: 8px;
    margin-left: 0;
}

/* Collapsed: hide submenu content inline (popover handles display) */
body.sidebar-collapsed #menu.sidebar .submenu-children {
    display: none !important;
}

/* Expanded: also hide submenu content inline — the floating popover is used
   for both collapsed and expanded modes so the UX is consistent. */
body:not(.sidebar-collapsed) #menu.sidebar .submenu-children {
    display: none !important;
}

/* ================================================================
   FLOATING POPOVER SUBMENU — Shown when sidebar is collapsed
   and a parent menu item with submenu is clicked. Appears as a
   flyout panel to the right of the collapsed sidebar icon.
   ================================================================ */

/* The popover container — positioned fixed, right of the sidebar */
.sidebar-popover-menu {
    position: fixed;
    top: 0;
    left: var(--slim-sidebar-width);
    z-index: 1050;
    width: 220px;
    max-height: calc(100vh - 20px);
    overflow-y: auto;
    overflow-x: hidden;
    background: #FFFFFF;
    border: 1px solid #EAECF0;
    border-radius: 12px;
    box-shadow: 0 12px 40px rgba(16, 24, 40, 0.15), 0 4px 12px rgba(16, 24, 40, 0.08);
    padding: 6px;
    opacity: 0;
    transform: scale(0.97);
    transition: opacity 0.18s ease, transform 0.18s ease;
    pointer-events: none;
}


[dir="rtl"] .sidebar-popover-menu {
    left: auto;
    right: var(--slim-sidebar-width);
    transform: scale(0.97);
}

/* RTL scrollbar */
[dir="rtl"] .sidebar-popover-menu {
    direction: rtl;
}

/* Small hover bridge connecting the popover back to the sidebar so the
   cursor never hovers "empty space" while moving from the collapsed
   sidebar icon into the popover. It is transparent and only 6px wide,
   so it does not cover the clickable icon area. */
.sidebar-popover-menu::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    right: 100%;
    width: 6px;
    background: transparent;
}

[dir="rtl"] .sidebar-popover-menu::before {
    right: auto;
    left: 100%;
}

/* Visible state */
.sidebar-popover-menu.visible {
    opacity: 1;
    transform: translateX(0) scale(1);
    pointer-events: auto;
}

[dir="rtl"] .sidebar-popover-menu.visible {
    transform: translateX(0) scale(1);
}

/* Popover header — shows the parent menu item name */
.sidebar-popover-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px 8px 12px;
    border-bottom: 1px solid #F2F4F7;
    margin-bottom: 4px;
}

.sidebar-popover-header .popover-parent-icon {
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background: var(--sidebar-accent-light);
    color: var(--sidebar-accent);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    flex-shrink: 0;
}

.sidebar-popover-header .popover-parent-label {
    font-size: 13px;
    font-weight: 600;
    color: #101828;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Popover submenu items */
.sidebar-popover-menu .popover-submenu-item {
    display: flex;
    align-items: center;
    padding: 8px 12px;
    border-radius: 8px;
    color: #475467;
    font-size: 13px;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: background 0.12s ease, color 0.12s ease;
    cursor: pointer;
    border: none;
    background: none;
    width: 100%;
    text-align: left;
}

.sidebar-popover-menu .popover-submenu-item:hover {
    background: #F2F4F7;
    color: #101828;
}

.sidebar-popover-menu .popover-submenu-item.active {
    background: var(--sidebar-accent-light);
    color: var(--sidebar-accent);
    font-weight: 600;
}

.sidebar-popover-menu .popover-submenu-item.active::before {
    content: '';
    width: 4px;
    height: 4px;
    min-width: 4px;
    border-radius: 50%;
    background: var(--sidebar-accent);
    margin-right: 8px;
    flex-shrink: 0;
}

/* Hidden submenu icons in popover (consistent with expanded sidebar) */
.sidebar-popover-menu .popover-submenu-item .material-symbols-outlined,
.sidebar-popover-menu .popover-submenu-item > i {
    display: none !important;
}

/* Popover scrollbar styling */
.sidebar-popover-menu::-webkit-scrollbar {
    width: 4px;
}

.sidebar-popover-menu::-webkit-scrollbar-track {
    background: transparent;
}

.sidebar-popover-menu::-webkit-scrollbar-thumb {
    background: #D0D5DD;
    border-radius: 999px;
}


/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .sidebar-popover-menu {
        transition: none !important;
    }
}

/* Collapsed: always hide pinned projects */
body.sidebar-collapsed #menu.sidebar .pinned-projects {
    display: none !important;
}

/* Collapsed: scrollbar hidden */
body.sidebar-collapsed #menu.sidebar::-webkit-scrollbar {
    width: 0px;
}

/* ================================================================
   HAMBURGER TOGGLE BUTTON — Left/Right chevron arrows
   ================================================================ */
#sidebar-toggle {
    display: inline-flex !important;
    cursor: pointer;
    z-index: 100;
}

/* Both icons — GPU-accelerated for smooth transitions */
.sidebar-toggle-icon {
    color: var(--sidebar-brand-navy);
    transform: translateZ(0);
    transition: opacity 0.2s ease, transform 0.2s ease;
    will-change: transform, opacity;
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
}

/* ── Left chevron (collapse) — visible when sidebar is expanded ── */
.sidebar-toggle-icon--collapse {
  transform: translateX(10px) translateZ(0);
}

/* ── Right chevron (expand) — hidden when sidebar is expanded ── */
.sidebar-toggle-icon--expand {
    display: none;
    opacity: 0;
    transform: translateX(-4px) translateZ(0);
}

/* ── Hamburger (mobile menu) — hidden on desktop ── */
.sidebar-toggle-icon--hamburger {
    display: none;
    opacity: 0;
}

/* ── Collapsed state: swap icons ── */
body.sidebar-collapsed .sidebar-toggle-icon--collapse {
    display: none;
    opacity: 0;
    transform: translateX(4px) translateZ(0);
}

body.sidebar-collapsed .sidebar-toggle-icon--expand {
    display: inline;
    opacity: 1;
    transform: translateX(0) translateZ(0);
}

/* ── RTL: mirrored transforms ── */
[dir="rtl"] .sidebar-toggle-icon--expand {
    transform: translateX(4px) translateZ(0);
}

[dir="rtl"] body.sidebar-collapsed .sidebar-toggle-icon--collapse {
    transform: translateX(-4px) translateZ(0);
}

[dir="rtl"] body.sidebar-collapsed .sidebar-toggle-icon--expand {
    transform: translateX(0) translateZ(0);
}

/* ================================================================
   #WRAPPER & #HEADER MARGINS
   ================================================================ */

/* Default expanded: content offset by expanded sidebar width */
body #wrapper {
    margin-left: 0 !important;
    transition: margin-left var(--sidebar-transition);
    width: auto !important;
}

body #header {
    margin-left: var(--sidebar-expanded-width) !important;
    transition: margin-left var(--sidebar-transition);
    width: auto !important;
}

/* Collapsed: content offset by slim sidebar width */
body.sidebar-collapsed #wrapper
{
    margin-left: 0 !important;
}

body.sidebar-collapsed #header {
    margin-left: var(--slim-sidebar-width) !important;
}

/* ── Override old body classes ── */
body.hide-sidebar #menu.sidebar,
body.page-small #menu.sidebar {
    margin-left: 0 !important;
}

body.hide-sidebar:not(.show-sidebar) #wrapper,
body.page-small #wrapper {
    margin-left: 0 !important;
}

body.hide-sidebar:not(.show-sidebar) #header,
body.page-small #header {
    margin-left: 0 !important;
}

body.page-small.show-sidebar #wrapper,
body.page-small.show-sidebar #header {
    margin-left: var(--sidebar-expanded-width) !important;
}

/* ================================================================
   TRANSITION ANIMATION
   ================================================================ */
#menu.sidebar,
#menu.sidebar [class*="menu-item-wrapper-"] > a,
#menu.sidebar .menu-item-wrapper-setup > a,
#menu.sidebar [class*="menu-item-wrapper-"] > a > i,
#menu.sidebar [class*="menu-item-wrapper-"] > a > .material-symbols-outlined,
#menu.sidebar .menu-item-wrapper-setup > a > i,
#menu.sidebar .menu-item-wrapper-setup > a > .material-symbols-outlined,
#menu.sidebar [class*="menu-item-wrapper-"] > a > span,
#menu.sidebar .menu-item-wrapper-setup > a > span,
#menu.sidebar [class*="menu-item-wrapper-"] > a > .badge,
#menu.sidebar .menu-item-wrapper-setup > a > .badge,
#wrapper,
#header {
    /* FLICKER FIX: only `margin-left` animates (sidebar collapse shifts
       page content right by 180px). Was transition: all — did double
       layout-paint on every sidebar toggle. */
    transition: margin-left var(--sidebar-transition);
}

/* ================================================================
   LOGO (hidden in header; now lives in sidebar)
   ================================================================ */
#logo {
    display: none !important;
}

/* ================================================================
   SIDEBAR LOGO — positioned at top of sidebar
   ================================================================ */
#sidebar-logo {
    background: var(--sidebar-bg);
}

/* ── Expanded state: show full logo, hide icon mark ── */
#sidebar-logo .sidebar-logo-full {
    display: inline;
    opacity: 1;
    transition: opacity 0.15s ease;
}

#sidebar-logo .sidebar-logo-icon {
    display: none !important;
    opacity: 0;
    transition: opacity 0.15s ease;
    height:45px;
}

/* ── Collapsed state: show icon-only mark, hide full text ── */
body.sidebar-collapsed #sidebar-logo {
    padding-left: 4px !important;
    padding-right: 4px !important;
}

body.sidebar-collapsed #sidebar-logo .sidebar-logo-full {
    display: none !important;
    opacity: 0;
}

body.sidebar-collapsed #sidebar-logo .sidebar-logo-icon {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    opacity: 1;
}

/* ================================================================
   REDUCED MOTION — honor user OS-level preference.
   When the user has set "reduce motion" in OS settings, scrub all
   sidebar submenu / chevron transitions so expand/collapse is instant.
   ================================================================ */
@media (prefers-reduced-motion: reduce) {
    /* Honor user's OS-level reduce-motion preference: scrub ALL
       sidebar / wrapper / header transitions so collapse, expand,
       hover and chevron rotation are instant instead of animated. */
    #menu.sidebar,
    #menu.sidebar .submenu-children,
    #menu.sidebar .submenu-children.submenu-open,
    #menu.sidebar .submenu-chevron,
    #menu.sidebar [class*="menu-item-wrapper-"] > a,
    #menu.sidebar .menu-item-wrapper-setup > a,
    #menu.sidebar .submenu-children a,
    #sidebar-toggle .material-symbols-outlined,
    #wrapper,
    #header {
        transition: none !important;
    }
}

/* ================================================================
   RTL SUPPORT
   ================================================================ */
[dir="rtl"] #menu.sidebar {
    left: auto;
    right: 0;
}

[dir="rtl"] #menu.sidebar [class*="menu-item-wrapper-"] > a {
    border-left: none !important;
    border-right: 3px solid transparent !important;
}

[dir="rtl"] #menu.sidebar [class*="menu-item-wrapper-"] > a.tw-border-secondary {
    border-right-color: var(--sidebar-accent) !important;
    border-left: none !important;
}

[dir="rtl"] #menu.sidebar [class*="menu-item-wrapper-"] > a > i,
[dir="rtl"] #menu.sidebar [class*="menu-item-wrapper-"] > a > .material-symbols-outlined {
    margin-right: 0 !important;
    margin-left: 14px !important;
}

body.sidebar-collapsed [dir="rtl"] #menu.sidebar [class*="menu-item-wrapper-"] > a > i,
body.sidebar-collapsed [dir="rtl"] #menu.sidebar [class*="menu-item-wrapper-"] > a > .material-symbols-outlined {
    margin-left: 0 !important;
}

[dir="rtl"] #wrapper,
[dir="rtl"] #header {
    margin-left: 0 !important;
    margin-right: var(--sidebar-expanded-width) !important;
    width: auto !important;
}

body.sidebar-collapsed [dir="rtl"] #wrapper,
body.sidebar-collapsed [dir="rtl"] #header {
    margin-right: var(--slim-sidebar-width) !important;
}

/* ================================================================
   MOBILE / TABLET RESPONSIVE (≤1024px)
   - Sidebar hidden off-canvas by default
   - Hamburger icon toggles sidebar as overlay drawer
   - Closes on outside click, navigation, or hamburger re-click
   ================================================================ */
@media (max-width: 1024px) {
    /* Hide sidebar off-canvas; no margin on content */
    #menu.sidebar {
        position: fixed !important;
        left: -260px !important;
        right: auto !important;
        top: 0;
        bottom: 0;
        width: 260px !important;
        z-index: 200 !important;
        transition: left 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
        box-shadow: none;
    }

    /* RTL: sidebar slides from right */
    [dir="rtl"] #menu.sidebar {
        left: auto !important;
        right: -260px !important;
        transition: right 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
    }

    #wrapper,
    #header {
        margin-left: 0 !important;
        margin-right: 0 !important;
        transition: none !important;
    }

    /* Show hamburger icon, hide chevron icons */
    #sidebar-toggle .sidebar-toggle-icon--collapse,
    #sidebar-toggle .sidebar-toggle-icon--expand {
        display: none !important;
    }

    #sidebar-toggle .sidebar-toggle-icon--hamburger {
        display: inline !important;
        opacity: 1;
    }

    /* Safety net: ensure collapsed state doesn't affect mobile layout
       (the JS removes sidebar-collapsed on mobile, but this guards against edge cases) */
    body.sidebar-collapsed #menu.sidebar {
        width: 260px !important;
        left: -260px !important;
    }

    [dir="rtl"] body.sidebar-collapsed #menu.sidebar {
        left: auto !important;
        right: -260px !important;
    }

    /* Disable icon tooltips on mobile */
    #sidebar-icon-tooltip {
        display: none !important;
    }

    /* ── OPEN STATE: Sidebar slides in as overlay ── */
    body.sidebar-mobile-open #menu.sidebar {
        left: 0 !important;
        box-shadow: 4px 0 24px rgba(0, 37, 97, 0.18);
    }

    [dir="rtl"] body.sidebar-mobile-open #menu.sidebar {
        left: auto !important;
        right: 0 !important;
        box-shadow: -4px 0 24px rgba(0, 37, 97, 0.18);
    }

    /* Backdrop overlay — pointer-events: none so clicks pass through
       to the wrapper/body JS handler that closes the sidebar */
    body.sidebar-mobile-open::before {
        content: '';
        position: fixed;
        inset: 0;
        animation: mobile-backdrop-in 0.3s ease both;
        pointer-events: none;
    }

    @keyframes mobile-backdrop-in {
        from { opacity: 0; }
        to   { opacity: 1; }
    }

    /* Prevent body scroll when drawer is open */
    body.sidebar-mobile-open {
        overflow: hidden;
    }

    /* Ensure sidebar is full expanded when open on mobile */
    body.sidebar-mobile-open #menu.sidebar [class*="menu-item-wrapper-"] > a > span:not(.badge):not(.material-symbols-outlined) {
        opacity: 1 !important;
        width: auto !important;
        flex: 1 !important;
    }

    body.sidebar-mobile-open #menu.sidebar [class*="menu-item-wrapper-"] > a > i,
    body.sidebar-mobile-open #menu.sidebar [class*="menu-item-wrapper-"] > a > .material-symbols-outlined {
        margin-right: 14px !important;
    }

    body.sidebar-mobile-open #menu.sidebar .submenu-chevron {
        display: inline-block !important;
    }

    /* Override collapsed submenu hiding when drawer is open */
    body.sidebar-mobile-open #menu.sidebar .submenu-children {
        display: block !important;
    }
}

/* ================================================================
   MODERN TOGGLE SWITCH — Overrides old Bootstrap .onoffswitch
   Matches JomCore brand (teal #14B8A6). No HTML changes needed.
   ================================================================ */

/* ── Reset the old .onoffswitch container ── */
/* Use high-specificity selectors to beat Tailwind @apply rules */
.onoffswitch.onoffswitch {
    position: relative !important;
    display: inline-block !important;
    width: 42px !important;
    height: 24px !important;
    min-height: 0 !important;
    max-height: none !important;
    margin: 0 !important;
    padding: 0 !important;
    border: none !important;
    overflow: visible !important;
    box-sizing: border-box !important;
}

/* ── Hide the native checkbox ── */
.onoffswitch-checkbox.onoffswitch-checkbox {
    opacity: 0 !important;
    width: 0 !important;
    height: 0 !important;
    position: absolute !important;
    margin: 0 !important;
    padding: 0 !important;
}

/* ── The switch track (label) ── */
/* Double-class specificity to beat Tailwind @layer components */
.onoffswitch-label.onoffswitch-label {
    display: block !important;
    position: absolute !important;
    cursor: pointer !important;
    inset: 0 !important;
    top: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    left: 0 !important;
    background: #D0D5DD !important;
    border: none !important;
    border-width: 0 !important;
    border-color: transparent !important;
    border-radius: 999px !important;
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.15), inset 0 0 0 1px rgba(0, 0, 0, 0.06) !important;
    transition: background 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease !important;
    margin: 0 !important;
    padding: 0 !important;
    overflow: visible !important;
    height: 24px !important;
    min-height: 0 !important;
    max-height: none !important;
    width: 42px !important;
    line-height: normal !important;
    vertical-align: middle !important;
    box-sizing: border-box !important;
}

/* ── The sliding circle knob (::before) ── */
/* Double-class on label to beat Tailwind before: utilities */
.onoffswitch-label.onoffswitch-label::before {
    content: "" !important;
    display: block !important;
    position: absolute !important;
    width: 23px !important;
    min-width: 23px !important;
    max-width: 23px !important;
    height: 23px !important;
    min-height: 23px !important;
    max-height: 23px !important;
    left: 3px !important;
    right: auto !important;
    top: 3px !important;
    bottom: auto !important;
    inset: auto !important;
    background: #FFFFFF !important;
    border: none !important;
    border-width: 0 !important;
    border-radius: 50% !important;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) !important;
    transition: transform 0.2s ease !important;
    margin: 0 !important;
    padding: 0 !important;
    will-change: transform !important;
    box-sizing: border-box !important;
}

/* Remove old ::after completely */
.onoffswitch-label.onoffswitch-label::after {
    content: none !important;
    display: none !important;
}

/* ── ON state — checked ── */
.onoffswitch-checkbox:checked + .onoffswitch-label.onoffswitch-label {
    background: #14B8A6 !important;
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), inset 0 0 0 1px rgba(0, 0, 0, 0.04) !important;
}

.onoffswitch-checkbox:checked + .onoffswitch-label.onoffswitch-label::before {
    transform: translateX(18px) !important;
    left: 3px !important;
    right: auto !important;
}

/* ── Hover states ── */
.onoffswitch-label.onoffswitch-label:hover {
    filter: brightness(0.95);
}

/* ── Click micro-interaction — smooth scale press ── */
@keyframes jomcore-toggle-press {
    0%   { transform: scale(1); }
    40%  { transform: scale(0.9); }
    100% { transform: scale(1); }
}

.onoffswitch-label.onoffswitch-label:active {
    transform: scale(0.92) !important;
    transition: transform 0.08s ease !important;
}

/* Bounce-back spring animation after click */
.onoffswitch.onoffswitch.toggle-pressed .onoffswitch-label.onoffswitch-label {
    animation: jomcore-toggle-press 0.35s cubic-bezier(0.34, 1.56, 0.64, 1) both !important;
}

.onoffswitch-checkbox:checked + .onoffswitch-label.onoffswitch-label:hover {
    background: #0D9488 !important;
}

.onoffswitch-checkbox:not(:checked) + .onoffswitch-label.onoffswitch-label:hover {
    background: #98A2B3 !important;
}

/* ── Focus accessibility ── */
.onoffswitch-checkbox:focus-visible + .onoffswitch-label.onoffswitch-label {
    outline: 2px solid rgba(20, 184, 166, 0.4);
    outline-offset: 2px;
}

/* ── Disabled state ── */
.onoffswitch-checkbox:disabled + .onoffswitch-label.onoffswitch-label {
    opacity: 0.5 !important;
    cursor: not-allowed !important;
    filter: grayscale(30%);
}

.onoffswitch-checkbox:disabled + .onoffswitch-label.onoffswitch-label:hover {
    filter: grayscale(30%);
    background: #D0D5DD !important;
}

.onoffswitch-checkbox:disabled:checked + .onoffswitch-label.onoffswitch-label {
    background: #14B8A6 !important;
    opacity: 0.5 !important;
}

/* ── Table alignment — center toggles in table cells ── */
td .onoffswitch.onoffswitch {
    display: flex !important;
    justify-content: center;
    align-items: center;
}

/* ── RTL support — mirror the circle slide direction ── */
[dir="rtl"] .onoffswitch-checkbox:checked + .onoffswitch-label.onoffswitch-label::before {
    transform: translateX(-18px) !important;
    left: 3px !important;
    right: auto !important;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
    .onoffswitch-label.onoffswitch-label,
    .onoffswitch-label.onoffswitch-label::before {
        transition: none !important;
    }
}

/* ================================================================
   MODERN MODALS — Overrides Bootstrap .modal
   Clean, spacious, with subtle backdrop blur
   ================================================================ */

/* ── Backdrop ── */
/* NOTE: backdrop-filter removed — it creates a compositing layer that
   can render above modal content in some browsers despite lower z-index.
   pointer-events: none lets clicks pass through to the modal content
   even when the backdrop is composited in front. The modal container
   still handles outside-click close via the delegated click handler
   in header.php. */
.modal-backdrop {
    display: none !important;
    position: fixed !important;
    top: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    left: 0 !important;
    background: rgba(15, 23, 42, 0.55) !important;
    z-index: 100040 !important;
    pointer-events: none !important;
}

.modal-backdrop.in {
    opacity: 1 !important;
}

/* ── Modal container ── */
.modal {
    z-index: 100050 !important;
    padding: 0 !important;
    /* Ensure the modal establishes its own stacking context
       so .modal-content (which uses transform for the entrance
       animation) is composited ABOVE the .modal-backdrop. */
    position: fixed !important;
    top: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    left: 0 !important;
    overflow-x: hidden !important;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch !important;
    outline: 0 !important;
}

/* Keep the dialog content above the backdrop even if a child element
   establishes its own stacking context. */
.modal-dialog,
.modal-content {
    position: relative;
    z-index: 1;
}

.modal-dialog {
    margin-top: 30px !important;
}

/* ── Modal content ── */
.modal-content {
    border: 1px solid #eaecf0 !important;
    border-radius: var(--dna-radius-modal) !important;
    box-shadow: var(--dna-shadow-1-hover) !important;
    overflow: hidden !important;
    background: #ffffff !important;
    animation: jomcore-modal-in var(--dna-anim-fast) var(--dna-anim-ease) both;
}

@keyframes jomcore-modal-in {
    from {
        opacity: 0;
        transform: translateY(12px) scale(0.97);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

/* ── Modal header ── */
.modal-header {
    border-bottom: 1px solid #eaecf0 !important;
    padding: 20px 24px !important;
    background: #fafbfc !important;
}

.modal-header .modal-title {
    font-size: 16px !important;
    font-weight: 600 !important;
    color: #101828 !important;
    letter-spacing: -0.01em !important;
}

.modal-header .close {
    opacity: 0.5 !important;
    font-size: 20px !important;
    width: 32px !important;
    height: 32px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    border-radius: 8px !important;
    transition: background 0.12s ease, opacity 0.12s ease !important;
    margin: -4px -4px -4px auto !important;
    border: none !important;
    background: transparent !important;
    cursor: pointer !important;
}

.modal-header .close:hover {
    opacity: 1 !important;
    background: #f2f4f7 !important;
}

/* ── Modal body ── */
.modal-body {
    padding: 24px !important;
}

/* ── Modal footer ── */
.modal-footer {
    border-top: 1px solid #eaecf0 !important;
    padding: 16px 24px !important;
    background: #fafbfc !important;
}

.modal-footer .btn {
    border-radius: 8px !important;
    font-size: 13.5px !important;
    font-weight: 500 !important;
    padding: 8px 16px !important;
}

/* ── Large modals ── */
.modal-lg {
    border-radius: 16px !important;
}

/* ── Full-screen modals (task modals etc.) ── */
.full-screen-modal .modal-content {
    border-radius: 16px !important;
}

/* ================================================================
   MODERN FORM INPUTS — Enhanced styling
   ================================================================ */

/* ── Base form controls ── */
.form-control,
select.form-control,
textarea.form-control {
    border: 1px solid var(--dna-border) !important;
    border-radius: var(--dna-radius-input) !important;
    font-size: 14px !important;
    color: var(--dna-text) !important;
    background: var(--dna-card) !important;
    transition: border-color var(--dna-anim-fast) ease, box-shadow var(--dna-anim-fast) ease !important;
    line-height: 1.5 !important;
}

.form-control::placeholder {
    color: #98a2b3 !important;
}

.form-control:hover {
    border-color: #98a2b3 !important;
}

.form-control:focus {
    /* Focus uses --dna-primary (sky-blue) per Design DNA.
       Sidebar keeps its teal accent for brand consistency;
       form chrome intentionally diverges per spec. */
    border-color: var(--dna-primary) !important;
    box-shadow: 0 0 0 3px rgba(14, 165, 233, 0.12) !important;
    outline: none !important;
}

/* ── Select dropdowns ── */
/* Only apply custom arrow to native selects, NOT bootstrap-select picker */
select.form-control:not(.selectpicker) {
    cursor: pointer !important;
    appearance: none !important;
    -webkit-appearance: none !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23667085' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E") !important;
    background-repeat: no-repeat !important;
    background-position: right 10px center !important;
    padding-right: 32px !important;
}

/* ── Textareas ── */
textarea.form-control {
    resize: vertical !important;
    min-height: 80px !important;
}

/* ── Input groups ── */
.input-group .form-control {
    border-radius: 0 !important;
}

.input-group .form-control:first-child {
    border-top-left-radius: 8px !important;
    border-bottom-left-radius: 8px !important;
}

.input-group .form-control:last-child {
    border-top-right-radius: 8px !important;
    border-bottom-right-radius: 8px !important;
}

.input-group-addon {
    border: 1px solid #d0d5dd !important;
    background: #f9fafb !important;
    color: #667085 !important;
    border-radius: 0 !important;
}

.input-group-addon:first-child {
    border-top-left-radius: 8px !important;
    border-bottom-left-radius: 8px !important;
}

.input-group-addon:last-child {
    border-top-right-radius: 8px !important;
    border-bottom-right-radius: 8px !important;
}

/* ── Error states ── */
.has-error .form-control {
    border-color: #f97066 !important;
    box-shadow: 0 0 0 3px rgba(249, 112, 102, 0.12) !important;
}

.has-error .control-label,
.has-error .help-block {
    color: #d92d20 !important;
}

/* ── Success states ── */
.has-success .form-control {
    border-color: #32d583 !important;
    box-shadow: 0 0 0 3px rgba(50, 213, 131, 0.12) !important;
}

/* ── Disabled states ── */
.form-control[disabled],
.form-control[readonly] {
    background: #f9fafb !important;
    color: #98a2b3 !important;
    cursor: not-allowed !important;
    border-color: #e4e7ec !important;
}

/* ── Checkbox / Radio modernization ── */
.checkbox label,
.radio label {
    font-weight: 400 !important;
    color: #344054 !important;
}

.checkbox label::before {
    border-radius: 4px !important;
    border: 1.5px solid #d0d5dd !important;
}

/* ── Labels / Form group labels ── */
.control-label {
    font-size: 13px !important;
    font-weight: 600 !important;
    color: #344054 !important;
    margin-bottom: 6px !important;
}

/* ── Form group spacing ── */
.form-group {
    margin-bottom: 16px !important;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
    .modal-content {
        animation: none !important;
    }
}

/* ================================================================
   MODERN KPI STATS CARDS — JomCore SaaS-style stat cards
   Overrides old PerfexCRM stat cards globally with a premium
   Stripe/Linear-inspired design. Works with existing HTML.
   ================================================================ */

/* ── CSS Variables for theming & dark mode preparation ── */
:root {
    --stat-card-bg: #FFFFFF;
    --stat-card-border: #EAECF0;
    --stat-card-radius: 16px;
    --stat-card-padding: 20px;
    --stat-card-shadow: var(--dna-shadow-1); /* aliased to DNA resting shadow */
    --stat-card-shadow-hover: var(--dna-shadow-1-hover); /* aliased to DNA hover shadow */
    --stat-text-primary: #101828;
    --stat-text-secondary: #667085;
    --stat-text-muted: #98A2B3;
    --stat-bar-track: #F2F4F7;
    --stat-icon-blue-bg: #EFF6FF;
    --stat-icon-blue-fg: #2563EB;
    --stat-icon-green-bg: #ECFDF3;
    --stat-icon-green-fg: #12B76A;
    --stat-icon-amber-bg: #FFFAEB;
    --stat-icon-amber-fg: #F79009;
    --stat-icon-red-bg: #FEF3F2;
    --stat-icon-red-fg: #F04438;
    --stat-icon-purple-bg: #F5F3FF;
    --stat-icon-purple-fg: #7C3AED;
}

/* ── Dark mode preparation (activate with .dark-mode on body) ── */
body.dark-mode {
    --stat-card-bg: #1D2939;
    --stat-card-border: #344054;
    --stat-card-shadow: var(--dna-shadow-1); /* aliased to DNA resting shadow */
    --stat-card-shadow-hover: var(--dna-shadow-1-hover); /* aliased to DNA hover shadow */
    --stat-text-primary: #F9FAFB;
    --stat-text-secondary: #98A2B3;
    --stat-text-muted: #667085;
    --stat-bar-track: #344054;
    --stat-icon-blue-bg: rgba(37, 99, 235, 0.15);
    --stat-icon-blue-fg: #60A5FA;
    --stat-icon-green-bg: rgba(18, 183, 106, 0.15);
    --stat-icon-green-fg: #34D399;
    --stat-icon-amber-bg: rgba(247, 144, 9, 0.15);
    --stat-icon-amber-fg: #FBBF24;
    --stat-icon-red-bg: rgba(240, 68, 56, 0.15);
    --stat-icon-red-fg: #F87171;
    --stat-icon-purple-bg: rgba(124, 58, 237, 0.15);
    --stat-icon-purple-fg: #A78BFA;
}

/* ── Responsive stats grid (replaces Bootstrap cols for stat cards) ──
   Layout strategy:
   - `minmax(160px, 1fr)` keeps the auto-fit behavior while ensuring 6 KPI
     cards fit on a single row at common laptop widths (~1280px viewport,
     sidebar 240px → content ~1040px; 6 × 160 + 5 × 12 gap = 1020 ≤ 1024).
     This eliminates the multi-row wrap that previously caused cards in
     separate rows to render at different heights.
   - `grid-auto-rows: minmax(108px, auto)` enforces a 108px floor on every
     implicit row. Cards without a progress bar stretch to fill via the
     default `align-items: stretch`, ending up the same height as cards
     WITH a progress bar in the same row. The `auto` upper bound keeps
     cards from clipping if a future widget ever renders taller. */
.jomcore-stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    grid-auto-rows: minmax(108px, auto);
    gap: 12px;
    margin-bottom: 24px;
}

/* ── Dashboard widgets — consistent section rhythm ──
   Add a uniform 20px bottom margin between WIDGET rows so the dashboard
   reads as a clean stacked layout instead of stacked-but-jammed. We
   intentionally avoid a `:last-child` reset here because hook outputs
   (e.g. `hooks()->do_action('after_dashboard')`) inserted after the last
   container would become the `:last-child` and break the reset; the
   trailing 20px above any hook content is a desirable gap. */
.content .row > [data-container] {
    margin-bottom: 20px;
}

@media (max-width: 1200px) {
    .jomcore-stats-grid {
        grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    }
}

@media (max-width: 768px) {
    .jomcore-stats-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 480px) {
    .jomcore-stats-grid {
        grid-template-columns: 1fr;
    }
}

/* ── Base card: overrides .top_stats_wrapper (dashboard) ── */
.top_stats_wrapper {
    background: var(--stat-card-bg) !important;
    border: 1px solid var(--stat-card-border) !important;
    border-radius: var(--stat-card-radius) !important;
    padding: 16px !important;
    min-height: 90px !important;
    box-shadow: var(--stat-card-shadow) !important;
    transition: transform 0.2s ease, box-shadow 0.2s ease !important;
    display: flex !important;
    flex-direction: column !important;
    justify-content: space-between !important;
    overflow: hidden !important;
    position: relative !important;
    box-sizing: border-box !important;
}

/* ── Interactive stat card (button/a wrappers) ── */
button.top_stats_wrapper,
a.top_stats_wrapper {
    cursor: pointer !important;
    text-align: left !important;
    text-decoration: none !important;
    color: inherit !important;
    font-family: inherit !important;
    width: 100% !important;
    border: 1px solid var(--stat-card-border) !important;
    outline: none !important;
}

button.top_stats_wrapper:hover,
a.top_stats_wrapper:hover {
    border-color: #D0D5DD !important;
}

.top_stats_wrapper:hover {
    /* DNA-mandated lift + hover shadow. See /JOMCORE_DESIGN_DNA.md */
    transform: var(--dna-lift-hover) !important;
    box-shadow: var(--dna-shadow-1-hover) !important;
}

/* ── Icon container inside stat cards ── */
.stats-icon-container {
    width: 40px !important;
    height: 40px !important;
    min-width: 40px !important;
    border-radius: 10px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    flex-shrink: 0 !important;
    transition: transform 0.2s ease !important;
    font-size: 18px !important;
}

.top_stats_wrapper:hover .stats-icon-container {
    transform: scale(1.05) !important;
}

/* ── Label text in stat cards ── */
.top_stats_wrapper .tw-text-xs,
.top_stats_wrapper .tw-text-neutral-500 {
    font-size: 13px !important;
    font-weight: 500 !important;
    color: var(--stat-text-secondary) !important;
    letter-spacing: 0 !important;
    text-transform: none !important;
}

/* ── Value text in stat cards ── */
.top_stats_wrapper .tw-text-lg,
.top_stats_wrapper .tw-font-bold {
    font-size: 22px !important;
    font-weight: 700 !important;
    color: var(--stat-text-primary) !important;
    letter-spacing: -0.02em !important;
    line-height: 1.2 !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
}

/* ── Sub-value (e.g. "/ 100") ── */
.top_stats_wrapper .tw-text-neutral-400 {
    color: var(--stat-text-muted) !important;
    font-size: 14px !important;
    font-weight: 500 !important;
}

/* ── Progress bar modernization ── */
.top_stats_wrapper .progress {
    height: 6px !important;
    border-radius: 999px !important;
    background: #F2F4F7 !important;
    overflow: hidden !important;
    margin-top: 12px !important;
    margin-bottom: 0 !important;
}

.top_stats_wrapper .progress-bar {
    border-radius: 999px !important;
    transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1) !important;
}

/* ── Quick stats grid (invoices/estimates/expenses) ── */
.quick-top-stats button,
.quick-top-stats dl > div,
.quick-top-stats .tw-bg-white {
    background: var(--stat-card-bg) !important;
    border: 1px solid var(--stat-card-border) !important;
    border-radius: var(--stat-card-radius) !important;
    padding: 16px !important;
    min-height: 90px !important;
    box-shadow: var(--stat-card-shadow) !important;
    transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease !important;
    text-align: left !important;
    box-sizing: border-box !important;
    overflow: hidden !important;
}

.quick-top-stats button:hover,
.quick-top-stats dl > div:hover {
    transform: var(--dna-lift-hover) !important;
    box-shadow: var(--dna-shadow-1-hover) !important;
    border-color: var(--dna-border) !important;
    background: var(--dna-bg) !important;
}

/* Quick stats label */
.quick-top-stats .tw-text-xs,
.quick-top-stats .tw-text-neutral-500,
.quick-top-stats dt {
    font-size: 13px !important;
    font-weight: 500 !important;
    color: var(--stat-text-secondary) !important;
}

/* Quick stats value */
.quick-top-stats .tw-font-semibold,
.quick-top-stats dd .tw-font-semibold {
    font-size: 18px !important;
    font-weight: 700 !important;
    color: var(--stat-text-primary) !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
}

/* ── Entrance animation (staggered) ── */
@keyframes jomcore-stat-card-in {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.top_stats_wrapper,
.quick-top-stats button {
    animation: jomcore-stat-card-in 0.3s ease both !important;
}

.top_stats_wrapper:nth-child(2),
.quick-top-stats button:nth-child(2) {
    animation-delay: 0.05s !important;
}

.top_stats_wrapper:nth-child(3),
.quick-top-stats button:nth-child(3) {
    animation-delay: 0.1s !important;
}

.top_stats_wrapper:nth-child(4),
.quick-top-stats button:nth-child(4) {
    animation-delay: 0.15s !important;
}

.top_stats_wrapper:nth-child(5),
.quick-top-stats button:nth-child(5) {
    animation-delay: 0.2s !important;
}

.top_stats_wrapper:nth-child(6),
.quick-top-stats button:nth-child(6) {
    animation-delay: 0.25s !important;
}

/* ── Grid responsive behavior ── */
.quick-top-stats .tw-grid,
.quick-top-stats .jomcore-stats-grid {
    gap: 12px !important;
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
    .top_stats_wrapper,
    .quick-top-stats button {
        animation: none !important;
        transition: none !important;
    }
    .top_stats_wrapper:hover,
    .quick-top-stats button:hover {
        transform: none !important;
    }
}

/* Extra: small phones (≤480px) — wider drawer with space
   to see the hamburger toggle (56px) behind the overlay */
@media (max-width: 480px) {
    #menu.sidebar {
        width: calc(100vw - 56px) !important;
        left: calc(-100vw + 56px) !important;
    }

    [dir="rtl"] #menu.sidebar {
        left: auto !important;
        right: calc(-100vw + 56px) !important;
    }

    body.sidebar-mobile-open #menu.sidebar {
        left: 0 !important;
    }

    [dir="rtl"] body.sidebar-mobile-open #menu.sidebar {
        left: auto !important;
        right: 0 !important;
    }
}

/* ================================================================
   MODERN ALERT BANNERS — Toast/banner style announcements
   Full-width banners with icon, content, and dismiss actions.
   Replaces old Bootstrap .alert-info announcements.
   ================================================================ */

/* ── Base banner ── */
.jomcore-alert-banner {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 16px 20px;
    border-radius: 14px;
    border: 1px solid;
    margin-bottom: 12px;
    position: relative;
    animation: jomcore-alert-in 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
    font-family: 'Inter', system-ui, -apple-system, sans-serif;
}

@keyframes jomcore-alert-in {
    from {
        opacity: 0;
        transform: translateY(-8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* ── Info variant (default/announcements) ── */
.jomcore-alert-info {
    background: #EFF6FF;
    border-color: #BFDBFE;
    color: #1E40AF;
}

/* ── Warning variant ── */
.jomcore-alert-warning {
    background: #FFFBEB;
    border-color: #FDE68A;
    color: #92400E;
}

/* ── Danger/Error variant ── */
.jomcore-alert-danger {
    background: #FEF2F2;
    border-color: #FECACA;
    color: #991B1B;
}

/* ── Success variant ── */
.jomcore-alert-success {
    background: #F0FDF4;
    border-color: #BBF7D0;
    color: #166534;
}

/* ── Icon container ── */
.jomcore-alert-icon {
    width: 40px;
    height: 40px;
    min-width: 40px;
    border-radius: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    margin-top: 2px;
}

.jomcore-alert-info .jomcore-alert-icon {
    background: #DBEAFE;
    color: #2563EB;
}

.jomcore-alert-warning .jomcore-alert-icon {
    background: #FEF3C7;
    color: #D97706;
}

.jomcore-alert-danger .jomcore-alert-icon {
    background: #FEE2E2;
    color: #DC2626;
}

.jomcore-alert-success .jomcore-alert-icon {
    background: #DCFCE7;
    color: #16A34A;
}

/* ── Content area ── */
.jomcore-alert-content {
    flex: 1;
    min-width: 0;
}

.jomcore-alert-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 4px;
}

.jomcore-alert-title {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.jomcore-alert-info .jomcore-alert-title { color: #1E40AF; }
.jomcore-alert-warning .jomcore-alert-title { color: #92400E; }
.jomcore-alert-danger .jomcore-alert-title { color: #991B1B; }
.jomcore-alert-success .jomcore-alert-title { color: #166534; }

.jomcore-alert-date {
    font-size: 11px;
    font-weight: 500;
    opacity: 0.7;
}

.jomcore-alert-from {
    font-size: 12px;
    margin: 0 0 6px 0;
    opacity: 0.8;
}

.jomcore-alert-heading {
    font-size: 15px;
    font-weight: 600;
    margin: 0 0 6px 0;
    line-height: 1.4;
}

.jomcore-alert-body {
    font-size: 13px;
    line-height: 1.6;
    opacity: 0.9;
}

.jomcore-alert-body p:last-child {
    margin-bottom: 0;
}

/* ── Actions (edit + dismiss) ── */
.jomcore-alert-actions {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    margin-top: 2px;
}

.jomcore-alert-action-btn,
.jomcore-alert-dismiss {
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    border: none;
    background: transparent;
    cursor: pointer;
    transition: background 0.12s ease, opacity 0.12s ease;
    opacity: 0.5;
    color: inherit;
    text-decoration: none;
}

.jomcore-alert-action-btn:hover,
.jomcore-alert-dismiss:hover {
    opacity: 1;
    background: rgba(0, 0, 0, 0.08);
}

/* ── Responsive: stack on mobile ── */
@media (max-width: 640px) {
    .jomcore-alert-banner {
        padding: 12px 14px;
        gap: 10px;
    }

    .jomcore-alert-icon {
        width: 34px;
        height: 34px;
        min-width: 34px;
    }

    .jomcore-alert-heading {
        font-size: 14px;
    }
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
    .jomcore-alert-banner {
        animation: none !important;
    }
}

/* ================================================================
   MODERN DASHBOARD WIDGET PANELS — Polish legacy .panel_s cards
   Gives all dashboard widget containers a premium look matching
   the new KPI stat cards (rounded, soft shadow, clean borders).
   ================================================================ */

/* ── Widget container panels ── */
.widget .panel_s {
    background: var(--stat-card-bg) !important;
    border: 1px solid var(--stat-card-border) !important;
    border-radius: var(--stat-card-radius) !important;
    box-shadow: var(--stat-card-shadow) !important;
    transition: box-shadow 0.2s ease, transform 0.2s ease !important;
}

.widget .panel_s:hover {
    box-shadow: var(--stat-card-shadow-hover) !important;
}

/* Hide widget drag handles — widgets are fixed, not draggable */
.widget-dragger {
    display: none !important;
}

/* Widget panel body padding */
.widget .panel_s .panel-body {
    padding: 20px !important;
}

/* Widget title inside panel */
.widget .panel_s .panel-body > *:first-child {
    font-size: 15px !important;
    font-weight: 600 !important;
    color: var(--stat-text-primary) !important;
    letter-spacing: -0.01em !important;
}

/* Widget drag handle placeholder */
.placeholder-dashboard-widgets {
    border: 2px dashed var(--stat-card-border) !important;
    border-radius: var(--stat-card-radius) !important;
    min-height: 80px !important;
    background: #FAFBFC !important;
    margin-bottom: 12px !important;
    transition: border-color 0.2s ease, background 0.2s ease !important;
}

.placeholder-dashboard-widgets.pl-preview {
    background: #F0FDFA !important;
    border-color: #14B8A6 !important;
}

/* ── Chart.js tooltip overrides are applied via JS in dashboard_js.php ── */

/* ── Dashboard data tables ── */
.widget .dataTable,
.widget table.table {
    border-collapse: collapse !important;
    border-spacing: 0 !important;
}

.widget .dataTable thead th {
    background: #FAFBFC !important;
    color: var(--stat-text-secondary) !important;
    font-size: 12px !important;
    font-weight: 600 !important;
    text-transform: uppercase !important;
    letter-spacing: 0.04em !important;
    border-bottom: 1px solid var(--stat-card-border) !important;
    padding: 10px 12px !important;
}

.widget .dataTable tbody td {
    font-size: 13px !important;
    color: var(--stat-text-primary) !important;
    border-bottom: 1px solid #F2F4F7 !important;
    padding: 10px 12px !important;
    vertical-align: middle !important;
}

.widget .dataTable tbody tr:last-child td {
    border-bottom: none !important;
}

.widget .dataTable tbody tr:hover td {
    background: #FAFBFC !important;
}

/* ================================================================
   MODERN DASHBOARD WIDGET MANAGER — Right-Side Drawer
   Notion/Linear-style slide-over panel for customizing dashboard widgets
   ================================================================ */

/* ── Overlay backdrop ── */
.jomcore-widget-drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    z-index: 1050;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s ease, visibility 0s linear 0.25s;
    pointer-events: none;
}

.jomcore-widget-drawer-backdrop.open {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.25s ease, visibility 0s linear 0s;
    pointer-events: auto;
}

/* ── Drawer panel ── */
.jomcore-widget-drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 420px;
    display: none;
    max-width: 90vw;
    background: #FFFFFF;
    z-index: 1060;
    flex-direction: column;
    box-shadow: -8px 0 32px rgba(16, 24, 40, 0.12), -2px 0 8px rgba(16, 24, 40, 0.06);
    border-left: 1px solid #EAECF0;
}

[dir="rtl"] .jomcore-widget-drawer {
    right: auto;
    left: 0;
    box-shadow: 8px 0 32px rgba(16, 24, 40, 0.12), 2px 0 8px rgba(16, 24, 40, 0.06);
    border-left: none;
    border-right: 1px solid #EAECF0;
}

.jomcore-widget-drawer.open {
    display: flex;
    flex-direction: column;
    transform: translateX(0);
    pointer-events: auto;
    animation: jomcore-drawer-in 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.jomcore-widget-drawer.closing {
    display: flex;
    flex-direction: column;
    pointer-events: none;
    animation: jomcore-drawer-out 0.25s cubic-bezier(0.4, 0, 0.2, 1) both;
}

@keyframes jomcore-drawer-in {
    from { transform: translateX(100%); }
    to   { transform: translateX(0); }
}

@keyframes jomcore-drawer-out {
    from { transform: translateX(0); }
    to   { transform: translateX(100%); }
}

/* RTL: mirror slide direction */
[dir="rtl"] .jomcore-widget-drawer.open {
    animation-name: jomcore-drawer-in-rtl;
}

[dir="rtl"] .jomcore-widget-drawer.closing {
    animation-name: jomcore-drawer-out-rtl;
}

@keyframes jomcore-drawer-in-rtl {
    from { transform: translateX(-100%); }
    to   { transform: translateX(0); }
}

@keyframes jomcore-drawer-out-rtl {
    from { transform: translateX(0); }
    to   { transform: translateX(-100%); }
}

/* ── Drawer header ── */
.jomcore-widget-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 20px 24px 16px;
    border-bottom: 1px solid #EAECF0;
    flex-shrink: 0;
}

.jomcore-widget-drawer-header h3 {
    font-size: 16px !important;
    font-weight: 600 !important;
    color: #101828 !important;
    margin: 0 !important;
    letter-spacing: -0.01em;
}

.jomcore-widget-drawer-close {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: transparent;
    border-radius: 8px;
    cursor: pointer;
    color: #667085;
    transition: background 0.12s ease, color 0.12s ease;
    flex-shrink: 0;
}

.jomcore-widget-drawer-close:hover {
    background: #F2F4F7;
    color: #101828;
}

/* ── Search bar ── */
.jomcore-widget-drawer-search {
    padding: 16px 24px 12px;
    flex-shrink: 0;
}

.jomcore-widget-drawer-search input {
    width: 100%;
    padding: 9px 12px 9px 36px;
    border: 1px solid #D0D5DD;
    border-radius: 8px;
    font-size: 13.5px;
    color: #101828;
    background: #FFFFFF;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    outline: none;
    font-family: 'Inter', system-ui, -apple-system, sans-serif;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2398A2B3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 10px center;
}

.jomcore-widget-drawer-search input::placeholder {
    color: #98A2B3;
}

.jomcore-widget-drawer-search input:focus {
    border-color: #14B8A6;
    box-shadow: 0 0 0 3px rgba(20, 184, 166, 0.12);
}

/* ── Drawer body (scrollable) ── */
.jomcore-widget-drawer-body {
    flex: 1;
    /* min-height: 0 lets this flex child actually shrink below its
       content's intrinsic height so overflow-y: auto can take over.
       Without it, the body's default min-height: auto (= content size)
       prevents the parent drawer from constraining its height, breaking
       scrolling. */
    min-height: 0;
    overflow-y: auto;
    padding: 8px 24px 24px;
    overscroll-behavior: contain;
}

/* ── Drawer safe-overflow & viewport-bounded height ──
   Belt-and-suspenders: clip any rogue element (wide images, code blocks,
   long unbroken strings) inside the drawer so it never spills past the
   420px panel width. Scroll is owned by the drawer body child (its own
   scroll container with overflow-y:auto), not the drawer itself — so a
   single `overflow: hidden` (clipping both axes) is correct and avoids
   the one-axis-hidden/visible→auto spec quirk.
   Also force an explicit viewport-bounded height because #wrapper carries
   a lingering transform (from .jomcore-page-enter animation, fill-mode:
   both) — when an ancestor has transform/perspective/filter/contain, it
   becomes the containing block for position:fixed descendants instead of
   the viewport, so `top:0; bottom:0` no longer resolves against the
   viewport; we explicitly set the height to bypass that quirk.
   `100dvh` is preferred to account for collapsing mobile browser chrome,
   but `100vh` is the universally-supported fallback. */
.jomcore-widget-drawer {
    height: 100vh;          /* fallback for browsers without dvh support */
    height: 100dvh;         /* accounts for dynamic mobile viewport (overrides above) */
    overflow: hidden;       /* clip horizontal AND vertical spills (no implicit auto scroll context) */
}

.jomcore-widget-drawer-body::-webkit-scrollbar {
    width: 6px;
}

.jomcore-widget-drawer-body::-webkit-scrollbar-track {
    background: transparent;
}

.jomcore-widget-drawer-body::-webkit-scrollbar-thumb {
    background: #D0D5DD;
    border-radius: 999px;
}

/* ── Presets section ── */
.jomcore-widget-presets {
    margin-bottom: 20px;
}

.jomcore-widget-presets-label {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #98A2B3;
    margin-bottom: 8px;
}

.jomcore-widget-presets-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.jomcore-widget-preset-btn {
    padding: 5px 12px;
    font-size: 12.5px;
    font-weight: 500;
    color: #475467;
    background: #F9FAFB;
    border: 1px solid #EAECF0;
    border-radius: 999px;
    cursor: pointer;
    /* FLICKER FIX: explicit props only (was transition: all). */
    transition:
        background-color 0.15s ease,
        border-color 0.15s ease,
        color 0.15s ease,
        box-shadow 0.15s ease;
    white-space: nowrap;
    font-family: 'Inter', system-ui, -apple-system, sans-serif;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.jomcore-widget-preset-btn svg {
    flex-shrink: 0;
    opacity: 0.7;
}

.jomcore-widget-preset-btn:hover {
    background: #F0FDFA;
    border-color: #14B8A6;
    color: #0F766E;
}

.jomcore-widget-preset-btn.active {
    background: #F0FDFA;
    border-color: #14B8A6;
    color: #0F766E;
    font-weight: 600;
}

/* ── Category section ── */
.jomcore-widget-category {
    margin-bottom: 20px;
}

.jomcore-widget-category-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 0 6px;
    border-bottom: 1px solid #F2F4F7;
    margin-bottom: 8px;
}

.jomcore-widget-category-header .cat-icon {
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #667085;
    flex-shrink: 0;
}

.jomcore-widget-category-header .cat-label {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #667085;
}

/* ── Widget card ── */
.jomcore-widget-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    border-radius: 10px;
    transition: background 0.12s ease, box-shadow 0.2s ease, transform 0.15s ease;
    cursor: default;
    position: relative;
    background: #FFFFFF;
}

.jomcore-widget-card:hover {
    background: #F9FAFB;
}

/* ── Drag handle (grip dots icon) ── */
.jomcore-widget-card-drag {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    min-width: 20px;
    height: 32px;
    color: #D0D5DD;
    cursor: grab;
    border-radius: 4px;
    transition: color 0.12s ease, background 0.12s ease;
    flex-shrink: 0;
    margin-right: -4px;
}

.jomcore-widget-card-drag:hover {
    color: #667085;
    background: #F2F4F7;
}

.jomcore-widget-card-drag:active {
    cursor: grabbing;
    color: #14B8A6;
}

/* ── Sortable placeholder (drop target indicator) ── */
.jomcore-widget-card-placeholder {
    background: #F0FDFA !important;
    border: 2px dashed #14B8A6 !important;
    border-radius: 10px !important;
    margin: 4px 0 !important;
    min-height: 56px;
    visibility: visible !important;
    opacity: 1 !important;
    display: flex !important;
}

/* ── Currently dragging card (scoped to drawer only) ── */
.jomcore-widget-drawer-body .jomcore-widget-card.ui-sortable-helper {
    background: #FFFFFF !important;
    box-shadow: 0 8px 24px rgba(16, 24, 40, 0.15), 0 2px 8px rgba(16, 24, 40, 0.08) !important;
    border-radius: 10px !important;
    transform: scale(1.02);
    z-index: 1070 !important;
}

/* ── RTL: mirror drag handle margin ── */
[dir="rtl"] .jomcore-widget-card-drag {
    margin-right: 0;
    margin-left: -4px;
}

.jomcore-widget-card.hidden-by-search {
    display: none !important;
}

/* ── Widget card icon ── */
.jomcore-widget-card-icon {
    width: 36px;
    height: 36px;
    min-width: 36px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    background: #F2F4F7;
    color: #475467;
    transition: transform 0.15s ease;
}

.jomcore-widget-card:hover .jomcore-widget-card-icon {
    transform: scale(1.05);
}

/* ── Widget card info ── */
.jomcore-widget-card-info {
    flex: 1;
    min-width: 0;
}

.jomcore-widget-card-name {
    font-size: 13px;
    font-weight: 500;
    color: #101828;
    line-height: 1.3;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.jomcore-widget-card-desc {
    font-size: 12px;
    color: #667085;
    line-height: 1.4;
    margin-top: 1px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── Widget card toggle (uses existing .onoffswitch) ── */
.jomcore-widget-card-toggle {
    flex-shrink: 0;
}

/* ── Customize Dashboard primary button (replaces old screen-options-btn) ── */
.jomcore-customize-dash-btn {
    display: inline-flex !important;
    align-items: center !important;
    gap: 6px !important;
    padding: 8px 16px !important;
    font-size: 13px !important;
    font-weight: 600 !important;
    font-family: 'Inter', system-ui, -apple-system, sans-serif !important;
    color: #FFFFFF !important;
    background: #14B8A6 !important;
    border: none !important;
    border-radius: 8px !important;
    cursor: pointer !important;
    transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease !important;
    box-shadow: 0 1px 3px rgba(20, 184, 166, 0.3), 0 1px 2px rgba(0, 0, 0, 0.06) !important;
    margin: 10px 0 16px !important;
    line-height: 1.4 !important;
    white-space: nowrap !important;
}

.jomcore-customize-dash-btn:hover {
    background: #0D9488 !important;
    box-shadow: 0 4px 12px rgba(20, 184, 166, 0.35), 0 2px 4px rgba(0, 0, 0, 0.06) !important;
    transform: translateY(-1px) !important;
}

.jomcore-customize-dash-btn:active {
    background: #0F766E !important;
    transform: translateY(0) !important;
    box-shadow: 0 1px 2px rgba(20, 184, 166, 0.2) !important;
}

.jomcore-customize-dash-btn:focus-visible {
    outline: 2px solid rgba(20, 184, 166, 0.4) !important;
    outline-offset: 2px !important;
}

/* Hide the old screen-options-btn if it still exists */
.screen-options-btn {
    display: none !important;
}

/* ── Drawer footer ── */
.jomcore-widget-drawer-footer {
    padding: 16px 24px;
    border-top: 1px solid #EAECF0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
    background: #FAFBFC;
}

.jomcore-widget-drawer-footer .drawer-reset-link {
    font-size: 13px;
    font-weight: 500;
    color: #667085;
    text-decoration: none;
    cursor: pointer;
    transition: color 0.12s ease;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.jomcore-widget-drawer-footer .drawer-reset-link:hover {
    color: #F04438;
}

.jomcore-widget-drawer-footer .drawer-view-areas-link {
    font-size: 13px;
    font-weight: 500;
    color: #14B8A6;
    text-decoration: none;
    cursor: pointer;
    transition: color 0.12s ease;
}

.jomcore-widget-drawer-footer .drawer-view-areas-link:hover {
    color: #0F766E;
}

/* ── Empty state ── */
.jomcore-widget-empty {
    text-align: center;
    padding: 32px 16px;
    color: #667085;
}

.jomcore-widget-empty .empty-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 8px;
    opacity: 0.5;
}

.jomcore-widget-empty p {
    font-size: 13px;
    margin: 0;
}

/* ── Active widget count badge ── */
.jomcore-widget-count {
    font-size: 11px;
    font-weight: 600;
    color: #14B8A6;
    background: #F0FDFA;
    border: 1px solid #99F6E4;
    border-radius: 999px;
    padding: 1px 7px;
    margin-left: 8px;
    line-height: 1.4;
}

/* ── Responsive: smaller drawer on mobile ── */
@media (max-width: 480px) {
    .jomcore-widget-drawer {
        width: 100vw;
        max-width: 100vw;
        border-left: none;
    }
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
    .jomcore-widget-drawer,
    .jomcore-widget-drawer-backdrop,
    .jomcore-widget-card,
    .jomcore-widget-card-icon,
    .jomcore-widget-drawer-close,
    .jomcore-widget-preset-btn {
        transition: none !important;
    }
    .jomcore-widget-drawer.open,
    .jomcore-widget-drawer.closing {
        animation: none !important;
    }
}

/* ── Hide the old screen-options-area and btn ── */
.screen-options-area {
    display: none !important;
}

.screen-options-btn {
    cursor: pointer;
}

/* ================================================================
   FULLCALENDAR UI REDESIGN (JomCore DNA)
   Complete visual overhaul of FullCalendar v5+ to match the
   JomCore Design System. Uses --fc-* CSS variables where possible
   and overrides specific selectors for deeper customization.
   Canonical spec: /JOMCORE_DESIGN_DNA.md
   ================================================================ */

/* ── 1. FullCalendar CSS Variable Overrides ── */
:root {
    --fc-border-color: var(--dna-border);
    --fc-page-bg-color: var(--dna-card);
    --fc-neutral-bg-color: var(--dna-bg);

    /* Buttons — outlined secondary style */
    --fc-button-bg-color: var(--dna-card);
    --fc-button-text-color: var(--dna-text-secondary);
    --fc-button-border-color: var(--dna-border);
    --fc-button-hover-bg-color: var(--dna-bg);
    --fc-button-hover-border-color: var(--dna-border);
    --fc-button-active-bg-color: var(--dna-primary-light);
    --fc-button-active-border-color: var(--dna-primary);

    /* Events — primary accent */
    --fc-event-bg-color: var(--dna-primary);
    --fc-event-border-color: var(--dna-primary);
    --fc-event-text-color: #FFFFFF;

    /* Highlights & Indicators */
    --fc-today-bg-color: var(--dna-primary-light);
    --fc-highlight-color: rgba(14, 165, 233, 0.08);
    --fc-now-indicator-color: var(--dna-danger);
    --fc-list-event-hover-bg-color: var(--dna-bg);

}

/* ── 2. Base Calendar Typography ── */
.fc {
    font-family: 'Inter', system-ui, -apple-system, sans-serif;
    color: var(--dna-text);
}

.fc table {
    font-size: 0.875rem;
}

/* ── 3. Toolbar & Navigation ── */
.fc .fc-toolbar.fc-header-toolbar {
    margin-bottom: var(--dna-sp-6);
}

.fc .fc-toolbar-title {
    font-size: 1.25rem;
    font-weight: 600;
    color: var(--dna-text);
    letter-spacing: -0.02em;
}

.fc .fc-button {
    border-radius: var(--dna-radius-button);
    font-weight: 500;
    font-size: 0.8125rem;
    text-transform: capitalize;
    box-shadow: 0 1px 2px rgba(2, 8, 20, 0.03);
    transition:
        transform var(--dna-anim-fast) var(--dna-anim-ease),
        box-shadow var(--dna-anim-fast) var(--dna-anim-ease);
    padding: var(--dna-sp-2) var(--dna-sp-4);
    font-family: 'Inter', system-ui, sans-serif;
}

.fc .fc-button:hover {
    transform: var(--dna-lift-hover);
    color: var(--dna-text);
    box-shadow: 0 3px 8px rgba(2, 8, 20, 0.06);
}

.fc .fc-button-primary:not(:disabled).fc-button-active,
.fc .fc-button-primary:not(:disabled):active {
    color: var(--dna-primary-hover);
    background: var(--dna-primary-light);
    border-color: var(--dna-primary);
    box-shadow: none;
    transform: none;
}

.fc .fc-button-primary:focus {
    box-shadow: 0 0 0 3px var(--dna-primary-light) !important;
    outline: none;
}

/* Fix grouped button border-radius */
.fc-direction-ltr .fc-button-group > .fc-button:first-child {
    border-top-left-radius: var(--dna-radius-button);
    border-bottom-left-radius: var(--dna-radius-button);
}

.fc-direction-ltr .fc-button-group > .fc-button:last-child {
    border-top-right-radius: var(--dna-radius-button);
    border-bottom-right-radius: var(--dna-radius-button);
}

/* ── 4. Scroll Grid & Borders ── */
.fc-theme-standard .fc-scrollgrid {
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid var(--dna-border);
}

.fc-theme-standard td,
.fc-theme-standard th {
    border-color: var(--dna-border);
}

/* ── 5. Column Header Cells ── */
.fc-theme-standard th {
    padding: var(--dna-sp-3) 0;
    font-weight: 600;
    font-size: 0.6875rem;
    color: var(--dna-text-secondary);
    background: var(--dna-bg);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border-bottom-width: 1px;
}

.fc .fc-col-header-cell-cushion {
    padding: var(--dna-sp-2) var(--dna-sp-1);
}

/* ── 6. Day Grid (Month View) ── */
.fc .fc-daygrid-day-number {
    font-size: 0.8125rem;
    font-weight: 500;
    padding: var(--dna-sp-2) var(--dna-sp-3);
    color: var(--dna-text-secondary);
    transition: color var(--dna-anim-fast) ease;
}

.fc .fc-daygrid-day-top {
    flex-direction: row-reverse;
}

/* Today highlight — primary accent number on light bg */
.fc .fc-daygrid-day.fc-day-today {
    background-color: var(--fc-today-bg-color);
}

.fc .fc-daygrid-day.fc-day-today .fc-daygrid-day-number {
    color: var(--dna-primary);
    font-weight: 700;
    background: transparent;
}

/* Other month days — faded */
.fc .fc-day-other .fc-daygrid-day-top {
    opacity: 0.35;
}

/* Weekend / non-business — subtle tint */
.fc .fc-non-business {
    background: rgba(241, 245, 249, 0.5);
}

/* Day cell hover */
.fc .fc-daygrid-day:hover {
    background-color: rgba(14, 165, 233, 0.04);
}

/* ── 7. Events (All Views) ── */
.fc-event {
    border-radius: 6px !important;
    padding: 3px 8px !important;
    font-size: 0.75rem !important;
    font-weight: 500;
    border: none !important;
    cursor: pointer;
    transition: transform var(--dna-anim-fast) var(--dna-anim-ease),
                box-shadow var(--dna-anim-fast) var(--dna-anim-ease);
}

.fc-event:hover {
    transform: var(--dna-lift-hover);
    box-shadow: var(--dna-shadow-1-hover);
    z-index: 10;
}

/* Dot events (month view compact) */
.fc-daygrid-dot-event {
    padding: 2px 4px;
    border-radius: 4px;
}

.fc-daygrid-event-dot {
    border-color: var(--dna-primary);
}

/* Block events (month view expanded) */
.fc-daygrid-block-event .fc-event-time {
    font-weight: 600;
    font-size: 0.6875rem;
}

.fc-daygrid-block-event .fc-event-title {
    font-size: 0.75rem;
}

/* Timegrid events */
.fc-timegrid-event {
    border-radius: 8px !important;
    padding: var(--dna-sp-1) var(--dna-sp-2) !important;
    box-shadow: 0 1px 3px rgba(2, 8, 20, 0.06);
}

.fc-timegrid-event .fc-event-main {
    padding: 2px 4px;
}

.fc-timegrid-event .fc-event-time {
    font-size: 0.6875rem;
    font-weight: 600;
}

/* ── 8. Time Grid (Week/Day Views) ── */
.fc .fc-timegrid-slot-label-cushion {
    font-size: 0.6875rem;
    color: var(--dna-text-secondary);
    padding-right: var(--dna-sp-3);
    font-weight: 500;
}

.fc .fc-timegrid-col.fc-day-today {
    background-color: transparent;
}

/* Now indicator — sleek red line + dot */
.fc .fc-timegrid-now-indicator-line {
    border-width: 2px 0 0;
    border-color: var(--dna-danger);
}

.fc .fc-timegrid-now-indicator-arrow {
    border: none;
    background-color: var(--dna-danger);
    border-radius: 50%;
    width: 8px;
    height: 8px;
    margin-top: -4px;
}

.fc-direction-ltr .fc-timegrid-now-indicator-arrow {
    border-width: 0;
    left: -4px;
}

/* Time slot grid lines */
.fc .fc-timegrid-slot {
    height: 2em;
}

.fc .fc-timegrid-slot-minor {
    border-top-style: dotted;
    border-top-color: var(--dna-border);
}

/* ── 9. List View ── */
.fc-theme-standard .fc-list {
    border-radius: var(--dna-radius-card);
    border: 1px solid var(--dna-border);
    overflow: hidden;
}

.fc .fc-list-day-cushion {
    background-color: var(--dna-bg);
    padding: var(--dna-sp-3) var(--dna-sp-4);
    font-weight: 600;
    color: var(--dna-text);
    font-size: 0.875rem;
}

.fc .fc-list-event td {
    padding: var(--dna-sp-3) var(--dna-sp-4);
    color: var(--dna-text-secondary);
    border-bottom: 1px solid var(--dna-border);
    transition: background-color var(--dna-anim-fast) var(--dna-anim-ease),
                color var(--dna-anim-fast) var(--dna-anim-ease);
}

.fc .fc-list-event:hover td {
    background-color: var(--dna-bg);
    color: var(--dna-text);
}

.fc .fc-list-event-time,
.fc .fc-list-event-title {
    font-size: 0.8125rem;
}

.fc .fc-list-event-dot {
    border-color: var(--dna-primary);
}

.fc .fc-list-event-graphic .fc-list-event-dot {
    border-color: var(--dna-primary);
}

/* ── 10. More Link (+N events) ── */
.fc .fc-more-link {
    display: block;
    background: var(--dna-bg);
    color: var(--dna-text-secondary);
    border-radius: 6px;
    padding: 2px 6px;
    margin: 2px 0;
    font-weight: 600;
    font-size: 0.6875rem;
    text-align: center;
    transition:
        transform var(--dna-anim-fast) var(--dna-anim-ease),
        box-shadow var(--dna-anim-fast) var(--dna-anim-ease);
}

.fc .fc-more-link:hover {
    background: var(--dna-border);
    color: var(--dna-text);
    text-decoration: none;
}

/* ── 11. Popovers (day cell overflow) ── */
.fc .fc-popover {
    border: 1px solid var(--dna-border);
    border-radius: 14px;
    box-shadow: var(--dna-shadow-1);
    background: var(--dna-card);
    overflow: hidden;
    z-index: 1050;
}

.fc .fc-popover-header {
    background: var(--dna-bg);
    padding: var(--dna-sp-3) var(--dna-sp-4);
    font-weight: 600;
    font-size: 0.8125rem;
    color: var(--dna-text);
    border-bottom: 1px solid var(--dna-border);
}

.fc .fc-popover-title {
    font-size: 0.8125rem;
    font-weight: 600;
}

.fc .fc-popover-close {
    opacity: 0.4;
    transition: opacity var(--dna-anim-fast) var(--dna-anim-ease),
                color var(--dna-anim-fast) var(--dna-anim-ease);
    font-size: 1em;
}

.fc .fc-popover-close:hover {
    opacity: 1;
    color: var(--dna-danger);
}

.fc .fc-popover-body {
    padding: var(--dna-sp-2);
    max-height: 280px;
    overflow-y: auto;
}

/* ── 12. Calendar View Harness ── */
.fc .fc-view-harness {
    border-radius: 0 0 12px 12px;
    overflow: hidden;
}

/* ── 13. Scrollbar Styling ── */
.fc .fc-scroller::-webkit-scrollbar {
    width: 5px;
    height: 5px;
}

.fc .fc-scroller::-webkit-scrollbar-track {
    background: transparent;
}

.fc .fc-scroller::-webkit-scrollbar-thumb {
    background: var(--dna-border);
    border-radius: 999px;
}

.fc .fc-scroller::-webkit-scrollbar-thumb:hover {
    background: var(--dna-text-secondary);
}

/* ── 14. Reduced Motion ── */
@media (prefers-reduced-motion: reduce) {
    .fc .fc-button,
    .fc-event,
    .fc .fc-more-link,
    .fc .fc-popover-close {
        transition: none !important;
    }
    .fc-event:hover {
        transform: none !important;
    }
}

/* ── 15. Calendar Filters (modernize) ── */
#calendar_filters {
    background: var(--dna-card);
    border: 1px solid var(--dna-border);
    border-radius: var(--dna-radius-card);
    padding: var(--dna-sp-5);
    margin-bottom: var(--dna-sp-5);
}

#calendar_filters .checkbox label {
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--dna-text-secondary);
}

#calendar_filters .checkbox input[type="checkbox"]:checked ~ label,
#calendar_filters .checkbox input[type="checkbox"]:checked + label {
    color: var(--dna-text);
    font-weight: 600;
}

#calendar_filters hr {
    border: none;
    border-top: 1px solid var(--dna-border);
    margin: var(--dna-sp-4) 0;
}

/* ===============================================================
   FLICKER FIX — Vendor `transition: all` overrides
   ================================================================
   Vendored CSS (Bootstrap 3.x, metisMenu, Dropzone, TinyMCE skins,
   elFinder themes, plugin bundles) ships `transition: all` on a
   handful of selectors that Perfex uses in the admin UI (modals,
   dropdowns, sidebar chevrons, dropzone uploads). Vendored sources
   are NOT modified directly — we override with explicit property
   lists here so the same flicker pattern is eliminated on every
   vendored transition as well.

   Strategy:
   - Same selector + higher specificity when needed.
   - All overrides use `!important` to win over vendor stylesheets
     loaded BEFORE custom.css in the Perfex layout.
   - Vendored sources are tracked in git; overrides live in
     custom.css so an upstream upgrade never undoes the fix.
   =============================================================== */

/* ── Bootstrap 3.x: modal fade — only opacity animates ── */
.fade {
    transition: opacity var(--vendor-fade-duration) linear !important;
}
/* ── Bootstrap 3.x: collapse / collapsing — height only ──
   Intentional: accordions need to animate height + visibility. */
.collapsing {
    transition:
        height var(--vendor-collapse-duration) ease,
        visibility 0s linear var(--vendor-collapse-duration) !important;
}

/* ── Bootstrap 3.x: modal-dialog drop-in — transform only ── */
.modal.fade .modal-dialog {
    transition: transform var(--vendor-modal-duration) ease-out !important;
}

/* ── Bootstrap 3.x: img-thumbnail hover — opacity + border-color only ── */
.img-thumbnail {
    transition:
        opacity var(--vendor-thumb-duration) ease-in-out,
        border-color var(--vendor-thumb-duration) ease-in-out !important;
}

/* ── metisMenu chevron — rotate-on-expand; only transform animates ──
   Vendored `transition: all .3s ease-out` re-animates `border-color`
   and `border-width` on hover, causing 0.3s chevron layout-paint. */
.metismenu .has-arrow:after {
    transition: transform var(--vendor-chevron-duration) ease-out !important;
}

/* ── Dropzone progress — width + opacity only ── */
.dropzone .dz-preview.dz-processing .dz-progress {
    transition:
        width var(--vendor-dropzone-duration) ease-in-out,
        opacity var(--vendor-thumb-duration) linear !important;
}
.dropzone .dz-preview.dz-complete .dz-progress {
    transition: opacity var(--vendor-dropzone-duration) ease-in !important;
}
.dropzone .dz-preview.dz-image-preview .dz-details {
    transition: opacity var(--vendor-thumb-duration) linear !important;
}
.dropzone .dz-preview .dz-error-message {
    transition: opacity var(--vendor-dropzone-error) ease !important;
}

/* ── Dropzone thumbnail hover — transform + filter only ── */
.dropzone .dz-preview:hover .dz-image img {
    transition:
        transform var(--vendor-thumb-duration) ease-in-out,
        filter var(--vendor-thumb-duration) ease-in-out !important;
}

/* ===============================================================
   Vendor timing tokens
   ================================================================
   Centralized CSS custom properties holding the durations used by
   the vendor `transition: all` override block at the bottom of
   this file. Mirror the upstream values of Bootstrap 3.x / metisMenu
   / Dropzone so a single edit here propagates everywhere. Sync these
   against the vendor source when upgrading any of those libraries.
   =============================================================== */
:root {
    --vendor-fade-duration:       0.15s;
    --vendor-collapse-duration:    0.35s;
    --vendor-modal-duration:       0.3s;
    --vendor-thumb-duration:       0.2s;
    --vendor-chevron-duration:     0.3s;
    --vendor-dropzone-duration:    0.3s;
    --vendor-dropzone-error:       0.3s;
}
