:root {
  --background_color: rgb(255, 255, 255); /*rgba(255, 253, 208);*/
  --navbar-height: 64px;

  /* ── The app's ONLY two blues ──────────────────────────────────────────
     Every dark header/bar in the app and every "accent" link/button/tab
     must use one of these two variables (never a hand-rolled hex/rgba).
     Both are solid (no alpha) so they render identically regardless of
     what's behind them / whether backdrop-filter is applied. */
  --apex-blue-dark: #1a2848;        /* solid equivalent of the old rgba(15,23,42,0.92) navbar color */
  --apex-blue-light: #1f5f8b;       /* the "active nav tab" dim blue */
  --apex-blue-light-hover: #174768; /* darker shade of the light blue, for hover/active states only */
}

.modebar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--navbar-height);
    z-index: 3000;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 0 16px;
    background: var(--apex-blue-dark) !important;
    backdrop-filter: blur(8px);
}

.modebar-title {
    position: absolute;
    left: 16px;
    margin: 0;
    color: white;
    font-size: 1.1rem;
    font-weight: 800;
    line-height: 1;
    white-space: nowrap;
}

.modebar-nav {
    display: flex;
    gap: 12px;
    align-items: center;
    justify-content: center;
}

.top-nav-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 10px 18px;
    border-radius: 12px;
    text-decoration: none;
    font-weight: 700;
    color: white;
    background: rgba(255, 255, 255, 0.12);
}

.top-nav-btn:hover {
    background: rgba(255, 255, 255, 0.2);
    color: white;
    text-decoration: none;
}

.analysis-layer,
.overlay-layer {
    position: fixed;

    top: var(--navbar-height);
    left: 0;
    right: 0;
    bottom: 0;

    overflow-y: auto;

    background-color: var(--background_color);

    overscroll-behavior: contain;
}
.page-shell {
    min-height: calc(100vh - var(--navbar-height));
}

/* A dbc.Collapse mounted already-open (is_open=True at page load) measures
   its content's height at that moment and can lock onto it. That's mostly
   invisible for content that stays roughly the same size (e.g. a form), but
   for a Collapse wrapping something that starts EMPTY and later grows a lot
   (e.g. the DESeq2/Enrichment result cards, empty until an analysis runs and
   then holding a 700px plot) it silently clips all of that later content
   inside the small height it locked onto — even overflow:visible alone
   doesn't fully fix this if height itself is still pinned, so force both. */
.collapse.show {
    overflow: visible !important;
    height: auto !important;
}

/* Lock scrolling when overlay is open */
body.overlay-open, html.overlay-open {
    overflow: hidden !important;
    height: 100%;
}

/* Active navigation button */
.top-nav-btn.active {
    background: var(--apex-blue-light) !important;
    color: white;
}



/* Global page */
/* background: linear-gradient(135deg, #f8f3e1 0%, #FFFFFF 100%) !important; */
html, body {
    margin: 0;
    padding: 0;

    width: 100%;
    height: 100%;

    overflow: hidden;

    background-color: var(--background_color) !important;
    font-family:
        -apple-system,
        BlinkMacSystemFont,
        'Segoe UI',
        Roboto,
        Helvetica,
        Arial,
        sans-serif;

    color: var(--apex-blue-dark) !important;
}

/* Main centered container */
.app-container {
    max-width: 1300px;
    margin: 0 auto;
    padding: 36px 18px;
    background-color: transparent !important;
}


/* Page title */
.app-main-title {
    color: var(--apex-blue-dark) !important;
    font-weight: 800;
    font-size: 2.4rem;
    margin-bottom: 32px;
    letter-spacing: -0.03em;
}


/* Material cards*/
.custom-card {
    position: relative;

    background: rgba(255, 255, 255, 0.96) !important;

    border: none !important;
    border-radius: 20px !important;

    overflow: hidden;

    backdrop-filter: blur(8px);

    margin-top: 1.5rem;
    margin-bottom: 1.5rem;

    transition:
        transform 0.22s ease,
        box-shadow 0.22s ease;

    /* Material-like elevation */
    box-shadow:
        0 4px 6px rgba(0,0,0,0.05),
        0 10px 20px rgba(0,0,0,0.08),
        0 18px 38px rgba(0,0,0,0.06) !important;
}

