/* --- Zippykind Admin Custom Styles 01.12.26 --- */

/* Custom overrides and additions to NexLink template */

/* --- Chart preloader skeleton 04.07.26 --- */
.chart-loader {
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(90deg, #f0f0f0 25%, #e8e8e8 50%, #f0f0f0 75%);
    background-size: 200% 100%;
    animation: chartShimmer 1.4s infinite;
    border-radius: 8px;
}
@keyframes chartShimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* --- Brand Color Override: Green instead of Purple 01.12.26 --- */
:root {
    --bs-primary: #449747 !important;
    --bs-primary-rgb: 68, 151, 71 !important;
    --bs-primary-text-emphasis: #2d6830 !important;
    --bs-primary-bg-subtle: #e8f5e9 !important;
    --bs-primary-border-subtle: #a5d6a7 !important;
    --bs-link-color: #449747 !important;
    --bs-link-hover-color: #367a39 !important;
}

/* --- Center sidebar logo 01.12.26 --- */
.app-navbar-brand {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 16px 0;
}

.app-navbar-brand a {
    display: flex;
    justify-content: center;
    align-items: center;
}

.app-navbar-brand img {
    max-height: 40px;
    width: auto;
}

/* --- Override CSS Variable for sidebar width 01.12.26 --- */
:root {
    --app-menubar-tabs: 240px !important;
}

/* --- Sidebar Fix: Single wide menu only (no icon column) 01.12.26 --- */
.app-menubar-tabs {
    width: 240px !important;
}

/* Hide the icon column completely */
.app-menubar-tabs .app-navbar-brand,
.app-menubar-tabs .app-navbar-tabs {
    display: none !important;
}

/* Position app-tab-content at left edge (remove 80px offset) */
.app-menubar-tabs .app-tab-content {
    display: block !important;
    position: fixed !important;
    left: 0 !important;
    top: 0 !important;
    width: 240px !important;
    height: 100vh !important;
}

/* Main content and header margins */
.page-content,
.app-wrapper {
    margin-left: 240px !important;
}

/* --- Fix: Add top padding to page-content for header clearance 01.14.26 --- */
.page-content {
    padding-top: 70px !important;
}

.app-header {
    padding-left: 240px !important;
}

/* Footer margin */
.footer-wrapper {
    margin-left: 240px !important;
}

/* Logo styling in sidebar 01.12.26 */
.app-menubar-tabs .app-side-brands {
    padding: 20px 15px !important;
    height: auto !important;
}

.app-menubar-tabs .app-side-brands a {
    display: inline-block;
}

.app-menubar-tabs .app-side-brands img {
    max-height: 36px;
    width: auto;
}

/* Version text at bottom 01.12.26 */
.sidebar-version {
    padding: 15px 20px;
    font-size: 12px;
    color: #888;
    margin-top: auto;
    border-top: 1px solid #eee;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
}

/* Make app-content-inner scrollable with room for version */
.app-menubar-tabs .app-content-inner {
    height: calc(100vh - 120px) !important;
    overflow-y: auto;
}

.app-menubar-tabs .app-navbar {
    height: auto !important;
}

/* KPI Card Styling */
.kpi-card {
    transition: transform 0.2s ease-in-out;
}

.kpi-card:hover {
    transform: translateY(-2px);
}

/* Phone Numbers Table */
#phone-numbers-table tbody tr:hover {
    background-color: rgba(var(--bs-primary-rgb), 0.05);
}

/* Chart containers */
.chart-container {
    min-height: 300px;
}

/* Loading state */
.loading-spinner {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 200px;
}

/* Toast positioning */
.toast-container {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 9999;
}

/* --- Toastr styling fix 01.22.26 --- */
#toast-container > div {
    color: #000 !important;
    opacity: 1 !important;
    background-color: #fff !important;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
    border-left: 4px solid #999 !important;
    padding: 15px 15px 15px 15px !important;
}
#toast-container > .toast-success {
    background-color: #fff !important;
    opacity: 1 !important;
    border-left-color: #51A351 !important;
}
#toast-container > .toast-success .toast-title,
#toast-container > .toast-success::before {
    color: #51A351 !important;
}
#toast-container > .toast-error {
    background-color: #fff !important;
    opacity: 1 !important;
    border-left-color: #BD362F !important;
}
#toast-container > .toast-error .toast-title,
#toast-container > .toast-error::before {
    color: #BD362F !important;
}
#toast-container > .toast-info {
    background-color: #fff !important;
    opacity: 1 !important;
    border-left-color: #2F96B4 !important;
}
#toast-container > .toast-info .toast-title,
#toast-container > .toast-info::before {
    color: #2F96B4 !important;
}
#toast-container > .toast-warning {
    background-color: #fff !important;
    opacity: 1 !important;
    border-left-color: #F89406 !important;
}
#toast-container > .toast-warning .toast-title,
#toast-container > .toast-warning::before {
    color: #F89406 !important;
}
#toast-container .toast-title {
    color: #000 !important;
}
#toast-container .toast-message {
    color: #333 !important;
}
#toast-container .toast-message a,
#toast-container .toast-message label {
    color: #333 !important;
}
#toast-container .toast-close-button {
    color: #666 !important;
}

