/* ----------------------------------------------------------------------------
 * Clientverse - Self-Hosted CRM
 *
 * @package     Clientverse
 * @author      A.Tselegidis <alextselegidis@gmail.com>
 * @copyright   Copyright (c) Alex Tselegidis
 * @license     https://opensource.org/licenses/GPL-3.0 - GPLv3
 * @link        https://clientverse.org
 * ---------------------------------------------------------------------------- */
/* Smooth transitions on interactive elements only */
a,
.btn,
.nav-link,
.dropdown-item,
.list-group-item-action,
.card,
.page-link,
.form-control,
.form-select,
.input-group-text,
.badge {
    transition: background-color 0.15s ease-in-out,
    border-color 0.15s ease-in-out,
    box-shadow 0.15s ease-in-out,
    color 0.15s ease-in-out,
    opacity 0.15s ease-in-out;
}

/* Design tokens - Bootstrap components all read these */
:root {
    /* Brand. Deep slate blue: confident without the corporate-navy heaviness. */
    --bs-primary: #33507a;
    --bs-primary-rgb: 51, 80, 122;
    --cv-primary-hover: #2a4265;
    --cv-primary-active: #223650;

    --bs-link-color: #33507a;
    --bs-link-color-rgb: 51, 80, 122;
    --bs-link-hover-color: #2a4265;
    --bs-link-hover-color-rgb: 42, 66, 101;

    --bs-body-color: #384252;
    --bs-secondary-color: #667085;

    /* Semantic colours, desaturated from the Bootswatch defaults. The bright teal
       and orange read as consumer-app; these hold up in a business report. */
    --bs-secondary: #667085;
    --bs-secondary-rgb: 102, 112, 133;
    --bs-success: #0e9384;
    --bs-success-rgb: 14, 147, 132;
    --bs-info: #175cd3;
    --bs-info-rgb: 23, 92, 211;
    --bs-warning: #b54708;
    --bs-warning-rgb: 181, 71, 8;
    --bs-danger: #b42318;
    --bs-danger-rgb: 180, 35, 24;

    /* Tinted pill palette: background / border / text for each semantic colour */
    --bs-primary-bg-subtle: #eef2f8;
    --bs-primary-border-subtle: #d3dded;
    --bs-primary-text-emphasis: #2a4265;

    --bs-secondary-bg-subtle: #f1f3f7;
    --bs-secondary-border-subtle: #dfe3eb;
    --bs-secondary-text-emphasis: #4b5565;

    --bs-success-bg-subtle: #e6f6f4;
    --bs-success-border-subtle: #bfe8e2;
    --bs-success-text-emphasis: #0b6f65;

    --bs-info-bg-subtle: #eaf0fd;
    --bs-info-border-subtle: #cbdcfa;
    --bs-info-text-emphasis: #1447a8;

    --bs-warning-bg-subtle: #fdf3e7;
    --bs-warning-border-subtle: #f6dfc0;
    --bs-warning-text-emphasis: #93450a;

    --bs-danger-bg-subtle: #fdecea;
    --bs-danger-border-subtle: #f8d2cf;
    --bs-danger-text-emphasis: #912018;

    /* System font stack: nothing to download, and it matches the host OS */
    --bs-font-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";

    /* Rounder corners */
    --bs-border-radius: 0.625rem;
    --bs-border-radius-sm: 0.4rem;
    --bs-border-radius-lg: 0.875rem;
    --bs-border-radius-xl: 1.25rem;

    /* Cool neutral ramp, replacing the warmer greys */
    --bs-border-color: #e5e8ee;
    --bs-border-color-translucent: rgba(20, 30, 50, 0.09);
    --cv-canvas: #f5f6f9;
    --cv-surface-muted: #f1f3f7;
    --cv-hairline: #e9ecf2;

    /* Softer, layered shadows instead of one hard drop */
    --bs-box-shadow-sm: 0 1px 2px rgba(20, 30, 50, 0.04), 0 1px 3px rgba(20, 30, 50, 0.06);
    --bs-box-shadow: 0 4px 6px -2px rgba(20, 30, 50, 0.05), 0 12px 20px -8px rgba(20, 30, 50, 0.1);
    --bs-box-shadow-lg: 0 12px 16px -6px rgba(20, 30, 50, 0.05), 0 24px 48px -12px rgba(20, 30, 50, 0.14);
}

