/*
 * Admin component layer — token-driven building blocks for internal pages.
 *
 * Use these classes in admin views instead of inline <style> blocks so the
 * design language stays consistent. Never apply to public/donor-facing
 * surfaces (donation form, checkout, web elements, campaign pages, donor
 * portal, receipts).
 */

/* -- Bootstrap tooltip background ---------------------------------------- */
/*
 * Bootstrap 5.3 defaults --bs-tooltip-bg to var(--bs-emphasis-color), which
 * is not defined by this app's CSS layer — leaving tooltips with a visible
 * arrow but a transparent body. Pin the dark scheme explicitly.
 */
.tooltip {
    --bs-tooltip-bg: var(--color-bg-tooltip) !important;
    --bs-tooltip-color: var(--color-text-on-dark);
}

.tooltip .tooltip-arrow::before,
.bs-tooltip-top .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before {
    border-top-color: var(--color-bg-tooltip);
}
.bs-tooltip-bottom .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before {
    border-bottom-color: var(--color-bg-tooltip);
}
.bs-tooltip-start .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before {
    border-left-color: var(--color-bg-tooltip);
}
.bs-tooltip-end .tooltip-arrow::before,
.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before {
    border-right-color: var(--color-bg-tooltip);
}

/* -- Page header ---------------------------------------------------------- */

.page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-4);
    margin-bottom: var(--space-4);
}

.page-header .page-title {
    margin: 0;
    font-size: 1.75rem;
    font-weight: 500;
    color: var(--color-text-strong);
}

.page-header__actions {
    display: flex;
    gap: var(--space-2);
    align-items: center;
}

.page-header__actions .btn,
.page-header__actions .btn-sm {
    padding: 6px 12px;
    font-size: 1rem;
    border-radius: var(--radius-md);
    white-space: nowrap;
}

/* -- Toolbar -------------------------------------------------------------- */

.toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    align-items: flex-end;
    margin-bottom: var(--space-2);
}

.toolbar__field {
    flex: 0 0 auto;
    min-width: 160px;
}

.toolbar__field--grow {
    flex: 1 1 200px;
}

.toolbar__actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
}

/* -- Card ----------------------------------------------------------------- */

.surface-card {
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    padding: var(--space-6);
}

/*
 * Use only on cards that are actually clickable (dashboard tiles, link tiles).
 * Do NOT apply to filter cards — they're not clickable and the hover-lift
 * implies the wrong affordance.
 */
.surface-card--interactive {
    transition: box-shadow 0.15s ease-in-out;
    cursor: pointer;
}

.surface-card--interactive:hover {
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
}

/* -- Filter controls ------------------------------------------------------ */

.filter-label {
    display: block;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--color-text-default);
    margin-bottom: var(--space-1);
}

.filter-input {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.filter-input:focus {
    border-color: var(--color-border);
    box-shadow: 0 0 0 0.1rem rgba(21, 43, 75, 0.15);
    outline: 0;
}

/* -- Row actions menu ----------------------------------------------------- */

.actions-dropdown {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
}

.actions-dropdown .btn-actions {
    background: none;
    border: none;
    padding: 6px 12px;
    color: var(--color-text-muted);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: background-color 0.15s ease-in-out;
    display: flex;
    align-items: center;
    justify-content: center;
}

.actions-dropdown .btn-actions:hover {
    background-color: var(--color-bg-row-hover);
    color: var(--color-bg-sidebar);
}

.actions-dropdown .btn-actions:focus {
    outline: none;
    box-shadow: none;
}

/* -- DataTables shared overrides ----------------------------------------- */

.dataTable.table {
    box-shadow: none;
}

.data-table-wrapper {
    width: 100%;
    -webkit-overflow-scrolling: touch;
}

/* Connected Apps: the scope list is the one free-text cell wide enough to push the
   trailing Status and Revoke columns off screen. Cap it and let it wrap. */
.connection-scopes {
    max-width: 320px;
    white-space: normal;
}

.data-table-wrapper .dataTables_length,
.data-table-wrapper .dataTables_filter,
.data-table-wrapper .dataTables_info {
    display: none !important;
}

.data-table-wrapper .dataTables_paginate {
    margin-top: var(--space-5) !important;
}

.data-table-wrapper .page-link {
    color: var(--color-bg-sidebar);
    background-color: var(--color-bg-faint);
    border-color: var(--color-border-subtle);
    box-shadow: none;
}

.data-table-wrapper .page-link:hover {
    color: var(--color-bg-sidebar);
    background-color: var(--color-bg-light);
    border-color: var(--color-border-subtle);
}

.data-table-wrapper .page-link.active,
.data-table-wrapper .active > .page-link {
    background-color: var(--color-bg-sidebar);
    border-color: var(--color-bg-sidebar);
    color: var(--color-text-on-dark);
}

.data-table-wrapper .page-link:focus {
    box-shadow: none !important;
}

.data-table-wrapper .page-item.disabled .page-link {
    color: var(--color-text-muted);
    background-color: var(--color-bg-faint);
    border-color: var(--color-border-subtle);
}

.data-table-wrapper table.dataTable thead > tr > th.sorting,
.data-table-wrapper table.dataTable thead > tr > th.sorting_asc,
.data-table-wrapper table.dataTable thead > tr > th.sorting_desc {
    background-image: none !important;
    padding-right: var(--space-3);
    position: relative;
    cursor: pointer;
}

.data-table-wrapper table.dataTable thead > tr > th.sorting:after,
.data-table-wrapper table.dataTable thead > tr > th.sorting:before {
    content: '';
}

.data-table-wrapper table.dataTable thead > tr > th.sorting_asc:after {
    content: '↑';
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 14px;
    color: var(--color-bg-sidebar);
    font-weight: bold;
    opacity: 1;
}

.data-table-wrapper table.dataTable thead > tr > th.sorting_desc:after {
    content: '↓';
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 14px;
    color: var(--color-bg-sidebar);
    font-weight: bold;
    opacity: 1;
}

@media (max-width: 768px) {
    .page-header {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-3);
    }
    .page-header__actions {
        flex-wrap: wrap;
    }
    .toolbar {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-3);
    }
    .toolbar__field,
    .toolbar__field--grow {
        flex: 0 0 auto;
        min-width: 100%;
    }
    .toolbar__actions {
        margin-left: 0;
        justify-content: flex-start;
    }
}

