<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Agentforce - Golf Fitting Appointment</title>
<link rel="stylesheet" href="agentforce.css">
</head>
<body>
<div class="agentforce-container">
<div class="agentforce-header">
<div class="agentforce-title">Agentforce</div>
</div>
<div class="agentforce-chat-area" id="agentforce-chat-area">
<div class="agentforce-width-maintainer" style="width: 100%; height: 0; overflow: hidden;"></div>
<!-- Message 1: Agent Greeting -->
<div class="agentforce-message agentforce-message-1" id="message-1">
<div class="agentforce-avatar agentforce-agent-avatar"></div>
<div class="agentforce-message-content">
<div class="agentforce-agent-bubble">
Welcome to Pro Golf Fitters! How can I help you with your golf equipment needs today?
</div>
</div>
</div>
<!-- Message 2: User Response -->
<div class="agentforce-message agentforce-user-message agentforce-message-2" id="message-2">
<div class="agentforce-avatar agentforce-user-avatar">
<svg class="agentforce-user-icon" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8 8C10.21 8 12 6.21 12 4C12 1.79 10.21 0 8 0C5.79 0 4 1.79 4 4C4 6.21 5.79 8 8 8ZM8 10C5.33 10 0 11.34 0 14V16H16V14C16 11.34 10.67 10 8 10Z" /></svg>
</div>
<div class="agentforce-message-content">
<div class="agentforce-user-bubble">
Hi, I'm interested in scheduling a club fitting. I've been playing for about a year and want to upgrade from my starter set.
</div>
</div>
</div>
<!-- Message 3: Agent Response -->
<div class="agentforce-message agentforce-message-3" id="message-3">
<div class="agentforce-avatar agentforce-agent-avatar"></div>
<div class="agentforce-message-content">
<div class="agentforce-agent-bubble">
I'd be happy to help you schedule a fitting session! To recommend the right package, could you share a bit about your current handicap or typical score, and what specific aspects of your game you're looking to improve?
</div>
</div>
</div>
<!-- Message 4: Record Card -->
<div class="agentforce-message agentforce-message-4" id="message-4">
<div class="agentforce-avatar agentforce-agent-avatar"></div>
<div class="agentforce-message-content">
<div class="agentforce-record-card">
<div class="agentforce-record-header">
<div class="agentforce-record-icon"></div>
<div class="agentforce-record-title">Golf Fitting Information</div>
</div>
<div class="agentforce-record-body">
<div class="agentforce-record-field">
<div class="agentforce-record-label">CUSTOMER NAME</div>
<div class="agentforce-record-value agentforce-record-value-highlight">Alex Johnson</div>
</div>
<div class="agentforce-record-field">
<div class="agentforce-record-label">HANDICAP/SKILL LEVEL</div>
<div class="agentforce-record-value agentforce-record-value-normal">Beginner (25+ handicap)</div>
</div>
<div class="agentforce-record-field">
<div class="agentforce-record-label">CURRENT EQUIPMENT</div>
<div class="agentforce-record-value agentforce-record-value-normal">Starter set (2 years old)</div>
</div>
<div class="agentforce-record-field">
<div class="agentforce-record-label">IMPROVEMENT GOALS</div>
<div class="agentforce-record-value agentforce-record-value-normal">Distance & consistency</div>
</div>
<div class="agentforce-button-row">
<button class="agentforce-action-button">Select Standard Fitting</button>
<button class="agentforce-action-button">Select Premium Fitting</button>
</div>
</div>
</div>
</div>
</div>
<!-- Message 5: User Response -->
<div class="agentforce-message agentforce-user-message agentforce-message-5" id="message-5">
<div class="agentforce-avatar agentforce-user-avatar">
<svg class="agentforce-user-icon" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8 8C10.21 8 12 6.21 12 4C12 1.79 10.21 0 8 0C5.79 0 4 1.79 4 4C4 6.21 5.79 8 8 8ZM8 10C5.33 10 0 11.34 0 14V16H16V14C16 11.34 10.67 10 8 10Z" /></svg>
</div>
<div class="agentforce-message-content">
<div class="agentforce-user-bubble">
I usually shoot around 95-100. I'm mostly looking to get more distance with my driver and more consistency with my irons. What fitting packages do you recommend?
</div>
</div>
</div>
<!-- Message 6: Agent Response -->
<div class="agentforce-message agentforce-message-6" id="message-6">
<div class="agentforce-avatar agentforce-agent-avatar"></div>
<div class="agentforce-message-content">
<div class="agentforce-agent-bubble">
Based on your goals, I recommend our Premium Fitting which includes driver and iron fitting. We have an opening next Tuesday at 2:00 PM with Mike, our specialist for newer golfers. The session takes about 90 minutes. Would that work for you?
</div>
</div>
</div>
<!-- Message 7: User Response -->
<div class="agentforce-message agentforce-user-message agentforce-message-7" id="message-7">
<div class="agentforce-avatar agentforce-user-avatar">
<svg class="agentforce-user-icon" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8 8C10.21 8 12 6.21 12 4C12 1.79 10.21 0 8 0C5.79 0 4 1.79 4 4C4 6.21 5.79 8 8 8ZM8 10C5.33 10 0 11.34 0 14V16H16V14C16 11.34 10.67 10 8 10Z" /></svg>
</div>
<div class="agentforce-message-content">
<div class="agentforce-user-bubble">
Tuesday at 2:00 PM works perfectly! Will I need to bring my current clubs, and is there anything I should do to prepare?
</div>
</div>
</div>
<!-- Message 8: Agent Response (added to ensure user satisfaction) -->
<div class="agentforce-message agentforce-message-8" id="message-8">
<div class="agentforce-avatar agentforce-agent-avatar"></div>
<div class="agentforce-message-content">
<div class="agentforce-agent-bubble">
Yes, please bring your current clubs so we can compare data. Wear comfortable clothes and golf shoes if you have them. You'll receive a confirmation email with details shortly. We look forward to helping you improve your game!
</div>
</div>
</div>
</div>
<div class="agentforce-input-area">
<div class="agentforce-input-box">Describe your task or ask a question...</div>
</div>
</div>
<script src="agentforce.js"></script>
</body>
</html>
/* Essential styles only */
.agentforce-container {
width: 100%;
max-width: 400px;
height: 600px;
margin: 0 auto;
background: white;
border: 1px solid #ccc;
border-radius: 8px;
overflow: hidden;
font-family: -apple-system, BlinkMacSystemFont, "SF Pro", "Segoe UI", Roboto, sans-serif;
display: flex;
flex-direction: column;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.agentforce-header {
padding: 12px 16px;
border-bottom: 1px solid #eee;
background: white;
z-index: 10;
}
.agentforce-title {
font-size: 18px;
font-weight: 500;
color: #03234D;
}
.agentforce-chat-area {
flex: 1;
overflow-y: auto;
padding: 16px;
background: white;
scroll-behavior: smooth;
/* Force minimum content width */
min-width: 368px; /* 400px container - 16px padding each side */
}
.agentforce-message {
margin-bottom: 16px;
display: flex;
align-items: flex-start;
gap: 12px;
opacity: 0;
transform: translateY(10px);
animation-name: fadeIn;
animation-duration: 0.5s;
animation-timing-function: ease-out;
animation-fill-mode: forwards;
animation-delay: var(--delay);
width: 100%; /* Ensure message takes full width */
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.agentforce-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
flex-shrink: 0;
}
.agentforce-agent-avatar {
background: #D6E6FF;
background-image: url("https://cdn.prod.website-files.com/66aa487c3d059183dbec419e/6813d788e5c463cc7821be59_Agentforce-RGB-stroke-icon.svg");
background-size: 20px 20px;
background-position: center;
background-repeat: no-repeat;
}
.agentforce-user-avatar {
background: #0B827C;
display: flex;
align-items: center;
justify-content: center;
}
.agentforce-user-icon {
width: 16px;
height: 16px;
fill: white;
}
.agentforce-message-content {
flex: 1;
min-width: 0;
width: calc(100% - 44px); /* Full width minus avatar and gap */
}
.agentforce-agent-bubble {
background: #f3f4f6;
border-radius: 12px;
border-top-left-radius: 2px;
padding: 10px 12px;
color: #2E2E2E;
font-size: 13px;
line-height: 1.4;
width: 100%;
box-sizing: border-box;
}
.agentforce-user-bubble {
background: #0250D9;
border-radius: 12px;
border-bottom-right-radius: 2px;
padding: 10px 12px;
color: white;
font-size: 13px;
line-height: 1.4;
width: 100%;
box-sizing: border-box;
}
.agentforce-record-card {
border: 1px solid #eee;
border-radius: 12px;
overflow: hidden;
background: white;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
width: 100%;
box-sizing: border-box;
}
.agentforce-record-header {
padding: 12px 16px;
display: flex;
align-items: center;
gap: 8px;
border-bottom: 1px solid #eee;
width: 100%;
box-sizing: border-box;
}
.agentforce-record-icon {
width: 24px;
height: 24px;
background: #5867E8; /* Example color */
border-radius: 4px;
/* SVG Icon for Retail Store */
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M12 7c1.66 0 3-1.34 3-3s-1.34-3-3-3-3 1.34-3 3 1.34 3 3 3zm0 8c-3.31 0-6 1.34-6 3v2h12v-2c0-1.66-2.69-3-6-3z'/%3E%3C/svg%3E"); /* Placeholder user icon, replace if needed */
background-size: 16px 16px;
background-position: center;
background-repeat: no-repeat;
}
.agentforce-record-title {
font-weight: 600;
font-size: 16px;
color: #03234D;
}
.agentforce-record-body {
padding: 12px 16px;
width: 100%;
box-sizing: border-box;
}
.agentforce-record-field {
margin-bottom: 8px;
width: 100%;
box-sizing: border-box;
}
.agentforce-record-label {
font-size: 12px;
font-weight: 700;
color: #5C5C5C;
margin-bottom: 2px;
width: 100%;
box-sizing: border-box;
}
.agentforce-record-value {
font-size: 12px;
line-height: 1.4;
width: 100%;
box-sizing: border-box;
}
.agentforce-record-value-normal {
color: #2E2E2E;
}
.agentforce-record-value-highlight {
color: #0250D9;
}
.agentforce-button-row {
display: flex;
margin-top: 12px; /* Adjusted margin for spacing */
width: 100%;
box-sizing: border-box;
gap: 8px; /* Add gap between buttons */
justify-content: center; /* Center buttons */
}
.agentforce-action-button {
height: 32px;
padding: 0 16px;
background: white;
border: 1px solid #5C5C5C;
border-radius: 9999px; /* Make buttons pill-shaped */
display: flex;
align-items: center;
justify-content: center;
color: #0250D9;
font-size: 14px;
cursor: pointer;
flex-grow: 1; /* Allow buttons to grow */
text-align: center;
}
.agentforce-action-button:hover {
background-color: #f0f0f0;
} /* Add hover effect */
/* Remove specific first/last child border adjustments */
.agentforce-action-button:first-child {
border-right: 1px solid #5C5C5C;
}
.agentforce-input-area {
padding: 8px 16px 16px;
border-top: 1px solid #eee;
background: white;
z-index: 10;
width: 100%;
box-sizing: border-box;
}
.agentforce-input-box {
height: 40px;
padding: 8px 12px;
background: white;
border-radius: 8px;
border: 1px solid #5C5C5C;
display: flex;
align-items: center;
color: #5C5C5C;
font-size: 13px;
width: 100%;
box-sizing: border-box;
}
.agentforce-user-message {
justify-content: flex-end;
}
.agentforce-user-message .agentforce-message-content {
order: -1;
}
/* Special hidden class */
.agentforce-message.hidden {
visibility: hidden;
opacity: 0;
transform: translateY(10px);
display: flex !important;
pointer-events: none;
height: 0;
margin: 0;
overflow: hidden;
}
// Auto-scrolling and message animation script
document.addEventListener('DOMContentLoaded', function() {
const chatArea = document.getElementById('agentforce-chat-area');
const messages = document.querySelectorAll('.agentforce-message');
const lastMessageIndex = messages.length - 1;
// Hide all messages initially
function hideAllMessages() {
messages.forEach(msg => {
msg.classList.add('hidden');
});
// No need to scroll to 0 initially, it will scroll as messages appear
}
// Calculate message display times based on content length
function calculateMessageTiming() {
// Base timing values (in milliseconds)
const baseDelayBetweenMessages = 50; // Delay *between* messages
const baseReadingTime = 500; // Minimum time to read a message
const charReadingTime = 20; // Milliseconds per character
const recordCardReadingTime = 4000; // Extra time for record cards
// Start cumulative delay at 0 for the *first* message
let cumulativeDelay = 0;
const timings = [];
messages.forEach((message, index) => {
// If we're on the second message (index 0 is first), reduce the cumulative delay by 25%
// This makes the second message appear 25% faster
if (index === 1) {
// We need to reduce the current cumulative delay (which is the timing for the 2nd message)
cumulativeDelay = cumulativeDelay * 0.5;
}
// Store the calculated timing for the *current* message
timings.push(cumulativeDelay);
// Calculate time to read *this* message to determine the delay for the *next* one
let currentContentLength = 0;
const bubbleElement = message.querySelector('.agentforce-agent-bubble, .agentforce-user-bubble');
if (bubbleElement) {
currentContentLength = bubbleElement.textContent.length;
}
const recordCard = message.querySelector('.agentforce-record-card');
let additionalTime = currentContentLength * charReadingTime;
if (recordCard) {
additionalTime += recordCardReadingTime;
}
// Add the reading time for the current message plus the base delay between messages
// to the cumulative delay for the *next* message.
cumulativeDelay += Math.max(baseReadingTime, additionalTime) + baseDelayBetweenMessages;
});
return timings;
}
// Display messages with calculated timing
function startSequence() {
hideAllMessages();
const timings = calculateMessageTiming();
messages.forEach((message, index) => {
// Use the calculated timing for when to *reveal* the message
setTimeout(() => {
// Make message visible
message.classList.remove('hidden');
// Scroll to the bottom after showing a message
// Use a small delay to ensure the element has height before scrolling
setTimeout(() => {
if (chatArea) {
chatArea.scrollTop = chatArea.scrollHeight;
}
}, 50); // Small delay to allow element to render and take up space
// Restart the sequence after showing the last message and adding a pause
if (index === lastMessageIndex) {
setTimeout(() => {
startSequence();
}, 6000); // 6-second pause before restart
}
}, timings[index]); // Use the calculated timing for THIS message
});
}
// Start the animation sequence almost immediately on DOM load
startSequence();
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.