/* Link colors - darker than labels */
a {
    color: var(--bs-link-color);
}

a:hover {
    color: var(--bs-link-hover-color);
}

/* Labels use a different color */
.form-label {
    color: #495057 !important;
}

.text-dark {
    color: #343a40 !important;
}

.btn-primary {
    --bs-btn-bg: var(--bs-primary);
    --bs-btn-border-color: var(--bs-primary);
    --bs-btn-hover-bg: var(--cv-primary-hover);
    --bs-btn-hover-border-color: var(--cv-primary-hover);
    --bs-btn-active-bg: var(--cv-primary-active);
    --bs-btn-active-border-color: var(--cv-primary-active);
    --bs-btn-disabled-bg: var(--bs-primary);
    --bs-btn-disabled-border-color: var(--bs-primary);
}

.btn-outline-primary {
    --bs-btn-color: var(--bs-primary);
    --bs-btn-border-color: var(--bs-primary);
    --bs-btn-hover-bg: var(--bs-primary);
    --bs-btn-hover-border-color: var(--bs-primary);
    --bs-btn-active-bg: var(--cv-primary-active);
    --bs-btn-active-border-color: var(--cv-primary-active);
}

.bg-primary {
    background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity, 1)) !important;
}

/* Dashboard card image gradient background */
.card .card-img-top {
    background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%) !important;
}

/* Card footer reads as a quiet strip, not a second surface */
.card .card-footer {
    background-color: transparent !important;
    border-top-color: var(--cv-hairline) !important;
}

/* Neutral surfaces */
.bg-light {
    background-color: var(--cv-canvas) !important;
}

.bg-body-secondary {
    background-color: var(--cv-surface-muted) !important;
}

.bg-body-tertiary {
    background-color: #f8f9fb !important;
}

.main-layout {
    background-color: var(--cv-canvas) !important;
}

.text-muted {
    color: #667085 !important;
}

.text-body-secondary {
    color: #667085 !important;
}

/* One secondary column per list table appears at md, so the record name stops
   claiming the whole row there rather than at lg */
@media (min-width: 768px) {
    .w-md-auto {
        width: auto !important;
    }
}

/* Responsive width utilities for lg breakpoint */
@media (min-width: 992px) {
    .w-lg-auto {
        width: auto !important;
    }

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

    .rounded-lg-3 {
        border-radius: var(--bs-border-radius-lg) !important;
    }

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

    .min-vh-lg-auto {
        min-height: auto !important;
    }

    .table-responsive {
        overflow: visible;
    }
}

/* Card hover effect */
.card-hover-move {
    transition: transform 0.2s ease-in-out,
    background-color 0.15s ease-in-out,
    border-color 0.15s ease-in-out,
    box-shadow 0.15s ease-in-out;
}

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

/* Link image styling - stretch for og_image, contain for favicon */
.card .card-img-top.img-cover {
    object-fit: cover;
}

.card .card-img-top.img-contain {
    object-fit: contain;
}

/* Equal width buttons */
.btn-equal-width {
    min-width: 120px;
}

/* Better button styling */
.btn {
    font-weight: 500;
    border-radius: var(--bs-border-radius);
}

/* Clean table design */
.table {
    border-collapse: separate;
    border-spacing: 0;
}

/* Rows are dense on a pointer and roomy on a thumb - see the touch-target block
   near the end of the file for the phone value */