/* -- Data table skin ------------------------------------------------------ */
/*
 * Generic styling for admin list tables (donors, donations, campaigns,
 * reports). Apply by wrapping a <table class="table"> in
 * <div class="data-table-wrapper">. View-specific column alignment and
 * column widths still live in the view.
 */

.data-table-wrapper .table {
    box-shadow: none;
    border-collapse: collapse;
    margin: 0 !important;
}

.data-table-wrapper .table thead tr { background: transparent; }

.data-table-wrapper .table th,
.data-table-wrapper .table td {
    text-align: left;
    vertical-align: middle;
    border: none;
    border-bottom: 1px solid var(--color-border-light);
    padding: var(--space-3);
}

.data-table-wrapper .table thead th {
    background-color: var(--color-bg-faint);
    color: var(--color-text-default);
    border-bottom: 1px solid var(--color-border-subtle);
}

.data-table-wrapper .table tbody tr {
    background-color: var(--color-bg-surface);
    cursor: pointer;
}

.data-table-wrapper .table tbody tr:hover {
    background-color: var(--color-bg-table-hover);
}

.data-table-wrapper .table tbody tr td > a {
    text-decoration: none;
    color: inherit;
    padding: var(--space-4) var(--space-3);
    display: flex;
    align-items: center;
    height: 100%;
}

.data-table-wrapper .table tr td:first-child > a { padding-left: var(--space-5); }
.data-table-wrapper .table tr td:last-child > a { padding-right: var(--space-5); }

/*
 * Two-line cell: a primary value with a smaller secondary line beneath it —
 * a donor's name over the address that was actually suppressed.
 *
 * The wrapper is load-bearing, not decoration. The rule above turns a direct
 * `td > a` into a padded flex box so that the whole cell becomes a click
 * target; a link that is only the FIRST line of a cell picks that padding up
 * too, and indents itself relative to the line underneath. Nesting the link
 * inside .cell-stack takes it out of `td > a` and both lines start at the
 * same edge — including on rows that have no link at all, which is what makes
 * the column read as a column.
 */
.data-table-wrapper .table td .cell-stack {
    display: flex;
    flex-direction: column;
}

.data-table-wrapper .table td .cell-subtext {
    font-size: 12px;
    color: var(--color-text-muted);
}

/* DataTables processing overlay + spinner */
.data-table-wrapper .dataTables_empty {
    text-align: center !important;
    padding: 2rem !important;
    color: var(--color-text-muted) !important;
    height: 84px;
}

.data-table-wrapper .dataTables_scrollBody {
    border: 1px solid var(--color-border-subtle);
}

.data-table-wrapper .dataTables_scrollHead,
.data-table-wrapper .dataTables_scrollBody {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.data-table-wrapper .dataTables_wrapper {
    width: 100%;
    position: relative;
}

.data-table-wrapper .dataTables_processing {
    position: absolute;
    top: 50px !important;
    left: calc(var(--bs-gutter-x) * 0.5) !important;
    width: calc(100% - var(--bs-gutter-x)) !important;
    height: calc(100% - 50px) !important;
    min-height: 150px;
    display: block;
    background-color: rgba(255, 255, 255, 0.9) !important;
    margin: 0 !important;
    z-index: 10;
    border-top-right-radius: 0;
    border-top-left-radius: 0;
    border: 1px solid var(--color-border-subtle);
}

.data-table-wrapper .dataTables_processing.card {
    background-color: unset;
    border-top: 0;
}

.data-table-wrapper .dataTables_processing div { display: none; }

@keyframes dataTableSpin { to { transform: rotate(360deg); } }

.data-table-wrapper .dataTables_processing::before {
    display: block;
    content: '';
    width: 50px;
    height: 50px;
    border: 4px solid rgba(21, 43, 75, 0.3);
    border-radius: 50%;
    border-top-color: var(--color-bg-sidebar);
    animation: dataTableSpin 1s ease-in-out infinite;
    position: absolute;
    top: calc(50% - 40px);
    left: calc(50% - 25px);
}

.data-table-wrapper .dataTables_processing::after {
    display: block;
    content: 'Loading...';
    font-family: avenirnext-medium, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    color: var(--color-bg-sidebar);
    font-size: 16px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, calc(-50% + 35px));
    white-space: nowrap;
}

/* DataTables Responsive plugin (dtr-*) child rows */
.data-table-wrapper table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control:before,
.data-table-wrapper table.dataTable.dtr-inline.collapsed > tbody > tr > th.dtr-control:before {
    background-color: transparent;
    position: absolute;
    right: 18px;
    margin-top: 18px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    text-align: right;
}

.data-table-wrapper table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control,
.data-table-wrapper table.dataTable.dtr-inline.collapsed > tbody > tr > th.dtr-control {
    padding-left: 30px;
    min-width: 40px;
}

.data-table-wrapper table.dataTable > tbody > tr.child ul.dtr-details {
    width: 100%;
    padding-left: 0;
}

.data-table-wrapper table.dataTable > tbody > tr.child ul.dtr-details > li {
    border-bottom: 1px solid var(--color-border-light);
    padding: var(--space-3) 0;
}

.data-table-wrapper table.dataTable > tbody > tr.child ul.dtr-details > li:last-child {
    border-bottom: none;
}

.data-table-wrapper table.dataTable > tbody > tr.child span.dtr-title {
    font-weight: 600;
    color: var(--color-text-default);
    min-width: 120px;
    display: inline-block;
}

.data-table-wrapper table.dataTable > tbody > tr.child span.dtr-data {
    color: var(--color-text-strong);
}

/* Filter helpers shared by list pages */
.advanced-filters-toggle {
    color: var(--color-text-muted);
    background: none;
    border: none;
    padding: 0;
    text-decoration: none;
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
    transition: color 0.15s ease-in-out;
}

.advanced-filters-toggle:hover {
    color: var(--color-bg-sidebar);
    text-decoration: none;
}

