/* =============================================================================
   Modern Custom Styles for ASAS Global System
   Bootstrap 5.3.8 Compatible | RTL Arabic Support | Universal Module Support

   BREAKPOINT STRATEGY (mobile-first):
     Base rules target phones (≤576px). Use @media (min-width: ...) to enhance
     for larger viewports. Bootstrap 5 breakpoints:
       sm ≥ 576px   md ≥ 768px   lg ≥ 992px   xl ≥ 1200px   xxl ≥ 1400px

     Historical max-width queries remain for mobile-only stacking of
     table-based original layouts; new components should prefer min-width.
   ============================================================================= */

/* Fonts are loaded via <link rel="preconnect"> + <link> in _AppLayout.cshtml — faster than an
   @import here (which blocks CSS parsing and serialises the request behind this file's download).
   The --font-primary stack below references them. */

/* CSS Custom Properties for consistent theming */
:root {
    /* Comprehensive Arabic Font Stack - Tajawal primary with modern Arabic fallbacks */
    --font-primary: 'Tajawal', 'Cairo', 'El Messiri', 'Amiri', 'Droid Arabic Kufi', 'Al Bayan', 'Geeza Pro', 'Arabic Typesetting', 'Traditional Arabic', 'Simplified Arabic', 'Tahoma', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', system-ui, sans-serif;

    /* Spacing */
    --navbar-height: 56px;
    --header-height: var(--navbar-height);
    --spacing-xs: 0.25rem;
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 1.5rem;
    --spacing-xl: 3rem;

    /* Transitions */
    --transition-fast: 0.15s ease;
    --transition-normal: 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    --transition-slow: 0.5s ease;

    /* Shadows */
    --shadow-soft: 0 2px 4px -1px rgb(0 0 0 / 0.06), 0 1px 2px -1px rgb(0 0 0 / 0.1);
    --shadow-medium: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
    --shadow-strong: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
    --shadow-glow: 0 0 0 1px rgb(13 110 253 / 0.5);  /* brand var(--asas-primary), paired with outline: var(--bs-primary) */

    /* Border Radius */
    --radius-sm: 0.375rem;
    --radius-md: 0.5rem;
    --radius-lg: 0.75rem;

    /* Typography - Tajawal font weights */
    --font-weight-light: 300;
    --font-weight-regular: 400;
    --font-weight-medium: 500;
    --font-weight-semibold: 600;
    --font-weight-bold: 700;
    --line-height-tight: 1.25;

    /* ASAS palette — semantic colour tokens. Defined as raw hex (matching the
       original literals across the codebase) so adopting a token does not change
       any visuals. Future theme work changes one token instead of chasing 200+
       hardcoded hex literals across custom.css and the per-page style blocks.
       Where a token mirrors Bootstrap, the BS variable name is noted for orientation. */

    /* Brand */
    --asas-primary:        #0d6efd;  /* mirrors --bs-primary */
    --asas-primary-strong: #0a58ca;  /* gradient end / link-hover */
    --asas-primary-hover:  #0b5ed7;  /* button-hover */
    --asas-primary-soft:   #f3f7ff;  /* hover/tint surface (no BS equivalent) */

    /* Status */
    --asas-success:        #198754;  /* mirrors --bs-success */
    --asas-success-strong: #157347;
    --asas-danger:         #dc3545;  /* mirrors --bs-danger */
    --asas-danger-strong:  #b02a37;
    --asas-danger-darker:  #a71d2a;  /* used by danger gradients/links */
    --asas-warning:        #ffc107;  /* mirrors --bs-warning */
    --asas-warning-strong: #997404;

    /* Surfaces */
    --asas-surface:        #fff;
    --asas-surface-muted:  #f8f9fa;  /* mirrors --bs-tertiary-bg */
    --asas-surface-subtle: #e9ecef;  /* mirrors --bs-secondary-bg */

    /* Borders */
    --asas-border:         #dee2e6;  /* mirrors --bs-border-color */
    --asas-border-soft:    #e9ecef;
    --asas-border-input:   #ced4da;

    /* Text */
    --asas-text:           #212529;  /* mirrors --bs-body-color */
    --asas-text-muted:     #6c757d;  /* mirrors --bs-secondary-color */
    --asas-text-strong:    #495057;  /* form labels, stat values */

    /* Status tints — BS4 alert-subtle values, used by alerts, the wizard's
       complete-step marker, and the submission-success card. Each tint pairs a
       background with an emphasis text. */
    --asas-tint-info-bg:      #cfe2ff;
    --asas-tint-info-text:    #052c65;
    --asas-tint-success-bg:   #d4edda;
    --asas-tint-success-text: #155724;
}

/* Fallback font handled by system fonts in font stack - no external dependencies needed */

/* Base Layout - Apply Tajawal font globally */
body {
    font-family: var(--font-primary);
    padding-top: var(--header-height);
    background-color: var(--asas-surface-muted);
    font-weight: var(--font-weight-regular);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    margin: 0;
    padding-bottom: 0;
}

/* Main grows to push the footer to the viewport bottom on short pages */
main {
    flex: 1 0 auto;
    padding-bottom: 2rem;
}

/* Footer follows content */
footer {
    flex-shrink: 0;
    width: 100%;
    position: relative;
    z-index: 10;
}

/* Focus management for accessibility — only show the ring for keyboard
   navigation. :focus-visible already excludes mouse/programmatic focus, so a
   separate *:focus rule + :not(:focus-visible) reset would be redundant.
   Keep this in sync with the identical first-paint rule in _AppLayout.cshtml's
   inline <style>, which (being later in source order) wins — so the global ring
   is outline-only; no box-shadow glow here or it would be dead anyway. */
*:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

/* =============================================================================
   Login Form Styling Enhancements
   ============================================================================= */

/* Mobile-first: phones already have tight column padding; restore roomy padding on ≥md */
@media (min-width: 768px) {
    .container .col-md-6 {
        padding-left: var(--spacing-lg);
        padding-right: var(--spacing-lg);
    }
}

/* Button width in card */
.card-body .btn {
    width: 100% !important;
    margin-top: var(--spacing-sm);
}

/* Inline buttons next to form controls (e.g. dropdown + "تحديث" rows) keep
   their natural width — the full-width rule above is for centered card
   action buttons, not flex-row companions. */
.card-body .d-flex > .btn,
.card-body .input-group > .btn,
.card-body .btn-toolbar .btn {
    width: auto !important;
    margin-top: 0;
}

/* A button occupying its own grid column (e.g. a search/filter bar's submit
   button in a .row > .col) keeps its full column width but must drop the
   stacked-action margin-top above, or it sits lower than the input sharing
   its row and breaks align-items-center alignment. Covers both a .row nested
   inside .card-body and the combined `class="card-body row"` form. */
.card-body .row > [class*="col"] > .btn,
.card-body.row > [class*="col"] > .btn {
    margin-top: 0;
}

/* =============================================================================
   Component Styles
   ============================================================================= */

/* Enhanced Card Components with modern styling */
.card {
    border-radius: var(--radius-lg);
    border: 1px solid var(--bs-border-color);
    box-shadow: var(--shadow-soft);
    transition: var(--transition-normal);
    overflow: hidden;
}

.card:hover {
    box-shadow: var(--shadow-strong);
    border-color: var(--bs-primary-border-subtle);
}

.card-header {
    font-family: var(--font-primary);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border-bottom: 1px solid var(--bs-border-color-translucent);
    font-weight: var(--font-weight-semibold);
    background: linear-gradient(135deg, var(--bs-light), var(--bs-gray-100));
    padding: var(--spacing-lg);
}

/* Flush header — drops the gradient fill and divider (and the bottom padding) so the
   title reads as one piece with the card body. `background: none` is needed because the
   base rule paints a gradient *image*, which .bg-transparent (color only) can't clear. */
.card-header.card-header-flush {
    background: none;
    border-bottom: 0;
    padding-bottom: 0;
}

/* Primary-background card headers — gradient fill with strong white-on-blue
   contrast. This single base rule replaces three separate, scattered
   `.card-header.bg-primary {}` blocks that had accreted over successive
   contrast fixes (background/border + min-height/flex + a lone color reset). */
.card-header.bg-primary {
    background: linear-gradient(135deg, var(--asas-primary), var(--asas-primary-strong)) !important;
    color: #ffffff !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.2);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    min-height: 60px;
    display: flex;
    align-items: center;
}

.card-header.bg-primary h1,
.card-header.bg-primary h2,
.card-header.bg-primary h3,
.card-header.bg-primary h4,
.card-header.bg-primary h5,
.card-header.bg-primary h6 {
    color: #ffffff !important;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
    margin-bottom: 0;
}