.table > :not(caption) > * > * {
    border-bottom-width: 1px;
    border-bottom-color: var(--cv-hairline);
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

/* A row is exactly one line tall. Cells do not wrap, and the wide text cells - a
   record name or a link - cut off with an ellipsis; the full text is on the detail
   page. `width: 0` on the inner block is what makes it work: a cell whose content
   is nowrap has the whole string as its minimum width, which would push the table
   out of its card, and a percentage `min-width` is ignored while the browser sizes
   the columns - so the cell asks for nothing and then fills the column it gets. */
.table td,
.table th {
    white-space: nowrap;
}

.table td .fw-medium,
.table td a:not(.dropdown-item) {
    display: block;
    width: 0;
    min-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Auto layout hands leftover width to whichever column happens to be widest, which
   is usually a date range that does not need it. These two preferences aim it at the
   two columns that do; they are preferences, so a column still keeps its content
   width when the table is tight. */
.table td:has(> .fw-medium) {
    width: 32%;
}

.table td:has(> a:not(.dropdown-item)) {
    width: 22%;
}

/* Remove last row border */
.table > tbody > tr:last-child > * {
    border-bottom: 0;
}

.table-striped > tbody > tr:nth-of-type(odd) > * {
    background-color: #fafbfc;
}

.table-hover > tbody > tr:hover > * {
    background-color: #eff2f7;
}

/* Table header: quiet, uppercase, no heavy rule underneath */
.table-light-header > thead {
    background-color: var(--cv-surface-muted);
}

.table-light-header > thead > tr > th {
    background-color: var(--cv-surface-muted);
    color: #6b7688;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--cv-hairline);
    transition: background-color 0.15s ease-in-out;
}

/* A checkbox is sized in em, so the 0.75rem header type would leave the select-all
   box smaller than the ones in the rows below it */
.table-light-header > thead > tr > th .form-check-input {
    font-size: 1rem;
}

.table-light-header > thead > tr > th:has(a):hover {
    background-color: #e7eaf1;
}

.table-light-header > thead > tr > th a {
    color: #495057;
}

.table-light-header > thead > tr > th a:hover {
    color: #212529;
}

/* Card with table - zero padding on card-body */
.card-table > .card-body {
    padding: 0;
}

/* Filter/search section above table */
.card-table .table-filters {
    padding: 1rem;
    border-bottom: 1px solid var(--cv-hairline);
}

/* Pagination section below table */
.card-table .table-pagination {
    padding: 1rem;
    border-top: 1px solid var(--cv-hairline);
}

/* Fix pagination styling */
.pagination {
    gap: 0.25rem;
}

.pagination .page-item .page-link {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 2.125rem;
    height: 2.125rem;
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
    font-weight: 500;
    border-radius: var(--bs-border-radius-sm);
    color: #52607a;
    background-color: transparent;
    border-color: transparent;
}

.pagination .page-item .page-link:hover {
    color: var(--bs-primary);
    background-color: var(--cv-surface-muted);
    border-color: transparent;
}

.pagination .page-item.active .page-link {
    color: #fff;
    background-color: var(--bs-primary);
    border-color: var(--bs-primary);
}

.pagination .page-item.disabled .page-link {
    color: #aeb6c4;
    background-color: transparent;
    border-color: transparent;
}

.pagination .page-item .page-link i {
    font-size: 0.75rem;
}

@media (min-width: 992px) {
    .navbar-nav .nav-item .nav-link.nav-menu-item {
        text-align: center;
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100%;
        padding-top: 1rem;
        padding-bottom: 1rem;
        transition: background-color 0.2s ease;
    }

    .navbar-nav .nav-item .nav-link.nav-menu-item:hover {
        background-color: rgba(255, 255, 255, 0.1);
    }

    /* The horizontal navbar appears at lg, but the even 120px item grid plus the
       brand wordmark and the account dropdown only fit from xl. Below that the
       items size to their label - otherwise the whole page scrolls sideways on a
       1024px tablet in landscape. */
    @media (min-width: 1200px) {
        .navbar-nav .nav-item .nav-link.nav-menu-item {
            min-width: 120px;
        }
    }

    /* User names have no length limit: icon-only below xxl (the name stays for
       screen readers), truncated from xxl, so the navbar never outgrows the page. */
    .nav-user-name {
        display: inline-block;
        max-width: 12rem;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        vertical-align: bottom;
    }

    @media (max-width: 1399.98px) {
        .nav-user-name {
            position: absolute;
            width: 1px;
            height: 1px;
            clip: rect(0, 0, 0, 0);
        }
    }

    .navbar {
        padding-top: 0;
        padding-bottom: 0;
    }

    .navbar-brand {
        padding-top: 0.75rem;
        padding-bottom: 0.75rem;
    }
}

/* Table header sorting hover effect */
.table-dark th a {
    display: inline-flex;
    align-items: center;
    padding: 0.25rem 0;
}

.table-dark th {
    vertical-align: middle;
}

.table-dark th a:hover {
    opacity: 0.8;
}

.table-dark th a::after {
    content: '\F282';
    font-family: 'bootstrap-icons';
    margin-left: 0.5rem;
    opacity: 0;
    font-size: 0.75rem;
    transition: opacity 0.15s ease-in-out;
}

.table-dark th a:hover::after {
    opacity: 0.6;
}

/* Borderless icon button, used for the row action and note menus. Transparent
   rather than a white fill so it follows the row tint on hover. */
.btn-icon {
    --bs-btn-color: #5c6779;
    --bs-btn-bg: transparent;
    --bs-btn-border-color: transparent;
    --bs-btn-hover-color: var(--bs-primary);
    --bs-btn-hover-bg: var(--cv-surface-muted);
    --bs-btn-hover-border-color: transparent;
    --bs-btn-active-color: var(--bs-primary);
    --bs-btn-active-bg: #e7eaf1;
    --bs-btn-active-border-color: transparent;
    --bs-btn-focus-shadow-rgb: var(--bs-primary-rgb);
    border-radius: var(--bs-border-radius);
}

/* The toggler reads as a menu icon, not a boxed button. The icon has to be
   repainted white because the bar is dark but the navbar is not in dark mode -
   switching it would also darken the account dropdown inside it. */
.navbar-toggler {
    --bs-navbar-toggler-border-color: transparent;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
}

.navbar-toggler .navbar-toggler-icon {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.9%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

.navbar-toggler:focus {
    box-shadow: none;
}

.navbar-toggler:focus-visible {
    box-shadow: 0 0 0 0.25rem rgba(255, 255, 255, 0.3);
}

/* Pace loading bar in brand colors */
.pace .pace-progress {
    background: var(--bs-primary);
}

/* Flex children must be allowed to shrink, otherwise long text and
   .table-responsive scroll containers push the whole page sideways */
.flex-grow-1 {
    min-width: 0;
}

/* Search input groups: white addon, and a single focus ring around the
   whole group instead of a square one clipping over the addon/button */
.input-group-text.border-end-0 {
    background-color: #fff;
}

.input-group:focus-within {
    border-radius: var(--bs-border-radius);
    box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
}

.input-group:focus-within > .form-control:focus,
.input-group:focus-within > .form-select:focus {
    box-shadow: none;
}

.input-group:focus-within > .form-control,
.input-group:focus-within > .form-select,
.input-group:focus-within > .input-group-text,
.input-group:focus-within > .btn {
    border-color: var(--bs-primary);
}

/* Header search box - roomier, and a light focus ring so it stays visible
   against the dark navbar */
#top-nav .input-group .form-control {
    min-width: 180px;
}

#top-nav .input-group:focus-within {
    box-shadow: 0 0 0 0.25rem rgba(255, 255, 255, 0.3);
}

#top-nav .input-group:focus-within > .form-control,
#top-nav .input-group:focus-within > .input-group-text {
    border-color: #fff;
}

