diff --git a/.Net Capstone Project/sidebarv8.js b/.Net Capstone Project/sidebarv8.js
new file mode 100644
index 0000000..ca265d7
--- /dev/null
+++ b/.Net Capstone Project/sidebarv8.js
@@ -0,0 +1,126 @@
+// Single source of truth for the left navigation on EVERY page.
+//
+// Two problems this file solves:
+//
+// 1. Pages that never call renderSidebar() ā it self-initialises on
+// DOMContentLoaded, so just including the script is enough.
+//
+// 2. Pages with their own custom script that renders a DIFFERENT (shorter)
+// menu ā a MutationObserver watches the container and re-asserts the full
+// list whenever something replaces it. This is why CDS Alerts and
+// Observations were showing only 10 items while the Dashboard showed all
+// of them: those pages build their own nav after this script has run.
+//
+// Adding a nav item? Add it to SIDEBAR_ITEMS and it appears everywhere.
+
+const SIDEBAR_ITEMS = [
+ { key: 'dashboard', href: 'dashboard.html', icon: 'š ', label: 'Dashboard' },
+ { key: 'patients', href: 'patients.html', icon: 'š§\u200dāļø', label: 'Patients' },
+ { key: 'conditions', href: 'conditions.html', icon: 'š©ŗ', label: 'Conditions' },
+ { key: 'observations', href: 'observations.html', icon: 'š', label: 'Observations' },
+ { key: 'allergies', href: 'allergies.html', icon: 'ā ļø', label: 'Allergies' },
+ { key: 'medications', href: 'medications.html', icon: 'š', label: 'Medications' },
+ { key: 'encounters', href: 'encounters.html', icon: 'š
', label: 'Encounters' },
+ { key: 'organizations', href: 'organizations.html', icon: 'š„', label: 'Organizations' },
+ { key: 'locations', href: 'locations.html', icon: 'š', label: 'Locations' },
+ { key: 'practitioners', href: 'practitioners.html', icon: 'šØāāļø', label: 'Practitioners' },
+ { key: 'practitionerroles', href: 'practitionerroles.html', icon: 'š©¹', label: 'Practitioner Roles' },
+ { key: 'servicerequests', href: 'servicerequests.html', icon: 'š', label: 'Service Requests' },
+ { key: 'riskassessments', href: 'riskassessments.html', icon: 'š', label: 'Risk Assessment' },
+ { key: 'cdsalerts', href: 'cdsalerts.html', icon: 'š', label: 'CDS Alerts' },
+ { key: 'careplans', href: 'careplans.html', icon: 'š', label: 'Care Plans' },
+ { key: 'cdsrules', href: 'cdsrules.html', icon: 'āļø', label: 'CDS Rules' },
+ { key: 'users', href: 'users.html', icon: 'š¤', label: 'Users' }
+];
+
+// Pages that deliberately have no sidebar (public / auth screens).
+const SIDEBAR_EXCLUDED_PAGES = ['index.html', 'login.html', 'register.html', 'callback.html'];
+
+// Set while this script is writing to the container, so the observer below
+// doesn't react to its own changes and loop forever.
+let sidebarWriting = false;
+
+function sidebarContainer() {
+ return document.getElementById('appSidebar') || document.querySelector('.app-sidebar');
+}
+
+// Works out which item to highlight from the URL, so a page doesn't have to
+// pass its key in. An explicit key still wins when one is supplied.
+function sidebarKeyFromUrl() {
+ const file = (window.location.pathname.split('/').pop() || 'dashboard.html').toLowerCase();
+ const match = SIDEBAR_ITEMS.find(i => i.href.toLowerCase() === file);
+ return match ? match.key : '';
+}
+
+function renderSidebar(activeKey) {
+ const container = sidebarContainer();
+ if (!container) return;
+
+ const key = activeKey || sidebarKeyFromUrl();
+ const collapsed = localStorage.getItem('cip_sidebar_collapsed') === '1';
+
+ sidebarWriting = true;
+
+ container.innerHTML = `
+
+
+ `;
+
+ applySidebarState(collapsed);
+
+ document.getElementById('sidebarToggle').addEventListener('click', () => {
+ const nowCollapsed = !document.body.classList.contains('sidebar-collapsed');
+ applySidebarState(nowCollapsed);
+ localStorage.setItem('cip_sidebar_collapsed', nowCollapsed ? '1' : '0');
+ });
+
+ // Release on the next tick so the observer ignores this whole write.
+ setTimeout(() => { sidebarWriting = false; }, 0);
+}
+
+function applySidebarState(collapsed) {
+ document.body.classList.toggle('sidebar-collapsed', collapsed);
+}
+
+// Re-render if the menu ever ends up with the wrong number of links ā which
+// is what happens when a page's own script overwrites the container after
+// this one has run.
+function guardSidebar() {
+ const container = sidebarContainer();
+ if (!container) return;
+
+ new MutationObserver(() => {
+ if (sidebarWriting) return;
+ const links = container.querySelectorAll('.sidebar-link').length;
+ if (links !== SIDEBAR_ITEMS.length) renderSidebar();
+ }).observe(container, { childList: true, subtree: true });
+}
+
+function initSidebar() {
+ const file = (window.location.pathname.split('/').pop() || '').toLowerCase();
+ if (SIDEBAR_EXCLUDED_PAGES.includes(file)) return;
+
+ renderSidebar();
+ guardSidebar();
+
+ // Belt and braces for pages whose own script runs late (after images and
+ // stylesheets finish loading).
+ window.addEventListener('load', () => {
+ const container = sidebarContainer();
+ if (container && container.querySelectorAll('.sidebar-link').length !== SIDEBAR_ITEMS.length) {
+ renderSidebar();
+ }
+ });
+}
+
+if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', initSidebar);
+} else {
+ initSidebar();
+}