customized-chatbot / index.html
KynosAi's picture
Add 3 files
84c4d17 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Linda Grey Law Firm Chatbot</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-5px); }
}
.bounce-hover:hover {
animation: bounce 0.8s ease infinite;
}
.teardrop {
width: 50px;
height: 50px;
background: #0D3B2E;
border-radius: 50% 0 50% 50%;
transform: rotate(90deg);
position: relative;
box-shadow: 0 4px 15px rgba(13, 59, 46, 0.3);
}
.teardrop-inner {
transform: rotate(-90deg);
position: absolute;
top: 8px;
left: 8px;
width: 34px;
height: 34px;
border-radius: 50%;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
background: white;
}
.chat-container {
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.98);
border-radius: 18px;
border: 1px solid rgba(13, 59, 46, 0.1);
}
.typing-indicator {
display: flex;
align-items: center;
}
.typing-dot {
width: 6px;
height: 6px;
margin: 0 2px;
background-color: #6b7280;
border-radius: 50%;
animation: typingAnimation 1.4s infinite ease-in-out;
}
.typing-dot:nth-child(1) {
animation-delay: 0s;
}
.typing-dot:nth-child(2) {
animation-delay: 0.2s;
}
.typing-dot:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes typingAnimation {
0%, 60%, 100% { transform: translateY(0); }
30% { transform: translateY(-5px); }
}
.message-fade-in {
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.navy-green-bg {
background-color: #0D3B2E;
}
.navy-green-text {
color: #0D3B2E;
}
.navy-green-border {
border-color: #0D3B2E;
}
.quick-reply-btn {
transition: all 0.2s ease;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 2px 6px;
font-size: 0.8rem;
}
.feedback-buttons {
display: none;
margin-top: 4px;
margin-left: 16px;
transition: all 0.3s ease;
}
.feedback-button {
background: transparent;
border: none;
cursor: pointer;
padding: 2px 4px;
border-radius: 4px;
transition: all 0.2s ease;
}
.feedback-button.thumbs-up.active {
color: #10B981 !important;
}
.feedback-button.thumbs-down.active {
color: #EF4444 !important;
}
.feedback-button:hover {
transform: scale(1.1);
}
.feedback-button.thumbs-up:hover {
color: #10B981;
}
.feedback-button.thumbs-down:hover {
color: #EF4444;
}
.bot-message-bubble {
max-width: 80%;
background: #f9fafb;
border-radius: 16px;
padding: 12px 16px;
margin-left: 8px;
box-shadow: 0 1px 4px rgba(0,0,0,0.05);
position: relative;
font-size: 15px;
color: #111827;
}
.user-message-bubble {
max-width: 80%;
background: #0D3B2E;
color: white;
border-radius: 16px;
padding: 12px 16px;
margin-right: 8px;
box-shadow: 0 1px 4px rgba(0,0,0,0.05);
line-height: 1.2;
font-weight: bold;
}
.message-container:hover .feedback-buttons {
display: block;
}
.timestamp {
font-size: 0.75rem;
color: #6b7280;
margin-top: 4px;
display: flex;
align-items: center;
}
.user-timestamp {
text-align: right;
padding-right: 10px;
}
.timestamp i {
margin-right: 3px;
font-size: 0.6rem;
}
.help-menu {
display: none;
background-color: white;
border-radius: 18px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 100;
padding: 20px;
overflow-y: auto;
animation: slideUp 0.3s ease-out;
}
.help-menu.show {
display: flex;
flex-direction: column;
}
.help-menu-header {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 16px;
border-bottom: 1px solid #e5e7eb;
margin-bottom: 16px;
}
.help-menu-title {
font-size: 1.2rem;
font-weight: 600;
color: #0D3B2E;
}
.help-menu-close {
cursor: pointer;
color: #6b7280;
font-size: 1.5rem;
}
.help-menu-item {
padding: 16px 12px;
cursor: pointer;
color: #4b5563;
border-bottom: 1px solid #f3f4f6;
transition: all 0.2s ease;
display: flex;
align-items: center;
}
.help-menu-item:hover {
background-color: #f9fafb;
color: #0D3B2E;
}
.help-menu-item i {
margin-right: 12px;
width: 24px;
text-align: center;
color: #0D3B2E;
}
.help-menu-divider {
height: 1px;
background-color: #e5e7eb;
margin: 12px 0;
}
.back-to-chat {
margin-top: auto;
padding: 16px;
background-color: #0D3B2E;
color: white;
border-radius: 12px;
text-align: center;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.back-to-chat:hover {
background-color: #0c3529;
}
@keyframes slideUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
/* Custom scrollbar */
.help-menu::-webkit-scrollbar {
width: 6px;
}
.help-menu::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
.help-menu::-webkit-scrollbar-thumb {
background: #0D3B2E;
border-radius: 10px;
}
.help-menu::-webkit-scrollbar-thumb:hover {
background: #0a2e24;
}
.powered-by {
font-size: 0.7rem;
color: #6b7280;
text-align: center;
padding: 8px 0;
margin-top: auto;
}
.powered-by a {
color: #0D3B2E;
font-weight: 500;
text-decoration: none;
transition: all 0.2s ease;
}
.powered-by a:hover {
color: #0a2e24;
text-decoration: underline;
}
.consecutive-message {
margin-top: 4px;
}
@media (max-width: 640px) {
#chatLauncher {
bottom: 16px;
right: 16px;
z-index: 1000;
}
#chatContainer {
width: calc(100vw - 32px);
max-width: 100%;
right: 16px;
left: 16px;
bottom: 80px;
top: auto;
height: calc(100vh - 160px);
max-height: none;
}
.quick-reply-btn {
font-size: 0.7rem;
padding: 6px 10px;
}
.bot-message-bubble, .user-message-bubble {
max-width: 85%;
padding: 10px 14px;
font-size: 14px;
}
.help-menu {
border-radius: 0;
top: 0;
}
}
</style>
</head>
<body class="font-sans">
<!-- Chat Launcher -->
<div id="chatLauncher" class="fixed bottom-8 right-8 z-30 cursor-pointer bounce-hover">
<div class="teardrop">
<div class="teardrop-inner">
<img src="https://kynosai.io/wp-content/uploads/2025/05/woman-8451051_1280.webp"
alt="Linda Grey"
class="w-full h-full object-cover">
</div>
</div>
</div>
<!-- Chat Container -->
<div id="chatContainer" class="fixed bottom-20 right-8 w-[400px] max-w-[95vw] h-[500px] max-h-[70vh] z-40 hidden">
<div class="chat-container flex flex-col h-full overflow-hidden">
<!-- Header -->
<div class="bg-[#0D3B2E] text-white p-4 flex items-center justify-between rounded-t-[18px] relative">
<div class="flex items-center space-x-3">
<img src="https://kynosai.io/wp-content/uploads/2025/05/gold-law-firm-logo-icon-design-creative-template-for-company-vector.webp"
alt="Linda Grey Law Firm"
class="w-10 h-10 rounded-full object-cover border-2 border-white">
<div>
<h3 class="font-bold">Linda Grey Law Firm</h3>
<p class="text-xs opacity-80">Justice Assistant</p>
</div>
</div>
<div class="flex items-center space-x-4">
<button id="helpButton" class="text-white hover:text-gray-200 text-lg">
<i class="fas fa-question-circle"></i>
</button>
<button id="closeChat" class="text-white hover:text-gray-200 text-2xl">&times;</button>
</div>
</div>
<!-- Help Menu (full screen) -->
<div id="helpMenu" class="help-menu">
<div class="help-menu-header">
<div class="help-menu-title">Help & Information</div>
<div id="helpMenuClose" class="help-menu-close">&times;</div>
</div>
<div class="help-menu-item" onclick="displayHelpOption('email')">
<i class="fas fa-envelope"></i>
<div>
<div class="font-medium">Email Linda Grey</div>
<div class="text-xs opacity-75">Click to email our firm</div>
</div>
</div>
<div class="help-menu-item" onclick="displayHelpOption('services')">
<i class="fas fa-gavel"></i>
<div class="font-medium">Services</div>
</div>
<div class="help-menu-item" onclick="displayHelpOption('location')">
<i class="fas fa-map-marker-alt"></i>
<div class="font-medium">Location</div>
</div>
<div class="help-menu-divider"></div>
<div class="help-menu-item" onclick="displayHelpOption('faq')">
<i class="fas fa-question-circle"></i>
<div class="font-medium">FAQ</div>
</div>
<div class="help-menu-item" onclick="displayHelpOption('contact')">
<i class="fas fa-phone-alt"></i>
<div class="font-medium">Contact</div>
</div>
<div class="powered-by">
Powered by <a href="https://kynosai.io" target="_blank">Kynos AI</a>
</div>
<div class="back-to-chat" id="backToChat">
Return to Chat
</div>
</div>
<!-- Chat Messages -->
<div id="chatMessages" class="flex-1 p-4 overflow-y-auto bg-white/90 space-y-3">
<!-- Initial bot message -->
<div class="flex flex-col mb-2 message-fade-in message-container">
<div class="flex">
<div class="flex-shrink-0 mr-1">
<img src="https://kynosai.io/wp-content/uploads/2025/05/gold-law-firm-logo-icon-design-creative-template-for-company-vector.webp"
alt="Linda Grey Law Firm"
class="w-6 h-6 rounded-full object-cover border border-gray-200">
</div>
<div>
<div class="bot-message-bubble whitespace-pre-line">
<p>Hi 👋 I'm Linda Grey, How can I help you today?</p>
</div>
<div class="feedback-buttons flex space-x-2">
<button class="feedback-button thumbs-up text-gray-400"
onclick="handleFeedback(this, 'thumbs-up', 'bot-1')">
<i class="fas fa-thumbs-up text-xs"></i>
</button>
<button class="feedback-button thumbs-down text-gray-400"
onclick="handleFeedback(this, 'thumbs-down', 'bot-1')">
<i class="fas fa-thumbs-down text-xs"></i>
</button>
</div>
</div>
</div>
<div class="timestamp ml-10">
<i class="far fa-clock"></i> Just now
</div>
</div>
</div>
<!-- Quick Reply Buttons -->
<div id="quickReplies" class="px-4 pb-2 bg-white/90">
<div class="flex gap-2 overflow-x-auto py-1">
<button class="quick-reply-btn bg-gray-100 hover:bg-gray-200 text-[#0D3B2E] rounded-full border border-gray-300 transition">
📅 Book appointment
</button>
<button class="quick-reply-btn bg-gray-100 hover:bg-gray-200 text-[#0D3B2E] rounded-full border border-gray-300 transition">
⚖️ Legal advice
</button>
<button class="quick-reply-btn bg-gray-100 hover:bg-gray-200 text-[#0D3B2E] rounded-full border border-gray-300 transition">
👩‍💼 Talk to Linda
</button>
</div>
</div>
<!-- Input Area -->
<div class="p-3 border-t border-gray-200 bg-white rounded-b-[18px]">
<div class="relative">
<input id="userInput"
type="text"
placeholder="Type your message..."
class="w-full p-2 pr-12 rounded-full border border-gray-300 focus:outline-none focus:ring-2 focus:ring-[#0D3B2E] focus:border-transparent text-sm">
<button id="sendButton" class="absolute right-2 top-1/2 transform -translate-y-1/2 text-[#0D3B2E] hover:text-opacity-80 font-medium text-xs md:text-sm">
Send
</button>
</div>
</div>
<!-- Powered by footer -->
<div class="powered-by">
Powered by <a href="https://kynosai.io" target="_blank">Kynos AI</a>
</div>
</div>
</div>
<script>
// Track feedback for messages
const feedbackMap = new Map();
const votedMessages = new Set();
let messageCounter = 1;
let helpMenuOpen = false;
let currentFeedbackAllowed = true;
let lastSender = null;
document.addEventListener('DOMContentLoaded', function() {
const chatLauncher = document.getElementById('chatLauncher');
const chatContainer = document.getElementById('chatContainer');
const quickReplies = document.getElementById('quickReplies');
const chatMessages = document.getElementById('chatMessages');
const helpButton = document.getElementById('helpButton');
const helpMenu = document.getElementById('helpMenu');
const helpMenuClose = document.getElementById('helpMenuClose');
const backToChat = document.getElementById('backToChat');
// Initial check for mobile
checkMobileView();
// Toggle chat visibility
chatLauncher.addEventListener('click', toggleChat);
// Close chat button
document.getElementById('closeChat').addEventListener('click', closeChat);
// Send message button
document.getElementById('sendButton').addEventListener('click', sendMessage);
// Quick reply buttons
document.querySelectorAll('.quick-reply-btn').forEach(button => {
button.addEventListener('click', function() {
const message = this.textContent.trim();
addMessageToChat(message, 'user');
// Reset feedback allowance on new user message
currentFeedbackAllowed = true;
processQuickReply(message);
});
});
// Handle Enter key for input
document.getElementById('userInput').addEventListener('keypress', function(e) {
if (e.key === 'Enter') sendMessage();
});
// Help menu toggle
helpButton.addEventListener('click', toggleHelpMenu);
// Help menu close button
helpMenuClose.addEventListener('click', closeHelpMenu);
// Back to chat button
backToChat.addEventListener('click', closeHelpMenu);
function toggleChat() {
if (chatContainer.classList.contains('hidden')) {
chatContainer.classList.remove('hidden');
checkMobileView();
closeHelpMenu(); // Ensure help menu is closed when chat opens
} else {
closeChat();
}
}
function closeChat() {
chatContainer.classList.add('hidden');
closeHelpMenu();
}
function toggleHelpMenu() {
if (helpMenuOpen) {
closeHelpMenu();
} else {
openHelpMenu();
}
}
function openHelpMenu() {
helpMenu.classList.add('show');
helpMenuOpen = true;
// Hide other UI elements
document.getElementById('chatMessages').style.display = 'none';
document.getElementById('quickReplies').style.display = 'none';
document.getElementById('userInput').parentElement.style.display = 'none';
document.querySelector('.powered-by').style.display = 'none';
}
function closeHelpMenu() {
helpMenu.classList.remove('show');
helpMenuOpen = false;
// Show other UI elements
document.getElementById('chatMessages').style.display = 'block';
document.getElementById('quickReplies').style.display = 'block';
document.getElementById('userInput').parentElement.style.display = 'block';
document.querySelector('.powered-by').style.display = 'block';
}
function checkMobileView() {
// Adjust layout for mobile
if (window.innerWidth <= 640) {
chatContainer.style.width = 'calc(100vw - 32px)';
chatContainer.style.left = '16px';
chatContainer.style.right = '16px';
chatContainer.style.bottom = '80px';
chatContainer.style.top = 'auto';
chatContainer.style.height = 'calc(100vh - 160px)';
chatContainer.style.maxHeight = 'none';
} else {
// Reset desktop styles
chatContainer.style.width = '400px';
chatContainer.style.right = '32px';
chatContainer.style.bottom = '90px';
chatContainer.style.left = 'auto';
chatContainer.style.height = '500px';
chatContainer.style.maxHeight = '90vh';
}
}
function sendMessage() {
const inputField = document.getElementById('userInput');
const message = inputField.value.trim();
if (message) {
if (helpMenuOpen) {
// If help menu is open, close it first
closeHelpMenu();
}
addMessageToChat(message, 'user');
// Reset feedback allowance on new user message
currentFeedbackAllowed = true;
// Clear input
inputField.value = '';
// Process message
setTimeout(() => {
processQuickReply(message);
}, 500);
}
inputField.focus();
}
function showTypingIndicator() {
const typingDiv = document.createElement('div');
typingDiv.id = 'typingIndicator';
typingDiv.classList.add('flex', 'mb-2', 'message-fade-in');
typingDiv.innerHTML = `
<div class="flex-shrink-0 mr-1">
<img src="https://kynosai.io/wp-content/uploads/2025/05/gold-law-firm-logo-icon-design-creative-template-for-company-vector.webp"
alt="Linda Grey Law Firm"
class="w-6 h-6 rounded-full object-cover border border-gray-200">
</div>
<div>
<div class="bot-message-bubble">
<div class="typing-indicator">
<div class="typing-dot"></div>
<div class="typing-dot"></div>
<div class="typing-dot"></div>
</div>
</div>
</div>
`;
chatMessages.appendChild(typingDiv);
scrollToBottom();
}
function removeTypingIndicator() {
const typingIndicator = document.getElementById('typingIndicator');
if (typingIndicator) {
typingIndicator.remove();
}
}
function processQuickReply(message) {
message = message.toLowerCase();
let botResponse = "";
showTypingIndicator();
if (message.includes('book') || message.includes('appointment') || message.includes('📅')) {
botResponse = "📅 Our team is ready to assist you with your legal needs. Please provide your contact details and preferred appointment date.";
} else if (message.includes('legal') || message.includes('advice') || message.includes('⚖️')) {
botResponse = "⚖️ We can help with various legal matters:\n\n• Family Law\n• Business Law\n• Real Estate\n• Criminal Defense\n\nWhat specific area are you inquiring about?";
} else if (message.includes('linda') || message.includes('grey') || message.includes('talk') || message.includes('👩‍💼')) {
botResponse = "👩‍💼 Linda Grey will respond to your inquiry shortly. Please share:\n\n1. Your contact information\n2. The nature of your request\n3. Any relevant documents";
} else if (message.includes('help') || message.includes('faq') || message.includes('support')) {
displayHelpOption('faq');
removeTypingIndicator();
return;
} else if (message.includes('contact') || message.includes('phone') || message.includes('email')) {
displayHelpOption('contact');
removeTypingIndicator();
return;
} else {
botResponse = "Thank you for your message. How can we assist you today? \n\nPlease select an option or ask your legal question directly.";
}
setTimeout(() => {
removeTypingIndicator();
addMessageToChat(botResponse, 'bot');
}, 1500);
}
function displayHelpOption(option) {
let helpMessage = "";
switch(option) {
case 'email':
window.open('mailto:info@lindagrey.com', '_blank');
helpMessage = "✉️ Your email client should open with our address pre-filled. If it doesn't, you can email us at info@lindagrey.com";
break;
case 'services':
helpMessage = "⚖️ Our Legal Services:\n\n• Civil Litigation\n• Family Law\n• Estate Planning\n• Business Law\n• Real Estate\n• Employment Law\n• Personal Injury\n\nWould you like more details about any of these services?";
break;
case 'location':
helpMessage = "📍 Our Office Location:\n\n🏢 Linda Grey Law Firm\n123 Justice Avenue, Suite 500\nLegal City, LC 12345\n\nMap: https://maps.google.com/lindagreylaw\n\n🅿️ Free parking available in the rear.\n\n⏰ Hours:\nMon-Fri: 9am-5pm\nSat: By appointment";
break;
case 'faq':
helpMessage = "❓ Frequently Asked Questions:\n\n1. How do I book a consultation?\n → Click 'Book appointment' or request via chat\n\n2. What are your office hours?\n → Mon-Fri: 9am-5pm | Sat: 10am-2pm\n\n3. Do you offer free consultations?\n → Yes, 30-minute initial consultations are free";
break;
case 'contact':
helpMessage = "📞 Contact Information:\n\n• Phone: +1 (555) 123-4567\n• Email: info@lindagreylaw.com\n• Address: 123 Justice Ave, Suite 500\n\n⏰ Office hours: Mon-Fri 9am-5pm";
break;
default:
helpMessage = "How can we help you today? Please select from the menu options.";
}
// Close help menu
closeHelpMenu();
// Add help message to chat
addMessageToChat(help
</html>