NEW RELEASE
v2.2 - 40+ new elementsWhat's new
<!DOCTYPE html>
<html lang="en">
<head>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Element Carousel Configurator - BricksFusion</title>
  <style>
    :root {
  --background: #000;
  --card-bg: #1e1e1e;
  --card-bg-hover: #252525;
  --text-primary: #f2f2f7;
  --text-secondary: #8e8e93;
  --accent: #ef6013;
  --accent-hover: #c64c0c;
  --border: #2c2c2e;
  --shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
  --track: #2c2c2e;
  --thumb: #ef6013;
  --card-radius: 16px;
  --input-radius: 8px;
  --button-radius: 12px;
  --transition: all 0.25s ease;
  --font: 'Inter', BlinkMacSystemFont, "San Francisco", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --action-bar-height: 70px;
  --success: #28a745;
  --warning: #ffc107;
  --danger: #dc3545;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: var(--font);
  background-color: var(--background);
  color: var(--text-primary);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  padding-bottom: var(--action-bar-height);
}

.action-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: var(--action-bar-height);
  background: linear-gradient(145deg, #1a1a1a, #0f0f0f);
  border-top: 1px solid var(--border);
  z-index: 1000;
  display: flex;
  align-items: center;
  padding: 0 1.5rem;
  gap: 1rem;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(10px);
}

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
}

.breadcrumb-item {
  color: var(--text-secondary);
  font-size: var(--text-xs);
  font-weight: 500;
  text-decoration: none;
  transition: var(--transition);
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
}

.breadcrumb-item:hover {
  color: var(--text-primary);
  background-color: rgba(255, 255, 255, 0.05);
}

.breadcrumb-item.active {
  color: var(--accent);
  background-color: rgba(239, 96, 19, 0.1);
}

.breadcrumb-separator {
  color: var(--text-secondary);
  font-size: var(--text-xs);
  opacity: 0.5;
}

.action-buttons {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.action-btn {
  padding: 0.6rem 1rem;
  background-color: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: var(--text-xs);
  font-weight: 500;
  border: 1px solid var(--border);
  border-radius: var(--button-radius);
  cursor: pointer;
  transition: var(--transition);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  white-space: nowrap;
}

.action-btn:hover {
  background-color: var(--card-bg-hover);
  border-color: var(--accent);
  transform: translateY(-1px);
}

.action-btn.primary {
  background: linear-gradient(90deg, var(--accent), #ff8c51);
  border-color: var(--accent);
  color: white;
}

.action-btn.primary:hover {
  background: linear-gradient(90deg, var(--accent-hover), #e67a3f);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(239, 96, 19, 0.3);
}

.data-attribute-display {
  background-color: rgba(50, 50, 50, 0.8);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
  font-size: var(--text-xs);
  color: #ff8c51;
  cursor: pointer;
  transition: var(--transition);
  user-select: all;
}

.data-attribute-display:hover {
  background-color: rgba(239, 96, 19, 0.2);
  border-color: var(--accent);
}

.container {
  max-width: 100%;
  margin: 0 auto;
  padding: 2rem 1.5rem;
}

.page-header {
  text-align: center;
  margin-bottom: 2rem;
}

.page-title {
  font-size: 2.5rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 0.5rem;
  background: linear-gradient(90deg, var(--accent), #ff8c51);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.page-subtitle {
  font-size: var(--text-s);
  color: var(--text-secondary);
  font-weight: 500;
}

.instructions-toggle {
  margin-bottom: 2rem;
}

.instructions-card {
  background-color: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  transition: var(--transition);
}

.instructions-header {
  padding: 1rem 1.5rem;
  cursor: pointer;
  transition: var(--transition);
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid transparent;
}

.instructions-header:hover {
  background-color: var(--card-bg-hover);
}

.instructions-card.expanded .instructions-header {
  border-bottom-color: var(--border);
}

.instructions-title {
  font-size: var(--text-s);
  font-weight: 600;
}

.toggle-icon {
  font-size: 1.2em;
  transition: transform 0.3s ease;
}

.toggle-icon.expanded {
  transform: rotate(180deg);
}

.instructions-content {
  padding: 0 1.5rem;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease, padding 0.3s ease;
}

.instructions-content.show {
  max-height: 500px;
  padding: 1.5rem;
}

.instructions-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}

.how-to-use ol {
  padding-left: 1.5rem;
}

.how-to-use li {
  margin-bottom: 0.75rem;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  line-height: 1.6;
}

.how-to-use strong {
  color: var(--text-primary);
  font-weight: 600;
}

.how-to-use code {
  background-color: rgba(50, 50, 50, 0.5);
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
  font-size: var(--text-xs);
  color: #ff8c51;
}

.content {
  display: grid;
  grid-template-columns: 1fr 500px;
  gap: 2rem;
  align-items: start;
}

.preview-section {
  position: sticky;
  top: 2rem;
}

.controls-section {
  max-width: 500px;
}

.card {
  background-color: var(--card-bg);
  border-radius: var(--card-radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  margin-bottom: 1.5rem;
  border: 1px solid var(--border);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
}

.preview-container {
  height: 400px;
  width: 100%;
  position: relative;
  overflow: hidden;
  border-radius: var(--card-radius);
  background-color: #000000;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  justify-content: center;
}

.preview-content {
  color: white;
  text-align: center;
  font-weight: bold;
  font-size: var(--text-s);
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
}

.preview-controls {
  position: absolute;
  top: 1rem;
  right: 1rem;
  display: flex;
  gap: 0.5rem;
  z-index: 10;
}

.preview-btn {
  padding: 0.5rem;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 6px;
  cursor: pointer;
  transition: var(--transition);
  font-size: var(--text-xs);
  backdrop-filter: blur(5px);
}

.preview-btn:hover {
  background-color: var(--accent);
  border-color: var(--accent);
}

.preview-btn svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
}

.background-selector-wrapper {
  position: relative;
  display: inline-block;
}

.background-selector-btn {
  position: relative;
}

.background-selector-btn:hover {
  background-color: rgba(239, 96, 19, 0.2);
  border-color: var(--accent);
  box-shadow: 0 0 8px rgba(239, 96, 19, 0.3);
}

.hidden-color-input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  z-index: 1;
}

.card-heading {
  padding: 1rem 1.5rem;
  font-size: var(--text-s);
  font-weight: 600;
  border-bottom: 1px solid var(--border);
  letter-spacing: 0.3px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.card-actions {
  display: flex;
  gap: 0.5rem;
}

.card-action-btn {
  padding: 0.4rem 0.8rem;
  background-color: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
  font-size: var(--text-xs);
  transition: var(--transition);
}

.card-action-btn:hover {
  color: var(--text-primary);
  border-color: var(--accent);
  background-color: rgba(239, 96, 19, 0.1);
}

.card-content {
  padding: 1.5rem;
}

.control-group {
  margin-bottom: 1.5rem;
  position: relative;
}

.control-group:last-child {
  margin-bottom: 0;
}

.control-label {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.75rem;
}

.label-text {
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.2px;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.help-tooltip {
  cursor: help;
  opacity: 0.7;
  transition: var(--transition);
}

.help-tooltip:hover {
  opacity: 1;
  color: var(--accent);
}

.value-display {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.value-text {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  background-color: rgba(50, 50, 50, 0.5);
  padding: 2px 8px;
  border-radius: 4px;
  min-width: 45px;
  text-align: center;
}

.reset-btn {
  padding: 0.2rem 0.4rem;
  background-color: transparent;
  color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: 4px;
  cursor: pointer;
  font-size: 10px;
  transition: var(--transition);
}

.reset-btn:hover {
  color: var(--danger);
  border-color: var(--danger);
  background-color: rgba(220, 53, 69, 0.1);
}

input[type="range"] {
  -webkit-appearance: none;
  width: 100%;
  height: 6px;
  background: var(--track);
  border-radius: 3px;
  outline: none;
  margin: 0.8rem 0;
  position: relative;
}

input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 20px;
  height: 20px;
  background: var(--thumb);
  border-radius: 50%;
  cursor: pointer;
  transition: var(--transition);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}

input[type="range"]::-webkit-slider-thumb:hover {
  transform: scale(1.2);
  box-shadow: 0 0 10px rgba(239, 96, 19, 0.5);
}

.color-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.color-row {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  padding: 1rem 1.25rem;
  background-color: rgba(30, 30, 30, 0.7);
  border: 1px solid var(--border);
  border-radius: var(--input-radius);
  transition: var(--transition);
}

.color-row:hover {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(239, 96, 19, 0.1);
}

.color-picker-container {
  position: relative;
  width: 40px;
  height: 40px;
  border-radius: 8px;
  overflow: hidden;
  border: 2px solid var(--border);
  cursor: pointer;
  transition: var(--transition);
  flex-shrink: 0;
  background: var(--card-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  --selected-color: #3b82f6;
}

.color-picker-container:hover {
  border-color: var(--accent);
  transform: scale(1.05);
  box-shadow: 0 0 12px rgba(239, 96, 19, 0.3);
}

.color-picker-container::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--selected-color, #3b82f6);
  border-radius: 6px;
  transition: var(--transition);
}

input[type="color"] {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: none;
  cursor: pointer;
  background: transparent;
  opacity: 0;
  z-index: 2;
}

.color-input-group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.color-label {
  font-size: 10px;
  font-weight: 500;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-left: 0.25rem;
}

.color-input {
  padding: 0.5rem 0.75rem;
  background-color: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-primary);
  font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
  font-size: 12px;
  transition: var(--transition);
  min-width: 0;
}

.color-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px rgba(239, 96, 19, 0.2);
  outline: none;
}

.color-input.invalid {
  border-color: var(--danger);
  box-shadow: 0 0 0 1px rgba(220, 53, 69, 0.2);
}

.hex-input,
.hsl-input {
  width: 100%;
}

.color-input-group:nth-child(2) {
  flex: 0.3;
}

.color-input-group:nth-child(3) {
  flex: 0.7;
}

.notification {
  position: fixed;
  bottom: calc(var(--action-bar-height) + 1rem);
  left: 50%;
  background-color: var(--success);
  color: white;
  padding: 0.75rem 1rem;
  border-radius: var(--input-radius);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  z-index: 1001;
  transform: translate(-50%, 200px);
  opacity: 0;
  transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s ease;
  font-size: var(--text-xs);
  font-weight: 500;
  max-width: 320px;
  word-wrap: break-word;
  line-height: 1.4;
  text-align: center;
}

.notification.show {
  transform: translate(-50%, 0);
  opacity: 1;
}

#element-carousel-container {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
  border-radius: var(--card-radius);
}

.element-carousel-preview {
  padding: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  height: 100%;
  width: 100%;
  border-radius: 8px;
  position: relative;
  background-color: #000000;
}

.carousel-blur-left,
.carousel-blur-right {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100px;
  pointer-events: none;
  z-index: 10;
  transition: var(--transition);
}

.carousel-blur-left {
  left: 0;
}

.carousel-blur-right {
  right: 0;
}

.element-carousel-track {
  display: flex;
  align-items: center;
  will-change: transform;
  padding: 0;
  position: relative;
  gap: 30px;
  backface-visibility: hidden;
  perspective: 1000px;
  transform: translateZ(0);
  overflow: visible;
  white-space: nowrap;
  height: 100%;
}

.carousel-element {
  min-height: 60px;
  min-width: 120px;
  opacity: 0.9;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: none;
  border-radius: 8px;
  flex-shrink: 0;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  font-weight: 600;
  font-size: 14px;
  text-align: center;
  box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
}

.carousel-element:hover {
  opacity: 1;
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
}

/* Optimized update indicator */
.updating {
  position: relative;
}

.updating::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: updatePulse 0.6s ease-out;
}

