/**
 * Vesper · Bootstrap 5.3 bridge (template.vesper.bs, depends on core `bootstrap.css`).
 *
 * Studio community kit file (template-studio/kit/community): edit the kit, then run
 * sync-kit.mjs for every template. Byte-portable between Vesper, Quorum and Mimeo: it reads
 * only L0 (--ec-*), L2 (--ts-*) and the optional K knobs of tokens.css (see the kit's
 * tokens-template.css); every knob is read as var(--knob, default).
 *
 * Loaded by index.php/component.php only when no Tailwind SPA is mounted (PageContext), right
 * after bootstrap.min.css and before every template stylesheet. It is the ONLY template file
 * allowed to name Bootstrap classes (contract §2.4 rule 4).
 *
 *   §A  root map: every theme-relevant --bs-* root variable -> template tokens, both schemes
 *   §B  hard-coded blue accent and focus fixes (bootstrap.css 5.3.8 compiles them as constants)
 *   §C  secondary variants (.btn-*, .btn-outline-*, .text-bg-*, .link-*, .table-*, .badge) on status tokens
 *   §D  component variables and box model (sizes, radii, surfaces), driven by the K knobs
 *   §E  Joomla core compositions of Bootstrap classes (subform toolbar, list filters)
 */

/* ==========================================================================
   §A Root map. Same specificity as Bootstrap's own `:root, [data-bs-theme]` blocks and printed
   later, so these win on <html> and on any nested [data-bs-theme] island (tokens.css flips the
   template palette on such islands too).
   ========================================================================== */

:root,
[data-bs-theme] {
    /* Theme colours and their rgb twins (utilities read rgba(var(--bs-*-rgb), a)) */
    --bs-primary: var(--ec-accent);
    --bs-secondary: var(--ec-fg-2);
    --bs-success: var(--ts-success);
    --bs-info: var(--ts-info);
    --bs-warning: var(--ts-warning);
    --bs-danger: var(--ts-danger);
    --bs-light: var(--ec-surface-2);
    --bs-dark: var(--ec-fg);
    --bs-primary-rgb: var(--ts-accent-rgb);
    --bs-secondary-rgb: var(--ts-fg-2-rgb);
    --bs-success-rgb: var(--ts-success-rgb);
    --bs-info-rgb: var(--ts-info-rgb);
    --bs-warning-rgb: var(--ts-warning-rgb);
    --bs-danger-rgb: var(--ts-danger-rgb);
    --bs-light-rgb: var(--ts-surface-2-rgb);
    --bs-dark-rgb: var(--ts-fg-rgb);

    /* Emphasis / subtle sets (.alert-*, .list-group-item-*, .text-*-emphasis, .bg-*-subtle) */
    --bs-primary-text-emphasis: var(--ts-on-tint);
    --bs-primary-bg-subtle: var(--ts-tint);
    --bs-primary-border-subtle: color-mix(in srgb, var(--ts-signal) 45%, transparent);
    --bs-secondary-text-emphasis: var(--ec-fg);
    --bs-secondary-bg-subtle: var(--ec-surface-2);
    --bs-secondary-border-subtle: var(--ec-border);
    --bs-success-text-emphasis: var(--ts-success);
    --bs-success-bg-subtle: var(--ts-success-bg);
    --bs-success-border-subtle: color-mix(in srgb, var(--ts-success) 45%, transparent);
    --bs-info-text-emphasis: var(--ts-info);
    --bs-info-bg-subtle: var(--ts-info-bg);
    --bs-info-border-subtle: color-mix(in srgb, var(--ts-info) 45%, transparent);
    --bs-warning-text-emphasis: var(--ts-warning);
    --bs-warning-bg-subtle: var(--ts-warning-bg);
    --bs-warning-border-subtle: color-mix(in srgb, var(--ts-warning) 45%, transparent);
    --bs-danger-text-emphasis: var(--ts-danger);
    --bs-danger-bg-subtle: var(--ts-danger-bg);
    --bs-danger-border-subtle: color-mix(in srgb, var(--ts-danger) 45%, transparent);
    --bs-light-text-emphasis: var(--ec-fg);
    --bs-light-bg-subtle: var(--ec-surface);
    --bs-light-border-subtle: var(--ec-border);
    --bs-dark-text-emphasis: var(--ec-fg);
    --bs-dark-bg-subtle: var(--ec-surface-2);
    --bs-dark-border-subtle: var(--ts-control);

    /* Body, type and text roles */
    --bs-font-sans-serif: var(--ec-font-body);
    --bs-font-monospace: var(--ts-font-mono);
    --bs-body-font-family: var(--ec-font-body);
    --bs-body-font-size: 1rem;
    --bs-body-color: var(--ec-fg);
    --bs-body-color-rgb: var(--ts-fg-rgb);
    --bs-body-bg: var(--ec-bg);
    --bs-body-bg-rgb: var(--ts-bg-rgb);
    --bs-emphasis-color: var(--ec-fg);
    --bs-emphasis-color-rgb: var(--ts-fg-rgb);
    --bs-secondary-color: var(--ec-fg-2);
    --bs-secondary-color-rgb: var(--ts-fg-2-rgb);
    --bs-secondary-bg: var(--ec-surface-2);
    --bs-secondary-bg-rgb: var(--ts-surface-2-rgb);
    --bs-tertiary-color: var(--ec-fg-2);
    --bs-tertiary-color-rgb: var(--ts-fg-2-rgb);
    --bs-tertiary-bg: var(--ec-surface);
    --bs-tertiary-bg-rgb: var(--ts-surface-rgb);
    --bs-heading-color: inherit;
    --bs-link-color: var(--ts-link);
    --bs-link-color-rgb: var(--ts-link-rgb);
    --bs-link-hover-color: var(--ts-link-hover);
    --bs-link-hover-color-rgb: var(--ts-link-hover-rgb);
    --bs-code-color: var(--ec-fg);
    --bs-highlight-color: var(--ec-fg);
    --bs-highlight-bg: var(--ts-warning-bg);

    /* Borders, radii, shadows */
    --bs-border-color: var(--ec-border);
    --bs-border-color-translucent: var(--ec-border);
    --bs-border-radius: var(--ts-control-radius, var(--ec-btn-radius));
    --bs-border-radius-sm: calc(var(--ts-control-radius, var(--ec-btn-radius)) * 0.75);
    --bs-border-radius-lg: var(--ec-radius);
    --bs-border-radius-xl: var(--ec-radius);
    --bs-border-radius-xxl: var(--ec-radius);
    --bs-border-radius-pill: 50rem;
    --bs-box-shadow: var(--ts-overlay-shadow);
    --bs-box-shadow-sm: var(--ec-shadow);
    --bs-box-shadow-lg: var(--ts-overlay-shadow);
    --bs-box-shadow-inset: none;

    /* Focus and validation */
    --bs-focus-ring-width: var(--ts-focus-width, 2px);
    --bs-focus-ring-opacity: 1;
    --bs-focus-ring-color: var(--ts-focus);
    --bs-form-valid-color: var(--ts-success);
    --bs-form-valid-border-color: var(--ts-success);
    --bs-form-invalid-color: var(--ts-danger);
    --bs-form-invalid-border-color: var(--ts-danger);

    /* Check, radio, indeterminate and switch marks: Bootstrap draws them as SVG backgrounds, which
       cannot read a custom property, so each comes as a paper (light) and an ink (dark) variant.
       tokens.css picks one per scheme with the --ts-check-mark / --ts-radio-mark / --ts-dash-mark /
       --ts-switch-mark knobs; the off-state switch knob follows the scheme below. */
    --ts-mark-paper-check: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
    --ts-mark-ink-check: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23111' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e");
    --ts-mark-paper-dot: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e");
    --ts-mark-ink-dot: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23111'/%3e%3c/svg%3e");
    --ts-mark-paper-dash: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e");
    --ts-mark-ink-dash: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23111' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e");
    --ts-mark-paper-knob: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
    --ts-mark-ink-knob: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23111'/%3e%3c/svg%3e");
    --ts-switch-off-mark: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23000' fill-opacity='.58'/%3e%3c/svg%3e");
}