#advancedFiltersContainer { overflow: hidden; }

.input-group-text {
    background-color: var(--color-bg-light);
    border-color: var(--color-border);
    color: var(--color-text-default);
}

/* -- Detail page components ----------------------------------------------- */
/*
 * Shared building blocks for single-record detail pages (donations/detail.php,
 * donors/detail.php, pledges/detail.php, recurring/detail.php, task/view.php,
 * etc.). View-specific layout (timeline content, fee breakdown rows, etc.)
 * still lives in the view, but the surface and typographic system is shared.
 */

.info-card {
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    overflow: hidden;
}

.card-header-custom {
    background: var(--color-bg-surface);
    border-bottom: 1px solid var(--color-border-light);
    padding: 1.25rem 1.5rem;
}

.card-header-custom h5 {
    font-size: 1.2rem;
    color: var(--color-text-strong);
}

.card-body-custom {
    padding: 1.5rem;
}

.detail-label {
    font-size: 0.875rem;
    color: var(--color-text-secondary);
    margin-bottom: 0.25rem;
    display: block;
}

.detail-value {
    font-size: 0.9375rem;
    color: var(--color-text-strong);
    font-weight: 500;
}

.amount-value {
    font-family: avenirnext-medium;
    font-size: 1.75rem;
    color: var(--color-text-strong);
}

.amount-currency {
    color: var(--color-text-secondary);
    font-size: 0.875rem;
}

.amount-icon {
    width: 60px;
    height: 60px;
    background: var(--color-green);
    border-radius: 0.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
}

.amount-icon i {
    font-size: 1.75rem;
    color: var(--color-text-on-dark);
}

/* Status badges */
.status-badge {
    padding: 0.5rem 1rem;
    border-radius: 0.375rem;
    font-size: 0.875rem;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
}

.badge-success { background-color: var(--color-green); color: var(--color-text-on-dark); }
.badge-danger { background-color: var(--color-red); color: var(--color-text-on-dark); }
.badge-warning { background-color: var(--color-amber); color: var(--color-text-on-dark); }
.badge-secondary { background-color: var(--color-text-secondary); color: var(--color-text-on-dark); }

/* Action buttons */
.action-btn {
    padding: 0.75rem 1.25rem;
    border-radius: 0.5rem;
    border: none;
    font-size: 0.9375rem;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    justify-content: start;
    text-decoration: none;
}

.action-btn-primary { background: var(--color-blue); color: var(--color-text-on-dark); }
.action-btn-primary:hover { background: var(--color-blue-hover); color: var(--color-text-on-dark); }

.action-btn-purple { background: var(--color-purple); color: var(--color-text-on-dark); }
.action-btn-purple:hover { background: var(--color-purple-hover); color: var(--color-text-on-dark); }

.action-btn-green,
.action-btn-success { background: var(--color-green); color: var(--color-text-on-dark); }
.action-btn-green:hover,
.action-btn-success:hover { background: var(--color-green-hover); color: var(--color-text-on-dark); }

.action-btn-primary i, .action-btn-primary span,
.action-btn-purple i, .action-btn-purple span,
.action-btn-green i, .action-btn-green span,
.action-btn-success i, .action-btn-success span { color: var(--color-text-on-dark); }

.action-btn-outline {
    background: var(--color-bg-surface);
    color: var(--color-text-secondary);
    border: 1px solid var(--color-border-mid);
}

.action-btn-outline:hover {
    background: var(--color-bg-light);
    color: var(--color-text-strong);
}

.action-btn-outline-primary {
    background: var(--color-bg-surface);
    color: var(--color-blue);
    border: 1px solid var(--color-blue-border);
}

.action-btn-outline-primary i,
.action-btn-outline-primary span { color: var(--color-blue); }

.action-btn-outline-primary:hover {
    background: var(--color-blue-tint);
    color: var(--color-blue-hover);
}

.action-btn-outline-danger {
    background: var(--color-bg-surface);
    color: var(--color-red);
    border: 1px solid var(--color-red-border);
}

.action-btn-outline-danger i,
.action-btn-outline-danger span { color: var(--color-red); }

.action-btn-outline-danger:hover {
    background: var(--color-red-tint);
    color: var(--color-red-hover);
}

.btn-text-shift-down {
    position: relative;
    top: 3px;
}

/* Timeline (donations/detail and similar) */
.timeline {
    position: relative;
    padding-left: 30px;
}

.timeline::before {
    content: '';
    position: absolute;
    left: 13px;
    top: 3px;
    bottom: 25px;
    width: 2px;
    background: var(--color-border-light);
}

.timeline-item {
    position: relative;
    margin-bottom: 1.5rem;
}

.timeline-item:last-child { margin-bottom: 0; }

.timeline-marker {
    position: absolute;
    left: -22px;
    top: 5px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 2px solid var(--color-bg-surface);
    box-shadow: 0 0 0 2px var(--color-border-light);
}

.timeline-title {
    font-size: 0.9375rem;
    font-weight: 500;
    margin-bottom: 0.25rem;
    color: var(--color-text-strong);
}

.timeline-text { color: var(--color-text-secondary); }

/* Detail page container */
.detail-container {
    max-width: 1400px;
    margin: 0 auto;
}

/* Fee breakdown (donations/detail, event-registrations/detail, attendees/view) */
.fee-breakdown {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.fee-breakdown-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.fee-breakdown-label {
    font-size: 0.875rem;
    color: var(--color-text-strong);
}

.fee-breakdown-value {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--color-text-strong);
}

.fee-breakdown-item .text-muted {
    color: var(--color-text-secondary) !important;
    font-weight: 400;
}

.fee-breakdown-divider {
    height: 1px;
    background: var(--color-border-light);
    margin: 0.5rem 0;
}

.fee-breakdown-total .fee-breakdown-label {
    font-weight: 600;
    font-size: 0.875rem;
}

.fee-breakdown-total .fee-breakdown-value {
    font-size: 0.875rem;
    font-weight: 700;
}

.action-btn-outline i,
.action-btn-outline span { color: var(--color-text-secondary); }

