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>Neural Flow 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);
}

.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-theme-section {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

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

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

.color-picker-container {
  position: relative;
  width: 50px;
  height: 50px;
  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;
}

.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, #6366f1);
  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;
  flex: 1;
}

.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);
}

.generated-palette {
  margin-top: 1rem;
}

.palette-title {
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.palette-colors {
  display: flex;
  gap: 0.5rem;
}

.palette-color {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  border: 1px solid var(--border);
  transition: var(--transition);
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.palette-color:hover {
  transform: scale(1.1);
  border-color: var(--accent);
  box-shadow: 0 0 8px rgba(239, 96, 19, 0.3);
}

.palette-color-label {
  position: absolute;
  bottom: -18px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 8px;
  color: var(--text-secondary);
  white-space: nowrap;
  opacity: 0;
  transition: var(--transition);
}

.palette-color:hover .palette-color-label {
  opacity: 1;
}

select {
  width: 100%;
  padding: 0.75rem;
  border: 1px solid var(--border);
  border-radius: var(--input-radius);
  font-family: var(--font);
  font-size: var(--text-xs);
  color: var(--text-primary);
  background-color: var(--card-bg);
  margin-bottom: 0.75rem;
  outline: none;
  transition: var(--transition);
}

select:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(239, 96, 19, 0.2);
}

.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;
}

.toggle-switch {
  position: relative;
  display: inline-block;
  width: 50px;
  height: 24px;
  margin-left: 8px;
}

.toggle-input {
  opacity: 0;
  width: 0;
  height: 0;
}

.toggle-label {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: var(--track);
  transition: var(--transition);
  border-radius: 34px;
}

.toggle-label:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 3px;
  bottom: 3px;
  background-color: white;
  transition: var(--transition);
  border-radius: 50%;
}

.toggle-input:checked + .toggle-label {
  background-color: var(--accent);
}

.toggle-input:checked + .toggle-label:before {
  transform: translateX(26px);
}