[data-bs-theme="dark"] {
    --ts-switch-off-mark: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff' fill-opacity='.62'/%3e%3c/svg%3e");
}

/* ==========================================================================
   §B Hard-coded accent and focus. One focus language for every Bootstrap control:
   outline in --ts-focus, 2px outside, with an inner band in --ts-focus-gap (transparent unless
   the design uses a two-colour ring). Items flush inside a container get the ring inset.
   ========================================================================== */

.btn-primary {
    --bs-btn-color: var(--ts-btn-primary-fg, var(--ec-accent-fg));
    --bs-btn-bg: var(--ts-btn-primary-bg, var(--ec-accent));
    --bs-btn-border-color: var(--ts-btn-primary-border, var(--ts-btn-primary-bg, var(--ec-accent)));
    --bs-btn-hover-color: var(--ts-btn-primary-hover-fg, var(--ts-btn-primary-fg, var(--ec-accent-fg)));
    --bs-btn-hover-bg: var(--ts-btn-primary-hover-bg, color-mix(in srgb, var(--ec-accent) 85%, var(--ec-fg)));
    --bs-btn-hover-border-color: var(--bs-btn-hover-bg);
    --bs-btn-active-color: var(--bs-btn-hover-color);
    --bs-btn-active-bg: var(--bs-btn-hover-bg);
    --bs-btn-active-border-color: var(--bs-btn-hover-bg);
    --bs-btn-focus-shadow-rgb: var(--ts-accent-rgb);
    box-shadow: var(--ts-btn-primary-shadow, none);
}

.btn-outline-primary {
    --bs-btn-color: var(--ts-link);
    --bs-btn-border-color: var(--ts-link);
    --bs-btn-hover-color: var(--ts-btn-primary-fg, var(--ec-accent-fg));
    --bs-btn-hover-bg: var(--ts-btn-primary-bg, var(--ec-accent));
    --bs-btn-hover-border-color: var(--ts-btn-primary-bg, var(--ec-accent));
    --bs-btn-active-color: var(--bs-btn-hover-color);
    --bs-btn-active-bg: var(--bs-btn-hover-bg);
    --bs-btn-active-border-color: var(--bs-btn-hover-border-color);
    --bs-btn-disabled-color: var(--ec-fg-2);
    --bs-btn-disabled-border-color: var(--ec-border);
    --bs-btn-focus-shadow-rgb: var(--ts-accent-rgb);
}

.btn {
    --bs-btn-focus-box-shadow: 0 0 0 2px var(--ts-focus-gap);
}

.dropdown-menu {
    --bs-dropdown-link-active-color: var(--ts-on-tint);
    --bs-dropdown-link-active-bg: var(--ts-tint);
}

.nav-pills {
    --bs-nav-pills-link-active-color: var(--ec-accent-fg);
    --bs-nav-pills-link-active-bg: var(--ec-accent);
}

.pagination {
    --bs-pagination-active-color: var(--ts-page-current-fg, var(--ec-accent-fg));
    --bs-pagination-active-bg: var(--ts-page-current-bg, var(--ec-accent));
    --bs-pagination-active-border-color: var(--ts-page-current-bg, var(--ec-accent));
    --bs-pagination-focus-box-shadow: 0 0 0 2px var(--ts-focus-gap);
}

.list-group {
    --bs-list-group-active-color: var(--ec-accent-fg);
    --bs-list-group-active-bg: var(--ec-accent);
    --bs-list-group-active-border-color: var(--ec-accent);
}

/* The bar is an accent fill carrying accent-fg labels (a text-safe pair); its 1px edge in
   --ts-signal keeps the filled extent >= 3:1 against the track where the accent itself is a
   light fill (it vanishes where signal equals the accent). Status-coloured bars drop the edge. */
.progress,
.progress-stacked {
    --bs-progress-bg: var(--ec-surface-2);
    --bs-progress-bar-color: var(--ec-accent-fg);
    --bs-progress-bar-bg: var(--ec-accent);
}

.progress-bar {
    box-shadow: inset 0 0 0 1px var(--ts-signal);
}

.progress-bar:is(.bg-secondary, .bg-success, .bg-danger, .bg-warning, .bg-info, .bg-light, .bg-dark,
    .text-bg-secondary, .text-bg-success, .text-bg-danger, .text-bg-warning, .text-bg-info,
    .text-bg-light, .text-bg-dark) {
    box-shadow: none;
}

/* Primary as TEXT. The accent is a fill colour and is not text-safe on every design's page
   (Vesper light: amber on paper), so primary text and .link-primary use the link pair, which is;
   Bootstrap's .link-primary hover is a compiled blue constant. */
.text-primary {
    color: rgba(var(--ts-link-rgb), var(--bs-text-opacity, 1)) !important;
}

.link-primary {
    color: rgba(var(--ts-link-rgb), var(--bs-link-opacity, 1)) !important;
    text-decoration-color: rgba(var(--ts-link-rgb), var(--bs-link-underline-opacity, 1)) !important;
}