.card-header.bg-primary .card-title {
    color: #ffffff !important;
    font-weight: var(--font-weight-semibold);
}

.card-header.bg-primary i {
    color: #ffffff !important;
    opacity: 0.9;
}

.card-header.bg-primary .bi {
    font-size: 1.2rem;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.2));
}

/* Catch-all: force white on any other element sitting on the solid fill. */
.card-header.bg-primary *:not(.dropdown-menu):not(.dropdown-menu *):not(.dropdown-item):not(.btn):not(.btn *) {
    color: #ffffff !important;
}

/* Fallback for any missed elements on a SOLID primary surface. Three classes
   of element are excluded because they do NOT sit on the solid fill:
     - .dropdown-menu *  → dropdown panels render on their own white background
     - .btn *            → buttons (e.g. btn-light "دخول") carry their own bg/color
     - bg-opacity-*       → a tinted .bg-primary (e.g. message bubbles using
                            `bg-primary bg-opacity-10`) is pale, so white text
                            would vanish; only solid bg-primary gets white text. */
.bg-primary:not([class*="bg-opacity"]) .card-title:not(.dropdown-menu *):not(.btn *),
.bg-primary:not([class*="bg-opacity"]) h1:not(.dropdown-menu *):not(.btn *), .bg-primary:not([class*="bg-opacity"]) h2:not(.dropdown-menu *):not(.btn *), .bg-primary:not([class*="bg-opacity"]) h3:not(.dropdown-menu *):not(.btn *),
.bg-primary:not([class*="bg-opacity"]) h4:not(.dropdown-menu *):not(.btn *), .bg-primary:not([class*="bg-opacity"]) h5:not(.dropdown-menu *):not(.btn *), .bg-primary:not([class*="bg-opacity"]) h6:not(.dropdown-menu *):not(.btn *),
.bg-primary:not([class*="bg-opacity"]) span:not(.dropdown-menu *):not(.btn *),
.bg-primary:not([class*="bg-opacity"]) i:not(.dropdown-menu *):not(.btn *),
.bg-primary:not([class*="bg-opacity"]) small:not(.dropdown-menu *):not(.btn *) {
    color: #ffffff !important;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.card-body {
    padding: var(--spacing-lg);
}

.card-footer {
    background-color: var(--asas-surface-muted);
    border-top: 1px solid var(--bs-border-color-translucent);
    padding: var(--spacing-md) var(--spacing-lg);
}

/* Navigation Bar Enhancements */
/* No backdrop-filter: the navbar is a solid .bg-primary surface, so a blur is
   invisible and only costs an extra compositing layer. */
.navbar {
    box-shadow: var(--shadow-medium);
    transition: var(--transition-normal);
}

.navbar-brand {
    font-family: var(--font-primary);
    font-weight: var(--font-weight-semibold);
    font-size: 1.25rem;
    transition: var(--transition-fast);
}

/* Improved navbar toggler */
.navbar-toggler {
    border: none;
    padding: var(--spacing-sm);
    border-radius: var(--radius-md);
    transition: var(--transition-fast);
}

.navbar-toggler:hover,
.navbar-toggler:focus {
    background-color: rgba(255, 255, 255, 0.1);
}

/* Modern Navigation Links */
.navbar-dark .navbar-nav .nav-link {
    color: rgba(255, 255, 255, 0.95) !important;
    font-size: 1rem;
    font-weight: var(--font-weight-medium);
    padding: var(--spacing-sm) var(--spacing-md);
    margin: 0 var(--spacing-xs);
    border-radius: var(--radius-sm);
    transition: var(--transition-fast);
    position: relative;
    overflow: hidden;
}

.navbar-dark .navbar-nav .nav-link::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(255, 255, 255, 0.1);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--transition-fast);
    z-index: -1;
}

.navbar-dark .navbar-nav .nav-link:hover::before,
.navbar-dark .navbar-nav .nav-link:focus::before {
    transform: scaleX(1);
}

.navbar-dark .navbar-nav .nav-link:hover,
.navbar-dark .navbar-nav .nav-link:focus {
    color: #ffffff !important;
}

.navbar-dark .navbar-nav .nav-link.active {
    color: var(--bs-primary) !important;
    background: #ffffff;
    font-weight: var(--font-weight-semibold);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}

/* On the white active pill the icon must be primary too — the bg-primary
   solid-surface fallback (forces icons to #fff) would otherwise wash it out. */
.navbar-dark .navbar-nav .nav-link.active .bi {
    color: var(--bs-primary) !important;
    text-shadow: none !important;
}

/* Keep the navbar user-dropdown toggle looking at home on a primary navbar,
   including when Bootstrap would otherwise invert btn-outline-light to white */
.navbar-dark .dropdown-toggle.btn-outline-light,
.navbar-dark .dropdown-toggle.btn-outline-light:hover,
.navbar-dark .dropdown-toggle.btn-outline-light:focus,
.navbar-dark .dropdown-toggle.btn-outline-light:active,
.navbar-dark .dropdown-toggle.btn-outline-light.show {
    background-color: rgba(255, 255, 255, 0.12) !important;
    border-color: rgba(255, 255, 255, 0.4) !important;
    color: #ffffff !important;
    box-shadow: none !important;
}

/* Restore dropdown-menu colors inside navbar-dark */
.navbar .dropdown-menu {
    --bs-dropdown-color: #212529;
    --bs-dropdown-link-color: #212529;
    --bs-dropdown-link-hover-color: #1e2125;
    --bs-dropdown-link-hover-bg: #f8f9fa;
    color: var(--asas-text);
}
.navbar .dropdown-menu .dropdown-item {
    color: var(--asas-text) !important;
}
.navbar .dropdown-menu .dropdown-item:hover,
.navbar .dropdown-menu .dropdown-item:focus {
    color: #1e2125 !important;
    background-color: var(--asas-surface-muted);
}
/* Reset span/i/small inside dropdown items — overrides any .bg-primary * rules.
   Exclude .badge so Bootstrap's white-on-colored-bg contrast survives. */
.navbar .dropdown-menu .dropdown-item span:not(.badge),
.navbar .dropdown-menu .dropdown-item i,
.navbar .dropdown-menu .dropdown-item small {
    color: inherit !important;
    text-shadow: none !important;
}

/* Notification-bell unread badge — pinned to the bell's top-right (the free side, away from
   the user menu). Physical `right` is deliberate: the logical start/end utilities get flipped
   by RTLCSS, which parked the badge in the gap between the bell and the user menu. */
.notif-badge {
    top: .2rem;
    right: .2rem;
    font-size: .6rem;
    line-height: 1;
    padding: .25em .4em;
}

/* Fix any regular links in navbar — exclude dropdown-item (white bg) */
.navbar-dark a:not(.nav-link):not(.btn):not(.dropdown-item) {
    color: rgba(255, 255, 255, 0.95) !important;
    text-decoration: none;
    transition: color 0.2s ease;
    padding: 0.5rem 0.75rem;
    border-radius: 0.375rem;
    margin: 0 0.25rem;
}

    .navbar-dark a:not(.nav-link):not(.btn):not(.dropdown-item):hover {
        color: #ffffff !important;
        background-color: rgba(255, 255, 255, 0.1);
        text-decoration: none;
    }

/* Ensure navbar list items without proper nav-item class still look good */
.navbar-dark .navbar-nav li > a:not(.nav-link):not(.dropdown-item) {
    color: rgba(255, 255, 255, 0.95) !important;
    display: block;
    padding: 0.5rem 1rem;
    text-decoration: none;
    border-radius: 0.375rem;
    transition: all 0.2s ease;
}

    .navbar-dark .navbar-nav li > a:not(.nav-link):not(.dropdown-item):hover {
        color: #ffffff !important;
        background-color: rgba(255, 255, 255, 0.1);
    }

/* Navbar action buttons (الرسائل / الحساب / خروج):
   Hover uses a solid dark-blue bg + white text for unambiguous contrast, with
   transform/font-weight locked so the button doesn't resize or jump on hover. */
.navbar-dark .btn-outline-light,
.navbar-dark .btn-light,
.navbar-dark .btn-info {
    font-weight: 500 !important;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

.navbar-dark .btn-outline-light:hover,
.navbar-dark .btn-outline-light:focus,
.navbar-dark .btn-outline-light:active,
.navbar-dark .btn-light:hover,
.navbar-dark .btn-light:focus,
.navbar-dark .btn-light:active,
.navbar-dark .btn-info:hover,
.navbar-dark .btn-info:focus,
.navbar-dark .btn-info:active {
    color: #ffffff !important;
    background-color: var(--asas-tint-info-text) !important;
    border-color: var(--asas-tint-info-text) !important;
    transform: none !important;
    box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.15) !important;
}

