@for (child of section.displayChildren; track child.id) {
app-sidebar-nav-item {
+ flex: 1;
+ min-width: 0;
+ }
+
+ .sb-section__chevron {
+ flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
- width: 22px;
- height: 22px;
+ width: 20px;
+ height: 20px;
border: none;
- border-radius: 4px;
+ border-radius: 5px;
background: transparent;
color: var(--color-sidebar-text-muted);
cursor: pointer;
- opacity: 0;
- transition: opacity 0.15s, background 0.15s, color 0.15s;
- z-index: 2;
+ opacity: 0.25;
+ transition: opacity 0.2s, background 0.2s, color 0.2s, transform 0.15s;
+ margin-right: 0.25rem;
&:hover {
- background: rgba(255, 255, 255, 0.06);
- color: var(--color-sidebar-text-heading);
+ opacity: 1 !important;
+ background: rgba(245, 166, 35, 0.12);
+ color: var(--color-sidebar-active-text);
+ transform: scale(1.1);
}
&:focus-visible {
- opacity: 1;
- outline: 1px solid var(--color-sidebar-active-border);
+ opacity: 1 !important;
+ outline: 1.5px solid var(--color-sidebar-active-border);
+ outline-offset: -1.5px;
}
}
- /* Show fold button on hover or when section is folded */
- .sb-section__head:hover .sb-section__fold,
- .sb-section--folded .sb-section__fold {
- opacity: 1;
+ .sb-section__head:hover .sb-section__chevron {
+ opacity: 0.7;
}
- .sb-section__fold-icon {
- transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
+ .sb-section--folded .sb-section__chevron {
+ opacity: 0.45;
}
- .sb-section--folded .sb-section__fold-icon {
+ .sb-section__chevron-icon {
+ transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
+ }
+
+ .sb-section--folded .sb-section__chevron-icon {
transform: rotate(-90deg);
}
@@ -435,7 +502,7 @@ interface NavSectionGroup {
.sb-section__body {
display: grid;
grid-template-rows: 1fr;
- transition: grid-template-rows 0.22s cubic-bezier(0.4, 0, 0.2, 1);
+ transition: grid-template-rows 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.sb-section--folded .sb-section__body {
@@ -444,16 +511,37 @@ interface NavSectionGroup {
.sb-section__body-inner {
overflow: hidden;
- margin-left: 1.25rem;
- border-left: 1px solid rgba(245, 166, 35, 0.12);
+ margin-left: 1.375rem;
+ padding-left: 0.375rem;
+ position: relative;
+ transition: opacity 0.24s ease;
+
+ &::before {
+ content: '';
+ position: absolute;
+ left: 0;
+ top: 0.125rem;
+ bottom: 0.125rem;
+ width: 1px;
+ background: linear-gradient(
+ 180deg,
+ rgba(245, 166, 35, 0.2) 0%,
+ rgba(245, 166, 35, 0.08) 100%
+ );
+ border-radius: 1px;
+ }
+ }
+
+ .sb-section--folded .sb-section__body-inner {
+ opacity: 0;
}
/* ================================================================
- Footer with collapse toggle
+ Footer
================================================================ */
.sidebar__footer {
flex-shrink: 0;
- padding: 0.375rem 0.75rem 0.5rem;
+ padding: 0.5rem 0.625rem 0.625rem;
}
.sidebar__collapse-btn {
@@ -461,28 +549,27 @@ interface NavSectionGroup {
align-items: center;
justify-content: center;
width: 100%;
- height: 28px;
- border: 1px solid var(--color-sidebar-divider);
- border-radius: 6px;
+ height: 30px;
+ border: 1px solid rgba(255, 255, 255, 0.06);
+ border-radius: 8px;
background: transparent;
color: var(--color-sidebar-text-muted);
cursor: pointer;
- margin-bottom: 0.375rem;
- transition: color 0.15s, background 0.15s, border-color 0.15s;
+ margin-bottom: 0.5rem;
+ transition: color 0.2s, background 0.2s, border-color 0.2s;
&:hover {
- color: var(--color-sidebar-text-heading);
- background: rgba(255, 255, 255, 0.04);
- border-color: rgba(255, 255, 255, 0.12);
+ color: var(--color-sidebar-active-text);
+ background: rgba(245, 166, 35, 0.06);
+ border-color: rgba(245, 166, 35, 0.15);
}
&:focus-visible {
- outline: 1px solid var(--color-sidebar-active-border);
- outline-offset: -1px;
+ outline: 1.5px solid var(--color-sidebar-active-border);
+ outline-offset: -1.5px;
}
}
- /* Hide collapse button on mobile (mobile uses the close X) */
@media (max-width: 991px) {
.sidebar__collapse-btn {
display: none;
@@ -491,8 +578,14 @@ interface NavSectionGroup {
.sidebar__footer-divider {
height: 1px;
- background: var(--color-sidebar-divider);
- margin-bottom: 0.375rem;
+ background: linear-gradient(
+ 90deg,
+ transparent 0%,
+ var(--color-sidebar-divider) 30%,
+ var(--color-sidebar-divider) 70%,
+ transparent 100%
+ );
+ margin-bottom: 0.5rem;
}
.sidebar__version {
@@ -504,6 +597,7 @@ interface NavSectionGroup {
color: var(--color-sidebar-version);
text-align: center;
white-space: nowrap;
+ transition: font-size 0.2s, opacity 0.2s;
}
.sidebar--collapsed .sidebar__footer {
@@ -512,6 +606,7 @@ interface NavSectionGroup {
.sidebar--collapsed .sidebar__version {
font-size: 0;
+ opacity: 0;
overflow: hidden;
}
`],
diff --git a/src/Web/StellaOps.Web/src/app/layout/app-sidebar/sidebar-nav-item.component.ts b/src/Web/StellaOps.Web/src/app/layout/app-sidebar/sidebar-nav-item.component.ts
index 60d4016f9..db5416a37 100644
--- a/src/Web/StellaOps.Web/src/app/layout/app-sidebar/sidebar-nav-item.component.ts
+++ b/src/Web/StellaOps.Web/src/app/layout/app-sidebar/sidebar-nav-item.component.ts
@@ -282,26 +282,35 @@ export interface NavItem {
align-items: center;
gap: 0.625rem;
padding: 0.4375rem 0.75rem;
- margin: 0 0.25rem 1px;
+ margin: 1px 0.125rem;
color: var(--color-sidebar-text);
text-decoration: none;
font-size: 0.8125rem;
font-weight: 450;
- transition: all 0.12s;
- border-radius: 6px;
+ transition:
+ background 0.18s cubic-bezier(0.4, 0, 0.2, 1),
+ color 0.18s cubic-bezier(0.4, 0, 0.2, 1),
+ box-shadow 0.18s cubic-bezier(0.4, 0, 0.2, 1),
+ border-color 0.18s cubic-bezier(0.4, 0, 0.2, 1),
+ transform 0.12s cubic-bezier(0.4, 0, 0.2, 1);
+ border-radius: 8px;
cursor: pointer;
position: relative;
min-width: 0;
border-left: 2px solid transparent;
&:hover {
- background: var(--color-sidebar-hover);
+ background: rgba(245, 166, 35, 0.08);
color: var(--color-sidebar-text-heading);
}
+ &:active {
+ transform: scale(0.98);
+ }
+
&:focus-visible {
- outline: 2px solid var(--color-sidebar-active-border);
- outline-offset: -2px;
+ outline: 1.5px solid var(--color-sidebar-active-border);
+ outline-offset: -1.5px;
}
}
@@ -310,39 +319,75 @@ export interface NavItem {
color: var(--color-sidebar-active-text);
font-weight: 600;
border-left-color: var(--color-sidebar-active-border);
+ box-shadow:
+ 0 0 0 1px rgba(245, 166, 35, 0.08),
+ 0 1px 6px rgba(245, 166, 35, 0.06);
.nav-item__icon {
color: var(--color-sidebar-active-text);
+ opacity: 1;
}
&:hover {
background: var(--color-sidebar-active-bg);
+ box-shadow:
+ 0 0 0 1px rgba(245, 166, 35, 0.12),
+ 0 2px 10px rgba(245, 166, 35, 0.08);
}
}
.nav-item--child {
- font-size: 0.8125rem;
- border-radius: 0;
- margin: 0 0.25rem 1px;
- padding: 0.375rem 0.75rem;
+ font-size: 0.7875rem;
+ font-weight: 420;
+ border-radius: 6px;
+ margin: 1px 0.125rem;
+ padding: 0.3125rem 0.625rem;
border-left: 2px solid transparent;
.nav-item__icon {
- width: 16px;
- height: 16px;
+ width: 15px;
+ height: 15px;
+ opacity: 0.45;
svg {
- width: 14px;
- height: 14px;
+ width: 13px;
+ height: 13px;
}
}
}
+ .nav-item--child:hover {
+ background: rgba(245, 166, 35, 0.06);
+
+ .nav-item__icon {
+ opacity: 0.7;
+ }
+ }
+
.nav-item--child.nav-item--active {
- background: transparent;
+ background: rgba(245, 166, 35, 0.1);
color: var(--color-sidebar-active-text);
font-weight: 600;
border-left-color: transparent;
+ box-shadow: none;
+
+ .nav-item__icon {
+ opacity: 1;
+ color: var(--color-sidebar-active-text);
+ }
+
+ &::before {
+ content: '';
+ position: absolute;
+ left: -0.625rem;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: var(--color-sidebar-active-border);
+ box-shadow: 0 0 6px rgba(245, 166, 35, 0.3);
+ }
}
.nav-item__icon {
@@ -352,11 +397,12 @@ export interface NavItem {
justify-content: center;
width: 18px;
height: 18px;
- opacity: 0.65;
+ opacity: 0.55;
+ transition: opacity 0.18s, color 0.18s;
}
.nav-item:hover .nav-item__icon {
- opacity: 0.9;
+ opacity: 0.85;
}
.nav-item--active .nav-item__icon {
@@ -384,23 +430,39 @@ export interface NavItem {
display: flex;
align-items: center;
justify-content: center;
+ box-shadow: 0 1px 4px rgba(245, 166, 35, 0.2);
}
/* Collapsed: icon-only mode */
.nav-item--icon-only {
justify-content: center;
padding: 0.5rem;
- margin: 0 0.125rem 1px;
+ margin: 1px 0.125rem;
border-left-color: transparent;
+ border-radius: 8px;
.nav-item__icon {
- opacity: 0.8;
+ opacity: 0.7;
+ }
+
+ &:hover .nav-item__icon {
+ opacity: 1;
}
}
.nav-item--icon-only.nav-item--active {
border-left-color: transparent;
- border-radius: 6px;
+
+ &::after {
+ content: '';
+ position: absolute;
+ left: -1px;
+ top: 25%;
+ bottom: 25%;
+ width: 2px;
+ border-radius: 2px;
+ background: var(--color-sidebar-active-border);
+ }
}
`],
changeDetection: ChangeDetectionStrategy.OnPush,