* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

:root {
    --bg: #eef3f6;
    --panel: #fbfdfe;
    --panel-strong: #f4f8fb;
    --line: #d7e2ea;
    --line-strong: #bdd0dc;
    --text: #18242d;
    --muted: #61717d;
    --accent: #146c94;
    --accent-strong: #0f4c68;
    --accent-soft: rgba(20, 108, 148, 0.1);
    --danger-soft: rgba(176, 63, 46, 0.1);
    --danger: #9f3526;
    --shadow: 0 18px 48px rgba(28, 52, 66, 0.08);
}

body {
    font-family: "IBM Plex Sans", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    background:
        radial-gradient(circle at top left, rgba(20, 108, 148, 0.08), transparent 28%),
        linear-gradient(180deg, #f7fafc 0%, var(--bg) 100%);
    min-height: 100vh;
    padding: 24px;
    color: var(--text);
}

.container {
    max-width: 1680px;
    margin: 0 auto;
    background: rgba(255, 255, 255, 0.88);
    border: 1px solid rgba(255, 255, 255, 0.9);
    border-radius: 28px;
    padding: 32px;
    box-shadow: var(--shadow);
    min-height: calc(100vh - 48px);
}

/* ===== Embedded 3D Atlas (native fusion) ===== */
#atlasSection.atlas-embed--framed {
    margin-top: 28px;
    padding: 0;
    border: 1px solid var(--line-strong);
    border-radius: 24px;
    background: var(--panel);
    box-shadow: 0 18px 48px rgba(28, 52, 66, 0.12);
    overflow: hidden;
}

.atlas-embed-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 16px 24px;
    padding: 20px 18px;
    border-bottom: 1px solid var(--line);
    background: var(--panel-strong);
}

.atlas-embed-titles {
    min-width: 260px;
}

.atlas-embed-titles .header-kicker {
    display: inline-block;
    margin-bottom: 6px;
    padding: 0;
    background: none;
    color: var(--accent-strong);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.atlas-embed-titles h2 {
    margin: 0 0 4px;
    font-size: 1.3rem;
    color: var(--text);
}

.atlas-embed-titles p {
    margin: 0;
    max-width: 560px;
    color: var(--muted);
    font-size: 0.86rem;
    line-height: 1.5;
}

.atlas-embed-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

/* Layer switch in the header row. Kept as a segmented control rather than four
   loose pills so the mutually exclusive choice, and which one is current, stay
   legible next to the two real buttons.

   Overrides two things from the atlas stylesheet, which loads after this file
   (hence the #atlasSection prefix, same trick as the type rules below):

   - display: the atlas base is `grid` with a hard-coded three-column template,
     written when there were only three layers, so the gene layer's fourth button
     dropped onto a second row. Switching to a nowrap flex row makes the column
     count irrelevant -- a fifth layer cannot re-introduce the bug, and each
     button sizes to its own label instead of all four padding out to the width
     of "Gene expression".
   - type size: 8px suits a 300px drawer, not a header row. */
#atlasSection .atlas-embed-layer-tabs {
    display: flex;
    flex-wrap: nowrap;
    gap: 2px;
    border-radius: 10px;
}

#atlasSection .atlas-embed-layer-tabs button {
    flex: 0 0 auto;
    min-height: 34px;
    padding: 7px 11px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

/* Status capsule, now sharing the header row with the layer switch. The atlas
   rewrites its text for every scope change -- in the cell-profiles layer the label
   becomes "Linked · <collection> · <dataset> · <donor>", which grows without bound
   and used to push Atlas settings onto a second row.

   So: cap the capsule, and scroll the label instead of widening it. The cap tracks
   the viewport so a wide window still shows the whole label without scrolling.
   The region count keeps its full width (flex: 0 0 auto) -- it is the part worth
   reading, so the descriptive half is what gives way.

   The dot and the count are unshrinkable, so the cap comes off the label alone:
   about 69px of label at a 1118px viewport, less on narrower ones. Below a readable
   width the label is hidden outright (see is-too-narrow) rather than scrolled
   through a sliver. Hiding can only make the row narrower, so unlike widening the
   cap it cannot bring the wrapping back. */
#atlasSection .atlas-embed-meta .dataset-status {
    max-width: clamp(180px, 22vw, 320px);
}

