👁️
5
fork

Configure Feed

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

respect prefers reduced motion

+36 -18
+18
CLAUDE.md
··· 86 86 - Borders: `border-gray-300 dark:border-slate-700` 87 87 - Interactive elements: `hover:bg-gray-100 dark:hover:bg-gray-800` 88 88 89 + **Reduced Motion Support:** 90 + - Respect `prefers-reduced-motion` for decorative and dramatic animations 91 + - Use `motion-safe:` prefix on transitions, NOT on the hover state itself (preserve functionality, remove animation) 92 + - Categories of effects: 93 + - **Keep without motion-safe:** Subtle state indicators - hover background colors, border color changes. These are quick and communicate interactivity. 94 + - **Wrap with motion-safe:** Flourishes and dramatic effects - font-variation-settings animations (weight/CASL), shadows appearing (`hover:shadow-lg`), overlay fades, scale transforms, ring transitions. Anything slow, dramatic, or purely decorative. 95 + - Pattern for flourish animations: 96 + ``` 97 + [font-variation-settings:'wght'_400] 98 + motion-safe:group-hover:[font-variation-settings:'wght'_500] 99 + motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out 100 + ``` 101 + - Pattern for functional features with animated presentation: 102 + ``` 103 + opacity-0 group-hover:opacity-100 motion-safe:transition-opacity 104 + ``` 105 + (Overlay still appears on hover, just instantly with reduced motion) 106 + 89 107 ### Development Tooling 90 108 91 109 - **Nix**: flake.nix provides Node.js 22, TypeSpec, and language servers
+3 -3
src/components/CardImage.tsx
··· 185 185 size="normal" 186 186 className="w-full h-full object-cover rounded-[4.75%/3.5%]" 187 187 /> 188 - <div className="absolute inset-0 bg-gradient-to-t from-black/80 dark:from-black/90 via-black/0 to-black/0 opacity-0 group-hover:opacity-100 transition-opacity"> 188 + <div className="absolute inset-0 bg-gradient-to-t from-black/80 dark:from-black/90 via-black/0 to-black/0 opacity-0 group-hover:opacity-100 motion-safe:transition-opacity"> 189 189 <div className="absolute bottom-0 left-0 right-0 p-3"> 190 190 <p className="text-white font-semibold text-sm line-clamp-2"> 191 191 {card.name} ··· 201 201 ); 202 202 203 203 const className = 204 - "group relative aspect-[5/7] overflow-hidden hover:ring-2 hover:ring-cyan-500 transition-all block rounded-[4.75%/3.5%]"; 204 + "group relative aspect-[5/7] overflow-hidden hover:ring-2 hover:ring-cyan-500 motion-safe:transition-shadow block rounded-[4.75%/3.5%]"; 205 205 206 206 if (href) { 207 207 return ( ··· 250 250 ); 251 251 252 252 const baseClassName = 253 - "aspect-[5/7] overflow-hidden hover:ring-2 hover:ring-cyan-500 transition-all block rounded-[4.75%/3.5%]"; 253 + "aspect-[5/7] overflow-hidden hover:ring-2 hover:ring-cyan-500 motion-safe:transition-shadow block rounded-[4.75%/3.5%]"; 254 254 const finalClassName = `${baseClassName} ${className ?? ""}`; 255 255 256 256 if (href) {
+1 -1
src/components/deck/DraggableCard.tsx
··· 100 100 <span className="text-gray-600 dark:text-gray-400 font-mono text-xs w-4 text-right flex-shrink-0"> 101 101 {card.quantity} 102 102 </span> 103 - <span className="text-gray-900 dark:text-white text-sm truncate flex-1 min-w-0 transition-[font-variation-settings] duration-200 ease-out [font-variation-settings:'wght'_400] group-hover:[font-variation-settings:'wght'_500]"> 103 + <span className="text-gray-900 dark:text-white text-sm truncate flex-1 min-w-0 motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out [font-variation-settings:'wght'_400] motion-safe:group-hover:[font-variation-settings:'wght'_500]"> 104 104 {primaryFace ? primaryFace.name : isLoading ? "" : "Unknown Card"} 105 105 </span> 106 106 {violations && violations.length > 0 && (
+1 -1
src/components/richtext/RichtextRenderer.tsx
··· 221 221 <Link 222 222 to="/card/$id" 223 223 params={{ id: scryfallId }} 224 - className="inline-flex items-center px-1.5 py-0.5 rounded bg-sky-50 dark:bg-sky-900/30 text-sky-700 dark:text-sky-300 text-sm font-medium hover:bg-sky-100 dark:hover:bg-sky-900/50 transition-[font-variation-settings] duration-200 ease-out [font-variation-settings:'CASL'_0,'wght'_500] hover:[font-variation-settings:'CASL'_0.5,'wght'_600]" 224 + className="inline-flex items-center px-1.5 py-0.5 rounded bg-sky-50 dark:bg-sky-900/30 text-sky-700 dark:text-sky-300 text-sm font-medium hover:bg-sky-100 dark:hover:bg-sky-900/50 motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out [font-variation-settings:'CASL'_0,'wght'_500] motion-safe:hover:[font-variation-settings:'CASL'_0.5,'wght'_600]" 225 225 {...hoverProps} 226 226 > 227 227 {children}
+13 -13
src/routes/index.tsx
··· 29 29 {session ? ( 30 30 <Link 31 31 to="/deck/new" 32 - className="group flex flex-col items-center p-6 bg-white dark:bg-slate-800/50 border border-gray-200 dark:border-slate-700 rounded-xl hover:border-cyan-500 dark:hover:border-cyan-500 hover:shadow-lg transition-all" 32 + className="group flex flex-col items-center p-6 bg-white dark:bg-slate-800/50 border border-gray-200 dark:border-slate-700 rounded-xl hover:border-cyan-500 dark:hover:border-cyan-500 motion-safe:hover:shadow-lg transition-colors motion-safe:transition-shadow" 33 33 > 34 34 <div className="w-12 h-12 bg-cyan-100 dark:bg-cyan-900/30 rounded-full flex items-center justify-center mb-4 group-hover:bg-cyan-200 dark:group-hover:bg-cyan-800/40 transition-colors"> 35 35 <Plus size={24} className="text-cyan-600 dark:text-cyan-400" /> 36 36 </div> 37 - <span className="font-semibold text-gray-900 dark:text-white transition-[font-variation-settings] duration-200 ease-out [font-variation-settings:'wght'_600] group-hover:[font-variation-settings:'wght'_700]"> 37 + <span className="font-semibold text-gray-900 dark:text-white motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out [font-variation-settings:'wght'_600] motion-safe:group-hover:[font-variation-settings:'wght'_700]"> 38 38 Create Deck 39 39 </span> 40 - <span className="text-sm text-gray-500 dark:text-gray-400 mt-1 transition-[font-variation-settings] duration-200 ease-out [font-variation-settings:'CASL'_0] group-hover:[font-variation-settings:'CASL'_1]"> 40 + <span className="text-sm text-gray-500 dark:text-gray-400 mt-1 motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out [font-variation-settings:'CASL'_0] motion-safe:group-hover:[font-variation-settings:'CASL'_1]"> 41 41 Start building 42 42 </span> 43 43 </Link> 44 44 ) : ( 45 45 <Link 46 46 to="/signin" 47 - className="group flex flex-col items-center p-6 bg-white dark:bg-slate-800/50 border border-gray-200 dark:border-slate-700 rounded-xl hover:border-cyan-500 dark:hover:border-cyan-500 hover:shadow-lg transition-all" 47 + className="group flex flex-col items-center p-6 bg-white dark:bg-slate-800/50 border border-gray-200 dark:border-slate-700 rounded-xl hover:border-cyan-500 dark:hover:border-cyan-500 motion-safe:hover:shadow-lg transition-colors motion-safe:transition-shadow" 48 48 > 49 49 <div className="w-12 h-12 bg-cyan-100 dark:bg-cyan-900/30 rounded-full flex items-center justify-center mb-4 group-hover:bg-cyan-200 dark:group-hover:bg-cyan-800/40 transition-colors"> 50 50 <User size={24} className="text-cyan-600 dark:text-cyan-400" /> 51 51 </div> 52 - <span className="font-semibold text-gray-900 dark:text-white transition-[font-variation-settings] duration-200 ease-out [font-variation-settings:'wght'_600] group-hover:[font-variation-settings:'wght'_700]"> 52 + <span className="font-semibold text-gray-900 dark:text-white motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out [font-variation-settings:'wght'_600] motion-safe:group-hover:[font-variation-settings:'wght'_700]"> 53 53 Sign In 54 54 </span> 55 - <span className="text-sm text-gray-500 dark:text-gray-400 mt-1 transition-[font-variation-settings] duration-200 ease-out [font-variation-settings:'CASL'_0] group-hover:[font-variation-settings:'CASL'_1]"> 55 + <span className="text-sm text-gray-500 dark:text-gray-400 mt-1 motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out [font-variation-settings:'CASL'_0] motion-safe:group-hover:[font-variation-settings:'CASL'_1]"> 56 56 Get started 57 57 </span> 58 58 </Link> ··· 62 62 <Link 63 63 to="/profile/$did" 64 64 params={{ did: session.info.sub }} 65 - className="group flex flex-col items-center p-6 bg-white dark:bg-slate-800/50 border border-gray-200 dark:border-slate-700 rounded-xl hover:border-cyan-500 dark:hover:border-cyan-500 hover:shadow-lg transition-all" 65 + className="group flex flex-col items-center p-6 bg-white dark:bg-slate-800/50 border border-gray-200 dark:border-slate-700 rounded-xl hover:border-cyan-500 dark:hover:border-cyan-500 motion-safe:hover:shadow-lg transition-colors motion-safe:transition-shadow" 66 66 > 67 67 <div className="w-12 h-12 bg-gray-100 dark:bg-slate-700 rounded-full flex items-center justify-center mb-4 group-hover:bg-gray-200 dark:group-hover:bg-slate-600 transition-colors"> 68 68 <User size={24} className="text-gray-600 dark:text-gray-300" /> 69 69 </div> 70 - <span className="font-semibold text-gray-900 dark:text-white transition-[font-variation-settings] duration-200 ease-out [font-variation-settings:'wght'_600] group-hover:[font-variation-settings:'wght'_700]"> 70 + <span className="font-semibold text-gray-900 dark:text-white motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out [font-variation-settings:'wght'_600] motion-safe:group-hover:[font-variation-settings:'wght'_700]"> 71 71 My Decks 72 72 </span> 73 - <span className="text-sm text-gray-500 dark:text-gray-400 mt-1 transition-[font-variation-settings] duration-200 ease-out [font-variation-settings:'CASL'_0] group-hover:[font-variation-settings:'CASL'_1]"> 73 + <span className="text-sm text-gray-500 dark:text-gray-400 mt-1 motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out [font-variation-settings:'CASL'_0] motion-safe:group-hover:[font-variation-settings:'CASL'_1]"> 74 74 View your collection 75 75 </span> 76 76 </Link> ··· 91 91 <Link 92 92 to="/cards" 93 93 search={{ q: "", sort: undefined }} 94 - className="group flex flex-col items-center p-6 bg-white dark:bg-slate-800/50 border border-gray-200 dark:border-slate-700 rounded-xl hover:border-cyan-500 dark:hover:border-cyan-500 hover:shadow-lg transition-all" 94 + className="group flex flex-col items-center p-6 bg-white dark:bg-slate-800/50 border border-gray-200 dark:border-slate-700 rounded-xl hover:border-cyan-500 dark:hover:border-cyan-500 motion-safe:hover:shadow-lg transition-colors motion-safe:transition-shadow" 95 95 > 96 96 <div className="w-12 h-12 bg-gray-100 dark:bg-slate-700 rounded-full flex items-center justify-center mb-4 group-hover:bg-gray-200 dark:group-hover:bg-slate-600 transition-colors"> 97 97 <Search size={24} className="text-gray-600 dark:text-gray-300" /> 98 98 </div> 99 - <span className="font-semibold text-gray-900 dark:text-white transition-[font-variation-settings] duration-200 ease-out [font-variation-settings:'wght'_600] group-hover:[font-variation-settings:'wght'_700]"> 99 + <span className="font-semibold text-gray-900 dark:text-white motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out [font-variation-settings:'wght'_600] motion-safe:group-hover:[font-variation-settings:'wght'_700]"> 100 100 Browse Cards 101 101 </span> 102 - <span className="text-sm text-gray-500 dark:text-gray-400 mt-1 transition-[font-variation-settings] duration-200 ease-out [font-variation-settings:'CASL'_0] group-hover:[font-variation-settings:'CASL'_1]"> 102 + <span className="text-sm text-gray-500 dark:text-gray-400 mt-1 motion-safe:transition-[font-variation-settings] motion-safe:duration-200 motion-safe:ease-out [font-variation-settings:'CASL'_0] motion-safe:group-hover:[font-variation-settings:'CASL'_1]"> 103 103 Search the database 104 104 </span> 105 105 </Link> ··· 125 125 126 126 <div className="mt-16 text-center"> 127 127 <p className="text-sm text-gray-500 dark:text-gray-500"> 128 - Built on the{" "} 128 + built on the{" "} 129 129 <a 130 130 href="https://atproto.com" 131 131 target="_blank"