/* ==========================================================================
   Badges, alerts, toasts, modals, empty states
   ========================================================================== */

/* Badges */
.badge {
    border-radius: var(--t-radius-pill);
    font-weight: 600;
    font-size: 0.72rem;
    padding: 0.32em 0.7em;
    letter-spacing: 0.01em;
}
.badge-primary { background: rgba(var(--t-primary-rgb), 0.12); color: var(--t-primary); }
.badge-success { background: rgba(var(--t-success-rgb), 0.14); color: #15803D; }
.badge-warning { background: rgba(var(--t-warning-rgb), 0.16); color: #B45309; }
.badge-danger  { background: rgba(var(--t-danger-rgb), 0.14); color: #B91C1C; }
.badge-info    { background: rgba(var(--t-info-rgb), 0.14); color: #0E7490; }
.badge-secondary { background: var(--t-bg); color: var(--t-secondary); border: 1px solid var(--t-border); }
:root[data-theme="dark"] .badge-success { color: #4ADE80; }
:root[data-theme="dark"] .badge-warning { color: #FBBF24; }
:root[data-theme="dark"] .badge-danger  { color: #F87171; }
:root[data-theme="dark"] .badge-info    { color: #22D3EE; }

/* Status word helpers usable via a data attribute in future markup, harmless if unused */
.status-pill { display: inline-flex; align-items: center; gap: 0.35em; border-radius: var(--t-radius-pill); padding: 0.3em 0.75em; font-size: 0.72rem; font-weight: 600; }

/* Alerts — exact spec palette (light theme); dark theme gets a tinted-on-card variant */
.alert {
    border: 1px solid transparent;
    border-radius: 10px;
    font-size: 0.875rem;
    box-shadow: var(--t-shadow-sm);
    padding: 0.9rem 1.1rem;
    position: relative;
    padding-left: 2.75rem;
    animation: t-fade-in 240ms ease both;
}
.alert::before {
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    position: absolute;
    left: 1rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 1rem;
}
.alert-success {
    background: #ECFDF5; border-color: #22C55E; color: #166534;
}
.alert-success::before { content: "\f058"; color: #22C55E; }
.alert-danger {
    background: #FEF2F2; border-color: #EF4444; color: #991B1B;
}
.alert-danger::before { content: "\f057"; color: #EF4444; }
.alert-warning {
    background: #FFFBEB; border-color: #F59E0B; color: #92400E;
}
.alert-warning::before { content: "\f06a"; color: #F59E0B; }
.alert-info {
    background: #EFF6FF; border-color: #3B82F6; color: #1E3A8A;
}
.alert-info::before { content: "\f05a"; color: #3B82F6; }
:root[data-theme="dark"] .alert-success { background: rgba(34, 197, 94, 0.12); color: #4ADE80; }
:root[data-theme="dark"] .alert-danger  { background: rgba(239, 68, 68, 0.12); color: #F87171; }
:root[data-theme="dark"] .alert-warning { background: rgba(245, 158, 11, 0.12); color: #FBBF24; }
:root[data-theme="dark"] .alert-info    { background: rgba(59, 130, 246, 0.12); color: #93C5FD; }

.alert .close {
    position: absolute;
    right: 0.85rem;
    top: 50%;
    transform: translateY(-50%);
    font-size: 1rem;
    text-shadow: none;
    color: inherit;
    opacity: 0.6;
}
.alert .close:hover { opacity: 1; }
.alert.fade:not(.show) { opacity: 0; }
.alert.fade { transition: opacity 300ms ease; }

/* Field-level validation error text (Blade @error / is-invalid pattern, if used) */
.field-help.text-danger { color: var(--t-danger) !important; }

/* Toasts (jquery.toast) — exact spec palette per type */
.jq-toast-single {
    background-color: var(--t-card-bg) !important;
    color: var(--t-text) !important;
    border: 1px solid var(--t-border) !important;
    border-left: 4px solid var(--t-primary) !important;
    border-radius: 10px !important;
    box-shadow: var(--t-shadow-lg) !important;
    padding: 0.9rem 1rem 0.9rem 1rem !important;
    font-family: var(--t-font) !important;
    font-size: 0.82rem !important;
    line-height: 1.45 !important;
    animation: t-toast-in 240ms ease both;
}
.jq-toast-single h2 { color: var(--t-text) !important; font-weight: 700 !important; font-size: 0.88rem !important; }
.jq-toast-single a { color: var(--t-primary) !important; border-bottom-color: var(--t-primary) !important; }

.jq-icon-success {
    background-color: #ECFDF5 !important; color: #166534 !important;
    border-left-color: #22C55E !important; background-image: none !important;
}
.jq-icon-success h2 { color: #166534 !important; }
.jq-icon-error {
    background-color: #FEF2F2 !important; color: #991B1B !important;
    border-left-color: #EF4444 !important; background-image: none !important;
}
.jq-icon-error h2 { color: #991B1B !important; }
.jq-icon-warning {
    background-color: #FFFBEB !important; color: #92400E !important;
    border-left-color: #F59E0B !important; background-image: none !important;
}
.jq-icon-warning h2 { color: #92400E !important; }
.jq-icon-info {
    background-color: #EFF6FF !important; color: #1E3A8A !important;
    border-left-color: #3B82F6 !important; background-image: none !important;
}
.jq-icon-info h2 { color: #1E3A8A !important; }
:root[data-theme="dark"] .jq-icon-success { background-color: rgba(34, 197, 94, 0.14) !important; color: #4ADE80 !important; }
:root[data-theme="dark"] .jq-icon-success h2 { color: #4ADE80 !important; }
:root[data-theme="dark"] .jq-icon-error   { background-color: rgba(239, 68, 68, 0.14) !important; color: #F87171 !important; }
:root[data-theme="dark"] .jq-icon-error h2 { color: #F87171 !important; }
:root[data-theme="dark"] .jq-icon-warning { background-color: rgba(245, 158, 11, 0.14) !important; color: #FBBF24 !important; }
:root[data-theme="dark"] .jq-icon-warning h2 { color: #FBBF24 !important; }
:root[data-theme="dark"] .jq-icon-info    { background-color: rgba(59, 130, 246, 0.14) !important; color: #93C5FD !important; }
:root[data-theme="dark"] .jq-icon-info h2 { color: #93C5FD !important; }

.close-jq-toast-single { color: inherit !important; opacity: 0.6; }
.close-jq-toast-single:hover { opacity: 1; }

@keyframes t-toast-in {
    from { opacity: 0; transform: translateX(12px); }
    to { opacity: 1; transform: translateX(0); }
}

/* Modals */
.modal-backdrop.show { opacity: 0.55; backdrop-filter: blur(1px); }
.modal-content {
    background: var(--t-card-bg);
    border: 1px solid var(--t-border);
    border-radius: var(--t-radius-lg);
    box-shadow: var(--t-shadow-lg);
    overflow: hidden;
}
/* The Tempus Dominus calendar popup renders as an absolutely-positioned sibling inside
   .modal-content, not appended to <body> — the overflow:hidden above (needed for the
   modal's rounded corners) was clipping that popup for any date/time field placed lower in
   a modal. common.js toggles .datepicker-open on .modal-dialog for the duration the popup
   is open: it lifts the overflow clipping here, and (below, next to the transform rules)
   also suspends .modal-dialog's own entrance-animation transform, which would otherwise
   make it the positioning reference frame for the calendar's absolute positioning instead
   of the viewport — that mismatch, not just the overflow, is what actually cut the
   calendar off for fields lower in the modal (Start/End Date). */
.modal-dialog.datepicker-open .modal-content { overflow: visible; }
/* ...and .modal-body, which AdminLTE gives `overflow-y: auto` (adminlte.min.css). Per the CSS
   overflow spec a non-visible overflow-y forces overflow-x to `auto` too, so .modal-body was a
   scroll container clipping the picker on BOTH axes — the Appointment Time dropdown in the
   Create Appointment / Edit Appointment modals is the last field in the body, so its popup
   opened straight into that clip and appeared cut off behind the form. Lifting the clipping on
   .modal-content alone (above) never reached it. Scoped to .datepicker-open, i.e. only while a
   picker is actually open, so the modal's normal scrolling behaviour is untouched the rest of
   the time. */
.modal-dialog.datepicker-open .modal-body { overflow: visible; }
/* Tempus Dominus's popup has no z-index of its own — it renders position:absolute with
   z-index:auto, which does NOT create its own stacking context, so it's compared against
   sibling elements within .modal-content's own context. Any positioned sibling with an
   EXPLICIT z-index (e.g. .aps-sticky-footer's z-index:5, package_modal.blade.php's sticky
   Close/Save bar) paints on top of it regardless of DOM order, which is what was making the
   picker "not display properly"/look cut off behind the modal footer. Forced high enough to
   always win against anything else inside a modal. */
.modal .bootstrap-datetimepicker-widget { z-index: 1071; }
/* The picker is absolutely positioned against its .input-group.date. Give that group a
   stacking position while its picker is open so the popup is layered above the fields that
   follow it in the modal (Remarks textarea, footer buttons) rather than behind them. Applied
   only to the open group, never globally — nothing else in the modal gets a new z-index. */
.modal .input-group.date.datepicker-open-group { position: relative; z-index: 1072; }
/* Small screens: the widget must not be wider than the viewport or push the page sideways. */
@media (max-width: 575.98px) {
    .bootstrap-datetimepicker-widget { max-width: calc(100vw - 24px); }
}
.modal-header {
    border-bottom: 1px solid var(--t-border);
    padding: 1.1rem 1.4rem;
}
.modal-header .card-title, .modal-header h2, .modal-header h3, .modal-header h4, .modal-header h5 {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--t-text);
    margin: 0;
}
.modal-body { padding: 1.4rem; color: var(--t-text); }
.modal-footer {
    border-top: 1px solid var(--t-border);
    padding: 0.9rem 1.4rem;
}
.modal.fade .modal-dialog { transform: translateY(-16px) scale(0.98); transition: transform 220ms ease, opacity 220ms ease; }
.modal.show .modal-dialog { transform: translateY(0) scale(1); }
/* See the .datepicker-open comment above — a non-none transform (even the settled
   scale(1)/translateY(0) above) makes this element the containing block for any
   position:absolute descendant, which is what was misplacing/clipping the calendar. */
.modal-dialog.datepicker-open { transform: none !important; }
.close { color: var(--t-muted); text-shadow: none; opacity: 1; }
.close:hover { color: var(--t-danger); }

/* Empty states — targets the common "colspan text row" pattern used across list tables */
td[colspan] {
    text-align: center;
    color: var(--t-muted);
    padding: 2.5rem 1rem !important;
    font-size: 0.875rem;
}
td[colspan]::before {
    content: "\f187";
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    display: block;
    font-size: 1.6rem;
    color: var(--t-border);
    margin-bottom: 0.5rem;
}
.dataTables_empty { color: var(--t-muted); padding: 2.5rem 1rem !important; }

/* Skeleton loading helper (opt-in via .t-skeleton, unused unless a view adds it) */
.t-skeleton {
    background: linear-gradient(90deg, var(--t-border) 25%, var(--t-bg) 37%, var(--t-border) 63%);
    background-size: 400% 100%;
    animation: t-skeleton-loading 1.4s ease infinite;
    border-radius: var(--t-radius-sm);
}
@keyframes t-skeleton-loading {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}
