/*
 * Bootstrap 5.3 in the CRM's look (app.css imports Bootstrap and orders the layers).
 *
 * The tokens layer maps Bootstrap's variables onto the CRM's own tokens, which
 * the theme settings set, and the theme layer restyles Bootstrap's components
 * to the CRM's sizes. Markup uses Bootstrap's classes as documented; this file
 * only makes them look like the rest of the CRM.
 */
@layer tokens {
    :root {
        /* Bootstrap's -rgb triplets of the theme colours: Theme::css() prints them from the settings, these are the defaults' */
        --bs-primary-rgb: 0, 113, 227;
        --bs-body-color-rgb: 29, 29, 31;
        --bs-emphasis-color-rgb: 29, 29, 31;
        --bs-body-bg-rgb: 255, 255, 255;
        --bs-tertiary-bg-rgb: 245, 245, 247;
        --bs-link-color-rgb: 0, 102, 204;
        --bs-link-hover-color-rgb: 0, 102, 204;

        /* the state colours are fixed, not theme settings */
        --bs-success: var(--color-success);
        --bs-success-rgb: 28, 124, 68;
        --bs-success-text-emphasis: var(--color-success);
        --bs-success-bg-subtle: var(--color-success-soft);
        --bs-success-border-subtle: rgba(28, 124, 68, .25);
        --bs-warning: var(--color-warning);
        --bs-warning-rgb: 169, 89, 9;
        --bs-warning-text-emphasis: var(--color-warning);
        --bs-warning-bg-subtle: var(--color-warning-soft);
        --bs-warning-border-subtle: rgba(169, 89, 9, .25);
        --bs-danger: var(--color-danger);
        --bs-danger-rgb: 215, 0, 21;
        --bs-danger-text-emphasis: var(--color-danger);
        --bs-danger-bg-subtle: var(--color-danger-soft);
        --bs-danger-border-subtle: rgba(215, 0, 21, .25);
        --bs-info: var(--color-info);
        --bs-info-rgb: 10, 111, 194;
        --bs-info-text-emphasis: var(--color-info);
        --bs-info-bg-subtle: var(--color-info-soft);
        --bs-info-border-subtle: rgba(10, 111, 194, .25);
    }

    /*
     * Bootstrap's variables from the own tokens. A box that sets the tokens on itself
     * ([data-theme-scope], the preview of the theme settings) repeats the mapping, since
     * a variable that refers to another one resolves where it is declared.
     */
    :root, [data-theme-scope] {
        --bs-primary: var(--color-primary);
        --bs-primary-text-emphasis: var(--color-primary-strong);
        --bs-primary-bg-subtle: var(--color-primary-soft);
        --bs-secondary-text-emphasis: var(--color-text);
        --bs-secondary-bg-subtle: var(--color-neutral-soft);
        --bs-body-font-family: var(--font);
        --bs-body-font-size: var(--text-md);
        --bs-body-line-height: 1.45;
        --bs-body-color: var(--color-text);
        /* Bootstrap paints cards, dialogs and fields with the body colour; the page itself is --color-bg */
        --bs-body-bg: var(--color-card);
        --bs-emphasis-color: var(--color-text);
        --bs-secondary-color: var(--color-muted);
        --bs-secondary-bg: var(--color-bg);
        --bs-tertiary-bg: var(--color-bg);
        --bs-heading-color: inherit;
        --bs-link-color: var(--color-primary-strong);
        --bs-link-hover-color: var(--color-primary-strong);
        --bs-highlight-bg: var(--color-warning-soft);
        --bs-border-color: var(--color-border);
        --bs-border-color-translucent: var(--color-border);
        --bs-border-radius-lg: var(--radius-lg);
        --bs-border-radius: var(--radius-md);
        --bs-border-radius-sm: var(--radius-sm);
        --bs-box-shadow-sm: var(--shadow-sm);
        --bs-box-shadow: var(--shadow-md);
        --bs-box-shadow-lg: var(--shadow-lg);
        --bs-focus-ring-width: 3px;
        --bs-focus-ring-color: var(--color-focus);
        --bs-form-valid-color: var(--color-success);
        --bs-form-valid-border-color: var(--color-success);
        --bs-form-invalid-color: var(--color-danger);
        --bs-form-invalid-border-color: var(--color-danger);
    }
}

