diff --git a/Data/Engine/web-interface/src/Admin/Page_Template.jsx b/Data/Engine/web-interface/src/Admin/Page_Template.jsx
new file mode 100644
index 00000000..fc2308e6
--- /dev/null
+++ b/Data/Engine/web-interface/src/Admin/Page_Template.jsx
@@ -0,0 +1,302 @@
+import React, { useMemo, useRef } from "react";
+import {
+ Paper,
+ Box,
+ Typography,
+ Button,
+ IconButton,
+ Stack,
+ Tooltip,
+} from "@mui/material";
+import {
+ Dashboard as TemplateIcon,
+ Cached as RefreshIcon,
+ Add as AddIcon,
+ Tune as TuneIcon,
+} from "@mui/icons-material";
+import { AgGridReact } from "ag-grid-react";
+import { ModuleRegistry, AllCommunityModule, themeQuartz } from "ag-grid-community";
+
+/**
+ * ============================================================================
+ * Borealis MagicUI — Page Template
+ * ---------------------------------------------------------------------------
+ * PURPOSE
+ * • A *visual-only* reference for building Borealis pages.
+ * • NO API calls, NO business logic. Everything is placeholder/demo.
+ * • Use this as a baseline for new pages to ensure perfect visual parity.
+ *
+ * WHAT THIS TEMPLATE SHOWS
+ * 1) Full-bleed gradient shell using the Borealis Aurora pattern.
+ * 2) Page header with Material icon to the LEFT of the title.
+ * 3) Subtitle directly beneath the title.
+ * 4) Top-right utility buttons (e.g., Refresh).
+ * 5) AG Grid using the Quartz theme with rounded corners, sorting, filtering,
+ * pagination, and example data/columns.
+ * 6) Gradient buttons consistent with MagicUI accents.
+ *
+ * DOs
+ * ✓ Keep pages full-bleed to their parent container (no gutters on the Paper).
+ * ✓ Use the same Aurora gradient shell across pages.
+ * ✓ Use IBM Plex Sans for a consistent typographic tone.
+ * ✓ Keep header icon SMALL (around 20–24px) and aligned with the title baseline.
+ * ✓ Put a concise subtitle under the page title to orient the user.
+ * ✓ Prefer rounded corners (8px) for grid chrome and panels.
+ * ✓ Use AG Grid Quartz theme and scope theme CSS vars on the wrapper.
+ * ✓ Use gradient-filled primary buttons for key actions.
+ *
+ * DON'Ts
+ * ✗ Do not introduce API/data fetching in this template (copy into real pages).
+ * ✗ Do not change global AG Grid CSS (keep theme-scoped).
+ * ✗ Do not mix multiple font families; stick to IBM Plex Sans.
+ * ✗ Do not leave empty margins around the page shell.
+ * ✗ Do not hardcode fixed heights unless absolutely necessary.
+ *
+ * HOW TO ADAPT THIS TEMPLATE
+ * • Replace the static sample rows/columns with your real grid model.
+ * • Wire the Refresh button to your data loader (keep the icon + placement).
+ * • Keep the theme params/vars to maintain cross-page visual cohesion.
+ *
+ * REFERENCES
+ * • See other pages for style parity (aurora shell, Quartz theme usage,
+ * rounded grid edges, and gradient buttons).
+ * ============================================================================
+ */
+
+// -----------------------------------------------------------------------------
+// AG Grid module registration (community only, consistent with other pages)
+// -----------------------------------------------------------------------------
+ModuleRegistry.registerModules([AllCommunityModule]);
+
+// -----------------------------------------------------------------------------
+// MagicUI x Quartz Theme
+// Keep these params consistent across pages for color/typography parity.
+// -----------------------------------------------------------------------------
+const gridTheme = themeQuartz.withParams({
+ accentColor: "#8b5cf6", // Indigo/Violet accent (matches MagicUI)
+ backgroundColor: "#070b1a", // Deep navy panel background
+ browserColorScheme: "dark",
+ fontFamily: { googleFont: "IBM Plex Sans" },
+ foregroundColor: "#f4f7ff",
+ headerFontSize: 13,
+});
+const themeClassName = gridTheme.themeName || "ag-theme-quartz";
+
+// -----------------------------------------------------------------------------
+/** Aurora gradient shell colors — identical across pages for cohesion. */
+// -----------------------------------------------------------------------------
+const AURORA_SHELL = {
+ background:
+ "radial-gradient(120% 120% at 0% 0%, rgba(76, 186, 255, 0.16), transparent 55%), " +
+ "radial-gradient(120% 120% at 100% 0%, rgba(214, 130, 255, 0.18), transparent 60%), #040711",
+ text: "#e2e8f0",
+ subtext: "#9ba3b4",
+ accent: "#7dd3fc",
+};
+
+// -----------------------------------------------------------------------------
+// Gradient button style — use for primary CTAs to feel 'alive' and branded.
+// -----------------------------------------------------------------------------
+const gradientButtonSx = {
+ backgroundImage: "linear-gradient(135deg,#7dd3fc,#c084fc)",
+ color: "#0b1220",
+ borderRadius: 999,
+ textTransform: "none",
+ boxShadow: "0 10px 26px rgba(124,58,237,0.28)",
+ "&:hover": {
+ backgroundImage: "linear-gradient(135deg,#86e1ff,#d1a6ff)",
+ boxShadow: "0 12px 34px rgba(124,58,237,0.38)",
+ filter: "none",
+ },
+};
+
+// -----------------------------------------------------------------------------
+// Example grid data — placeholder only. Replace with real rows on real pages.
+// -----------------------------------------------------------------------------
+const SAMPLE_ROWS = [
+ { id: "ROW-001", category: "Example", name: "Gemini Borealis", owner: "alice", updated: "2025-06-12 10:32" },
+ { id: "ROW-002", category: "Demo", name: "Aurora Runner", owner: "bob", updated: "2025-07-01 14:05" },
+ { id: "ROW-003", category: "Sample", name: "Quartz Tables", owner: "carol", updated: "2025-08-20 09:18" },
+ { id: "ROW-004", category: "Guide", name: "MagicUI Rules", owner: "dave", updated: "2025-09-03 16:41" },
+ { id: "ROW-005", category: "Pattern", name: "Borealis Blue", owner: "erin", updated: "2025-10-11 08:27" },
+];
+
+// -----------------------------------------------------------------------------
+// Column definitions — keep sorting/filtering enabled; rounded edges come from
+// the theme vars on the wrapper element below.
+// -----------------------------------------------------------------------------
+const sampleColumnDefs = [
+ { headerName: "ID", field: "id", minWidth: 140, sortable: true, filter: "agTextColumnFilter" },
+ { headerName: "Category", field: "category", minWidth: 140, sortable: true, filter: "agTextColumnFilter" },
+ { headerName: "Name", field: "name", minWidth: 220, sortable: true, filter: "agTextColumnFilter" },
+ { headerName: "Owner", field: "owner", minWidth: 140, sortable: true, filter: "agTextColumnFilter" },
+ { headerName: "Updated", field: "updated", minWidth: 180, sortable: true, filter: "agTextColumnFilter" },
+];
+
+const defaultColDef = {
+ sortable: true,
+ filter: "agTextColumnFilter",
+ resizable: true,
+ minWidth: 140,
+};
+
+const gridFontFamily = "'IBM Plex Sans','Helvetica Neue',Arial,sans-serif";
+const iconFontFamily = "'Quartz Regular'";
+
+// -----------------------------------------------------------------------------
+// Page Template Component
+// -----------------------------------------------------------------------------
+export default function PageTemplate() {
+ const gridRef = useRef(null);
+
+ // NOTE: No data fetching, no side effects — this is a pure visual template.
+ const columnDefs = useMemo(() => sampleColumnDefs, []);
+
+ const handleRefresh = () => {
+ // In real pages, call your data loader. Here we do nothing (visual only).
+ // Keeping the icon + placement ensures consistent muscle memory.
+ // eslint-disable-next-line no-console
+ console.log("Refresh clicked (template; no-op).");
+ };
+
+ return (
+
+ {/* Page header */}
+
+
+
+
+ Page Template
+
+
+ {/* Top-right controls: keep order + sizes consistent project-wide */}
+
+
+
+
+
+
+
+
+
+
+ } sx={gradientButtonSx}>
+ New Item
+
+
+
+
+
+ }
+ sx={{
+ borderColor: "rgba(148,163,184,0.35)",
+ color: "#e2e8f0",
+ textTransform: "none",
+ borderRadius: 999,
+ "&:hover": { borderColor: "rgba(148,163,184,0.55)" },
+ }}
+ >
+ Settings
+
+
+
+
+
+
+ {/* Subtitle directly under title */}
+
+ Page Styling Guide and Template - Use as a baseline when designing new pages.
+
+
+
+ {/* Content area — the grid lives in a chromeless card that still keeps rounded corners */}
+
+
+
+
+
+
+ );
+}
diff --git a/Data/Engine/web-interface/src/App.jsx b/Data/Engine/web-interface/src/App.jsx
index dceb4bdb..c677e6ce 100644
--- a/Data/Engine/web-interface/src/App.jsx
+++ b/Data/Engine/web-interface/src/App.jsx
@@ -46,6 +46,7 @@ import CredentialList from "./Access_Management/Credential_List.jsx";
import UserManagement from "./Access_Management/Users.jsx";
import GithubAPIToken from "./Access_Management/Github_API_Token.jsx";
import ServerInfo from "./Admin/Server_Info.jsx";
+import PageTemplate from "./Admin/Page_Template.jsx";
import EnrollmentCodes from "./Devices/Enrollment_Codes.jsx";
import DeviceApprovals from "./Devices/Device_Approvals.jsx";
@@ -224,6 +225,8 @@ const LOCAL_STORAGE_KEY = "borealis_persistent_state";
return "/access_management/users";
case "server_info":
return "/admin/server_info";
+ case "page_template":
+ return "/admin/page_template";
case "admin_enrollment_codes":
return "/admin/enrollment-codes";
case "admin_device_approvals":
@@ -279,6 +282,7 @@ const LOCAL_STORAGE_KEY = "borealis_persistent_state";
if (path === "/access_management/github_token") return { page: "access_github_token", options: {} };
if (path === "/access_management/credentials") return { page: "access_credentials", options: {} };
if (path === "/admin/server_info") return { page: "server_info", options: {} };
+ if (path === "/admin/page_template") return { page: "page_template", options: {} };
if (path === "/admin/enrollment-codes") return { page: "admin_enrollment_codes", options: {} };
if (path === "/admin/device-approvals") return { page: "admin_device_approvals", options: {} };
return { page: "devices", options: {} };
@@ -458,6 +462,10 @@ const LOCAL_STORAGE_KEY = "borealis_persistent_state";
items.push({ label: "Admin Settings" });
items.push({ label: "Server Info", page: "server_info" });
break;
+ case "page_template":
+ items.push({ label: "Developer Tools" });
+ items.push({ label: "Page Template", page: "page_template" });
+ break;
case "admin_enrollment_codes":
items.push({ label: "Admin Settings", page: "server_info" });
items.push({ label: "Installer Codes", page: "admin_enrollment_codes" });
@@ -998,7 +1006,8 @@ const LOCAL_STORAGE_KEY = "borealis_persistent_state";
|| currentPage === 'access_users'
|| currentPage === 'ssh_devices'
|| currentPage === 'winrm_devices'
- || currentPage === 'agent_devices';
+ || currentPage === 'agent_devices'
+ || currentPage === 'page_template';
if (!isAdmin && requiresAdmin) {
setNotAuthorizedOpen(true);
navigateTo('devices', { replace: true, suppressPending: true });
@@ -1124,6 +1133,9 @@ const LOCAL_STORAGE_KEY = "borealis_persistent_state";
case "server_info":
return ;
+ case "page_template":
+ return ;
+
case "admin_enrollment_codes":
return ;
diff --git a/Data/Engine/web-interface/src/Navigation_Sidebar.jsx b/Data/Engine/web-interface/src/Navigation_Sidebar.jsx
index 5103c6a5..7bde2d1b 100644
--- a/Data/Engine/web-interface/src/Navigation_Sidebar.jsx
+++ b/Data/Engine/web-interface/src/Navigation_Sidebar.jsx
@@ -25,6 +25,7 @@ import {
PersonOutline as UserIcon,
GitHub as GitHubIcon,
Key as KeyIcon,
+ Dashboard as PageTemplateIcon,
AdminPanelSettings as AdminPanelSettingsIcon,
} from "@mui/icons-material";
@@ -68,7 +69,7 @@ function NavigationSidebar({ currentPage, onNavigate, isAdmin = false }) {
"access_users",
"access_github_token",
].includes(currentPage),
- admin: ["server_info"].includes(currentPage),
+ admin: ["server_info", "page_template"].includes(currentPage),
}),
[currentPage]
);
@@ -285,6 +286,11 @@ function NavigationSidebar({ currentPage, onNavigate, isAdmin = false }) {
label="Server Info"
pageKey="server_info"
/>
+ }
+ label="Page Template"
+ pageKey="page_template"
+ />
)}