.navbar-dark .btn-outline-light > .bi,
.navbar-dark .btn-light > .bi,
.navbar-dark .btn-info > .bi {
    color: inherit;
}

.social-links img {
    width: 24px;
    height: 24px;
    margin: 0 4px;
}

/* Form enhancements */
.form-control,
.form-select {
    font-family: var(--font-primary);
    border-radius: var(--radius-sm);
    border: 2px solid var(--bs-border-color);
    transition: var(--transition-fast);
    font-weight: var(--font-weight-regular);
}

.form-control:focus,
.form-select:focus {
    border-color: var(--bs-primary);
    box-shadow: var(--shadow-glow);
}

/* Button enhancements */
.btn {
    font-family: var(--font-primary);
    border-radius: var(--radius-sm);
    font-weight: var(--font-weight-medium);
    padding: var(--spacing-sm) var(--spacing-md);
    transition: var(--transition-fast);
    position: relative;
    overflow: hidden;
}

.btn:hover {
    box-shadow: var(--shadow-medium);
}

/* =============================================================================
   Responsive Design
   ============================================================================= */

@media (max-width: 768px) {
    .card-header h4 {
        font-size: 1.1rem;
    }

    .navbar-nav .nav-link {
        padding: var(--spacing-md) var(--spacing-lg);
        border-radius: 0;
        border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    }

    .social-links-container {
        justify-content: center;
        margin-top: var(--spacing-md);
    }
}

@media (max-width: 576px) {
    :root {
        --spacing-md: 0.75rem;
        --spacing-lg: 1rem;
    }

    .container {
        padding-left: var(--spacing-md);
        padding-right: var(--spacing-md);
    }
}

/* High contrast mode support */
@media (prefers-contrast: high) {
    .card {
        border-width: 2px;
    }
    
    .btn {
        border-width: 2px;
    }
    
    .form-control,
    .form-select {
        border-width: 2px;
    }
}

/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
    :root {
        --transition-fast: 0s;
        --transition-normal: 0s;
        --transition-slow: 0s;
    }
    
    * {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* Shared spin keyframes used by .page-loading-spinner */
@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* =============================================================================
   Modern Form Enhancements
   ============================================================================= */

.form-floating {
    position: relative;
}

.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label {
    opacity: 0.65;
    transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
}

/* :user-invalid / :user-valid (vs :invalid / :valid) so a fresh form
 * doesn't show red on empty required fields before the user has even
 * interacted. Fires only after the user has committed a change to the
 * field. Browser support: Chrome 119+, Firefox 88+, Safari 16.5+. */
.form-control:user-invalid {
    border-color: var(--bs-danger);
    box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
}

.form-control:user-valid {
    border-color: var(--bs-success);
    box-shadow: 0 0 0 0.2rem rgba(25, 135, 84, 0.25);
}

.invalid-feedback {
    display: block;
    width: 100%;
    margin-top: 0.25rem;
    font-size: 0.875em;
    color: var(--bs-danger);
    animation: slideIn var(--transition-fast);
}

.valid-feedback {
    display: block;
    width: 100%;
    margin-top: 0.25rem;
    font-size: 0.875em;
    color: var(--bs-success);
    animation: slideIn var(--transition-fast);
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateY(-10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Custom checkbox and radio styles */
.form-check-input {
    width: 1.25em;
    height: 1.25em;
    margin-top: 0.125em;
    border-radius: var(--radius-sm);
    transition: var(--transition-fast);
}

.form-check-input:checked {
    background-color: var(--bs-primary);
    border-color: var(--bs-primary);
    box-shadow: var(--shadow-glow);
}

/* Shared fadeIn keyframes used by chat UI */
@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

/* =============================================================================
   Tajawal Font Application - Ensure all elements use primary font
   ============================================================================= */

/* Typography - Apply Tajawal to all headings */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-primary);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
}

/* Placeholder text styling — font-family inherits from html; weight/opacity are the intent */
::placeholder {
    font-weight: var(--font-weight-light);
    opacity: 0.7;
}

/* font-family is set once on <html> and inherits everywhere (Bootstrap's Reboot
   already sets `font-family: inherit` on form controls/headings, so no per-element
   re-declaration is needed). An explicit `* { font-family: inherit }` would add
   nothing and would strip the monospace default from <code>/<pre>/<kbd>. */
html {
    font-family: var(--font-primary);
    height: 100%;
}

/* Enhanced Arabic text rendering optimizations */
[lang="ar"], [dir="rtl"], .arabic-text {
    font-family: var(--font-primary);
    text-rendering: optimizeLegibility;
    -webkit-font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
    font-feature-settings: "kern" 1, "liga" 1, "calt" 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Specific Arabic typography improvements */
.arabic-content {
    line-height: 1.6;
    letter-spacing: 0.01em;
}

/* Ensure minimum content height */
.container.my-4 {
    min-height: calc(100vh - var(--header-height) - 150px);
}

/* =============================================================================
   MOBILE-FIRST UX FOUNDATION
   Additive rules that enforce consistent touch targets, RTL-safe spacing
   utilities, and table-to-stack fallbacks for pre-Bootstrap form markup.
   ============================================================================= */

/* Touch-target minimum — WCAG 2.5.5 / mobile HIG recommend 44px.
   Applies to all .btn and form inputs unless explicitly .btn-sm. */
.btn {
    min-height: 44px;
}

.btn-sm {
    min-height: 36px;
}

.btn-lg {
    min-height: 52px;
}

.form-control,
.form-select {
    min-height: 44px;
}

.form-control-sm,
.form-select-sm {
    min-height: 36px;
}

/* =============================================================================
   SHARED PAGE CHROME — the few cross-page helpers still in use.
   ============================================================================= */

.section-title {
    font-size: 18px;
    font-weight: 600;
    color: var(--asas-text);
    margin-bottom: 20px;
    padding-bottom: 10px;
    border-bottom: 2px solid var(--asas-primary);
}

/* Bootstrap doesn't set a pointer cursor on form-check labels by default, so
   clicking the label text feels unresponsive. Replaces inline `style="cursor:pointer"`
   on `<label class="form-check-label" for="...">` across the codebase. */
.form-check-label[for] {
    cursor: pointer;
}

/* Anonymous-form captcha image — token-based border/surface (was inline hex
   #ced4da / 6px / #f1f3f5; the first two map exactly to the tokens below). */
.captcha-img {
    border: 1px solid var(--asas-border-input);
    border-radius: var(--radius-sm);
    background: var(--asas-surface-muted);
}

/* Narrow numeric inputs (e.g. the ترتيب / order field in editable grid rows). */
.input-num-narrow {
    width: 70px;
}

/* Sidebar menu panel — used by as_Resalh (messaging) and as_Nshrh (newsletter).
   Responsive pill-bar overrides on ≤768px are further below. */
.rs-menu-section {
    background: var(--asas-surface);
    border-radius: 8px;
    padding: 15px;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

/* =============================================================================
   Messaging (Resalh) — chat UI (mobile-first)
   .chat-list-*    : conversation list rows
   .chat-avatar    : circular initials badge, shared with .chat-row
   .chat-thread    : bubble stream
   .chat-bubble-*  : message bubble + meta row
   .chat-compose-* : compose form polish
   ============================================================================= */

.chat-list-card {
    overflow: hidden;
}
.chat-list {
    margin: 0;
    padding: 0;
}
.chat-list li + li {
    border-top: 1px solid var(--bs-gray-200);
}
.chat-list-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.85rem 1rem;
    color: inherit;
    text-decoration: none;
    transition: background 0.15s;
}
.chat-list-item:hover,
.chat-list-item:focus-visible {
    background: var(--bs-gray-100);
    color: inherit;
}
.chat-list-item.chat-list-unread {
    background: var(--asas-primary-soft);
}
.chat-list-item.chat-list-unread:hover {
    background: #e8efff;
}
.chat-list-content {
    flex-grow: 1;
    min-width: 0;
}
.chat-list-top {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    margin-bottom: 0.15rem;
}
.chat-list-sender {
    font-weight: 500;
    color: var(--bs-body-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex-grow: 1;
    min-width: 0;
}
.chat-list-unread .chat-list-sender {
    font-weight: 700;
}
.chat-list-time {
    flex-shrink: 0;
    font-size: 0.75rem;
    color: var(--bs-gray-600);
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    line-height: 1.1;
}
.chat-list-date {
    font-size: 0.68rem;
    color: var(--bs-gray-500);
    margin-top: 0.1rem;
}
.chat-list-subject {
    font-size: 0.92rem;
    color: var(--bs-gray-700);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-bottom: 0.1rem;
}
.chat-list-unread .chat-list-subject {
    color: var(--bs-body-color);
    font-weight: 600;
}
.chat-list-preview {
    font-size: 0.82rem;
    color: var(--bs-gray-600);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Sender grouping (WhatsApp/Telegram style). A non-collapsed row starts a
 * new sender cluster; a collapsed row continues the current one and hides
 * the avatar + name + recipient-count pill so adjacent threads with the
 * same person stack tightly. The thread-message-count badge inside the
 * subject line stays visible -- it's per-thread, not per-sender. */
.chat-list > li:not(:first-child) .chat-list-item:not(.chat-list-collapsed) {
    border-top: 1px solid var(--bs-border-color, #e9ecef);
}
.chat-list-collapsed {
    padding-top: 0.35rem;
    padding-bottom: 0.35rem;
}
.chat-list-collapsed .chat-avatar { visibility: hidden; }
.chat-list-collapsed .chat-list-top .chat-list-sender,
.chat-list-collapsed .chat-list-top .chat-list-thread-count { display: none; }
.chat-list-unread-dot {
    flex-shrink: 0;
    width: 0.55rem;
    height: 0.55rem;
    border-radius: 50%;
    background: var(--bs-primary);
    display: inline-block;
}

/* Numeric unread badge — shown on a conversation row when the thread has
   unread messages. Replaces the flat dot once the inbox groups by thread. */
.chat-list-unread-badge {
    flex-shrink: 0;
    min-width: 1.5rem;
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: var(--bs-primary);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 600;
    text-align: center;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
    display: inline-block;
}

/* Thread-length counter — subtle grey pill next to the subject when a
   conversation contains more than one message. */
.chat-list-thread-count {
    display: inline-block;
    padding: 0.05rem 0.4rem;
    margin-inline-start: 0.35rem;
    border-radius: 999px;
    background: var(--bs-gray-200);
    color: var(--bs-gray-700);
    font-size: 0.7rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    vertical-align: middle;
}

/* Circular avatar with initials — shared by list rows and thread bubbles.
   Background is a soft tint so it reads as UI chrome, not a real photo. */
.chat-avatar {
    flex-shrink: 0;
    width: 2.4rem;
    height: 2.4rem;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--asas-tint-info-bg), #9ec5fe);
    color: var(--asas-primary-strong);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 0.9rem;
    letter-spacing: 0.02em;
}
.chat-row-sent .chat-avatar {
    background: linear-gradient(135deg, #d1e7dd, #a3cfbb);
    color: #0f5132;
}
/* When the user has uploaded a real avatar, an <img class="chat-avatar-img">
   replaces the initials text inside the same .chat-avatar circle. Fill the
   parent and crop with object-fit so portraits, squares, and wide photos all
   land as a tidy circular badge. */
.chat-avatar-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
    display: block;
}

/* Inline reply-bubble avatar (as_Tthkrh my/view + cp/view). Sized to match
   the surrounding small text so it sits flush with the author name. */
.reply-avatar-img {
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    object-fit: cover;
    vertical-align: middle;
    margin-left: 0.15rem;
    margin-right: 0.15rem;
}

/* Inline staff-list avatar (as_Tthkrh cp/staff). One step larger than the
   reply-bubble variant since the table row is normal-sized text. */
.staff-avatar-img {
    width: 1.8rem;
    height: 1.8rem;
    border-radius: 50%;
    object-fit: cover;
    vertical-align: middle;
}
.staff-avatar-fallback { font-size: 1.6rem; vertical-align: middle; }

/* Account-manage avatar editor: larger preview circle next to the upload
   control. The .avatar-preview shell mirrors .chat-avatar's centering so the
   bi-person-circle fallback icon also lands tidy. */
.avatar-preview {
    width: 5rem;
    height: 5rem;
    border-radius: 50%;
    background: var(--bs-gray-200);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
}
.avatar-preview-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Chat thread — vertical scroll area, roomy enough on desktop to
   read a long conversation without the whole page scrolling. */
.chat-panel {
    overflow: hidden;
}
.chat-panel-header .chat-panel-title h2 { line-height: 1.2; }
.chat-thread {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    background: var(--bs-gray-100);
    padding: 1rem;
    max-height: 60vh;
    overflow-y: auto;
    scroll-behavior: smooth;
}
.chat-row {
    display: flex;
    gap: 0.6rem;
    align-items: flex-end;
    max-width: 100%;
}
.chat-row-received {
    justify-content: flex-start;
}
.chat-row-sent {
    justify-content: flex-end;
    flex-direction: row-reverse;
}
.chat-bubble {
    max-width: 85%;
    padding: 0.6rem 0.85rem;
    border-radius: var(--radius-lg);
    background: var(--asas-surface);
    box-shadow: var(--shadow-soft);
    word-wrap: break-word;
    overflow-wrap: anywhere;
}
/* Flat "tail" corner on the edge side. Page is RTL, so sent bubbles sit
   on the left and received on the right — tail corner follows accordingly. */
.chat-row-sent .chat-bubble {
    background: #d1e7dd;
    border-bottom-left-radius: var(--radius-sm);
}
.chat-row-received .chat-bubble {
    border-bottom-right-radius: var(--radius-sm);
}
.chat-bubble-sender {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--bs-primary);
    margin-bottom: 0.2rem;
}
.chat-row-sent .chat-bubble-sender {
    color: #0f5132;
}
.chat-bubble-body {
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--bs-body-color);
    white-space: pre-wrap;
}
.chat-bubble-meta {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.4rem;
    margin-top: 0.35rem;
    font-size: 0.7rem;
    color: var(--bs-gray-600);
}
.chat-bubble-time { font-variant-numeric: tabular-nums; }
.chat-bubble-date { opacity: 0.75; }
.chat-bubble-status .bi { font-size: 0.85rem; }

/* Per-bubble action buttons (forward / delete). Hidden by default,
 * fade in on bubble hover (Telegram-style). margin-inline-start:auto
 * pushes them to the trailing edge of the meta row. */
.chat-bubble-actions {
    display: inline-flex;
    gap: 0.15rem;
    margin-inline-start: auto;
    opacity: 0;
    transition: opacity 0.15s;
}
.chat-bubble:hover .chat-bubble-actions,
.chat-bubble:focus-within .chat-bubble-actions { opacity: 1; }
.chat-bubble-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--bs-gray-600);
    border-radius: 50%;
    text-decoration: none;
    line-height: 1;
}
.chat-bubble-action:hover,
.chat-bubble-action:focus-visible {
    background: rgba(0, 0, 0, 0.06);
    color: var(--bs-body-color);
    text-decoration: none;
}
/* Touch devices have no hover, so the hover-reveal pattern above strands
 * the actions invisible. Always-visible there. */
