├── profiles ├── dsawithaditi │ ├── js │ │ └── main.js │ ├── assets │ │ └── images │ │ │ └── aditi.jpeg │ ├── index.html │ └── css │ │ └── style.css ├── ritwik1709 │ ├── assets │ │ └── 618072.jpg │ ├── index.html │ ├── js │ │ └── main.js │ └── css │ │ └── style.css ├── rumi20 │ ├── assets │ │ └── images │ │ │ └── rumi.jpeg │ ├── js │ │ └── main.js │ ├── index.html │ └── css │ │ └── style.css ├── nusrat80 │ ├── assets │ │ └── images │ │ │ └── nusrat.jpg │ ├── js │ │ └── main.js │ ├── index.html │ └── css │ │ └── style.css ├── withaarzoo │ ├── assets │ │ └── images │ │ │ └── aarzoo.png │ ├── index.html │ ├── js │ │ └── main.js │ └── css │ │ └── style.css ├── rakesh-dev-07 │ ├── assets │ │ └── image │ │ │ └── rakesh.jpeg │ ├── js │ │ └── main.js │ ├── index.html │ └── css │ │ └── style.css └── seobysoumik │ ├── assets │ └── images │ │ └── profile.jpeg │ ├── js │ └── main.js │ ├── index.html │ └── css │ └── style.css ├── contributors.json ├── index.html ├── README.md ├── CONTRIBUTING.md ├── js └── main.js └── css └── style.css /profiles/dsawithaditi/js/main.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /profiles/ritwik1709/assets/618072.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsawithaditi/Hacktoberfest2025/HEAD/profiles/ritwik1709/assets/618072.jpg -------------------------------------------------------------------------------- /profiles/rumi20/assets/images/rumi.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsawithaditi/Hacktoberfest2025/HEAD/profiles/rumi20/assets/images/rumi.jpeg -------------------------------------------------------------------------------- /profiles/nusrat80/assets/images/nusrat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsawithaditi/Hacktoberfest2025/HEAD/profiles/nusrat80/assets/images/nusrat.jpg -------------------------------------------------------------------------------- /profiles/dsawithaditi/assets/images/aditi.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsawithaditi/Hacktoberfest2025/HEAD/profiles/dsawithaditi/assets/images/aditi.jpeg -------------------------------------------------------------------------------- /profiles/withaarzoo/assets/images/aarzoo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsawithaditi/Hacktoberfest2025/HEAD/profiles/withaarzoo/assets/images/aarzoo.png -------------------------------------------------------------------------------- /profiles/rakesh-dev-07/assets/image/rakesh.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsawithaditi/Hacktoberfest2025/HEAD/profiles/rakesh-dev-07/assets/image/rakesh.jpeg -------------------------------------------------------------------------------- /profiles/seobysoumik/assets/images/profile.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsawithaditi/Hacktoberfest2025/HEAD/profiles/seobysoumik/assets/images/profile.jpeg -------------------------------------------------------------------------------- /profiles/rakesh-dev-07/js/main.js: -------------------------------------------------------------------------------- 1 | const card = document.querySelector(".card"); 2 | const maxRotation = 10; 3 | 4 | card.addEventListener("mousemove", (e) => { 5 | const cardRect = card.getBoundingClientRect(); 6 | 7 | const x = e.clientX - cardRect.left - cardRect.width / 2; 8 | const y = e.clientY - cardRect.top - cardRect.height / 2; 9 | 10 | const rotateY = (x / (cardRect.width / 2)) * maxRotation; 11 | const rotateX = -1 * (y / (cardRect.height / 2)) * maxRotation; 12 | 13 | card.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; 14 | }); 15 | 16 | card.addEventListener("mouseleave", () => { 17 | card.style.transform = "rotateX(0deg) rotateY(0deg)"; 18 | }); 19 | -------------------------------------------------------------------------------- /profiles/nusrat80/js/main.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", () => { 2 | const card = document.querySelector(".profile-card"); 3 | 4 | if (card) { 5 | card.addEventListener("mousemove", (e) => { 6 | const cardRect = card.getBoundingClientRect(); 7 | const x = e.clientX - cardRect.left; 8 | const y = e.clientY - cardRect.top; 9 | 10 | const centerX = card.offsetWidth / 2; 11 | const centerY = card.offsetHeight / 2; 12 | 13 | const rotateX = ((y - centerY) / centerY) * -10; 14 | const rotateY = ((x - centerX) / centerX) * 10; 15 | 16 | card.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; 17 | }); 18 | 19 | card.addEventListener("mouseleave", () => { 20 | card.style.transform = "rotateX(0deg) rotateY(0deg)"; 21 | }); 22 | } 23 | }); 24 | -------------------------------------------------------------------------------- /profiles/seobysoumik/js/main.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", () => { 2 | const card = document.querySelector(".profile-card"); 3 | 4 | const maxTilt = 15; 5 | 6 | card.addEventListener("mousemove", (e) => { 7 | const cardRect = card.getBoundingClientRect(); 8 | 9 | const mouseX = e.clientX - cardRect.left - cardRect.width / 2; 10 | const mouseY = e.clientY - cardRect.top - cardRect.height / 2; 11 | 12 | const rotateY = (mouseX / (cardRect.width / 2)) * maxTilt; 13 | const rotateX = -1 * (mouseY / (cardRect.height / 2)) * maxTilt; 14 | 15 | card.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(1.05)`; 16 | card.style.transition = "transform 0.1s linear"; 17 | }); 18 | 19 | card.addEventListener("mouseleave", () => { 20 | card.style.transform = "rotateX(0deg) rotateY(0deg) scale(1)"; 21 | card.style.transition = "transform 0.5s cubic-bezier(0.23, 1, 0.32, 1)"; 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /profiles/rumi20/js/main.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", () => { 2 | const card = document.querySelector(".profile-card"); 3 | 4 | if (card) { 5 | card.addEventListener("mousemove", (e) => { 6 | const { width, height, left, top } = card.getBoundingClientRect(); 7 | const x = e.clientX - left; 8 | const y = e.clientY - top; 9 | const centerX = width / 2; 10 | const centerY = height / 2; 11 | 12 | const rotateX = (y - centerY) / 15; 13 | const rotateY = (centerX - x) / 15; 14 | 15 | card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(1.05)`; 16 | 17 | card.style.setProperty("--shine-x", `${x}px`); 18 | card.style.setProperty("--shine-y", `${y}px`); 19 | }); 20 | 21 | card.addEventListener("mouseleave", () => { 22 | card.style.transform = 23 | "perspective(1000px) rotateX(0) rotateY(0) scale(1)"; 24 | }); 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /profiles/dsawithaditi/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | Aditi - Profile Card 16 | 17 | 18 | 19 |
20 | Profile Picture 21 | 22 |
23 | Aditi Sharma 24 |

Software Engineer

25 |
26 | Follow 27 |
28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /profiles/nusrat80/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | Nusrat Profile Card 13 | 14 | 15 | 16 |
17 |
18 | Profile Picture 19 |

Nusrat Jahan

20 |

Frontend Developer

21 | 25 | View Projects 26 |
27 |
28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /profiles/rakesh-dev-07/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Rakesh | Profile Card 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 | Profile picture of Rakesh 20 |
21 |
22 |

Rakesh Sharma

23 |

Software Engineer

24 | 30 |
31 |
32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /profiles/rakesh-dev-07/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | html { 8 | font-size: 16px; 9 | } 10 | 11 | body { 12 | display: flex; 13 | align-items: center; 14 | justify-content: center; 15 | min-height: 100vh; 16 | background-color: #f0f2f5; 17 | font-family: 'Poppins', sans-serif; 18 | color: #333; 19 | perspective: 1000px; 20 | } 21 | 22 | .card { 23 | width: 320px; 24 | background: #ffffff; 25 | border-radius: 16px; 26 | box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); 27 | overflow: hidden; 28 | text-align: center; 29 | transition: transform 0.4s ease, box-shadow 0.4s ease; 30 | transform-style: preserve-3d; 31 | } 32 | 33 | .card-image img { 34 | width: 100%; 35 | height: auto; 36 | display: block; 37 | } 38 | 39 | .card-content { 40 | padding: 2rem; 41 | } 42 | 43 | .card-name { 44 | font-size: 1.75rem; 45 | font-weight: 600; 46 | color: #2c3e50; 47 | margin-bottom: 0.25rem; 48 | } 49 | 50 | .card-title { 51 | font-size: 1rem; 52 | font-weight: 300; 53 | color: #7f8c8d; 54 | margin-bottom: 1.5rem; 55 | } 56 | 57 | .social-links { 58 | display: flex; 59 | justify-content: center; 60 | gap: 1.5rem; 61 | } 62 | 63 | .social-links a { 64 | color: #95a5a6; 65 | font-size: 1.25rem; 66 | text-decoration: none; 67 | transition: color 0.3s ease, transform 0.3s ease; 68 | } 69 | 70 | .card:hover { 71 | box-shadow: 0 16px 48px rgba(0, 0, 0, 0.15); 72 | } 73 | 74 | .social-links a:hover { 75 | color: #3498db; 76 | transform: translateY(-3px) scale(1.1); 77 | } -------------------------------------------------------------------------------- /profiles/seobysoumik/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Soumik | Profile Card | SEO Specialist 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 | Soumik's Profile Picture 21 |
22 |
23 |

Soumik

24 |

SEO Specialist & Web Developer

25 |

26 | Passionate about ranking websites and crafting beautiful digital experiences. Let's connect and build 27 | something amazing together. 28 |

29 | 35 |
36 | 39 |
40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /profiles/rumi20/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Rumi | Full-Stack Web Developer 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 |
23 |
24 | Profile Picture of Rumi 25 |
26 |
27 |
28 |

Rumi

29 |

Full-Stack Web Developer

30 |

Crafting beautiful and intuitive digital experiences with a passion for clean code and 31 | delightful design.

32 |
33 |
34 | 40 |
41 | 44 |
45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /profiles/withaarzoo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Developer Profile Card 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 |
20 |
21 |
22 | Profile Picture 23 |
24 |
25 |

Aarzoo

26 |

Full-Stack Web Developer

27 |
28 |
29 | React 30 | CSS 31 | JavaScript 32 | Express JS 33 | SQL 34 |
35 | 41 |
42 |
43 |
44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /profiles/nusrat80/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | body { 8 | display: flex; 9 | justify-content: center; 10 | align-items: center; 11 | min-height: 100vh; 12 | background: #f4f7f6; 13 | font-family: "Poppins", sans-serif; 14 | color: #333; 15 | perspective: 1000px; 16 | } 17 | 18 | @keyframes fadeIn { 19 | from { 20 | opacity: 0; 21 | transform: translateY(20px); 22 | } 23 | to { 24 | opacity: 1; 25 | transform: translateY(0); 26 | } 27 | } 28 | 29 | .profile-card { 30 | width: 320px; 31 | background: #ffffff; 32 | border-radius: 20px; 33 | box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); 34 | text-align: center; 35 | padding: 40px 30px; 36 | transition: 37 | transform 0.2s ease-out, 38 | box-shadow 0.2s ease-out; 39 | animation: fadeIn 0.8s ease-out forwards; 40 | transform-style: preserve-3d; 41 | } 42 | 43 | .profile-card:hover { 44 | box-shadow: 0 15px 45px rgba(0, 0, 0, 0.15); 45 | } 46 | 47 | .profile-picture { 48 | width: 120px; 49 | height: 120px; 50 | border-radius: 50%; 51 | object-fit: cover; 52 | border: 4px solid #eceff1; 53 | margin-bottom: 20px; 54 | } 55 | 56 | .name { 57 | font-size: 1.8rem; 58 | font-weight: 600; 59 | color: #2c3e50; 60 | } 61 | 62 | .title { 63 | font-size: 1rem; 64 | font-weight: 300; 65 | color: #7f8c8d; 66 | margin-bottom: 25px; 67 | } 68 | 69 | .social-links { 70 | margin-bottom: 25px; 71 | } 72 | 73 | .social-links a { 74 | color: #3498db; 75 | text-decoration: none; 76 | margin: 0 10px; 77 | font-weight: 400; 78 | transition: color 0.3s ease; 79 | } 80 | 81 | .social-links a:hover { 82 | color: #2980b9; 83 | } 84 | 85 | .projects-button { 86 | display: inline-block; 87 | padding: 12px 30px; 88 | background: #3498db; 89 | color: #fff; 90 | text-decoration: none; 91 | border-radius: 30px; 92 | font-weight: 400; 93 | transition: 94 | background-color 0.3s ease, 95 | transform 0.3s ease; 96 | } 97 | 98 | .projects-button:hover { 99 | background-color: #2980b9; 100 | transform: translateY(-2px); 101 | } 102 | -------------------------------------------------------------------------------- /profiles/withaarzoo/js/main.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", () => { 2 | const cardContainer = document.querySelector(".card-container"); 3 | const card = document.querySelector(".card"); 4 | const glow = document.querySelector(".card-glow"); 5 | 6 | const TILT_AMOUNT = 15; // Max tilt in degrees 7 | 8 | // Function to calculate tilt values 9 | const calculateTilt = (e, element) => { 10 | const rect = element.getBoundingClientRect(); 11 | const x = e.clientX - rect.left; // Mouse X position relative to element 12 | const y = e.clientY - rect.top; // Mouse Y position relative to element 13 | 14 | const width = element.offsetWidth; 15 | const height = element.offsetHeight; 16 | 17 | // Calculate rotation values from -TILT_AMOUNT to +TILT_AMOUNT 18 | const rotateY = (TILT_AMOUNT / (width / 2)) * (x - width / 2); 19 | const rotateX = -(TILT_AMOUNT / (height / 2)) * (y - height / 2); 20 | 21 | return { rotateX, rotateY }; 22 | }; 23 | 24 | // Mouse Move Event on the container 25 | cardContainer.addEventListener("mousemove", (e) => { 26 | const { rotateX, rotateY } = calculateTilt(e, cardContainer); 27 | 28 | // Apply 3D transform to the card 29 | card.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; 30 | 31 | // Move the glow effect 32 | const glowX = 33 | ((e.clientX - card.getBoundingClientRect().left) / card.offsetWidth) * 34 | 100; 35 | const glowY = 36 | ((e.clientY - card.getBoundingClientRect().top) / card.offsetHeight) * 37 | 100; 38 | glow.style.setProperty("--glow-x", `${glowX}%`); 39 | glow.style.setProperty("--glow-y", `${glowY}%`); 40 | 41 | // Update glow position in its ::before pseudo-element 42 | const glowElement = 43 | glow.querySelector("::before") || getComputedStyle(glow, "::before"); 44 | glow.style.top = `${glowY}%`; 45 | glow.style.left = `${glowX}%`; 46 | 47 | // A slightly more direct way to set the glow position using custom properties 48 | glow.style.setProperty( 49 | "left", 50 | `${e.clientX - card.getBoundingClientRect().left}px` 51 | ); 52 | glow.style.setProperty( 53 | "top", 54 | `${e.clientY - card.getBoundingClientRect().top}px` 55 | ); 56 | }); 57 | 58 | // Mouse Leave Event to reset 59 | cardContainer.addEventListener("mouseleave", () => { 60 | card.style.transform = "rotateX(0deg) rotateY(0deg)"; // Reset transform 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /profiles/dsawithaditi/css/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | box-sizing: border-box; 5 | font-family: "Poppins", sans-serif; 6 | } 7 | 8 | body { 9 | background: #FFF5F7; 10 | display: flex; 11 | justify-content: center; 12 | align-items: center; 13 | min-height: 100vh; 14 | padding: 20px; 15 | } 16 | 17 | .card { 18 | width: 350px; 19 | height: 300px; 20 | display: flex; 21 | flex-direction: column; 22 | align-items: center; 23 | justify-content: center; 24 | text-align: center; 25 | gap: 10px; 26 | background-color: #fffffe; 27 | border-radius: 15px; 28 | position: relative; 29 | overflow: hidden; 30 | box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); 31 | } 32 | 33 | .card::before { 34 | content: ""; 35 | width: 350px; 36 | height: 100px; 37 | position: absolute; 38 | top: 0; 39 | border-top-left-radius: 15px; 40 | border-top-right-radius: 15px; 41 | border-bottom: 3px solid #fefefe; 42 | background: linear-gradient(40deg, #ffc0cb, #ff7f9f); 43 | transition: all 0.5s ease; 44 | } 45 | 46 | .card * { 47 | z-index: 1; 48 | } 49 | 50 | .image { 51 | width: 90px; 52 | height: 90px; 53 | border-radius: 50%; /* This makes the image a circle */ 54 | border: 4px solid #fefefe; 55 | margin-top: 30px; 56 | object-fit: cover; /* Added this to prevent image distortion */ 57 | transition: all 0.5s ease; 58 | } 59 | 60 | .card-info { 61 | display: flex; 62 | flex-direction: column; 63 | align-items: center; 64 | gap: 15px; 65 | transition: all 0.5s ease; 66 | } 67 | 68 | .card-info span { 69 | font-weight: 600; 70 | font-size: 24px; 71 | color: #333333; 72 | margin-top: 15px; 73 | line-height: 5px; 74 | } 75 | 76 | .card-info p { 77 | color: rgba(0, 0, 0, 0.5); 78 | } 79 | 80 | .button { 81 | text-decoration: none; 82 | background-color: #ff7f9f; 83 | color: white; 84 | padding: 5px 20px; 85 | border-radius: 5px; 86 | border: 1px solid white; 87 | transition: all 0.5s ease; 88 | } 89 | 90 | .card:hover::before { 91 | width: 350px; 92 | height: 300px; 93 | border-bottom: none; 94 | border-bottom-left-radius: 15px; 95 | border-bottom-right-radius: 15px; 96 | transform: scale(0.95); 97 | } 98 | 99 | .card:hover .card-info { 100 | transform: translate(0%, -25%); 101 | } 102 | 103 | .card:hover .image { 104 | transform: scale(2) translate(-60%, -40%); 105 | } 106 | 107 | .button:hover { 108 | background-color: #E6718E; 109 | transform: scale(1.1); 110 | } -------------------------------------------------------------------------------- /contributors.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Aditi Sharma", 4 | "occupation": "Software Engineer", 5 | "place": "Kolkata, India", 6 | "bio": "Building beautiful things for the web!", 7 | "github_profile_url": "https://github.com/dsawithaditi", 8 | "project_netlify_link": "https://aditi-profile-card.netlify.app/", 9 | "tags": ["minimalist", "animation", "light-theme"] 10 | }, 11 | { 12 | "name": "Md Aarzoo Islam", 13 | "occupation": "Full-Stack Web Developer | Founder of dgisight", 14 | "place": "Beldanga, India", 15 | "bio": "Building beautiful things for the web!", 16 | "github_profile_url": "https://github.com/withaarzoo", 17 | "project_netlify_link": "https://aarzoo-profile-card.netlify.app/", 18 | "tags": ["minimalist", "animation", "dark-theme"] 19 | }, 20 | { 21 | "name": "Nusrat Jahan", 22 | "occupation": "Frontend Web Developer", 23 | "place": "Chennai, India", 24 | "bio": "Frontend developer focused on clean code, pixel-perfect UIs, and seamless user experiences.", 25 | "github_profile_url": "https://github.com/nusrat80", 26 | "project_netlify_link": "https://nusrat-profile-card.netlify.app/", 27 | "tags": ["minimalist", "light-theme"] 28 | }, 29 | { 30 | "name": "Rakesh Sharma", 31 | "occupation": "Frontend Web Developer", 32 | "place": "Delhi, India", 33 | "bio": "As a Software Engineer at Paytm, I'm on a mission to simplify financial services for everyone. I architect and build the technology that brings seamless payments, banking, and commerce to the fingertips of millions, driving true financial inclusion in India.", 34 | "github_profile_url": "https://github.com/rakesh-dev-07", 35 | "project_netlify_link": "https://rakesh-profile-card.netlify.app/", 36 | "tags": ["minimalist", "light-theme"] 37 | }, 38 | { 39 | "name": "Ritwik Tat", 40 | "occupation": "Full Stack Developer", 41 | "place": "Maharashtra", 42 | "bio": "Passionate about crafting seamless web experiences and turning ideas into reality through code.", 43 | "github_profile_url":"https://github.com/ritwik1709", 44 | "project_netlify_link": "https://ritwik-profile-card.netlify.app/", 45 | "tags":["minimalist","animation","dark-theme"] 46 | }, 47 | { 48 | "name": "rumi", 49 | "occupation": "Frontend Web Developer", 50 | "place": "Mumbai, India", 51 | "bio": "passionate about crafting clean code, scalable systems, and intuitive user experiences.", 52 | "github_profile_url": "https://github.com/rumi20", 53 | "project_netlify_link": "https://rumi-profile-card.netlify.app/", 54 | "tags": ["animated", "light-theme"] 55 | }, 56 | { 57 | "name": "Soumik Nandan", 58 | "occupation": "SEO Specialist", 59 | "place": "Beldanga, India", 60 | "bio": "SEO Specialist with 3 years of experience driving organic growth and improving search visibility. Focused on the technical backbone of SEO, data analysis, and content strategy to enhance website performance and user experience.", 61 | "github_profile_url": "https://github.com/seobysoumik", 62 | "project_netlify_link": "https://soumik-profile-card.netlify.app/", 63 | "tags": ["animated", "light-theme"] 64 | } 65 | ] -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Hacktoberfest - Developer Profile Card Showcase 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |
21 | 33 | 34 |
35 |
36 |

The Contributor Gallery

37 |

A showcase of creative developer profile cards from the open-source community. Built 38 | for Hacktoberfest 2025.

39 | Start Contributing Today 41 |
42 |
43 | 44 |
45 |
46 | 47 | 48 |
49 | 50 |
51 |
52 |
53 |
54 |

No contributors found matching your search.

55 |
56 |
57 | 58 | 65 | 66 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /profiles/ritwik1709/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Ritwik1709 - Profile Card 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | Ritwik1709 Profile 17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | 26 |
27 |

Ritwik1709

28 |

Full Stack Developer

29 |

30 | Passionate developer creating amazing web experiences with modern technologies. 31 | Always learning and building something new! 32 |

33 | 34 |
35 | JavaScript 36 | React 37 | Node.js 38 | Express.js 39 | MongoDB 40 | AWS 41 |
42 | 43 |
44 |
45 |
0
46 |
Commits
47 |
48 |
49 |
0
50 |
Contributions
51 |
52 |
53 |
0
54 |
Stars
55 |
56 |
57 |
58 | 59 | 80 |
81 | 82 | 83 |
84 |
85 |
86 |
87 |
88 |
89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /profiles/seobysoumik/css/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --saffron-start: #ff9933; 3 | --saffron-end: #f47a20; 4 | --card-bg: rgba(255, 255, 255, 0.1); 5 | --text-color: #e0e0e0; 6 | --text-dark: #333; 7 | --white-color: #ffffff; 8 | --shadow-color: rgba(0, 0, 0, 0.2); 9 | } 10 | 11 | * { 12 | margin: 0; 13 | padding: 0; 14 | box-sizing: border-box; 15 | } 16 | 17 | body { 18 | font-family: "Poppins", sans-serif; 19 | display: flex; 20 | align-items: center; 21 | justify-content: center; 22 | min-height: 100vh; 23 | background: radial-gradient(circle at top right, var(--saffron-start), var(--saffron-end) 80%); 24 | perspective: 1000px; 25 | overflow: hidden; 26 | } 27 | 28 | .profile-card { 29 | position: relative; 30 | width: 360px; 31 | background: var(--card-bg); 32 | border-radius: 20px; 33 | backdrop-filter: blur(15px); 34 | -webkit-backdrop-filter: blur(15px); 35 | border: 1px solid rgba(255, 255, 255, 0.2); 36 | box-shadow: 0 15px 35px var(--shadow-color); 37 | text-align: center; 38 | padding: 2.5rem; 39 | color: var(--text-color); 40 | transform-style: preserve-3d; 41 | transition: transform 0.1s ease-out; 42 | opacity: 0; 43 | transform: scale(0.9) translateY(20px); 44 | animation: card-entry 0.8s 0.2s cubic-bezier(0.165, 0.84, 0.44, 1) forwards; 45 | } 46 | 47 | .card-border { 48 | position: absolute; 49 | top: -2px; 50 | left: -2px; 51 | right: -2px; 52 | bottom: -2px; 53 | background: linear-gradient(45deg, var(--white-color), var(--saffron-start), var(--white-color)); 54 | background-size: 200% 200%; 55 | border-radius: 22px; 56 | z-index: -1; 57 | animation: shimmer 4s linear infinite; 58 | } 59 | 60 | @keyframes shimmer { 61 | 0% { 62 | background-position: 0% 50%; 63 | } 64 | 50% { 65 | background-position: 100% 50%; 66 | } 67 | 100% { 68 | background-position: 0% 50%; 69 | } 70 | } 71 | 72 | .card-header .profile-img { 73 | width: 140px; 74 | height: 140px; 75 | border-radius: 50%; 76 | border: 4px solid var(--white-color); 77 | box-shadow: 0 5px 15px var(--shadow-color); 78 | margin-bottom: 1.5rem; 79 | object-fit: cover; 80 | } 81 | 82 | .card-body > * { 83 | opacity: 0; 84 | transform: translateY(15px); 85 | animation: content-entry 0.7s cubic-bezier(0.23, 1, 0.32, 1) forwards; 86 | } 87 | 88 | .profile-name { 89 | animation-delay: 0.6s; 90 | } 91 | .profile-title { 92 | animation-delay: 0.7s; 93 | } 94 | .profile-bio { 95 | animation-delay: 0.8s; 96 | } 97 | .social-links { 98 | animation-delay: 0.9s; 99 | } 100 | .card-footer { 101 | animation-delay: 1s; 102 | } 103 | 104 | .profile-name { 105 | font-size: 2.2rem; 106 | font-weight: 700; 107 | color: var(--white-color); 108 | } 109 | 110 | .profile-title { 111 | font-size: 1rem; 112 | font-weight: 300; 113 | margin-bottom: 1rem; 114 | } 115 | 116 | .profile-bio { 117 | font-size: 0.9rem; 118 | font-weight: 400; 119 | line-height: 1.6; 120 | margin-bottom: 2rem; 121 | } 122 | 123 | .social-links { 124 | display: flex; 125 | justify-content: center; 126 | gap: 1.5rem; 127 | margin-bottom: 2rem; 128 | } 129 | 130 | .social-links a { 131 | color: var(--white-color); 132 | font-size: 1.5rem; 133 | transition: 134 | transform 0.3s ease, 135 | color 0.3s ease; 136 | } 137 | 138 | .social-links a:hover { 139 | transform: scale(1.3) translateY(-5px); 140 | color: var(--saffron-start); 141 | } 142 | 143 | .contact-btn { 144 | display: inline-block; 145 | background: linear-gradient(45deg, var(--saffron-start), var(--saffron-end)); 146 | color: var(--text-dark); 147 | padding: 12px 30px; 148 | border-radius: 50px; 149 | text-decoration: none; 150 | font-weight: 600; 151 | box-shadow: 0 5px 15px rgba(244, 122, 32, 0.4); 152 | transition: 153 | transform 0.3s ease, 154 | box-shadow 0.3s ease; 155 | } 156 | 157 | .contact-btn:hover { 158 | transform: scale(1.05); 159 | box-shadow: 0 8px 25px rgba(244, 122, 32, 0.6); 160 | } 161 | 162 | @keyframes card-entry { 163 | to { 164 | opacity: 1; 165 | transform: scale(1) translateY(0); 166 | } 167 | } 168 | 169 | @keyframes content-entry { 170 | to { 171 | opacity: 1; 172 | transform: translateY(0); 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /profiles/withaarzoo/css/style.css: -------------------------------------------------------------------------------- 1 | /* --- Basic Setup & Variables --- */ 2 | :root { 3 | --card-bg: rgba(255, 255, 255, 0.15); 4 | --card-border-color: rgba(255, 255, 255, 0.3); 5 | --text-color: #f0f0f0; 6 | --glow-color: rgb(180, 140, 255); 7 | --primary-font: 'Inter', sans-serif; 8 | } 9 | 10 | * { 11 | margin: 0; 12 | padding: 0; 13 | box-sizing: border-box; 14 | } 15 | 16 | body { 17 | font-family: var(--primary-font); 18 | display: grid; 19 | place-items: center; 20 | min-height: 100vh; 21 | background-color: #101015; 22 | background-image: radial-gradient(circle at 1px 1px, rgba(255,255,255,0.1) 1px, transparent 0); 23 | background-size: 20px 20px; 24 | color: var(--text-color); 25 | } 26 | 27 | /* --- Card Container & Perspective --- */ 28 | .card-container { 29 | perspective: 1000px; 30 | } 31 | 32 | /* --- Main Card Styling --- */ 33 | .card { 34 | width: 340px; 35 | padding: 2rem; 36 | position: relative; 37 | border-radius: 24px; 38 | background: var(--card-bg); 39 | border: 1px solid var(--card-border-color); 40 | backdrop-filter: blur(20px); 41 | -webkit-backdrop-filter: blur(20px); 42 | box-shadow: 0 15px 35px rgba(0, 0, 0, 0.3); 43 | 44 | /* For 3D transform */ 45 | transform-style: preserve-3d; 46 | transition: transform 0.4s ease-out; 47 | } 48 | 49 | /* --- Content Styling --- */ 50 | .card-content { 51 | display: flex; 52 | flex-direction: column; 53 | align-items: center; 54 | gap: 1.5rem; 55 | text-align: center; 56 | /* Move content forward in 3D space */ 57 | transform: translateZ(50px); 58 | } 59 | 60 | /* --- Profile Image --- */ 61 | .profile-image { 62 | width: 140px; 63 | height: 140px; 64 | border-radius: 50%; 65 | overflow: hidden; 66 | border: 3px solid var(--card-border-color); 67 | box-shadow: 0 0 20px rgba(0,0,0,0.5); 68 | animation: fadeInScaleUp 0.6s ease-in-out; 69 | } 70 | 71 | .profile-image img { 72 | width: 100%; 73 | height: 100%; 74 | object-fit: cover; 75 | } 76 | 77 | /* --- Profile Info --- */ 78 | .profile-info { 79 | animation: fadeIn 0.6s ease-in-out 0.2s backwards; 80 | } 81 | 82 | .profile-info h1 { 83 | font-size: 1.75rem; 84 | font-weight: 700; 85 | letter-spacing: 0.5px; 86 | } 87 | 88 | .profile-info p { 89 | font-size: 1rem; 90 | font-weight: 300; 91 | color: rgba(255, 255, 255, 0.7); 92 | margin-top: 0.25rem; 93 | } 94 | 95 | /* --- Skills --- */ 96 | .skills { 97 | display: flex; 98 | flex-wrap: wrap; 99 | justify-content: center; 100 | gap: 0.5rem; 101 | animation: fadeIn 0.6s ease-in-out 0.4s backwards; 102 | } 103 | 104 | .skills span { 105 | background: rgba(255, 255, 255, 0.1); 106 | padding: 0.5rem 1rem; 107 | border-radius: 12px; 108 | font-size: 0.85rem; 109 | font-weight: 500; 110 | } 111 | 112 | /* --- Social Links --- */ 113 | .social-links { 114 | display: flex; 115 | gap: 1.25rem; 116 | animation: fadeIn 0.6s ease-in-out 0.6s backwards; 117 | } 118 | 119 | .social-links a { 120 | color: var(--text-color); 121 | font-size: 1.5rem; 122 | transition: color 0.3s ease, transform 0.3s ease; 123 | } 124 | 125 | .social-links a:hover { 126 | color: var(--glow-color); 127 | transform: scale(1.2) translateY(-3px); 128 | } 129 | 130 | /* --- Glow Effect --- */ 131 | .card-glow { 132 | position: absolute; 133 | top: 0; 134 | left: 0; 135 | width: 100%; 136 | height: 100%; 137 | overflow: hidden; 138 | border-radius: 24px; 139 | pointer-events: none; /* Allows clicks to go through */ 140 | } 141 | 142 | .card-glow::before { 143 | content: ''; 144 | position: absolute; 145 | width: 250px; 146 | height: 250px; 147 | background: radial-gradient(circle, var(--glow-color), transparent 60%); 148 | opacity: 0; 149 | filter: blur(60px); 150 | transform: translate(-50%, -50%); 151 | transition: opacity 0.4s ease-out; 152 | animation: floatGlow 5s ease-in-out infinite; 153 | } 154 | 155 | .card-container:hover .card-glow::before { 156 | opacity: 0.2; 157 | } 158 | 159 | /* --- Keyframe Animations --- */ 160 | @keyframes fadeIn { 161 | from { opacity: 0; transform: translateY(20px); } 162 | to { opacity: 1; transform: translateY(0); } 163 | } 164 | 165 | @keyframes fadeInScaleUp { 166 | from { opacity: 0; transform: scale(0.8); } 167 | to { opacity: 1; transform: scale(1); } 168 | } 169 | 170 | @keyframes floatGlow { 171 | 0%, 100% { transform: translate(-50%, -50%) scale(1); } 172 | 50% { transform: translate(-45%, -55%) scale(1.1); } 173 | } -------------------------------------------------------------------------------- /profiles/rumi20/css/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --primary-color: #ff85a2; 3 | --secondary-color: #a279f7; 4 | --background-start: #f5e0e6; 5 | --background-mid: #d8b4fe; 6 | --background-end: #a7d8e8; 7 | --text-dark: #333; 8 | --text-light: #6a6a6a; 9 | --card-background: rgba(255, 255, 255, 0.6); 10 | --shadow-color: rgba(100, 100, 150, 0.2); 11 | } 12 | 13 | * { 14 | margin: 0; 15 | padding: 0; 16 | box-sizing: border-box; 17 | } 18 | 19 | body { 20 | font-family: 'Poppins', sans-serif; 21 | display: flex; 22 | align-items: center; 23 | justify-content: center; 24 | min-height: 100vh; 25 | background: linear-gradient(135deg, var(--background-start), var(--background-mid), var(--background-end)); 26 | background-size: 400% 400%; 27 | animation: gradientAnimation 15s ease infinite; 28 | overflow: hidden; 29 | } 30 | 31 | @keyframes gradientAnimation { 32 | 0% { background-position: 0% 50%; } 33 | 50% { background-position: 100% 50%; } 34 | 100% { background-position: 0% 50%; } 35 | } 36 | 37 | .profile-card { 38 | position: relative; 39 | width: 340px; 40 | background: var(--card-background); 41 | border-radius: 20px; 42 | padding: 40px 30px; 43 | text-align: center; 44 | box-shadow: 0 10px 30px var(--shadow-color); 45 | backdrop-filter: blur(15px); 46 | -webkit-backdrop-filter: blur(15px); 47 | border: 1px solid rgba(255, 255, 255, 0.3); 48 | transition: transform 0.2s ease-out; 49 | animation: fadeInDown 1s ease-out forwards; 50 | opacity: 0; 51 | overflow: hidden; 52 | } 53 | 54 | @keyframes fadeInDown { 55 | from { 56 | opacity: 0; 57 | transform: translateY(-50px); 58 | } 59 | to { 60 | opacity: 1; 61 | transform: translateY(0); 62 | } 63 | } 64 | 65 | .card-header { 66 | margin-bottom: 20px; 67 | } 68 | 69 | .profile-image-container { 70 | display: inline-block; 71 | padding: 5px; 72 | border-radius: 50%; 73 | background: linear-gradient(45deg, var(--primary-color), var(--secondary-color)); 74 | animation: popIn 0.8s 0.2s ease-out forwards; 75 | transform: scale(0); 76 | } 77 | 78 | .profile-image-container img { 79 | width: 130px; 80 | height: 130px; 81 | border-radius: 50%; 82 | border: 4px solid #fff; 83 | display: block; 84 | transition: transform 0.3s ease; 85 | } 86 | 87 | .profile-image-container:hover img { 88 | transform: scale(1.08) rotate(5deg); 89 | } 90 | 91 | .card-body .name { 92 | font-size: 2em; 93 | font-weight: 600; 94 | color: var(--text-dark); 95 | margin-bottom: 5px; 96 | } 97 | 98 | .card-body .title { 99 | font-size: 1.1em; 100 | font-weight: 400; 101 | color: var(--secondary-color); 102 | margin-bottom: 15px; 103 | } 104 | 105 | .card-body .bio { 106 | font-size: 0.95em; 107 | color: var(--text-light); 108 | line-height: 1.6; 109 | } 110 | 111 | .card-socials { 112 | margin: 25px 0; 113 | } 114 | 115 | .social-links { 116 | display: flex; 117 | justify-content: center; 118 | gap: 15px; 119 | list-style: none; 120 | } 121 | 122 | .social-links li { 123 | animation: popIn 0.5s ease-out forwards; 124 | transform: scale(0); 125 | } 126 | 127 | .social-links li:nth-child(1) { animation-delay: 0.5s; } 128 | .social-links li:nth-child(2) { animation-delay: 0.6s; } 129 | .social-links li:nth-child(3) { animation-delay: 0.7s; } 130 | .social-links li:nth-child(4) { animation-delay: 0.8s; } 131 | 132 | 133 | .social-links a { 134 | color: var(--text-light); 135 | font-size: 1.4em; 136 | transition: color 0.3s ease, transform 0.3s ease; 137 | } 138 | 139 | .social-links a:hover { 140 | color: var(--primary-color); 141 | transform: translateY(-5px); 142 | } 143 | 144 | .card-footer { 145 | margin-top: 20px; 146 | } 147 | 148 | .cta-button { 149 | display: inline-block; 150 | padding: 12px 35px; 151 | border-radius: 50px; 152 | background: linear-gradient(45deg, var(--primary-color), var(--secondary-color)); 153 | color: #fff; 154 | text-decoration: none; 155 | font-weight: 600; 156 | font-size: 1em; 157 | box-shadow: 0 5px 15px rgba(255, 133, 162, 0.4); 158 | transition: transform 0.3s ease, box-shadow 0.3s ease; 159 | animation: popIn 0.8s 0.9s ease-out forwards; 160 | transform: scale(0); 161 | } 162 | 163 | .cta-button:hover { 164 | transform: scale(1.05) translateY(-2px); 165 | box-shadow: 0 8px 20px rgba(162, 121, 247, 0.5); 166 | } 167 | 168 | @keyframes popIn { 169 | to { 170 | transform: scale(1); 171 | } 172 | } 173 | 174 | .shine { 175 | position: absolute; 176 | top: 0; 177 | left: 0; 178 | width: 100%; 179 | height: 100%; 180 | overflow: hidden; 181 | border-radius: 20px; 182 | pointer-events: none; 183 | } 184 | 185 | .shine::before { 186 | content: ''; 187 | position: absolute; 188 | width: 150px; 189 | height: 300%; 190 | background: linear-gradient(rgba(255,255,255,0.5), rgba(255,255,255,0)); 191 | transform: translate(-50%, -50%) rotate(35deg); 192 | top: var(--shine-y, -100%); 193 | left: var(--shine-x, -100%); 194 | transition: top 0.1s ease-out, left 0.1s ease-out; 195 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hacktoberfest 2025 - Developer Profile Card Showcase 2 | 3 | ![Hacktoberfest 2025](https://img.shields.io/badge/Hacktoberfest-2025-orange.svg) 4 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 5 | [![GitHub stars](https://img.shields.io/github/stars/dsawithaditi/Hacktoberfest2025?style=social)](https://github.com/dsawithaditi/Hacktoberfest2025/stargazers) 6 | [![GitHub forks](https://img.shields.io/github/forks/dsawithaditi/Hacktoberfest2025?style=social)](https://github.com/dsawithaditi/Hacktoberfest2025/network/members) 7 | 8 | Welcome to the **Developer Profile Card Showcase** for Hacktoberfest 2025! 🎉 This repository is a creative space for you to design and share your own unique developer profile card using HTML and CSS. It's a perfect project for everyone, especially those new to open source. The goal is to create a beautiful, collaborative gallery of developer profiles from around the world. 9 | 10 | ### ✨ **[Click Here to See Our Amazing Contributors' Profile Cards!](https://dsawithaditi.github.io/Hacktoberfest2025/)** ✨ 11 | 12 | ## How to Contribute 13 | 14 | Contributing to this project is a simple, three-step process. Follow these instructions carefully to get your pull request merged and count towards your Hacktoberfest goals! 15 | 16 | --- 17 | 18 | ### **Step 1: Create Your Profile Card Locally** 19 | 20 | 1. **Fork the Repository** 21 | - Click the "Fork" button at the top right of this page to create your own copy of this project. 22 | 23 | 2. **Clone Your Fork** 24 | - Clone your forked repository to your local machine. Replace `YOUR_USERNAME` with your GitHub username. 25 | ```bash 26 | git clone [https://github.com/YOUR_USERNAME/Hacktoberfest2025.git](https://github.com/YOUR_USERNAME/Hacktoberfest2025.git) 27 | cd Hacktoberfest2025 28 | ``` 29 | 30 | 3. **Create Your Folder** 31 | - Navigate to the `profiles` directory. 32 | - Inside this folder, create a **new folder named with your GitHub username**. (e.g., `profiles/dsawithaditi`). This is where all your files will go. 33 | 34 | 4. **Set Up the File Structure** 35 | - Inside your `[your_username]` folder, create the following file structure: 36 | ``` 37 | your_username/ 38 | ├── assets/ 39 | │ └── images/ 40 | ├── css/ 41 | │ └── style.css 42 | ├── js/ 43 | │ └── main.js (Optional: for animations) 44 | └── index.html 45 | ``` 46 | 47 | 5. **Build Your Profile Card** 48 | - Now, get creative! Code your unique developer profile card within the files you just created. Make it your own—add your picture, links, skills, and style. Make sure it's a self-contained project that runs from your `index.html`. 49 | 50 | --- 51 | 52 | ### **Step 2: Deploy Your Profile Card to Netlify** 53 | 54 | To showcase your work, you need to deploy **only your profile card's folder** to Netlify for a live preview. 55 | 56 | 1. **Log in to Netlify:** 57 | - Go to [netlify.com](https://www.netlify.com/) and log in or sign up. 58 | 59 | 2. **Deploy Manually:** 60 | - From your Netlify dashboard, click on **"Add new site"** and select **"Deploy manually"**. 61 | - Drag and drop your **username folder** (e.g., the `dsawithaditi` folder, not the entire `Hacktoberfest2025` project) into the upload area. 62 | 63 | 3. **Configure Your Site:** 64 | - Once uploaded, go to the site settings. Click **"Change site name"** and give your project a unique name. 65 | - Copy the live URL of your project (e.g., `aditi-profile-card.netlify.app`). 66 | 67 | --- 68 | 69 | ### **Step 3: Add Your Details and Create a Pull Request** 70 | 71 | 1. **Update `contributors.json`:** 72 | - Open the `contributors.json` file in the root of the main project. 73 | - Add a new JSON object with your details at the end of the list. 74 | - **Add a `tags` array** to help categorize your card. Please add 3-4 relevant tags that describe your design's style or features. 75 | 76 | **Example format:** 77 | ```json 78 | { 79 | "name": "Aditi", 80 | "occupation": "Full-Stack Developer", 81 | "place": "Delhi, India", 82 | "bio": "Building beautiful things for the web!", 83 | "github_profile_url": "[https://github.com/dsawithaditi](https://github.com/dsawithaditi)", 84 | "project_netlify_link": "[https://aditi-profile-card.netlify.app](https://aditi-profile-card.netlify.app)", 85 | "tags": ["minimalist", "animation", "dark-theme"] 86 | } 87 | ``` 88 | > **Good tag examples:** `minimalist`, `retro`, `glassmorphism`, `neumorphism`, `dark-theme`, `light-theme`, `animation`, `interactive`. 89 | 90 | 91 | 2. **Commit and Push Your Changes:** 92 | - Add your changes to git and push them to your forked repository. 93 | ```bash 94 | git add . 95 | git commit -m "feat: Add profile card for dsawithaditi" 96 | git push origin main 97 | ``` 98 | 99 | 3. **Open a Pull Request:** 100 | - Go to your forked repository on GitHub and click the **"Contribute"** button, then **"Open pull request"**. 101 | - Provide a clear title and description for your pull request. 102 | - Wait for your PR to be reviewed and merged. 103 | 104 | ## Contribution Guidelines 105 | 106 | - Please do not create spam or low-effort pull requests. 107 | - Ensure your profile card is your own original work. 108 | - Your card should be responsive and work on different screen sizes. 109 | - Follow the prescribed folder and file structure. 110 | 111 | ## Our Amazing Contributors 112 | 113 | A huge thank you to all the wonderful people who have contributed to this project! This section will automatically update as we merge new pull requests. 114 | 115 | [![Contributors](https://contrib.rocks/image?repo=dsawithaditi/Hacktoberfest2025)](https://github.com/dsawithaditi/Hacktoberfest2025/graphs/contributors) 116 | 117 | ## License 118 | 119 | This project is licensed under the **MIT License**. See the `LICENSE` file for details. 120 | 121 | Thank you for your contribution! **Happy Hacking!** 🚀 -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to the Developer Profile Card Showcase ✨ 2 | 3 | First off, a huge thank you for considering contributing! We're thrilled you're here. This project is a celebration of open source and creativity, especially for those participating in **Hacktoberfest 2025**. 4 | 5 | This document provides all the guidelines you need to contribute effectively. Let's build something amazing together! 🚀 6 | 7 | ## 📜 Code of Conduct 8 | 9 | We are committed to providing a welcoming and inclusive experience for everyone. We do not tolerate harassment of participants in any form. By participating in this project, you agree to abide by our **Code of Conduct**. Please be respectful and considerate in all your interactions. 10 | 11 | ## 🤔 How to Contribute 12 | 13 | We've designed a straightforward, three-step process to make contributing as easy as possible. 14 | 15 | --- 16 | 17 | ### **Step 1: Create Your Profile Card Locally** 18 | 19 | 1. **Fork the Repository** 20 | - Click the "Fork" button at the top-right corner of this page to create your personal copy. 21 | 22 | 2. **Clone Your Fork** 23 | - Clone the repository to your local machine using git. 24 | ```bash 25 | git clone [https://github.com/YOUR_USERNAME/Hacktoberfest2025.git](https://github.com/YOUR_USERNAME/Hacktoberfest2025.git) 26 | cd Hacktoberfest2025 27 | ``` 28 | 29 | 3. **Create Your Folder** 30 | - Navigate to the `profiles` directory. 31 | - Inside this folder, create a **new folder named with your GitHub username**. (e.g., `profiles/dsawithaditi`). This is where all your files will go. 32 | 33 | 4. **Set Up the File Structure** 34 | - Inside your `[your_username]` folder, you **must** create the following file structure. This is essential for your project to be displayed correctly. 35 | ``` 36 | your_username/ 37 | ├── assets/ 38 | │ └── images/ (for any images you use) 39 | ├── css/ 40 | │ └── style.css 41 | ├── js/ 42 | │ └── main.js (Optional: for animations) 43 | └── index.html 44 | ``` 45 | 46 | 5. **Build Your Profile Card** 47 | - Get creative! Code your unique developer profile card within the files you just created. Ensure it's a self-contained project that runs perfectly from its own `index.html`. 48 | 49 | --- 50 | 51 | ### **Step 2: Deploy Your Profile Card to Netlify** 52 | 53 | To showcase a live version of your work, you need to deploy **only your profile card's folder** to Netlify. 54 | 55 | 1. **Log in to Netlify:** 56 | - Go to [netlify.com](https://www.netlify.com/) and log in or sign up (it's free!). 57 | 58 | 2. **Deploy Manually:** 59 | - From your Netlify dashboard, go to the "Sites" tab, click on **"Add new site"**, and select **"Deploy manually"**. 60 | - Drag and drop your **personal username folder** (e.g., the `dsawithaditi` folder from `profiles/`) into the upload area. 61 | 62 | 3. **Get Your Live URL:** 63 | - Once uploaded, Netlify will give you a live URL. You can customize the site name in **Site settings** to make it more memorable. 64 | - Copy this URL (e.g., `aditi-profile-card.netlify.app`). You'll need it for the next step. 65 | 66 | --- 67 | 68 | ### **Step 3: Add Your Details & Create a Pull Request** 69 | 70 | 1. **Update `contributors.json`** 71 | - In the root of the project, open the `contributors.json` file. 72 | - Add a new JSON object with your details at the end of the list. 73 | - **Add a `tags` array** to help categorize your card. Please add 3-4 relevant tags that describe your design's style or features. 74 | 75 | **Example format:** 76 | ```json 77 | { 78 | "name": "Aditi", 79 | "occupation": "Full-Stack Developer", 80 | "place": "Delhi, India", 81 | "bio": "Building beautiful things for the web!", 82 | "github_profile_url": "[https://github.com/dsawithaditi](https://github.com/dsawithaditi)", 83 | "project_netlify_link": "[https://aditi-profile-card.netlify.app](https://aditi-profile-card.netlify.app)", 84 | "tags": ["minimalist", "animation", "dark-theme"] 85 | } 86 | ``` 87 | > **Good tag examples:** `minimalist`, `retro`, `glassmorphism`, `neumorphism`, `dark-theme`, `light-theme`, `animation`, `interactive`. 88 | 89 | 2. **Commit and Push Your Changes** 90 | - Stage your changes, commit them with a descriptive message, and push them to your forked repository. 91 | ```bash 92 | git add . 93 | git commit -m "feat: Add profile card for YourUsername" 94 | git push origin main 95 | ``` 96 | 97 | 3. **Open a Pull Request** 98 | - Go to your forked repository on GitHub. Click the **"Contribute"** button, then **"Open pull request"**. 99 | - Provide a clear title and a brief description of the profile card you've added. 100 | - Our team will review your PR. Once it's approved and merged, your card will appear in the gallery! 101 | 102 | ## ✅ Contribution Guidelines 103 | 104 | To ensure a high-quality showcase and a positive experience for everyone, please adhere to the following rules: 105 | 106 | - **Original Work:** Your component must be your own original work. 107 | - **Responsive Design:** Please ensure your component is responsive and looks good on different screen sizes. 108 | - **Follow the Structure:** Submissions that do not follow the prescribed folder and file structure will not be accepted. 109 | - **One Component Per PR:** Please submit only one profile card per pull request to keep reviews manageable. 110 | 111 | ## 🎃 Hacktoberfest 2025 Rules 112 | 113 | This project proudly participates in Hacktoberfest. For your PR to count towards your Hacktoberfest goals, you must follow these official rules: 114 | 115 | - Your pull requests must be submitted between **October 1 and October 31, 2025**. 116 | - Your PR must be merged by a maintainer or labeled as **"hacktoberfest-accepted"** to be considered valid. 117 | - **Do Not Submit Spam or Low-Quality PRs**. This includes but is not limited to: 118 | - Automated PRs for fixing typos or whitespace. 119 | - Disruptive pull requests that take someone else's work. 120 | - Anything that goes against Hacktoberfest's values. 121 | - Contributors with **2 or more PRs marked as spam will be disqualified** from participating in Hacktoberfest. 122 | 123 | We look forward to seeing your amazing creations. **Happy Hacking!** 🎉 -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", () => { 2 | // --- DOM Elements --- 3 | const container = document.getElementById("contributors-container"); 4 | const loader = document.getElementById("loader"); 5 | const sentinel = document.getElementById("sentinel"); 6 | const searchInput = document.getElementById("search-input"); 7 | const noResultsMsg = document.getElementById("no-results"); 8 | 9 | // Detail Modal Elements 10 | const detailModal = document.getElementById("modal"); 11 | const detailModalCloseBtn = document.getElementById("modal-close"); 12 | const detailModalIframeContainer = document.getElementById( 13 | "modal-iframe-container" 14 | ); 15 | const detailModalInfo = document.getElementById("modal-info"); 16 | 17 | // Preview Modal Elements 18 | const previewModal = document.getElementById("preview-modal"); 19 | const previewModalCloseBtn = document.getElementById("preview-modal-close"); 20 | const deviceControls = document.getElementById("device-controls"); 21 | const previewIframeContainer = document.getElementById( 22 | "preview-iframe-container" 23 | ); 24 | const previewIframe = document.getElementById("preview-iframe"); 25 | const previewCta = document.getElementById("preview-cta"); 26 | 27 | // --- State Variables --- 28 | let allContributors = []; 29 | let displayedContributors = []; 30 | let displayedCount = 0; 31 | const batchSize = 12; 32 | let isLoading = false; 33 | 34 | /** 35 | * Creates a single profile card element with the new "View Project" button. 36 | */ 37 | function createProfileCard(contributor) { 38 | const card = document.createElement("div"); 39 | card.className = "contributor-card"; 40 | card.dataset.contributorData = JSON.stringify(contributor); 41 | 42 | const tagsHTML = (contributor.tags || []) 43 | .map((tag) => `${tag}`) 44 | .join(""); 45 | 46 | card.innerHTML = ` 47 |
48 |
49 | 50 |
51 | 62 | `; 63 | return card; 64 | } 65 | 66 | // --- Card Creation & Display Logic (Largely unchanged) --- 67 | function loadCardIframe(card) { 68 | /* ... same as before ... */ 69 | } 70 | function displayNextBatch() { 71 | /* ... same as before ... */ 72 | } 73 | function filterContributors() { 74 | /* ... same as before ... */ 75 | } 76 | 77 | // --- NEW: Device Preview Modal Logic --- 78 | function openPreviewModal(contributor) { 79 | previewIframe.src = contributor.project_netlify_link; 80 | previewCta.href = contributor.project_netlify_link; 81 | previewModal.classList.add("visible"); 82 | } 83 | 84 | function closePreviewModal() { 85 | previewModal.classList.remove("visible"); 86 | previewIframe.src = "about:blank"; // Clear iframe to stop loading 87 | } 88 | 89 | function setPreviewSize(device) { 90 | // Update active button 91 | deviceControls.querySelector(".active").classList.remove("active"); 92 | deviceControls 93 | .querySelector(`[data-device="${device}"]`) 94 | .classList.add("active"); 95 | 96 | // Update iframe container class 97 | previewIframeContainer.className = "preview-iframe-container"; // Reset classes 98 | previewIframeContainer.classList.add(`view-${device}`); 99 | } 100 | 101 | // --- Main Initialization --- 102 | async function initialize() { 103 | /* ... same as before ... */ 104 | } 105 | 106 | // --- Event Delegation for Card Buttons --- 107 | container.addEventListener("click", (e) => { 108 | const card = e.target.closest(".contributor-card"); 109 | if (!card) return; 110 | 111 | const contributor = JSON.parse(card.dataset.contributorData); 112 | 113 | if (e.target.closest(".card-iframe-wrapper")) { 114 | openDetailModal(contributor); 115 | } else if (e.target.closest(".view-project-btn")) { 116 | openPreviewModal(contributor); 117 | } 118 | }); 119 | 120 | // --- Other Event Listeners --- 121 | searchInput.addEventListener("input", filterContributors); 122 | 123 | // Detail Modal 124 | detailModalCloseBtn.addEventListener("click", closeDetailModal); 125 | detailModal.addEventListener("click", (e) => { 126 | if (e.target === detailModal) closeDetailModal(); 127 | }); 128 | 129 | // Preview Modal 130 | previewModalCloseBtn.addEventListener("click", closePreviewModal); 131 | previewModal.addEventListener("click", (e) => { 132 | if (e.target === previewModal) closePreviewModal(); 133 | }); 134 | deviceControls.addEventListener("click", (e) => { 135 | const button = e.target.closest("button"); 136 | if (button && button.dataset.device) { 137 | setPreviewSize(button.dataset.device); 138 | } 139 | }); 140 | 141 | // --- All Function Definitions (including unchanged ones for completeness) --- 142 | 143 | // Detail Modal Functions (renamed for clarity) 144 | function openDetailModal(contributor) { 145 | detailModalIframeContainer.innerHTML = ``; 146 | detailModalInfo.innerHTML = `

${contributor.name}

${contributor.bio}

View on GitHub `; 147 | detailModal.classList.add("visible"); 148 | } 149 | function closeDetailModal() { 150 | detailModal.classList.remove("visible"); 151 | detailModalIframeContainer.innerHTML = ""; 152 | detailModalInfo.innerHTML = ""; 153 | } 154 | 155 | // Unchanged Functions 156 | function loadCardIframe(card) { 157 | const iframe = card.querySelector("iframe"); 158 | if (iframe && !iframe.src) { 159 | const contributor = JSON.parse(card.dataset.contributorData); 160 | iframe.src = contributor.project_netlify_link; 161 | iframe.onload = () => { 162 | iframe.classList.add("loaded"); 163 | card.querySelector(".skeleton").style.display = "none"; 164 | }; 165 | } 166 | } 167 | function displayNextBatch() { 168 | if (isLoading || displayedCount >= displayedContributors.length) return; 169 | isLoading = true; 170 | loader.classList.add("visible"); 171 | const batch = displayedContributors.slice( 172 | displayedCount, 173 | displayedCount + batchSize 174 | ); 175 | setTimeout(() => { 176 | batch.forEach((contributor) => { 177 | const card = createProfileCard(contributor); 178 | container.appendChild(card); 179 | cardObserver.observe(card); 180 | }); 181 | displayedCount += batch.length; 182 | isLoading = false; 183 | loader.classList.remove("visible"); 184 | if (displayedCount >= displayedContributors.length) { 185 | sentinel.style.display = "none"; 186 | } 187 | }, 300); 188 | } 189 | function filterContributors() { 190 | const searchTerm = searchInput.value.toLowerCase().trim(); 191 | displayedContributors = allContributors.filter((c) => { 192 | const tags = (c.tags || []).join(",").toLowerCase(); 193 | return ( 194 | c.name.toLowerCase().includes(searchTerm) || 195 | c.bio.toLowerCase().includes(searchTerm) || 196 | tags.includes(searchTerm) 197 | ); 198 | }); 199 | container.innerHTML = ""; 200 | displayedCount = 0; 201 | noResultsMsg.style.display = 202 | displayedContributors.length === 0 ? "block" : "none"; 203 | sentinel.style.display = "block"; 204 | displayNextBatch(); 205 | } 206 | async function initialize() { 207 | try { 208 | const response = await fetch("contributors.json"); 209 | if (!response.ok) throw new Error("contributors.json not found."); 210 | let data = await response.json(); 211 | if (Array.isArray(data)) { 212 | allContributors = data; 213 | } else { 214 | console.error("Data from contributors.json is not a valid array."); 215 | allContributors = []; 216 | } 217 | displayedContributors = [...allContributors]; 218 | const intersectionObserver = new IntersectionObserver((entries) => { 219 | if (entries[0].isIntersecting && !isLoading) { 220 | displayNextBatch(); 221 | } 222 | }); 223 | intersectionObserver.observe(sentinel); 224 | displayNextBatch(); 225 | } catch (error) { 226 | console.error("Failed to load or parse contributors.json:", error); 227 | container.innerHTML = `

Could not load contributor data.

`; 228 | } 229 | } 230 | const cardObserver = new IntersectionObserver( 231 | (entries, observer) => { 232 | entries.forEach((entry) => { 233 | if (entry.isIntersecting) { 234 | loadCardIframe(entry.target); 235 | observer.unobserve(entry.target); 236 | } 237 | }); 238 | }, 239 | { rootMargin: "200px" } 240 | ); 241 | 242 | initialize(); 243 | }); 244 | -------------------------------------------------------------------------------- /profiles/ritwik1709/js/main.js: -------------------------------------------------------------------------------- 1 | // DOM Elements 2 | const profileCard = document.querySelector('.profile-card'); 3 | const contactBtn = document.querySelector('.contact-btn'); 4 | const socialLinks = document.querySelectorAll('.social-link'); 5 | const skillTags = document.querySelectorAll('.skill-tag'); 6 | const statNumbers = document.querySelectorAll('.stat-number'); 7 | const profileImage = document.querySelector('.profile-image'); 8 | 9 | // Initialize animations when page loads 10 | document.addEventListener('DOMContentLoaded', function() { 11 | initializeAnimations(); 12 | setupEventListeners(); 13 | animateStats(); 14 | setupParallaxEffect(); 15 | }); 16 | 17 | // Initialize all animations 18 | function initializeAnimations() { 19 | // Add staggered animation to skill tags 20 | skillTags.forEach((tag, index) => { 21 | tag.style.animationDelay = `${0.1 * index}s`; 22 | tag.style.animation = 'fadeInUp 0.6s ease-out forwards'; 23 | }); 24 | 25 | // Add hover effect to profile image 26 | profileImage.addEventListener('mouseenter', function() { 27 | this.style.transform = 'scale(1.05) rotate(5deg)'; 28 | }); 29 | 30 | profileImage.addEventListener('mouseleave', function() { 31 | this.style.transform = 'scale(1) rotate(0deg)'; 32 | }); 33 | } 34 | 35 | // Setup event listeners for interactive elements 36 | function setupEventListeners() { 37 | // Contact button interaction 38 | contactBtn.addEventListener('click', function(e) { 39 | e.preventDefault(); 40 | createRippleEffect(e); 41 | showContactModal(); 42 | }); 43 | 44 | // Social links interaction 45 | socialLinks.forEach(link => { 46 | link.addEventListener('click', function(e) { 47 | e.preventDefault(); 48 | createClickAnimation(this); 49 | }); 50 | }); 51 | 52 | // Skill tags hover effect 53 | skillTags.forEach(tag => { 54 | tag.addEventListener('mouseenter', function() { 55 | this.style.transform = 'translateY(-3px) scale(1.05)'; 56 | this.style.boxShadow = '0 8px 25px rgba(102, 126, 234, 0.3)'; 57 | }); 58 | 59 | tag.addEventListener('mouseleave', function() { 60 | this.style.transform = 'translateY(0) scale(1)'; 61 | this.style.boxShadow = 'none'; 62 | }); 63 | }); 64 | 65 | // Card tilt effect 66 | setupCardTiltEffect(); 67 | } 68 | 69 | // Create ripple effect for buttons 70 | function createRippleEffect(event) { 71 | const button = event.currentTarget; 72 | const ripple = document.createElement('span'); 73 | const rect = button.getBoundingClientRect(); 74 | const size = Math.max(rect.width, rect.height); 75 | const x = event.clientX - rect.left - size / 2; 76 | const y = event.clientY - rect.top - size / 2; 77 | 78 | ripple.style.width = ripple.style.height = size + 'px'; 79 | ripple.style.left = x + 'px'; 80 | ripple.style.top = y + 'px'; 81 | ripple.classList.add('ripple'); 82 | 83 | // Add ripple styles 84 | ripple.style.position = 'absolute'; 85 | ripple.style.borderRadius = '50%'; 86 | ripple.style.background = 'rgba(255, 255, 255, 0.6)'; 87 | ripple.style.transform = 'scale(0)'; 88 | ripple.style.animation = 'ripple 0.6s linear'; 89 | ripple.style.pointerEvents = 'none'; 90 | 91 | button.style.position = 'relative'; 92 | button.style.overflow = 'hidden'; 93 | button.appendChild(ripple); 94 | 95 | // Remove ripple after animation 96 | setTimeout(() => { 97 | ripple.remove(); 98 | }, 600); 99 | } 100 | 101 | // Create click animation for social links 102 | function createClickAnimation(element) { 103 | element.style.transform = 'scale(0.9)'; 104 | setTimeout(() => { 105 | element.style.transform = 'scale(1)'; 106 | }, 150); 107 | } 108 | 109 | // Animate statistics numbers 110 | function animateStats() { 111 | const observer = new IntersectionObserver((entries) => { 112 | entries.forEach(entry => { 113 | if (entry.isIntersecting) { 114 | const target = entry.target; 115 | const targetValue = parseInt(target.getAttribute('data-target')); 116 | animateNumber(target, targetValue); 117 | observer.unobserve(target); 118 | } 119 | }); 120 | }); 121 | 122 | statNumbers.forEach(number => { 123 | observer.observe(number); 124 | }); 125 | } 126 | 127 | // Animate number counting 128 | function animateNumber(element, target) { 129 | const duration = 2000; 130 | const start = performance.now(); 131 | const startValue = 0; 132 | 133 | function updateNumber(currentTime) { 134 | const elapsed = currentTime - start; 135 | const progress = Math.min(elapsed / duration, 1); 136 | 137 | // Easing function for smooth animation 138 | const easeOutQuart = 1 - Math.pow(1 - progress, 4); 139 | const currentValue = Math.floor(startValue + (target - startValue) * easeOutQuart); 140 | 141 | element.textContent = currentValue; 142 | 143 | if (progress < 1) { 144 | requestAnimationFrame(updateNumber); 145 | } else { 146 | element.textContent = target; 147 | } 148 | } 149 | 150 | requestAnimationFrame(updateNumber); 151 | } 152 | 153 | // Setup card tilt effect 154 | function setupCardTiltEffect() { 155 | let isTilted = false; 156 | 157 | profileCard.addEventListener('mousemove', function(e) { 158 | if (isTilted) return; 159 | 160 | const rect = this.getBoundingClientRect(); 161 | const centerX = rect.left + rect.width / 2; 162 | const centerY = rect.top + rect.height / 2; 163 | const mouseX = e.clientX - centerX; 164 | const mouseY = e.clientY - centerY; 165 | 166 | const rotateX = (mouseY / rect.height) * -10; 167 | const rotateY = (mouseX / rect.width) * 10; 168 | 169 | this.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) translateZ(10px)`; 170 | }); 171 | 172 | profileCard.addEventListener('mouseleave', function() { 173 | this.style.transform = 'perspective(1000px) rotateX(0deg) rotateY(0deg) translateZ(0px)'; 174 | isTilted = false; 175 | }); 176 | } 177 | 178 | // Setup parallax effect for background elements 179 | function setupParallaxEffect() { 180 | const bgElements = document.querySelectorAll('.bg-circle'); 181 | 182 | window.addEventListener('mousemove', function(e) { 183 | const mouseX = e.clientX / window.innerWidth; 184 | const mouseY = e.clientY / window.innerHeight; 185 | 186 | bgElements.forEach((element, index) => { 187 | const speed = (index + 1) * 0.5; 188 | const x = (mouseX - 0.5) * speed * 20; 189 | const y = (mouseY - 0.5) * speed * 20; 190 | 191 | element.style.transform = `translate(${x}px, ${y}px)`; 192 | }); 193 | }); 194 | } 195 | 196 | // Show contact modal (placeholder function) 197 | function showContactModal() { 198 | // Create a simple alert for now - can be replaced with actual modal 199 | const modal = document.createElement('div'); 200 | modal.style.cssText = ` 201 | position: fixed; 202 | top: 0; 203 | left: 0; 204 | width: 100%; 205 | height: 100%; 206 | background: rgba(0, 0, 0, 0.8); 207 | display: flex; 208 | align-items: center; 209 | justify-content: center; 210 | z-index: 1000; 211 | animation: fadeIn 0.3s ease-out; 212 | `; 213 | 214 | const modalContent = document.createElement('div'); 215 | modalContent.style.cssText = ` 216 | background: white; 217 | padding: 40px; 218 | border-radius: 20px; 219 | text-align: center; 220 | max-width: 400px; 221 | margin: 20px; 222 | animation: slideUp 0.3s ease-out; 223 | `; 224 | 225 | modalContent.innerHTML = ` 226 |