/* Status badges */
.badge-active {
    background-color: var(--bs-success);
}

.badge-pending {
    background-color: var(--bs-warning);
}

.badge-cancelled {
    background-color: var(--bs-danger);
}

/* DataTable customizations */
.dataTables_wrapper .dataTables_filter input {
    border-radius: 0.375rem;
}

/* Sidebar active state */
.app-menubar-tabs .menu-link.active {
    background-color: rgba(var(--bs-primary-rgb), 0.1);
    color: var(--bs-primary);
}

/* Mobile responsive adjustments */
@media (max-width: 768px) {
    .kpi-card .display-6 {
        font-size: 1.5rem;
    }
}

/* Modal fixes 01.07.26 */
.modal-xl .modal-body {
    overflow-y: auto;
    max-height: 70vh;
}

.modal-content {
    position: relative;
    display: flex;
    flex-direction: column;
}

.modal-backdrop {
    z-index: 1040;
}

.modal {
    z-index: 1050;
}

.modal-dialog {
    margin: 1.75rem auto;
}

.modal.show + .modal-backdrop + .modal {
    z-index: 1060;
}

/* --- Integrations hub selection cards 07.24.26 --- */
/* The NexLink template forces height: var(--bs-card-height) on .card, which
   collapses this equal-height card grid — same override pattern as .card-compact. */
.integration-hub-card {
    height: auto !important;
    cursor: pointer;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}

.integration-hub-card:hover {
    border-color: #89d541;
    box-shadow: 0 2px 10px rgba(0, 0, 0, .08);
    transform: translateY(-2px);
}

.integration-hub-icon {
    width: 42px;
    height: 42px;
    flex: 0 0 42px;
    border-radius: 8px;
    background: #f2f9ea;
    color: #6fb830;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 19px;
}

.integration-hub-card .card-body {
    height: 100%;
}

/* --- God's Eye heatmap legend swatches 08.12.26 --- */
.godseye-legend-swatch {
    display: inline-block;
    width: 24px;
    height: 16px;
    border-radius: 3px;
    flex-shrink: 0;
}

/* --- God's Eye map container responsive height 08.12.26 --- */
@media (max-width: 767px) {
    #godseye-map { height: 400px !important; }
}
/* --- Unclosed media query CLOSED 08.14.26 (T213) --- */
/* The closing brace above was missing, so this @media block never ended and
   EVERY rule from here to the end of the file was nested inside
   (max-width: 767px) - i.e. dead on any viewport wider than 767px. The visible
   symptom was the Code Logic Helper: at 1440px the FAB fell back to
   position:static and the panel rendered as a full-width static block at the
   bottom of every admin page, while at 700px both were correct. If a desktop
   style below this line ever "stopped working", this brace is why. */

/* --- Code Logic Helper Panel 08.12.26 --- */
.code-helper-fab {
    position: fixed;
    bottom: 28px;
    right: 28px;
    z-index: 1030;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: none;
    background: #449747;
    color: #fff;
    font-size: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
    cursor: pointer;
    transition: background .15s ease, transform .15s ease;
}
.code-helper-fab:hover {
    background: #367a39;
    transform: scale(1.08);
}

.code-helper-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1039;
    background: rgba(0, 0, 0, 0.25);
}
.code-helper-backdrop.open {
    display: block;
}

.code-helper-panel {
    position: fixed;
    top: 0;
    right: -420px;
    width: 400px;
    max-width: 90vw;
    height: 100vh;
    z-index: 1040;
    background: #fff;
    box-shadow: -4px 0 20px rgba(0, 0, 0, 0.12);
    transition: right .25s ease;
    display: flex;
    flex-direction: column;
}
.code-helper-panel.open {
    right: 0;
}

