A personal media tracker built on the AT Protocol opnshelf.xyz
0
fork

Configure Feed

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

feat: design cleanup

+376 -194
+48 -10
apps/web/src/components/CastSection.tsx
··· 35 35 key={`cast-${person.id}`} 36 36 className="shrink-0 w-32 group cursor-pointer" 37 37 > 38 - <div className="relative overflow-hidden rounded-lg bg-gray-900/50 aspect-2/3 mb-2 transition-transform duration-300 group-hover:scale-[1.02]"> 38 + <div 39 + className="relative overflow-hidden rounded-lg aspect-2/3 mb-2 transition-transform duration-300 group-hover:scale-[1.02]" 40 + style={{ 41 + backgroundColor: 42 + "var(--md-sys-color-surface-container)", 43 + }} 44 + > 39 45 {profileUrl ? ( 40 46 <img 41 47 src={profileUrl} ··· 44 50 loading="lazy" 45 51 /> 46 52 ) : ( 47 - <div className="w-full h-full bg-gray-800 flex items-center justify-center"> 48 - <span className="text-gray-600 text-xs text-center px-2"> 53 + <div 54 + className="w-full h-full flex items-center justify-center" 55 + style={{ 56 + backgroundColor: 57 + "var(--md-sys-color-surface-container-high)", 58 + color: "var(--md-sys-color-on-surface-variant)", 59 + }} 60 + > 61 + <span className="text-xs text-center px-2"> 49 62 No photo 50 63 </span> 51 64 </div> 52 65 )} 53 66 </div> 54 67 <div className="space-y-0.5"> 55 - <p className="text-sm font-medium text-gray-200 line-clamp-2 transition-colors duration-200 group-hover:text-white"> 68 + <p 69 + className="text-sm font-medium line-clamp-2 transition-colors duration-200" 70 + style={{ 71 + color: "var(--md-sys-color-on-surface)", 72 + }} 73 + > 56 74 {person.name} 57 75 </p> 58 76 {person.character && ( ··· 71 89 <div 72 90 className="absolute right-0 top-0 bottom-4 w-16 pointer-events-none" 73 91 style={{ 74 - background: `linear-gradient(to left, rgb(3, 7, 18), transparent)`, 92 + background: 93 + "linear-gradient(to left, var(--md-sys-color-background), transparent)", 75 94 }} 76 95 /> 77 96 </div> ··· 95 114 key={`guest-${person.id}`} 96 115 className="shrink-0 w-32 group cursor-pointer" 97 116 > 98 - <div className="relative overflow-hidden rounded-lg bg-gray-900/50 aspect-2/3 mb-2 transition-transform duration-300 group-hover:scale-[1.02]"> 117 + <div 118 + className="relative overflow-hidden rounded-lg aspect-2/3 mb-2 transition-transform duration-300 group-hover:scale-[1.02]" 119 + style={{ 120 + backgroundColor: 121 + "var(--md-sys-color-surface-container)", 122 + }} 123 + > 99 124 {profileUrl ? ( 100 125 <img 101 126 src={profileUrl} ··· 104 129 loading="lazy" 105 130 /> 106 131 ) : ( 107 - <div className="w-full h-full bg-gray-800 flex items-center justify-center"> 108 - <span className="text-gray-600 text-xs text-center px-2"> 132 + <div 133 + className="w-full h-full flex items-center justify-center" 134 + style={{ 135 + backgroundColor: 136 + "var(--md-sys-color-surface-container-high)", 137 + color: "var(--md-sys-color-on-surface-variant)", 138 + }} 139 + > 140 + <span className="text-xs text-center px-2"> 109 141 No photo 110 142 </span> 111 143 </div> 112 144 )} 113 145 </div> 114 146 <div className="space-y-0.5"> 115 - <p className="text-sm font-medium text-gray-200 line-clamp-2 transition-colors duration-200 group-hover:text-white"> 147 + <p 148 + className="text-sm font-medium line-clamp-2 transition-colors duration-200" 149 + style={{ 150 + color: "var(--md-sys-color-on-surface)", 151 + }} 152 + > 116 153 {person.name} 117 154 </p> 118 155 {person.character && ( ··· 131 168 <div 132 169 className="absolute right-0 top-0 bottom-4 w-16 pointer-events-none" 133 170 style={{ 134 - background: `linear-gradient(to left, rgb(3, 7, 18), transparent)`, 171 + background: 172 + "linear-gradient(to left, var(--md-sys-color-background), transparent)", 135 173 }} 136 174 /> 137 175 </div>
+2 -2
apps/web/src/components/CreateListDialog.tsx
··· 110 110 </div> 111 111 <div className="space-y-2"> 112 112 <div 113 - className="relative rounded-[var(--md-sys-shape-corner-extra-small)] border bg-transparent transition-all duration-200" 113 + className="relative rounded-(--md-sys-shape-corner-extra-small) border bg-transparent transition-all duration-200" 114 114 style={{ 115 115 borderColor: isDescriptionFocused 116 116 ? "var(--md-sys-color-primary)" ··· 139 139 onBlur={() => setIsDescriptionFocused(false)} 140 140 maxLength={500} 141 141 rows={3} 142 - className="w-full resize-none bg-transparent py-4 px-4 text-[var(--md-sys-color-on-surface)] placeholder:text-[var(--md-sys-color-on-surface-variant)] outline-none md-body-large" 142 + className="w-full resize-none bg-transparent py-4 px-4 text-(--md-sys-color-on-surface) placeholder:text-(--md-sys-color-on-surface-variant) outline-none md-body-large" 143 143 /> 144 144 </div> 145 145 </div>
+2 -2
apps/web/src/components/CrewSection.tsx
··· 23 23 {crew.map((person) => ( 24 24 <div 25 25 key={`${person.id}-${person.job}`} 26 - className="group p-3 rounded-lg bg-gray-900/30 hover:bg-gray-900/60 transition-all duration-200 cursor-pointer" 26 + className="group p-3 rounded-lg bg-(--md-sys-color-surface-container)/30 hover:bg-(--md-sys-color-surface-container)/60 transition-all duration-200 cursor-pointer" 27 27 > 28 - <p className="text-sm font-medium text-gray-200 line-clamp-1 transition-colors duration-200 group-hover:text-white"> 28 + <p className="text-sm font-medium text-(--md-sys-color-on-surface) line-clamp-1 transition-colors duration-200 group-hover:brightness-110"> 29 29 {person.name} 30 30 </p> 31 31 <p className="text-xs mt-0.5" style={{ color: colors.muted }}>
+38 -14
apps/web/src/components/Footer.tsx
··· 3 3 4 4 export default function Footer() { 5 5 return ( 6 - <footer className="bg-gray-900 text-gray-400 py-8 border-t border-gray-800"> 7 - <div className="container mx-auto px-4"> 8 - <div className="flex flex-col md:flex-row items-center justify-between gap-4"> 6 + <footer 7 + className="border-t py-8" 8 + style={{ 9 + backgroundColor: "var(--md-sys-color-surface-container-low)", 10 + borderColor: "var(--md-sys-color-outline-variant)", 11 + }} 12 + > 13 + <div className="container mx-auto max-w-7xl px-4"> 14 + <div className="flex flex-col items-center gap-6 md:flex-row md:justify-between md:gap-4"> 9 15 <div className="flex items-center gap-2"> 10 - <Film className="w-6 h-6 text-amber-500" /> 11 - <span className="font-semibold text-white">OpnShelf</span> 16 + <Film 17 + className="size-6" 18 + style={{ color: "var(--md-sys-color-primary)" }} 19 + /> 20 + <span 21 + className="font-semibold" 22 + style={{ color: "var(--md-sys-color-on-surface)" }} 23 + > 24 + OpnShelf 25 + </span> 12 26 </div> 13 27 14 - <nav className="flex items-center gap-6 text-sm"> 15 - <Link to="/privacy" className="hover:text-white transition-colors"> 28 + <nav className="flex flex-wrap items-center justify-center gap-5 text-sm sm:gap-6"> 29 + <Link 30 + to="/privacy" 31 + className="whitespace-nowrap transition-colors hover:text-(--md-sys-color-on-surface)" 32 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 33 + > 16 34 Privacy Policy 17 35 </Link> 18 36 <a 19 37 href="https://tangled.org/rowanpaulflynn.dev/opnshelf" 20 38 target="_blank" 21 39 rel="noopener noreferrer" 22 - className="flex items-center gap-2 hover:text-white transition-colors" 40 + className="flex items-center gap-2 transition-colors hover:text-(--md-sys-color-on-surface)" 41 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 23 42 > 24 43 <img 25 44 src="https://assets.tangled.network/tangled_dolly_face_only_white_on_trans.svg" 26 45 alt="Tangled" 27 - className="w-4 h-4" 46 + className="size-4" 28 47 /> 29 48 Tangled 30 49 </a> ··· 32 51 href="https://bsky.app/profile/opnshelf.xyz" 33 52 target="_blank" 34 53 rel="noopener noreferrer" 35 - className="flex items-center gap-2 hover:text-white transition-colors" 54 + className="flex items-center gap-2 transition-colors hover:text-(--md-sys-color-on-surface)" 55 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 36 56 > 37 57 <svg 38 58 preserveAspectRatio="xMidYMid" 39 59 viewBox="0 0 256 226" 40 - className="w-4 h-4" 60 + className="size-4" 41 61 aria-hidden="true" 42 62 > 43 63 <path ··· 51 71 href="https://github.com/Rowan-Paul/opnshelf" 52 72 target="_blank" 53 73 rel="noopener noreferrer" 54 - className="flex items-center gap-2 hover:text-white transition-colors" 74 + className="flex items-center gap-2 transition-colors hover:text-(--md-sys-color-on-surface)" 75 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 55 76 > 56 - <Github className="w-4 h-4" /> 77 + <Github className="size-4" /> 57 78 GitHub 58 79 </a> 59 80 </nav> 60 81 61 - <p className="text-sm"> 82 + <p 83 + className="text-sm" 84 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 85 + > 62 86 © {new Date().getFullYear()} OpnShelf. Built on AT Protocol. 63 87 </p> 64 88 </div>
+4 -4
apps/web/src/components/Header.tsx
··· 98 98 }} 99 99 /> 100 100 101 - <div className="container mx-auto flex h-16 max-w-7xl items-center justify-between gap-3 px-4 md:h-[4.5rem]"> 101 + <div className="container mx-auto flex h-16 max-w-7xl items-center justify-between gap-3 px-4 md:h-18"> 102 102 <Brand seedColor={seedColor} /> 103 103 104 104 <nav className="hidden min-w-0 flex-1 items-center justify-center gap-2 md:flex"> ··· 233 233 {...target} 234 234 className={cn( 235 235 "inline-flex items-center gap-2 rounded-full border px-4 py-2 transition-all duration-200", 236 - "hover:-translate-y-0.5 hover:bg-[var(--md-sys-color-surface-container-high)] hover:text-[var(--md-sys-color-on-surface)]", 236 + "hover:-translate-y-0.5 hover:bg-(--md-sys-color-surface-container-high) hover:text-(--md-sys-color-on-surface)", 237 237 )} 238 238 style={ 239 239 isActive ··· 365 365 type="button" 366 366 onClick={onLogout} 367 367 disabled={isLoggingOut} 368 - className="flex w-full items-center gap-3 rounded-[18px] px-3 py-3 text-left transition-colors hover:bg-[var(--md-sys-color-surface-container-low)] disabled:opacity-60" 368 + className="flex w-full items-center gap-3 rounded-[18px] px-3 py-3 text-left transition-colors hover:bg-(--md-sys-color-surface-container-low) disabled:opacity-60" 369 369 style={{ color: "var(--md-sys-color-on-surface)" }} 370 370 > 371 371 <LogOut className="size-4" /> ··· 392 392 <Link 393 393 {...target} 394 394 onClick={onSelect} 395 - className="flex items-center gap-3 rounded-[18px] px-3 py-3 transition-colors hover:bg-[var(--md-sys-color-surface-container-low)]" 395 + className="flex items-center gap-3 rounded-[18px] px-3 py-3 transition-colors hover:bg-(--md-sys-color-surface-container-low)" 396 396 style={{ color: "var(--md-sys-color-on-surface)" }} 397 397 > 398 398 <Icon className="size-4" />
+17 -4
apps/web/src/components/MovieCard.tsx
··· 96 96 movieId: movieId, 97 97 title: createTitleSlug(movie.title), 98 98 }} 99 - className="block relative aspect-2/3 bg-gray-900 rounded-lg overflow-hidden mb-2" 99 + className="block relative aspect-2/3 rounded-lg overflow-hidden mb-2" 100 + style={{ 101 + backgroundColor: "var(--md-sys-color-surface-container-high)", 102 + }} 100 103 > 101 104 {posterUrl ? ( 102 105 <img ··· 105 108 className="w-full h-full object-cover transition-transform duration-200 group-hover:scale-105" 106 109 /> 107 110 ) : ( 108 - <div className="w-full h-full flex items-center justify-center text-gray-600"> 111 + <div 112 + className="w-full h-full flex items-center justify-center md-body-medium" 113 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 114 + > 109 115 No poster 110 116 </div> 111 117 )} ··· 163 169 }} 164 170 className="block" 165 171 > 166 - <h3 className="font-semibold text-sm line-clamp-2 mb-1 hover:text-amber-400 transition-colors"> 172 + <h3 className="font-semibold text-sm line-clamp-2 mb-1 transition-colors hover:text-(--md-sys-color-primary)"> 167 173 {movie.title} 168 174 </h3> 169 - {releaseYear && <p className="text-gray-500 text-sm">{releaseYear}</p>} 175 + {releaseYear && ( 176 + <p 177 + className="text-sm" 178 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 179 + > 180 + {releaseYear} 181 + </p> 182 + )} 170 183 </Link> 171 184 </div> 172 185 );
+46 -8
apps/web/src/components/MovieDetails.tsx
··· 16 16 return ( 17 17 <section className="grid grid-cols-2 gap-4 min-w-0"> 18 18 {movie?.release_date && ( 19 - <div className="p-4 rounded-lg bg-gray-900/50"> 20 - <span className="text-gray-500 text-sm block mb-1">Release Date</span> 19 + <div 20 + className="p-4 rounded-lg" 21 + style={{ 22 + backgroundColor: "var(--md-sys-color-surface-container)", 23 + }} 24 + > 25 + <span 26 + className="text-sm block mb-1" 27 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 28 + > 29 + Release Date 30 + </span> 21 31 <span className="font-medium" style={{ color: colors.accent }}> 22 32 {formatDateOnly(movie.release_date)} 23 33 </span> ··· 27 37 <button 28 38 type="button" 29 39 onClick={() => setShowHours(!showHours)} 30 - className="p-4 rounded-lg bg-gray-900/50 text-left cursor-pointer hover:bg-gray-800/50 transition-colors w-full" 40 + className="p-4 rounded-lg text-left cursor-pointer transition-colors w-full" 41 + style={{ 42 + backgroundColor: "var(--md-sys-color-surface-container)", 43 + }} 31 44 > 32 - <span className="text-gray-500 text-sm block mb-1">Runtime</span> 45 + <span 46 + className="text-sm block mb-1" 47 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 48 + > 49 + Runtime 50 + </span> 33 51 <span className="font-medium" style={{ color: colors.accent }}> 34 52 {formatRuntime(movie.runtime, showHours)} 35 53 </span> 36 54 </button> 37 55 )} 38 56 {movie?.vote_average && ( 39 - <div className="p-4 rounded-lg bg-gray-900/50"> 40 - <span className="text-gray-500 text-sm block mb-1">Rating</span> 57 + <div 58 + className="p-4 rounded-lg" 59 + style={{ 60 + backgroundColor: "var(--md-sys-color-surface-container)", 61 + }} 62 + > 63 + <span 64 + className="text-sm block mb-1" 65 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 66 + > 67 + Rating 68 + </span> 41 69 <span className="font-medium" style={{ color: colors.accent }}> 42 70 {movie.vote_average.toFixed(1)}/10 43 71 </span> 44 72 </div> 45 73 )} 46 74 {movie?.vote_count && ( 47 - <div className="p-4 rounded-lg bg-gray-900/50"> 48 - <span className="text-gray-500 text-sm block mb-1">Votes</span> 75 + <div 76 + className="p-4 rounded-lg" 77 + style={{ 78 + backgroundColor: "var(--md-sys-color-surface-container)", 79 + }} 80 + > 81 + <span 82 + className="text-sm block mb-1" 83 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 84 + > 85 + Votes 86 + </span> 49 87 <span className="font-medium" style={{ color: colors.accent }}> 50 88 {movie.vote_count.toLocaleString()} 51 89 </span>
+13 -3
apps/web/src/components/MovieHero.tsx
··· 111 111 className="w-full aspect-2/3 object-cover" 112 112 /> 113 113 ) : ( 114 - <div className="w-full aspect-2/3 bg-gray-900 flex items-center justify-center"> 115 - <span className="text-gray-600">No poster</span> 114 + <div 115 + className="w-full aspect-2/3 flex items-center justify-center" 116 + style={{ 117 + backgroundColor: 118 + "var(--md-sys-color-surface-container-high)", 119 + color: "var(--md-sys-color-on-surface-variant)", 120 + }} 121 + > 122 + No poster 116 123 </div> 117 124 )} 118 125 </div> ··· 128 135 {movie?.title} 129 136 </h1> 130 137 {releaseYear && ( 131 - <div className="flex items-center gap-4 text-lg text-gray-300"> 138 + <div 139 + className="flex items-center gap-4 text-lg" 140 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 141 + > 132 142 <span className="flex items-center gap-2"> 133 143 <Calendar 134 144 className="w-4 h-4"
+1 -1
apps/web/src/components/ShelfEpisodeCard.tsx
··· 151 151 }} 152 152 className="block rounded-[20px] px-1 pb-1" 153 153 > 154 - <h3 className="mb-1 line-clamp-2 text-sm font-semibold transition-colors hover:text-[var(--md-sys-color-primary)]"> 154 + <h3 className="mb-1 line-clamp-2 text-sm font-semibold transition-colors hover:text-(--md-sys-color-primary)"> 155 155 {tracked.showTitle} 156 156 </h3> 157 157 <p
+1 -1
apps/web/src/components/ShelfMovieCard.tsx
··· 134 134 }} 135 135 className="block rounded-[20px] px-1 pb-1" 136 136 > 137 - <h3 className="mb-1 line-clamp-2 text-sm font-semibold transition-colors hover:text-[var(--md-sys-color-primary)]"> 137 + <h3 className="mb-1 line-clamp-2 text-sm font-semibold transition-colors hover:text-(--md-sys-color-primary)"> 138 138 {tracked.title} 139 139 </h3> 140 140 {tracked.releaseYear && (
+17 -4
apps/web/src/components/ShowCard.tsx
··· 91 91 <Link 92 92 to="/shows/$showId/$title" 93 93 params={{ showId, title: createTitleSlug(show.name) }} 94 - className="block relative aspect-2/3 bg-gray-900 rounded-lg overflow-hidden mb-2" 94 + className="block relative aspect-2/3 rounded-lg overflow-hidden mb-2" 95 + style={{ 96 + backgroundColor: "var(--md-sys-color-surface-container-high)", 97 + }} 95 98 > 96 99 {posterUrl ? ( 97 100 <img ··· 100 103 className="w-full h-full object-cover transition-transform duration-200 group-hover:scale-105" 101 104 /> 102 105 ) : ( 103 - <div className="w-full h-full flex items-center justify-center text-gray-600"> 106 + <div 107 + className="w-full h-full flex items-center justify-center md-body-medium" 108 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 109 + > 104 110 No poster 105 111 </div> 106 112 )} ··· 156 162 params={{ showId, title: createTitleSlug(show.name) }} 157 163 className="block" 158 164 > 159 - <h3 className="font-semibold text-sm line-clamp-2 mb-1 hover:text-amber-400 transition-colors"> 165 + <h3 className="font-semibold text-sm line-clamp-2 mb-1 transition-colors hover:text-(--md-sys-color-primary)"> 160 166 {show.name} 161 167 </h3> 162 - {year && <p className="text-gray-500 text-sm">{year}</p>} 168 + {year && ( 169 + <p 170 + className="text-sm" 171 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 172 + > 173 + {year} 174 + </p> 175 + )} 163 176 </Link> 164 177 </div> 165 178 );
+36 -21
apps/web/src/components/UnauthenticatedState.tsx
··· 1 1 import { Link } from "@tanstack/react-router"; 2 2 import { BookOpen, LogIn, Settings2 } from "lucide-react"; 3 - import { Button } from "@/components/ui/button"; 3 + import { M3Button } from "@/components/ui/m3-button"; 4 4 import { 5 - Card, 6 - CardContent, 7 - CardDescription, 8 - CardHeader, 9 - CardTitle, 10 - } from "@/components/ui/card"; 5 + M3Card, 6 + M3CardContent, 7 + M3CardDescription, 8 + M3CardHeader, 9 + M3CardTitle, 10 + } from "@/components/ui/m3-card"; 11 11 12 12 interface UnauthenticatedStateProps { 13 13 title: string; ··· 21 21 icon = "shelf", 22 22 }: UnauthenticatedStateProps) { 23 23 const Icon = icon === "settings" ? Settings2 : BookOpen; 24 - const iconColor = icon === "settings" ? "text-amber-500" : "text-amber-500"; 25 24 26 25 return ( 27 - <div className="min-h-screen bg-gray-950 text-gray-50"> 26 + <div 27 + className="min-h-screen" 28 + style={{ 29 + backgroundColor: "var(--md-sys-color-background)", 30 + color: "var(--md-sys-color-on-background)", 31 + }} 32 + > 28 33 <div className="container mx-auto px-4 py-16 max-w-4xl"> 29 - <Card className="bg-gray-900 border-gray-800 text-center"> 30 - <CardHeader> 31 - <Icon className={`w-16 h-16 ${iconColor} mx-auto mb-4`} /> 32 - <CardTitle className="text-3xl">{title}</CardTitle> 33 - <CardDescription className="text-xl">{description}</CardDescription> 34 - </CardHeader> 35 - <CardContent> 36 - <Button asChild size="lg"> 34 + <M3Card variant="filled" className="rounded-[28px] text-center"> 35 + <M3CardHeader className="items-center px-6 pt-8"> 36 + <Icon 37 + className="size-16 mb-4" 38 + style={{ color: "var(--md-sys-color-primary)" }} 39 + /> 40 + <M3CardTitle className="md-headline-medium">{title}</M3CardTitle> 41 + <M3CardDescription className="md-title-large"> 42 + {description} 43 + </M3CardDescription> 44 + </M3CardHeader> 45 + <M3CardContent className="pb-8"> 46 + <M3Button 47 + variant="filled" 48 + size="lg" 49 + asChild 50 + className="rounded-full" 51 + > 37 52 <Link to="/login"> 38 - <LogIn className="w-5 h-5 mr-2" /> 53 + <LogIn className="size-5" /> 39 54 Sign in 40 55 </Link> 41 - </Button> 42 - </CardContent> 43 - </Card> 56 + </M3Button> 57 + </M3CardContent> 58 + </M3Card> 44 59 </div> 45 60 </div> 46 61 );
+4 -2
apps/web/src/components/detail/BreadcrumbNav.tsx
··· 15 15 16 16 return ( 17 17 <div key={item.label} className="flex items-center gap-1"> 18 - {index > 0 && <ChevronRight className="w-4 h-4 text-gray-500" />} 18 + {index > 0 && ( 19 + <ChevronRight className="w-4 h-4 text-(--md-sys-color-on-surface-variant)" /> 20 + )} 19 21 {item.linkTo && !isLast ? ( 20 22 <Link 21 23 to={item.linkTo.to} 22 24 params={item.linkTo.params} 23 - className="text-gray-400 hover:text-gray-200 transition-colors" 25 + className="text-(--md-sys-color-on-surface-variant) hover:text-(--md-sys-color-on-surface) transition-colors" 24 26 > 25 27 {item.label} 26 28 </Link>
+12 -3
apps/web/src/components/detail/DetailHero.tsx
··· 58 58 className="w-full aspect-2/3 object-cover" 59 59 /> 60 60 ) : ( 61 - <div className="w-full aspect-2/3 bg-gray-900 flex items-center justify-center"> 62 - <span className="text-gray-600">No poster</span> 61 + <div 62 + className="w-full aspect-2/3 flex items-center justify-center" 63 + style={{ 64 + backgroundColor: "var(--md-sys-color-surface-container-high)", 65 + color: "var(--md-sys-color-on-surface-variant)", 66 + }} 67 + > 68 + No poster 63 69 </div> 64 70 ); 65 71 ··· 136 142 {title} 137 143 </h1> 138 144 {subtitle && ( 139 - <h2 className="text-lg md:text-2xl text-gray-200"> 145 + <h2 146 + className="text-lg md:text-2xl" 147 + style={{ color: "var(--md-sys-color-on-surface-variant)" }} 148 + > 140 149 {subtitle} 141 150 </h2> 142 151 )}
+7 -7
apps/web/src/components/detail/EpisodeCard.tsx
··· 128 128 seasonNumber, 129 129 episodeNumber: String(episode.episode_number), 130 130 }} 131 - className="group block rounded-xl border bg-gray-900/30 hover:bg-gray-900/50 transition-all overflow-hidden" 131 + className="group block rounded-xl border bg-(--md-sys-color-surface-container)/30 hover:bg-(--md-sys-color-surface-container)/50 transition-all overflow-hidden" 132 132 style={{ 133 133 borderColor: 134 134 watchedCount > 0 ··· 137 137 }} 138 138 > 139 139 <div className="grid grid-cols-[120px_1fr] gap-4"> 140 - <div className="h-full bg-gray-900 min-h-[67px] relative"> 140 + <div className="h-full bg-(--md-sys-color-surface-container) min-h-[67px] relative"> 141 141 {episode.still_path ? ( 142 142 <img 143 143 src={`https://image.tmdb.org/t/p/w300${episode.still_path}`} ··· 145 145 className="w-full h-full object-cover" 146 146 /> 147 147 ) : ( 148 - <div className="w-full h-full flex items-center justify-center text-gray-600 text-xs"> 148 + <div className="w-full h-full flex items-center justify-center text-(--md-sys-color-on-surface-variant) text-xs"> 149 149 No image 150 150 </div> 151 151 )} 152 152 </div> 153 153 <div className="p-3 min-w-0"> 154 154 <div className="flex items-center justify-between gap-2 mb-1"> 155 - <p className="font-medium line-clamp-1 group-hover:text-white transition-colors"> 155 + <p className="font-medium line-clamp-1 group-hover:text-(--md-sys-color-on-surface) transition-colors"> 156 156 E{episode.episode_number} · {episode.name} 157 157 </p> 158 158 {episode.vote_average ? ( 159 - <span className="text-xs flex items-center gap-1 text-gray-300"> 159 + <span className="text-xs flex items-center gap-1 text-(--md-sys-color-on-surface-variant)"> 160 160 <Star className="w-3 h-3" /> 161 161 {episode.vote_average.toFixed(1)} 162 162 </span> 163 163 ) : null} 164 164 </div> 165 - <p className="text-xs text-gray-400 line-clamp-2 mb-2"> 165 + <p className="text-xs text-(--md-sys-color-on-surface-variant) line-clamp-2 mb-2"> 166 166 {episode.overview || "No overview available."} 167 167 </p> 168 168 <div className="flex items-center justify-between gap-3"> 169 - <div className="flex items-center gap-3 text-xs text-gray-400"> 169 + <div className="flex items-center gap-3 text-xs text-(--md-sys-color-on-surface-variant)"> 170 170 <span className="flex items-center gap-1"> 171 171 <Calendar className="w-3 h-3" /> 172 172 {episode.air_date ? formatDateOnly(episode.air_date) : "TBA"}
+10 -8
apps/web/src/components/detail/EpisodeNav.tsx
··· 54 54 ), 55 55 episodeNumber: String(previousEpisode.episode_number), 56 56 }} 57 - className="flex-1 flex items-center justify-center gap-2 py-2 px-4 rounded-lg border border-(--md-sys-color-outline) hover:bg-gray-900/40 transition-colors text-sm" 57 + className="flex-1 flex items-center justify-center gap-2 py-2 px-4 rounded-lg border border-(--md-sys-color-outline) hover:bg-(--md-sys-color-surface-container)/40 transition-colors text-sm" 58 58 > 59 59 <ArrowLeft className="w-4 h-4" /> 60 60 <span>Episode {previousEpisode.episode_number}</span> ··· 72 72 seasonNumber: String(nextContext?.seasonNumber ?? seasonNumber), 73 73 episodeNumber: String(nextEpisode.episode_number), 74 74 }} 75 - className="flex-1 flex items-center justify-center gap-2 py-2 px-4 rounded-lg border border-(--md-sys-color-outline) hover:bg-gray-900/40 transition-colors text-sm" 75 + className="flex-1 flex items-center justify-center gap-2 py-2 px-4 rounded-lg border border-(--md-sys-color-outline) hover:bg-(--md-sys-color-surface-container)/40 transition-colors text-sm" 76 76 > 77 77 <span>Episode {nextEpisode.episode_number}</span> 78 78 <ArrowRight className="w-4 h-4" /> ··· 132 132 borderColor: "var(--md-sys-color-outline)", 133 133 }} 134 134 > 135 - <div className="text-xs uppercase tracking-wide text-gray-400 mb-2 flex items-center gap-2"> 135 + <div className="text-xs uppercase tracking-wide text-(--md-sys-color-on-surface-variant) mb-2 flex items-center gap-2"> 136 136 {slot.icon} 137 137 {slot.label} 138 138 </div> 139 - <div className="text-gray-500 text-sm">No episode</div> 139 + <div className="text-(--md-sys-color-on-surface-variant) text-sm"> 140 + No episode 141 + </div> 140 142 </div> 141 143 ); 142 144 } ··· 155 157 }} 156 158 className={`rounded-lg border p-3 transition-colors ${ 157 159 slot.highlighted 158 - ? "bg-gray-900/60 hover:bg-gray-900/70" 159 - : "bg-gray-900/30 hover:bg-gray-900/50" 160 + ? "bg-(--md-sys-color-surface-container)/60 hover:bg-(--md-sys-color-surface-container)/70" 161 + : "bg-(--md-sys-color-surface-container)/30 hover:bg-(--md-sys-color-surface-container)/50" 160 162 }`} 161 163 style={{ 162 164 borderColor: slot.highlighted ··· 164 166 : "var(--md-sys-color-outline)", 165 167 }} 166 168 > 167 - <div className="text-xs uppercase tracking-wide text-gray-400 mb-2 flex items-center gap-2"> 169 + <div className="text-xs uppercase tracking-wide text-(--md-sys-color-on-surface-variant) mb-2 flex items-center gap-2"> 168 170 {slot.icon} 169 171 {slot.label} 170 172 </div> ··· 181 183 <div className="font-medium text-sm"> 182 184 E{slot.episode.episode_number}: {slot.episode.name} 183 185 </div> 184 - <div className="text-xs text-gray-400 mt-1"> 186 + <div className="text-xs text-(--md-sys-color-on-surface-variant) mt-1"> 185 187 {slot.episode.air_date 186 188 ? formatDateOnly(slot.episode.air_date) 187 189 : "TBA"}
+2 -2
apps/web/src/components/detail/MetadataPills.tsx
··· 22 22 key={item.label} 23 23 to={item.linkTo.to} 24 24 params={item.linkTo.params} 25 - className="rounded-full border border-(--md-sys-color-outline) px-3 py-1.5 text-sm text-gray-300 flex items-center gap-2 hover:bg-gray-900/40 transition-colors" 25 + className="rounded-full border border-(--md-sys-color-outline) px-3 py-1.5 text-sm text-(--md-sys-color-on-surface-variant) flex items-center gap-2 hover:bg-(--md-sys-color-surface-container)/40 transition-colors" 26 26 > 27 27 {content} 28 28 </Link> ··· 32 32 return ( 33 33 <div 34 34 key={item.label} 35 - className="rounded-full border border-(--md-sys-color-outline) px-3 py-1.5 text-sm text-gray-300 flex items-center gap-2" 35 + className="rounded-full border border-(--md-sys-color-outline) px-3 py-1.5 text-sm text-(--md-sys-color-on-surface-variant) flex items-center gap-2" 36 36 > 37 37 {content} 38 38 </div>
+11 -10
apps/web/src/components/detail/SeasonCard.tsx
··· 135 135 title, 136 136 seasonNumber: String(seasonNumber), 137 137 }} 138 - className="group block rounded-xl border bg-gray-900/30 hover:bg-gray-900/50 transition-all overflow-hidden" 139 - style={{ borderColor: "var(--md-sys-color-outline)" }} 138 + className="group block rounded-xl border border-(--md-sys-color-outline) bg-(--md-sys-color-surface-container)/30 hover:bg-(--md-sys-color-surface-container)/50 transition-all overflow-hidden" 140 139 > 141 140 <div className="grid grid-cols-[100px_1fr] gap-4"> 142 - <div className="aspect-2/3 bg-gray-900 relative"> 141 + <div className="aspect-2/3 bg-(--md-sys-color-surface-container) relative"> 143 142 {posterUrl ? ( 144 143 <img 145 144 src={posterUrl} ··· 147 146 className="w-full h-full object-cover" 148 147 /> 149 148 ) : ( 150 - <div className="w-full h-full flex items-center justify-center text-gray-600 text-xs"> 149 + <div className="w-full h-full flex items-center justify-center text-(--md-sys-color-on-surface-variant) text-xs"> 151 150 No poster 152 151 </div> 153 152 )} ··· 155 154 <div className="py-3 pr-4 min-w-0"> 156 155 <div className="flex items-center justify-between gap-2 mb-1"> 157 156 <h3 158 - className="font-semibold text-lg group-hover:text-white transition-colors" 157 + className="font-semibold text-lg group-hover:text-(--md-sys-color-on-surface) transition-colors" 159 158 style={{ color: colors.primary }} 160 159 > 161 160 Season {seasonNumber} 162 161 </h3> 163 162 {airDate && ( 164 - <span className="text-xs text-gray-400 flex items-center gap-1"> 163 + <span className="text-xs text-(--md-sys-color-on-surface-variant) flex items-center gap-1"> 165 164 <Calendar className="w-3 h-3" /> 166 165 {new Date(airDate).getFullYear()} 167 166 </span> 168 167 )} 169 168 </div> 170 169 171 - <div className="flex items-center gap-3 text-xs text-gray-400 mb-2"> 170 + <div className="flex items-center gap-3 text-xs text-(--md-sys-color-on-surface-variant) mb-2"> 172 171 <span className="flex items-center gap-1"> 173 172 <Film className="w-3 h-3" /> 174 173 {episodeCount} episodes 175 174 </span> 176 175 {watchedCount > 0 && ( 177 - <span className="text-gray-300">{watchedCount} watched</span> 176 + <span className="text-(--md-sys-color-on-surface)"> 177 + {watchedCount} watched 178 + </span> 178 179 )} 179 180 </div> 180 181 181 182 {overview && ( 182 - <p className="text-xs text-gray-400 line-clamp-2 mb-3"> 183 + <p className="text-xs text-(--md-sys-color-on-surface-variant) line-clamp-2 mb-3"> 183 184 {overview} 184 185 </p> 185 186 )} 186 187 187 188 {episodeCount > 0 && ( 188 - <div className="w-full h-1.5 bg-gray-800 rounded-full overflow-hidden mb-3"> 189 + <div className="w-full h-1.5 bg-(--md-sys-color-surface-container-high) rounded-full overflow-hidden mb-3"> 189 190 <div 190 191 className="h-full rounded-full transition-all" 191 192 style={{
+2 -2
apps/web/src/components/detail/SeasonNav.tsx
··· 31 31 title, 32 32 seasonNumber: String(currentSeason - 1), 33 33 }} 34 - className="flex-1 flex items-center justify-center gap-2 py-2 px-4 rounded-lg border border-(--md-sys-color-outline) hover:bg-gray-900/40 transition-colors text-sm" 34 + className="flex-1 flex items-center justify-center gap-2 py-2 px-4 rounded-lg border border-(--md-sys-color-outline) hover:bg-(--md-sys-color-surface-container)/40 transition-colors text-sm" 35 35 > 36 36 <ArrowLeft className="w-4 h-4" /> 37 37 <span>Season {currentSeason - 1}</span> ··· 48 48 title, 49 49 seasonNumber: String(currentSeason + 1), 50 50 }} 51 - className="flex-1 flex items-center justify-center gap-2 py-2 px-4 rounded-lg border border-(--md-sys-color-outline) hover:bg-gray-900/40 transition-colors text-sm" 51 + className="flex-1 flex items-center justify-center gap-2 py-2 px-4 rounded-lg border border-(--md-sys-color-outline) hover:bg-(--md-sys-color-surface-container)/40 transition-colors text-sm" 52 52 > 53 53 <span>Season {currentSeason + 1}</span> 54 54 <ArrowRight className="w-4 h-4" />
+4 -4
apps/web/src/components/home/FriendsActivitySection.tsx
··· 140 140 {Array.from({ length: 5 }, (_, index) => ( 141 141 <div 142 142 key={`friends-activity-skeleton-${index + 1}`} 143 - className="w-[min(11rem,70vw)] shrink-0 rounded-[24px] border p-3 sm:w-[11.5rem] lg:w-[12rem]" 143 + className="w-[min(11rem,70vw)] shrink-0 rounded-[24px] border p-3 sm:w-46 lg:w-48" 144 144 style={{ 145 145 backgroundColor: "var(--md-sys-color-surface-container-low)", 146 146 borderColor: "var(--md-sys-color-outline-variant)", ··· 229 229 230 230 return ( 231 231 <div 232 - className="group flex h-full w-[min(11rem,70vw)] shrink-0 flex-col rounded-[24px] border p-3 transition-transform duration-200 hover:-translate-y-1 sm:w-[11.5rem] lg:w-[12rem]" 232 + className="group flex h-full w-[min(11rem,70vw)] shrink-0 flex-col rounded-[24px] border p-3 transition-transform duration-200 hover:-translate-y-1 sm:w-46 lg:w-48" 233 233 style={{ 234 234 backgroundColor: "var(--md-sys-color-surface-container-low)", 235 235 borderColor: "var(--md-sys-color-outline-variant)", ··· 274 274 </div> 275 275 )} 276 276 277 - <div className="flex min-h-[8.75rem] flex-1 flex-col px-1 pb-1"> 277 + <div className="flex min-h-35 flex-1 flex-col px-1 pb-1"> 278 278 <div> 279 279 {mediaTarget ? ( 280 280 <Link {...mediaTarget} className="block rounded-[20px]"> 281 - <h3 className="mb-1 line-clamp-2 text-sm font-semibold transition-colors hover:text-[var(--md-sys-color-primary)]"> 281 + <h3 className="mb-1 line-clamp-2 text-sm font-semibold transition-colors hover:text-(--md-sys-color-primary)"> 282 282 {mediaTitle} 283 283 </h3> 284 284 </Link>
+3 -3
apps/web/src/components/home/LandingHomePage.tsx
··· 77 77 color: "var(--md-sys-color-on-background)", 78 78 }} 79 79 > 80 - <section className="relative border-b border-[var(--md-sys-color-outline-variant)]"> 80 + <section className="relative border-b border-(--md-sys-color-outline-variant)"> 81 81 <div 82 82 className="absolute inset-0 opacity-90" 83 83 style={{ ··· 150 150 </div> 151 151 </section> 152 152 153 - <section className="border-b border-[var(--md-sys-color-outline-variant)] bg-[color:rgba(255,255,255,0.02)]"> 153 + <section className="border-b border-(--md-sys-color-outline-variant) bg-[rgba(255,255,255,0.02)]"> 154 154 <div className="container mx-auto max-w-7xl px-4 py-10 md:py-14"> 155 155 <div className="mb-8 max-w-2xl"> 156 156 <p ··· 209 209 <M3Card 210 210 key={section.title} 211 211 variant="elevated" 212 - className="rounded-[28px] border border-[var(--md-sys-color-outline-variant)]" 212 + className="rounded-[28px] border border-(--md-sys-color-outline-variant)" 213 213 > 214 214 <M3CardHeader className="px-6 pt-6"> 215 215 <div
+1 -1
apps/web/src/components/onboarding/onboarding-content.tsx
··· 51 51 WandSparkles, 52 52 ] as const; 53 53 const INPUT_CLASS = 54 - "w-full rounded-(--md-sys-shape-corner-medium) border border-[var(--md-sys-color-outline)] bg-[var(--md-sys-color-surface)] px-3 py-2 text-[var(--md-sys-color-on-surface)] outline-none transition placeholder:text-[var(--md-sys-color-on-surface-variant)] focus:border-[var(--md-sys-color-primary)] focus:ring-2 focus:ring-[var(--md-sys-color-primary)]/30"; 54 + "w-full rounded-(--md-sys-shape-corner-medium) border border-(--md-sys-color-outline) bg-(--md-sys-color-surface) px-3 py-2 text-(--md-sys-color-on-surface) outline-none transition placeholder:text-(--md-sys-color-on-surface-variant) focus:border-(--md-sys-color-primary) focus:ring-2 focus:ring-(--md-sys-color-primary)/30"; 55 55 56 56 export const ONBOARDING_STEPS = ONBOARDING_STEP_DETAILS.length; 57 57
+1 -1
apps/web/src/components/show-episode-detail/ShowEpisodeContent.tsx
··· 95 95 > 96 96 Overview 97 97 </h2> 98 - <p className="text-gray-300 leading-relaxed mb-4"> 98 + <p className="text-(--md-sys-color-on-surface-variant) leading-relaxed mb-4"> 99 99 {episode?.overview || "No overview available."} 100 100 </p> 101 101 </section>
+9 -6
apps/web/src/components/ui/badge.tsx
··· 9 9 { 10 10 variants: { 11 11 variant: { 12 - default: "bg-amber-600 text-white", 13 - secondary: "bg-gray-700 text-gray-200", 14 - destructive: "bg-red-600 text-white", 15 - outline: "border border-gray-600 text-gray-200 bg-gray-800", 16 - ghost: "text-gray-400 hover:text-white hover:bg-gray-800/50", 17 - link: "text-amber-400 underline-offset-4 hover:underline hover:text-amber-300", 12 + default: "bg-(--md-sys-color-primary) text-(--md-sys-color-on-primary)", 13 + secondary: 14 + "bg-(--md-sys-color-surface-container-highest) text-(--md-sys-color-on-surface)", 15 + destructive: "bg-(--md-sys-color-error) text-(--md-sys-color-on-error)", 16 + outline: 17 + "border border-(--md-sys-color-outline) text-(--md-sys-color-on-surface) bg-(--md-sys-color-surface-container-high)", 18 + ghost: 19 + "text-(--md-sys-color-on-surface-variant) hover:text-(--md-sys-color-on-surface) hover:bg-(--md-sys-color-surface-container-high)/50", 20 + link: "text-(--md-sys-color-primary) underline-offset-4 hover:underline hover:brightness-110", 18 21 }, 19 22 }, 20 23 defaultVariants: {
+10 -7
apps/web/src/components/ui/button.tsx
··· 5 5 import { cn } from "@/lib/utils"; 6 6 7 7 const buttonVariants = cva( 8 - "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-2 focus-visible:ring-[var(--md-sys-color-primary)]/50", 8 + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-2 focus-visible:ring-(--md-sys-color-primary)/50", 9 9 { 10 10 variants: { 11 11 variant: { 12 12 default: 13 - "bg-[var(--md-sys-color-primary)] text-[var(--md-sys-color-on-primary)] hover:brightness-110", 14 - destructive: "bg-red-600 text-white hover:bg-red-700", 13 + "bg-(--md-sys-color-primary) text-(--md-sys-color-on-primary) hover:brightness-110", 14 + destructive: 15 + "bg-(--md-sys-color-error) text-(--md-sys-color-on-error) hover:brightness-110", 15 16 outline: 16 - "border border-gray-700 bg-gray-900 text-gray-50 hover:bg-gray-800 hover:text-white", 17 - secondary: "bg-gray-800 text-gray-50 hover:bg-gray-700", 18 - ghost: "text-gray-400 hover:text-white hover:bg-gray-800/50", 19 - link: "text-[var(--md-sys-color-primary)] underline-offset-4 hover:underline hover:brightness-110", 17 + "border border-(--md-sys-color-outline-variant) bg-(--md-sys-color-surface-container) text-(--md-sys-color-on-surface) hover:bg-(--md-sys-color-surface-container-high)", 18 + secondary: 19 + "bg-(--md-sys-color-surface-container-high) text-(--md-sys-color-on-surface) hover:bg-(--md-sys-color-surface-container-highest)", 20 + ghost: 21 + "text-(--md-sys-color-on-surface-variant) hover:text-(--md-sys-color-on-surface) hover:bg-(--md-sys-color-surface-container-high)/50", 22 + link: "text-(--md-sys-color-primary) underline-offset-4 hover:underline hover:brightness-110", 20 23 }, 21 24 size: { 22 25 default: "h-9 px-4 py-2 has-[>svg]:px-3",
+5 -2
apps/web/src/components/ui/card.tsx
··· 7 7 <div 8 8 data-slot="card" 9 9 className={cn( 10 - "bg-gray-900 text-gray-50 flex flex-col gap-6 rounded-xl border border-gray-800 py-6 shadow-sm", 10 + "bg-(--md-sys-color-surface-container) text-(--md-sys-color-on-surface) flex flex-col gap-6 rounded-xl border border-(--md-sys-color-outline-variant) py-6 shadow-sm", 11 11 className, 12 12 )} 13 13 {...props} ··· 42 42 return ( 43 43 <div 44 44 data-slot="card-description" 45 - className={cn("text-gray-400 text-sm", className)} 45 + className={cn( 46 + "text-(--md-sys-color-on-surface-variant) text-sm", 47 + className, 48 + )} 46 49 {...props} 47 50 /> 48 51 );
+3 -3
apps/web/src/components/ui/input.tsx
··· 8 8 type={type} 9 9 data-slot="input" 10 10 className={cn( 11 - "placeholder:text-gray-500 selection:bg-amber-500 selection:text-white h-9 w-full min-w-0 rounded-md border border-gray-700 bg-gray-900 px-3 py-1 text-base text-gray-50 shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", 12 - "focus-visible:border-amber-500 focus-visible:ring-amber-500/50 focus-visible:ring-2", 13 - "aria-invalid:ring-red-500/20 aria-invalid:border-red-500", 11 + "placeholder:text-(--md-sys-color-on-surface-variant) selection:bg-(--md-sys-color-primary) selection:text-(--md-sys-color-on-primary) h-9 w-full min-w-0 rounded-md border border-(--md-sys-color-outline-variant) bg-(--md-sys-color-surface-container) px-3 py-1 text-base text-(--md-sys-color-on-surface) shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", 12 + "focus-visible:border-(--md-sys-color-primary) focus-visible:ring-(--md-sys-color-primary)/50 focus-visible:ring-2", 13 + "aria-invalid:ring-(--md-sys-color-error)/20 aria-invalid:border-(--md-sys-color-error)", 14 14 className, 15 15 )} 16 16 {...props}
+14 -14
apps/web/src/components/ui/m3-button.tsx
··· 20 20 "transition-all duration-200", 21 21 "disabled:pointer-events-none disabled:opacity-38", 22 22 "[&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-[18px] shrink-0 [&_svg]:shrink-0", 23 - "outline-none focus-visible:ring-2 focus-visible:ring-[var(--md-sys-color-primary)] focus-visible:ring-offset-2 focus-visible:ring-offset-[var(--md-sys-color-surface)]", 23 + "outline-none focus-visible:ring-2 focus-visible:ring-(--md-sys-color-primary) focus-visible:ring-offset-2 focus-visible:ring-offset-(--md-sys-color-surface)", 24 24 "md-label-large", 25 25 "md-ripple", 26 26 ].join(" "), ··· 34 34 * - Primary color text on surface container low 35 35 */ 36 36 elevated: [ 37 - "bg-[var(--md-sys-color-surface-container-low)]", 38 - "text-[var(--md-sys-color-primary)]", 37 + "bg-(--md-sys-color-surface-container-low)", 38 + "text-(--md-sys-color-primary)", 39 39 "md-elevation-1", 40 40 "hover:md-elevation-2", 41 41 "active:md-elevation-1", ··· 47 47 * - Primary color background 48 48 */ 49 49 filled: [ 50 - "bg-[var(--md-sys-color-primary)]", 51 - "text-[var(--md-sys-color-on-primary)]", 50 + "bg-(--md-sys-color-primary)", 51 + "text-(--md-sys-color-on-primary)", 52 52 "hover:brightness-110", 53 53 "active:brightness-95", 54 54 ].join(" "), ··· 59 59 * - Secondary container background 60 60 */ 61 61 "filled-tonal": [ 62 - "bg-[var(--md-sys-color-secondary-container)]", 63 - "text-[var(--md-sys-color-on-secondary-container)]", 62 + "bg-(--md-sys-color-secondary-container)", 63 + "text-(--md-sys-color-on-secondary-container)", 64 64 "hover:brightness-110", 65 65 "active:brightness-95", 66 66 ].join(" "), ··· 72 72 */ 73 73 outlined: [ 74 74 "bg-transparent", 75 - "text-[var(--md-sys-color-primary)]", 76 - "border border-[var(--md-sys-color-outline)]", 77 - "hover:bg-[var(--md-sys-color-primary-container)]/10", 78 - "active:bg-[var(--md-sys-color-primary-container)]/20", 75 + "text-(--md-sys-color-primary)", 76 + "border border-(--md-sys-color-outline)", 77 + "hover:bg-(--md-sys-color-primary-container)/10", 78 + "active:bg-(--md-sys-color-primary-container)/20", 79 79 ].join(" "), 80 80 81 81 /** ··· 85 85 */ 86 86 text: [ 87 87 "bg-transparent", 88 - "text-[var(--md-sys-color-primary)]", 89 - "hover:bg-[var(--md-sys-color-primary-container)]/10", 90 - "active:bg-[var(--md-sys-color-primary-container)]/20", 88 + "text-(--md-sys-color-primary)", 89 + "hover:bg-(--md-sys-color-primary-container)/10", 90 + "active:bg-(--md-sys-color-primary-container)/20", 91 91 "px-3", 92 92 ].join(" "), 93 93 },
+5 -7
apps/web/src/components/ui/m3-card.tsx
··· 14 14 const m3CardVariants = cva( 15 15 [ 16 16 "relative overflow-hidden", 17 - "rounded-[var(--md-sys-shape-corner-medium)]", 17 + "rounded-(--md-sys-shape-corner-medium)", 18 18 "transition-all duration-200", 19 19 ].join(" "), 20 20 { ··· 26 26 * - Hover elevation: level 2 27 27 */ 28 28 elevated: [ 29 - "bg-[var(--md-sys-color-surface-container-low)]", 29 + "bg-(--md-sys-color-surface-container-low)", 30 30 "md-elevation-1", 31 31 "hover:md-elevation-2", 32 32 ].join(" "), ··· 36 36 * - Surface container highest color 37 37 * - No shadow 38 38 */ 39 - filled: ["bg-[var(--md-sys-color-surface-container-highest)]"].join( 40 - " ", 41 - ), 39 + filled: ["bg-(--md-sys-color-surface-container-highest)"].join(" "), 42 40 43 41 /** 44 42 * Outlined Card ··· 46 44 * - 1px outline 47 45 */ 48 46 outlined: [ 49 - "bg-[var(--md-sys-color-surface)]", 50 - "border border-[var(--md-sys-color-outline-variant)]", 47 + "bg-(--md-sys-color-surface)", 48 + "border border-(--md-sys-color-outline-variant)", 51 49 ].join(" "), 52 50 }, 53 51 },
+11 -11
apps/web/src/components/ui/m3-text-field.tsx
··· 22 22 * - 2px primary color outline on focus 23 23 */ 24 24 outlined: [ 25 - "rounded-[var(--md-sys-shape-corner-extra-small)]", 26 - "border border-[var(--md-sys-color-outline)]", 25 + "rounded-(--md-sys-shape-corner-extra-small)", 26 + "border border-(--md-sys-color-outline)", 27 27 "bg-transparent", 28 - "focus-within:border-[var(--md-sys-color-primary)]", 28 + "focus-within:border-(--md-sys-color-primary)", 29 29 "focus-within:border-2", 30 30 ].join(" "), 31 31 ··· 35 35 * - Underline that animates on focus 36 36 */ 37 37 filled: [ 38 - "rounded-t-[var(--md-sys-shape-corner-extra-small)]", 39 - "bg-[var(--md-sys-color-surface-container-highest)]", 40 - "border-b border-[var(--md-sys-color-on-surface-variant)]", 38 + "rounded-t-(--md-sys-shape-corner-extra-small)", 39 + "bg-(--md-sys-color-surface-container-highest)", 40 + "border-b border-(--md-sys-color-on-surface-variant)", 41 41 "focus-within:border-b-2", 42 - "focus-within:border-[var(--md-sys-color-primary)]", 42 + "focus-within:border-(--md-sys-color-primary)", 43 43 ].join(" "), 44 44 }, 45 45 /** ··· 47 47 */ 48 48 error: { 49 49 true: [ 50 - "border-[var(--md-sys-color-error)]", 51 - "focus-within:border-[var(--md-sys-color-error)]", 50 + "border-(--md-sys-color-error)", 51 + "focus-within:border-(--md-sys-color-error)", 52 52 ].join(" "), 53 53 false: "", 54 54 }, ··· 63 63 const m3TextFieldInputVariants = cva( 64 64 [ 65 65 "w-full bg-transparent", 66 - "text-[var(--md-sys-color-on-surface)]", 67 - "placeholder:text-[var(--md-sys-color-on-surface-variant)]", 66 + "text-(--md-sys-color-on-surface)", 67 + "placeholder:text-(--md-sys-color-on-surface-variant)", 68 68 "outline-none", 69 69 "md-body-large", 70 70 ].join(" "),
+4 -1
apps/web/src/components/ui/skeleton.tsx
··· 4 4 return ( 5 5 <div 6 6 data-slot="skeleton" 7 - className={cn("bg-gray-800 animate-pulse rounded-md", className)} 7 + className={cn( 8 + "animate-pulse rounded-md bg-(--md-sys-color-surface-container-high)", 9 + className, 10 + )} 8 11 {...props} 9 12 /> 10 13 );
+2 -2
apps/web/src/components/ui/switch.tsx
··· 11 11 <SwitchPrimitives.Root 12 12 data-slot="switch" 13 13 className={cn( 14 - "peer data-[state=checked]:bg-amber-500 data-[state=unchecked]:bg-slate-700 focus-visible:ring-amber-500/50 inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-950 disabled:cursor-not-allowed disabled:opacity-50", 14 + "peer data-[state=checked]:bg-(--md-sys-color-primary) data-[state=unchecked]:bg-(--md-sys-color-surface-container-highest) focus-visible:ring-(--md-sys-color-primary)/50 inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-offset-(--md-sys-color-surface) disabled:cursor-not-allowed disabled:opacity-50", 15 15 className, 16 16 )} 17 17 {...props} ··· 19 19 <SwitchPrimitives.Thumb 20 20 data-slot="switch-thumb" 21 21 className={cn( 22 - "bg-slate-50 pointer-events-none block h-5 w-5 rounded-full shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0", 22 + "bg-(--md-sys-color-on-primary) pointer-events-none block h-5 w-5 rounded-full shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0", 23 23 )} 24 24 /> 25 25 </SwitchPrimitives.Root>
+3 -3
apps/web/src/components/ui/textarea.tsx
··· 7 7 <textarea 8 8 data-slot="textarea" 9 9 className={cn( 10 - "placeholder:text-gray-500 selection:bg-amber-500 selection:text-white min-h-[60px] w-full rounded-md border border-gray-700 bg-gray-900 px-3 py-2 text-base text-gray-50 shadow-xs transition-[color,box-shadow] outline-none resize-none md:text-sm", 11 - "focus-visible:border-amber-500 focus-visible:ring-amber-500/50 focus-visible:ring-2", 12 - "aria-invalid:ring-red-500/20 aria-invalid:border-red-500", 10 + "placeholder:text-(--md-sys-color-on-surface-variant) selection:bg-(--md-sys-color-primary) selection:text-(--md-sys-color-on-primary) min-h-[60px] w-full rounded-md border border-(--md-sys-color-outline-variant) bg-(--md-sys-color-surface-container) px-3 py-2 text-base text-(--md-sys-color-on-surface) shadow-xs transition-[color,box-shadow] outline-none resize-none md:text-sm", 11 + "focus-visible:border-(--md-sys-color-primary) focus-visible:ring-(--md-sys-color-primary)/50 focus-visible:ring-2", 12 + "aria-invalid:ring-(--md-sys-color-error)/20 aria-invalid:border-(--md-sys-color-error)", 13 13 className, 14 14 )} 15 15 {...props}
+12 -6
apps/web/src/components/ui/time-picker.tsx
··· 17 17 return ( 18 18 <div className="flex items-center gap-2"> 19 19 <div className="grid gap-1 text-center"> 20 - <Label htmlFor="hours" className="text-xs text-gray-400"> 20 + <Label 21 + htmlFor="hours" 22 + className="text-xs text-(--md-sys-color-on-surface-variant)" 23 + > 21 24 Hours 22 25 </Label> 23 26 <TimePickerInput ··· 26 29 setDate={setDate} 27 30 ref={hourRef} 28 31 onRightFocus={() => minuteRef.current?.focus()} 29 - className="w-[60px] bg-gray-800 border-gray-700 text-white focus:border-amber-500" 32 + className="w-[60px] bg-(--md-sys-color-surface-container-high) border-(--md-sys-color-outline-variant) text-(--md-sys-color-on-surface) focus:border-(--md-sys-color-primary)" 30 33 /> 31 34 </div> 32 - <span className="text-gray-400 mt-5">:</span> 35 + <span className="text-(--md-sys-color-on-surface-variant) mt-5">:</span> 33 36 <div className="grid gap-1 text-center"> 34 - <Label htmlFor="minutes" className="text-xs text-gray-400"> 37 + <Label 38 + htmlFor="minutes" 39 + className="text-xs text-(--md-sys-color-on-surface-variant)" 40 + > 35 41 Minutes 36 42 </Label> 37 43 <TimePickerInput ··· 40 46 setDate={setDate} 41 47 ref={minuteRef} 42 48 onLeftFocus={() => hourRef.current?.focus()} 43 - className="w-[60px] bg-gray-800 border-gray-700 text-white focus:border-amber-500" 49 + className="w-[60px] bg-(--md-sys-color-surface-container-high) border-(--md-sys-color-outline-variant) text-(--md-sys-color-on-surface) focus:border-(--md-sys-color-primary)" 44 50 /> 45 51 </div> 46 52 <div className="flex h-10 items-center mt-4"> 47 - <Clock className="ml-2 h-4 w-4 text-gray-400" /> 53 + <Clock className="ml-2 h-4 w-4 text-(--md-sys-color-on-surface-variant)" /> 48 54 </div> 49 55 </div> 50 56 );
+2 -2
apps/web/src/components/ui/tooltip.tsx
··· 42 42 data-slot="tooltip-content" 43 43 sideOffset={sideOffset} 44 44 className={cn( 45 - "bg-gray-100 text-gray-900 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance", 45 + "bg-(--md-sys-color-inverse-surface) text-(--md-sys-color-inverse-on-surface) animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance", 46 46 className, 47 47 )} 48 48 {...props} 49 49 > 50 50 {children} 51 - <TooltipPrimitive.Arrow className="bg-gray-100 fill-gray-100 z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]" /> 51 + <TooltipPrimitive.Arrow className="bg-(--md-sys-color-inverse-surface) fill-(--md-sys-color-inverse-surface) z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px]" /> 52 52 </TooltipPrimitive.Content> 53 53 </TooltipPrimitive.Portal> 54 54 );
+2 -2
apps/web/src/components/up-next/UpNextShowCollection.tsx
··· 171 171 className={`flex gap-4 p-4 items-stretch ${cardMinHeight}`} 172 172 > 173 173 <div className="w-24 shrink-0 self-center"> 174 - <div className="aspect-2/3 w-full overflow-hidden rounded-xl bg-gray-900"> 174 + <div className="aspect-2/3 w-full overflow-hidden rounded-xl bg-(--md-sys-color-surface-container)"> 175 175 {posterUrl ? ( 176 176 <img 177 177 src={posterUrl} ··· 180 180 loading="lazy" 181 181 /> 182 182 ) : ( 183 - <div className="flex h-full w-full items-center justify-center text-sm text-gray-500"> 183 + <div className="flex h-full w-full items-center justify-center text-sm text-(--md-sys-color-on-surface-variant)"> 184 184 No poster 185 185 </div> 186 186 )}
+1 -1
apps/web/src/routes/login.tsx
··· 143 143 }} 144 144 > 145 145 <div className="mb-8"> 146 - <h1 className="md-headline-large mb-3">Login</h1> 146 + <h1 className="md-headline-large mb-3">Sign in</h1> 147 147 <p className="md-body-large text-(--md-sys-color-on-surface-variant)"> 148 148 Connect with your Atmosphere account 149 149 </p>
+1 -1
apps/web/src/routes/profile.$handle.list.$slug.tsx
··· 342 342 size="sm" 343 343 onClick={() => setShowDeleteConfirm(true)} 344 344 disabled={deleteMutation.isPending} 345 - className="border-[var(--md-sys-color-error)] text-[var(--md-sys-color-error)]" 345 + className="border-(--md-sys-color-error) text-(--md-sys-color-error)" 346 346 > 347 347 <Trash2 className="mr-2 h-4 w-4" /> 348 348 {deleteMutation.isPending ? "Deleting..." : "Delete"}
+4 -6
apps/web/src/routes/profile.$handle.tsx
··· 152 152 </div> 153 153 )} 154 154 <div className="min-w-0 flex-1"> 155 - <h1 className="md-headline-medium [overflow-wrap:anywhere]"> 156 - {displayName} 157 - </h1> 155 + <h1 className="md-headline-medium wrap-anywhere">{displayName}</h1> 158 156 <p 159 - className="[overflow-wrap:anywhere]" 157 + className="wrap-anywhere" 160 158 style={{ color: "var(--md-sys-color-on-surface-variant)" }} 161 159 > 162 160 @{profile.handle} ··· 359 357 return ( 360 358 <Link 361 359 {...route} 362 - className={`flex items-center gap-2 rounded-[var(--md-sys-shape-corner-large)] px-4 py-2 transition-colors md-label-large ${ 360 + className={`flex items-center gap-2 rounded-(--md-sys-shape-corner-large) px-4 py-2 transition-colors md-label-large ${ 363 361 isActive 364 362 ? "" 365 - : "hover:bg-[var(--md-sys-color-surface-container)] hover:text-[var(--md-sys-color-on-surface)]" 363 + : "hover:bg-(--md-sys-color-surface-container) hover:text-(--md-sys-color-on-surface)" 366 364 }`} 367 365 style={ 368 366 isActive
+4 -1
apps/web/src/routes/search.tsx
··· 246 246 {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((i) => ( 247 247 <div 248 248 key={i} 249 - className="aspect-2/3 bg-gray-800 rounded-lg animate-pulse" 249 + className="aspect-2/3 rounded-lg animate-pulse" 250 + style={{ 251 + backgroundColor: "var(--md-sys-color-surface-container-high)", 252 + }} 250 253 /> 251 254 ))} 252 255 </div>
+1 -1
apps/web/src/routes/shows.$showId.$title.seasons.$seasonNumber.tsx
··· 369 369 > 370 370 Overview 371 371 </h2> 372 - <p className="text-gray-300 leading-relaxed"> 372 + <p className="text-(--md-sys-color-on-surface-variant) leading-relaxed"> 373 373 {season?.overview || "No season overview available."} 374 374 </p> 375 375 </section>
+1 -1
apps/web/src/routes/shows.$showId.$title.tsx
··· 313 313 > 314 314 Overview 315 315 </h2> 316 - <p className="text-gray-300 leading-relaxed"> 316 + <p className="text-(--md-sys-color-on-surface-variant) leading-relaxed"> 317 317 {show?.overview || "No overview available."} 318 318 </p> 319 319 </section>