Get in Touch!

227 |

Thanks for your interest! You can reach me through the social links above.

228 | 237 | `; 238 | 239 | modal.appendChild(modalContent); 240 | document.body.appendChild(modal); 241 | 242 | // Close modal when clicking outside 243 | modal.addEventListener('click', function(e) { 244 | if (e.target === modal) { 245 | modal.remove(); 246 | } 247 | }); 248 | } 249 | 250 | // Add CSS animations dynamically 251 | const style = document.createElement('style'); 252 | style.textContent = ` 253 | @keyframes ripple { 254 | to { 255 | transform: scale(4); 256 | opacity: 0; 257 | } 258 | } 259 | 260 | @keyframes fadeIn { 261 | from { opacity: 0; } 262 | to { opacity: 1; } 263 | } 264 | 265 | .profile-card { 266 | transition: transform 0.3s ease; 267 | } 268 | 269 | .skill-tag { 270 | transition: all 0.3s ease; 271 | } 272 | `; 273 | document.head.appendChild(style); 274 | 275 | // Add loading animation 276 | window.addEventListener('load', function() { 277 | document.body.style.opacity = '0'; 278 | document.body.style.transition = 'opacity 0.5s ease-in-out'; 279 | 280 | setTimeout(() => { 281 | document.body.style.opacity = '1'; 282 | }, 100); 283 | }); 284 | 285 | // Add scroll animations 286 | const observerOptions = { 287 | threshold: 0.1, 288 | rootMargin: '0px 0px -50px 0px' 289 | }; 290 | 291 | const observer = new IntersectionObserver((entries) => { 292 | entries.forEach(entry => { 293 | if (entry.isIntersecting) { 294 | entry.target.style.opacity = '1'; 295 | entry.target.style.transform = 'translateY(0)'; 296 | } 297 | }); 298 | }, observerOptions); 299 | 300 | // Observe elements for scroll animations 301 | document.addEventListener('DOMContentLoaded', function() { 302 | const animatedElements = document.querySelectorAll('.profile-name, .profile-title, .profile-description, .skills-container, .stats-container, .social-links, .contact-btn'); 303 | 304 | animatedElements.forEach(element => { 305 | element.style.opacity = '0'; 306 | element.style.transform = 'translateY(20px)'; 307 | element.style.transition = 'opacity 0.6s ease-out, transform 0.6s ease-out'; 308 | observer.observe(element); 309 | }); 310 | }); 311 | -------------------------------------------------------------------------------- /profiles/ritwik1709/css/style.css: -------------------------------------------------------------------------------- 1 | /* Reset and base styles */ 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | } 7 | 8 | body { 9 | font-family: 'Inter', sans-serif; 10 | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 11 | min-height: 100vh; 12 | display: flex; 13 | align-items: center; 14 | justify-content: center; 15 | overflow-x: hidden; 16 | position: relative; 17 | } 18 | 19 | .container { 20 | position: relative; 21 | z-index: 2; 22 | padding: 20px; 23 | width: 100%; 24 | max-width: 400px; 25 | } 26 | 27 | /* Profile Card */ 28 | .profile-card { 29 | background: rgba(255, 255, 255, 0.95); 30 | backdrop-filter: blur(20px); 31 | border-radius: 24px; 32 | box-shadow: 33 | 0 20px 40px rgba(0, 0, 0, 0.1), 34 | 0 0 0 1px rgba(255, 255, 255, 0.2); 35 | overflow: hidden; 36 | position: relative; 37 | animation: slideUp 0.8s ease-out; 38 | transition: transform 0.3s ease, box-shadow 0.3s ease; 39 | } 40 | 41 | .profile-card:hover { 42 | transform: translateY(-10px); 43 | box-shadow: 44 | 0 30px 60px rgba(0, 0, 0, 0.15), 45 | 0 0 0 1px rgba(255, 255, 255, 0.3); 46 | } 47 | 48 | /* Card Header */ 49 | .card-header { 50 | position: relative; 51 | padding: 40px 30px 20px; 52 | text-align: center; 53 | background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); 54 | overflow: hidden; 55 | } 56 | 57 | .profile-image-container { 58 | position: relative; 59 | display: inline-block; 60 | margin-bottom: 20px; 61 | } 62 | 63 | .profile-image { 64 | width: 120px; 65 | height: 120px; 66 | border-radius: 50%; 67 | object-fit: cover; 68 | border: 4px solid rgba(255, 255, 255, 0.9); 69 | box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); 70 | transition: transform 0.3s ease, box-shadow 0.3s ease; 71 | animation: imageFloat 3s ease-in-out infinite; 72 | } 73 | 74 | .profile-image:hover { 75 | transform: scale(1.05); 76 | box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3); 77 | } 78 | 79 | .status-indicator { 80 | position: absolute; 81 | bottom: 10px; 82 | right: 10px; 83 | width: 20px; 84 | height: 20px; 85 | background: #4ade80; 86 | border: 3px solid white; 87 | border-radius: 50%; 88 | animation: pulse 2s infinite; 89 | } 90 | 91 | .floating-elements { 92 | position: absolute; 93 | top: 0; 94 | left: 0; 95 | width: 100%; 96 | height: 100%; 97 | pointer-events: none; 98 | } 99 | 100 | .floating-element { 101 | position: absolute; 102 | background: rgba(255, 255, 255, 0.1); 103 | border-radius: 50%; 104 | animation: float 6s ease-in-out infinite; 105 | } 106 | 107 | .element-1 { 108 | width: 20px; 109 | height: 20px; 110 | top: 20%; 111 | left: 10%; 112 | animation-delay: 0s; 113 | } 114 | 115 | .element-2 { 116 | width: 15px; 117 | height: 15px; 118 | top: 60%; 119 | right: 15%; 120 | animation-delay: 2s; 121 | } 122 | 123 | .element-3 { 124 | width: 25px; 125 | height: 25px; 126 | bottom: 30%; 127 | left: 20%; 128 | animation-delay: 4s; 129 | } 130 | 131 | /* Card Body */ 132 | .card-body { 133 | padding: 30px; 134 | } 135 | 136 | .profile-name { 137 | font-size: 28px; 138 | font-weight: 700; 139 | color: #1f2937; 140 | margin-bottom: 8px; 141 | text-align: center; 142 | animation: fadeInUp 0.8s ease-out 0.2s both; 143 | } 144 | 145 | .profile-title { 146 | font-size: 16px; 147 | color: #6b7280; 148 | text-align: center; 149 | margin-bottom: 16px; 150 | font-weight: 500; 151 | animation: fadeInUp 0.8s ease-out 0.4s both; 152 | } 153 | 154 | .profile-description { 155 | font-size: 14px; 156 | color: #4b5563; 157 | text-align: center; 158 | line-height: 1.6; 159 | margin-bottom: 24px; 160 | animation: fadeInUp 0.8s ease-out 0.6s both; 161 | } 162 | 163 | /* Skills */ 164 | .skills-container { 165 | display: flex; 166 | flex-wrap: wrap; 167 | gap: 8px; 168 | justify-content: center; 169 | margin-bottom: 30px; 170 | animation: fadeInUp 0.8s ease-out 0.8s both; 171 | } 172 | 173 | .skill-tag { 174 | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 175 | color: white; 176 | padding: 6px 12px; 177 | border-radius: 20px; 178 | font-size: 12px; 179 | font-weight: 500; 180 | transition: transform 0.2s ease; 181 | } 182 | 183 | .skill-tag:hover { 184 | transform: translateY(-2px); 185 | } 186 | 187 | /* Stats */ 188 | .stats-container { 189 | display: flex; 190 | justify-content: space-around; 191 | margin-bottom: 30px; 192 | animation: fadeInUp 0.8s ease-out 1s both; 193 | } 194 | 195 | .stat-item { 196 | text-align: center; 197 | } 198 | 199 | .stat-number { 200 | font-size: 24px; 201 | font-weight: 700; 202 | color: #1f2937; 203 | display: block; 204 | margin-bottom: 4px; 205 | } 206 | 207 | .stat-label { 208 | font-size: 12px; 209 | color: #6b7280; 210 | font-weight: 500; 211 | } 212 | 213 | /* Card Footer */ 214 | .card-footer { 215 | padding: 20px 30px 30px; 216 | border-top: 1px solid rgba(0, 0, 0, 0.05); 217 | } 218 | 219 | .social-links { 220 | display: flex; 221 | justify-content: center; 222 | gap: 16px; 223 | margin-bottom: 20px; 224 | animation: fadeInUp 0.8s ease-out 1.2s both; 225 | } 226 | 227 | .social-link { 228 | width: 44px; 229 | height: 44px; 230 | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 231 | color: white; 232 | border-radius: 12px; 233 | display: flex; 234 | align-items: center; 235 | justify-content: center; 236 | text-decoration: none; 237 | font-size: 18px; 238 | transition: all 0.3s ease; 239 | position: relative; 240 | overflow: hidden; 241 | } 242 | 243 | .social-link::before { 244 | content: ''; 245 | position: absolute; 246 | top: 0; 247 | left: -100%; 248 | width: 100%; 249 | height: 100%; 250 | background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); 251 | transition: left 0.5s; 252 | } 253 | 254 | .social-link:hover::before { 255 | left: 100%; 256 | } 257 | 258 | .social-link:hover { 259 | transform: translateY(-3px); 260 | box-shadow: 0 10px 25px rgba(102, 126, 234, 0.4); 261 | } 262 | 263 | .contact-btn { 264 | width: 100%; 265 | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 266 | color: white; 267 | border: none; 268 | padding: 14px 24px; 269 | border-radius: 12px; 270 | font-size: 16px; 271 | font-weight: 600; 272 | cursor: pointer; 273 | transition: all 0.3s ease; 274 | display: flex; 275 | align-items: center; 276 | justify-content: center; 277 | gap: 8px; 278 | animation: fadeInUp 0.8s ease-out 1.4s both; 279 | position: relative; 280 | overflow: hidden; 281 | } 282 | 283 | .contact-btn::before { 284 | content: ''; 285 | position: absolute; 286 | top: 0; 287 | left: -100%; 288 | width: 100%; 289 | height: 100%; 290 | background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); 291 | transition: left 0.5s; 292 | } 293 | 294 | .contact-btn:hover::before { 295 | left: 100%; 296 | } 297 | 298 | .contact-btn:hover { 299 | transform: translateY(-2px); 300 | box-shadow: 0 15px 35px rgba(102, 126, 234, 0.4); 301 | } 302 | 303 | .contact-btn:active { 304 | transform: translateY(0); 305 | } 306 | 307 | /* Background Elements */ 308 | .bg-elements { 309 | position: fixed; 310 | top: 0; 311 | left: 0; 312 | width: 100%; 313 | height: 100%; 314 | pointer-events: none; 315 | z-index: 1; 316 | } 317 | 318 | .bg-circle { 319 | position: absolute; 320 | border-radius: 50%; 321 | background: rgba(255, 255, 255, 0.1); 322 | animation: float 8s ease-in-out infinite; 323 | } 324 | 325 | .circle-1 { 326 | width: 200px; 327 | height: 200px; 328 | top: 10%; 329 | left: -100px; 330 | animation-delay: 0s; 331 | } 332 | 333 | .circle-2 { 334 | width: 150px; 335 | height: 150px; 336 | top: 60%; 337 | right: -75px; 338 | animation-delay: 3s; 339 | } 340 | 341 | .circle-3 { 342 | width: 100px; 343 | height: 100px; 344 | bottom: 20%; 345 | left: 20%; 346 | animation-delay: 6s; 347 | } 348 | 349 | /* Animations */ 350 | @keyframes slideUp { 351 | from { 352 | opacity: 0; 353 | transform: translateY(50px); 354 | } 355 | to { 356 | opacity: 1; 357 | transform: translateY(0); 358 | } 359 | } 360 | 361 | @keyframes fadeInUp { 362 | from { 363 | opacity: 0; 364 | transform: translateY(20px); 365 | } 366 | to { 367 | opacity: 1; 368 | transform: translateY(0); 369 | } 370 | } 371 | 372 | @keyframes imageFloat { 373 | 0%, 100% { 374 | transform: translateY(0px); 375 | } 376 | 50% { 377 | transform: translateY(-10px); 378 | } 379 | } 380 | 381 | @keyframes float { 382 | 0%, 100% { 383 | transform: translateY(0px) rotate(0deg); 384 | } 385 | 50% { 386 | transform: translateY(-20px) rotate(180deg); 387 | } 388 | } 389 | 390 | @keyframes pulse { 391 | 0%, 100% { 392 | transform: scale(1); 393 | opacity: 1; 394 | } 395 | 50% { 396 | transform: scale(1.2); 397 | opacity: 0.8; 398 | } 399 | } 400 | 401 | /* Responsive Design */ 402 | @media (max-width: 480px) { 403 | .container { 404 | padding: 15px; 405 | max-width: 350px; 406 | } 407 | 408 | .card-header { 409 | padding: 30px 20px 15px; 410 | } 411 | 412 | .profile-image { 413 | width: 100px; 414 | height: 100px; 415 | } 416 | 417 | .card-body { 418 | padding: 25px 20px; 419 | } 420 | 421 | .profile-name { 422 | font-size: 24px; 423 | } 424 | 425 | .stats-container { 426 | gap: 10px; 427 | } 428 | 429 | .stat-number { 430 | font-size: 20px; 431 | } 432 | 433 | .card-footer { 434 | padding: 15px 20px 25px; 435 | } 436 | 437 | .social-link { 438 | width: 40px; 439 | height: 40px; 440 | font-size: 16px; 441 | } 442 | } 443 | 444 | @media (max-width: 360px) { 445 | .container { 446 | padding: 10px; 447 | max-width: 320px; 448 | } 449 | 450 | .profile-image { 451 | width: 90px; 452 | height: 90px; 453 | } 454 | 455 | .profile-name { 456 | font-size: 22px; 457 | } 458 | 459 | .skills-container { 460 | gap: 6px; 461 | } 462 | 463 | .skill-tag { 464 | padding: 4px 10px; 465 | font-size: 11px; 466 | } 467 | } 468 | 469 | /* Dark mode support */ 470 | @media (prefers-color-scheme: dark) { 471 | .profile-card { 472 | background: rgba(17, 24, 39, 0.95); 473 | color: #f9fafb; 474 | } 475 | 476 | .profile-name { 477 | color: #f9fafb; 478 | } 479 | 480 | .profile-title { 481 | color: #d1d5db; 482 | } 483 | 484 | .profile-description { 485 | color: #9ca3af; 486 | } 487 | 488 | .stat-number { 489 | color: #f9fafb; 490 | } 491 | 492 | .stat-label { 493 | color: #d1d5db; 494 | } 495 | 496 | .card-footer { 497 | border-top-color: rgba(255, 255, 255, 0.1); 498 | } 499 | } 500 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --dark-bg: #111827; 3 | --card-bg: rgba(42, 53, 71, 0.5); 4 | --border-color: rgba(255, 255, 255, 0.1); 5 | --text-white: #f9fafb; 6 | --text-muted: #9ca3af; 7 | --accent-primary: #8b5cf6; 8 | --accent-secondary: #a78bfa; 9 | --font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; 10 | } 11 | 12 | /* --- Base & Aurora BG (Unchanged) --- */ 13 | * { 14 | margin: 0; 15 | padding: 0; 16 | box-sizing: border-box; 17 | text-decoration: none; 18 | } 19 | 20 | body { 21 | font-family: var(--font-family); 22 | background-color: var(--dark-bg); 23 | color: var(--text-white); 24 | overflow-x: hidden; 25 | } 26 | 27 | .background-aurora { 28 | position: fixed; 29 | top: 0; 30 | left: 0; 31 | width: 100%; 32 | height: 100%; 33 | background: 34 | radial-gradient(ellipse at top, #6366f130, transparent), 35 | radial-gradient(ellipse at bottom, #a855f730, transparent); 36 | z-index: -1; 37 | animation: pulse 10s infinite alternate; 38 | } 39 | 40 | @keyframes pulse { 41 | from { 42 | opacity: 0.5; 43 | } 44 | 45 | to { 46 | opacity: 1; 47 | } 48 | } 49 | 50 | /* --- Navbar, Hero, Search (Unchanged) --- */ 51 | .container { 52 | max-width: 1600px; 53 | margin: 0 auto; 54 | padding: 0 24px; 55 | } 56 | 57 | .navbar { 58 | position: sticky; 59 | top: 20px; 60 | z-index: 1000; 61 | display: flex; 62 | justify-content: space-between; 63 | align-items: center; 64 | padding: 15px 30px; 65 | margin-bottom: 20px; 66 | background: rgba(31, 41, 55, 0.5); 67 | backdrop-filter: blur(10px); 68 | -webkit-backdrop-filter: blur(10px); 69 | border: 1px solid var(--border-color); 70 | border-radius: 20px; 71 | box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.2); 72 | } 73 | 74 | .logo { 75 | font-size: 1.5rem; 76 | font-weight: 700; 77 | } 78 | 79 | .nav-links { 80 | display: flex; 81 | align-items: center; 82 | gap: 16px; 83 | } 84 | 85 | .nav-link { 86 | display: flex; 87 | align-items: center; 88 | gap: 8px; 89 | text-decoration: none; 90 | color: var(--text-muted); 91 | transition: color 0.3s; 92 | } 93 | 94 | .nav-link:hover { 95 | color: var(--text-white); 96 | } 97 | 98 | .nav-cta { 99 | background-color: var(--text-white); 100 | color: var(--dark-bg); 101 | padding: 10px 20px; 102 | border-radius: 12px; 103 | text-decoration: none; 104 | font-weight: 600; 105 | display: flex; 106 | align-items: center; 107 | gap: 8px; 108 | transition: 109 | transform 0.3s, 110 | background-color 0.3s; 111 | } 112 | 113 | .nav-cta:hover { 114 | transform: translateY(-2px); 115 | background-color: #e5e7eb; 116 | } 117 | 118 | .hero { 119 | text-align: center; 120 | padding: 60px 0; 121 | } 122 | 123 | .hero h1 { 124 | font-size: 3.5rem; 125 | font-weight: 700; 126 | margin-bottom: 16px; 127 | } 128 | 129 | .hero .subtitle { 130 | font-size: 1.1rem; 131 | color: var(--text-muted); 132 | max-width: 600px; 133 | margin: 0 auto 32px; 134 | } 135 | 136 | .hero-cta { 137 | display: inline-block; 138 | background-color: var(--accent-primary); 139 | color: var(--text-white); 140 | font-size: 1.1rem; 141 | font-weight: 600; 142 | text-decoration: none; 143 | padding: 16px 36px; 144 | border-radius: 50px; 145 | transition: 146 | transform 0.3s, 147 | background-color 0.3s; 148 | } 149 | 150 | .hero-cta:hover { 151 | transform: translateY(-3px); 152 | background-color: var(--accent-secondary); 153 | } 154 | 155 | .search-container { 156 | position: relative; 157 | max-width: 700px; 158 | margin: 0 auto 50px; 159 | } 160 | 161 | .search-container i { 162 | position: absolute; 163 | left: 20px; 164 | top: 50%; 165 | transform: translateY(-50%); 166 | color: var(--text-muted); 167 | } 168 | 169 | #search-input { 170 | width: 100%; 171 | background-color: #1f2937; 172 | color: var(--text-white); 173 | border: 1px solid var(--border-color); 174 | border-radius: 16px; 175 | padding: 16px 20px 16px 50px; 176 | font-size: 1rem; 177 | outline: none; 178 | transition: 179 | border-color 0.3s, 180 | box-shadow 0.3s; 181 | } 182 | 183 | #search-input:focus { 184 | border-color: var(--accent-primary); 185 | box-shadow: 0 0 15px rgba(139, 92, 246, 0.3); 186 | } 187 | 188 | /* --- Masonry Grid & Cards --- */ 189 | #contributors-container { 190 | column-count: 4; 191 | column-gap: 20px; 192 | } 193 | 194 | .contributor-card { 195 | background: var(--card-bg); 196 | backdrop-filter: blur(20px); 197 | -webkit-backdrop-filter: blur(20px); 198 | border: 1px solid var(--border-color); 199 | border-radius: 24px; 200 | margin-bottom: 20px; 201 | overflow: hidden; 202 | break-inside: avoid; 203 | animation: fadeIn 0.5s forwards; 204 | opacity: 0; 205 | transform: translateY(20px); 206 | box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2); 207 | transition: 208 | transform 0.3s ease, 209 | box-shadow 0.3s ease; 210 | } 211 | 212 | .contributor-card.hidden { 213 | display: none; 214 | } 215 | 216 | .contributor-card:hover { 217 | transform: scale(1.03) translateY(-5px); 218 | box-shadow: 0 8px 40px rgba(0, 0, 0, 0.3); 219 | } 220 | 221 | .card-iframe-wrapper { 222 | width: 100%; 223 | aspect-ratio: 3 / 4; 224 | position: relative; 225 | cursor: pointer; 226 | border-top-left-radius: 24px; 227 | border-top-right-radius: 24px; 228 | overflow: hidden; 229 | } 230 | 231 | .skeleton { 232 | width: 100%; 233 | height: 100%; 234 | background: linear-gradient(90deg, #1f2937, #374151, #1f2937); 235 | background-size: 200% 100%; 236 | animation: shimmer 1.5s infinite; 237 | position: absolute; 238 | } 239 | 240 | @keyframes shimmer { 241 | 0% { 242 | background-position: 200% 0; 243 | } 244 | 245 | 100% { 246 | background-position: -200% 0; 247 | } 248 | } 249 | 250 | .card-iframe-wrapper iframe { 251 | width: 100%; 252 | height: 100%; 253 | border: none; 254 | opacity: 0; 255 | transition: opacity 0.5s ease; 256 | } 257 | 258 | .card-iframe-wrapper iframe.loaded { 259 | opacity: 1; 260 | } 261 | 262 | .card-footer { 263 | padding: 20px; 264 | display: flex; 265 | flex-direction: column; 266 | gap: 16px; 267 | } 268 | 269 | .card-footer-header { 270 | display: flex; 271 | justify-content: space-between; 272 | align-items: center; 273 | gap: 12px; 274 | } 275 | 276 | .card-footer-header h3 { 277 | font-size: 1.25rem; 278 | font-weight: 600; 279 | white-space: nowrap; 280 | overflow: hidden; 281 | text-overflow: ellipsis; 282 | } 283 | 284 | .card-footer-header a { 285 | color: var(--text-muted); 286 | font-size: 1.5rem; 287 | transition: color 0.3s; 288 | flex-shrink: 0; 289 | } 290 | 291 | .card-footer-header a:hover { 292 | color: var(--text-white); 293 | } 294 | 295 | .card-footer .bio { 296 | font-size: 0.9rem; 297 | color: var(--text-muted); 298 | line-height: 1.6; 299 | overflow: hidden; 300 | display: -webkit-box; 301 | -webkit-line-clamp: 1; 302 | -webkit-box-orient: vertical; 303 | } 304 | 305 | .tags-container { 306 | display: flex; 307 | flex-wrap: wrap; 308 | gap: 8px; 309 | } 310 | 311 | .tag { 312 | background: rgba(255, 255, 255, 0.1); 313 | color: var(--text-white); 314 | font-size: 0.75rem; 315 | font-weight: 500; 316 | padding: 5px 12px; 317 | border-radius: 20px; 318 | } 319 | 320 | /* NEW: "View Project" button on the card */ 321 | .view-project-btn { 322 | width: 100%; 323 | background: rgba(255, 255, 255, 0.1); 324 | color: var(--text-white); 325 | border: none; 326 | border-radius: 12px; 327 | padding: 12px; 328 | font-size: 1rem; 329 | font-weight: 600; 330 | font-family: var(--font-family); 331 | cursor: pointer; 332 | display: flex; 333 | align-items: center; 334 | justify-content: center; 335 | gap: 8px; 336 | transition: background-color 0.3s; 337 | } 338 | 339 | .view-project-btn:hover { 340 | background: rgba(255, 255, 255, 0.2); 341 | } 342 | 343 | /* --- Modals --- */ 344 | .modal-overlay { 345 | position: fixed; 346 | top: 0; 347 | left: 0; 348 | width: 100%; 349 | height: 100%; 350 | background: rgba(17, 24, 39, 0.8); 351 | backdrop-filter: blur(8px); 352 | display: flex; 353 | align-items: center; 354 | justify-content: center; 355 | opacity: 0; 356 | visibility: hidden; 357 | transition: 358 | opacity 0.3s, 359 | visibility 0.3s; 360 | z-index: 2000; 361 | padding: 20px; 362 | } 363 | 364 | .modal-overlay.visible { 365 | opacity: 1; 366 | visibility: visible; 367 | } 368 | 369 | .modal-content { 370 | background: #1f2937; 371 | border-radius: 16px; 372 | width: 90%; 373 | max-width: 800px; 374 | height: 80%; 375 | display: flex; 376 | flex-direction: column; 377 | position: relative; 378 | transform: scale(0.9); 379 | transition: transform 0.3s; 380 | } 381 | 382 | .modal-overlay.visible .modal-content { 383 | transform: scale(1); 384 | } 385 | 386 | .modal-close-button { 387 | position: absolute; 388 | top: -15px; 389 | right: -15px; 390 | background: var(--text-white); 391 | color: var(--dark-bg); 392 | border: none; 393 | border-radius: 50%; 394 | width: 30px; 395 | height: 30px; 396 | font-size: 1.5rem; 397 | cursor: pointer; 398 | z-index: 10; 399 | } 400 | 401 | #modal-iframe-container { 402 | flex-grow: 1; 403 | border-top-left-radius: 16px; 404 | border-top-right-radius: 16px; 405 | overflow: hidden; 406 | } 407 | 408 | #modal-iframe-container iframe { 409 | width: 100%; 410 | height: 100%; 411 | border: none; 412 | } 413 | 414 | #modal-info { 415 | padding: 20px; 416 | text-align: center; 417 | } 418 | 419 | #modal-info h3 { 420 | font-size: 1.5rem; 421 | margin-bottom: 8px; 422 | } 423 | 424 | #modal-info a { 425 | color: var(--accent-secondary); 426 | text-decoration: none; 427 | } 428 | 429 | /* NEW: Device Preview Modal */ 430 | .preview-modal-content { 431 | background: var(--dark-bg); 432 | border: 1px solid var(--border-color); 433 | border-radius: 16px; 434 | width: 100%; 435 | max-width: 1400px; 436 | height: 90vh; 437 | display: flex; 438 | flex-direction: column; 439 | transform: scale(0.9); 440 | transition: transform 0.3s; 441 | box-shadow: 0 10px 50px rgba(0, 0, 0, 0.5); 442 | } 443 | 444 | .modal-overlay.visible .preview-modal-content { 445 | transform: scale(1); 446 | } 447 | 448 | .preview-modal-header { 449 | display: flex; 450 | align-items: center; 451 | padding: 12px 20px; 452 | border-bottom: 1px solid var(--border-color); 453 | flex-shrink: 0; 454 | } 455 | 456 | .preview-modal-header h3 { 457 | font-size: 1rem; 458 | font-weight: 600; 459 | margin-right: auto; 460 | } 461 | 462 | .device-controls { 463 | display: flex; 464 | gap: 8px; 465 | background: #1f2937; 466 | border-radius: 10px; 467 | padding: 4px; 468 | } 469 | 470 | .device-controls button { 471 | background: transparent; 472 | border: none; 473 | color: var(--text-muted); 474 | padding: 8px 12px; 475 | border-radius: 8px; 476 | cursor: pointer; 477 | transition: 478 | background-color 0.3s, 479 | color 0.3s; 480 | } 481 | 482 | .device-controls button.active { 483 | background: var(--accent-primary); 484 | color: var(--text-white); 485 | } 486 | 487 | .preview-modal-header .modal-close-button { 488 | position: static; 489 | transform: none; 490 | width: 24px; 491 | height: 24px; 492 | font-size: 1rem; 493 | margin-left: 16px; 494 | } 495 | 496 | .preview-iframe-container { 497 | flex-grow: 1; 498 | display: flex; 499 | justify-content: center; 500 | align-items: center; 501 | padding: 20px; 502 | overflow: auto; 503 | } 504 | 505 | #preview-iframe { 506 | background-color: #fff; 507 | border-radius: 8px; 508 | box-shadow: 0 5px 20px rgba(0, 0, 0, 0.3); 509 | border: 4px solid #333; 510 | transition: 511 | width 0.4s ease, 512 | height 0.4s ease; 513 | } 514 | 515 | .preview-iframe-container.view-desktop #preview-iframe { 516 | width: 100%; 517 | height: 100%; 518 | } 519 | 520 | .preview-iframe-container.view-tablet #preview-iframe { 521 | width: 768px; 522 | height: 1024px; 523 | max-width: 100%; 524 | max-height: 100%; 525 | } 526 | 527 | .preview-iframe-container.view-mobile #preview-iframe { 528 | width: 375px; 529 | height: 667px; 530 | max-width: 100%; 531 | max-height: 100%; 532 | } 533 | 534 | .preview-modal-footer { 535 | text-align: center; 536 | padding: 16px; 537 | border-top: 1px solid var(--border-color); 538 | flex-shrink: 0; 539 | } 540 | 541 | .preview-modal-footer .hero-cta { 542 | padding: 12px 24px; 543 | font-size: 1rem; 544 | } 545 | 546 | /* --- Final Polish & Responsive --- */ 547 | .no-results-message { 548 | display: none; 549 | text-align: center; 550 | color: var(--text-muted); 551 | padding: 40px; 552 | } 553 | 554 | #loader { 555 | display: none; 556 | width: 40px; 557 | height: 40px; 558 | border: 4px solid var(--border-color); 559 | border-top-color: var(--accent-secondary); 560 | border-radius: 50%; 561 | margin: 40px auto; 562 | animation: spin 1s linear infinite; 563 | } 564 | 565 | #loader.visible { 566 | display: block; 567 | } 568 | 569 | @keyframes spin { 570 | to { 571 | transform: rotate(30deg); 572 | } 573 | } 574 | 575 | #sentinel { 576 | height: 10px; 577 | } 578 | 579 | @media (max-width: 1200px) { 580 | #contributors-container { 581 | column-count: 3; 582 | } 583 | } 584 | 585 | @media (max-width: 900px) { 586 | #contributors-container { 587 | column-count: 2; 588 | } 589 | } 590 | 591 | @media (max-width: 600px) { 592 | #contributors-container { 593 | column-count: 1; 594 | } 595 | 596 | .hero h1 { 597 | font-size: 2.5rem; 598 | } 599 | } 600 | 601 | @keyframes fadeIn { 602 | to { 603 | opacity: 1; 604 | transform: translateY(0); 605 | } 606 | } 607 | --------------------------------------------------------------------------------