adamqab commited on
Commit
68ed2c7
·
verified ·
1 Parent(s): 2e12a31

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +122 -194
index.html CHANGED
@@ -35,113 +35,133 @@
35
  url('https://i.postimg.cc/hjBVvCM8/4uoIBUi.jpg') no-repeat center center/cover;
36
  }
37
 
38
- /* Chatbot Styles */
39
- .chatbot-container {
40
- max-width: 500px;
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  width: 100%;
42
- margin-bottom: 2rem;
43
- background: rgba(26, 26, 46, 0.7);
 
 
44
  backdrop-filter: blur(10px);
45
- border: 1px solid rgba(255, 215, 0, 0.2);
46
- border-radius: 12px;
47
- box-shadow: 0 8px 16px rgba(0,0,0,0.3);
48
- overflow: hidden;
49
- display: flex;
50
- flex-direction: column;
51
  }
52
- .chat-window {
53
- height: 200px;
54
- padding: 1rem;
55
- overflow-y: auto;
56
- display: flex;
57
- flex-direction: column;
58
- gap: 0.75rem;
59
  }
60
- .chat-message {
61
- padding: 0.5rem 1rem;
62
- border-radius: 10px;
63
- max-width: 80%;
64
- line-height: 1.4;
65
- word-wrap: break-word;
66
  }
67
- .user-message {
68
- background-color: var(--primary-red);
69
- color: white;
70
- align-self: flex-end;
71
- border-bottom-right-radius: 2px;
 
 
 
 
 
 
 
72
  }
73
- .bot-message {
74
- background-color: #333;
75
- color: #f1f1f1;
76
- align-self: flex-start;
77
- border-bottom-left-radius: 2px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  }
79
- .chat-input-area {
80
- display: flex;
81
- border-top: 1px solid rgba(255, 215, 0, 0.2);
 
 
82
  }
83
- #chat-input {
84
- flex-grow: 1;
85
- background: transparent;
86
- border: none;
87
  color: white;
88
- padding: 0.75rem 1rem;
 
 
89
  outline: none;
 
 
90
  }
91
- #send-btn {
92
- background: var(--primary-red);
93
- border: none;
94
- color: white;
95
- padding: 0.75rem 1.25rem;
96
- cursor: pointer;
97
- transition: background-color 0.3s;
98
  }
99
- #send-btn:hover {
100
- background-color: #c42d38;
 
101
  }
102
 
103
- /* Existing Styles */
104
- .nav-link { position: relative; }
105
- .nav-link::after { content: ''; position: absolute; width: 0; height: 2px; bottom: -2px; left: 0; background-color: var(--primary-gold); transition: width 0.3s ease; }
106
- .nav-link:hover::after { width: 100%; }
107
- .project-card { background: rgba(26, 26, 46, 0.5); backdrop-filter: blur(10px); border: 1px solid rgba(255, 215, 0, 0.1); transition: all 0.3s ease; }
108
- .project-card:hover { transform: translateY(-10px); box-shadow: 0 10px 20px rgba(230, 57, 70, 0.3); border-color: rgba(255, 215, 0, 0.3); }
109
- .gold-accent { color: var(--primary-gold); }
110
- .red-accent { color: var(--primary-red); }
111
- .section-divider { height: 100px; background: linear-gradient(to bottom, var(--primary-black), var(--space-blue)); }
112
- .tech-icon { transition: all 0.3s ease; }
113
- .tech-icon:hover { transform: scale(1.2); color: var(--primary-gold); }
114
- .floating { animation: floating 3s ease-in-out infinite; }
115
- @keyframes floating { 0% { transform: translateY(0px); } 50% { transform: translateY(-15px); } 100% { transform: translateY(0px); } }
116
- .glow { text-shadow: 0 0 10px rgba(255, 215, 0, 0.7); }
117
- .typewriter { overflow: hidden; border-right: 3px solid var(--primary-gold); white-space: nowrap; margin: 0 auto; letter-spacing: 2px; animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite; }
118
- @keyframes typing { from { width: 0 } to { width: 100% } }
119
- @keyframes blink-caret { from, to { border-color: transparent } 50% { border-color: var(--primary-gold) } }
120
- .scroll-indicator { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); animation: bounce 2s infinite; }
121
- @keyframes bounce { 0%, 20%, 50%, 80%, 100% { transform: translateY(0) translateX(-50%); } 40% { transform: translateY(-20px) translateX(-50%); } 60% { transform: translateY(-10px) translateX(-50%); } }
122
- .contact-input { background: rgba(26, 26, 46, 0.5); border: 1px solid rgba(255, 215, 0, 0.2); color: white; }
123
- .contact-input:focus { outline: none; border-color: var(--primary-gold); box-shadow: 0 0 10px rgba(255, 215, 0, 0.3); }
124
- .animate-fadeIn { animation: fadeIn 1s ease-out; }
125
- @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
126
-
127
  </style>
