/* Analysis page — the Summary page's grammar applied to a cohort instead of a
   protein: an identity card that never leaves the screen, then tabs that ask
   different questions of the same subject. */

.analysis-main,
.analysis-shell {
    max-width: 1900px;
    margin-inline: auto;
}

/* --- identity card ------------------------------------------------------- */
.analysis-card {
    overflow: hidden;
}
.analysis-card-head {
    padding: 1rem 1.25rem;
}
.analysis-card-icon {
    font-size: 1.7rem;
    color: var(--bs-primary);
}
.analysis-card-title {
    font-size: 1.45rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}
.analysis-card-desc {
    max-width: 70ch;
}

/* The three numbers, sized to be read from across the room — they are the first
   thing that tells you whether this set is worth a question. */
.analysis-stats {
    flex-shrink: 0;
}
.analysis-stat {
    min-width: 7.5rem;
    padding: 0.35rem 0.85rem;
    border-left: 3px solid rgba(var(--bs-primary-rgb), 0.35);
}
.analysis-stat-value {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}
.analysis-stat-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--bs-secondary-color);
}

/* --- picker -------------------------------------------------------------- */
.analysis-group-box {
    border: 1px solid rgba(var(--bs-secondary-rgb), 0.25);
    border-radius: 0.5rem;
    padding: 0.5rem 0.6rem;
}
.analysis-group-title {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--bs-secondary-color);
    margin-bottom: 0.35rem;
}
.analysis-cohort-item {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.15rem 0;
    cursor: pointer;
    min-width: 0;
}
.analysis-cohort-icon {
    width: 1.15rem;
    height: 1.15rem;
    object-fit: contain;
    font-size: 1.05rem;
    flex-shrink: 0;
    color: var(--bs-secondary-color);
}
.analysis-cohort-pill {
    font-size: 0.72rem;
    font-weight: 500;
    padding: 0.15em 0.55em;
    border-radius: 999px;
    line-height: 1.25;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- tabs ---------------------------------------------------------------- */
.analysis-tabs {
    border: 1px solid var(--bs-border-color);
    border-bottom: 0;
    border-radius: 0.5rem 0.5rem 0 0;
    overflow: hidden;
    background: var(--bs-tertiary-bg);
}
.analysis-tab {
    border: 0;
    background: transparent;
    padding: 0.55rem 1rem;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--bs-secondary-color);
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    border-bottom: 2px solid transparent;
}
.analysis-tab:hover {
    color: var(--bs-body-color);
}
.analysis-tab.is-active {
    color: var(--bs-primary);
    background: var(--bs-body-bg);
    border-bottom-color: var(--bs-primary);
}
.analysis-pane {
    border-top: 0;
}
.analysis-section-title {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--bs-secondary-color);
    margin-bottom: 0.3rem;
}

/* --- composition bars ---------------------------------------------------- */
/* A bar per region kind rather than a pie: these are counts of different things,
   not shares of one whole, and a pie would imply they sum to the set. */
