chore: updated header 04285cc5
Steve · 2026-03-31 20:46 1 file(s) · +98 −89
packages/client/src/components/layout/Header.astro +98 −89
5 5
---
6 6
7 7
<script>
8 -
	import { toggleClass } from "@/utils";
8 +
  import { toggleClass } from "@/utils";
9 9
10 10
  class MobileNavBtn extends HTMLElement {
11 -
		constructor() {
12 -
			super();
13 -
			const headerEl = document.getElementById("main-header")!;
14 -
			const mobileButtonEl = document.getElementById("toggle-navigation-menu") as HTMLButtonElement;
15 -
			let menuOpen = false;
11 +
    constructor() {
12 +
      super();
13 +
      const headerEl = document.getElementById("main-header")!;
14 +
      const mobileButtonEl = document.getElementById(
15 +
        "toggle-navigation-menu",
16 +
      ) as HTMLButtonElement;
17 +
      let menuOpen = false;
16 18
17 -
			function toggleMobileMenu() {
18 -
				toggleClass(headerEl, "menu-open");
19 -
				menuOpen = !menuOpen;
20 -
				mobileButtonEl.setAttribute("aria-expanded", menuOpen.toString());
21 -
			}
19 +
      function toggleMobileMenu() {
20 +
        toggleClass(headerEl, "menu-open");
21 +
        menuOpen = !menuOpen;
22 +
        mobileButtonEl.setAttribute("aria-expanded", menuOpen.toString());
23 +
      }
22 24
23 -
			mobileButtonEl.addEventListener("click", toggleMobileMenu);
25 +
      mobileButtonEl.addEventListener("click", toggleMobileMenu);
24 26
25 -
			document.addEventListener("astro:after-swap", () => {
26 -
				if (menuOpen) toggleMobileMenu();
27 -
			});
28 -
		}
29 -
	}
27 +
      document.addEventListener("astro:after-swap", () => {
28 +
        if (menuOpen) toggleMobileMenu();
29 +
      });
30 +
    }
31 +
  }
30 32
31 -
	customElements.define("mobile-button", MobileNavBtn);
32 -
33 +
  customElements.define("mobile-button", MobileNavBtn);
33 34
</script>
34 35
35 -
<header id="main-header" class="group relative mb-14 sm:mb-28 flex items-center justify-between sm:pl-[4.5rem]">
36 -
	<div class="flex sm:flex-col">
37 -
		<a
38 -
			href="/"
39 -
			class="inline-flex items-center sm:relative sm:inline-block"
40 -
			aria-current={url.pathname === "/" ? "page" : false}
41 -
			data-astro-reload
42 -
      >
43 -
36 +
<header
37 +
  id="main-header"
38 +
  class="group relative mb-14 sm:mb-28 flex items-center justify-between sm:pl-[4.5rem]"
39 +
>
40 +
  <div class="flex sm:flex-col">
41 +
    <a
42 +
      href="/"
43 +
      class="inline-flex items-center sm:relative sm:inline-block"
44 +
      aria-current={url.pathname === "/" ? "page" : false}
45 +
      data-astro-reload
46 +
    >
44 47
      <svg
45 -
        class="mr-3 h-10 w-6 sm:pb-4 sm:absolute sm:left-[-4.5rem] sm:mr-0 sm:h-20 sm:w-12"
48 +
        xmlns="http://www.w3.org/2000/svg"
49 +
        class="mr-3 h-10 w-6 sm:pb-4 sm:absolute sm:left-[-4.5rem] sm:mr-0 sm:h-20 sm:w-[52px]"
46 50
        fill="none"
47 51
        stroke="currentColor"
48 52
        stroke-linecap="round"
49 53
        stroke-linejoin="round"
50 -
        stroke-width="2"
51 -
        viewBox="0 0 24 24"
52 -
        xmlns="http://www.w3.org/2000/svg"
54 +
        viewBox="0 0 256 256"
55 +
        ><!-- Icon from Phosphor by Phosphor Icons - https://github.com/phosphor-icons/core/blob/main/LICENSE -->
56 +
        <path
57 +
          fill="currentColor"
58 +
          d="M164 78a26 26 0 1 0-26-26a26 26 0 0 0 26 26m0-40a14 14 0 1 1-14 14a14 14 0 0 1 14-14m89.16 158.94l-54.56-92.08a13.9 13.9 0 0 0-12-6.86a13.88 13.88 0 0 0-12 6.86l-27.88 47.05l-46.56-79a14 14 0 0 0-24.13 0L2.83 197A6 6 0 0 0 8 206h240a6 6 0 0 0 5.16-9.06M86.27 79a2 2 0 0 1 3.46 0l25.34 43H60.93ZM18.5 194l35.36-60h68.29l19.3 32.77l16 27.2Zm152.93 0l-17.85-30.29L184.83 111a2 2 0 0 1 1.72-1a1.93 1.93 0 0 1 1.72 1l49.2 83Z"
59 +
        ></path></svg
53 60
      >
54 -
        <path d="m8 3 4 8 5-5 5 15H2L8 3z" />
55 -
      </svg>
56 61
57 -
58 -
			<span class="text-xl font-bold sm:text-2xl">Steve Simkins</span>
59 -
		</a>
60 -
		<nav
61 -
			id="navigation-menu"
62 -
			class="absolute -inset-x-4 top-14 hidden flex-col items-end gap-y-4 rounded-md bg-[color:var(--theme-menu-bg)] py-4 text-accent shadow backdrop-blur group-[.menu-open]:z-50 group-[.menu-open]:flex sm:static sm:z-auto sm:mt-1 sm:-ml-4 sm:flex sm:flex-row sm:items-center sm:divide-x sm:divide-dashed sm:divide-accent sm:rounded-none sm:bg-transparent sm:py-0 sm:shadow-none sm:backdrop-blur-none"
