+
+
+
@Body
-
\ No newline at end of file
+
+
+@code {
+ private bool isShelfExpanded { get; set; } = false;
+
+ private void OnShelfStateChanged(bool newState)
+ {
+ isShelfExpanded = newState;
+
+ // This forces Blazor to re-evaluate the DOM, instantly applying
+ // the "shelf-open" and "shifted-canvas" CSS utility classes.
+ StateHasChanged();
+ }
+}
\ No newline at end of file
diff --git a/ShopAdmin/Components/Pages/NavShelf.razor b/ShopAdmin/Components/Pages/NavShelf.razor
new file mode 100644
index 0000000..2ad4566
--- /dev/null
+++ b/ShopAdmin/Components/Pages/NavShelf.razor
@@ -0,0 +1,80 @@
+@inject NavigationManager NavManager
+
+
+
+
+
+
+
+@code {
+ [Parameter] public bool IsOpen { get; set; } = false;
+ [Parameter] public EventCallback
IsOpenChanged { get; set; }
+
+ private async Task ToggleShelf()
+ {
+ IsOpen = !IsOpen;
+ await IsOpenChanged.InvokeAsync(IsOpen);
+ }
+
+ private async Task CloseShelf()
+ {
+ if (IsOpen)
+ {
+ IsOpen = false;
+ await IsOpenChanged.InvokeAsync(IsOpen);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ShopAdmin/Components/Pages/NavShelf.razor.css b/ShopAdmin/Components/Pages/NavShelf.razor.css
new file mode 100644
index 0000000..d1f6e8b
--- /dev/null
+++ b/ShopAdmin/Components/Pages/NavShelf.razor.css
@@ -0,0 +1,159 @@
+/* --- 1. The Flyout Side Panel --- */
+.nav-shelf-panel {
+ position: fixed;
+ top: var(--header-height); /* Drops clean below your top-bar */
+ right: -300px; /* Hidden by default */
+ width: 300px;
+ height: calc(100vh - var(--header-height));
+ background-color: var(--shelf-bg);
+ border-left: 1px solid rgba(144, 224, 239, 0.15);
+ z-index: 2000;
+ display: flex;
+ flex-direction: column;
+ padding: 2rem 1.5rem;
+ box-sizing: border-box;
+ transition: right 0.35s cubic-bezier(0.16, 1, 0.3, 1);
+ box-shadow: -15px 0 40px rgba(0, 0, 0, 0.6);
+}
+
+ .nav-shelf-panel.shelf-open {
+ right: 0; /* Animate into viewport */
+ }
+
+/* --- 2. The Floating Mechanical Grip Handle --- */
+.shelf-grip {
+ position: fixed;
+ top: calc(var(--header-height) + 24px);
+ right: 0;
+ width: 44px;
+ height: 44px;
+ background-color: var(--shelf-bg);
+ border: 1px solid var(--border-mid-opacity);
+ border-right: none;
+ border-radius: 8px 0 0 8px;
+ color: var(--payoff-color);
+ cursor: pointer;
+ z-index: 2001;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: right 0.35s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.2s ease;
+}
+
+ /* Moves out dynamically alongside the shelf edge when open */
+ .shelf-grip.grip-open {
+ right: 300px;
+ background-color: var(--shelf-bg);
+ border-color: var(--border-low-opacity);
+ }
+
+ .shelf-grip:hover {
+ background-color: #112930;
+ color: var(--text-white);
+ }
+
+.grip-icon {
+ width: 20px;
+ height: 20px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+/* --- 3. Panel Internal Layout & Links --- */
+.shelf-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 2rem;
+ padding-bottom: 1rem;
+ border-bottom: 1px solid rgba(144, 224, 239, 0.1);
+}
+
+ .shelf-header h3 {
+ font-size: 1.1rem;
+ font-weight: 700;
+ color: var(--text-white);
+ margin: 0;
+ }
+
+.environment-badge {
+ font-size: 0.65rem;
+ font-family: monospace;
+ font-weight: bold;
+ padding: 2px 6px;
+ background: rgba(0, 150, 199, 0.15);
+ border: 1px solid rgba(0, 150, 199, 0.4);
+ color: var(--payoff-color);
+ border-radius: 4px;
+}
+
+.shelf-navigation {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+/* Deep selection matching Blazor's active class matching system */
+::deep .shelf-link {
+ display: flex;
+ align-items: center;
+ gap: 14px;
+ color: rgba(255, 255, 255, 0.65);
+ text-decoration: none;
+ padding: 12px 16px;
+ font-size: 0.95rem;
+ font-weight: 500;
+ border-radius: 6px;
+ transition: all 0.2s ease;
+}
+
+ ::deep .shelf-link:hover {
+ background-color: rgba(0, 150, 199, 0.08);
+ color: var(--text-white);
+ }
+
+ ::deep .shelf-link.active {
+ background-color: var(--brand-blue);
+ color: var(--text-white);
+ font-weight: 600;
+ }
+
+.link-icon {
+ width: 18px;
+ height: 18px;
+ opacity: 0.8;
+}
+
+.icon-warn {
+ color: var(--payoff-color);
+}
+
+.shelf-divider {
+ height: 1px;
+ background: rgba(144, 224, 239, 0.1);
+ margin: 1rem 0;
+}
+
+/* --- 4. Content Blur/Backdrop Overlay --- */
+.shelf-backdrop {
+ position: fixed;
+ top: var(--header-height);
+ left: 0;
+ width: 100vw;
+ height: calc(100vh - var(--header-height));
+ background-color: rgba(0, 0, 0, 0.25);
+ backdrop-filter: blur(0px);
+ z-index: 1999;
+ opacity: 0;
+ visibility: hidden;
+ pointer-events: none;
+ transition: opacity 0.3s ease, backdrop-filter 0.3s ease;
+}
+
+ .shelf-backdrop.backdrop-active {
+ opacity: 1;
+ visibility: visible;
+ pointer-events: auto;
+ backdrop-filter: blur(3px);
+ }
diff --git a/ShopAdmin/Components/_Imports.razor b/ShopAdmin/Components/_Imports.razor
index 5fd3442..6e2128b 100644
--- a/ShopAdmin/Components/_Imports.razor
+++ b/ShopAdmin/Components/_Imports.razor
@@ -9,3 +9,4 @@
@using ShopAdmin
@using ShopAdmin.Components
@using ShopAdmin.Components.Layout
+@using ShopAdmin.Components.Pages
diff --git a/ShopAdmin/wwwroot/app.css b/ShopAdmin/wwwroot/app.css
index c5fdd03..5944cd6 100644
--- a/ShopAdmin/wwwroot/app.css
+++ b/ShopAdmin/wwwroot/app.css
@@ -1,10 +1,21 @@
/* --- 1. Variables & Global Reset --- */
:root {
- --bar-bg: #001219;
- --text-white: #ffffff;
+ /* --- BRAND CORES --- */
--brand-blue: #0096c7;
- --hover-blue: #00b4d8;
+ --hover-blue: #4dabff;
+ /* --- NEW CANVAS BALANCE --- */
+ /* Lighter, slate-tinted midnight for the main workspace body */
+ --body-bg: #0b1519;
+ /* Deep obsidian for the fixed navigation anchors */
+ --bar-bg: #03090b;
+ /* The NavShelf background: sits right between the bar and body */
+ --shelf-bg: #070e10;
+ /* --- TYPOGRAPHY & LINES --- */
+ --text-white: #f8f9fa;
+ /* Soft cyan-gray tone for secondary text and structural borders */
--payoff-color: #90e0ef;
+ --border-low-opacity: rgba(144, 224, 239, 0.08);
+ --border-mid-opacity: rgba(144, 224, 239, 0.18);
--header-height: 92px;
}
@@ -31,7 +42,7 @@ html, body {
display: flex;
align-items: center;
justify-content: space-between;
- padding: 0 4rem;
+ padding: 0 4rem 0 1rem;
z-index: 1000;
border-bottom: 1px solid rgba(144, 224, 239, 0.15);
}
@@ -93,6 +104,8 @@ html, body {
padding-top: var(--header-height);
box-sizing: border-box;
background-color: var(--bar-bg);
+ position: relative;
+ transition: padding-right 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}
main {
@@ -100,6 +113,7 @@ main {
display: flex;
flex-direction: column;
width: 100%;
+ background-color: var(--body-bg) !important;
}
/* --- Responsive Logic --- */