.analysis-composition-row {
    display: grid;
    grid-template-columns: minmax(9rem, 14rem) 1fr auto;
    align-items: center;
    gap: 0.6rem;
    padding: 0.2rem 0;
}
.analysis-composition-label {
    font-size: 0.8rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.analysis-composition-bar {
    height: 0.7rem;
    border-radius: 0.35rem;
    background: rgba(var(--bs-secondary-rgb), 0.15);
    overflow: hidden;
}
.analysis-composition-bar > span {
    display: block;
    height: 100%;
    border-radius: 0.35rem;
}
.analysis-composition-count {
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
    color: var(--bs-secondary-color);
    white-space: nowrap;
}

.analysis-empty {
    padding: 2rem 0;
    text-align: center;
    color: var(--bs-secondary-color);
}

/* How this set differs from the proteome, right under the number it qualifies —
   a mean is only informative against a reference, and making the reader open a
   second page to find one is what made the old Statistics page hard to conclude
   from. */
.analysis-stat-delta {
    font-size: 0.7rem;
    font-weight: 600;
    margin-top: 0.1rem;
}
.analysis-stat-delta.is-up { color: #b91c1c; }
.analysis-stat-delta.is-down { color: #1d4ed8; }
.analysis-stat-delta.is-flat { color: var(--bs-secondary-color); }

/* Figure heights are set by the figure itself, from how many rows it has to
   draw — a fixed 220 px meant a two-row chart and a fifteen-row one were given
   the same space, and both were wrong. */
.analysis-chart {
    min-height: 0;
}

/* Mutation sources, kept apart rather than summed. Each row is one source: how
   many mutations, and how many of them landed on a disordered residue — the
   split is the finding, so it is drawn as a divided bar rather than a number. */
.analysis-source-row {
    display: grid;
    grid-template-columns: minmax(8rem, 11rem) 1fr auto;
    align-items: center;
    gap: 0.6rem;
    padding: 0.28rem 0;
}
.analysis-source-label {
    font-size: 0.8rem;
    font-weight: 600;
}
.analysis-source-bar {
    display: flex;
    position: relative; /* anchors the residue-baseline mark */
    height: 0.95rem;
    border-radius: 0.35rem;
    overflow: hidden;
    background: rgba(var(--bs-secondary-rgb), 0.15);
}
.analysis-source-bar > span {
    display: block;
    height: 100%;
}
/* The residue baseline drawn onto every mutation bar, so "is this enriched in
   disorder" is answered by looking at one bar rather than by comparing a number
   here with a number in the panel above. */
.analysis-baseline-mark {
    /* Inside the bar's bounds: the bar clips overflow, so an overhang would be
       cut off rather than drawn. */
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0;
    border-left: 2px dashed var(--bs-body-color);
    opacity: 0.55;
    pointer-events: none;
}

/* The baseline row itself: same geometry as a source row so the bars line up
   column for column, but taller and unshaded to read as a reference rather than
   as one more source. */
.analysis-baseline-row {
    display: grid;
    grid-template-columns: minmax(8rem, 11rem) 1fr auto;
    align-items: center;
    gap: 0.6rem;
    padding: 0.3rem 0;
}
.analysis-baseline-row .analysis-source-bar {
    height: 1.35rem;
    border-radius: 0.4rem;
}
.analysis-baseline-tag {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 600;
    padding: 0.1rem 0.45rem;
    border-radius: 0.3rem;
    border: 1px solid rgba(var(--bs-secondary-rgb), 0.4);
    color: var(--bs-secondary-color);
}
.analysis-cell-note {
    display: block;
    font-size: 0.68rem;
    color: var(--bs-secondary-color);
    font-weight: 400;
}
.analysis-source-figures {
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    color: var(--bs-secondary-color);
}
.analysis-source-figures b { color: var(--bs-body-color); }
.analysis-source-vs {
    font-size: 0.72rem;
    font-weight: 600;
}
.analysis-source-vs.is-up { color: #b91c1c; }
.analysis-source-vs.is-down { color: #1d4ed8; }

/* Sortable headers. The cursor and the arrow are the only affordance a table
   header needs; a button in every cell would be louder than the data. */
.analysis-th { cursor: pointer; user-select: none; white-space: nowrap; }
.analysis-th:hover { color: var(--bs-primary); }
.analysis-th.is-sorted { color: var(--bs-primary); }
/* A column the server cannot order by. It used to look identical to a sortable
   one, so clicking it quietly re-sorted the table by accession. */
.analysis-th.is-static { cursor: default; }
.analysis-th.is-static:hover { color: inherit; }

/* Busy: dim rather than blank, so the previous answer stays readable while the
   next one is fetched — a page that empties itself on every keystroke is harder
   to work with than one that lags. */
.analysis-pane { position: relative; transition: opacity 0.15s ease; }
.analysis-pane.is-busy { opacity: 0.55; pointer-events: none; }
.analysis-pane.is-busy::after {
    content: "";
    position: absolute;
    top: 0.75rem;
    right: 1rem;
    width: 1rem;
    height: 1rem;
    border: 2px solid var(--bs-primary);
    border-right-color: transparent;
    border-radius: 50%;
    animation: analysis-spin 0.6s linear infinite;
}
@keyframes analysis-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
    .analysis-pane.is-busy::after { animation: none; }
}

/* Mutation x context. Cells shaded by row percentage so the shape of a row is
   readable before any number is; the number stays because a shade is not a
   measurement. */
.analysis-matrix td.analysis-cell {
    text-align: center;
    position: relative;
}
.analysis-cell-pct { font-weight: 600; }
.analysis-cell-n { font-size: 0.72rem; color: var(--bs-secondary-color); display: block; }

/* Score ratios, drawn from a centre line: the proteome is 1.0 and sits in the
   middle, so "more damaging" and "less" fall on opposite sides instead of both
   growing rightwards from zero. */
.analysis-score-row {
    display: grid;
    grid-template-columns: minmax(9rem, 13rem) 1fr auto;
    align-items: center;
    gap: 0.6rem;
    padding: 0.14rem 0;
}
.analysis-score-label { font-size: 0.78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.analysis-score-track {
    position: relative;
    height: 0.72rem;
    background: rgba(var(--bs-secondary-rgb), 0.13);
    border-radius: 0.3rem;
}
.analysis-score-track::before {
    content: "";
    position: absolute;
    left: 50%;
    top: -2px;
    bottom: -2px;
    width: 1px;
    background: rgba(var(--bs-secondary-rgb), 0.55);
}
.analysis-score-fill {
    position: absolute;
    top: 0;
    bottom: 0;
    border-radius: 0.3rem;
}
.analysis-score-figure {
    font-size: 0.76rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    min-width: 4.5rem;
    text-align: right;
}
.analysis-score-group {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--bs-secondary-color);
    margin: 0.5rem 0 0.15rem;
}
.analysis-score-group-badge .summary-badge-custom {
    font-size: 0.68rem !important;
}

.analysis-mode-chip {
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.15em 0.55em;
    border-radius: 999px;
    background: var(--bs-tertiary-bg);
    border: 1px solid var(--bs-border-color);
    color: var(--bs-secondary-color);
}

#analysis-annotation-legend .badge {
    margin-right: 0.15rem;
}

.summary-badge-custom {
    display: inline-block;
    border: 1px solid rgba(0, 0, 0, 0.12);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.04) inset;
}

/* Picker — one pane at a time */
.analysis-picker-nav {
    border-bottom: 1px solid var(--bs-border-color);
    gap: 0.25rem !important;
}
.analysis-picker-tab {
    border: 0;
    background: transparent;
    padding: 0.45rem 0.75rem;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--bs-secondary-color);
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}
.analysis-picker-tab .material-symbols-outlined { font-size: 1.05rem; }
.analysis-picker-tab:hover { color: var(--bs-body-color); }
.analysis-picker-tab.is-active {
    color: var(--bs-primary);
    border-bottom-color: var(--bs-primary);
}

.analysis-picker-footer {
    background: var(--bs-tertiary-bg);
    position: sticky;
    bottom: 0;
    z-index: 2;
}

.analysis-active-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-size: 0.72rem;
    font-weight: 500;
    padding: 0.15em 0.45em 0.15em 0.55em;
    border-radius: 999px;
    border: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
    color: var(--bs-body-color);
    line-height: 1.3;
}
.analysis-active-chip button {
    border: 0;
    background: transparent;
    color: var(--bs-secondary-color);
    font-size: 0.95rem;
    line-height: 1;
    padding: 0 0.1rem;
    cursor: pointer;
}
.analysis-active-chip button:hover { color: var(--bs-danger); }
.analysis-active-chip.is-mode {
    background: var(--bs-tertiary-bg);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-weight: 600;
}
.analysis-active-chip.is-filter {
    border-color: rgba(var(--bs-primary-rgb), 0.35);
    background: rgba(var(--bs-primary-rgb), 0.06);
}
.analysis-active-chip.is-discover {
    border-color: rgba(13, 148, 136, 0.45);
    background: rgba(13, 148, 136, 0.1);
}
.analysis-active-chip.is-workflow {
    border-color: rgba(var(--bs-primary-rgb), 0.5);
    background: rgba(var(--bs-primary-rgb), 0.12);
}

.analysis-dirty-banner {
    font-size: 0.8rem;
    padding: 0.4rem 0.65rem;
    border-radius: 0.4rem;
    border: 1px dashed rgba(var(--bs-warning-rgb, 255, 193, 7), 0.7);
    background: rgba(255, 193, 7, 0.12);
    color: var(--bs-body-color);
}

.analysis-workflow-chip {
    border: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
    border-radius: 999px;
    padding: 0.35rem 0.75rem;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}
.analysis-workflow-chip:hover,
.analysis-workflow-chip.is-selected {
    border-color: var(--bs-primary);
    color: var(--bs-primary);
    box-shadow: 0 0 0 1px rgba(var(--bs-primary-rgb), 0.15);
}

/* Analyse — actions on the current selection */
.analysis-scan-subject {
    background: var(--bs-tertiary-bg);
}
.analysis-scan-card {
    display: flex;
    gap: 0.65rem;
    align-items: flex-start;
    padding: 0.65rem 0.75rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.5rem;
    cursor: pointer;
    background: var(--bs-body-bg);
}
.analysis-scan-card:has(input:checked) {
    border-color: var(--bs-primary);
    box-shadow: 0 0 0 1px rgba(var(--bs-primary-rgb), 0.2);
}
.analysis-scan-card input {
    margin-top: 0.2rem;
    flex-shrink: 0;
}

/* Metric bar (Browse Dynamic style) */
.analysis-metric-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem 1rem;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.5rem;
    background: var(--bs-tertiary-bg);
}
.analysis-metric-bar .metric-group {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 9rem;
}
.analysis-metric-bar .form-label {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* Column filter row */
#analysis-table thead tr.dt-col-filters th {
    padding: 0.25rem 0.35rem;
    vertical-align: middle;
    background: var(--bs-tertiary-bg);
}
#analysis-table .analysis-col-filter {
    min-width: 4.5rem;
    font-size: 0.75rem;
}
/* Numeric filters take a comparison, so they are right-aligned like the numbers
   they narrow and the placeholder has room to say so. */