/* Hover lift */
.custom-card:hover {
    transform: translateY(-4px);

    box-shadow:
        0 8px 12px rgba(0,0,0,0.08),
        0 18px 28px rgba(0,0,0,0.12),
        0 30px 60px rgba(0,0,0,0.10) !important;
}

/* Shadow for all dbc.Card components (analysis page cards) */
.card {
    box-shadow:
        0 2px 4px rgba(0,0,0,0.06),
        0 6px 16px rgba(0,0,0,0.09) !important;
    border-radius: 12px !important;
    overflow: hidden;
}

/* Bootstrap primary override — uses the app's single "dim light blue" accent.
   Covers: Dataset Composition / Preliminary Analysis / Functional Enrichment expand-
   collapse buttons, the volcano/MA "Apply" buttons, and "Run Enrichment
   Analysis" — anything using dbc.Button(color='primary'). */
html body .btn.btn-primary,
html body .btn-primary {
    background-color: var(--apex-blue-light) !important;
    /*background-color: #1f5f8b !important;*/
    border-color: var(--apex-blue-light) !important;
    /*border-color: #1f5f8b !important;*/
    color: #ffffff !important;
}
html body .btn.btn-primary:hover,
html body .btn-primary:hover,
html body .btn-primary:focus,
html body .btn-primary:active {
    background-color: var(--apex-blue-light-hover) !important;
    /*background-color: #174768 !important;*/
    border-color: var(--apex-blue-light-hover) !important;
    /*border-color: #174768 !important;*/
    color: #ffffff !important;
    box-shadow: none !important;
}

/* Bootstrap's .text-primary utility (used e.g. on the Functional Enrichment
   Settings panel title, and the filter funnel icon) — same light blue. */
.text-primary {
    color: var(--apex-blue-light) !important;
}

/* Info-button icons: light blue by default, white variant for dark headers */
.info-btn-link {
    color: var(--apex-blue-light) !important;
}
.info-btn-link:hover {
    color: var(--apex-blue-light-hover) !important;
}
.info-btn-link.white-icon { color: #ffffff !important; }
.info-btn-link.white-icon:hover { color: rgba(255,255,255,0.75) !important; }

/* Links rendered inside AgGrid cells (e.g. the LinkRenderer used in the
   Database table's first card) */
.ag-cell a,
.ag-cell a:visited {
    color: var(--apex-blue-light) !important;
}
.ag-cell a:hover {
    color: var(--apex-blue-light-hover) !important;
}

/* "Enforce Field Dependencies" switch */
#dependency-toggle .form-check-input:checked {
    background-color: var(--apex-blue-light) !important;
    border-color: var(--apex-blue-light) !important;
}
#dependency-toggle .form-check-input:focus {
    border-color: var(--apex-blue-light) !important;
    box-shadow: 0 0 0 0.2rem rgba(31, 95, 139, 0.25) !important;
}



/* Card headers — override Bootstrap's .card-header with high specificity */
html body .card > .card-header.card-header-styled,
html body .card-header-styled {
    position: relative;
    border: none !important;
    padding: 18px 24px !important;
    font-size: 1.3rem !important;
    font-weight: 700 !important;
    letter-spacing: 0.01em;
    background: var(--apex-blue-dark) !important;
    background-color: var(--apex-blue-dark) !important;
    color: #ffffff !important;
    display: flex;
    align-items: center;
    gap: 12px;
}

html body .card > .card-header.card-small-header-styled,
html body .card-small-header-styled {
    position: relative;
    border: none !important;
    padding: 8px 24px !important;
    font-size: 1.3rem !important;
    font-weight: 700 !important;
    letter-spacing: 0.01em;
    background: var(--apex-blue-dark) !important;
    background-color: var(--apex-blue-dark) !important;
    color: #ffffff !important;
    display: flex;
    align-items: center;
    gap: 12px;
}

/* Dataset Composition subcards (per-column cards built while the section is
   expanded) - headers were plain Bootstrap white; force them to the same
   dark blue used everywhere else, with white text to stay legible. Scoped
   generically to .card-header so it also covers headers produced by the
   plot_card_header() helper, not just the plain dbc.CardHeader(col) ones. */
#composition-container .card > .card-header {
    background: var(--apex-blue-dark) !important;
    color: #ffffff !important;
    border: none !important;
}
#composition-container .card > .card-header * {
    color: #ffffff !important;
}


/* Decorative top shine */
.card-header-styled::after {
    content: '';

    position: absolute;

    top: 0;
    left: 0;
    right: 0;

    height: 2px;

    background: rgba(255,255,255,0.35);
}


