Files
Control-Center/frontend-legacy/src/app/components/adaptive-navigation/adaptive-navigation.component.scss
Joshua 8da593c450
All checks were successful
Dev Build / build-test (pull_request) Successful in 1m57s
CUB-122: Scaffold Control Center React frontend
2026-05-07 20:15:30 -04:00

365 lines
8.6 KiB
SCSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================================
// Adaptive Navigation — Desktop sidebar / Mobile header
// Per CUB-27 spec breakpoints:
// Compact (0599px): Mobile header + hamburger + drawer
// Medium (6001023px): Collapsed sidebar (icon-only, 72px)
// Expanded (≥1024px): Full sidebar with labels (72px collapsed, 256px expanded)
// ============================================================================
// ---------------------------------------------------------------------------
// Desktop Sidebar (visible ≥600px)
// ---------------------------------------------------------------------------
.adaptive-nav__sidebar {
display: none; // Hidden by default (mobile-first)
flex-direction: column;
width: var(--cc-nav-rail-collapsed-width, 72px);
min-height: 100vh;
background-color: var(--cc-surface-container-high);
border-right: 1px solid var(--cc-outline);
z-index: 10;
}
.adaptive-nav__sidebar-header {
display: flex;
align-items: center;
justify-content: center;
height: 64px;
border-bottom: 1px solid var(--cc-outline);
}
.adaptive-nav__brand {
font-size: 18px;
font-weight: 700;
color: var(--status-active);
letter-spacing: 0.04em;
}
.adaptive-nav__sidebar-nav {
flex: 1;
padding-top: 8px;
}
.adaptive-nav__sidebar-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
min-height: 56px;
padding: 8px 0;
margin: 2px 8px;
border-radius: 28px;
color: var(--cc-on-surface-variant);
text-decoration: none;
transition: background-color 150ms ease, color 150ms ease;
&:hover {
background-color: rgba(255, 255, 255, 0.08);
color: var(--cc-on-surface);
}
&--active {
background-color: var(--status-active-bg);
color: var(--status-active);
.adaptive-nav__sidebar-label {
font-weight: 500;
}
}
}
.adaptive-nav__sidebar-label {
font-size: 11px;
font-weight: 400;
letter-spacing: 0.02em;
white-space: nowrap;
}
// ---------------------------------------------------------------------------
// Sidebar Footer — LIVE indicator + action buttons
// ---------------------------------------------------------------------------
.adaptive-nav__sidebar-footer {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 12px 0 20px;
border-top: 1px solid var(--cc-outline);
}
.adaptive-nav__sidebar-actions {
display: flex;
gap: 4px;
.mat-mdc-icon-button {
color: var(--cc-on-surface-variant) !important;
--mdc-icon-button-icon-size: 20px;
&:hover {
color: var(--cc-on-surface) !important;
}
}
}
// ---------------------------------------------------------------------------
// LIVE Status Indicator
// ---------------------------------------------------------------------------
.adaptive-nav__live {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
border-radius: 16px;
transition: background-color 200ms ease;
&--connected {
background-color: var(--status-active-bg);
}
}
.adaptive-nav__live-dot {
display: inline-block;
width: 8px;
height: 8px;
min-width: 8px;
border-radius: 50%;
background-color: var(--status-error);
transition: background-color 200ms ease;
&--connected {
background-color: var(--status-active);
animation: pulse-active 2s ease-in-out infinite;
}
}
.adaptive-nav__live-chip {
font-size: 11px !important;
font-weight: 600 !important;
letter-spacing: 0.06em;
height: 24px !important;
min-height: 24px !important;
padding: 0 8px !important;
color: var(--status-active) !important;
--mdc-chip-elevated-container-color: transparent;
background: transparent !important;
border: none !important;
box-shadow: none !important;
}
.adaptive-nav__live-text {
font-size: 12px;
font-weight: 600;
letter-spacing: 0.06em;
color: var(--status-active);
}
// ---------------------------------------------------------------------------
// Mobile Header (visible <600px only)
// ---------------------------------------------------------------------------
.adaptive-nav__mobile-header {
display: none; // Hidden on desktop, shown on mobile via media query
align-items: center;
height: var(--cc-header-height-compact, 56px);
padding: 0 12px;
background-color: var(--cc-surface-container-high);
border-bottom: 1px solid var(--cc-outline);
z-index: 20;
gap: 8px;
}
.adaptive-nav__hamburger {
color: var(--cc-on-surface-variant) !important;
min-width: 48px;
min-height: 48px;
&:hover {
color: var(--cc-on-surface) !important;
}
}
.adaptive-nav__mobile-title {
flex: 1;
font-size: 20px;
font-weight: 500;
color: var(--cc-on-surface);
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.adaptive-nav__live--mobile {
padding: 4px 10px;
border-radius: 16px;
.adaptive-nav__live-text {
font-size: 11px;
font-weight: 700;
}
}
.adaptive-nav__mobile-action {
color: var(--cc-on-surface-variant) !important;
min-width: 48px;
min-height: 48px;
&:hover {
color: var(--cc-on-surface) !important;
}
}
// ---------------------------------------------------------------------------
// Mobile Drawer
// ---------------------------------------------------------------------------
.adaptive-nav__overlay {
position: fixed;
inset: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 40;
}
.adaptive-nav__mobile-drawer {
position: fixed;
top: var(--cc-header-height-compact, 56px); // Below header
left: 0;
bottom: 0;
width: 280px;
max-width: 80vw;
background-color: var(--cc-surface-container);
border-right: 1px solid var(--cc-outline);
z-index: 50;
padding: 12px 0;
overflow-y: auto;
animation: slide-in-left 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.adaptive-nav__drawer-item {
display: flex;
align-items: center;
gap: 16px;
min-height: 48px;
padding: 0 20px;
color: var(--cc-on-surface-variant);
text-decoration: none;
transition: background-color 150ms ease, color 150ms ease;
&:hover {
background-color: rgba(255, 255, 255, 0.08);
color: var(--cc-on-surface);
}
&--active {
background-color: var(--status-active-bg);
color: var(--status-active);
.adaptive-nav__drawer-label {
font-weight: 500;
}
}
}
.adaptive-nav__drawer-label {
font-size: 14px;
font-weight: 400;
white-space: nowrap;
}
// ---------------------------------------------------------------------------
// Drawer slide-in animation
// ---------------------------------------------------------------------------
@keyframes slide-in-left {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
// ---------------------------------------------------------------------------
// Media Queries — Layout Switch (CUB-27 breakpoints)
// ---------------------------------------------------------------------------
// Compact (0599px): Show mobile header, hide sidebar
@media (max-width: 599px) {
.adaptive-nav__sidebar {
display: none;
}
.adaptive-nav__mobile-header {
display: flex;
}
// Hide mobile drawer and overlay on desktop
.adaptive-nav__overlay,
.adaptive-nav__mobile-drawer {
// These are conditional via @if in template, no display:none needed
}
}
// Medium (6001023px): Show collapsed sidebar (icon-only), hide mobile
@media (min-width: 600px) and (max-width: 1023px) {
.adaptive-nav__sidebar {
display: flex;
width: var(--cc-nav-rail-collapsed-width, 72px);
}
// Hide labels on medium (collapsed)
.adaptive-nav__sidebar-label,
.adaptive-nav__brand {
display: none;
}
.adaptive-nav__sidebar-header {
justify-content: center;
}
.adaptive-nav__sidebar-item {
flex-direction: column;
justify-content: center;
}
.adaptive-nav__mobile-header {
display: none;
}
.adaptive-nav__overlay,
.adaptive-nav__mobile-drawer {
display: none;
}
}
// Expanded (≥1024px): Show sidebar with labels
@media (min-width: 1024px) {
.adaptive-nav__sidebar {
display: flex;
width: var(--cc-nav-rail-collapsed-width, 72px);
transition: width 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.adaptive-nav__mobile-header {
display: none;
}
.adaptive-nav__overlay,
.adaptive-nav__mobile-drawer {
display: none;
}
}
// ---------------------------------------------------------------------------
// Accessibility: Reduced Motion
// ---------------------------------------------------------------------------
@media (prefers-reduced-motion: reduce) {
.adaptive-nav__live-dot--connected {
animation: none;
}
.adaptive-nav__mobile-drawer {
animation: none;
}
.adaptive-nav__sidebar {
transition: none;
}
}