/* -- Dashboard components ------------------------------------------------- */
/*
 * Shared building blocks for dashboard pages (campaign/dashboard.php,
 * event/dashboard.php, sponsorship/dashboard.php, donors/dashboard.php).
 * Surface aesthetic matches .surface-card / .info-card: hairline border,
 * subtle shadow, 8px radius.
 */

.dashboard-container {
    display: flex;
    flex-wrap: wrap;
    column-gap: 30px;
}

.dashboard-header {
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    flex-basis: 100%;
}

.header-title {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.header-subtitle {
    font-size: 0.875rem;
    color: var(--color-text-muted);
    margin-top: 0.5rem;
    margin-bottom: 0;
}

.header-actions {
    display: flex;
    gap: 0.5rem;
}

/* Tab button bar */
.tab-button-group {
    margin: 1rem 0;
    background: var(--color-bg-faint);
    padding: 1rem;
    border-radius: var(--radius-lg);
    border: 1px solid var(--color-border-subtle);
    flex-basis: 100%;
}

.tab-buttons-container {
    display: flex;
    flex-wrap: wrap;
    padding: 0;
    margin: 0;
}

.tab-button {
    border: none;
    background: transparent;
    padding: var(--space-3) var(--space-5);
    font-weight: 500;
    color: var(--color-text-default);
    cursor: pointer;
    border-radius: var(--radius-md);
    transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out;
}

.tab-button:hover {
    background-color: var(--color-bg-row-hover);
}

.tab-button.active,
.tab-button[aria-selected="true"] {
    background-color: var(--color-bg-sidebar);
    color: var(--color-text-on-dark);
}

/* Content area / section panels */
.content-area {
    flex: 1;
    display: none;
}

.content-area.active {
    display: block;
}

.content-area form {
    height: 100%;
}

.content-section {
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    padding: 2rem;
    display: none;
    height: 100%;
}

.content-section.active {
    display: block;
}

.content-section-title {
    font-size: 1.5rem;
    margin-bottom: 1.5rem;
    color: var(--color-text-strong);
}

/* Sidebar menu (left rail in dashboard tabs) */
.sidebar-menu {
    width: 280px;
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    padding: 2rem 0;
    display: none;
    align-self: start;
}

.sidebar-menu.active {
    display: block;
}

.sidebar-section-title {
    padding: 0 1.5rem;
    margin-bottom: 1rem;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--color-text-muted);
}

