Write on the margins of the internet. Powered by the AT Protocol. margin.at
extension web atproto comments

fix some mobile stuff

+68 -27
+3 -3
web/src/components/feed/MasonryFeed.tsx
··· 107 107 } 108 108 109 109 return ( 110 - <div className="columns-1 sm:columns-2 xl:columns-3 2xl:columns-4 gap-4 animate-fade-in"> 110 + <div className="columns-1 sm:columns-2 md:columns-3 xl:columns-4 gap-4 animate-fade-in"> 111 111 {items.map((item) => ( 112 112 <div key={item.uri || item.cid} className="break-inside-avoid mb-4"> 113 113 <Card item={item} onDelete={handleDelete} /> ··· 158 158 onChange={handleTabChange} 159 159 /> 160 160 </div> 161 - <LayoutToggle /> 161 + <LayoutToggle className="hidden sm:inline-flex" /> 162 162 </div> 163 163 </div> 164 164 )} 165 165 166 166 {!showTabs && ( 167 167 <div className="flex justify-end mb-4"> 168 - <LayoutToggle /> 168 + <LayoutToggle className="hidden sm:inline-flex" /> 169 169 </div> 170 170 )} 171 171
+14
web/src/components/navigation/MobileNav.tsx
··· 17 17 Highlighter, 18 18 X, 19 19 } from "lucide-react"; 20 + import { AppleIcon } from "../common/Icons"; 20 21 21 22 export default function MobileNav() { 22 23 const user = useStore($user); ··· 118 119 <Settings size={20} /> 119 120 <span>Settings</span> 120 121 </Link> 122 + 123 + <div className="h-px bg-surface-200 dark:bg-surface-700 my-2" /> 124 + 125 + <a 126 + href="https://www.icloud.com/shortcuts/21c87edf29b046db892c9e57dac6d1fd" 127 + target="_blank" 128 + rel="noopener noreferrer" 129 + className="flex items-center gap-3 p-3 rounded-xl hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors text-surface-700 dark:text-surface-200" 130 + onClick={closeMenu} 131 + > 132 + <AppleIcon size={20} /> 133 + <span>iOS Shortcut</span> 134 + </a> 121 135 122 136 <div className="h-px bg-surface-200 dark:bg-surface-700 my-2" /> 123 137
+7 -2
web/src/components/ui/LayoutToggle.tsx
··· 8 8 } from "../../store/feedLayout"; 9 9 import { clsx } from "clsx"; 10 10 11 - export default function LayoutToggle() { 11 + export default function LayoutToggle({ className }: { className?: string }) { 12 12 const layout = useStore($feedLayout); 13 13 14 14 const options: { id: FeedLayout; icon: typeof List; label: string }[] = [ ··· 17 17 ]; 18 18 19 19 return ( 20 - <div className="inline-flex items-center rounded-lg border border-surface-200 dark:border-surface-700 p-0.5 bg-surface-100 dark:bg-surface-800/60"> 20 + <div 21 + className={clsx( 22 + "inline-flex items-center rounded-lg border border-surface-200 dark:border-surface-700 p-0.5 bg-surface-100 dark:bg-surface-800/60", 23 + className, 24 + )} 25 + > 21 26 {options.map((opt) => ( 22 27 <button 23 28 key={opt.id}
+25 -3
web/src/views/content/Url.tsx
··· 17 17 Globe, 18 18 } from "lucide-react"; 19 19 20 - import { EmptyState, Tabs } from "../../components/ui"; 20 + import { EmptyState, Tabs, Input, Button } from "../../components/ui"; 21 21 22 22 export default function UrlPage() { 23 23 const user = useStore($user); ··· 187 187 Explore 188 188 </h1> 189 189 <p className="text-surface-500 dark:text-surface-400 max-w-md mx-auto mb-8"> 190 - Search for any URL in the sidebar to specific see annotations and 190 + Search for any URL in the sidebar to see specific annotations and 191 191 highlights. 192 192 </p> 193 + 194 + <form 195 + onSubmit={(e) => { 196 + e.preventDefault(); 197 + const formData = new FormData(e.currentTarget); 198 + const q = formData.get("q") as string; 199 + if (q?.trim()) { 200 + navigate(`/url?q=${encodeURIComponent(q.trim())}`); 201 + } 202 + }} 203 + className="max-w-md mx-auto mb-8 flex gap-2" 204 + > 205 + <div className="flex-1"> 206 + <Input 207 + name="q" 208 + placeholder="https://example.com" 209 + className="w-full bg-surface-50 dark:bg-surface-800" 210 + autoFocus 211 + /> 212 + </div> 213 + <Button type="submit">Search</Button> 214 + </form> 193 215 194 216 {recentSearches.length > 0 && ( 195 217 <div className="text-left max-w-lg mx-auto bg-surface-50 dark:bg-surface-800/50 rounded-2xl p-6 border border-surface-100 dark:border-surface-800"> ··· 259 281 className="flex items-center gap-1.5 px-3 py-1.5 bg-surface-100 dark:bg-surface-800 hover:bg-surface-200 dark:hover:bg-surface-700 text-surface-900 dark:text-white text-sm font-medium rounded-lg transition-colors" 260 282 > 261 283 {copied ? <Check size={14} /> : <Copy size={14} />} 262 - {copied ? "Copied" : "Share"} 284 + {copied ? "Copied" : "Share your thoughts on this URL"} 263 285 </button> 264 286 )} 265 287 </div>
+19 -19
web/src/views/content/UserUrl.tsx
··· 135 135 136 136 return ( 137 137 <div className="max-w-3xl mx-auto pb-20"> 138 - <header className="flex items-center gap-6 mb-8 p-6 bg-white rounded-2xl border border-surface-200 shadow-sm"> 138 + <header className="flex items-center gap-6 mb-8 p-6 bg-white dark:bg-surface-800 rounded-2xl border border-surface-200 dark:border-surface-700 shadow-sm"> 139 139 <a 140 140 href={bskyProfileUrl} 141 141 target="_blank" ··· 146 146 <img 147 147 src={avatarUrl} 148 148 alt={displayName} 149 - className="w-20 h-20 rounded-full object-cover border-4 border-surface-50" 149 + className="w-20 h-20 rounded-full object-cover border-4 border-surface-50 dark:border-surface-700" 150 150 /> 151 151 ) : ( 152 - <div className="w-20 h-20 rounded-full bg-surface-100 flex items-center justify-center text-2xl font-bold text-surface-500 border-4 border-surface-50"> 152 + <div className="w-20 h-20 rounded-full bg-surface-100 dark:bg-surface-700 flex items-center justify-center text-2xl font-bold text-surface-500 dark:text-surface-400 border-4 border-surface-50 dark:border-surface-700"> 153 153 {getInitial()} 154 154 </div> 155 155 )} 156 156 </a> 157 157 <div className="flex-1"> 158 - <h1 className="text-2xl font-bold text-surface-900 mb-1"> 158 + <h1 className="text-2xl font-bold text-surface-900 dark:text-white mb-1"> 159 159 {displayName} 160 160 </h1> 161 161 {displayHandle && ( ··· 163 163 href={bskyProfileUrl} 164 164 target="_blank" 165 165 rel="noopener noreferrer" 166 - className="text-surface-500 hover:text-primary-600 transition-colors bg-surface-50 hover:bg-primary-50 px-2 py-1 rounded-md text-sm inline-flex items-center gap-1" 166 + className="text-surface-500 dark:text-surface-400 hover:text-primary-600 transition-colors bg-surface-50 dark:bg-surface-700 hover:bg-primary-50 dark:hover:bg-primary-900/30 px-2 py-1 rounded-md text-sm inline-flex items-center gap-1" 167 167 > 168 168 @{displayHandle} <ExternalLink size={12} /> 169 169 </a> ··· 171 171 </div> 172 172 </header> 173 173 174 - <div className="mb-8 p-4 bg-surface-50 border border-surface-200 rounded-xl flex flex-col sm:flex-row sm:items-center gap-4"> 175 - <span className="text-sm font-semibold text-surface-500 uppercase tracking-wide"> 174 + <div className="mb-8 p-4 bg-surface-50 dark:bg-surface-800 border border-surface-200 dark:border-surface-700 rounded-xl flex flex-col sm:flex-row sm:items-center gap-4"> 175 + <span className="text-sm font-semibold text-surface-500 dark:text-surface-400 uppercase tracking-wide"> 176 176 Annotations on: 177 177 </span> 178 178 <a ··· 199 199 )} 200 200 201 201 {!loading && !error && totalItems === 0 && ( 202 - <div className="text-center py-16 bg-surface-50 rounded-2xl border border-dashed border-surface-200"> 203 - <div className="w-12 h-12 bg-surface-100 rounded-full flex items-center justify-center mx-auto mb-4 text-surface-400"> 202 + <div className="text-center py-16 bg-surface-50 dark:bg-surface-800 rounded-2xl border border-dashed border-surface-200 dark:border-surface-700"> 203 + <div className="w-12 h-12 bg-surface-100 dark:bg-surface-700 rounded-full flex items-center justify-center mx-auto mb-4 text-surface-400"> 204 204 <PenTool size={24} /> 205 205 </div> 206 - <h3 className="text-lg font-bold text-surface-900 mb-1"> 206 + <h3 className="text-lg font-bold text-surface-900 dark:text-white mb-1"> 207 207 No items found 208 208 </h3> 209 - <p className="text-surface-500"> 209 + <p className="text-surface-500 dark:text-surface-400"> 210 210 {displayName} hasn&apos;t annotated this page yet. 211 211 </p> 212 212 </div> ··· 215 215 {!loading && !error && totalItems > 0 && ( 216 216 <div className="animate-fade-in"> 217 217 <div className="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-6"> 218 - <h2 className="text-xl font-bold text-surface-900"> 218 + <h2 className="text-xl font-bold text-surface-900 dark:text-white"> 219 219 {totalItems} item{totalItems !== 1 ? "s" : ""} 220 220 </h2> 221 - <div className="flex bg-surface-100 p-1 rounded-xl self-start md:self-auto"> 221 + <div className="flex bg-surface-100 dark:bg-surface-800 p-1 rounded-xl self-start md:self-auto"> 222 222 <button 223 223 className={clsx( 224 224 "px-4 py-1.5 rounded-lg text-sm font-medium transition-all", 225 225 activeTab === "all" 226 - ? "bg-white text-surface-900 shadow-sm" 227 - : "text-surface-500 hover:text-surface-700", 226 + ? "bg-white dark:bg-surface-700 text-surface-900 dark:text-white shadow-sm" 227 + : "text-surface-500 dark:text-surface-400 hover:text-surface-700 dark:hover:text-surface-200", 228 228 )} 229 229 onClick={() => setActiveTab("all")} 230 230 > ··· 234 234 className={clsx( 235 235 "px-4 py-1.5 rounded-lg text-sm font-medium transition-all", 236 236 activeTab === "annotations" 237 - ? "bg-white text-surface-900 shadow-sm" 238 - : "text-surface-500 hover:text-surface-700", 237 + ? "bg-white dark:bg-surface-700 text-surface-900 dark:text-white shadow-sm" 238 + : "text-surface-500 dark:text-surface-400 hover:text-surface-700 dark:hover:text-surface-200", 239 239 )} 240 240 onClick={() => setActiveTab("annotations")} 241 241 > ··· 245 245 className={clsx( 246 246 "px-4 py-1.5 rounded-lg text-sm font-medium transition-all", 247 247 activeTab === "highlights" 248 - ? "bg-white text-surface-900 shadow-sm" 249 - : "text-surface-500 hover:text-surface-700", 248 + ? "bg-white dark:bg-surface-700 text-surface-900 dark:text-white shadow-sm" 249 + : "text-surface-500 dark:text-surface-400 hover:text-surface-700 dark:hover:text-surface-200", 250 250 )} 251 251 onClick={() => setActiveTab("highlights")} 252 252 >