.link-primary:hover,
.link-primary:focus {
    color: rgba(var(--ts-link-hover-rgb), var(--bs-link-opacity, 1)) !important;
    text-decoration-color: rgba(var(--ts-link-hover-rgb), var(--bs-link-underline-opacity, 1)) !important;
}

.accordion {
    --bs-accordion-btn-focus-box-shadow: inset 0 0 0 2px var(--ts-focus-gap);
}

/* Chevrons drawn in currentColor: the SVG only supplies the shape (mask), so the icon follows the
   text colour in both schemes and on the active tint. */
.accordion-button::after {
    background-image: none;
    background-color: currentColor;
    -webkit-mask: var(--bs-accordion-btn-icon) center / var(--bs-accordion-btn-icon-width) no-repeat;
    mask: var(--bs-accordion-btn-icon) center / var(--bs-accordion-btn-icon-width) no-repeat;
}

.accordion-button:not(.collapsed)::after {
    background-image: none;
    -webkit-mask-image: var(--bs-accordion-btn-active-icon);
    mask-image: var(--bs-accordion-btn-active-icon);
}

.btn-close {
    --bs-btn-close-opacity: 0.7;
    --bs-btn-close-hover-opacity: 1;
    --bs-btn-close-focus-shadow: 0 0 0 2px var(--ts-focus-gap);
}

.form-control:focus,
.form-select:focus {
    border-color: var(--ts-control-focus-border, var(--ts-focus));
    box-shadow: 0 0 0 2px var(--ts-focus-gap);
}

.form-check-input:focus {
    border-color: var(--ts-control);
    box-shadow: none;
}

.form-check-input:checked,
.form-check-input[type="checkbox"]:indeterminate {
    background-color: var(--ts-check-bg, var(--ec-accent));
    border-color: var(--ts-check-bg, var(--ec-accent));
}

.form-check-input:checked[type="checkbox"] {
    --bs-form-check-bg-image: var(--ts-check-mark, var(--ts-mark-paper-check));
}

.form-check-input:checked[type="radio"] {
    --bs-form-check-bg-image: var(--ts-radio-mark, var(--ts-mark-paper-dot));
}

.form-check-input[type="checkbox"]:indeterminate {
    --bs-form-check-bg-image: var(--ts-dash-mark, var(--ts-mark-paper-dash));
}

/* (0,5,0): beats Bootstrap's [data-bs-theme=dark] .form-switch … :not(:checked):not(:focus) */
[data-bs-theme] .form-switch .form-check-input:not(:checked):not(:focus),
[data-bs-theme] .form-switch .form-check-input:not(:checked):focus {
    --bs-form-switch-bg: var(--ts-switch-off-mark);
}

.form-switch .form-check-input:checked {
    --bs-form-switch-bg: var(--ts-switch-mark, var(--ts-mark-paper-knob));
}

.form-range::-webkit-slider-thumb {
    background-color: var(--ts-check-bg, var(--ec-accent));
    border: 2px solid var(--ts-control-bg, var(--ec-surface));
    box-shadow: 0 0 0 1px var(--ts-control);
}

.form-range::-moz-range-thumb {
    background-color: var(--ts-check-bg, var(--ec-accent));
    border: 2px solid var(--ts-control-bg, var(--ec-surface));
    box-shadow: 0 0 0 1px var(--ts-control);
}

.form-range::-webkit-slider-thumb:active,
.form-range::-moz-range-thumb:active {
    background-color: var(--ts-signal);
}

.form-range:focus::-webkit-slider-thumb {
    box-shadow: 0 0 0 2px var(--ec-bg), 0 0 0 calc(2px + var(--ts-focus-width, 2px)) var(--ts-focus);
}

.form-range:focus::-moz-range-thumb {
    box-shadow: 0 0 0 2px var(--ec-bg), 0 0 0 calc(2px + var(--ts-focus-width, 2px)) var(--ts-focus);
}

.nav-link:focus-visible {
    box-shadow: 0 0 0 2px var(--ts-focus-gap);
}

/* The ring itself (outline), outside the control */
.btn:focus-visible,
.btn-check:focus-visible + .btn,
.btn-close:focus-visible,
.nav-link:focus-visible,
.page-link:focus-visible,
.navbar-toggler:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
.form-check-input:focus-visible {
    outline: var(--ts-focus-width, 2px) solid var(--ts-focus);
    outline-offset: 2px;
}

.form-check-input:focus-visible {
    box-shadow: 0 0 0 2px var(--ts-focus-gap);
}

/* … and inset, where the item is flush with its container */
.dropdown-item:focus-visible,
.list-group-item-action:focus-visible,
.accordion-button:focus-visible,
.nav-tabs .nav-link:focus-visible {
    outline: var(--ts-focus-width, 2px) solid var(--ts-focus);
    outline-offset: calc(-2px - var(--ts-focus-width, 2px));
    box-shadow: inset 0 0 0 2px var(--ts-focus-gap);
}

.form-range:focus-visible {
    outline: 0;
}

/* ==========================================================================
   §C Secondary variants on the status tokens (Bootstrap compiles them as light-only
   constants). Status fills carry --ec-bg text: every status colour is verified >= 4.5:1 against
   --ec-bg in both schemes, and contrast is symmetric.
   ========================================================================== */

.btn-secondary,
.btn-outline-secondary {
    --bs-btn-color: var(--ts-btn-secondary-fg, var(--ec-fg));
    --bs-btn-bg: var(--ts-btn-secondary-bg, transparent);
    --bs-btn-border-color: var(--ts-btn-secondary-border, var(--ts-control));
    --bs-btn-hover-color: var(--ts-btn-secondary-hover-fg, var(--ec-fg));
    --bs-btn-hover-bg: var(--ts-btn-secondary-hover-bg, var(--ec-surface-2));
    --bs-btn-hover-border-color: var(--ts-btn-secondary-hover-border, var(--ec-fg));
    --bs-btn-active-color: var(--bs-btn-hover-color);
    --bs-btn-active-bg: var(--bs-btn-hover-bg);
    --bs-btn-active-border-color: var(--bs-btn-hover-border-color);
    --bs-btn-focus-shadow-rgb: var(--ts-fg-rgb);
}

.btn-success,
.btn-info,
.btn-warning,
.btn-danger {
    --bs-btn-color: var(--ts-btn-status);
    --bs-btn-bg: var(--ts-btn-status-bg);
    --bs-btn-border-color: var(--ts-btn-status);
    --bs-btn-hover-color: var(--ec-bg);
    --bs-btn-hover-bg: var(--ts-btn-status);
    --bs-btn-hover-border-color: var(--ts-btn-status);
    --bs-btn-active-color: var(--ec-bg);
    --bs-btn-active-bg: var(--ts-btn-status);
    --bs-btn-active-border-color: var(--ts-btn-status);
}

