ATlast — you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto

add ATmosphere explanation w tooltip

byarielm.fyi fdbab043 0411d34f

verified
Changed files
+59 -4
src
components
+43
src/components/common/Tooltip.tsx
··· 1 + import { ReactNode, useState } from "react"; 2 + import { Info } from "lucide-react"; 3 + 4 + interface TooltipProps { 5 + content: ReactNode; 6 + children?: ReactNode; 7 + className?: string; 8 + } 9 + 10 + export default function Tooltip({ content, children, className = "" }: TooltipProps) { 11 + const [isVisible, setIsVisible] = useState(false); 12 + 13 + return ( 14 + <div className="relative inline-block"> 15 + <button 16 + type="button" 17 + className={`inline-flex items-center ${className}`} 18 + onMouseEnter={() => setIsVisible(true)} 19 + onMouseLeave={() => setIsVisible(false)} 20 + onFocus={() => setIsVisible(true)} 21 + onBlur={() => setIsVisible(false)} 22 + aria-label="More information" 23 + > 24 + {children || ( 25 + <Info className="w-4 h-4 text-purple-750/70 dark:text-cyan-250/70 hover:text-purple-900 dark:hover:text-cyan-100 transition-colors" /> 26 + )} 27 + </button> 28 + 29 + {isVisible && ( 30 + <div 31 + className="absolute left-1/2 -translate-x-1/2 bottom-full mb-2 w-72 px-3 py-2 bg-slate-900 dark:bg-slate-800 text-white text-sm rounded-lg shadow-lg z-50 pointer-events-none" 32 + role="tooltip" 33 + > 34 + <div className="relative"> 35 + {content} 36 + {/* Arrow */} 37 + <div className="absolute left-1/2 -translate-x-1/2 -bottom-5 w-0 h-0 border-l-8 border-l-transparent border-r-8 border-r-transparent border-t-8 border-t-slate-900 dark:border-t-slate-800" /> 38 + </div> 39 + </div> 40 + )} 41 + </div> 42 + ); 43 + }
+1
src/components/common/index.tsx
··· 17 17 export { default as SetupPrompt } from "./SetupPrompt"; 18 18 export { default as Skeleton } from "./Skeleton"; 19 19 export { default as Toggle } from "./Toggle"; 20 + export { default as Tooltip } from "./Tooltip"; 20 21 21 22 // Export Stats components 22 23 export { StatItem, StatBadge, StatsGroup } from "./Stats";
+15 -4
src/components/login/HeroSection.tsx
··· 1 1 import FireflyLogo from "../../assets/at-firefly-logo.svg?react"; 2 + import Tooltip from "../common/Tooltip"; 2 3 3 4 interface HeroSectionProps { 4 5 reducedMotion?: boolean; ··· 16 17 <h1 className="text-5xl md:text-6xl font-bold bg-gradient-to-r from-purple-600 via-cyan-500 to-pink-500 dark:from-cyan-300 dark:via-purple-300 dark:to-pink-300 bg-clip-text text-transparent mb-3 md:mb-4"> 17 18 ATlast 18 19 </h1> 19 - <p className="text-xl md:text-2xl lg:text-2xl text-purple-900 dark:text-cyan-100 mb-2 font-medium"> 20 - Find Your Light in the ATmosphere 20 + <p className="text-xl md:text-2xl lg:text-2xl text-purple-900 dark:text-cyan-100 mb-2 font-medium inline-flex items-center gap-2 justify-center md:justify-start w-full"> 21 + <span>Find Your Light in the ATmosphere</span> 22 + <Tooltip 23 + content={ 24 + <div> 25 + <p className="font-semibold mb-1">What's the ATmosphere?</p> 26 + <p className="text-xs leading-relaxed"> 27 + The <strong>ATmosphere</strong> is an open network of social apps that use one login, including Bluesky, Blacksky, Tangled, Flashes, Leaflet, and more. Once you login, you can explore the social apps that let you follow different people! 28 + </p> 29 + </div> 30 + } 31 + /> 21 32 </p> 22 - <p className="text-purple-750 dark:text-cyan-250 mb-6"> 23 - Reconnect with your internet, one firefly at a time ✨ 33 + <p className="text-purple-750 dark:text-cyan-250 mb-2"> 34 + Reconnect with your internet, one firefly at a time 24 35 </p> 25 36 26 37 {/* Decorative firefly trail - only show if motion enabled */}