├── .deployment ├── static ├── images │ ├── moon.png │ ├── ss1.png │ ├── ss14.png │ ├── ss3.png │ ├── ss33.png │ ├── ss4.png │ ├── ss5.png │ ├── sun.png │ ├── calcc.png │ ├── fithub.png │ ├── about-img.jpg │ ├── codevault.png │ ├── favicon.ico │ ├── fluxshop.png │ ├── logo-dark.png │ ├── myResume.pdf │ ├── nav-menu.png │ ├── portfolio.png │ ├── uemxmap.png │ ├── weather.png │ ├── close-icon.png │ ├── codevault2.png │ ├── logo-light.png │ ├── profile-pic.jpg │ └── gemini-quizz.png ├── scroll.js ├── main.js └── style.css ├── requirements.txt ├── .gitignore ├── .vscode └── settings.json ├── README.md ├── app.py └── templates └── index.html /.deployment: -------------------------------------------------------------------------------- 1 | [config] 2 | SCM_DO_BUILD_DURING_DEPLOYMENT=true -------------------------------------------------------------------------------- /static/images/moon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/moon.png -------------------------------------------------------------------------------- /static/images/ss1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/ss1.png -------------------------------------------------------------------------------- /static/images/ss14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/ss14.png -------------------------------------------------------------------------------- /static/images/ss3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/ss3.png -------------------------------------------------------------------------------- /static/images/ss33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/ss33.png -------------------------------------------------------------------------------- /static/images/ss4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/ss4.png -------------------------------------------------------------------------------- /static/images/ss5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/ss5.png -------------------------------------------------------------------------------- /static/images/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/sun.png -------------------------------------------------------------------------------- /static/images/calcc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/calcc.png -------------------------------------------------------------------------------- /static/images/fithub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/fithub.png -------------------------------------------------------------------------------- /static/images/about-img.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/about-img.jpg -------------------------------------------------------------------------------- /static/images/codevault.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/codevault.png -------------------------------------------------------------------------------- /static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/favicon.ico -------------------------------------------------------------------------------- /static/images/fluxshop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/fluxshop.png -------------------------------------------------------------------------------- /static/images/logo-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/logo-dark.png -------------------------------------------------------------------------------- /static/images/myResume.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/myResume.pdf -------------------------------------------------------------------------------- /static/images/nav-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/nav-menu.png -------------------------------------------------------------------------------- /static/images/portfolio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/portfolio.png -------------------------------------------------------------------------------- /static/images/uemxmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/uemxmap.png -------------------------------------------------------------------------------- /static/images/weather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/weather.png -------------------------------------------------------------------------------- /static/images/close-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/close-icon.png -------------------------------------------------------------------------------- /static/images/codevault2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/codevault2.png -------------------------------------------------------------------------------- /static/images/logo-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/logo-light.png -------------------------------------------------------------------------------- /static/images/profile-pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/profile-pic.jpg -------------------------------------------------------------------------------- /static/images/gemini-quizz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Anubhob435/Anubhob_Portfolio/HEAD/static/images/gemini-quizz.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==3.0.0 2 | google-generativeai==0.3.1 3 | gunicorn==21.2.0 4 | Flask-Session==0.5.0 5 | python-dotenv==1.0.0 6 | pymongo==4.5.0 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Python 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | *.so 6 | .Python 7 | env/ 8 | venv/ 9 | ENV/ 10 | build/ 11 | develop-eggs/ 12 | dist/ 13 | downloads/ 14 | eggs/ 15 | .eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # Flask 26 | instance/ 27 | flask_session/ 28 | .webassets-cache 29 | 30 | # Environment variables 31 | .env 32 | .env.* 33 | 34 | # IDEs and editors 35 | .idea/ 36 | .vscode/ 37 | *.swp 38 | *.swo 39 | *~ 40 | 41 | # OS generated files 42 | .DS_Store 43 | .DS_Store? 44 | ._* 45 | .Spotlight-V100 46 | .Trashes 47 | ehthumbs.db 48 | Thumbs.db 49 | -------------------------------------------------------------------------------- /static/scroll.js: -------------------------------------------------------------------------------- 1 | let calcScrollValue = () => { 2 | let scrollProg = document.getElementById("progress"); 3 | let pos = document.documentElement.scrollTop; 4 | let calcHeight = 5 | document.documentElement.scrollHeight - 6 | document.documentElement.clientHeight; 7 | let scrollValue = Math.round((pos * 100) / calcHeight); 8 | if (pos > 100) { 9 | scrollProg.style.display = "grid"; 10 | } else { 11 | scrollProg.style.display = "none"; 12 | } 13 | scrollProg.addEventListener("click", () => { 14 | document.documentElement.scrollTop = 0; 15 | }); 16 | scrollProg.style.background = `conic-gradient(#6862e8 ${scrollValue}%, #d499de ${scrollValue}%)`; 17 | }; 18 | 19 | window.onscroll = calcScrollValue; 20 | window.onload = calcScrollValue; -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "appService.zipIgnorePattern": [ 3 | "__pycache__{,/**}", 4 | "*.py[cod]", 5 | "*$py.class", 6 | ".Python{,/**}", 7 | "build{,/**}", 8 | "develop-eggs{,/**}", 9 | "dist{,/**}", 10 | "downloads{,/**}", 11 | "eggs{,/**}", 12 | ".eggs{,/**}", 13 | "lib{,/**}", 14 | "lib64{,/**}", 15 | "parts{,/**}", 16 | "sdist{,/**}", 17 | "var{,/**}", 18 | "wheels{,/**}", 19 | "share/python-wheels{,/**}", 20 | "*.egg-info{,/**}", 21 | ".installed.cfg", 22 | "*.egg", 23 | "MANIFEST", 24 | ".env{,/**}", 25 | ".venv{,/**}", 26 | "env{,/**}", 27 | "venv{,/**}", 28 | "ENV{,/**}", 29 | "env.bak{,/**}", 30 | "venv.bak{,/**}", 31 | ".vscode{,/**}" 32 | ], 33 | "appService.defaultWebAppToDeploy": "/subscriptions/02825273-0bb3-4b5a-a19b-777a7c78a6b4/resourceGroups/trackbeez/providers/Microsoft.Web/sites/portfoliomine", 34 | "appService.deploySubpath": "." 35 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Anubhob's Portfolio Website 2 | 3 | This is the source code for Anubhob Dey's portfolio website. The website showcases Anubhob's skills, projects, and contact information. It also includes a chatbot named "Friday" that acts as a personal assistant. 4 | 5 | ## Features 6 | 7 | - Responsive design 8 | - Dark mode toggle 9 | - Scroll reveal animations 10 | - Chatbot assistant 11 | - Project showcase 12 | - Contact form 13 | 14 | ## Technologies Used 15 | 16 | - HTML 17 | - CSS 18 | - JavaScript 19 | - Flask 20 | - Google Gemini API 21 | 22 | ## Setup Instructions 23 | 24 | 1. Clone the repository: 25 | ```sh 26 | git clone https://github.com/yourusername/Anubhob_Portfolio.git 27 | cd Anubhob_Portfolio 28 | ``` 29 | 30 | 2. Create a virtual environment and activate it: 31 | ```sh 32 | python -m venv venv 33 | source venv/bin/activate # On Windows, use `venv\Scripts\activate` 34 | ``` 35 | 36 | 3. Install the required packages: 37 | ```sh 38 | pip install -r requirements.txt 39 | ``` 40 | 41 | 4. Set up environment variables: 42 | Create a `.env` file in the root directory and add your Gemini API key: 43 | ```env 44 | GEMINI_API_KEY=your_api_key_here 45 | ``` 46 | 47 | 5. Run the Flask application: 48 | ```sh 49 | python app.py 50 | ``` 51 | 52 | 6. Open your browser and navigate to `http://127.0.0.1:5000` to view the website. 53 | 54 | ## Deployment 55 | 56 | To deploy the website, you can use platforms like Render, Heroku, or any other hosting service that supports Python/Flask applications. 57 | 58 | ## License 59 | 60 | This project is licensed under the MIT License. 61 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import os 2 | import requests 3 | import google.generativeai as genai 4 | from flask import Flask, render_template, send_from_directory, request, jsonify, session 5 | from flask_session import Session 6 | from dotenv import load_dotenv 7 | import time 8 | from google.api_core import exceptions 9 | from pymongo import MongoClient 10 | from datetime import datetime 11 | from uuid import uuid4 12 | 13 | load_dotenv() 14 | 15 | client = MongoClient(os.getenv('MONGODB_URI')) 16 | db = client['chatbot_db'] 17 | chats_collection = db['conversations'] 18 | 19 | 20 | app = Flask(__name__) 21 | app.secret_key = 'your_secret_key' # Set the secret key for session management 22 | app.config['SESSION_TYPE'] = 'filesystem' 23 | Session(app) 24 | 25 | # Configure Gemini API 26 | genai.configure(api_key=os.getenv('GEMINI_API_KEY')) 27 | 28 | # Create the model 29 | generation_config = { 30 | "temperature": 1, 31 | "top_p": 0.95, 32 | "top_k": 40, 33 | "max_output_tokens": 8192, 34 | } 35 | 36 | model = genai.GenerativeModel( 37 | model_name="gemini-1.5-pro", 38 | generation_config=generation_config, 39 | ) 40 | 41 | # Create initial context/history about you 42 | INITIAL_CONTEXT = """ 43 | You are known as Friday and act as a personal assistant to Master Anubhob Dey, a B.Tech undergraduate at UEM Kolkata. He is a tech enthusiast, passionate about exploring new technologies, and has extensive experience as a web developer and competitive programmer. 44 | He is also a machine learning enthusiast who has worked on projects related to AI and Python, including creating UEMxMaps (a map application using Ola Maps APIs), a quiz app powered by the Gemini API, and a shopping website using Python Flask, HTML, and SQL Server. 45 | Anubhob holds a CS50x certification, showcasing his expertise in computer science fundamentals. He has also designed several web applications, such as a fitness website front-end and a shuttle app for tracking buses for school and college students. 46 | In addition to his technical skills, Anubhob is skilled in backend development, data engineering, and building data pipelines. He’s always eager to learn and expand his expertise in cutting-edge fields like Artificial Intelligence and Machine Learning. 47 | He is a male in his early 20s, residing in Kolkata, West Bengal, and is known for his problem-solving skills, creativity, and teamwork. In case anyone asks for his contact details: 48 | Mobile: +91 8583005957 Email: anubhob435@gmail.com 49 | If asked who you are, state that you are Friday, an AI personal assistant inspired from Ironman trained by Anubhob Dey. 50 | Keep your answers concise, limited to 40–45 words. 51 | start by responding to the users query that will follow this message. 52 | """ 53 | 54 | # Initialize global chat session with context 55 | chat = model.start_chat(history=[]) 56 | chat.send_message(INITIAL_CONTEXT) 57 | 58 | # Add rate limiting variables 59 | RATE_LIMIT_WINDOW = 60 # 1 minute 60 | MAX_REQUESTS = 60 # maximum requests per minute 61 | request_timestamps = [] 62 | 63 | @app.route('/') 64 | def index(): 65 | return render_template('index.html') 66 | 67 | @app.route('/static/') 68 | def static_files(filename): 69 | return send_from_directory('static', filename) 70 | 71 | @app.route('/chatbot', methods=['POST']) 72 | def chatbot(): 73 | try: 74 | # Rate limiting check 75 | current_time = time.time() 76 | request_timestamps.append(current_time) 77 | 78 | # Remove timestamps older than the window 79 | while request_timestamps and request_timestamps[0] < current_time - RATE_LIMIT_WINDOW: 80 | request_timestamps.pop(0) 81 | 82 | # Check if rate limit exceeded 83 | if len(request_timestamps) > MAX_REQUESTS: 84 | return jsonify({ 85 | 'response': "I'm receiving too many requests right now. Please try again in a minute." 86 | }), 429 87 | 88 | # Get or create session ID 89 | if 'chat_session_id' not in session: 90 | session['chat_session_id'] = str(uuid4()) 91 | 92 | user_message = request.json.get('message') 93 | 94 | try: 95 | # Prepend context for the AI 96 | full_message = INITIAL_CONTEXT + user_message 97 | response = chat.send_message(full_message) 98 | bot_response = response.text.strip() 99 | 100 | # Store conversation in MongoDB 101 | chat_document = { 102 | 'group_id': request.remote_addr, # Group by IP 103 | 'session_id': session['chat_session_id'], 104 | 'timestamp': datetime.utcnow(), 105 | 'user_message': user_message, 106 | 'bot_response': bot_response, 107 | 'ip_address': request.remote_addr 108 | } 109 | chats_collection.insert_one(chat_document) 110 | 111 | except exceptions.ResourceExhausted: 112 | return jsonify({ 113 | 'response': "I've reached my quota limit. Please try again later." 114 | }), 429 115 | except Exception as e: 116 | print(f"Gemini API Error: {str(e)}") 117 | return jsonify({ 118 | 'response': "I encountered an error processing your request. Please try again." 119 | }), 500 120 | 121 | return jsonify({'response': bot_response}) 122 | 123 | except Exception as e: 124 | print(f"Server Error: {str(e)}") 125 | return jsonify({ 126 | 'response': "I apologize, but I encountered an error. Please try again." 127 | }), 500 128 | 129 | # Add new route to get chat history 130 | @app.route('/chat-history', methods=['GET']) 131 | def get_chat_history(): 132 | try: 133 | if 'chat_session_id' not in session: 134 | return jsonify([]) 135 | 136 | # Fetch chat history for current session 137 | history = list(chats_collection.find( 138 | {'session_id': session['chat_session_id']}, 139 | {'_id': 0, 'user_message': 1, 'bot_response': 1, 'timestamp': 1} 140 | ).sort('timestamp', 1)) 141 | 142 | return jsonify(history) 143 | except Exception as e: 144 | print(f"Error fetching chat history: {str(e)}") 145 | return jsonify([]) 146 | 147 | # Optional: new route to fetch history by IP 148 | @app.route('/chat-history-by-ip', methods=['GET']) 149 | def get_chat_history_by_ip(): 150 | try: 151 | ip_addr = request.remote_addr 152 | # Fetch chat history by IP (group_id) 153 | history = list(chats_collection.find( 154 | {'group_id': ip_addr}, 155 | {'_id': 0, 'user_message': 1, 'bot_response': 1, 'timestamp': 1} 156 | ).sort('timestamp', 1)) 157 | return jsonify(history) 158 | except Exception as e: 159 | print(f"Error fetching chat history: {str(e)}") 160 | return jsonify([]) 161 | 162 | if __name__ == '__main__': 163 | app.run(debug=False, use_reloader=False, host='0.0.0.0', port=5000) -------------------------------------------------------------------------------- /static/main.js: -------------------------------------------------------------------------------- 1 | //NAVIGATION BAR EFFECTS ON SCROLL 2 | window.addEventListener("scroll", function() { 3 | const header = document.querySelector("header"); 4 | header.classList.toggle("sticky", window.scrollY > 0); 5 | }); 6 | 7 | //DARK THEME TOGGLE 8 | var icon = document.getElementById("icon"); 9 | var logo = document.getElementsByClassName("logo")[0]; 10 | var image = document.getElementById("image"); 11 | 12 | icon.onclick = function() { 13 | document.body.classList.toggle("dark-theme"); 14 | 15 | if (document.body.classList.contains("dark-theme")) { 16 | icon.src = "/static/images/sun.png"; // Change to sun icon in dark mode 17 | logo.src = "/static/images/logo-light.png"; // Use dark mode logo 18 | // Don't change the profile picture source 19 | } else { 20 | icon.src = "/static/images/moon.png"; // Change to moon icon in light mode 21 | logo.src = "/static/images/logo-light.png"; // Use light mode logo 22 | // Don't change the profile picture source 23 | } 24 | } 25 | 26 | //PROJECTS SECTION MODAL 27 | const projectModals = document.querySelectorAll(".project-model"); 28 | const imgCards = document.querySelectorAll(".img-card"); 29 | const projectcloseBtns = document.querySelectorAll(".project-close-btn"); 30 | 31 | var projectModal = function(modalclick) { 32 | projectModals[modalclick].classList.add("active"); 33 | } 34 | 35 | imgCards.forEach((imgCard, index) => { 36 | imgCard.addEventListener("click", () => { 37 | projectModal(index); 38 | }); 39 | }); 40 | 41 | projectcloseBtns.forEach((closeBtn) => { 42 | closeBtn.addEventListener("click", (event) => { 43 | event.stopPropagation(); 44 | projectModals.forEach((projectModalView) => { 45 | projectModalView.classList.remove("active"); 46 | }); 47 | }); 48 | }); 49 | 50 | //SCROLL REVEAL ANIMATION 51 | //COMMON REVEAL OPTIONS TO CREATE REVEAL ANIMATIONS 52 | ScrollReveal({ 53 | reset: true, 54 | distance: '60px', 55 | duration: 2500, 56 | delay: 100 57 | }); 58 | 59 | ScrollReveal().reveal('.home .info h2, .section-title-01, .section-title-02', { 60 | delay: 500, 61 | origin: 'left' 62 | }); 63 | ScrollReveal().reveal('.home .info h3, .home .info p, .about-info .btn', { 64 | delay: 600, 65 | origin: 'right' 66 | }); 67 | ScrollReveal().reveal('.home .info .btn', { 68 | delay: 700, 69 | origin: 'bottom' 70 | }); 71 | ScrollReveal().reveal('.media-icons i, .contact-left li', { 72 | delay: 500, 73 | origin: 'left', 74 | interval: 200 75 | }); 76 | ScrollReveal().reveal('.home-img, .about-img', { 77 | delay: 500, 78 | origin: 'bottom' 79 | }); 80 | ScrollReveal().reveal('.about .description, .contact-right', { 81 | delay: 600, 82 | origin: 'right' 83 | }); 84 | ScrollReveal().reveal('.about .professional-list li', { 85 | delay: 500, 86 | origin: 'right', 87 | interval: 200 88 | }); 89 | ScrollReveal().reveal('.skills-description, .contact-card, .contact-left h2', { 90 | delay: 700, 91 | origin: 'left' 92 | }); 93 | ScrollReveal().reveal('.education, .projects .img-card', { 94 | delay: 800, 95 | origin: 'bottom', 96 | interval: 200 97 | }); 98 | ScrollReveal().reveal('.footer-container .group', { 99 | delay: 500, 100 | origin: 'top' 101 | }); 102 | 103 | //RESPONSIVE NAVIGATION BAR 104 | const menuBtn = document.querySelector(".nav-menu-btn"); 105 | const closeBtn = document.querySelector(".nav-close-btn"); 106 | const navMenu = document.querySelector(".navigation"); 107 | const navItems = document.querySelectorAll(".nav-items a"); 108 | 109 | menuBtn.addEventListener("click", () => { 110 | navMenu.classList.add("active"); 111 | }); 112 | 113 | closeBtn.addEventListener("click", () => { 114 | navMenu.classList.remove("active"); 115 | }); 116 | 117 | navItems.forEach((navItem) => { 118 | navItem.addEventListener("click", () => { 119 | navMenu.classList.remove("active"); 120 | }); 121 | }); 122 | 123 | //CHATBOT FUNCTIONALITY 124 | document.addEventListener("DOMContentLoaded", function() { 125 | // Set initial theme state 126 | icon.src = "/static/images/sun.png"; // Start with sun icon 127 | logo.src = "/static/images/logo-light.png"; // Use dark mode logo 128 | 129 | const chatbotMessages = document.getElementById("chatbot-messages"); 130 | const chatbotInput = document.getElementById("chatbot-input"); 131 | const chatbotSendBtn = document.getElementById("chatbot-send-btn"); 132 | const chatbotMinimizeBtn = document.getElementById("chatbot-minimize-btn"); 133 | const chatbotReopenBtn = document.getElementById("chatbot-reopen-btn"); 134 | 135 | // Function to display a message 136 | function displayMessage(message, className) { 137 | const messageElement = document.createElement("div"); 138 | messageElement.className = `chatbot-message ${className}`; 139 | messageElement.textContent = message; 140 | chatbotMessages.appendChild(messageElement); 141 | chatbotMessages.scrollTop = chatbotMessages.scrollHeight; // Scroll to the bottom 142 | } 143 | 144 | // Add typing animation function 145 | function showTypingAnimation() { 146 | const animation = document.createElement('div'); 147 | animation.className = 'typing-animation'; 148 | animation.innerHTML = ` 149 | 150 | 151 | 152 | `; 153 | chatbotMessages.appendChild(animation); 154 | chatbotMessages.scrollTop = chatbotMessages.scrollHeight; 155 | return animation; 156 | } 157 | 158 | // Function to handle sending a message 159 | async function handleSendMessage() { 160 | const userMessage = chatbotInput.value; 161 | if (userMessage.trim() === "") return; 162 | 163 | // Display user message 164 | displayMessage(userMessage, "user-message"); 165 | chatbotInput.value = ""; 166 | 167 | // Show typing animation 168 | const typingAnimation = showTypingAnimation(); 169 | 170 | try { 171 | // Send message to backend 172 | const response = await fetch('/chatbot', { 173 | method: 'POST', 174 | headers: { 175 | 'Content-Type': 'application/json' 176 | }, 177 | body: JSON.stringify({ message: userMessage }) 178 | }); 179 | const data = await response.json(); 180 | 181 | // Remove typing animation 182 | typingAnimation.remove(); 183 | 184 | // Display bot message 185 | displayMessage(data.response, "bot-message"); 186 | } catch (error) { 187 | // Remove typing animation 188 | typingAnimation.remove(); 189 | 190 | // Display error message 191 | displayMessage("Sorry, I encountered an error. Please try again.", "bot-message"); 192 | } 193 | } 194 | 195 | // Event listeners 196 | chatbotSendBtn.addEventListener("click", handleSendMessage); 197 | chatbotInput.addEventListener("keypress", function(event) { 198 | if (event.key === "Enter") { 199 | handleSendMessage(); 200 | } 201 | }); 202 | chatbotMinimizeBtn.addEventListener("click", function() { 203 | document.getElementById("chatbot").style.display = "none"; 204 | chatbotReopenBtn.style.display = "block"; 205 | }); 206 | chatbotReopenBtn.addEventListener("click", function() { 207 | document.getElementById("chatbot").style.display = "flex"; 208 | chatbotReopenBtn.style.display = "none"; 209 | }); 210 | 211 | // Add window resize handler 212 | function handleResize() { 213 | const chatbot = document.getElementById("chatbot"); 214 | const reopenBtn = document.getElementById("chatbot-reopen-btn"); 215 | 216 | if (window.innerWidth <= 768) { 217 | if (chatbot.style.display !== "flex") { 218 | chatbot.style.display = "none"; 219 | reopenBtn.style.display = "block"; 220 | } 221 | } 222 | } 223 | 224 | // Listen for window resize 225 | window.addEventListener('resize', handleResize); 226 | 227 | // Check initial window size 228 | handleResize(); 229 | 230 | // Greet the user on page load 231 | displayMessage("Hola, I am master Dey's Assistant, How can I help", "bot-message"); 232 | 233 | // Ensure chatbot is visible on mobile when reopened 234 | const chatbot = document.getElementById("chatbot"); 235 | const reopenBtn = document.getElementById("chatbot-reopen-btn"); 236 | 237 | // Add touchstart event for mobile devices 238 | reopenBtn.addEventListener("touchstart", function(e) { 239 | e.preventDefault(); // Prevent default touch behavior 240 | chatbot.style.display = "flex"; 241 | this.style.display = "none"; 242 | }, false); 243 | 244 | // Keep click event for desktop 245 | reopenBtn.addEventListener("click", function(e) { 246 | e.preventDefault(); // Prevent default click behavior 247 | chatbot.style.display = "flex"; 248 | this.style.display = "none"; 249 | }); 250 | 251 | // Initialize chatbot state for mobile 252 | if (window.innerWidth <= 768) { 253 | chatbot.style.display = "none"; 254 | reopenBtn.style.display = "block"; 255 | } 256 | 257 | // Dropdown and View More functionality 258 | // Handle dropdowns 259 | const dropdownBtns = document.querySelectorAll('.dropdown-btn'); 260 | 261 | dropdownBtns.forEach(btn => { 262 | btn.addEventListener('click', function() { 263 | const targetId = this.getAttribute('data-target'); 264 | const content = document.getElementById(targetId); 265 | 266 | // Toggle active class 267 | this.classList.toggle('active'); 268 | content.classList.toggle('active'); 269 | }); 270 | }); 271 | 272 | // Handle View More buttons 273 | const viewMoreBtns = document.querySelectorAll('.view-more-btn'); 274 | 275 | viewMoreBtns.forEach(btn => { 276 | btn.addEventListener('click', function() { 277 | const hiddenContent = this.previousElementSibling; 278 | hiddenContent.classList.toggle('active'); 279 | 280 | // Toggle button text 281 | this.textContent = hiddenContent.classList.contains('active') ? 282 | 'View Less' : 'View More'; 283 | }); 284 | }); 285 | }); 286 | 287 | // Ensure chatbot is visible on mobile when reopened 288 | document.getElementById("chatbot-reopen-btn").addEventListener("click", function() { 289 | document.getElementById("chatbot").style.display = "flex"; 290 | this.style.display = "none"; 291 | }); -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Portfilio Website 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 18 |