/*
 * Bootstrap's components at the CRM's sizes and colours. Where Bootstrap compiled
 * a colour into a rule instead of a variable (#0d6efd in .btn-primary, the focus
 * glow of fields), the rule is restated here with the theme's tokens.
 */
@layer theme {
    /* ---------- Buttons: the CRM's size on every .btn, the colours by variant ---------- */
    .btn {
        --bs-btn-padding-x: 14px;
        --bs-btn-padding-y: 0;
        --bs-btn-font-size: var(--text-md);
        --bs-btn-font-weight: 550;
        --bs-btn-line-height: 1;
        --bs-btn-border-radius: var(--radius-sm);
        --bs-btn-disabled-opacity: .45;
        --bs-btn-focus-box-shadow: 0 0 0 3px var(--color-focus);
        display: inline-flex; align-items: center; justify-content: center; gap: 6px;
        height: var(--control-height);
        white-space: nowrap;
        transition: background-color var(--duration) var(--ease), border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease), transform var(--duration) var(--ease);
    }
    .btn:active { transform: translateY(1px); }
    .btn-sm { --bs-btn-padding-x: 10px; --bs-btn-padding-y: 0; --bs-btn-font-size: var(--text-sm); --bs-btn-border-radius: var(--radius-sm); height: var(--control-height-sm); }
    /* the everyday button: white with a border, a shade darker under the pointer */
    .btn-outline-secondary {
        --bs-btn-color: var(--color-text); --bs-btn-bg: var(--color-card); --bs-btn-border-color: var(--color-border);
        --bs-btn-hover-color: var(--color-text); --bs-btn-hover-bg: var(--color-bg); --bs-btn-hover-border-color: var(--color-border-strong);
        --bs-btn-active-color: var(--color-text); --bs-btn-active-bg: var(--color-bg); --bs-btn-active-border-color: var(--color-border-strong);
        --bs-btn-disabled-color: var(--color-text); --bs-btn-disabled-bg: var(--color-card); --bs-btn-disabled-border-color: var(--color-border);
    }
    .btn-primary {
        --bs-btn-bg: var(--color-primary); --bs-btn-border-color: var(--color-primary);
        --bs-btn-hover-bg: var(--color-primary-strong); --bs-btn-hover-border-color: var(--color-primary-strong);
        --bs-btn-active-bg: var(--color-primary-strong); --bs-btn-active-border-color: var(--color-primary-strong);
        --bs-btn-disabled-bg: var(--color-primary); --bs-btn-disabled-border-color: var(--color-primary);
    }
    .btn-outline-primary {
        --bs-btn-color: var(--color-primary-strong); --bs-btn-bg: var(--color-card); --bs-btn-border-color: var(--color-primary);
        --bs-btn-hover-color: #fff; --bs-btn-hover-bg: var(--color-primary); --bs-btn-hover-border-color: var(--color-primary);
        --bs-btn-active-color: #fff; --bs-btn-active-bg: var(--color-primary-strong); --bs-btn-active-border-color: var(--color-primary-strong);
        --bs-btn-disabled-color: var(--color-primary-strong); --bs-btn-disabled-bg: var(--color-card); --bs-btn-disabled-border-color: var(--color-primary);
    }
    .btn-danger {
        --bs-btn-bg: var(--color-danger); --bs-btn-border-color: var(--color-danger);
        --bs-btn-hover-bg: #b80012; --bs-btn-hover-border-color: #b80012;
        --bs-btn-active-bg: #b80012; --bs-btn-active-border-color: #b80012;
        --bs-btn-disabled-bg: var(--color-danger); --bs-btn-disabled-border-color: var(--color-danger);
    }
    /* a destructive action that is not the main one: red text, the neutral border until hovered */
    .btn-outline-danger {
        --bs-btn-color: var(--color-danger); --bs-btn-bg: var(--color-card); --bs-btn-border-color: var(--color-border);
        --bs-btn-hover-color: var(--color-danger); --bs-btn-hover-bg: var(--color-danger-soft); --bs-btn-hover-border-color: rgba(215, 0, 21, .4);
        --bs-btn-active-color: var(--color-danger); --bs-btn-active-bg: var(--color-danger-soft); --bs-btn-active-border-color: rgba(215, 0, 21, .4);
        --bs-btn-disabled-color: var(--color-danger); --bs-btn-disabled-bg: var(--color-card); --bs-btn-disabled-border-color: var(--color-border);
    }
    /* drawn in the text colour, so it stays visible in a dark theme; a mask on a child keeps the focus ring unclipped */
    .btn-close { --bs-btn-close-opacity: .8; --bs-btn-close-hover-opacity: 1; --bs-btn-close-focus-shadow: 0 0 0 3px var(--color-focus); flex: none; color: var(--color-text); background: none; }
    .btn-close::before {
        content: ""; display: block; width: 1em; height: 1em; background: currentColor;
        -webkit-mask: var(--bs-btn-close-bg) center / 1em auto no-repeat; mask: var(--bs-btn-close-bg) center / 1em auto no-repeat;
    }

    /* ---------- Cards ---------- */
    .card {
        --bs-card-spacer-y: var(--space-5);
        --bs-card-spacer-x: var(--space-5);
        --bs-card-cap-padding-y: var(--space-4);
        --bs-card-cap-padding-x: var(--space-5);
        --bs-card-cap-bg: transparent;
        --bs-card-bg: var(--color-card);
        --bs-card-border-color: var(--color-border);
        --bs-card-border-radius: var(--radius-lg);
        --bs-card-inner-border-radius: calc(var(--radius-lg) - 1px);
        box-shadow: var(--shadow-sm);
    }
    .card-title { font-size: var(--text-lg); font-weight: 650; }
    .card-header .card-title { margin-bottom: 0; }
    .card-footer { padding-block: var(--space-3); background-color: var(--color-bg); }
    /* a table flush with its card keeps the card's rounded corners: its scroll box clips the rows to them */
    .card > .table-responsive:first-child { border-top-left-radius: var(--bs-card-inner-border-radius); border-top-right-radius: var(--bs-card-inner-border-radius); }
    .card > .table-responsive:last-child { border-bottom-left-radius: var(--bs-card-inner-border-radius); border-bottom-right-radius: var(--bs-card-inner-border-radius); }

    /* ---------- Forms ---------- */
    .form-label { margin-bottom: 6px; font-size: var(--text-sm); font-weight: 600; }
    .form-text { margin-top: 6px; font-size: var(--text-xs); }
    .invalid-feedback { margin-top: 6px; font-size: var(--text-xs); }
    .form-control, .form-select {
        min-height: var(--control-height); padding: 8px 12px;
        font-size: var(--text-md); line-height: 1.45; border-radius: var(--radius-sm);
    }
    /* a fixed height, not only a minimum: a date input's own field is taller than text and grew the box past the buttons */
    input.form-control, .form-select:not([multiple]):not([size]) { height: var(--control-height); }
    textarea.form-control { min-height: 96px; }
    /* the full muted colour: lighter, a placeholder falls below 3:1 on the field */
    .form-control::placeholder { color: var(--color-muted); opacity: 1; }
    .form-control:hover, .form-select:hover { border-color: var(--color-border-strong); }
    .form-control:focus, .form-select:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px var(--color-focus); }
    .form-control:disabled, .form-select:disabled, .form-control[readonly] { background-color: var(--color-bg); color: var(--color-muted); }
    .form-select, .form-control[list] {
        --bs-form-select-bg-img: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236e6e73' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
        padding-right: 34px; background-position: right 10px center; background-size: 16px 16px;
    }
    .form-control-sm, .form-select-sm { min-height: var(--control-height-sm); padding: 4px 10px; font-size: var(--text-sm); border-radius: var(--radius-sm); }
    input.form-control-sm, .form-select-sm:not([multiple]):not([size]) { height: var(--control-height-sm); }
    .form-select-sm { padding-right: 34px; }
    /* the red border is the whole mark of an invalid field: no icon inside it */
    .form-control.is-invalid { padding-right: 12px; background-image: none; }
    .form-select.is-invalid { --bs-form-select-bg-icon: none; padding-right: 34px; background-position: right 10px center; }
    /* after .form-control:hover and :focus, whose grey and primary borders would hide the mark of the invalid field */
    .form-control.is-invalid:hover, .form-select.is-invalid:hover { border-color: var(--color-danger); }
    .form-control.is-invalid:focus, .form-select.is-invalid:focus { border-color: var(--color-danger); box-shadow: 0 0 0 3px var(--color-danger-soft); }
    /* Reboot hides the browser's own arrow of a field with suggestions (a datalist), !important in the lowest
       layer: the select's chevron says there is a list; after .is-invalid, so an invalid one keeps it too */
    .form-control[list] { padding-right: 34px; background-image: var(--bs-form-select-bg-img); background-repeat: no-repeat; }
    .form-check { min-height: 0; margin-bottom: 0; padding-left: 26px; }
    .form-check .form-check-input { margin-left: -26px; }
    /* the muted text colour, not a border grey: an empty box needs 3:1 against the card to be seen */
    .form-check-input { width: 18px; height: 18px; margin-top: 1px; border-color: var(--color-muted); }
    .form-check-input:checked, .form-check-input[type="checkbox"]:indeterminate { background-color: var(--color-primary); border-color: var(--color-primary); }
    .form-check-input:focus { border-color: var(--color-primary); box-shadow: 0 0 0 3px var(--color-focus); }
    /* the ring for the keyboard only, as around the other controls: Bootstrap shows it after a click too */
    .form-check-input:focus:not(:focus-visible) { border-color: var(--color-muted); box-shadow: none; }
    .form-check-input:checked:focus:not(:focus-visible), .form-check-input[type="checkbox"]:indeterminate:focus:not(:focus-visible) { border-color: var(--color-primary); }
    /* a switch: a grey track with a white knob, green when on */
    .form-switch { padding-left: 52px; }
    .form-switch .form-check-input {
        --bs-form-switch-bg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3.3' fill='%23fff'/%3E%3C/svg%3E");
        width: 40px; height: 24px; margin-top: -2px; margin-left: -52px; border-color: transparent; background-color: var(--color-border-strong);
    }
    .form-switch .form-check-input:focus { --bs-form-switch-bg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3.3' fill='%23fff'/%3E%3C/svg%3E"); border-color: transparent; }
    .form-switch .form-check-input:checked { background-color: var(--color-success); border-color: transparent; }

    /* ---------- Tables ---------- */
    .table {
        --bs-table-color: var(--color-text);
        --bs-table-bg: var(--color-card);
        --bs-table-border-color: var(--color-border);
        --bs-table-hover-color: var(--color-text);
        --bs-table-hover-bg: var(--color-row-hover);
        --bs-table-active-color: var(--color-text);
        --bs-table-active-bg: var(--color-row-selected);
        margin-bottom: 0; font-size: var(--text-md);
    }
    .table > :not(caption) > * > * { padding: 11px 14px; vertical-align: middle; }
    /* column headers only: a row's header cell in tbody or tfoot sits on the card and reads as data */
    .table > thead th {
        position: sticky; top: 0; z-index: 1;
        padding: 10px 14px; text-align: left; white-space: nowrap;
        font-size: var(--text-xs); font-weight: 650; text-transform: uppercase; letter-spacing: .03em; color: var(--color-muted);
        background: var(--color-header-bg);
    }
    .table > tbody > tr:last-child > * { border-bottom-width: 0; }
    .table-sm > :not(caption) > * > td { padding: 7px 12px; }

    /* ---------- Alerts and badges ---------- */
    .alert { --bs-alert-padding-x: var(--space-4); --bs-alert-padding-y: var(--space-3); --bs-alert-margin-bottom: 0; --bs-alert-border-radius: var(--radius-md); font-size: var(--text-md); }
    .alert .icon { margin-top: 1px; }
    /* the CRM's secondary text size, not Reboot's .875em of whatever holds it */
    .small { font-size: var(--text-sm); }
    /* a soft pill; Bootstrap's own is solid and needs a colour class */
    .badge {
        --bs-badge-padding-x: 9px; --bs-badge-padding-y: 0; --bs-badge-font-size: var(--text-xs); --bs-badge-font-weight: 600;
        --bs-badge-color: var(--color-text); --bs-badge-border-radius: 999px;
        display: inline-flex; align-items: center; gap: 4px; max-width: 100%; height: 22px;
        overflow: hidden; text-overflow: ellipsis; background-color: var(--color-neutral-soft);
    }

    /* ---------- Navigation: pills as a segmented control, breadcrumbs, pages ---------- */
    .nav-link:focus-visible { box-shadow: 0 0 0 3px var(--color-focus); }
    /* the track is the page colour with a border: a darker one leaves the muted inactive tabs below 4.5:1 */
    .nav-pills {
        --bs-nav-link-padding-x: 14px; --bs-nav-link-padding-y: 0; --bs-nav-link-font-weight: 600;
        --bs-nav-link-color: var(--color-muted); --bs-nav-link-hover-color: var(--color-text);
        --bs-nav-pills-border-radius: var(--radius-md); --bs-nav-pills-link-active-color: var(--color-text); --bs-nav-pills-link-active-bg: var(--color-card);
        flex-wrap: nowrap; gap: 2px; max-width: 100%; padding: 3px; overflow-x: auto;
        border-radius: calc(var(--radius-md) + 3px); background: var(--color-bg); box-shadow: inset 0 0 0 1px var(--color-border);
    }
    .nav-pills .nav-link { display: inline-flex; align-items: center; gap: 6px; height: 32px; font-size: var(--text-sm); white-space: nowrap; }
    .nav-pills .nav-link.active { box-shadow: var(--shadow-sm); }
    /* radios drawn as the segmented control: each input.btn-check right before its label.nav-link */
    .nav-pills .btn-check + .nav-link { cursor: pointer; }
    .nav-pills .btn-check:checked + .nav-link { color: var(--bs-nav-pills-link-active-color); background-color: var(--bs-nav-pills-link-active-bg); box-shadow: var(--shadow-sm); }
    .nav-pills .btn-check:focus-visible + .nav-link { box-shadow: 0 0 0 3px var(--color-focus); }
    .breadcrumb {
        --bs-breadcrumb-margin-bottom: 6px; --bs-breadcrumb-font-size: var(--text-sm); --bs-breadcrumb-item-padding-x: 6px;
        --bs-breadcrumb-divider-color: var(--color-muted); --bs-breadcrumb-item-active-color: var(--color-text);
        --bs-breadcrumb-divider: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236e6e73' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E");
        align-items: center; color: var(--color-muted);
    }
    .breadcrumb a { color: var(--color-muted); }
    .pagination {
        --bs-pagination-padding-x: 12px; --bs-pagination-padding-y: 6px; --bs-pagination-font-size: var(--text-sm);
        --bs-pagination-color: var(--color-text); --bs-pagination-bg: var(--color-card); --bs-pagination-border-color: var(--color-border); --bs-pagination-border-radius: var(--radius-sm);
        --bs-pagination-hover-color: var(--color-text); --bs-pagination-hover-bg: var(--color-bg); --bs-pagination-hover-border-color: var(--color-border-strong);
        --bs-pagination-focus-color: var(--color-text); --bs-pagination-focus-bg: var(--color-bg); --bs-pagination-focus-box-shadow: 0 0 0 3px var(--color-focus);
        --bs-pagination-active-bg: var(--color-primary); --bs-pagination-active-border-color: var(--color-primary);
        --bs-pagination-disabled-color: var(--color-muted); --bs-pagination-disabled-bg: var(--color-card); --bs-pagination-disabled-border-color: var(--color-border);
    }

    /* ---------- Feedback: spinners, toasts, the drawer's backdrop ---------- */
    .spinner-border { --bs-spinner-animation-speed: .7s; border-color: rgba(0, 0, 0, .12); border-top-color: currentColor; }
    .spinner-border-sm { --bs-spinner-width: 18px; --bs-spinner-height: 18px; --bs-spinner-border-width: 2px; }
    /* dark and sized to the text up to 420 px; an error adds .text-bg-danger */
    .toast {
        --bs-toast-max-width: 420px; --bs-toast-font-size: var(--text-md); --bs-toast-color: #fff; --bs-toast-bg: #1d1d1f;
        --bs-toast-border-width: 0; --bs-toast-border-radius: var(--radius-md); --bs-toast-box-shadow: var(--shadow-lg);
        width: auto; font-weight: 500;
    }
    .toast-body { padding: 12px 16px; }
    .offcanvas-backdrop { --bs-backdrop-opacity: .28; }
}
