/* public/assets/css/s30-ui-polish.css
 * KHMER HRMS — Global UI Polish / One-Standard Pass
 *
 * WHY THIS FILE EXISTS
 * Across S00–S29, several components (most visibly icon-only action
 * buttons — .action-icon-btn / .btn-icon-only) picked up a new
 * width/height override in nearly every season's patch (28px → 32px →
 * 34px !important → 36px !important, scattered across app.css and
 * s29-standard-ui.css). Because each override targeted a slightly
 * different selector/context, the RESOLVED size silently differs from
 * page to page depending on which container the button happens to sit
 * in — which is exactly what reads as "not one same standard" /
 * "រញ៉េរញៃ" even though every individual season's CSS was internally
 * consistent at the time it was written.
 *
 * This file does not remove or rewrite any of that legacy CSS (touching
 * a 5,000+ line stylesheet blind is how new regressions get introduced).
 * Instead, exactly like s29-standard-ui.css already does, it is loaded
 * LAST and pins ONE canonical, final value for the handful of
 * components that had drifted, using max practical specificity. Every
 * value below reuses the app's own existing CSS variables (--primary,
 * --surface, --border, --radius-sm, --space-*, --shadow-*) — nothing
 * new is invented, and Day/Night + all 5 color themes keep working
 * automatically.
 *
 * UI-only: no routes, form names, data attributes, JS hooks, PHP, or
 * business logic are touched by this file.
 *
 * Season: S29 continuity — UI/UX consistency pass.
 */

/* ══════════════════════════════════════════════════════════════════
   1. ICON-ONLY ACTION BUTTONS — one final size, everywhere
   Every icon-only control in the app — table row actions, card
   headers, mobile check-in rows, filter panel actions, dropdown
   triggers — resolves to the exact same 36×36 touch target, 18px
   icon, 9px radius. This is the largest of the sizes already in use
   (36px), so nothing that previously fit now overflows; it only
   stops shrinking back down to 28–34px on pages an earlier patch
   didn't reach.
   ══════════════════════════════════════════════════════════════════ */
.action-icon-btn,
.btn-icon-only,
.btn.btn-icon-only,
.actions .action-icon-btn,
.actions .btn-icon-only,
.header-actions .action-icon-btn,
.mobile-checkin-actions-cell .action-icon-btn,
.mobile-checkin-actions-cell .btn-icon-only,
.device-card-actions .action-icon-btn,
.reason-row-actions .action-icon-btn,
.reason-edit-actions .action-icon-btn {
    box-sizing: border-box !important;
    width: 36px !important;
    min-width: 36px !important;
    max-width: 36px !important;
    height: 36px !important;
    min-height: 36px !important;
    max-height: 36px !important;
    padding: 0 !important;
    margin: 0 !important;
    flex: 0 0 36px !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    border-radius: 9px !important;
    line-height: 1 !important;
    vertical-align: middle;
}

.action-icon-btn svg,
.btn-icon-only svg,
.actions .action-icon-btn svg,
.actions .btn-icon-only svg,
.mobile-checkin-actions-cell .action-icon-btn svg,
.mobile-checkin-actions-cell .btn-icon-only svg {
    width: 18px !important;
    height: 18px !important;
    min-width: 18px !important;
    min-height: 18px !important;
    flex: 0 0 18px !important;
    margin: 0 !important;
}

/* Icon-only buttons inside a compact/xs context (dense audit-log rows,
   small filter chips) — one deliberate, smaller companion size, so
   "compact" still means the same 30px everywhere it's used rather than
   each page inventing its own smaller number. */
.actions.actions-compact .action-icon-btn,
.actions.actions-compact .btn-icon-only,
.audit-log-table tbody td.actions .action-icon-btn {
    width: 30px !important;
    min-width: 30px !important;
    max-width: 30px !important;
    height: 30px !important;
    min-height: 30px !important;
    max-height: 30px !important;
    flex: 0 0 30px !important;
}
.actions.actions-compact .action-icon-btn svg,
.actions.actions-compact .btn-icon-only svg,
.audit-log-table tbody td.actions .action-icon-btn svg {
    width: 15px !important;
    height: 15px !important;
}

