A fork of pds-dash for selfhosted.social
1<script lang="ts">
2 import { page } from '$app/stores';
3
4 let menuOpen = $state(false);
5
6 function toggleMenu() {
7 menuOpen = !menuOpen;
8 }
9
10 function closeMenu() {
11 menuOpen = false;
12 }
13</script>
14
15<nav class="navbar">
16 <div class="navbar-container">
17 <a href="/" class="navbar-brand">selfhosted.social</a>
18
19 <button class="hamburger" onclick={toggleMenu} aria-label="Toggle menu">
20 <span class="hamburger-line"></span>
21 <span class="hamburger-line"></span>
22 <span class="hamburger-line"></span>
23 </button>
24
25 <div class="navbar-links" class:open={menuOpen}>
26 <a href="/info" class:active={$page.url.pathname === '/info'} onclick={closeMenu}>Info</a>
27 <a href="/legal" class:active={$page.url.pathname === '/legal'} onclick={closeMenu}>Legal</a>
28 <a href="https://pdsmoover.com/moover/selfhosted.social">Migrate</a>
29 </div>
30 </div>
31</nav>
32
33<style>
34 .navbar {
35 position: fixed;
36 top: 0;
37 left: 0;
38 right: 0;
39 width: 100%;
40 background-color: var(--header-background-color, #ffffff);
41 border-bottom: 1px solid var(--border-color, #e2e8f0);
42 padding: 1rem 2rem;
43 box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
44 z-index: 1000;
45 }
46
47 .navbar-container {
48 max-width: 1400px;
49 margin: 0 auto;
50 display: flex;
51 justify-content: space-between;
52 align-items: center;
53 position: relative;
54 }
55
56 .navbar-brand {
57 font-size: 1.5rem;
58 font-weight: bold;
59 color: var(--text-color, #111827);
60 text-decoration: none;
61 transition: opacity 0.2s;
62 flex-shrink: 0;
63 }
64
65 .navbar-brand:hover {
66 opacity: 0.8;
67 }
68
69 .hamburger {
70 display: none;
71 flex-direction: column;
72 gap: 4px;
73 background: none;
74 border: none;
75 cursor: pointer;
76 padding: 0.5rem;
77 z-index: 1001;
78 }
79
80 .hamburger-line {
81 width: 25px;
82 height: 3px;
83 background-color: var(--text-color, #111827);
84 transition: all 0.3s ease;
85 border-radius: 2px;
86 }
87
88 .navbar-links {
89 display: flex;
90 gap: 2rem;
91 align-items: center;
92 flex-wrap: wrap;
93 justify-content: flex-end;
94 }
95
96 .navbar-links a {
97 color: var(--text-color, #111827);
98 text-decoration: none;
99 font-weight: 500;
100 transition: opacity 0.2s;
101 padding: 0.5rem 0;
102 border-bottom: 2px solid transparent;
103 white-space: nowrap;
104 }
105
106 .navbar-links a:hover {
107 opacity: 0.8;
108 }
109
110 .navbar-links a.active {
111 border-bottom-color: var(--link-color, #6366f1);
112 }
113
114 @media (max-width: 1200px) {
115 .navbar-links {
116 gap: 1.5rem;
117 }
118
119 .navbar-links a {
120 font-size: 0.95rem;
121 }
122 }
123
124 @media (max-width: 1024px) {
125 .navbar {
126 padding: 1rem;
127 }
128
129 .navbar-links {
130 gap: 1rem;
131 }
132
133 .navbar-links a {
134 font-size: 0.9rem;
135 }
136 }
137
138 @media (max-width: 768px) {
139 .navbar {
140 padding: 0.75rem 1rem;
141 }
142
143 .navbar-container {
144 flex-direction: row;
145 width: 100%;
146 }
147
148 .navbar-brand {
149 font-size: 1.25rem;
150 }
151
152 .hamburger {
153 display: flex;
154 }
155
156 .navbar-links {
157 position: absolute;
158 top: 100%;
159 left: 0;
160 right: 0;
161 flex-direction: column;
162 gap: 0;
163 background-color: var(--header-background-color, #ffffff);
164 border-bottom: 1px solid var(--border-color, #e2e8f0);
165 box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
166 max-height: 0;
167 overflow: hidden;
168 transition: max-height 0.3s ease;
169 }
170
171 .navbar-links.open {
172 max-height: 500px;
173 }
174
175 .navbar-links a {
176 width: 100%;
177 padding: 1rem;
178 text-align: center;
179 border-bottom: 1px solid var(--border-color, #e2e8f0);
180 font-size: 1rem;
181 }
182
183 .navbar-links a:last-child {
184 border-bottom: none;
185 }
186
187 .navbar-links a.active {
188 border-bottom: 1px solid var(--link-color, #6366f1);
189 background-color: rgba(99, 102, 241, 0.05);
190 }
191
192 .navbar-links a.active:last-child {
193 border-bottom: none;
194 }
195 }
196
197 @media (max-width: 480px) {
198 .navbar {
199 padding: 0.5rem 0.75rem;
200 }
201
202 .navbar-brand {
203 font-size: 1.1rem;
204 }
205
206 .hamburger-line {
207 width: 22px;
208 height: 2.5px;
209 }
210 }
211</style>