.btn-outline-success,
.btn-outline-info,
.btn-outline-warning,
.btn-outline-danger {
    --bs-btn-color: var(--ts-btn-status);
    --bs-btn-border-color: var(--ts-btn-status);
    --bs-btn-hover-color: var(--ec-bg);
    --bs-btn-hover-bg: var(--ts-btn-status);
    --bs-btn-hover-border-color: var(--ts-btn-status);
    --bs-btn-active-color: var(--ec-bg);
    --bs-btn-active-bg: var(--ts-btn-status);
    --bs-btn-active-border-color: var(--ts-btn-status);
    --bs-btn-disabled-color: var(--ec-fg-2);
    --bs-btn-disabled-border-color: var(--ec-border);
}

.btn-success,
.btn-outline-success {
    --ts-btn-status: var(--ts-success);
    --ts-btn-status-bg: var(--ts-success-bg);
    --bs-btn-focus-shadow-rgb: var(--ts-success-rgb);
}

.btn-info,
.btn-outline-info {
    --ts-btn-status: var(--ts-info);
    --ts-btn-status-bg: var(--ts-info-bg);
    --bs-btn-focus-shadow-rgb: var(--ts-info-rgb);
}

.btn-warning,
.btn-outline-warning {
    --ts-btn-status: var(--ts-warning);
    --ts-btn-status-bg: var(--ts-warning-bg);
    --bs-btn-focus-shadow-rgb: var(--ts-warning-rgb);
}

.btn-danger,
.btn-outline-danger {
    --ts-btn-status: var(--ts-danger);
    --ts-btn-status-bg: var(--ts-danger-bg);
    --bs-btn-focus-shadow-rgb: var(--ts-danger-rgb);
}

.btn-light,
.btn-outline-light {
    --bs-btn-color: var(--ec-fg);
    --bs-btn-bg: var(--ec-surface-2);
    --bs-btn-border-color: var(--ec-surface-2);
    --bs-btn-hover-color: var(--ec-fg);
    --bs-btn-hover-bg: var(--ec-border);
    --bs-btn-hover-border-color: var(--ec-border);
    --bs-btn-active-color: var(--ec-fg);
    --bs-btn-active-bg: var(--ec-border);
    --bs-btn-active-border-color: var(--ts-control);
    --bs-btn-focus-shadow-rgb: var(--ts-fg-rgb);
}

.btn-outline-light {
    --bs-btn-bg: transparent;
    --bs-btn-border-color: var(--ts-control);
}

.btn-dark,
.btn-outline-dark {
    --bs-btn-color: var(--ec-bg);
    --bs-btn-bg: var(--ec-fg);
    --bs-btn-border-color: var(--ec-fg);
    --bs-btn-hover-color: var(--ec-bg);
    --bs-btn-hover-bg: var(--ec-fg-2);
    --bs-btn-hover-border-color: var(--ec-fg-2);
    --bs-btn-active-color: var(--ec-bg);
    --bs-btn-active-bg: var(--ec-fg-2);
    --bs-btn-active-border-color: var(--ec-fg-2);
    --bs-btn-focus-shadow-rgb: var(--ts-fg-rgb);
}

.btn-outline-dark {
    --bs-btn-color: var(--ec-fg);
    --bs-btn-bg: transparent;
    --bs-btn-hover-bg: var(--ec-fg);
    --bs-btn-hover-border-color: var(--ec-fg);
}

.btn-link {
    --bs-btn-color: var(--ts-link);
    --bs-btn-hover-color: var(--ts-link-hover);
    --bs-btn-active-color: var(--ts-link-hover);
    --bs-btn-disabled-color: var(--ec-fg-2);
    --bs-btn-focus-shadow-rgb: var(--ts-link-rgb);
}

/* Disabled: no opacity (it drops contrast unpredictably); neutral, unprinted look instead */
.btn:disabled,
.btn.disabled,
fieldset:disabled .btn {
    --bs-btn-disabled-opacity: 1;
    --bs-btn-disabled-color: var(--ec-fg-2);
    --bs-btn-disabled-bg: var(--ec-surface-2);
    --bs-btn-disabled-border-color: var(--ec-border);
    box-shadow: none;
}

.btn-link:disabled,
.btn-link.disabled {
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: transparent;
}

.text-bg-primary {
    color: var(--ec-accent-fg) !important;
}

.text-bg-secondary,
.text-bg-success,
.text-bg-info,
.text-bg-warning,
.text-bg-danger,
.text-bg-dark {
    color: var(--ec-bg) !important;
}

.text-bg-light {
    color: var(--ec-fg) !important;
}

/* Legacy pairing `.bg-{colour}.text-white`: the theme fills follow the scheme (dark is the ink,
   which is light in the dark scheme), so literal white text on them takes the .text-bg-* pair. */
.text-white.bg-primary {
    color: var(--ec-accent-fg) !important;
}

.text-white:is(.bg-secondary, .bg-success, .bg-danger, .bg-warning, .bg-info, .bg-dark) {
    color: var(--ec-bg) !important;
}

/* .link-* hover colours are compiled light-scheme constants: hover keeps the variant's own
   colour (the underline is the hover cue) and secondary strengthens to the ink. */
.link-secondary:hover,
.link-secondary:focus {
    color: rgba(var(--ts-fg-rgb), var(--bs-link-opacity, 1)) !important;
    text-decoration-color: rgba(var(--ts-fg-rgb), var(--bs-link-underline-opacity, 1)) !important;
}

.link-success:hover,
.link-success:focus {
    color: rgba(var(--ts-success-rgb), var(--bs-link-opacity, 1)) !important;
    text-decoration-color: rgba(var(--ts-success-rgb), var(--bs-link-underline-opacity, 1)) !important;
}

.link-info:hover,
.link-info:focus {
    color: rgba(var(--ts-info-rgb), var(--bs-link-opacity, 1)) !important;
    text-decoration-color: rgba(var(--ts-info-rgb), var(--bs-link-underline-opacity, 1)) !important;
}

.link-warning:hover,
.link-warning:focus {
    color: rgba(var(--ts-warning-rgb), var(--bs-link-opacity, 1)) !important;
    text-decoration-color: rgba(var(--ts-warning-rgb), var(--bs-link-underline-opacity, 1)) !important;
}

.link-danger:hover,
.link-danger:focus {
    color: rgba(var(--ts-danger-rgb), var(--bs-link-opacity, 1)) !important;
    text-decoration-color: rgba(var(--ts-danger-rgb), var(--bs-link-underline-opacity, 1)) !important;
}