/* ══════════════════════════════════════════════════════════════════
   2. CONTROL HEIGHT — buttons and text inputs/selects sit at the
   same height when placed side by side (filter bars, inline forms),
   instead of buttons (10px vertical padding, no border) reading
   ~2–3px shorter than inputs (11px padding + 1px border) as they do
   today. box-sizing: border-box makes the padding/border trade-off
   exact rather than approximate.
   ══════════════════════════════════════════════════════════════════ */
.btn,
.form-group input[type="text"],
.form-group input[type="email"],
.form-group input[type="password"],
.form-group input[type="number"],
.form-group input[type="date"],
.form-group input[type="tel"],
.form-group input[type="search"],
.form-group select,
.filter-form input[type="text"],
.filter-form select,
.s11-picker-display {
    box-sizing: border-box;
}

.btn:not(.btn-xs):not(.btn-sm):not(.btn-icon-only) {
    min-height: 42px;
}
.filter-bar .filter-form > .btn,
.filter-form-compact .btn {
    min-height: 42px !important;
}
.form-group input[type="text"],
.form-group input[type="email"],
.form-group input[type="password"],
.form-group input[type="number"],
.form-group input[type="date"],
.form-group select,
.s11-picker-display {
    min-height: 42px;
}

/* ══════════════════════════════════════════════════════════════════
   3. ONE FOCUS RING — buttons, inputs, selects, textareas, tabs and
   text links all use the same primary-tinted halo, instead of
   buttons using :focus-visible with an outline and form fields using
   :focus with a box-shadow (two different visual languages for the
   same concept of "this is what's focused").
   ══════════════════════════════════════════════════════════════════ */
.btn:focus-visible,
.action-icon-btn:focus-visible,
.tab-btn:focus-visible,
a:focus-visible {
    outline: 3px solid color-mix(in srgb, var(--primary) 22%, transparent);
    outline-offset: 2px;
}
.form-group input:focus-visible,
.form-group select:focus-visible,
.form-group textarea:focus-visible,
.s11-picker-display:focus-visible {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
}

/* ══════════════════════════════════════════════════════════════════
   4. BADGES — consistent vertical centering inside table cells and a
   fixed minimum height so a row of mixed-length badges (e.g. "Active"
   next to "Pending Review") reads as one even row instead of the
   pill heights drifting with their own text.
   ══════════════════════════════════════════════════════════════════ */
.badge {
    min-height: 24px;
    line-height: 1.1;
    vertical-align: middle;
}
.data-table td .badge,
.table td .badge {
    display: inline-flex;
}

/* ══════════════════════════════════════════════════════════════════
   5. CARD RHYTHM — every .card-shaped surface (stat cards, filter
   bar, form cards, the plain .card) shares the exact same radius +
   shadow pairing, matching the Premium UI spec's "12–16px radius,
   soft double-layer shadow" rule exactly, rather than each one being
   defined separately and free to drift.
   ══════════════════════════════════════════════════════════════════ */
.card,
.stat-card,
.filter-bar,
.tabs-nav.tabs-nav-boxed {
    border-radius: var(--radius);
    box-shadow: var(--shadow-ambient), var(--shadow-contact);
}
.filter-bar {
    background: var(--surface);
    border: 1px solid var(--border);
    padding: var(--space-2);
}

/* ══════════════════════════════════════════════════════════════════
   7. LOCATIONS FILTER PANEL — Filter/Reset back next to the fields
   s29-standard-ui.css's later "S29.3" section set
   `.locations-filter-panel .filter-panel-actions { margin-left: auto
   !important; }`, which directly contradicts an EARLIER, correct fix
   in app.css ("keep Filter + Reset visually close to the Search
   box") and pushes the two icon buttons all the way to the far edge
   of the filter row on every Locations tab (Provinces, Districts,
   Communes, Villages, Recycle Bin). This restores the original,
   correct behaviour: Filter/Reset sit immediately after the last
   field, not stranded at the opposite end of the row.
   ══════════════════════════════════════════════════════════════════ */
.locations-filter-panel .filter-panel-actions {
    margin-left: 0 !important;
}

/* Recycle Bin's "Table" filter — previously an unwrapped <select>
   that picked up filter-responsive.css's flex-grow rule for bare
   .filter-form > select children and stretched to fill most of the
   row. Now wrapped like every other Locations cascade field, so it
   gets the same fixed, compact width instead. */
