Add terms of service page and update login/error UI stylingUnverified
9a4b0ff parent: 3d8db14 modified
internal/server/server.go +1 -0 | @@ -218,6 +218,7 @@ func (s *Server) setupRoutes() { | ||
| 218 | 218 | s.router.Get("/xrpc/at.glean.getRecommendations", xrpc.GetRecommendations) |
| 219 | 219 | s.router.Get("/xrpc/at.glean.listFeedLists", xrpc.ListFeedLists) |
| 220 | 220 | |
| 221 | + s.router.Get("/terms", s.handleTerms) | |
| 221 | 222 | s.router.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.FS(static.Files)))) |
| 222 | 223 | s.router.Handle("/metrics", promhttp.Handler()) |
| 223 | 224 | s.router.Get("/stats", s.handleStats) |
| @@ -218,6 +218,7 @@ func (s *Server) setupRoutes() { | |||
| 218 | s.router.Get("/xrpc/at.glean.getRecommendations", xrpc.GetRecommendations) | 218 | s.router.Get("/xrpc/at.glean.getRecommendations", xrpc.GetRecommendations) |
| 219 | s.router.Get("/xrpc/at.glean.listFeedLists", xrpc.ListFeedLists) | 219 | s.router.Get("/xrpc/at.glean.listFeedLists", xrpc.ListFeedLists) |
| 220 | 220 | ||
| 221 | + s.router.Get("/terms", s.handleTerms) | ||
| 221 | s.router.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.FS(static.Files)))) | 222 | s.router.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.FS(static.Files)))) |
| 222 | s.router.Handle("/metrics", promhttp.Handler()) | 223 | s.router.Handle("/metrics", promhttp.Handler()) |
| 223 | s.router.Get("/stats", s.handleStats) | 224 | s.router.Get("/stats", s.handleStats) |
added
internal/server/terms_handler.go +7 -0 | new file mode 100644 | ||
| @@ -0,0 +1,7 @@ | ||
| 1 | +package server | |
| 2 | + | |
| 3 | +import "net/http" | |
| 4 | + | |
| 5 | +func (s *Server) handleTerms(w http.ResponseWriter, r *http.Request) { | |
| 6 | + s.render(w, r, "terms.html", map[string]any{}) | |
| 7 | +} | |
| new file mode 100644 | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | +package server | ||
| 2 | + | ||
| 3 | +import "net/http" | ||
| 4 | + | ||
| 5 | +func (s *Server) handleTerms(w http.ResponseWriter, r *http.Request) { | ||
| 6 | + s.render(w, r, "terms.html", map[string]any{}) | ||
| 7 | +} | ||
modified
internal/tmpl/404.html +7 -7 | @@ -1,12 +1,12 @@ | ||
| 1 | 1 | {{define "404.html"}} |
| 2 | -<div class="max-w-md mx-auto mt-20"> | |
| 3 | - <div class="bg-spot-surface rounded-xl shadow-spot-heavy p-8"> | |
| 4 | - <div class="flex justify-center mb-6"> | |
| 5 | - <span class="w-14 h-14">{{template "logo-icon"}}</span> | |
| 2 | +<div class="flex items-center justify-center min-h-screen px-4 py-12"> | |
| 3 | + <div class="max-w-sm w-full"> | |
| 4 | + <div class="flex justify-center mb-8"> | |
| 5 | + <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a> | |
| 6 | 6 | </div> |
| 7 | - <h1 class="text-2xl font-bold text-spot-text mb-2 text-center">Page not found</h1> | |
| 8 | - <p class="text-spot-secondary text-sm mb-6 text-center">This page doesn't exist, but your feeds do.</p> | |
| 9 | - <a href="/dashboard" class="w-full flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-4 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | |
| 7 | + <h1 class="text-2xl font-bold text-spot-text mb-1 text-center">Page not found</h1> | |
| 8 | + <p class="text-spot-secondary text-sm mb-8 text-center">This page doesn't exist, but your feeds do.</p> | |
| 9 | + <a href="/dashboard" class="w-full flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-4 py-3.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | |
| 10 | 10 | Back to Dashboard |
| 11 | 11 | </a> |
| 12 | 12 | </div> |
| @@ -1,12 +1,12 @@ | |||
| 1 | {{define "404.html"}} | 1 | {{define "404.html"}} |
| 2 | -<div class="max-w-md mx-auto mt-20"> | 2 | +<div class="flex items-center justify-center min-h-screen px-4 py-12"> |
| 3 | - <div class="bg-spot-surface rounded-xl shadow-spot-heavy p-8"> | 3 | + <div class="max-w-sm w-full"> |
| 4 | - <div class="flex justify-center mb-6"> | 4 | + <div class="flex justify-center mb-8"> |
| 5 | - <span class="w-14 h-14">{{template "logo-icon"}}</span> | 5 | + <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a> |
| 6 | </div> | 6 | </div> |
| 7 | - <h1 class="text-2xl font-bold text-spot-text mb-2 text-center">Page not found</h1> | 7 | + <h1 class="text-2xl font-bold text-spot-text mb-1 text-center">Page not found</h1> |
| 8 | - <p class="text-spot-secondary text-sm mb-6 text-center">This page doesn't exist, but your feeds do.</p> | 8 | + <p class="text-spot-secondary text-sm mb-8 text-center">This page doesn't exist, but your feeds do.</p> |
| 9 | - <a href="/dashboard" class="w-full flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-4 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | 9 | + <a href="/dashboard" class="w-full flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-4 py-3.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> |
| 10 | Back to Dashboard | 10 | Back to Dashboard |
| 11 | </a> | 11 | </a> |
| 12 | </div> | 12 | </div> |
modified
internal/tmpl/base.html +5 -5 | @@ -210,10 +210,10 @@ | ||
| 210 | 210 | </button> |
| 211 | 211 | </div> |
| 212 | 212 | </div> |
| 213 | - <div class="text-right"> | |
| 214 | - <div class="text-xs text-spot-secondary">© {{now.Format "2006"}} <a href="https://bsky.app/profile/julien.rbrt.fr" class="hover:text-spot-text transition">julien.rbrt.fr</a></div> | |
| 215 | - <div class="text-[10px] text-spot-secondary mt-0.5">Made in Europe 🇪🇺</div> | |
| 216 | - </div> | |
| 213 | + <div class="text-right"> | |
| 214 | + <div class="text-xs text-spot-secondary">© {{now.Format "2006"}} <a href="https://bsky.app/profile/julien.rbrt.fr" class="hover:text-spot-text transition">julien.rbrt.fr</a></div> | |
| 215 | + <div class="text-[10px] text-spot-secondary mt-0.5">Made in Europe 🇪🇺 · <a href="/terms" class="hover:text-spot-text transition">Terms</a></div> | |
| 216 | + </div> | |
| 217 | 217 | </div> |
| 218 | 218 | |
| 219 | 219 | <div class="md:hidden flex flex-col gap-5"> |
| @@ -246,7 +246,7 @@ | ||
| 246 | 246 | </button> |
| 247 | 247 | </div> |
| 248 | 248 | <div class="border-t border-spot-divider mt-4 pt-3"> |
| 249 | - <span class="text-xs text-spot-secondary">© {{now.Format "2006"}} <a href="https://bsky.app/profile/julien.rbrt.fr" class="hover:text-spot-text transition">julien.rbrt.fr</a> · Made in Europe 🇪🇺</span> | |
| 249 | + <span class="text-xs text-spot-secondary">© {{now.Format "2006"}} <a href="https://bsky.app/profile/julien.rbrt.fr" class="hover:text-spot-text transition">julien.rbrt.fr</a> · Made in Europe 🇪🇺 · <a href="/terms" class="hover:text-spot-text transition">Terms</a></span> | |
| 250 | 250 | </div> |
| 251 | 251 | </div> |
| 252 | 252 | </div> |
| @@ -210,10 +210,10 @@ | |||
| 210 | </button> | 210 | </button> |
| 211 | </div> | 211 | </div> |
| 212 | </div> | 212 | </div> |
| 213 | - <div class="text-right"> | 213 | + <div class="text-right"> |
| 214 | - <div class="text-xs text-spot-secondary">© {{now.Format "2006"}} <a href="https://bsky.app/profile/julien.rbrt.fr" class="hover:text-spot-text transition">julien.rbrt.fr</a></div> | 214 | + <div class="text-xs text-spot-secondary">© {{now.Format "2006"}} <a href="https://bsky.app/profile/julien.rbrt.fr" class="hover:text-spot-text transition">julien.rbrt.fr</a></div> |
| 215 | - <div class="text-[10px] text-spot-secondary mt-0.5">Made in Europe 🇪🇺</div> | 215 | + <div class="text-[10px] text-spot-secondary mt-0.5">Made in Europe 🇪🇺 · <a href="/terms" class="hover:text-spot-text transition">Terms</a></div> |
| 216 | - </div> | 216 | + </div> |
| 217 | </div> | 217 | </div> |
| 218 | 218 | ||
| 219 | <div class="md:hidden flex flex-col gap-5"> | 219 | <div class="md:hidden flex flex-col gap-5"> |
| @@ -246,7 +246,7 @@ | |||
| 246 | </button> | 246 | </button> |
| 247 | </div> | 247 | </div> |
| 248 | <div class="border-t border-spot-divider mt-4 pt-3"> | 248 | <div class="border-t border-spot-divider mt-4 pt-3"> |
| 249 | - <span class="text-xs text-spot-secondary">© {{now.Format "2006"}} <a href="https://bsky.app/profile/julien.rbrt.fr" class="hover:text-spot-text transition">julien.rbrt.fr</a> · Made in Europe 🇪🇺</span> | 249 | + <span class="text-xs text-spot-secondary">© {{now.Format "2006"}} <a href="https://bsky.app/profile/julien.rbrt.fr" class="hover:text-spot-text transition">julien.rbrt.fr</a> · Made in Europe 🇪🇺 · <a href="/terms" class="hover:text-spot-text transition">Terms</a></span> |
| 250 | </div> | 250 | </div> |
| 251 | </div> | 251 | </div> |
| 252 | </div> | 252 | </div> |
modified
internal/tmpl/error.html +7 -7 | @@ -1,12 +1,12 @@ | ||
| 1 | 1 | {{define "error.html"}} |
| 2 | -<div class="max-w-md mx-auto mt-20"> | |
| 3 | - <div class="bg-spot-surface rounded-xl shadow-spot-heavy p-8"> | |
| 4 | - <div class="flex justify-center mb-6"> | |
| 5 | - <span class="w-14 h-14">{{template "logo-icon"}}</span> | |
| 2 | +<div class="flex items-center justify-center min-h-screen px-4 py-12"> | |
| 3 | + <div class="max-w-sm w-full"> | |
| 4 | + <div class="flex justify-center mb-8"> | |
| 5 | + <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a> | |
| 6 | 6 | </div> |
| 7 | - <h1 class="text-2xl font-bold text-spot-text mb-2 text-center">{{.Title}}</h1> | |
| 8 | - <p class="text-spot-secondary text-sm mb-6 text-center">{{.Message}}</p> | |
| 9 | - <a href="/dashboard" class="w-full flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-4 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | |
| 7 | + <h1 class="text-2xl font-bold text-spot-text mb-1 text-center">{{.Title}}</h1> | |
| 8 | + <p class="text-spot-secondary text-sm mb-8 text-center">{{.Message}}</p> | |
| 9 | + <a href="/dashboard" class="w-full flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-4 py-3.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | |
| 10 | 10 | Back to Dashboard |
| 11 | 11 | </a> |
| 12 | 12 | </div> |
| @@ -1,12 +1,12 @@ | |||
| 1 | {{define "error.html"}} | 1 | {{define "error.html"}} |
| 2 | -<div class="max-w-md mx-auto mt-20"> | 2 | +<div class="flex items-center justify-center min-h-screen px-4 py-12"> |
| 3 | - <div class="bg-spot-surface rounded-xl shadow-spot-heavy p-8"> | 3 | + <div class="max-w-sm w-full"> |
| 4 | - <div class="flex justify-center mb-6"> | 4 | + <div class="flex justify-center mb-8"> |
| 5 | - <span class="w-14 h-14">{{template "logo-icon"}}</span> | 5 | + <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a> |
| 6 | </div> | 6 | </div> |
| 7 | - <h1 class="text-2xl font-bold text-spot-text mb-2 text-center">{{.Title}}</h1> | 7 | + <h1 class="text-2xl font-bold text-spot-text mb-1 text-center">{{.Title}}</h1> |
| 8 | - <p class="text-spot-secondary text-sm mb-6 text-center">{{.Message}}</p> | 8 | + <p class="text-spot-secondary text-sm mb-8 text-center">{{.Message}}</p> |
| 9 | - <a href="/dashboard" class="w-full flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-4 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | 9 | + <a href="/dashboard" class="w-full flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-4 py-3.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> |
| 10 | Back to Dashboard | 10 | Back to Dashboard |
| 11 | </a> | 11 | </a> |
| 12 | </div> | 12 | </div> |
modified
internal/tmpl/login.html +31 -28 | @@ -1,44 +1,47 @@ | ||
| 1 | 1 | {{define "login.html"}} |
| 2 | -<div class="max-w-md mx-auto mt-20"> | |
| 3 | - <div class="bg-spot-surface rounded-xl shadow-spot-heavy p-8"> | |
| 4 | - <div class="flex justify-center mb-6"> | |
| 5 | - <a href="/" class="w-14 h-14 block">{{template "logo-icon"}}</a> | |
| 2 | +<style> | |
| 3 | +.login-divider { display: flex; align-items: center; gap: 0.75rem; } | |
| 4 | +.login-divider::before, .login-divider::after { content: ''; flex: 1; height: 1px; background: var(--spot-divider); } | |
| 5 | +</style> | |
| 6 | + | |
| 7 | +<div class="flex items-center justify-center min-h-screen px-4 py-12"> | |
| 8 | + <div class="max-w-sm w-full"> | |
| 9 | + <div class="flex justify-center mb-8"> | |
| 10 | + <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a> | |
| 6 | 11 | </div> |
| 7 | - <h1 class="text-2xl font-bold text-spot-text mb-2 text-center">Sign in to Glean</h1> | |
| 8 | - <p class="text-spot-secondary text-sm mb-6 text-center">Enter your handle.</p> | |
| 12 | + | |
| 13 | + <h1 class="text-2xl font-bold text-spot-text mb-1 text-center">Welcome to Glean</h1> | |
| 14 | + <p class="text-spot-secondary text-sm mb-8 text-center">The social RSS reader built on AT Protocol.</p> | |
| 9 | 15 | |
| 10 | 16 | <form action="/auth/start" method="POST" id="login-form"> |
| 11 | 17 | {{csrfInput .CSRFToken}} |
| 12 | - <div class="relative mb-5"> | |
| 18 | + <div class="relative mb-4"> | |
| 19 | + <label for="handle-input" class="block text-xs text-spot-secondary mb-1.5">Login with your Atmosphere account</label> | |
| 13 | 20 | <input type="text" name="handle" placeholder="you.bsky.social" id="handle-input" |
| 14 | - class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder" | |
| 21 | + class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-3.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder" | |
| 15 | 22 | required autocomplete="off"> |
| 16 | 23 | <div id="handle-suggestions" class="absolute left-0 right-0 top-full mt-1 bg-spot-surface border border-spot-divider rounded-xl shadow-spot-heavy z-50 overflow-hidden hidden"></div> |
| 17 | 24 | </div> |
| 18 | - </form> | |
| 19 | 25 | |
| 20 | - <div class="space-y-3"> | |
| 21 | - <button type="submit" form="login-form" | |
| 22 | - class="w-full flex items-center justify-center gap-3 bg-[#0284FF] text-white rounded-pill px-4 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | |
| 23 | - <span class="w-5 h-5">{{template "icon-bluesky"}}</span> | |
| 24 | - Sign in with Bluesky | |
| 26 | + <button type="submit" | |
| 27 | + class="w-full flex items-center justify-center bg-spot-green text-white rounded-pill px-4 py-3.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | |
| 28 | + Login | |
| 25 | 29 | </button> |
| 30 | + </form> | |
| 26 | 31 | |
| 27 | - <button type="submit" form="login-form" | |
| 28 | - class="w-full flex items-center justify-center gap-3 border border-spot-outline text-spot-text rounded-pill px-4 py-3 text-sm font-bold uppercase tracking-button hover:bg-spot-hover-50 transition"> | |
| 29 | - <svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">{{template "icon-globe"}}</svg> | |
| 30 | - Sign in with Atmosphere | |
| 31 | - </button> | |
| 32 | + <div class="login-divider text-xs text-spot-muted uppercase tracking-wide mt-8 mb-6"> | |
| 33 | + <span>New here?</span> | |
| 32 | 34 | </div> |
| 33 | 35 | |
| 34 | - <div class="mt-6 pt-6 border-t border-spot-divider text-center"> | |
| 35 | - <p class="text-xs text-spot-secondary mb-3">No account yet?</p> | |
| 36 | - <a href="https://portal.eurosky.tech/create-account" target="_blank" rel="noopener noreferrer" | |
| 37 | - class="inline-flex items-center justify-center gap-2 w-full border border-spot-outline text-spot-text rounded-pill px-4 py-2.5 text-sm font-bold uppercase tracking-button hover:bg-spot-hover-50 transition"> | |
| 38 | - <span class="text-base">🇪🇺</span> | |
| 39 | - Create an account on Eurosky | |
| 40 | - </a> | |
| 41 | - </div> | |
| 36 | + <a href="https://portal.eurosky.tech/create-account" target="_blank" rel="noopener noreferrer" | |
| 37 | + class="w-full flex items-center justify-center gap-3 border border-spot-outline rounded-pill px-4 py-3.5 text-sm font-bold uppercase tracking-button hover:bg-spot-hover-50 transition"> | |
| 38 | + <svg class="h-5 w-auto" fill="currentColor" viewBox="77.86 113.9 129.15 129.15" xmlns="http://www.w3.org/2000/svg"><path d="M148.846 144.562C148.846 159.75 161.158 172.062 176.346 172.062H207.012V185.865H176.346C161.158 185.865 148.846 198.177 148.846 213.365V243.045H136.029V213.365C136.029 198.177 123.717 185.865 108.529 185.865H77.8633V172.062H108.529C123.717 172.062 136.029 159.75 136.029 144.562V113.896H148.846V144.562Z"/></svg> | |
| 39 | + Register with Eurosky | |
| 40 | + </a> | |
| 41 | + | |
| 42 | + <p class="text-[11px] text-spot-muted text-center leading-relaxed mt-8"> | |
| 43 | + By continuing, you agree to the <a href="/terms" class="underline hover:text-spot-secondary transition">Terms of Service</a>. | |
| 44 | + </p> | |
| 42 | 45 | </div> |
| 43 | 46 | </div> |
| 44 | 47 | <script> |
| @@ -119,4 +122,4 @@ | ||
| 119 | 122 | }); |
| 120 | 123 | })(); |
| 121 | 124 | </script> |
| 122 | -{{end}} | |
| 125 | +{{end}} | |
| \ No newline at end of file | ||
| @@ -1,44 +1,47 @@ | |||
| 1 | {{define "login.html"}} | 1 | {{define "login.html"}} |
| 2 | -<div class="max-w-md mx-auto mt-20"> | 2 | +<style> |
| 3 | - <div class="bg-spot-surface rounded-xl shadow-spot-heavy p-8"> | 3 | +.login-divider { display: flex; align-items: center; gap: 0.75rem; } |
| 4 | - <div class="flex justify-center mb-6"> | 4 | +.login-divider::before, .login-divider::after { content: ''; flex: 1; height: 1px; background: var(--spot-divider); } |
| 5 | - <a href="/" class="w-14 h-14 block">{{template "logo-icon"}}</a> | 5 | +</style> |
| 6 | + | ||
| 7 | +<div class="flex items-center justify-center min-h-screen px-4 py-12"> | ||
| 8 | + <div class="max-w-sm w-full"> | ||
| 9 | + <div class="flex justify-center mb-8"> | ||
| 10 | + <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a> | ||
| 6 | </div> | 11 | </div> |
| 7 | - <h1 class="text-2xl font-bold text-spot-text mb-2 text-center">Sign in to Glean</h1> | 12 | + |
| 8 | - <p class="text-spot-secondary text-sm mb-6 text-center">Enter your handle.</p> | 13 | + <h1 class="text-2xl font-bold text-spot-text mb-1 text-center">Welcome to Glean</h1> |
| 14 | + <p class="text-spot-secondary text-sm mb-8 text-center">The social RSS reader built on AT Protocol.</p> | ||
| 9 | 15 | ||
| 10 | <form action="/auth/start" method="POST" id="login-form"> | 16 | <form action="/auth/start" method="POST" id="login-form"> |
| 11 | {{csrfInput .CSRFToken}} | 17 | {{csrfInput .CSRFToken}} |
| 12 | - <div class="relative mb-5"> | 18 | + <div class="relative mb-4"> |
| 19 | + <label for="handle-input" class="block text-xs text-spot-secondary mb-1.5">Login with your Atmosphere account</label> | ||
| 13 | <input type="text" name="handle" placeholder="you.bsky.social" id="handle-input" | 20 | <input type="text" name="handle" placeholder="you.bsky.social" id="handle-input" |
| 14 | - class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder" | 21 | + class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-3.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder" |
| 15 | required autocomplete="off"> | 22 | required autocomplete="off"> |
| 16 | <div id="handle-suggestions" class="absolute left-0 right-0 top-full mt-1 bg-spot-surface border border-spot-divider rounded-xl shadow-spot-heavy z-50 overflow-hidden hidden"></div> | 23 | <div id="handle-suggestions" class="absolute left-0 right-0 top-full mt-1 bg-spot-surface border border-spot-divider rounded-xl shadow-spot-heavy z-50 overflow-hidden hidden"></div> |
| 17 | </div> | 24 | </div> |
| 18 | - </form> | ||
| 19 | 25 | ||
| 20 | - <div class="space-y-3"> | 26 | + <button type="submit" |
| 21 | - <button type="submit" form="login-form" | 27 | + class="w-full flex items-center justify-center bg-spot-green text-white rounded-pill px-4 py-3.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> |
| 22 | - class="w-full flex items-center justify-center gap-3 bg-[#0284FF] text-white rounded-pill px-4 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | 28 | + Login |
| 23 | - <span class="w-5 h-5">{{template "icon-bluesky"}}</span> | ||
| 24 | - Sign in with Bluesky | ||
| 25 | </button> | 29 | </button> |
| 30 | + </form> | ||
| 26 | 31 | ||
| 27 | - <button type="submit" form="login-form" | 32 | + <div class="login-divider text-xs text-spot-muted uppercase tracking-wide mt-8 mb-6"> |
| 28 | - class="w-full flex items-center justify-center gap-3 border border-spot-outline text-spot-text rounded-pill px-4 py-3 text-sm font-bold uppercase tracking-button hover:bg-spot-hover-50 transition"> | 33 | + <span>New here?</span> |
| 29 | - <svg class="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">{{template "icon-globe"}}</svg> | ||
| 30 | - Sign in with Atmosphere | ||
| 31 | - </button> | ||
| 32 | </div> | 34 | </div> |
| 33 | 35 | ||
| 34 | - <div class="mt-6 pt-6 border-t border-spot-divider text-center"> | 36 | + <a href="https://portal.eurosky.tech/create-account" target="_blank" rel="noopener noreferrer" |
| 35 | - <p class="text-xs text-spot-secondary mb-3">No account yet?</p> | 37 | + class="w-full flex items-center justify-center gap-3 border border-spot-outline rounded-pill px-4 py-3.5 text-sm font-bold uppercase tracking-button hover:bg-spot-hover-50 transition"> |
| 36 | - <a href="https://portal.eurosky.tech/create-account" target="_blank" rel="noopener noreferrer" | 38 | + <svg class="h-5 w-auto" fill="currentColor" viewBox="77.86 113.9 129.15 129.15" xmlns="http://www.w3.org/2000/svg"><path d="M148.846 144.562C148.846 159.75 161.158 172.062 176.346 172.062H207.012V185.865H176.346C161.158 185.865 148.846 198.177 148.846 213.365V243.045H136.029V213.365C136.029 198.177 123.717 185.865 108.529 185.865H77.8633V172.062H108.529C123.717 172.062 136.029 159.75 136.029 144.562V113.896H148.846V144.562Z"/></svg> |
| 37 | - class="inline-flex items-center justify-center gap-2 w-full border border-spot-outline text-spot-text rounded-pill px-4 py-2.5 text-sm font-bold uppercase tracking-button hover:bg-spot-hover-50 transition"> | 39 | + Register with Eurosky |
| 38 | - <span class="text-base">🇪🇺</span> | 40 | + </a> |
| 39 | - Create an account on Eurosky | 41 | + |
| 40 | - </a> | 42 | + <p class="text-[11px] text-spot-muted text-center leading-relaxed mt-8"> |
| 41 | - </div> | 43 | + By continuing, you agree to the <a href="/terms" class="underline hover:text-spot-secondary transition">Terms of Service</a>. |
| 44 | + </p> | ||
| 42 | </div> | 45 | </div> |
| 43 | </div> | 46 | </div> |
| 44 | <script> | 47 | <script> |
| @@ -119,4 +122,4 @@ | |||
| 119 | }); | 122 | }); |
| 120 | })(); | 123 | })(); |
| 121 | </script> | 124 | </script> |
| 122 | -{{end}} | 125 | +{{end}} |
| \ No newline at end of file | \ No newline at end of file | ||
added
internal/tmpl/terms.html +72 -0 | new file mode 100644 | ||
| @@ -0,0 +1,72 @@ | ||
| 1 | +{{define "terms.html"}} | |
| 2 | +<div class="max-w-2xl mx-auto py-12 px-4"> | |
| 3 | + <h1 class="text-2xl font-bold text-spot-text mb-2">Terms of Service</h1> | |
| 4 | + <p class="text-sm text-spot-secondary mb-8">Last updated: May 2, 2026</p> | |
| 5 | + | |
| 6 | + <div class="space-y-6 text-sm text-spot-body leading-relaxed"> | |
| 7 | + <div> | |
| 8 | + <h2 class="text-lg font-bold text-spot-text mb-3">1. Acceptance of Terms</h2> | |
| 9 | + <p>By accessing or using Glean ("the Service"), you agree to be bound by these Terms of Service. If you do not agree, do not use the Service.</p> | |
| 10 | + </div> | |
| 11 | + | |
| 12 | + <div> | |
| 13 | + <h2 class="text-lg font-bold text-spot-text mb-3">2. Description of Service</h2> | |
| 14 | + <p>Glean is a social RSS reader built on the AT Protocol. It allows you to subscribe to RSS and Atom feeds, read articles, highlight passages, leave annotations, and discover new content through personalized recommendations based on your network.</p> | |
| 15 | + </div> | |
| 16 | + | |
| 17 | + <div> | |
| 18 | + <h2 class="text-lg font-bold text-spot-text mb-3">3. Account and Authentication</h2> | |
| 19 | + <p>Glean uses AT Protocol identity. You sign in with your handle (e.g. from Bluesky or another AT Protocol account provider). Your subscriptions, annotations, and likes are stored in your personal data repository (PDS) on the AT Protocol. You retain full ownership of your data at all times.</p> | |
| 20 | + </div> | |
| 21 | + | |
| 22 | + <div> | |
| 23 | + <h2 class="text-lg font-bold text-spot-text mb-3">4. Your Data</h2> | |
| 24 | + <p>Your data belongs to you. Glean stores records in your PDS using AT Protocol collections. You can export or move your data at any time using standard AT Protocol tools. Glean does not sell, share, or monetize your personal data.</p> | |
| 25 | + </div> | |
| 26 | + | |
| 27 | + <div> | |
| 28 | + <h2 class="text-lg font-bold text-spot-text mb-3">5. Acceptable Use</h2> | |
| 29 | + <p>You agree not to use the Service to: violate any applicable law; infringe on the rights of others; distribute spam, malware, or harmful content; attempt to gain unauthorized access to the Service or its infrastructure; or interfere with the proper functioning of the Service.</p> | |
| 30 | + </div> | |
| 31 | + | |
| 32 | + <div> | |
| 33 | + <h2 class="text-lg font-bold text-spot-text mb-3">6. Content</h2> | |
| 34 | + <p>Glean indexes publicly available RSS and Atom feeds. We do not host article content. Feed publishers retain all rights to their content. If you are a feed publisher and wish to have your feed removed from our index, please contact us.</p> | |
| 35 | + </div> | |
| 36 | + | |
| 37 | + <div> | |
| 38 | + <h2 class="text-lg font-bold text-spot-text mb-3">7. Availability</h2> | |
| 39 | + <p>The Service is provided "as is" and "as available." We strive for reliability but do not guarantee uninterrupted access. We may modify, suspend, or discontinue the Service at any time.</p> | |
| 40 | + </div> | |
| 41 | + | |
| 42 | + <div> | |
| 43 | + <h2 class="text-lg font-bold text-spot-text mb-3">8. Open Source</h2> | |
| 44 | + <p>Glean is open source software. You can inspect, fork, and self-host the code. Contributions are welcome subject to the project's license and contribution guidelines.</p> | |
| 45 | + </div> | |
| 46 | + | |
| 47 | + <div> | |
| 48 | + <h2 class="text-lg font-bold text-spot-text mb-3">9. Limitation of Liability</h2> | |
| 49 | + <p>To the maximum extent permitted by law, the Service is provided without warranties of any kind. We are not liable for any indirect, incidental, or consequential damages arising from your use of the Service.</p> | |
| 50 | + </div> | |
| 51 | + | |
| 52 | + <div> | |
| 53 | + <h2 class="text-lg font-bold text-spot-text mb-3">10. Changes to Terms</h2> | |
| 54 | + <p>We may update these Terms from time to time. Material changes will be communicated through the Service. Continued use of the Service after changes constitutes acceptance of the updated Terms.</p> | |
| 55 | + </div> | |
| 56 | + | |
| 57 | + <div> | |
| 58 | + <h2 class="text-lg font-bold text-spot-text mb-3">11. Contact</h2> | |
| 59 | + <p>For questions about these Terms, reach out via <a href="https://bsky.app/profile/glean.at" class="text-spot-green hover:brightness-110 underline">Bluesky</a> or email at <span id="contact-email"></span>.</p> | |
| 60 | + </div> | |
| 61 | + </div> | |
| 62 | + | |
| 63 | + <div class="mt-12 pt-6 border-t border-spot-divider"> | |
| 64 | + <a href="/" class="inline-flex items-center justify-center bg-spot-green text-white rounded-pill px-6 py-2.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | |
| 65 | + Back to Glean | |
| 66 | + </a> | |
| 67 | + </div> | |
| 68 | +</div> | |
| 69 | +<script> | |
| 70 | +(function(){var p='contact',d='glean.at',e=p+'@'+d;var el=document.getElementById('contact-email');var a=document.createElement('a');a.href='mailto:'+e;a.textContent=e;a.className='text-spot-green hover:brightness-110 underline';el.replaceWith(a)})(); | |
| 71 | +</script> | |
| 72 | +{{end}} | |
| \ No newline at end of file | ||
| new file mode 100644 | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | +{{define "terms.html"}} | ||
| 2 | +<div class="max-w-2xl mx-auto py-12 px-4"> | ||
| 3 | + <h1 class="text-2xl font-bold text-spot-text mb-2">Terms of Service</h1> | ||
| 4 | + <p class="text-sm text-spot-secondary mb-8">Last updated: May 2, 2026</p> | ||
| 5 | + | ||
| 6 | + <div class="space-y-6 text-sm text-spot-body leading-relaxed"> | ||
| 7 | + <div> | ||
| 8 | + <h2 class="text-lg font-bold text-spot-text mb-3">1. Acceptance of Terms</h2> | ||
| 9 | + <p>By accessing or using Glean ("the Service"), you agree to be bound by these Terms of Service. If you do not agree, do not use the Service.</p> | ||
| 10 | + </div> | ||
| 11 | + | ||
| 12 | + <div> | ||
| 13 | + <h2 class="text-lg font-bold text-spot-text mb-3">2. Description of Service</h2> | ||
| 14 | + <p>Glean is a social RSS reader built on the AT Protocol. It allows you to subscribe to RSS and Atom feeds, read articles, highlight passages, leave annotations, and discover new content through personalized recommendations based on your network.</p> | ||
| 15 | + </div> | ||
| 16 | + | ||
| 17 | + <div> | ||
| 18 | + <h2 class="text-lg font-bold text-spot-text mb-3">3. Account and Authentication</h2> | ||
| 19 | + <p>Glean uses AT Protocol identity. You sign in with your handle (e.g. from Bluesky or another AT Protocol account provider). Your subscriptions, annotations, and likes are stored in your personal data repository (PDS) on the AT Protocol. You retain full ownership of your data at all times.</p> | ||
| 20 | + </div> | ||
| 21 | + | ||
| 22 | + <div> | ||
| 23 | + <h2 class="text-lg font-bold text-spot-text mb-3">4. Your Data</h2> | ||
| 24 | + <p>Your data belongs to you. Glean stores records in your PDS using AT Protocol collections. You can export or move your data at any time using standard AT Protocol tools. Glean does not sell, share, or monetize your personal data.</p> | ||
| 25 | + </div> | ||
| 26 | + | ||
| 27 | + <div> | ||
| 28 | + <h2 class="text-lg font-bold text-spot-text mb-3">5. Acceptable Use</h2> | ||
| 29 | + <p>You agree not to use the Service to: violate any applicable law; infringe on the rights of others; distribute spam, malware, or harmful content; attempt to gain unauthorized access to the Service or its infrastructure; or interfere with the proper functioning of the Service.</p> | ||
| 30 | + </div> | ||
| 31 | + | ||
| 32 | + <div> | ||
| 33 | + <h2 class="text-lg font-bold text-spot-text mb-3">6. Content</h2> | ||
| 34 | + <p>Glean indexes publicly available RSS and Atom feeds. We do not host article content. Feed publishers retain all rights to their content. If you are a feed publisher and wish to have your feed removed from our index, please contact us.</p> | ||
| 35 | + </div> | ||
| 36 | + | ||
| 37 | + <div> | ||
| 38 | + <h2 class="text-lg font-bold text-spot-text mb-3">7. Availability</h2> | ||
| 39 | + <p>The Service is provided "as is" and "as available." We strive for reliability but do not guarantee uninterrupted access. We may modify, suspend, or discontinue the Service at any time.</p> | ||
| 40 | + </div> | ||
| 41 | + | ||
| 42 | + <div> | ||
| 43 | + <h2 class="text-lg font-bold text-spot-text mb-3">8. Open Source</h2> | ||
| 44 | + <p>Glean is open source software. You can inspect, fork, and self-host the code. Contributions are welcome subject to the project's license and contribution guidelines.</p> | ||
| 45 | + </div> | ||
| 46 | + | ||
| 47 | + <div> | ||
| 48 | + <h2 class="text-lg font-bold text-spot-text mb-3">9. Limitation of Liability</h2> | ||
| 49 | + <p>To the maximum extent permitted by law, the Service is provided without warranties of any kind. We are not liable for any indirect, incidental, or consequential damages arising from your use of the Service.</p> | ||
| 50 | + </div> | ||
| 51 | + | ||
| 52 | + <div> | ||
| 53 | + <h2 class="text-lg font-bold text-spot-text mb-3">10. Changes to Terms</h2> | ||
| 54 | + <p>We may update these Terms from time to time. Material changes will be communicated through the Service. Continued use of the Service after changes constitutes acceptance of the updated Terms.</p> | ||
| 55 | + </div> | ||
| 56 | + | ||
| 57 | + <div> | ||
| 58 | + <h2 class="text-lg font-bold text-spot-text mb-3">11. Contact</h2> | ||
| 59 | + <p>For questions about these Terms, reach out via <a href="https://bsky.app/profile/glean.at" class="text-spot-green hover:brightness-110 underline">Bluesky</a> or email at <span id="contact-email"></span>.</p> | ||
| 60 | + </div> | ||
| 61 | + </div> | ||
| 62 | + | ||
| 63 | + <div class="mt-12 pt-6 border-t border-spot-divider"> | ||
| 64 | + <a href="/" class="inline-flex items-center justify-center bg-spot-green text-white rounded-pill px-6 py-2.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition"> | ||
| 65 | + Back to Glean | ||
| 66 | + </a> | ||
| 67 | + </div> | ||
| 68 | +</div> | ||
| 69 | +<script> | ||
| 70 | +(function(){var p='contact',d='glean.at',e=p+'@'+d;var el=document.getElementById('contact-email');var a=document.createElement('a');a.href='mailto:'+e;a.textContent=e;a.className='text-spot-green hover:brightness-110 underline';el.replaceWith(a)})(); | ||
| 71 | +</script> | ||
| 72 | +{{end}} | ||
| \ No newline at end of file | \ No newline at end of file | ||
modified
static/input.css +3 -3 | @@ -19,9 +19,9 @@ | ||
| 19 | 19 | --spot-placeholder: rgba(255,255,255,0.45); |
| 20 | 20 | --spot-active-bg: #ffffff; |
| 21 | 21 | --spot-active-text: #1E3932; |
| 22 | - --radius-sm: 0.125rem; | |
| 23 | - --radius-md: 0.375rem; | |
| 24 | - --radius-lg: 0.5rem; | |
| 22 | + --radius-sm: 0.5rem; | |
| 23 | + --radius-md: 0.75rem; | |
| 24 | + --radius-lg: 1rem; | |
| 25 | 25 | --radius-pill: 9999px; |
| 26 | 26 | --radius-full: 50%; |
| 27 | 27 | --spot-shadow: 0 1px 2px rgba(0,0,0,0.40), 0 2px 4px rgba(0,0,0,0.20); |
| @@ -19,9 +19,9 @@ | |||
| 19 | --spot-placeholder: rgba(255,255,255,0.45); | 19 | --spot-placeholder: rgba(255,255,255,0.45); |
| 20 | --spot-active-bg: #ffffff; | 20 | --spot-active-bg: #ffffff; |
| 21 | --spot-active-text: #1E3932; | 21 | --spot-active-text: #1E3932; |
| 22 | - --radius-sm: 0.125rem; | 22 | + --radius-sm: 0.5rem; |
| 23 | - --radius-md: 0.375rem; | 23 | + --radius-md: 0.75rem; |
| 24 | - --radius-lg: 0.5rem; | 24 | + --radius-lg: 1rem; |
| 25 | --radius-pill: 9999px; | 25 | --radius-pill: 9999px; |
| 26 | --radius-full: 50%; | 26 | --radius-full: 50%; |
| 27 | --spot-shadow: 0 1px 2px rgba(0,0,0,0.40), 0 2px 4px rgba(0,0,0,0.20); | 27 | --spot-shadow: 0 1px 2px rgba(0,0,0,0.40), 0 2px 4px rgba(0,0,0,0.20); |