/* Optional header icons */
.header-icon {
    width: 34px;
    height: 34px;

    border-radius: 10px;

    background: rgba(255,255,255,0.18);

    display: flex;
    align-items: center;
    justify-content: center;

    font-size: 1rem;

    backdrop-filter: blur(4px);
}


/* Card body */
.card-body-styled {
    padding: 26px !important;
    background-color: #ffffff !important;
}


/* Labels + inputs */
.small-label {
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--apex-blue-light) !important; /*#475569 !important;*/
    margin-bottom: 6px;
}

.custom-search-bar {
    border-radius: 12px !important;

    border: 1px solid #dbe4f0 !important;

    padding: 11px 16px !important;

    font-size: 0.95rem;

    background: #ffffff;

    transition:
        border-color 0.2s ease,
        box-shadow 0.2s ease,
        background 0.2s ease;
}

.custom-search-bar:focus {
    background: white;

    border-color: #3b82f6 !important;

    box-shadow:
        0 0 0 4px rgba(59,130,246,0.12) !important;
}


/* Buttons */
.action-btn {
    border-radius: 12px !important;

    padding: 11px 30px !important;

    font-weight: 700 !important;

    border: none !important;

    transition:
        transform 0.15s ease,
        box-shadow 0.15s ease;
}

.action-btn:hover {
    transform: translateY(-1px);

    box-shadow:
        0 8px 18px rgba(0,0,0,0.15);
}

.download-btn {
    font-size: 0.9rem !important;
    padding: 9px 16px !important;
}





/* ── Modern Table Container with an Outer Outline ─────────────────────── */
/* ── The Structural Overhaul ─────────────────────────────────────────── */
.custom-table-container {
    border: 1px solid #dcdcdc !important; 
    border-radius: 8px !important;        
    overflow: hidden !important;          
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); 
    display: flex !important;          /* Changed from block to flex to kill all hidden baselines */
    flex-direction: column !important;
    padding: 0 !important;
    margin-top: 0 !important;
}

/* Clear out any deep hidden sub-elements generated by Dash Bootstrap components */
.custom-table-container > div,
.custom-table-container > table {
    margin: 0 !important;
    padding: 0 !important;
}

/* Beautiful Table Resets */
.custom-beautiful-table {
    border-collapse: collapse !important; /* Flatten cell boundaries to destroy any double rows */
    width: 100% !important;
    color: var(--apex-blue-light) !important; /*#4a5568 !important;*/
    background-color: #ffffff !important;
    margin: 0 !important;
}

html body .custom-beautiful-table thead th {
    background-color: var(--apex-blue-dark) !important;
    /*background-color: #0f172a !important; */
    color: #f9f9f9 !important;
    font-weight: 600;
    text-transform: uppercase;
    font-size: 1rem; /* 0.75rem; */
    letter-spacing: 0.05em;
    padding: 10px 14px !important;
    border-bottom: 2px solid #cbd5e0 !important;
}

/* Target every single row and remove double bounding behaviors */
.custom-beautiful-table tbody tr {
    border-bottom: 1px solid #edf2f7 !important;
    background-color: #ffffff;
}

/* ── THE NUCLEAR BLANK-LINE ERASED STRATEGY ────────────────────────── */
/* Completely strip the bottom line from the final actual data row */
.custom-beautiful-table tbody tr:last-of-type,
.custom-beautiful-table tbody tr:last-child {
    border-bottom: none !important;
}

.custom-beautiful-table tbody tr:last-of-type td,
.custom-beautiful-table tbody tr:last-child td {
    border-bottom: none !important;
}

/* Force-remove any ghost pseudo-elements (like ::after or ::before) injected by themes */
.custom-beautiful-table::after,
.custom-beautiful-table::before,
.custom-table-container::after,
.custom-table-container::before {
    content: none !important;
    display: none !important;
    height: 0 !important;
}
/* ─────────────────────────────────────────────────────────────────────── */

/* Zebra Striping */
.custom-beautiful-table.table-striped tbody tr:nth-of-type(odd) {
    background-color: #f7fafc !important;
}

/* Interactive Row Hover Effect */
.custom-beautiful-table tbody tr:hover {
    background-color: #edf2f7 !important;
}



/* ── Consistent Custom Tab Styling ────────────────────────────────────── */
.custom-tabs-container {
    background: transparent;
    overflow: visible !important;
}