#atlasSection .atlas-embed-meta .dataset-status > span:not(.status-dot) {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

#atlasSection .atlas-embed-meta .dataset-status > span.is-too-narrow {
    display: none;
}

#atlasSection .atlas-embed-meta .dataset-status > strong {
    flex: 0 0 auto;
}

/* The label must be the ONLY shrinkable item in the capsule: a 7px status indicator
   shipped with the default flex-shrink: 1 and min-width: auto (0 for an empty
   element), so once the capsule was capped the dot was squeezed -- measured rendering
   at 4.1px, deformed into an ellipse by its own border-radius. The count gets the
   same treatment because it is the part worth reading. */
#atlasSection .atlas-embed-meta .dataset-status > .status-dot {
    flex: 0 0 auto;
}

/* The scroll moves an injected track with a transform, which the compositor handles
   without laying anything out again. The first attempt animated text-indent on the
   label instead; that is a layout property, so every frame re-ran the flex layout of
   the whole capsule -- visible as jitter, and it perturbed the dot through the label's
   intrinsic width. A transform cannot reach a sibling.

   The track has to be injected from JS because the atlas replaces the capsule's
   children with innerHTML on every update, and it is re-injected by the same observer
   that re-measures. app.js only injects it when the text actually overflows, so a
   label that fits stays a plain text node and the ellipsis above still applies -- an
   inline-block track would be replaced wholesale by a bare ellipsis instead. */
#atlasSection .atlas-embed-meta .marquee-track {
    display: inline-block;
    white-space: nowrap;
}

#atlasSection .atlas-embed-meta .marquee-track.is-marquee {
    animation: capsuleMarquee var(--marquee-duration, 10s) linear infinite;
}

#atlasSection .atlas-embed-meta .dataset-status:hover .marquee-track.is-marquee {
    animation-play-state: paused;
}

/* linear, with the pauses written into the keyframes rather than borrowed from an
   easing curve: ease-in-out spends most of the cycle at the two ends and crosses the
   middle fast, which reads as the text jumping to its end rather than scrolling. */
@keyframes capsuleMarquee {
    0%, 8% { transform: translateX(0); }
    46%, 54% { transform: translateX(var(--marquee-shift, 0)); }
    92%, 100% { transform: translateX(0); }
}

/* prefers-reduced-motion is handled in app.js by simply not injecting the track: the
   label then stays a plain text node and falls back to the ellipsis above, with the
   full text on hover. A CSS override here would be a rule that can never match. */

.atlas-embed-head .summary-strip {
    margin: 0;
    padding: 0;
    border: 0;
}

.atlas-embed-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.atlas-embed-btn {
    border: 1px solid var(--line-strong);
    background: rgba(255, 255, 255, 0.05);
    color: var(--text);
    font-family: inherit;
    font-weight: 600;
    font-size: 11px;
    padding: 8px 15px;
    border-radius: 10px;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}

.atlas-embed-btn:hover {
    border-color: var(--accent);
    background: rgba(85, 214, 176, 0.12);
    color: var(--accent-strong);
}

.atlas-embed-stage {
    position: relative;
    height: min(80vh, 880px);
    min-height: 560px;
}

.atlas-embed--framed .viewer-panel {
    position: absolute;
    inset: 0;
}

.atlas-embed--framed .control-panel {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 300px;
    max-width: 84%;
    z-index: 6;
    transform: translateX(-102%);
    transition: transform 220ms ease;
    box-shadow: 20px 0 46px rgba(2, 8, 12, 0.5);
}

.atlas-embed--framed.show-settings .control-panel {
    transform: translateX(0);
}

.atlas-embed--framed .detail-panel {
    position: absolute;
    top: 14px;
    right: 14px;
    bottom: 14px;
    width: 340px;
    max-width: calc(100% - 28px);
    z-index: 7;
    border-radius: 16px;
    border: 1px solid var(--line-strong);
    box-shadow: 0 24px 60px rgba(2, 8, 12, 0.55);
}

.atlas-embed--framed .detail-panel:not(.open) {
    display: none;
}

@media (max-width: 720px) {
    .atlas-embed--framed .detail-panel {
        width: calc(100% - 28px);
    }
}