@media (hover: none) {
    .chat-bubble-actions { opacity: 1; }
}

/* Trash review (?trash=1): bubbles render dimmed and struck-through so
 * the operator knows they're looking at deleted history. Per-bubble
 * delete in this mode hard-purges the row. */
.chat-row-trash .chat-bubble {
    opacity: 0.55;
    border: 1px dashed var(--bs-border-color, var(--asas-border));
    box-shadow: none;
}
.chat-row-trash .chat-bubble-body { text-decoration: line-through; }
.chat-panel-trash .chat-thread { background: var(--bs-tertiary-bg, #f6f8fa); }

/* Inline reply composer — textarea grows on focus, send/forward sit flush right. */
.chat-reply-body {
    resize: none;
    min-height: 2.6rem;
    transition: min-height 0.15s ease;
}
.chat-reply-body:focus { min-height: 5rem; }

@media (min-width: 768px) {
    .chat-thread {
        max-height: 68vh;
        padding: 1.25rem;
    }
    .chat-bubble { max-width: 72%; }
}

@media (min-width: 1200px) {
    .chat-bubble { max-width: 60%; }
}

/* Mobile: tighter card chrome + hide the back arrow only on desktop. */
@media (max-width: 575.98px) {
    .chat-list-item { padding: 0.75rem 0.85rem; gap: 0.6rem; }
    .chat-avatar { width: 2.1rem; height: 2.1rem; font-size: 0.8rem; }
    .chat-thread { padding: 0.75rem; max-height: 62vh; }
    .chat-bubble { padding: 0.55rem 0.75rem; }
    .chat-bubble-body { font-size: 0.92rem; }
}

/* Compose — same card base, textarea grows vertically only. */
.chat-compose-card .chat-compose-body {
    resize: vertical;
    min-height: 8rem;
}

/* =============================================================================
   SHARED GRID STYLES — admin data tables (.asas-grid)
   A thin theme over Bootstrap's .table (every grid already carries .table +
   utilities in markup): grey centered header, comfortable cell padding, soft
   row hover. No !important needed — custom.css loads after Bootstrap, so these
   equal-specificity rules win on source order; the .bg-primary white-text
   enforcer never targets table cells, so cell colours are safe too.
   ============================================================================= */

.asas-grid th,
.asas-grid th * {
    color: var(--asas-text);
}

.asas-grid th {
    background: var(--asas-surface-subtle);
    font-weight: 600;
    padding: 12px 15px;
    text-align: center;
}

.asas-grid td {
    padding: 10px 15px;
    vertical-align: middle;
    text-align: center;
}

.asas-grid tr:hover {
    background: var(--asas-primary-soft);
}

/* Mobile compact padding */
@media (max-width: 768px) {
    .asas-grid th,
    .asas-grid td {
        padding: 8px 6px;
    }
}

/* =============================================================================
   FORM-FIELD COMPONENT
   Canonical form field structure for unified label / input / help / error UX.

   Canonical markup (wrap each field in .form-field):

       <div class="form-field">
           <label class="form-field-label" asp-for="X">
               النص <span class="form-field-required">*</span>
           </label>
           <input class="form-control" asp-for="X" />
           <small class="form-field-help">نص المساعدة الاختياري</small>
           <span class="form-field-error" asp-validation-for="X"></span>
       </div>

   The wrapper provides consistent spacing, label typography, required-star
   styling, and validation error positioning across all packages.
   ============================================================================= */

.form-field {
    margin-bottom: var(--spacing-md);
    display: flex;
    flex-direction: column;
}

.form-field-label {
    display: block;
    margin-bottom: var(--spacing-xs);
    font-weight: var(--font-weight-medium);
    font-size: 0.95rem;
    color: var(--bs-dark);
    line-height: var(--line-height-tight);
}

.form-field-required {
    color: var(--bs-danger);
    margin-inline-start: 0.25rem;
    font-weight: var(--font-weight-bold);
}

.form-field .form-control,
.form-field .form-select {
    width: 100%;
}

/* …but inside an input-group the control must keep Bootstrap's flex sizing, or the
   width:100% above leaves no room for the addon (e.g. password-reveal) and wraps it. */
.form-field .input-group > .form-control {
    width: 1%;
}

.form-field-help {
    display: block;
    margin-top: var(--spacing-xs);
    font-size: 0.8125rem;
    color: var(--bs-secondary);
    line-height: 1.4;
}

.form-field-error {
    display: block;
    margin-top: var(--spacing-xs);
    font-size: 0.8125rem;
    color: var(--bs-danger);
    font-weight: var(--font-weight-medium);
}

.form-field-error:empty {
    display: none;
}

/* Invalid state on the input when a sibling .form-field-error has content */
.form-field:has(.form-field-error:not(:empty)) .form-control,
.form-field:has(.form-field-error:not(:empty)) .form-select {
    border-color: var(--bs-danger);
}

/* Horizontal variant — label beside input on ≥md, stacked below */
.form-field-horizontal {
    flex-direction: row;
    align-items: flex-start;
    gap: var(--spacing-md);
}

.form-field-horizontal .form-field-label {
    flex: 0 0 30%;
    padding-top: 0.625rem;
    margin-bottom: 0;
    text-align: end;
}

.form-field-horizontal > *:not(.form-field-label) {
    flex: 1;
}

@media (max-width: 768px) {
    .form-field-horizontal {
        flex-direction: column;
    }

    .form-field-horizontal .form-field-label {
        flex: 0 0 auto;
        padding-top: 0;
        text-align: start;
    }
}

/* =============================================================================
   RESPONSIVE SIDEBAR — .rs-menu-section (as_Resalh / messaging module)
   On phones the vertical menu consumes 50%+ of viewport height. Turn it into
   a horizontal scrollable pill bar so main content is immediately visible.
   ============================================================================= */

@media (max-width: 768px) {
    .rs-menu-section {
        padding: var(--spacing-sm) !important;
        margin-bottom: var(--spacing-md);
    }

    .rs-menu-section ul,
    .rs-menu-section ul.mn {
        display: flex !important;
        flex-wrap: nowrap;
        overflow-x: auto;
        gap: var(--spacing-sm);
        padding: var(--spacing-xs) 0;
        margin: 0;
        list-style: none;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: thin;
    }

    .rs-menu-section ul li,
    .rs-menu-section ul.mn li {
        flex: 0 0 auto;
        margin: 0;
    }

    .rs-menu-section ul a,
    .rs-menu-section ul.mn a {
        display: inline-block;
        white-space: nowrap;
        padding: var(--spacing-sm) var(--spacing-md);
        background: var(--bs-gray-100);
        border-radius: var(--radius-md);
        color: var(--bs-dark);
        text-decoration: none;
        font-weight: var(--font-weight-medium);
        font-size: 0.875rem;
        border: 1px solid var(--bs-border-color);
        min-height: 40px;
        line-height: 1.4;
    }

    .rs-menu-section ul a:hover,
    .rs-menu-section ul a.active,
    .rs-menu-section ul.mn a:hover,
    .rs-menu-section ul.mn a.active {
        background: var(--bs-primary);
        color: #fff;
        border-color: var(--bs-primary);
    }
}

/* =============================================================================
   BUTTON SEMANTIC GUIDE (Bootstrap 5)
   Use these conventions project-wide for consistency. Never use inline
   background-color / color for action buttons — pick the semantic class:

       Save / Submit / Confirm         →  btn btn-primary
       Cancel / Back / Close           →  btn btn-secondary
       Delete / Remove / Destructive   →  btn btn-danger
       Export / Download / Print       →  btn btn-outline-primary
       Edit                            →  btn btn-outline-secondary (or btn-warning)
       Add new / Create                →  btn btn-success
       Info / View details             →  btn btn-info
       Small inline actions            →  btn btn-sm <variant>

   Touch targets: all .btn are enforced to min-height 44px above. Do not
   override with style="height:30px" — use .btn-sm (min-height 36px) instead.
   ============================================================================= */

/* Icon-in-button consistent spacing (replaces ad-hoc margin-left on <i>) */
.btn > i,
.btn > .bi {
    margin-inline-end: 0.35rem;
    vertical-align: -0.125em;
}

.btn > i:last-child,
.btn > .bi:last-child {
    margin-inline-end: 0;
    margin-inline-start: 0.35rem;
}

.btn > i:only-child,
.btn > .bi:only-child {
    margin: 0;
}

/* =============================================================================
   PAGE-LOADING OVERLAY
   Shown during navigations and htmx async requests. Prevents users from staring
   at a frozen UI during long stored-procedure calls. Markup and JS hook live in
   _AppLayout.cshtml.
   ============================================================================= */

#pageLoadingOverlay {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 10000;
    background: rgba(255, 255, 255, 0.96);
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: var(--spacing-md);
    font-family: var(--font-primary);
}

#pageLoadingOverlay[data-show] {
    display: flex;
    animation: fadeIn 0.2s ease;
}