/* Long URLs and email addresses must wrap instead of spilling out of a card */
.card-body a {
    overflow-wrap: break-word;
}

/* --------------------------------------------------------------------------
 * Modern UI pass - surfaces, badges, controls
 * -------------------------------------------------------------------------- */

/* Cards sit on a hairline ring so they read as surfaces, not floating boxes */
.shadow-sm {
    box-shadow: 0 0 0 1px rgba(20, 30, 50, 0.05),
    0 1px 2px rgba(20, 30, 50, 0.04),
    0 2px 6px rgba(20, 30, 50, 0.05) !important;
}

.card-header {
    border-bottom-color: var(--cv-hairline);
    padding-top: 0.875rem;
    padding-bottom: 0.875rem;
    font-weight: 600;
}

/* Badges: quiet tinted pills instead of saturated blocks */
.badge {
    padding: 0.35em 0.7em;
    font-weight: 500;
    font-size: 0.75em;
    border: 1px solid transparent;
    border-radius: var(--bs-border-radius-pill);
}

.badge.bg-primary {
    background-color: var(--bs-primary-bg-subtle) !important;
    border-color: var(--bs-primary-border-subtle);
    color: var(--bs-primary-text-emphasis) !important;
}

.badge.bg-secondary {
    background-color: var(--bs-secondary-bg-subtle) !important;
    border-color: var(--bs-secondary-border-subtle);
    color: var(--bs-secondary-text-emphasis) !important;
}