/* Typography: align the embedded atlas with the dashboard font (drop the
   atlas's Inter/Georgia mix inside the framed section only; standalone keeps
   its own type). #atlasSection ids win over the atlas's class rules. */
#atlasSection,
#atlasSection button,
#atlasSection input,
#atlasSection h1,
#atlasSection h2,
#atlasSection h3,
#atlasSection .brand strong,
#atlasSection dialog h2,
#atlasSection dialog h3 {
    font-family: "IBM Plex Sans", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
}

/* About dialog: match the light dashboard, center it, drop the top accent
   line, and give it a clear top-right close button. Re-declaring the page
   palette flips every var()-based child rule to the light theme. */
#atlasSection dialog {
    --panel: #fbfdfe;
    --panel-strong: #f4f8fb;
    --line: #d7e2ea;
    --line-strong: #bdd0dc;
    --text: #18242d;
    --muted: #61717d;
    --accent: #146c94;
    --accent-strong: #0f4c68;
    color-scheme: light;
    position: fixed;
    inset: 0;
    margin: auto;
    border: none;
    border-radius: 16px;
    background: var(--panel);
    color: var(--text);
    box-shadow: 0 24px 60px rgba(28, 52, 66, 0.28);
}

#atlasSection dialog::backdrop {
    background: rgba(24, 36, 45, 0.42);
    backdrop-filter: blur(6px);
}

#atlasSection dialog form {
    padding: 22px 24px 20px;
}

#atlasSection dialog h2 {
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--text);
}

#atlasSection dialog h3 {
    color: var(--muted);
}

#atlasSection dialog p {
    color: var(--muted);
    font-size: 0.82rem;
}

#atlasSection dialog pre {
    border: 1px solid var(--line);
    background: var(--panel-strong);
    color: var(--accent-strong);
}

#atlasSection dialog .dialog-close {
    top: 12px;
    right: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border: 1px solid var(--line-strong);
    border-radius: 50%;
    background: var(--panel-strong);
    color: var(--muted);
    font-size: 20px;
    line-height: 1;
}

#atlasSection dialog .dialog-close:hover {
    border-color: var(--accent);
    color: var(--text);
}

#atlasSection dialog .primary-button {
    border: 1px solid var(--accent);
    background: var(--accent);
    color: #fff;
}

/* Collapsible cell-type lists: show ~5 rows, fade the overflow, expand on
   click. Applied to the control-panel classes, the legend key, and the detail
   composition list. */
.atlas-embed--framed .atlas-collapsible {
    transition: max-height 240ms ease;
}

.atlas-embed--framed .atlas-collapsible.is-collapsed {
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to bottom, #000 58%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 58%, transparent 100%);
}

.atlas-embed--framed .atlas-list-toggle {
    margin-top: 8px;
    padding: 2px 0;
    border: 0;
    background: transparent;
    color: var(--accent-strong);
    font: inherit;
    font-size: 9px;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
}

.atlas-embed--framed .atlas-list-toggle:hover {
    color: var(--accent);
    text-decoration: underline;
}

/* The legend overlay is pointer-events:none so canvas drags pass through; the
   collapse toggle must opt back in to be clickable (task: legend show-all). */
.atlas-embed--framed .legend .atlas-list-toggle {
    pointer-events: auto;
}

/* Cell-class list rows: smaller, panel-consistent size. */
#atlasSection .cell-type-button {
    font-size: 10px;
}

/* Settings drawer close button (top-right of the control panel). */
.atlas-embed--framed .atlas-panel-close {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: 1px solid var(--line-strong);
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.05);
    color: var(--muted);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}

.atlas-embed--framed .atlas-panel-close:hover {
    border-color: var(--accent);
    color: var(--text);
}

/* Detail panel: enlarge composition + region-role text one step (task 5),
   leaving the section titles and the "Curated context" badge untouched. */
#atlasSection .composition-row {
    font-size: 9px;
}

#atlasSection .composition-section .section-heading span,
#atlasSection .gene-region-section .section-heading span {
    font-size: 8px;
}

#atlasSection .region-overview {
    font-size: 10px;
}

#atlasSection .region-role {
    font-size: 9.5px;
}