.link-light:hover,
.link-light:focus {
    color: rgba(var(--ts-surface-2-rgb), var(--bs-link-opacity, 1)) !important;
    text-decoration-color: rgba(var(--ts-surface-2-rgb), var(--bs-link-underline-opacity, 1)) !important;
}

.link-dark:hover,
.link-dark:focus {
    color: rgba(var(--ts-fg-rgb), var(--bs-link-opacity, 1)) !important;
    text-decoration-color: rgba(var(--ts-fg-rgb), var(--bs-link-underline-opacity, 1)) !important;
}

.text-white-50 {
    color: rgba(var(--ts-bg-rgb), 0.7) !important;
}

.text-black-50 {
    color: var(--ec-fg-2) !important;
}

.badge {
    --bs-badge-color: var(--ec-bg);
    --bs-badge-font-weight: 700;
    --bs-badge-padding-x: 0.5em;
    --bs-badge-padding-y: 0.3em;
    --bs-badge-border-radius: var(--ts-badge-radius, min(var(--ec-btn-radius), 0.375rem));
}

.badge:is(.bg-primary, .text-bg-primary) {
    --bs-badge-color: var(--ec-accent-fg);
}

.badge:is(.bg-light, .bg-body, .bg-body-secondary, .bg-body-tertiary, .bg-white, .bg-transparent) {
    --bs-badge-color: var(--ec-fg);
}

.table {
    --bs-table-color: var(--ec-fg);
    --bs-table-bg: transparent;
    --bs-table-border-color: var(--ec-border);
    --bs-table-striped-color: var(--ec-fg);
    --bs-table-striped-bg: rgba(var(--ts-fg-rgb), 0.045);
    --bs-table-active-color: var(--ec-fg);
    --bs-table-active-bg: rgba(var(--ts-fg-rgb), 0.09);
    --bs-table-hover-color: var(--ec-fg);
    --bs-table-hover-bg: rgba(var(--ts-fg-rgb), 0.065);
}

.table-primary,
.table-secondary,
.table-success,
.table-info,
.table-warning,
.table-danger,
.table-light {
    --bs-table-color: var(--ec-fg);
    --bs-table-border-color: var(--ec-border);
    --bs-table-striped-color: var(--ec-fg);
    --bs-table-striped-bg: rgba(var(--ts-fg-rgb), 0.05);
    --bs-table-active-color: var(--ec-fg);
    --bs-table-active-bg: rgba(var(--ts-fg-rgb), 0.1);
    --bs-table-hover-color: var(--ec-fg);
    --bs-table-hover-bg: rgba(var(--ts-fg-rgb), 0.075);
}

.table-primary {
    --bs-table-color: var(--ts-on-tint);
    --bs-table-bg: var(--ts-tint);
}

.table-secondary,
.table-light {
    --bs-table-bg: var(--ec-surface-2);
}

.table-success {
    --bs-table-bg: var(--ts-success-bg);
}

.table-info {
    --bs-table-bg: var(--ts-info-bg);
}

.table-warning {
    --bs-table-bg: var(--ts-warning-bg);
}

.table-danger {
    --bs-table-bg: var(--ts-danger-bg);
}

/* "Dark" is an inverse table in the light scheme (WebAuthn key list, some extension tables) and a
   raised surface in the dark scheme, where a light inverse block would glare */
.table-dark {
    --bs-table-color: var(--ec-bg);
    --bs-table-bg: var(--ec-fg);
    --bs-table-border-color: var(--ec-fg-2);
    --bs-table-striped-color: var(--ec-bg);
    --bs-table-striped-bg: rgba(var(--ts-bg-rgb), 0.08);
    --bs-table-active-color: var(--ec-bg);
    --bs-table-active-bg: rgba(var(--ts-bg-rgb), 0.16);
    --bs-table-hover-color: var(--ec-bg);
    --bs-table-hover-bg: rgba(var(--ts-bg-rgb), 0.12);
}

[data-bs-theme="dark"] .table-dark {
    --bs-table-color: var(--ec-fg);
    --bs-table-bg: var(--ec-surface-2);
    --bs-table-border-color: var(--ts-control);
    --bs-table-striped-color: var(--ec-fg);
    --bs-table-striped-bg: rgba(var(--ts-fg-rgb), 0.05);
    --bs-table-active-color: var(--ec-fg);
    --bs-table-active-bg: rgba(var(--ts-fg-rgb), 0.1);
    --bs-table-hover-color: var(--ec-fg);
    --bs-table-hover-bg: rgba(var(--ts-fg-rgb), 0.075);
}

.alert {
    --bs-alert-color: var(--ec-fg);
    --bs-alert-link-color: var(--ts-link);
}

.alert-primary {
    --bs-alert-color: var(--ts-on-tint);
    --bs-alert-link-color: var(--ts-on-tint);
    border-inline-start-color: var(--ts-signal);
}

.alert-success {
    border-inline-start-color: var(--ts-success);
}

.alert-info {
    border-inline-start-color: var(--ts-info);
}

.alert-warning {
    border-inline-start-color: var(--ts-warning);
}

.alert-danger {
    border-inline-start-color: var(--ts-danger);
}

.alert-secondary,
.alert-light,
.alert-dark {
    border-inline-start-color: var(--ts-control);
}

.list-group-item-primary {
    --bs-list-group-action-hover-bg: var(--ts-tint);
    --bs-list-group-action-active-bg: var(--ts-tint);
}

.blockquote-footer,
.form-floating > :disabled ~ label,
.form-floating > .form-control:disabled ~ label {
    color: var(--ec-fg-2);
}

.valid-tooltip,
.invalid-tooltip {
    color: var(--ec-bg);
}

.offcanvas-backdrop {
    background-color: var(--ts-scrim);
}

.offcanvas-backdrop.show {
    opacity: 1;
}

/* ==========================================================================
   §D Component variables and box model. Sizes follow the K knobs so every control is at least
   the design's target height; surfaces follow the card/overlay knobs.
   ========================================================================== */

.btn {
    --bs-btn-font-family: var(--ts-btn-font, var(--ec-font-body));
    --bs-btn-font-weight: var(--ts-btn-weight, 600);
    --bs-btn-border-width: var(--ts-btn-border-width, var(--ts-control-border-width, 1px));
    --bs-btn-border-radius: var(--ts-control-radius, var(--ec-btn-radius));
    --bs-btn-padding-x: var(--ts-btn-pad-x, 1.125rem);
    --bs-btn-padding-y: calc((var(--ts-control-height, 2.75rem) - var(--bs-btn-font-size) * var(--bs-btn-line-height) - 2 * var(--bs-btn-border-width)) / 2);
    min-height: var(--ts-control-height, 2.75rem);
    letter-spacing: var(--ts-btn-tracking, normal);
    text-transform: var(--ts-btn-transform, none);
}