/* The underlying tab horizontal track bar. flex-wrap lets a long row of
   tabs (e.g. the 13 on the DESeq2 results card) settle onto a tight second
   line instead of every tab being squeezed ever-narrower to force them
   onto one row — which was also the most likely cause of wheel-scroll
   getting swallowed when hovering that area (a squeezed/overflowing flex
   row is exactly the kind of element a browser will try to scroll
   internally first). */
.custom-tabs {
    border-bottom: none !important;
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: wrap !important;
    margin-bottom: 8px !important;
    gap: 4px;
    overflow: visible !important;
}

.tab-info-btn {
    font-size: 13px !important;
    color: inherit !important;
    opacity: 0.85;
}
.tab-info-btn:hover {
    color: inherit !important;
    opacity: 1;
}

/* Default state for unselected tab */
html body .custom-tab {
    background-color: #ffffff !important;
    border: 2px solid var(--apex-blue-light) !important;
    /*border: 2px solid #1f5f8b !important;*/
    border-radius: 6px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    color: var(--apex-blue-light) !important;
    /*color: #1f5f8b !important;*/
    padding: 5px 10px !important;
    font-weight: 500;
    font-size: 0.82rem;
    cursor: pointer;
    transition: all 0.2s ease;
    /* Tabs size to their own content and wrap tightly (was flex: 1 1 auto,
       which stretched/squeezed every tab to fill exactly one row). */
    flex: 0 1 auto !important;
    min-width: 108px;
    text-align: center !important;
    margin-bottom: 0 !important;
    line-height: 1.2 !important;
}

/* Hover state for tabs */
html body .custom-tab:hover {
    background-color: #e8f0fe !important;
    color: var(--apex-blue-light-hover) !important;
    /*color: #475569 !important; /*#174768 !important;*/
}

/* The Active / Selected Tab State */
html body .custom-tab--selected {
    background-color: var(--apex-blue-light) !important;
    /*background-color: #1f5f8b !important;*/
    color: #ffffff !important;
    border: 2px solid var(--apex-blue-light) !important;
    /*border: 2px solid #1f5f8b !important;*/
    font-weight: 600 !important;
}

.custom-control-panel {
    background-color: #f8fafc !important; /* Soft, professional cool-gray tint */
    border: 1px solid #e2e8f0 !important;   /* Clean, non-distracting border line */
    border-radius: 8px !important;         /* Matches modern UI layout flows */
    padding: 16px !important;              /* Generous inner breathing room */
    margin-bottom: 24px !important;         /* Explicit boundary spacing before the plot begins */
    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.02); /* Subtle inner depth */
}


/* Plotly modebar */

/* Decent bar */
.js-plotly-plot .plotly .modebar,
.js-plotly-plot .plotly .modebar-container {
    position: absolute !important;
    top: 8px !important;
    right: 8px !important;
    left: auto !important;
    width: auto !important;
    max-width: none !important;
    height: auto !important;
    display: flex !important;
    align-items: center !important;
    background: transparent !important;
    box-shadow: none !important;
    z-index: 10 !important;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease-in-out;
}

.js-plotly-plot:hover .plotly .modebar,
.js-plotly-plot:hover .plotly .modebar-container {
    opacity: 1;
    pointer-events: auto;
}

.js-plotly-plot .plotly .modebar-row {
    display: flex !important;
    flex-wrap: nowrap !important;
    width: auto !important;
    margin: 0 !important;
    padding: 0 !important;
}

.js-plotly-plot .plotly .modebar-group {
    display: flex !important;
    width: auto !important;
    margin: 0 2px !important;
    padding: 2px 4px !important;
    border-radius: 6px;
    background: rgba(30, 41, 59, 0.85) !important;
    backdrop-filter: blur(4px);
}

.js-plotly-plot .plotly .modebar-btn path {
    fill: #ffffff !important;
}

.js-plotly-plot .plotly .modebar-btn:hover path {
    fill: #60a5fa !important;
}







.highlight-target {
    animation: highlight-flash 2s ease forwards;
}