@keyframes updatePulse {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(100%); }
}

@media (max-width: 1200px) {
  .content {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }
  
  .preview-section {
    position: static;
  }
  
  .controls-section {
    max-width: 100%;
  }
}

@media (max-width: 768px) {
  .action-bar {
    flex-direction: column;
    height: auto;
    min-height: var(--action-bar-height);
    padding: 0.75rem;
  }
  
  .breadcrumb {
    order: 1;
    width: 100%;
  }
  
  .action-buttons {
    order: 2;
    width: 100%;
    justify-content: center;
    flex-wrap: wrap;
  }
  
  body {
    padding-bottom: calc(var(--action-bar-height) + 20px);
  }
  
  .notification {
    bottom: calc(var(--action-bar-height) + 2rem);
    max-width: 280px;
    transform: translate(-50%, 250px);
  }
  
  .notification.show {
    transform: translate(-50%, 0);
    opacity: 1;
  }
  
  .color-row {
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
    padding: 1rem;
  }
  
  .color-picker-container {
    align-self: center;
    margin-bottom: 0.5rem;
  }
  
  .color-input-group {
    align-items: stretch;
  }
  
  .hex-input,
  .hsl-input {
    width: 100%;
  }

  .preview-container {
    height: 300px;
  }
  
  .data-attribute-display {
    font-size: 10px;
    padding: 0.4rem 0.6rem;
  }
  
  .action-btn {
    font-size: 11px;
    padding: 0.5rem 0.8rem;
  }
  
  .page-title {
    font-size: 2rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

button:focus-visible,
input:focus-visible,
.action-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-track {
  background: var(--background);
}

::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--accent);
}

.loading {
  opacity: 0.6;
  pointer-events: none;
  position: relative;
}

.loading::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}
  </style>
