aboutsummaryrefslogtreecommitdiff
path: root/src/components/NavBar.svelte
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/NavBar.svelte')
-rw-r--r--src/components/NavBar.svelte306
1 files changed, 273 insertions, 33 deletions
diff --git a/src/components/NavBar.svelte b/src/components/NavBar.svelte
index 44118ba..2b64c88 100644
--- a/src/components/NavBar.svelte
+++ b/src/components/NavBar.svelte
@@ -1,34 +1,274 @@
-<nav class="navbar navbar-expand-md navbar-dark bg-dark">
- <div class="container">
- <a href="/" class="navbar-brand abs">
- <img height="100" src="/logo.png" alt="Misty Mountains Therapy"/>
- </a>
- <button class="navbar-toggler ms-auto" type="button" data-bs-toggle="collapse" data-bs-target="#toggle">
- <span class="navbar-toggler-icon"></span>
- </button>
- <div class="navbar-collapse collapse" id="toggle">
- <ul class="navbar-nav ">
- <li class="nav-item active">
- <a class="nav-link" href="/">Home</a>
- </li>
- <li class="nav-item active">
- <a class="nav-link" href="/team">Our Team</a>
- </li>
- <li class="nav-item active">
- <a class="nav-link" href="/services">Services</a>
- </li>
- <li class="nav-item active">
- <a class="nav-link" href="/approach">Approach</a>
- </li>
- <li class="nav-item active">
- <a class="nav-link" href="https://joni-hunt.clientsecure.me/" target="_blank">Portal</a>
- </li>
- </ul>
- <ul class="navbar-nav ms-auto">
- <li class="nav-item">
- <a class="btn btn-primary" href="/contact">Contact Us</a>
- </li>
- </ul>
- </div>
- </div>
+<script>
+ import { resolveRoute } from '$app/paths';
+ import { page } from '$app/stores';
+
+ let menuOpen = false;
+ const menuId = 'primary-navigation';
+ let menuEl;
+ let toggleEl;
+
+ const navLinks = [
+ { href: '/', label: 'Home' },
+ { href: '/team', label: 'Team' },
+ { href: '/services', label: 'Services' },
+ { href: '/approach', label: 'Approach' }
+ ];
+
+ function isActive(path, currentPath) {
+ if (path === '/') return currentPath === '/';
+ return currentPath.startsWith(path);
+ }
+
+ function onWindowPointerDown(event) {
+ if (!menuOpen) return;
+ const target = event.target;
+ if (menuEl?.contains(target) || toggleEl?.contains(target)) return;
+ closeMenu();
+ }
+
+ function toggleMenu() {
+ menuOpen = !menuOpen;
+ }
+
+ function closeMenu() {
+ menuOpen = false;
+ }
+
+ function onNavKeydown(event) {
+ if (event.key === 'Escape') {
+ menuOpen = false;
+ }
+ }
+</script>
+
+<svelte:window on:keydown={onNavKeydown} on:pointerdown={onWindowPointerDown} />
+
+{#if menuOpen}
+ <div class="site-nav__backdrop" aria-hidden="true" on:click={closeMenu}></div>
+{/if}
+
+<nav class="site-nav" aria-label="Primary">
+ <div class="container site-nav__inner">
+ <a class="site-nav__brand" href={resolveRoute('/')} on:click={closeMenu}>
+ <img class="site-nav__logo" height="64" src="/logo.png" alt="Misty Mountains Therapy" />
+ <span class="visually-hidden">Misty Mountains Therapy</span>
+ </a>
+
+ <button
+ bind:this={toggleEl}
+ class="site-nav__toggle"
+ type="button"
+ aria-expanded={menuOpen}
+ aria-controls={menuId}
+ on:click={toggleMenu}
+ >
+ <span class="visually-hidden">{menuOpen ? 'Close menu' : 'Open menu'}</span>
+ <i class={'bi ' + (menuOpen ? 'bi-x-lg' : 'bi-list')} aria-hidden="true"></i>
+ </button>
+
+ <div bind:this={menuEl} id={menuId} class="site-nav__menu" class:site-nav__menuOpen={menuOpen}>
+ <ul class="site-nav__links">
+ {#each navLinks as link (link.href)}
+ <li>
+ <a
+ class="site-nav__link"
+ class:site-nav__link--active={isActive(link.href, $page.url.pathname)}
+ href={resolveRoute(link.href)}
+ aria-current={isActive(link.href, $page.url.pathname) ? 'page' : undefined}
+ on:click={closeMenu}
+ >
+ {link.label}
+ </a>
+ </li>
+ {/each}
+ <li>
+ <a
+ class="site-nav__link"
+ href="https://joni-hunt.clientsecure.me/"
+ target="_blank"
+ rel="noopener noreferrer"
+ on:click={closeMenu}
+ >
+ Portal
+ <i class="bi bi-box-arrow-up-right" aria-hidden="true"></i>
+ </a>
+ </li>
+ </ul>
+
+ <div class="site-nav__cta">
+ <a class="button button--primary" href={resolveRoute('/contact')} on:click={closeMenu}>Contact Us</a>
+ </div>
+ </div>
+ </div>
</nav>
+
+<style>
+ .site-nav {
+ position: sticky;
+ top: 0;
+ z-index: 70;
+ background: rgba(247, 247, 243, 0.86);
+ backdrop-filter: blur(10px);
+ border-bottom: 1px solid var(--color-border);
+ }
+
+ .site-nav__inner {
+ position: relative;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: var(--space-4);
+ padding-block: var(--space-3);
+ }
+
+ .site-nav__brand {
+ display: inline-flex;
+ align-items: center;
+ gap: var(--space-3);
+ text-decoration: none;
+ }
+
+ .site-nav__logo {
+ display: block;
+ width: auto;
+ height: 64px;
+ }
+
+ .site-nav__toggle {
+ margin-left: auto;
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-pill);
+ background: transparent;
+ padding: 0.75rem 0.9rem;
+ cursor: pointer;
+ line-height: 1;
+ }
+
+ .site-nav__toggle:hover {
+ border-color: var(--color-accent);
+ }
+
+ .site-nav__toggle i {
+ font-size: 1.25rem;
+ }
+
+ .site-nav__backdrop {
+ position: fixed;
+ inset: 0;
+ background: rgba(16, 20, 19, 0.32);
+ backdrop-filter: blur(2px);
+ z-index: 40;
+ }
+
+ .site-nav__menu {
+ z-index: 60;
+ position: absolute;
+ top: calc(100% + var(--space-2));
+ left: 0;
+ right: 0;
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4);
+ padding: var(--space-3);
+ border: 1px solid var(--color-border);
+ border-radius: var(--radius-sm);
+ background: rgba(247, 247, 243, 0.95);
+ box-shadow: var(--shadow-sm);
+
+ transform: translateX(0.75rem);
+ opacity: 0;
+ max-height: 0;
+ overflow: hidden;
+ pointer-events: none;
+ transition:
+ transform 180ms ease,
+ opacity 180ms ease,
+ max-height 240ms ease;
+ }
+
+ .site-nav__menuOpen {
+ transform: translateX(0);
+ opacity: 1;
+ max-height: 70vh;
+ pointer-events: auto;
+ }
+
+ .site-nav__links {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2);
+ }
+
+ .site-nav__link {
+ position: relative;
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ text-decoration: none;
+ padding: 0.75rem 0.9rem;
+ border-radius: var(--radius-pill);
+ font-weight: 600;
+ transition: background 150ms ease, color 150ms ease;
+ }
+
+ .site-nav__link:hover {
+ background: color-mix(in srgb, var(--color-accent) 12%, transparent);
+ }
+
+ .site-nav__link--active {
+ background: color-mix(in srgb, var(--color-accent) 15%, transparent);
+ color: var(--color-accent-strong);
+ }
+
+ .site-nav__link--active:hover {
+ background: color-mix(in srgb, var(--color-accent) 20%, transparent);
+ }
+
+ .site-nav__cta {
+ display: flex;
+ }
+
+ @media (min-width: 768px) {
+ .site-nav__toggle {
+ display: none;
+ }
+
+ .site-nav__backdrop {
+ display: none;
+ }
+
+ .site-nav__menu {
+ z-index: auto;
+ position: static;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: flex-end;
+ gap: var(--space-4);
+ margin-top: 0;
+ padding: 0;
+ border: 0;
+ border-radius: 0;
+ background: transparent;
+ box-shadow: none;
+ width: auto;
+ margin-left: auto;
+
+ transform: none;
+ opacity: 1;
+ max-height: none;
+ overflow: visible;
+ pointer-events: auto;
+ transition: none;
+ }
+
+ .site-nav__links {
+ flex-direction: row;
+ align-items: center;
+ }
+ }
+</style>