#analysis-table .analysis-col-filter.is-num {
    text-align: right;
    min-width: 5.5rem;
    font-variant-numeric: tabular-nums;
}
.analysis-scan-figure {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

/* DisProt autocomplete */
.analysis-ac-dropdown {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 1050;
    max-height: 14rem;
    overflow: auto;
    display: none;
}
.analysis-ac-dropdown.show { display: block; }
.analysis-disprot-ns-chip {
    border: 1px solid color-mix(in srgb, var(--chip-bg, #a7662b) 55%, #000 0%);
    background: color-mix(in srgb, var(--chip-bg, #a7662b) 18%, transparent);
    color: var(--bs-body-color);
    border-radius: 999px;
    padding: 0.2rem 0.65rem;
    font-size: 0.75rem;
    font-weight: 600;
    cursor: pointer;
}
.analysis-disprot-ns-chip.is-on {
    background: var(--chip-bg, #a7662b);
    color: var(--chip-fg, #fff);
    border-color: transparent;
}

/* Apply / Discover progress overlay */
.analysis-run-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(15, 23, 42, 0.45);
    padding: 1rem;
}
.analysis-run-overlay.d-none { display: none !important; }
.analysis-run-card {
    width: min(28rem, 100%);
    background: var(--bs-body-bg);
    border-radius: 0.75rem;
    padding: 1.1rem 1.25rem;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
}
.analysis-run-step {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.85rem;
    padding: 0.2rem 0;
    color: var(--bs-secondary-color);
}
.analysis-run-step .material-symbols-outlined { font-size: 1.1rem; }
.analysis-run-step--active {
    color: var(--bs-body-color);
    font-weight: 600;
}
.analysis-run-step--done { color: var(--bs-success); }
.analysis-region-parts .analysis-region-part {
    font-weight: 500;
    white-space: normal;
    text-align: left;
    max-width: 22rem;
}
.analysis-region-part-label {
    display: block;
    font-size: 0.65em;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.7;
    line-height: 1.1;
}
.analysis-region-part-value {
    display: block;
    line-height: 1.2;
}

/* Dataset facets. Chips rather than selects: the choices are few and named, and
   a chip you can see the state of beats a select you have to open to read. */
.analysis-facet { margin-bottom: 0.6rem; }
.analysis-facet-title {
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--bs-secondary-color);
    margin-bottom: 0.25rem;
}
.analysis-facet-chip {
    font-size: 0.75rem;
    padding: 0.15em 0.6em;
    border-radius: 999px;
    border: 1px solid rgba(var(--bs-secondary-rgb), 0.4);
    cursor: pointer;
    user-select: none;
    line-height: 1.4;
}
.analysis-facet-chip:hover { border-color: var(--bs-primary); }
.analysis-facet-chip.is-on {
    background: var(--bs-primary);
    border-color: var(--bs-primary);
    color: #fff;
    font-weight: 600;
}

/* An annotation's own properties, indented under it so the ownership is visible
   rather than asserted: the facets belong to the box above them, not to the list. */
.analysis-region-item { margin-bottom: 0.15rem; }
.analysis-region-facets {
    margin: 0.25rem 0 0.5rem 1.6rem;
    padding-left: 0.6rem;
    border-left: 2px solid rgba(var(--bs-primary-rgb), 0.3);
}
.analysis-region-facets .analysis-facet { margin-bottom: 0.35rem; }
.analysis-region-facets .analysis-facet:last-child { margin-bottom: 0; }

/* -------------------------------------------------------------------------- */
/* applied selection, split by axis                                            */
/* -------------------------------------------------------------------------- */

/* Three rails rather than one row: a cohort narrows proteins, an annotation
   narrows spans, a source picker narrows mutations, and read as one undivided
   line a number on the card could not be attributed to any of them. */
.analysis-axis {
    display: flex;
    align-items: baseline;
    gap: .5rem;
    padding: .12rem 0;
}

.analysis-axis-label {
    flex: 0 0 4.5rem;
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);
    text-align: right;
}

.analysis-axis-empty {
    font-size: .78rem;
    color: var(--bs-secondary-color);
    font-style: italic;
}

.analysis-active-chip.analysis-chip-all {
    border-style: dashed !important;
    color: var(--bs-secondary-color);
}

/* -------------------------------------------------------------------------- */
/* per-protein readout (Search's three bars)                                   */
/* -------------------------------------------------------------------------- */

.analysis-split {
    display: flex;
    align-items: center;
    gap: .35rem;
    min-width: 7rem;
}

.analysis-split-bar {
    display: flex;
    flex: 1 1 auto;
    height: 8px;
    min-width: 3.5rem;
    border-radius: 4px;
    overflow: hidden;
    background: var(--bs-tertiary-bg);
}

.analysis-split-bar > span { display: block; height: 100%; }

.analysis-split-figure {
    font-size: .72rem;
    font-variant-numeric: tabular-nums;
    color: var(--bs-secondary-color);
}

.analysis-spectrum-cell { min-width: 11rem; }

.analysis-spectrum {
    display: grid;
    grid-template-columns: 4.5rem 1fr 2.6rem;
    align-items: center;
    gap: .3rem;
    margin-bottom: .12rem;
}

.analysis-spectrum-db {
    font-size: .68rem;
    color: var(--bs-secondary-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.analysis-spectrum-n {
    font-size: .68rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: var(--bs-secondary-color);
}

.analysis-mix-bar {
    display: flex;
    height: 10px;
    border-radius: 5px;
    overflow: hidden;
    background: var(--bs-tertiary-bg);
}

.analysis-mix-bar > span { display: block; height: 100%; }

.analysis-mix-cell {
    min-width: 8rem;
    padding-left: 1.25rem !important;
}

/* -------------------------------------------------------------------------- */
/* autocomplete                                                                */
/* -------------------------------------------------------------------------- */

.analysis-ac-wrap { position: relative; }

.analysis-ac-menu {
    position: absolute;
    inset-inline: 0;
    top: 100%;
    max-height: 16rem;
    overflow-y: auto;
    font-size: .82rem;
    z-index: 1080;
}

.analysis-ac-item {
    white-space: normal;
    line-height: 1.25;
    padding: .3rem .6rem;
}

.analysis-ac-picked { min-height: 1rem; }

/* -------------------------------------------------------------------------- */
/* custom list                                                                 */
/* -------------------------------------------------------------------------- */

.analysis-custom-text {
    font-family: var(--bs-font-monospace);
    font-size: .8rem;
    resize: vertical;
}

.analysis-custom-ok {
    padding: .35rem .55rem;
    border-radius: .35rem;
    background: var(--bs-tertiary-bg);
}

/* -------------------------------------------------------------------------- */
/* sub-tabs (Most damaging)                                                    */
/* -------------------------------------------------------------------------- */

.analysis-subtab {
    border: 0;
    background: transparent;
    font-size: .8rem;
    padding: .2rem .6rem;
    border-radius: 999px;
    color: var(--bs-secondary-color);
}

.analysis-subtab:hover { background: var(--bs-tertiary-bg); }

.analysis-subtab.is-active {
    background: var(--bs-primary-bg-subtle);
    color: var(--bs-emphasis-color);
    font-weight: 600;
}

/* -------------------------------------------------------------------------- */
/* narrow viewports                                                            */
/* -------------------------------------------------------------------------- */

/* The card is a three-column layout that only works while there is room for it.
   Below a laptop the stats belong under the title, the axis rails need their
   labels above rather than beside the chips, and the wide tables have to be
   allowed to scroll inside themselves instead of pushing the page sideways. */
@media (max-width: 1199.98px) {
    .analysis-card-head {
        flex-direction: column;
    }

    .analysis-stats {
        width: 100%;
        justify-content: flex-start;
    }
}

@media (max-width: 767.98px) {
    .analysis-axis {
        flex-direction: column;
        align-items: stretch;
        gap: .15rem;
        padding: .25rem 0;
    }

    .analysis-axis-label {
        flex: none;
        text-align: left;
    }

    .analysis-tabs {
        overflow-x: auto;
    }

    .analysis-spectrum-cell {
        min-width: 9rem;
    }

    .analysis-stat-value {
        font-size: 1.25rem;
    }
}

/* Wide content scrolls inside its own box; the page body never does. */
.analysis-pane .table-responsive {
    overflow-x: auto;
    max-width: 100%;
}

@media (max-width: 575.98px) {
    /* The three-column rows (label · bar · figure) assume a label column that a
       phone does not have. Stacked, the bar still reads and the figure stops
       pushing the page sideways. */
    .analysis-composition-row,
    .analysis-source-row,
    .analysis-score-row {
        grid-template-columns: 1fr;
        gap: .15rem;
        padding: .35rem 0;
    }

    .analysis-composition-count,
    .analysis-source-figures,
    .analysis-score-figure {
        white-space: normal;
        text-align: left;
    }

    .analysis-composition-label,
    .analysis-source-label,
    .analysis-score-label {
        white-space: normal;
    }
}

/* -------------------------------------------------------------------------- */
/* donuts                                                                      */
/* -------------------------------------------------------------------------- */

/* The legend is HTML rather than Plotly's, because Plotly lays its legend out
   inside the plot box and these labels ("Disorder complex (PDB ∩ disorder)") are
   longer than the chart is wide — it clipped or grew a scrollbar. */
.analysis-donut { min-height: 200px; }

.analysis-donut-legend {
    display: flex;
    flex-wrap: wrap;
    gap: .15rem .7rem;
    margin-top: .35rem;
}

.analysis-donut-key {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: .72rem;
    color: var(--bs-secondary-color);
    max-width: 100%;
}

.analysis-donut-key > i {
    width: .6rem;
    height: .6rem;
    border-radius: .15rem;
    flex: 0 0 auto;
}

/* -------------------------------------------------------------------------- */
/* dashboard shell: settings rail beside the results                           */
/* -------------------------------------------------------------------------- */

/* The settings used to be a collapse over the results — you opened it, changed
   something, closed it, and then had to remember what you had done. Side by side,
   the controls and what they produced are readable at the same time. */
.analysis-shell {
    display: grid;
    grid-template-columns: minmax(17rem, 25%) minmax(0, 1fr);
    gap: 1rem;
    padding: 1rem;
    align-items: start;
    width: 100%;
}

/* One column, not a zero-width first track: the rail is `display:none` when
   hidden, so the results would otherwise become the first grid item and land in
   the empty track. */
.analysis-shell.is-rail-hidden {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
}

.analysis-shell.is-rail-hidden .analysis-rail {
    display: none;
}

.analysis-rail {
    position: sticky;
    top: .75rem;
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 1.5rem);
    min-width: 0;
    border: 1px solid var(--bs-border-color);
    border-radius: .5rem;
    background: var(--bs-body-bg);
    overflow: hidden;
}

.analysis-rail-head {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    gap: .45rem;
    padding: .55rem .75rem;
    border-bottom: 1px solid var(--bs-border-color);
    background: var(--bs-tertiary-bg);
}

.analysis-rail-title {
    font-weight: 600;
    font-size: .85rem;
    letter-spacing: .02em;
}

.analysis-rail-close,
.analysis-rail-open {
    margin-left: auto;
    border: 0;
    background: transparent;
    color: var(--bs-secondary-color);
    line-height: 1;
    padding: .1rem;
    border-radius: .3rem;
}

.analysis-rail-close:hover { background: var(--bs-secondary-bg); }

.analysis-rail-body {
    /* min-height:0 is what actually lets this scroll. Without it a flex item
       refuses to shrink below its content, so an expanded section pushed the rail
       past its max-height and squeezed Apply/Reset off the bottom instead of
       scrolling. */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.analysis-rail-foot {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    padding: .55rem .75rem;
    border-top: 1px solid var(--bs-border-color);
    background: var(--bs-tertiary-bg);
    /* Never shrink: these two buttons are the only way to run or clear a query,
       so they stay on screen however tall the sections above get. */
    flex: 0 0 auto;
}

/* A section, not a tab: several can be open, and the header counts what is set
   inside it — a filter three sections down cannot hide. */
.analysis-rail-section + .analysis-rail-section {
    border-top: 1px solid var(--bs-border-color);
}

.analysis-rail-head-btn {
    display: flex;
    align-items: center;
    gap: .45rem;
    width: 100%;
    border: 0;
    background: transparent;
    padding: .5rem .75rem;
    font-size: .82rem;
    font-weight: 600;
    color: var(--bs-body-color);
    text-align: left;
}

.analysis-rail-head-btn:hover { background: var(--bs-tertiary-bg); }
.analysis-rail-head-btn .material-symbols-outlined { font-size: 1.05rem; }
.analysis-rail-name { flex: 1 1 auto; min-width: 0; }

.analysis-rail-count {
    font-size: .7rem;
    font-weight: 700;
    min-width: 1.25rem;
    text-align: center;
    padding: 0 .3rem;
    border-radius: 999px;
    background: var(--bs-primary);
    color: #fff;
}

.analysis-rail-count:empty { display: none; }

.analysis-rail-caret {
    transition: transform .15s ease;
    color: var(--bs-secondary-color);
}

.analysis-rail-section.is-open .analysis-rail-caret { transform: rotate(180deg); }

/* Panes are hidden by section state now, not by the old tab class. */
.analysis-rail .analysis-picker-pane {
    display: none;
    padding: 0 .75rem .75rem;
}

.analysis-rail-section.is-open .analysis-picker-pane { display: block; }

/* A 25% rail has no room for the multi-column grids the wide panel used. */
.analysis-rail .row > .col,
.analysis-rail .row > [class*="col-"] {
    flex: 0 0 100%;
    max-width: 100%;
}

.analysis-rail .form-control,
.analysis-rail .form-select {
    max-width: none !important;
}

.analysis-rail .analysis-group-box { height: auto !important; }

.analysis-results {
    min-width: 0;
}

.analysis-rail-open {
    display: none;
    align-items: center;
    gap: .35rem;
    margin: 0 0 .6rem;
    padding: .3rem .6rem;
    border: 1px solid var(--bs-border-color);
    border-radius: .4rem;
    background: var(--bs-body-bg);
    font-size: .82rem;
    color: var(--bs-body-color);
}

.analysis-shell.is-rail-hidden .analysis-rail-open { display: inline-flex; }

@media (max-width: 991.98px) {
    /* Below a tablet the rail stops being a rail; it stacks above the results,
       which is the only arrangement where both stay readable. */
    .analysis-shell {
        grid-template-columns: minmax(0, 1fr);
    }

    .analysis-rail {
        position: static;
        max-height: none;
    }
}

/* -------------------------------------------------------------------------- */
/* query summary                                                               */
/* -------------------------------------------------------------------------- */

.analysis-query {
    border-top: 1px solid var(--bs-border-color);
    padding: .5rem .9rem .65rem;
}

.analysis-query-sentence {
    font-size: .84rem;
    margin: 0 0 .4rem;
    color: var(--bs-body-color);
}

.analysis-query-row {
    display: grid;
    grid-template-columns: 7.5rem minmax(0, 1fr) auto;
    align-items: start;
    gap: .5rem;
    padding: .2rem 0;
}

.analysis-query-row + .analysis-query-row {
    border-top: 1px dashed var(--bs-border-color);
}

.analysis-query-axis {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);
    padding-top: .18rem;
}

.analysis-query-axis .material-symbols-outlined { font-size: .95rem; }

.analysis-query-clause {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .25rem;
    min-width: 0;
}

.analysis-query-count {
    font-size: .78rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    color: var(--bs-secondary-color);
    padding-top: .18rem;
}

.analysis-query-count b { color: var(--bs-body-color); }

@media (max-width: 767.98px) {
    .analysis-query-row {
        grid-template-columns: minmax(0, 1fr);
        gap: .2rem;
    }
    .analysis-query-count { padding-top: 0; }
}

/* -------------------------------------------------------------------------- */
/* discovery scan summary                                                      */
/* -------------------------------------------------------------------------- */

.analysis-scan-overview {
    border: 1px solid var(--bs-border-color);
    border-left: 3px solid #0f766e;
    border-radius: .4rem;
    padding: .75rem .9rem;
    background: var(--bs-tertiary-bg);
}

.analysis-scan-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
    gap: .6rem;
}

.analysis-scan-stat-value {
    font-size: 1.15rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.analysis-scan-stat-label {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--bs-secondary-color);
}

.analysis-scan-stat-note {
    font-size: .68rem;
    color: var(--bs-secondary-color);
}

/* The pasted region set, marked as belonging to this session rather than to the
   registry — it disappears when the list does. */
.analysis-group-box--custom {
    border-color: #0f766e !important;
    border-style: dashed !important;
}

/* -------------------------------------------------------------------------- */
/* rail steps and sub-groups                                                   */
/* -------------------------------------------------------------------------- */

/* Four steps, not seven drawers. The number is part of the affordance: the rail
   reads in the same order as the sentence on the card. */
.analysis-rail-step {
    flex: 0 0 auto;
    width: 1.15rem;
    height: 1.15rem;
    border-radius: 50%;
    background: var(--bs-secondary-bg);
    color: var(--bs-secondary-color);
    font-size: .66rem;
    font-weight: 700;
    line-height: 1.15rem;
    text-align: center;
}

.analysis-rail-step:empty { display: none; }

.analysis-rail-section.is-open .analysis-rail-step {
    background: var(--bs-primary);
    color: #fff;
}

.analysis-rail-name { line-height: 1.15; }

.analysis-rail-sub {
    display: block;
    font-size: .68rem;
    font-weight: 400;
    color: var(--bs-secondary-color);
}

.analysis-subgroup + .analysis-subgroup {
    margin-top: .9rem;
    padding-top: .7rem;
    border-top: 1px dashed var(--bs-border-color);
}

.analysis-subgroup-title {
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);
    margin-bottom: .35rem;
}

/* -------------------------------------------------------------------------- */
/* evidence groups                                                             */
/* -------------------------------------------------------------------------- */

/* Grouped by the question each asks. Eight bare number boxes could not say that
   this is where regions are narrowed by measurement — the section's whole job. */
.analysis-ev-group {
    border: 1px solid var(--bs-border-color);
    border-radius: .4rem;
    padding: .5rem .6rem;
    margin-bottom: .5rem;
}

.analysis-ev-title {
    display: flex;
    align-items: center;
    gap: .3rem;
    font-size: .78rem;
    font-weight: 600;
    margin-bottom: .4rem;
}

.analysis-ev-title .material-symbols-outlined {
    font-size: 1rem;
    color: var(--bs-secondary-color);
}

.analysis-ev-check {
    display: flex;
    align-items: center;
    gap: .4rem;
    font-size: .78rem;
    margin-top: .3rem;
}

.analysis-ev-presets {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem;
    margin-top: .45rem;
}

.analysis-ev-preset {
    border: 1px solid var(--bs-border-color);
    background: var(--bs-tertiary-bg);
    border-radius: 999px;
    font-size: .7rem;
    padding: .1rem .5rem;
    color: var(--bs-body-color);
}

.analysis-ev-preset:hover {
    border-color: var(--bs-primary);
    color: var(--bs-primary);
}

/* The count the evidence filters removed, so a cutoff visibly does something. */
.analysis-funnel {
    color: var(--bs-secondary-color);
    text-decoration: line-through;
    text-decoration-color: var(--bs-border-color);
}

.analysis-funnel span { text-decoration: none; display: inline-block; }

/* -------------------------------------------------------------------------- */
/* workflow question cards                                                     */
/* -------------------------------------------------------------------------- */

.analysis-wf-group + .analysis-wf-group { margin-top: .8rem; }

.analysis-wf-caption {
    display: flex;
    align-items: center;
    gap: .3rem;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--bs-secondary-color);
    margin-bottom: .35rem;
}

.analysis-wf-caption .material-symbols-outlined { font-size: .95rem; }

.analysis-wf-card {
    display: block;
    width: 100%;
    text-align: left;
    border: 1px solid var(--bs-border-color);
    border-left: 3px solid var(--bs-primary);
    border-radius: .4rem;
    background: var(--bs-body-bg);
    padding: .4rem .55rem;
    margin-bottom: .35rem;
}

.analysis-wf-card:hover {
    background: var(--bs-tertiary-bg);
    border-color: var(--bs-primary);
}

.analysis-wf-card--scan { border-left-color: #b45309; }

.analysis-wf-q {
    display: block;
    font-size: .8rem;
    font-weight: 600;
    line-height: 1.25;
}

.analysis-wf-hint {
    display: block;
    font-size: .69rem;
    color: var(--bs-secondary-color);
    line-height: 1.25;
    margin-top: .1rem;
}

/* -------------------------------------------------------------------------- */
/* studies and merged spans                                                    */
/* -------------------------------------------------------------------------- */

/* A study's name is a control, not a label: clicking it restricts the protein
   set to that collection's genes. */
.analysis-study-pick {
    border: 0;
    background: transparent;
    padding: 0;
    text-align: left;
    color: var(--bs-link-color);
    font-size: inherit;
}

.analysis-study-pick:hover { text-decoration: underline; }

.analysis-merged-cell { min-width: 14rem; }

.analysis-merged-ann { display: inline-block; margin-right: .15rem; }

.analysis-study-key {
    display: block;
    font-size: .68rem;
    color: var(--bs-secondary-color);
    font-family: var(--bs-font-monospace);
}

/* What one row of the studies table is. Sits between the kind buttons and the
   table because that is where the question "what am I looking at" is asked. */
.analysis-study-note {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0.1rem 0 0.6rem;
    padding: 0.5rem 0.7rem;
    font-size: 0.8rem;
    line-height: 1.45;
    color: var(--bs-secondary-color);
    background: rgba(var(--bs-secondary-rgb), 0.07);
    border-left: 3px solid rgba(var(--bs-primary-rgb), 0.45);
    border-radius: 0.3rem;
}
.analysis-study-note .material-symbols-outlined {
    font-size: 1.05rem;
    line-height: 1.35;
    opacity: 0.75;
}

/* Where a filter's numbers come from. The groups look alike, so without an origin
   the reader cannot tell that AlphaMissense scores a substitution while ANCHOR
   scores the residue — different questions in identical boxes. */
.analysis-ev-origin {
    margin-left: auto;
    font-size: 0.63rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.1rem 0.4rem;
    border-radius: 0.25rem;
    color: var(--bs-secondary-color);
    background: rgba(var(--bs-secondary-rgb), 0.14);
    white-space: nowrap;
}
.analysis-ev-help {
    font-size: 0.73rem;
    line-height: 1.4;
    color: var(--bs-secondary-color);
    margin: 0 0 0.5rem;
}

/* --- picked study ---------------------------------------------------------- */
/* The study's own variants, kept visually separate from the panels below, which
   describe its genes' entire mutation load. Conflating the two is the specific
   confusion this panel exists to prevent. */
.analysis-study-focus {
    border: 1px solid rgba(var(--bs-primary-rgb), 0.35);
    border-radius: 0.5rem;
    padding: 0.85rem 1rem;
    background: rgba(var(--bs-primary-rgb), 0.04);
}
.analysis-focus-head {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.6rem;
}
.analysis-focus-head .material-symbols-outlined {
    color: var(--bs-primary);
}
.analysis-focus-titles {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.analysis-focus-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.85rem;
    font-weight: 600;
    padding: 0.15rem 0.5rem;
    border-radius: 0.3rem;
    background: var(--bs-body-bg);
    border: 1px solid rgba(var(--bs-secondary-rgb), 0.3);
}
.analysis-focus-kind {
    font-size: 0.65rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.05rem 0.35rem;
    border-radius: 0.2rem;
    background: rgba(var(--bs-primary-rgb), 0.15);
    color: var(--bs-primary);
}
.analysis-focus-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 1.75rem;
    margin-bottom: 0.9rem;
}
.analysis-focus-value {
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}
.analysis-focus-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--bs-secondary-color);
}
.analysis-focus-genes-title {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--bs-secondary-color);
    margin-bottom: 0.35rem;
}
.analysis-focus-genes-title .text-secondary {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
}
.analysis-focus-gene {
    display: grid;
    grid-template-columns: minmax(5rem, 7rem) 1fr auto;
    align-items: center;
    gap: 0.6rem;
    padding: 0.12rem 0;
}
.analysis-focus-gene-name {
    font-size: 0.78rem;
    font-weight: 600;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.analysis-focus-gene-n {
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
    color: var(--bs-secondary-color);
}
.analysis-focus-caveat {
    font-size: 0.73rem;
    line-height: 1.45;
    color: var(--bs-secondary-color);
    margin: 0.75rem 0 0;
    padding-top: 0.6rem;
    border-top: 1px dashed rgba(var(--bs-secondary-rgb), 0.35);
}

/* A picked study, marked in the table it was picked from. Without this the only
   sign that a row was filtering the page was a chip inside a rail section that is
   closed by default. */
.analysis-study-pick.is-picked {
    font-weight: 700;
    color: var(--bs-primary);
    background: rgba(var(--bs-primary-rgb), 0.12);
    border-radius: 0.25rem;
    padding: 0.05rem 0.35rem;
}
.analysis-study-pick.is-picked .material-symbols-outlined {
    font-size: 0.9rem;
    vertical-align: -2px;
    margin-right: 0.15rem;
}

/* One card per picked study. Two studies picked used to render as one summed
   block whose numbers described neither of them. */
.analysis-focus-cards {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 0.85rem;
}
.analysis-focus-card {
    flex: 1 1 20rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid rgba(var(--bs-secondary-rgb), 0.28);
    border-radius: 0.4rem;
    background: var(--bs-body-bg);
}
.analysis-focus-nums {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    margin-top: 0.45rem;
    font-size: 0.8rem;
    color: var(--bs-secondary-color);
}
.analysis-focus-nums b {
    font-size: 1.05rem;
    color: var(--bs-body-color);
    font-variant-numeric: tabular-nums;
}
.analysis-focus-drill {
    margin-top: 0.55rem;
    border: 0;
    background: rgba(var(--bs-primary-rgb), 0.1);
    color: var(--bs-primary);
    font-size: 0.76rem;
    font-weight: 600;
    padding: 0.25rem 0.55rem;
    border-radius: 0.3rem;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}
.analysis-focus-drill .material-symbols-outlined { font-size: 1rem; }
.analysis-focus-union {
    font-size: 0.78rem;
    color: var(--bs-secondary-color);
    margin: -0.4rem 0 0.8rem;
}
.analysis-focus-variants { margin-top: 1rem; }
.analysis-focus-ann {
    display: inline-block;
    font-size: 0.68rem;
    padding: 0.05rem 0.35rem;
    border-radius: 0.25rem;
    background: rgba(var(--bs-secondary-rgb), 0.16);
    margin: 0.05rem 0.1rem 0.05rem 0;
}
.analysis-focus-dis { color: #d63384; font-weight: 600; font-size: 0.78rem; }
/* A region that recurs in this study's own cancer is the finding; one that recurs
   in some other cancer is context, and they must not look alike. */
.analysis-focus-sig {
    font-size: 0.7rem;
    padding: 0.05rem 0.4rem;
    border-radius: 0.25rem;
    background: rgba(var(--bs-secondary-rgb), 0.18);
    color: var(--bs-secondary-color);
}
.analysis-focus-sig.is-own {
    background: rgba(185, 28, 28, 0.15);
    color: #b91c1c;
    font-weight: 700;
}

/* ClinVar's own classification, coloured by the coarse bucket. Pathogenic and
   benign must not look alike, and "uncertain" — most of ClinVar — must not look
   like either. */
.analysis-clin {
    display: inline-block;
    font-size: 0.68rem;
    font-weight: 600;
    padding: 0.05rem 0.35rem;
    border-radius: 0.25rem;
}
.analysis-clin-path { background: rgba(185, 28, 28, 0.15); color: #b91c1c; }
.analysis-clin-benign { background: rgba(29, 78, 216, 0.13); color: #1d4ed8; }
.analysis-clin-vus { background: rgba(var(--bs-secondary-rgb), 0.18); color: var(--bs-secondary-color); }
.analysis-clin-stars {
    font-size: 0.6rem;
    letter-spacing: -0.04em;
    margin-left: 0.25rem;
    color: var(--bs-secondary-color);
}

/* Export controls, docked to the right of the table toolbar. */
.analysis-table-export {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}
.analysis-table-export .material-symbols-outlined {
    font-size: 1rem;
    vertical-align: -3px;
}

/* Disease-group badge, coloured with the paper's tab20 palette pinned to the
   canonical category order so a group keeps its colour between queries. */
.analysis-dgroup-badge {
    display: inline-block;
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
    font-size: 0.7rem;
    font-weight: 600;
    padding: 0.1rem 0.45rem;
    border-radius: 0.25rem;
}

/* How many annotations of a kind cover a merged span. */
.analysis-merged-n {
    font-size: 0.66rem;
    font-weight: 700;
    margin-left: 0.15rem;
    color: var(--bs-secondary-color);
    vertical-align: middle;
}

/* Plotly measures its container on first draw. Inside a Bootstrap column, whose
   default min-width is auto, the SVG it sizes to can then refuse to shrink when
   the column narrows — so the plot hangs out over the panel edge. Letting the
   column shrink and clipping the plot to it keeps the figure inside the card. */
.analysis-chart {
    max-width: 100%;
    min-width: 0;
    overflow: hidden;
}
.analysis-chart .js-plotly-plot,
.analysis-chart .plot-container,
.analysis-chart .svg-container {
    max-width: 100% !important;
}
.analysis-pane .row > [class*="col-"] {
    min-width: 0;
}

/* --- overview sub-tabs ----------------------------------------------------- */
/* Four questions, four sections, one visible at a time. Stacked in one column
   they were a scroll with no structure; as tabs the reader picks the question. */
.analysis-overview-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin-bottom: 0.85rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid var(--bs-border-color);
}
.analysis-otab {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    border: 1px solid transparent;
    background: transparent;
    border-radius: 0.4rem;
    padding: 0.35rem 0.7rem;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--bs-secondary-color);
}
.analysis-otab:hover {
    background: rgba(var(--bs-secondary-rgb), 0.1);
    color: var(--bs-body-color);
}
.analysis-otab.is-active {
    color: var(--bs-primary);
    background: rgba(var(--bs-primary-rgb), 0.1);
    border-color: rgba(var(--bs-primary-rgb), 0.35);
}
.analysis-otab .material-symbols-outlined { font-size: 1.05rem; }

/* One sentence per section saying what it answers, so a section is never just a
   pile of panels. */
.analysis-osection-lede {
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--bs-secondary-color);
    max-width: 78ch;
    margin: 0 0 1.1rem;
}

/* One control bar for "Genes & regions", above the figures it drives — rather
   than a copy of the same switch inside each of them. */
.analysis-hits-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-bottom: 0.75rem;
    padding: 0.5rem 0.7rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.55rem;
    background: var(--bs-tertiary-bg);
}
.analysis-hits-label {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--bs-secondary-color);
}
.analysis-hits-bar .form-select {
    width: auto;
    max-width: 15rem;
    font-size: 0.78rem;
}

