/**
 * MOJO Framework Core Styles
 * Essential utilities and animations for MOJO framework
 * Version: 2.0.0
 *
 * Note: This file contains only core MOJO utilities not provided by Bootstrap 5.
 * Bootstrap 5 is required as a dependency for base styles.
 */

/* ========================================================================
   MOJO CSS Custom Properties
   ======================================================================== */

:root {
    /* === Core Theme Colors === */
    --bs-primary: #1a73e8;
    --bs-secondary: #5f6368;
    --bs-success: #34a853;
    --bs-info: #4285f4;
    --bs-warning: #fbbc05;
    --bs-danger: #ea4335;
    --bs-light: #f1f3f4;
    --bs-dark: #202124;

    /* === Subtle Backgrounds === */
    --bs-primary-bg-subtle: #e8f0fe;
    --bs-secondary-bg-subtle: #f1f3f4;
    --bs-success-bg-subtle: #e6f4ea;
    --bs-info-bg-subtle: #e8f0fe;
    --bs-warning-bg-subtle: #fef7e0;
    --bs-danger-bg-subtle: #fce8e6;

    /* === Subtle Borders === */
    --bs-primary-border-subtle: #aecbfa;
    --bs-secondary-border-subtle: #dadce0;
    --bs-success-border-subtle: #81c995;
    --bs-info-border-subtle: #aecbfa;
    --bs-warning-border-subtle: #fad2cf;
    --bs-danger-border-subtle: #f28b82;

    /* === Text Emphasis === */
    --bs-primary-text-emphasis: #174ea6;
    --bs-secondary-text-emphasis: #3c4043;
    --bs-success-text-emphasis: #0d652d;
    --bs-info-text-emphasis: #174ea6;
    --bs-warning-text-emphasis: #b06000;
    --bs-danger-text-emphasis: #a50e0e;

    --bs-btn-hover-bg: #e8f0fe;
}

:root[data-bs-theme="ocean"] {
    --bs-primary: #0077b6;
    --bs-secondary: #90e0ef;
    --bs-success: #00b4d8;
    --bs-info: #48cae4;
    --bs-warning: #ffd166;
    --bs-danger: #ef476f;
    --bs-light: #f1faff;
    --bs-dark: #03045e;

    --bs-primary-bg-subtle: #caf0f8;
    --bs-secondary-bg-subtle: #e0fbfc;
    --bs-success-bg-subtle: #ade8f4;
    --bs-info-bg-subtle: #caf0f8;
    --bs-warning-bg-subtle: #fff3cd;
    --bs-danger-bg-subtle: #fde2e4;

    --bs-primary-text-emphasis: #023e8a;
    --bs-success-text-emphasis: #0077b6;
    --bs-danger-text-emphasis: #9d0208;
}

:root[data-bs-theme="sunrise"] {
    --bs-primary: #ff6f00;
    --bs-secondary: #ffb703;
    --bs-success: #fb8500;
    --bs-info: #ffb4a2;
    --bs-warning: #ffd166;
    --bs-danger: #e63946;
    --bs-light: #fff3e6;
    --bs-dark: #432818;

    --bs-primary-bg-subtle: #fff4e1;
    --bs-secondary-bg-subtle: #fff8dc;
    --bs-success-bg-subtle: #ffe5b4;
    --bs-info-bg-subtle: #ffe0d9;
    --bs-warning-bg-subtle: #fff7d6;
    --bs-danger-bg-subtle: #fddede;

    --bs-primary-text-emphasis: #9d4b00;
    --bs-success-text-emphasis: #a85d00;
    --bs-danger-text-emphasis: #8d0000;
}

:root[data-bs-theme="forest"] {
    --bs-primary: #2b9348;
    --bs-secondary: #95d5b2;
    --bs-success: #55a630;
    --bs-info: #76c893;
    --bs-warning: #ffba08;
    --bs-danger: #d62828;
    --bs-light: #f0fdf4;
    --bs-dark: #081c15;

    --bs-primary-bg-subtle: #d8f3dc;
    --bs-secondary-bg-subtle: #e9f5eb;
    --bs-success-bg-subtle: #c7f9cc;
    --bs-info-bg-subtle: #e9fbee;
    --bs-warning-bg-subtle: #fff8e1;
    --bs-danger-bg-subtle: #ffe5e5;

    --bs-primary-text-emphasis: #1a472a;
    --bs-success-text-emphasis: #2f5233;
    --bs-danger-text-emphasis: #7a1a1a;
}

:root[data-bs-theme="midnight"] {
    --bs-primary: #5a189a;
    --bs-secondary: #7b2cbf;
    --bs-success: #06d6a0;
    --bs-info: #118ab2;
    --bs-warning: #ffd166;
    --bs-danger: #ef476f;
    --bs-light: #f8f9fa;
    --bs-dark: #03071e;

    --bs-primary-bg-subtle: #e0d4f7;
    --bs-secondary-bg-subtle: #f1e4ff;
    --bs-success-bg-subtle: #d0fdf2;
    --bs-info-bg-subtle: #d0ebff;
    --bs-warning-bg-subtle: #fff3cd;
    --bs-danger-bg-subtle: #fbdde2;

    --bs-primary-text-emphasis: #240046;
    --bs-success-text-emphasis: #056b53;
    --bs-danger-text-emphasis: #9d001f;
}

:root[data-bs-theme="corporate"] {
    /* Core brand accent */
    --bs-primary: #2a5d9f; /* Corporate blue */
    --bs-secondary: #6c757d; /* Neutral gray */
    --bs-success: #4caf50; /* Green for positive states */
    --bs-info: #17a2b8; /* Teal info */
    --bs-warning: #f0ad4e; /* Amber warning */
    --bs-danger: #dc3545; /* Red for errors */
    --bs-light: #f8f9fa; /* Light background */
    --bs-dark: #212529; /* Dark text/UI */

    /* Subtle backgrounds */
    --bs-primary-bg-subtle: #e7f0fa;
    --bs-secondary-bg-subtle: #f1f3f5;
    --bs-success-bg-subtle: #eaf6ec;
    --bs-info-bg-subtle: #e6f7fa;
    --bs-warning-bg-subtle: #fff4e0;
    --bs-danger-bg-subtle: #fcebec;

    /* Subtle borders */
    --bs-primary-border-subtle: #c2d7ed;
    --bs-secondary-border-subtle: #dee2e6;
    --bs-success-border-subtle: #c8e6c9;
    --bs-info-border-subtle: #bde3ea;
    --bs-warning-border-subtle: #ffe0b2;
    --bs-danger-border-subtle: #f5c2c7;

    /* Text emphasis */
    --bs-primary-text-emphasis: #1d3f6e;
    --bs-secondary-text-emphasis: #495057;
    --bs-success-text-emphasis: #2e7d32;
    --bs-info-text-emphasis: #0d6673;
    --bs-warning-text-emphasis: #a46900;
    --bs-danger-text-emphasis: #8a1c24;
}

/* Framework dark theme — deep mission-control surfaces.
   Re-skins Bootstrap's dark-mode tokens so every dark page in a consuming
   app reads as NOC tooling instead of the default washed-out gray.
   No !important — downstream apps that set their own --bs-body-bg etc.
   under [data-bs-theme="dark"] still win on source order. */
:root[data-bs-theme="dark"] {
    --bs-body-bg:                  #0a0d11;
    --bs-tertiary-bg:              #11161d;
    --bs-secondary-bg:             #161b22;
    --bs-border-color:             #1f2630;
    --bs-border-color-translucent: rgba(255, 255, 255, 0.04);
    --bs-emphasis-color:           #e6ecf3;
    --bs-secondary-color:          #8a96a6;
}

:root {
    /* MOJO Framework Colors - Inherit from Bootstrap */
    --mojo-primary: var(--bs-primary);
    --mojo-primary-rgb: var(--bs-primary-rgb);
    --mojo-secondary: var(--bs-secondary);
    --mojo-secondary-rgb: var(--bs-secondary-rgb);
    --mojo-success: var(--bs-success);
    --mojo-success-rgb: var(--bs-success-rgb);
    --mojo-info: var(--bs-info);
    --mojo-info-rgb: var(--bs-info-rgb);
    --mojo-warning: var(--bs-warning);
    --mojo-warning-rgb: var(--bs-warning-rgb);
    --mojo-danger: var(--bs-danger);
    --mojo-danger-rgb: var(--bs-danger-rgb);
    --mojo-light: var(--bs-light);
    --mojo-light-rgb: var(--bs-light-rgb);
    --mojo-dark: var(--bs-dark);
    --mojo-dark-rgb: var(--bs-dark-rgb);

    /* MOJO Semantic Colors - Use Bootstrap's color system */
    --mojo-body-bg: var(--bs-body-bg);
    --mojo-body-color: var(--bs-body-color);
    --mojo-emphasis-color: var(--bs-emphasis-color);
    --mojo-secondary-color: var(--bs-secondary-color);
    --mojo-tertiary-color: var(--bs-tertiary-color);

    /* MOJO Background System */
    --mojo-bg-primary: var(--bs-body-bg);
    --mojo-bg-secondary: var(--bs-secondary-bg);
    --mojo-bg-tertiary: var(--bs-tertiary-bg);

    /* MOJO Border System */
    --mojo-border-color: var(--bs-border-color);
    --mojo-border-color-translucent: var(--bs-border-color-translucent);

    /* MOJO Interactive States */
    --mojo-hover-bg: var(--bs-secondary-bg);
    --mojo-active-bg: var(--bs-primary);
    --mojo-focus-color: var(--bs-primary);
    --mojo-focus-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);

    /* MOJO Transition defaults */
    --mojo-transition-fast: 0.15s ease-in-out;
    --mojo-transition-base: 0.2s ease-in-out;
    --mojo-transition-slow: 0.3s ease-in-out;

    /* MOJO Border radius - Use Bootstrap system */
    --mojo-border-radius-sm: var(--bs-border-radius-sm);
    --mojo-border-radius: var(--bs-border-radius);
    --mojo-border-radius-lg: var(--bs-border-radius-lg);
    --mojo-border-radius-xl: var(--bs-border-radius-xl);

    /* MOJO Spacing - Use Bootstrap spacing system */
    --mojo-spacer-xs: calc(var(--bs-spacer) * 0.25);
    --mojo-spacer-sm: calc(var(--bs-spacer) * 0.5);
    --mojo-spacer: var(--bs-spacer);
    --mojo-spacer-lg: calc(var(--bs-spacer) * 1.5);
    --mojo-spacer-xl: calc(var(--bs-spacer) * 3);

    /* MOJO Typography - Use Bootstrap font system */
    --mojo-font-sans-serif: var(--bs-font-sans-serif);
    --mojo-font-monospace: var(--bs-font-monospace);

    /* MOJO Box Shadows - Use Bootstrap shadow system */
    --mojo-box-shadow-sm: var(--bs-box-shadow-sm);
    --mojo-box-shadow: var(--bs-box-shadow);
    --mojo-box-shadow-lg: var(--bs-box-shadow-lg);

    /* MOJO Z-index layers - Use Bootstrap z-index system */
    --mojo-zindex-dropdown: var(--bs-zindex-dropdown, 1000);
    --mojo-zindex-sticky: var(--bs-zindex-sticky, 1020);
    --mojo-zindex-fixed: var(--bs-zindex-fixed, 1030);
    --mojo-zindex-modal-backdrop: var(--bs-zindex-modal-backdrop, 1040);
    --mojo-zindex-offcanvas: var(--bs-zindex-offcanvas, 1045);
    --mojo-zindex-modal: var(--bs-zindex-modal, 1050);
    --mojo-zindex-popover: var(--bs-zindex-popover, 1070);
    --mojo-zindex-tooltip: var(--bs-zindex-tooltip, 1080);
}

/* =========================================================
   Primary-driven components (Bootstrap 5.3+)
   Put this AFTER bootstrap.css. Do not scope it.
   Switching themes = only change --bs-primary (and optional subtle vars).
   ========================================================= */

/* Buttons (solid) */
/* =========================================================
   Buttons tied to theme tokens (Bootstrap 5.3+)
   Put AFTER bootstrap.css
   ========================================================= */