@keyframes highlight-flash {
    0%   { background-color: #fff3cd; }
    30%  { background-color: #ffe69c; }
    100% { background-color: transparent; }
}




/* Container for the subsection toggle button.
   Deliberately colorless: this sits on a white card body, and per request
   should never read as "another blue" alongside the two accent colors used
   everywhere else - it previously had a hardcoded Bootstrap blue (#0d6efd)
   accent that was never migrated to the app's 2-blue system. */
html body .section-toggle-btn {
    background-color: transparent !important;
    border: none !important;
    border-left: 4px solid #ffffff !important;
    padding: 0.5rem 0.75rem !important;
    font-weight: 600;
    color: var(--apex-blue-dark) !important;/*#212529 !important;*/
    transition: background-color 0.2s ease, color 0.2s ease;
    box-shadow: none !important;
}

/* Hover effects for improved interactivity feedback */
html body .section-toggle-btn:hover,
html body .section-toggle-btn:focus,
html body .section-toggle-btn:active,
html body .section-toggle-btn:focus-visible {
    background-color: #f8f9fa !important;
    color: var(--apex-blue-dark) !important;
    box-shadow: none !important;
    outline: none !important;
}

/* Clean styling for the inner dynamic content container.
   Forced white on the container AND on any Bootstrap alert/bg-* utility box
   that might be nested inside it (e.g. a tip/note callout) - if the pale
   blue wasn't the container's own background, it was one of these. Scoped
   strictly to .section-collapse-content descendants so nothing else in the
   app is affected. */
.section-collapse-content,
.section-collapse-content .card,
.section-collapse-content .card-body,
.section-collapse-content .alert,
.section-collapse-content [class*="alert-"],
.section-collapse-content [class*="bg-"] {
    background-color: #ffffff !important;
    background-image: none !important;
}
.section-collapse-content {
    padding: 1rem 1.25rem;
    border: 1px solid #dee2e6;
    border-top: none;
    border-bottom-left-radius: 0.375rem;
    border-bottom-right-radius: 0.375rem;
    font-size: 1.0rem !important; /* Standard base body text size (e.g., 16px) */
    color: var(--apex-blue-dark) !important; /*#495057 !important; */   /* Highly legible charcoal color */
    line-height: 1.6;             /* Enhances readability for long text descriptions */
}

/* Base style for the indicator arrow */
.chevron-arrow {
    display: inline-block;
    transition: transform 0.2s ease-in-out;
}

/* Custom modifier class to smoothly rotate the icon down when opened
   (this is the normal path: click -> Dash callback -> className='...rotated') */
.chevron-arrow.rotated {
    transform: rotate(90deg);
}

/* Backstop: rotate the arrow based on the ACTUAL rendered state of the
   Bootstrap collapse it controls, regardless of what opened it (a real
   click, or something that forces it open by manipulating the DOM/Bootstrap
   collapse classes directly without going through the Dash callback that
   sets .rotated). Bootstrap always adds 'show' to an open .collapse element
   no matter how it was opened, so this can never fall out of sync. */
.section-toggle-btn:has(~ .collapse.show) .chevron-arrow {
    transform: rotate(90deg) !important;
}

.help-card-expand-btn {
    background-color: transparent !important;
    border: none !important;
    color: #ffffff !important;
    font-weight: 600 !important;
    box-shadow: none !important;
}
.help-card-expand-btn:hover,
.help-card-expand-btn:focus,
.help-card-expand-btn:active {
    background-color: rgba(255, 255, 255, 0.15) !important;
    color: #ffffff !important;
    box-shadow: none !important;
}
/* ── DESeq2 card: "Enforce Field Dependencies" toggle ──────────────────── */
/* Overlaid centered on top of the Sample 1 / Sample 2 title row (see
   selector_row()'s header_extra param) — absolutely positioned so it
   doesn't disturb the md=6/md=6 grid the dropdown row below has to stay
   aligned with. */
.selector-row-header-extra {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
}

/* Wraps the existing dbc.Checklist switch in a "nice button" pill instead
   of a bare small switch. */
.dependency-toggle-pill {
    display: inline-flex;
    align-items: center;
    background-color: #ffffff;
    border: 1px solid #d7dce2;
    border-radius: 999px;
    padding: 5px 14px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}
.dependency-toggle-pill:hover {
    border-color: var(--apex-blue-light);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
}

.dependency-toggle-switch {
    margin-bottom: 0 !important;
}
.dependency-toggle-switch .form-check {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 0;
    padding-left: 2.2em;
}
.dependency-toggle-switch .form-check-input {
    width: 2.2em !important;
    height: 1.2em !important;
    margin-left: -2.2em;
    cursor: pointer;
}
.dependency-toggle-switch .form-check-label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--apex-blue-dark) !important;
    cursor: pointer;
}