128
  </head>
129
  <body>
130
- <section class="hero-section relative flex flex-col items-center justify-center text-center overflow-hidden p-4">
131
  <div class="absolute inset-0 bg-black opacity-40"></div>
132
- <div class="relative z-10 flex flex-col items-center justify-center w-full max-w-4xl px-6">
133
-
134
- <div id="chatbot" class="chatbot-container">
135
- <div id="chat-window" class="chat-window">
136
- <div class="chat-message bot-message">Hello! Ask me about Adham, or give me a simple math problem.</div>
137
- </div>
138
- <div class="chat-input-area">
139
- <input type="text" id="chat-input" placeholder="Type your message..." autocomplete="off">
140
- <button id="send-btn" aria-label="Send message">
141
- <i class="fas fa-paper-plane"></i>
142
- </button>
143
- </div>
144
- </div>
145
  <h1 class="text-5xl md:text-7xl font-bold mb-6 glow">
146
  ADHAM <span class="red-accent">QAB</span>
147
  </h1>
@@ -576,8 +596,12 @@
576
  e.preventDefault();
577
  const targetElement = document.querySelector(this.getAttribute('href'));
578
  if (targetElement) {
579
- targetElement.scrollIntoView({ behavior: 'smooth' });
 
 
580
  }
 
 
581
  const mobileMenu = document.getElementById('mobile-menu');