.btn-sm,
.btn-group-sm > .btn {
    --bs-btn-font-size: 0.875rem;
    --bs-btn-padding-x: 0.75rem;
    --bs-btn-padding-y: calc((var(--ts-control-height-sm, 2.25rem) - var(--bs-btn-font-size) * var(--bs-btn-line-height) - 2 * var(--bs-btn-border-width)) / 2);
    --bs-btn-border-radius: var(--bs-border-radius-sm);
    min-height: var(--ts-control-height-sm, 2.25rem);
}

.btn-lg,
.btn-group-lg > .btn {
    --bs-btn-font-size: 1.125rem;
    --bs-btn-padding-x: 1.5rem;
    --bs-btn-padding-y: calc((var(--ts-control-height, 2.75rem) + 0.5rem - var(--bs-btn-font-size) * var(--bs-btn-line-height) - 2 * var(--bs-btn-border-width)) / 2);
    --bs-btn-border-radius: var(--ts-control-radius, var(--ec-btn-radius));
    min-height: calc(var(--ts-control-height, 2.75rem) + 0.5rem);
}

.btn-link {
    --bs-btn-font-weight: 600;
    --bs-btn-bg: transparent;
    --bs-btn-border-color: transparent;
    --bs-btn-hover-border-color: transparent;
    --bs-btn-active-border-color: transparent;
}

.form-control,
.form-select {
    --ts-control-pad-y: calc((var(--ts-control-height, 2.75rem) - 1.5em - 2 * var(--ts-control-border-width, 1px)) / 2);
    min-height: var(--ts-control-height, 2.75rem);
    padding-top: var(--ts-control-pad-y);
    padding-bottom: var(--ts-control-pad-y);
    background-color: var(--ts-control-bg, var(--ec-surface));
    border-color: var(--ts-control);
    border-width: var(--ts-control-border-width, 1px);
    border-radius: var(--ts-control-radius, var(--ec-btn-radius));
}

.form-control-sm,
.form-select-sm {
    --ts-control-pad-y: calc((var(--ts-control-height-sm, 2.25rem) - 1.5em - 2 * var(--ts-control-border-width, 1px)) / 2);
    min-height: var(--ts-control-height-sm, 2.25rem);
    border-radius: var(--bs-border-radius-sm);
}

.form-control-lg,
.form-select-lg {
    --ts-control-pad-y: calc((var(--ts-control-height, 2.75rem) + 0.5rem - 1.5em - 2 * var(--ts-control-border-width, 1px)) / 2);
    min-height: calc(var(--ts-control-height, 2.75rem) + 0.5rem);
}

.form-control::file-selector-button {
    margin-top: calc(-1 * var(--ts-control-pad-y));
    margin-bottom: calc(-1 * var(--ts-control-pad-y));
    padding-top: var(--ts-control-pad-y);
    padding-bottom: var(--ts-control-pad-y);
    color: var(--ec-fg);
    background-color: var(--ec-surface-2);
}

.form-control:disabled,
.form-select:disabled {
    background-color: var(--ec-surface-2);
    border-color: var(--ec-border);
    color: var(--ec-fg-2);
}

.form-control[readonly]:not(.form-control-plaintext) {
    background-color: var(--ec-surface-2);
}

.form-control-plaintext {
    min-height: var(--ts-control-height, 2.75rem);
    color: var(--ec-fg);
}

.form-control-color {
    min-height: var(--ts-control-height, 2.75rem);
    padding: 0.375rem;
}

.input-group-text {
    color: var(--ec-fg-2);
    background-color: var(--ec-surface-2);
    border-color: var(--ts-control);
    border-width: var(--ts-control-border-width, 1px);
    border-radius: var(--ts-control-radius, var(--ec-btn-radius));
}

.form-check {
    padding-left: calc(var(--ts-check-size, 1.25em) + 0.5em);
}

.form-check .form-check-input {
    margin-left: calc(-1 * (var(--ts-check-size, 1.25em) + 0.5em));
}

.form-check-input {
    --bs-form-check-bg: var(--ts-control-bg, var(--ec-surface));
    width: var(--ts-check-size, 1.25em);
    height: var(--ts-check-size, 1.25em);
    margin-top: calc((1.5em - var(--ts-check-size, 1.25em)) / 2);
    border-color: var(--ts-control);
    border-width: var(--ts-control-border-width, 1px);
}

.form-check-input[type="checkbox"] {
    border-radius: min(var(--ts-control-radius, var(--ec-btn-radius)), 0.3125em);
}

.form-check-input:disabled {
    border-color: var(--ec-border);
}

.form-switch {
    padding-left: calc(var(--ts-check-size, 1.25em) * 1.8 + 0.5em);
}

.form-switch .form-check-input {
    width: calc(var(--ts-check-size, 1.25em) * 1.8);
    margin-left: calc(-1 * (var(--ts-check-size, 1.25em) * 1.8 + 0.5em));
    border-radius: calc(var(--ts-check-size, 1.25em) * 0.9);
}

.form-check-inline {
    margin-right: 1.25rem;
}

.form-label,
.col-form-label {
    font-weight: 600;
}

.form-text {
    color: var(--ec-fg-2);
}

.card {
    --bs-card-spacer-y: 1.25rem;
    --bs-card-spacer-x: 1.25rem;
    --bs-card-cap-padding-y: 0.875rem;
    --bs-card-cap-padding-x: 1.25rem;
    --bs-card-color: var(--ec-fg);
    --bs-card-bg: var(--ts-card-bg, var(--ec-surface));
    --bs-card-border-color: var(--ts-card-border, var(--ec-border));
    --bs-card-border-radius: var(--ts-card-radius, var(--ec-radius));
    --bs-card-inner-border-radius: calc(var(--ts-card-radius, var(--ec-radius)) - var(--bs-card-border-width));
    --bs-card-cap-bg: var(--ec-surface-2);
    --bs-card-cap-color: var(--ec-fg);
    --bs-card-title-color: var(--ec-fg);
    --bs-card-subtitle-color: var(--ec-fg-2);
    --bs-card-box-shadow: var(--ts-card-shadow, var(--ec-shadow));
    box-shadow: var(--bs-card-box-shadow);
}

