annot.at is a service for syncing static websites, such as blogs, to atproto and standard.site annot.at
elixir atproto standardsite
3

Configure Feed

Select the types of activity you want to include in your feed.

Add mobile menu

Feeling a big saturated with tailwind classes but it's ok I guess

Johanna Larsson (Jun 21, 2026, 10:05 PM +0100) a52b7e1d c08fac72

+78 -22
+63 -13
lib/annot_at_web/components/layouts.ex
··· 5 5 """ 6 6 use AnnotAtWeb, :html 7 7 8 + alias Phoenix.LiveView.JS 9 + 8 10 # Embed all files in layouts/* within this module. 9 11 # The default root.html.heex file contains the HTML 10 12 # skeleton of your application, namely HTML headers ··· 53 55 54 56 def dashboard(assigns) do 55 57 ~H""" 56 - <div class="flex min-h-screen bg-paper text-ink"> 57 - <aside class="flex w-60 flex-none flex-col border-r-2 border-ink p-4"> 58 - <.link 59 - navigate={~p"/dashboard"} 60 - class="px-3 py-2 font-display text-xl font-bold tracking-tight" 61 - > 58 + <div class="min-h-screen bg-paper text-ink lg:flex"> 59 + <div class="flex items-center justify-between border-b-2 border-ink p-4 60 + lg:hidden"> 61 + <.link navigate={~p"/dashboard"} class="font-display text-xl font-bold 62 + tracking-tight"> 62 63 annot.at 63 64 </.link> 65 + <button 66 + phx-click={toggle_sidebar()} 67 + class="grid size-10 place-items-center rounded-xl border-2 border-ink 68 + bg-paper transition-all active:scale-95" 69 + aria-label="Open menu" 70 + > 71 + <.icon name="hero-bars-3" class="size-6" /> 72 + </button> 73 + </div> 74 + 75 + <div 76 + id="sidebar-backdrop" 77 + phx-click={toggle_sidebar()} 78 + class="fixed inset-0 z-40 hidden bg-ink/40 lg:hidden" 79 + /> 80 + 81 + <aside 82 + id="sidebar" 83 + class="fixed inset-y-0 left-0 z-50 flex w-60 -translate-x-full flex-col 84 + border-r-2 border-ink bg-paper p-4 transition-transform duration-200 lg:static 85 + lg:z-auto lg:translate-x-0" 86 + > 87 + <div class="flex items-center justify-between"> 88 + <.link 89 + navigate={~p"/dashboard"} 90 + class="px-3 py-2 font-display text-xl font-bold tracking-tight" 91 + > 92 + annot.at 93 + </.link> 94 + <button 95 + phx-click={toggle_sidebar()} 96 + class="grid size-9 place-items-center rounded-lg border-2 border-ink 97 + lg:hidden" 98 + aria-label="Close menu" 99 + > 100 + <.icon name="hero-x-mark" class="size-5" /> 101 + </button> 102 + </div> 64 103 65 104 <nav class="mt-4 flex flex-col gap-1"> 66 105 <.dash_nav_item ··· 71 110 Overview 72 111 </.dash_nav_item> 73 112 74 - <div class="px-3 pt-5 pb-1.5 text-[11px] font-bold uppercase tracking-widest text-ink/40"> 113 + <div class="px-3 pt-5 pb-1.5 text-[11px] font-bold uppercase 114 + tracking-widest text-ink/40"> 75 115 Publish 76 116 </div> 77 117 <.dash_nav_item icon="hero-globe-alt" navigate={~p"/sites"} active={@active == :sites}> ··· 79 119 </.dash_nav_item> 80 120 <.dash_nav_item icon="hero-document-text">Posts</.dash_nav_item> 81 121 82 - <div class="px-3 pt-5 pb-1.5 text-[11px] font-bold uppercase tracking-widest text-ink/40"> 122 + <div class="px-3 pt-5 pb-1.5 text-[11px] font-bold uppercase 123 + tracking-widest text-ink/40"> 83 124 Account 84 125 </div> 85 126 <.dash_nav_item icon="hero-cog-6-tooth">Settings</.dash_nav_item> ··· 95 136 /> 96 137 <div 97 138 :if={!@current_scope.user.avatar_url} 98 - class="size-9 flex-none rounded-full border-2 border-ink bg-gradient-to-br from-sky-bold to-peach-bold" 139 + class="size-9 flex-none rounded-full border-2 border-ink 140 + bg-gradient-to-br from-sky-bold to-peach-bold" 99 141 /> 100 142 <div class="min-w-0"> 101 143 <div class="truncate text-sm font-bold leading-tight"> 102 144 {@current_scope.user.display_name || @current_scope.user.handle} 103 145 </div> 104 - <div class="truncate text-xs text-ink/55">{"@" <> @current_scope.user.handle}</div> 146 + <div class="truncate text-xs text-ink/55"> 147 + {"@" <> 148 + @current_scope.user.handle} 149 + </div> 105 150 </div> 106 151 </div> 107 152 <.link 108 153 href={~p"/logout"} 109 154 method="delete" 110 - class="block px-3 py-1.5 text-[11px] font-bold uppercase tracking-widest text-ink/45 hover:text-ink" 155 + class="block px-3 py-1.5 text-[11px] font-bold uppercase 156 + tracking-widest text-ink/45 hover:text-ink" 111 157 > 112 158 Sign out 113 159 </.link> ··· 118 164 {render_slot(@inner_block)} 119 165 </main> 120 166 </div> 121 - 122 - <.flash_group flash={@flash} /> 123 167 """ 168 + end 169 + 170 + defp toggle_sidebar(js \\ %JS{}) do 171 + js 172 + |> JS.toggle_class("-translate-x-full", to: "#sidebar") 173 + |> JS.toggle(to: "#sidebar-backdrop") 124 174 end 125 175 126 176 attr :icon, :string, required: true
+15 -9
lib/annot_at_web/controllers/live/dashboard_live.ex
··· 9 9 def render(assigns) do 10 10 ~H""" 11 11 <Layouts.dashboard flash={@flash} current_scope={@current_scope} active={:overview}> 12 - <div class="flex justify-end"> 12 + <div class="flex flex-col gap-4 sm:flex-row sm:items-center 13 + sm:justify-between"> 14 + <div> 15 + <h1 class="font-display text-3xl font-bold tracking-tight 16 + sm:text-4xl"> 17 + Hi {@current_scope.user.display_name || @current_scope.user.handle} 18 + </h1> 19 + <p class="mt-2 text-ink/60">Here's what you're publishing to the 20 + ATmosphere.</p> 21 + </div> 13 22 <.link 14 23 navigate={~p"/sites/new"} 15 - class="mt-5 inline-flex items-center gap-1.5 rounded-xl bg-ink px-5 py-2.5 text-sm font-bold text-paper transition-all hover:scale-[1.02] active:scale-[0.98]" 24 + class="inline-flex items-center gap-1.5 self-start rounded-xl border-2 25 + border-ink bg-ink px-5 py-2.5 text-sm font-bold text-paper 26 + shadow-[4px_4px_0px_0px_var(--color-peach-bold)] transition-all 27 + hover:-translate-y-0.5 active:translate-y-0 sm:self-auto" 16 28 > 17 - <.icon name="hero-plus" class="size-4" /> Add your first site 29 + <.icon name="hero-plus" class="size-5" /> Add a site 18 30 </.link> 19 31 </div> 20 - 21 - <h1 class="mt-2 font-display text-3xl font-bold tracking-tight sm:text-4xl"> 22 - Hi {@current_scope.user.display_name || @current_scope.user.handle} 23 - </h1> 24 - <p class="mt-2 text-ink/60">Here's what you're publishing to the ATmosphere.</p> 25 - 26 32 <div class="mt-8 grid grid-cols-2 gap-4 lg:grid-cols-4"> 27 33 <.stat_card 28 34 label="Sites"