/* --- discovery hits in the regions table ----------------------------------- */
/* A found motif belongs to no database, so it is badged as what it is rather
   than borrowed from the annotation palette. */
.analysis-scan-badge {
    background: #6d28d9;
    color: #fff;
    font-size: 0.68rem;
    font-weight: 600;
}
.analysis-map-btn {
    border: 1px solid rgba(var(--bs-primary-rgb), 0.45);
    background: transparent;
    color: var(--bs-primary);
    border-radius: 0.35rem;
    padding: 0.05rem 0.5rem;
    font-size: 0.72rem;
    font-weight: 600;
}
.analysis-map-btn:hover {
    background: var(--bs-primary-bg-subtle);
}

/* --- the figure shell ------------------------------------------------------ */
/* Every answer in the Overview is built the same way: a header that names it,
   one line saying how to read it, and the plot. Before this, each chart brought
   its own title style, its own paragraph, its own margins and — often — a table
   underneath repeating what it had just drawn, so twelve figures read as twelve
   unrelated pages. The shell is what makes them one dashboard. */
.analysis-figgrid {
    display: grid;
    gap: 0.75rem;
    /* Two columns, stated rather than fitted. `auto-fit` looked right until a
       figure spanning the full width occupied the third track it had made room
       for: the track was no longer empty, so it was not collapsed, and the two
       ordinary figures beside it kept a third of the width each with a third of
       the row left blank. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: stretch;
}
@media (max-width: 991.98px) {
    .analysis-figgrid {
        grid-template-columns: minmax(0, 1fr);
    }
}
.analysis-figgrid .is-wide {
    grid-column: 1 / -1;
}
/* Three readings of one thing, side by side, because the comparison between them
   is the point. Falls back to the two-column rule below 1400px, where a third of
   the width stops being enough for a ranking's labels. */
@media (min-width: 1400px) {
    .analysis-figgrid--three {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}
.analysis-fig {
    margin: 0;
    min-width: 0;
    padding: 0.7rem 0.85rem 0.75rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.55rem;
    background: var(--bs-body-bg);
}
.analysis-fig-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 0.6rem;
    min-height: 1.6rem;
}
.analysis-fig-title {
    margin: 0;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.055em;
    color: var(--bs-body-color);
}
/* One sentence, not a paragraph: the figure has to earn its height with the
   plot, not with prose above it. */
.analysis-fig-sub {
    margin: 0.25rem 0 0.5rem;
    font-size: 0.72rem;
    line-height: 1.45;
    color: var(--bs-secondary-color);
    max-width: 74ch;
}
.analysis-fig-hint {
    font-size: 0.68rem;
    font-style: italic;
    color: var(--bs-secondary-color);
}
/* Legends are HTML in the header rather than Plotly's own, which lays itself
   out inside the plot box and takes the height off a figure that is 150 px
   tall to begin with. */
.analysis-fig-legend {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.1rem 0.6rem;
}
.analysis-fig-key {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.7rem;
    color: var(--bs-secondary-color);
}
.analysis-fig-key > i {
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 0.15rem;
    flex: 0 0 auto;
}
.analysis-fig-tools {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin-left: auto;
}
.analysis-fig-tools .form-select {
    width: auto;
    max-width: 13rem;
    font-size: 0.75rem;
}
.analysis-fig-btn {
    margin-left: auto;
    border: 1px solid var(--bs-border-color);
    background: transparent;
    border-radius: 999px;
    padding: 0.1rem 0.55rem;
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--bs-secondary-color);
}
.analysis-fig-btn:hover {
    background: rgba(var(--bs-secondary-rgb), 0.12);
    color: var(--bs-body-color);
}
.analysis-fig-btn.is-on {
    background: var(--bs-primary-bg-subtle);
    border-color: rgba(var(--bs-primary-rgb), 0.35);
    color: var(--bs-emphasis-color);
}
/* A tools row and a Numbers button both claim the right edge; only the first of
   them may take it, or they stack against each other. */