.list-group {
    --bs-list-group-color: var(--ec-fg);
    --bs-list-group-bg: var(--ts-card-bg, var(--ec-surface));
    --bs-list-group-border-color: var(--ts-card-border, var(--ec-border));
    --bs-list-group-border-radius: var(--ts-card-radius, var(--ec-radius));
    --bs-list-group-item-padding-x: 1.125rem;
    --bs-list-group-item-padding-y: 0.75rem;
    --bs-list-group-action-color: var(--ec-fg);
    --bs-list-group-action-hover-color: var(--ec-fg);
    --bs-list-group-action-hover-bg: var(--ec-surface-2);
    --bs-list-group-action-active-color: var(--ec-fg);
    --bs-list-group-action-active-bg: var(--ec-surface-2);
    --bs-list-group-disabled-color: var(--ec-fg-2);
    --bs-list-group-disabled-bg: var(--ts-card-bg, var(--ec-surface));
}

.dropdown-menu {
    --bs-dropdown-color: var(--ec-fg);
    --bs-dropdown-bg: var(--ec-surface);
    --bs-dropdown-border-color: var(--ec-border);
    --bs-dropdown-border-radius: var(--ts-overlay-radius, var(--ec-radius));
    --bs-dropdown-inner-border-radius: calc(var(--ts-overlay-radius, var(--ec-radius)) - var(--bs-dropdown-border-width));
    --bs-dropdown-box-shadow: var(--ts-overlay-shadow);
    --bs-dropdown-divider-bg: var(--ec-border);
    --bs-dropdown-padding-y: 0.375rem;
    --bs-dropdown-item-padding-x: 1rem;
    --bs-dropdown-item-padding-y: 0.625rem;
    --bs-dropdown-link-color: var(--ec-fg);
    --bs-dropdown-link-hover-color: var(--ec-fg);
    --bs-dropdown-link-hover-bg: var(--ec-surface-2);
    --bs-dropdown-link-disabled-color: var(--ec-fg-2);
    --bs-dropdown-header-color: var(--ec-fg-2);
    box-shadow: var(--bs-dropdown-box-shadow);
}

.modal {
    --bs-modal-color: var(--ec-fg);
    --bs-modal-bg: var(--ec-surface);
    --bs-modal-border-color: var(--ec-border);
    --bs-modal-border-radius: var(--ts-overlay-radius, var(--ec-radius));
    --bs-modal-inner-border-radius: calc(var(--ts-overlay-radius, var(--ec-radius)) - var(--bs-modal-border-width));
    --bs-modal-box-shadow: var(--ts-overlay-shadow);
    --bs-modal-header-border-color: var(--ec-border);
    --bs-modal-footer-border-color: var(--ec-border);
}

.modal-content {
    box-shadow: var(--bs-modal-box-shadow);
}

.modal-backdrop {
    --bs-backdrop-bg: var(--ts-scrim);
    --bs-backdrop-opacity: 1;
}

.offcanvas,
.offcanvas-sm,
.offcanvas-md,
.offcanvas-lg,
.offcanvas-xl,
.offcanvas-xxl {
    --bs-offcanvas-color: var(--ec-fg);
    --bs-offcanvas-bg: var(--ec-surface);
    --bs-offcanvas-border-color: var(--ec-border);
    --bs-offcanvas-box-shadow: var(--ts-overlay-shadow);
}

.popover {
    --bs-popover-bg: var(--ec-surface);
    --bs-popover-border-color: var(--ec-border);
    --bs-popover-border-radius: var(--ts-overlay-radius, var(--ec-radius));
    --bs-popover-inner-border-radius: calc(var(--ts-overlay-radius, var(--ec-radius)) - var(--bs-popover-border-width));
    --bs-popover-box-shadow: var(--ts-overlay-shadow);
    --bs-popover-header-color: var(--ec-fg);
    --bs-popover-header-bg: var(--ec-surface-2);
    --bs-popover-body-color: var(--ec-fg);
    --bs-popover-arrow-border: var(--ec-border);
    --bs-popover-font-size: 0.9375rem;
    box-shadow: var(--bs-popover-box-shadow);
}

.tooltip {
    --bs-tooltip-color: var(--ts-tooltip-fg, var(--ec-bg));
    --bs-tooltip-bg: var(--ts-tooltip-bg, var(--ec-fg));
    --bs-tooltip-opacity: 1;
    --bs-tooltip-border-radius: var(--ts-badge-radius, min(var(--ec-btn-radius), 0.375rem));
    --bs-tooltip-font-size: 0.875rem;
    --bs-tooltip-padding-x: 0.625rem;
    --bs-tooltip-padding-y: 0.375rem;
}

.toast {
    --bs-toast-color: var(--ec-fg);
    --bs-toast-bg: var(--ec-surface);
    --bs-toast-border-color: var(--ec-border);
    --bs-toast-border-radius: var(--ts-overlay-radius, var(--ec-radius));
    --bs-toast-box-shadow: var(--ts-overlay-shadow);
    --bs-toast-header-color: var(--ec-fg);
    --bs-toast-header-bg: var(--ec-surface-2);
    --bs-toast-header-border-color: var(--ec-border);
    --bs-toast-font-size: 0.9375rem;
}

.accordion {
    --bs-accordion-color: var(--ec-fg);
    --bs-accordion-bg: var(--ts-card-bg, var(--ec-surface));
    --bs-accordion-border-color: var(--ts-card-border, var(--ec-border));
    --bs-accordion-border-radius: var(--ts-card-radius, var(--ec-radius));
    --bs-accordion-inner-border-radius: calc(var(--ts-card-radius, var(--ec-radius)) - var(--bs-accordion-border-width));
    --bs-accordion-btn-color: var(--ec-fg);
    --bs-accordion-btn-bg: var(--ts-card-bg, var(--ec-surface));
    --bs-accordion-btn-padding-y: 0.875rem;
    --bs-accordion-active-color: var(--ts-on-tint);
    --bs-accordion-active-bg: var(--ts-tint);
    --bs-accordion-transition: color var(--ec-dur-2) var(--ec-ease), background-color var(--ec-dur-2) var(--ec-ease), border-color var(--ec-dur-2) var(--ec-ease), border-radius var(--ec-dur-2) var(--ec-ease);
    --bs-accordion-btn-icon-transition: transform var(--ec-dur-2) var(--ec-ease);
}

.accordion-button {
    font-weight: 600;
}

.nav {
    --bs-nav-link-color: var(--ts-link);
    --bs-nav-link-hover-color: var(--ts-link-hover);
    --bs-nav-link-disabled-color: var(--ec-fg-2);
    --bs-nav-link-font-weight: 600;
}