.code-helper-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid #e9ecef;
    flex-shrink: 0;
}

.code-helper-panel-body {
    flex: 1;
    overflow-y: auto;
    padding: 20px;
}

.code-helper-panel-body code {
    font-size: 12px;
    background: #f4f6f8;
    padding: 1px 5px;
    border-radius: 3px;
    color: #d63384;
}

@media (max-width: 576px) {
    .code-helper-fab {
        bottom: 16px;
        right: 16px;
        width: 40px;
        height: 40px;
        font-size: 17px;
    }
    .code-helper-panel {
        width: 100vw;
        max-width: 100vw;
        right: -100vw;
    }
}

/* --- t353-st12: Anti-Fraud review page 09.05.26 --- */
/* Appended at the END of the file on purpose. The T213 note on the ?ver bump in
   ScriptManagerAdmin.php records that an unclosed @media block once trapped every rule
   after it inside a mobile query; this section opens no media query of its own so it
   cannot repeat that, and nothing below it can be swallowed by it. */

#antiFraudPage .card-compact {
    height: auto !important; /* NexLink forces height:var(--bs-card-height) on .card */
}

/* The value/baseline column carries a long explanatory note under the numbers. Without a
   line height and a max width it pushes the action buttons off the right of the table. */
#antiFraudFlagsTable td .small {
    line-height: 1.35;
}

/* Hard freezes are listed first; a left rule makes the boundary between them and the soft
   flags readable at a glance without adding a whole column. */
#antiFraudFlagsTable tbody tr:has(.badge.bg-danger) {
    border-left: 3px solid #dc3545;
}

/* The policy panel is reference material, not a working surface: slightly smaller, wrapped
   rather than truncated, and the header reads as clickable. */
.zk-af-policy .card-header {
    cursor: pointer;
    user-select: none;
}
.zk-af-policy .card-header:hover {
    background-color: #f6f8f4;
}
.zk-af-policy-table td,
.zk-af-policy-table th {
    font-size: 13px;
    vertical-align: top;
}
.zk-af-policy-table tr.zk-af-policy-note td {
    background-color: #fbfcfa;
    border-top: 0;
}
/* Brand green, from reference_brand_colors: the policy panel's own accent so it reads as
   Zippykind documentation rather than as another data table. */
.zk-af-policy .card-header h5 {
    color: #74b636;
}

/* --- t353-st15: Automatic suspensions switch + Would-have-suspended list 09.05.26 --- */

/* The switch card carries the page's whole meaning, so it is colour-coded rather than being
   another white card: red down the left when the guard can suspend on its own, grey when it
   cannot. Left border only - a full red card at the top of every page visit reads as an error. */
.zk-af-enforce {
    border-left: 4px solid #adb5bd;
}
.zk-af-enforce-on {
    border-left-color: #dc3545;
}
.zk-af-enforce-off {
    border-left-color: #adb5bd;
}
#antiFraudEnforceSwitch:checked {
    background-color: #dc3545;
    border-color: #dc3545;
}

/* Would-have-suspended is a decision queue, not a log. Given the same red edge as an ON switch
   so the two read as the same subject. */
.zk-af-wouldhave {
    border-left: 4px solid #dc3545;
}
.zk-af-wouldhave .card-header h5 {
    color: #dc3545;
}

/* --- The table loading dots are brand green, not Bootstrap blue 09.10.26 (David) --- */
/* "in the backend /admin tables there is a preloader that has a group of small to medium size
   blue circles that are animated, can you change that preloader's circles so they are our brand
   green?"

   It is DataTables' own processing indicator: div.dt-processing > div:last-child holds four
   13px circles, and datatables.min.css paints them rgb(13, 110, 253) - Bootstrap blue - through
   its --dt-row-selected variable.

   THE COLOUR IS SET HERE RATHER THAN BY REDEFINING --dt-row-selected, deliberately. That
   variable also drives the selected-row highlight, so overriding it would quietly recolour row
   selection across every admin table as well, which is not what was asked for.

   No !important: this selector matches the library's own specificity exactly, and
   AdminCustom.css is registered after datatables.min.css, so it wins on order. */
div.dt-processing > div:last-child > div {
    background: #74b636;
}