.badge.bg-success {
    background-color: var(--bs-success-bg-subtle) !important;
    border-color: var(--bs-success-border-subtle);
    color: var(--bs-success-text-emphasis) !important;
}

.badge.bg-info {
    background-color: var(--bs-info-bg-subtle) !important;
    border-color: var(--bs-info-border-subtle);
    color: var(--bs-info-text-emphasis) !important;
}

.badge.bg-warning {
    background-color: var(--bs-warning-bg-subtle) !important;
    border-color: var(--bs-warning-border-subtle);
    color: var(--bs-warning-text-emphasis) !important;
}

.badge.bg-danger {
    background-color: var(--bs-danger-bg-subtle) !important;
    border-color: var(--bs-danger-border-subtle);
    color: var(--bs-danger-text-emphasis) !important;
}

.badge.bg-light {
    background-color: var(--cv-surface-muted) !important;
    border-color: var(--cv-hairline);
    color: #5c6779 !important;
}

/* Form controls */
.form-control,
.form-select {
    border-color: #dde2ea;
}

/* Roomier single-line inputs, but leave textareas alone so `rows` still means rows */
input.form-control,
.form-select {
    padding-top: 0.5rem;
    padding-bottom: 0.5rem;
}

.form-control::placeholder {
    color: #9aa3b2;
}

.form-label {
    font-size: 0.875rem;
    font-weight: 500;
    margin-bottom: 0.375rem;
}

.form-check-input {
    border-color: #cbd2dd;
}

/* Dropdowns and modals */
.dropdown-menu {
    border-color: var(--cv-hairline);
    border-radius: var(--bs-border-radius-lg);
    box-shadow: var(--bs-box-shadow);
    padding: 0.375rem;
}

.dropdown-item {
    border-radius: var(--bs-border-radius-sm);
    padding: 0.4rem 0.625rem;
}

.dropdown-divider {
    border-top-color: var(--cv-hairline);
}

.modal-content {
    border: 0;
    border-radius: var(--bs-border-radius-xl);
    box-shadow: var(--bs-box-shadow-lg);
}

.modal-header,
.modal-footer {
    border-color: var(--cv-hairline);
}

/* List groups used as row lists */
.list-group-flush > .list-group-item {
    border-color: var(--cv-hairline);
}

.list-group-item-action:hover {
    background-color: #f7f9fc;
}

/* Toasts */
.toast {
    border-radius: var(--bs-border-radius-lg);
    box-shadow: var(--bs-box-shadow);
}

/* Breadcrumb reads as a quiet trail, and scrolls rather than clipping when a
   deep trail does not fit on a phone */