@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-main-input {
    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;
  }

  .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/corebackground/" class="breadcrumb-item">Core Backgrounds</a>
      <span class="breadcrumb-separator">›</span>
      <span class="breadcrumb-item active">Neural Flow</span>
    </nav>
    
    <div class="action-buttons">
      <div class="data-attribute-display" id="quick-attribute" title="Click to copy data attribute">
        data-neural-flow
      </div>
      <button class="action-btn primary" id="download-config" title="Copy JavaScript code (Ctrl+D)">
        <span>📋</span>
        Copy JS
      </button>
      <button class="action-btn" id="copy-full-section" title="Copy complete section JSON for Bricks Builder (Ctrl+S)">
        <span>📦</span>
        Copy Full Section
      </button>
    </div>
  </div>

  <div class="container">
    <div class="page-header">
      <h1 class="page-title">Neural Flow</h1>
      <p class="page-subtitle">Interactive neural network animations 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>Choose your <strong>Color Theme</strong> to generate a harmonious color palette</li>
                <li>Adjust <strong>Color Variation</strong> to control how different the generated colors are</li>
                <li>Customize the flow settings and advanced options</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 and paste the JavaScript</li>
                <li>Add <code>data-neural-flow</code> as attribute to any section (leave value empty)</li>
              </ol>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="content">
      <section class="preview-section">
        <div class="preview-container" id="neural-preview" data-neural-flow="true">
          <div class="preview-content">Interactive Neural Flow Preview</div>
          <div class="preview-controls">
            <button class="preview-btn" id="randomize-neural" 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>
      </section>

      <section class="controls-section">
        <div class="card">
          <div class="card-heading">
            Color Theme
            <div class="card-actions">
              <button class="card-action-btn" id="reset-colors" title="Reset Colors">↺</button>
            </div>
          </div>
          <div class="card-content">
            <div class="color-theme-section">
              <div class="color-main-input">
                <div class="color-picker-container">
                  <input type="color" id="base-color" value="#6366f1">
                </div>
                <div class="color-input-group">
                  <span class="color-label">Primary Color</span>
                  <input type="text" class="color-input" id="base-color-hex" value="#6366f1" placeholder="#FFFFFF">
                </div>
              </div>

              <div class="control-group">
                <div class="control-label">
                  <span class="label-text">
                    Color Variation
                    <span class="help-tooltip" title="Controls how different the generated palette colors are">ℹ</span>
                  </span>
                  <div class="value-display">
                    <span class="value-text"><span id="color-variation-value">50</span>%</span>
                    <button class="reset-btn" onclick="resetParameter('color-variation', 50)">↺</button>
                  </div>
                </div>
                <input type="range" id="color-variation" min="0" max="100" step="5" value="50">
              </div>

              <div class="generated-palette">
                <div class="palette-title">
                  <span>Generated Palette</span>
                  <span class="help-tooltip" title="These are the exact colors used in the effect">ℹ</span>
                </div>
                <div class="palette-colors">
                  <div class="palette-color" id="palette-color-1" style="background-color: #6366f1;">
                    <div class="palette-color-label">Primary</div>
                  </div>
                  <div class="palette-color" id="palette-color-2" style="background-color: #8b5cf6;">
                    <div class="palette-color-label">Secondary</div>
                  </div>
                  <div class="palette-color" id="palette-color-3" style="background-color: #ec4899;">
                    <div class="palette-color-label">Accent</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div class="card">
          <div class="card-heading">
            Flow Settings
            <div class="card-actions">
              <button class="card-action-btn" id="reset-flow" title="Reset Flow Settings">↺</button>
            </div>
          </div>
          <div class="card-content">
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Intensity
                  <span class="help-tooltip" title="Overall intensity of the neural flow effect">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="intensity-value">1.0</span></span>
                  <button class="reset-btn" onclick="resetParameter('intensity', 1.0)">↺</button>
                </div>
              </div>
              <input type="range" id="intensity" min="0.1" max="3.0" step="0.1" value="1.0">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Animation Speed
                  <span class="help-tooltip" title="Speed of the neural flow animation">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="speed-value">1.0</span></span>
                  <button class="reset-btn" onclick="resetParameter('speed', 1.0)">↺</button>
                </div>
              </div>
              <input type="range" id="speed" min="0.1" max="3.0" step="0.1" value="1.0">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Mouse Sensitivity
                  <span class="help-tooltip" title="How much the effect responds to mouse movement">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="mouse-sensitivity-value">1.0</span></span>
                  <button class="reset-btn" onclick="resetParameter('mouse-sensitivity', 1.0)">↺</button>
                </div>
              </div>
              <input type="range" id="mouse-sensitivity" min="0.1" max="2.0" step="0.1" value="1.0">
            </div>
          </div>
        </div>

        <div class="card">
          <div class="card-heading">
            Advanced Options
            <div class="card-actions">
              <button class="card-action-btn" id="reset-advanced" title="Reset Advanced Settings">↺</button>
            </div>
          </div>
          <div class="card-content">
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">Scroll Effect</span>
                <label class="toggle-switch">
                  <input type="checkbox" id="scroll-effect" class="toggle-input" checked>
                  <span class="toggle-label"></span>
                </label>
              </div>
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">Blur Edges</span>
                <label class="toggle-switch">
                  <input type="checkbox" id="blur-edges" class="toggle-input" checked>
                  <span class="toggle-label"></span>
                </label>
              </div>
            </div>
          </div>
        </div>
      </section>
    </div>
  </div>

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

  <script>
    document.addEventListener('DOMContentLoaded', function() {
      let neuralConfig = {
        intensity: 1.0,
        speed: 1.0,
        mouseSensitivity: 1.0,
        scrollEffect: true,
        blurEdges: true,
        baseColor: "#6366f1",
        colorVariation: 50
      };

      const defaultConfig = { ...neuralConfig };

      let previewInstance = null;
      
      // FUNCIONES COMPARTIDAS - Estas son idénticas en preview y código generado
      function hexToHsl(hex) {
        const r = parseInt(hex.slice(1, 3), 16) / 255;
        const g = parseInt(hex.slice(3, 5), 16) / 255;
        const b = parseInt(hex.slice(5, 7), 16) / 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 hslToHex(h, s, l) {
        h /= 360;
        s /= 100;
        l /= 100;
        const a = s * Math.min(l, 1 - l);
        const f = n => {
          const k = (n + h * 12) % 12;
          const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
          return Math.round(255 * color).toString(16).padStart(2, '0');
        };
        return '#' + f(0) + f(8) + f(4);
      }

      function generateColorVariations(baseColor, variationPercentage = 50) {
        const hsl = hexToHsl(baseColor);
        const variation = variationPercentage / 100;
        
        const variation1 = hslToHex(hsl.h, hsl.s, hsl.l);
        
        const variation2 = hslToHex(
          hsl.h, 
          Math.max(20, Math.min(100, hsl.s + (variation * 30 - 15))), 
          Math.max(20, Math.min(80, hsl.l + (variation * 20 - 10)))
        );
        
        const hueShift = variation > 0.7 ? 180 : (variation * 60);
        const variation3 = hslToHex(
          (hsl.h + hueShift) % 360,
          Math.max(30, Math.min(100, hsl.s + (variation * 20 - 10))),
          Math.max(30, Math.min(70, hsl.l - (variation * 15)))
        );
        
        return [variation1, variation2, variation3];
      }

      function updatePaletteDisplay(colors) {
        const paletteColors = document.querySelectorAll('.palette-color');
        paletteColors.forEach((colorElement, index) => {
          if (colors[index]) {
            colorElement.style.backgroundColor = colors[index];
          }
        });
      }

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

      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();
      }
      
      // CLASE NEURALFLOW - Esta es IDÉNTICA en preview y código generado
      class NeuralFlow {
        constructor(container, options = {}) {
          this.container = container;
          this.canvas = document.createElement('canvas');
          this.pointer = { x: 0, y: 0, tX: 0, tY: 0 };
          this.animationId = null;
          
          // CRÍTICO: Esta lógica es IDÉNTICA en preview y código generado
          const baseColor = options.baseColor || '#6366f1';
          const colorVariation = options.colorVariation !== undefined ? options.colorVariation : 50;
          this.colors = options.colors || generateColorVariations(baseColor, colorVariation);
          this.intensity = options.intensity !== undefined ? options.intensity : 1.0;
          this.speed = options.speed !== undefined ? options.speed : 1.0;
          this.mouseSensitivity = options.mouseSensitivity !== undefined ? options.mouseSensitivity : 1.0;
          this.scrollEffect = options.scrollEffect !== false;
          this.blurEdges = options.blurEdges !== false;

          this.setupCanvas();
          this.initWebGL();
        }

        setupCanvas() {
          this.canvas.style.position = 'absolute';
          this.canvas.style.top = '0';
          this.canvas.style.left = '0';
          this.canvas.style.width = '100%';
          this.canvas.style.height = '100%';
          this.canvas.style.pointerEvents = 'none';
          this.canvas.style.opacity = '0.95';
          this.canvas.style.zIndex = '0';
          
          if (this.blurEdges) {
            this.canvas.style.filter = 'blur(0.5px)';
          }

          this.container.style.position = this.container.style.position || 'relative';
          this.container.style.overflow = 'hidden';
          this.container.appendChild(this.canvas);
        }

        initWebGL() {
          this.gl = this.canvas.getContext('webgl') || this.canvas.getContext('experimental-webgl');
          if (!this.gl) {
            return;
          }

          const vsSource = `
            precision mediump float;
            attribute vec2 a_position;
            varying vec2 vUv;
            void main() {
              vUv = .5 * (a_position + 1.);
              gl_Position = vec4(a_position, 0.0, 1.0);
            }
          `;

          const fsSource = `
            precision mediump float;
            varying vec2 vUv;
            uniform float u_time;
            uniform float u_ratio;
            uniform vec2 u_pointer_position;
            uniform float u_scroll_progress;
            uniform float u_intensity;
            uniform float u_speed;
            uniform float u_mouse_sensitivity;
            uniform vec3 u_color1;
            uniform vec3 u_color2;
            uniform vec3 u_color3;
            
            vec2 rotate(vec2 uv, float th) {
              return mat2(cos(th), sin(th), -sin(th), cos(th)) * uv;
            }
            
            float neuro_shape(vec2 uv, float t, float p) {
              vec2 sine_acc = vec2(0.);
              vec2 res = vec2(0.);
              float scale = 8.;
              for (int j = 0; j < 15; j++) {
                uv = rotate(uv, 1.);
                sine_acc = rotate(sine_acc, 1.);
                vec2 layer = uv * scale + float(j) + sine_acc - t * u_speed;
                sine_acc += sin(layer) + 2.4 * p * u_mouse_sensitivity;
                res += (.5 + .5 * cos(layer)) / scale;
                scale *= (1.2);
              }
              return res.x + res.y;
            }
            
            void main() {
              vec2 uv = .5 * vUv;
              uv.x *= u_ratio;
              vec2 pointer = vUv - u_pointer_position;
              pointer.x *= u_ratio;
              float p = clamp(length(pointer), 0., 1.);
              p = .5 * pow(1. - p, 2.) * u_intensity;
              float t = .001 * u_time;
              vec3 color = vec3(0.);
              float noise = neuro_shape(uv, t, p);
              noise = 1.2 * pow(noise, 3.);
              noise += pow(noise, 10.);
              noise = max(.0, noise - .5);
              noise *= (1. - length(vUv - .5));
              color = u_color1;
              color = mix(color, u_color2, 0.32 + 0.16 * sin(2.0 * u_scroll_progress + 1.2));
              color += u_color3 * sin(2.0 * u_scroll_progress + 1.5);
              color = color * noise * u_intensity;
              gl_FragColor = vec4(color, noise);
            }
          `;

          const compileShader = (gl, source, type) => {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
              gl.deleteShader(shader);
              return null;
            }
            return shader;
          };

          const vertexShader = compileShader(this.gl, vsSource, this.gl.VERTEX_SHADER);
          const fragmentShader = compileShader(this.gl, fsSource, this.gl.FRAGMENT_SHADER);

          this.program = this.gl.createProgram();
          this.gl.attachShader(this.program, vertexShader);
          this.gl.attachShader(this.program, fragmentShader);
          this.gl.linkProgram(this.program);
          
          if (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {
            return;
          }
          
          this.gl.useProgram(this.program);

          const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
          const vertexBuffer = this.gl.createBuffer();
          this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
          this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);

          const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
          this.gl.enableVertexAttribArray(positionLocation);
          this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
          this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);

          this.uTime = this.gl.getUniformLocation(this.program, 'u_time');
          this.uRatio = this.gl.getUniformLocation(this.program, 'u_ratio');
          this.uPointerPosition = this.gl.getUniformLocation(this.program, 'u_pointer_position');
          this.uScrollProgress = this.gl.getUniformLocation(this.program, 'u_scroll_progress');
          this.uIntensity = this.gl.getUniformLocation(this.program, 'u_intensity');
          this.uSpeed = this.gl.getUniformLocation(this.program, 'u_speed');
          this.uMouseSensitivity = this.gl.getUniformLocation(this.program, 'u_mouse_sensitivity');
          this.uColor1 = this.gl.getUniformLocation(this.program, 'u_color1');
          this.uColor2 = this.gl.getUniformLocation(this.program, 'u_color2');
          this.uColor3 = this.gl.getUniformLocation(this.program, 'u_color3');

          this.setupEventListeners();
          this.resizeCanvas();
          this.render();
        }

        hexToRgb(hex) {
          const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
          return result ? [
            parseInt(result[1], 16) / 255,
            parseInt(result[2], 16) / 255,
            parseInt(result[3], 16) / 255
          ] : [0.39, 0.4, 0.95];
        }

        setupEventListeners() {
          const handleResize = () => {
            this.resizeCanvas();
          };

          const handleMouseMove = (e) => {
            const rect = this.container.getBoundingClientRect();
            this.pointer.tX = e.clientX - rect.left;
            this.pointer.tY = e.clientY - rect.top;
          };

          const handleTouchMove = (e) => {
            if (e.touches[0]) {
              const rect = this.container.getBoundingClientRect();
              this.pointer.tX = e.touches[0].clientX - rect.left;
              this.pointer.tY = e.touches[0].clientY - rect.top;
            }
          };

          window.addEventListener('resize', handleResize);
          this.container.addEventListener('pointermove', handleMouseMove);
          this.container.addEventListener('touchmove', handleTouchMove);

          this.cleanup = () => {
            window.removeEventListener('resize', handleResize);
            this.container.removeEventListener('pointermove', handleMouseMove);
            this.container.removeEventListener('touchmove', handleTouchMove);
          };
        }

        resizeCanvas() {
          const rect = this.container.getBoundingClientRect();
          const devicePixelRatio = Math.min(window.devicePixelRatio, 2);
          this.canvas.width = rect.width * devicePixelRatio;
          this.canvas.height = rect.height * devicePixelRatio;
          this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
          this.gl.uniform1f(this.uRatio, this.canvas.width / this.canvas.height);
        }

        updateOptions(options) {
          this.intensity = options.intensity !== undefined ? options.intensity : this.intensity;
          this.speed = options.speed !== undefined ? options.speed : this.speed;
          this.mouseSensitivity = options.mouseSensitivity !== undefined ? options.mouseSensitivity : this.mouseSensitivity;
          this.scrollEffect = options.scrollEffect !== undefined ? options.scrollEffect : this.scrollEffect;
          
          if (options.colors) {
            this.colors = options.colors;
          }
          
          if (options.blurEdges !== undefined && options.blurEdges !== this.blurEdges) {
            this.blurEdges = options.blurEdges;
            this.canvas.style.filter = this.blurEdges ? 'blur(0.5px)' : 'none';
          }
        }

        render = () => {
          const currentTime = performance.now();
          
          this.pointer.x += (this.pointer.tX - this.pointer.x) * 0.15;
          this.pointer.y += (this.pointer.tY - this.pointer.y) * 0.15;
          
          this.gl.uniform1f(this.uTime, currentTime);
          this.gl.uniform2f(this.uPointerPosition, 
            this.pointer.x / this.container.offsetWidth, 
            1 - this.pointer.y / this.container.offsetHeight
          );
          
          if (this.scrollEffect) {
            this.gl.uniform1f(this.uScrollProgress, window.pageYOffset / (2 * window.innerHeight));
          } else {
            this.gl.uniform1f(this.uScrollProgress, 0);
          }
          
          this.gl.uniform1f(this.uIntensity, this.intensity);
          this.gl.uniform1f(this.uSpeed, this.speed);
          this.gl.uniform1f(this.uMouseSensitivity, this.mouseSensitivity);
          
          const color1 = this.hexToRgb(this.colors[0] || '#6366f1');
          const color2 = this.hexToRgb(this.colors[1] || '#8b5cf6');
          const color3 = this.hexToRgb(this.colors[2] || '#ec4899');
          
          this.gl.uniform3f(this.uColor1, color1[0], color1[1], color1[2]);
          this.gl.uniform3f(this.uColor2, color2[0], color2[1], color2[2]);
          this.gl.uniform3f(this.uColor3, color3[0], color3[1], color3[2]);
          
          this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
          this.animationId = requestAnimationFrame(this.render);
        };

        destroy() {
          if (this.animationId) {
            cancelAnimationFrame(this.animationId);
          }
          if (this.cleanup) {
            this.cleanup();
          }
          if (this.gl && this.program) {
            this.gl.deleteProgram(this.program);
          }
          if (this.canvas.parentNode) {
            this.canvas.parentNode.removeChild(this.canvas);
          }
        }
      }
      
      // INICIALIZACIÓN DEL PREVIEW - Ahora usa EXACTAMENTE la misma lógica que el código generado
      function initializePreview() {
        const container = document.getElementById('neural-preview');
        if (previewInstance) {
          previewInstance.destroy();
        }
        
        // CRÍTICO: Pasamos baseColor y colorVariation, NO los colores pregenerados
        previewInstance = new NeuralFlow(container, {
          baseColor: neuralConfig.baseColor,
          colorVariation: neuralConfig.colorVariation,
          intensity: neuralConfig.intensity,
          speed: neuralConfig.speed,
          mouseSensitivity: neuralConfig.mouseSensitivity,
          scrollEffect: neuralConfig.scrollEffect,
          blurEdges: neuralConfig.blurEdges
        });
        
        // Actualizamos la paleta mostrada
        const colors = generateColorVariations(neuralConfig.baseColor, neuralConfig.colorVariation);
        updatePaletteDisplay(colors);
      }
      
      function updatePreview() {
        const colors = generateColorVariations(neuralConfig.baseColor, neuralConfig.colorVariation);
        updatePaletteDisplay(colors);
        
        if (previewInstance) {
          previewInstance.updateOptions({
            ...neuralConfig,
            colors: colors
          });
        }
      }

      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() {
        const sectionId = generateUniqueId();
        const containerId = generateUniqueId();
        const codeId = generateUniqueId();
        const attributeId = generateUniqueId();
        
        const jsCode = generateJavaScriptCode();
        
        const fullSectionData = {
          "content": [
            {
              "id": sectionId,
              "name": "section",
              "parent": 0,
              "children": [containerId, codeId],
              "settings": {
                "_height": "500",
                "_justifyContent": "center",
                "_background": {
                  "color": {
                    "hex": "#000000"
                  }
                },
                "_attributes": [
                  {
                    "id": attributeId,
                    "name": "data-neural-flow"
                  }
                ]
              },
              "label": "Neural Section"
            },
            {
              "id": containerId,
              "name": "container",
              "parent": sectionId,
              "children": [],
              "settings": []
            },
            {
              "id": codeId,
              "name": "code",
              "parent": sectionId,
              "children": [],
              "settings": {
                "javascriptCode": jsCode,
                "executeCode": true,
                "_display": "none"
              },
              "label": "Neural JS"
            }
          ],
          "source": "bricksCopiedElements",
          "sourceUrl": "https://bricksfusion.com",
          "version": "2.0.1",
          "globalClasses": [],
          "globalElements": []
        };
        
        return JSON.stringify(fullSectionData, null, 2);
      }

      function generateJavaScriptCode() {
        // CRÍTICO: Ahora usamos los valores ACTUALES del neuralConfig
        return `(function() {
  'use strict';

  function hexToHsl(hex) {
    const r = parseInt(hex.slice(1, 3), 16) / 255;
    const g = parseInt(hex.slice(3, 5), 16) / 255;
    const b = parseInt(hex.slice(5, 7), 16) / 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: h * 360, s: s, l: l };
  }
  
  function hslToHex(h, s, l) {
    h /= 360;
    const a = s * Math.min(l, 1 - l);
    const f = n => {
      const k = (n + h * 12) % 12;
      const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
      return Math.round(255 * color).toString(16).padStart(2, '0');
    };
    return '#' + f(0) + f(8) + f(4);
  }
  
  function generateColorVariations(baseColor, variationPercentage = 50) {
    const hsl = hexToHsl(baseColor);
    const variation = variationPercentage / 100;
    
    const variation1 = hslToHex(hsl.h, hsl.s, hsl.l);
    
    const variation2 = hslToHex(
      hsl.h, 
      Math.max(20, Math.min(100, hsl.s + (variation * 30 - 15))), 
      Math.max(20, Math.min(80, hsl.l + (variation * 20 - 10)))
    );
    
    const hueShift = variation > 0.7 ? 180 : (variation * 60);
    const variation3 = hslToHex(
      (hsl.h + hueShift) % 360,
      Math.max(30, Math.min(100, hsl.s + (variation * 20 - 10))),
      Math.max(30, Math.min(70, hsl.l - (variation * 15)))
    );
    
    return [variation1, variation2, variation3];
  }

  class NeuralFlow {
    constructor(container, options = {}) {
      this.container = container;
      this.canvas = document.createElement('canvas');
      this.pointer = { x: 0, y: 0, tX: 0, tY: 0 };
      this.animationId = null;
      
      const baseColor = options.baseColor || '${neuralConfig.baseColor}';
      const colorVariation = options.colorVariation !== undefined ? options.colorVariation : ${neuralConfig.colorVariation};
      this.colors = options.colors || generateColorVariations(baseColor, colorVariation);
      this.intensity = options.intensity !== undefined ? options.intensity : ${neuralConfig.intensity};
      this.speed = options.speed !== undefined ? options.speed : ${neuralConfig.speed};
      this.mouseSensitivity = options.mouseSensitivity !== undefined ? options.mouseSensitivity : ${neuralConfig.mouseSensitivity};
      this.scrollEffect = options.scrollEffect !== undefined ? options.scrollEffect : ${neuralConfig.scrollEffect};
      this.blurEdges = options.blurEdges !== undefined ? options.blurEdges : ${neuralConfig.blurEdges};

      this.setupCanvas();
      this.initWebGL();
    }

    setupCanvas() {
      this.canvas.style.position = 'absolute';
      this.canvas.style.top = '0';
      this.canvas.style.left = '0';
      this.canvas.style.width = '100%';
      this.canvas.style.height = '100%';
      this.canvas.style.pointerEvents = 'none';
      this.canvas.style.opacity = '0.95';
      this.canvas.style.zIndex = '0';
      
      if (this.blurEdges) {
        this.canvas.style.filter = 'blur(0.5px)';
      }

      this.container.style.position = this.container.style.position || 'relative';
      this.container.style.overflow = 'hidden';
      this.container.appendChild(this.canvas);
    }

    initWebGL() {
      this.gl = this.canvas.getContext('webgl') || this.canvas.getContext('experimental-webgl');
      if (!this.gl) {
        return;
      }

      const vsSource = \`
        precision mediump float;
        attribute vec2 a_position;
        varying vec2 vUv;
        void main() {
          vUv = .5 * (a_position + 1.);
          gl_Position = vec4(a_position, 0.0, 1.0);
        }
      \`;

      const fsSource = \`
        precision mediump float;
        varying vec2 vUv;
        uniform float u_time;
        uniform float u_ratio;
        uniform vec2 u_pointer_position;
        uniform float u_scroll_progress;
        uniform float u_intensity;
        uniform float u_speed;
        uniform float u_mouse_sensitivity;
        uniform vec3 u_color1;
        uniform vec3 u_color2;
        uniform vec3 u_color3;
        
        vec2 rotate(vec2 uv, float th) {
          return mat2(cos(th), sin(th), -sin(th), cos(th)) * uv;
        }
        
        float neuro_shape(vec2 uv, float t, float p) {
          vec2 sine_acc = vec2(0.);
          vec2 res = vec2(0.);
          float scale = 8.;
          for (int j = 0; j < 15; j++) {
            uv = rotate(uv, 1.);
            sine_acc = rotate(sine_acc, 1.);
            vec2 layer = uv * scale + float(j) + sine_acc - t * u_speed;
            sine_acc += sin(layer) + 2.4 * p * u_mouse_sensitivity;
            res += (.5 + .5 * cos(layer)) / scale;
            scale *= (1.2);
          }
          return res.x + res.y;
        }
        
        void main() {
          vec2 uv = .5 * vUv;
          uv.x *= u_ratio;
          vec2 pointer = vUv - u_pointer_position;
          pointer.x *= u_ratio;
          float p = clamp(length(pointer), 0., 1.);
          p = .5 * pow(1. - p, 2.) * u_intensity;
          float t = .001 * u_time;
          vec3 color = vec3(0.);
          float noise = neuro_shape(uv, t, p);
          noise = 1.2 * pow(noise, 3.);
          noise += pow(noise, 10.);
          noise = max(.0, noise - .5);
          noise *= (1. - length(vUv - .5));
          color = u_color1;
          color = mix(color, u_color2, 0.32 + 0.16 * sin(2.0 * u_scroll_progress + 1.2));
          color += u_color3 * sin(2.0 * u_scroll_progress + 1.5);
          color = color * noise * u_intensity;
          gl_FragColor = vec4(color, noise);
        }
      \`;

      const compileShader = (gl, source, type) => {
        const shader = gl.createShader(type);
        gl.shaderSource(shader, source);
        gl.compileShader(shader);
        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
          gl.deleteShader(shader);
          return null;
        }
        return shader;
      };

      const vertexShader = compileShader(this.gl, vsSource, this.gl.VERTEX_SHADER);
      const fragmentShader = compileShader(this.gl, fsSource, this.gl.FRAGMENT_SHADER);

      this.program = this.gl.createProgram();
      this.gl.attachShader(this.program, vertexShader);
      this.gl.attachShader(this.program, fragmentShader);
      this.gl.linkProgram(this.program);
      
      if (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {
        return;
      }
      
      this.gl.useProgram(this.program);

      const vertices = new Float32Array([-1, -1, 1, -1, -1, 1, 1, 1]);
      const vertexBuffer = this.gl.createBuffer();
      this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
      this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);

      const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
      this.gl.enableVertexAttribArray(positionLocation);
      this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
      this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);

      this.uTime = this.gl.getUniformLocation(this.program, 'u_time');
      this.uRatio = this.gl.getUniformLocation(this.program, 'u_ratio');
      this.uPointerPosition = this.gl.getUniformLocation(this.program, 'u_pointer_position');
      this.uScrollProgress = this.gl.getUniformLocation(this.program, 'u_scroll_progress');
      this.uIntensity = this.gl.getUniformLocation(this.program, 'u_intensity');
      this.uSpeed = this.gl.getUniformLocation(this.program, 'u_speed');
      this.uMouseSensitivity = this.gl.getUniformLocation(this.program, 'u_mouse_sensitivity');
      this.uColor1 = this.gl.getUniformLocation(this.program, 'u_color1');
      this.uColor2 = this.gl.getUniformLocation(this.program, 'u_color2');
      this.uColor3 = this.gl.getUniformLocation(this.program, 'u_color3');

      this.setupEventListeners();
      this.resizeCanvas();
      this.render();
    }

    hexToRgb(hex) {
      const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);
      return result ? [
        parseInt(result[1], 16) / 255,
        parseInt(result[2], 16) / 255,
        parseInt(result[3], 16) / 255
      ] : [0.39, 0.4, 0.95];
    }

    setupEventListeners() {
      const handleResize = () => {
        this.resizeCanvas();
      };

      const handleMouseMove = (e) => {
        const rect = this.container.getBoundingClientRect();
        this.pointer.tX = e.clientX - rect.left;
        this.pointer.tY = e.clientY - rect.top;
      };

      const handleTouchMove = (e) => {
        if (e.touches[0]) {
          const rect = this.container.getBoundingClientRect();
          this.pointer.tX = e.touches[0].clientX - rect.left;
          this.pointer.tY = e.touches[0].clientY - rect.top;
        }
      };

      window.addEventListener('resize', handleResize);
      this.container.addEventListener('pointermove', handleMouseMove);
      this.container.addEventListener('touchmove', handleTouchMove);

      this.cleanup = () => {
        window.removeEventListener('resize', handleResize);
        this.container.removeEventListener('pointermove', handleMouseMove);
        this.container.removeEventListener('touchmove', handleTouchMove);
      };
    }

    resizeCanvas() {
      const rect = this.container.getBoundingClientRect();
      const devicePixelRatio = Math.min(window.devicePixelRatio, 2);
      this.canvas.width = rect.width * devicePixelRatio;
      this.canvas.height = rect.height * devicePixelRatio;
      this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
      this.gl.uniform1f(this.uRatio, this.canvas.width / this.canvas.height);
    }

    render() {
      const currentTime = performance.now();
      
      this.pointer.x += (this.pointer.tX - this.pointer.x) * 0.15;
      this.pointer.y += (this.pointer.tY - this.pointer.y) * 0.15;
      
      this.gl.uniform1f(this.uTime, currentTime);
      this.gl.uniform2f(this.uPointerPosition, 
        this.pointer.x / this.container.offsetWidth, 
        1 - this.pointer.y / this.container.offsetHeight
      );
      
      if (this.scrollEffect) {
        this.gl.uniform1f(this.uScrollProgress, window.pageYOffset / (2 * window.innerHeight));
      } else {
        this.gl.uniform1f(this.uScrollProgress, 0);
      }
      
      this.gl.uniform1f(this.uIntensity, this.intensity);
      this.gl.uniform1f(this.uSpeed, this.speed);
      this.gl.uniform1f(this.uMouseSensitivity, this.mouseSensitivity);
      
      const color1 = this.hexToRgb(this.colors[0] || '#6366f1');
      const color2 = this.hexToRgb(this.colors[1] || '#8b5cf6');
      const color3 = this.hexToRgb(this.colors[2] || '#ec4899');
      
      this.gl.uniform3f(this.uColor1, color1[0], color1[1], color1[2]);
      this.gl.uniform3f(this.uColor2, color2[0], color2[1], color2[2]);
      this.gl.uniform3f(this.uColor3, color3[0], color3[1], color3[2]);
      
      this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
      this.animationId = requestAnimationFrame(() => this.render());
    }

    destroy() {
      if (this.animationId) {
        cancelAnimationFrame(this.animationId);
      }
      if (this.cleanup) {
        this.cleanup();
      }
      if (this.gl && this.program) {
        this.gl.deleteProgram(this.program);
      }
      if (this.canvas.parentNode) {
        this.canvas.parentNode.removeChild(this.canvas);
      }
    }
  }

  function initNeuralFlow() {
    const elements = document.querySelectorAll('[data-neural-flow]');
    
    elements.forEach(element => {
      const baseColor = element.getAttribute('data-base-color') || '${neuralConfig.baseColor}';
      const colorVariation = element.hasAttribute('data-color-variation') 
        ? parseFloat(element.getAttribute('data-color-variation')) 
        : ${neuralConfig.colorVariation};

      const options = {
        baseColor: baseColor,
        colorVariation: colorVariation,
        intensity: element.hasAttribute('data-intensity') 
          ? parseFloat(element.getAttribute('data-intensity')) 
          : ${neuralConfig.intensity},
        speed: element.hasAttribute('data-speed') 
          ? parseFloat(element.getAttribute('data-speed')) 
          : ${neuralConfig.speed},
        mouseSensitivity: element.hasAttribute('data-mouse-sensitivity') 
          ? parseFloat(element.getAttribute('data-mouse-sensitivity')) 
          : ${neuralConfig.mouseSensitivity},
        scrollEffect: element.getAttribute('data-scroll-effect') !== 'false',
        blurEdges: element.getAttribute('data-blur-edges') !== 'false',
      };

      new NeuralFlow(element, options);
    });
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initNeuralFlow);
  } else {
    initNeuralFlow();
  }

  const observer = new MutationObserver((mutations) => {
    let shouldInit = false;

    mutations.forEach((mutation) => {
      if (mutation.type === 'childList') {
        mutation.addedNodes.forEach(node => {
          if (node.nodeType === 1) {
            if (node.hasAttribute && node.hasAttribute('data-neural-flow')) {
              shouldInit = true;
            } else if (node.querySelectorAll) {
              const neuralElements = node.querySelectorAll('[data-neural-flow]');
              if (neuralElements.length > 0) {
                shouldInit = true;
              }
            }
          }
        });
      } else if (mutation.type === 'attributes' && mutation.attributeName === 'data-neural-flow') {
        shouldInit = true;
      }
    });

    if (shouldInit) {
      setTimeout(initNeuralFlow, 100);
    }
  });

  observer.observe(document.body, { 
    childList: true, 
    subtree: true,
    attributes: true,
    attributeFilter: ['data-neural-flow']
  });

  window.initNeuralFlow = initNeuralFlow;

})();`;
      }

      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 'intensity':
              neuralConfig.intensity = defaultValue;
              break;
            case 'speed':
              neuralConfig.speed = defaultValue;
              break;
            case 'mouse-sensitivity':
              neuralConfig.mouseSensitivity = defaultValue;
              break;
            case 'color-variation':
              neuralConfig.colorVariation = defaultValue;
              break;
          }
          
          updatePreview();
          showNotification(`${parameterId.replace(/-/g, ' ')} reset to default`);
        }
      };

      function generateRandomNeural() {
        neuralConfig.intensity = Math.random() * 2.9 + 0.1;
        neuralConfig.speed = Math.random() * 2.9 + 0.1;
        neuralConfig.mouseSensitivity = Math.random() * 1.9 + 0.1;
        neuralConfig.baseColor = generateRandomColor();
        neuralConfig.colorVariation = Math.floor(Math.random() * 100);
        neuralConfig.scrollEffect = Math.random() > 0.5;
        neuralConfig.blurEdges = Math.random() > 0.3;
        
        document.getElementById('intensity').value = neuralConfig.intensity;
        document.getElementById('speed').value = neuralConfig.speed;
        document.getElementById('mouse-sensitivity').value = neuralConfig.mouseSensitivity;
        document.getElementById('base-color').value = neuralConfig.baseColor;
        document.getElementById('color-variation').value = neuralConfig.colorVariation;
        document.getElementById('scroll-effect').checked = neuralConfig.scrollEffect;
        document.getElementById('blur-edges').checked = neuralConfig.blurEdges;
        
        document.getElementById('intensity-value').textContent = neuralConfig.intensity.toFixed(1);
        document.getElementById('speed-value').textContent = neuralConfig.speed.toFixed(1);
        document.getElementById('mouse-sensitivity-value').textContent = neuralConfig.mouseSensitivity.toFixed(1);
        document.getElementById('color-variation-value').textContent = neuralConfig.colorVariation;
        
        updateColorInputs();
        initializePreview();
        showNotification('Random neural flow generated!');
      }

      function updateColorInputs() {
        const colorInput = document.getElementById('base-color');
        const hexInput = document.getElementById('base-color-hex');
        
        if (colorInput && hexInput) {
          colorInput.value = neuralConfig.baseColor;
          hexInput.value = neuralConfig.baseColor;
          
          hexInput.classList.remove('invalid');
          
          const colorPickerContainer = colorInput.closest('.color-main-input').querySelector('.color-picker-container');
          if (colorPickerContainer) {
            colorPickerContainer.style.setProperty('--selected-color', neuralConfig.baseColor);
          }
        }
      }

      function initializeUI() {
        initializePreview();
        
        const instructionsToggle = document.getElementById('instructions-toggle');
        const instructionsContent = document.getElementById('instructions-content');
        const instructionsCard = document.getElementById('instructions-card');
        const toggleIcon = instructionsToggle.querySelector('.toggle-icon');
        
        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');
          }
        });

        document.getElementById('quick-attribute').addEventListener('click', () => {
          copyToClipboard('data-neural-flow');
        });

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

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

        document.getElementById('randomize-neural').addEventListener('click', () => {
          generateRandomNeural();
        });

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

        backgroundPicker.addEventListener('input', (e) => {
          const selectedColor = e.target.value;
          previewContainer.style.backgroundColor = selectedColor;
          showNotification(`Preview background changed to ${selectedColor}`);
        });

        previewContainer.style.backgroundColor = '#000000';

        document.getElementById('reset-colors').addEventListener('click', () => {
          neuralConfig.baseColor = defaultConfig.baseColor;
          neuralConfig.colorVariation = defaultConfig.colorVariation;
          
          document.getElementById('base-color').value = defaultConfig.baseColor;
          document.getElementById('color-variation').value = defaultConfig.colorVariation;
          document.getElementById('color-variation-value').textContent = defaultConfig.colorVariation;
          
          updateColorInputs();
          initializePreview();
          showNotification('Colors reset to default');
        });

        document.getElementById('reset-flow').addEventListener('click', () => {
          neuralConfig.intensity = defaultConfig.intensity;
          neuralConfig.speed = defaultConfig.speed;
          neuralConfig.mouseSensitivity = defaultConfig.mouseSensitivity;
          
          document.getElementById('intensity').value = defaultConfig.intensity;
          document.getElementById('speed').value = defaultConfig.speed;
          document.getElementById('mouse-sensitivity').value = defaultConfig.mouseSensitivity;
          
          document.getElementById('intensity-value').textContent = defaultConfig.intensity;
          document.getElementById('speed-value').textContent = defaultConfig.speed;
          document.getElementById('mouse-sensitivity-value').textContent = defaultConfig.mouseSensitivity;
          
          updatePreview();
          showNotification('Flow settings reset');
        });

        document.getElementById('reset-advanced').addEventListener('click', () => {
          neuralConfig.scrollEffect = defaultConfig.scrollEffect;
          neuralConfig.blurEdges = defaultConfig.blurEdges;
          
          document.getElementById('scroll-effect').checked = defaultConfig.scrollEffect;
          document.getElementById('blur-edges').checked = defaultConfig.blurEdges;
          
          updatePreview();
          showNotification('Advanced settings reset');
        });

        const colorInput = document.getElementById('base-color');
        const hexInput = document.getElementById('base-color-hex');
        
        colorInput.addEventListener('input', () => {
          const color = colorInput.value;
          hexInput.value = color;
          hexInput.classList.remove('invalid');
          neuralConfig.baseColor = color;
          
          const colorPickerContainer = colorInput.closest('.color-main-input').querySelector('.color-picker-container');
          colorPickerContainer.style.setProperty('--selected-color', color);
          
          updatePreview();
        });
        
        hexInput.addEventListener('input', (e) => {
          let hex = e.target.value;
          
          hex = formatHex(hex);
          e.target.value = hex;
          
          if (isValidHex(hex)) {
            colorInput.value = hex;
            neuralConfig.baseColor = hex;
            e.target.classList.remove('invalid');
            
            const colorPickerContainer = colorInput.closest('.color-main-input').querySelector('.color-picker-container');
            colorPickerContainer.style.setProperty('--selected-color', hex);
            
            updatePreview();
          } 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');
          }
        });

        document.getElementById('color-variation').addEventListener('input', (e) => {
          const value = parseInt(e.target.value);
          document.getElementById('color-variation-value').textContent = value;
          neuralConfig.colorVariation = value;
          updatePreview();
        });

        const rangeInputs = document.querySelectorAll('input[type="range"]');
        rangeInputs.forEach(input => {
          if (input.id === 'color-variation') return;
          
          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 'intensity':
                neuralConfig.intensity = parseFloat(input.value);
                break;
              case 'speed':
                neuralConfig.speed = parseFloat(input.value);
                break;
              case 'mouse-sensitivity':
                neuralConfig.mouseSensitivity = parseFloat(input.value);
                break;
            }
            
            updatePreview();
          });
        });

        document.getElementById('scroll-effect').addEventListener('change', function() {
          neuralConfig.scrollEffect = this.checked;
          updatePreview();
        });

        document.getElementById('blur-edges').addEventListener('change', function() {
          neuralConfig.blurEdges = this.checked;
          updatePreview();
        });

        document.querySelectorAll('.palette-color').forEach((colorElement, index) => {
          colorElement.addEventListener('click', () => {
            const colors = generateColorVariations(neuralConfig.baseColor, neuralConfig.colorVariation);
            copyToClipboard(colors[index]);
          });
        });

        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();
                copyJsToClipboard();
                break;
              case 's':
                e.preventDefault();
                copyFullSectionToClipboard();
                break;
            }
          } else {
            switch (e.key.toLowerCase()) {
              case 'r':
                generateRandomNeural();
                break;
              case 'b':
                document.getElementById('preview-background-picker').click();
                break;
            }
          }
        });

        updateColorInputs();
        
        setTimeout(() => {
          showNotification('Neural Flow Configurator loaded - 100% preview accuracy!');
        }, 500);

        function saveConfiguration() {
          try {
            localStorage.setItem('bricksfusion-neural-config', JSON.stringify(neuralConfig));
          } catch (e) {
          }
        }

        function loadConfiguration() {
          try {
            const saved = localStorage.getItem('bricksfusion-neural-config');
            if (saved) {
              const savedConfig = JSON.parse(saved);
              Object.assign(neuralConfig, savedConfig);
              
              document.getElementById('intensity').value = savedConfig.intensity;
              document.getElementById('speed').value = savedConfig.speed;
              document.getElementById('mouse-sensitivity').value = savedConfig.mouseSensitivity;
              document.getElementById('base-color').value = savedConfig.baseColor;
              document.getElementById('color-variation').value = savedConfig.colorVariation || 50;
              document.getElementById('scroll-effect').checked = savedConfig.scrollEffect;
              document.getElementById('blur-edges').checked = savedConfig.blurEdges;
              
              document.getElementById('intensity-value').textContent = savedConfig.intensity;
              document.getElementById('speed-value').textContent = savedConfig.speed;
              document.getElementById('mouse-sensitivity-value').textContent = savedConfig.mouseSensitivity;
              document.getElementById('color-variation-value').textContent = savedConfig.colorVariation || 50;
              
              updateColorInputs();
              initializePreview();
            }
          } catch (e) {
          }
        }

        const originalUpdatePreview = updatePreview;
        updatePreview = function() {
          originalUpdatePreview();
          saveConfiguration();
        };

        loadConfiguration();
      }
      
      initializeUI();
    });
  </script>
