Spaces:
Sleeping
Sleeping
| /* Keep the app font + background; let Bootstrap do the rest */ | |
| :root { | |
| --sidebar-width: 420px; | |
| /* --sidebar-width: 28vw; */ | |
| /* If the sidebar ever feels too dominant, you can later refine: */ | |
| /* --sidebar-width: clamp(380px, 22vw, 520px); */ | |
| } | |
| /* Let the app actually fill the viewport */ | |
| html, | |
| body { | |
| height: 100%; | |
| } | |
| body { | |
| margin: 0; | |
| font-family: "Roboto", system-ui, -apple-system, Segoe UI, Arial, sans-serif; | |
| background: #f4f6f8; | |
| /* Optional but recommended: prevent the page itself from scrolling */ | |
| overflow: hidden; | |
| } | |
| /* Your top-level bootstrap container becomes the app frame */ | |
| .app-frame { | |
| height: 100dvh; | |
| /* or 100vh if you prefer */ | |
| box-sizing: border-box; | |
| /* IMPORTANT: includes py-3 padding inside height */ | |
| display: flex; | |
| flex-direction: column; | |
| gap: 12px; | |
| } | |
| /* Utility */ | |
| .hidden { | |
| display: none ; | |
| } | |
| /* --- Main visualization layout should consume remaining height --- */ | |
| .visualization-area { | |
| flex: 1; | |
| /* ✅ THIS makes <main> fill the screen */ | |
| display: flex; | |
| gap: 1rem; | |
| min-height: 0; | |
| /* ✅ allow children to shrink + scroll */ | |
| } | |
| /* Graph Wrapper & Cytoscape container */ | |
| .graph-wrapper { | |
| flex: 1; | |
| position: relative; | |
| min-height: 0; | |
| border-radius: 0.5rem; | |
| overflow: hidden; | |
| background: #fff; | |
| border: 1px solid #dee2e6; | |
| } | |
| /* Cytoscape canvas fills wrapper */ | |
| .graph-container { | |
| position: absolute; | |
| inset: 0; | |
| } | |
| /* Details panel */ | |
| .details-panel { | |
| font-size: 1.10rem; | |
| /* slightly larger base */ | |
| width: var(--sidebar-width); | |
| min-width: var(--sidebar-width); | |
| display: flex; | |
| flex-direction: column; | |
| min-height: 0; | |
| background: #fff; | |
| border: 1px solid #dee2e6; | |
| border-radius: 0.5rem; | |
| overflow: hidden; | |
| } | |
| .details-panel .small { | |
| font-size: 1.25rem; | |
| /* don't make metadata tiny */ | |
| } | |
| .details-panel .badge { | |
| font-size: 1.0rem; | |
| } | |
| /* .details-panel h3 { | |
| font-size: 1.3rem; | |
| margin: 0; | |
| padding: 0.75rem 1rem; | |
| border-bottom: 1px solid #dee2e6; | |
| } */ | |
| .details-panel .text-muted { | |
| color: #495057 ; | |
| /* darker than default muted */ | |
| } | |
| .details-header { | |
| padding: 0.75rem 1rem; | |
| border-bottom: 1px solid #dee2e6; | |
| } | |
| .details-header h3 { | |
| font-size: 1.3rem; | |
| margin: 0; | |
| padding: 0; | |
| border-bottom: 0; | |
| } | |
| .details-content { | |
| line-height: 1.6; | |
| padding: 1rem; | |
| overflow-y: auto; | |
| flex: 1; | |
| min-height: 0; | |
| } | |
| .placeholder-text { | |
| color: #6c757d; | |
| font-style: italic; | |
| text-align: center; | |
| margin-top: 2rem; | |
| } | |
| /* Make tab-content fill graph-wrapper */ | |
| #view-tabs-content { | |
| height: 100%; | |
| min-height: 0; | |
| } | |
| /* Compact tabs for space-constrained layouts */ | |
| .nav-tabs .nav-link { | |
| padding: 0.35rem 0.65rem; /* default is ~0.5rem 1rem */ | |
| font-size: 0.9rem; | |
| } | |
| /* ------------------------------------------------------------ | |
| Oversight layout: keep everything bounded inside #oversight-view | |
| ------------------------------------------------------------ */ | |
| /* The section must also be a flex column and shrinkable */ | |
| #oversight-section { | |
| flex: 1 1 auto; | |
| min-height: 0; | |
| /* CRITICAL */ | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| /* prevent section content from escaping */ | |
| max-height: 90%; | |
| } | |
| /* Oversight table readability */ | |
| #oversight-section .table td, | |
| #oversight-section .table th { | |
| padding-top: 0.85rem; | |
| padding-bottom: 0.85rem; | |
| } | |
| #oversight-section .quality-cell { | |
| /* font-size: 1.02rem; */ | |
| /* line-height: 1.35; */ | |
| } | |
| /* Bigger checkbox */ | |
| .oversight-checkbox { | |
| transform: scale(1.25); | |
| transform-origin: center; | |
| } | |
| /* The Oversight tab-pane must be a flex column that can shrink */ | |
| #oversight-view { | |
| display: flex; | |
| flex-direction: column; | |
| min-height: 0; | |
| /* CRITICAL */ | |
| overflow: hidden; | |
| /* keep scrolling inside inner container */ | |
| } | |
| /* The split container should fill the remaining section height */ | |
| .oversight-split-container { | |
| flex: 1 1 auto; | |
| min-height: 0; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| /* The top area owns the vertical space; bottom is hidden for now */ | |
| .oversight-top { | |
| flex: 1 1 auto; | |
| min-height: 0; | |
| overflow: hidden; | |
| } | |
| /* This is the ONLY scrolling viewport */ | |
| #oversight-inner-tabs-content { | |
| flex: 1 1 auto; | |
| min-height: 0; | |
| overflow: auto; | |
| /* give the pager some breathing room so it never looks clipped */ | |
| padding-bottom: 1rem; | |
| } | |
| /* Optional: ensure each pane doesn’t fight heights */ | |
| #oversight-inner-tabs-content .tab-pane { | |
| height: auto ; | |
| } | |
| /* Triplets panel: header stays fixed, only table scrolls */ | |
| #oversight-bottom { | |
| max-height: 60vh; | |
| /* keep whatever height you liked */ | |
| overflow: hidden; | |
| /* prevent the whole panel from scrolling */ | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| /* The table area becomes the scroll container */ | |
| #triplets-table-wrap { | |
| flex: 1; | |
| /* take remaining space under header/toolbars */ | |
| min-height: 0; | |
| /* CRITICAL in flex layouts for scrolling */ | |
| overflow-y: auto; | |
| overflow-x: auto; | |
| /* keep horizontal scroll if needed */ | |
| } | |
| /* Optional: sticky table header while scrolling */ | |
| #triplets-table-wrap thead th { | |
| position: sticky; | |
| top: 0; | |
| background: #fff; | |
| z-index: 2; | |
| } | |
| .relation-card:hover { | |
| background: rgba(13, 110, 253, 0.05); | |
| /* bootstrap primary-ish tint */ | |
| border-color: rgba(13, 110, 253, 0.35); | |
| } | |
| .relation-card:focus { | |
| outline: 2px solid rgba(13, 110, 253, 0.35); | |
| outline-offset: 2px; | |
| } | |
| /* Tiny emoji confetti */ | |
| .confetti-box { | |
| position: fixed; | |
| inset: 0; | |
| pointer-events: none; | |
| z-index: 4000; | |
| /* above toast */ | |
| } | |
| .confetti-particle { | |
| position: absolute; | |
| font-size: 18px; | |
| animation-name: confetti-fly; | |
| animation-timing-function: ease-out; | |
| animation-fill-mode: forwards; | |
| filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.15)); | |
| } | |
| @keyframes confetti-fly { | |
| from { | |
| transform: translate(0, 0) rotate(0deg); | |
| opacity: 1; | |
| } | |
| to { | |
| transform: translate(var(--dx), var(--dy)) rotate(var(--rot)); | |
| opacity: 0; | |
| } | |
| } | |