.sidebar-menu-item {
    padding: 0.75rem 1.5rem;
    margin: 0.25rem 0.75rem;
    color: var(--color-text-default);
    text-decoration: none;
    display: flex;
    align-items: center;
    cursor: pointer;
    border-radius: var(--radius-md);
    border: 1px solid transparent;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.sidebar-menu-item:hover,
.sidebar-menu-item.active {
    color: var(--color-text-strong);
    background: var(--color-bg-row-alt);
    border-color: var(--color-border-subtle);
}

.sidebar-menu-item i {
    margin-right: 0.75rem;
    width: 20px;
    text-align: center;
}

/* Metric cards (KPIs) */
.metric-card {
    background: var(--color-bg-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    padding: 1.25rem;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    flex: 1 1 280px;
    min-width: 280px;
}

.metric-card--interactive {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    cursor: pointer;
}

.metric-card--interactive:hover {
    transform: translateY(-2px);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
}

.metric-label {
    font-size: 0.875rem;
    color: var(--color-text-muted);
    margin-bottom: 0.5rem;
    font-weight: 500;
}

.metric-value {
    font-size: 2rem;
    font-family: avenirnext-medium;
    color: var(--color-text-strong);
    margin-bottom: 0.25rem;
}

.metric-subtitle {
    color: var(--color-text-muted);
    font-size: 0.85rem;
}

/* Stat card (highlighted KPI tile with accent stripe) */
.stat-card {
    background: var(--color-bg-surface);
    padding: 1.75rem;
    border-radius: var(--radius-lg);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    border: 1px solid var(--color-border-subtle);
    border-left: 4px solid var(--color-accent-navy);
    transition: all 0.2s ease;
}

@media (max-width: 768px) {
    .metric-card {
        flex: 1 1 100%;
        min-width: 100%;
        padding: 1rem;
    }
    .metric-value {
        font-size: 1.5rem;
    }
    .stat-card {
        padding: 1.25rem;
    }
}

@media (max-width: 480px) {
    .metric-value {
        font-size: 1.25rem;
    }
    .stat-card {
        padding: 1rem;
    }
}

/* -- Status icon ---------------------------------------------------------- */
/*
 * Shared status icon base and unified color modifiers for all donation,
 * recurring, campaign, and event status indicators.
 */
.status-icon {
    text-align: center;
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: bold;
    font-size: 16px;
}

/* Status color modifiers - used across donations, recurring, campaigns, events */
.status-complete {
    color: var(--color-success);
}

.status-refunded {
    color: var(--color-danger);
}

.status-refunded i {
    font-size: 14px;
}

.status-pending {
    color: var(--color-warning);
}

.status-failed {
    color: var(--color-danger);
}

.status-active {
    color: var(--color-success);
}

.status-canceled,
.status-cancelled {
    color: var(--color-text-secondary);
}

.status-incomplete {
    color: var(--color-warning);
}

.status-pastdue {
    color: var(--color-danger);
}

.status-completed {
    color: var(--color-text-secondary);
}

.status-paused {
    color: var(--color-danger);
}

.status-retrying {
    color: var(--color-orange);
}

.status-archived {
    color: var(--color-text-secondary);
}

/* Donation type icons - recurring, offline, one-time */
.recurring-icon {
    color: var(--color-text-muted);
    font-size: 14px;
}

/* Recurring rows carry which payment of the plan they are, as a #N beside the
   mark. Set next to the glyph rather than pinned over it, so a three-digit
   count on a long-running plan cannot swallow the mark it belongs to. */
.recurring-icon-numbered {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: var(--color-text-muted);
    line-height: 1;
    cursor: help;
}

/* Both children sit on the flex cross-axis centre only if neither carries its
   own leading — the icon's line box would otherwise push the number down. */
.recurring-icon-numbered > i {
    display: block;
    line-height: 1;
}

.recurring-installment {
    display: block;
    font-size: 11.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.2px;
    line-height: 1;
    color: var(--color-text-secondary);
}

.offline-icon,
.onetime-icon {
    color: var(--color-text-muted);
    font-size: 18px;
}

/* Payment method icons - used across donations, events, registrations */
.payment-method-icon {
    color: var(--color-text-default);
    font-size: 16px;
    flex-shrink: 0;
}

/* Image-based method marks (tap to pay, Stripe Link) need an explicit box —
   they are <img>, so font-size does not size them. */
.payment-method-icon-img {
    width: 24px;
    height: 24px;
}

/* Inline brand SVGs (Zelle, Venmo) — Font Awesome carries no mark for either.
   Third-party brand colors, same exception as .fa-apple-pay / .fa-google-pay
   below; sourced from venmo.com/about/brand and zellepay.com.
   Two selectors per rule because the PHP renderer wraps the mark in a <span>
   while the React one puts the class on the <svg> itself. */
.payment-method-icon--zelle,
.payment-method-icon--venmo {
    display: inline-flex;
    align-items: center;
}

.payment-method-icon--zelle {
    color: #6d1ed4;
}

.payment-method-icon--venmo {
    color: #008cff;
}

/* Venmo ships as a wordmark occupying a 24x4.55 band, so it needs a wide box —
   a square one renders it as an illegible sliver. */
.payment-method-icon--venmo svg,
svg.payment-method-icon--venmo {
    width: 2.5em;
    height: 0.474em;
}

.fa-apple-pay {
    color: #000000;
}

.fa-google-pay {
    color: #4285f4;
}

.fa-credit-card {
    color: var(--color-text-muted);
}

.fa-mobile-alt {
    color: var(--color-success);
}

.fa-university {
    color: #007bff;
}

/* Add item button - reusable for "Add Amount", "Add Designation", "Add Mapping", etc. */
.btn-add-item {
    background-color: var(--color-bg-light);
    border: 1px solid var(--color-border-mid);
    color: var(--color-text-secondary);
    transition: all 0.2s ease;
    padding: 6px 12px;
    border-radius: 6px;
    cursor: pointer;
}

.btn-add-item:hover {
    background-color: var(--color-border-light);
    border-color: var(--color-border-hover);
    color: var(--color-text-emphasis);
    /* box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); */
}

.btn-add-item:active {
    /* box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); */
}

@media screen and (max-width: 768px) {
    .data-table-wrapper .dataTables_processing {
        top: 32.5px !important;
        height: calc(100% - 32.5px) !important;
        left: 0 !important;
        width: 100% !important;
    }
    .data-table-wrapper .dataTables_wrapper .dataTables_paginate {
        margin-top: 15px !important;
    }
    .data-table-wrapper .dataTables_wrapper .dataTables_paginate .pagination {
        flex-wrap: wrap;
        gap: var(--space-1);
    }
    .data-table-wrapper .page-item { margin: 0; }
    .data-table-wrapper .page-link {
        padding: 0.375rem 0.65rem;
        font-size: 0.875rem;
    }
    .data-table-wrapper table.dataTable > tbody > tr.child ul.dtr-details {
        display: block;
        width: 100%;
        padding: 10px 15px;
        background-color: var(--color-bg-light);
        margin: 0;
    }
    .data-table-wrapper table.dataTable > tbody > tr.child ul.dtr-details > li {
        display: flex;
        flex-direction: column;
        padding: var(--space-2) 0;
        border-bottom: 1px solid var(--color-border-subtle);
    }
    .data-table-wrapper table.dataTable > tbody > tr.child span.dtr-title {
        margin-bottom: var(--space-1);
        font-size: 0.875rem;
    }
    .data-table-wrapper table.dataTable > tbody > tr.child span.dtr-data {
        font-size: 0.875rem;
        word-break: break-word;
    }
    .data-table-wrapper table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control:before,
    .data-table-wrapper table.dataTable.dtr-inline.collapsed > tbody > tr > th.dtr-control:before {
        border-radius: 4px;
        width: 24px;
        height: 24px;
        line-height: 24px;
        font-size: 14px;
        margin-right: 0;
    }
    .export-button-text { display: none !important; }
}

@media screen and (max-width: 576px) {
    .data-table-wrapper .page-link {
        padding: 0.25rem 0.5rem;
        font-size: 0.8125rem;
    }
    .data-table-wrapper table.dataTable > tbody > tr.child ul.dtr-details {
        padding: var(--space-2) var(--space-3);
    }
    .data-table-wrapper table.dataTable > tbody > tr.child span.dtr-title,
    .data-table-wrapper table.dataTable > tbody > tr.child span.dtr-data {
        font-size: 0.8125rem;
    }
    .data-table-wrapper table.dataTable.dtr-inline.collapsed > tbody > tr > td.dtr-control:before,
    .data-table-wrapper table.dataTable.dtr-inline.collapsed > tbody > tr > th.dtr-control:before {
        width: 20px;
        height: 20px;
        line-height: 20px;
        font-size: 12px;
    }
}

@media screen and (max-width: 480px) {
    .data-table-wrapper .dataTables_wrapper {
        width: 100%;
        overflow-x: auto;
    }
}

/* -- Admin index page chrome --------------------------------------------- */
/*
 * Shared helpers used by index views (campaign, donations, donors). Keep
 * view-specific column-hiding / nth-child rules in the views themselves;
 * everything below is mechanically identical across those pages.
 */
.admin-index input { margin-bottom: 0 !important; }
.admin-index select { padding: 7px 7px 3px 7px; }

.admin-index .modal-body { padding: 0; }

.admin-index__table-wrap { margin-top: var(--space-5); }
.admin-index__table {
    width: 100%;
    display: table;
    height: 1px;
    border-collapse: collapse;
}

.admin-index__filter-toggle {
    color: var(--color-text-muted);
    transition: transform 0.2s ease;
    cursor: pointer;
}
.admin-index__filter-divider {
    border-color: var(--color-border-subtle);
    margin: 1rem 0;
}
.btn-clear-all {
    white-space: nowrap;
    padding: 6px 12px;
}

@media screen and (max-width: 768px) {
    .admin-index-table { font-size: 0.875rem; }
    .admin-index-table th,
    .admin-index-table td { padding: 8px 6px; }
    .admin-index-table tr td:last-child a { padding-right: var(--space-3); }
}
@media screen and (max-width: 576px) {
    .admin-index-table { font-size: 0.8125rem; }
    .admin-index-table th,
    .admin-index-table td { padding: 6px 4px; }
    .data-table-wrapper .dataTables_wrapper .row,
    .data-table-wrapper .dataTables_wrapper .col-sm-12 { margin: 0; padding: 0; }
}
@media screen and (max-width: 480px) {
    .admin-index-table { min-width: 100%; }
}

/* -- Integration Modal Common Styles -------------------------------------- */
/*
 * Shared styles for all integration configuration modals
 * (Mailchimp, Meta Pixel, Bloomerang, Double the Donation, Meta Business)
 */

/* Message alerts */
.message-container {
    margin-bottom: var(--space-5);
    display: none;
}

.message-alert {
    padding: var(--space-3) var(--space-4);
    border-radius: 6px;
    margin-bottom: var(--space-3);
    position: relative;
    border: 1px solid;
}

.message-alert.success {
    background-color: var(--color-alert-success-bg);
    border-color: var(--color-alert-success-border);
    color: var(--color-alert-success-text);
}

.message-alert.error {
    background-color: var(--color-alert-danger-bg);
    border-color: var(--color-alert-danger-border);
    color: var(--color-alert-danger-text);
}

.message-alert.info {
    background-color: var(--color-alert-info-bg);
    border-color: var(--color-alert-info-border);
    color: var(--color-alert-info-text);
}

.message-alert .close-btn {
    position: absolute;
    top: 8px;
    right: 12px;
    background: none;
    border: none;
    font-size: 18px;
    cursor: pointer;
    color: inherit;
    opacity: 0.7;
}

.message-alert .close-btn:hover {
    opacity: 1;
}

/* Welcome/no-config state containers */
.no-api-key-container,
.no-pixel-id-container,
.no-keys-container {
    text-align: center;
    padding: var(--space-10) var(--space-5);
    min-height: 300px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.welcome-section {
    margin-bottom: 30px;
}

.welcome-section h3 {
    color: var(--color-text-strong);
    font-size: 20px;
    font-weight: 600;
    margin-bottom: 10px;
}

.welcome-section p {
    color: var(--color-text-secondary);
    margin-bottom: 0;
    font-size: 14px;
}

/* Form containers */
.api-key-form-centered,
.pixel-id-form-centered,
.keys-form {
    width: 100%;
    max-width: 400px;
}

.api-key-form-centered .form-group,
.pixel-id-form-centered .form-group,
.keys-form .form-group {
    margin-bottom: var(--space-5);
}

.api-key-form-centered input[type="text"],
.api-key-form-centered input[type="password"],
.pixel-id-form-centered input[type="text"],
.pixel-id-form-centered input[type="password"],
.keys-form input[type="text"],
.keys-form input[type="password"] {
    width: 100%;
    padding: var(--space-3) var(--space-4);
    border: 2px solid var(--color-border-light);
    border-radius: 6px;
    font-size: 14px;
    transition: border-color 0.15s ease-in-out;
}

.api-key-form-centered input:focus,
.pixel-id-form-centered input:focus,
.keys-form input:focus {
    outline: 0;
}

.help-text {
    color: var(--color-text-secondary);
    font-size: 12px;
    margin-top: var(--space-2);
    text-align: left;
}

/* Connected state */
.connected-container {
    padding: var(--space-5);
}

.account-info-section {
    background: var(--color-bg-light);
    border-radius: 8px;
    padding: var(--space-5);
    margin-bottom: var(--space-5);
    border: 1px solid var(--color-border-light);
}

/* Info items */
.info-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--color-border-light);
}

.info-item:last-child {
    border-bottom: none;
}

.info-label {
    font-weight: 500;
    color: var(--color-text-emphasis);
    font-size: 14px;
}

.info-value {
    color: var(--color-text-secondary);
    font-size: 14px;
}

/* Status badges */
.status-badge {
    display: inline-block;
    padding: var(--space-1) var(--space-3);
    border-radius: 4px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.status-connected {
    background-color: var(--color-alert-success-bg);
    color: var(--color-alert-success-text);
}

.status-disconnected {
    background-color: var(--color-alert-danger-bg);
    color: var(--color-alert-danger-text);
}

/* Disconnect section */
.disconnect-section {
    border-top: 1px solid var(--color-border-light);
    padding-top: var(--space-5);
    margin-top: var(--space-5);
    text-align: center;
}

.btn-disconnect {
    background: var(--color-danger);
    border: none;
    color: var(--color-text-on-dark);
    padding: 10px 20px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    transition: background-color 0.2s;
}

.btn-disconnect:hover {
    background: var(--color-danger-hover);
}

.btn-disconnect:disabled {
    background-color: var(--color-gray-disabled);
    cursor: not-allowed;
}

/* Section titles with icons */
.section-title-with-icon {
    margin-top: 0;
    margin-bottom: var(--space-4);
    color: var(--color-text-emphasis);
    display: flex;
    align-items: center;
    font-size: 16px;
    font-weight: 600;
}

.section-title-with-icon i {
    margin-right: var(--space-2);
    font-size: 18px;
}

/* Section titles without icons */
.section-title {
    margin-top: 0;
    margin-bottom: var(--space-3);
    color: var(--color-text-emphasis);
    font-size: 16px;
    font-weight: 600;
}


/* ------------------------------------------------------------------
   Salesforce connect: authentication-method chooser + JWT setup
   Two flows share one modal (OAuth browser consent, JWT server-to-server),
   so the chooser has to make the trade-off legible before anything is typed.
   ------------------------------------------------------------------ */
.auth-method-tabs {
    display: flex;
    gap: var(--space-2);
    margin-bottom: var(--space-5);
    border-bottom: 1px solid var(--color-border-light);
}

.auth-method-tab {
    appearance: none;
    background: none;
    border: 0;
    border-bottom: 2px solid transparent;
    padding: var(--space-3) var(--space-4);
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text-secondary);
    cursor: pointer;
}

.auth-method-tab:hover {
    color: var(--color-text-emphasis);
}

.auth-method-tab.is-active {
    color: var(--color-link);
    border-bottom-color: var(--color-link);
}

.auth-method-panel[hidden] {
    display: none;
}

/* Inline notices inside integration modals. Sized down from .message-alert:
   these are static explanatory copy, not dismissible feedback. */
.setup-notice {
    border: 1px solid var(--color-border-light);
    border-left: 3px solid var(--color-border-hover);
    border-radius: 4px;
    padding: var(--space-3) var(--space-4);
    font-size: 13px;
    line-height: 1.5;
    color: var(--color-text-emphasis);
    background: var(--color-bg-light);
    margin-bottom: var(--space-4);
}

.setup-notice--info {
    background: var(--color-blue-tint);
    border-color: var(--color-blue-border);
    border-left-color: var(--color-blue);
    color: var(--color-alert-info-text);
}

.setup-notice--warning {
    background: var(--color-bg-faint);
    border-color: var(--color-border-mid);
    border-left-color: var(--color-amber);
    color: var(--color-text-emphasis);
}

.setup-notice--error {
    background: var(--color-alert-danger-bg);
    border-color: var(--color-alert-danger-border);
    border-left-color: var(--color-danger);
    color: var(--color-alert-danger-text);
}

.setup-notice strong {
    display: block;
    margin-bottom: var(--space-1);
}

/* Ordered setup instructions handed to a Salesforce admin. */
.setup-steps {
    margin: var(--space-3) 0 var(--space-5);
    padding-left: var(--space-5);
    font-size: 13px;
    line-height: 1.6;
    color: var(--color-text-emphasis);
}

.setup-steps li {
    margin-bottom: var(--space-2);
}

.setup-steps code {
    background: var(--color-bg-light);
    border: 1px solid var(--color-border-light);
    border-radius: 3px;
    padding: 1px 4px;
    font-size: 12px;
}

/* Monospace echo of an opaque identifier (consumer key, username). */
.info-value--mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
    word-break: break-all;
}