.page-loading-spinner {
    width: 48px;
    height: 48px;
    border: 4px solid var(--bs-gray-300);
    border-top-color: var(--bs-primary);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

.page-loading-text {
    font-size: 0.95rem;
    font-weight: var(--font-weight-medium);
    color: var(--bs-dark);
}

/* =============================================================================
   WHATSAPP FLOATING BUTTON
   Used in _AppLayout.cshtml. Mobile-first: compact by default, roomier on
   desktop. Landscape phones get the smallest variant so fixed chrome doesn't
   eat the already-short viewport.
   ============================================================================= */

.whatsapp-float {
    position: fixed;
    bottom: 16px;
    left: 16px;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: #25d366;
    color: #fff;
    text-decoration: none;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
    transition: transform var(--transition-fast), box-shadow var(--transition-fast);
}

.whatsapp-float:hover,
.whatsapp-float:focus-visible {
    color: #fff;
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.3);
}

.whatsapp-float svg {
    width: 26px;
    height: 26px;
}

@media (min-width: 576px) {
    .whatsapp-float {
        bottom: 24px;
        left: 24px;
        width: 56px;
        height: 56px;
    }
    .whatsapp-float svg {
        width: 30px;
        height: 30px;
    }
}

/* =============================================================================
   LANDSCAPE PHONE COMPRESSION
   Phones in landscape have very little vertical room (e.g., 375px tall).
   Fixed navbar + fixed WhatsApp button can consume ~30% of viewport height.
   Shrink both aggressively so content gets priority.
   ============================================================================= */
