<!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();
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.