/* ============================================
   Utilities - Animations, Helpers
   ============================================ */

/* ===========================================
   ANIMATIONS
   =========================================== */

@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes slideInRight {
    from {
        transform: translateX(100%);
        opacity: 0;
    }
    to {
        transform: translateX(0);
        opacity: 1;
    }
}

@keyframes slideOutRight {
    from {
        transform: translateX(0);
        opacity: 1;
    }
    to {
        transform: translateX(100%);
        opacity: 0;
    }
}

@keyframes slideInUp {
    from {
        transform: translateY(100%);
        opacity: 0;
    }
    to {
        transform: translateY(0);
        opacity: 1;
    }
}

@keyframes slideOutDown {
    from {
        transform: translateY(0);
        opacity: 1;
    }
    to {
        transform: translateY(100%);
        opacity: 0;
    }
}

@keyframes modalSlideIn {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes shake {
    0%, 100% { transform: translateX(0); }
    10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
    20%, 40%, 60%, 80% { transform: translateX(5px); }
}

@keyframes spin {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}

@keyframes pulse {
    0%, 100% {
        opacity: 1;
    }
    50% {
        opacity: 0.5;
    }
}

/* ===========================================
   FOLDER ANIMATIONS
   =========================================== */

.folder-expand-enter {
    opacity: 0;
    max-height: 0;
    overflow: hidden;
}

.folder-expand-enter-active {
    opacity: 1;
    max-height: 200px;
    transition: all var(--transition-slow);
}

.folder-expand-exit {
    opacity: 1;
    max-height: 200px;
}

.folder-expand-exit-active {
    opacity: 0;
    max-height: 0;
    overflow: hidden;
    transition: all var(--transition-slow);
}

/* ===========================================
   UTILITY CLASSES
   =========================================== */

/* Visibility */
.hidden {
    display: none !important;
}

.invisible {
    visibility: hidden !important;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Overflow */
.overflow-hidden {
    overflow: hidden !important;
}

.overflow-auto {
    overflow: auto !important;
}

.overflow-scroll {
    overflow: scroll !important;
}

/* Cursor */
.cursor-pointer {
    cursor: pointer !important;
}

.cursor-not-allowed {
    cursor: not-allowed !important;
}

.cursor-move {
    cursor: move !important;
}

/* User Select */
.user-select-none {
    user-select: none !important;
}

.user-select-all {
    user-select: all !important;
}

/* Pointer Events */
.pointer-events-none {
    pointer-events: none !important;
}

.pointer-events-auto {
    pointer-events: auto !important;
}

/* ===========================================
   TEXT UTILITIES
   =========================================== */

.text-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.text-wrap {
    white-space: normal !important;
}

.text-nowrap {
    white-space: nowrap !important;
}

.text-break {
    word-wrap: break-word !important;
    word-break: break-word !important;
}

.text-center {
    text-align: center !important;
}

.text-start {
    text-align: left !important;
}

.text-end {
    text-align: right !important;
}

/* ===========================================
   FLEX UTILITIES
   =========================================== */

.d-flex {
    display: flex !important;
}

.d-inline-flex {
    display: inline-flex !important;
}

.d-none {
    display: none !important;
}

.d-block {
    display: block !important;
}

.d-inline-block {
    display: inline-block !important;
}

/* Responsive display utilities for medium screens and up (768px+) */
@media (min-width: 768px) {
    .d-md-none {
        display: none !important;
    }
    .d-md-block {
        display: block !important;
    }
    .d-md-inline-block {
        display: inline-block !important;
    }
    .d-md-flex {
        display: flex !important;
    }
    .d-md-inline-flex {
        display: inline-flex !important;
    }
}

.flex-row {
    flex-direction: row !important;
}

.flex-column {
    flex-direction: column !important;
}

.flex-wrap {
    flex-wrap: wrap !important;
}

.flex-nowrap {
    flex-wrap: nowrap !important;
}

.flex-grow-0 {
    flex-grow: 0 !important;
}

.flex-grow-1 {
    flex-grow: 1 !important;
}

.flex-shrink-0 {
    flex-shrink: 0 !important;
}

.flex-shrink-1 {
    flex-shrink: 1 !important;
}

.justify-content-start {
    justify-content: flex-start !important;
}

.justify-content-end {
    justify-content: flex-end !important;
}

.justify-content-center {
    justify-content: center !important;
}

.justify-content-between {
    justify-content: space-between !important;
}

.justify-content-around {
    justify-content: space-around !important;
}

.align-items-start {
    align-items: flex-start !important;
}

.align-items-end {
    align-items: flex-end !important;
}

.align-items-center {
    align-items: center !important;
}

.align-items-stretch {
    align-items: stretch !important;
}

.align-self-start {
    align-self: flex-start !important;
}

.align-self-end {
    align-self: flex-end !important;
}

.align-self-center {
    align-self: center !important;
}

/* ===========================================
   GAP UTILITIES
   =========================================== */

.gap-0 { gap: 0 !important; }
.gap-1 { gap: 0.25rem !important; }
.gap-2 { gap: 0.5rem !important; }
.gap-3 { gap: 1rem !important; }
.gap-4 { gap: 1.5rem !important; }
.gap-5 { gap: 3rem !important; }

/* ===========================================
   MARGIN UTILITIES
   =========================================== */

.m-0 { margin: 0 !important; }
.m-1 { margin: 0.25rem !important; }
.m-2 { margin: 0.5rem !important; }
.m-3 { margin: 1rem !important; }
.m-4 { margin: 1.5rem !important; }
.m-5 { margin: 3rem !important; }
.m-auto { margin: auto !important; }

.mt-0 { margin-top: 0 !important; }
.mt-1 { margin-top: 0.25rem !important; }
.mt-2 { margin-top: 0.5rem !important; }
.mt-3 { margin-top: 1rem !important; }
.mt-4 { margin-top: 1.5rem !important; }
.mt-5 { margin-top: 3rem !important; }
.mt-auto { margin-top: auto !important; }

.mb-0 { margin-bottom: 0 !important; }
.mb-1 { margin-bottom: 0.25rem !important; }
.mb-2 { margin-bottom: 0.5rem !important; }
.mb-3 { margin-bottom: 1rem !important; }
.mb-4 { margin-bottom: 1.5rem !important; }
.mb-5 { margin-bottom: 3rem !important; }
.mb-auto { margin-bottom: auto !important; }

.ms-0 { margin-left: 0 !important; }
.ms-1 { margin-left: 0.25rem !important; }
.ms-2 { margin-left: 0.5rem !important; }
.ms-3 { margin-left: 1rem !important; }
.ms-auto { margin-left: auto !important; }

.me-0 { margin-right: 0 !important; }
.me-1 { margin-right: 0.25rem !important; }
.me-2 { margin-right: 0.5rem !important; }
.me-3 { margin-right: 1rem !important; }
.me-auto { margin-right: auto !important; }

/* ===========================================
   PADDING UTILITIES
   =========================================== */

.p-0 { padding: 0 !important; }
.p-1 { padding: 0.25rem !important; }
.p-2 { padding: 0.5rem !important; }
.p-3 { padding: 1rem !important; }
.p-4 { padding: 1.5rem !important; }
.p-5 { padding: 3rem !important; }

.pt-0 { padding-top: 0 !important; }
.pt-1 { padding-top: 0.25rem !important; }
.pt-2 { padding-top: 0.5rem !important; }
.pt-3 { padding-top: 1rem !important; }
.pt-4 { padding-top: 1.5rem !important; }
.pt-5 { padding-top: 3rem !important; }

.pb-0 { padding-bottom: 0 !important; }
.pb-1 { padding-bottom: 0.25rem !important; }
.pb-2 { padding-bottom: 0.5rem !important; }
.pb-3 { padding-bottom: 1rem !important; }
.pb-4 { padding-bottom: 1.5rem !important; }
.pb-5 { padding-bottom: 3rem !important; }

.ps-0 { padding-left: 0 !important; }
.ps-1 { padding-left: 0.25rem !important; }
.ps-2 { padding-left: 0.5rem !important; }
.ps-3 { padding-left: 1rem !important; }

.pe-0 { padding-right: 0 !important; }
.pe-1 { padding-right: 0.25rem !important; }
.pe-2 { padding-right: 0.5rem !important; }
.pe-3 { padding-right: 1rem !important; }

/* ===========================================
   WIDTH/HEIGHT UTILITIES
   =========================================== */

.w-25 { width: 25% !important; }
.w-50 { width: 50% !important; }
.w-75 { width: 75% !important; }
.w-100 { width: 100% !important; }
.w-auto { width: auto !important; }

.h-25 { height: 25% !important; }
.h-50 { height: 50% !important; }
.h-75 { height: 75% !important; }
.h-100 { height: 100% !important; }
.h-auto { height: auto !important; }

.min-w-0 { min-width: 0 !important; }
.min-h-0 { min-height: 0 !important; }

.max-w-100 { max-width: 100% !important; }
.max-h-100 { max-height: 100% !important; }

/* ===========================================
   POSITION UTILITIES
   =========================================== */

.position-relative { position: relative !important; }
.position-absolute { position: absolute !important; }
.position-fixed { position: fixed !important; }
.position-sticky { position: sticky !important; }

.top-0 { top: 0 !important; }
.bottom-0 { bottom: 0 !important; }
.start-0 { left: 0 !important; }
.end-0 { right: 0 !important; }

/* ===========================================
   BORDER UTILITIES
   =========================================== */

.border { border: 1px solid var(--border) !important; }
.border-0 { border: 0 !important; }
.border-top { border-top: 1px solid var(--border) !important; }
.border-bottom { border-bottom: 1px solid var(--border) !important; }
/* LOGICAL, and the names demand it: `start`/`end` mean the reading edges, so a
   physical left/right here is wrong in Arabic by definition. It was worse than
   wrong — Bootstrap's RTL build already maps .border-start to `border-right`,
   and this rule set `border-left` with its own !important, so under RTL the two
   did not conflict, they ADDED UP: an element would carry a border down BOTH
   sides. Nothing uses these two classes today (no template, no script), which
   is the only reason it never showed. Same defect the header search bar had —
   see the tombstone in app-rtl.css — and the one _calendar.css:371 already
   documents for the month grid. */
.border-start { border-inline-start: 1px solid var(--border) !important; }
.border-end { border-inline-end: 1px solid var(--border) !important; }

.rounded { border-radius: var(--radius-md) !important; }
.rounded-0 { border-radius: 0 !important; }
.rounded-circle { border-radius: var(--radius-circle) !important; }
.rounded-pill { border-radius: var(--radius-pill) !important; }

/* ===========================================
   SHADOW UTILITIES
   =========================================== */

.shadow-none { box-shadow: none !important; }
.shadow-sm { box-shadow: var(--shadow-sm) !important; }
.shadow { box-shadow: var(--shadow-md) !important; }
.shadow-lg { box-shadow: var(--shadow-lg) !important; }

/* ===========================================
   OPACITY UTILITIES
   =========================================== */

.opacity-0 { opacity: 0 !important; }
.opacity-25 { opacity: 0.25 !important; }
.opacity-50 { opacity: 0.5 !important; }
.opacity-75 { opacity: 0.75 !important; }
.opacity-100 { opacity: 1 !important; }

/* ===========================================
   TRANSITION UTILITIES
   =========================================== */

.transition-none { transition: none !important; }
.transition-all { transition: all var(--transition-normal) !important; }
.transition-colors { transition: color var(--transition-normal), background-color var(--transition-normal), border-color var(--transition-normal) !important; }
.transition-transform { transition: transform var(--transition-normal) !important; }
.transition-opacity { transition: opacity var(--transition-normal) !important; }

/* ===========================================
   TRANSFORM UTILITIES
   =========================================== */

.rotate-45 { transform: rotate(45deg) !important; }
.rotate-90 { transform: rotate(90deg) !important; }
.rotate-180 { transform: rotate(180deg) !important; }
.-rotate-45 { transform: rotate(-45deg) !important; }
.-rotate-90 { transform: rotate(-90deg) !important; }

.scale-95 { transform: scale(0.95) !important; }
.scale-100 { transform: scale(1) !important; }
.scale-105 { transform: scale(1.05) !important; }
.scale-110 { transform: scale(1.1) !important; }

/* ===========================================
   Z-INDEX UTILITIES
   =========================================== */

.z-0 { z-index: 0 !important; }
.z-10 { z-index: 10 !important; }
.z-20 { z-index: 20 !important; }
.z-30 { z-index: 30 !important; }
.z-40 { z-index: 40 !important; }
.z-50 { z-index: 50 !important; }
.z-auto { z-index: auto !important; }
/* ============================================================================
   TOUCH — minimum tap target
   ============================================================================
   iOS HIG asks for 44x44pt, Android Material for 48dp. The app's own buttons
   are laid out for a mouse: the row-action icon buttons in every register
   (.btn-sm.btn-outline-secondary) measure ~31x30, and they sit shoulder to
   shoulder in the actions column, which is exactly the arrangement that turns a
   near-miss into the WRONG action rather than no action.

   A floor, not a redesign: only min-height / min-width are set, so nothing
   moves on a pointer device and nothing about the visual scale changes on a
   phone beyond the box growing to something a thumb can hit.

   `pointer: coarse`, not a width breakpoint — a finger is the same size on a
   1024px tablet as on a 390px phone, and that tablet sails past a max-width
   query. Same scoping as the 16px control floor in _forms.css.

   The inline-flex is load-bearing for ONE case: a <button> centres its content
   vertically on its own, but `a.btn` does not, so the 7 anchor-buttons in the
   templates would grow downward and leave their label stuck at the top. */
@media (pointer: coarse) {

    .btn,
    .page-link,
    .btn-navbar,
    .navbar-toggler,
    .btn-toggle-footer,
    .sidebar-link,
    .navbar-brand,
    /* Feature buttons that are <button> but do NOT carry .btn, so the line
       above does not reach them: the /employees grid-list switch and the two
       controls in the /lookups source rail. Named individually because that is
       the honest cost of styling a button without the button class — a bare
       `button` selector here would also hit every toggle inside a widget that
       sizes itself. */
    .view-toggle-btn,
    .lookup-category-toggle,
    .lookup-source-btn,
    /* Every people column's avatar stack (common/avatar-stack.js): the
       .row-count-btn it replaced had this floor through .btn. */
    .avatar-stack,
    /* Menu rows (2026-09-16). Bootstrap gives .dropdown-item ~32px, which is
       a thumb target in a list of thumb targets. The design picker's rows are
       what raised it, and the user menu sitting beside it gets the same floor:
       flooring one menu and not the one next to it is the kind of exception
       this app does not make. */
    .dropdown-item,
    /* Fields too (2026-09-12): now that .form-control-sm really is 30px, a
       small field beside a floored 44px button would sit 14px shorter on a
       phone — the exact mismatch the button fix removed on the desktop. */
    .form-control,
    .form-select {
        min-height: 44px;
    }

    /* Icon-only controls — no label to give them width. */
    .admin-table .btn-sm,
    .btn-group > .btn,
    .page-link,
    .btn-navbar,
    .navbar-toggler,
    .btn-toggle-footer,
    .modal-close,
    .view-toggle-btn {
        min-width: 44px;
    }

    .btn,
    .page-link {
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* Chips are links, but INLINE ones — a 44px floor here would push every
       table row that carries a متعلق بـ chip half again as tall for a secondary
       navigation aid. WCAG 2.5.8 (AA) asks 24x24 of these rather than 44, and
       they measure 23. One pixel, so they clear it. Ordinary text links inside
       prose are exempt from 2.5.8 entirely and are deliberately left alone. */
    .row-parent-chip {
        min-height: 24px;
    }
}