@media (max-height: 500px) and (orientation: landscape) {
    :root {
        --navbar-height: 44px;
        --header-height: 44px;
    }
    .whatsapp-float {
        width: 40px;
        height: 40px;
        bottom: 8px;
        left: 8px;
    }
    .whatsapp-float svg {
        width: 22px;
        height: 22px;
    }
    /* Trim nav-link vertical padding to match 44px navbar */
    .navbar-nav .nav-link {
        padding-top: 0.35rem;
        padding-bottom: 0.35rem;
    }
}

/* Print: hide the floating button (already handled elsewhere, kept local for discoverability) */
@media print {
    .whatsapp-float {
        display: none !important;
    }
}


/* =============================================================================
   RESPONSIVE CARDS — opt-in card layout for data tables on phones
   Add class="responsive-cards" to a <table> or any ancestor of a table. On
   ≤575px viewports, rows become stacked cards with per-cell labels (taken from
   <thead> automatically by JS in _AppLayout.cshtml). Above 576px, the table
   renders normally.

   Usage:
     <table class="table responsive-cards"> ... </table>
   or
     <div class="responsive-cards"> <table> ... </table> </div>
   ============================================================================= */

@media (max-width: 575.98px) {
    .responsive-cards table {
        display: block;
        width: 100% !important;
        overflow-x: visible;
    }

    .responsive-cards thead {
        /* Hide headers but keep them in the DOM so JS can read labels */
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
    }

    .responsive-cards tbody,
    .responsive-cards tfoot {
        display: block;
        width: 100%;
    }

    .responsive-cards tbody tr {
        display: block;
        width: 100%;
        margin-bottom: var(--spacing-md);
        border: 1px solid var(--bs-border-color);
        border-radius: var(--radius-md);
        padding: var(--spacing-sm);
        background: var(--asas-surface);
        box-shadow: var(--shadow-soft);
    }

    .responsive-cards td {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: var(--spacing-xs) 0;
        border: none;
        gap: var(--spacing-sm);
        text-align: start;
        width: auto !important;
    }

    .responsive-cards td:not(:last-child) {
        border-bottom: 1px dashed var(--bs-border-color-translucent);
    }

    .responsive-cards td::before {
        content: attr(data-label);
        font-weight: var(--font-weight-semibold);
        color: var(--bs-secondary);
        flex: 0 0 40%;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    /* Cells without a label (edit/delete action columns) get the full width */
    .responsive-cards td[data-label=""]::before,
    .responsive-cards td:not([data-label])::before {
        display: none;
    }

    /* Empty cells — collapse */
    .responsive-cards td:empty {
        display: none;
    }

    /* Pager stays put; don't try to card-ify it */
    .responsive-cards .pagination {
        display: flex;
        justify-content: center;
        flex-wrap: wrap;
    }
}

@media (prefers-reduced-motion: reduce) {
    .page-loading-spinner {
        animation: none;
        border-top-color: var(--bs-gray-400);
    }

    #pageLoadingOverlay[data-show] {
        animation: none;
    }
}

/* =============================================================================
   TOUCH-DEVICE FALLBACKS
   Hover effects don't fire on touch until tap, producing a sticky "stuck hover"
   and hiding interactive affordances. On (hover: none) devices:
     - Remove lift/transform hints that only hover triggers
     - Surface interactive cues in the default state (so users see them)
     - Give tactile feedback via :active instead of :hover
   ============================================================================= */

@media (hover: none) {
    /* Cards: no hover lift; compress transition for snappier taps */
    .card {
        transition: background-color var(--transition-fast), box-shadow var(--transition-fast);
    }

    .card:hover {
        transform: none;
        box-shadow: var(--shadow-soft);
    }

    .card:active {
        box-shadow: var(--shadow-medium);
        transform: scale(0.995);
    }

    /* Buttons: prefer :active feedback over :hover */
    .btn:hover {
        transform: none;
    }

    .btn:active {
        transform: scale(0.97);
        opacity: 0.9;
    }

    /* Data grid rows: show row affordance via alternating background instead of hover */
    .asas-grid tr:hover {
        background-color: inherit;
    }

    .asas-grid tr:active {
        background-color: rgba(13, 110, 253, 0.08);
    }

    /* Navbar links: underline always visible on touch so the target is obvious */
    .navbar-dark .navbar-nav .nav-link::before {
        opacity: 0.4;
    }

    /* Hint images: drop hover scale (a tap shouldn't feel like a drag) */
    .social-links img:hover {
        transform: none;
    }

    /* Prevent 300ms tap delay and double-tap zoom on interactive controls */
    .btn,
    .nav-link,
    .card,
    a[role="button"] {
        touch-action: manipulation;
    }
}

/* =============================================================================
   PRINT STYLES
   Strip chrome (navbar, footer, floating buttons) and render content
   black-on-white for maximum ink efficiency. Applies to all pages.
   ============================================================================= */

@media print {
    /* Hide non-content chrome */
    header,
    footer,
    .navbar,
    .skip-to-main,
    #pageLoadingOverlay,
    .no-print,
    /* WhatsApp floating button */
    a[href*="wa.me"] {
        display: none !important;
    }

    /* Reset page layout for print */
    body {
        padding-top: 0 !important;
        background: var(--asas-surface) !important;
        color: #000 !important;
        font-size: 11pt;
    }

    main,
    main.container,
    .container.my-4 {
        max-width: 100% !important;
        padding: 0 !important;
        margin: 0 !important;
        min-height: 0 !important;
    }

    /* Strip shadows, gradients, hover effects */
    .card,
    .card-header,
    .card-body,
    .card-footer,
    .rs-menu-section {
        box-shadow: none !important;
        border: 1px solid #999 !important;
        background: var(--asas-surface) !important;
        background-image: none !important;
        transform: none !important;
    }

    /* Preserve table legibility */
    table {
        border-collapse: collapse !important;
        page-break-inside: auto;
    }

    thead {
        display: table-header-group;
    }

    tr {
        page-break-inside: avoid;
    }

    /* Links: show URL after text (except local fragments) */
    a[href]:not([href^="#"]):not([href^="javascript"])::after {
        content: " (" attr(href) ")";
        font-size: 0.85em;
        color: #555;
    }

    /* Hide interactive-only controls inside printed reports */
    .btn,
    button,
    input[type="button"],
    input[type="submit"] {
        display: none !important;
    }

    /* But allow print-only buttons to survive */
    .print-only {
        display: revert !important;
    }

    /* Arabic typography at print size */
    body, h1, h2, h3, h4, h5, h6, p, span, div, td, th {
        font-family: 'Traditional Arabic', 'Simplified Arabic', 'Tajawal', 'Cairo', Tahoma, serif !important;
    }

    /* Page margins */
    @page {
        margin: 1.5cm 1cm;
    }
}

/* Override Bootstrap Icons' @font-face to use font-display: swap instead of
   block. The vendor stylesheet ships with `block`, which hides glyphs for ~3s
   while the font loads (FOIT). `swap` shows fallback text immediately and
   swaps to the icon font when ready — better perceived perf with no downside
   here since the icons aren't text-content-critical. Same src; last-
   declaration-wins means this replaces the earlier face. */
@font-face {
    font-family: "bootstrap-icons";
    font-display: swap;
    src: url("./fonts/bootstrap-icons.woff2") format("woff2"),
         url("./fonts/bootstrap-icons.woff") format("woff");
}

/* Public bulletin listing (qNshrh) — compact list rows. Thumb on the
   leading edge (RTL: right), title + category + date + view-count on
   the left, chevron at the trailing edge. Each row is a full-area link
   to the detail page; rows behave as list-group items. */