/* --- st348: admin Support Case chat, message-center look 09.16.26 --- */
/* David (verbatim): "make the support cases page in the backend /admin/support-cases more
   like the message center in the dispatch software /app/message-center. i like the styling of
   the message center and the lazy load of messages and i like how the most recent messages
   are at the bottom near the textarea field."

   Class names and layout are ported from dispatch-software/src/assets/v2/dispatch.css's
   .messaging-thread-* / .msg-* rules (the Message Center on /app/message-center), so this is
   the same visual language rather than a lookalike copy: customer bubbles left in grey with
   an avatar, admin/operator replies right in the brand green the Message Center already uses
   for outgoing messages, internal notes right with a dashed outline + badge so they read as a
   distinct kind of message the customer never sees. */

#supportCaseChatPage.messaging-thread-card {
    display: flex;
    flex-direction: column;
    min-height: 60vh;
    border-radius: 6px;
    overflow: hidden;
}

#supportCaseChatPage .messaging-thread-header {
    padding: 14px 16px;
    border-bottom: 1px solid #e4e6eb;
    background: #f7f7f7;
    display: flex;
    align-items: center;
    gap: 12px;
}
#supportCaseChatPage .messaging-thread-header-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: #fff;
    line-height: 40px;
    text-align: center;
    font-weight: 600;
    flex: 0 0 40px;
}
#supportCaseChatPage .messaging-thread-header-text h2 {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
}
#supportCaseChatPage .messaging-thread-subtitle {
    color: #65676b;
    font-size: 12px;
}

#supportCaseChatPage .messaging-thread-body {
    flex: 1;
    overflow-y: auto;
    background: #ffffff;
    padding: 16px;
    min-height: 45vh;
    max-height: 55vh;
}
#supportCaseChatPage .messaging-thread-empty { color: #65676b; text-align: center; padding: 24px; }
#supportCaseChatPage .messaging-thread-loader { text-align: center; color: #65676b; font-size: 12px; padding: 10px; }

/* Clusters — consecutive messages from the same sender within 5 minutes share one header line,
   the same grouping the Message Center uses. */
#supportCaseChatPage .msg-cluster { margin-bottom: 14px; clear: both; }
#supportCaseChatPage .msg-cluster:after { content: ""; display: table; clear: both; }
#supportCaseChatPage .msg-cluster-time {
    text-align: center;
    color: #65676b;
    font-size: 11px;
    font-weight: 600;
    margin: 12px 0 8px;
}
#supportCaseChatPage .msg-cluster-sender {
    color: #65676b;
    font-size: 12px;
    font-weight: 500;
    margin: 0 0 4px 48px;
}
#supportCaseChatPage .msg-cluster-sender-out {
    text-align: right;
    margin: 0 12px 4px 0;
}
#supportCaseChatPage .msg-cluster-label {
    color: #8a8d91;
    font-weight: 400;
    font-size: 11px;
    margin-left: 6px;
    text-transform: uppercase;
}

#supportCaseChatPage .msg-side-in  { text-align: left; }
#supportCaseChatPage .msg-side-out { text-align: right; }

#supportCaseChatPage .msg-bubble {
    display: block;
    max-width: 65%;
    width: fit-content;
    padding: 8px 12px;
    margin-bottom: 2px;
    font-size: 14px;
    line-height: 1.4;
    word-wrap: break-word;
    white-space: normal;
    text-align: left;
}
#supportCaseChatPage .msg-side-in  .msg-bubble { margin-left: 48px; margin-right: auto; }
#supportCaseChatPage .msg-side-out .msg-bubble { margin-left: auto;  margin-right: 0; }

/* Customer = grey (Message Center's incoming colour); admin/operator = brand green
   (Message Center's outgoing colour). */
#supportCaseChatPage .msg-bubble-customer { background: #F0F0F0; color: #050505; }
#supportCaseChatPage .msg-bubble-admin    { background: #8bc34a; color: #ffffff; }

/* Internal note: same right-side placement as an admin reply, but a dashed outline instead of
   a solid fill — it must never be mistaken for something the customer received. */
#supportCaseChatPage .msg-bubble-internal {
    background: #fff8dc;
    color: #5d4b00;
    outline: 1px dashed rgba(0,0,0,0.35);
    outline-offset: -3px;
}
#supportCaseChatPage .msg-internal-badge {
    display: block;
    margin-top: 5px;
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    opacity: 0.85;
    color: #8a6d00;
}
#supportCaseChatPage .msg-internal-badge .material-icons {
    font-size: 13px;
    line-height: 1;
    vertical-align: -2px;
    margin-right: 3px;
}