/* Primary */
.btn-primary {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--bs-primary);
    --bs-btn-border-color: var(--bs-primary);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: color-mix(in srgb, var(--bs-primary) 88%, #000 12%);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--bs-primary) 82%, #000 18%);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: color-mix(in srgb, var(--bs-primary) 75%, #000 25%);
    --bs-btn-active-border-color: color-mix(in srgb, var(--bs-primary) 72%, #000 28%);
    --bs-btn-focus-shadow-rgb: var(--bs-primary-rgb, 13, 110, 253);
}

/* Success */
.btn-success {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--bs-success);
    --bs-btn-border-color: var(--bs-success);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: color-mix(in srgb, var(--bs-success) 88%, #000 12%);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--bs-success) 82%, #000 18%);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: color-mix(in srgb, var(--bs-success) 75%, #000 25%);
    --bs-btn-active-border-color: color-mix(in srgb, var(--bs-success) 72%, #000 28%);
    --bs-btn-focus-shadow-rgb: var(--bs-success-rgb, 25, 135, 84);
}

/* Danger */
.btn-danger {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--bs-danger);
    --bs-btn-border-color: var(--bs-danger);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: color-mix(in srgb, var(--bs-danger) 88%, #000 12%);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--bs-danger) 82%, #000 18%);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: color-mix(in srgb, var(--bs-danger) 75%, #000 25%);
    --bs-btn-active-border-color: color-mix(in srgb, var(--bs-danger) 72%, #000 28%);
    --bs-btn-focus-shadow-rgb: var(--bs-danger-rgb, 220, 53, 69);
}

/* Warning */
.btn-warning {
    --bs-btn-color: #000;
    --bs-btn-bg: var(--bs-warning);
    --bs-btn-border-color: var(--bs-warning);
    --bs-btn-hover-color: #000;
    --bs-btn-hover-bg: color-mix(in srgb, var(--bs-warning) 88%, #000 12%);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--bs-warning) 82%, #000 18%);
    --bs-btn-active-color: #000;
    --bs-btn-active-bg: color-mix(in srgb, var(--bs-warning) 75%, #000 25%);
    --bs-btn-active-border-color: color-mix(in srgb, var(--bs-warning) 72%, #000 28%);
    --bs-btn-focus-shadow-rgb: var(--bs-warning-rgb, 255, 193, 7);
}

/* Info */
.btn-info {
    --bs-btn-color: #000;
    --bs-btn-bg: var(--bs-info);
    --bs-btn-border-color: var(--bs-info);
    --bs-btn-hover-color: #000;
    --bs-btn-hover-bg: color-mix(in srgb, var(--bs-info) 88%, #000 12%);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--bs-info) 82%, #000 18%);
    --bs-btn-active-color: #000;
    --bs-btn-active-bg: color-mix(in srgb, var(--bs-info) 75%, #000 25%);
    --bs-btn-active-border-color: color-mix(in srgb, var(--bs-info) 72%, #000 28%);
    --bs-btn-focus-shadow-rgb: var(--bs-info-rgb, 13, 202, 240);
}

/* Secondary */
.btn-secondary {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--bs-secondary);
    --bs-btn-border-color: var(--bs-secondary);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: color-mix(in srgb, var(--bs-secondary) 88%, #000 12%);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--bs-secondary) 82%, #000 18%);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: color-mix(in srgb, var(--bs-secondary) 75%, #000 25%);
    --bs-btn-active-border-color: color-mix(in srgb, var(--bs-secondary) 72%, #000 28%);
    --bs-btn-focus-shadow-rgb: var(--bs-secondary-rgb, 108, 117, 125);
}

/* Buttons (outline) */
.btn-outline-primary {
    --bs-btn-color: var(--bs-primary);
    --bs-btn-border-color: var(--bs-primary);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--bs-primary);
    --bs-btn-hover-border-color: var(--bs-primary);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: color-mix(in srgb, var(--bs-primary) 75%, #000 25%);
    --bs-btn-active-border-color: color-mix(in srgb, var(--bs-primary) 75%, #000 25%);
    --bs-btn-focus-shadow-rgb: var(--bs-primary-rgb, 13, 110, 253);
}

/* Optional: make the plain .btn use primary by default (comment out if you don't want this) */
/*
.btn {
  --bs-btn-color:              #fff;
  --bs-btn-bg:                 var(--bs-primary);
  --bs-btn-border-color:       var(--bs-primary);
  --bs-btn-hover-color:        #fff;
  --bs-btn-hover-bg:           color-mix(in srgb, var(--bs-primary) 88%, #000 12%);
  --bs-btn-hover-border-color: color-mix(in srgb, var(--bs-primary) 82%, #000 18%);
  --bs-btn-active-color:       #fff;
  --bs-btn-active-bg:          color-mix(in srgb, var(--bs-primary) 75%, #000 25%);
  --bs-btn-active-border-color:color-mix(in srgb, var(--bs-primary) 72%, #000 28%);
  --bs-btn-focus-shadow-rgb:   var(--bs-primary-rgb, 13,110,253);
}
*/

/* Pagination */
.pagination {
    --bs-pagination-color: var(--bs-primary);
    --bs-pagination-hover-color: color-mix(in srgb, var(--bs-primary) 85%, #000 15%);
    --bs-pagination-focus-color: var(--bs-primary);
    --bs-pagination-focus-box-shadow: 0 0 0 0.25rem
        color-mix(in srgb, var(--bs-primary) 25%, transparent);
    --bs-pagination-active-color: #fff;
    --bs-pagination-active-bg: var(--bs-primary);
    --bs-pagination-active-border-color: var(--bs-primary);
    --bs-pagination-disabled-color: var(--bs-secondary, #6c757d);
}

.btn-link {
    text-decoration: none;
}

.btn-link:hover {
    text-decoration: underline;
    background-color: transparent;
    border-color: none;
}

/* ========================================================================
   Soft badges by default
   ========================================================================
   web-mojo softens Bootstrap's default loud badges to a tinted-pill look
   that matches modern design systems (Linear / Stripe / Vercel). The
   variant CSS variables are remapped to use Bootstrap's `*-bg-subtle` +
   `*-text-emphasis` tokens, so any consumer writing `<span class="badge
   bg-primary">` or `<span class="badge text-bg-success">` automatically
   picks up the soft look — no markup change required.

   For the rare attention case (notification dots, critical alerts,
   call-to-action chips) opt into the loud variant with `.badge-loud`.
*/
.badge {
    border-radius: 999px;          /* pill shape */
    font-weight: 600;
    padding: 0.3em 0.7em;
    border: 1px solid transparent; /* keeps height stable when a caller adds `border` */
}

.badge.bg-primary,
.badge.text-bg-primary {
    --bs-badge-color: var(--bs-primary-text-emphasis);
    --bs-badge-bg:    var(--bs-primary-bg-subtle);
    background-color: var(--bs-primary-bg-subtle) !important;
    color:            var(--bs-primary-text-emphasis) !important;
    border-color:     transparent;
}
.badge.bg-secondary,
.badge.text-bg-secondary {
    background-color: var(--bs-secondary-bg-subtle) !important;
    color:            var(--bs-secondary-text-emphasis) !important;
    border-color:     transparent;
}
.badge.bg-success,
.badge.text-bg-success {
    background-color: var(--bs-success-bg-subtle) !important;
    color:            var(--bs-success-text-emphasis) !important;
    border-color:     transparent;
}
.badge.bg-danger,
.badge.text-bg-danger {
    background-color: var(--bs-danger-bg-subtle) !important;
    color:            var(--bs-danger-text-emphasis) !important;
    border-color:     transparent;
}
.badge.bg-warning,
.badge.text-bg-warning {
    background-color: var(--bs-warning-bg-subtle) !important;
    color:            var(--bs-warning-text-emphasis) !important;
    border-color:     transparent;
}
.badge.bg-info,
.badge.text-bg-info {
    background-color: var(--bs-info-bg-subtle) !important;
    color:            var(--bs-info-text-emphasis) !important;
    border-color:     transparent;
}
.badge.bg-light,
.badge.text-bg-light {
    background-color: var(--bs-tertiary-bg) !important;
    color:            var(--bs-body-color) !important;
    border-color:     transparent;
}
.badge.bg-dark,
.badge.text-bg-dark {
    background-color: var(--bs-emphasis-bg, var(--bs-secondary-bg)) !important;
    color:            var(--bs-emphasis-color, var(--bs-body-color)) !important;
    border-color:     transparent;
}

/*
 * Loud opt-in: restore Bootstrap's solid-color attention treatment for cases
 * where you really do want a punchy badge (notification dots, critical alerts).
 * Apply alongside any `bg-*` / `text-bg-*` class — the loud rule wins on
 * specificity.
 */
.badge.badge-loud.bg-primary,   .badge.badge-loud.text-bg-primary   { background-color: var(--bs-primary)   !important; color: #fff !important; border-color: transparent; }
.badge.badge-loud.bg-secondary, .badge.badge-loud.text-bg-secondary { background-color: var(--bs-secondary) !important; color: #fff !important; border-color: transparent; }
.badge.badge-loud.bg-success,   .badge.badge-loud.text-bg-success   { background-color: var(--bs-success)   !important; color: #fff !important; border-color: transparent; }
.badge.badge-loud.bg-danger,    .badge.badge-loud.text-bg-danger    { background-color: var(--bs-danger)    !important; color: #fff !important; border-color: transparent; }
.badge.badge-loud.bg-warning,   .badge.badge-loud.text-bg-warning   { background-color: var(--bs-warning)   !important; color: #000 !important; border-color: transparent; }
.badge.badge-loud.bg-info,      .badge.badge-loud.text-bg-info      { background-color: var(--bs-info)      !important; color: #000 !important; border-color: transparent; }

/* Nav pills & tabs */
.nav-pills {
    --bs-nav-pills-link-active-bg: var(--bs-primary);
    --bs-nav-pills-link-active-color: #fff;
}
.nav-tabs {
    --bs-nav-tabs-link-hover-border-color: color-mix(in srgb, var(--bs-primary) 35%, transparent);
    --bs-nav-tabs-link-active-color: var(--bs-primary);
    --bs-nav-tabs-link-active-border-color: var(--bs-primary);
}

.nav-tabs .nav-link {
    color: var(--bs-secondary);
}

.nav-tabs .nav-link.active {
    border-top-color: rgb(26, 115, 232);
    border-right-color: rgb(26, 115, 232);
    border-bottom-color: transparent;
    border-left-color: rgb(26, 115, 232);
}

/* ========================================================================
   TabView Component Styles
   ======================================================================== */

/*
 * Style for the 'select' mode dropdown in the TabView component.
 * These styles mimic the appearance of a Bootstrap .form-select element
 * to provide a consistent look and feel with standard form inputs.
 */
.tab-view-select-style {
    display: inline-flex; /* Use inline-flex to allow the button to size to its content */
    align-items: center; /* Vertically align the label and chevron */

    /* Mimic Bootstrap .form-select styles for appearance */
    padding: 0.375rem 2.25rem 0.375rem 0.75rem;
    font-size: 1rem;
    font-weight: 400;
    line-height: 1.5;
    color: var(--bs-body-color);
    background-color: var(--bs-body-bg);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    background-size: 16px 12px;
    border-top: 1px solid var(--bs-border-color);
    border-right: 1px solid var(--bs-border-color);
    border-left: 1px solid var(--bs-border-color);
    border-top-left-radius: var(--bs-border-radius);
    border-top-right-radius: var(--bs-border-radius);
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    transition:
        border-color 0.15s ease-in-out,
        box-shadow 0.15s ease-in-out;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
}

/* The .dropdown-toggle class adds its own chevron, which we don't want. */
/* This rule hides the default Bootstrap chevron so we can use our own background-image version. */
.tab-view-select-style::after {
    display: none;
}

/* Hover state - slightly darken the border like a real input */
.tab-view-select-style:hover {
    border-color: var(--bs-secondary-border-subtle);
}

/* Focus state - mimic Bootstrap's standard focus ring */
.tab-view-select-style:focus {
    border-color: var(--bs-primary);
    outline: 0;
    box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
}

/* The text label inside the button */
.tab-view-select-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Alerts (optional, stays tied to primary) */
.alert-primary {
    --bs-alert-color: var(
        --bs-primary-text-emphasis,
        color-mix(in srgb, var(--bs-primary) 35%, #000)
    );
    --bs-alert-bg: var(--bs-primary-bg-subtle, color-mix(in srgb, var(--bs-primary) 10%, #fff));
    --bs-alert-border-color: var(
        --bs-primary-border-subtle,
        color-mix(in srgb, var(--bs-primary) 25%, #fff)
    );
}

/* Links (so the whole site “feels” primary) */
:root {
    --bs-link-color: var(--bs-primary);
    --bs-link-hover-color: color-mix(in srgb, var(--bs-primary) 85%, #000 15%);
}

.form-check {
    margin-top: 0.9rem;
}

/* ========================================================================
   TabView Variants — modern visual treatments
   ========================================================================
   Hook classes emitted by `TabView.VARIANT_CLASSES` (see TabView.js).
   `'traditional'` reuses the existing `.nav-tabs` rules above — no block
   in this section. All `[data-bs-theme="dark"]` overrides cluster at the
   bottom of the section, per `.claude/rules/theming.md`.
*/

/* Shared neutral baseline — every variant starts from the same nav-link
   reset so none of Bootstrap's nav-tabs side-effects leak in. */
.tab-view-variant-minimal,
.tab-view-variant-underline,
.tab-view-variant-underline-all,
.tab-view-variant-pills,
.tab-view-variant-pills-solid,
.tab-view-variant-segmented,
.tab-view-variant-btn-group {
    border-bottom: 0;
    gap: 0.25rem;
}

.tab-view-variant-minimal .nav-link,
.tab-view-variant-underline .nav-link,
.tab-view-variant-underline-all .nav-link,
.tab-view-variant-pills .nav-link,
.tab-view-variant-pills-solid .nav-link,
.tab-view-variant-segmented .nav-link,
.tab-view-variant-btn-group .nav-link {
    border: 0;
    background: transparent;
    color: var(--bs-secondary-color);
    padding: 0.4rem 0.85rem;
    font-weight: 500;
    border-radius: var(--bs-border-radius);
    transition: color 0.12s ease, background-color 0.12s ease;
}

.tab-view-variant-minimal .nav-link:focus-visible,
.tab-view-variant-underline .nav-link:focus-visible,
.tab-view-variant-underline-all .nav-link:focus-visible,
.tab-view-variant-pills .nav-link:focus-visible,
.tab-view-variant-pills-solid .nav-link:focus-visible,
.tab-view-variant-segmented .nav-link:focus-visible,
.tab-view-variant-btn-group .nav-link:focus-visible {
    outline: 0;
    box-shadow: 0 0 0 0.2rem rgba(var(--bs-primary-rgb), 0.25);
    z-index: 1;
}

.tab-view-variant-minimal .nav-link.disabled,
.tab-view-variant-underline .nav-link.disabled,
.tab-view-variant-underline-all .nav-link.disabled,
.tab-view-variant-pills .nav-link.disabled,
.tab-view-variant-pills-solid .nav-link.disabled,
.tab-view-variant-segmented .nav-link.disabled,
.tab-view-variant-btn-group .nav-link.disabled,
.tab-view-variant-minimal .nav-link:disabled,
.tab-view-variant-underline .nav-link:disabled,
.tab-view-variant-underline-all .nav-link:disabled,
.tab-view-variant-pills .nav-link:disabled,
.tab-view-variant-pills-solid .nav-link:disabled,
.tab-view-variant-segmented .nav-link:disabled,
.tab-view-variant-btn-group .nav-link:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* --- minimal: text-only, primary on active, no border or underline ----- */
.tab-view-variant-minimal .nav-link:hover {
    color: var(--bs-primary);
    background: rgba(0, 0, 0, 0.04);
}
.tab-view-variant-minimal .nav-link.active {
    color: var(--bs-primary);
    background: transparent;
    font-weight: 600;
}

/* --- underline: clean primary underline under active label only -------- */
.tab-view-variant-underline .nav-link {
    /* reserve space for the underline so hover/active don't shift layout */
    padding-bottom: calc(0.4rem + 2px);
    border-bottom: 2px solid transparent;
    border-radius: 0;
}
.tab-view-variant-underline .nav-link:hover {
    color: var(--bs-primary);
}
.tab-view-variant-underline .nav-link.active {
    color: var(--bs-primary);
    border-bottom-color: var(--bs-primary);
    font-weight: 600;
}

/* --- underline-all: continuous 2px line across the whole bar; the active
       tab's segment paints in primary by overlaying the bar's bottom
       border at the same y-position (Bootstrap nav-tabs-style overlap).
*/
.tab-view-variant-underline-all {
    border-bottom: 2px solid var(--bs-border-color);
}
.tab-view-variant-underline-all .nav-link {
    /* extend the link 2px past its parent so its own border-bottom sits
       directly on top of the bar's border-bottom — no double line */
    margin-bottom: -2px;
    border-bottom: 2px solid transparent;
    border-radius: 0;
}
.tab-view-variant-underline-all .nav-link:hover {
    color: var(--bs-primary);
}
.tab-view-variant-underline-all .nav-link.active {
    color: var(--bs-primary);
    border-bottom-color: var(--bs-primary);
    font-weight: 600;
}

/* --- pills: soft pill on active, no border ----------------------------- */
.tab-view-variant-pills .nav-link:hover {
    color: var(--bs-primary);
    background: rgba(0, 0, 0, 0.04);
}
.tab-view-variant-pills .nav-link.active {
    color: var(--bs-primary);
    background: var(--bs-primary-bg-subtle);
    font-weight: 600;
}

/* --- pills-solid: solid primary pill on active, no border -------------- */
.tab-view-variant-pills-solid .nav-link:hover {
    color: var(--bs-primary);
    background: rgba(0, 0, 0, 0.04);
}
.tab-view-variant-pills-solid .nav-link.active {
    color: #fff;
    background: var(--bs-primary);
    font-weight: 600;
}
.tab-view-variant-pills-solid .nav-link.active:hover {
    /* keep the solid fill visible on hover */
    color: #fff;
    background: color-mix(in srgb, var(--bs-primary) 90%, #000 10%);
}

/* --- segmented: connected, neutral container, solid primary active -----
   No padding inside the container — the active tab fills its slot edge
   to edge. First/last buttons inherit the container's outer rounding so
   the curve reads as one shape. (Bootstrap btn-group corner pattern.)
*/
.tab-view-variant-segmented {
    display: inline-flex;
    gap: 0;
    background: var(--bs-secondary-bg);
    border-radius: var(--bs-border-radius);
    overflow: hidden; /* belt-and-suspenders for the rounded corners */
}
.tab-view-variant-segmented .nav-link {
    color: var(--bs-secondary-color);
    border-radius: 0;
}
.tab-view-variant-segmented .nav-item:first-child .nav-link {
    border-top-left-radius: var(--bs-border-radius);
    border-bottom-left-radius: var(--bs-border-radius);
}
.tab-view-variant-segmented .nav-item:last-child .nav-link {
    border-top-right-radius: var(--bs-border-radius);
    border-bottom-right-radius: var(--bs-border-radius);
}
.tab-view-variant-segmented .nav-link:hover {
    color: var(--bs-primary);
    background: rgba(var(--bs-primary-rgb), 0.06);
}
.tab-view-variant-segmented .nav-link.active {
    color: #fff;
    background: var(--bs-primary);
    font-weight: 600;
    z-index: 1;
}
.tab-view-variant-segmented .nav-link.active:hover {
    color: #fff;
    background: color-mix(in srgb, var(--bs-primary) 90%, #000 10%);
}

/* --- btn-group: Bootstrap btn-group look, hairline borders between ----- */
.tab-view-variant-btn-group {
    display: inline-flex;
    gap: 0;
    border-radius: var(--bs-border-radius);
}
.tab-view-variant-btn-group .nav-item {
    /* let the outer rounded corners come from the first/last button */
    margin: 0;
}
.tab-view-variant-btn-group .nav-link {
    border: 1px solid var(--bs-border-color);
    border-radius: 0;
    background: var(--bs-body-bg);
    color: var(--bs-body-color);
    /* compensate for the border so the button height matches other variants */
    padding: calc(0.4rem - 1px) calc(0.85rem - 1px);
}
.tab-view-variant-btn-group .nav-item + .nav-item .nav-link {
    /* shared border between adjacent buttons */
    border-left-width: 0;
}
.tab-view-variant-btn-group .nav-item:first-child .nav-link {
    border-top-left-radius: var(--bs-border-radius);
    border-bottom-left-radius: var(--bs-border-radius);
}
.tab-view-variant-btn-group .nav-item:last-child .nav-link {
    border-top-right-radius: var(--bs-border-radius);
    border-bottom-right-radius: var(--bs-border-radius);
}
.tab-view-variant-btn-group .nav-link:hover {
    color: var(--bs-primary);
    background: var(--bs-tertiary-bg);
}
.tab-view-variant-btn-group .nav-link.active {
    color: #fff;
    background: var(--bs-primary);
    border-color: var(--bs-primary);
    font-weight: 600;
    z-index: 1;
}
.tab-view-variant-btn-group .nav-link.active:hover {
    color: #fff;
    background: color-mix(in srgb, var(--bs-primary) 90%, #000 10%);
    border-color: color-mix(in srgb, var(--bs-primary) 90%, #000 10%);
}

/* --- responsive collapse trigger: variant-tinted ----------------------
   Wrapper div carries the variant class so the dropdown trigger reads as
   part of the same family. Solid-fill variants get a primary-tinted
   trigger; the rest use the neutral default `.tab-view-select-style`.
*/
.tab-view-variant-pills-solid > .tab-view-select-style,
.tab-view-variant-segmented > .tab-view-select-style,
.tab-view-variant-btn-group > .tab-view-select-style {
    color: #fff;
    background-color: var(--bs-primary);
    border-color: var(--bs-primary);
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ffffff' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}
.tab-view-variant-pills-solid > .tab-view-select-style:hover,
.tab-view-variant-segmented > .tab-view-select-style:hover,
.tab-view-variant-btn-group > .tab-view-select-style:hover {
    background-color: color-mix(in srgb, var(--bs-primary) 90%, #000 10%);
    border-color: color-mix(in srgb, var(--bs-primary) 90%, #000 10%);
}

/* ---- Dark theme refinements (clustered per .claude/rules/theming.md) -- */
[data-bs-theme="dark"] .tab-view-variant-minimal .nav-link:hover,
[data-bs-theme="dark"] .tab-view-variant-pills .nav-link:hover,
[data-bs-theme="dark"] .tab-view-variant-pills-solid .nav-link:hover {
    background: rgba(255, 255, 255, 0.05);
}
[data-bs-theme="dark"] .tab-view-variant-segmented .nav-link:hover {
    background: rgba(var(--bs-primary-rgb), 0.18);
}
[data-bs-theme="dark"] .tab-view-variant-btn-group .nav-link {
    background: var(--bs-tertiary-bg);
}
[data-bs-theme="dark"] .tab-view-variant-btn-group .nav-link:hover {
    background: var(--bs-secondary-bg);
}

/* ========================================================================
   MOJO Core Animations
   ======================================================================== */

@keyframes mojo-fadeIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes mojo-slideUp {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes mojo-spin {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}

@keyframes mojo-pulse {
    0%,
    100% {
        opacity: 1;
    }
    50% {
        opacity: 0.6;
    }
}

@keyframes mojo-bounce {
    0%,
    100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-3px);
    }
}

/* ========================================================================
   MOJO Animation Utility Classes
   ======================================================================== */

.mojo-fade-in {
    animation: mojo-fadeIn var(--mojo-transition-slow) ease-in-out;
}

.mojo-slide-up {
    animation: mojo-slideUp 0.4s ease-out;
}

.mojo-spin {
    animation: mojo-spin 1s linear infinite;
    display: inline-block;
}

.mojo-pulse {
    animation: mojo-pulse 2s ease-in-out infinite;
}

.mojo-bounce {
    animation: mojo-bounce 0.5s ease-in-out;
}

/* Bootstrap Icons animation enhancement */
.bi-spin {
    animation: mojo-spin 1s linear infinite;
    display: inline-block;
}

/* ========================================================================
   MOJO Utility Classes
   ======================================================================== */

/* Text truncation utilities */
.mojo-text-truncate-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
}

.mojo-text-truncate-3 {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Transition utilities */
.mojo-transition-fast {
    transition: all var(--mojo-transition-fast);
}

.mojo-transition {
    transition: all var(--mojo-transition-base);
}

.mojo-transition-slow {
    transition: all var(--mojo-transition-slow);
}

/* Transform utilities */
.mojo-transform-center {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.mojo-transform-center-x {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
}

.mojo-transform-center-y {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}

/* Hover effects */
.mojo-hover-lift:hover {
    transform: translateY(-2px);
    transition: transform var(--mojo-transition-fast);
}

.mojo-hover-shadow:hover {
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
    transition: box-shadow var(--mojo-transition-fast);
}

/* Glass morphism effect */
.mojo-glass {
    backdrop-filter: blur(10px);
    background: rgba(255, 255, 255, 0.1);
    border: 1px solid rgba(255, 255, 255, 0.2);
}

[data-bs-theme="dark"] .mojo-glass {
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.1);
}

/* ========================================================================
   MOJO Loading States
   ======================================================================== */

.mojo-loading {
    pointer-events: none;
    opacity: 0.6;
    position: relative;
}

.mojo-loading::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 1rem;
    height: 1rem;
    margin: -0.5rem 0 0 -0.5rem;
    border: 2px solid transparent;
    border-top: 2px solid var(--mojo-primary);
    border-radius: 50%;
    animation: mojo-spin 1s linear infinite;
    z-index: 1;
}

/* ========================================================================
   MOJO Focus States
   ======================================================================== */

.mojo-focus-ring:focus {
    outline: none;
    box-shadow: var(--mojo-focus-shadow);
}

.mojo-focus-ring:focus-visible {
    outline: 2px solid var(--mojo-focus-color);
    outline-offset: 2px;
}

/* Extend Bootstrap font sizes smaller than fs-6 */
.fs-7 {
    font-size: 0.75rem !important; /* ~12px */
}
.fs-8 {
    font-size: 0.6875rem !important; /* ~11px */
}
.fs-9 {
    font-size: 0.625rem !important; /* ~10px */
}
.fs-10 {
    font-size: 0.5625rem !important; /* ~9px */
}

/* ========================================================================
   MOJO Print Utilities
   ======================================================================== */

@media print {
    .mojo-print-hide {
        display: none !important;
    }

    .mojo-print-show {
        display: block !important;
    }

    .mojo-no-print-shadow {
        box-shadow: none !important;
    }

    .mojo-no-print-bg {
        background: white !important;
        color: black !important;
    }
}

/* ========================================================================
   MOJO Accessibility Enhancements
   ======================================================================== */

/* Screen reader only content */
.mojo-sr-only {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* Skip link for accessibility */
.mojo-skip-link {
    position: absolute;
    top: -40px;
    left: 6px;
    background: var(--mojo-emphasis-color);
    color: var(--mojo-body-bg);
    padding: 8px;
    text-decoration: none;
    z-index: var(--mojo-zindex-tooltip);
    border-radius: var(--mojo-border-radius);
}

.mojo-skip-link:focus {
    top: 6px;
}

/* ========================================================================
   MOJO Reduced Motion Support
   ======================================================================== */

@media (prefers-reduced-motion: reduce) {
    .mojo-fade-in,
    .mojo-slide-up,
    .mojo-spin,
    .mojo-pulse,
    .mojo-bounce,
    .bi-spin,
    .mojo-loading::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
    }

    .mojo-transition-fast,
    .mojo-transition,
    .mojo-transition-slow,
    .mojo-hover-lift:hover,
    .mojo-hover-shadow:hover {
        transition: none !important;
    }
}

/* ========================================================================
   MOJO High Contrast Support
   ======================================================================== */

@media (prefers-contrast: high) {
    .mojo-glass {
        background: var(--mojo-body-bg);
        border: 2px solid var(--mojo-border-color);
        backdrop-filter: none;
    }

    .mojo-focus-ring:focus,
    .mojo-focus-ring:focus-visible {
        outline: 3px solid var(--mojo-focus-color);
        outline-offset: 2px;
        box-shadow: 0 0 0 0.5rem rgba(var(--mojo-primary-rgb), 0.5);
    }
}

/* ========================================================================
   MOJO Framework Initialization
   ======================================================================== */

/* Ensure MOJO framework is ready */
.mojo-app {
    min-height: 100vh;
    font-family: var(--mojo-font-sans-serif);
    background-color: var(--mojo-body-bg);
    color: var(--mojo-body-color);
}

.mojo-app.mojo-loading {
    opacity: 0;
}

.mojo-app.mojo-ready {
    opacity: 1;
    transition: opacity var(--mojo-transition-slow);
}

/* MOJO component base class */
.mojo-component {
    position: relative;
}

.mojo-component.mojo-disabled {
    pointer-events: none;
    opacity: 0.6;
}

/* ========================================================================
   MOJO Debug Helpers (Development Only)
   ======================================================================== */

.mojo-debug * {
    outline: 1px solid red !important;
}

.mojo-debug *:hover {
    background: rgba(255, 0, 0, 0.1) !important;
}

/* ========================================================================
   FileDropMixin - Drag and Drop Visual Feedback
   ======================================================================== */

.drag-over {
    border-color: var(--bs-primary) !important;
    background-color: var(--bs-primary-bg-subtle) !important;
    transition: all 0.2s ease;
}

.drag-active {
    border-style: dashed !important;
    border-width: 2px !important;
    box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25) !important;
}

/* Combined drag state */
.drag-over.drag-active {
    transform: scale(1.02);
    box-shadow:
        0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25),
        0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
}

/* Dark theme support */
[data-bs-theme="dark"] .drag-over {
    background-color: rgba(var(--bs-primary-rgb), 0.15) !important;
}

/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
    .drag-over,
    .drag-active {
        transition: none !important;
        transform: none !important;
    }
}

/* Hide debug helpers in production */
@media (min-width: 1px) {
    .mojo-debug {
        display: none;
    }
}

/* Show debug helpers when explicitly enabled */
.mojo-debug-enabled .mojo-debug {
    display: block !important;
}

/* ========================================
   Image Field Styles
   ======================================== */

.image-field-container {
    position: relative;
    display: inline-block;
    border-radius: 0.375rem;
    overflow: hidden;
}

.image-drop-zone {
    position: relative;
    border-radius: 0.375rem;
    transition: all 0.2s ease;
    overflow: hidden;
}

.image-drop-zone.droppable {
    border: 2px dashed var(--bs-border-color);
}

.image-drop-zone.droppable:hover {
    border-color: var(--bs-primary);
    background-color: var(--bs-primary-bg-subtle);
}

/* Drop zone states */
.image-drop-zone.drag-over {
    border-color: var(--bs-primary) !important;
    background-color: var(--bs-primary-bg-subtle) !important;
    transform: scale(1.02);
}

.image-drop-zone.drag-active {
    border-color: var(--bs-success) !important;
    background-color: var(--bs-success-bg-subtle) !important;
    box-shadow: 0 0 0 3px rgba(var(--bs-success-rgb), 0.25);
}

/* Size variants */
.image-field-xs {
    width: 48px;
    height: 48px;
}

.image-field-sm {
    width: 96px;
    height: 96px;
}

.image-field-md {
    width: 150px;
    height: 150px;
}

.image-field-lg {
    width: 200px;
    height: 200px;
}

.image-field-xl {
    width: 300px;
    height: 300px;
}

/* Preview images */
.image-field-container img {
    transition: transform 0.2s ease;
}

.image-field-container:hover img {
    transform: scale(1.05);
}

/* Remove button positioning */
.image-field-container .btn {
    transition: opacity 0.2s ease;
}

.image-field-container:not(:hover) .btn {
    opacity: 0.6;
}

/* Dark theme adjustments */
[data-bs-theme="dark"] .image-drop-zone.droppable {
    border-color: var(--bs-border-color-translucent);
}

[data-bs-theme="dark"] .image-drop-zone.droppable:hover {
    border-color: var(--bs-primary);
    background-color: rgba(var(--bs-primary-rgb), 0.1);
}

/* Responsive adjustments */
@media (max-width: 576px) {
    .image-field-xl {
        width: 250px;
        height: 250px;
    }

    .image-field-lg {
        width: 180px;
        height: 180px;
    }
}

/* Accessibility */
.image-drop-zone:focus {
    outline: 2px solid var(--bs-primary);
    outline-offset: 2px;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .image-drop-zone,
    .image-field-container img,
    .image-field-container .btn {
        transition: none;
    }

    .image-drop-zone.drag-over {
        transform: none;
    }

    .image-field-container:hover img {
        transform: none;
    }
}

/* ========================================================================
   MOJO Form Groups
   ======================================================================== */

.mojo-form-group {
    margin-bottom: 1rem;
}

.mojo-form-group .h6 {
    color: var(--bs-secondary);
    font-weight: 600;
    margin-bottom: 0.75rem;
    padding-bottom: 0.25rem;
    border-bottom: 1px solid var(--bs-border-color);
}

/* Responsive adjustments for form groups */
@media (max-width: 767.98px) {
    .mojo-form-group {
        padding: 0.75rem;
        margin-bottom: 0.75rem;
    }
}

/* ========================================================================
   MOJO Form Controls
   ======================================================================== */

.mojo-form-control {
    margin-bottom: 1rem;
    position: relative;
}

.mojo-form-control .form-label {
    font-weight: 500;
    margin-bottom: 0.5rem;
    color: var(--bs-body-color);
}

.mojo-form-control .form-text {
    margin-top: 0.25rem;
    font-size: 0.875rem;
    color: var(--bs-secondary);
}

.mojo-form-control .invalid-feedback {
    margin-top: 0.25rem;
}

/* Form check controls (checkboxes, switches, radios) */
.mojo-form-control .form-check {
    margin-bottom: 0;
}

.mojo-form-control .form-check .form-check-label {
    font-weight: normal;
}

/* Image field specific styling */
.mojo-form-control .image-field-container {
    margin-top: 0.5rem;
}

/* Range slider specific styling */
.mojo-form-control input[type="range"] {
    margin-top: 0.5rem;
    margin-bottom: 0.5rem;
}

/* Responsive adjustments for form controls */
@media (max-width: 767.98px) {
    .mojo-form-control {
        margin-bottom: 0.75rem;
    }

    .mojo-form-control .form-label {
        margin-bottom: 0.375rem;
    }
}

/* ========================================================================
   MultiSelectDropdown Component Styles
   ======================================================================== */

/* Container */
.multiselect-dropdown {
    position: relative;
}

/* Dropdown menu */
.multiselect-dropdown .dropdown-menu {
    padding: 0;
    min-width: 250px;
}

/* Items list container */
.multiselect-list {
    padding: 0.25rem 0;
}

/* Individual item - remove form-check default spacing */
.multiselect-item {
    cursor: pointer;
    transition: background-color 0.15s ease-in-out;
    user-select: none;
    margin-top: 0 !important;
    margin-bottom: 0 !important;
    padding-top: 0.5rem !important;
    padding-bottom: 0.5rem !important;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.multiselect-item:hover {
    background-color: var(--bs-light);
}

.multiselect-item.disabled {
    cursor: not-allowed;
    opacity: 0.5;
}

.multiselect-item input[type="checkbox"] {
    cursor: pointer;
    pointer-events: none; /* Let the parent div handle clicks */
    margin: 0;
    flex-shrink: 0;
}

.multiselect-item label {
    cursor: pointer;
    margin-bottom: 0;
    pointer-events: none; /* Let the parent div handle clicks */
    flex: 1;
}

/* Empty state */
.multiselect-empty {
    padding: 1rem;
    border: 1px dashed var(--bs-border-color);
    border-radius: 0.25rem;
    margin: 0.5rem;
}

/* Button text */
.multiselect-button-text {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Dropdown button adjustments */
.multiselect-dropdown .dropdown-toggle {
    padding: 0.375rem 0.75rem;
}

.multiselect-dropdown .dropdown-toggle::after {
    display: none !important; /* Hide default Bootstrap caret, use custom icon */
}

/* Also target buttons that might not be inside .multiselect-dropdown wrapper */
button.dropdown-toggle:has(.multiselect-button-text)::after {
    display: none !important;
}

/* Scrollbar styling for items list */
.multiselect-list::-webkit-scrollbar {
    width: 8px;
}

.multiselect-list::-webkit-scrollbar-track {
    background: var(--bs-light);
    border-radius: 4px;
}

.multiselect-list::-webkit-scrollbar-thumb {
    background: var(--bs-secondary);
    border-radius: 4px;
}

.multiselect-list::-webkit-scrollbar-thumb:hover {
    background: var(--bs-dark);
}

/* Focus states */
.multiselect-dropdown .dropdown-toggle:focus {
    border-color: var(--bs-primary);
    box-shadow: 0 0 0 0.25rem rgba(var(--bs-primary-rgb), 0.25);
}

/* Disabled state */
.multiselect-dropdown .dropdown-toggle:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ==============================================
   ComboBox (Autocomplete) Styles
   ============================================== */

.combobox-container {
    position: relative;
    width: 100%;
}

.combobox-input {
    border-top-right-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
}

.combobox-toggle {
    border-top-left-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
    padding: 0.375rem 0.75rem;
}

.combobox-toggle i {
    transition: transform 0.2s ease-in-out;
}

.combobox-container:has(.combobox-dropdown.show) .combobox-toggle i {
    transform: rotate(180deg);
}

.combobox-dropdown {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 1000;
    margin-top: 0.125rem;
}

.combobox-dropdown.show {
    display: block;
}

.combobox-item {
    cursor: pointer;
    padding: 0.5rem 1rem;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.combobox-item.active {
    background-color: var(--bs-primary);
    color: white;
}

.combobox-item:hover:not(.active) {
    background-color: var(--bs-light);
}

.combobox-no-match {
    padding: 0.5rem 1rem;
    text-align: center;
    font-style: italic;
}

/* ==============================================
   Modal Context Menu Button Styles
   ============================================== */

/* Base context menu button - inherits header color by default */
.mojo-modal-context-menu-btn {
    color: inherit !important;
    border: none;
    background: transparent;
    opacity: 0.7;
    transition: opacity 0.15s ease-in-out;
}

.mojo-modal-context-menu-btn:hover,
.mojo-modal-context-menu-btn:focus {
    color: inherit !important;
    background: rgba(var(--bs-emphasis-color-rgb), 0.1);
    opacity: 1;
}

.mojo-modal-context-menu-btn:active {
    background: rgba(var(--bs-emphasis-color-rgb), 0.2);
}

/* Modal type-specific overrides */
.modal.modal-info .mojo-modal-context-menu-btn {
    color: #ffffff !important;
}

.modal.modal-success .mojo-modal-context-menu-btn {
    color: #ffffff !important;
}

.modal.modal-warning .mojo-modal-context-menu-btn {
    color: #000000 !important;
}

.modal.modal-error .mojo-modal-context-menu-btn {
    color: #ffffff !important;
}

.modal.modal-dark .mojo-modal-context-menu-btn {
    color: #ffffff !important;
}

/* Dark theme support */
[data-bs-theme="dark"] .mojo-modal-context-menu-btn {
    color: #ffffff !important;
}

/* Ensure proper spacing and alignment */
.modal-header .mojo-modal-context-menu-btn {
    margin-left: auto;
    margin-right: 0;
}

/* ==============================================
   Modal xxl size

   Bootstrap 5 ships .modal-sm / .modal-lg / .modal-xl but stops there.
   Dialog accepts size: 'xxl' and emits .modal-xxl, so we provide a
   matching rule that follows Bootstrap's --bs-modal-width pattern at
   the xxl breakpoint (1400px).
   ============================================== */
@media (min-width: 1400px) {
    .modal-xxl {
        --bs-modal-width: 1320px;
    }
}

/* ==============================================
   Dialog / Modal Chrome — "Hero Band + Tinted Card"

   Direction picked from planning/mockups/modals/10-stripe-icon-tint.html.
   - Default modals = stock Bootstrap. No custom chrome at all.
   - Typed alerts (modal-alert + modal-alert-{success|warning|error|info})
     get three layered cues:
       1) 4px top accent stripe in the type color (Stripe-style)
       2) 1.25rem outline icon next to the title (Modal.alert injects the
          markup; CSS colors it via --mojo-current-accent)
       3) Soft full-card tint (5% light / 10% dark) so the brand color
          is felt across the whole surface
   - Bootstrap's native border / radius / shadow / padding tokens drive
     everything else, so the card looks like a stock Bootstrap 5 modal
     with three small overlays on typed alerts only.
   ============================================== */

:root {
    --mojo-dialog-accent: var(--bs-primary);
    --mojo-dialog-success: #198754;
    --mojo-dialog-warning: #ffc107;
    --mojo-dialog-error:   #dc3545;
}

/* No header/footer dividers — modern OS-native sheets don't have them. */
.modal-header { border-bottom: 0; }
.modal-footer { border-top: 0; }

/* Dark mode: Bootstrap ships no modal box-shadow by default, so the card
   blends into the dark backdrop. Add a soft white inner halo so the edge
   reads, plus a deep drop shadow so the elevation still feels lifted. The
   tint mix bumps from 5% → 10% because dark backgrounds absorb color. */
[data-bs-theme="dark"] .modal-content {
    box-shadow:
        0 0 0 1px rgba(255, 255, 255, 0.08),
        0 24px 48px -12px rgba(0, 0, 0, 0.7);
}

/* ── Typed alerts — chrome scoped strictly to .modal.modal-alert ── */

/* 4px top accent stripe — Stripe-style. Hugs the card's inner radius so
   it never squares off against the rounded corners. */
.modal.modal-alert .modal-content::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: var(--mojo-current-accent);
    border-top-left-radius: var(--bs-modal-inner-border-radius);
    border-top-right-radius: var(--bs-modal-inner-border-radius);
    pointer-events: none;
    z-index: 1;
}

/* Soft full-card tint — felt across the surface without screaming.
   Light = 5% accent mix, dark = 10% (dark surfaces absorb color). */
.modal.modal-alert .modal-content {
    background:
        linear-gradient(
            180deg,
            color-mix(in srgb, var(--mojo-current-accent) 5%, var(--bs-modal-bg, #fff)) 0%,
            var(--bs-modal-bg, #fff) 100%
        );
}
[data-bs-theme="dark"] .modal.modal-alert .modal-content {
    background:
        linear-gradient(
            180deg,
            color-mix(in srgb, var(--mojo-current-accent) 10%, var(--bs-modal-bg, #14181f)) 0%,
            var(--bs-modal-bg, #14181f) 100%
        );
}

/* Leading outline icon next to the title. Modal.alert injects
   <i class="bi bi-{icon} modal-alert-icon"></i> at the start of the title. */
.modal-alert-icon {
    display: inline-block;
    font-size: 1.25rem;
    margin-right: 0.625rem;
    vertical-align: -0.15em;
    color: var(--mojo-current-accent);
    flex-shrink: 0;
}

/* Per-type accent color — drives stripe, icon, tint, and primary button. */
.modal.modal-alert.modal-alert-info    .modal-content { --mojo-current-accent: var(--mojo-dialog-accent); }
.modal.modal-alert.modal-alert-success .modal-content { --mojo-current-accent: var(--mojo-dialog-success); }
.modal.modal-alert.modal-alert-warning .modal-content { --mojo-current-accent: var(--mojo-dialog-warning); }
.modal.modal-alert.modal-alert-error   .modal-content { --mojo-current-accent: var(--mojo-dialog-error); }

/* Primary action button picks up the type color. */
.modal.modal-alert .modal-footer .btn-primary {
    --bs-btn-bg: var(--mojo-current-accent);
    --bs-btn-border-color: var(--mojo-current-accent);
    --bs-btn-hover-bg: color-mix(in srgb, var(--mojo-current-accent) 88%, #000);
    --bs-btn-hover-border-color: color-mix(in srgb, var(--mojo-current-accent) 85%, #000);
    --bs-btn-active-bg: color-mix(in srgb, var(--mojo-current-accent) 80%, #000);
    --bs-btn-active-border-color: color-mix(in srgb, var(--mojo-current-accent) 78%, #000);
}

/* Warning button needs dark text on yellow for AAA contrast */
.modal.modal-alert.modal-alert-warning .modal-footer .btn-primary {
    --bs-btn-color: #1a1a1a;
    --bs-btn-hover-color: #1a1a1a;
    --bs-btn-active-color: #1a1a1a;
}

/* Edge-to-edge body. ModalView sets `modal-body-flush` when the caller
   passes `noBodyPadding: true`. The body paints to the card walls — top,
   sides, and bottom included. We round the bottom corners to match the
   card's inner radius so footerless flush bodies don't square off. */
.modal-content > .modal-body.modal-body-flush {
    padding: 0;
}
.modal-content > .modal-body.modal-body-flush:last-child {
    border-bottom-left-radius: var(--bs-modal-inner-border-radius);
    border-bottom-right-radius: var(--bs-modal-inner-border-radius);
    overflow: hidden;
}

/* Typed-alert title typography — let the modal-alert-headline span control
   the styling instead of Bootstrap's h5 defaults. */
.modal.modal-alert .modal-title {
    display: flex;
    align-items: center;
    font-size: inherit;
    font-weight: inherit;
    line-height: inherit;
    margin: 0;
    padding-right: 1.75rem; /* clear the close X */
}

.modal-alert-headline {
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.015em;
    line-height: 1.3;
    color: var(--bs-body-color, #212529);
}

.modal.modal-alert .modal-body .modal-alert-message {
    margin: 0;
    font-size: 0.9375rem;
    line-height: 1.55;
    color: var(--bs-secondary-color, #5b6478);
}

/* ── Dark mode ─────────────────────────────────────────────
   Brighter accent tokens read against dark surfaces. The modal box-shadow
   is also adjusted in dark mode (see the .modal-content rule near the top)
   so the card doesn't blend into the dark backdrop. */
@media (prefers-color-scheme: dark) {
    :root {
        --mojo-dialog-success: #4ade80;
        --mojo-dialog-warning: #fbbf24;
        --mojo-dialog-error:   #f87171;
    }
}

/* ========================================================================
   Field Status Indicators
   ======================================================================== */

/* Field status containers */
.field-status {
    display: inline-block;
    margin-left: 8px;
}

/* Label inline status (for toggles/checkboxes) */
.field-status-label-inline {
    display: inline-block;
    margin-left: 8px;
    font-size: 0.875rem;
    vertical-align: middle;
}

/* Input overlay status (for text inputs/selects) */
.field-status-overlay {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    z-index: 10;
    pointer-events: none;
}

/* Full overlay status (for textareas) */
.field-status-full-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(var(--bs-body-bg-rgb), 0.9);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 20;
    border-radius: var(--bs-border-radius);
}

.field-status-full-overlay .saving-indicator,
.field-status-full-overlay .success-indicator,
.field-status-full-overlay .error-indicator {
    display: flex;
    align-items: center;
    padding: 8px 12px;
    background-color: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: var(--bs-border-radius);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.field-status [data-status] {
    display: none;
    font-size: 1rem;
    transition:
        opacity 0.3s ease,
        transform 0.3s ease;
}

.field-status .spinner-border {
    /* Align spinner with other icons */
    width: 1rem;
    height: 1rem;
    vertical-align: middle;
    /* Let Bootstrap handle the animation */
}

.field-status [data-status="saved"] {
    color: var(--bs-success);
}

.field-status [data-status="error"] {
    color: var(--bs-danger);
    cursor: help;
}

@keyframes mojo-status-fade-in {
    from {
        opacity: 0;
        transform: scale(0.8);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}

@keyframes mojo-status-fade-out {
    from {
        opacity: 1;
        transform: scale(1);
    }
    to {
        opacity: 0;
        transform: scale(0.8);
    }
}

/* Responsive adjustments for field status */
@media (max-width: 576px) {
    .field-status {
        margin-left: 4px;
    }

    .field-status [data-status] {
        font-size: 0.875rem;
    }
}

/* High contrast mode support */
@media (prefers-contrast: high) {
    .field-status [data-status="saving"] {
        color: #0066cc;
    }

    .field-status [data-status="saved"] {
        color: #006600;
    }

    .field-status [data-status="error"] {
        color: #cc0000;
    }
}

/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
    .field-status [data-status] {
        transition: none;
    }

    .field-status [data-status].show {
        animation: none;
    }

    .field-status [data-status].hide {
        animation: none;
    }

    @keyframes mojo-status-fade-in {
        from,
        to {
            opacity: 1;
            transform: scale(1);
        }
    }

    @keyframes mojo-status-fade-out {
        from,
        to {
            opacity: 0;
            transform: scale(1);
        }
    }
}

/* =================================================================
   Collection Multi-Select
   ================================================================= */

.collection-multiselect-view {
    width: 100%;
}

/* Action buttons */
.collection-multiselect-actions {
    font-size: 0.8125rem;
    font-weight: 500;
    letter-spacing: 0.025em;
}

.collection-multiselect-actions .btn-link {
    color: var(--bs-primary);
    transition: all 0.2s ease;
}

.collection-multiselect-actions .btn-link:hover:not(:disabled) {
    color: var(--bs-primary);
    transform: translateY(-1px);
}

.collection-multiselect-actions .btn-link:active:not(:disabled) {
    transform: translateY(0);
}

.collection-multiselect-actions .btn-link:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* List container */
.collection-multiselect-list {
    background: var(--bs-body-bg);
}

/* List items */
.collection-multiselect-item {
    user-select: none;
    transition: background-color 0.15s ease-in-out;
    border-bottom: 1px solid transparent;
}

.collection-multiselect-item:not(:last-child) {
    border-bottom-color: var(--bs-border-color);
}

.collection-multiselect-item.clickable {
    cursor: pointer;
}

.collection-multiselect-item.clickable:hover {
    background-color: rgba(var(--bs-primary-rgb), 0.06);
}

.collection-multiselect-item.clickable:active {
    background-color: rgba(var(--bs-primary-rgb), 0.1);
}

.collection-multiselect-item i {
    flex-shrink: 0;
    transition: transform 0.15s ease;
}

.collection-multiselect-item.clickable:hover i {
    transform: scale(1.1);
}

/* Dark mode */
[data-bs-theme="dark"] .collection-multiselect-item.clickable:hover {
    background-color: rgba(var(--bs-primary-rgb), 0.12);
}

[data-bs-theme="dark"] .collection-multiselect-item.clickable:active {
    background-color: rgba(var(--bs-primary-rgb), 0.18);
}

/* Empty state */
.collection-multiselect-empty {
    background: var(--bs-light);
    border-style: dashed !important;
}

[data-bs-theme="dark"] .collection-multiselect-empty {
    background: var(--bs-gray-900);
}

/* Smooth scrollbar */
.collection-multiselect-list::-webkit-scrollbar {
    width: 6px;
}

.collection-multiselect-list::-webkit-scrollbar-track {
    background: transparent;
}

.collection-multiselect-list::-webkit-scrollbar-thumb {
    background: var(--bs-gray-400);
    border-radius: 3px;
}

.collection-multiselect-list::-webkit-scrollbar-thumb:hover {
    background: var(--bs-gray-500);
}

[data-bs-theme="dark"] .collection-multiselect-list::-webkit-scrollbar-thumb {
    background: var(--bs-gray-600);
}

[data-bs-theme="dark"] .collection-multiselect-list::-webkit-scrollbar-thumb:hover {
    background: var(--bs-gray-500);
}

/* Animations */
@keyframes multiselect-fade-in {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.collection-multiselect-item {
    animation: multiselect-fade-in 0.2s ease;
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .collection-multiselect-item,
    .collection-multiselect-item i,
    .collection-multiselect-actions .btn-link {
        transition: none;
        animation: none;
    }

    .collection-multiselect-actions .btn-link:hover:not(:disabled) {
        transform: none;
    }
}

/* =================================================================
   Tooltip Styling & Themes
   ================================================================= */

/* Base tooltip styling - applies to all tooltips */
.tooltip {
    --mojo-tooltip-bg: var(--bs-dark);
    --mojo-tooltip-color: #fff;
    --mojo-tooltip-opacity: 0.95;
    --mojo-tooltip-border-radius: 0.375rem;
    --mojo-tooltip-font-size: 0.875rem;
    --mojo-tooltip-padding-y: 0.5rem;
    --mojo-tooltip-padding-x: 0.75rem;
    --mojo-tooltip-max-width: 200px;
    --mojo-tooltip-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
    font-size: var(--mojo-tooltip-font-size);
}

.tooltip .tooltip-inner {
    max-width: var(--mojo-tooltip-max-width);
    padding: var(--mojo-tooltip-padding-y) var(--mojo-tooltip-padding-x);
    background-color: var(--mojo-tooltip-bg);
    color: var(--mojo-tooltip-color);
    border-radius: var(--mojo-tooltip-border-radius);
    opacity: var(--mojo-tooltip-opacity);
    box-shadow: var(--mojo-tooltip-box-shadow);
    text-align: left;
    font-weight: 500;
}

/* Dark theme adjustments */
[data-bs-theme="dark"] .tooltip {
    --mojo-tooltip-bg: rgba(255, 255, 255, 0.95);
    --mojo-tooltip-color: var(--bs-dark);
    --mojo-tooltip-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.3);
}

/* Arrow styling */
.tooltip .tooltip-arrow::before {
    border-color: transparent;
}

/* Top placement arrow */
.tooltip.bs-tooltip-top .tooltip-arrow::before,
.tooltip.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before {
    border-top-color: var(--mojo-tooltip-bg);
}

/* Bottom placement arrow */
.tooltip.bs-tooltip-bottom .tooltip-arrow::before,
.tooltip.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before {
    border-bottom-color: var(--mojo-tooltip-bg);
}

/* Left placement arrow */
.tooltip.bs-tooltip-start .tooltip-arrow::before,
.tooltip.bs-tooltip-auto[data-popper-placement^="left"] .tooltip-arrow::before {
    border-left-color: var(--mojo-tooltip-bg);
}

/* Right placement arrow */
.tooltip.bs-tooltip-end .tooltip-arrow::before,
.tooltip.bs-tooltip-auto[data-popper-placement^="right"] .tooltip-arrow::before {
    border-right-color: var(--mojo-tooltip-bg);
}

/* === Tooltip Theme Variants === */

/* Primary Theme */
.tooltip-primary .tooltip-inner {
    --mojo-tooltip-bg: var(--bs-primary);
    --mojo-tooltip-color: #fff;
}

.tooltip-primary.bs-tooltip-top .tooltip-arrow::before,
.tooltip-primary.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before {
    border-top-color: var(--bs-primary);
}

.tooltip-primary.bs-tooltip-bottom .tooltip-arrow::before,
.tooltip-primary.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before {
    border-bottom-color: var(--bs-primary);
}

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

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

/* Success Theme */
.tooltip-success .tooltip-inner {
    --mojo-tooltip-bg: var(--bs-success);
    --mojo-tooltip-color: #fff;
}

.tooltip-success.bs-tooltip-top .tooltip-arrow::before,
.tooltip-success.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before {
    border-top-color: var(--bs-success);
}

.tooltip-success.bs-tooltip-bottom .tooltip-arrow::before,
.tooltip-success.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before {
    border-bottom-color: var(--bs-success);
}

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

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

/* Warning Theme */
.tooltip-warning .tooltip-inner {
    --mojo-tooltip-bg: var(--bs-warning);
    --mojo-tooltip-color: var(--bs-dark);
}

.tooltip-warning.bs-tooltip-top .tooltip-arrow::before,
.tooltip-warning.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before {
    border-top-color: var(--bs-warning);
}

.tooltip-warning.bs-tooltip-bottom .tooltip-arrow::before,
.tooltip-warning.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before {
    border-bottom-color: var(--bs-warning);
}

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

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

/* Danger Theme */
.tooltip-danger .tooltip-inner {
    --mojo-tooltip-bg: var(--bs-danger);
    --mojo-tooltip-color: #fff;
}

.tooltip-danger.bs-tooltip-top .tooltip-arrow::before,
.tooltip-danger.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before {
    border-top-color: var(--bs-danger);
}

.tooltip-danger.bs-tooltip-bottom .tooltip-arrow::before,
.tooltip-danger.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before {
    border-bottom-color: var(--bs-danger);
}

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

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

/* Info Theme */
.tooltip-info .tooltip-inner {
    --mojo-tooltip-bg: var(--bs-info);
    --mojo-tooltip-color: #fff;
}

.tooltip-info.bs-tooltip-top .tooltip-arrow::before,
.tooltip-info.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before {
    border-top-color: var(--bs-info);
}

.tooltip-info.bs-tooltip-bottom .tooltip-arrow::before,
.tooltip-info.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before {
    border-bottom-color: var(--bs-info);
}

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

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

/* Light Theme */
.tooltip-light .tooltip-inner {
    --mojo-tooltip-bg: var(--bs-light);
    --mojo-tooltip-color: var(--bs-dark);
    --mojo-tooltip-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 0, 0, 0.05);
}

.tooltip-light.bs-tooltip-top .tooltip-arrow::before,
.tooltip-light.bs-tooltip-auto[data-popper-placement^="top"] .tooltip-arrow::before {
    border-top-color: var(--bs-light);
}

.tooltip-light.bs-tooltip-bottom .tooltip-arrow::before,
.tooltip-light.bs-tooltip-auto[data-popper-placement^="bottom"] .tooltip-arrow::before {
    border-bottom-color: var(--bs-light);
}

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

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

/* === Size Variants === */

/* Small tooltips */
.tooltip-sm .tooltip-inner {
    --mojo-tooltip-font-size: 0.75rem;
    --mojo-tooltip-padding-y: 0.25rem;
    --mojo-tooltip-padding-x: 0.5rem;
    --mojo-tooltip-max-width: 150px;
}

/* Large tooltips */
.tooltip-lg .tooltip-inner {
    --mojo-tooltip-font-size: 1rem;
    --mojo-tooltip-padding-y: 0.75rem;
    --mojo-tooltip-padding-x: 1rem;
    --mojo-tooltip-max-width: 300px;
}

/* === Accessibility === */

/* High contrast mode adjustments */
@media (prefers-contrast: high) {
    .tooltip .tooltip-inner {
        --mojo-tooltip-opacity: 1;
        border: 2px solid currentColor;
    }

    [data-bs-theme="dark"] .tooltip .tooltip-inner {
        border-color: var(--mojo-tooltip-color);
    }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
    .tooltip {
        transition: none;
    }
}

/* ============================================
   GroupSearchView - Hierarchical Tree Styles
   ============================================ */

/* Hide chevron in group search - it's a nav tree, not a menu */
.group-search-view .bi-chevron-right {
    display: none !important;
}

/* Tree item wrapper - flat list with visual hierarchy */
.group-search-view .tree-item-wrapper {
    display: flex;
    align-items: center;
    position: relative;
}

/* Container for tree line segments */
.group-search-view .tree-lines {
    display: flex;
    flex-shrink: 0;
    align-self: stretch;
}

/* Each segment is a fixed width column */
.group-search-view .tree-seg {
    width: 24px;
    position: relative;
    align-self: stretch;
}

/* Vertical line segment - continues through (for ancestors that aren't last) */
.group-search-view .tree-seg-vert::before {
    content: "";
    position: absolute;
    left: 12px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--bs-border-color);
}

/* Vertical line segment ending - only draws top half (for last item in branch) */
.group-search-view .tree-seg-vert-end::before {
    content: "";
    position: absolute;
    left: 12px;
    top: 0;
    height: 50%;
    width: 2px;
    background: var(--bs-border-color);
}

/* Middle segment - vertical line full height + horizontal branch */
.group-search-view .tree-seg-mid::before {
    content: "";
    position: absolute;
    left: 12px;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--bs-border-color);
}
.group-search-view .tree-seg-mid::after {
    content: "";
    position: absolute;
    left: 12px;
    top: 50%;
    width: 12px;
    height: 2px;
    background: var(--bs-border-color);
}

/* Last segment - vertical line stops at middle + horizontal branch */
.group-search-view .tree-seg-last::before {
    content: "";
    position: absolute;
    left: 12px;
    top: 0;
    height: 50%;
    width: 2px;
    background: var(--bs-border-color);
}
.group-search-view .tree-seg-last::after {
    content: "";
    position: absolute;
    left: 12px;
    top: 50%;
    width: 12px;
    height: 2px;
    background: var(--bs-border-color);
}

/* Bold text for parents with children */
.group-search-view .tree-item-wrapper.has-children .tree-item-name {
    font-weight: 600;
}

/* Hover state - highlight text */
.group-search-view .simple-search-item:hover .tree-item-name {
    color: var(--bs-primary);
}

.group-search-view .simple-search-item:hover .tree-item-kind {
    background: var(--bs-primary);
    color: white;
}

.group-search-view .tree-item-body {
    min-width: 0;
}

.group-search-view .tree-item-content {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.75rem;
}

.group-search-view .tree-item-name {
    font-weight: 500;
    color: var(--bs-body-color);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.group-search-view .tree-item-kind {
    font-size: 0.75rem;
    color: var(--bs-secondary);
    background: var(--bs-secondary-bg);
    padding: 0.125rem 0.5rem;
    border-radius: 0.25rem;
    text-transform: uppercase;
    font-weight: 600;
    letter-spacing: 0.025em;
    flex-shrink: 0;
}

.group-search-view .simple-search-item {
    cursor: pointer;
    transition: background-color 0.15s ease;
    /*border: 1px dotted #efefef;*/
}

.group-search-view .simple-search-item:hover {
    background-color: var(--bs-light);
}

/* ========================================================================
   MetricCard
   ========================================================================
   Compact KPI card — label / value / hint with an optional left-border
   tone accent. Used in record-detail Overview rows and dashboard panels.
*/
/* Borderless flat surface; the bg tint is the only visual separation.
   Tone variants get a thin left-edge accent so the tone signal still
   reads without the surrounding box. */
.metric-card {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    padding: 0.7rem 0.9rem;
    background: var(--bs-tertiary-bg);
    border: 0;
    border-left: 3px solid transparent;
    border-radius: 0.6rem;
    color: var(--bs-body-color);
    font: inherit;
    text-align: left;
    min-width: 0;
    width: 100%;
}
button.metric-card { cursor: pointer; }
button.metric-card:hover { background: var(--bs-secondary-bg); }
button.metric-card:focus-visible { outline: 2px solid var(--bs-primary); outline-offset: -1px; }

.metric-card-tone-success { border-left-color: var(--bs-success); }
.metric-card-tone-warning { border-left-color: var(--bs-warning); }
.metric-card-tone-danger  { border-left-color: var(--bs-danger);  }
.metric-card-tone-info    { border-left-color: var(--bs-info);    }
.metric-card-tone-primary { border-left-color: var(--bs-primary); }

.metric-card-label {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 600;
    color: var(--bs-secondary-color);
    display: flex;
    align-items: center;
    gap: 0.3rem;
}
.metric-card-icon { font-size: 0.85rem; opacity: 0.75; }

.metric-card-value {
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.25;
    font-variant-numeric: tabular-nums;
    color: var(--bs-emphasis-color, var(--bs-body-color));
    word-break: break-word;
    display: flex;
    align-items: center;
    gap: 0.3rem;
}
.metric-card-value-icon { font-size: 0.9rem; flex-shrink: 0; }
.metric-card-tone-success .metric-card-value-icon { color: var(--bs-success); }
.metric-card-tone-warning .metric-card-value-icon { color: var(--bs-warning); }
.metric-card-tone-danger  .metric-card-value-icon { color: var(--bs-danger);  }
.metric-card-tone-info    .metric-card-value-icon { color: var(--bs-info);    }
.metric-card-tone-primary .metric-card-value-icon { color: var(--bs-primary); }

.metric-card-hint {
    font-size: 0.75rem;
    color: var(--bs-secondary-color);
}

/* ========================================================================
   StatusPanel
   ========================================================================
   Hero state banner used in the Overview section of state-driven records
   (incident status, job lifecycle, runner alive/dead). The tone variants
   tint the background + border with the matching Bootstrap semantic color
   so the panel reads as the dominant signal in the section.

   JS: src/core/views/data/StatusPanel.js
*/
/* Borderless flat surface; the tone-tinted bg + colored state eyebrow
   carry the entire visual signal. The container queries further down
   stack the actions below the headline when the panel is narrower
   than ~480px (typical inside an `lg` modal). */
.detail-status-panel {
    container-type: inline-size;
    border: 0;
    border-radius: 0.75rem;
    padding: 1rem 1.25rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.25rem;
    margin-bottom: 1.5rem;
    background: var(--bs-tertiary-bg);
}
@container (max-width: 480px) {
    .detail-status-panel {
        flex-direction: column;
        align-items: stretch;
        gap: 0.85rem;
    }
    .detail-status-panel .detail-status-actions { flex-wrap: wrap; }
}
.detail-status-panel .detail-status-headline { min-width: 0; flex: 1; }
.detail-status-panel .detail-status-state {
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-weight: 600;
    margin-bottom: 0.2rem;
    color: var(--bs-secondary-color);
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}
.detail-status-panel .detail-status-state .detail-status-dot {
    width: 0.5rem; height: 0.5rem;
    border-radius: 999px;
    background: currentColor;
    box-shadow: 0 0 0.5rem currentColor;
}
.detail-status-panel .detail-status-state .detail-status-icon {
    font-size: 0.95rem;
    line-height: 1;
}
.detail-status-panel .detail-status-line {
    font-size: 1rem;
    font-weight: 600;
    margin: 0 0 0.2rem;
    line-height: 1.25;
    color: var(--bs-emphasis-color, var(--bs-body-color));
    letter-spacing: -0.005em;
}
.detail-status-panel .detail-status-meta {
    color: var(--bs-secondary-color);
    font-size: 0.78rem;
    line-height: 1.4;
}
.detail-status-panel .detail-status-actions {
    display: flex; gap: 0.4rem; flex-shrink: 0;
}
/* Tones bump the tinted bg slightly (0.08 → 0.10) so the surface still
   reads cleanly without the border. */
.detail-status-panel.tone-danger    { background: rgba(var(--bs-danger-rgb),    0.10); }
.detail-status-panel.tone-warning   { background: rgba(var(--bs-warning-rgb),   0.10); }
.detail-status-panel.tone-success   { background: rgba(var(--bs-success-rgb),   0.10); }
.detail-status-panel.tone-info      { background: rgba(var(--bs-info-rgb),      0.10); }
.detail-status-panel.tone-primary   { background: rgba(var(--bs-primary-rgb),   0.10); }
.detail-status-panel.tone-secondary { background: rgba(var(--bs-secondary-rgb), 0.07); }
.detail-status-panel.tone-danger    .detail-status-state { color: var(--bs-danger);    }
.detail-status-panel.tone-warning   .detail-status-state { color: var(--bs-warning);   }
.detail-status-panel.tone-success   .detail-status-state { color: var(--bs-success);   }
.detail-status-panel.tone-info      .detail-status-state { color: var(--bs-info);      }
.detail-status-panel.tone-primary   .detail-status-state { color: var(--bs-primary);   }
.detail-status-panel.tone-secondary .detail-status-state { color: var(--bs-secondary); }


/* ========================================================================
   Timeline (vertical event feed)
   ========================================================================
   Vertical list with a hairline connector and tone-colored dots. Used for
   incident history, job lifecycle events, recent activity in user/group
   overviews, audit trails. Renders as an `<ol>` with `.detail-timeline`
   on the root and `.detail-timeline-item.tone-*` on each entry.

   JS: src/core/views/data/Timeline.js
*/
.detail-timeline {
    list-style: none;
    margin: 0;
    padding: 0 0 0 1.1rem;
    position: relative;
}
.detail-timeline::before {
    content: '';
    position: absolute;
    left: 0.35rem; top: 0.5rem; bottom: 0.5rem;
    width: 1px;
    background: linear-gradient(180deg, var(--bs-border-color), transparent);
}
.detail-timeline-item {
    position: relative;
    padding: 0.4rem 0 0.85rem;
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.5rem;
}
.detail-timeline-item::before {
    content: '';
    position: absolute;
    left: -1.1rem; top: 0.75rem;
    width: 0.55rem; height: 0.55rem;
    border-radius: 999px;
    background: var(--bs-tertiary-bg);
    border: 1.5px solid var(--bs-secondary-color);
}
.detail-timeline-item.tone-danger::before    { border-color: var(--bs-danger);    }
.detail-timeline-item.tone-warning::before   { border-color: var(--bs-warning);   }
.detail-timeline-item.tone-success::before   { border-color: var(--bs-success);   }
.detail-timeline-item.tone-info::before      { border-color: var(--bs-info);      }
.detail-timeline-item.tone-primary::before   { border-color: var(--bs-primary);   }
.detail-timeline-item.tone-secondary::before { border-color: var(--bs-secondary); }
.detail-timeline-headline {
    font-size: 0.85rem;
    color: var(--bs-body-color);
    font-weight: 500;
}
.detail-timeline-detail {
    font-size: 0.8rem;
    color: var(--bs-secondary-color);
}
.detail-timeline-when {
    font-family: var(--bs-font-monospace);
    font-size: 0.72rem;
    color: var(--bs-secondary-color);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    align-self: start;
}
.detail-timeline-empty {
    list-style: none;
    padding: 0.5rem 0;
}


/* ========================================================================
   DetailView — Flat labeled-section primitives
   ========================================================================
   The minimalist "labeled section eyebrow + flat field rows" pattern
   that section views in DetailView subclasses default to.

   Use:
     <div class="detail-section">
       <div class="detail-section-eyebrow">
         CONTACT & VERIFICATION
         <button class="detail-section-action" data-action="edit-contact">
           <i class="bi bi-pencil"></i>
         </button>
       </div>
       <div class="detail-flat-row">
         <div class="detail-flat-row-label">Email</div>
         <div class="detail-flat-row-value">…</div>
         <div class="detail-flat-row-action">
           <button class="detail-section-action" data-action="…">…</button>
         </div>
       </div>
       …
     </div>
*/
.detail-section { margin-bottom: 2.5rem; }
.detail-section:last-child { margin-bottom: 0; }
.detail-section-eyebrow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin: 0 0 0.4rem;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);
}
/* Subsection eyebrows (a second `Account` eyebrow after a stack of rows
   or items inside the same section) get automatic breathing room above
   when they're not the first child of their parent. No inline `mt-3` /
   `mt-4` needed in templates. */
.detail-section-eyebrow:not(:first-child) {
    margin-top: 1.25rem;
}
.detail-section-action {
    background: transparent;
    border: 1px solid transparent;
    color: var(--bs-tertiary-color, var(--bs-secondary-color));
    cursor: pointer;
    padding: 0.2rem 0.4rem;
    font-size: 0.78rem;
    border-radius: 0.3rem;
    line-height: 1;
    opacity: 0.7;
    transition: opacity 0.15s, background 0.15s, color 0.15s;
}
.detail-section-action:hover {
    background: var(--bs-secondary-bg);
    color: var(--bs-primary);
    opacity: 1;
}
.detail-flat-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.55rem 0;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
    font-size: 0.875rem;
    line-height: 1.45;
}
.detail-flat-row:last-child { border-bottom: none; }
[data-bs-theme="dark"] .detail-flat-row {
    border-bottom-color: rgba(255, 255, 255, 0.06);
}
.detail-flat-row-label {
    width: 110px;
    flex-shrink: 0;
    font-size: 0.8rem;
    color: var(--bs-secondary-color);
}
.detail-flat-row-value {
    flex: 1;
    min-width: 0;
    color: var(--bs-body-color);
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
}
/* URL modifier — for value cells holding long URLs that would otherwise
   blow out the row width. Wraps at any character so long paths don't
   force horizontal overflow inside Modal.detail. */
.detail-flat-row-value--url {
    display: block;
    max-width: 100%;
    word-break: break-all;
    overflow-wrap: anywhere;
}
.detail-flat-row-action {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    flex-shrink: 0;
}


/* ========================================================================
   KnownFieldsCard
   ========================================================================
   Promotes known JSON keys to a 2-column label/value grid with the raw
   blob accessible but visually subordinated below. Reuses the flat-row
   primitives above for the known-keys grid.

   JS: src/core/views/data/KnownFieldsCard.js
*/
.detail-known-fields-card {
    display: block;
    margin-bottom: 1.5rem;
}
.detail-known-fields-grid {
    margin-bottom: 0.85rem;
}
.detail-known-fields-raw {
    margin-top: 1rem;
    border: 0;
    border-radius: 0.6rem;
    background: var(--bs-tertiary-bg);
    overflow: hidden;
}
.detail-known-fields-raw-summary {
    cursor: pointer;
    list-style: none;
    padding: 0.5rem 0.85rem;
    font-size: 0.78rem;
    color: var(--bs-secondary-color);
    user-select: none;
    display: flex;
    align-items: center;
    gap: 0.4rem;
}
.detail-known-fields-raw-summary::-webkit-details-marker { display: none; }
.detail-known-fields-raw-summary::before {
    content: '\25B6'; /* ▶ */
    display: inline-block;
    font-size: 0.65rem;
    transition: transform 0.15s;
    color: var(--bs-tertiary-color, var(--bs-secondary-color));
}
.detail-known-fields-raw[open] > .detail-known-fields-raw-summary::before {
    transform: rotate(90deg);
}
.detail-known-fields-raw-summary:hover { color: var(--bs-body-color); }
.detail-known-fields-raw-body {
    margin: 0;
    padding: 0.75rem 0.85rem 0.85rem;
    border-top: 1px solid var(--bs-border-color-translucent);
    font-family: var(--bs-font-monospace);
    font-size: 0.78rem;
    color: var(--bs-body-color);
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 28rem;
    overflow: auto;
    background: rgba(0, 0, 0, 0.02);
}
[data-bs-theme="dark"] .detail-known-fields-raw-body {
    background: rgba(255, 255, 255, 0.02);
}


/* ========================================================================
   FlowStrip (horizontal STEP 1 → STEP 2 → … flow)
   ========================================================================
   Used for records that describe a process — RuleSet triggering
   (Match → Bundle → Threshold → Re-trigger), incident triage, anywhere
   a sequence of stages reads better as a left-to-right strip than a
   flat field list. Chevron arrows separate steps; the strip wraps to
   2 columns on tablet and 1 on mobile.

   JS: src/core/views/data/FlowStrip.js
*/
/* Borderless tinted surface; thin translucent hairlines between
   steps replace the bordered + chevroned 2025 treatment. The strip
   uses container queries so it stacks before the steps get crunched
   inside an `lg` modal. */
.detail-flow-strip {
    container-type: inline-size;
    display: grid;
    grid-template-columns: repeat(var(--flow-strip-cols, 4), 1fr);
    background: var(--bs-tertiary-bg);
    border: 0;
    border-radius: 0.75rem;
    overflow: hidden;
    margin-bottom: 1.5rem;
}
.detail-flow-strip .flow-strip-step {
    padding: 1rem 1.1rem;
    background: transparent;
    position: relative;
    min-width: 0;
}
.detail-flow-strip .flow-strip-step + .flow-strip-step {
    border-left: 1px solid var(--bs-border-color-translucent);
}
.detail-flow-strip .flow-strip-num {
    font-family: var(--bs-font-monospace);
    font-size: 0.62rem;
    color: var(--bs-tertiary-color, var(--bs-secondary-color));
    font-weight: 600;
    letter-spacing: 0.04em;
}
.detail-flow-strip .flow-strip-title {
    font-size: 0.78rem;
    font-weight: 600;
    margin: 0.15rem 0 0.35rem;
    display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
    color: var(--bs-emphasis-color, var(--bs-body-color));
}
.detail-flow-strip .flow-strip-title .flow-strip-action {
    padding: 0.1rem 0.35rem;
    font-size: 0.7rem;
}
.detail-flow-strip .flow-strip-value {
    font-size: 0.82rem;
    color: var(--bs-body-color);
    font-weight: 500;
    line-height: 1.35;
}
.detail-flow-strip .flow-strip-empty {
    color: var(--bs-secondary-color);
    font-style: italic;
    font-weight: 400;
}
.detail-flow-strip .flow-strip-hint {
    font-size: 0.72rem;
    color: var(--bs-secondary-color);
    margin-top: 0.25rem;
    line-height: 1.4;
}
/* Container-query stacking: based on the strip's own width (not the
   viewport) so it stacks correctly when nested inside narrow modals. */
@container (max-width: 760px) {
    .detail-flow-strip { grid-template-columns: 1fr 1fr; }
}
@container (max-width: 460px) {
    .detail-flow-strip { grid-template-columns: 1fr; }
    .detail-flow-strip .flow-strip-step + .flow-strip-step {
        border-left: 0;
        border-top: 1px solid var(--bs-border-color-translucent);
    }
}


/* ========================================================================
   DetailView / DetailHeaderView
   ========================================================================
   Standard record-detail layout: flat header (icon, title, subtitle, chips,
   active toggle, actions, X close) + SideNavView. The shell flexes to fill
   the modal body so the rail extends to the bottom edge.
*/
.detail-view, .detail-view-shell {
    display: flex;
    flex-direction: column;
    min-height: 100%;
    height: 100%;
}
.detail-view-body { flex: 1 1 auto; min-height: 0; display: flex; }
.detail-view-body > .side-nav-view { flex: 1 1 auto; min-height: 0; }

.detail-header {
    padding: 1.25rem 1.5rem;
    border-bottom: 1px solid var(--bs-border-color);
    position: relative;
}
/* Right-side action cluster floats out of flex flow so the title block
   (subtitle + chips) can use the full row width below it. The cluster only
   occupies the top row vertically, so chips never collide with it. */
.detail-header .dh-actions {
    position: absolute;
    top: 1.25rem;
    right: 1.5rem;
    z-index: 1;
}
/* Reserve space on the right of the title row so a long name doesn't run
   under the absolute-positioned actions. */
.detail-header .dh-meta { padding-right: 200px; }
/* Mobile reflow — sm-breakpoint (matches Bootstrap's `sm` cutoff).
   ⋮ ✕ stay pinned top-right (don't stack below the title); muted aux
   content (relative-time meta line, "Online"/"Offline" label, inactivity
   warnings) hides to keep the cluster compact. The active toggle and
   the icon-only chrome stay visible. */
@media (max-width: 575.98px) {
    .detail-header { padding: 1rem 1rem; }
    .detail-header > .d-flex.align-items-start { gap: 0.6rem !important; }
    /* Keep the action cluster pinned top-right, just tighter */
    .detail-header .dh-actions {
        top: 1rem;
        right: 1rem;
        gap: 0.1rem;
    }
    /* Reserve room only for the compressed top-right cluster */
    .detail-header .dh-meta { padding-right: 100px; }
    .detail-header .dh-icon {
        width: 36px;
        height: 36px;
        font-size: 1.1rem;
    }
    .detail-header .dh-name { font-size: 1.05rem; }
    .detail-header .dh-subtitle { font-size: 0.8rem; }
    /* Hide muted secondary aux content — the toggle and dot stay; the
       relative-time / Online-Offline / warning rows go away to fit the
       tighter top-right cluster. The full info is still reachable inside
       the modal sections. */
    .detail-header .dh-aux .dh-aux-meta,
    .detail-header .dh-aux .dh-aux-warning { display: none; }
    .detail-header .dh-aux .dh-aux-presence > span:not(.dh-aux-dot) { display: none; }
    .detail-header .dh-active-switch .dh-track-label { display: none; }
    .detail-header .dh-aux-top { gap: 0.4rem; }
    /* Group separator hides — there's no Group 1 / Group 2 visual division
       worth keeping at mobile width. */
    .detail-header .dh-group-sep { display: none; }
}

.detail-header .dh-icon {
    width: 44px; height: 44px;
    border-radius: 0.5rem;
    background: rgba(13, 110, 253, 0.10);
    color: var(--bs-primary);
    border: 1px solid transparent;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 1.4rem;
    flex-shrink: 0;
}
/* Image slot — drops the tinted background so the caller's HTML (avatar
   img, custom badge) carries the visual identity. The container becomes
   a 44x44 frame with rounded corners; <img> children stretch to fill. */
.detail-header .dh-icon-image {
    background: transparent;
    border: none;
    padding: 0;
    overflow: hidden;
}
.detail-header .dh-icon-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.detail-header .dh-icon-image .dh-icon-action {
    width: 100%;
    height: 100%;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Toned icon variants — opt-in via header `iconTone: 'danger'|'warning'|'success'|'info'|'primary'` */
.detail-header .dh-icon.dh-icon-tone-danger {
    color: var(--bs-danger);
    background: rgba(var(--bs-danger-rgb), 0.10);
    border-color: rgba(var(--bs-danger-rgb), 0.25);
}
.detail-header .dh-icon.dh-icon-tone-warning {
    color: var(--bs-warning);
    background: rgba(var(--bs-warning-rgb), 0.10);
    border-color: rgba(var(--bs-warning-rgb), 0.25);
}
.detail-header .dh-icon.dh-icon-tone-success {
    color: var(--bs-success);
    background: rgba(var(--bs-success-rgb), 0.10);
    border-color: rgba(var(--bs-success-rgb), 0.25);
}
.detail-header .dh-icon.dh-icon-tone-info {
    color: var(--bs-info);
    background: rgba(var(--bs-info-rgb), 0.10);
    border-color: rgba(var(--bs-info-rgb), 0.25);
}
.detail-header .dh-icon.dh-icon-tone-primary {
    color: var(--bs-primary);
    background: rgba(var(--bs-primary-rgb), 0.10);
    border-color: rgba(var(--bs-primary-rgb), 0.25);
}
.detail-header .dh-name-row {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    flex-wrap: wrap;
    min-width: 0;
}
.detail-header .dh-name {
    font-size: 1.25rem;
    font-weight: 600;
    margin: 0 0 0.15rem;
    color: var(--bs-emphasis-color, var(--bs-body-color));
    min-width: 0;
}
/* Trusted-HTML slot rendered inline beside the title — for copy buttons,
   edit pencils, or other context-relevant single-icon affordances. The
   inline icon-button below is the standard ghost treatment; consumers
   that need different styling can override at the button class level. */
.detail-header .dh-title-affix {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}
.detail-header .dh-title-affix .dh-name-action {
    background: transparent;
    color: var(--bs-secondary-color);
    border: 1px solid transparent;
    padding: 0.15rem 0.35rem;
    border-radius: 0.3rem;
    cursor: pointer;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    font-size: 0.85rem;
}
.detail-header .dh-title-affix .dh-name-action:hover {
    background: var(--bs-tertiary-bg);
    border-color: var(--bs-border-color);
    color: var(--bs-body-color);
}
.detail-header .dh-subtitle {
    color: var(--bs-secondary-color);
    font-size: 0.875rem;
    margin: 0 0 0.5rem;
    max-width: 720px;
    line-height: 1.45;
}
.detail-header .dh-subtitle-empty {
    font-style: italic;
    color: var(--bs-tertiary-color, var(--bs-secondary-color));
    opacity: 0.85;
}
.detail-header .dh-subtitle-empty[role="button"] { cursor: pointer; }
.detail-header .dh-subtitle-empty[role="button"]:hover {
    color: var(--bs-primary);
    opacity: 1;
}
.detail-header .dh-chips {
    display: flex; gap: 0.4rem; flex-wrap: wrap; align-items: center;
}

/* Ghost-style action — quieter than Bootstrap's default outline buttons */
.detail-header .dh-action {
    background: transparent;
    color: var(--bs-secondary-color);
    border: 1px solid transparent;
    padding: 0.25rem 0.6rem;
    font-size: 0.85rem;
    border-radius: 0.375rem;
    cursor: pointer;
    line-height: 1.2;
    display: inline-flex; align-items: center; gap: 0.25rem;
}
.detail-header .dh-action:hover {
    background: var(--bs-tertiary-bg);
    border-color: var(--bs-border-color);
    color: var(--bs-body-color);
}
.detail-header .dh-close {
    padding: 0.25rem 0.45rem;
    color: var(--bs-tertiary-color, var(--bs-secondary-color));
    margin-left: 0.15rem;
}

/* Vertical hairline between Group 1 (record actions) and Group 2 (modal chrome) */
.detail-header .dh-group-sep {
    display: inline-block;
    width: 1px;
    height: 16px;
    background: var(--bs-border-color);
    margin: 0 0.2rem 0 0.1rem;
    opacity: 0.5;
}

/* Active toggle — small, subtle, secondary-text label. Tuned to read as
   a hint, not a primary control: the green-when-checked track is the
   only color signal; the label stays muted in both states. */
.dh-active-switch {
    display: inline-flex; align-items: center; gap: 0.35rem;
    cursor: pointer; user-select: none;
    font-size: 0.72rem;
    color: var(--bs-secondary-color);
    line-height: 1;
}
.dh-active-switch input { display: none; }
.dh-active-switch .dh-track {
    width: 24px; height: 13px;
    background: var(--bs-secondary-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 999px;
    position: relative;
    transition: background 0.15s, border-color 0.15s;
}
.dh-active-switch .dh-track::after {
    content: '';
    position: absolute; top: 1px; left: 1px;
    width: 9px; height: 9px;
    background: var(--bs-body-bg);
    border-radius: 999px;
    transition: transform 0.15s;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}
.dh-active-switch input:checked + .dh-track {
    background: var(--bs-success);
    border-color: var(--bs-success);
}
.dh-active-switch input:checked + .dh-track::after { transform: translateX(11px); }
/* Don't bump label weight on checked — keep the toggle subtle. The dot
   color carries the state signal; the label just identifies what's
   being toggled. */
.dh-active-switch .dh-track-label { font-weight: 400; }

/* Aux slot — right-gutter inline state read-out (presence, last-seen,
   attempt counter, etc.). Trusted HTML emitted by `auxFn(model)`. */
.detail-header .dh-aux {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.1rem;
    margin-right: 0.25rem;
    font-size: 0.78rem;
    line-height: 1.3;
    color: var(--bs-secondary-color);
    text-align: right;
    user-select: none;
}
.detail-header .dh-aux .dh-aux-presence {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--bs-body-color);
    font-weight: 500;
}
.detail-header .dh-aux .dh-aux-dot {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: 999px;
    background: var(--bs-secondary);
    box-shadow: 0 0 0 2px rgba(var(--bs-secondary-rgb), 0.18);
}
.detail-header .dh-aux .dh-aux-dot.is-online {
    background: var(--bs-success);
    box-shadow: 0 0 0 2px rgba(var(--bs-success-rgb), 0.18);
}
.detail-header .dh-aux .dh-aux-meta {
    color: var(--bs-secondary-color);
    font-size: 0.72rem;
}
/* Inactivity-warning row inside the aux block. Yellow muted, with a
   "Reset" link that reactivates the user (clearing the warning).
   Shown only when `metadata.protected.disable.warning.sent_at` is set
   AND `is_active=true`. */
.detail-header .dh-aux .dh-aux-warning {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.2rem;
    font-size: 0.72rem;
    color: var(--bs-warning-text-emphasis, #997404);
    background: var(--bs-warning-bg-subtle, rgba(255, 193, 7, 0.12));
    border: 1px solid var(--bs-warning-border-subtle, rgba(255, 193, 7, 0.3));
    padding: 0.2rem 0.5rem;
    border-radius: 0.3rem;
}
.detail-header .dh-aux .dh-aux-warning a {
    color: inherit;
    font-weight: 600;
    margin-left: 0.25rem;
}
/* Two-row aux block: top row holds inline controls (presence + active
   toggle, attempt counter + retry, etc); bottom row is a muted meta line.
   Used by views that emit their own active toggle from auxFn. */
.detail-header .dh-aux .dh-aux-top {
    display: flex;
    align-items: center;
    gap: 1rem;
}
.detail-header .dh-aux .dh-aux-top + .dh-aux-meta { margin-top: 0.15rem; }

[data-bs-theme="dark"] .detail-header .dh-icon {
    background: rgba(77, 139, 255, 0.16);
}

/* ========================================================================
   SideNavView
   ========================================================================
   Sectioned detail layout — left rail of nav links beside a content panel
   that mounts one child view at a time. Width and content padding are
   applied per-instance via inline `style="..."` attributes from the JS
   template (the only two values that vary per consumer).
*/
.snv-layout { display: flex; height: 100%; min-height: 0; }
.snv-nav {
    background: var(--bs-tertiary-bg);
    border-right: 1px solid var(--bs-border-color);
    padding: 0.75rem 0;
    flex-shrink: 0;
    overflow-y: auto;
}
.snv-nav a {
    color: var(--bs-secondary-color);
    padding: 0.45rem 1.25rem;
    font-size: 0.85rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    text-decoration: none;
    cursor: pointer;
}
.snv-nav a:hover {
    background: var(--bs-secondary-bg);
    color: var(--bs-body-color);
}
.snv-nav a.active {
    background: rgba(13, 110, 253, 0.10);
    color: var(--bs-primary);
    font-weight: 600;
    border-right: 2px solid var(--bs-primary);
}
.snv-nav a i { width: 18px; text-align: center; font-size: 0.9rem; }
.snv-nav-label {
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--bs-tertiary-color, var(--bs-secondary-color));
    padding: 0.75rem 1.25rem 0.25rem;
}

/* Section badges — right-aligned pills inside nav links */
.snv-badge {
    margin-left: auto;
    font-size: 0.7rem;
    font-weight: 600;
    padding: 0.05rem 0.45rem;
    border-radius: 999px;
    line-height: 1.4;
    font-variant-numeric: tabular-nums;
}
.snv-badge-muted   { background: var(--bs-secondary-bg); color: var(--bs-secondary-color); }
.snv-badge-primary { background: var(--bs-primary); color: #fff; }
.snv-badge-success { background: var(--bs-success); color: #fff; }
.snv-badge-warning { background: var(--bs-warning); color: #000; }
.snv-badge-danger  { background: var(--bs-danger);  color: #fff; }
.snv-nav a.active .snv-badge-muted {
    background: var(--bs-primary);
    color: #fff;
}

.snv-content {
    flex: 1;
    overflow-y: auto;
    min-width: 0;
}
.snv-content > .snv-section { display: none; }
.snv-content > .snv-section.snv-active { display: block; }

.snv-dropdown { margin-bottom: 0.75rem; }
.snv-select-btn {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.5rem 1rem;
    background: var(--bs-tertiary-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
    font-size: 0.85rem;
    color: var(--bs-body-color);
    cursor: pointer;
}
.snv-select-btn:hover { background: var(--bs-secondary-bg); }
.snv-select-btn::after {
    content: '';
    display: inline-block;
    margin-left: auto;
    border-top: 0.3em solid;
    border-right: 0.3em solid transparent;
    border-left: 0.3em solid transparent;
}

@media (max-width: 576px) {
    .snv-nav { display: none; }
    .snv-content { padding: 1.25rem !important; }
}

[data-bs-theme="dark"] .snv-nav a.active {
    background: rgba(77, 139, 255, 0.16);
}
[data-bs-theme="dark"] .snv-badge-warning { color: #000; }
