nandi/gleanpublic Fork 0
814b648
Commits
Clone
git clone https://git.rickub.com/nandi/glean.git
git clone ssh://git@rickub.com/nandi/glean.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Refine UI design and typography across all templatesUnverified

Julien Robert committed 2026-05-09T21:20:01+02:00 Browse files
814b648 parent: 512bdc4
modified internal/tmpl/404.html +5 -4
@@ -1,12 +1,13 @@
11 {{define "404.html"}}
22 <div class="flex items-center justify-center min-h-screen px-4 py-12">
3- <div class="max-w-sm w-full">
3+ <div class="max-w-sm w-full text-center">
44 <div class="flex justify-center mb-8">
55 <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a>
66 </div>
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">
7+ <div class="text-6xl font-bold text-spot-green/30 mb-4">404</div>
8+ <h1 class="text-2xl font-bold text-spot-text mb-2">Page not found</h1>
9+ <p class="text-spot-secondary text-sm mb-8">This page doesn't exist, but your feeds do.</p>
10+ <a href="/dashboard" class="inline-flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-6 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">
1011 Back to Dashboard
1112 </a>
1213 </div>
@@ -1,12 +1,13 @@
1 {{define "404.html"}}1 {{define "404.html"}}
2 <div class="flex items-center justify-center min-h-screen px-4 py-12">2 <div class="flex items-center justify-center min-h-screen px-4 py-12">
3- <div class="max-w-sm w-full">3+ <div class="max-w-sm w-full text-center">
4 <div class="flex justify-center mb-8">4 <div class="flex justify-center mb-8">
5 <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a>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-1 text-center">Page not found</h1>7+ <div class="text-6xl font-bold text-spot-green/30 mb-4">404</div>
8- <p class="text-spot-secondary text-sm mb-8 text-center">This page doesn't exist, but your feeds do.</p>8+ <h1 class="text-2xl font-bold text-spot-text mb-2">Page not found</h1>
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">9+ <p class="text-spot-secondary text-sm mb-8">This page doesn't exist, but your feeds do.</p>
10+ <a href="/dashboard" class="inline-flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-6 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">
10 Back to Dashboard11 Back to Dashboard
11 </a>12 </a>
12 </div>13 </div>
modified internal/tmpl/article_detail.html +13 -12
@@ -15,16 +15,17 @@
1515 </div>
1616
1717 <article>
18- <h1 class="text-2xl font-bold leading-tight">
18+ <h1 class="text-2xl font-bold leading-tight" style="letter-spacing: -0.02em;">
1919 {{if .Article.URL.Valid}}<a href="{{.Article.URL.String}}" target="_blank" rel="noopener noreferrer" class="text-spot-text hover:text-spot-green transition">{{.Article.Title}}</a>
2020 {{else}}<span class="text-spot-text">{{.Article.Title}}</span>{{end}}
2121 </h1>
2222
23- <div class="flex items-center gap-2.5 mt-3 text-sm text-spot-secondary flex-wrap">
24- {{if .Article.Author.Valid}}<span>{{.Article.Author.String}}</span>{{end}}
25- {{if .Article.Published.Valid}}<span>{{.Article.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}}
23+ <div class="flex items-center gap-2.5 mt-4 text-sm text-spot-secondary flex-wrap">
24+ {{if .Article.Author.Valid}}<span class="font-medium">{{.Article.Author.String}}</span>{{end}}
25+ {{if .Article.Published.Valid}}<span class="text-spot-muted">&middot;</span><span>{{.Article.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}}
2626 {{if .Feed}}
27- <a href="/articles?feed={{.Feed.FeedURL}}" class="inline-flex items-center gap-1 hover:text-spot-green transition">
27+ <span class="text-spot-muted">&middot;</span>
28+ <a href="/articles?feed={{.Feed.FeedURL}}" class="inline-flex items-center gap-1.5 hover:text-spot-green transition">
2829 {{if .Feed}}{{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-4 h-4"}}{{end}}
2930 {{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}}
3031 </a>
@@ -66,7 +67,7 @@
6667
6768 {{if .Article.URL.Valid}}
6869 {{with youtubeID .Article.URL.String}}
69- <div class="my-6 aspect-video w-full rounded-xl overflow-hidden shadow-spot">
70+ <div class="my-8 aspect-video w-full rounded-xl overflow-hidden shadow-spot-heavy">
7071 <iframe class="w-full h-full" src="https://www.youtube.com/embed/{{.}}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
7172 </div>
7273 {{end}}
@@ -97,7 +98,7 @@
9798 {{if and (not .Article.Content.Valid) (not .Article.FullContent.Valid) .Article.URL.Valid (not (isEmbedURL .Article.URL.String))}}
9899 <div id="article-content" class="mt-6">
99100 <button hx-post="/articles/{{.Article.ID}}/fetch-content" hx-target="#article-content" hx-swap="outerHTML"
100- class="border border-spot-outline text-spot-text rounded-pill px-2.5 py-1.5 text-xs font-bold uppercase tracking-button hover:border-spot-text transition inline-flex items-center gap-1.5">
101+ class="border border-spot-outline text-spot-text rounded-pill px-3 py-1.5 text-xs font-bold uppercase tracking-button hover:border-spot-text transition inline-flex items-center gap-1.5">
101102 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"/></svg>
102103 Fetch full content
103104 </button>
@@ -110,7 +111,7 @@
110111 <hr class="my-8 border-spot-divider">
111112
112113 <section>
113- <div class="flex items-center justify-between mb-4">
114+ <div class="flex items-center justify-between mb-5">
114115 <h2 class="text-lg font-semibold text-spot-text">Annotations</h2>
115116 <button id="toggle-highlights" class="text-xs text-spot-secondary hover:text-spot-text transition inline-flex items-center gap-1.5">
116117 <span id="toggle-highlights-icon" class="w-4 h-4 inline-flex">
@@ -132,11 +133,11 @@
132133 <input type="hidden" name="quote" id="quote-input">
133134 <div>
134135 <textarea name="note" rows="2" placeholder="Add a note..."
135- class="w-full bg-spot-hover text-spot-text rounded-pill px-4 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder resize-none"></textarea>
136+ class="w-full bg-spot-hover text-spot-text rounded-lg px-4 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder resize-none"></textarea>
136137 </div>
137138 <div class="flex gap-2">
138139 <input type="text" name="tags" placeholder="Tags (comma separated)"
139- class="flex-1 bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">
140+ class="flex-1 bg-spot-hover text-spot-text rounded-pill px-5 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">
140141 <button type="submit" class="bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Annotate</button>
141142 </div>
142143 </form>
@@ -145,12 +146,12 @@
145146 {{range .Annotations}}
146147 {{template "annotation-card.html" dict "annotation" . "userDID" $.CurrentUserDID}}
147148 {{else}}
148- <p class="text-sm text-spot-secondary">No annotations yet. Be the first to add one.</p>
149+ <p class="text-sm text-spot-secondary text-center py-6">No annotations yet. Select text above or add a note.</p>
149150 {{end}}
150151 </div>
151152 </section>
152153
153- <div class="flex items-center justify-between mt-8">
154+ <div class="flex items-center justify-between mt-8 mb-4">
154155 <a href="javascript:history.back()" class="text-sm text-spot-secondary hover:text-spot-text inline-flex items-center gap-1.5 transition">
155156 <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5"/></svg>
156157 Back
@@ -15,16 +15,17 @@
15 </div>15 </div>
16 16
17 <article>17 <article>
18- <h1 class="text-2xl font-bold leading-tight">18+ <h1 class="text-2xl font-bold leading-tight" style="letter-spacing: -0.02em;">
19 {{if .Article.URL.Valid}}<a href="{{.Article.URL.String}}" target="_blank" rel="noopener noreferrer" class="text-spot-text hover:text-spot-green transition">{{.Article.Title}}</a>19 {{if .Article.URL.Valid}}<a href="{{.Article.URL.String}}" target="_blank" rel="noopener noreferrer" class="text-spot-text hover:text-spot-green transition">{{.Article.Title}}</a>
20 {{else}}<span class="text-spot-text">{{.Article.Title}}</span>{{end}}20 {{else}}<span class="text-spot-text">{{.Article.Title}}</span>{{end}}
21 </h1>21 </h1>
22 22
23- <div class="flex items-center gap-2.5 mt-3 text-sm text-spot-secondary flex-wrap">23+ <div class="flex items-center gap-2.5 mt-4 text-sm text-spot-secondary flex-wrap">
24- {{if .Article.Author.Valid}}<span>{{.Article.Author.String}}</span>{{end}}24+ {{if .Article.Author.Valid}}<span class="font-medium">{{.Article.Author.String}}</span>{{end}}
25- {{if .Article.Published.Valid}}<span>{{.Article.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}}25+ {{if .Article.Published.Valid}}<span class="text-spot-muted">&middot;</span><span>{{.Article.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}}
26 {{if .Feed}}26 {{if .Feed}}
27- <a href="/articles?feed={{.Feed.FeedURL}}" class="inline-flex items-center gap-1 hover:text-spot-green transition">27+ <span class="text-spot-muted">&middot;</span>
28+ <a href="/articles?feed={{.Feed.FeedURL}}" class="inline-flex items-center gap-1.5 hover:text-spot-green transition">
28 {{if .Feed}}{{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-4 h-4"}}{{end}}29 {{if .Feed}}{{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-4 h-4"}}{{end}}
29 {{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}}30 {{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}}
30 </a>31 </a>
@@ -66,7 +67,7 @@
66 67
67 {{if .Article.URL.Valid}}68 {{if .Article.URL.Valid}}
68 {{with youtubeID .Article.URL.String}}69 {{with youtubeID .Article.URL.String}}
69- <div class="my-6 aspect-video w-full rounded-xl overflow-hidden shadow-spot">70+ <div class="my-8 aspect-video w-full rounded-xl overflow-hidden shadow-spot-heavy">
70 <iframe class="w-full h-full" src="https://www.youtube.com/embed/{{.}}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>71 <iframe class="w-full h-full" src="https://www.youtube.com/embed/{{.}}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
71 </div>72 </div>
72 {{end}}73 {{end}}
@@ -97,7 +98,7 @@
97 {{if and (not .Article.Content.Valid) (not .Article.FullContent.Valid) .Article.URL.Valid (not (isEmbedURL .Article.URL.String))}}98 {{if and (not .Article.Content.Valid) (not .Article.FullContent.Valid) .Article.URL.Valid (not (isEmbedURL .Article.URL.String))}}
98 <div id="article-content" class="mt-6">99 <div id="article-content" class="mt-6">
99 <button hx-post="/articles/{{.Article.ID}}/fetch-content" hx-target="#article-content" hx-swap="outerHTML"100 <button hx-post="/articles/{{.Article.ID}}/fetch-content" hx-target="#article-content" hx-swap="outerHTML"
100- class="border border-spot-outline text-spot-text rounded-pill px-2.5 py-1.5 text-xs font-bold uppercase tracking-button hover:border-spot-text transition inline-flex items-center gap-1.5">101+ class="border border-spot-outline text-spot-text rounded-pill px-3 py-1.5 text-xs font-bold uppercase tracking-button hover:border-spot-text transition inline-flex items-center gap-1.5">
101 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"/></svg>102 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"/></svg>
102 Fetch full content103 Fetch full content
103 </button>104 </button>
@@ -110,7 +111,7 @@
110 <hr class="my-8 border-spot-divider">111 <hr class="my-8 border-spot-divider">
111 112
112 <section>113 <section>
113- <div class="flex items-center justify-between mb-4">114+ <div class="flex items-center justify-between mb-5">
114 <h2 class="text-lg font-semibold text-spot-text">Annotations</h2>115 <h2 class="text-lg font-semibold text-spot-text">Annotations</h2>
115 <button id="toggle-highlights" class="text-xs text-spot-secondary hover:text-spot-text transition inline-flex items-center gap-1.5">116 <button id="toggle-highlights" class="text-xs text-spot-secondary hover:text-spot-text transition inline-flex items-center gap-1.5">
116 <span id="toggle-highlights-icon" class="w-4 h-4 inline-flex">117 <span id="toggle-highlights-icon" class="w-4 h-4 inline-flex">
@@ -132,11 +133,11 @@
132 <input type="hidden" name="quote" id="quote-input">133 <input type="hidden" name="quote" id="quote-input">
133 <div>134 <div>
134 <textarea name="note" rows="2" placeholder="Add a note..."135 <textarea name="note" rows="2" placeholder="Add a note..."
135- class="w-full bg-spot-hover text-spot-text rounded-pill px-4 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder resize-none"></textarea>136+ class="w-full bg-spot-hover text-spot-text rounded-lg px-4 py-3 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder resize-none"></textarea>
136 </div>137 </div>
137 <div class="flex gap-2">138 <div class="flex gap-2">
138 <input type="text" name="tags" placeholder="Tags (comma separated)"139 <input type="text" name="tags" placeholder="Tags (comma separated)"
139- class="flex-1 bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">140+ class="flex-1 bg-spot-hover text-spot-text rounded-pill px-5 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">
140 <button type="submit" class="bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Annotate</button>141 <button type="submit" class="bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Annotate</button>
141 </div>142 </div>
142 </form>143 </form>
@@ -145,12 +146,12 @@
145 {{range .Annotations}}146 {{range .Annotations}}
146 {{template "annotation-card.html" dict "annotation" . "userDID" $.CurrentUserDID}}147 {{template "annotation-card.html" dict "annotation" . "userDID" $.CurrentUserDID}}
147 {{else}}148 {{else}}
148- <p class="text-sm text-spot-secondary">No annotations yet. Be the first to add one.</p>149+ <p class="text-sm text-spot-secondary text-center py-6">No annotations yet. Select text above or add a note.</p>
149 {{end}}150 {{end}}
150 </div>151 </div>
151 </section>152 </section>
152 153
153- <div class="flex items-center justify-between mt-8">154+ <div class="flex items-center justify-between mt-8 mb-4">
154 <a href="javascript:history.back()" class="text-sm text-spot-secondary hover:text-spot-text inline-flex items-center gap-1.5 transition">155 <a href="javascript:history.back()" class="text-sm text-spot-secondary hover:text-spot-text inline-flex items-center gap-1.5 transition">
155 <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5"/></svg>156 <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5L8.25 12l7.5-7.5"/></svg>
156 Back157 Back
modified internal/tmpl/articles.html +12 -12
@@ -2,15 +2,15 @@
22 <div id="new-articles-poll" hx-get="/articles/new-count?since={{.Now.Unix}}&return={{if .FeedURL}}/articles?feed={{.FeedURL}}{{else}}/articles{{end}}" hx-trigger="every 30s" hx-swap="innerHTML"></div>
33
44 {{if .Feed}}
5- <div class="mb-6">
6- <div class="flex items-center gap-2 mb-3">
5+ <div class="mb-8">
6+ <div class="flex items-center gap-2 mb-4">
77 <a href="/articles" class="text-xs text-spot-secondary hover:text-spot-text transition">&larr; All articles</a>
88 </div>
99 <div class="flex items-center justify-between">
10- <div class="flex items-center gap-3">
11- {{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-8 h-8"}}
10+ <div class="flex items-center gap-3.5">
11+ {{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-10 h-10"}}
1212 <div>
13- <h1 class="text-2xl font-bold text-spot-text">{{if .Feed.SiteURL.Valid}}<a href="{{.Feed.SiteURL.String}}" target="_blank" rel="noopener noreferrer" class="hover:text-spot-green transition">{{end}}{{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}}{{if .Feed.SiteURL.Valid}}</a>{{end}}</h1>
13+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">{{if .Feed.SiteURL.Valid}}<a href="{{.Feed.SiteURL.String}}" target="_blank" rel="noopener noreferrer" class="hover:text-spot-green transition">{{end}}{{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}}{{if .Feed.SiteURL.Valid}}</a>{{end}}</h1>
1414 {{if .Feed.SiteURL.Valid}}<a href="{{.Feed.SiteURL.String}}" target="_blank" rel="noopener noreferrer" class="text-xs text-spot-secondary hover:text-spot-green transition">{{.Feed.SiteURL.String}}</a>{{end}}
1515 </div>
1616 </div>
@@ -30,11 +30,11 @@
3030 {{end}}
3131 </div>
3232 </div>
33- {{if .Feed.Description.Valid}}<p class="text-sm text-spot-secondary mt-2">{{.Feed.Description.String}}</p>{{end}}
33+ {{if .Feed.Description.Valid}}<p class="text-sm text-spot-secondary mt-3 leading-relaxed">{{.Feed.Description.String}}</p>{{end}}
3434 </div>
3535 {{else}}
3636 <div class="flex items-center justify-between mb-2">
37- <h1 class="text-2xl font-bold text-spot-text">Articles</h1>
37+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">Articles</h1>
3838 <form hx-post="/articles/mark-all-read" hx-confirm="Mark all articles as read?">
3939 {{csrfInput .CSRFToken}}
4040 <button type="submit" class="border border-spot-outline text-spot-text rounded-pill px-4 py-1.5 text-xs font-bold uppercase tracking-button hover:border-spot-text transition">Mark all read</button>
@@ -47,26 +47,26 @@
4747 <form method="GET" action="/articles" class="flex-1" id="search-form">
4848 <div class="relative">
4949 <input type="text" name="q" value="{{.SearchQuery}}" placeholder="Search articles..."
50- class="w-full bg-spot-hover text-spot-text rounded-pill pl-10 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"
50+ class="w-full bg-spot-hover text-spot-text rounded-pill pl-10 pr-4 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"
5151 hx-get="/articles" hx-trigger="keyup changed delay:300ms, search" hx-target="#article-list" hx-swap="innerHTML" hx-include="[name='q']">
5252 <svg class="w-4 h-4 text-spot-muted absolute left-3.5 top-1/2 -translate-y-1/2 pointer-events-none" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
5353 {{if .FeedURL}}<input type="hidden" name="feed" value="{{.FeedURL}}">{{end}}
5454 {{if .Status}}<input type="hidden" name="status" value="{{.Status}}">{{end}}
5555 </div>
5656 </form>
57- <div class="flex items-center gap-2 shrink-0">
57+ <div class="flex items-center gap-1.5 shrink-0">
5858 <a href="/articles?status=all{{if .FeedURL}}&feed={{.FeedURL}}{{end}}"
59- class="px-4 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition
59+ class="px-3.5 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition
6060 {{if eq .Status "all"}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">
6161 All
6262 </a>
6363 <a href="/articles?status=unread{{if .FeedURL}}&feed={{.FeedURL}}{{end}}"
64- class="px-4 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition
64+ class="px-3.5 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition
6565 {{if or (eq .Status "unread") (eq .Status "")}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">
6666 Unread
6767 </a>
6868 <a href="/articles?status=read{{if .FeedURL}}&feed={{.FeedURL}}{{end}}"
69- class="px-4 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition
69+ class="px-3.5 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition
7070 {{if eq .Status "read"}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">
7171 Read
7272 </a>
@@ -2,15 +2,15 @@
2 <div id="new-articles-poll" hx-get="/articles/new-count?since={{.Now.Unix}}&return={{if .FeedURL}}/articles?feed={{.FeedURL}}{{else}}/articles{{end}}" hx-trigger="every 30s" hx-swap="innerHTML"></div>2 <div id="new-articles-poll" hx-get="/articles/new-count?since={{.Now.Unix}}&return={{if .FeedURL}}/articles?feed={{.FeedURL}}{{else}}/articles{{end}}" hx-trigger="every 30s" hx-swap="innerHTML"></div>
3 3
4 {{if .Feed}}4 {{if .Feed}}
5- <div class="mb-6">5+ <div class="mb-8">
6- <div class="flex items-center gap-2 mb-3">6+ <div class="flex items-center gap-2 mb-4">
7 <a href="/articles" class="text-xs text-spot-secondary hover:text-spot-text transition">&larr; All articles</a>7 <a href="/articles" class="text-xs text-spot-secondary hover:text-spot-text transition">&larr; All articles</a>
8 </div>8 </div>
9 <div class="flex items-center justify-between">9 <div class="flex items-center justify-between">
10- <div class="flex items-center gap-3">10+ <div class="flex items-center gap-3.5">
11- {{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-8 h-8"}}11+ {{template "favicon" dict "src" .Feed.FaviconURL.String "size" "w-10 h-10"}}
12 <div>12 <div>
13- <h1 class="text-2xl font-bold text-spot-text">{{if .Feed.SiteURL.Valid}}<a href="{{.Feed.SiteURL.String}}" target="_blank" rel="noopener noreferrer" class="hover:text-spot-green transition">{{end}}{{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}}{{if .Feed.SiteURL.Valid}}</a>{{end}}</h1>13+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">{{if .Feed.SiteURL.Valid}}<a href="{{.Feed.SiteURL.String}}" target="_blank" rel="noopener noreferrer" class="hover:text-spot-green transition">{{end}}{{if .Feed.Title.Valid}}{{.Feed.Title.String}}{{else}}{{.Feed.FeedURL}}{{end}}{{if .Feed.SiteURL.Valid}}</a>{{end}}</h1>
14 {{if .Feed.SiteURL.Valid}}<a href="{{.Feed.SiteURL.String}}" target="_blank" rel="noopener noreferrer" class="text-xs text-spot-secondary hover:text-spot-green transition">{{.Feed.SiteURL.String}}</a>{{end}}14 {{if .Feed.SiteURL.Valid}}<a href="{{.Feed.SiteURL.String}}" target="_blank" rel="noopener noreferrer" class="text-xs text-spot-secondary hover:text-spot-green transition">{{.Feed.SiteURL.String}}</a>{{end}}
15 </div>15 </div>
16 </div>16 </div>
@@ -30,11 +30,11 @@
30 {{end}}30 {{end}}
31 </div>31 </div>
32 </div>32 </div>
33- {{if .Feed.Description.Valid}}<p class="text-sm text-spot-secondary mt-2">{{.Feed.Description.String}}</p>{{end}}33+ {{if .Feed.Description.Valid}}<p class="text-sm text-spot-secondary mt-3 leading-relaxed">{{.Feed.Description.String}}</p>{{end}}
34 </div>34 </div>
35 {{else}}35 {{else}}
36 <div class="flex items-center justify-between mb-2">36 <div class="flex items-center justify-between mb-2">
37- <h1 class="text-2xl font-bold text-spot-text">Articles</h1>37+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">Articles</h1>
38 <form hx-post="/articles/mark-all-read" hx-confirm="Mark all articles as read?">38 <form hx-post="/articles/mark-all-read" hx-confirm="Mark all articles as read?">
39 {{csrfInput .CSRFToken}}39 {{csrfInput .CSRFToken}}
40 <button type="submit" class="border border-spot-outline text-spot-text rounded-pill px-4 py-1.5 text-xs font-bold uppercase tracking-button hover:border-spot-text transition">Mark all read</button>40 <button type="submit" class="border border-spot-outline text-spot-text rounded-pill px-4 py-1.5 text-xs font-bold uppercase tracking-button hover:border-spot-text transition">Mark all read</button>
@@ -47,26 +47,26 @@
47 <form method="GET" action="/articles" class="flex-1" id="search-form">47 <form method="GET" action="/articles" class="flex-1" id="search-form">
48 <div class="relative">48 <div class="relative">
49 <input type="text" name="q" value="{{.SearchQuery}}" placeholder="Search articles..."49 <input type="text" name="q" value="{{.SearchQuery}}" placeholder="Search articles..."
50- class="w-full bg-spot-hover text-spot-text rounded-pill pl-10 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"50+ class="w-full bg-spot-hover text-spot-text rounded-pill pl-10 pr-4 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"
51 hx-get="/articles" hx-trigger="keyup changed delay:300ms, search" hx-target="#article-list" hx-swap="innerHTML" hx-include="[name='q']">51 hx-get="/articles" hx-trigger="keyup changed delay:300ms, search" hx-target="#article-list" hx-swap="innerHTML" hx-include="[name='q']">
52 <svg class="w-4 h-4 text-spot-muted absolute left-3.5 top-1/2 -translate-y-1/2 pointer-events-none" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>52 <svg class="w-4 h-4 text-spot-muted absolute left-3.5 top-1/2 -translate-y-1/2 pointer-events-none" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
53 {{if .FeedURL}}<input type="hidden" name="feed" value="{{.FeedURL}}">{{end}}53 {{if .FeedURL}}<input type="hidden" name="feed" value="{{.FeedURL}}">{{end}}
54 {{if .Status}}<input type="hidden" name="status" value="{{.Status}}">{{end}}54 {{if .Status}}<input type="hidden" name="status" value="{{.Status}}">{{end}}
55 </div>55 </div>
56 </form>56 </form>
57- <div class="flex items-center gap-2 shrink-0">57+ <div class="flex items-center gap-1.5 shrink-0">
58 <a href="/articles?status=all{{if .FeedURL}}&feed={{.FeedURL}}{{end}}"58 <a href="/articles?status=all{{if .FeedURL}}&feed={{.FeedURL}}{{end}}"
59- class="px-4 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition59+ class="px-3.5 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition
60 {{if eq .Status "all"}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">60 {{if eq .Status "all"}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">
61 All61 All
62 </a>62 </a>
63 <a href="/articles?status=unread{{if .FeedURL}}&feed={{.FeedURL}}{{end}}"63 <a href="/articles?status=unread{{if .FeedURL}}&feed={{.FeedURL}}{{end}}"
64- class="px-4 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition64+ class="px-3.5 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition
65 {{if or (eq .Status "unread") (eq .Status "")}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">65 {{if or (eq .Status "unread") (eq .Status "")}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">
66 Unread66 Unread
67 </a>67 </a>
68 <a href="/articles?status=read{{if .FeedURL}}&feed={{.FeedURL}}{{end}}"68 <a href="/articles?status=read{{if .FeedURL}}&feed={{.FeedURL}}{{end}}"
69- class="px-4 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition69+ class="px-3.5 py-1.5 rounded-pill text-xs font-bold uppercase tracking-button transition
70 {{if eq .Status "read"}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">70 {{if eq .Status "read"}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">
71 Read71 Read
72 </a>72 </a>
modified internal/tmpl/base.html +50 -48
@@ -52,62 +52,66 @@
5252 </dialog>
5353 <dialog id="shortcuts-dialog" class="bg-spot-surface rounded-xl p-6 max-w-xs shadow-spot-elevated border border-spot-divider backdrop:bg-black/50" onclick="if(event.target===this)this.close()">
5454 <h3 class="text-sm font-bold text-spot-text uppercase tracking-wide mb-4">Keyboard shortcuts</h3>
55- <div class="space-y-2 text-sm">
56- <div class="text-spot-secondary font-bold text-xs uppercase tracking-wide">Navigation</div>
57- <div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1.5">
58- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">g</kbd><span class="text-spot-secondary">Dashboard</span>
59- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">a</kbd><span class="text-spot-secondary">Articles</span>
60- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">f</kbd><span class="text-spot-secondary">Feeds</span>
61- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">t</kbd><span class="text-spot-secondary">Trending</span>
62- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">l</kbd><span class="text-spot-secondary">Library</span>
55+ <div class="space-y-3 text-sm">
56+ <div>
57+ <div class="text-spot-secondary font-bold text-xs uppercase tracking-wide mb-2">Navigation</div>
58+ <div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1.5">
59+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">g</kbd><span class="text-spot-secondary">Dashboard</span>
60+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">a</kbd><span class="text-spot-secondary">Articles</span>
61+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">f</kbd><span class="text-spot-secondary">Feeds</span>
62+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">t</kbd><span class="text-spot-secondary">Trending</span>
63+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">l</kbd><span class="text-spot-secondary">Library</span>
64+ </div>
6365 </div>
64- <div class="text-spot-secondary font-bold text-xs uppercase tracking-wide pt-2">Articles</div>
65- <div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1.5">
66- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">j</kbd><span class="text-spot-secondary">Next article</span>
67- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">k</kbd><span class="text-spot-secondary">Previous article</span>
68- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">o</kbd><span class="text-spot-secondary">Open article</span>
69- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">m</kbd><span class="text-spot-secondary">Toggle read</span>
66+ <div>
67+ <div class="text-spot-secondary font-bold text-xs uppercase tracking-wide mb-2">Articles</div>
68+ <div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1.5">
69+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">j</kbd><span class="text-spot-secondary">Next article</span>
70+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">k</kbd><span class="text-spot-secondary">Previous article</span>
71+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">o</kbd><span class="text-spot-secondary">Open article</span>
72+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">m</kbd><span class="text-spot-secondary">Toggle read</span>
73+ </div>
7074 </div>
7175 </div>
72- <button onclick="document.getElementById('shortcuts-dialog').close()" class="mt-4 w-full text-sm text-spot-text px-4 py-2 rounded-pill border border-spot-outline hover:border-spot-text transition">Close</button>
76+ <button onclick="document.getElementById('shortcuts-dialog').close()" class="mt-5 w-full text-sm text-spot-text px-4 py-2 rounded-pill border border-spot-outline hover:border-spot-text transition">Close</button>
7377 </dialog>
7478 {{if or .User (or (eq .ActivePath "/trending") (eq .ActivePath "/stats"))}}
7579 <aside class="hidden lg:flex flex-col w-60 bg-spot-bg h-screen fixed left-0 top-0 px-3 py-4 z-20">
7680 <div class="mb-8 px-3">
7781 {{template "logo-link"}}
7882 </div>
79- <nav class="flex flex-col gap-1 text-sm">
80- <a href="/dashboard" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-md {{activeClass .ActivePath "/dashboard"}}">
81- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>
83+ <nav class="flex flex-col gap-0.5 text-sm">
84+ <a href="/dashboard" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-lg {{activeClass .ActivePath "/dashboard"}}">
85+ <svg class="w-[18px] h-[18px]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>
8286 Dashboard
8387 </a>
84- <a href="/articles" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-md {{activeClass .ActivePath "/articles"}}">
85- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>
88+ <a href="/articles" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-lg {{activeClass .ActivePath "/articles"}}">
89+ <svg class="w-[18px] h-[18px]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>
8690 Articles
8791 </a>
88- <a href="/trending" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-md {{activeClass .ActivePath "/trending"}}">
89- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/></svg>
92+ <a href="/trending" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-lg {{activeClass .ActivePath "/trending"}}">
93+ <svg class="w-[18px] h-[18px]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/></svg>
9094 Trending
9195 </a>
92- <a href="/feeds" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-md {{activeClass .ActivePath "/feeds"}}">
93- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
96+ <a href="/feeds" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-lg {{activeClass .ActivePath "/feeds"}}">
97+ <svg class="w-[18px] h-[18px]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
9498 Feeds
9599 </a>
96- <a href="/library" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-md {{activeClass .ActivePath "/library"}}">
97- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>
100+ <a href="/library" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-lg {{activeClass .ActivePath "/library"}}">
101+ <svg class="w-[18px] h-[18px]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>
98102 Library
99103 </a>
100104 </nav>
101105 <div class="mt-auto pt-4 border-t border-spot-divider-30 px-1">
102106 {{if .User}}
103107 <div class="flex items-center gap-2">
104- <a href="/profile/{{.User.DID}}" class="flex items-center gap-2 flex-1 min-w-0 px-2 py-1.5 rounded-md hover:bg-spot-hover-50 transition">
105- {{if .User.AvatarURL}}<img src="{{.User.AvatarURL}}" class="w-7 h-7 rounded-full shrink-0">{{end}}
108+ <a href="/profile/{{.User.DID}}" class="flex items-center gap-2.5 flex-1 min-w-0 px-2 py-1.5 rounded-lg hover:bg-spot-hover-50 transition">
109+ {{if .User.AvatarURL}}<img src="{{.User.AvatarURL}}" class="w-7 h-7 rounded-full shrink-0 ring-1 ring-spot-divider">{{end}}
106110 <span class="text-sm font-medium truncate text-spot-text">@{{.User.Handle}}</span>
107111 </a>
108112 <form method="POST" action="/auth/logout" class="shrink-0">
109113 {{csrfInput .CSRFToken}}
110- <button type="submit" class="text-spot-secondary hover:text-spot-red p-1.5 rounded-md hover:bg-spot-hover-50 transition" title="Logout">
114+ <button type="submit" class="text-spot-muted hover:text-spot-red p-1.5 rounded-md hover:bg-spot-hover-50 transition" title="Logout">
111115 <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>
112116 </button>
113117 </form>
@@ -124,27 +128,27 @@
124128
125129 <main id="main-content" class="{{if or .User (or (eq .ActivePath "/trending") (eq .ActivePath "/stats"))}}lg:ml-60{{end}} flex-1 min-h-screen flex flex-col">
126130 {{if or .User (or (eq .ActivePath "/trending") (eq .ActivePath "/stats"))}}
127- <div class="lg:hidden bg-spot-surface border-b border-spot-divider px-2 py-2 flex items-center justify-between sticky top-0 z-20">
131+ <div class="lg:hidden bg-spot-surface/80 backdrop-blur-lg border-b border-spot-divider px-3 py-2 flex items-center justify-between sticky top-0 z-20">
128132 {{template "logo-link"}}
129133 <div class="flex items-center gap-0.5">
130- <a href="/dashboard" class="p-1.5 rounded-md {{if eq .ActivePath "/dashboard"}}text-spot-green{{else}}text-spot-secondary hover:text-spot-text{{end}} transition" title="Dashboard">
131- <svg class="w-[1.2rem] h-[1.2rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>
134+ <a href="/dashboard" class="p-2 rounded-lg {{if eq .ActivePath "/dashboard"}}text-spot-green bg-spot-green/10{{else}}text-spot-secondary hover:text-spot-text hover:bg-spot-hover-50{{end}} transition" title="Dashboard">
135+ <svg class="w-[1.15rem] h-[1.15rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>
132136 </a>
133- <a href="/articles" class="p-1.5 rounded-md {{if eq .ActivePath "/articles"}}text-spot-green{{else}}text-spot-secondary hover:text-spot-text{{end}} transition" title="Articles">
134- <svg class="w-[1.2rem] h-[1.2rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>
137+ <a href="/articles" class="p-2 rounded-lg {{if eq .ActivePath "/articles"}}text-spot-green bg-spot-green/10{{else}}text-spot-secondary hover:text-spot-text hover:bg-spot-hover-50{{end}} transition" title="Articles">
138+ <svg class="w-[1.15rem] h-[1.15rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>
135139 </a>
136- <a href="/trending" class="p-1.5 rounded-md {{if eq .ActivePath "/trending"}}text-spot-green{{else}}text-spot-secondary hover:text-spot-text{{end}} transition" title="Trending">
137- <svg class="w-[1.2rem] h-[1.2rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/></svg>
140+ <a href="/trending" class="p-2 rounded-lg {{if eq .ActivePath "/trending"}}text-spot-green bg-spot-green/10{{else}}text-spot-secondary hover:text-spot-text hover:bg-spot-hover-50{{end}} transition" title="Trending">
141+ <svg class="w-[1.15rem] h-[1.15rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/></svg>
138142 </a>
139- <a href="/feeds" class="p-1.5 rounded-md {{if eq .ActivePath "/feeds"}}text-spot-green{{else}}text-spot-secondary hover:text-spot-text{{end}} transition" title="Feeds">
140- <svg class="w-[1.2rem] h-[1.2rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
143+ <a href="/feeds" class="p-2 rounded-lg {{if eq .ActivePath "/feeds"}}text-spot-green bg-spot-green/10{{else}}text-spot-secondary hover:text-spot-text hover:bg-spot-hover-50{{end}} transition" title="Feeds">
144+ <svg class="w-[1.15rem] h-[1.15rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
141145 </a>
142- <a href="/library" class="p-1.5 rounded-md {{if eq .ActivePath "/library"}}text-spot-green{{else}}text-spot-secondary hover:text-spot-text{{end}} transition" title="Library">
143- <svg class="w-[1.2rem] h-[1.2rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>
146+ <a href="/library" class="p-2 rounded-lg {{if eq .ActivePath "/library"}}text-spot-green bg-spot-green/10{{else}}text-spot-secondary hover:text-spot-text hover:bg-spot-hover-50{{end}} transition" title="Library">
147+ <svg class="w-[1.15rem] h-[1.15rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>
144148 </a>
145149 {{if .User}}
146150 <a href="/profile/{{.User.DID}}" class="shrink-0 ml-1" title="@{{.User.Handle}}">
147- {{if .User.AvatarURL}}<img src="{{.User.AvatarURL}}" class="w-7 h-7 rounded-full ring-1 ring-spot-divider">{{end}}
151+ {{if .User.AvatarURL}}<img src="{{.User.AvatarURL}}" class="w-7 h-7 rounded-full ring-2 ring-spot-divider">{{end}}
148152 </a>
149153 {{else}}
150154 <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-3 py-1 text-xs font-bold uppercase tracking-button hover:brightness-110 transition shrink-0 ml-1">Sign in</a>
@@ -160,7 +164,7 @@
160164 <div class="max-w-6xl mx-auto px-4 lg:px-8 py-6 lg:py-8">
161165 <div class="hidden md:grid md:grid-cols-[2fr_1fr] md:gap-8 md:items-start">
162166 <div class="grid grid-cols-3 gap-8">
163- <div class="flex flex-col gap-1.5">
167+ <div class="flex flex-col gap-2">
164168 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Browse</div>
165169 <a href="/dashboard" class="text-xs text-spot-secondary hover:text-spot-text hover:underline inline-flex gap-1.5 items-center transition">
166170 <svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>
@@ -175,7 +179,7 @@
175179 Articles
176180 </a>
177181 </div>
178- <div class="flex flex-col gap-1.5">
182+ <div class="flex flex-col gap-2">
179183 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Library</div>
180184 <a href="/feeds" class="text-xs text-spot-secondary hover:text-spot-text hover:underline inline-flex gap-1.5 items-center transition">
181185 <svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
@@ -186,7 +190,7 @@
186190 Library
187191 </a>
188192 </div>
189- <div class="flex flex-col gap-1.5">
193+ <div class="flex flex-col gap-2">
190194 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Settings</div>
191195 <button onclick="toggleTheme()" class="text-xs text-spot-secondary hover:text-spot-text hover:underline inline-flex gap-1.5 items-center transition text-left">
192196 <svg class="w-3.5 h-3.5 shrink-0 theme-icon-dark" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg>
@@ -210,13 +214,13 @@
210214
211215 <div class="md:hidden flex flex-col gap-5">
212216 <div class="grid grid-cols-2 gap-6">
213- <div class="flex flex-col gap-1.5">
217+ <div class="flex flex-col gap-2">
214218 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Browse</div>
215219 <a href="/dashboard" class="text-xs text-spot-secondary hover:text-spot-text transition">Dashboard</a>
216220 <a href="/trending" class="text-xs text-spot-secondary hover:text-spot-text transition">Trending</a>
217221 <a href="/articles" class="text-xs text-spot-secondary hover:text-spot-text transition">Articles</a>
218222 </div>
219- <div class="flex flex-col gap-1.5">
223+ <div class="flex flex-col gap-2">
220224 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Library</div>
221225 <a href="/feeds" class="text-xs text-spot-secondary hover:text-spot-text transition">Feeds</a>
222226 <a href="/library" class="text-xs text-spot-secondary hover:text-spot-text transition">Library</a>
@@ -274,8 +278,6 @@
274278
275279 applyTheme();
276280
277- // reload page when page restored from bfcache.
278- // useful for reloading article read/unread status.
279281 window.addEventListener('pageshow', function(e) {
280282 if (e.persisted) location.reload();
281283 });
@@ -52,62 +52,66 @@
52 </dialog>52 </dialog>
53 <dialog id="shortcuts-dialog" class="bg-spot-surface rounded-xl p-6 max-w-xs shadow-spot-elevated border border-spot-divider backdrop:bg-black/50" onclick="if(event.target===this)this.close()">53 <dialog id="shortcuts-dialog" class="bg-spot-surface rounded-xl p-6 max-w-xs shadow-spot-elevated border border-spot-divider backdrop:bg-black/50" onclick="if(event.target===this)this.close()">
54 <h3 class="text-sm font-bold text-spot-text uppercase tracking-wide mb-4">Keyboard shortcuts</h3>54 <h3 class="text-sm font-bold text-spot-text uppercase tracking-wide mb-4">Keyboard shortcuts</h3>
55- <div class="space-y-2 text-sm">55+ <div class="space-y-3 text-sm">
56- <div class="text-spot-secondary font-bold text-xs uppercase tracking-wide">Navigation</div>56+ <div>
57- <div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1.5">57+ <div class="text-spot-secondary font-bold text-xs uppercase tracking-wide mb-2">Navigation</div>
58- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">g</kbd><span class="text-spot-secondary">Dashboard</span>58+ <div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1.5">
59- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">a</kbd><span class="text-spot-secondary">Articles</span>59+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">g</kbd><span class="text-spot-secondary">Dashboard</span>
60- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">f</kbd><span class="text-spot-secondary">Feeds</span>60+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">a</kbd><span class="text-spot-secondary">Articles</span>
61- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">t</kbd><span class="text-spot-secondary">Trending</span>61+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">f</kbd><span class="text-spot-secondary">Feeds</span>
62- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">l</kbd><span class="text-spot-secondary">Library</span>62+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">t</kbd><span class="text-spot-secondary">Trending</span>
63+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">l</kbd><span class="text-spot-secondary">Library</span>
64+ </div>
63 </div>65 </div>
64- <div class="text-spot-secondary font-bold text-xs uppercase tracking-wide pt-2">Articles</div>66+ <div>
65- <div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1.5">67+ <div class="text-spot-secondary font-bold text-xs uppercase tracking-wide mb-2">Articles</div>
66- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">j</kbd><span class="text-spot-secondary">Next article</span>68+ <div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1.5">
67- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">k</kbd><span class="text-spot-secondary">Previous article</span>69+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">j</kbd><span class="text-spot-secondary">Next article</span>
68- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">o</kbd><span class="text-spot-secondary">Open article</span>70+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">k</kbd><span class="text-spot-secondary">Previous article</span>
69- <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">m</kbd><span class="text-spot-secondary">Toggle read</span>71+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">o</kbd><span class="text-spot-secondary">Open article</span>
72+ <kbd class="text-spot-text bg-spot-hover rounded px-1.5 py-0.5 text-xs font-mono text-center min-w-[28px]">m</kbd><span class="text-spot-secondary">Toggle read</span>
73+ </div>
70 </div>74 </div>
71 </div>75 </div>
72- <button onclick="document.getElementById('shortcuts-dialog').close()" class="mt-4 w-full text-sm text-spot-text px-4 py-2 rounded-pill border border-spot-outline hover:border-spot-text transition">Close</button>76+ <button onclick="document.getElementById('shortcuts-dialog').close()" class="mt-5 w-full text-sm text-spot-text px-4 py-2 rounded-pill border border-spot-outline hover:border-spot-text transition">Close</button>
73 </dialog>77 </dialog>
74 {{if or .User (or (eq .ActivePath "/trending") (eq .ActivePath "/stats"))}}78 {{if or .User (or (eq .ActivePath "/trending") (eq .ActivePath "/stats"))}}
75 <aside class="hidden lg:flex flex-col w-60 bg-spot-bg h-screen fixed left-0 top-0 px-3 py-4 z-20">79 <aside class="hidden lg:flex flex-col w-60 bg-spot-bg h-screen fixed left-0 top-0 px-3 py-4 z-20">
76 <div class="mb-8 px-3">80 <div class="mb-8 px-3">
77 {{template "logo-link"}}81 {{template "logo-link"}}
78 </div>82 </div>
79- <nav class="flex flex-col gap-1 text-sm">83+ <nav class="flex flex-col gap-0.5 text-sm">
80- <a href="/dashboard" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-md {{activeClass .ActivePath "/dashboard"}}">84+ <a href="/dashboard" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-lg {{activeClass .ActivePath "/dashboard"}}">
81- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>85+ <svg class="w-[18px] h-[18px]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>
82 Dashboard86 Dashboard
83 </a>87 </a>
84- <a href="/articles" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-md {{activeClass .ActivePath "/articles"}}">88+ <a href="/articles" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-lg {{activeClass .ActivePath "/articles"}}">
85- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>89+ <svg class="w-[18px] h-[18px]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>
86 Articles90 Articles
87 </a>91 </a>
88- <a href="/trending" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-md {{activeClass .ActivePath "/trending"}}">92+ <a href="/trending" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-lg {{activeClass .ActivePath "/trending"}}">
89- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/></svg>93+ <svg class="w-[18px] h-[18px]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/></svg>
90 Trending94 Trending
91 </a>95 </a>
92- <a href="/feeds" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-md {{activeClass .ActivePath "/feeds"}}">96+ <a href="/feeds" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-lg {{activeClass .ActivePath "/feeds"}}">
93- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>97+ <svg class="w-[18px] h-[18px]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
94 Feeds98 Feeds
95 </a>99 </a>
96- <a href="/library" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-md {{activeClass .ActivePath "/library"}}">100+ <a href="/library" class="sidebar-link flex items-center gap-3 px-3 py-2 rounded-lg {{activeClass .ActivePath "/library"}}">
97- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>101+ <svg class="w-[18px] h-[18px]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>
98 Library102 Library
99 </a>103 </a>
100 </nav>104 </nav>
101 <div class="mt-auto pt-4 border-t border-spot-divider-30 px-1">105 <div class="mt-auto pt-4 border-t border-spot-divider-30 px-1">
102 {{if .User}}106 {{if .User}}
103 <div class="flex items-center gap-2">107 <div class="flex items-center gap-2">
104- <a href="/profile/{{.User.DID}}" class="flex items-center gap-2 flex-1 min-w-0 px-2 py-1.5 rounded-md hover:bg-spot-hover-50 transition">108+ <a href="/profile/{{.User.DID}}" class="flex items-center gap-2.5 flex-1 min-w-0 px-2 py-1.5 rounded-lg hover:bg-spot-hover-50 transition">
105- {{if .User.AvatarURL}}<img src="{{.User.AvatarURL}}" class="w-7 h-7 rounded-full shrink-0">{{end}}109+ {{if .User.AvatarURL}}<img src="{{.User.AvatarURL}}" class="w-7 h-7 rounded-full shrink-0 ring-1 ring-spot-divider">{{end}}
106 <span class="text-sm font-medium truncate text-spot-text">@{{.User.Handle}}</span>110 <span class="text-sm font-medium truncate text-spot-text">@{{.User.Handle}}</span>
107 </a>111 </a>
108 <form method="POST" action="/auth/logout" class="shrink-0">112 <form method="POST" action="/auth/logout" class="shrink-0">
109 {{csrfInput .CSRFToken}}113 {{csrfInput .CSRFToken}}
110- <button type="submit" class="text-spot-secondary hover:text-spot-red p-1.5 rounded-md hover:bg-spot-hover-50 transition" title="Logout">114+ <button type="submit" class="text-spot-muted hover:text-spot-red p-1.5 rounded-md hover:bg-spot-hover-50 transition" title="Logout">
111 <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>115 <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"/></svg>
112 </button>116 </button>
113 </form>117 </form>
@@ -124,27 +128,27 @@
124 128
125 <main id="main-content" class="{{if or .User (or (eq .ActivePath "/trending") (eq .ActivePath "/stats"))}}lg:ml-60{{end}} flex-1 min-h-screen flex flex-col">129 <main id="main-content" class="{{if or .User (or (eq .ActivePath "/trending") (eq .ActivePath "/stats"))}}lg:ml-60{{end}} flex-1 min-h-screen flex flex-col">
126 {{if or .User (or (eq .ActivePath "/trending") (eq .ActivePath "/stats"))}}130 {{if or .User (or (eq .ActivePath "/trending") (eq .ActivePath "/stats"))}}
127- <div class="lg:hidden bg-spot-surface border-b border-spot-divider px-2 py-2 flex items-center justify-between sticky top-0 z-20">131+ <div class="lg:hidden bg-spot-surface/80 backdrop-blur-lg border-b border-spot-divider px-3 py-2 flex items-center justify-between sticky top-0 z-20">
128 {{template "logo-link"}}132 {{template "logo-link"}}
129 <div class="flex items-center gap-0.5">133 <div class="flex items-center gap-0.5">
130- <a href="/dashboard" class="p-1.5 rounded-md {{if eq .ActivePath "/dashboard"}}text-spot-green{{else}}text-spot-secondary hover:text-spot-text{{end}} transition" title="Dashboard">134+ <a href="/dashboard" class="p-2 rounded-lg {{if eq .ActivePath "/dashboard"}}text-spot-green bg-spot-green/10{{else}}text-spot-secondary hover:text-spot-text hover:bg-spot-hover-50{{end}} transition" title="Dashboard">
131- <svg class="w-[1.2rem] h-[1.2rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>135+ <svg class="w-[1.15rem] h-[1.15rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>
132 </a>136 </a>
133- <a href="/articles" class="p-1.5 rounded-md {{if eq .ActivePath "/articles"}}text-spot-green{{else}}text-spot-secondary hover:text-spot-text{{end}} transition" title="Articles">137+ <a href="/articles" class="p-2 rounded-lg {{if eq .ActivePath "/articles"}}text-spot-green bg-spot-green/10{{else}}text-spot-secondary hover:text-spot-text hover:bg-spot-hover-50{{end}} transition" title="Articles">
134- <svg class="w-[1.2rem] h-[1.2rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>138+ <svg class="w-[1.15rem] h-[1.15rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>
135 </a>139 </a>
136- <a href="/trending" class="p-1.5 rounded-md {{if eq .ActivePath "/trending"}}text-spot-green{{else}}text-spot-secondary hover:text-spot-text{{end}} transition" title="Trending">140+ <a href="/trending" class="p-2 rounded-lg {{if eq .ActivePath "/trending"}}text-spot-green bg-spot-green/10{{else}}text-spot-secondary hover:text-spot-text hover:bg-spot-hover-50{{end}} transition" title="Trending">
137- <svg class="w-[1.2rem] h-[1.2rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/></svg>141+ <svg class="w-[1.15rem] h-[1.15rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6"/></svg>
138 </a>142 </a>
139- <a href="/feeds" class="p-1.5 rounded-md {{if eq .ActivePath "/feeds"}}text-spot-green{{else}}text-spot-secondary hover:text-spot-text{{end}} transition" title="Feeds">143+ <a href="/feeds" class="p-2 rounded-lg {{if eq .ActivePath "/feeds"}}text-spot-green bg-spot-green/10{{else}}text-spot-secondary hover:text-spot-text hover:bg-spot-hover-50{{end}} transition" title="Feeds">
140- <svg class="w-[1.2rem] h-[1.2rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>144+ <svg class="w-[1.15rem] h-[1.15rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
141 </a>145 </a>
142- <a href="/library" class="p-1.5 rounded-md {{if eq .ActivePath "/library"}}text-spot-green{{else}}text-spot-secondary hover:text-spot-text{{end}} transition" title="Library">146+ <a href="/library" class="p-2 rounded-lg {{if eq .ActivePath "/library"}}text-spot-green bg-spot-green/10{{else}}text-spot-secondary hover:text-spot-text hover:bg-spot-hover-50{{end}} transition" title="Library">
143- <svg class="w-[1.2rem] h-[1.2rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>147+ <svg class="w-[1.15rem] h-[1.15rem]" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>
144 </a>148 </a>
145 {{if .User}}149 {{if .User}}
146 <a href="/profile/{{.User.DID}}" class="shrink-0 ml-1" title="@{{.User.Handle}}">150 <a href="/profile/{{.User.DID}}" class="shrink-0 ml-1" title="@{{.User.Handle}}">
147- {{if .User.AvatarURL}}<img src="{{.User.AvatarURL}}" class="w-7 h-7 rounded-full ring-1 ring-spot-divider">{{end}}151+ {{if .User.AvatarURL}}<img src="{{.User.AvatarURL}}" class="w-7 h-7 rounded-full ring-2 ring-spot-divider">{{end}}
148 </a>152 </a>
149 {{else}}153 {{else}}
150 <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-3 py-1 text-xs font-bold uppercase tracking-button hover:brightness-110 transition shrink-0 ml-1">Sign in</a>154 <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-3 py-1 text-xs font-bold uppercase tracking-button hover:brightness-110 transition shrink-0 ml-1">Sign in</a>
@@ -160,7 +164,7 @@
160 <div class="max-w-6xl mx-auto px-4 lg:px-8 py-6 lg:py-8">164 <div class="max-w-6xl mx-auto px-4 lg:px-8 py-6 lg:py-8">
161 <div class="hidden md:grid md:grid-cols-[2fr_1fr] md:gap-8 md:items-start">165 <div class="hidden md:grid md:grid-cols-[2fr_1fr] md:gap-8 md:items-start">
162 <div class="grid grid-cols-3 gap-8">166 <div class="grid grid-cols-3 gap-8">
163- <div class="flex flex-col gap-1.5">167+ <div class="flex flex-col gap-2">
164 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Browse</div>168 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Browse</div>
165 <a href="/dashboard" class="text-xs text-spot-secondary hover:text-spot-text hover:underline inline-flex gap-1.5 items-center transition">169 <a href="/dashboard" class="text-xs text-spot-secondary hover:text-spot-text hover:underline inline-flex gap-1.5 items-center transition">
166 <svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>170 <svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0a1 1 0 01-1-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 01-1 1"/></svg>
@@ -175,7 +179,7 @@
175 Articles179 Articles
176 </a>180 </a>
177 </div>181 </div>
178- <div class="flex flex-col gap-1.5">182+ <div class="flex flex-col gap-2">
179 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Library</div>183 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Library</div>
180 <a href="/feeds" class="text-xs text-spot-secondary hover:text-spot-text hover:underline inline-flex gap-1.5 items-center transition">184 <a href="/feeds" class="text-xs text-spot-secondary hover:text-spot-text hover:underline inline-flex gap-1.5 items-center transition">
181 <svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>185 <svg class="w-3.5 h-3.5 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
@@ -186,7 +190,7 @@
186 Library190 Library
187 </a>191 </a>
188 </div>192 </div>
189- <div class="flex flex-col gap-1.5">193+ <div class="flex flex-col gap-2">
190 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Settings</div>194 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Settings</div>
191 <button onclick="toggleTheme()" class="text-xs text-spot-secondary hover:text-spot-text hover:underline inline-flex gap-1.5 items-center transition text-left">195 <button onclick="toggleTheme()" class="text-xs text-spot-secondary hover:text-spot-text hover:underline inline-flex gap-1.5 items-center transition text-left">
192 <svg class="w-3.5 h-3.5 shrink-0 theme-icon-dark" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg>196 <svg class="w-3.5 h-3.5 shrink-0 theme-icon-dark" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"/></svg>
@@ -210,13 +214,13 @@
210 214
211 <div class="md:hidden flex flex-col gap-5">215 <div class="md:hidden flex flex-col gap-5">
212 <div class="grid grid-cols-2 gap-6">216 <div class="grid grid-cols-2 gap-6">
213- <div class="flex flex-col gap-1.5">217+ <div class="flex flex-col gap-2">
214 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Browse</div>218 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Browse</div>
215 <a href="/dashboard" class="text-xs text-spot-secondary hover:text-spot-text transition">Dashboard</a>219 <a href="/dashboard" class="text-xs text-spot-secondary hover:text-spot-text transition">Dashboard</a>
216 <a href="/trending" class="text-xs text-spot-secondary hover:text-spot-text transition">Trending</a>220 <a href="/trending" class="text-xs text-spot-secondary hover:text-spot-text transition">Trending</a>
217 <a href="/articles" class="text-xs text-spot-secondary hover:text-spot-text transition">Articles</a>221 <a href="/articles" class="text-xs text-spot-secondary hover:text-spot-text transition">Articles</a>
218 </div>222 </div>
219- <div class="flex flex-col gap-1.5">223+ <div class="flex flex-col gap-2">
220 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Library</div>224 <div class="text-spot-text font-bold text-xs uppercase tracking-wide mb-1">Library</div>
221 <a href="/feeds" class="text-xs text-spot-secondary hover:text-spot-text transition">Feeds</a>225 <a href="/feeds" class="text-xs text-spot-secondary hover:text-spot-text transition">Feeds</a>
222 <a href="/library" class="text-xs text-spot-secondary hover:text-spot-text transition">Library</a>226 <a href="/library" class="text-xs text-spot-secondary hover:text-spot-text transition">Library</a>
@@ -274,8 +278,6 @@
274 278
275 applyTheme();279 applyTheme();
276 280
277- // reload page when page restored from bfcache.
278- // useful for reloading article read/unread status.
279 window.addEventListener('pageshow', function(e) {281 window.addEventListener('pageshow', function(e) {
280 if (e.persisted) location.reload();282 if (e.persisted) location.reload();
281 });283 });
modified internal/tmpl/dashboard.html +14 -14
@@ -1,6 +1,6 @@
11 {{define "dashboard.html"}}
22 <div class="flex items-center justify-between mb-2">
3- <h1 class="text-2xl font-bold text-spot-text">Dashboard</h1>
3+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">Dashboard</h1>
44 {{if gt .SubscriptionCount 0}}
55 <div class="flex gap-4 text-sm">
66 <span class="text-spot-secondary"><strong class="text-spot-text">{{.UnreadCount}}</strong> unread</span>
@@ -15,13 +15,13 @@
1515 {{if eq .SubscriptionCount 0}}
1616 <div id="new-articles-poll" hx-get="/articles/new-count?since={{.Now.Unix}}&return=/dashboard" hx-trigger="every 30s" hx-swap="innerHTML"></div>
1717
18-<div class="bg-spot-surface rounded-xl py-12 px-6 text-center mb-8">
19- <div class="w-16 h-16 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">
20- <svg class="w-8 h-8 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12.75 19.5v-15m0 0l-6.75 6.75M12.75 4.5l6.75 6.75"/></svg>
18+<div class="bg-spot-surface rounded-2xl py-12 px-6 text-center mb-8">
19+ <div class="w-16 h-16 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
20+ <svg class="w-8 h-8 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12.75 19.5v-15m0 0l-6.75 6.75M12.75 4.5l6.75 6.75"/></svg>
2121 </div>
2222 <h2 class="text-lg font-semibold text-spot-text mb-2">Add your first feed</h2>
23- <p class="text-sm text-spot-secondary mb-6">Subscribe to RSS feeds to start building your personalized reading experience.</p>
24- <a href="/feeds" class="inline-flex items-center gap-2 px-5 py-2.5 rounded-lg bg-spot-green text-white text-sm font-medium hover:opacity-90 transition">
23+ <p class="text-sm text-spot-secondary mb-6 max-w-xs mx-auto">Subscribe to RSS feeds to start building your personalized reading experience.</p>
24+ <a href="/feeds" class="inline-flex items-center gap-2 px-5 py-2.5 rounded-pill bg-spot-green text-white text-sm font-bold uppercase tracking-button hover:brightness-110 transition">
2525 <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>
2626 Add feeds
2727 </a>
@@ -29,7 +29,7 @@
2929
3030 {{if .GlobalTrending}}
3131 <div class="mb-8">
32- <div class="flex items-center justify-between mb-3">
32+ <div class="flex items-center justify-between mb-4">
3333 <h2 class="text-lg font-semibold text-spot-text">Trending</h2>
3434 <a href="/trending" class="text-xs text-spot-secondary hover:text-spot-green uppercase tracking-button transition">See all</a>
3535 </div>
@@ -59,8 +59,8 @@
5959 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
6060 <div class="lg:col-span-2">
6161 {{if .ArticleRecommendations}}
62- <div class="mb-6">
63- <h2 class="text-lg font-semibold text-spot-text mb-3">Recommended for you</h2>
62+ <div class="mb-8">
63+ <h2 class="text-lg font-semibold text-spot-text mb-4">Recommended for you</h2>
6464 <div class="space-y-3">
6565 {{range .ArticleRecommendations}}
6666 {{template "recommendation-article-card.html" .}}
@@ -69,7 +69,7 @@
6969 </div>
7070 {{end}}
7171
72- <h2 class="text-lg font-semibold text-spot-text mb-3">Unread articles</h2>
72+ <h2 class="text-lg font-semibold text-spot-text mb-4">Unread articles</h2>
7373 <div id="article-list" class="space-y-3">
7474 {{range .Articles}}
7575 {{template "article-card.html" .}}
@@ -105,7 +105,7 @@
105105 </div>
106106 {{end}}
107107 {{if .DiscoverPeople}}
108- <h2 class="text-lg font-semibold text-spot-text mb-4 {{if .FollowedPeople}}mt-6{{end}}">Discover new readers</h2>
108+ <h2 class="text-lg font-semibold text-spot-text mb-4 {{if .FollowedPeople}}mt-8{{end}}">Discover new readers</h2>
109109 <div class="space-y-3">
110110 {{range .DiscoverPeople}}
111111 {{template "profile-card.html" .}}
@@ -129,8 +129,8 @@
129129 </div>
130130 {{else}}
131131 <div id="article-list"></div>
132-<div class="bg-spot-surface rounded-xl py-16 px-6 text-center mb-8">
133- <div class="w-16 h-16 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">
132+<div class="bg-spot-surface rounded-2xl py-14 px-6 text-center mb-8">
133+ <div class="w-16 h-16 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
134134 <svg class="w-8 h-8 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
135135 </div>
136136 <h2 class="text-xl font-semibold text-spot-text mb-2">You're all caught up!</h2>
@@ -139,7 +139,7 @@
139139
140140 {{if .ArticleRecommendations}}
141141 <div class="mb-8">
142- <h2 class="text-lg font-semibold text-spot-text mb-3">Recommended for you</h2>
142+ <h2 class="text-lg font-semibold text-spot-text mb-4">Recommended for you</h2>
143143 <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
144144 {{range .ArticleRecommendations}}
145145 {{template "recommendation-article-card.html" .}}
@@ -1,6 +1,6 @@
1 {{define "dashboard.html"}}1 {{define "dashboard.html"}}
2 <div class="flex items-center justify-between mb-2">2 <div class="flex items-center justify-between mb-2">
3- <h1 class="text-2xl font-bold text-spot-text">Dashboard</h1>3+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">Dashboard</h1>
4 {{if gt .SubscriptionCount 0}}4 {{if gt .SubscriptionCount 0}}
5 <div class="flex gap-4 text-sm">5 <div class="flex gap-4 text-sm">
6 <span class="text-spot-secondary"><strong class="text-spot-text">{{.UnreadCount}}</strong> unread</span>6 <span class="text-spot-secondary"><strong class="text-spot-text">{{.UnreadCount}}</strong> unread</span>
@@ -15,13 +15,13 @@
15 {{if eq .SubscriptionCount 0}}15 {{if eq .SubscriptionCount 0}}
16 <div id="new-articles-poll" hx-get="/articles/new-count?since={{.Now.Unix}}&return=/dashboard" hx-trigger="every 30s" hx-swap="innerHTML"></div>16 <div id="new-articles-poll" hx-get="/articles/new-count?since={{.Now.Unix}}&return=/dashboard" hx-trigger="every 30s" hx-swap="innerHTML"></div>
17 17
18-<div class="bg-spot-surface rounded-xl py-12 px-6 text-center mb-8">18+<div class="bg-spot-surface rounded-2xl py-12 px-6 text-center mb-8">
19- <div class="w-16 h-16 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">19+ <div class="w-16 h-16 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
20- <svg class="w-8 h-8 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12.75 19.5v-15m0 0l-6.75 6.75M12.75 4.5l6.75 6.75"/></svg>20+ <svg class="w-8 h-8 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12.75 19.5v-15m0 0l-6.75 6.75M12.75 4.5l6.75 6.75"/></svg>
21 </div>21 </div>
22 <h2 class="text-lg font-semibold text-spot-text mb-2">Add your first feed</h2>22 <h2 class="text-lg font-semibold text-spot-text mb-2">Add your first feed</h2>
23- <p class="text-sm text-spot-secondary mb-6">Subscribe to RSS feeds to start building your personalized reading experience.</p>23+ <p class="text-sm text-spot-secondary mb-6 max-w-xs mx-auto">Subscribe to RSS feeds to start building your personalized reading experience.</p>
24- <a href="/feeds" class="inline-flex items-center gap-2 px-5 py-2.5 rounded-lg bg-spot-green text-white text-sm font-medium hover:opacity-90 transition">24+ <a href="/feeds" class="inline-flex items-center gap-2 px-5 py-2.5 rounded-pill bg-spot-green text-white text-sm font-bold uppercase tracking-button hover:brightness-110 transition">
25 <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>25 <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15"/></svg>
26 Add feeds26 Add feeds
27 </a>27 </a>
@@ -29,7 +29,7 @@
29 29
30 {{if .GlobalTrending}}30 {{if .GlobalTrending}}
31 <div class="mb-8">31 <div class="mb-8">
32- <div class="flex items-center justify-between mb-3">32+ <div class="flex items-center justify-between mb-4">
33 <h2 class="text-lg font-semibold text-spot-text">Trending</h2>33 <h2 class="text-lg font-semibold text-spot-text">Trending</h2>
34 <a href="/trending" class="text-xs text-spot-secondary hover:text-spot-green uppercase tracking-button transition">See all</a>34 <a href="/trending" class="text-xs text-spot-secondary hover:text-spot-green uppercase tracking-button transition">See all</a>
35 </div>35 </div>
@@ -59,8 +59,8 @@
59 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">59 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
60 <div class="lg:col-span-2">60 <div class="lg:col-span-2">
61 {{if .ArticleRecommendations}}61 {{if .ArticleRecommendations}}
62- <div class="mb-6">62+ <div class="mb-8">
63- <h2 class="text-lg font-semibold text-spot-text mb-3">Recommended for you</h2>63+ <h2 class="text-lg font-semibold text-spot-text mb-4">Recommended for you</h2>
64 <div class="space-y-3">64 <div class="space-y-3">
65 {{range .ArticleRecommendations}}65 {{range .ArticleRecommendations}}
66 {{template "recommendation-article-card.html" .}}66 {{template "recommendation-article-card.html" .}}
@@ -69,7 +69,7 @@
69 </div>69 </div>
70 {{end}}70 {{end}}
71 71
72- <h2 class="text-lg font-semibold text-spot-text mb-3">Unread articles</h2>72+ <h2 class="text-lg font-semibold text-spot-text mb-4">Unread articles</h2>
73 <div id="article-list" class="space-y-3">73 <div id="article-list" class="space-y-3">
74 {{range .Articles}}74 {{range .Articles}}
75 {{template "article-card.html" .}}75 {{template "article-card.html" .}}
@@ -105,7 +105,7 @@
105 </div>105 </div>
106 {{end}}106 {{end}}
107 {{if .DiscoverPeople}}107 {{if .DiscoverPeople}}
108- <h2 class="text-lg font-semibold text-spot-text mb-4 {{if .FollowedPeople}}mt-6{{end}}">Discover new readers</h2>108+ <h2 class="text-lg font-semibold text-spot-text mb-4 {{if .FollowedPeople}}mt-8{{end}}">Discover new readers</h2>
109 <div class="space-y-3">109 <div class="space-y-3">
110 {{range .DiscoverPeople}}110 {{range .DiscoverPeople}}
111 {{template "profile-card.html" .}}111 {{template "profile-card.html" .}}
@@ -129,8 +129,8 @@
129 </div>129 </div>
130 {{else}}130 {{else}}
131 <div id="article-list"></div>131 <div id="article-list"></div>
132-<div class="bg-spot-surface rounded-xl py-16 px-6 text-center mb-8">132+<div class="bg-spot-surface rounded-2xl py-14 px-6 text-center mb-8">
133- <div class="w-16 h-16 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">133+ <div class="w-16 h-16 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
134 <svg class="w-8 h-8 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>134 <svg class="w-8 h-8 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
135 </div>135 </div>
136 <h2 class="text-xl font-semibold text-spot-text mb-2">You're all caught up!</h2>136 <h2 class="text-xl font-semibold text-spot-text mb-2">You're all caught up!</h2>
@@ -139,7 +139,7 @@
139 139
140 {{if .ArticleRecommendations}}140 {{if .ArticleRecommendations}}
141 <div class="mb-8">141 <div class="mb-8">
142- <h2 class="text-lg font-semibold text-spot-text mb-3">Recommended for you</h2>142+ <h2 class="text-lg font-semibold text-spot-text mb-4">Recommended for you</h2>
143 <div class="grid grid-cols-1 md:grid-cols-2 gap-3">143 <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
144 {{range .ArticleRecommendations}}144 {{range .ArticleRecommendations}}
145 {{template "recommendation-article-card.html" .}}145 {{template "recommendation-article-card.html" .}}
modified internal/tmpl/error.html +4 -4
@@ -1,12 +1,12 @@
11 {{define "error.html"}}
22 <div class="flex items-center justify-center min-h-screen px-4 py-12">
3- <div class="max-w-sm w-full">
3+ <div class="max-w-sm w-full text-center">
44 <div class="flex justify-center mb-8">
55 <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a>
66 </div>
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">
7+ <h1 class="text-2xl font-bold text-spot-text mb-2">{{.Title}}</h1>
8+ <p class="text-spot-secondary text-sm mb-8">{{.Message}}</p>
9+ <a href="/dashboard" class="inline-flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-6 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">
1010 Back to Dashboard
1111 </a>
1212 </div>
@@ -1,12 +1,12 @@
1 {{define "error.html"}}1 {{define "error.html"}}
2 <div class="flex items-center justify-center min-h-screen px-4 py-12">2 <div class="flex items-center justify-center min-h-screen px-4 py-12">
3- <div class="max-w-sm w-full">3+ <div class="max-w-sm w-full text-center">
4 <div class="flex justify-center mb-8">4 <div class="flex justify-center mb-8">
5 <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a>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-1 text-center">{{.Title}}</h1>7+ <h1 class="text-2xl font-bold text-spot-text mb-2">{{.Title}}</h1>
8- <p class="text-spot-secondary text-sm mb-8 text-center">{{.Message}}</p>8+ <p class="text-spot-secondary text-sm mb-8">{{.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">9+ <a href="/dashboard" class="inline-flex items-center justify-center gap-2 bg-spot-green text-white rounded-pill px-6 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">
10 Back to Dashboard10 Back to Dashboard
11 </a>11 </a>
12 </div>12 </div>
modified internal/tmpl/feeds.html +12 -12
@@ -1,6 +1,6 @@
11 {{define "feeds.html"}}
22 <div class="flex items-center justify-between gap-3 mb-2 flex-wrap">
3- <h1 class="text-2xl font-bold text-spot-text">Feeds <span class="text-base font-normal text-spot-secondary">({{.SubscriptionCount}})</span></h1>
3+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">Feeds <span class="text-base font-normal text-spot-secondary">({{.SubscriptionCount}})</span></h1>
44 <div class="flex items-center gap-3">
55 <button id="refresh-btn"
66 hx-post="/feeds/refresh" hx-target="#feed-list" hx-swap="innerHTML"
@@ -34,7 +34,7 @@ function gleanRefreshPoll(){setTimeout(function(){htmx.ajax('GET','/feeds/list',
3434 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
3535 <div class="lg:col-span-2">
3636 {{if .Categories}}
37- <div class="flex gap-2 mb-6 flex-wrap">
37+ <div class="flex gap-1.5 mb-6 flex-wrap">
3838 <a href="/feeds" class="text-sm px-4 py-1.5 rounded-pill font-bold {{if not .Category}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}} transition">All</a>
3939 {{range .Categories}}
4040 <a href="/feeds?category={{.}}" class="text-sm px-4 py-1.5 rounded-pill font-bold {{if eq $.Category .}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}} transition">{{.}}</a>
@@ -42,16 +42,16 @@ function gleanRefreshPoll(){setTimeout(function(){htmx.ajax('GET','/feeds/list',
4242 </div>
4343 {{end}}
4444
45- <div id="feed-list" class="bg-spot-surface rounded-xl divide-y divide-spot-divider">
45+ <div id="feed-list" class="bg-spot-surface rounded-xl divide-y divide-spot-divider overflow-hidden">
4646 {{range .Subscriptions}}
4747 {{template "feed-item.html" dict "FeedURL" .FeedURL "FeedTitle" .FeedTitle "Category" .Category "FaviconURL" .FaviconURL "UnreadCount" .UnreadCount "CSRFToken" $.CSRFToken}}
4848 {{else}}
4949 <div class="flex flex-col items-center justify-center py-12 px-6 text-center">
50- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">
51- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
50+ <div class="w-14 h-14 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-4 mx-auto">
51+ <svg class="w-7 h-7 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
5252 </div>
53- <p class="text-sm text-spot-secondary mb-1">No feeds yet</p>
54- <p class="text-xs text-spot-muted">Add one from the sidebar to get started.</p>
53+ <p class="text-sm text-spot-text font-semibold mb-1">No feeds yet</p>
54+ <p class="text-xs text-spot-muted">Add one using the form on the right to get started.</p>
5555 </div>
5656 {{end}}
5757 </div>
@@ -68,16 +68,16 @@ function gleanRefreshPoll(){setTimeout(function(){htmx.ajax('GET','/feeds/list',
6868 class="space-y-3">
6969 {{csrfInput .CSRFToken}}
7070 <input type="text" name="feed_url" placeholder="https://example.com/feed.xml or at://did:plc:.../site.standard.publication/..."
71- class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"
71+ class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"
7272 required>
7373 <input type="text" name="category" placeholder="Category (optional)"
74- class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">
75- <button type="submit" class="w-full bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>
74+ class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">
75+ <button type="submit" class="w-full bg-spot-green text-white rounded-pill px-5 py-2.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>
7676 </form>
7777 <div id="add-feed-error" class="text-sm text-spot-red"></div>
7878 <div class="border-t border-spot-divider pt-4 space-y-3">
7979 <h2 class="text-xs text-spot-secondary font-bold uppercase tracking-wide">Import / Export</h2>
80- <form hx-post="/feeds/opml/upload" hx-encoding="multipart/form-data" class="flex flex-col gap-2">
80+ <form hx-post="/feeds/opml/upload" hx-encoding="multipart/form-data" class="flex flex-col gap-2.5">
8181 {{csrfInput .CSRFToken}}
8282 <input type="file" name="opml" accept=".opml,.xml" class="text-sm text-spot-secondary file:mr-2 file:py-1 file:px-3 file:rounded-pill file:border-0 file:text-sm file:bg-spot-hover file:text-spot-text hover:file:bg-spot-surface file:cursor-pointer">
8383 <button type="submit" class="w-full border border-spot-outline text-spot-text rounded-pill px-4 py-1.5 text-sm font-bold uppercase tracking-button hover:border-spot-text transition">Import OPML</button>
@@ -97,7 +97,7 @@ function gleanRefreshPoll(){setTimeout(function(){htmx.ajax('GET','/feeds/list',
9797 </div>
9898 {{end}}
9999 {{if .DiscoverPeople}}
100- <h2 class="text-lg font-semibold text-spot-text mb-4 {{if .FollowedPeople}}mt-6{{end}}">Discover new readers</h2>
100+ <h2 class="text-lg font-semibold text-spot-text mb-4 {{if .FollowedPeople}}mt-8{{end}}">Discover new readers</h2>
101101 <div class="space-y-3">
102102 {{range .DiscoverPeople}}
103103 {{template "profile-card.html" .}}
@@ -1,6 +1,6 @@
1 {{define "feeds.html"}}1 {{define "feeds.html"}}
2 <div class="flex items-center justify-between gap-3 mb-2 flex-wrap">2 <div class="flex items-center justify-between gap-3 mb-2 flex-wrap">
3- <h1 class="text-2xl font-bold text-spot-text">Feeds <span class="text-base font-normal text-spot-secondary">({{.SubscriptionCount}})</span></h1>3+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">Feeds <span class="text-base font-normal text-spot-secondary">({{.SubscriptionCount}})</span></h1>
4 <div class="flex items-center gap-3">4 <div class="flex items-center gap-3">
5 <button id="refresh-btn"5 <button id="refresh-btn"
6 hx-post="/feeds/refresh" hx-target="#feed-list" hx-swap="innerHTML"6 hx-post="/feeds/refresh" hx-target="#feed-list" hx-swap="innerHTML"
@@ -34,7 +34,7 @@ function gleanRefreshPoll(){setTimeout(function(){htmx.ajax('GET','/feeds/list',
34 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">34 <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
35 <div class="lg:col-span-2">35 <div class="lg:col-span-2">
36 {{if .Categories}}36 {{if .Categories}}
37- <div class="flex gap-2 mb-6 flex-wrap">37+ <div class="flex gap-1.5 mb-6 flex-wrap">
38 <a href="/feeds" class="text-sm px-4 py-1.5 rounded-pill font-bold {{if not .Category}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}} transition">All</a>38 <a href="/feeds" class="text-sm px-4 py-1.5 rounded-pill font-bold {{if not .Category}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}} transition">All</a>
39 {{range .Categories}}39 {{range .Categories}}
40 <a href="/feeds?category={{.}}" class="text-sm px-4 py-1.5 rounded-pill font-bold {{if eq $.Category .}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}} transition">{{.}}</a>40 <a href="/feeds?category={{.}}" class="text-sm px-4 py-1.5 rounded-pill font-bold {{if eq $.Category .}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}} transition">{{.}}</a>
@@ -42,16 +42,16 @@ function gleanRefreshPoll(){setTimeout(function(){htmx.ajax('GET','/feeds/list',
42 </div>42 </div>
43 {{end}}43 {{end}}
44 44
45- <div id="feed-list" class="bg-spot-surface rounded-xl divide-y divide-spot-divider">45+ <div id="feed-list" class="bg-spot-surface rounded-xl divide-y divide-spot-divider overflow-hidden">
46 {{range .Subscriptions}}46 {{range .Subscriptions}}
47 {{template "feed-item.html" dict "FeedURL" .FeedURL "FeedTitle" .FeedTitle "Category" .Category "FaviconURL" .FaviconURL "UnreadCount" .UnreadCount "CSRFToken" $.CSRFToken}}47 {{template "feed-item.html" dict "FeedURL" .FeedURL "FeedTitle" .FeedTitle "Category" .Category "FaviconURL" .FaviconURL "UnreadCount" .UnreadCount "CSRFToken" $.CSRFToken}}
48 {{else}}48 {{else}}
49 <div class="flex flex-col items-center justify-center py-12 px-6 text-center">49 <div class="flex flex-col items-center justify-center py-12 px-6 text-center">
50- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">50+ <div class="w-14 h-14 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-4 mx-auto">
51- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>51+ <svg class="w-7 h-7 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
52 </div>52 </div>
53- <p class="text-sm text-spot-secondary mb-1">No feeds yet</p>53+ <p class="text-sm text-spot-text font-semibold mb-1">No feeds yet</p>
54- <p class="text-xs text-spot-muted">Add one from the sidebar to get started.</p>54+ <p class="text-xs text-spot-muted">Add one using the form on the right to get started.</p>
55 </div>55 </div>
56 {{end}}56 {{end}}
57 </div>57 </div>
@@ -68,16 +68,16 @@ function gleanRefreshPoll(){setTimeout(function(){htmx.ajax('GET','/feeds/list',
68 class="space-y-3">68 class="space-y-3">
69 {{csrfInput .CSRFToken}}69 {{csrfInput .CSRFToken}}
70 <input type="text" name="feed_url" placeholder="https://example.com/feed.xml or at://did:plc:.../site.standard.publication/..."70 <input type="text" name="feed_url" placeholder="https://example.com/feed.xml or at://did:plc:.../site.standard.publication/..."
71- class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"71+ class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder"
72 required>72 required>
73 <input type="text" name="category" placeholder="Category (optional)"73 <input type="text" name="category" placeholder="Category (optional)"
74- class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">74+ class="w-full bg-spot-hover text-spot-text rounded-pill px-5 py-2.5 text-sm focus:outline-none focus:ring-2 focus:ring-spot-green placeholder:text-spot-placeholder">
75- <button type="submit" class="w-full bg-spot-green text-white rounded-pill px-5 py-2 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>75+ <button type="submit" class="w-full bg-spot-green text-white rounded-pill px-5 py-2.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition">Add</button>
76 </form>76 </form>
77 <div id="add-feed-error" class="text-sm text-spot-red"></div>77 <div id="add-feed-error" class="text-sm text-spot-red"></div>
78 <div class="border-t border-spot-divider pt-4 space-y-3">78 <div class="border-t border-spot-divider pt-4 space-y-3">
79 <h2 class="text-xs text-spot-secondary font-bold uppercase tracking-wide">Import / Export</h2>79 <h2 class="text-xs text-spot-secondary font-bold uppercase tracking-wide">Import / Export</h2>
80- <form hx-post="/feeds/opml/upload" hx-encoding="multipart/form-data" class="flex flex-col gap-2">80+ <form hx-post="/feeds/opml/upload" hx-encoding="multipart/form-data" class="flex flex-col gap-2.5">
81 {{csrfInput .CSRFToken}}81 {{csrfInput .CSRFToken}}
82 <input type="file" name="opml" accept=".opml,.xml" class="text-sm text-spot-secondary file:mr-2 file:py-1 file:px-3 file:rounded-pill file:border-0 file:text-sm file:bg-spot-hover file:text-spot-text hover:file:bg-spot-surface file:cursor-pointer">82 <input type="file" name="opml" accept=".opml,.xml" class="text-sm text-spot-secondary file:mr-2 file:py-1 file:px-3 file:rounded-pill file:border-0 file:text-sm file:bg-spot-hover file:text-spot-text hover:file:bg-spot-surface file:cursor-pointer">
83 <button type="submit" class="w-full border border-spot-outline text-spot-text rounded-pill px-4 py-1.5 text-sm font-bold uppercase tracking-button hover:border-spot-text transition">Import OPML</button>83 <button type="submit" class="w-full border border-spot-outline text-spot-text rounded-pill px-4 py-1.5 text-sm font-bold uppercase tracking-button hover:border-spot-text transition">Import OPML</button>
@@ -97,7 +97,7 @@ function gleanRefreshPoll(){setTimeout(function(){htmx.ajax('GET','/feeds/list',
97 </div>97 </div>
98 {{end}}98 {{end}}
99 {{if .DiscoverPeople}}99 {{if .DiscoverPeople}}
100- <h2 class="text-lg font-semibold text-spot-text mb-4 {{if .FollowedPeople}}mt-6{{end}}">Discover new readers</h2>100+ <h2 class="text-lg font-semibold text-spot-text mb-4 {{if .FollowedPeople}}mt-8{{end}}">Discover new readers</h2>
101 <div class="space-y-3">101 <div class="space-y-3">
102 {{range .DiscoverPeople}}102 {{range .DiscoverPeople}}
103 {{template "profile-card.html" .}}103 {{template "profile-card.html" .}}
modified internal/tmpl/index.html +58 -53
@@ -1,7 +1,8 @@
11 {{define "index.html"}}
22 <style>
3-.landing-hero { padding-top: 6rem; padding-bottom: 4rem; }
4-@media (min-width: 768px) { .landing-hero { padding-top: 8rem; padding-bottom: 6rem; } }
3+.landing-hero { padding-top: 4rem; padding-bottom: 3rem; }
4+@media (min-width: 768px) { .landing-hero { padding-top: 6rem; padding-bottom: 5rem; } }
5+@media (min-width: 1024px) { .landing-hero { padding-top: 7rem; padding-bottom: 6rem; } }
56 </style>
67
78 <section class="landing-hero">
@@ -12,77 +13,77 @@
1213 <span class="w-10 h-10">{{template "logo-icon"}}</span>
1314 <span class="font-bold text-xl text-spot-text" style="letter-spacing: -0.02em;">Glean</span>
1415 </div>
15- <h1 class="text-3xl md:text-5xl font-bold mb-6 leading-[1.1] text-spot-text" style="letter-spacing: -0.03em;">
16+ <h1 class="text-4xl md:text-5xl lg:text-[3.5rem] font-bold mb-6 leading-[1.08] text-spot-text" style="letter-spacing: -0.035em;">
1617 The social<br>RSS reader.
1718 </h1>
18- <p class="text-lg text-spot-secondary mb-8 max-w-md leading-relaxed">
19+ <p class="text-lg md:text-xl text-spot-secondary mb-8 max-w-md leading-relaxed" style="letter-spacing: -0.01em;">
1920 Read your feeds. See what your circle reads. Discover new sources through personalized recommendations. All on AT Protocol.
2021 </p>
2122 <div class="flex flex-col sm:flex-row gap-3">
22- <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-7 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition active:scale-95 inline-flex items-center justify-center gap-2">
23+ <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-8 py-3.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition active:scale-[0.98] inline-flex items-center justify-center gap-2 shadow-spot">
2324 Sign in
2425 </a>
25- <a href="/trending" class="border border-spot-outline text-spot-text rounded-pill px-7 py-3 text-sm font-bold uppercase tracking-button hover:border-spot-text transition active:scale-95">
26+ <a href="/trending" class="border border-spot-outline text-spot-text rounded-pill px-8 py-3.5 text-sm font-bold uppercase tracking-button hover:border-spot-text hover:bg-spot-hover-50 transition active:scale-[0.98]">
2627 See what's trending
2728 </a>
2829 </div>
2930 </div>
3031
3132 <div class="hidden lg:block">
32- <div class="bg-spot-surface rounded-xl shadow-spot overflow-hidden">
33- <div class="px-5 py-3 border-b border-spot-divider flex items-center gap-2">
34- <div class="w-2 h-2 rounded-full bg-spot-red"></div>
35- <div class="w-2 h-2 rounded-full bg-spot-orange"></div>
36- <div class="w-2 h-2 rounded-full bg-spot-green"></div>
37- <span class="text-xs text-spot-muted ml-3">Dashboard</span>
33+ <div class="bg-spot-surface rounded-2xl shadow-spot-heavy overflow-hidden">
34+ <div class="px-5 py-3.5 border-b border-spot-divider flex items-center gap-2">
35+ <div class="w-2.5 h-2.5 rounded-full bg-spot-red/80"></div>
36+ <div class="w-2.5 h-2.5 rounded-full bg-spot-orange/80"></div>
37+ <div class="w-2.5 h-2.5 rounded-full bg-spot-green/80"></div>
38+ <span class="text-xs text-spot-muted ml-3 font-medium">Dashboard</span>
3839 </div>
39- <div class="p-4 space-y-2">
40- <div class="rounded-lg px-4 py-3 flex items-start gap-3 hover:bg-spot-hover transition">
41- <div class="w-8 h-8 rounded-full bg-spot-green/20 shrink-0 flex items-center justify-center">
42- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 7.5h1.5m-1.5 3h1.5m-7.5 3h7.5m-7.5 3h7.5m3-9h3.375c.621 0 1.125.504 1.125 1.125V18a2.25 2.25 0 0 1-2.25 2.25M16.5 7.5V18a2.25 2.25 0 0 0 2.25 2.25M16.5 7.5V4.875c0-.621-.504-1.125-1.125-1.125H4.125C3.504 3.75 3 4.254 3 4.875V18a2.25 2.25 0 0 0 2.25 2.25h13.5M6 7.5h3v3H6v-3Z"/></svg>
40+ <div class="p-3.5 space-y-1.5">
41+ <div class="rounded-xl px-4 py-3.5 flex items-start gap-3 hover:bg-spot-hover transition cursor-default">
42+ <div class="w-9 h-9 rounded-lg bg-spot-green/15 shrink-0 flex items-center justify-center">
43+ <svg class="w-4.5 h-4.5 text-spot-green" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 7.5h1.5m-1.5 3h1.5m-7.5 3h7.5m-7.5 3h7.5m3-9h3.375c.621 0 1.125.504 1.125 1.125V18a2.25 2.25 0 0 1-2.25 2.25M16.5 7.5V18a2.25 2.25 0 0 0 2.25 2.25M16.5 7.5V4.875c0-.621-.504-1.125-1.125-1.125H4.125C3.504 3.75 3 4.254 3 4.875V18a2.25 2.25 0 0 0 2.25 2.25h13.5M6 7.5h3v3H6v-3Z"/></svg>
4344 </div>
4445 <div class="flex-1 min-w-0">
45- <div class="text-sm font-bold text-spot-text leading-tight">Why the open web is making a comeback</div>
46- <div class="text-xs text-spot-secondary mt-0.5">theopenweb.press &middot; 2h ago</div>
46+ <div class="text-sm font-semibold text-spot-text leading-tight">Why the open web is making a comeback</div>
47+ <div class="text-xs text-spot-secondary mt-1">theopenweb.press &middot; 2h ago</div>
4748 </div>
4849 <div class="flex items-center gap-1 text-spot-green shrink-0">
4950 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">{{template "icon-heart"}}</svg>
50- <span class="text-xs">12</span>
51+ <span class="text-xs font-medium">12</span>
5152 </div>
5253 </div>
53- <div class="rounded-lg px-4 py-3 flex items-start gap-3 hover:bg-spot-hover transition">
54- <div class="w-8 h-8 rounded-full bg-spot-blue/20 shrink-0 flex items-center justify-center">
55- <svg class="w-4 h-4 text-spot-blue" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.5 21v-7.5a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 .75.75V21m-4.5 0H2.36m11.14 0H18m0 0h3.64m-1.39 0V9.349M3.75 21V9.349m0 0a3.001 3.001 0 0 0 3.75-.615A2.993 2.993 0 0 0 9.75 9.75c.896 0 1.7-.393 2.25-1.016a2.993 2.993 0 0 0 2.25 1.016c.896 0 1.7-.393 2.25-1.015a3.001 3.001 0 0 0 3.75.614m-16.5 0a3.004 3.004 0 0 1-.621-4.72l1.189-1.19A1.5 1.5 0 0 1 5.378 3h13.243a1.5 1.5 0 0 1 1.06.44l1.19 1.189a3 3 0 0 1-.621 4.72M6.75 18h3.75a.75.75 0 0 0 .75-.75V13.5a.75.75 0 0 0-.75-.75H6.75a.75.75 0 0 0-.75.75v3.75c0 .414.336.75.75.75Z"/></svg>
54+ <div class="rounded-xl px-4 py-3.5 flex items-start gap-3 hover:bg-spot-hover transition cursor-default">
55+ <div class="w-9 h-9 rounded-lg bg-spot-blue/15 shrink-0 flex items-center justify-center">
56+ <svg class="w-4.5 h-4.5 text-spot-blue" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.5 21v-7.5a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 .75.75V21m-4.5 0H2.36m11.14 0H18m0 0h3.64m-1.39 0V9.349M3.75 21V9.349m0 0a3.001 3.001 0 0 0 3.75-.615A2.993 2.993 0 0 0 9.75 9.75c.896 0 1.7-.393 2.25-1.016a2.993 2.993 0 0 0 2.25 1.016c.896 0 1.7-.393 2.25-1.015a3.001 3.001 0 0 0 3.75.614m-16.5 0a3.004 3.004 0 0 1-.621-4.72l1.189-1.19A1.5 1.5 0 0 1 5.378 3h13.243a1.5 1.5 0 0 1 1.06.44l1.19 1.189a3 3 0 0 1-.621 4.72M6.75 18h3.75a.75.75 0 0 0 .75-.75V13.5a.75.75 0 0 0-.75-.75H6.75a.75.75 0 0 0-.75.75v3.75c0 .414.336.75.75.75Z"/></svg>
5657 </div>
5758 <div class="flex-1 min-w-0">
58- <div class="text-sm font-bold text-spot-text leading-tight">How to take back control of your reading list</div>
59- <div class="text-xs text-spot-secondary mt-0.5">readwrite.cafe &middot; 5h ago</div>
59+ <div class="text-sm font-semibold text-spot-text leading-tight">How to take back control of your reading list</div>
60+ <div class="text-xs text-spot-secondary mt-1">readwrite.cafe &middot; 5h ago</div>
6061 </div>
6162 </div>
62- <div class="rounded-lg px-4 py-3 flex items-start gap-3 hover:bg-spot-hover transition">
63- <div class="w-8 h-8 rounded-full bg-spot-orange/20 shrink-0 flex items-center justify-center">
64- <svg class="w-4 h-4 text-spot-orange" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z"/></svg>
63+ <div class="rounded-xl px-4 py-3.5 flex items-start gap-3 hover:bg-spot-hover transition cursor-default">
64+ <div class="w-9 h-9 rounded-lg bg-spot-orange/15 shrink-0 flex items-center justify-center">
65+ <svg class="w-4.5 h-4.5 text-spot-orange" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z"/></svg>
6566 </div>
6667 <div class="flex-1 min-w-0">
67- <div class="text-sm font-bold text-spot-text leading-tight">RSS is not dead, it was just resting</div>
68- <div class="text-xs text-spot-secondary mt-0.5">syndication.xyz &middot; 8h ago</div>
68+ <div class="text-sm font-semibold text-spot-text leading-tight">RSS is not dead, it was just resting</div>
69+ <div class="text-xs text-spot-secondary mt-1">syndication.xyz &middot; 8h ago</div>
6970 </div>
7071 <div class="flex items-center gap-1 text-spot-secondary shrink-0">
7172 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z"/></svg>
7273 <span class="text-xs">3</span>
7374 </div>
7475 </div>
75- <div class="rounded-lg px-4 py-3 flex items-start gap-3 hover:bg-spot-hover transition">
76- <div class="w-8 h-8 rounded-full bg-spot-green/20 shrink-0 flex items-center justify-center">
77- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>
76+ <div class="rounded-xl px-4 py-3.5 flex items-start gap-3 hover:bg-spot-hover transition cursor-default">
77+ <div class="w-9 h-9 rounded-lg bg-spot-green/15 shrink-0 flex items-center justify-center">
78+ <svg class="w-4.5 h-4.5 text-spot-green" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>
7879 </div>
7980 <div class="flex-1 min-w-0">
80- <div class="text-sm font-bold text-spot-text leading-tight">The case for owning your reading history</div>
81- <div class="text-xs text-spot-secondary mt-0.5">protocolweekly.io &middot; 1d ago</div>
81+ <div class="text-sm font-semibold text-spot-text leading-tight">The case for owning your reading history</div>
82+ <div class="text-xs text-spot-secondary mt-1">protocolweekly.io &middot; 1d ago</div>
8283 </div>
8384 </div>
8485 </div>
85- <div class="px-5 py-3 border-t border-spot-divider flex items-center justify-between">
86+ <div class="px-5 py-3.5 border-t border-spot-divider flex items-center justify-between bg-spot-hover/30">
8687 <div class="flex items-center gap-2 text-xs text-spot-muted">
8788 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18 9 11.25l4.306 4.306a11.95 11.95 0 0 1 5.814-5.518l2.74-1.22m0 0-5.94-2.281m5.94 2.28-2.28 5.941"/></svg>
8889 4 trending in your network
@@ -96,26 +97,30 @@
9697 </section>
9798
9899 <section class="max-w-6xl mx-auto px-6 py-16">
100+ <div class="text-center mb-12">
101+ <h2 class="text-2xl md:text-3xl font-bold text-spot-text mb-3" style="letter-spacing: -0.025em;">Reading, reimagined</h2>
102+ <p class="text-spot-secondary max-w-lg mx-auto">Everything you need to stay informed, discover great writing, and connect with fellow readers.</p>
103+ </div>
99104 <div class="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-12">
100- <div>
101- <div class="flex items-center gap-2 mb-3">
105+ <div class="text-center md:text-left">
106+ <div class="w-10 h-10 rounded-xl bg-spot-green/15 flex items-center justify-center mb-4 mx-auto md:mx-0">
102107 <svg class="w-5 h-5 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
103- <h3 class="font-bold text-spot-text">Subscribe</h3>
104108 </div>
109+ <h3 class="font-bold text-spot-text mb-2">Subscribe</h3>
105110 <p class="text-sm text-spot-secondary leading-relaxed">Add any RSS or Atom feed. Import your existing subscriptions from another reader via OPML. Highlight passages and leave notes on articles.</p>
106111 </div>
107- <div>
108- <div class="flex items-center gap-2 mb-3">
112+ <div class="text-center md:text-left">
113+ <div class="w-10 h-10 rounded-xl bg-spot-green/15 flex items-center justify-center mb-4 mx-auto md:mx-0">
109114 <svg class="w-5 h-5 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
110- <h3 class="font-bold text-spot-text">Discover</h3>
111115 </div>
116+ <h3 class="font-bold text-spot-text mb-2">Discover</h3>
112117 <p class="text-sm text-spot-secondary leading-relaxed">Find new articles and feeds through personalized recommendations based on what your circle and readers with similar tastes are subscribing to.</p>
113118 </div>
114- <div>
115- <div class="flex items-center gap-2 mb-3">
119+ <div class="text-center md:text-left">
120+ <div class="w-10 h-10 rounded-xl bg-spot-green/15 flex items-center justify-center mb-4 mx-auto md:mx-0">
116121 <svg class="w-5 h-5 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
117- <h3 class="font-bold text-spot-text">Connect</h3>
118122 </div>
123+ <h3 class="font-bold text-spot-text mb-2">Connect</h3>
119124 <p class="text-sm text-spot-secondary leading-relaxed">Find and follow people with similar reading tastes. See what they read and share. Build your circle on the Atmosphere.</p>
120125 </div>
121126 </div>
@@ -124,25 +129,25 @@
124129 <section class="bg-spot-green-house">
125130 <div class="max-w-6xl mx-auto px-6 py-16">
126131 <div class="max-w-2xl">
127- <h2 class="text-2xl md:text-3xl font-bold text-white mb-4" style="letter-spacing: -0.02em;">Your feeds. Your data. Yours.</h2>
132+ <h2 class="text-2xl md:text-3xl font-bold text-white mb-4" style="letter-spacing: -0.025em;">Your feeds. Your data. Yours.</h2>
128133 <p class="text-[rgba(255,255,255,0.70)] leading-relaxed mb-8">
129134 Glean stores subscriptions and annotations in your personal data repository (PDS) on the AT Protocol. Your social graph comes from your existing Bluesky or Atmosphere connections. Take your data anywhere. Glean will never show you ads or track you.
130135 </p>
131- <div class="flex flex-wrap gap-x-8 gap-y-4 text-sm">
136+ <div class="grid grid-cols-2 sm:grid-cols-4 gap-4 text-sm">
132137 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">
133- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
138+ <svg class="w-4 h-4 text-spot-green shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
134139 AT Protocol identity
135140 </div>
136141 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">
137- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
142+ <svg class="w-4 h-4 text-spot-green shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
138143 Portable data
139144 </div>
140145 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">
141- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
146+ <svg class="w-4 h-4 text-spot-green shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
142147 <a href="https://tangled.org/julien.rbrt.fr/glean" class="hover:text-white transition">Open source</a>
143148 </div>
144149 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">
145- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
150+ <svg class="w-4 h-4 text-spot-green shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
146151 Self-hostable
147152 </div>
148153 </div>
@@ -152,9 +157,9 @@
152157
153158 <section class="py-16 text-center">
154159 <div class="max-w-md mx-auto px-6">
155- <h2 class="text-2xl font-bold text-spot-text mb-3" style="letter-spacing: -0.02em;">Start reading</h2>
156- <p class="text-spot-secondary mb-6 text-sm leading-relaxed">Sign in with your Bluesky handle or any Atmosphere account. Your network is already waiting.</p>
157- <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-8 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition active:scale-95 inline-flex items-center justify-center gap-2">
160+ <h2 class="text-2xl md:text-3xl font-bold text-spot-text mb-3" style="letter-spacing: -0.025em;">Start reading</h2>
161+ <p class="text-spot-secondary mb-6 text-sm leading-relaxed">Sign in with your Bluesky handle or any Atmosphere account. Your network is already waiting.</p>
162+ <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-10 py-3.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition active:scale-[0.98] inline-flex items-center justify-center gap-2 shadow-spot">
158163 Get started
159164 </a>
160165 </div>
@@ -1,7 +1,8 @@
1 {{define "index.html"}}1 {{define "index.html"}}
2 <style>2 <style>
3-.landing-hero { padding-top: 6rem; padding-bottom: 4rem; }3+.landing-hero { padding-top: 4rem; padding-bottom: 3rem; }
4-@media (min-width: 768px) { .landing-hero { padding-top: 8rem; padding-bottom: 6rem; } }4+@media (min-width: 768px) { .landing-hero { padding-top: 6rem; padding-bottom: 5rem; } }
5+@media (min-width: 1024px) { .landing-hero { padding-top: 7rem; padding-bottom: 6rem; } }
5 </style>6 </style>
6 7
7 <section class="landing-hero">8 <section class="landing-hero">
@@ -12,77 +13,77 @@
12 <span class="w-10 h-10">{{template "logo-icon"}}</span>13 <span class="w-10 h-10">{{template "logo-icon"}}</span>
13 <span class="font-bold text-xl text-spot-text" style="letter-spacing: -0.02em;">Glean</span>14 <span class="font-bold text-xl text-spot-text" style="letter-spacing: -0.02em;">Glean</span>
14 </div>15 </div>
15- <h1 class="text-3xl md:text-5xl font-bold mb-6 leading-[1.1] text-spot-text" style="letter-spacing: -0.03em;">16+ <h1 class="text-4xl md:text-5xl lg:text-[3.5rem] font-bold mb-6 leading-[1.08] text-spot-text" style="letter-spacing: -0.035em;">
16 The social<br>RSS reader.17 The social<br>RSS reader.
17 </h1>18 </h1>
18- <p class="text-lg text-spot-secondary mb-8 max-w-md leading-relaxed">19+ <p class="text-lg md:text-xl text-spot-secondary mb-8 max-w-md leading-relaxed" style="letter-spacing: -0.01em;">
19 Read your feeds. See what your circle reads. Discover new sources through personalized recommendations. All on AT Protocol.20 Read your feeds. See what your circle reads. Discover new sources through personalized recommendations. All on AT Protocol.
20 </p>21 </p>
21 <div class="flex flex-col sm:flex-row gap-3">22 <div class="flex flex-col sm:flex-row gap-3">
22- <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-7 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition active:scale-95 inline-flex items-center justify-center gap-2">23+ <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-8 py-3.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition active:scale-[0.98] inline-flex items-center justify-center gap-2 shadow-spot">
23 Sign in24 Sign in
24 </a>25 </a>
25- <a href="/trending" class="border border-spot-outline text-spot-text rounded-pill px-7 py-3 text-sm font-bold uppercase tracking-button hover:border-spot-text transition active:scale-95">26+ <a href="/trending" class="border border-spot-outline text-spot-text rounded-pill px-8 py-3.5 text-sm font-bold uppercase tracking-button hover:border-spot-text hover:bg-spot-hover-50 transition active:scale-[0.98]">
26 See what's trending27 See what's trending
27 </a>28 </a>
28 </div>29 </div>
29 </div>30 </div>
30 31
31 <div class="hidden lg:block">32 <div class="hidden lg:block">
32- <div class="bg-spot-surface rounded-xl shadow-spot overflow-hidden">33+ <div class="bg-spot-surface rounded-2xl shadow-spot-heavy overflow-hidden">
33- <div class="px-5 py-3 border-b border-spot-divider flex items-center gap-2">34+ <div class="px-5 py-3.5 border-b border-spot-divider flex items-center gap-2">
34- <div class="w-2 h-2 rounded-full bg-spot-red"></div>35+ <div class="w-2.5 h-2.5 rounded-full bg-spot-red/80"></div>
35- <div class="w-2 h-2 rounded-full bg-spot-orange"></div>36+ <div class="w-2.5 h-2.5 rounded-full bg-spot-orange/80"></div>
36- <div class="w-2 h-2 rounded-full bg-spot-green"></div>37+ <div class="w-2.5 h-2.5 rounded-full bg-spot-green/80"></div>
37- <span class="text-xs text-spot-muted ml-3">Dashboard</span>38+ <span class="text-xs text-spot-muted ml-3 font-medium">Dashboard</span>
38 </div>39 </div>
39- <div class="p-4 space-y-2">40+ <div class="p-3.5 space-y-1.5">
40- <div class="rounded-lg px-4 py-3 flex items-start gap-3 hover:bg-spot-hover transition">41+ <div class="rounded-xl px-4 py-3.5 flex items-start gap-3 hover:bg-spot-hover transition cursor-default">
41- <div class="w-8 h-8 rounded-full bg-spot-green/20 shrink-0 flex items-center justify-center">42+ <div class="w-9 h-9 rounded-lg bg-spot-green/15 shrink-0 flex items-center justify-center">
42- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 7.5h1.5m-1.5 3h1.5m-7.5 3h7.5m-7.5 3h7.5m3-9h3.375c.621 0 1.125.504 1.125 1.125V18a2.25 2.25 0 0 1-2.25 2.25M16.5 7.5V18a2.25 2.25 0 0 0 2.25 2.25M16.5 7.5V4.875c0-.621-.504-1.125-1.125-1.125H4.125C3.504 3.75 3 4.254 3 4.875V18a2.25 2.25 0 0 0 2.25 2.25h13.5M6 7.5h3v3H6v-3Z"/></svg>43+ <svg class="w-4.5 h-4.5 text-spot-green" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 7.5h1.5m-1.5 3h1.5m-7.5 3h7.5m-7.5 3h7.5m3-9h3.375c.621 0 1.125.504 1.125 1.125V18a2.25 2.25 0 0 1-2.25 2.25M16.5 7.5V18a2.25 2.25 0 0 0 2.25 2.25M16.5 7.5V4.875c0-.621-.504-1.125-1.125-1.125H4.125C3.504 3.75 3 4.254 3 4.875V18a2.25 2.25 0 0 0 2.25 2.25h13.5M6 7.5h3v3H6v-3Z"/></svg>
43 </div>44 </div>
44 <div class="flex-1 min-w-0">45 <div class="flex-1 min-w-0">
45- <div class="text-sm font-bold text-spot-text leading-tight">Why the open web is making a comeback</div>46+ <div class="text-sm font-semibold text-spot-text leading-tight">Why the open web is making a comeback</div>
46- <div class="text-xs text-spot-secondary mt-0.5">theopenweb.press &middot; 2h ago</div>47+ <div class="text-xs text-spot-secondary mt-1">theopenweb.press &middot; 2h ago</div>
47 </div>48 </div>
48 <div class="flex items-center gap-1 text-spot-green shrink-0">49 <div class="flex items-center gap-1 text-spot-green shrink-0">
49 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">{{template "icon-heart"}}</svg>50 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">{{template "icon-heart"}}</svg>
50- <span class="text-xs">12</span>51+ <span class="text-xs font-medium">12</span>
51 </div>52 </div>
52 </div>53 </div>
53- <div class="rounded-lg px-4 py-3 flex items-start gap-3 hover:bg-spot-hover transition">54+ <div class="rounded-xl px-4 py-3.5 flex items-start gap-3 hover:bg-spot-hover transition cursor-default">
54- <div class="w-8 h-8 rounded-full bg-spot-blue/20 shrink-0 flex items-center justify-center">55+ <div class="w-9 h-9 rounded-lg bg-spot-blue/15 shrink-0 flex items-center justify-center">
55- <svg class="w-4 h-4 text-spot-blue" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.5 21v-7.5a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 .75.75V21m-4.5 0H2.36m11.14 0H18m0 0h3.64m-1.39 0V9.349M3.75 21V9.349m0 0a3.001 3.001 0 0 0 3.75-.615A2.993 2.993 0 0 0 9.75 9.75c.896 0 1.7-.393 2.25-1.016a2.993 2.993 0 0 0 2.25 1.016c.896 0 1.7-.393 2.25-1.015a3.001 3.001 0 0 0 3.75.614m-16.5 0a3.004 3.004 0 0 1-.621-4.72l1.189-1.19A1.5 1.5 0 0 1 5.378 3h13.243a1.5 1.5 0 0 1 1.06.44l1.19 1.189a3 3 0 0 1-.621 4.72M6.75 18h3.75a.75.75 0 0 0 .75-.75V13.5a.75.75 0 0 0-.75-.75H6.75a.75.75 0 0 0-.75.75v3.75c0 .414.336.75.75.75Z"/></svg>56+ <svg class="w-4.5 h-4.5 text-spot-blue" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M13.5 21v-7.5a.75.75 0 0 1 .75-.75h3a.75.75 0 0 1 .75.75V21m-4.5 0H2.36m11.14 0H18m0 0h3.64m-1.39 0V9.349M3.75 21V9.349m0 0a3.001 3.001 0 0 0 3.75-.615A2.993 2.993 0 0 0 9.75 9.75c.896 0 1.7-.393 2.25-1.016a2.993 2.993 0 0 0 2.25 1.016c.896 0 1.7-.393 2.25-1.015a3.001 3.001 0 0 0 3.75.614m-16.5 0a3.004 3.004 0 0 1-.621-4.72l1.189-1.19A1.5 1.5 0 0 1 5.378 3h13.243a1.5 1.5 0 0 1 1.06.44l1.19 1.189a3 3 0 0 1-.621 4.72M6.75 18h3.75a.75.75 0 0 0 .75-.75V13.5a.75.75 0 0 0-.75-.75H6.75a.75.75 0 0 0-.75.75v3.75c0 .414.336.75.75.75Z"/></svg>
56 </div>57 </div>
57 <div class="flex-1 min-w-0">58 <div class="flex-1 min-w-0">
58- <div class="text-sm font-bold text-spot-text leading-tight">How to take back control of your reading list</div>59+ <div class="text-sm font-semibold text-spot-text leading-tight">How to take back control of your reading list</div>
59- <div class="text-xs text-spot-secondary mt-0.5">readwrite.cafe &middot; 5h ago</div>60+ <div class="text-xs text-spot-secondary mt-1">readwrite.cafe &middot; 5h ago</div>
60 </div>61 </div>
61 </div>62 </div>
62- <div class="rounded-lg px-4 py-3 flex items-start gap-3 hover:bg-spot-hover transition">63+ <div class="rounded-xl px-4 py-3.5 flex items-start gap-3 hover:bg-spot-hover transition cursor-default">
63- <div class="w-8 h-8 rounded-full bg-spot-orange/20 shrink-0 flex items-center justify-center">64+ <div class="w-9 h-9 rounded-lg bg-spot-orange/15 shrink-0 flex items-center justify-center">
64- <svg class="w-4 h-4 text-spot-orange" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z"/></svg>65+ <svg class="w-4.5 h-4.5 text-spot-orange" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.362 5.214A8.252 8.252 0 0 1 12 21 8.25 8.25 0 0 1 6.038 7.047 8.287 8.287 0 0 0 9 9.601a8.983 8.983 0 0 1 3.361-6.867 8.21 8.21 0 0 0 3 2.48Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M12 18a3.75 3.75 0 0 0 .495-7.468 5.99 5.99 0 0 0-1.925 3.547 5.975 5.975 0 0 1-2.133-1.001A3.75 3.75 0 0 0 12 18Z"/></svg>
65 </div>66 </div>
66 <div class="flex-1 min-w-0">67 <div class="flex-1 min-w-0">
67- <div class="text-sm font-bold text-spot-text leading-tight">RSS is not dead, it was just resting</div>68+ <div class="text-sm font-semibold text-spot-text leading-tight">RSS is not dead, it was just resting</div>
68- <div class="text-xs text-spot-secondary mt-0.5">syndication.xyz &middot; 8h ago</div>69+ <div class="text-xs text-spot-secondary mt-1">syndication.xyz &middot; 8h ago</div>
69 </div>70 </div>
70 <div class="flex items-center gap-1 text-spot-secondary shrink-0">71 <div class="flex items-center gap-1 text-spot-secondary shrink-0">
71 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z"/></svg>72 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 0 1 .865-.501 48.172 48.172 0 0 0 3.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z"/></svg>
72 <span class="text-xs">3</span>73 <span class="text-xs">3</span>
73 </div>74 </div>
74 </div>75 </div>
75- <div class="rounded-lg px-4 py-3 flex items-start gap-3 hover:bg-spot-hover transition">76+ <div class="rounded-xl px-4 py-3.5 flex items-start gap-3 hover:bg-spot-hover transition cursor-default">
76- <div class="w-8 h-8 rounded-full bg-spot-green/20 shrink-0 flex items-center justify-center">77+ <div class="w-9 h-9 rounded-lg bg-spot-green/15 shrink-0 flex items-center justify-center">
77- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>78+ <svg class="w-4.5 h-4.5 text-spot-green" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"/></svg>
78 </div>79 </div>
79 <div class="flex-1 min-w-0">80 <div class="flex-1 min-w-0">
80- <div class="text-sm font-bold text-spot-text leading-tight">The case for owning your reading history</div>81+ <div class="text-sm font-semibold text-spot-text leading-tight">The case for owning your reading history</div>
81- <div class="text-xs text-spot-secondary mt-0.5">protocolweekly.io &middot; 1d ago</div>82+ <div class="text-xs text-spot-secondary mt-1">protocolweekly.io &middot; 1d ago</div>
82 </div>83 </div>
83 </div>84 </div>
84 </div>85 </div>
85- <div class="px-5 py-3 border-t border-spot-divider flex items-center justify-between">86+ <div class="px-5 py-3.5 border-t border-spot-divider flex items-center justify-between bg-spot-hover/30">
86 <div class="flex items-center gap-2 text-xs text-spot-muted">87 <div class="flex items-center gap-2 text-xs text-spot-muted">
87 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18 9 11.25l4.306 4.306a11.95 11.95 0 0 1 5.814-5.518l2.74-1.22m0 0-5.94-2.281m5.94 2.28-2.28 5.941"/></svg>88 <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18 9 11.25l4.306 4.306a11.95 11.95 0 0 1 5.814-5.518l2.74-1.22m0 0-5.94-2.281m5.94 2.28-2.28 5.941"/></svg>
88 4 trending in your network89 4 trending in your network
@@ -96,26 +97,30 @@
96 </section>97 </section>
97 98
98 <section class="max-w-6xl mx-auto px-6 py-16">99 <section class="max-w-6xl mx-auto px-6 py-16">
100+ <div class="text-center mb-12">
101+ <h2 class="text-2xl md:text-3xl font-bold text-spot-text mb-3" style="letter-spacing: -0.025em;">Reading, reimagined</h2>
102+ <p class="text-spot-secondary max-w-lg mx-auto">Everything you need to stay informed, discover great writing, and connect with fellow readers.</p>
103+ </div>
99 <div class="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-12">104 <div class="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-12">
100- <div>105+ <div class="text-center md:text-left">
101- <div class="flex items-center gap-2 mb-3">106+ <div class="w-10 h-10 rounded-xl bg-spot-green/15 flex items-center justify-center mb-4 mx-auto md:mx-0">
102 <svg class="w-5 h-5 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>107 <svg class="w-5 h-5 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
103- <h3 class="font-bold text-spot-text">Subscribe</h3>
104 </div>108 </div>
109+ <h3 class="font-bold text-spot-text mb-2">Subscribe</h3>
105 <p class="text-sm text-spot-secondary leading-relaxed">Add any RSS or Atom feed. Import your existing subscriptions from another reader via OPML. Highlight passages and leave notes on articles.</p>110 <p class="text-sm text-spot-secondary leading-relaxed">Add any RSS or Atom feed. Import your existing subscriptions from another reader via OPML. Highlight passages and leave notes on articles.</p>
106 </div>111 </div>
107- <div>112+ <div class="text-center md:text-left">
108- <div class="flex items-center gap-2 mb-3">113+ <div class="w-10 h-10 rounded-xl bg-spot-green/15 flex items-center justify-center mb-4 mx-auto md:mx-0">
109 <svg class="w-5 h-5 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>114 <svg class="w-5 h-5 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/></svg>
110- <h3 class="font-bold text-spot-text">Discover</h3>
111 </div>115 </div>
116+ <h3 class="font-bold text-spot-text mb-2">Discover</h3>
112 <p class="text-sm text-spot-secondary leading-relaxed">Find new articles and feeds through personalized recommendations based on what your circle and readers with similar tastes are subscribing to.</p>117 <p class="text-sm text-spot-secondary leading-relaxed">Find new articles and feeds through personalized recommendations based on what your circle and readers with similar tastes are subscribing to.</p>
113 </div>118 </div>
114- <div>119+ <div class="text-center md:text-left">
115- <div class="flex items-center gap-2 mb-3">120+ <div class="w-10 h-10 rounded-xl bg-spot-green/15 flex items-center justify-center mb-4 mx-auto md:mx-0">
116 <svg class="w-5 h-5 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z"/></svg>121 <svg class="w-5 h-5 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
117- <h3 class="font-bold text-spot-text">Connect</h3>
118 </div>122 </div>
123+ <h3 class="font-bold text-spot-text mb-2">Connect</h3>
119 <p class="text-sm text-spot-secondary leading-relaxed">Find and follow people with similar reading tastes. See what they read and share. Build your circle on the Atmosphere.</p>124 <p class="text-sm text-spot-secondary leading-relaxed">Find and follow people with similar reading tastes. See what they read and share. Build your circle on the Atmosphere.</p>
120 </div>125 </div>
121 </div>126 </div>
@@ -124,25 +129,25 @@
124 <section class="bg-spot-green-house">129 <section class="bg-spot-green-house">
125 <div class="max-w-6xl mx-auto px-6 py-16">130 <div class="max-w-6xl mx-auto px-6 py-16">
126 <div class="max-w-2xl">131 <div class="max-w-2xl">
127- <h2 class="text-2xl md:text-3xl font-bold text-white mb-4" style="letter-spacing: -0.02em;">Your feeds. Your data. Yours.</h2>132+ <h2 class="text-2xl md:text-3xl font-bold text-white mb-4" style="letter-spacing: -0.025em;">Your feeds. Your data. Yours.</h2>
128 <p class="text-[rgba(255,255,255,0.70)] leading-relaxed mb-8">133 <p class="text-[rgba(255,255,255,0.70)] leading-relaxed mb-8">
129 Glean stores subscriptions and annotations in your personal data repository (PDS) on the AT Protocol. Your social graph comes from your existing Bluesky or Atmosphere connections. Take your data anywhere. Glean will never show you ads or track you.134 Glean stores subscriptions and annotations in your personal data repository (PDS) on the AT Protocol. Your social graph comes from your existing Bluesky or Atmosphere connections. Take your data anywhere. Glean will never show you ads or track you.
130 </p>135 </p>
131- <div class="flex flex-wrap gap-x-8 gap-y-4 text-sm">136+ <div class="grid grid-cols-2 sm:grid-cols-4 gap-4 text-sm">
132 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">137 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">
133- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>138+ <svg class="w-4 h-4 text-spot-green shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
134 AT Protocol identity139 AT Protocol identity
135 </div>140 </div>
136 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">141 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">
137- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>142+ <svg class="w-4 h-4 text-spot-green shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
138 Portable data143 Portable data
139 </div>144 </div>
140 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">145 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">
141- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>146+ <svg class="w-4 h-4 text-spot-green shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
142 <a href="https://tangled.org/julien.rbrt.fr/glean" class="hover:text-white transition">Open source</a>147 <a href="https://tangled.org/julien.rbrt.fr/glean" class="hover:text-white transition">Open source</a>
143 </div>148 </div>
144 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">149 <div class="flex items-center gap-2 text-[rgba(255,255,255,0.70)]">
145- <svg class="w-4 h-4 text-spot-green" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>150+ <svg class="w-4 h-4 text-spot-green shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"/></svg>
146 Self-hostable151 Self-hostable
147 </div>152 </div>
148 </div>153 </div>
@@ -152,9 +157,9 @@
152 157
153 <section class="py-16 text-center">158 <section class="py-16 text-center">
154 <div class="max-w-md mx-auto px-6">159 <div class="max-w-md mx-auto px-6">
155- <h2 class="text-2xl font-bold text-spot-text mb-3" style="letter-spacing: -0.02em;">Start reading</h2>160+ <h2 class="text-2xl md:text-3xl font-bold text-spot-text mb-3" style="letter-spacing: -0.025em;">Start reading</h2>
156- <p class="text-spot-secondary mb-6 text-sm leading-relaxed">Sign in with your Bluesky handle or any Atmosphere account. Your network is already waiting.</p>161+ <p class="text-spot-secondary mb-6 text-sm leading-relaxed">Sign in with your Bluesky handle or any Atmosphere account. Your network is already waiting.</p>
157- <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-8 py-3 text-sm font-bold uppercase tracking-button hover:brightness-110 transition active:scale-95 inline-flex items-center justify-center gap-2">162+ <a href="/auth/login" class="bg-spot-green text-white rounded-pill px-10 py-3.5 text-sm font-bold uppercase tracking-button hover:brightness-110 transition active:scale-[0.98] inline-flex items-center justify-center gap-2 shadow-spot">
158 Get started163 Get started
159 </a>164 </a>
160 </div>165 </div>
modified internal/tmpl/library.html +10 -10
@@ -1,22 +1,22 @@
11 {{define "library.html"}}
22 <div class="flex items-center justify-between mb-2">
3- <h1 class="text-2xl font-bold text-spot-text">Library</h1>
3+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">Library</h1>
44 <div></div>
55 </div>
66 <p class="text-sm text-spot-secondary mb-6">Your liked articles and annotations.</p>
77
8-<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
8+<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 lg:gap-12">
99 <div>
1010 <h2 class="text-lg font-semibold text-spot-text mb-4">Liked articles</h2>
1111 <div id="liked-list" class="space-y-3">
1212 {{range .Articles}}
1313 {{template "article-card.html" .}}
1414 {{else}}
15- <div class="bg-spot-surface rounded-xl py-12 px-6 text-center">
16- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">
17- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">{{template "icon-heart"}}</svg>
15+ <div class="bg-spot-surface rounded-2xl py-12 px-6 text-center">
16+ <div class="w-14 h-14 rounded-2xl bg-spot-red/15 flex items-center justify-center mb-5 mx-auto">
17+ <svg class="w-7 h-7 text-spot-red" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">{{template "icon-heart"}}</svg>
1818 </div>
19- <p class="text-sm text-spot-secondary mb-1">No liked articles yet</p>
19+ <p class="text-sm text-spot-text font-semibold mb-1">No liked articles yet</p>
2020 <p class="text-xs text-spot-muted">Like articles to save them here.</p>
2121 </div>
2222 {{end}}
@@ -47,11 +47,11 @@
4747 {{range .Annotations}}
4848 {{template "annotation-card.html" dict "annotation" . "userDID" $.CurrentUserDID}}
4949 {{else}}
50- <div class="bg-spot-surface rounded-xl py-12 px-6 text-center">
51- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">
52- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>
50+ <div class="bg-spot-surface rounded-2xl py-12 px-6 text-center">
51+ <div class="w-14 h-14 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
52+ <svg class="w-7 h-7 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>
5353 </div>
54- <p class="text-sm text-spot-secondary mb-1">No annotations yet</p>
54+ <p class="text-sm text-spot-text font-semibold mb-1">No annotations yet</p>
5555 <p class="text-xs text-spot-muted">Highlight and annotate articles as you read.</p>
5656 </div>
5757 {{end}}
@@ -1,22 +1,22 @@
1 {{define "library.html"}}1 {{define "library.html"}}
2 <div class="flex items-center justify-between mb-2">2 <div class="flex items-center justify-between mb-2">
3- <h1 class="text-2xl font-bold text-spot-text">Library</h1>3+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">Library</h1>
4 <div></div>4 <div></div>
5 </div>5 </div>
6 <p class="text-sm text-spot-secondary mb-6">Your liked articles and annotations.</p>6 <p class="text-sm text-spot-secondary mb-6">Your liked articles and annotations.</p>
7 7
8-<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">8+<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 lg:gap-12">
9 <div>9 <div>
10 <h2 class="text-lg font-semibold text-spot-text mb-4">Liked articles</h2>10 <h2 class="text-lg font-semibold text-spot-text mb-4">Liked articles</h2>
11 <div id="liked-list" class="space-y-3">11 <div id="liked-list" class="space-y-3">
12 {{range .Articles}}12 {{range .Articles}}
13 {{template "article-card.html" .}}13 {{template "article-card.html" .}}
14 {{else}}14 {{else}}
15- <div class="bg-spot-surface rounded-xl py-12 px-6 text-center">15+ <div class="bg-spot-surface rounded-2xl py-12 px-6 text-center">
16- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">16+ <div class="w-14 h-14 rounded-2xl bg-spot-red/15 flex items-center justify-center mb-5 mx-auto">
17- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">{{template "icon-heart"}}</svg>17+ <svg class="w-7 h-7 text-spot-red" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24">{{template "icon-heart"}}</svg>
18 </div>18 </div>
19- <p class="text-sm text-spot-secondary mb-1">No liked articles yet</p>19+ <p class="text-sm text-spot-text font-semibold mb-1">No liked articles yet</p>
20 <p class="text-xs text-spot-muted">Like articles to save them here.</p>20 <p class="text-xs text-spot-muted">Like articles to save them here.</p>
21 </div>21 </div>
22 {{end}}22 {{end}}
@@ -47,11 +47,11 @@
47 {{range .Annotations}}47 {{range .Annotations}}
48 {{template "annotation-card.html" dict "annotation" . "userDID" $.CurrentUserDID}}48 {{template "annotation-card.html" dict "annotation" . "userDID" $.CurrentUserDID}}
49 {{else}}49 {{else}}
50- <div class="bg-spot-surface rounded-xl py-12 px-6 text-center">50+ <div class="bg-spot-surface rounded-2xl py-12 px-6 text-center">
51- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">51+ <div class="w-14 h-14 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
52- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>52+ <svg class="w-7 h-7 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"/></svg>
53 </div>53 </div>
54- <p class="text-sm text-spot-secondary mb-1">No annotations yet</p>54+ <p class="text-sm text-spot-text font-semibold mb-1">No annotations yet</p>
55 <p class="text-xs text-spot-muted">Highlight and annotate articles as you read.</p>55 <p class="text-xs text-spot-muted">Highlight and annotate articles as you read.</p>
56 </div>56 </div>
57 {{end}}57 {{end}}
modified internal/tmpl/login.html +4 -4
@@ -6,17 +6,17 @@
66
77 <div class="flex items-center justify-center min-h-screen px-4 py-12">
88 <div class="max-w-sm w-full">
9- <div class="flex justify-center mb-8">
9+ <div class="flex justify-center mb-10">
1010 <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a>
1111 </div>
1212
13- <h1 class="text-2xl font-bold text-spot-text mb-1 text-center">Welcome to Glean</h1>
13+ <h1 class="text-2xl font-bold text-spot-text mb-2 text-center" style="letter-spacing: -0.02em;">Welcome to Glean</h1>
1414 <p class="text-spot-secondary text-sm mb-8 text-center">The social RSS reader built on AT Protocol.</p>
1515
1616 <form action="/auth/start" method="POST" id="login-form">
1717 {{csrfInput .CSRFToken}}
1818 <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>
19+ <label for="handle-input" class="block text-xs text-spot-secondary mb-1.5 font-medium">Login with your Atmosphere account</label>
2020 <input type="text" name="handle" placeholder="you.bsky.social" id="handle-input"
2121 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"
2222 required autocomplete="off">
@@ -122,4 +122,4 @@
122122 });
123123 })();
124124 </script>
125-{{end}}
\ No newline at end of file
125+{{end}}
@@ -6,17 +6,17 @@
6 6
7 <div class="flex items-center justify-center min-h-screen px-4 py-12">7 <div class="flex items-center justify-center min-h-screen px-4 py-12">
8 <div class="max-w-sm w-full">8 <div class="max-w-sm w-full">
9- <div class="flex justify-center mb-8">9+ <div class="flex justify-center mb-10">
10 <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a>10 <a href="/" class="w-16 h-16 block">{{template "logo-icon"}}</a>
11 </div>11 </div>
12 12
13- <h1 class="text-2xl font-bold text-spot-text mb-1 text-center">Welcome to Glean</h1>13+ <h1 class="text-2xl font-bold text-spot-text mb-2 text-center" style="letter-spacing: -0.02em;">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>14 <p class="text-spot-secondary text-sm mb-8 text-center">The social RSS reader built on AT Protocol.</p>
15 15
16 <form action="/auth/start" method="POST" id="login-form">16 <form action="/auth/start" method="POST" id="login-form">
17 {{csrfInput .CSRFToken}}17 {{csrfInput .CSRFToken}}
18 <div class="relative mb-4">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>19+ <label for="handle-input" class="block text-xs text-spot-secondary mb-1.5 font-medium">Login with your Atmosphere account</label>
20 <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"
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"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"
22 required autocomplete="off">22 required autocomplete="off">
@@ -122,4 +122,4 @@
122 });122 });
123 })();123 })();
124 </script>124 </script>
125-{{end}}
\ No newline at end of file\ No newline at end of file
125+{{end}}
modified internal/tmpl/partials/annotation-card.html +4 -4
@@ -1,5 +1,5 @@
11 {{define "annotation-card.html"}}
2-<div id="annotation-{{.annotation.ID}}" class="bg-spot-surface rounded-xl p-5 border border-spot-divider shadow-sm">
2+<div id="annotation-{{.annotation.ID}}" class="bg-spot-surface rounded-xl p-5 border border-spot-divider">
33 {{if .annotation.ArticleURL}}
44 <div class="text-xs mb-3 flex items-center gap-2">
55 {{if .annotation.ArticleID.Valid}}<a href="/articles/{{.annotation.ArticleID.Int64}}" class="text-spot-green hover:text-spot-text transition truncate inline-flex items-center gap-1">
@@ -28,10 +28,10 @@
2828 {{if .annotation.CreatedAt.Valid}}<span>&middot;</span><span>{{.annotation.CreatedAt.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}}
2929 </div>
3030 {{if eq .annotation.AuthorDID .userDID}}
31- <div class="flex items-center gap-2">
32- <button class="text-xs text-spot-secondary hover:text-spot-text transition" onclick="editAnnotation(this, {{.annotation.ID}}, '{{js .annotation.FeedURL}}', '{{js .annotation.ArticleURL}}', '{{js .annotation.Quote.String}}', '{{js .annotation.Note.String}}', '{{js .annotation.Tags.String}}')">Edit</button>
31+ <div class="flex items-center gap-3">
32+ <button class="text-xs text-spot-secondary hover:text-spot-text transition font-medium" onclick="editAnnotation(this, {{.annotation.ID}}, '{{js .annotation.FeedURL}}', '{{js .annotation.ArticleURL}}', '{{js .annotation.Quote.String}}', '{{js .annotation.Note.String}}', '{{js .annotation.Tags.String}}')">Edit</button>
3333 <button hx-post="/library/{{.annotation.ID}}/delete" hx-target="#annotation-{{.annotation.ID}}" hx-swap="outerHTML swap:0.3s" hx-confirm="Delete this annotation?"
34- class="text-xs text-spot-secondary hover:text-spot-red transition">Delete</button>
34+ class="text-xs text-spot-secondary hover:text-spot-red transition font-medium">Delete</button>
3535 </div>
3636 {{end}}
3737 </div>
@@ -1,5 +1,5 @@
1 {{define "annotation-card.html"}}1 {{define "annotation-card.html"}}
2-<div id="annotation-{{.annotation.ID}}" class="bg-spot-surface rounded-xl p-5 border border-spot-divider shadow-sm">2+<div id="annotation-{{.annotation.ID}}" class="bg-spot-surface rounded-xl p-5 border border-spot-divider">
3 {{if .annotation.ArticleURL}}3 {{if .annotation.ArticleURL}}
4 <div class="text-xs mb-3 flex items-center gap-2">4 <div class="text-xs mb-3 flex items-center gap-2">
5 {{if .annotation.ArticleID.Valid}}<a href="/articles/{{.annotation.ArticleID.Int64}}" class="text-spot-green hover:text-spot-text transition truncate inline-flex items-center gap-1">5 {{if .annotation.ArticleID.Valid}}<a href="/articles/{{.annotation.ArticleID.Int64}}" class="text-spot-green hover:text-spot-text transition truncate inline-flex items-center gap-1">
@@ -28,10 +28,10 @@
28 {{if .annotation.CreatedAt.Valid}}<span>&middot;</span><span>{{.annotation.CreatedAt.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}}28 {{if .annotation.CreatedAt.Valid}}<span>&middot;</span><span>{{.annotation.CreatedAt.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}}
29 </div>29 </div>
30 {{if eq .annotation.AuthorDID .userDID}}30 {{if eq .annotation.AuthorDID .userDID}}
31- <div class="flex items-center gap-2">31+ <div class="flex items-center gap-3">
32- <button class="text-xs text-spot-secondary hover:text-spot-text transition" onclick="editAnnotation(this, {{.annotation.ID}}, '{{js .annotation.FeedURL}}', '{{js .annotation.ArticleURL}}', '{{js .annotation.Quote.String}}', '{{js .annotation.Note.String}}', '{{js .annotation.Tags.String}}')">Edit</button>32+ <button class="text-xs text-spot-secondary hover:text-spot-text transition font-medium" onclick="editAnnotation(this, {{.annotation.ID}}, '{{js .annotation.FeedURL}}', '{{js .annotation.ArticleURL}}', '{{js .annotation.Quote.String}}', '{{js .annotation.Note.String}}', '{{js .annotation.Tags.String}}')">Edit</button>
33 <button hx-post="/library/{{.annotation.ID}}/delete" hx-target="#annotation-{{.annotation.ID}}" hx-swap="outerHTML swap:0.3s" hx-confirm="Delete this annotation?"33 <button hx-post="/library/{{.annotation.ID}}/delete" hx-target="#annotation-{{.annotation.ID}}" hx-swap="outerHTML swap:0.3s" hx-confirm="Delete this annotation?"
34- class="text-xs text-spot-secondary hover:text-spot-red transition">Delete</button>34+ class="text-xs text-spot-secondary hover:text-spot-red transition font-medium">Delete</button>
35 </div>35 </div>
36 {{end}}36 {{end}}
37 </div>37 </div>
modified internal/tmpl/partials/article-card.html +6 -6
@@ -1,22 +1,22 @@
11 {{define "article-card.html"}}
2-<article data-article-id="{{.ID}}" data-feed-url="{{.FeedURL}}" data-article-url="{{if .URL.Valid}}{{.URL.String}}{{end}}" class="bg-spot-surface rounded-xl px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot relative {{if .IsRead.Bool}}opacity-60{{end}}">
2+<article data-article-id="{{.ID}}" data-feed-url="{{.FeedURL}}" data-article-url="{{if .URL.Valid}}{{.URL.String}}{{end}}" class="bg-spot-surface rounded-xl px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot relative group {{if .IsRead.Bool}}opacity-55{{end}}">
33 <div class="flex items-start justify-between gap-4">
44 <div class="min-w-0 flex-1">
55 <div class="flex items-start gap-2.5">
6- {{if not .IsRead.Bool}}<span class="w-2.5 h-2.5 rounded-full bg-spot-green shrink-0 mt-1.5"></span>{{end}}
7- <a href="/articles/{{.ID}}{{.NavSuffix}}" class="font-semibold text-spot-text hover:text-spot-green transition text-[17px] leading-snug">{{.Title}}</a>
6+ {{if not .IsRead.Bool}}<span class="w-2 h-2 rounded-full bg-spot-green shrink-0 mt-2 animate-pulse-dot"></span>{{end}}
7+ <a href="/articles/{{.ID}}{{.NavSuffix}}" class="font-semibold text-spot-text hover:text-spot-green transition leading-snug {{if .IsRead.Bool}}text-[15px]{{else}}text-[17px]{{end}}">{{.Title}}</a>
88 </div>
9- <div class="text-xs text-spot-secondary mt-2 flex items-center gap-1.5 flex-wrap pl-5">
9+ <div class="text-xs text-spot-secondary mt-2 flex items-center gap-1.5 flex-wrap {{if not .IsRead.Bool}}pl-[18px]{{end}}">
1010 {{template "favicon" dict "src" .FeedFaviconURL.String "size" "w-3.5 h-3.5"}}
1111 <a href="/articles?feed={{.FeedURL}}" class="hover:text-spot-text transition font-medium">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</a>
1212 {{if .Author.Valid}}{{if .Author.String}}<span class="text-spot-muted">&middot;</span><span>{{.Author.String}}</span>{{end}}{{end}}
1313 {{if .Published.Valid}}<span class="text-spot-muted">&middot;</span><span>{{.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}}
1414 </div>
1515 {{if .Summary.Valid}}{{if .Summary.String}}
16- <p class="text-sm text-spot-secondary mt-2.5 line-clamp-2 leading-relaxed pl-5">{{plainText .Summary.String}}</p>
16+ <p class="text-sm text-spot-secondary mt-2.5 line-clamp-2 leading-relaxed {{if not .IsRead.Bool}}pl-[18px]{{else}}pl-0{{end}}">{{plainText .Summary.String}}</p>
1717 {{end}}{{end}}
1818 </div>
19- <div class="grid gap-2 shrink-0 pt-1">
19+ <div class="grid gap-2 shrink-0 pt-0.5">
2020 <div class="flex justify-center">{{template "like-button.html" .}}</div>
2121 {{if .IsRead.Bool}}
2222 <div class="flex justify-center">
@@ -1,22 +1,22 @@
1 {{define "article-card.html"}}1 {{define "article-card.html"}}
2-<article data-article-id="{{.ID}}" data-feed-url="{{.FeedURL}}" data-article-url="{{if .URL.Valid}}{{.URL.String}}{{end}}" class="bg-spot-surface rounded-xl px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot relative {{if .IsRead.Bool}}opacity-60{{end}}">2+<article data-article-id="{{.ID}}" data-feed-url="{{.FeedURL}}" data-article-url="{{if .URL.Valid}}{{.URL.String}}{{end}}" class="bg-spot-surface rounded-xl px-5 py-4 hover:bg-spot-hover-50 transition shadow-spot relative group {{if .IsRead.Bool}}opacity-55{{end}}">
3 <div class="flex items-start justify-between gap-4">3 <div class="flex items-start justify-between gap-4">
4 <div class="min-w-0 flex-1">4 <div class="min-w-0 flex-1">
5 <div class="flex items-start gap-2.5">5 <div class="flex items-start gap-2.5">
6- {{if not .IsRead.Bool}}<span class="w-2.5 h-2.5 rounded-full bg-spot-green shrink-0 mt-1.5"></span>{{end}}6+ {{if not .IsRead.Bool}}<span class="w-2 h-2 rounded-full bg-spot-green shrink-0 mt-2 animate-pulse-dot"></span>{{end}}
7- <a href="/articles/{{.ID}}{{.NavSuffix}}" class="font-semibold text-spot-text hover:text-spot-green transition text-[17px] leading-snug">{{.Title}}</a>7+ <a href="/articles/{{.ID}}{{.NavSuffix}}" class="font-semibold text-spot-text hover:text-spot-green transition leading-snug {{if .IsRead.Bool}}text-[15px]{{else}}text-[17px]{{end}}">{{.Title}}</a>
8 </div>8 </div>
9- <div class="text-xs text-spot-secondary mt-2 flex items-center gap-1.5 flex-wrap pl-5">9+ <div class="text-xs text-spot-secondary mt-2 flex items-center gap-1.5 flex-wrap {{if not .IsRead.Bool}}pl-[18px]{{end}}">
10 {{template "favicon" dict "src" .FeedFaviconURL.String "size" "w-3.5 h-3.5"}}10 {{template "favicon" dict "src" .FeedFaviconURL.String "size" "w-3.5 h-3.5"}}
11 <a href="/articles?feed={{.FeedURL}}" class="hover:text-spot-text transition font-medium">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</a>11 <a href="/articles?feed={{.FeedURL}}" class="hover:text-spot-text transition font-medium">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</a>
12 {{if .Author.Valid}}{{if .Author.String}}<span class="text-spot-muted">&middot;</span><span>{{.Author.String}}</span>{{end}}{{end}}12 {{if .Author.Valid}}{{if .Author.String}}<span class="text-spot-muted">&middot;</span><span>{{.Author.String}}</span>{{end}}{{end}}
13 {{if .Published.Valid}}<span class="text-spot-muted">&middot;</span><span>{{.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}}13 {{if .Published.Valid}}<span class="text-spot-muted">&middot;</span><span>{{.Published.Time.Format "Jan 2, 2006 15:04"}}</span>{{end}}
14 </div>14 </div>
15 {{if .Summary.Valid}}{{if .Summary.String}}15 {{if .Summary.Valid}}{{if .Summary.String}}
16- <p class="text-sm text-spot-secondary mt-2.5 line-clamp-2 leading-relaxed pl-5">{{plainText .Summary.String}}</p>16+ <p class="text-sm text-spot-secondary mt-2.5 line-clamp-2 leading-relaxed {{if not .IsRead.Bool}}pl-[18px]{{else}}pl-0{{end}}">{{plainText .Summary.String}}</p>
17 {{end}}{{end}}17 {{end}}{{end}}
18 </div>18 </div>
19- <div class="grid gap-2 shrink-0 pt-1">19+ <div class="grid gap-2 shrink-0 pt-0.5">
20 <div class="flex justify-center">{{template "like-button.html" .}}</div>20 <div class="flex justify-center">{{template "like-button.html" .}}</div>
21 {{if .IsRead.Bool}}21 {{if .IsRead.Bool}}
22 <div class="flex justify-center">22 <div class="flex justify-center">
modified internal/tmpl/partials/articles-content.html +4 -4
@@ -2,11 +2,11 @@
22 {{range .Articles}}
33 {{template "article-card.html" .}}
44 {{else}}
5-<div class="bg-spot-surface rounded-xl py-12 px-6 text-center">
6- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">
7- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>
5+<div class="bg-spot-surface rounded-2xl py-12 px-6 text-center">
6+ <div class="w-14 h-14 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
7+ <svg class="w-7 h-7 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>
88 </div>
9- <p class="text-sm text-spot-secondary mb-1">No articles found</p>
9+ <p class="text-sm text-spot-text font-semibold mb-1">No articles found</p>
1010 {{if eq .Status "unread"}}<p class="text-xs text-spot-muted">You've read everything. Nice work.</p>
1111 {{else if eq .Status "read"}}<p class="text-xs text-spot-muted">Nothing marked as read yet.</p>
1212 {{else}}<p class="text-xs text-spot-muted">Subscribe to feeds to see articles here.</p>{{end}}
@@ -2,11 +2,11 @@
2 {{range .Articles}}2 {{range .Articles}}
3 {{template "article-card.html" .}}3 {{template "article-card.html" .}}
4 {{else}}4 {{else}}
5-<div class="bg-spot-surface rounded-xl py-12 px-6 text-center">5+<div class="bg-spot-surface rounded-2xl py-12 px-6 text-center">
6- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">6+ <div class="w-14 h-14 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
7- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>7+ <svg class="w-7 h-7 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M19 20H5a2 2 0 01-2-2V6a2 2 0 012-2h10a2 2 0 012 2v1m2 13a2 2 0 01-2-2V7m2 13a2 2 0 002-2V9a2 2 0 00-2-2h-2"/></svg>
8 </div>8 </div>
9- <p class="text-sm text-spot-secondary mb-1">No articles found</p>9+ <p class="text-sm text-spot-text font-semibold mb-1">No articles found</p>
10 {{if eq .Status "unread"}}<p class="text-xs text-spot-muted">You've read everything. Nice work.</p>10 {{if eq .Status "unread"}}<p class="text-xs text-spot-muted">You've read everything. Nice work.</p>
11 {{else if eq .Status "read"}}<p class="text-xs text-spot-muted">Nothing marked as read yet.</p>11 {{else if eq .Status "read"}}<p class="text-xs text-spot-muted">Nothing marked as read yet.</p>
12 {{else}}<p class="text-xs text-spot-muted">Subscribe to feeds to see articles here.</p>{{end}}12 {{else}}<p class="text-xs text-spot-muted">Subscribe to feeds to see articles here.</p>{{end}}
modified internal/tmpl/partials/dead-feeds.html +2 -2
@@ -6,9 +6,9 @@
66 {{range .DeadFeeds}}
77 <div class="dead-feed-item flex items-start justify-between gap-3 text-sm flex-wrap">
88 <div class="min-w-0 flex-1">
9- <span class="text-spot-text truncate block">{{if .Title.Valid}}{{.Title.String}}{{else}}{{.FeedURL}}{{end}}</span>
9+ <span class="text-spot-text truncate block font-medium">{{if .Title.Valid}}{{.Title.String}}{{else}}{{.FeedURL}}{{end}}</span>
1010 <div class="flex items-center gap-2 mt-1 flex-wrap">
11- <span class="text-spot-red text-xs">{{.ErrorCount}} errors</span>
11+ <span class="text-spot-red text-xs font-medium">{{.ErrorCount}} errors</span>
1212 {{if .LastError.Valid}}<span class="text-spot-secondary text-xs truncate max-w-48" title="{{.LastError.String}}">{{.LastError.String}}</span>{{end}}
1313 </div>
1414 </div>
@@ -6,9 +6,9 @@
6 {{range .DeadFeeds}}6 {{range .DeadFeeds}}
7 <div class="dead-feed-item flex items-start justify-between gap-3 text-sm flex-wrap">7 <div class="dead-feed-item flex items-start justify-between gap-3 text-sm flex-wrap">
8 <div class="min-w-0 flex-1">8 <div class="min-w-0 flex-1">
9- <span class="text-spot-text truncate block">{{if .Title.Valid}}{{.Title.String}}{{else}}{{.FeedURL}}{{end}}</span>9+ <span class="text-spot-text truncate block font-medium">{{if .Title.Valid}}{{.Title.String}}{{else}}{{.FeedURL}}{{end}}</span>
10 <div class="flex items-center gap-2 mt-1 flex-wrap">10 <div class="flex items-center gap-2 mt-1 flex-wrap">
11- <span class="text-spot-red text-xs">{{.ErrorCount}} errors</span>11+ <span class="text-spot-red text-xs font-medium">{{.ErrorCount}} errors</span>
12 {{if .LastError.Valid}}<span class="text-spot-secondary text-xs truncate max-w-48" title="{{.LastError.String}}">{{.LastError.String}}</span>{{end}}12 {{if .LastError.Valid}}<span class="text-spot-secondary text-xs truncate max-w-48" title="{{.LastError.String}}">{{.LastError.String}}</span>{{end}}
13 </div>13 </div>
14 </div>14 </div>
modified internal/tmpl/partials/feed-item.html +4 -4
@@ -1,22 +1,22 @@
11 {{define "feed-item.html"}}
2-<div class="feed-item px-5 py-4 flex items-center justify-between gap-3 hover:bg-spot-hover-50 transition rounded-xl">
2+<div class="feed-item px-5 py-4 flex items-center justify-between gap-3 hover:bg-spot-hover-50 transition">
33 <a href="/articles?feed={{.FeedURL}}" class="min-w-0 flex-1 flex items-center gap-3">
44 {{template "favicon" dict "src" .FaviconURL.String "size" "w-5 h-5"}}
55 <div class="min-w-0 flex-1">
66 <div class="flex items-center gap-2 flex-wrap">
7- <span class="font-bold text-spot-text truncate">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</span>
7+ <span class="font-semibold text-spot-text truncate">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</span>
88 {{if and .Category.Valid .Category.String}}<span class="text-xs bg-spot-hover text-spot-secondary px-2 py-0.5 rounded-pill shrink-0">{{.Category.String}}</span>{{end}}
99 </div>
1010 <div class="text-xs text-spot-muted truncate mt-0.5">{{.FeedURL}}</div>
1111 </div>
1212 </a>
1313 <div class="flex items-center gap-3 shrink-0">
14- {{if .UnreadCount}}<span class="text-xs bg-spot-green/20 text-spot-green px-2.5 py-0.5 rounded-pill font-bold">{{.UnreadCount}}</span>{{end}}
14+ {{if .UnreadCount}}<span class="text-xs bg-spot-green/15 text-spot-green px-2.5 py-0.5 rounded-pill font-bold">{{.UnreadCount}}</span>{{end}}
1515 <form hx-delete="/feeds/remove" hx-target="closest .feed-item" hx-swap="outerHTML swap:0.3s"
1616 hx-confirm="Unsubscribe from this feed?" class="inline">
1717 {{csrfInput .CSRFToken}}
1818 <input type="hidden" name="url" value="{{.FeedURL}}">
19- <button type="submit" class="text-sm text-spot-secondary hover:text-spot-red transition">Unsubscribe</button>
19+ <button type="submit" class="text-xs text-spot-secondary hover:text-spot-red transition font-medium">Unsubscribe</button>
2020 </form>
2121 </div>
2222 </div>
@@ -1,22 +1,22 @@
1 {{define "feed-item.html"}}1 {{define "feed-item.html"}}
2-<div class="feed-item px-5 py-4 flex items-center justify-between gap-3 hover:bg-spot-hover-50 transition rounded-xl">2+<div class="feed-item px-5 py-4 flex items-center justify-between gap-3 hover:bg-spot-hover-50 transition">
3 <a href="/articles?feed={{.FeedURL}}" class="min-w-0 flex-1 flex items-center gap-3">3 <a href="/articles?feed={{.FeedURL}}" class="min-w-0 flex-1 flex items-center gap-3">
4 {{template "favicon" dict "src" .FaviconURL.String "size" "w-5 h-5"}}4 {{template "favicon" dict "src" .FaviconURL.String "size" "w-5 h-5"}}
5 <div class="min-w-0 flex-1">5 <div class="min-w-0 flex-1">
6 <div class="flex items-center gap-2 flex-wrap">6 <div class="flex items-center gap-2 flex-wrap">
7- <span class="font-bold text-spot-text truncate">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</span>7+ <span class="font-semibold text-spot-text truncate">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</span>
8 {{if and .Category.Valid .Category.String}}<span class="text-xs bg-spot-hover text-spot-secondary px-2 py-0.5 rounded-pill shrink-0">{{.Category.String}}</span>{{end}}8 {{if and .Category.Valid .Category.String}}<span class="text-xs bg-spot-hover text-spot-secondary px-2 py-0.5 rounded-pill shrink-0">{{.Category.String}}</span>{{end}}
9 </div>9 </div>
10 <div class="text-xs text-spot-muted truncate mt-0.5">{{.FeedURL}}</div>10 <div class="text-xs text-spot-muted truncate mt-0.5">{{.FeedURL}}</div>
11 </div>11 </div>
12 </a>12 </a>
13 <div class="flex items-center gap-3 shrink-0">13 <div class="flex items-center gap-3 shrink-0">
14- {{if .UnreadCount}}<span class="text-xs bg-spot-green/20 text-spot-green px-2.5 py-0.5 rounded-pill font-bold">{{.UnreadCount}}</span>{{end}}14+ {{if .UnreadCount}}<span class="text-xs bg-spot-green/15 text-spot-green px-2.5 py-0.5 rounded-pill font-bold">{{.UnreadCount}}</span>{{end}}
15 <form hx-delete="/feeds/remove" hx-target="closest .feed-item" hx-swap="outerHTML swap:0.3s"15 <form hx-delete="/feeds/remove" hx-target="closest .feed-item" hx-swap="outerHTML swap:0.3s"
16 hx-confirm="Unsubscribe from this feed?" class="inline">16 hx-confirm="Unsubscribe from this feed?" class="inline">
17 {{csrfInput .CSRFToken}}17 {{csrfInput .CSRFToken}}
18 <input type="hidden" name="url" value="{{.FeedURL}}">18 <input type="hidden" name="url" value="{{.FeedURL}}">
19- <button type="submit" class="text-sm text-spot-secondary hover:text-spot-red transition">Unsubscribe</button>19+ <button type="submit" class="text-xs text-spot-secondary hover:text-spot-red transition font-medium">Unsubscribe</button>
20 </form>20 </form>
21 </div>21 </div>
22 </div>22 </div>
modified internal/tmpl/partials/feed-list.html +3 -3
@@ -3,10 +3,10 @@
33 {{template "feed-item.html" dict "FeedURL" .FeedURL "FeedTitle" .FeedTitle "Category" .Category "FaviconURL" .FaviconURL "UnreadCount" .UnreadCount "CSRFToken" $.CSRFToken}}
44 {{else}}
55 <div class="flex flex-col items-center justify-center py-12 px-6 text-center">
6- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">
7- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
6+ <div class="w-14 h-14 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
7+ <svg class="w-7 h-7 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
88 </div>
9- <p class="text-sm text-spot-secondary mb-1">No feeds yet</p>
9+ <p class="text-sm text-spot-text font-semibold mb-1">No feeds yet</p>
1010 <p class="text-xs text-spot-muted">Add one from the sidebar to get started.</p>
1111 </div>
1212 {{end}}
@@ -3,10 +3,10 @@
3 {{template "feed-item.html" dict "FeedURL" .FeedURL "FeedTitle" .FeedTitle "Category" .Category "FaviconURL" .FaviconURL "UnreadCount" .UnreadCount "CSRFToken" $.CSRFToken}}3 {{template "feed-item.html" dict "FeedURL" .FeedURL "FeedTitle" .FeedTitle "Category" .Category "FaviconURL" .FaviconURL "UnreadCount" .UnreadCount "CSRFToken" $.CSRFToken}}
4 {{else}}4 {{else}}
5 <div class="flex flex-col items-center justify-center py-12 px-6 text-center">5 <div class="flex flex-col items-center justify-center py-12 px-6 text-center">
6- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">6+ <div class="w-14 h-14 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
7- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>7+ <svg class="w-7 h-7 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 5c7.18 0 13 5.82 13 13M6 11a7 7 0 017 7m-7-1a1 1 0 11-2 0 1 1 0 012 0z"/></svg>
8 </div>8 </div>
9- <p class="text-sm text-spot-secondary mb-1">No feeds yet</p>9+ <p class="text-sm text-spot-text font-semibold mb-1">No feeds yet</p>
10 <p class="text-xs text-spot-muted">Add one from the sidebar to get started.</p>10 <p class="text-xs text-spot-muted">Add one from the sidebar to get started.</p>
11 </div>11 </div>
12 {{end}}12 {{end}}
modified internal/tmpl/partials/profile-card.html +3 -3
@@ -1,8 +1,8 @@
11 {{define "profile-card.html"}}
2-<a href="/profile/{{.DID}}" class="bg-spot-surface rounded-xl p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition relative group">
3- {{if .AvatarURL}}<img src="{{.AvatarURL}}" class="w-10 h-10 rounded-full">{{end}}
2+<a href="/profile/{{.DID}}" class="bg-spot-surface rounded-xl p-4 flex items-center gap-3.5 hover:bg-spot-hover-50 transition relative group">
3+ {{if .AvatarURL}}<img src="{{.AvatarURL}}" class="w-10 h-10 rounded-full ring-1 ring-spot-divider">{{end}}
44 <div class="min-w-0 flex-1">
5- <span class="font-bold text-spot-text hover:text-spot-green transition">@{{.Handle}}</span>
5+ <span class="font-semibold text-spot-text hover:text-spot-green transition">@{{.Handle}}</span>
66 {{if .IsFollowed}}
77 <span class="inline-flex items-center gap-0.5 text-[10px] font-medium text-spot-green bg-spot-green/10 px-1.5 py-0.5 rounded-pill ml-1.5">Following</span>
88 {{end}}
@@ -1,8 +1,8 @@
1 {{define "profile-card.html"}}1 {{define "profile-card.html"}}
2-<a href="/profile/{{.DID}}" class="bg-spot-surface rounded-xl p-4 flex items-center gap-3 hover:bg-spot-hover-50 transition relative group">2+<a href="/profile/{{.DID}}" class="bg-spot-surface rounded-xl p-4 flex items-center gap-3.5 hover:bg-spot-hover-50 transition relative group">
3- {{if .AvatarURL}}<img src="{{.AvatarURL}}" class="w-10 h-10 rounded-full">{{end}}3+ {{if .AvatarURL}}<img src="{{.AvatarURL}}" class="w-10 h-10 rounded-full ring-1 ring-spot-divider">{{end}}
4 <div class="min-w-0 flex-1">4 <div class="min-w-0 flex-1">
5- <span class="font-bold text-spot-text hover:text-spot-green transition">@{{.Handle}}</span>5+ <span class="font-semibold text-spot-text hover:text-spot-green transition">@{{.Handle}}</span>
6 {{if .IsFollowed}}6 {{if .IsFollowed}}
7 <span class="inline-flex items-center gap-0.5 text-[10px] font-medium text-spot-green bg-spot-green/10 px-1.5 py-0.5 rounded-pill ml-1.5">Following</span>7 <span class="inline-flex items-center gap-0.5 text-[10px] font-medium text-spot-green bg-spot-green/10 px-1.5 py-0.5 rounded-pill ml-1.5">Following</span>
8 {{end}}8 {{end}}
modified internal/tmpl/partials/recommendation-article-card.html +4 -4
@@ -3,18 +3,18 @@
33 <div class="flex items-start justify-between gap-4">
44 <div class="min-w-0 flex-1">
55 <div class="flex items-start gap-2.5">
6- {{if not .IsRead}}<span class="w-2.5 h-2.5 rounded-full bg-spot-green shrink-0 mt-1.5"></span>{{end}}
6+ {{if not .IsRead}}<span class="w-2 h-2 rounded-full bg-spot-green shrink-0 mt-2 animate-pulse-dot"></span>{{end}}
77 <a href="/articles/{{.ArticleID}}" class="font-semibold text-spot-text hover:text-spot-green transition text-[17px] leading-snug">{{.Title}}</a>
88 </div>
9- <div class="text-xs text-spot-secondary mt-2 flex items-center gap-1.5 flex-wrap pl-5">
9+ <div class="text-xs text-spot-secondary mt-2 flex items-center gap-1.5 flex-wrap {{if not .IsRead}}pl-[18px]{{end}}">
1010 {{if .FaviconURL}}{{template "favicon" dict "src" .FaviconURL "size" "w-3.5 h-3.5"}}{{end}}
1111 <a href="/articles?feed={{.FeedURL}}" class="hover:text-spot-text transition font-medium">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</a>
1212 {{if .Author}}<span class="text-spot-muted">&middot;</span><span>{{.Author}}</span>{{end}}
1313 {{if .Published.Valid}}<span class="text-spot-muted">&middot;</span><span>{{.Published.Time.Format "Jan 2"}}</span>{{end}}
1414 </div>
15- {{if .Summary}}<p class="text-sm text-spot-secondary mt-2.5 line-clamp-2 leading-relaxed pl-5">{{plainText .Summary}}</p>{{end}}
15+ {{if .Summary}}<p class="text-sm text-spot-secondary mt-2.5 line-clamp-2 leading-relaxed {{if not .IsRead}}pl-[18px]{{end}}">{{plainText .Summary}}</p>{{end}}
1616 </div>
17- <div class="shrink-0 pt-1">
17+ <div class="shrink-0 pt-0.5">
1818 <button hx-post="/recs/dismiss-article" hx-target="closest article" hx-swap="delete" hx-include="#dismiss-{{.ArticleID}}"
1919 class="text-[10px] text-spot-muted hover:text-spot-text uppercase tracking-button transition flex items-center gap-1"
2020 title="Not interested">
@@ -3,18 +3,18 @@
3 <div class="flex items-start justify-between gap-4">3 <div class="flex items-start justify-between gap-4">
4 <div class="min-w-0 flex-1">4 <div class="min-w-0 flex-1">
5 <div class="flex items-start gap-2.5">5 <div class="flex items-start gap-2.5">
6- {{if not .IsRead}}<span class="w-2.5 h-2.5 rounded-full bg-spot-green shrink-0 mt-1.5"></span>{{end}}6+ {{if not .IsRead}}<span class="w-2 h-2 rounded-full bg-spot-green shrink-0 mt-2 animate-pulse-dot"></span>{{end}}
7 <a href="/articles/{{.ArticleID}}" class="font-semibold text-spot-text hover:text-spot-green transition text-[17px] leading-snug">{{.Title}}</a>7 <a href="/articles/{{.ArticleID}}" class="font-semibold text-spot-text hover:text-spot-green transition text-[17px] leading-snug">{{.Title}}</a>
8 </div>8 </div>
9- <div class="text-xs text-spot-secondary mt-2 flex items-center gap-1.5 flex-wrap pl-5">9+ <div class="text-xs text-spot-secondary mt-2 flex items-center gap-1.5 flex-wrap {{if not .IsRead}}pl-[18px]{{end}}">
10 {{if .FaviconURL}}{{template "favicon" dict "src" .FaviconURL "size" "w-3.5 h-3.5"}}{{end}}10 {{if .FaviconURL}}{{template "favicon" dict "src" .FaviconURL "size" "w-3.5 h-3.5"}}{{end}}
11 <a href="/articles?feed={{.FeedURL}}" class="hover:text-spot-text transition font-medium">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</a>11 <a href="/articles?feed={{.FeedURL}}" class="hover:text-spot-text transition font-medium">{{if .FeedTitle}}{{.FeedTitle}}{{else}}{{.FeedURL}}{{end}}</a>
12 {{if .Author}}<span class="text-spot-muted">&middot;</span><span>{{.Author}}</span>{{end}}12 {{if .Author}}<span class="text-spot-muted">&middot;</span><span>{{.Author}}</span>{{end}}
13 {{if .Published.Valid}}<span class="text-spot-muted">&middot;</span><span>{{.Published.Time.Format "Jan 2"}}</span>{{end}}13 {{if .Published.Valid}}<span class="text-spot-muted">&middot;</span><span>{{.Published.Time.Format "Jan 2"}}</span>{{end}}
14 </div>14 </div>
15- {{if .Summary}}<p class="text-sm text-spot-secondary mt-2.5 line-clamp-2 leading-relaxed pl-5">{{plainText .Summary}}</p>{{end}}15+ {{if .Summary}}<p class="text-sm text-spot-secondary mt-2.5 line-clamp-2 leading-relaxed {{if not .IsRead}}pl-[18px]{{end}}">{{plainText .Summary}}</p>{{end}}
16 </div>16 </div>
17- <div class="shrink-0 pt-1">17+ <div class="shrink-0 pt-0.5">
18 <button hx-post="/recs/dismiss-article" hx-target="closest article" hx-swap="delete" hx-include="#dismiss-{{.ArticleID}}"18 <button hx-post="/recs/dismiss-article" hx-target="closest article" hx-swap="delete" hx-include="#dismiss-{{.ArticleID}}"
19 class="text-[10px] text-spot-muted hover:text-spot-text uppercase tracking-button transition flex items-center gap-1"19 class="text-[10px] text-spot-muted hover:text-spot-text uppercase tracking-button transition flex items-center gap-1"
20 title="Not interested">20 title="Not interested">
modified internal/tmpl/partials/recommendation-feed-card.html +4 -4
@@ -1,10 +1,10 @@
11 {{define "recommendation-feed-card.html"}}
2-<div class="recommendation-card bg-spot-surface rounded-xl p-3 hover:bg-spot-hover-50 transition shadow-spot">
2+<div class="recommendation-card bg-spot-surface rounded-xl p-3.5 hover:bg-spot-hover-50 transition shadow-spot">
33 <div class="flex items-center justify-between gap-2">
4- <a href="/articles?feed={{.feed_url}}" class="min-w-0 flex items-center gap-2 flex-1">
5- {{template "favicon" dict "src" .favicon_url "size" "w-4 h-4"}}
4+ <a href="/articles?feed={{.feed_url}}" class="min-w-0 flex items-center gap-2.5 flex-1">
5+ {{template "favicon" dict "src" .favicon_url "size" "w-5 h-5"}}
66 <div class="min-w-0">
7- <div class="font-bold text-sm text-spot-text truncate">{{if .title}}{{.title}}{{else}}{{.feed_url}}{{end}}</div>
7+ <div class="font-semibold text-sm text-spot-text truncate">{{if .title}}{{.title}}{{else}}{{.feed_url}}{{end}}</div>
88 {{if .description}}<p class="text-xs text-spot-secondary truncate mt-0.5">{{.description}}</p>{{end}}
99 </div>
1010 </a>
@@ -1,10 +1,10 @@
1 {{define "recommendation-feed-card.html"}}1 {{define "recommendation-feed-card.html"}}
2-<div class="recommendation-card bg-spot-surface rounded-xl p-3 hover:bg-spot-hover-50 transition shadow-spot">2+<div class="recommendation-card bg-spot-surface rounded-xl p-3.5 hover:bg-spot-hover-50 transition shadow-spot">
3 <div class="flex items-center justify-between gap-2">3 <div class="flex items-center justify-between gap-2">
4- <a href="/articles?feed={{.feed_url}}" class="min-w-0 flex items-center gap-2 flex-1">4+ <a href="/articles?feed={{.feed_url}}" class="min-w-0 flex items-center gap-2.5 flex-1">
5- {{template "favicon" dict "src" .favicon_url "size" "w-4 h-4"}}5+ {{template "favicon" dict "src" .favicon_url "size" "w-5 h-5"}}
6 <div class="min-w-0">6 <div class="min-w-0">
7- <div class="font-bold text-sm text-spot-text truncate">{{if .title}}{{.title}}{{else}}{{.feed_url}}{{end}}</div>7+ <div class="font-semibold text-sm text-spot-text truncate">{{if .title}}{{.title}}{{else}}{{.feed_url}}{{end}}</div>
8 {{if .description}}<p class="text-xs text-spot-secondary truncate mt-0.5">{{.description}}</p>{{end}}8 {{if .description}}<p class="text-xs text-spot-secondary truncate mt-0.5">{{.description}}</p>{{end}}
9 </div>9 </div>
10 </a>10 </a>
modified internal/tmpl/profile.html +12 -12
@@ -1,20 +1,20 @@
11 {{define "profile.html"}}
22 <div class="max-w-2xl mx-auto">
3- <div class="bg-spot-surface rounded-xl p-6 mb-6">
4- <div class="flex items-center gap-4">
3+ <div class="bg-spot-surface rounded-2xl p-6 mb-6">
4+ <div class="flex items-center gap-5">
55 {{if .ProfileUser.AvatarURL}}<img src="{{.ProfileUser.AvatarURL}}" class="w-20 h-20 rounded-full ring-2 ring-spot-divider">{{else}}<div class="w-20 h-20 rounded-full bg-spot-hover flex items-center justify-center text-spot-muted"><svg class="w-10 h-10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 4-7 8-7s8 3 8 7"/></svg></div>{{end}}
66 <div class="min-w-0 flex-1">
7- <h1 class="text-2xl font-bold text-spot-text truncate">
7+ <h1 class="text-2xl font-bold text-spot-text truncate" style="letter-spacing: -0.02em;">
88 {{if .ProfileUser.DisplayName}}{{.ProfileUser.DisplayName}}{{end}}
99 </h1>
10- <p class="flex items-center gap-1.5 text-spot-secondary">@{{.ProfileUser.Handle}}<a href="https://bsky.app/profile/{{.ProfileUser.Handle}}" target="_blank" rel="noopener" class="text-spot-secondary hover:text-spot-green transition"><svg class="w-4 h-4" viewBox="0 0 24 24" fill="currentColor">{{template "icon-bluesky"}}</svg></a></p>
10+ <p class="flex items-center gap-1.5 text-spot-secondary mt-1">@{{.ProfileUser.Handle}}<a href="https://bsky.app/profile/{{.ProfileUser.Handle}}" target="_blank" rel="noopener" class="text-spot-secondary hover:text-spot-green transition"><svg class="w-4 h-4" viewBox="0 0 24 24" fill="currentColor">{{template "icon-bluesky"}}</svg></a></p>
1111 <div class="flex gap-4 mt-3">
1212 <a href="/feeds" class="group">
13- <span class="text-lg font-bold text-spot-text">{{.SubscriptionCount}}</span>
13+ <span class="text-xl font-bold text-spot-text">{{.SubscriptionCount}}</span>
1414 <span class="text-sm text-spot-secondary ml-1 group-hover:text-spot-text transition">feeds</span>
1515 </a>
16- <a href="/library" class="border-l border-spot-divider pl-4 group">
17- <span class="text-lg font-bold text-spot-text">{{.AnnotationCount}}</span>
16+ <a href="/library" class="border-l border-spot-divider pl-5 group">
17+ <span class="text-xl font-bold text-spot-text">{{.AnnotationCount}}</span>
1818 <span class="text-sm text-spot-secondary ml-1 group-hover:text-spot-text transition">annotations</span>
1919 </a>
2020 </div>
@@ -28,7 +28,7 @@
2828 <form id="lang-form" hx-post="/settings/languages" hx-swap="none" hx-on::after-request="location.reload()">
2929 <p class="text-sm font-semibold text-spot-text mb-1">Recommendation languages</p>
3030 <p class="text-xs text-spot-secondary mb-4">Filter article recommendations to specific languages. Leave empty to show all.</p>
31- <div class="flex flex-wrap gap-2 mb-4">
31+ <div class="flex flex-wrap gap-1.5 mb-4">
3232 {{range .AvailableLanguages}}
3333 <label class="lang-pill cursor-pointer text-sm px-4 py-1.5 rounded-pill font-bold transition {{if containsString $.UserLanguages .Code}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">
3434 <input type="checkbox" name="languages" value="{{.Code}}" {{if containsString $.UserLanguages .Code}}checked{{end}} class="hidden">
@@ -56,9 +56,9 @@
5656 {{end}}
5757
5858 <h2 class="text-sm font-bold text-spot-text uppercase tracking-wide mb-3">Feeds</h2>
59- <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider mb-6">
59+ <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider mb-6 overflow-hidden">
6060 {{range .Subscriptions}}
61- <a href="/articles?feed={{.FeedURL}}" class="flex items-center gap-3 px-5 py-3 hover:bg-spot-hover-50 transition first:rounded-t-xl last:rounded-b-xl">
61+ <a href="/articles?feed={{.FeedURL}}" class="flex items-center gap-3 px-5 py-3.5 hover:bg-spot-hover-50 transition">
6262 {{template "favicon" dict "src" .FaviconURL.String "size" "w-5 h-5"}}
6363 <div class="min-w-0 flex-1">
6464 <div class="flex items-center gap-2 flex-wrap">
@@ -70,7 +70,7 @@
7070 <svg class="w-4 h-4 text-spot-muted shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/></svg>
7171 </a>
7272 {{else}}
73- <div class="px-4 py-6 text-center text-spot-secondary text-sm">No feeds.</div>
73+ <div class="px-5 py-6 text-center text-spot-secondary text-sm">No feeds.</div>
7474 {{end}}
7575 </div>
7676
@@ -79,7 +79,7 @@
7979 {{range .Annotations}}
8080 {{template "annotation-card.html" dict "annotation" . "userDID" $.CurrentUserDID}}
8181 {{else}}
82- <p class="text-sm text-spot-secondary text-center py-4">No annotations.</p>
82+ <p class="text-sm text-spot-secondary text-center py-6">No annotations.</p>
8383 {{end}}
8484 </div>
8585 </div>
@@ -1,20 +1,20 @@
1 {{define "profile.html"}}1 {{define "profile.html"}}
2 <div class="max-w-2xl mx-auto">2 <div class="max-w-2xl mx-auto">
3- <div class="bg-spot-surface rounded-xl p-6 mb-6">3+ <div class="bg-spot-surface rounded-2xl p-6 mb-6">
4- <div class="flex items-center gap-4">4+ <div class="flex items-center gap-5">
5 {{if .ProfileUser.AvatarURL}}<img src="{{.ProfileUser.AvatarURL}}" class="w-20 h-20 rounded-full ring-2 ring-spot-divider">{{else}}<div class="w-20 h-20 rounded-full bg-spot-hover flex items-center justify-center text-spot-muted"><svg class="w-10 h-10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 4-7 8-7s8 3 8 7"/></svg></div>{{end}}5 {{if .ProfileUser.AvatarURL}}<img src="{{.ProfileUser.AvatarURL}}" class="w-20 h-20 rounded-full ring-2 ring-spot-divider">{{else}}<div class="w-20 h-20 rounded-full bg-spot-hover flex items-center justify-center text-spot-muted"><svg class="w-10 h-10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 4-7 8-7s8 3 8 7"/></svg></div>{{end}}
6 <div class="min-w-0 flex-1">6 <div class="min-w-0 flex-1">
7- <h1 class="text-2xl font-bold text-spot-text truncate">7+ <h1 class="text-2xl font-bold text-spot-text truncate" style="letter-spacing: -0.02em;">
8 {{if .ProfileUser.DisplayName}}{{.ProfileUser.DisplayName}}{{end}}8 {{if .ProfileUser.DisplayName}}{{.ProfileUser.DisplayName}}{{end}}
9 </h1>9 </h1>
10- <p class="flex items-center gap-1.5 text-spot-secondary">@{{.ProfileUser.Handle}}<a href="https://bsky.app/profile/{{.ProfileUser.Handle}}" target="_blank" rel="noopener" class="text-spot-secondary hover:text-spot-green transition"><svg class="w-4 h-4" viewBox="0 0 24 24" fill="currentColor">{{template "icon-bluesky"}}</svg></a></p>10+ <p class="flex items-center gap-1.5 text-spot-secondary mt-1">@{{.ProfileUser.Handle}}<a href="https://bsky.app/profile/{{.ProfileUser.Handle}}" target="_blank" rel="noopener" class="text-spot-secondary hover:text-spot-green transition"><svg class="w-4 h-4" viewBox="0 0 24 24" fill="currentColor">{{template "icon-bluesky"}}</svg></a></p>
11 <div class="flex gap-4 mt-3">11 <div class="flex gap-4 mt-3">
12 <a href="/feeds" class="group">12 <a href="/feeds" class="group">
13- <span class="text-lg font-bold text-spot-text">{{.SubscriptionCount}}</span>13+ <span class="text-xl font-bold text-spot-text">{{.SubscriptionCount}}</span>
14 <span class="text-sm text-spot-secondary ml-1 group-hover:text-spot-text transition">feeds</span>14 <span class="text-sm text-spot-secondary ml-1 group-hover:text-spot-text transition">feeds</span>
15 </a>15 </a>
16- <a href="/library" class="border-l border-spot-divider pl-4 group">16+ <a href="/library" class="border-l border-spot-divider pl-5 group">
17- <span class="text-lg font-bold text-spot-text">{{.AnnotationCount}}</span>17+ <span class="text-xl font-bold text-spot-text">{{.AnnotationCount}}</span>
18 <span class="text-sm text-spot-secondary ml-1 group-hover:text-spot-text transition">annotations</span>18 <span class="text-sm text-spot-secondary ml-1 group-hover:text-spot-text transition">annotations</span>
19 </a>19 </a>
20 </div>20 </div>
@@ -28,7 +28,7 @@
28 <form id="lang-form" hx-post="/settings/languages" hx-swap="none" hx-on::after-request="location.reload()">28 <form id="lang-form" hx-post="/settings/languages" hx-swap="none" hx-on::after-request="location.reload()">
29 <p class="text-sm font-semibold text-spot-text mb-1">Recommendation languages</p>29 <p class="text-sm font-semibold text-spot-text mb-1">Recommendation languages</p>
30 <p class="text-xs text-spot-secondary mb-4">Filter article recommendations to specific languages. Leave empty to show all.</p>30 <p class="text-xs text-spot-secondary mb-4">Filter article recommendations to specific languages. Leave empty to show all.</p>
31- <div class="flex flex-wrap gap-2 mb-4">31+ <div class="flex flex-wrap gap-1.5 mb-4">
32 {{range .AvailableLanguages}}32 {{range .AvailableLanguages}}
33 <label class="lang-pill cursor-pointer text-sm px-4 py-1.5 rounded-pill font-bold transition {{if containsString $.UserLanguages .Code}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">33 <label class="lang-pill cursor-pointer text-sm px-4 py-1.5 rounded-pill font-bold transition {{if containsString $.UserLanguages .Code}}bg-spot-active-pill-bg text-spot-active-pill-text{{else}}bg-spot-hover text-spot-secondary hover:text-spot-text{{end}}">
34 <input type="checkbox" name="languages" value="{{.Code}}" {{if containsString $.UserLanguages .Code}}checked{{end}} class="hidden">34 <input type="checkbox" name="languages" value="{{.Code}}" {{if containsString $.UserLanguages .Code}}checked{{end}} class="hidden">
@@ -56,9 +56,9 @@
56 {{end}}56 {{end}}
57 57
58 <h2 class="text-sm font-bold text-spot-text uppercase tracking-wide mb-3">Feeds</h2>58 <h2 class="text-sm font-bold text-spot-text uppercase tracking-wide mb-3">Feeds</h2>
59- <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider mb-6">59+ <div class="bg-spot-surface rounded-xl divide-y divide-spot-divider mb-6 overflow-hidden">
60 {{range .Subscriptions}}60 {{range .Subscriptions}}
61- <a href="/articles?feed={{.FeedURL}}" class="flex items-center gap-3 px-5 py-3 hover:bg-spot-hover-50 transition first:rounded-t-xl last:rounded-b-xl">61+ <a href="/articles?feed={{.FeedURL}}" class="flex items-center gap-3 px-5 py-3.5 hover:bg-spot-hover-50 transition">
62 {{template "favicon" dict "src" .FaviconURL.String "size" "w-5 h-5"}}62 {{template "favicon" dict "src" .FaviconURL.String "size" "w-5 h-5"}}
63 <div class="min-w-0 flex-1">63 <div class="min-w-0 flex-1">
64 <div class="flex items-center gap-2 flex-wrap">64 <div class="flex items-center gap-2 flex-wrap">
@@ -70,7 +70,7 @@
70 <svg class="w-4 h-4 text-spot-muted shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/></svg>70 <svg class="w-4 h-4 text-spot-muted shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/></svg>
71 </a>71 </a>
72 {{else}}72 {{else}}
73- <div class="px-4 py-6 text-center text-spot-secondary text-sm">No feeds.</div>73+ <div class="px-5 py-6 text-center text-spot-secondary text-sm">No feeds.</div>
74 {{end}}74 {{end}}
75 </div>75 </div>
76 76
@@ -79,7 +79,7 @@
79 {{range .Annotations}}79 {{range .Annotations}}
80 {{template "annotation-card.html" dict "annotation" . "userDID" $.CurrentUserDID}}80 {{template "annotation-card.html" dict "annotation" . "userDID" $.CurrentUserDID}}
81 {{else}}81 {{else}}
82- <p class="text-sm text-spot-secondary text-center py-4">No annotations.</p>82+ <p class="text-sm text-spot-secondary text-center py-6">No annotations.</p>
83 {{end}}83 {{end}}
84 </div>84 </div>
85 </div>85 </div>
modified internal/tmpl/stats.html +8 -8
@@ -1,6 +1,6 @@
11 {{define "stats.html"}}
22 <div class="flex items-center justify-between mb-2">
3- <h1 class="text-2xl font-bold text-spot-text">Stats</h1>
3+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">Stats</h1>
44 </div>
55 <p class="text-sm text-spot-secondary mb-6">Application metrics and performance data.</p>
66
@@ -11,12 +11,12 @@
1111 <div id="metrics-content" class="space-y-3">
1212 {{range $category, $metrics := .Metrics}}
1313 <div class="bg-spot-surface rounded-xl overflow-hidden">
14- <div class="px-4 py-3 border-b border-spot-divider">
14+ <div class="px-5 py-3.5 border-b border-spot-divider">
1515 <h2 class="font-semibold text-spot-text">{{$category}}</h2>
1616 </div>
1717 <div class="divide-y divide-spot-divider">
1818 {{range $metrics}}
19- <div class="px-4 py-3 flex items-start justify-between hover:bg-spot-hover transition">
19+ <div class="px-5 py-3.5 flex items-start justify-between hover:bg-spot-hover transition">
2020 <div class="flex-1 min-w-0">
2121 <div class="flex items-center gap-2">
2222 <span class="text-sm font-medium text-spot-text">{{.Name}}</span>
@@ -25,7 +25,7 @@
2525 {{end}}
2626 </div>
2727 {{if .Labels}}
28- <div class="flex gap-2 mt-1">
28+ <div class="flex gap-1.5 mt-1.5">
2929 {{range $key, $value := .Labels}}
3030 <span class="text-xs bg-spot-hover text-spot-secondary px-2 py-0.5 rounded-pill">{{$key}}={{$value}}</span>
3131 {{end}}
@@ -46,11 +46,11 @@
4646 </div>
4747 </div>
4848 {{else}}
49- <div class="bg-spot-surface rounded-xl py-12 px-6 text-center">
50- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">
51- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 19.5v-15m0 0l-6.75 6.75M12.75 4.5l6.75 6.75"/></svg>
49+ <div class="bg-spot-surface rounded-2xl py-14 px-6 text-center">
50+ <div class="w-14 h-14 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
51+ <svg class="w-7 h-7 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 19.5v-15m0 0l-6.75 6.75M12.75 4.5l6.75 6.75"/></svg>
5252 </div>
53- <p class="text-sm text-spot-secondary mb-1">No metrics available</p>
53+ <p class="text-sm text-spot-text font-semibold mb-1">No metrics available</p>
5454 <p class="text-xs text-spot-muted">Metrics will appear here once the application has been running for a while.</p>
5555 </div>
5656 {{end}}
@@ -1,6 +1,6 @@
1 {{define "stats.html"}}1 {{define "stats.html"}}
2 <div class="flex items-center justify-between mb-2">2 <div class="flex items-center justify-between mb-2">
3- <h1 class="text-2xl font-bold text-spot-text">Stats</h1>3+ <h1 class="text-2xl font-bold text-spot-text" style="letter-spacing: -0.02em;">Stats</h1>
4 </div>4 </div>
5 <p class="text-sm text-spot-secondary mb-6">Application metrics and performance data.</p>5 <p class="text-sm text-spot-secondary mb-6">Application metrics and performance data.</p>
6 6
@@ -11,12 +11,12 @@
11 <div id="metrics-content" class="space-y-3">11 <div id="metrics-content" class="space-y-3">
12 {{range $category, $metrics := .Metrics}}12 {{range $category, $metrics := .Metrics}}
13 <div class="bg-spot-surface rounded-xl overflow-hidden">13 <div class="bg-spot-surface rounded-xl overflow-hidden">
14- <div class="px-4 py-3 border-b border-spot-divider">14+ <div class="px-5 py-3.5 border-b border-spot-divider">
15 <h2 class="font-semibold text-spot-text">{{$category}}</h2>15 <h2 class="font-semibold text-spot-text">{{$category}}</h2>
16 </div>16 </div>
17 <div class="divide-y divide-spot-divider">17 <div class="divide-y divide-spot-divider">
18 {{range $metrics}}18 {{range $metrics}}
19- <div class="px-4 py-3 flex items-start justify-between hover:bg-spot-hover transition">19+ <div class="px-5 py-3.5 flex items-start justify-between hover:bg-spot-hover transition">
20 <div class="flex-1 min-w-0">20 <div class="flex-1 min-w-0">
21 <div class="flex items-center gap-2">21 <div class="flex items-center gap-2">
22 <span class="text-sm font-medium text-spot-text">{{.Name}}</span>22 <span class="text-sm font-medium text-spot-text">{{.Name}}</span>
@@ -25,7 +25,7 @@
25 {{end}}25 {{end}}
26 </div>26 </div>
27 {{if .Labels}}27 {{if .Labels}}
28- <div class="flex gap-2 mt-1">28+ <div class="flex gap-1.5 mt-1.5">
29 {{range $key, $value := .Labels}}29 {{range $key, $value := .Labels}}
30 <span class="text-xs bg-spot-hover text-spot-secondary px-2 py-0.5 rounded-pill">{{$key}}={{$value}}</span>30 <span class="text-xs bg-spot-hover text-spot-secondary px-2 py-0.5 rounded-pill">{{$key}}={{$value}}</span>
31 {{end}}31 {{end}}
@@ -46,11 +46,11 @@
46 </div>46 </div>
47 </div>47 </div>
48 {{else}}48 {{else}}
49- <div class="bg-spot-surface rounded-xl py-12 px-6 text-center">49+ <div class="bg-spot-surface rounded-2xl py-14 px-6 text-center">
50- <div class="w-14 h-14 rounded-full bg-spot-hover flex items-center justify-center mb-4 mx-auto">50+ <div class="w-14 h-14 rounded-2xl bg-spot-green/15 flex items-center justify-center mb-5 mx-auto">
51- <svg class="w-7 h-7 text-spot-muted" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 19.5v-15m0 0l-6.75 6.75M12.75 4.5l6.75 6.75"/></svg>51+ <svg class="w-7 h-7 text-spot-green" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M9 19.5v-15m0 0l-6.75 6.75M12.75 4.5l6.75 6.75"/></svg>
52 </div>52 </div>
53- <p class="text-sm text-spot-secondary mb-1">No metrics available</p>53+ <p class="text-sm text-spot-text font-semibold mb-1">No metrics available</p>
54 <p class="text-xs text-spot-muted">Metrics will appear here once the application has been running for a while.</p>54 <p class="text-xs text-spot-muted">Metrics will appear here once the application has been running for a while.</p>
55 </div>55 </div>
56 {{end}}56 {{end}}
modified internal/tmpl/terms.html +3 -3
@@ -1,9 +1,9 @@
11 {{define "terms.html"}}
22 <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>
3+ <h1 class="text-2xl font-bold text-spot-text mb-2" style="letter-spacing: -0.02em;">Terms of Service</h1>
44 <p class="text-sm text-spot-secondary mb-8">Last updated: May 2, 2026</p>
55
6- <div class="space-y-6 text-sm text-spot-body leading-relaxed">
6+ <div class="space-y-7 text-sm text-spot-body leading-relaxed">
77 <div>
88 <h2 class="text-lg font-bold text-spot-text mb-3">1. Acceptance of Terms</h2>
99 <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>
@@ -69,4 +69,4 @@
6969 <script>
7070 (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)})();
7171 </script>
72-{{end}}
\ No newline at end of file
72+{{end}}
@@ -1,9 +1,9 @@
1 {{define "terms.html"}}1 {{define "terms.html"}}
2 <div class="max-w-2xl mx-auto py-12 px-4">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>3+ <h1 class="text-2xl font-bold text-spot-text mb-2" style="letter-spacing: -0.02em;">Terms of Service</h1>
4 <p class="text-sm text-spot-secondary mb-8">Last updated: May 2, 2026</p>4 <p class="text-sm text-spot-secondary mb-8">Last updated: May 2, 2026</p>
5 5
6- <div class="space-y-6 text-sm text-spot-body leading-relaxed">6+ <div class="space-y-7 text-sm text-spot-body leading-relaxed">
7 <div>7 <div>
8 <h2 class="text-lg font-bold text-spot-text mb-3">1. Acceptance of Terms</h2>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>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>
@@ -69,4 +69,4 @@
69 <script>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)})();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>71 </script>
72-{{end}}
\ No newline at end of file\ No newline at end of file
72+{{end}}
modified static/input.css +40 -3
@@ -87,23 +87,60 @@
8787 body {
8888 font-family: 'Inter', 'Helvetica Neue', helvetica, arial, sans-serif;
8989 letter-spacing: -0.01em;
90+ -webkit-font-smoothing: antialiased;
91+ -moz-osx-font-smoothing: grayscale;
9092 }
9193
9294 .sidebar-link {
93- transition: color 0.15s;
95+ transition: color 0.15s, background-color 0.15s;
9496 }
9597 .sidebar-link:hover {
9698 color: var(--spot-text);
99+ background: var(--spot-hover-50);
100+}
101+.sidebar-link.active {
102+ color: var(--spot-green);
103+ background: var(--spot-hover-50);
97104 }
98-
99-
100105
101106 ::-webkit-scrollbar { width: 8px; }
102107 ::-webkit-scrollbar-track { background: var(--spot-bg); }
103108 ::-webkit-scrollbar-thumb { background: var(--spot-muted); border-radius: 6px; }
104109 ::-webkit-scrollbar-thumb:hover { background: var(--spot-outline); }
105110
111+* {
112+ scrollbar-width: thin;
113+ scrollbar-color: var(--spot-muted) transparent;
114+}
115+
106116 .htmx-swapping {
107117 opacity: 0;
108118 transition: opacity 0.3s ease-out;
109119 }
120+
121+::selection {
122+ background: rgba(0,117,74,0.30);
123+ color: var(--spot-text);
124+}
125+
126+input:focus, textarea:focus {
127+ outline: none;
128+}
129+
130+@keyframes fadeIn {
131+ from { opacity: 0; transform: translateY(4px); }
132+ to { opacity: 1; transform: translateY(0); }
133+}
134+
135+.animate-fade-in {
136+ animation: fadeIn 0.3s ease-out forwards;
137+}
138+
139+@keyframes pulse-dot {
140+ 0%, 100% { opacity: 1; }
141+ 50% { opacity: 0.5; }
142+}
143+
144+.animate-pulse-dot {
145+ animation: pulse-dot 2s ease-in-out infinite;
146+}
@@ -87,23 +87,60 @@
87 body {87 body {
88 font-family: 'Inter', 'Helvetica Neue', helvetica, arial, sans-serif;88 font-family: 'Inter', 'Helvetica Neue', helvetica, arial, sans-serif;
89 letter-spacing: -0.01em;89 letter-spacing: -0.01em;
90+ -webkit-font-smoothing: antialiased;
91+ -moz-osx-font-smoothing: grayscale;
90 }92 }
91 93
92 .sidebar-link {94 .sidebar-link {
93- transition: color 0.15s;95+ transition: color 0.15s, background-color 0.15s;
94 }96 }
95 .sidebar-link:hover {97 .sidebar-link:hover {
96 color: var(--spot-text);98 color: var(--spot-text);
99+ background: var(--spot-hover-50);
100+}
101+.sidebar-link.active {
102+ color: var(--spot-green);
103+ background: var(--spot-hover-50);
97 }104 }
98-
99-
100 105
101 ::-webkit-scrollbar { width: 8px; }106 ::-webkit-scrollbar { width: 8px; }
102 ::-webkit-scrollbar-track { background: var(--spot-bg); }107 ::-webkit-scrollbar-track { background: var(--spot-bg); }
103 ::-webkit-scrollbar-thumb { background: var(--spot-muted); border-radius: 6px; }108 ::-webkit-scrollbar-thumb { background: var(--spot-muted); border-radius: 6px; }
104 ::-webkit-scrollbar-thumb:hover { background: var(--spot-outline); }109 ::-webkit-scrollbar-thumb:hover { background: var(--spot-outline); }
105 110
111+* {
112+ scrollbar-width: thin;
113+ scrollbar-color: var(--spot-muted) transparent;
114+}
115+
106 .htmx-swapping {116 .htmx-swapping {
107 opacity: 0;117 opacity: 0;
108 transition: opacity 0.3s ease-out;118 transition: opacity 0.3s ease-out;
109 }119 }
120+
121+::selection {
122+ background: rgba(0,117,74,0.30);
123+ color: var(--spot-text);
124+}
125+
126+input:focus, textarea:focus {
127+ outline: none;
128+}
129+
130+@keyframes fadeIn {
131+ from { opacity: 0; transform: translateY(4px); }
132+ to { opacity: 1; transform: translateY(0); }
133+}
134+
135+.animate-fade-in {
136+ animation: fadeIn 0.3s ease-out forwards;
137+}
138+
139+@keyframes pulse-dot {
140+ 0%, 100% { opacity: 1; }
141+ 50% { opacity: 0.5; }
142+}
143+
144+.animate-pulse-dot {
145+ animation: pulse-dot 2s ease-in-out infinite;
146+}