#supportCaseChatPage .msg-bubble.msg-pos-single { border-radius: 18px; }
#supportCaseChatPage .msg-side-out .msg-bubble.msg-pos-first { border-radius: 18px 18px 4px 18px; }
#supportCaseChatPage .msg-side-out .msg-bubble.msg-pos-mid   { border-radius: 18px 4px 4px 18px; }
#supportCaseChatPage .msg-side-out .msg-bubble.msg-pos-last  { border-radius: 18px 4px 18px 18px; }
#supportCaseChatPage .msg-side-in  .msg-bubble.msg-pos-first { border-radius: 18px 18px 18px 4px; }
#supportCaseChatPage .msg-side-in  .msg-bubble.msg-pos-mid   { border-radius: 4px 18px 18px 4px; }
#supportCaseChatPage .msg-side-in  .msg-bubble.msg-pos-last  { border-radius: 4px 18px 18px 18px; }

#supportCaseChatPage .msg-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    line-height: 28px;
    text-align: center;
    position: absolute;
    bottom: 2px;
    left: 12px;
}
#supportCaseChatPage .msg-cluster-with-avatar { position: relative; }

/* st295 open-tracking indicator, carried over from the old inline-styled version of this page. */
#supportCaseChatPage .msg-view-indicator {
    display: block;
    margin-top: 5px;
    font-size: 10.5px;
    white-space: nowrap;
}
#supportCaseChatPage .msg-view-indicator-seen   { color: #4caf50; }
#supportCaseChatPage .msg-view-indicator-unseen { color: #b0b3b8; }
#supportCaseChatPage .msg-view-indicator .fi { margin-right: 3px; }

#supportCaseChatPage .support-message-attachment { margin-top: 8px; }
#supportCaseChatPage .support-message-attachment img {
    max-width: 240px;
    max-height: 240px;
    border: 1px solid rgba(0,0,0,0.15);
    padding: 3px;
    border-radius: 4px;
    cursor: zoom-in;
}

/* Compose box — kept as the fuller form (internal-note checkbox + attachment) this page has
   always needed, styled to match the Message Center's light compose footer rather than the
   single-line pill input the Message Center uses for its plain-SMS case. */
#supportCaseChatPage .messaging-thread-compose {
    border-top: 1px solid #e4e6eb;
    padding: 12px 16px;
    background: #f7f7f7;
}
#supportCaseChatPage .support-case-reply-input {
    resize: vertical;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 8px 10px;
    background: #fff;
}
#supportCaseChatPage .support-case-reply-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 10px;
}
#supportCaseChatPage .support-case-reply-checkbox {
    font-weight: normal;
    white-space: nowrap;
}
#supportCaseChatPage .support-case-reply-attach {
    flex: 1;
    min-width: 220px;
}
#supportCaseChatPage .support-case-reply-attach label {
    font-weight: normal;
    color: #888;
    display: block;
    margin-bottom: 4px;
}
#supportCaseChatPage .support-case-reply-attach input[type="file"] {
    border: 1px solid #ccc;
    padding: 6px 8px;
}

/* --- st348 layout 09.16.26 (David): thread + reply box left (col-md-8), case info + customer right (col-md-4) --- */
/* The reply row puts the file input left and Send Reply flush right, bottom-aligned with the input
   (the attach label sits above the input, so flex-end lines the button up with the input box). */
#supportCaseChatPage .support-case-reply-row {
    align-items: flex-end;
    flex-wrap: nowrap;
}
#supportCaseChatPage .support-case-reply-send {
    flex: 0 0 auto;
    margin-left: auto;
    white-space: nowrap;
}
#supportCaseChatPage .support-case-reply-checkbox {
    display: block;
    margin: 8px 0 0;
}
/* Case header card at the top of the right column, above the customer / status box. */
.support-case-info-card {
    background: #fff;
    padding: 14px;
    border: 1px solid #eee;
    border-radius: 4px;
    margin-bottom: 14px;
}
.support-case-info-card .support-case-info-title {
    margin: 0 0 8px;
    font-size: 20px;
    line-height: 1.5;
}
.support-case-info-card .support-case-info-title .badge { display: inline-block; margin-top: 2px; }
.support-case-info-card .support-case-info-subject { margin: 0 0 6px; font-size: 15px; word-break: break-word; }
.support-case-info-card .support-case-info-meta { color: #888; margin: 0; font-size: 13px; }
/* Stacked (below md) the case info sits above the thread; give the thread room below it. */
@media (max-width: 767.98px) {
    #supportCaseChatPage.messaging-thread-card { margin-top: 14px; }
}