.analysis-fig-tools ~ .analysis-fig-btn {
    margin-left: 0;
}
.analysis-fig .analysis-donut {
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* --- headline: the section's claim before its evidence --------------------- */
.analysis-headline {
    margin-bottom: 1.1rem;
}
.analysis-kpis {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 1rem;
}
.analysis-kpi {
    flex: 1 1 13rem;
    padding: 0.7rem 0.9rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.5rem;
    background: var(--bs-body-bg);
}
.analysis-kpi-value {
    font-size: 1.9rem;
    font-weight: 700;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}
.analysis-kpi-value.is-up { color: #b91c1c; }
.analysis-kpi-value.is-down { color: #1d4ed8; }
.analysis-kpi-label {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--bs-body-color);
    margin-top: 0.1rem;
}
.analysis-kpi-sub {
    font-size: 0.72rem;
    color: var(--bs-secondary-color);
    margin-top: 0.15rem;
}

/* Diverging bars: polarity against the chain, centred on "no difference". The
   centre is a neutral rule, never a hue — a coloured midpoint would read as a
   third state. */
.analysis-div-title {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--bs-secondary-color);
    margin-bottom: 0.4rem;
}
.analysis-div-title .text-secondary {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
}
.analysis-div-row,
.analysis-div-head {
    display: grid;
    grid-template-columns: minmax(7rem, 10rem) 1fr 3.9rem 6rem 4rem;
    align-items: center;
    gap: 0.6rem;
    padding: 0.22rem 0;
}
.analysis-div-head {
    padding: 0 0 0.3rem;
    margin-bottom: 0.15rem;
    border-bottom: 1px solid var(--bs-border-color);
    font-size: 0.66rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--bs-secondary-color);
    text-align: right;
}
/* The label and track columns carry no heading; the three headings sit over the
   numbers they name. */