Friday

19 | 20 |
21 |
22 | 23 | 24 |
25 | 26 | 27 |
28 | 45 |
46 | 47 | 48 |
49 |
50 |
51 | 52 | 53 | 54 |
55 |
56 |

Hi, Anubhob Here

57 |

I'm tech enthusiast.

58 |

As an aspiring software developer and B.Tech undergrad, I thrive on discovering new innovations, diving into coding projects, and staying updated with the latest trends in the tech world.

59 | Join Me 60 |
61 |
62 | 63 |
64 |
65 | 66 |
67 | 68 | 69 | 70 |
71 |
72 |

About Me

73 |

About Me

74 |
75 |
76 | 77 |
78 |
79 |
80 |

I'm Anubhob

81 |

Currently a B.Tech student at UEMK.

82 |

I stepped into the world of computer science during high school, starting with Python and SQL. Since then, I have delved into various languages and skills, including C, Web development, Data structures and algorithms and many 83 | more. My curiosity drives me to continuously learn and grow in this ever-evolving field.

84 |
85 |
    86 |
  • 87 |

    2+

    88 | Years
    in the field of Computer Science (Currently a Student)
    89 |
  • 90 |
  • 91 |

    50+

    92 | Connections on
    LinkedIn
    93 |
  • 94 |
  • 95 |

    5+

    96 | Successfull
    Projects
    97 |
  • 98 |