</head>
<body>
  <div class="action-bar">
    <nav class="breadcrumb">
      <a href="https://bricksfusion.com" class="breadcrumb-item">Home</a>
      <span class="breadcrumb-separator">›</span>
      <a href="https://bricksfusion.com/showcase/" class="breadcrumb-item">Showcase</a>
      <span class="breadcrumb-separator">›</span>
      <span class="breadcrumb-item active">Element Carousel</span>
    </nav>
    
    <div class="action-buttons">
      <div class="data-attribute-display" id="quick-attribute" title="Click to copy data attribute">
        data-element-carousel
      </div>
      <button class="action-btn primary" id="download-config" title="Copy JavaScript code (Ctrl+D)" data-protection-animation="true">
        <span>📋</span>
        Copy JS
      </button>
      <button class="action-btn" id="copy-full-section" title="Copy complete section JSON for Bricks Builder (Ctrl+S)" data-protection-animation="true">
        <span>📦</span>
        Copy Full Section
      </button>
    </div>
  </div>

  <div class="container">
    <div class="page-header">
      <h1 class="page-title">Element Carousel</h1>
      <p class="page-subtitle">Transform any div elements into a smooth carousel for Bricks Builder</p>
    </div>

    <div class="instructions-toggle">
      <div class="instructions-card" id="instructions-card">
        <div class="instructions-header" id="instructions-toggle">
          <div class="instructions-title">
            How to Use & Code Information
          </div>
          <span class="toggle-icon">▼</span>
        </div>
        <div class="instructions-content" id="instructions-content">
          <div class="instructions-grid">
            <div class="how-to-use">
              <ol>
                <li>Customize your element carousel using the controls below</li>
                <li>Click <strong>Copy JS</strong> to copy the JavaScript code to clipboard</li>
                <li>In Bricks Builder, add a <strong>Code</strong> element</li>
                <li>Paste or upload the JavaScript code</li>
                <li>To add the effect to any section: go to <strong>Section → Style → Attributes</strong>, add <code>data-element-carousel</code> as attribute name (leave value empty)</li>
                
              </ol>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="content">
      <section class="preview-section">
        <div class="preview-container" id="carousel-preview">
          <div class="preview-content">Interactive Element Carousel Preview</div>
          <div class="preview-controls">
            <button class="preview-btn" id="randomize-carousel" title="Randomize (R)">🎲</button>
            <div class="background-selector-wrapper">
              <button class="preview-btn background-selector-btn" id="background-selector">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polygon points="12,2 2,7 12,12 22,7"/>
                  <polyline points="2,17 12,22 22,17"/>
                  <polyline points="2,12 12,17 22,12"/>
                </svg>
              </button>
              <input type="color" id="preview-background-picker" class="hidden-color-input" value="#000000" title="Change Preview Background (B)">
            </div>
          </div>
          <div id="element-carousel-container" data-element-carousel="true"></div>
        </div>
      </section>

      <section class="controls-section">
        <div class="card">
          <div class="card-heading">
            Animation Settings
            <div class="card-actions">
              <button class="card-action-btn" id="reset-animation" title="Reset Animation Settings">↺</button>
            </div>
          </div>
          <div class="card-content">
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Animation Speed
                  <span class="help-tooltip" title="Speed multiplier for the carousel animation">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="animation-speed-value">1</span>x</span>
                  <button class="reset-btn" onclick="resetParameter('animation-speed', 1)">↺</button>
                </div>
              </div>
              <input type="range" id="animation-speed" min="0.2" max="3" step="0.1" value="1">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Element Gap
                  <span class="help-tooltip" title="Space between carousel elements in pixels">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="element-gap-value">30</span>px</span>
                  <button class="reset-btn" onclick="resetParameter('element-gap', 30)">↺</button>
                </div>
              </div>
              <input type="range" id="element-gap" min="10" max="80" step="5" value="30">
            </div>
          </div>
        </div>

        <div class="card">
          <div class="card-heading">
            Blur Effects
            <div class="card-actions">
              <button class="card-action-btn" id="reset-blur" title="Reset Blur Settings">↺</button>
            </div>
          </div>
          <div class="card-content">
            <div class="color-list">
              <div class="color-row">
                <div class="color-picker-container">
                  <input type="color" id="blur-color" value="#000000">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HEX</span>
                  <input type="text" class="color-input hex-input" id="blur-color-hex" value="#000000" placeholder="#FFFFFF">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HSL</span>
                  <input type="text" class="color-input hsl-input" id="blur-color-hsl" placeholder="hsl(0, 100%, 50%)">
                </div>
              </div>
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Blur Intensity
                  <span class="help-tooltip" title="Opacity of edge blur effects">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="blur-opacity-value">90</span>%</span>
                  <button class="reset-btn" onclick="resetParameter('blur-opacity', 90)">↺</button>
                </div>
              </div>
              <input type="range" id="blur-opacity" min="0" max="100" step="10" value="90">
            </div>
          </div>
        </div>
      </section>
    </div>
  </div>

  <div class="notification" id="notification"></div>

  <script>
    document.addEventListener('DOMContentLoaded', function() {
      let carouselConfig = {
        animationSpeed: 1,
        elementGap: 30,
        blurColor: '#000000',
        blurOpacity: 0.9
      };

      const defaultConfig = { ...carouselConfig };
      let activeCarousel = null;
      
      // Optimized InfiniteCarousel class for elements
      class InfiniteCarousel {
        constructor(container, options = {}) {
          this.container = container;
          this.track = container.querySelector('.element-carousel-track');
          this.preview = container.querySelector('.element-carousel-preview');
          this.leftBlur = container.querySelector('.carousel-blur-left');
          this.rightBlur = container.querySelector('.carousel-blur-right');
          
          this.options = {
            speed: options.speed || 1,
            gap: options.gap || 30,
            blurColor: options.blurColor || '#000000',
            blurOpacity: options.blurOpacity || 0.9,
            ...options
          };
          
          this.animationId = null;
          this.currentX = 0;
          this.elements = [];
          this.clones = [];
          this.containerWidth = 0;
          this.contentWidth = 0;
          this.isRunning = false;
          this.isScrolling = false;
          this.lastMeasureTime = 0;
          this.isVisible = true;
          this.isUpdating = false;
          
          this.init();
        }
        
        // Optimized updateConfig method
        updateConfig(newOptions, updateType = 'full') {
          if (this.isUpdating) return;
          this.isUpdating = true;
          
          // Show visual feedback
          this.container.classList.add('updating');
          setTimeout(() => this.container.classList.remove('updating'), 600);
          
          const prevOptions = { ...this.options };
          Object.assign(this.options, newOptions);
          
          // Only update what's necessary based on what changed
          if (updateType === 'visual' || this.optionsChanged(prevOptions, ['blurColor', 'blurOpacity'])) {
            this.updateBlurEffects();
            this.updatePreviewBackground();
          }
          
          if (updateType === 'style' || this.optionsChanged(prevOptions, ['gap'])) {
            this.updateElementStyles();
          }
          
          if (updateType === 'speed' || this.optionsChanged(prevOptions, ['speed'])) {
            // Speed changes are applied in real-time during animation
          }
          
          this.isUpdating = false;
        }
        
        optionsChanged(prevOptions, keys) {
          return keys.some(key => prevOptions[key] !== this.options[key]);
        }
        
        updateBlurEffects() {
          if (!this.leftBlur || !this.rightBlur) return;
          
          const rgb = this.hexToRgb(this.options.blurColor);
          const blurColor = rgb ? `${rgb.r},${rgb.g},${rgb.b}` : '0,0,0';
          const opacity = this.options.blurOpacity;
          
          this.leftBlur.style.background = `linear-gradient(to right, rgba(${blurColor},${opacity}), rgba(${blurColor},0))`;
          this.rightBlur.style.background = `linear-gradient(to left, rgba(${blurColor},${opacity}), rgba(${blurColor},0))`;
        }
        
        updatePreviewBackground() {
          if (this.preview) {
            this.preview.style.backgroundColor = this.options.blurColor;
          }
        }
        
        updateElementStyles() {
          this.track.style.gap = `${this.options.gap}px`;
          
          // Recalculate dimensions after style changes
          setTimeout(() => {
            this.measureDimensions();
            this.createClones();
          }, 50);
        }
        
        init() {
          this.elements = Array.from(this.track.children);
          if (this.elements.length === 0) {
            this.createDefaultElements();
            this.elements = Array.from(this.track.children);
          }
          
          setTimeout(() => {
            this.measureDimensions();
            this.createClones();
            this.setupIntersectionObserver();
            this.setupScrollDetection();
            this.setupResizeHandler();
            this.updateBlurEffects();
            this.updatePreviewBackground();
            this.start();
          }, 100);
        }
        
        createDefaultElements() {
          const gradients = [
            'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
            'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
            'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)',
            'linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)',
            'linear-gradient(135deg, #fa709a 0%, #fee140 100%)',
            'linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)'
          ];
          
          for (let i = 0; i < 6; i++) {
            const element = document.createElement('div');
            element.className = 'carousel-element';
            element.style.background = gradients[i % gradients.length];
            element.textContent = `Element ${i + 1}`;
            this.track.appendChild(element);
          }
        }
        
        setupIntersectionObserver() {
          const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
              this.isVisible = entry.isIntersecting;
              if (!this.isVisible) {
                this.pause();
              } else {
                this.resume();
              }
            });
          }, {
            threshold: 0.1,
            rootMargin: '50px'
          });
          
          observer.observe(this.container);
          this.intersectionObserver = observer;
        }
        
        setupScrollDetection() {
          let scrollTimer = null;
          
          const handleScroll = () => {
            this.isScrolling = true;
            clearTimeout(scrollTimer);
            
            scrollTimer = setTimeout(() => {
              this.isScrolling = false;
            }, 150);
          };
          
          window.addEventListener('scroll', handleScroll, { passive: true });
          window.addEventListener('touchmove', handleScroll, { passive: true });
          
          this.scrollHandler = handleScroll;
        }
        
        setupResizeHandler() {
          let resizeTimer = null;
          let lastWidth = this.container.offsetWidth;
          
          const handleResize = () => {
            if (this.isScrolling) return;
            
            const currentWidth = this.container.offsetWidth;
            if (Math.abs(currentWidth - lastWidth) < 10) return;
            
            lastWidth = currentWidth;
            clearTimeout(resizeTimer);
            
            resizeTimer = setTimeout(() => {
              if (!this.isScrolling && this.isVisible) {
                this.measureDimensions();
                this.createClones();
              }
            }, 300);
          };
          
          window.addEventListener('resize', handleResize, { passive: true });
          this.resizeHandler = handleResize;
        }
        
        measureDimensions() {
          const now = Date.now();
          if (now - this.lastMeasureTime < 100) return;
          this.lastMeasureTime = now;
          
          this.containerWidth = this.container.offsetWidth;
          
          this.contentWidth = 0;
          this.elements.forEach(element => {
            if (element.offsetWidth > 0) {
              this.contentWidth += element.offsetWidth + this.options.gap;
            }
          });
          this.contentWidth = Math.max(this.contentWidth - this.options.gap, 100);
        }
        
        createClones() {
          if (this.isScrolling) return;
          
          this.clones.forEach(clone => clone.remove());
          this.clones = [];
          
          if (this.contentWidth === 0) return;
          
          const totalNeeded = Math.ceil((this.containerWidth * 2.5) / this.contentWidth) + 1;
          
          for (let i = 0; i < totalNeeded; i++) {
            this.elements.forEach(element => {
              const clone = element.cloneNode(true);
              clone.classList.add('carousel-clone');
              this.track.appendChild(clone);
              this.clones.push(clone);
            });
          }
        }
        
        start() {
          if (this.isRunning || !this.isVisible) return;
          this.isRunning = true;
          this.animate();
        }
        
        pause() {
          this.isRunning = false;
          if (this.animationId) {
            cancelAnimationFrame(this.animationId);
            this.animationId = null;
          }
        }
        
        resume() {
          if (!this.isRunning && this.isVisible) {
            this.start();
          }
        }
        
        stop() {
          this.pause();
        }
        
        animate() {
          if (!this.isRunning || !this.isVisible) return;
          
          // Use current speed from options (allows real-time speed changes)
          this.currentX -= this.options.speed * 0.5;
          
          if (Math.abs(this.currentX) >= this.contentWidth + this.options.gap) {
            this.currentX = 0;
          }
          
          this.track.style.transform = `translateX(${this.currentX}px)`;
          
          this.animationId = requestAnimationFrame(() => this.animate());
        }
        
        hexToRgb(hex) {
          const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
          return result ? {
            r: parseInt(result[1], 16),
            g: parseInt(result[2], 16),
            b: parseInt(result[3], 16)
          } : null;
        }
        
        destroy() {
          this.stop();
          this.clones.forEach(clone => clone.remove());
          this.clones = [];
          
          if (this.intersectionObserver) {
            this.intersectionObserver.disconnect();
          }
          
          if (this.resizeHandler) {
            window.removeEventListener('resize', this.resizeHandler);
          }
          
          if (this.scrollHandler) {
            window.removeEventListener('scroll', this.scrollHandler);
            window.removeEventListener('touchmove', this.scrollHandler);
          }
        }
      }
      
      function initElementCarousel() {
        const container = document.getElementById('element-carousel-container');
        if (!container) return;
        
        const previewContent = document.querySelector('.preview-content');
        if (previewContent) {
          previewContent.style.display = 'none';
        }
        
        // Only create new instance if one doesn't exist
        if (!activeCarousel) {
          container.innerHTML = '';
          
          const preview = document.createElement('div');
          preview.className = 'element-carousel-preview';
          
          const track = document.createElement('div');
          track.className = 'element-carousel-track';
          
          const leftBlur = document.createElement('div');
          leftBlur.className = 'carousel-blur-left';
          const rightBlur = document.createElement('div');
          rightBlur.className = 'carousel-blur-right';
          
          preview.appendChild(leftBlur);
          preview.appendChild(track);
          preview.appendChild(rightBlur);
          container.appendChild(preview);
          
          setTimeout(() => {
            activeCarousel = new InfiniteCarousel(preview, {
              speed: carouselConfig.animationSpeed,
              gap: carouselConfig.elementGap,
              blurColor: carouselConfig.blurColor,
              blurOpacity: carouselConfig.blurOpacity
            });
          }, 100);
        }
      }
      
      // Optimized update function
      function updateCarouselPreview(updateType = 'full') {
        if (activeCarousel && activeCarousel.updateConfig) {
          const newOptions = {
            speed: carouselConfig.animationSpeed,
            gap: carouselConfig.elementGap,
            blurColor: carouselConfig.blurColor,
            blurOpacity: carouselConfig.blurOpacity
          };
          
          activeCarousel.updateConfig(newOptions, updateType);
        } else {
          // Fallback to full recreation if carousel doesn't exist
          if (activeCarousel) {
            activeCarousel.destroy();
            activeCarousel = null;
          }
          initElementCarousel();
        }
      }

      function hexToRgb(hex) {
        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result ? {
          r: parseInt(result[1], 16),
          g: parseInt(result[2], 16),
          b: parseInt(result[3], 16)
        } : null;
      }

      function hslToHex(hsl) {
        const match = hsl.match(/hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/);
        if (!match) return null;
        
        let h = parseInt(match[1]) / 360;
        let s = parseInt(match[2]) / 100;
        let l = parseInt(match[3]) / 100;
        
        const hue2rgb = (p, q, t) => {
          if (t < 0) t += 1;
          if (t > 1) t -= 1;
          if (t < 1/6) return p + (q - p) * 6 * t;
          if (t < 1/2) return q;
          if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
          return p;
        };
        
        let r, g, b;
        if (s === 0) {
          r = g = b = l;
        } else {
          const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
          const p = 2 * l - q;
          r = hue2rgb(p, q, h + 1/3);
          g = hue2rgb(p, q, h);
          b = hue2rgb(p, q, h - 1/3);
        }
        
        const toHex = (c) => {
          const hex = Math.round(c * 255).toString(16);
          return hex.length === 1 ? '0' + hex : hex;
        };
        
        return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
      }

      function isValidHex(hex) {
        return /^#[0-9A-F]{6}$/i.test(hex);
      }

      function isValidHsl(hsl) {
        return /^hsl\(\s*(\d{1,3})\s*,\s*(\d{1,3})%\s*,\s*(\d{1,3})%\s*\)$/i.test(hsl);
      }

      function formatHex(value) {
        let hex = value.replace(/[^0-9A-Fa-f#]/g, '');
        
        if (!hex.startsWith('#')) {
          hex = '#' + hex;
        }
        
        if (hex.length > 7) {
          hex = hex.substring(0, 7);
        }
        
        return hex.toUpperCase();
      }

      function formatHsl(value) {
        const cleanValue = value.replace(/[^\d,\s]/g, '');
        const numbers = cleanValue.match(/\d+/g);
        
        if (!numbers || numbers.length < 3) {
          const partialMatch = value.match(/(\d+)/g);
          if (partialMatch && partialMatch.length >= 1) {
            const h = Math.min(360, Math.max(0, parseInt(partialMatch[0]) || 0));
            const s = Math.min(100, Math.max(0, parseInt(partialMatch[1]) || 50));
            const l = Math.min(100, Math.max(0, parseInt(partialMatch[2]) || 50));
            return `hsl(${h}, ${s}%, ${l}%)`;
          }
          return value;
        }
        
        let h = Math.min(360, Math.max(0, parseInt(numbers[0])));
        let s = Math.min(100, Math.max(0, parseInt(numbers[1])));
        let l = Math.min(100, Math.max(0, parseInt(numbers[2])));
        
        return `hsl(${h}, ${s}%, ${l}%)`;
      }

      function generateRandomColor() {
        return '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0');
      }

      function showNotification(message, type = 'success') {
        const notification = document.getElementById('notification');
        notification.textContent = message;
        notification.className = `notification ${type}`;
        
        notification.offsetHeight;
        
        notification.style.visibility = 'visible';
        notification.classList.add('show');
        
        setTimeout(() => {
          notification.classList.remove('show');
          
          setTimeout(() => {
            if (!notification.classList.contains('show')) {
              notification.style.visibility = 'hidden';
            }
          }, 400);
        }, 3000);
      }

      function generateUniqueId() {
        return Math.random().toString(36).substring(2, 8);
      }

      function generateFullSectionJSON() {
  // Generar IDs únicos para todos los elementos
  const wgotyeId = generateUniqueId();
  const lbpduqId = generateUniqueId();
  const aqirmeId = generateUniqueId();
  const qywqnxId = generateUniqueId();
  const ttsijwId = generateUniqueId();
  const maddkjId = generateUniqueId();
  const ljpljyId = generateUniqueId();
  const ojurgvId = generateUniqueId();
  const rxkuanId = generateUniqueId();
  const bsyrxyId = generateUniqueId();
  const qgfciaId = generateUniqueId();
  const gylgleId = generateUniqueId();
  const xumandId = generateUniqueId();
  const wactzm = generateUniqueId();
  const qgldenId = generateUniqueId();
  const vtmbzoId = generateUniqueId();
  const cgtuxkId = generateUniqueId();
  const gycnmnId = generateUniqueId();
  const cdfvapId = generateUniqueId();
  const osjebjId = generateUniqueId();
  const dwmygzId = generateUniqueId();
  const ykcyffId = generateUniqueId();
  const unomdkId = generateUniqueId();
  const dbnfpaId = generateUniqueId();
  const bjrmgdId = generateUniqueId();
  const qxvgduId = generateUniqueId();
  const gxbkreId = generateUniqueId();
  const izzjvfId = generateUniqueId();
  const nbiufkId = generateUniqueId();
  const nmkefiId = generateUniqueId();
  const tiznzoId = generateUniqueId();
  const bqktsyId = generateUniqueId();
  const yucuiiId = generateUniqueId();
  const vrbwfeId = generateUniqueId();
  const vbkvjzId = generateUniqueId();
  const cqliuaId = generateUniqueId();
  const qrofwnId = generateUniqueId();
  const xatfabId = generateUniqueId();
  const cqerbiId = generateUniqueId();
  const liehxjId = generateUniqueId();
  const aslogsId = generateUniqueId();
  const jqhulvId = generateUniqueId();
  const zdozjgId = generateUniqueId();
  const ynpvumId = generateUniqueId();
  const bhphidId = generateUniqueId();
  const dhzquvId = generateUniqueId();
  const wlucovId = generateUniqueId();
  const bvqpezId = generateUniqueId();
  const jmusfcId = generateUniqueId();
  const apkcznId = generateUniqueId();
  const kopplnId = generateUniqueId();
  const mmlemwId = generateUniqueId();
  const fnifwcId = generateUniqueId();
  const hmmmxxId = generateUniqueId();

  // Obtener el JavaScript actual con la configuración del usuario
  const jsCode = generateJavaScriptCode();

  // Crear el objeto JSON completo de Bricks Builder
  const bricksJSON = {
    "content": [
      {
        "id": wgotyeId,
        "name": "section",
        "parent": 0,
        "children": [lbpduqId],
        "settings": {
          "_padding": {"top": "100", "right": "20", "bottom": "100", "left": "20"},
          "_padding:mobile_landscape": {"top": "50", "bottom": "50"}
        },
        "label": "Loomia 004"
      },
      {
        "id": lbpduqId,
        "name": "container",
        "parent": wgotyeId,
        "children": [aqirmeId, maddkjId, zdozjgId],
        "settings": {
          "_alignItems": "center",
          "_rowGap": "60"
        }
      },
      {
        "id": aqirmeId,
        "name": "div",
        "parent": lbpduqId,
        "children": [qywqnxId, ttsijwId],
        "settings": {
          "_alignItems": "center",
          "_display": "flex",
          "_direction": "column",
          "_zIndex": "999",
          "_width": "50%",
          "_rowGap": "30",
          "_width:tablet_portrait": "70%",
          "_width:mobile_landscape": "100%"
        }
      },
      {
        "id": qywqnxId,
        "name": "text-basic",
        "parent": aqirmeId,
        "children": [],
        "settings": {
          "_display": "flex",
          "text": "Features",
          "tag": "span",
          "_padding": {"right": "10", "left": "10", "top": "2", "bottom": "2"},
          "_width": "fit-content",
          "_border": {"radius": {"top": "15", "right": "15", "bottom": "15", "left": "15"}},
          "_background": {"color": {"hex": "#242424"}},
          "_gradient": {
            "colors": [
              {"id": "redtyh", "color": {"hex": "#1e40af"}},
              {"id": "qogjyx", "color": {"hex": "#112464"}}
            ],
            "repeat": true,
            "angle": "90"
          },
          "_typography": {"color": {"hex": "#ffffff"}, "font-size": "15", "font-weight": "400"}
        }
      },
      {
        "id": ttsijwId,
        "name": "heading",
        "parent": aqirmeId,
        "children": [],
        "settings": {
          "text": "Everything you need, nothing you don't.",
          "tag": "h2",
          "_typography": {
            "color": {"hex": "#1e40af"},
            "font-size": "50",
            "font-weight": "600",
            "line-height": "1.2",
            "text-align": "center"
          },
          "_typography:tablet_portrait": {"font-size": "40"},
          "_typography:mobile_landscape": {"font-size": "30"}
        }
      },
      {
        "id": maddkjId,
        "name": "block",
        "parent": lbpduqId,
        "children": [ljpljyId, xumandId, cdfvapId, bjrmgdId, tiznzoId, qrofwnId],
        "settings": {
          "_display": "grid",
          "_gridTemplateColumns": "1fr 1fr 1fr",
          "_gridGap": "20",
          "_gridTemplateColumns:tablet_portrait": "1fr 1fr",
          "_gridTemplateColumns:mobile_landscape": "1fr"
        }
      },
      {
        "id": ljpljyId,
        "name": "div",
        "parent": maddkjId,
        "children": [ojurgvId, bsyrxyId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_padding": {"top": "30", "right": "30", "bottom": "30", "left": "30"},
          "_border": {
            "radius": {"top": "10", "right": "10", "bottom": "10", "left": "10"},
            "style": "solid",
            "width": {"top": "5", "right": "5", "bottom": "5", "left": "5"},
            "color": {"hex": "#f7f7f7"}
          },
          "_rowGap": "20"
        }
      },
      {
        "id": ojurgvId,
        "name": "div",
        "parent": ljpljyId,
        "children": [rxkuanId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_alignSelf": "flex-start"
        }
      },
      {
        "id": rxkuanId,
        "name": "icon",
        "parent": ojurgvId,
        "children": [],
        "settings": {
          "icon": {"library": "themify", "icon": "ti-control-pause"},
          "iconSize": "40",
          "iconColor": {"hex": "#1e40af"},
          "iconSize:mobile_landscape": "30"
        },
        "themeStyles": []
      },
      {
        "id": bsyrxyId,
        "name": "div",
        "parent": ljpljyId,
        "children": [qgfciaId, gylgleId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_rowGap": "10"
        }
      },
      {
        "id": qgfciaId,
        "name": "text-basic",
        "parent": bsyrxyId,
        "children": [],
        "settings": {
          "text": "Effortless setup",
          "tag": "span",
          "_typography": {"color": {"hex": "#000000"}, "font-size": "25", "font-weight": "600"},
          "_typography:mobile_landscape": {"font-size": "20"}
        }
      },
      {
        "id": gylgleId,
        "name": "text-basic",
        "parent": bsyrxyId,
        "children": [],
        "settings": {
          "text": "Start designing instantly. No tech hurdles, no wasted time.",
          "tag": "p",
          "_typography": {"font-size": "16", "color": {"hex": "#707070"}, "font-weight": "400", "line-height": "1.4"}
        }
      },
      {
        "id": xumandId,
        "name": "div",
        "parent": maddkjId,
        "children": [wactzm, vtmbzoId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_padding": {"top": "30", "right": "30", "bottom": "30", "left": "30"},
          "_border": {
            "radius": {"top": "10", "right": "10", "bottom": "10", "left": "10"},
            "style": "solid",
            "width": {"top": "5", "right": "5", "bottom": "5", "left": "5"},
            "color": {"hex": "#f7f7f7"}
          },
          "_rowGap": "20"
        }
      },
      {
        "id": wactzm,
        "name": "div",
        "parent": xumandId,
        "children": [qgldenId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_alignSelf": "flex-start"
        }
      },
      {
        "id": qgldenId,
        "name": "icon",
        "parent": wactzm,
        "children": [],
        "settings": {
          "icon": {"library": "ionicons", "icon": "ion-ios-refresh"},
          "iconSize": "40",
          "iconColor": {"hex": "#1e40af"},
          "iconSize:mobile_landscape": "30"
        },
        "themeStyles": []
      },
      {
        "id": vtmbzoId,
        "name": "div",
        "parent": xumandId,
        "children": [cgtuxkId, gycnmnId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_rowGap": "10"
        }
      },
      {
        "id": cgtuxkId,
        "name": "text-basic",
        "parent": vtmbzoId,
        "children": [],
        "settings": {
          "text": "Total flexibility",
          "tag": "span",
          "_typography": {"color": {"hex": "#000000"}, "font-size": "25", "font-weight": "600"},
          "_typography:mobile_landscape": {"font-size": "20"}
        }
      },
      {
        "id": gycnmnId,
        "name": "text-basic",
        "parent": vtmbzoId,
        "children": [],
        "settings": {
          "text": "Adapt every section to your brand with complete freedom.",
          "tag": "p",
          "_typography": {"font-size": "16", "color": {"hex": "#707070"}, "font-weight": "400", "line-height": "1.4"}
        }
      },
      {
        "id": cdfvapId,
        "name": "div",
        "parent": maddkjId,
        "children": [osjebjId, ykcyffId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_padding": {"top": "30", "right": "30", "bottom": "30", "left": "30"},
          "_border": {
            "radius": {"top": "10", "right": "10", "bottom": "10", "left": "10"},
            "style": "solid",
            "width": {"top": "5", "right": "5", "bottom": "5", "left": "5"},
            "color": {"hex": "#f7f7f7"}
          },
          "_rowGap": "20"
        }
      },
      {
        "id": osjebjId,
        "name": "div",
        "parent": cdfvapId,
        "children": [dwmygzId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_alignSelf": "flex-start"
        }
      },
      {
        "id": dwmygzId,
        "name": "icon",
        "parent": osjebjId,
        "children": [],
        "settings": {
          "icon": {"library": "themify", "icon": "ti-rocket"},
          "iconSize": "40",
          "iconColor": {"hex": "#1e40af"},
          "iconSize:mobile_landscape": "30"
        },
        "themeStyles": []
      },
      {
        "id": ykcyffId,
        "name": "div",
        "parent": cdfvapId,
        "children": [unomdkId, dbnfpaId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_rowGap": "10"
        }
      },
      {
        "id": unomdkId,
        "name": "text-basic",
        "parent": ykcyffId,
        "children": [],
        "settings": {
          "text": "Lightning-fast workflow",
          "tag": "span",
          "_typography": {"color": {"hex": "#000000"}, "font-size": "25", "font-weight": "600"},
          "_typography:mobile_landscape": {"font-size": "20"}
        }
      },
      {
        "id": dbnfpaId,
        "name": "text-basic",
        "parent": ykcyffId,
        "children": [],
        "settings": {
          "text": "Build and launch stunning pages in record time.",
          "tag": "p",
          "_typography": {"font-size": "16", "color": {"hex": "#707070"}, "font-weight": "400", "line-height": "1.4"}
        }
      },
      {
        "id": bjrmgdId,
        "name": "div",
        "parent": maddkjId,
        "children": [qxvgduId, izzjvfId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_padding": {"top": "30", "right": "30", "bottom": "30", "left": "30"},
          "_border": {
            "radius": {"top": "10", "right": "10", "bottom": "10", "left": "10"},
            "style": "solid",
            "width": {"top": "5", "right": "5", "bottom": "5", "left": "5"},
            "color": {"hex": "#f7f7f7"}
          },
          "_rowGap": "20"
        }
      },
      {
        "id": qxvgduId,
        "name": "div",
        "parent": bjrmgdId,
        "children": [gxbkreId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_alignSelf": "flex-start"
        }
      },
      {
        "id": gxbkreId,
        "name": "icon",
        "parent": qxvgduId,
        "children": [],
        "settings": {
          "icon": {"library": "themify", "icon": "ti-star"},
          "iconSize": "40",
          "iconColor": {"hex": "#1e40af"},
          "iconSize:mobile_landscape": "30"
        },
        "themeStyles": []
      },
      {
        "id": izzjvfId,
        "name": "div",
        "parent": bjrmgdId,
        "children": [nbiufkId, nmkefiId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_rowGap": "10"
        }
      },
      {
        "id": nbiufkId,
        "name": "text-basic",
        "parent": izzjvfId,
        "children": [],
        "settings": {
          "text": "Premium quality",
          "tag": "span",
          "_typography": {"color": {"hex": "#000000"}, "font-size": "25", "font-weight": "600"},
          "_typography:mobile_landscape": {"font-size": "20"}
        }
      },
      {
        "id": nmkefiId,
        "name": "text-basic",
        "parent": izzjvfId,
        "children": [],
        "settings": {
          "text": "Beautifully designed layouts crafted for professionals.",
          "tag": "p",
          "_typography": {"font-size": "16", "color": {"hex": "#707070"}, "font-weight": "400", "line-height": "1.4"}
        }
      },
      {
        "id": tiznzoId,
        "name": "div",
        "parent": maddkjId,
        "children": [bqktsyId, vrbwfeId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_padding": {"top": "30", "right": "30", "bottom": "30", "left": "30"},
          "_border": {
            "radius": {"top": "10", "right": "10", "bottom": "10", "left": "10"},
            "style": "solid",
            "width": {"top": "5", "right": "5", "bottom": "5", "left": "5"},
            "color": {"hex": "#f7f7f7"}
          },
          "_rowGap": "20"
        }
      },
      {
        "id": bqktsyId,
        "name": "div",
        "parent": tiznzoId,
        "children": [yucuiiId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_alignSelf": "flex-start"
        }
      },
      {
        "id": yucuiiId,
        "name": "icon",
        "parent": bqktsyId,
        "children": [],
        "settings": {
          "icon": {"library": "ionicons", "icon": "ion-md-hammer"},
          "iconSize": "40",
          "iconColor": {"hex": "#1e40af"},
          "iconSize:mobile_landscape": "30"
        },
        "themeStyles": []
      },
      {
        "id": vrbwfeId,
        "name": "div",
        "parent": tiznzoId,
        "children": [vbkvjzId, cqliuaId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_rowGap": "10"
        }
      },
      {
        "id": vbkvjzId,
        "name": "text-basic",
        "parent": vrbwfeId,
        "children": [],
        "settings": {
          "text": "Full control",
          "tag": "span",
          "_typography": {"color": {"hex": "#000000"}, "font-size": "25", "font-weight": "600"},
          "_typography:mobile_landscape": {"font-size": "20"}
        }
      },
      {
        "id": cqliuaId,
        "name": "text-basic",
        "parent": vrbwfeId,
        "children": [],
        "settings": {
          "text": "You decide what to keep, tweak, or change, it's yours.",
          "tag": "p",
          "_typography": {"font-size": "16", "color": {"hex": "#707070"}, "font-weight": "400", "line-height": "1.4"}
        }
      },
      {
        "id": qrofwnId,
        "name": "div",
        "parent": maddkjId,
        "children": [xatfabId, liehxjId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_padding": {"top": "30", "right": "30", "bottom": "30", "left": "30"},
          "_border": {
            "radius": {"top": "10", "right": "10", "bottom": "10", "left": "10"},
            "style": "solid",
            "width": {"top": "5", "right": "5", "bottom": "5", "left": "5"},
            "color": {"hex": "#f7f7f7"}
          },
          "_rowGap": "20"
        }
      },
      {
        "id": xatfabId,
        "name": "div",
        "parent": qrofwnId,
        "children": [cqerbiId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_alignSelf": "flex-start"
        }
      },
      {
        "id": cqerbiId,
        "name": "icon",
        "parent": xatfabId,
        "children": [],
        "settings": {
          "icon": {"library": "themify", "icon": "ti-bar-chart"},
          "iconSize": "40",
          "iconColor": {"hex": "#1e40af"},
          "iconSize:mobile_landscape": "30"
        },
        "themeStyles": []
      },
      {
        "id": liehxjId,
        "name": "div",
        "parent": qrofwnId,
        "children": [aslogsId, jqhulvId],
        "settings": {
          "_display": "flex",
          "_direction": "column",
          "_rowGap": "10"
        }
      },
      {
        "id": aslogsId,
        "name": "text-basic",
        "parent": liehxjId,
        "children": [],
        "settings": {
          "text": "Scalable design",
          "tag": "span",
          "_typography": {"color": {"hex": "#000000"}, "font-size": "25", "font-weight": "600"},
          "_typography:mobile_landscape": {"font-size": "20"}
        }
      },
      {
        "id": jqhulvId,
        "name": "text-basic",
        "parent": liehxjId,
        "children": [],
        "settings": {
          "text": "Grow and expand without redesigning from scratch.",
          "tag": "p",
          "_typography": {"font-size": "16", "color": {"hex": "#707070"}, "font-weight": "400", "line-height": "1.4"}
        }
      },
      {
        "id": zdozjgId,
        "name": "div",
        "parent": lbpduqId,
        "children": [ynpvumId, dhzquvId, bvqpezId, apkcznId, mmlemwId, hmmmxxId],
        "settings": {
          "_direction": "row",
          "_alignSelf": "flex-start",
          "_display": "flex",
          "_width": "100%",
          "_attributes": [{"id": "thseuz", "name": "data-element-carousel"}]
        },
        "label": "Element Carousel"
      },
      {
        "id": ynpvumId,
        "name": "div",
        "parent": zdozjgId,
        "children": [bhphidId],
        "settings": {
          "_display": "flex",
          "_padding": {"right": "10", "left": "10", "top": "2", "bottom": "2"},
          "_border": {"radius": {"top": "15", "right": "15", "bottom": "15", "left": "15"}},
          "_gradient": {
            "colors": [
              {"id": "redtyh", "color": {"hex": "#1e40af"}},
              {"id": "qogjyx", "color": {"hex": "#112464"}}
            ],
            "repeat": true,
            "angle": "90"
          }
        }
      },
      {
        "id": bhphidId,
        "name": "text-basic",
        "parent": ynpvumId,
        "children": [],
        "settings": {
          "text": "Pitch Decks",
          "tag": "span",
          "_typography": {"font-size": "15", "color": {"hex": "#ffffff"}, "font-weight": "500"}
        }
      },
      {
        "id": dhzquvId,
        "name": "div",
        "parent": zdozjgId,
        "children": [wlucovId],
        "settings": {
          "_display": "flex",
          "_padding": {"right": "10", "left": "10", "top": "2", "bottom": "2"},
          "_border": {"radius": {"top": "15", "right": "15", "bottom": "15", "left": "15"}},
          "_gradient": {
            "colors": [
              {"id": "redtyh", "color": {"hex": "#1e40af"}},
              {"id": "qogjyx", "color": {"hex": "#112464"}}
            ],
            "repeat": true,
            "angle": "90"
          }
        }
      },
      {
        "id": wlucovId,
        "name": "text-basic",
        "parent": dhzquvId,
        "children": [],
        "settings": {
          "text": "Branding",
          "tag": "span",
          "_typography": {"font-size": "15", "color": {"hex": "#ffffff"}, "font-weight": "500"}
        }
      },
      {
        "id": bvqpezId,
        "name": "div",
        "parent": zdozjgId,
        "children": [jmusfcId],
        "settings": {
          "_display": "flex",
          "_padding": {"right": "10", "left": "10", "top": "2", "bottom": "2"},
          "_border": {"radius": {"top": "15", "right": "15", "bottom": "15", "left": "15"}},
          "_gradient": {
            "colors": [
              {"id": "redtyh", "color": {"hex": "#1e40af"}},
              {"id": "qogjyx", "color": {"hex": "#112464"}}
            ],
            "repeat": true,
            "angle": "90"
          }
        }
      },
      {
        "id": jmusfcId,
        "name": "text-basic",
        "parent": bvqpezId,
        "children": [],
        "settings": {
          "text": "Web Design",
          "tag": "span",
          "_typography": {"font-size": "15", "color": {"hex": "#ffffff"}, "font-weight": "500"}
        }
      },
      {
        "id": apkcznId,
        "name": "div",
        "parent": zdozjgId,
        "children": [kopplnId],
        "settings": {
          "_display": "flex",
          "_padding": {"right": "10", "left": "10", "top": "2", "bottom": "2"},
          "_border": {"radius": {"top": "15", "right": "15", "bottom": "15", "left": "15"}},
          "_background": {"color": {"hex": "#242424"}},
          "_gradient": {
            "colors": [
              {"id": "redtyh", "color": {"hex": "#1e40af"}},
              {"id": "qogjyx", "color": {"hex": "#112464"}}
            ],
            "repeat": true,
            "angle": "90"
          }
        }
      },
      {
        "id": kopplnId,
        "name": "text-basic",
        "parent": apkcznId,
        "children": [],
        "settings": {
          "tag": "span",
          "_typography": {"font-size": "15", "color": {"hex": "#ffffff"}, "font-weight": "500"},
          "text": "UX Design"
        }
      },
      {
        "id": mmlemwId,
        "name": "div",
        "parent": zdozjgId,
        "children": [fnifwcId],
        "settings": {
          "_display": "flex",
          "_padding": {"right": "10", "left": "10", "top": "2", "bottom": "2"},
          "_border": {"radius": {"top": "15", "right": "15", "bottom": "15", "left": "15"}},
          "_background": {"color": {"hex": "#242424"}},
          "_gradient": {
            "colors": [
              {"id": "redtyh", "color": {"hex": "#1e40af"}},
              {"id": "qogjyx", "color": {"hex": "#112464"}}
            ],
            "repeat": true,
            "angle": "90"
          }
        }
      },
      {
        "id": fnifwcId,
        "name": "text-basic",
        "parent": mmlemwId,
        "children": [],
        "settings": {
          "tag": "span",
          "_typography": {"font-size": "15", "color": {"hex": "#ffffff"}, "font-weight": "500"},
          "text": "Social Graphics"
        }
      },
      {
        "id": hmmmxxId,
        "name": "code",
        "parent": zdozjgId,
        "children": [],
        "settings": {
          "javascriptCode": jsCode,
          "executeCode": true,
          "_display": "none"
        },
        "label": "Element Carousel JS",
        "themeStyles": []
      }
    ],
    "source": "bricksCopiedElements",
    "sourceUrl": "https://library.bricksfusion.com",
    "version": "2.0.1",
    "globalClasses": [],
    "globalElements": []
  };

  return JSON.stringify(bricksJSON, null, 2);
}

      function generateJavaScriptCode() {
        return `(function(){
  // Inject styles only once globally
  if (!document.getElementById('element-carousel-styles')) {
    const style = document.createElement('style');
    style.id = 'element-carousel-styles';
    style.textContent = \`
      .element-carousel-preview {
        display: flex;
        align-items: center;
        overflow: hidden;
        position: relative;
        width: 100%;
        height: 100%;
      }
      
      .element-carousel-track {
        display: flex;
        align-items: center;
        will-change: transform;
        padding: 0;
        position: relative;
        gap: ${carouselConfig.elementGap}px;
        backface-visibility: hidden;
        perspective: 1000px;
        transform: translateZ(0);
        height: 100%;
      }
      
      .element-carousel-track > * {
        flex-shrink: 0;
        transition: all 0.3s ease;
        opacity: 0.95;
      }
      
      .element-carousel-track > *:hover {
        opacity: 1;
        transform: translateY(-2px);
      }
      
      .carousel-blur-left,
      .carousel-blur-right {
        position: absolute;
        top: 0;
        bottom: 0;
        width: min(80px, 15%);
        pointer-events: none;
        z-index: 1;
      }
      
      .carousel-blur-left {
        left: 0;
        background: linear-gradient(to right, rgba(${(() => {
          const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(carouselConfig.blurColor);
          return result ? `${parseInt(result[1], 16)},${parseInt(result[2], 16)},${parseInt(result[3], 16)}` : '0,0,0';
        })()},${carouselConfig.blurOpacity}), rgba(${(() => {
          const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(carouselConfig.blurColor);
          return result ? `${parseInt(result[1], 16)},${parseInt(result[2], 16)},${parseInt(result[3], 16)}` : '0,0,0';
        })()},0));
      }
      
      .carousel-blur-right {
        right: 0;
        background: linear-gradient(to left, rgba(${(() => {
          const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(carouselConfig.blurColor);
          return result ? `${parseInt(result[1], 16)},${parseInt(result[2], 16)},${parseInt(result[3], 16)}` : '0,0,0';
        })()},${carouselConfig.blurOpacity}), rgba(${(() => {
          const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(carouselConfig.blurColor);
          return result ? `${parseInt(result[1], 16)},${parseInt(result[2], 16)},${parseInt(result[3], 16)}` : '0,0,0';
        })()},0));
      }
    \`;
    document.head.appendChild(style);
  }

  // Centralized Carousel Manager for performance optimization
  class CarouselManager {
    constructor() {
      this.instances = new Map();
      this.animationId = null;
      this.isAnimating = false;
      this.intersectionObserver = null;
      this.resizeObserver = null;
      this.resizeTimer = null;
      this.scrollTimer = null;
      this.isScrolling = false;
      
      this.setupGlobalObservers();
      this.setupGlobalEventListeners();
    }

    setupGlobalObservers() {
      // Single intersection observer for all carousels
      this.intersectionObserver = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
          const carousel = this.instances.get(entry.target);
          if (carousel) {
            carousel.isVisible = entry.isIntersecting;
            this.updateAnimationState();
          }
        });
      }, {
        threshold: 0.1,
        rootMargin: '50px'
      });

      // Single resize observer for all carousels
      if (window.ResizeObserver) {
        this.resizeObserver = new ResizeObserver((entries) => {
          clearTimeout(this.resizeTimer);
          this.resizeTimer = setTimeout(() => {
            if (!this.isScrolling) {
              this.instances.forEach(carousel => {
                if (carousel.isVisible) {
                  carousel.measureAndUpdate();
                }
              });
            }
          }, 250);
        });
      }
    }

    setupGlobalEventListeners() {
      // Global scroll detection
      const handleScroll = () => {
        this.isScrolling = true;
        clearTimeout(this.scrollTimer);
        this.scrollTimer = setTimeout(() => {
          this.isScrolling = false;
        }, 150);
      };

      window.addEventListener('scroll', handleScroll, { passive: true });
      window.addEventListener('touchmove', handleScroll, { passive: true });

      // Fallback resize handler if ResizeObserver is not available
      if (!window.ResizeObserver) {
        window.addEventListener('resize', () => {
          clearTimeout(this.resizeTimer);
          this.resizeTimer = setTimeout(() => {
            if (!this.isScrolling) {
              this.instances.forEach(carousel => {
                if (carousel.isVisible) {
                  carousel.measureAndUpdate();
                }
              });
            }
          }, 250);
        }, { passive: true });
      }
    }

    // Single animation loop for all carousels
    startGlobalAnimation() {
      if (this.isAnimating) return;
      this.isAnimating = true;
      
      const animate = () => {
        if (!this.isAnimating) return;
        
        let hasActiveCarousels = false;
        this.instances.forEach(carousel => {
          if (carousel.isVisible && carousel.isRunning) {
            carousel.updatePosition();
            hasActiveCarousels = true;
          }
        });

        if (hasActiveCarousels) {
          this.animationId = requestAnimationFrame(animate);
        } else {
          this.isAnimating = false;
          this.animationId = null;
        }
      };
      
      this.animationId = requestAnimationFrame(animate);
    }

    stopGlobalAnimation() {
      this.isAnimating = false;
      if (this.animationId) {
        cancelAnimationFrame(this.animationId);
        this.animationId = null;
      }
    }

    updateAnimationState() {
      const hasVisibleCarousels = Array.from(this.instances.values()).some(c => c.isVisible);
      if (hasVisibleCarousels && !this.isAnimating) {
        this.startGlobalAnimation();
      } else if (!hasVisibleCarousels && this.isAnimating) {
        this.stopGlobalAnimation();
      }
    }

    addCarousel(container, carousel) {
      this.instances.set(container, carousel);
      this.intersectionObserver.observe(container);
      if (this.resizeObserver) {
        this.resizeObserver.observe(container);
      }
      this.updateAnimationState();
    }

    removeCarousel(container) {
      const carousel = this.instances.get(container);
      if (carousel) {
        this.intersectionObserver.unobserve(container);
        if (this.resizeObserver) {
          this.resizeObserver.unobserve(container);
        }
        this.instances.delete(container);
        this.updateAnimationState();
      }
    }
  }

  // Create global manager instance
  if (!window.__carouselManager) {
    window.__carouselManager = new CarouselManager();
  }
  const manager = window.__carouselManager;
  
  class InfiniteCarousel {
    constructor(container, options = {}) {
      this.container = container;
      this.track = container.querySelector('.element-carousel-track');
      this.options = {
        speed: options.speed || ${carouselConfig.animationSpeed},
        gap: options.gap || ${carouselConfig.elementGap},
        ...options
      };
      
      this.currentX = 0;
      this.elements = [];
      this.clones = [];
      this.containerWidth = 0;
      this.contentWidth = 0;
      this.isRunning = true;
      this.isVisible = true;
      this.lastMeasureTime = 0;
      
      this.init();
    }
    
    init() {
      this.elements = Array.from(this.track.children);
      if (this.elements.length === 0) return;
      
      this.track.style.gap = \`\${this.options.gap}px\`;
      this.measureAndUpdate();
      
      // Register with global manager
      manager.addCarousel(this.container, this);
    }
    
    measureAndUpdate() {
      const now = Date.now();
      if (now - this.lastMeasureTime < 100) return;
      this.lastMeasureTime = now;
      
      this.measureDimensions();
      this.createClones();
    }
    
    measureDimensions() {
      this.containerWidth = this.container.offsetWidth;
      
      this.contentWidth = 0;
      this.elements.forEach(element => {
        if (element.offsetWidth > 0) {
          this.contentWidth += element.offsetWidth + this.options.gap;
        }
      });
      this.contentWidth = Math.max(this.contentWidth - this.options.gap, 100);
    }
    
    createClones() {
      // Clean up old clones
      this.clones.forEach(clone => clone.remove());
      this.clones = [];
      
      if (this.contentWidth === 0) return;
      
      const totalNeeded = Math.ceil((this.containerWidth * 2.5) / this.contentWidth) + 1;
      
      for (let i = 0; i < totalNeeded; i++) {
        this.elements.forEach(element => {
          const clone = element.cloneNode(true);
          clone.classList.add('carousel-clone');
          this.track.appendChild(clone);
          this.clones.push(clone);
        });
      }
    }
    
    // Called by global animation loop
    updatePosition() {
      if (!this.isRunning || !this.isVisible || this.contentWidth === 0) return;
      
      this.currentX -= this.options.speed * 0.5;
      
      if (Math.abs(this.currentX) >= this.contentWidth + this.options.gap) {
        this.currentX = 0;
      }
      
      this.track.style.transform = \`translateX(\${this.currentX}px)\`;
    }
    
    destroy() {
      manager.removeCarousel(this.container);
      this.clones.forEach(clone => clone.remove());
      this.clones = [];
    }
  }
  
  function init() {
    const containers = document.querySelectorAll('[data-element-carousel]');
    
    if(!containers || containers.length === 0) {
      return;
    }
    
    containers.forEach((container) => {
      // Skip if already initialized
      if(container._carouselInstance && container.querySelector('.element-carousel-track')) {
        return;
      }
      
      const validChildren = Array.from(container.children).filter(child => 
        !child.classList.contains('element-carousel-preview') && 
        child.tagName !== 'SCRIPT'
      );
      
      if(validChildren.length === 0) {
        return;
      }
      
      if(container._carouselInstance) {
        container._carouselInstance.destroy();
      }
      
      // Create the carousel structure
      const preview = document.createElement('div');
      preview.className = 'element-carousel-preview';
      
      const track = document.createElement('div');
      track.className = 'element-carousel-track';
      
      // Move existing child elements to the track
      validChildren.forEach((child) => {
        track.appendChild(child.cloneNode(true));
      });
      
      const leftBlur = document.createElement('div');
      leftBlur.className = 'carousel-blur-left';
      const rightBlur = document.createElement('div');
      rightBlur.className = 'carousel-blur-right';
      
      preview.appendChild(leftBlur);
      preview.appendChild(track);
      preview.appendChild(rightBlur);
      
      // Clear container and add carousel structure
      container.innerHTML = '';
      container.appendChild(preview);
      
      // Mark as initialized and create instance immediately
      container.setAttribute('data-carousel-initialized', 'true');
      
      try {
        container._carouselInstance = new InfiniteCarousel(preview, {
          speed: ${carouselConfig.animationSpeed},
          gap: ${carouselConfig.elementGap}
        });
      } catch(error) {
        // Silent error handling
      }
    });
  }
  
  // Immediate initialization
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }
  
  document.addEventListener('bricks/content_loaded', init);
})();`;
      }

      function copyJsToClipboard() {
        const jsCode = generateJavaScriptCode();
        
        navigator.clipboard.writeText(jsCode)
          .then(() => {
            showNotification('JavaScript code copied to clipboard!');
          })
          .catch(err => {
            try {
              const textArea = document.createElement('textarea');
              textArea.value = jsCode;
              textArea.style.position = 'fixed';
              textArea.style.opacity = '0';
              document.body.appendChild(textArea);
              textArea.select();
              document.execCommand('copy');
              document.body.removeChild(textArea);
              showNotification('JavaScript code copied to clipboard!');
            } catch (fallbackErr) {
              showNotification('Failed to copy to clipboard. Please try again.', 'error');
            }
          });
      }

      function copyFullSectionToClipboard() {
        const sectionJSON = generateFullSectionJSON();
        
        navigator.clipboard.writeText(sectionJSON)
          .then(() => {
            showNotification('Full section JSON copied to clipboard!');
          })
          .catch(err => {
            try {
              const textArea = document.createElement('textarea');
              textArea.value = sectionJSON;
              textArea.style.position = 'fixed';
              textArea.style.opacity = '0';
              document.body.appendChild(textArea);
              textArea.select();
              document.execCommand('copy');
              document.body.removeChild(textArea);
              showNotification('Full section JSON copied to clipboard!');
            } catch (fallbackErr) {
              showNotification('Failed to copy to clipboard. Please try again.', 'error');
            }
          });
      }

      function copyToClipboard(text) {
        navigator.clipboard.writeText(text)
          .then(() => {
            showNotification('Copied to clipboard!');
          })
          .catch(err => {
            showNotification('Failed to copy to clipboard', 'error');
          });
      }

      window.resetParameter = function(parameterId, defaultValue) {
        const element = document.getElementById(parameterId);
        if (element) {
          element.value = defaultValue;
          const valueElement = document.getElementById(`${parameterId}-value`);
          if (valueElement) {
            valueElement.textContent = defaultValue;
          }
          
          switch (parameterId) {
            case 'animation-speed':
              carouselConfig.animationSpeed = defaultValue;
              updateCarouselPreview('speed');
              break;
            case 'element-gap':
              carouselConfig.elementGap = defaultValue;
              updateCarouselPreview('style');
              break;
            case 'blur-opacity':
              carouselConfig.blurOpacity = defaultValue / 100;
              updateCarouselPreview('visual');
              break;
          }
          
          showNotification(`${parameterId.replace(/-/g, ' ')} reset to default`);
        }
      };

      function generateRandomCarousel() {
        carouselConfig.animationSpeed = Math.random() * 2.8 + 0.2;
        carouselConfig.elementGap = Math.floor(Math.random() * 70) + 10;
        carouselConfig.blurColor = generateRandomColor();
        carouselConfig.blurOpacity = (Math.floor(Math.random() * 10) + 1) / 10;
        
        document.getElementById('animation-speed').value = carouselConfig.animationSpeed;
        document.getElementById('element-gap').value = carouselConfig.elementGap;
        document.getElementById('blur-color').value = carouselConfig.blurColor;
        document.getElementById('blur-opacity').value = carouselConfig.blurOpacity * 100;
        
        document.getElementById('animation-speed-value').textContent = carouselConfig.animationSpeed;
        document.getElementById('element-gap-value').textContent = carouselConfig.elementGap;
        document.getElementById('blur-opacity-value').textContent = Math.round(carouselConfig.blurOpacity * 100);
        
        updateColorInputs();
        updateCarouselPreview('full');
        showNotification('Random element carousel generated!');
      }

      function updateColorInputs() {
        const colorInput = document.getElementById('blur-color');
        const hexInput = document.getElementById('blur-color-hex');
        const hslInput = document.getElementById('blur-color-hsl');
        
        if (colorInput && hexInput && hslInput) {
          colorInput.value = carouselConfig.blurColor;
          hexInput.value = carouselConfig.blurColor;
          const hsl = hexToRgb(carouselConfig.blurColor);
          if (hsl) {
            const hslColor = rgbToHsl(hsl.r, hsl.g, hsl.b);
            hslInput.value = `hsl(${hslColor.h}, ${hslColor.s}%, ${hslColor.l}%)`;
          }
          
          hexInput.classList.remove('invalid');
          hslInput.classList.remove('invalid');
          
          const colorPickerContainer = colorInput.closest('.color-row').querySelector('.color-picker-container');
          if (colorPickerContainer) {
            colorPickerContainer.style.setProperty('--selected-color', carouselConfig.blurColor);
          }
        }
      }

      function rgbToHsl(r, g, b) {
        r /= 255;
        g /= 255;
        b /= 255;
        const max = Math.max(r, g, b);
        const min = Math.min(r, g, b);
        let h, s, l = (max + min) / 2;

        if (max === min) {
          h = s = 0;
        } else {
          const d = max - min;
          s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
          switch (max) {
            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
            case g: h = (b - r) / d + 2; break;
            case b: h = (r - g) / d + 4; break;
          }
          h /= 6;
        }

        return {
          h: Math.round(h * 360),
          s: Math.round(s * 100),
          l: Math.round(l * 100)
        };
      }

      function initializeUI() {
        // Initialize carousel
        setTimeout(() => {
          initElementCarousel();
        }, 100);
        
        const instructionsToggle = document.getElementById('instructions-toggle');
        const instructionsContent = document.getElementById('instructions-content');
        const instructionsCard = document.getElementById('instructions-card');
        const toggleIcon = instructionsToggle?.querySelector('.toggle-icon');
        
        if (instructionsToggle && instructionsContent && instructionsCard && toggleIcon) {
          instructionsToggle.addEventListener('click', () => {
            const isVisible = instructionsContent.classList.contains('show');
            
            if (isVisible) {
              instructionsContent.classList.remove('show');
              instructionsCard.classList.remove('expanded');
              toggleIcon.classList.remove('expanded');
            } else {
              instructionsContent.classList.add('show');
              instructionsCard.classList.add('expanded');
              toggleIcon.classList.add('expanded');
            }
          });
        }

        const quickAttribute = document.getElementById('quick-attribute');
        if (quickAttribute) {
          quickAttribute.addEventListener('click', () => {
            copyToClipboard('data-element-carousel');
          });
        }

        const downloadConfig = document.getElementById('download-config');
        if (downloadConfig) {
          downloadConfig.addEventListener('click', () => {
            copyJsToClipboard();
          });
        }

        const copyFullSection = document.getElementById('copy-full-section');
        if (copyFullSection) {
          copyFullSection.addEventListener('click', () => {
            copyFullSectionToClipboard();
          });
        }

        const randomizeCarousel = document.getElementById('randomize-carousel');
        if (randomizeCarousel) {
          randomizeCarousel.addEventListener('click', () => {
            generateRandomCarousel();
          });
        }

        const backgroundPicker = document.getElementById('preview-background-picker');
        const previewContainer = document.getElementById('carousel-preview');

        if (backgroundPicker && previewContainer) {
          backgroundPicker.addEventListener('input', (e) => {
            const selectedColor = e.target.value;
            previewContainer.style.backgroundColor = selectedColor;
            
            const carouselPreview = previewContainer.querySelector('.element-carousel-preview');
            if (carouselPreview) {
              carouselPreview.style.backgroundColor = selectedColor;
            }
            
            showNotification(`Preview background changed to ${selectedColor}`);
          });
          
          previewContainer.style.backgroundColor = '#000000';
        }

        // Reset buttons
        const resetAnimation = document.getElementById('reset-animation');
        if (resetAnimation) {
          resetAnimation.addEventListener('click', () => {
            carouselConfig.animationSpeed = defaultConfig.animationSpeed;
            carouselConfig.elementGap = defaultConfig.elementGap;
            
            const animationSpeed = document.getElementById('animation-speed');
            const elementGap = document.getElementById('element-gap');
            const animationSpeedValue = document.getElementById('animation-speed-value');
            const elementGapValue = document.getElementById('element-gap-value');
            
            if (animationSpeed) animationSpeed.value = defaultConfig.animationSpeed;
            if (elementGap) elementGap.value = defaultConfig.elementGap;
            if (animationSpeedValue) animationSpeedValue.textContent = defaultConfig.animationSpeed;
            if (elementGapValue) elementGapValue.textContent = defaultConfig.elementGap;
            
            updateCarouselPreview('style');
            showNotification('Animation settings reset');
          });
        }

        const resetBlur = document.getElementById('reset-blur');
        if (resetBlur) {
          resetBlur.addEventListener('click', () => {
            carouselConfig.blurColor = defaultConfig.blurColor;
            carouselConfig.blurOpacity = defaultConfig.blurOpacity;
            
            const blurColor = document.getElementById('blur-color');
            const blurOpacity = document.getElementById('blur-opacity');
            const blurOpacityValue = document.getElementById('blur-opacity-value');
            
            if (blurColor) blurColor.value = defaultConfig.blurColor;
            if (blurOpacity) blurOpacity.value = defaultConfig.blurOpacity * 100;
            if (blurOpacityValue) blurOpacityValue.textContent = Math.round(defaultConfig.blurOpacity * 100);
            
            updateColorInputs();
            updateCarouselPreview('visual');
            showNotification('Blur settings reset');
          });
        }

        // Color controls
        const colorInput = document.getElementById('blur-color');
        const hexInput = document.getElementById('blur-color-hex');
        const hslInput = document.getElementById('blur-color-hsl');
        
        if (colorInput && hexInput && hslInput) {
          const hsl = hexToRgb(colorInput.value);
          if (hsl) {
            const hslColor = rgbToHsl(hsl.r, hsl.g, hsl.b);
            hslInput.value = `hsl(${hslColor.h}, ${hslColor.s}%, ${hslColor.l}%)`;
          }
          
          colorInput.addEventListener('input', () => {
            const color = colorInput.value;
            hexInput.value = color;
            const rgb = hexToRgb(color);
            if (rgb) {
              const hslColor = rgbToHsl(rgb.r, rgb.g, rgb.b);
              hslInput.value = `hsl(${hslColor.h}, ${hslColor.s}%, ${hslColor.l}%)`;
            }
            hexInput.classList.remove('invalid');
            hslInput.classList.remove('invalid');
            carouselConfig.blurColor = color;
            
            const colorPickerContainer = colorInput.closest('.color-row')?.querySelector('.color-picker-container');
            if (colorPickerContainer) {
              colorPickerContainer.style.setProperty('--selected-color', color);
            }
            
            updateCarouselPreview('visual');
          });
          
          hexInput.addEventListener('input', (e) => {
            let hex = e.target.value;
            
            hex = formatHex(hex);
            e.target.value = hex;
            
            if (isValidHex(hex)) {
              colorInput.value = hex;
              const rgb = hexToRgb(hex);
              if (rgb) {
                const hslColor = rgbToHsl(rgb.r, rgb.g, rgb.b);
                hslInput.value = `hsl(${hslColor.h}, ${hslColor.s}%, ${hslColor.l}%)`;
              }
              carouselConfig.blurColor = hex;
              e.target.classList.remove('invalid');
              hslInput.classList.remove('invalid');
              
              const colorPickerContainer = colorInput.closest('.color-row')?.querySelector('.color-picker-container');
              if (colorPickerContainer) {
                colorPickerContainer.style.setProperty('--selected-color', hex);
              }
              
              updateCarouselPreview('visual');
            } else {
              e.target.classList.add('invalid');
            }
          });
          
          hexInput.addEventListener('blur', (e) => {
            if (!isValidHex(e.target.value)) {
              e.target.value = colorInput.value;
              e.target.classList.remove('invalid');
            }
          });
          
          hslInput.addEventListener('input', (e) => {
            let hsl = e.target.value;
            
            if (isValidHsl(hsl)) {
              const hex = hslToHex(hsl);
              if (hex) {
                colorInput.value = hex;
                hexInput.value = hex;
                carouselConfig.blurColor = hex;
                e.target.classList.remove('invalid');
                hexInput.classList.remove('invalid');
                
                const colorPickerContainer = colorInput.closest('.color-row')?.querySelector('.color-picker-container');
                if (colorPickerContainer) {
                  colorPickerContainer.style.setProperty('--selected-color', hex);
                }
                
                updateCarouselPreview('visual');
                return;
              }
            }
            
            e.target.classList.add('invalid');
          });
          
          hslInput.addEventListener('blur', (e) => {
            let hsl = e.target.value;
            
            if (!isValidHsl(hsl) && hsl.trim()) {
              const formatted = formatHsl(hsl);
              if (isValidHsl(formatted)) {
                e.target.value = formatted;
                const hex = hslToHex(formatted);
                if (hex) {
                  colorInput.value = hex;
                  hexInput.value = hex;
                  carouselConfig.blurColor = hex;
                  e.target.classList.remove('invalid');
                  hexInput.classList.remove('invalid');
                  updateCarouselPreview('visual');
                  return;
                }
              }
            }
            
            if (!isValidHsl(e.target.value)) {
              const rgb = hexToRgb(colorInput.value);
              if (rgb) {
                const hslColor = rgbToHsl(rgb.r, rgb.g, rgb.b);
                e.target.value = `hsl(${hslColor.h}, ${hslColor.s}%, ${hslColor.l}%)`;
              }
              e.target.classList.remove('invalid');
            }
          });
        }

        // Range inputs
        const rangeInputs = document.querySelectorAll('input[type="range"]');
        rangeInputs.forEach(input => {
          const valueElement = document.getElementById(`${input.id}-value`);
          
          if (valueElement) {
            valueElement.textContent = input.value;
          }
          
          input.addEventListener('input', () => {
            if (valueElement) {
              valueElement.textContent = input.value;
            }
            
            switch (input.id) {
              case 'animation-speed':
                carouselConfig.animationSpeed = parseFloat(input.value);
                updateCarouselPreview('speed');
                break;
              case 'element-gap':
                carouselConfig.elementGap = parseInt(input.value);
                updateCarouselPreview('style');
                break;
              case 'blur-opacity':
                carouselConfig.blurOpacity = parseInt(input.value) / 100;
                updateCarouselPreview('visual');
                break;
            }
          });
        });

        // Keyboard shortcuts
        document.addEventListener('keydown', (e) => {
          if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') {
            return;
          }
          
          if (e.ctrlKey || e.metaKey) {
            switch (e.key.toLowerCase()) {
              case 'd':
                e.preventDefault();
                const downloadBtn = document.getElementById('download-config');
                if (downloadBtn && downloadBtn.hasAttribute('data-protection-animation')) {
                  downloadBtn.click();
                } else {
                  copyJsToClipboard();
                }
                break;
              case 's':
                e.preventDefault();
                const fullSectionBtn = document.getElementById('copy-full-section');
                if (fullSectionBtn && fullSectionBtn.hasAttribute('data-protection-animation')) {
                  fullSectionBtn.click();
                } else {
                  copyFullSectionToClipboard();
                }
                break;
            }
          } else {
            switch (e.key.toLowerCase()) {
              case 'r':
                generateRandomCarousel();
                break;
              case 'b':
                document.getElementById('preview-background-picker').click();
                break;
            }
          }
        });

        updateColorInputs();
        
        setTimeout(() => {
          showNotification('Element Carousel configurator loaded!');
        }, 500);
      }
      
      initializeUI();
    });
  </script>
</body>
</html>
Carousel Elements - Bricksfusion
LIGHTWEIGHT

Carousel Elements

Creates an infinite horizontal carousel of your elements. Perfect for partner logos, testimonials, product showcases, or any repeating content strip.

Item 1
Item 2
Item 3
Item 4
Item 5

Animation

Animation Speed 0.5-5.0

How fast elements scroll across. Lower is slow and elegant, higher is fast and energetic. 1.0 is a good balanced speed.

Default: 1.0

Layout

Element Gap 0-100 pixels

Space between each element in the carousel. Larger gaps create breathing room, smaller gaps pack elements tighter.

Default: 30

Blur Effects

Blur Color color picker

Color of the fade effect at the edges. Match this to your background color for seamless blending.

Default: Black (#000000)

Blur Opacity 0.0-1.0

Strength of the edge fade. Higher values create stronger fades, lower values make edges more visible.

Default: 0.9

Performance

This element uses CSS transforms with hardware acceleration for smooth 60fps animations. It automatically pauses when scrolled out of view and clones elements efficiently. Works great with any number of items.