···3333 </a>
3434 <!-- Navigation links -->
3535 <div class="flex items-center gap-4">
3636+ if !props.IsAuthenticated {
3737+ <div class="flex items-center gap-4">
3838+ <button
3939+ x-data
4040+ @click="$dispatch('open-login')"
4141+ class="text-sm font-semibold text-brown-100 hover:text-white transition-colors"
4242+ >
4343+ Log In
4444+ </button>
4545+ </div>
4646+ }
3647 if props.IsAuthenticated {
3748 <!-- Notification bell -->
3849 <a href="/notifications" class="relative hover:opacity-80 transition p-1" title="Notifications">
···194205 </div>
195206 </div>
196207 </nav>
208208+ if !props.IsAuthenticated {
209209+ @LoginModal()
210210+ }
211211+}
212212+213213+// LoginModal renders the login dialog for unauthenticated users
214214+templ LoginModal() {
215215+ <dialog id="login-modal" class="modal-dialog" x-data @open-login.window="$el.showModal()">
216216+ <div class="modal-content">
217217+ <div class="flex items-center justify-between mb-4">
218218+ <h3 class="modal-title mb-0">Log in with your Atmosphere account</h3>
219219+ <button
220220+ type="button"
221221+ @click="$el.closest('dialog').close()"
222222+ class="text-brown-400 hover:text-brown-600 transition-colors"
223223+ >
224224+ @IconX()
225225+ </button>
226226+ </div>
227227+ <form method="POST" action="/auth/login" class="space-y-4">
228228+ <div class="relative">
229229+ <label { "for" }="login-handle" class="block text-sm font-medium text-brown-900 mb-2">Handle</label>
230230+ <input
231231+ type="text"
232232+ id="login-handle"
233233+ name="handle"
234234+ placeholder="your-handle.bsky.social"
235235+ autocomplete="off"
236236+ required
237237+ class="w-full form-input-lg"
238238+ />
239239+ <div id="autocomplete-results" class="hidden handle-dropdown"></div>
240240+ </div>
241241+ <button
242242+ type="submit"
243243+ class="btn-primary w-full py-3 font-semibold"
244244+ >
245245+ Log In
246246+ </button>
247247+ </form>
248248+ <div class="mt-4 text-sm text-brown-600 text-center">
249249+ <a href="/join/create" class="font-medium text-brown-800 hover:text-brown-900 transition-colors hover:underline">Create an account</a>
250250+ <span class="mx-1.5 text-brown-400">·</span>
251251+ <a href="/about" class="text-brown-600 hover:text-brown-800 transition-colors hover:underline">Learn more</a>
252252+ </div>
253253+ <details class="mt-4">
254254+ <summary class="text-brown-500 text-sm cursor-pointer hover:text-brown-700 transition-colors">What's an Atmosphere account?</summary>
255255+ <p class="text-brown-600 mt-2 text-sm leading-relaxed">
256256+ One account { "for" } the entire <a href="/atproto" class="link">AT Protocol</a> ecosystem. Sign up once and use it across Arabica, <a href="https://bsky.app" class="link" target="_blank" rel="noopener noreferrer">Bluesky</a>, <a href="https://leaflet.pub" class="link" target="_blank" rel="noopener noreferrer">Leaflet</a>, and more. Your data is portable — you own it.
257257+ </p>
258258+ </details>
259259+ <script src="/static/js/handle-autocomplete.js?v=0.2.0"></script>
260260+ </div>
261261+ </dialog>
197262}
198263199264// Helper function to get profile identifier (handle or DID)
+1-1
internal/web/components/shared.templ
···287287 <details class="mt-4">
288288 <summary class="text-brown-500 text-sm cursor-pointer hover:text-brown-700 transition-colors text-center">What's an Atmosphere account?</summary>
289289 <p class="text-brown-600 mt-2 text-sm leading-relaxed">
290290- Arabica uses the <a href="/atproto" class="link">AT Protocol</a> { "for" } social features and data ownership. Your account works across compatible apps like <a href="https://bsky.app" class="link" target="_blank" rel="noopener noreferrer">Bluesky</a> and <a href="https://leaflet.pub" class="link" target="_blank" rel="noopener noreferrer">Leaflet</a>.
290290+ One account { "for" } the entire <a href="/atproto" class="link">AT Protocol</a> ecosystem. Sign up once and use it across Arabica, <a href="https://bsky.app" class="link" target="_blank" rel="noopener noreferrer">Bluesky</a>, <a href="https://leaflet.pub" class="link" target="_blank" rel="noopener noreferrer">Leaflet</a>, and more. Your data is portable — you own it.
291291 </p>
292292 </details>
293293 <script src="/static/js/handle-autocomplete.js?v=0.2.0"></script>