99 | Download CV 100 |
101 |
102 |
103 |
104 | 105 | 106 | 107 |
108 |
109 |

Skills

110 |

Skills

111 |
112 |
113 |

Education & Skills

114 |

Below are my education qualifications and the skills I have explored.

115 |
116 |
117 | 118 |
119 | 122 | 145 |
146 | 147 | 148 |
149 | 152 | 187 |
188 | 189 | 190 |
191 | 194 | 235 |
236 |
237 |
238 |
239 |
240 | 241 | 242 | 243 |
244 |
245 |

Projects

246 |

Projects

247 |
248 |
249 |
250 |
251 |
252 |
253 |

Project 1

254 | TrackBees 255 |
256 | 257 | 258 | 259 | 260 |
261 |
262 | Disney+ Hotstar Clone 263 |
264 |
265 |
266 | 267 |

TrackBees

268 | TrackBees 269 |
270 | 271 | 272 | 273 | 274 |
275 |

Introducing TrackBees, a comprehensive vehicle tracking solution developed for my university's transport system. This web application utilizes GPS technology and real-time mapping to provide live tracking of university buses, helping students and staff monitor bus locations and estimated arrival times efficiently.

276 | Visit Project 277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |

Project 2: Code Vault

285 | Code Vault 286 |
287 | 288 | 289 | 290 |
291 |
292 | Calculator 293 |
294 |
295 |
296 | 297 |

Project #2: Code Vault

298 | Calculator 299 |
300 | 301 | 302 | 303 |
304 |

A premium software marketplace to buy and exchange codes. Built using Python Django, MongoDB, MySQL, and HTML/CSS/JS.

305 | Visit Project 306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |

Project 3

314 | AI Stock Analysis 315 |
316 | 317 | 318 | 319 | 320 |
321 |
322 | e-learning site 323 |
324 |
325 |
326 | 327 |

AI Stock Analysis

328 | AI Stock Analysis 329 |
330 | 331 | 332 | 333 | 334 |
335 |

A sophisticated stock analysis tool powered by artificial intelligence. This project combines machine learning algorithms with financial data to provide predictive analytics, trend analysis, and automated trading signals. Features include real-time market data processing, pattern recognition, and predictive modeling for informed investment decisions.

336 | Visit Project 337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |

Project 4

345 | Portfolio with AI Assistant 346 |
347 | 348 | 349 | 350 | 351 |
352 |
353 | Eduverity 354 |
355 |
356 |
357 | 358 |

Portfolio with AI Assistant

359 | Portfolio 360 |
361 | 362 | 363 | 364 | 365 |
366 |

A modern portfolio website featuring an integrated AI assistant powered by Google's Gemini API. This project showcases my work while providing interactive assistance to visitors. The AI can answer questions about my projects, skills, and experience, creating an engaging user experience.

367 | Visit Project 368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |

Project 5

376 | Web Scrapper with Ai Analysis 377 |
378 | 379 | 380 | 381 | 382 |
383 |
384 | Career-Crafters 385 |
386 |
387 |
388 | 389 |

Web Scrapper with AI Analysis

390 | Web Scrapper 391 |
392 | 393 | 394 | 395 | 396 |
397 |

An advanced web scraping tool enhanced with AI capabilities for intelligent data analysis. This project automatically collects data from various web sources and uses machine learning to analyze and categorize the information. Features include automated data extraction, sentiment analysis, and trend identification.

398 | Visit Project 399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |

Project 6

407 | Weather analytics App 408 |
409 | 410 | 411 | 412 | 413 |
414 |
415 | weather-app 416 |
417 |
418 |
419 | 420 |

Weather App

421 | weather-app 422 |
423 | 424 | 425 | 426 | 427 |
428 |

Presenting my Weather App project—a website designed for users to effortlessly check weather conditions in their city. Built using HTML, CSS, and JavaScript, this project represents my first attempt of integrating APIs 429 | into web development. By seamlessly incorporating weather data, users can stay informed about current and upcoming weather patterns with ease.

430 | Visit Project 431 |
432 |
433 |
434 |
435 |
436 | More Projects 437 |
438 |
439 | 440 | 441 |
442 |
443 |

Join Me

444 |

Join Me

445 |
446 |
447 |

Let's discuss your project

448 |
    449 |
  • 450 |

    Phone

    451 | +91 8583005957 452 |
  • 453 |
  • 454 |

    Email-Id

    455 | anubhob435@gmail.com 456 |
  • 457 |
  • 458 |

    Official Address

    459 | Kolkata, India 460 |
  • 461 |
462 |
463 |
464 |

Would love to Chat and talk about
Projects and Ideas or aything

