origin
This commit is contained in:
		
							
								
								
									
										106
									
								
								src/App.tsx
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										106
									
								
								src/App.tsx
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| import React from 'react'; | ||||
| import { Terminal } from 'lucide-react'; | ||||
| import TerminalButton from './components/TerminalButton'; | ||||
| import ProfileContent from './components/ProfileContent'; | ||||
| import ProjectsContent from './components/ProjectsContent'; | ||||
|  | ||||
| function App() { | ||||
|   const [activeSection, setActiveSection] = React.useState('about'); | ||||
|  | ||||
|   return ( | ||||
|     <div className="min-h-screen bg-gray-900 flex items-center justify-center overflow-hidden"> | ||||
|       {/* TV Container */} | ||||
|       <div className="w-[95%] max-w-[1400px] relative h-[80vh]"> | ||||
|         {/* TV Frame */} | ||||
|         <div className="absolute inset-0 tv-frame"> | ||||
|           {/* Screen Container with Convex Effect */} | ||||
|           <div className="relative w-full h-full rounded-[20px] overflow-hidden tv-screen-container"> | ||||
|             {/* Convex Screen Effect */} | ||||
|             <div className="absolute inset-0 tv-screen-convex"></div> | ||||
|  | ||||
|             {/* Screen Content */} | ||||
|             <div className="relative h-full w-full bg-[#003300] p-6 font-mono text-[#00FF00] overflow-hidden z-10"> | ||||
|               <div className="animate-pulse mb-4"> | ||||
|                 <Terminal className="inline-block mr-2" /> | ||||
|                 <span className="text-sm">echo "Hey there!"</span> | ||||
|               </div> | ||||
|  | ||||
|               {/* Split Screen Container */} | ||||
|               <div className="flex gap-8 h-[calc(100%-3rem)]"> | ||||
|                 {/* Left Column - Navigation */} | ||||
|                 <div className="w-64 space-y-3 overflow-y-auto custom-scrollbar"> | ||||
|                   <TerminalButton | ||||
|                     onClick={() => setActiveSection('about')} | ||||
|                     isSelected={activeSection === 'about'} | ||||
|                   > | ||||
|                     ABOUT | ||||
|                   </TerminalButton> | ||||
|                   <TerminalButton | ||||
|                     onClick={() => setActiveSection('projects')} | ||||
|                     isSelected={activeSection === 'projects'} | ||||
|                   > | ||||
|                     PROJECTS | ||||
|                   </TerminalButton> | ||||
|                   <TerminalButton | ||||
|                     onClick={() => setActiveSection('skills')} | ||||
|                     isSelected={activeSection === 'skills'} | ||||
|                   > | ||||
|                     SKILLS | ||||
|                   </TerminalButton> | ||||
|                   <TerminalButton | ||||
|                     onClick={() => setActiveSection('contact')} | ||||
|                     isSelected={activeSection === 'contact'} | ||||
|                   > | ||||
|                     CONTACT | ||||
|                   </TerminalButton> | ||||
|                   <TerminalButton | ||||
|                     onClick={() => setActiveSection('resume')} | ||||
|                     isSelected={activeSection === 'resume'} | ||||
|                   > | ||||
|                     RESUME | ||||
|                   </TerminalButton> | ||||
|                 </div> | ||||
|  | ||||
|                 {/* Vertical Separator */} | ||||
|                 <div className="w-px h-full bg-[#00FF00] opacity-30"></div> | ||||
|  | ||||
|                 {/* Right Column - Content */} | ||||
|                 <div className="flex-1 overflow-y-auto pr-4 custom-scrollbar"> | ||||
|                   {activeSection === 'about' && <ProfileContent />} | ||||
|                   {activeSection === 'projects' && ( | ||||
|                     <ProjectsContent markdownPath="/content/projects.md" /> | ||||
|                   )} | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|  | ||||
|             {/* Scan Line Effect */} | ||||
|             <div className="absolute inset-0 pointer-events-none z-20" style={{ | ||||
|               background: 'linear-gradient(rgba(0, 17, 0, 0.1) 50%, rgba(0, 17, 0, 0.2) 50%)', | ||||
|               backgroundSize: '100% 4px' | ||||
|             }}></div> | ||||
|  | ||||
|             {/* Screen Glare */} | ||||
|             <div className="screen-glare"></div> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
|         {/* TV Controls */} | ||||
|         <div className="absolute -bottom-10 right-20 flex space-x-6"> | ||||
|           <div className="w-8 h-8 bg-gray-700 rounded-full shadow-inner"></div> | ||||
|           <div className="w-8 h-8 bg-gray-700 rounded-full shadow-inner"></div> | ||||
|           <div className="w-8 h-8 bg-gray-700 rounded-full shadow-inner"></div> | ||||
|         </div> | ||||
|  | ||||
|         {/* TV Speaker Grills */} | ||||
|         <div className="absolute -bottom-6 left-20 flex space-x-1.5"> | ||||
|           {[...Array(10)].map((_, i) => ( | ||||
|             <div key={i} className="w-1.5 h-6 bg-gray-700 rounded-full opacity-50"></div> | ||||
|           ))} | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| export default App; | ||||
							
								
								
									
										43
									
								
								src/components/GlitchyLink.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/components/GlitchyLink.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| import React, { useState } from 'react'; | ||||
|  | ||||
| interface GlitchyLinkProps { | ||||
|     text: string; | ||||
|     url: string; | ||||
|     type?: 'email' | 'link'; | ||||
| } | ||||
|  | ||||
| const GlitchyLink: React.FC<GlitchyLinkProps> = ({ text, url, type = 'link' }) => { | ||||
|     const [copied, setCopied] = useState(false); | ||||
|  | ||||
|     const handleClick = async (e: React.MouseEvent) => { | ||||
|         if (type === 'email') { | ||||
|             e.preventDefault(); | ||||
|             if (copied) return; | ||||
|             await navigator.clipboard.writeText(text); | ||||
|             setCopied(true); | ||||
|             setTimeout(() => setCopied(false), 2000); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     return ( | ||||
|         <a | ||||
|             href={url} | ||||
|             target="_blank" | ||||
|             rel="noopener noreferrer" | ||||
|             onClick={handleClick} | ||||
|             className="group relative inline-block hover:text-green-400 transition-colors" | ||||
|         > | ||||
|             <span className="relative inline-block animate-glitch-1"> | ||||
|                 {copied ? 'Copied!' : text} | ||||
|             </span> | ||||
|             <span className="absolute top-0 left-0 w-full h-full opacity-0 group-hover:opacity-70 group-hover:animate-glitch-1"> | ||||
|                 {copied ? 'Copied!' : text} | ||||
|             </span> | ||||
|             <span className="absolute top-0 left-0 w-full h-full opacity-0 group-hover:opacity-70 group-hover:animate-glitch-2"> | ||||
|                 {copied ? 'Copied!' : text} | ||||
|             </span> | ||||
|         </a> | ||||
|     ); | ||||
| }; | ||||
|  | ||||
| export default GlitchyLink; | ||||
							
								
								
									
										60
									
								
								src/components/ProfileContent.tsx
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										60
									
								
								src/components/ProfileContent.tsx
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| import React from 'react'; | ||||
| import { Mail, Github, Linkedin, User, Code, BookOpen, Building, MapPin } from 'lucide-react'; | ||||
| import GlitchyLink from './GlitchyLink'; | ||||
|  | ||||
| const ProfileContent: React.FC = () => { | ||||
|   return ( | ||||
|     <div className="flex-1 overflow-auto"> | ||||
|       <div className="space-y-8"> | ||||
|         <div className="flex items-center gap-2"> | ||||
|           <User className="w-6 h-6" /> | ||||
|           <h2 className="text-2xl font-bold">José Henrique Ivanchechen</h2> | ||||
|         </div> | ||||
|  | ||||
|         <div className="flex items-center gap-2"> | ||||
|           <Code className="w-6 h-6" /> | ||||
|           <p className="text-lg">Software Engineer</p> | ||||
|         </div> | ||||
|  | ||||
|         <div className="flex items-center gap-2"> | ||||
|           <Building className="w-6 h-6" /> | ||||
|           <p className="text-lg">EposNow</p> | ||||
|         </div> | ||||
|  | ||||
|         <div className="flex items-center gap-2"> | ||||
|           <MapPin className="w-6 h-6" /> | ||||
|           <p className="text-lg">Curitiba, PR - Brazil</p> | ||||
|         </div> | ||||
|  | ||||
|         <div className="flex items-center gap-2"> | ||||
|           <BookOpen className="w-6 h-6" /> | ||||
|           <p className="text-lg">5+ Years Experience</p> | ||||
|         </div> | ||||
|  | ||||
|         <div className="mt-12 space-y-6"> | ||||
|           <h3 className="text-xl font-semibold">> Contact Info:</h3> | ||||
|           <div className="space-y-4 pl-6"> | ||||
|             <div className="flex items-center gap-3"> | ||||
|               <Mail className="w-5 h-5" /> | ||||
|               <GlitchyLink | ||||
|                 text="jose.henrique.ivan@gmail.com" | ||||
|                 url="mailto:jose.henrique.ivan@gmail.com" | ||||
|                 type="email" | ||||
|               /> | ||||
|             </div> | ||||
|             <div className="flex items-center gap-3"> | ||||
|               <Github className="w-5 h-5" /> | ||||
|               <GlitchyLink text="@ivanch" url="https://github.com/ivanch" /> | ||||
|             </div> | ||||
|             <div className="flex items-center gap-3"> | ||||
|               <Linkedin className="w-5 h-5" /> | ||||
|               <GlitchyLink text="/in/joseivanch" url="https://linkedin.com/in/joseivanch" /> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| export default ProfileContent; | ||||
							
								
								
									
										46
									
								
								src/components/ProjectsContent.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/components/ProjectsContent.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| import React from 'react'; | ||||
| import ReactMarkdown from 'react-markdown'; | ||||
| import remarkGfm from 'remark-gfm'; | ||||
| import { FileWarning } from 'lucide-react'; | ||||
|  | ||||
| interface ProjectsContentProps { | ||||
|   markdownPath: string; | ||||
| } | ||||
|  | ||||
| const ProjectsContent: React.FC<ProjectsContentProps> = ({ markdownPath }) => { | ||||
|   const [content, setContent] = React.useState<string>(''); | ||||
|   const [error, setError] = React.useState<string>(''); | ||||
|  | ||||
|   React.useEffect(() => { | ||||
|     fetch(markdownPath) | ||||
|       .then(response => { | ||||
|         if (!response.ok) throw new Error('Failed to load content'); | ||||
|         return response.text(); | ||||
|       }) | ||||
|       .then(text => setContent(text)) | ||||
|       .catch(err => setError(err.message)); | ||||
|   }, [markdownPath]); | ||||
|  | ||||
|   if (error) { | ||||
|     return ( | ||||
|       <div className="flex-1 flex items-center justify-center"> | ||||
|         <div className="text-center space-y-4"> | ||||
|           <FileWarning className="w-12 h-12 mx-auto" /> | ||||
|           <p className="text-lg">Error loading content: {error}</p> | ||||
|         </div> | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|     <div className="flex-1"> | ||||
|       <div className="prose prose-invert prose-green max-w-none"> | ||||
|         <ReactMarkdown remarkPlugins={[remarkGfm]}> | ||||
|           {content} | ||||
|         </ReactMarkdown> | ||||
|       </div> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| export default ProjectsContent; | ||||
							
								
								
									
										34
									
								
								src/components/TerminalButton.tsx
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										34
									
								
								src/components/TerminalButton.tsx
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| import React from 'react'; | ||||
| import { ChevronRight } from 'lucide-react'; | ||||
|  | ||||
| interface TerminalButtonProps { | ||||
|   children: React.ReactNode; | ||||
|   onClick?: () => void; | ||||
|   isSelected?: boolean; | ||||
| } | ||||
|  | ||||
| const TerminalButton: React.FC<TerminalButtonProps> = ({ children, onClick, isSelected }) => { | ||||
|   const playKeyPress = () => { | ||||
|     const audio = new Audio('data:audio/wav;base64,UklGRnQGAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YU8GAACBhYqFbF1fdH2Dg4R/gIKFi4SAgX98eoCFhQAAhIWKhWxdX3R9g4OEf4CChYuEgIF/fHqAhYUAAP//'); | ||||
|     audio.volume = 0.2; | ||||
|     audio.play().catch(() => {}); | ||||
|   }; | ||||
|  | ||||
|   const handleClick = (e: React.MouseEvent) => { | ||||
|     playKeyPress(); | ||||
|     onClick?.(e); | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|     <button  | ||||
|       className={`terminal-button group ${isSelected ? 'terminal-button-selected' : ''}`} | ||||
|       onClick={handleClick} | ||||
|     > | ||||
|       <div className="glare-effect"></div> | ||||
|       <ChevronRight className="inline-block mr-2 w-4 h-4 transition-transform group-hover:translate-x-1" /> | ||||
|       {children} | ||||
|     </button> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| export default TerminalButton; | ||||
							
								
								
									
										252
									
								
								src/index.css
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										252
									
								
								src/index.css
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,252 @@ | ||||
| @tailwind base; | ||||
| @tailwind components; | ||||
| @tailwind utilities; | ||||
|  | ||||
| @font-face { | ||||
|   font-family: 'VT323'; | ||||
|   src: url('https://fonts.googleapis.com/css2?family=VT323&display=swap'); | ||||
| } | ||||
|  | ||||
| @layer utilities { | ||||
|   .typing-effect { | ||||
|     border-right: 2px solid #00FF00; | ||||
|     animation: cursor-blink 1s step-end infinite; | ||||
|   } | ||||
|  | ||||
|   .tv-frame { | ||||
|     @apply rounded-[50px] p-8; | ||||
|     background: linear-gradient(145deg, #4a4a4a, #2a2a2a); | ||||
|     box-shadow: | ||||
|       20px 20px 60px #1a1a1a, | ||||
|       -20px -20px 60px #3a3a3a, | ||||
|       inset 0 2px 20px rgba(255, 255, 255, 0.1); | ||||
|     border: 12px solid #1a1a1a; | ||||
|     border-radius: 50px; | ||||
|     transform: perspective(1000px) rotateX(2deg); | ||||
|   } | ||||
|  | ||||
|   .tv-frame::before { | ||||
|     content: ''; | ||||
|     position: absolute; | ||||
|     top: -12px; | ||||
|     left: -12px; | ||||
|     right: -12px; | ||||
|     bottom: -12px; | ||||
|     background: linear-gradient(145deg, #3a3a3a, #1a1a1a); | ||||
|     border-radius: 60px; | ||||
|     z-index: -1; | ||||
|   } | ||||
|  | ||||
|   .tv-frame::after { | ||||
|     content: ''; | ||||
|     position: absolute; | ||||
|     top: 0; | ||||
|     left: 0; | ||||
|     right: 0; | ||||
|     height: 40%; | ||||
|     background: linear-gradient( | ||||
|       180deg, | ||||
|       rgba(255, 255, 255, 0.1) 0%, | ||||
|       transparent 100% | ||||
|     ); | ||||
|     border-radius: 40px 40px 0 0; | ||||
|     pointer-events: none; | ||||
|   } | ||||
|  | ||||
|   .tv-screen-container { | ||||
|     background: #000; | ||||
|     box-shadow: | ||||
|       inset 0 0 50px rgba(0, 0, 0, 0.5), | ||||
|       inset 0 0 100px rgba(0, 0, 0, 0.3); | ||||
|     transform: perspective(1000px) rotateX(1deg); | ||||
|   } | ||||
|  | ||||
|   .tv-screen-convex { | ||||
|     content: ''; | ||||
|     background: radial-gradient( | ||||
|       circle at center, | ||||
|       transparent 0%, | ||||
|       rgba(0, 0, 0, 0) 50%, | ||||
|       rgba(0, 0, 0, 0.3) 100% | ||||
|     ); | ||||
|     border-radius: 50% / 5%; | ||||
|     pointer-events: none; | ||||
|     z-index: 40; | ||||
|   } | ||||
|  | ||||
|   .tv-screen-convex::before { | ||||
|     content: ''; | ||||
|     position: absolute; | ||||
|     top: 0; | ||||
|     left: 0; | ||||
|     right: 0; | ||||
|     bottom: 0; | ||||
|     background: radial-gradient( | ||||
|       circle at 50% 0%, | ||||
|       rgba(255, 255, 255, 0.1) 0%, | ||||
|       rgba(255, 255, 255, 0.05) 25%, | ||||
|       transparent 50% | ||||
|     ); | ||||
|     border-radius: inherit; | ||||
|   } | ||||
|  | ||||
|   .terminal-button { | ||||
|     @apply relative w-full px-6 py-3 font-mono text-lg | ||||
|            transition-all duration-150 overflow-hidden | ||||
|            border border-[#00FF00]/30 select-none; | ||||
|     font-family: 'VT323', 'Courier New', monospace; | ||||
|     background: linear-gradient(180deg, | ||||
|       rgba(0, 25, 0, 0.9) 0%, | ||||
|       rgba(0, 20, 0, 0.95) 100% | ||||
|     ); | ||||
|     color: #4AFF4A; | ||||
|     text-shadow: 0 0 8px rgba(74, 255, 74, 0.5); | ||||
|     box-shadow: | ||||
|       inset 0 0 15px rgba(0, 255, 0, 0.1), | ||||
|       0 0 2px rgba(0, 255, 0, 0.5), | ||||
|       0 0 5px rgba(0, 255, 0, 0.2); | ||||
|   } | ||||
|  | ||||
|   .terminal-button-selected { | ||||
|     @apply text-[110%] font-bold; | ||||
|     background: linear-gradient(180deg, | ||||
|       rgba(0, 35, 0, 0.95) 0%, | ||||
|       rgba(0, 30, 0, 1) 100% | ||||
|     ); | ||||
|     color: #7FFF7F; | ||||
|     text-shadow: 0 0 12px rgba(74, 255, 74, 0.8); | ||||
|     box-shadow: | ||||
|       inset 0 0 25px rgba(0, 255, 0, 0.2), | ||||
|       0 0 4px rgba(0, 255, 0, 0.6), | ||||
|       0 0 8px rgba(0, 255, 0, 0.3); | ||||
|   } | ||||
|  | ||||
|   .terminal-button::before { | ||||
|     content: ''; | ||||
|     @apply absolute inset-0 opacity-0 transition-opacity duration-150; | ||||
|     background: linear-gradient(180deg, | ||||
|       rgba(0, 255, 0, 0.1) 0%, | ||||
|       rgba(0, 255, 0, 0.05) 100% | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   .terminal-button:hover { | ||||
|     color: #7FFF7F; | ||||
|     text-shadow: 0 0 8px rgba(74, 255, 74, 0.8); | ||||
|     box-shadow: | ||||
|       inset 0 0 20px rgba(0, 255, 0, 0.2), | ||||
|       0 0 4px rgba(0, 255, 0, 0.6), | ||||
|       0 0 8px rgba(0, 255, 0, 0.3); | ||||
|   } | ||||
|  | ||||
|   .terminal-button:hover::before { | ||||
|     @apply opacity-100; | ||||
|   } | ||||
|  | ||||
|   .terminal-button:active { | ||||
|     @apply transform scale-[0.98]; | ||||
|     background: linear-gradient(180deg, | ||||
|       rgba(0, 35, 0, 0.95) 0%, | ||||
|       rgba(0, 30, 0, 1) 100% | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   .terminal-button::after { | ||||
|     content: ''; | ||||
|     @apply absolute inset-0 pointer-events-none; | ||||
|     background: repeating-linear-gradient( | ||||
|       0deg, | ||||
|       rgba(0, 255, 0, 0.03), | ||||
|       rgba(0, 255, 0, 0.03) 1px, | ||||
|       transparent 1px, | ||||
|       transparent 2px | ||||
|     ); | ||||
|   } | ||||
|  | ||||
|   .glare-effect { | ||||
|     @apply absolute inset-0 pointer-events-none; | ||||
|     background: linear-gradient( | ||||
|       90deg, | ||||
|       transparent 0%, | ||||
|       rgba(74, 255, 74, 0.1) 25%, | ||||
|       rgba(74, 255, 74, 0.1) 75%, | ||||
|       transparent 100% | ||||
|     ); | ||||
|     animation: glare 3s ease-in-out infinite; | ||||
|     opacity: 0.5; | ||||
|   } | ||||
|  | ||||
|   .screen-glare { | ||||
|     @apply absolute inset-0 pointer-events-none z-30; | ||||
|     background: linear-gradient( | ||||
|       90deg, | ||||
|       transparent 0%, | ||||
|       rgba(255, 255, 255, 0.03) 45%, | ||||
|       rgba(255, 255, 255, 0.07) 50%, | ||||
|       rgba(255, 255, 255, 0.03) 55%, | ||||
|       transparent 100% | ||||
|     ); | ||||
|     animation: horizontal-glare 4s linear infinite; | ||||
|   } | ||||
| } | ||||
|  | ||||
| @keyframes cursor-blink { | ||||
|   from, to { border-color: transparent } | ||||
|   50% { border-color: #00FF00 } | ||||
| } | ||||
|  | ||||
| @keyframes glare { | ||||
|   0% { | ||||
|     transform: translateX(-200%); | ||||
|   } | ||||
|   100% { | ||||
|     transform: translateX(200%); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @keyframes horizontal-glare { | ||||
|   from { | ||||
|     transform: translateX(-200%); | ||||
|   } | ||||
|   to { | ||||
|     transform: translateX(200%); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /* Custom scrollbar for the terminal */ | ||||
| ::-webkit-scrollbar { | ||||
|   width: 8px; | ||||
| } | ||||
|  | ||||
| ::-webkit-scrollbar-track { | ||||
|   background: #001100; | ||||
| } | ||||
|  | ||||
| ::-webkit-scrollbar-thumb { | ||||
|   background: #00FF00; | ||||
|   border-radius: 4px; | ||||
| } | ||||
|  | ||||
| ::-webkit-scrollbar-thumb:hover { | ||||
|   background: #00CC00; | ||||
| } | ||||
|  | ||||
| /* Custom Scrollbar */ | ||||
| .custom-scrollbar::-webkit-scrollbar { | ||||
|   width: 8px; | ||||
| } | ||||
|  | ||||
| .custom-scrollbar::-webkit-scrollbar-track { | ||||
|   background: rgba(0, 51, 0, 0.3); | ||||
|   border-radius: 4px; | ||||
| } | ||||
|  | ||||
| .custom-scrollbar::-webkit-scrollbar-thumb { | ||||
|   background: #00FF00; | ||||
|   border-radius: 4px; | ||||
|   opacity: 0.7; | ||||
| } | ||||
|  | ||||
| .custom-scrollbar::-webkit-scrollbar-thumb:hover { | ||||
|   background: #00CC00; | ||||
| } | ||||
							
								
								
									
										10
									
								
								src/main.tsx
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								src/main.tsx
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| import { StrictMode } from 'react'; | ||||
| import { createRoot } from 'react-dom/client'; | ||||
| import App from './App.tsx'; | ||||
| import './index.css'; | ||||
|  | ||||
| createRoot(document.getElementById('root')!).render( | ||||
|   <StrictMode> | ||||
|     <App /> | ||||
|   </StrictMode> | ||||
| ); | ||||
							
								
								
									
										1
									
								
								src/vite-env.d.ts
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										1
									
								
								src/vite-env.d.ts
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1 @@ | ||||
| /// <reference types="vite/client" /> | ||||
		Reference in New Issue
	
	Block a user