63 -
			aria-label="Main menu"
64 -
		>
65 -
			{
66 -
				MENU_LINKS.map((link) => (
67 -
					<a
68 -
						href={link.path}
69 -
						class="py-4 px-4 sm:py-0 sm:hover:underline"
70 -
						aria-current={url.pathname === link.path ? "page" : false}
71 -
						rel="prefetch"
72 -
					>
73 -
						{link.title}
74 -
					</a>
75 -
				))
76 -
			}
77 -
		</nav>
78 -
	</div>
62 +
      <span class="text-xl font-bold sm:text-2xl">Steve Simkins</span>
63 +
    </a>
64 +
    <nav
65 +
      id="navigation-menu"
66 +
      class="absolute -inset-x-4 top-14 hidden flex-col items-end gap-y-4 rounded-md bg-[color:var(--theme-menu-bg)] py-4 text-accent shadow backdrop-blur group-[.menu-open]:z-50 group-[.menu-open]:flex sm:static sm:z-auto sm:mt-1 sm:-ml-4 sm:flex sm:flex-row sm:items-center sm:divide-x sm:divide-dashed sm:divide-accent sm:rounded-none sm:bg-transparent sm:py-0 sm:shadow-none sm:backdrop-blur-none"
67 +
      aria-label="Main menu"
68 +
    >
69 +
      {
70 +
        MENU_LINKS.map((link) => (
71 +
          <a
72 +
            href={link.path}
73 +
            class="py-4 px-4 sm:py-0 sm:hover:underline"
74 +
            aria-current={url.pathname === link.path ? "page" : false}
75 +
            rel="prefetch"
76 +
          >
77 +
            {link.title}
78 +
          </a>
79 +
        ))
80 +
      }
81 +
    </nav>
82 +
  </div>
79 83
  <mobile-button>
80 84
    <button
81 -
        id="toggle-navigation-menu"
82 -
        class="group relative ml-8 h-7 w-7 sm:invisible sm:hidden"
83 -
        type="button"
84 -
        aria-label="Open main menu"
85 -
        aria-expanded="false"
86 -
        aria-haspopup="menu"
87 -
        >
88 -
        <svg
89 -
            id="line-svg"
90 -
            class="absolute top-1/2 left-1/2 h-full w-full -translate-x-1/2 -translate-y-1/2 transition-all group-aria-expanded:scale-0 group-aria-expanded:opacity-0"
91 -
            aria-hidden="true"
92 -
            focusable="false"
93 -
            xmlns="http://www.w3.org/2000/svg"
94 -
                   fill="none"
95 -
                         viewBox="0 0 24 24"
96 -
                                  stroke-width="1.5"
97 -
                                                stroke="currentColor"
98 -
                                                        >
99 -
                                                        <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 9h16.5m-16.5 6.75h16.5"></path>
100 -
        </svg>
85 +
      id="toggle-navigation-menu"
86 +
      class="group relative ml-8 h-7 w-7 sm:invisible sm:hidden"
87 +
      type="button"
88 +
      aria-label="Open main menu"
89 +
      aria-expanded="false"
90 +
      aria-haspopup="menu"
91 +
    >
92 +
      <svg
93 +
        id="line-svg"
94 +
        class="absolute top-1/2 left-1/2 h-full w-full -translate-x-1/2 -translate-y-1/2 transition-all group-aria-expanded:scale-0 group-aria-expanded:opacity-0"
95 +
        aria-hidden="true"
96 +
        focusable="false"
97 +
        xmlns="http://www.w3.org/2000/svg"
98 +
        fill="none"
99 +
        viewBox="0 0 24 24"
100 +
        stroke-width="1.5"
101 +
        stroke="currentColor"
102 +
      >
103 +
        <path
104 +
          stroke-linecap="round"
105 +
          stroke-linejoin="round"
106 +
          d="M3.75 9h16.5m-16.5 6.75h16.5"></path>
107 +
      </svg>
101 108
      <svg
102 -
          id="cross-svg"
103 -
          class="absolute top-1/2 left-1/2 h-full w-full -translate-x-1/2 -translate-y-1/2 scale-0 text-accent opacity-0 transition-all group-aria-expanded:scale-100 group-aria-expanded:opacity-100"
104 -
          class="text-accent"
105 -
          aria-hidden="true"
106 -
          focusable="false"
107 -
          xmlns="http://www.w3.org/2000/svg"
108 -
                 fill="none"
109 -
                       viewBox="0 0 24 24"
110 -
                                stroke-width="1.5"
111 -
                                              stroke="currentColor"
112 -
                                                      >
113 -
                                                      <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"></path>
109 +
        id="cross-svg"
110 +
        class="absolute top-1/2 left-1/2 h-full w-full -translate-x-1/2 -translate-y-1/2 scale-0 text-accent opacity-0 transition-all group-aria-expanded:scale-100 group-aria-expanded:opacity-100"
111 +
        class="text-accent"
112 +
        aria-hidden="true"
113 +
        focusable="false"
114 +
        xmlns="http://www.w3.org/2000/svg"
115 +
        fill="none"
116 +
        viewBox="0 0 24 24"
117 +
        stroke-width="1.5"
118 +
        stroke="currentColor"
119 +
      >
120 +
        <path
121 +
          stroke-linecap="round"
122 +
          stroke-linejoin="round"
123 +
          d="M6 18L18 6M6 6l12 12"></path>
114 124
      </svg>
115 125
    </button>
116 126
  </mobile-button>
117 -
118 127
</header>