465 |
466 |
467 | 468 |
469 |
470 | 471 | 472 |
473 |
474 | 475 |
476 | 477 |
478 |
479 |
480 |
481 |
482 | 483 | 484 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | -------------------------------------------------------------------------------- /static/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap'); 2 | :root { 3 | /*===========Main theme colours==========*/ 4 | --first-color: #0e2431; 5 | --second-color: #6a59d1; 6 | --third-color: #777; 7 | /*===========Hover colours==========*/ 8 | --hover-color: #614fd0; 9 | /*===========Backgroung colours==========*/ 10 | --body-bg-color: #fefefe; 11 | --card-bg-color: #fff; 12 | --modal-bg-colour: #fff; 13 | --bg-tansparent-color: rgba(0, 0, 0, 0.1); 14 | --transparent-colour-01: rgba(0, 0, 0, 0.1); 15 | --transparent-colour-02: rgba(106, 89, 209, 0.1); 16 | --line-color: #d7d7d7; 17 | /*===========Color Filter==========*/ 18 | --color-filter: invert(1); 19 | /*===========Box Shadow==========*/ 20 | --box-shadow: 0px 0px 20px rgb(0 0 0 / 10%); 21 | /*===========Font size==========*/ 22 | --small-font-size: 0.9em; 23 | --normal-font-size: 1em; 24 | /*=========Scroll bar colours========*/ 25 | --scroll-bar-color: #c5cadf; 26 | --scroll-thum-color: #70768a; 27 | --scroll-thum-hover-color: #454f6b; 28 | } 29 | 30 | /* Add these style rules after the :root section */ 31 | 32 | .dropdown-list { 33 | margin-bottom: 0; /* Remove bottom margin */ 34 | padding-bottom: 0; /* Remove bottom padding */ 35 | } 36 | 37 | .dropdown-container:not(:last-child) { 38 | margin-bottom: 10px; /* Add small space between containers */ 39 | } 40 | 41 | /* If there's specific padding/margin on individual elements, you may need: */ 42 | .education-dropdown, 43 | .certification-dropdown, 44 | .skills-dropdown { 45 | margin: 0; 46 | padding: 5px 0; 47 | } 48 | 49 | * { 50 | margin: 0; 51 | padding: 0; 52 | box-sizing: border-box; 53 | font-family: 'Poppins', sans-serif; 54 | } 55 | 56 | html { 57 | scroll-behavior: smooth; 58 | } 59 | 60 | body { 61 | color: var(--first-color); 62 | background: var(--body-bg-color); 63 | margin: 2rem 0 0 0; 64 | transition: .5s ease; 65 | } 66 | 67 | a { 68 | text-decoration: none; 69 | } 70 | 71 | li { 72 | list-style: none; 73 | } 74 | 75 | h1 { 76 | background: linear-gradient(to top, transparent 0%, black 70%); 77 | -webkit-background-clip: text; 78 | -webkit-text-fill-color: transparent; 79 | opacity: .9; 80 | } 81 | 82 | /*=======Dark Theme========*/ 83 | 84 | .dark-theme { 85 | background: var(--first-color); 86 | color: var(--body-bg-color); 87 | } 88 | 89 | .dark-theme .nav-menu-btn, 90 | .dark-theme .nav-close-btn { 91 | background-color: #fff; 92 | border-radius: 100%; 93 | } 94 | 95 | .dark-theme .nav-items a { 96 | color: var(--body-bg-color); 97 | } 98 | 99 | .dark-theme h1 { 100 | background: linear-gradient(to top, transparent 0%, white 70%); 101 | -webkit-background-clip: text; 102 | -webkit-text-fill-color: transparent; 103 | opacity: .2; 104 | } 105 | 106 | .dark-theme .nav-bar .logo { 107 | margin-top: 10px; 108 | } 109 | 110 | .dark-theme .home .scroll-down { 111 | color: var(--body-bg-color); 112 | } 113 | 114 | .dark-theme .contact-form input, 115 | .contact-form textarea { 116 | color: var(--body-bg-color); 117 | } 118 | 119 | .dark-theme .contact-right p { 120 | color: var(--body-bg-color) 121 | } 122 | 123 | .dark-theme ::placeholder { 124 | color: var(--body-bg-color) 125 | } 126 | 127 | .dark-theme .edu-list .item, 128 | .dark-theme .bars .info { 129 | color: var(--first-color) 130 | } 131 | 132 | .dark-theme .project-model-body { 133 | background: #1a3442; 134 | } 135 | 136 | /* Dark theme image adjustments */ 137 | .dark-theme img { 138 | filter: brightness(0.9); /* Slightly reduce brightness in dark mode */ 139 | } 140 | 141 | .dark-theme .logo, 142 | .dark-theme #icon, 143 | .dark-theme .footer-logo { 144 | filter: invert(1); /* Invert colors for specific images */ 145 | } 146 | 147 | .dark-theme .home-img img, 148 | .dark-theme .about-img img, 149 | .dark-theme .img-card img { 150 | filter: brightness(0.9); /* Adjust project images in dark mode */ 151 | } 152 | 153 | /*=======Scroll Bar========*/ 154 | 155 | ::-webkit-scrollbar { 156 | width: 10px; 157 | background: var(--scroll-bar-color); 158 | } 159 | 160 | ::-webkit-scrollbar-thumb { 161 | background: var(--scroll-thum-color); 162 | border-radius: 2em; 163 | } 164 | 165 | ::-webkit-scrollbar-thumb:hover { 166 | background: var(--scroll-thum-hover-color); 167 | } 168 | 169 | /*======Header=======*/ 170 | 171 | header { 172 | z-index: 99999; 173 | width: 100%; 174 | position: fixed; 175 | top: 0; 176 | left: 0; 177 | backdrop-filter: blur(20px); 178 | transition: .3s ease; 179 | } 180 | 181 | header.sticky { 182 | background: rgba(255, 255, 255, 0.1); 183 | box-shadow: var(--box-shadow); 184 | } 185 | 186 | .nav-bar { 187 | position: relative; 188 | height: calc(4rem + 1rem); 189 | max-width: 1250px; 190 | display: flex; 191 | justify-content: space-between; 192 | align-items: center; 193 | margin-left: auto; 194 | margin-right: auto; 195 | padding: 0 20px; 196 | transition: .3s ease; 197 | } 198 | 199 | header.sticky .nav-bar { 200 | height: calc(3rem + 3rem); 201 | } 202 | 203 | .nav-bar .logo { 204 | color: var(--first-color); 205 | font-size: 1.3cm; 206 | font-weight: 600; 207 | } 208 | 209 | .nav-bar img { 210 | width: 60px; /* Changed from 80px */ 211 | cursor: pointer; 212 | padding-top: 8px; /* Added padding */ 213 | } 214 | 215 | .nav-items a { 216 | color: var(--first-color); 217 | font-size: var(--normal-font-size); 218 | font-weight: 500; 219 | } 220 | 221 | .nav-items a:not(:last-child) { 222 | margin-right: 50px; 223 | } 224 | 225 | .nav-items a:hover { 226 | color: var(--second-color); 227 | } 228 | 229 | #icon { 230 | width: 30px; 231 | cursor: pointer; 232 | } 233 | 234 | .nav-menu-btn { 235 | display: none; 236 | } 237 | 238 | /*=============HOME SECTION=============*/ 239 | 240 | .home { 241 | position: relative; 242 | max-width: 1250px; 243 | min-height: 100vh; 244 | margin-left: auto; 245 | margin-right: auto; 246 | padding: 4rem 2rem; 247 | flex-direction: column; 248 | } 249 | 250 | .home .home-container { 251 | display: flex; 252 | justify-content: space-between; 253 | align-items: center; 254 | width: 100%; 255 | } 256 | 257 | .home-container .media-icons { 258 | display: flex; 259 | flex-direction: column; 260 | margin-right: 40px; 261 | } 262 | 263 | .home-container .media-icons a { 264 | color: #fff; /* Change icon color to white */ 265 | font-size: 1.5em; 266 | margin: 10px 0; 267 | } 268 | 269 | .home-container .media-icons a:hover { 270 | color: var(--hover-color); 271 | } 272 | 273 | .home-container .info h2 { 274 | font-size: 4em; 275 | font-weight: 600; 276 | line-height: 70px; 277 | } 278 | 279 | .home-container .info h3 { 280 | color: var(--third-color); 281 | font-feature-settings: 1.3em; 282 | font-weight: 600; 283 | line-height: 50px; 284 | } 285 | 286 | .home-container .info p { 287 | color: var(--third-color); 288 | font-size: var(--normal-font-size); 289 | max-width: 350px; 290 | } 291 | 292 | .btn { 293 | background: var(--second-color); 294 | color: #fff; 295 | font-size: var(--normal-font-size); 296 | font-weight: 500; 297 | display: inline-block; 298 | margin-top: 25px; 299 | padding: 20px 30px; 300 | letter-spacing: 1px; 301 | border-radius: 10px; 302 | } 303 | 304 | .btn:hover { 305 | background: var(--hover-color); 306 | } 307 | 308 | .home-container .home-img { 309 | position: relative; 310 | display: flex; 311 | justify-content: center; 312 | align-items: center; 313 | } 314 | 315 | .home-container .home-img img { 316 | width: 300px; /* Increased from 250px */ 317 | height: 300px; /* Increased from 250px */ 318 | border-radius: 50%; 319 | object-fit: cover; 320 | } 321 | 322 | .home .scroll-down { 323 | color: var(--first-color); 324 | font-size: var(--normal-font-size); 325 | font-weight: 500; 326 | margin-top: 20px; 327 | } 328 | 329 | .home .scroll-down i { 330 | color: var(--second-color); 331 | font-size: 1.2em; 332 | animation: arrow-down ease 2s infinite; 333 | } 334 | 335 | @keyframes arrow-down { 336 | 0% { 337 | transform: translateY(0); 338 | } 339 | 30% { 340 | transform: translateY(10px); 341 | } 342 | } 343 | 344 | /*=========Common sheet style=========*/ 345 | 346 | .flex-center { 347 | display: flex; 348 | justify-content: center; 349 | align-items: center; 350 | } 351 | 352 | .section { 353 | position: relative; 354 | max-width: 1150px; 355 | margin-left: auto; 356 | margin-right: auto; 357 | padding: 6rem 2rem 2rem; 358 | } 359 | 360 | .sub-section { 361 | position: relative; 362 | max-width: 1150px; 363 | margin-left: auto; 364 | margin-right: auto; 365 | padding: 6rem 0; 366 | } 367 | 368 | .section-title-01 { 369 | font-size: 4.5em; 370 | font-weight: 800; 371 | margin-bottom: 2rem; 372 | --webkit-background-clip: text; 373 | --webkit-text-fill-color: transparent; 374 | opacity: .1; 375 | } 376 | 377 | .section-title-02 { 378 | font-size: 2.5em; 379 | font-weight: 700; 380 | transform: translateY(-50px); 381 | } 382 | 383 | .section-title-02:before { 384 | content: ''; 385 | position: absolute; 386 | width: 100px; 387 | height: 5px; 388 | left: 5px; 389 | bottom: 0; 390 | background: var(--second-color); 391 | } 392 | 393 | .container { 394 | position: relative; 395 | flex-direction: column; 396 | } 397 | 398 | /*===========About section========*/ 399 | 400 | .about .container .content { 401 | column-gap: 150px; 402 | width: 100%; 403 | } 404 | 405 | .about-img { 406 | position: relative; 407 | } 408 | 409 | .about-img img { 410 | max-width: 100%; 411 | min-width: 500px; 412 | border-radius: 10px; 413 | } 414 | 415 | .about-info .description { 416 | max-width: 600px; 417 | } 418 | 419 | .about-info .description h3 { 420 | font-size: 2em; 421 | font-weight: 600; 422 | margin-bottom: 10px; 423 | } 424 | 425 | .about-info .description h4 { 426 | font-size: 1.3em; 427 | font-weight: 600; 428 | margin-bottom: 10px; 429 | } 430 | 431 | .about-info .description h4 span { 432 | color: var(--second-color); 433 | } 434 | 435 | .about-info .description p { 436 | color: var(--third-color); 437 | font-size: var(--normal-font-size); 438 | margin-bottom: 15px; 439 | padding-bottom: 25px; 440 | border-bottom: 2px solid var(--line-color); 441 | } 442 | 443 | .about-info .professional-list { 444 | display: flex; 445 | column-gap: 30px; 446 | } 447 | 448 | .about-info .professional-list .list-item { 449 | display: flex; 450 | justify-content: center; 451 | align-items: center; 452 | column-gap: 20px; 453 | margin-bottom: 20px; 454 | } 455 | 456 | .about-info .professional-list .list-item h3 { 457 | font-size: 2.5em; 458 | font-weight: 700; 459 | } 460 | 461 | .about-info .professional-list .list-item span { 462 | color: var(--third-color); 463 | font-size: var(--small-font-size); 464 | } 465 | 466 | /*======Skills Section=========*/ 467 | 468 | .skills .container .content { 469 | width: 100%; 470 | } 471 | 472 | .skills-description { 473 | max-width: 700px; 474 | margin-bottom: 50px; 475 | } 476 | 477 | .skills-description h3 { 478 | font-size: 2em; 479 | margin-bottom: 5px; 480 | } 481 | 482 | .skills-info { 483 | max-width: 100%; 484 | display: grid; 485 | grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 486 | gap: 250px; 487 | margin: 0 auto; 488 | } 489 | 490 | .skills-info h4 { 491 | margin-bottom: 20px; 492 | } 493 | 494 | .skills-info h4 label { 495 | background: var(--second-color); 496 | color: #fff; 497 | font-size: var(--normal-font-size); 498 | font-weight: 400; 499 | padding: 5px 15px; 500 | border-radius: 5px; 501 | } 502 | 503 | .education-all { 504 | margin-bottom: 0; /* Remove gap below education */ 505 | } 506 | 507 | .edu-list .item { 508 | background: var(--card-bg-color); 509 | box-shadow: var(--box-shadow); 510 | border-bottom: 3px solid var(--second-color); 511 | padding: 20px; 512 | margin-top: 15px; 513 | border-radius: 6px; 514 | transition: .3s ease; 515 | } 516 | 517 | .edu-list .item .year { 518 | font-size: var(--small-font-size); 519 | margin-bottom: 5px; 520 | color: var(--second-color); 521 | font-weight: 600; 522 | } 523 | 524 | .edu-list .item p { 525 | color: var(--first-color); 526 | font-size: var(--normal-font-size); 527 | } 528 | 529 | .edu-list .item p span { 530 | color: var(--second-color); 531 | font-weight: 600; 532 | } 533 | 534 | .bars { 535 | background: var(--card-bg-color); 536 | box-shadow: var(--box-shadow); 537 | margin-bottom: 10px; 538 | padding: 20px; 539 | border-radius: 6px; 540 | transition: .3s ease; 541 | } 542 | 543 | .bars .info { 544 | display: flex; 545 | justify-content: space-between; 546 | align-items: center; 547 | margin-bottom: 5px; 548 | font-size: var(--small-font-size); 549 | } 550 | 551 | .bars .info span { 552 | font-weight: 500; 553 | } 554 | 555 | .bars .line { 556 | position: relative; 557 | width: 100%; 558 | height: 7px; 559 | background: #c5cadf; 560 | border-radius: 2px; 561 | } 562 | 563 | .bars .line:before { 564 | content: ''; 565 | position: absolute; 566 | height: 100%; 567 | top: 0; 568 | left: 0; 569 | background: var(--second-color); 570 | border-radius: 2px; 571 | } 572 | 573 | .bars .html:before { 574 | width: 70%; 575 | } 576 | 577 | .bars .css:before { 578 | width: 65%; 579 | } 580 | 581 | .bars .javascript:before { 582 | width: 45%; 583 | } 584 | 585 | .bars .python:before { 586 | width: 90%; 587 | } 588 | 589 | .bars .cprog:before { 590 | width: 85%; 591 | } 592 | 593 | /* PROJECTS SECTION */ 594 | 595 | .projects .container .content { 596 | width: 100%; 597 | } 598 | 599 | .projects-list { 600 | display: grid; 601 | grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); 602 | max-width: 100%; 603 | gap: 25px; 604 | margin: 0 auto; 605 | padding: 20px 0; 606 | } 607 | 608 | .projects-list .img-card { 609 | position: relative; 610 | max-width: 100%; 611 | height: 250px; /* Changed from 400px to make it more rectangular */ 612 | border-radius: 10px; 613 | overflow: hidden; 614 | box-shadow: var(--box-shadow); 615 | cursor: pointer; 616 | transition: transform 0.3s ease; 617 | } 618 | 619 | .projects-list .img-card:hover { 620 | transform: translateY(-5px); 621 | } 622 | 623 | .projects-list .img-card .overlay { 624 | transition: 1s ease; 625 | width: 100%; 626 | } 627 | 628 | .projects-list .img-card:hover .overlay { 629 | z-index: 777; 630 | position: absolute; 631 | width: 100%; 632 | height: 100%; 633 | margin-top: 0px; 634 | background: rgba(0, 0, 0, 0.5); 635 | } 636 | 637 | .projects-list .img-card .info { 638 | z-index: 777; 639 | position: absolute; 640 | bottom: 0; 641 | left: 0; 642 | margin: 20px; 643 | color: var(--modal-bg-colour); 644 | transform: translateY(20px); 645 | opacity: 0; 646 | transition: .5s ease; 647 | } 648 | 649 | .projects-list .img-card:hover .info { 650 | transform: translateY(0); 651 | opacity: 1; 652 | background: rgba(0, 0, 0, 0.7); 653 | padding: 1rem; 654 | border-radius: 8px; 655 | } 656 | 657 | .projects-list .img-card .info h3 { 658 | font-size: 1.5em; 659 | } 660 | 661 | .projects-list .img-card .info span { 662 | font-size: 1.2em; 663 | } 664 | 665 | .projects-list .img-card img { 666 | width: 100%; 667 | height: 100%; 668 | object-fit: cover; 669 | object-position: top; /* Align image to top of container */ 670 | transition: .5s ease; 671 | } 672 | 673 | .project-model { 674 | z-index: 999999; 675 | position: fixed; 676 | top: 0; 677 | left: 0; 678 | width: 100%; 679 | height: 100vh; 680 | background: var(--transparent-colour-01); 681 | backdrop-filter: blur(20px); 682 | visibility: hidden; 683 | opacity: 0; 684 | transition: .3s ease; 685 | } 686 | 687 | .project-model-body { 688 | position: relative; 689 | max-width: 600px; 690 | margin: 20px; 691 | padding: 40px; 692 | background: var(--modal-bg-colour); 693 | box-shadow: var(--box-shadow); 694 | border-radius: 10px; 695 | transform: translateY(-50px); 696 | transition: .5s ease; 697 | } 698 | 699 | .project-model.active { 700 | visibility: visible; 701 | opacity: 1; 702 | } 703 | 704 | .project-model.active .project-model-body { 705 | transform: translateY(0); 706 | } 707 | 708 | .project-close-btn { 709 | position: absolute; 710 | top: 0; 711 | right: 0; 712 | margin: 20px; 713 | cursor: pointer; 714 | } 715 | 716 | .project-model-body h3 { 717 | font-size: 1.5em; 718 | } 719 | 720 | .project-model-body img { 721 | width: 100%; 722 | border-radius: 10px; 723 | margin: 20px 0; 724 | } 725 | 726 | /* Adjust for mobile screens */ 727 | @media screen and (max-width: 480px) { 728 | .projects-list { 729 | grid-template-columns: 1fr; /* Single column on mobile */ 730 | gap: 20px; 731 | } 732 | 733 | .projects-list .img-card { 734 | height: 200px; /* Slightly shorter on mobile */ 735 | } 736 | } 737 | 738 | /*===========Contact section===========*/ 739 | 740 | .contact .container .content { 741 | display: flex; 742 | justify-content: space-between; 743 | width: 100%; 744 | } 745 | 746 | .contact-left h2 { 747 | font-size: 2.1em; 748 | font-weight: 800; 749 | margin-bottom: 40px; 750 | } 751 | 752 | .contact-list li { 753 | margin-bottom: 40px; 754 | } 755 | 756 | .contact-list li h3 { 757 | font-size: 1.3em; 758 | font-weight: 600; 759 | margin-bottom: 10px; 760 | } 761 | 762 | .contact-list li h3 i { 763 | color: var(--second-color); 764 | font-size: 1.3em; 765 | margin-right: 10px; 766 | } 767 | 768 | .contact-list li span { 769 | color: var(--third-color); 770 | margin-left: 40px; 771 | } 772 | 773 | .contact-list li span a { 774 | color: var(--third-color); 775 | } 776 | 777 | .contact-right p { 778 | color: var(--first-color); 779 | font-size: 1.6em; 780 | margin-bottom: 30px; 781 | } 782 | 783 | .contact-right p span { 784 | color: var(--second-color); 785 | font-weight: 700; 786 | } 787 | 788 | .contact-form input, 789 | .contact-form textarea { 790 | border: none; 791 | color: var(--first-color); 792 | background: var(--transparent-colour-02); 793 | font-size: var(--normal-font-size); 794 | margin-bottom: 20px; 795 | padding: 15px 40px 40px 20px; 796 | border-radius: 5px; 797 | } 798 | 799 | .contact-form textarea { 800 | width: 100%; 801 | resize: none; 802 | } 803 | 804 | ::placeholder { 805 | color: var(--first-color); 806 | } 807 | 808 | .contact-form .first-row input { 809 | width: 100%; 810 | } 811 | 812 | .contact-form .second-row { 813 | display: flex; 814 | justify-content: space-between; 815 | } 816 | 817 | .contact-form .second-row input { 818 | width: 48%; 819 | } 820 | 821 | .contact-form .btn { 822 | border: none; 823 | margin-top: 0; 824 | border-radius: 5px; 825 | cursor: pointer; 826 | } 827 | 828 | /*=======Footer===========*/ 829 | 830 | footer { 831 | display: flex; 832 | justify-content: center; 833 | align-items: center; 834 | flex-direction: column; 835 | background: var(--second-color); 836 | width: 100%; 837 | margin-top: 50px; 838 | padding: 3rem 2rem; 839 | color: #fff; 840 | } 841 | 842 | footer a { 843 | color: #fff; 844 | } 845 | 846 | .footer-container { 847 | display: flex; 848 | justify-content: space-between; 849 | width: 100%; 850 | max-width: 1250px; 851 | } 852 | 853 | .footer-container .about img { 854 | width: 100px; /* Changed from 120px */ 855 | opacity: .8; 856 | padding-top: 8px; /* Added padding */ 857 | } 858 | 859 | .footer-container .about p { 860 | font-size: var(--normal-font-size); 861 | font-weight: 300; 862 | margin-bottom: 30px; 863 | } 864 | 865 | .footer-container .info, 866 | .footer-container .follow { 867 | display: flex; 868 | align-items: center; 869 | flex-direction: column; 870 | } 871 | 872 | .footer-container .info h3, 873 | .footer-container .follow h3 { 874 | font-size: 1.1em; 875 | font-weight: 500; 876 | margin-bottom: 30px; 877 | } 878 | 879 | .footer-container .info ul, 880 | .footer-container .follow ul { 881 | display: flex; 882 | } 883 | 884 | .footer-container .info a { 885 | margin: 20px; 886 | } 887 | 888 | .footer-container .follow a { 889 | font-size: 1.5em; 890 | margin: 20px; 891 | } 892 | 893 | .footer-copyright p { 894 | font-size: var(--normal-font-size); 895 | font-weight: 300; 896 | margin-top: 50px; 897 | } 898 | 899 | #progress { 900 | position: fixed; 901 | bottom: 20px; 902 | left: 20px; /* Changed from right to left */ 903 | height: 50px; 904 | width: 50px; 905 | display: none; 906 | place-items: center; 907 | border-radius: 50%; 908 | background: var(--second-color); /* Added solid background */ 909 | transition: all 0.3s ease; 910 | cursor: pointer; 911 | z-index: 999; /* Added z-index to stay above content */ 912 | } 913 | 914 | #progress:hover { 915 | opacity: 0.8; 916 | transform: translateY(-5px); 917 | } 918 | 919 | #progress-value { 920 | display: flex; 921 | align-items: center; 922 | justify-content: center; 923 | height: 100%; 924 | width: 100%; 925 | color: white; /* Changed color to white */ 926 | font-size: 20px; /* Adjusted size */ 927 | } 928 | 929 | /* Chatbot Styles */ 930 | 931 | #chatbot { 932 | position: fixed; 933 | bottom: 30px; 934 | right: 30px; 935 | width: 350px; 936 | background-color: rgba(255, 255, 255, 0.95); 937 | border-radius: 20px; 938 | box-shadow: 0 5px 25px rgba(0, 0, 0, 0.15); 939 | display: flex; 940 | flex-direction: column; 941 | overflow: hidden; 942 | transition: all 0.2s ease; /* Faster animation */ 943 | max-height: 500px; 944 | border: 1px solid rgba(106, 89, 209, 0.1); 945 | backdrop-filter: blur(10px); 946 | z-index: 999999; /* Move to very front */ 947 | } 948 | 949 | #chatbot-header { 950 | background: linear-gradient(135deg, var(--second-color), var(--hover-color)); 951 | color: white; 952 | padding: 15px 20px; 953 | display: flex; 954 | justify-content: space-between; 955 | align-items: center; 956 | border-bottom: 1px solid rgba(255, 255, 255, 0.1); 957 | } 958 | 959 | #chatbot-header h2 { 960 | font-size: 1.1em; 961 | font-weight: 500; 962 | } 963 | 964 | #chatbot-header .fa-robot { 965 | font-size: 1.2em; 966 | margin-right: 10px; 967 | } 968 | 969 | #chatbot-messages { 970 | flex: 1; 971 | padding: 20px; 972 | overflow-y: auto; 973 | max-height: 300px; 974 | scroll-behavior: smooth; 975 | } 976 | 977 | #chatbot-input { 978 | border: none; 979 | padding: 15px; 980 | width: 100%; 981 | background: rgba(106, 89, 209, 0.05); 982 | font-size: 0.9em; 983 | transition: all 0.3s ease; 984 | } 985 | 986 | #chatbot-input:focus { 987 | outline: none; 988 | background: rgba(106, 89, 209, 0.1); 989 | } 990 | 991 | #chatbot-send-btn { 992 | background: linear-gradient(135deg, var(--second-color), var(--hover-color)); 993 | color: white; 994 | border: none; 995 | padding: 15px 25px; 996 | cursor: pointer; 997 | transition: all 0.3s ease; 998 | } 999 | 1000 | #chatbot-send-btn:hover { 1001 | background: linear-gradient(135deg, var(--hover-color), var(--second-color)); 1002 | } 1003 | 1004 | #chatbot-close-btn, 1005 | #chatbot-minimize-btn { 1006 | background: none; 1007 | border: none; 1008 | color: white; 1009 | cursor: pointer; 1010 | font-size: 1.2em; 1011 | opacity: 0.8; 1012 | transition: opacity 0.2s ease; /* Faster animation */ 1013 | } 1014 | 1015 | #chatbot-close-btn:hover, 1016 | #chatbot-minimize-btn:hover { 1017 | opacity: 1; 1018 | } 1019 | 1020 | #chatbot-reopen-btn { 1021 | position: fixed; 1022 | bottom: 30px; 1023 | right: 30px; 1024 | background: linear-gradient(135deg, var(--second-color), var(--hover-color)); 1025 | color: white; 1026 | border: none; 1027 | padding: 15px 25px; 1028 | border-radius: 50px; 1029 | box-shadow: 0 5px 25px rgba(0, 0, 0, 0.15); 1030 | cursor: pointer; 1031 | transition: all 0.3s ease; 1032 | } 1033 | 1034 | #chatbot-reopen-btn:hover { 1035 | background: linear-gradient(135deg, var(--hover-color), var(--second-color)); 1036 | } 1037 | 1038 | .chatbot-message { 1039 | margin-bottom: 15px; 1040 | padding: 10px 15px; 1041 | border-radius: 15px; 1042 | max-width: 80%; 1043 | word-wrap: break-word; 1044 | } 1045 | 1046 | .user-message { 1047 | background: linear-gradient(135deg, var(--second-color), var(--hover-color)); 1048 | color: white; 1049 | margin-left: auto; 1050 | border-bottom-right-radius: 5px; 1051 | } 1052 | 1053 | .bot-message { 1054 | background: rgba(106, 89, 209, 0.1); 1055 | margin-right: auto; 1056 | border-bottom-left-radius: 5px; 1057 | } 1058 | 1059 | .dark-theme #chatbot { 1060 | background-color: rgba(14, 36, 49, 0.95); 1061 | border: 1px solid rgba(255, 255, 255, 0.1); 1062 | } 1063 | 1064 | .dark-theme #chatbot-input { 1065 | background: rgba(255, 255, 255, 0.05); 1066 | color: white; 1067 | } 1068 | 1069 | .dark-theme #chatbot-input:focus { 1070 | background: rgba(255, 255, 255, 0.1); 1071 | } 1072 | 1073 | .dark-theme .bot-message { 1074 | background: rgba(255, 255, 255, 0.1); 1075 | color: white; 1076 | } 1077 | 1078 | @media screen and (max-width: 480px) { 1079 | #chatbot { 1080 | width: 90%; 1081 | right: 5%; 1082 | bottom: 20px; 1083 | max-height: 70vh; /* Limit height on mobile */ 1084 | display: none; /* Start hidden on mobile */ 1085 | } 1086 | 1087 | #chatbot-reopen-btn { 1088 | display: block; /* Show button by default on mobile */ 1089 | right: 5%; 1090 | bottom: 20px; 1091 | padding: 15px 25px; 1092 | font-size: 1em; 1093 | z-index: 999999; 1094 | border-radius: 25px; 1095 | box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); 1096 | } 1097 | 1098 | #chatbot-messages { 1099 | max-height: 50vh; /* Adjust message container height */ 1100 | } 1101 | } 1102 | 1103 | @media screen and (max-width: 768px) { 1104 | #chatbot { 1105 | width: 90%; 1106 | right: 5%; 1107 | bottom: 20px; 1108 | } 1109 | #chatbot-reopen-btn { 1110 | right: 5%; 1111 | bottom: 20px; 1112 | padding: 10px 20px; 1113 | font-size: 0.9em; 1114 | } 1115 | #progress { 1116 | width: 50px; /* Ensure consistency */ 1117 | height: 50px; /* Ensure consistency */ 1118 | } 1119 | } 1120 | 1121 | /* =============Media Queries =====================*/ 1122 | 1123 | @media screen and (max-width: 1070px) { 1124 | /* ===NAV BAR=== */ 1125 | .navigation { 1126 | position: fixed; 1127 | width: 100%; 1128 | height: 100vh; 1129 | top: 0; 1130 | left: 0; 1131 | display: flex; 1132 | justify-content: center; 1133 | align-items: center; 1134 | background: var(--transparent-colour-01); 1135 | visibility: hidden; 1136 | opacity: 0; 1137 | transition: .3s ease; 1138 | } 1139 | .navigation.active { 1140 | visibility: visible; 1141 | opacity: 1; 1142 | } 1143 | .nav-items { 1144 | position: relative; 1145 | background: var(--modal-bg-colour); 1146 | width: 600px; 1147 | max-width: 600px; 1148 | display: flex; 1149 | flex-direction: column; 1150 | align-items: center; 1151 | margin: 20px; 1152 | padding: 40px; 1153 | border-radius: 10px; 1154 | box-shadow: var(--box-shadow); 1155 | transform: translateY(-50px); 1156 | transition: .3 ease; 1157 | } 1158 | .navigation.active .nav-items { 1159 | transform: translateY(0); 1160 | } 1161 | .nav-items a { 1162 | margin: 15px 50px; 1163 | } 1164 | .nav-close-btn { 1165 | position: absolute; 1166 | background: url(images/close-icon.png)no-repeat; 1167 | background-size: 12px; 1168 | background-position: center; 1169 | width: 40px; 1170 | height: 40px; 1171 | top: 0; 1172 | right: 0; 1173 | cursor: pointer; 1174 | margin: 10px; 1175 | } 1176 | .nav-menu-btn { 1177 | background: url(images/nav-menu.png)no-repeat; 1178 | background-size: 30px; 1179 | background-position: center; 1180 | width: 40px; 1181 | height: 40px; 1182 | padding-right: 15px; 1183 | cursor: pointer; 1184 | display: block; 1185 | } 1186 | /* =========HOME SECTION======= */ 1187 | .home .container .content { 1188 | font-size: 0.85rem; 1189 | } 1190 | .home-container .home-img img { 1191 | width: 250px; /* Increased from 200px */ 1192 | height: 250px; /* Increased from 200px */ 1193 | } 1194 | /* =========ABOUT SECTION========= */ 1195 | .about .container .content { 1196 | display: grid; 1197 | width: 100%; 1198 | row-gap: 20px; 1199 | } 1200 | .about-img img { 1201 | min-width: 0; 1202 | width: 100%; 1203 | } 1204 | .about-info { 1205 | min-width: 0; 1206 | width: 100%; 1207 | } 1208 | .about-info .professional-list { 1209 | flex-direction: column; 1210 | } 1211 | .about-info .professional-list .list-item { 1212 | justify-content: start; 1213 | } 1214 | /*========== CONTACT SECTION========= */ 1215 | .contact .content { 1216 | flex-direction: column; 1217 | font-size: 0.9rem; 1218 | } 1219 | .contact .contact-left { 1220 | margin-bottom: 40px; 1221 | } 1222 | .contact-form .second-row { 1223 | flex-direction: column; 1224 | } 1225 | .contact-form .second-row input { 1226 | width: 100%; 1227 | } 1228 | /* =========FOOTER========= */ 1229 | footer .footer-container { 1230 | flex-direction: column; 1231 | } 1232 | .footer-container .about, 1233 | .footer-container .info { 1234 | display: flex; 1235 | justify-content: center; 1236 | align-items: center; 1237 | flex-direction: column; 1238 | margin-bottom: 50px; 1239 | } 1240 | .footer-container .info ul { 1241 | align-items: center; 1242 | flex-direction: column; 1243 | } 1244 | .footer-container .info ul li { 1245 | margin: 5px 0; 1246 | } 1247 | .footer-container .hr { 1248 | width: 100%; 1249 | height: 2px; 1250 | background: rgba(255, 255, 255, 0.1); 1251 | margin: 10px 0 22px; 1252 | } 1253 | .dark-theme .nav-items { 1254 | background: #1a3442; 1255 | } 1256 | } 1257 | 1258 | @media screen and (max-width: 730px) { 1259 | body { 1260 | margin: 5rem 0 0 0; 1261 | } 1262 | .section-title-01 { 1263 | font-size: 3em; 1264 | } 1265 | .section-title-02 { 1266 | font-size: 2em; 1267 | transform: translateY(-65px); 1268 | } 1269 | .home .home-container { 1270 | display: flex; 1271 | flex-direction: column-reverse; 1272 | gap: 2rem; 1273 | } 1274 | 1275 | .home-container .home-img { 1276 | position: relative; 1277 | width: 100%; 1278 | transform: none; 1279 | } 1280 | 1281 | .home-container .home-img img { 1282 | width: 200px; /* Increased from 150px */ 1283 | height: 200px; /* Increased from 150px */ 1284 | } 1285 | 1286 | .home .home-container .info { 1287 | font-size: 0.8rem; 1288 | text-align: center; 1289 | } 1290 | 1291 | .media-icons { 1292 | position: relative; 1293 | margin-bottom: 2rem; 1294 | } 1295 | .home .home-container .info { 1296 | font-size: 0.8rem; 1297 | } 1298 | .media-icons { 1299 | margin-bottom: 80px; 1300 | } 1301 | .dark-theme .nav-items { 1302 | background-color: #1a3442; 1303 | } 1304 | } 1305 | 1306 | /* New styles for the updated skills section */ 1307 | 1308 | .skills-grid { 1309 | display: grid; 1310 | grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); 1311 | gap: 2rem; 1312 | margin-top: 2rem; 1313 | } 1314 | 1315 | .skill-category { 1316 | background: var(--card-bg-color); 1317 | padding: 1.5rem; 1318 | border-radius: 10px; 1319 | box-shadow: var(--box-shadow); 1320 | transition: transform 0.3s ease; 1321 | } 1322 | 1323 | .skill-category:hover { 1324 | transform: translateY(-5px); 1325 | } 1326 | 1327 | .skill-category h5 { 1328 | color: var(--second-color); 1329 | font-size: 1.2em; 1330 | margin-bottom: 1rem; 1331 | padding-bottom: 0.5rem; 1332 | border-bottom: 2px solid var(--transparent-colour-02); 1333 | } 1334 | 1335 | .skill-tags { 1336 | display: flex; 1337 | flex-wrap: wrap; 1338 | gap: 0.8rem; 1339 | } 1340 | 1341 | .skill-tags li { 1342 | background: var(--transparent-colour-02); 1343 | color: var(--first-color); 1344 | padding: 0.5rem 1rem; 1345 | border-radius: 25px; 1346 | font-size: 0.9em; 1347 | transition: all 0.3s ease; 1348 | } 1349 | 1350 | .skill-tags li:hover { 1351 | background: var(--second-color); 1352 | color: white; 1353 | transform: translateY(-2px); 1354 | } 1355 | 1356 | .dark-theme .skill-category { 1357 | background: var(--transparent-colour-02); 1358 | } 1359 | 1360 | .dark-theme .skill-tags li { 1361 | background: rgba(255, 255, 255, 0.1); 1362 | color: var(--body-bg-color); 1363 | } 1364 | 1365 | .dark-theme .skill-tags li:hover { 1366 | background: var(--second-color); 1367 | } 1368 | 1369 | /* Update existing progress bars */ 1370 | .bars .sql:before { 1371 | width: 85%; 1372 | } 1373 | 1374 | /* Responsive adjustments */ 1375 | @media screen and (max-width: 768px) { 1376 | .skills-grid { 1377 | grid-template-columns: 1fr; 1378 | gap: 1.5rem; 1379 | } 1380 | 1381 | .skill-category { 1382 | padding: 1rem; 1383 | } 1384 | 1385 | .skill-tags { 1386 | gap: 0.5rem; 1387 | } 1388 | 1389 | .skill-tags li { 1390 | font-size: 0.8em; 1391 | padding: 0.4rem 0.8rem; 1392 | } 1393 | } 1394 | 1395 | /* ...existing code... */ 1396 | 1397 | .edu-list { 1398 | margin-bottom: 2rem; 1399 | } 1400 | 1401 | .edu-list:last-child { 1402 | margin-bottom: 0; 1403 | } 1404 | 1405 | .education h4:not(:first-child) { 1406 | margin-top: 2.5rem; 1407 | } 1408 | 1409 | .edu-list .item { 1410 | background: var(--card-bg-color); 1411 | box-shadow: var(--box-shadow); 1412 | border-bottom: 3px solid var(--second-color); 1413 | padding: 20px; 1414 | margin-top: 15px; 1415 | border-radius: 6px; 1416 | transition: .3s ease; 1417 | } 1418 | 1419 | .edu-list .item:hover { 1420 | transform: translateX(10px); 1421 | } 1422 | 1423 | /* Dark theme adjustments */ 1424 | .dark-theme .edu-list .item { 1425 | background: var(--transparent-colour-02); 1426 | } 1427 | 1428 | /* Mobile responsiveness */ 1429 | @media screen and (max-width: 768px) { 1430 | .edu-list .item { 1431 | padding: 15px; 1432 | } 1433 | 1434 | .edu-list .item:hover { 1435 | transform: none; 1436 | } 1437 | } 1438 | 1439 | /* ...existing code... */ 1440 | 1441 | /* Certification Dropdown Styles */ 1442 | .certification-dropdown { 1443 | margin-top: 2rem; 1444 | } 1445 | 1446 | .dropdown-btn { 1447 | width: 100%; 1448 | padding: 15px 20px; 1449 | background: var(--second-color); 1450 | color: white; 1451 | border: none; 1452 | border-radius: 6px; 1453 | cursor: pointer; 1454 | display: flex; 1455 | justify-content: space-between; 1456 | align-items: center; 1457 | font-size: var(--normal-font-size); 1458 | transition: 0.3s ease; 1459 | margin: 0; 1460 | } 1461 | 1462 | .dropdown-btn:hover { 1463 | background: var(--hover-color); 1464 | } 1465 | 1466 | .dropdown-btn i { 1467 | transition: 0.3s ease; 1468 | } 1469 | 1470 | .dropdown-content { 1471 | display: none; 1472 | padding-top: 15px; 1473 | } 1474 | 1475 | .dropdown-content.active { 1476 | display: block; 1477 | } 1478 | 1479 | .dropdown-btn.active i { 1480 | transform: rotate(180deg); 1481 | } 1482 | 1483 | /* Dark theme adjustments */ 1484 | .dark-theme .edu-list .item { 1485 | background: var(--transparent-colour-02); 1486 | } 1487 | 1488 | .dark-theme .edu-list .item p { 1489 | color: var(--body-bg-color); 1490 | } 1491 | 1492 | /* Mobile adjustments */ 1493 | @media screen and (max-width: 768px) { 1494 | .dropdown-btn { 1495 | padding: 12px 15px; 1496 | font-size: 0.9em; 1497 | } 1498 | } 1499 | 1500 | /* ...existing code... */ 1501 | 1502 | .info-section { 1503 | margin-bottom: 0; /* Remove gap between info sections */ 1504 | } 1505 | 1506 | .dropdown-btn { 1507 | width: 100%; 1508 | padding: 1rem 1.5rem; 1509 | background: var(--second-color); 1510 | color: white; 1511 | border: none; 1512 | border-radius: 8px; 1513 | cursor: pointer; 1514 | display: flex; 1515 | justify-content: space-between; 1516 | align-items: center; 1517 | font-size: 1.1em; 1518 | transition: 0.3s ease; 1519 | margin: 0; 1520 | } 1521 | 1522 | .dropdown-btn:hover { 1523 | background: var(--hover-color); 1524 | } 1525 | 1526 | .dropdown-btn i { 1527 | transition: 0.3s ease; 1528 | } 1529 | 1530 | .dropdown-content { 1531 | display: none; 1532 | padding: 1rem 0; 1533 | } 1534 | 1535 | .dropdown-content.active { 1536 | display: block; 1537 | } 1538 | 1539 | .dropdown-btn.active i { 1540 | transform: rotate(180deg); 1541 | } 1542 | 1543 | .preview { 1544 | margin-bottom: 1rem; 1545 | } 1546 | 1547 | .hidden-content { 1548 | display: none; 1549 | } 1550 | 1551 | .hidden-content.active { 1552 | display: block; 1553 | } 1554 | 1555 | .view-more-btn { 1556 | width: 100%; 1557 | padding: 0.8rem; 1558 | margin-top: 1rem; 1559 | background: var(--transparent-colour-02); 1560 | color: var(--second-color); 1561 | border: 1px solid var(--second-color); 1562 | border-radius: 6px; 1563 | cursor: pointer; 1564 | transition: 0.3s ease; 1565 | } 1566 | 1567 | .view-more-btn:hover { 1568 | background: var(--second-color); 1569 | color: white; 1570 | } 1571 | 1572 | /* Update skill tags style */ 1573 | .skill-tags { 1574 | display: flex; 1575 | flex-wrap: wrap; 1576 | gap: 0.8rem; 1577 | margin-top: 1rem; 1578 | } 1579 | 1580 | .skill-tags li { 1581 | background: var(--transparent-colour-02); 1582 | color: var(--first-color); 1583 | padding: 0.5rem 1rem; 1584 | border-radius: 25px; 1585 | font-size: 0.9em; 1586 | transition: all 0.3s ease; 1587 | } 1588 | 1589 | /* ...existing code... */ 1590 | 1591 | .skills { 1592 | margin-top: 0; /* Remove gap above skills section */ 1593 | } 1594 | 1595 | .info-section + .info-section { 1596 | margin-top: 0; 1597 | } 1598 | 1599 | .dropdown-btn { 1600 | margin: 0; 1601 | border-radius: 0; 1602 | } 1603 | 1604 | .info-section:first-child .dropdown-btn { 1605 | border-top-left-radius: 8px; 1606 | border-top-right-radius: 8px; 1607 | } 1608 | 1609 | .info-section:last-child .dropdown-btn { 1610 | border-bottom-left-radius: 8px; 1611 | border-bottom-right-radius: 8px; 1612 | } 1613 | 1614 | .dropdown-content { 1615 | padding: 1rem 0 0 0; 1616 | margin: 0; 1617 | } 1618 | 1619 | /* ...existing code... */ 1620 | 1621 | /* Remove spaces between dropdown buttons */ 1622 | .info-section { 1623 | margin: 0; 1624 | padding: 0; 1625 | } 1626 | 1627 | .info-section:not(:first-child) .dropdown-btn { 1628 | border-top: 1px solid rgba(255, 255, 255, 0.1); 1629 | } 1630 | 1631 | .dropdown-btn { 1632 | margin: 0; 1633 | padding: 15px 20px; 1634 | border-radius: 0; 1635 | } 1636 | 1637 | .info-section:first-child .dropdown-btn { 1638 | border-radius: 8px 8px 0 0; 1639 | } 1640 | 1641 | .info-section:last-child .dropdown-btn { 1642 | border-radius: 0 0 8px 8px; 1643 | } 1644 | 1645 | .dropdown-content { 1646 | padding: 15px; 1647 | margin: 0; 1648 | border-bottom: none; 1649 | } 1650 | 1651 | /* Remove any inherited margins */ 1652 | .skills-info { 1653 | margin: 0; 1654 | padding: 0; 1655 | } 1656 | 1657 | .education-all { 1658 | margin: 0; 1659 | padding: 0; 1660 | } 1661 | 1662 | /* ...existing code... */ 1663 | 1664 | /* Reset spacing for skills section */ 1665 | .skills-info { 1666 | margin: 0; 1667 | padding: 0; 1668 | } 1669 | 1670 | /* New dropdown section styles */ 1671 | .info-sections-container { 1672 | background: var(--card-bg-color); 1673 | border-radius: 8px; 1674 | overflow: hidden; 1675 | box-shadow: var(--box-shadow); 1676 | } 1677 | 1678 | .info-section { 1679 | border-bottom: 1px solid rgba(255, 255, 255, 0.1); 1680 | } 1681 | 1682 | .info-section:last-child { 1683 | border-bottom: none; 1684 | } 1685 | 1686 | .dropdown-btn { 1687 | width: 100%; 1688 | padding: 1.2rem; 1689 | background: var(--second-color); 1690 | color: white; 1691 | border: none; 1692 | border-radius: 0; 1693 | cursor: pointer; 1694 | display: flex; 1695 | justify-content: space-between; 1696 | align-items: center; 1697 | font-size: 1.1em; 1698 | transition: 0.3s ease; 1699 | } 1700 | 1701 | .dropdown-btn:hover { 1702 | background: var(--hover-color); 1703 | } 1704 | 1705 | .dropdown-content { 1706 | display: none; 1707 | background: var(--body-bg-color); 1708 | padding: 1.2rem; 1709 | } 1710 | 1711 | .dropdown-content.active { 1712 | display: block; 1713 | } 1714 | 1715 | /* Dark theme adjustments */ 1716 | .dark-theme .info-sections-container { 1717 | background: var(--transparent-colour-02); 1718 | } 1719 | 1720 | .dark-theme .dropdown-content { 1721 | background: var(--transparent-colour-02); 1722 | } 1723 | 1724 | /* ...existing code... */ 1725 | 1726 | /* Flex container for side-by-side layout */ 1727 | .flex-container { 1728 | display: flex; 1729 | justify-content: space-between; 1730 | gap: 2rem; 1731 | } 1732 | 1733 | /* Ensure each section takes equal space */ 1734 | .info-section { 1735 | flex: 1; 1736 | background: var(--card-bg-color); 1737 | border-radius: 8px; 1738 | overflow: hidden; 1739 | box-shadow: var(--box-shadow); 1740 | margin-bottom: 0; 1741 | } 1742 | 1743 | /* Adjust dropdown button styles */ 1744 | .dropdown-btn { 1745 | width: 100%; 1746 | padding: 1.2rem; 1747 | background: var(--second-color); 1748 | color: white; 1749 | border: none; 1750 | border-radius: 0; 1751 | cursor: pointer; 1752 | display: flex; 1753 | justify-content: space-between; 1754 | align-items: center; 1755 | font-size: 1.1em; 1756 | transition: 0.3s ease; 1757 | } 1758 | 1759 | .dropdown-btn:hover { 1760 | background: var(--hover-color); 1761 | } 1762 | 1763 | /* Adjust dropdown content styles */ 1764 | .dropdown-content { 1765 | display: none; 1766 | background: var(--body-bg-color); 1767 | padding: 1.2rem; 1768 | } 1769 | 1770 | .dropdown-content.active { 1771 | display: block; 1772 | } 1773 | 1774 | /* Dark theme adjustments */ 1775 | .dark-theme .info-section { 1776 | background: var(--transparent-colour-02); 1777 | } 1778 | 1779 | .dark-theme .dropdown-content { 1780 | background: var(--transparent-colour-02); 1781 | } 1782 | 1783 | /* Responsive adjustments */ 1784 | @media screen and (max-width: 768px) { 1785 | .flex-container { 1786 | flex-direction: column; 1787 | } 1788 | } 1789 | 1790 | .dropdown-content { 1791 | /* ...existing code... */ 1792 | color: #fff !important; 1793 | } 1794 | 1795 | .dropdown-content * { 1796 | color: #fff !important; 1797 | } 1798 | 1799 | .edu-list .item p, 1800 | .edu-list .item .year, 1801 | .edu-list .item p span, 1802 | .skill-category h5, 1803 | .skill-tags li { 1804 | color: #fff !important; 1805 | } 1806 | 1807 | /* Ensure white text in dark theme */ 1808 | .dark-theme .dropdown-content, 1809 | .dark-theme .edu-list .item p, 1810 | .dark-theme .edu-list .item .year, 1811 | .dark-theme .edu-list .item p span, 1812 | .dark-theme .skill-category h5, 1813 | .dark-theme .skill-tags li { 1814 | color: #fff !important; 1815 | } 1816 | 1817 | /* ...existing code... */ 1818 | 1819 | .tech-stack { 1820 | display: flex; 1821 | gap: 1rem; 1822 | margin-top: 0.5rem; 1823 | } 1824 | 1825 | .tech-stack i { 1826 | color: #fff; 1827 | font-size: 1.2em; 1828 | transition: transform 0.3s ease; 1829 | } 1830 | 1831 | .tech-stack i:hover { 1832 | transform: translateY(-3px); 1833 | color: var(--second-color); 1834 | } 1835 | 1836 | /* ...existing code... */ 1837 | 1838 | .project-tech-stack { 1839 | display: flex; 1840 | gap: 1.5rem; 1841 | margin: 1rem 0; 1842 | padding: 1rem; 1843 | background: rgba(0, 0, 0, 0.1); 1844 | border-radius: 8px; 1845 | justify-content: center; 1846 | } 1847 | 1848 | .project-tech-stack i { 1849 | font-size: 1.5em; 1850 | color: var(--second-color); 1851 | transition: transform 0.3s ease; 1852 | } 1853 | 1854 | .project-tech-stack i:hover { 1855 | transform: translateY(-3px); 1856 | color: var(--hover-color); 1857 | } 1858 | 1859 | .dark-theme .project-tech-stack { 1860 | background: rgba(255, 255, 255, 0.1); 1861 | } 1862 | 1863 | .dark-theme .project-tech-stack i { 1864 | color: #fff; 1865 | } 1866 | 1867 | /* ...existing code... */ 1868 | 1869 | /* ...existing code... */ 1870 | 1871 | .typing-animation { 1872 | display: flex; 1873 | gap: 5px; 1874 | padding: 10px 15px; 1875 | background: rgba(106, 89, 209, 0.1); 1876 | border-radius: 15px; 1877 | margin-bottom: 15px; 1878 | max-width: 60px; 1879 | } 1880 | 1881 | .typing-dot { 1882 | width: 8px; 1883 | height: 8px; 1884 | background: var(--second-color); 1885 | border-radius: 50%; 1886 | animation: typing 1.5s infinite ease-in-out; 1887 | } 1888 | 1889 | .typing-dot:nth-child(2) { 1890 | animation-delay: 0.2s; 1891 | } 1892 | 1893 | .typing-dot:nth-child(3) { 1894 | animation-delay: 0.4s; 1895 | } 1896 | 1897 | @keyframes typing { 1898 | 0%, 100% { 1899 | transform: translateY(0); 1900 | opacity: 0.3; 1901 | } 1902 | 50% { 1903 | transform: translateY(-5px); 1904 | opacity: 1; 1905 | } 1906 | } 1907 | 1908 | .dark-theme .typing-animation { 1909 | background: rgba(255, 255, 255, 0.1); 1910 | } 1911 | 1912 | .dark-theme .typing-dot { 1913 | background: #fff; 1914 | } 1915 | 1916 | /* ...existing code... */ 1917 | 1918 | /* ...existing code... */ 1919 | 1920 | #chatbot-header .fa-comments { /* Changed from .fa-robot to .fa-comments */ 1921 | font-size: 1.4em; /* Slightly larger size */ 1922 | margin-right: 10px; 1923 | color: #fff; 1924 | animation: pulse 2s infinite; /* Add subtle animation */ 1925 | } 1926 | 1927 | @keyframes pulse { 1928 | 0% { transform: scale(1); } 1929 | 50% { transform: scale(1.1); } 1930 | 100% { transform: scale(1); } 1931 | } 1932 | 1933 | /* ...existing code... */ 1934 | 1935 | --------------------------------------------------------------------------------