/* ------------------------------------------------------------------
   Integration-modal building blocks.

   These replace inline styles that had been re-typing token values by
   hand — `color: #6c757d` is exactly --color-text-secondary and
   `color: #495057` is --color-text-emphasis — which is how the modal
   drifted from the rest of the admin UI in the first place.
   ------------------------------------------------------------------ */

/* Modal heading with the integration's logo beside the title. */
.modal-title--with-logo {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.integration-logo {
    height: 28px;
    width: auto;
}

/* Explanatory paragraph under a section title. */
.section-lede {
    color: var(--color-text-secondary);
    font-size: 13px;
    margin-bottom: var(--space-3);
}

/* Last element of a section, so the section's own padding does the spacing. */
.section-lede--flush {
    margin-bottom: 0;
}

/* One radio/checkbox choice in a settings list. */
.radio-option {
    margin-bottom: var(--space-2);
}

.radio-option .form-check-label {
    font-size: 14px;
    color: var(--color-text-emphasis);
}

/* A labelled control standing on its own inside a modal section. The
   .form-group rule above only applies inside .keys-form / .api-key-form-centered,
   so a bare .form-group out here silently falls through to the older
   definition in main.css and lands at the wrong size. */
.setting-group {
    margin-bottom: var(--space-4);
}

.setting-group > label {
    display: block;
    margin-bottom: var(--space-2);
    font-size: 14px;
    font-weight: 500;
    color: var(--color-text-emphasis);
}

/* Row of buttons, optionally trailed by an aria-live status line. */
.form-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-4);
}