.breadcrumb {
    --bs-breadcrumb-divider-color: #b3bbc9;
    font-weight: 500;
    scrollbar-width: none;
}

.breadcrumb::-webkit-scrollbar {
    display: none;
}

/* --------------------------------------------------------------------------
 * Touch targets below the lg breakpoint
 *
 * A 16px checkbox, a 14px sort link and a 31px button are all reliable with a
 * mouse and awkward with a thumb, so everything interactive grows to roughly
 * 40px on phones and tablets.
 * -------------------------------------------------------------------------- */

@media (max-width: 991.98px) {
    .form-check-input {
        width: 1.5rem;
        height: 1.5rem;
        margin-top: 0;
    }

    .form-check {
        min-height: 1.5rem;
        padding-left: 2rem;
    }

    .form-check .form-check-input {
        margin-left: -2rem;
    }

    .form-check-label {
        line-height: 1.5rem;
    }

    .form-switch {
        padding-left: 3.5rem;
    }

    .form-switch .form-check-input {
        width: 3rem;
        margin-left: -3.5rem;
    }

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

    /* Centering is only the default; the alignment utilities still win */
    .btn.text-start {
        justify-content: flex-start;
    }

    .btn.text-end {
        justify-content: flex-end;
    }

    .btn-sm {
        --bs-btn-padding-y: 0.5rem;
        --bs-btn-padding-x: 0.75rem;
        min-height: 2.5rem;
    }

    /* Sorting is triggered by the whole header cell, not just the label text */
    .table-light-header > thead > tr > th a {
        display: block;
        padding: 0.7rem 0;
    }

    .breadcrumb-item a {
        display: inline-block;
        padding: 0.5rem;
        margin: -0.5rem;
    }

    /* Links in dense areas need vertical room to be tappable. Two exclusions:
       dropdown items are sized by the .dropdown-item rule below, and mailto:/tel:
       get the taller target of the next rule - either would otherwise be outweighed
       by this selector and flattened back to 30px. */
    .table td a:not(.dropdown-item):not([href^="mailto:"]):not([href^="tel:"]),
    .card-body p a:not([href^="mailto:"]):not([href^="tel:"]),
    footer a {
        display: inline-block;
        padding-top: 0.2rem;
        padding-bottom: 0.2rem;
    }

    /* The mailto: and tel: links on detail pages matter most - on a phone they are
       the primary action, so they get a full-height target. */
    a[href^="mailto:"],
    a[href^="tel:"] {
        display: inline-block;
        padding-top: 0.5rem;
        padding-bottom: 0.5rem;
    }

    /* Bulk select needs a pointer and a keyboard to be worth anything. On a phone
       the column only steals width from the record name, and with no checkboxes
       the bulk actions toolbar simply never unhides itself. */
    .table th:has(.bulk-select-all),
    .table td:has(.bulk-select-item) {
        display: none;
    }

    /* A file name or URL with no spaces sets the cell's minimum width and pushes
       the card wider than the phone; let it break mid-token instead. Table cells
       do not need this - they truncate rather than wrap at every width. */
    .card-body p a {
        overflow-wrap: anywhere;
    }

    /* A long paginator overflows a phone; let the links wrap instead */
    .pagination {
        flex-wrap: wrap;
        justify-content: center;
    }

    .dropdown-item {
        padding: 0.625rem 0.75rem;
    }

    /* A row is a tap target on a phone, so it keeps the taller padding */
    .table > :not(caption) > * > * {
        padding-top: 0.75rem;
        padding-bottom: 0.75rem;
    }

    /* Stacked checkboxes and switches sit flush; space them so a thumb cannot
       hit the wrong one */
    .form-check + .form-check {
        margin-top: 0.5rem;
    }

    /* A lone form action becomes a full-width, thumb-friendly button */
    .card-footer > .btn:only-child {
        width: 100%;
    }

    .pagination .page-item .page-link {
        min-width: 2.5rem;
        height: 2.5rem;
    }
}