.nshrh-list .list-group-item {
    padding: 14px 16px;
    border-color: var(--asas-border-soft);
    color: inherit;
    transition: background-color .12s ease;
}
.nshrh-list .list-group-item:hover,
.nshrh-list .list-group-item:focus {
    background: var(--asas-primary-soft);
    color: inherit;
}
.nshrh-list-thumb {
    width: 96px;
    height: 72px;
    object-fit: cover;
    border-radius: 6px;
    flex-shrink: 0;
    border: 1px solid var(--asas-border-soft);
    background: var(--asas-surface-muted, #f8f9fa);
}
.nshrh-list-thumb-placeholder {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--asas-text-muted);
    font-size: 1.4rem;
}
.nshrh-list-title {
    font-weight: 600;
    color: var(--asas-text);
    font-size: 1rem;
    line-height: 1.4;
    /* Two-line clamp keeps long Arabic titles from breaking the row height */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.nshrh-list-meta i { opacity: .7; }
.min-width-0 { min-width: 0; }

/* Newsletter cards — as_Nshrh (detail + listing). Body HTML is admin-authored rich content. */
.nshrh-card {
    border-radius: 6px;
    border: 1px solid var(--asas-border-soft);
    margin-bottom: 16px;
}
.nshrh-card .card-header {
    background: var(--asas-surface-muted);
    border-bottom: 2px solid var(--asas-primary);
    border-radius: 6px 6px 0 0;
    padding: 12px 16px;
}
/* Detail title renders as <h1 class="h4 card-title"> — keep Bootstrap's .h4 sizing,
   bump weight/colour. (Was a dead `h3` selector that matched no markup.) */
.nshrh-card .card-header .card-title {
    font-weight: 600;
    color: var(--asas-text);
}
.nshrh-card .card-body {
    padding: 16px;
    font-size: 14px;
    color: var(--asas-text-strong);
    line-height: 1.7;
}
.nshrh-card .card-body img {
    max-width: 100%;
    height: auto;
    display: block;
}

/* =============================================================================
   Choices.js — align the wrapped combobox with Bootstrap 5 form-select in RTL.
   Initialized globally by _AppLayout.cshtml for every <select> inside <main>.
   Base styles come from Content/choices/choices.min.css; keep this block minimal.
   ============================================================================= */
.choices {
    margin-bottom: 0;
    font-family: var(--font-primary);
    font-size: 1rem;
}
.choices__inner {
    font-family: var(--font-primary);
    font-size: 1rem;
    min-height: calc(1.5em + 0.75rem + 2px);
    padding: 0.375rem 0.75rem 0.375rem 2.25rem;
    background-color: var(--asas-surface);
    border: 1px solid var(--asas-border);
    border-radius: 0.375rem;
    line-height: 1.5;
    text-align: right;
}
.choices.is-focused .choices__inner,
.choices.is-open .choices__inner {
    border-color: #86b7fe;
    box-shadow: 0 0 0 0.25rem rgb(13 110 253 / 25%);
    outline: 0;
}
/* Caret on the LEFT for RTL — Bootstrap's .form-select arrow sits on the left
   in bootstrap.rtl.min.css; mirror that so Choices visually matches. */
.choices[data-type*="select-one"]::after {
    right: auto;
    left: 11.5px;
}
.choices[data-type*="select-one"].is-open::after {
    right: auto;
    left: 11.5px;
}
.choices__list--single {
    padding: 0;
    text-align: right;
}
.choices__list--dropdown,
.choices__list[aria-expanded] {
    text-align: right;
    font-family: var(--font-primary);
}
.choices__list--dropdown .choices__item,
.choices__list[aria-expanded] .choices__item {
    text-align: right;
}
.choices__input {
    font-family: var(--font-primary);
    background-color: var(--asas-surface);
    text-align: right;
}
/* Validator error outline propagates from the hidden <select> to the wrapper.
   Choices nests the original <select> INSIDE .choices, so the adjacent-sibling rule
   only fires for un-wrapped selects; the :has rule below covers the Choices case. */
.input-validation-error + .choices .choices__inner,
.choices:has(select.input-validation-error) .choices__inner {
    border-color: var(--asas-danger);
}
/* Direct fallback when a control isn't wrapped by Choices (disabled/skipped selects, inputs). */
.form-select.input-validation-error,
.form-control.input-validation-error {
    border-color: var(--asas-danger);
}
/* Containers with overflow:hidden (e.g. .card for rounded-corner clipping)
   truncate a Choices dropdown that opens past their edge. Lift the clip on
   ANY ancestor while a dropdown is open — scoped to .is-open, so normal
   clipping resumes once the menu closes. */
:has(> .choices.is-open),
:has(.choices.is-open) {
    overflow: visible !important;
}
/* Lift the wrapper above later-painted siblings (Bootstrap .input-group
   members in a bulk-actions strip, adjacent cards, etc.) while the menu is
   open. The base Choices CSS only sets z-index:1 on .choices__list--dropdown,
   which is scoped to the wrapper's own stacking context and loses to any
   following position:relative element. */
.choices.is-open {
    z-index: 1021;
}
/* .card:hover applies translateY which creates a stacking context, trapping
   the 1021 above inside the card's local layer. At root level the card then
   competes with following siblings (e.g. cp/queue's bulk-actions strip) by
   document order and loses. Lift the card itself so the open dropdown wins
   against everything painted after it. */
.card:has(.choices.is-open) {
    z-index: 1021;
}

/* ============================================================
   Dashboard landing (_asas/home/dashboard)
   ============================================================ */
.dashboard-avatar {
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--asas-border, #e5e7eb);
    background-color: #fff;
}
/* ============================================================
   Bulletin thumbnails — small cover image (+ icon placeholder for rows
   without a cover) shared by the dashboard/portal bulletin lists.
   ============================================================ */
.bulletin-thumb {
    width: 64px;
    height: 48px;
    object-fit: cover;
    border-radius: .35rem;
    flex-shrink: 0;
    border: 1px solid var(--asas-border, #e5e7eb);
    background: var(--asas-surface-muted, #f8f9fa);
}
.bulletin-thumb-placeholder {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--asas-text-muted, #6c757d);
    font-size: 1.15rem;
}
.bulletin-title {
    font-weight: 600;
    color: var(--asas-text);
    display: block;
}

/* ============================================================
   Public portal landing (as_Portal/_home/_default)
   ============================================================ */

/* Welcome / sign-in band — the landing's primary greeting + CTA. Soft primary
   tint that also reads as the top hero when no carousel slides are configured. */
.portal-welcome {
    background: linear-gradient(135deg, var(--asas-primary-soft, #f3f7ff), var(--asas-surface, #fff));
    border: 1px solid var(--asas-border, #dee2e6);
}
.portal-welcome-icon {
    font-size: 2.5rem;
    color: var(--asas-primary, #0d6efd);
    line-height: 1;
    flex-shrink: 0;
}
.portal-welcome-title {
    font-size: 1.2rem;
    font-weight: 700;
    /* primary-strong (#0a58ca, ≈5.7:1 on the tinted band) clears AA; plain --asas-primary fails at this size. */
    color: var(--asas-primary-strong, #0a58ca);
    margin: 0 0 .25rem;
}
@media (min-width: 768px) {
    .portal-welcome-title { font-size: 1.4rem; }
}

.portal-quick-card {
    border: 1px solid var(--asas-border, #e5e7eb);
    color: inherit;
    transition: transform .12s ease, box-shadow .12s ease;
}
.portal-quick-card:hover,
.portal-quick-card:focus {
    box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .075);
    color: inherit;
}
.portal-quick-icon {
    font-size: 2.25rem;
    color: var(--asas-primary, #0d6efd);
}
.portal-quick-title {
    font-size: 1.05rem;
    font-weight: 600;
    /* #0a58ca clears AA (≈5.7:1 on white); plain --asas-primary (#0d6efd) is ≈3.9:1 and fails for ~17px text. */
    color: var(--asas-primary-strong, #0a58ca);
}
.portal-section-title {
    font-weight: 700;
    color: var(--asas-primary, #0d6efd);
}
.portal-section-title i {
    margin-inline-end: .35rem;
}
.portal-bulletin-card {
    border: 1px solid var(--asas-border, #e5e7eb);
    color: inherit;
    overflow: hidden;
    transition: transform .12s ease, box-shadow .12s ease;
}
.portal-bulletin-card:hover,
.portal-bulletin-card:focus {
    box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .075);
    color: inherit;
}
.portal-bulletin-thumb {
    aspect-ratio: 16 / 9;
    background-color: var(--asas-surface-hover, #f8f9fa);
    background-size: cover;
    background-position: center;
}
.portal-bulletin-thumb-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--asas-muted, #6c757d);
    font-size: 3rem;
}
/* No-cover variant: drops the empty thumb, runs an accent rule down the
   inline-start edge, and lets the title own the card. RTL-safe via the
   logical border property. */
.portal-bulletin-card.portal-bulletin-card-textonly {
    border-inline-start: 4px solid var(--asas-primary, #0d6efd);
}
.portal-bulletin-card.portal-bulletin-card-textonly .card-body {
    padding-top: 1.25rem;
    padding-bottom: 1.25rem;
}
.portal-bulletin-card.portal-bulletin-card-textonly .portal-bulletin-title {
    font-size: 1.15rem;
    -webkit-line-clamp: 3;
}
.portal-bulletin-title {
    font-size: 1rem;
    font-weight: 600;
    /* #0a58ca clears AA (≈5.7:1 on white); plain --asas-primary (#0d6efd) is ≈3.9:1 and fails for 16px text. */
    color: var(--asas-primary-strong, #0a58ca);
    margin: 0 0 .5rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.portal-bulletin-meta i {
    margin-inline-end: .25rem;
}
/* Pause/play toggle for the auto-advancing portal carousel (WCAG 2.2.2). */
/* Fixed-height hero carousel: every slide shares one height so the page no longer
   jumps when images of different aspect ratios cycle. Images cover-crop to fill. */
#portalCarousel .carousel-item {
    height: 360px;
}
#portalCarousel .carousel-item a {
    display: block;
    height: 100%;
}
#portalCarousel .carousel-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
}
@media (max-width: 991.98px) {
    #portalCarousel .carousel-item { height: 280px; }
}
@media (max-width: 575.98px) {
    #portalCarousel .carousel-item { height: 190px; }
}

.portal-carousel-pause {
    position: absolute;
    bottom: .75rem;
    inset-inline-end: .75rem;
    z-index: 5;
    opacity: .85;
    padding: .25rem .5rem;
    line-height: 1;
}
.portal-carousel-pause:hover,
.portal-carousel-pause:focus {
    opacity: 1;
}
.portal-footer .card {
    border: 1px solid var(--asas-border, #e5e7eb);
}
.portal-socials {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .5rem;
}
.portal-social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    border: 1px solid var(--asas-border, #e5e7eb);
    background: var(--asas-surface, #fff);
    color: var(--asas-primary, #0d6efd);
    font-size: 1.25rem;
    text-decoration: none;
    transition: transform .12s ease, background-color .12s ease, color .12s ease;
}
.portal-social-link:hover,
.portal-social-link:focus {
    background: var(--asas-primary, #0d6efd);
    color: #fff;
}
.portal-social-link img {
    max-width: 1.5rem;
    max-height: 1.5rem;
    object-fit: contain;
}
.portal-maintenance {
    border: 1px solid #ffc107;
    background: #fff8e1;
}
.portal-maintenance-icon {
    font-size: 3.5rem;
    color: #b97a04;
    line-height: 1;
}
.portal-maintenance-title {
    font-size: 1.5rem;
    font-weight: 700;
    color: #b97a04;
}
.portal-maintenance-message {
    font-size: 1rem;
    color: #664d03;
    line-height: 1.7;
    white-space: pre-line;
}

/* =========================================================================
   Desktop side-rail navigation (authenticated only).
   Below lg the #mainMenu offcanvas slides in via the hamburger; at lg+
   offcanvas-lg renders it inline and these rules turn it into a sticky
   side rail beside the page content.
   ========================================================================= */
:root {
    --sidebar-width: 280px;
    /* Width the side rail + its gap steal from the content row. The authenticated
       shell/header widen by exactly this (via .container-app below) so the content
       column lands at the same width as the public .container. */
    --rail-offset: calc(var(--sidebar-width) + 1.5rem);
}

/* Authenticated canvas widening (rail-offset compensation).
   The header and .app-shell carry `.container .container-app`. At lg+ — where the
   rail sits in-flow and eats --rail-offset from the row — .container-app bumps the
   Bootstrap container max-width by that same offset, so .app-main ends up the width
   the public .container would have had. max-width only caps wide viewports, so on
   narrower screens the shell still uses ~100% width (no overflow); the residual
   squeeze at the low end of lg is geometric and unavoidable. Below lg the rail is an
   offcanvas (out of flow) and .container-app adds nothing, matching the public width.
   Offsets = Bootstrap container max-width (960 / 1140 / 1320) + --rail-offset. */
@media (min-width: 992px) {
    .container-app { max-width: calc(960px + var(--rail-offset)); }
}
@media (min-width: 1200px) {
    .container-app { max-width: calc(1140px + var(--rail-offset)); }
}
@media (min-width: 1400px) {
    .container-app { max-width: calc(1320px + var(--rail-offset)); }
}

/* The shell is the growing body child, so it carries the sticky-footer flex
   chain (body{flex column} -> .app-shell{flex:1 0 auto} -> footer stays put). */
.app-shell {
    display: flex;
    flex-direction: column;
    flex: 1 0 auto;
}

@media (min-width: 992px) {
    .app-shell {
        flex-direction: row;
        align-items: flex-start;
        gap: 1.5rem;
    }

    .app-sidebar {
        flex: 0 0 var(--sidebar-width);
        position: sticky;
        /* Float the card 1.5rem below the header and leave a matching bottom gap. */
        top: calc(var(--header-height) + 1.5rem);
        margin-block: 1.5rem;
        /* No max-height/overflow-y: the rail grows to its full natural height and
           the page scrolls, so the menu never gets its own vertical scrollbar.
           overflow-x:hidden stays so the menu text wraps, never scrolls sideways. */
        overflow-x: hidden;
        /* Card-style rail matching the app's .card (radius/border/shadow). Bootstrap
           forces .offcanvas-lg transparent at lg+, so restore the white surface here.
           Mobile keeps the plain slide-in offcanvas — this whole block is lg+ only. */
        background-color: var(--asas-surface, #fff) !important;
        border: 1px solid var(--bs-border-color, #dee2e6);
        border-radius: var(--radius-lg, .75rem);
        box-shadow: var(--shadow-soft);
    }

    /* Bootstrap sets .offcanvas-lg .offcanvas-body { display:flex } at lg+, which
       would shrink the accordion to its content width — force a full-width block. */
    .app-sidebar .offcanvas-body {
        display: block;
    }

    .app-main {
        flex: 1 1 auto;
        /* min-width:0 lets wide .responsive-cards tables shrink instead of
           overflowing the flex item and forcing horizontal page scroll. */
        min-width: 0;
    }
}

/* -------------------------------------------------------------------------
   Borderless menu chrome. Applies to both the desktop rail and the mobile
   offcanvas (both carry .app-sidebar). Strips the accordion/list-group
   divider lines and the expanded-group highlight so the menu reads as one
   clean list; affordance comes from hover/active backgrounds instead.
   ------------------------------------------------------------------------- */
.app-sidebar .accordion,
.app-sidebar .accordion-item,
.app-sidebar .accordion-button,
.app-sidebar .list-group,
.app-sidebar .list-group-item {
    background-color: transparent;
    border: 0 !important;
}

/* Group headers read in the primary color in every state (matches the reference
   menu where both collapsed and expanded groups are blue). */
.app-sidebar .accordion-button,
.app-sidebar .accordion-button:not(.collapsed) {
    padding: .75rem 1rem;
    font-weight: var(--font-weight-semibold, 600);
    color: var(--asas-primary, #0d6efd);
    box-shadow: none;
}
.app-sidebar .accordion-button:focus {
    box-shadow: none;
}

.app-sidebar .list-group-item {
    padding: .5rem 1rem;
    margin: .125rem .5rem;
    border-radius: var(--radius-sm, .5rem) !important;
    color: var(--asas-text, #212529);
    transition: background-color .12s ease, color .12s ease;
}
.app-sidebar .list-group-item-action:hover,
.app-sidebar .list-group-item-action:focus {
    background-color: var(--asas-surface-muted, #f8f9fa);
    color: var(--asas-primary, #0d6efd);
}
.app-sidebar .list-group-item.active {
    background-color: var(--bs-primary-bg-subtle, #cfe2ff);
    color: var(--bs-primary-text-emphasis, #052c65);
    font-weight: var(--font-weight-semibold, 600);
}

/* Small circular chevron at the trailing (RTL: left) end of each navigable item;
   fills with the primary color on hover/active and nudges forward on hover. */
.app-sidebar .menu-item-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background-color: var(--asas-surface-muted, #f8f9fa);
    color: var(--asas-primary, #0d6efd);
    font-size: .7rem;
    transition: background-color .12s ease, color .12s ease, transform .12s ease;
}
.app-sidebar .list-group-item-action:hover .menu-item-arrow {
    transform: translateX(-3px);
}

/* Desktop rail card header (lg+ only — d-none hides it on mobile, which keeps the
   offcanvas-header instead). Sticky so it stays pinned while the menu list scrolls. */
.app-sidebar-header {
    position: sticky;
    top: 0;
    z-index: 1;
    align-items: center;
    gap: .5rem;
    padding: .85rem 1rem;
    font-weight: var(--font-weight-semibold, 600);
    color: var(--asas-text, #212529);
    background-color: var(--asas-surface, #fff);
    border-bottom: 1px solid var(--bs-border-color, #dee2e6);
}
.app-sidebar-header i {
    color: var(--asas-primary, #0d6efd);
    font-size: 1.1rem;
}

/* Status badge for the terminal "مكلف" (granted/assigned) application state. Indigo keeps it
   distinct from "جديد" (primary blue) and "مقبول" (success green) — the two states it would
   otherwise be confused with — while still reading as a final, positive outcome. .badge already
   defaults its text to white, so only the background is set here. Returned by the BadgeClass
   switches in TshkylatTlb / TshkylatTlbDetail. */
.bg-tklyf {
    background-color: #6610f2 !important;  /* mirrors --bs-indigo */
}