#atlasSection .function-tags span,
#atlasSection .network-tags span {
    font-size: 8px;
}


.header {
    margin-bottom: 24px;
    padding: 4px 0 20px;
    border-bottom: 1px solid var(--line);
}

.header-kicker {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent-strong);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin-bottom: 14px;
}

.header h1 {
    color: var(--text);
    font-size: clamp(2rem, 3vw, 3.1rem);
    margin-bottom: 10px;
    font-weight: 700;
    letter-spacing: -0.03em;
    max-width: none;
    text-wrap: balance;
}

.header p {
    color: var(--muted);
    font-size: 1.05rem;
    line-height: 1.6;
    max-width: 64ch;
}

/* Controls Section */
.controls {
    display: flex;
    gap: 18px;
    margin-bottom: 20px;
    padding: 20px;
    background: var(--panel-strong);
    border-radius: 20px;
    border: 1px solid var(--line);
    position: relative;
}

/* Gene layer scope lock. The three filters cannot narrow a cross-study merge, so
   the gene layer disables them and explains why. The explanation is a hover
   tooltip, never an inline paragraph: as a flex child it stole width and squeezed
   the selects flat. A small badge on the row's edge makes the tooltip findable. */
.controls.is-scope-locked::after {
    content: "\24D8  Global scope";
    position: absolute;
    top: 0;
    right: 20px;
    transform: translateY(-50%);
    padding: 4px 12px;
    border-radius: 999px;
    background: var(--accent-strong);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    white-space: nowrap;
    cursor: help;
    box-shadow: 0 6px 16px rgba(31, 59, 78, 0.18);
}

.scope-note {
    /* Out of the flex flow so it never resizes the selects; revealed on hover. */
    position: absolute;
    top: calc(100% + 8px);
    right: 20px;
    z-index: 30;
    max-width: 360px;
    margin: 0;
    padding: 12px 14px;
    border-radius: 12px;
    background: var(--panel);
    border: 1px solid var(--line-strong);
    box-shadow: 0 14px 34px rgba(31, 59, 78, 0.16);
    color: var(--muted);
    font-size: 0.82rem;
    line-height: 1.5;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-4px);
    transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
    pointer-events: none;
}

.scope-note strong {
    color: var(--text);
}

/* Show it while the cursor is over the locked filter row (or a select regains
   focus). Gated on the armed note so it never appears in the cell layer. */