.location-trash-table-field {
    width: 200px !important;
    max-width: 200px !important;
    min-width: 200px !important;
    flex: 0 0 200px !important;
}
@media (max-width: 767.98px) {
    .location-trash-table-field {
        width: 100% !important;
        max-width: none !important;
        min-width: 0 !important;
        flex: 1 1 100% !important;
    }
}

/* ══════════════════════════════════════════════════════════════════
   8. MOBILE / QR CHECK-IN FILTER — fill the row evenly instead of
   leaving empty space after Reset. The existing rules give Search,
   the Source select, and the two date fields fixed pixel widths that
   add up to far less than the available row width on a normal
   desktop screen, so everything bunches on the left and the rest of
   the bar sits empty. Above 1300px (where the fixed-width rules
   apply and the gap actually appears), every field instead grows
   proportionally to fill the full row, with Filter/Reset staying a
   fixed 38px at the end.
   ══════════════════════════════════════════════════════════════════ */
@media (min-width: 1301px) {
    .mobile-checkins-filter-panel .filter-form {
        flex-wrap: nowrap !important;
    }
    .mobile-checkins-filter-panel .filter-search-field {
        flex: 1 1 0 !important;
        width: auto !important;
        min-width: 200px !important;
        max-width: none !important;
    }
    .mobile-checkins-filter-panel .filter-form > select[name="source"] {
        flex: 1 1 0 !important;
        width: auto !important;
        min-width: 170px !important;
        max-width: none !important;
    }
    .mobile-checkins-filter-panel .date-range-inline {
        flex: 2 1 0 !important;
        width: auto !important;
        min-width: 400px !important;
        max-width: none !important;
    }
    .mobile-checkins-filter-panel .date-range-field,
    .mobile-checkins-filter-panel .date-range-field .s11-picker-field,
    .mobile-checkins-filter-panel .date-range-field .hrms-date-input-wrap,
    .mobile-checkins-filter-panel .date-range-field input.hrms-date-text,
    .mobile-checkins-filter-panel .date-range-field .s11-picker-display {
        flex: 1 1 0 !important;
        width: auto !important;
        min-width: 180px !important;
        max-width: none !important;
    }
}

/* ══════════════════════════════════════════════════════════════════
   9. DATA RESET — Preview button, moved beside Module/Time Window
   (see app/Views/data_reset/index.php). Matches the height of the
   selects beside it and keeps its own row's spacing rhythm; the
   empty &nbsp; label keeps it bottom-aligned with the two selects
   exactly like every other .form-row in the app.
   ══════════════════════════════════════════════════════════════════ */
.data-reset-preview-field {
    justify-content: flex-end;
}
.data-reset-preview-field label {
    visibility: hidden;
}
.data-reset-preview-field .btn {
    min-height: 42px;
}

/* ══════════════════════════════════════════════════════════════════
   10. NOTIFICATION DELIVERY LOG — "Notification Type" combo dropdown
   was invisible/clipped when opened. Root cause: filter-responsive.css
   has `.filter-bar:not(.filter-form-compact) { overflow: hidden; }` —
   but `.filter-form-compact` is a class on the inner <form>, never on
   `.filter-bar` itself, so that :not() never actually excludes
   anything and overflow:hidden silently applies to every .filter-bar,
   clipping the dropdown the moment it opens below the box. Restore
   visibility specifically wherever a combo dropdown lives, without
   touching the (correct, intentional) overflow:hidden everywhere
   else this rule is actually needed.
   ══════════════════════════════════════════════════════════════════ */
.filter-bar:has(.combo-dropdown) {
    overflow: visible !important;
}

/* Date From / Date To on this same row: previously shrink-only
   (never grow), so once the Notification Type box hit its max width
   nothing absorbed the rest of the row, leaving a gap before Filter/
   Reset instead of the icons landing at the true right edge. Letting
   both date fields grow too closes that gap and reads as one full,
   evenly-filled row. */
.filter-form-compact .field-date-wide {
    flex: 1 1 250px !important;
    max-width: 320px;
}

/* ══════════════════════════════════════════════════════════════════
   6. BUTTON GROUPS — Import/Export and similar connected pairs keep
   the exact same 36px+ height as every other primary-context button,
   even though .btn-group strips border-radius per-button (previously
   these could end up shorter than a lone .btn next to them).
   ══════════════════════════════════════════════════════════════════ */
.btn-group .btn:not(.btn-xs):not(.btn-sm) {
    min-height: 42px;
}