/* Icon to the left of button text. 6px is deliberately off the 4px scale:
   it is what every button in these modals already used inline, and rounding
   to 8px would nudge a dozen buttons for no reason. */
.btn-icon-left {
    margin-right: 6px;
}

/* Primary connect button for integration modals. Previously inline-styled in
   views/salesforce/configure-modal.php; folded here so the two connect flows
   and the retry action share one definition. */
.btn-connect {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    width: 100%;
    background: var(--color-brand-salesforce);
    border: none;
    color: var(--color-text-on-dark);
    padding: var(--space-3) var(--space-6);
    border-radius: 6px;
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s ease-in-out;
}

.btn-connect:hover {
    background: var(--color-brand-salesforce-hover);
    color: var(--color-text-on-dark);
    text-decoration: none;
}

.btn-connect:disabled {
    background: var(--color-gray-disabled);
    cursor: not-allowed;
}

.btn-connect-secondary {
    display: block;
    text-align: center;
    margin-top: var(--space-3);
    color: var(--color-text-secondary);
    font-size: 13px;
    text-decoration: underline;
}

.keys-form label {
    display: block;
    margin-bottom: var(--space-2);
    font-size: 13px;
    font-weight: 500;
    color: var(--color-text-emphasis);
}

.keys-form .form-select {
    width: 100%;
    padding: var(--space-3) var(--space-4);
    border: 2px solid var(--color-border-light);
    border-radius: 6px;
    font-size: 14px;
}


.welcome-lede {
    color: var(--color-text-secondary);
    font-size: 14px;
    line-height: 1.55;
}

.icon-brand-salesforce {
    color: var(--color-brand-salesforce);
}

/* Empty-state container, form variant.
   The base .no-api-key-container centres its text and shrink-wraps its children
   (align-items: center) — right for a blurb plus one button, wrong for a setup
   flow with instructions, labelled fields and a tab bar. Those need a common
   left edge and a single full-bleed content width, or the numbered steps detach
   from their markers and each block finds its own width.
   Applied per-view; the six other integrations keep the centred base. */
.no-api-key-container--form {
    text-align: left;
    align-items: stretch;
    justify-content: flex-start;
    min-height: 0;
    padding: var(--space-6) var(--space-5);
}

.no-api-key-container--form .welcome-section {
    margin-bottom: var(--space-5);
}

/* Full-bleed so the tab bar's underline spans the panel rather than floating
   under just the two labels. */