.controls.is-scope-locked:hover .scope-note:not([hidden]),
.controls.is-scope-locked:focus-within .scope-note:not([hidden]) {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.scope-banner {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 20px;
    padding: 22px 24px;
    margin-bottom: 28px;
    background:
        linear-gradient(135deg, rgba(20, 108, 148, 0.1), rgba(15, 76, 104, 0.03)),
        var(--panel);
    border: 1px solid var(--line);
    border-radius: 20px;
}

.scope-copy {
    display: flex;
    flex-direction: column;
    gap: 8px;
    flex: 1 1 auto;
    min-width: 0;
}

.scope-eyebrow {
    color: var(--accent-strong);
    font-size: 0.8rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.scope-title {
    font-size: clamp(1.4rem, 2vw, 2rem);
    font-weight: 700;
    letter-spacing: -0.03em;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.scope-subtitle {
    color: var(--muted);
    max-width: 62ch;
    line-height: 1.5;
}

.scope-metrics {
    display: flex;
    gap: 12px;
    flex-wrap: nowrap;
    justify-content: flex-end;
}

.scope-chip {
    min-width: 112px;
    padding: 14px 16px;
    border-radius: 16px;
    background: rgba(255, 255, 255, 0.76);
    border: 1px solid rgba(255, 255, 255, 0.75);
    box-shadow: 0 8px 20px rgba(31, 59, 78, 0.06);
}

.scope-chip span {
    display: block;
    color: var(--muted);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: 8px;
}

.scope-chip strong {
    font-size: 1.4rem;
    color: var(--text);
}

.control-group {
    display: flex;
    flex-direction: column;
    flex: 1;
}

.control-group label {
    font-weight: 600;
    color: var(--muted);
    margin-bottom: 8px;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

select {
    width: 100%;
    padding: 13px 15px;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    font-size: 1em;
    background: rgba(255, 255, 255, 0.95);
    color: var(--text);
    cursor: pointer;
    transition: all 0.2s ease;
}

select:disabled {
    background: #f3f6f8;
    cursor: not-allowed;
    opacity: 0.6;
}

select:hover:not(:disabled) {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px rgba(20, 108, 148, 0.08);
}

select:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 4px rgba(20, 108, 148, 0.12);
}

/* Main Content Layout */
/* ===== Atlas-first view switch (quiet icon+text toggle) ===== */
.scope-right {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 14px;
    flex: 0 0 auto;
}

.view-switch-wrap {
    position: relative;
}

.view-switch {
    display: inline-flex;
    align-items: center;
    gap: 18px;
}

.view-switch-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 2px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--muted);
    font-family: inherit;
    font-size: 0.86rem;
    font-weight: 600;
    cursor: pointer;
    transition: color 0.18s ease, border-color 0.18s ease;
}

.view-switch-btn:hover {
    color: var(--accent-strong);
}

.view-switch-btn.is-active {
    color: var(--accent-strong);
    border-bottom-color: var(--accent);
}

.view-switch-icon {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.view-hint {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    z-index: 20;
    width: 264px;
    padding: 12px 14px;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    background: var(--panel);
    box-shadow: 0 16px 40px rgba(28, 52, 66, 0.18);
    text-align: left;
}

.view-hint::before {
    content: "";
    position: absolute;
    top: -6px;
    right: 46px;
    width: 12px;
    height: 12px;
    background: var(--panel);
    border-left: 1px solid var(--line-strong);
    border-top: 1px solid var(--line-strong);
    transform: rotate(45deg);
}

.view-hint p {
    margin: 0 0 10px;
    color: var(--muted);
    font-size: 0.8rem;
    line-height: 1.5;
}

.view-hint strong {
    color: var(--accent-strong);
}

.view-hint-dismiss {
    border: 1px solid var(--accent);
    border-radius: 8px;
    background: var(--accent);
    color: #fff;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 5px 12px;
    cursor: pointer;
}

/* One-time Atlas layer tour: a coach-mark popover walks through each layer
   button the first time the atlas scrolls into view. (The pulse that used to
   invite opening the settings drawer is gone along with it -- the layer switch
   is in the header row now, so there is nothing to coax open.) */
.atlas-tour-target {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 8px;
}

.atlas-tour-pop {
    position: fixed;
    z-index: 1000;
    width: 268px;
    padding: 14px 16px;
    border: 1px solid var(--line-strong);
    border-radius: 12px;
    background: var(--panel);
    box-shadow: 0 18px 44px rgba(28, 52, 66, 0.22);
    text-align: left;
}

.atlas-tour-pop[hidden] {
    display: none;
}

.atlas-tour-arrow {
    position: absolute;
    left: var(--arrow-left, 24px);
    width: 12px;
    height: 12px;
    background: var(--panel);
    border-left: 1px solid var(--line-strong);
    border-top: 1px solid var(--line-strong);
    transform: translateX(-50%) rotate(45deg);
}

.atlas-tour-pop[data-place="below"] .atlas-tour-arrow {
    top: -6px;
}

.atlas-tour-pop[data-place="above"] .atlas-tour-arrow {
    bottom: -6px;
    transform: translateX(-50%) rotate(225deg);
}

.atlas-tour-step {
    display: inline-block;
    margin-bottom: 6px;
    color: var(--accent-strong);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.atlas-tour-title {
    margin: 0 0 6px;
    font-size: 0.98rem;
    color: var(--text);
}

.atlas-tour-body {
    margin: 0 0 12px;
    color: var(--muted);
    font-size: 0.82rem;
    line-height: 1.5;
}

.atlas-tour-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.atlas-tour-nav {
    display: flex;
    gap: 8px;
}

.atlas-tour-skip {
    border: 0;
    background: none;
    padding: 4px 2px;
    font: inherit;
    font-size: 0.78rem;
    color: var(--muted);
    cursor: pointer;
}

.atlas-tour-skip:hover {
    color: var(--text);
}

.atlas-tour-back {
    border: 1px solid var(--line-strong);
    border-radius: 8px;
    background: var(--panel);
    color: var(--text);
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 5px 12px;
    cursor: pointer;
}

.atlas-tour-back[disabled] {
    opacity: 0.45;
    cursor: default;
}

.atlas-tour-next {
    border: 1px solid var(--accent);
    border-radius: 8px;
    background: var(--accent);
    color: #fff;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    padding: 5px 12px;
    cursor: pointer;
}

/* View swap: one content region at a time (atlas is the default). */
.app-view.is-hidden {
    display: none;
}

.app-view:not(.is-hidden) {
    animation: appViewFade 0.24s ease;
}

@keyframes appViewFade {
    from {
        opacity: 0;
        transform: translateY(4px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.main-content {
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: 30px;
    min-height: calc(100vh - 400px);
}

.left-panel {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.right-panel {
    display: flex;
    flex-direction: column;
    gap: 20px;
}

/* Overview Cards */
.overview-card {
    background: var(--panel);
    border-radius: 20px;
    padding: 30px;
    box-shadow: 0 12px 32px rgba(22, 39, 49, 0.06);
    border: 1px solid var(--line);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.overview-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 18px 36px rgba(22, 39, 49, 0.09);
}

.collection-overview {
    background: linear-gradient(180deg, rgba(20, 108, 148, 0.09), rgba(255, 255, 255, 0.96));
}

.dataset-overview {
    background: linear-gradient(180deg, rgba(15, 76, 104, 0.08), rgba(255, 255, 255, 0.96));
}

.overview-title {
    font-size: 1.2rem;
    font-weight: 700;
    margin-bottom: 25px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--line);
    color: var(--text);
}

.overview-stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
    margin-bottom: 25px;
}

.stat-item {
    display: grid;
    gap: 10px;
    padding: 16px 18px;
    border: 1px solid rgba(20, 108, 148, 0.08);
    border-radius: 16px;
    background: rgba(255, 255, 255, 0.76);
}

.stat-label {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.stat-number {
    font-size: 1.45rem;
    font-weight: 700;
    color: var(--accent-strong);
}

.stat-breakdown {
    display: grid;
    gap: 4px;
    font-size: 1rem;
}

.stat-breakdown-item {
    color: var(--muted);
    font-size: 0.85rem;
    font-weight: 600;
}

.stat-breakdown-item strong {
    color: var(--accent-strong);
    font-size: 1rem;
    margin-left: 6px;
}

/* Status Badges */
.status-badges {
    display: grid;
    gap: 12px;
    margin-top: 20px;
    padding: 18px 20px;
    border-radius: 18px;
    background: rgba(255, 255, 255, 0.68);
    border: 1px solid rgba(20, 108, 148, 0.08);
}

.status-badge {
    background: rgba(255, 255, 255, 0.85);
    border: 1px solid var(--line-strong);
    padding: 9px 14px;
    border-radius: 999px;
    font-size: 0.92rem;
    font-weight: 700;
    text-transform: capitalize;
    letter-spacing: 0.02em;
    transition: all 0.2s ease;
}

.status-badge:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}

/* Disease-specific badge colors */
.status-glioblastoma {
    background: var(--danger-soft);
    color: var(--danger);
    border-color: rgba(159, 53, 38, 0.25);
}

.status-muted {
    color: var(--muted);
}

.status-overflow {
    background: rgba(20, 108, 148, 0.08);
    border-style: dashed;
    color: var(--accent-strong);
}

.overview-summary-inline {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
}

.overview-toggle {
    border: none;
    background: transparent;
    color: var(--accent-strong);
    font-weight: 700;
    font-size: 0.88rem;
    cursor: pointer;
    padding: 0;
    text-decoration: underline;
    text-underline-offset: 0.18em;
}

.overview-toggle:hover {
    color: var(--accent);
}

.overview-toggle:focus-visible {
    outline: 2px solid rgba(20, 108, 148, 0.28);
    outline-offset: 3px;
    border-radius: 6px;
}

.overview-expanded {
    margin-top: 12px;
    padding: 14px 16px;
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.72);
    border: 1px solid var(--line);
}

.overview-expanded.status-badges {
    display: flex;
    flex-wrap: wrap;
}

.regions-summary {
    margin-top: 20px;
    padding: 18px 20px;
    font-size: 0.96rem;
    line-height: 1.6;
    color: var(--muted);
    font-weight: 500;
    display: grid;
    gap: 10px;
    border-radius: 18px;
    background: rgba(255, 255, 255, 0.68);
    border: 1px solid rgba(20, 108, 148, 0.08);
}

.summary-line {
    display: grid;
    gap: 6px;
}

.module-header {
    display: grid;
    gap: 6px;
}

.module-kicker {
    color: var(--text);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.module-meta {
    color: var(--muted);
    font-size: 0.95rem;
    line-height: 1.6;
}

.module-highlight-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
    margin: 6px 0 10px;
}

.module-highlight-card {
    display: grid;
    gap: 6px;
    padding: 14px 16px;
    border-radius: 14px;
    background: rgba(20, 108, 148, 0.06);
    border: 1px solid rgba(20, 108, 148, 0.1);
}

.module-highlight-label {
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.module-highlight-value {
    color: var(--text);
    font-size: 1rem;
    line-height: 1.4;
}

.module-highlight-meta {
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.5;
}

.summary-line strong {
    color: var(--text);
    font-size: 0.82rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.summary-detail-list {
    color: var(--text);
    line-height: 1.7;
}

/* Donor Details */
.donor-details {
    background: var(--panel);
    border-radius: 20px;
    padding: 30px;
    box-shadow: 0 12px 32px rgba(22, 39, 49, 0.06);
    border: 1px solid var(--line);
}

.donor-details h3 {
    color: var(--text);
    font-size: 1.15rem;
    margin-bottom: 25px;
    font-weight: 700;
    letter-spacing: 0.01em;
}

.donor-info {
    display: flex;
    flex-direction: column;
    gap: 15px;
    margin-bottom: 25px;
    padding: 20px;
    background: var(--panel-strong);
    border-radius: 16px;
    border: 1px solid var(--line);
}

.donor-name {
    font-size: 1.8em;
    font-weight: 800;
    color: var(--text);
    letter-spacing: -0.03em;
}

.donor-metadata {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
}

.donor-meta-item {
    display: inline-flex;
    align-items: center;
    padding: 8px 15px;
    background: white;
    border-radius: 20px;
    font-size: 1em;
    font-weight: 600;
    color: var(--text);
    border: 1px solid var(--line);
}

.donor-cells {
    font-size: 1rem;
    font-weight: 600;
    color: var(--accent-strong);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.donor-status-badges {
    display: grid;
    gap: 15px;
    padding: 20px;
    background: rgba(255, 255, 255, 0.72);
    border-radius: 16px;
    border: 1px solid rgba(20, 108, 148, 0.08);
}

.donor-highlights {
    display: grid;
    gap: 14px;
    margin-top: 16px;
    padding: 20px;
    background: rgba(255, 255, 255, 0.72);
    border-radius: 16px;
    border: 1px solid rgba(20, 108, 148, 0.08);
}

/* Cell Type Section */
.cell-type-section,
.brain-regions-section {
    background: var(--panel);
    border-radius: 20px;
    padding: 25px;
    box-shadow: 0 12px 32px rgba(22, 39, 49, 0.06);
    border: 1px solid var(--line);
}

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    gap: 18px;
}

.section-title {
    color: var(--text);
    font-size: 1.15rem;
    font-weight: 700;
}

.section-copy {
    display: grid;
    gap: 6px;
}

.section-subtitle {
    color: var(--muted);
    font-size: 0.95rem;
    line-height: 1.55;
    max-width: 64ch;
}

.section-controls {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    justify-content: flex-end;
}

.view-toggle,
.region-type-toggle,
.metric-toggle,
.range-toggle {
    display: flex;
    background: #edf3f6;
    border-radius: 12px;
    padding: 3px;
}

.toggle-btn {
    padding: 8px 16px;
    border: none;
    background: transparent;
    border-radius: 9px;
    cursor: pointer;
    font-size: 0.9em;
    font-weight: 600;
    transition: all 0.2s ease;
    color: var(--muted);
}

.toggle-btn:hover {
    color: var(--text);
}

.toggle-btn.active {
    background: var(--accent);
    color: white;
}

.toggle-btn:disabled {
    opacity: 0.42;
    cursor: not-allowed;
}

/* Cell Type Content */
.cell-type-content {
    min-height: 300px;
}

.cell-type-content--split {
    display: grid;
    grid-template-columns: minmax(0, 1.55fr) minmax(260px, 0.95fr);
    gap: 18px;
    align-items: start;
}

.chart-insights {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
    margin-bottom: 18px;
}

.chart-insight-card {
    display: grid;
    gap: 6px;
    padding: 14px 16px;
    border-radius: 14px;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(238, 245, 248, 0.85));
    border: 1px solid rgba(20, 108, 148, 0.08);
}

.chart-insight-label {
    color: var(--muted);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.chart-insight-value {
    color: var(--text);
    font-size: 1rem;
    font-weight: 700;
}

.chart-insight-meta {
    color: var(--muted);
    font-size: 0.85rem;
    line-height: 1.5;
}

.cell-type-table {
    max-height: 400px;
    overflow-y: auto;
}

.cell-type-content--split .cell-type-table {
    max-height: none;
    overflow-y: auto;
    border: 1px solid var(--line);
    border-radius: 16px;
    background: rgba(255, 255, 255, 0.82);
    padding: 6px 0;
}

.cell-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 15px;
    border-bottom: 1px solid #ecf0f1;
    transition: background-color 0.3s ease;
}

.cell-row:hover {
    background-color: var(--accent-soft);
}

.cell-type-name {
    font-weight: 600;
    color: var(--text);
    flex: 1;
}

.cell-type-content--split .cell-type-name {
    font-size: 0.92rem;
}

.cell-count {
    font-size: 1.2em;
    font-weight: 700;
    color: var(--accent-strong);
    margin-left: 20px;
}

.cell-type-content--split .cell-count {
    font-size: 1rem;
}

.cell-percentage {
    font-size: 0.9em;
    color: var(--muted);
    margin-left: 10px;
}

.cell-type-content--split .cell-percentage {
    display: block;
    margin-left: 0;
    text-align: right;
}

/* Brain Regions */
.regions-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}

.chart-container {
    height: 300px;
}

.regions-table {
    max-height: 300px;
    overflow-y: auto;
}

.region-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 15px;
    border-bottom: 1px solid #ecf0f1;
    transition: background-color 0.3s ease;
}

.region-row:hover {
    background-color: var(--accent-soft);
}

.region-name {
    font-weight: 600;
    color: var(--text);
}

.region-count {
    font-size: 1.2em;
    font-weight: 700;
    color: var(--accent-strong);
}

.region-percentage {
    font-size: 0.9em;
    color: var(--muted);
    margin-left: 10px;
}

/* Utility Classes */
.hidden {
    display: none !important;
}

.no-data {
    text-align: center;
    color: var(--muted);
    font-style: italic;
    padding: 40px;
    background: rgba(97, 113, 125, 0.05);
    border-radius: 14px;
    border: 1px dashed var(--line-strong);
}

/* Responsive Design */
@media (max-width: 1200px) {
    .main-content {
        grid-template-columns: 1fr;
    }

    .regions-grid {
        grid-template-columns: 1fr;
    }

    .cell-type-content--split {
        grid-template-columns: 1fr;
    }

    .module-highlight-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .scope-banner {
        flex-direction: column;
    }

    .scope-title {
        white-space: normal;
        overflow: visible;
        text-overflow: clip;
    }

    .scope-metrics {
        width: 100%;
        justify-content: flex-start;
        flex-wrap: wrap;
    }
}

@media (max-width: 768px) {
    .controls {
        flex-direction: column;
    }

    .header h1 {
        font-size: 1.8em;
        max-width: none;
        text-wrap: pretty;
    }

    .donor-name {
        font-size: 1.5em;
    }

    .section-header {
        flex-direction: column;
        gap: 15px;
        align-items: flex-start;
    }

    .section-controls,
    .chart-insights {
        width: 100%;
    }

    .overview-stats,
    .module-highlight-grid,
    .chart-insights {
        grid-template-columns: 1fr;
    }
}

/* Cloud access status; selection itself has no count limit. */
#accessQuotaStatus { margin: 0; padding: .6rem 1rem; background: #edf3f5; color: #23424c; font-size: .85rem; }
.gene-chip { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