</body>
</html>
Neural Flow - Bricksfusion
HEAVY

Neural Flow

Creates dynamic neural network patterns that react to mouse movement. Features flowing organic shapes that pulse and evolve continuously. Choose your base color and the effect generates complementary variations automatically. Responds to cursor position and scroll for immersive interaction. Perfect for tech backgrounds, hero sections, or creating futuristic atmospheres.

Neural Flow

Move your mouse to interact with the neural patterns.

Colors

Base Color Color picker

Choose your main color. The effect will automatically generate two complementary color variations to create a rich, harmonious palette for the neural patterns.

Default: Indigo

Color Variety Similar to Diverse

Controls how different the automatic color variations are from your base color. Lower keeps colors close together. Higher creates bold, contrasting variations.

Default: Balanced (50)

Intensity

Brightness Subtle to Vibrant

Overall brightness and visibility of the neural patterns. Lower creates a gentle, understated effect. Higher produces bold, eye-catching visuals.

Default: Medium-High (1.5)

Motion

Animation Speed Slow to Fast

How quickly the neural patterns evolve and pulse. Lower creates calm, meditative movement. Higher produces energetic, dynamic flow.

Default: Moderate

Mouse Response Minimal to Strong

How dramatically patterns react to cursor movement. Lower keeps it subtle and smooth. Higher creates intense, responsive distortion.

Default: Balanced

Effects

Scroll Animation On/Off toggle

When enabled, colors shift smoothly as users scroll down the page. Creates a dynamic, evolving background that changes with content.

Default: Enabled

Soft Edges On/Off toggle

Adds a subtle blur to smooth the edges of patterns. Creates a softer, more organic look that blends naturally with content.

Default: Enabled

Performance

This effect uses WebGL with custom shaders for GPU-accelerated rendering. Creates organic patterns using mathematical noise functions with real-time mouse tracking. Features automatic color palette generation from single base color. Smooth interpolation for cursor movement. Very resource intensive - limit to 1 instance per page. Not recommended for mobile devices or low-end hardware.