.no-api-key-container--form .auth-method-tabs,
.no-api-key-container--form .auth-method-panel {
    width: 100%;
}

/* The base .keys-form caps at 400px for a single centred API-key field. Here it
   sits under full-width notices and steps, so that cap would leave a ragged
   right edge halfway across the modal. */
.no-api-key-container--form .keys-form {
    max-width: none;
}

/* Shrink to its label and stay on the left edge, under the steps it follows. */
.sf-cert-download {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    align-self: flex-start;
    margin-bottom: var(--space-5);
}

/* Toggle row with the label on the left and the switch pushed to the right
   edge, so a column of switches lines up regardless of label length. */
.switch-wrapper--between {
    justify-content: space-between;
}

/* -- OAuth consent / error pages ------------------------------------------ */

/*
 * loginLayout centres its content with a flex parent, so a plain .container
 * shrink-wraps to its text: the short error page collapsed to a ~150px column
 * while the long consent page happened to look fine. Pin the width here so both
 * pages render at the same size regardless of how much copy they hold.
 */
.oauth-page {
    width: min(640px, calc(100vw - var(--space-8)));
    margin: var(--space-8) auto;
}

/* .info-value--mono sets word-break, but <pre>'s white-space: pre overrides it,
   so a long redirect_uri or a sentence-length note runs off the card edge. The
   detail is copy-pasteable config text, so keep its line breaks — just wrap. */
.oauth-page pre.info-value--mono {
    white-space: pre-wrap;
    /* break-all would split ordinary words mid-letter; overflow-wrap only kicks
       in for tokens that genuinely cannot fit, like a long redirect_uri. */
    word-break: normal;
    overflow-wrap: anywhere;
    margin-bottom: 0;
}

/* ---------------------------------------------------------------------------
   Outbound webhooks — health pills, signing secret, delivery log
   ------------------------------------------------------------------------ */

.webhook-health {
    display: inline-block;
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-sm);
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    white-space: nowrap;
}

.webhook-health--healthy {
    background-color: var(--color-alert-success-bg);
    color: var(--color-alert-success-text);
}
.webhook-health--failing {
    background-color: var(--color-alert-warning-bg);
    color: var(--color-alert-warning-text);
}
.webhook-health--disabled {
    background-color: var(--color-alert-danger-bg);
    color: var(--color-alert-danger-text);
}
.webhook-health--inactive {
    background-color: var(--color-bg-light);
    color: var(--color-text-secondary);
}
.webhook-health--new {
    background-color: var(--color-alert-info-bg);
    color: var(--color-alert-info-text);
}

/* Read-only credential with a copy button beside it. */
.secret-field {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}
.secret-field input {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xs);
    background-color: var(--color-bg-light);
}

/* JSON bodies and response snippets. Scrolls in its own box — a 4KB payload
   must not widen the page. */
.payload-view {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xs);
    background-color: var(--color-bg-light);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-sm);
    padding: var(--space-3);
    max-height: 320px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-word;
    margin: 0;
}

.webhook-meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-6);
    font-size: var(--font-size-sm);
    color: var(--color-text-secondary);
}

/* Response code in the delivery table: legible at a glance without a pill. */
.delivery-code {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xs);
}
.delivery-code--ok { color: var(--color-alert-success-text); }
.delivery-code--bad { color: var(--color-alert-danger-text); }

/* ---------------------------------------------------------------------------
   Email preview surface
   ---------------------------------------------------------------------------
   Renders an email body the way the recipient will actually see it, NOT the way
   the admin page would style it. Deliberately not on the design tokens: it has
   to mirror mail/layouts/html-wide.php, which sets Helvetica Neue / 14px / 1.6
   and is what the mail client receives.

   Two rules keep it honest:
   - Bootstrap sizes h2/h3 for a page, which made the same heading render large
     in the preview and small in the editor. The heading and margin values below
     are the browser defaults an email client applies, expressed against the
     14px base so both panes agree.
   - The TinyMCE `content_style` on the event template editors is kept in sync
     with this block by hand. Change one, change the other, or the editor and
     the preview drift apart again.
   ------------------------------------------------------------------------- */
.email-surface {
    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    font-size: 14px;
    line-height: 1.6;
    color: #333;
}
/* Admin CSS sets font-family on h2/h3/p directly, which beats inheriting from
   the container -- so the panes matched on size but not typeface until this.
   The caption is excluded because it is admin chrome, not email content. */
.email-surface *:not(.email-locked-note) {
    font-family: inherit;
}
.email-surface h1 { font-size: 2em;    font-weight: bold; margin: 0.67em 0; line-height: 1.3; }
.email-surface h2 { font-size: 1.5em;  font-weight: bold; margin: 0.83em 0; line-height: 1.3; }
.email-surface h3 { font-size: 1.17em; font-weight: bold; margin: 1em 0;    line-height: 1.3; }
.email-surface h4 { font-size: 1em;    font-weight: bold; margin: 1.33em 0; line-height: 1.3; }
.email-surface p  { margin: 0 0 10px; }
.email-surface ul,
.email-surface ol { margin: 0 0 10px; padding-left: 40px; }
.email-surface table { border-collapse: collapse; }

/* The "added automatically" caption sits inside .email-surface but is admin
   chrome, not part of the email — keep it on the admin type scale. */
.email-locked-note {
    font-family: var(--font-family-base);
    font-size: var(--font-size-xs);
    color: var(--color-text-secondary);
    margin-bottom: var(--space-2);
}

/* -- Page tabs (module sub-navigation) ------------------------------------ */

.page-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    border-bottom: 1px solid var(--color-border-subtle);
    margin-bottom: var(--space-4);
}

.page-tabs__link {
    padding: var(--space-2) var(--space-3);
    font-size: var(--font-size-sm);
    color: var(--color-text-secondary);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    white-space: nowrap;
}

.page-tabs__link:hover {
    color: var(--color-text-strong);
    background: var(--color-bg-light);
}

.page-tabs__link--active {
    color: var(--color-accent-navy);
    border-bottom-color: var(--color-accent-navy);
    font-weight: 500;
}