582
  if (mobileMenu && !mobileMenu.classList.contains('hidden')) {
583
  mobileMenu.classList.add('hidden');
@@ -588,6 +612,7 @@
588
  // Mobile menu toggle
589
  const mobileMenuButton = document.querySelector('.mobile-menu-button');
590
  const mobileMenu = document.getElementById('mobile-menu');
 
591
  if (mobileMenuButton && mobileMenu) {
592
  mobileMenuButton.addEventListener('click', function() {
593
  mobileMenu.classList.toggle('hidden');
@@ -599,125 +624,28 @@
599
  entries.forEach(entry => {
600
  if (entry.isIntersecting) {
601
  entry.target.classList.add('animate-fadeIn');
602
- observer.unobserve(entry.target);
603
  }
604
  });
605
  }, { threshold: 0.1 });
 
606
  document.querySelectorAll('.project-card, .achievement-card').forEach(card => {
607
  observer.observe(card);
608
  });
609
 
610
- // Typewriter effect
611
  const typewriterElement = document.querySelector('.typewriter');
612
  if (typewriterElement) {
 
 
613
  setTimeout(() => {
614
  typewriterElement.style.borderRight = 'none';
615
- }, 3500);
616
  }
617
 
618
- // Update copyright year
619
  document.getElementById('currentYear').textContent = new Date().getFullYear();
620
 
621
- // --- NEW CHATBOT JAVASCRIPT (NO API) ---
622
- const chatWindow = document.getElementById('chat-window');
623
- const chatInput = document.getElementById('chat-input');
624
- const sendBtn = document.getElementById('send-btn');
625
-
626
- const addMessage = (message, sender) => {
627
- const messageElement = document.createElement('div');
628
- messageElement.classList.add('chat-message', `${sender}-message`);
629
- messageElement.textContent = message;
630
- chatWindow.appendChild(messageElement);
631
- chatWindow.scrollTop = chatWindow.scrollHeight;
632
- };
633
-
634
- const handleSendMessage = () => {
635
- const userMessage = chatInput.value.trim();
636
- if (!userMessage) return;
637
-
638
- addMessage(userMessage, 'user');
639
- chatInput.value = '';
640
-
641
- // Generate bot response instantly
642
- const botResponse = generateBotResponse(userMessage);
643
-
644
- // Add a small delay for a more natural feel
645
- setTimeout(() => {
646
- addMessage(botResponse, 'bot');
647
- }, 500);
648
- };
649
-
650
- const performSafeCalculation = (expression) => {
651
- // This function safely evaluates a mathematical expression.
652
- // It only allows numbers, basic operators, parentheses, and spaces.
653
- // It prevents execution of harmful code.
654
- const sanitizedExpression = expression.replace(/[^-\d/*+().\s]/g, '');
655
-
656
- // Check if the expression contains at least one number and one operator
657
- if (!/[\d]/.test(sanitizedExpression) || !/[-+*/]/.test(sanitizedExpression)) {
658
- return null;
659
- }
660
-
661
- try {
662
- // Using the Function constructor is safer than a direct eval().
663
- const result = new Function('return ' + sanitizedExpression)();
664
- if (typeof result === 'number' && isFinite(result)) {
665
- return result;
666
- }
667
- return null; // Not a valid number
668
- } catch (error) {
669
- return null; // Error during evaluation
670
- }
671
- };
672
-
673
- const generateBotResponse = (userInput) => {
674
- const lowerInput = userInput.toLowerCase();
675
-
676
- // --- Calculation Check ---
677
- // First, try to see if it's a math problem.
678
- const calcResult = performSafeCalculation(lowerInput);
679
- if (calcResult !== null) {
680
- return `The result is ${calcResult}.`;
681
- }
682
-
683
- // --- Keyword-Based Q&A ---
684
- if (lowerInput.includes('hello') || lowerInput.includes('hi') || lowerInput.includes('hey')) {
685
- return 'Hello there! You can ask me about Adham or give me a simple calculation.';
686
- }
687
- if (lowerInput.includes('who are you') || lowerInput.includes('your name')) {
688
- return 'I am a simple chatbot designed to answer questions about Adham Qab\'s portfolio.';
689
- }
690
- if (lowerInput.includes('skill') || lowerInput.includes('what can he do')) {
691
- return 'Adham is a Tech Innovator and Full Stack Developer, specializing in AI/ML, Python, JavaScript, and React. See the "About Me" section for more!';
692
- }
693
- if (lowerInput.includes('project')) {
694
- return 'Adham has several projects including a Snake Game, Tic-Tac-Toe, an n8n Automation workflow, and a more advanced AI Chatbot. You can play some of them right here on the page!';
695
- }
696
- if (lowerInput.includes('achievement') || lowerInput.includes('certificate')) {
697
- return 'Adham holds certificates in areas like Google AI Essentials, Ethical Hacking, and Computer Networking. Scroll down to the Achievements section to see them all.';
698
- }
699
- if (lowerInput.includes('contact') || lowerInput.includes('email')) {
700
- return 'You can contact Adham at adamqab.18@gmail.com or connect with him on LinkedIn. All links are in the "Get In Touch" section at the bottom.';
701
- }
702
- if (lowerInput.includes('location') || lowerInput.includes('where is he')) {
703
- return 'Adham is based in the United States.';
704
- }
705
- if (lowerInput.includes('help') || lowerInput.includes('what can you do')) {
706
- return 'I can answer questions about Adham\'s skills, projects, and achievements. I can also solve simple math problems, like "100 / 4" or "(5 + 5) * 2".';
707
- }
708
-
709
- // --- Default Response ---
710
- return "I'm not sure how to answer that. Please ask about Adham's skills, projects, achievements, or give me a simple calculation.";
711
- };
712
-
713
-
714
- sendBtn.addEventListener('click', handleSendMessage);
715
- chatInput.addEventListener('keypress', (e) => {
716
- if (e.key === 'Enter') {
717
- handleSendMessage();
718
- }
719
- });
720
-
721
  </script>
722
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=adamqab/https-huggingface-co-spaces-adamqab-myweb" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p>
723
  </body>
 
35
  url('https://i.postimg.cc/hjBVvCM8/4uoIBUi.jpg') no-repeat center center/cover;
36
  }
37
 
38
+ .nav-link {
39
+ position: relative;
40
+ }
41
+
42
+ .nav-link::after {
43
+ content: '';
44
+ position: absolute;
45
+ width: 0;
46
+ height: 2px;
47
+ bottom: -2px;
48
+ left: 0;
49
+ background-color: var(--primary-gold);
50
+ transition: width 0.3s ease;
51
+ }
52
+
53
+ .nav-link:hover::after {
54
  width: 100%;
55
+ }
56
+
57
+ .project-card {
58
+ background: rgba(26, 26, 46, 0.5);
59
  backdrop-filter: blur(10px);
60
+ border: 1px solid rgba(255, 215, 0, 0.1);
61
+ transition: all 0.3s ease;
 
 
 
 
62
  }
63
+
64
+ .project-card:hover {
65
+ transform: translateY(-10px);
66
+ box-shadow: 0 10px 20px rgba(230, 57, 70, 0.3);
67
+ border-color: rgba(255, 215, 0, 0.3);
 
 
68
  }
69
+
70
+ .gold-accent {
71
+ color: var(--primary-gold);
 
 
 
72
  }
73
+
74
+ .red-accent {
75
+ color: var(--primary-red);
76
+ }
77
+
78
+ .section-divider {
79
+ height: 100px;
80
+ background: linear-gradient(to bottom, var(--primary-black), var(--space-blue));
81
+ }
82
+
83
+ .tech-icon {
84
+ transition: all 0.3s ease;
85
  }
86
+
87
+ .tech-icon:hover {
88
+ transform: scale(1.2);
89
+ color: var(--primary-gold);
90
+ }
91
+
92
+ .floating {
93
+ animation: floating 3s ease-in-out infinite;
94
+ }
95
+
96
+ @keyframes floating {
97
+ 0% { transform: translateY(0px); }
98
+ 50% { transform: translateY(-15px); }
99
+ 100% { transform: translateY(0px); }
100
+ }
101
+
102
+ .glow {
103
+ text-shadow: 0 0 10px rgba(255, 215, 0, 0.7);
104
+ }
105
+
106
+ .typewriter {
107
+ overflow: hidden;
108
+ border-right: 3px solid var(--primary-gold);
109
+ white-space: nowrap;
110
+ margin: 0 auto;
111
+ letter-spacing: 2px;
112
+ animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite;
113
+ }
114
+
115
+ @keyframes typing {
116
+ from { width: 0 }
117
+ to { width: 100% }
118
+ }
119
+
120
+ @keyframes blink-caret {
121
+ from, to { border-color: transparent }
122
+ 50% { border-color: var(--primary-gold) }
123
+ }
124
+
125
+ .scroll-indicator {
126
+ position: absolute;
127
+ bottom: 30px;
128
+ left: 50%;
129
+ transform: translateX(-50%);
130
+ animation: bounce 2s infinite;
131
  }
132
+
133
+ @keyframes bounce {
134
+ 0%, 20%, 50%, 80%, 100% { transform: translateY(0) translateX(-50%); }
135
+ 40% { transform: translateY(-20px) translateX(-50%); }
136
+ 60% { transform: translateY(-10px) translateX(-50%); }
137
  }
138
+
139
+ .contact-input {
140
+ background: rgba(26, 26, 46, 0.5);
141
+ border: 1px solid rgba(255, 215, 0, 0.2);
142
  color: white;
143
+ }
144
+
145
+ .contact-input:focus {
146
  outline: none;
147
+ border-color: var(--primary-gold);
148
+ box-shadow: 0 0 10px rgba(255, 215, 0, 0.3);
149
  }
150
+ /* Basic animation for elements coming into view */
151
+ .animate-fadeIn {
152
+ animation: fadeIn 1s ease-out;
 
 
 
 
153
  }
154
+ @keyframes fadeIn {
155
+ from { opacity: 0; transform: translateY(20px); }
156
+ to { opacity: 1; transform: translateY(0); }
157
  }
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  </style>
160
  </head>
161
  <body>
162
+ <section class="hero-section relative flex items-center justify-center text-center overflow-hidden">
163
  <div class="absolute inset-0 bg-black opacity-40"></div>
164
+ <div class="relative z-10 px-6 max-w-4xl">
 
 
 
 
 
 
 
 
 
 
 
 
165
  <h1 class="text-5xl md:text-7xl font-bold mb-6 glow">
166
  ADHAM <span class="red-accent">QAB</span>
167
  </h1>
 
596
  e.preventDefault();
597
  const targetElement = document.querySelector(this.getAttribute('href'));
598
  if (targetElement) {
599
+ targetElement.scrollIntoView({
600
+ behavior: 'smooth'
601
+ });
602
  }
603
+
604
+ // Close mobile menu if open and it exists
605
  const mobileMenu = document.getElementById('mobile-menu');
606
  if (mobileMenu && !mobileMenu.classList.contains('hidden')) {
607
  mobileMenu.classList.add('hidden');
 
612
  // Mobile menu toggle
613
  const mobileMenuButton = document.querySelector('.mobile-menu-button');
614
  const mobileMenu = document.getElementById('mobile-menu');
615
+
616
  if (mobileMenuButton && mobileMenu) {
617
  mobileMenuButton.addEventListener('click', function() {
618
  mobileMenu.classList.toggle('hidden');
 
624
  entries.forEach(entry => {
625
  if (entry.isIntersecting) {
626
  entry.target.classList.add('animate-fadeIn');
627
+ observer.unobserve(entry.target); // Optional: unobserve after animation
628
  }
629
  });
630
  }, { threshold: 0.1 });
631
+
632
  document.querySelectorAll('.project-card, .achievement-card').forEach(card => {
633
  observer.observe(card);
634
  });
635
 
636
+ // Typewriter effect - ensure border is removed
637
  const typewriterElement = document.querySelector('.typewriter');
638
  if (typewriterElement) {
639
+ // Ensure animation completes before removing border if animation-duration is known
640
+ // For this example, using a timeout matching CSS animation
641
  setTimeout(() => {
642
  typewriterElement.style.borderRight = 'none';
643
+ }, 3500); // Match the 'typing' animation duration in CSS
644
  }
645
 
646
+ // Update copyright year dynamically
647
  document.getElementById('currentYear').textContent = new Date().getFullYear();
648
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
649
  </script>
650
  <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=adamqab/https-huggingface-co-spaces-adamqab-myweb" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p>
651
  </body>