.analysis-div-spacer {
    grid-column: 1 / 3;
}
.analysis-div-num {
    font-size: 0.74rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: var(--bs-secondary-color);
}
.analysis-div-label { font-size: 0.8rem; font-weight: 600; }
.analysis-div-track {
    position: relative;
    height: 1rem;
    border-radius: 0.3rem;
    background: rgba(var(--bs-secondary-rgb), 0.1);
}
.analysis-div-zero {
    position: absolute;
    left: 50%;
    top: -2px;
    bottom: -2px;
    width: 1px;
    background: var(--bs-secondary-color);
    opacity: 0.55;
}
.analysis-div-bar {
    position: absolute;
    top: 2px;
    bottom: 2px;
    border-radius: 3px;
}
.analysis-div-bar.is-up { background: #d63384; }
.analysis-div-bar.is-down { background: #6f9ceb; }
.analysis-div-value {
    font-size: 0.78rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: right;
}
.analysis-div-value.is-up { color: #b91c1c; }
.analysis-div-value.is-down { color: #1d4ed8; }

/* Donuts are drawn while their sub-tab is hidden, so they measure a zero-width
   parent and keep that size on reveal. Clipping them to the column stops the
   overflow even before the resize lands. */
.analysis-donut {
    max-width: 100%;
    min-width: 0;
    overflow: hidden;
}
.analysis-donut .js-plotly-plot,
.analysis-donut .plot-container,
.analysis-donut .svg-container {
    max-width: 100% !important;
}

/* --- dark mode for the colours added with the overview rework -------------- */
/* These are *text* colours, and the light-mode steps measure 2.7:1 against the
   dark surface — unreadable. Re-stepped rather than flipped: #ef4444 / #3b82f6
   pass the lightness band, chroma floor, CVD separation and 3:1 contrast on the
   dark surface (checked with the palette validator), which the lighter tints
   #fca5a5 / #93c5fd do not. */
[data-bs-theme="dark"] .analysis-kpi-value.is-up,
[data-bs-theme="dark"] .analysis-div-value.is-up,
[data-bs-theme="dark"] .analysis-stat-delta.is-up,
[data-bs-theme="dark"] .analysis-source-vs.is-up,
[data-bs-theme="dark"] .analysis-focus-sig.is-own,
[data-bs-theme="dark"] .analysis-clin-path {
    color: #ef4444;
}
[data-bs-theme="dark"] .analysis-kpi-value.is-down,
[data-bs-theme="dark"] .analysis-div-value.is-down,
[data-bs-theme="dark"] .analysis-stat-delta.is-down,
[data-bs-theme="dark"] .analysis-source-vs.is-down,
[data-bs-theme="dark"] .analysis-clin-benign {
    color: #3b82f6;
}
[data-bs-theme="dark"] .analysis-focus-sig.is-own {
    background: rgba(239, 68, 68, 0.18);
}
[data-bs-theme="dark"] .analysis-clin-path {
    background: rgba(239, 68, 68, 0.18);
}
[data-bs-theme="dark"] .analysis-clin-benign {
    background: rgba(59, 130, 246, 0.18);
}
/* The disease-group badges carry the paper's tab20 fills in both themes; only
   their ink is chosen per fill, so they need no dark variant. */

/* Cancer Gene Census roles. Three fixed roles, so fixed hues rather than a ramp —
   the role is an identity, not a magnitude. */
.analysis-role {
    display: inline-block;
    font-size: 0.66rem;
    font-weight: 600;
    padding: 0.05rem 0.35rem;
    border-radius: 0.25rem;
    white-space: nowrap;
}
.analysis-role-oncogene { background: rgba(217, 119, 6, 0.16); color: #b45309; }
.analysis-role-tsg { background: rgba(29, 78, 216, 0.14); color: #1d4ed8; }
.analysis-role-fusion { background: rgba(124, 58, 237, 0.15); color: #6d28d9; }
[data-bs-theme="dark"] .analysis-role-oncogene { color: #fbbf24; }
[data-bs-theme="dark"] .analysis-role-tsg { color: #60a5fa; }
[data-bs-theme="dark"] .analysis-role-fusion { color: #a78bfa; }

/* A significance call, stated as a result rather than drawn as an annotation. */
.analysis-sigmut-yes {
    display: inline-block;
    font-size: 0.68rem;
    font-weight: 700;
    padding: 0.05rem 0.35rem;
    border-radius: 0.25rem;
    background: rgba(185, 28, 28, 0.15);
    color: #b91c1c;
}
[data-bs-theme="dark"] .analysis-sigmut-yes { color: #ef4444; background: rgba(239, 68, 68, 0.18); }



/* --------------------------------------------------------------------------
   Column picker and API preview.

   Both belong to the Table, not to Settings: they are about what an answer looks
   like once you have it, not about which question was asked.
   -------------------------------------------------------------------------- */
.analysis-columns-panel,
.analysis-api-panel {
    border: 1px solid var(--bs-border-color);
    border-radius: 0.6rem;
    background: var(--bs-tertiary-bg);
    padding: 0.75rem 0.9rem;
    margin-bottom: 0.75rem;
}
.analysis-col-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.2rem 0.6rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 999px;
    background: var(--bs-body-bg);
    font-size: 0.8rem;
    cursor: pointer;
    user-select: none;
    margin: 0;
}
.analysis-col-chip.is-on {
    border-color: var(--bs-primary);
    background: rgba(var(--bs-primary-rgb), 0.08);
    font-weight: 600;
}
.analysis-col-chip input { margin: 0; }
.analysis-api-code {
    font-size: 0.76rem;
    line-height: 1.45;
    white-space: pre-wrap;
    word-break: break-all;
    background: var(--bs-body-bg);
    border: 1px solid var(--bs-border-color);
    border-radius: 0.4rem;
    padding: 0.6rem 0.7rem;
    max-height: 9rem;
    overflow: auto;
    color: var(--bs-body-color);
}

/* Region-type legend, which is also the filter. The badges keep the colours they
   have everywhere else on the site; only the selected state is added, as a ring
   rather than a colour change — recolouring them would break the one thing the
   strip is for, which is recognising a type by its colour. */
.analysis-annotation-chip {
    opacity: 0.55;
    transition: opacity .12s ease, box-shadow .12s ease;
}
.analysis-annotation-chip:hover { opacity: 0.85; }
.analysis-annotation-chip.is-active {
    opacity: 1;
    box-shadow: 0 0 0 2px var(--bs-body-bg), 0 0 0 4px currentColor;
}
/* "All" carries no annotation colour, so its ring needs a visible one of its own. */
.analysis-annotation-chip[data-region-type=""].is-active {
    box-shadow: 0 0 0 2px var(--bs-body-bg), 0 0 0 4px var(--bs-primary);
}

/* A study name that cannot be picked because another study is already filtering.
   Dimmed rather than hidden: the row is still worth reading, it just is not a
   choice until the current one is cleared. */
.analysis-study-pick.is-blocked {
    opacity: 0.45;
    cursor: not-allowed;
    text-decoration: none;
}


/* The region condition group — "…and only where they overlap".
   One row, so it reads as a clause on the annotations above it rather than as a
   second question of its own. */
.analysis-region-condition {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
    padding: .5rem .6rem;
    border: 1px dashed var(--bs-border-color);
    border-radius: .5rem;
    background: var(--bs-tertiary-bg);
}
.analysis-region-condition-label { font-size: .78rem; font-weight: 650; }
.analysis-region-condition-chips { display: flex; flex-wrap: wrap; gap: .3rem; }
.analysis-region-condition-chips:empty { display: none; }
#analysis-region-condition-add { max-width: 13rem; }
.analysis-chip-join {
    font-size: .72rem;
    font-weight: 650;
    color: var(--bs-secondary-color);
    align-self: center;
    padding: 0 .1rem;
}

/* The body map: drawing beside its list, the way the Summary card reads. */
.analysis-body-figure {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 6fr);
    gap: .9rem;
    align-items: start;
}
/* A height before the drawing lands, so the lazy-load observer has an area to
   intersect — a zero-height host never becomes visible and the body never
   appeared at all. It also stops the card jumping when the 172 KB SVG arrives. */
.analysis-body-diagram { min-width: 0; min-height: 18rem; }
.analysis-body-diagram svg { width: 100%; height: auto; max-height: 22rem; }
.analysis-body-list { min-width: 0; font-size: .8rem; }
@media (max-width: 720px) {
    .analysis-body-figure { grid-template-columns: minmax(0, 1fr); }
}