/* Tabs: an indicator bar on the active tab (--ts-tab-indicator), no folder outline unless the
   design sets --ts-tab-active-border / --ts-tab-active-bg. */
.nav-tabs {
    --bs-nav-link-color: var(--ec-fg-2);
    --bs-nav-link-hover-color: var(--ec-fg);
    --bs-nav-tabs-border-color: var(--ec-border);
    --bs-nav-tabs-border-radius: var(--ts-control-radius, var(--ec-btn-radius));
    --bs-nav-tabs-link-hover-border-color: transparent;
    --bs-nav-tabs-link-active-color: var(--ec-fg);
    --bs-nav-tabs-link-active-bg: var(--ts-tab-active-bg, transparent);
    --bs-nav-tabs-link-active-border-color: var(--ts-tab-active-border, transparent) var(--ts-tab-active-border, transparent) var(--ts-tab-active-bg, transparent);
}

.nav-tabs .nav-link {
    min-height: var(--ts-control-height, 2.75rem);
}

.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link {
    box-shadow: inset 0 calc(-1 * var(--ts-tab-indicator-width, 3px)) 0 var(--ts-tab-indicator, var(--ts-signal));
}

.nav-underline {
    --bs-nav-underline-link-active-color: var(--ec-fg);
}

.navbar {
    --bs-navbar-color: var(--ec-fg-2);
    --bs-navbar-hover-color: var(--ec-fg);
    --bs-navbar-disabled-color: var(--ec-fg-2);
    --bs-navbar-active-color: var(--ec-fg);
    --bs-navbar-brand-color: var(--ec-fg);
    --bs-navbar-brand-hover-color: var(--ec-fg);
    --bs-navbar-toggler-border-color: var(--ts-control);
    --bs-navbar-toggler-border-radius: var(--ts-control-radius, var(--ec-btn-radius));
}

.pagination {
    --bs-pagination-padding-x: 0.75rem;
    --bs-pagination-padding-y: calc((var(--ts-control-height, 2.75rem) - 1.5rem - 2 * var(--bs-pagination-border-width)) / 2);
    --bs-pagination-color: var(--ec-fg);
    --bs-pagination-bg: var(--ec-surface);
    --bs-pagination-border-color: var(--ts-control);
    --bs-pagination-border-radius: var(--ts-control-radius, var(--ec-btn-radius));
    --bs-pagination-hover-color: var(--ec-fg);
    --bs-pagination-hover-bg: var(--ec-surface-2);
    --bs-pagination-hover-border-color: var(--ec-fg-2);
    --bs-pagination-focus-color: var(--ec-fg);
    --bs-pagination-focus-bg: var(--ec-surface-2);
    --bs-pagination-disabled-color: var(--ec-fg-2);
    --bs-pagination-disabled-bg: transparent;
    --bs-pagination-disabled-border-color: var(--ec-border);
    flex-wrap: wrap;
    gap: var(--ts-page-gap, 0.375rem);
}

/* Separate tiles (every design draws gapped squares), each with its own radius */
.page-item:not(:first-child) .page-link {
    margin-left: 0;
}

.page-link {
    min-width: var(--ts-control-height, 2.75rem);
    font-weight: 600;
    text-align: center;
    border-radius: var(--bs-pagination-border-radius);
}

.breadcrumb {
    --bs-breadcrumb-margin-bottom: 0;
    --bs-breadcrumb-bg: transparent;
    --bs-breadcrumb-divider-color: var(--ec-fg-2);
    --bs-breadcrumb-item-active-color: var(--ec-fg);
}

.alert {
    --bs-alert-padding-x: 1.25rem;
    --bs-alert-padding-y: 1rem;
    --bs-alert-border-radius: var(--ts-alert-radius, var(--ec-radius));
    border-width: var(--ts-alert-border-width, 1px);
    border-inline-start-width: var(--ts-alert-bar-width, 1px);
}

.progress,
.progress-stacked {
    --bs-progress-border-radius: var(--ts-badge-radius, min(var(--ec-btn-radius), 0.375rem));
}

.table:not(.table-dark) > thead {
    --bs-table-bg: var(--ts-table-head-bg, transparent);
    --bs-table-color: var(--ts-table-head-fg, var(--ec-fg-2));
}

.table > thead > tr:last-child > * {
    border-bottom-width: 2px;
    border-bottom-color: var(--ts-table-head-rule, var(--ec-border));
}

.table > :not(caption) > * > * {
    padding: 0.75rem 0.75rem;
}

.table-sm > :not(caption) > * > * {
    padding: 0.375rem 0.5rem;
}

.spinner-border,
.spinner-grow {
    --bs-spinner-animation-speed: 0.9s;
}

/* ==========================================================================
   §E Joomla core compositions of Bootstrap classes (layout only; the names are Bootstrap's, so
   they may only live in this file)
   ========================================================================== */

/* Core button markup colours its icon `.text-white` (com_config Save: icon-check text-white);
   the icon follows the button's own text pair instead, which the design guarantees */
.btn > .text-white {
    color: inherit !important;
}

/* Subform repeatable rows: the add/remove/move toolbar sits in the row's top corner */
.subform-repeatable-group > .btn-toolbar {
    position: absolute;
    inset-block-start: 0.5rem;
    inset-inline-end: 0.5rem;
    gap: 0.25rem;
}

.subform-repeatable-wrapper > .btn-toolbar,
.subform-repeatable > .btn-toolbar {
    margin-block-end: 0.5rem;
}

/* Core filter rows are printed as .btn-group: keep them as separate controls with a gap */
:is(.com-tags-tags__filter, .com-tags-tag__filter, .com-content__filter, .com-contact-category__filter, .com-newsfeeds-category__filter).btn-group > .btn {
    flex: 0 0 auto;
    margin-inline-start: 0 !important;
    border-radius: var(--bs-btn-border-radius) !important;
}

/* Article count badge next to a category title */
:is(.com-content-categories__item-title, .com-contact-categories__item-title, .com-newsfeeds-categories__item-title) > .badge {
    margin-inline-start: 0.5rem;
    vertical-align: middle;
}

/* List filters (category list, contacts, tags): the limit/sort group goes to the end */
:is(.com-content__filter, .com-contact-category__filter, .com-tags-tag__filter, .com-tags-tags__filter) > .btn-group {
    margin-inline-start: auto;
}

/* Bootstrap transitions follow the template motion tokens (zeroed under reduced motion) */
.btn,
.form-control,
.form-select,
.page-link,
.nav-link,
.list-group-item-action,
.dropdown-item {
    transition-duration: var(--ec-dur-1, 0.15s);
}
