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

        .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: linear-gradient(45deg, #f0f0f0 25%, transparent 25%), 
                        linear-gradient(-45deg, #f0f0f0 25%, transparent 25%), 
                        linear-gradient(45deg, transparent 75%, #f0f0f0 75%), 
                        linear-gradient(-45deg, transparent 75%, #f0f0f0 75%);
            background-size: 8px 8px;
            background-position: 0 0, 0 4px, 4px -4px, -4px 0px;
        }

        .color-picker-container::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: var(--current-color, #4444ff);
            border-radius: 6px;
            z-index: 1;
        }

        .color-picker-container:hover {
            border-color: var(--accent);
            transform: scale(1.05);
        }

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

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

        .switch-container {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 1.2rem;
            padding: 0.5rem 0;
        }

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

        .switch {
            position: relative;
            display: inline-block;
            width: 52px;
            height: 28px;
        }

        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }

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

        .slider:before {
            position: absolute;
            content: "";
            height: 20px;
            width: 20px;
            left: 4px;
            bottom: 4px;
            background-color: #f2f2f7;
            transition: var(--transition);
            border-radius: 50%;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
        }

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

        input:checked + .slider:before {
            transform: translateX(24px);
        }

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

        @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/corebackground/" class="breadcrumb-item">Core Backgrounds</a>
            <span class="breadcrumb-separator">›</span>
            <span class="breadcrumb-item active">Aura Flow</span>
        </nav>
        
        <div class="action-buttons">
            <div class="data-attribute-display" id="quick-attribute" title="Click to copy data attribute">
                data-aura-flow
            </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">Aura Flow</h1>
            <p class="page-subtitle">Interactive fluid 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>Customize your Aura Flow animation 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-aura-flow</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="aura-flow-preview" data-aura-flow="true">
                    <div class="preview-content">Interactive Aura Flow Preview</div>
                    <div class="preview-controls">
                        <button class="preview-btn" id="randomize-aura-flow" 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">
                        Aura Colors
                        <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-list">
                            <div class="color-row">
                                <div class="color-picker-container">
                                    <input type="color" id="color1" value="#4444ff">
                                </div>
                                <div class="color-input-group">
                                    <span class="color-label">HEX</span>
                                    <input type="text" class="color-input hex-input" id="color1-hex" value="#4444ff" placeholder="#FFFFFF">
                                </div>
                                <div class="color-input-group">
                                    <span class="color-label">HSL</span>
                                    <input type="text" class="color-input hsl-input" id="color1-hsl" placeholder="hsl(0, 100%, 50%)">
                                </div>
                            </div>
                            
                            <div class="color-row">
                                <div class="color-picker-container">
                                    <input type="color" id="color2" value="#0088ff">
                                </div>
                                <div class="color-input-group">
                                    <span class="color-label">HEX</span>
                                    <input type="text" class="color-input hex-input" id="color2-hex" value="#0088ff" placeholder="#FFFFFF">
                                </div>
                                <div class="color-input-group">
                                    <span class="color-label">HSL</span>
                                    <input type="text" class="color-input hsl-input" id="color2-hsl" placeholder="hsl(0, 100%, 50%)">
                                </div>
                            </div>
                            
                            <div class="color-row">
                                <div class="color-picker-container">
                                    <input type="color" id="color3" value="#00ffff">
                                </div>
                                <div class="color-input-group">
                                    <span class="color-label">HEX</span>
                                    <input type="text" class="color-input hex-input" id="color3-hex" value="#00ffff" placeholder="#FFFFFF">
                                </div>
                                <div class="color-input-group">
                                    <span class="color-label">HSL</span>
                                    <input type="text" class="color-input hsl-input" id="color3-hsl" placeholder="hsl(0, 100%, 50%)">
                                </div>
                            </div>
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Opacity
                                    <span class="help-tooltip" title="Controls the overall opacity of the effect">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="opacity-value">0.9</span></span>
                                    <button class="reset-btn" onclick="resetParameter('opacity', 0.9)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="opacity" min="0.1" max="1" value="0.9" step="0.05">
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-heading">
                        Effect Properties
                        <div class="card-actions">
                            <button class="card-action-btn" id="reset-effects" title="Reset Effect 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="Controls the overall intensity of the 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="2" value="1.0" step="0.1">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Glow Effect
                                    <span class="help-tooltip" title="Controls the glow radius around the cursor">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="glow-value">0.8</span></span>
                                    <button class="reset-btn" onclick="resetParameter('glow', 0.8)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="glow" min="0.1" max="2" value="0.8" step="0.1">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Electric Effect
                                    <span class="help-tooltip" title="Controls the electric lightning trails">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="electric-value">1.2</span></span>
                                    <button class="reset-btn" onclick="resetParameter('electric', 1.2)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="electric" min="0.1" max="2" value="1.2" step="0.1">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Effect Radius
                                    <span class="help-tooltip" title="Controls the radius of the effect area">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="radius-value">100</span></span>
                                    <button class="reset-btn" onclick="resetParameter('radius', 100)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="radius" min="10" max="300" value="100" step="5">
                        </div>
                    </div>
                </div>

                <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>
                                <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="2" value="1.0" step="0.1">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">Pulse Speed</span>
                                <div class="value-display">
                                    <span class="value-text"><span id="pulse-speed-value">8.0</span></span>
                                    <button class="reset-btn" onclick="resetParameter('pulse-speed', 8.0)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="pulse-speed" min="1" max="15" value="8.0" step="0.5">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">Mouse Transition</span>
                                <div class="value-display">
                                    <span class="value-text"><span id="transition-value">0.08</span></span>
                                    <button class="reset-btn" onclick="resetParameter('transition', 0.08)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="transition" min="0.01" max="0.2" value="0.08" step="0.01">
                        </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="switch-container">
                            <span class="switch-label">Auto Movement</span>
                            <label class="switch">
                                <input type="checkbox" id="auto-movement" checked>
                                <span class="slider"></span>
                            </label>
                        </div>
                        
                        <div class="switch-container">
                            <span class="switch-label">Performance Mode</span>
                            <label class="switch">
                                <input type="checkbox" id="performance-mode">
                                <span class="slider"></span>
                            </label>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </div>

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

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            let fluidConfig = {
                colors: ['#4444ff', '#0088ff', '#00ffff'],
                opacity: 0.9,
                intensity: 1.0,
                glow: 0.8,
                electric: 1.2,
                radius: 100,
                speed: 1.0,
                pulseSpeed: 8.0,
                transition: 0.08,
                autoMovement: true,
                performanceMode: false
            };

            const defaultConfig = { ...fluidConfig };
            let activeFluid = null;

            function hexToRGB(hex) {
                try {
                    if (!hex || typeof hex !== 'string') {
                        return [0.5, 0.5, 1.0];
                    }
                    
                    if (hex.charAt(0) !== '#') {
                        hex = '#' + hex;
                    }
                    
                    const shorthand = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
                    hex = hex.replace(shorthand, (m, r, g, b) => {
                        return '#' + r + r + g + g + b + b;
                    });
                    
                    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
                    if (!result) {
                        return [0.5, 0.5, 1.0];
                    }
                    
                    const r = parseInt(result[1], 16) / 255;
                    const g = parseInt(result[2], 16) / 255;
                    const b = parseInt(result[3], 16) / 255;
                    
                    return [r, g, b];
                } catch (error) {
                    return [0.5, 0.5, 1.0];
                }
            }

            function initFluidAnimation() {
                destroyExistingFluid();
                
                const container = document.getElementById('aura-flow-preview');
                
                container.setAttribute('data-aura-flow-color1', fluidConfig.colors[0]);
                container.setAttribute('data-aura-flow-color2', fluidConfig.colors[1]);
                container.setAttribute('data-aura-flow-color3', fluidConfig.colors[2]);
                container.setAttribute('data-aura-flow-opacity', fluidConfig.opacity);
                container.setAttribute('data-aura-flow-intensity', fluidConfig.intensity);
                container.setAttribute('data-aura-flow-glow', fluidConfig.glow);
                container.setAttribute('data-aura-flow-electric', fluidConfig.electric);
                container.setAttribute('data-aura-flow-radius', fluidConfig.radius);
                container.setAttribute('data-aura-flow-speed', fluidConfig.speed);
                container.setAttribute('data-aura-flow-pulse-speed', fluidConfig.pulseSpeed);
                container.setAttribute('data-aura-flow-transition', fluidConfig.transition);
                
                activeFluid = new FluidAnimation(container);
            }

            function destroyExistingFluid() {
                if (activeFluid) {
                    activeFluid.destroy();
                    activeFluid = null;
                }
            }

            class FluidAnimation {
                constructor(container) {
                    this.container = container;
                    this._cache = {
                        dimensions: { width: 0, height: 0, aspect: 0 },
                        mouse: { current: { x: 0.5, y: 0.5 }, last: { x: 0.5, y: 0.5 } },
                        time: 0,
                        frameCount: 0,
                        autonomous: true
                    };
                    
                    this.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
                    this._frameInterval = this.isMobile ? 1000/30 : 1000/60;
                    this._lastFrameTime = 0;
                    this.mouseX = 0.5;
                    this.mouseY = 0.5;
                    this.lastX = 0.5;
                    this.lastY = 0.5;
                    this.targetX = 0.5;
                    this.targetY = 0.5;
                    this.transitionSpeed = parseFloat(container.getAttribute('data-aura-flow-transition')) || fluidConfig.transition;
                    this.isMouseDown = false;
                    
                    this.config = this._parseConfig(container);
                    this._setup(container);
                    this._initWebGL();
                    this._setupShaders();
                    this._setupEvents();
                    this._animate();
                }
                
                _parseConfig(container) {
                    const colors = [];
                    
                    for (let i = 1; i <= 3; i++) {
                        const colorAttr = 'data-aura-flow-color' + i;
                        if (container.hasAttribute(colorAttr)) {
                            const hexColor = container.getAttribute(colorAttr);
                            colors.push(hexToRGB(hexColor));
                        }
                    }
                    
                    if (colors.length !== 3) {
                        colors.length = 0;
                        colors.push(hexToRGB(fluidConfig.colors[0]));
                        colors.push(hexToRGB(fluidConfig.colors[1]));
                        colors.push(hexToRGB(fluidConfig.colors[2]));
                    }
                    
                    return {
                        colors: colors,
                        opacity: parseFloat(container.getAttribute('data-aura-flow-opacity')) || fluidConfig.opacity,
                        intensity: parseFloat(container.getAttribute('data-aura-flow-intensity')) || fluidConfig.intensity,
                        glow: parseFloat(container.getAttribute('data-aura-flow-glow')) || fluidConfig.glow,
                        electric: parseFloat(container.getAttribute('data-aura-flow-electric')) || fluidConfig.electric,
                        radius: parseFloat(container.getAttribute('data-aura-flow-radius')) || fluidConfig.radius,
                        speed: parseFloat(container.getAttribute('data-aura-flow-speed')) || fluidConfig.speed,
                        pulseSpeed: parseFloat(container.getAttribute('data-aura-flow-pulse-speed')) || fluidConfig.pulseSpeed
                    };
                }
                
                _setup(container) {
                    if (getComputedStyle(container).position === 'static') {
                        container.style.position = 'relative';
                    }
                    
                    this.wrapper = document.createElement('div');
                    Object.assign(this.wrapper.style, {
                        position: 'absolute',
                        top: '0',
                        left: '0',
                        width: '100%',
                        height: '100%',
                        zIndex: '1',
                        pointerEvents: 'none',
                        opacity: this.config.opacity.toString()
                    });
                    
                    this.canvas = document.createElement('canvas');
                    Object.assign(this.canvas.style, {
                        position: 'absolute',
                        top: '0',
                        left: '0',
                        width: '100%',
                        height: '100%',
                        mixBlendMode: 'screen',
                        pointerEvents: 'none'
                    });
                    
                    this.wrapper.appendChild(this.canvas);
                    container.insertBefore(this.wrapper, container.firstChild);
                }
                
                _initWebGL() {
                    this.gl = this.canvas.getContext('webgl', {
                        premultipliedAlpha: false,
                        alpha: true
                    });
                    
                    if (!this.gl) {
                        return;
                    }
                    
                    this.gl.clearColor(0.0, 0.0, 0.0, 0.0);
                    this.startTime = Date.now();
                    this.vertices = new Float32Array([-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0]);
                    
                    this._resize();
                }
                
                _setupShaders() {
                    const vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER);
                    this.gl.shaderSource(vertexShader, `
                        attribute vec2 position;
                        varying vec2 uv;
                        void main() {
                            uv = position * 0.5 + 0.5;
                            gl_Position = vec4(position, 0.0, 1.0);
                        }
                    `);
                    this.gl.compileShader(vertexShader);
                    
                    const fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
                    this.gl.shaderSource(fragmentShader, `
                        precision highp float;
                        varying vec2 uv;
                        uniform vec2 resolution;
                        uniform vec2 mouse;
                        uniform float time;
                        uniform vec2 lastMouse;
                        uniform float isMouseDown;
                        uniform vec3 color1;
                        uniform vec3 color2;
                        uniform vec3 color3;
                        uniform float intensity;
                        uniform float glow;
                        uniform float electric;
                        uniform float radius;
                        uniform float pulseSpeed;

                        float lightning(vec2 p, vec2 a, vec2 b) {
                            vec2 pa = p - a;
                            vec2 ba = b - a;
                            float h = clamp(dot(pa,ba)/dot(ba,ba), 0.0, 1.0);
                            float d = length(pa - ba*h);
                            float strength = 1.0 - smoothstep(0.0, 0.02 / electric, d);
                            strength *= sin(time * pulseSpeed + p.x * 10.0) * 0.5 + 0.5;
                            return strength;
                        }

                        void main() {
                            vec2 p = (uv * resolution * 2.0 - resolution) / min(resolution.x, resolution.y);
                            vec2 m = (mouse * resolution * 2.0 - resolution) / min(resolution.x, resolution.y);
                            vec2 lm = (lastMouse * resolution * 2.0 - resolution) / min(resolution.x, resolution.y);
                            
                            vec3 color = vec3(0.0);
                            vec2 mouseVel = (m - lm) * isMouseDown;
                            float mouseLen = length(mouseVel);
                            
                            for(float i = 0.0; i < 3.0; i++) {
                                vec2 pos = p - m;
                                float dist = length(pos);
                                float a = atan(pos.y, pos.x) + sin(time * 0.5) * 2.0;
                                
                                float h = dist * (1.0 + mouseLen * 2.0);
                                vec3 col = mix(
                                    mix(color1, color2, i / 2.0),
                                    color3,
                                    sin(time * 0.5 + h) * 0.5 + 0.5
                                );
                                
                                color += col * (0.15 * intensity / abs(dist - mouseLen * 2.0));
                                color += col * (0.15 * intensity / abs(dist - mouseLen));
                            }

                            float glowStr = exp(-length(p - m) * (1.5 / glow));
                            color += mix(color1, color2, 0.5) * glowStr * 0.8;

                            if (mouseLen > 0.001) {
                                float electricEffect = lightning(p, lm, m);
                                electricEffect += lightning(p, lm + vec2(0.1), m + vec2(-0.1));
                                electricEffect += lightning(p, lm - vec2(0.1), m + vec2(0.1));
                                color += mix(color2, color3, 0.5) * electricEffect * electric;
                            }

                            float pulse = sin(time * pulseSpeed) * 0.5 + 0.5;
                            float mouseGlow = exp(-length(p - m) * (2.0 + pulse * 2.0));
                            color += mix(color1, color3, pulse) * mouseGlow * pulse * intensity;

                            color = pow(color, vec3(0.8));
                            float alpha = min(1.0, length(color) * 0.7);
                            gl_FragColor = vec4(color, alpha);
                        }
                    `);
                    this.gl.compileShader(fragmentShader);
                    
                    if (!this.gl.getShaderParameter(vertexShader, this.gl.COMPILE_STATUS)) {
                        return;
                    }
                    
                    if (!this.gl.getShaderParameter(fragmentShader, this.gl.COMPILE_STATUS)) {
                        return;
                    }
                    
                    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 buffer = this.gl.createBuffer();
                    this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
                    this.gl.bufferData(this.gl.ARRAY_BUFFER, this.vertices, this.gl.STATIC_DRAW);
                    
                    const positionLocation = this.gl.getAttribLocation(this.program, 'position');
                    this.gl.enableVertexAttribArray(positionLocation);
                    this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);
                    
                    this.uniformLocations = {};
                    ['resolution', 'mouse', 'time', 'lastMouse', 'isMouseDown', 
                     'color1', 'color2', 'color3', 'intensity', 'glow', 
                     'electric', 'radius', 'pulseSpeed'].forEach(name => {
                        this.uniformLocations[name] = this.gl.getUniformLocation(this.program, name);
                    });
                }
                
                _setupEvents() {
                    this.resizeHandler = this._resize.bind(this);
                    window.addEventListener('resize', this.resizeHandler);
                    
                    const updatePosition = (e, touch = false) => {
                        const rect = this.container.getBoundingClientRect();
                        const clientX = touch ? e.touches[0].clientX : e.clientX;
                        const clientY = touch ? e.touches[0].clientY : e.clientY;
                        
                        if (clientX < rect.left || clientX > rect.right || 
                            clientY < rect.top || clientY > rect.bottom) {
                            this._cache.autonomous = true;
                            return;
                        }
                        
                        this._cache.autonomous = false;
                        this.targetX = (clientX - rect.left) / rect.width;
                        this.targetY = 1.0 - (clientY - rect.top) / rect.height;
                        
                        clearTimeout(this.autonomousTimeout);
                        this.autonomousTimeout = setTimeout(() => {
                            this._cache.autonomous = true;
                        }, 2000);
                    };
                    
                    this.mouseMoveHandler = e => updatePosition(e);
                    this.mouseDownHandler = e => {
                        const rect = this.container.getBoundingClientRect();
                        if (e.clientX >= rect.left && e.clientX <= rect.right && 
                            e.clientY >= rect.top && e.clientY <= rect.bottom) {
                            this.isMouseDown = true;
                        }
                    };
                    this.mouseUpHandler = () => this.isMouseDown = false;
                    this.mouseLeaveHandler = () => this._cache.autonomous = true;
                    
                    this.container.addEventListener('mousemove', this.mouseMoveHandler);
                    this.container.addEventListener('mousedown', this.mouseDownHandler);
                    window.addEventListener('mouseup', this.mouseUpHandler);
                    this.container.addEventListener('mouseleave', this.mouseLeaveHandler);
                    
                    this.touchStartHandler = e => {
                        this.isMouseDown = true;
                        updatePosition(e, true);
                    };
                    
                    this.touchMoveHandler = e => {
                        if (this.isMouseDown) {
                            updatePosition(e, true);
                        }
                    };
                    
                    this.touchEndHandler = () => {
                        this.isMouseDown = false;
                        this._cache.autonomous = true;
                    };
                    
                    this.container.addEventListener('touchstart', this.touchStartHandler, {passive: true});
                    this.container.addEventListener('touchmove', this.touchMoveHandler, {passive: true});
                    this.container.addEventListener('touchend', this.touchEndHandler, {passive: true});
                }
                
                _updateAutonomousPosition(time) {
                    if (this._cache.autonomous) {
                        const radius = 0.3;
                        const speed = 0.5 * this.config.speed;
                        this.targetX = 0.5 + Math.cos(time * speed) * radius;
                        this.targetY = 0.5 + Math.sin(time * speed * 1.5) * radius;
                    }
                    
                    this.lastX = this.mouseX;
                    this.lastY = this.mouseY;
                    
                    this.mouseX += (this.targetX - this.mouseX) * this.transitionSpeed;
                    this.mouseY += (this.targetY - this.mouseY) * this.transitionSpeed;
                }
                
                _resize() {
                    const width = this.canvas.clientWidth;
                    const height = this.canvas.clientHeight;
                    
                    if (this.canvas.width !== width || this.canvas.height !== height) {
                        this.canvas.width = width;
                        this.canvas.height = height;
                        this.gl.viewport(0, 0, width, height);
                    }
                }
                
                _animate(timestamp = 0) {
                    if (timestamp - this._lastFrameTime < this._frameInterval) {
                        this.animationFrame = requestAnimationFrame(this._animate.bind(this));
                        return;
                    }
                    
                    this._lastFrameTime = timestamp;
                    this._resize();
                    
                    const time = (Date.now() - this.startTime) * 0.001 * this.config.speed;
                    
                    this._updateAutonomousPosition(time);
                    
                    this.gl.enable(this.gl.BLEND);
                    this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
                    
                    this.gl.uniform2f(this.uniformLocations.resolution, this.canvas.width, this.canvas.height);
                    this.gl.uniform2f(this.uniformLocations.mouse, this.mouseX, this.mouseY);
                    this.gl.uniform2f(this.uniformLocations.lastMouse, this.lastX, this.lastY);
                    this.gl.uniform1f(this.uniformLocations.time, time);
                    this.gl.uniform1f(this.uniformLocations.isMouseDown, this.isMouseDown ? 1.0 : 0.0);
                    
                    this.gl.uniform3fv(this.uniformLocations.color1, this.config.colors[0]);
                    this.gl.uniform3fv(this.uniformLocations.color2, this.config.colors[1]);
                    this.gl.uniform3fv(this.uniformLocations.color3, this.config.colors[2]);
                    
                    this.gl.uniform1f(this.uniformLocations.intensity, this.config.intensity);
                    this.gl.uniform1f(this.uniformLocations.glow, this.config.glow);
                    this.gl.uniform1f(this.uniformLocations.electric, this.config.electric);
                    this.gl.uniform1f(this.uniformLocations.radius, this.config.radius);
                    this.gl.uniform1f(this.uniformLocations.pulseSpeed, this.config.pulseSpeed);
                    
                    this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
                    
                    this.animationFrame = requestAnimationFrame(this._animate.bind(this));
                }
                
                destroy() {
                    if (this.animationFrame) {
                        cancelAnimationFrame(this.animationFrame);
                    }
                    
                    if (this.autonomousTimeout) {
                        clearTimeout(this.autonomousTimeout);
                    }
                    
                    window.removeEventListener('resize', this.resizeHandler);
                    
                    this.container.removeEventListener('mousemove', this.mouseMoveHandler);
                    this.container.removeEventListener('mousedown', this.mouseDownHandler);
                    window.removeEventListener('mouseup', this.mouseUpHandler);
                    this.container.removeEventListener('mouseleave', this.mouseLeaveHandler);
                    
                    this.container.removeEventListener('touchstart', this.touchStartHandler);
                    this.container.removeEventListener('touchmove', this.touchMoveHandler);
                    this.container.removeEventListener('touchend', this.touchEndHandler);
                    
                    if (this.gl) {
                        this.gl.deleteProgram(this.program);
                        const ext = this.gl.getExtension('WEBGL_lose_context');
                        if (ext) ext.loseContext();
                    }
                    
                    if (this.wrapper && this.wrapper.parentNode) {
                        this.wrapper.parentNode.removeChild(this.wrapper);
                    }
                }
            }

            function generateJavaScriptCode() {
                return `(function() {
const DEFAULT_CONFIG = {
opacity: ${fluidConfig.opacity},
intensity: ${fluidConfig.intensity},
glow: ${fluidConfig.glow},
electric: ${fluidConfig.electric},
radius: ${fluidConfig.radius},
speed: ${fluidConfig.speed},
pulseSpeed: ${fluidConfig.pulseSpeed},
transition: ${fluidConfig.transition},
colors: [
'${fluidConfig.colors[0]}',
'${fluidConfig.colors[1]}',
'${fluidConfig.colors[2]}'
]
};

function hexToRGB(hex) {
try {
if (!hex || typeof hex !== 'string') {
return [0.5, 0.5, 1.0];
}

if (hex.charAt(0) !== '#') {
hex = '#' + hex;
}

const shorthand = /^#?([a-f\\d])([a-f\\d])([a-f\\d])$/i;
hex = hex.replace(shorthand, (m, r, g, b) => {
return '#' + r + r + g + g + b + b;
});

const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);
if (!result) {
return [0.5, 0.5, 1.0];
}

const r = parseInt(result[1], 16) / 255;
const g = parseInt(result[2], 16) / 255;
const b = parseInt(result[3], 16) / 255;

return [r, g, b];
} catch (error) {
return [0.5, 0.5, 1.0];
}
}

class FluidAnimation {
constructor(container) {
this.container = container;
this._cache = {
dimensions: { width: 0, height: 0, aspect: 0 },
mouse: { current: { x: 0.5, y: 0.5 }, last: { x: 0.5, y: 0.5 } },
time: 0,
frameCount: 0,
autonomous: true
};

this.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
this._frameInterval = this.isMobile ? 1000/30 : 1000/60;
this._lastFrameTime = 0;
this.mouseX = 0.5;
this.mouseY = 0.5;
this.lastX = 0.5;
this.lastY = 0.5;
this.targetX = 0.5;
this.targetY = 0.5;
this.transitionSpeed = parseFloat(container.getAttribute('data-aura-flow-transition')) || DEFAULT_CONFIG.transition;
this.isMouseDown = false;

this.config = this._parseConfig(container);
this._setup(container);
this._initWebGL();
this._setupShaders();
this._setupEvents();
this._animate();
}

_parseConfig(container) {
const colors = [];

for (let i = 1; i <= 3; i++) {
const colorAttr = 'data-aura-flow-color' + i;
if (container.hasAttribute(colorAttr)) {
const hexColor = container.getAttribute(colorAttr);
colors.push(hexToRGB(hexColor));
}
}

if (colors.length !== 3) {
colors.length = 0;
colors.push(hexToRGB(DEFAULT_CONFIG.colors[0]));
colors.push(hexToRGB(DEFAULT_CONFIG.colors[1]));
colors.push(hexToRGB(DEFAULT_CONFIG.colors[2]));
}

return {
colors: colors,
opacity: parseFloat(container.getAttribute('data-aura-flow-opacity')) || DEFAULT_CONFIG.opacity,
intensity: parseFloat(container.getAttribute('data-aura-flow-intensity')) || DEFAULT_CONFIG.intensity,
glow: parseFloat(container.getAttribute('data-aura-flow-glow')) || DEFAULT_CONFIG.glow,
electric: parseFloat(container.getAttribute('data-aura-flow-electric')) || DEFAULT_CONFIG.electric,
radius: parseFloat(container.getAttribute('data-aura-flow-radius')) || DEFAULT_CONFIG.radius,
speed: parseFloat(container.getAttribute('data-aura-flow-speed')) || DEFAULT_CONFIG.speed,
pulseSpeed: parseFloat(container.getAttribute('data-aura-flow-pulse-speed')) || DEFAULT_CONFIG.pulseSpeed
};
}

_setup(container) {
if (getComputedStyle(container).position === 'static') {
container.style.position = 'relative';
}

this.wrapper = document.createElement('div');
Object.assign(this.wrapper.style, {
position: 'absolute',
top: '0',
left: '0',
width: '100%',
height: '100%',
zIndex: '1',
pointerEvents: 'none',
opacity: this.config.opacity.toString()
});

this.canvas = document.createElement('canvas');
Object.assign(this.canvas.style, {
position: 'absolute',
top: '0',
left: '0',
width: '100%',
height: '100%',
mixBlendMode: 'screen',
pointerEvents: 'none'
});

this.wrapper.appendChild(this.canvas);
container.insertBefore(this.wrapper, container.firstChild);
}

_initWebGL() {
this.gl = this.canvas.getContext('webgl', {
premultipliedAlpha: false,
alpha: true
});

if (!this.gl) {
return;
}

this.gl.clearColor(0.0, 0.0, 0.0, 0.0);
this.startTime = Date.now();
this.vertices = new Float32Array([-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0]);

this._resize();
}

_setupShaders() {
const vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER);
this.gl.shaderSource(vertexShader, \`
attribute vec2 position;
varying vec2 uv;
void main() {
uv = position * 0.5 + 0.5;
gl_Position = vec4(position, 0.0, 1.0);
}
\`);
this.gl.compileShader(vertexShader);

const fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
this.gl.shaderSource(fragmentShader, \`
precision highp float;
varying vec2 uv;
uniform vec2 resolution;
uniform vec2 mouse;
uniform float time;
uniform vec2 lastMouse;
uniform float isMouseDown;
uniform vec3 color1;
uniform vec3 color2;
uniform vec3 color3;
uniform float intensity;
uniform float glow;
uniform float electric;
uniform float radius;
uniform float pulseSpeed;

float lightning(vec2 p, vec2 a, vec2 b) {
vec2 pa = p - a;
vec2 ba = b - a;
float h = clamp(dot(pa,ba)/dot(ba,ba), 0.0, 1.0);
float d = length(pa - ba*h);
float strength = 1.0 - smoothstep(0.0, 0.02 / electric, d);
strength *= sin(time * pulseSpeed + p.x * 10.0) * 0.5 + 0.5;
return strength;
}

void main() {
vec2 p = (uv * resolution * 2.0 - resolution) / min(resolution.x, resolution.y);
vec2 m = (mouse * resolution * 2.0 - resolution) / min(resolution.x, resolution.y);
vec2 lm = (lastMouse * resolution * 2.0 - resolution) / min(resolution.x, resolution.y);

vec3 color = vec3(0.0);
vec2 mouseVel = (m - lm) * isMouseDown;
float mouseLen = length(mouseVel);

for(float i = 0.0; i < 3.0; i++) {
vec2 pos = p - m;
float dist = length(pos);
float a = atan(pos.y, pos.x) + sin(time * 0.5) * 2.0;

float h = dist * (1.0 + mouseLen * 2.0);
vec3 col = mix(
mix(color1, color2, i / 2.0),
color3,
sin(time * 0.5 + h) * 0.5 + 0.5
);

color += col * (0.15 * intensity / abs(dist - mouseLen * 2.0));
color += col * (0.15 * intensity / abs(dist - mouseLen));
}

float glowStr = exp(-length(p - m) * (1.5 / glow));
color += mix(color1, color2, 0.5) * glowStr * 0.8;

if (mouseLen > 0.001) {
float electricEffect = lightning(p, lm, m);
electricEffect += lightning(p, lm + vec2(0.1), m + vec2(-0.1));
electricEffect += lightning(p, lm - vec2(0.1), m + vec2(0.1));
color += mix(color2, color3, 0.5) * electricEffect * electric;
}

float pulse = sin(time * pulseSpeed) * 0.5 + 0.5;
float mouseGlow = exp(-length(p - m) * (2.0 + pulse * 2.0));
color += mix(color1, color3, pulse) * mouseGlow * pulse * intensity;

color = pow(color, vec3(0.8));
float alpha = min(1.0, length(color) * 0.7);
gl_FragColor = vec4(color, alpha);
}
\`);
this.gl.compileShader(fragmentShader);

if (!this.gl.getShaderParameter(vertexShader, this.gl.COMPILE_STATUS)) {
return;
}

if (!this.gl.getShaderParameter(fragmentShader, this.gl.COMPILE_STATUS)) {
return;
}

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 buffer = this.gl.createBuffer();
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.vertices, this.gl.STATIC_DRAW);

const positionLocation = this.gl.getAttribLocation(this.program, 'position');
this.gl.enableVertexAttribArray(positionLocation);
this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 0, 0);

this.uniformLocations = {};
['resolution', 'mouse', 'time', 'lastMouse', 'isMouseDown', 
'color1', 'color2', 'color3', 'intensity', 'glow', 
'electric', 'radius', 'pulseSpeed'].forEach(name => {
this.uniformLocations[name] = this.gl.getUniformLocation(this.program, name);
});
}

_setupEvents() {
this.resizeHandler = this._resize.bind(this);
window.addEventListener('resize', this.resizeHandler);

const updatePosition = (e, touch = false) => {
const rect = this.container.getBoundingClientRect();
const clientX = touch ? e.touches[0].clientX : e.clientX;
const clientY = touch ? e.touches[0].clientY : e.clientY;

if (clientX < rect.left || clientX > rect.right || 
clientY < rect.top || clientY > rect.bottom) {
this._cache.autonomous = true;
return;
}

this._cache.autonomous = false;
this.targetX = (clientX - rect.left) / rect.width;
this.targetY = 1.0 - (clientY - rect.top) / rect.height;

clearTimeout(this.autonomousTimeout);
this.autonomousTimeout = setTimeout(() => {
this._cache.autonomous = true;
}, 2000);
};

this.mouseMoveHandler = e => updatePosition(e);
this.mouseDownHandler = e => {
const rect = this.container.getBoundingClientRect();
if (e.clientX >= rect.left && e.clientX <= rect.right && 
e.clientY >= rect.top && e.clientY <= rect.bottom) {
this.isMouseDown = true;
}
};
this.mouseUpHandler = () => this.isMouseDown = false;
this.mouseLeaveHandler = () => this._cache.autonomous = true;

this.container.addEventListener('mousemove', this.mouseMoveHandler);
this.container.addEventListener('mousedown', this.mouseDownHandler);
window.addEventListener('mouseup', this.mouseUpHandler);
this.container.addEventListener('mouseleave', this.mouseLeaveHandler);

this.touchStartHandler = e => {
this.isMouseDown = true;
updatePosition(e, true);
};

this.touchMoveHandler = e => {
if (this.isMouseDown) {
updatePosition(e, true);
}
};

this.touchEndHandler = () => {
this.isMouseDown = false;
this._cache.autonomous = true;
};

this.container.addEventListener('touchstart', this.touchStartHandler, {passive: true});
this.container.addEventListener('touchmove', this.touchMoveHandler, {passive: true});
this.container.addEventListener('touchend', this.touchEndHandler, {passive: true});
}

_updateAutonomousPosition(time) {
if (this._cache.autonomous) {
const radius = 0.3;
const speed = 0.5 * this.config.speed;
this.targetX = 0.5 + Math.cos(time * speed) * radius;
this.targetY = 0.5 + Math.sin(time * speed * 1.5) * radius;
}

this.lastX = this.mouseX;
this.lastY = this.mouseY;

this.mouseX += (this.targetX - this.mouseX) * this.transitionSpeed;
this.mouseY += (this.targetY - this.mouseY) * this.transitionSpeed;
}

_resize() {
const width = this.canvas.clientWidth;
const height = this.canvas.clientHeight;

if (this.canvas.width !== width || this.canvas.height !== height) {
this.canvas.width = width;
this.canvas.height = height;
this.gl.viewport(0, 0, width, height);
}
}

_animate(timestamp = 0) {
if (timestamp - this._lastFrameTime < this._frameInterval) {
this.animationFrame = requestAnimationFrame(this._animate.bind(this));
return;
}

this._lastFrameTime = timestamp;
this._resize();

const time = (Date.now() - this.startTime) * 0.001 * this.config.speed;

this._updateAutonomousPosition(time);

this.gl.enable(this.gl.BLEND);
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);

this.gl.uniform2f(this.uniformLocations.resolution, this.canvas.width, this.canvas.height);
this.gl.uniform2f(this.uniformLocations.mouse, this.mouseX, this.mouseY);
this.gl.uniform2f(this.uniformLocations.lastMouse, this.lastX, this.lastY);
this.gl.uniform1f(this.uniformLocations.time, time);
this.gl.uniform1f(this.uniformLocations.isMouseDown, this.isMouseDown ? 1.0 : 0.0);

this.gl.uniform3fv(this.uniformLocations.color1, this.config.colors[0]);
this.gl.uniform3fv(this.uniformLocations.color2, this.config.colors[1]);
this.gl.uniform3fv(this.uniformLocations.color3, this.config.colors[2]);

this.gl.uniform1f(this.uniformLocations.intensity, this.config.intensity);
this.gl.uniform1f(this.uniformLocations.glow, this.config.glow);
this.gl.uniform1f(this.uniformLocations.electric, this.config.electric);
this.gl.uniform1f(this.uniformLocations.radius, this.config.radius);
this.gl.uniform1f(this.uniformLocations.pulseSpeed, this.config.pulseSpeed);

this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);

this.animationFrame = requestAnimationFrame(this._animate.bind(this));
}

destroy() {
if (this.animationFrame) {
cancelAnimationFrame(this.animationFrame);
}

if (this.autonomousTimeout) {
clearTimeout(this.autonomousTimeout);
}

window.removeEventListener('resize', this.resizeHandler);

this.container.removeEventListener('mousemove', this.mouseMoveHandler);
this.container.removeEventListener('mousedown', this.mouseDownHandler);
window.removeEventListener('mouseup', this.mouseUpHandler);
this.container.removeEventListener('mouseleave', this.mouseLeaveHandler);

this.container.removeEventListener('touchstart', this.touchStartHandler);
this.container.removeEventListener('touchmove', this.touchMoveHandler);
this.container.removeEventListener('touchend', this.touchEndHandler);

if (this.gl) {
this.gl.deleteProgram(this.program);
const ext = this.gl.getExtension('WEBGL_lose_context');
if (ext) ext.loseContext();
}

if (this.wrapper && this.wrapper.parentNode) {
this.wrapper.parentNode.removeChild(this.wrapper);
}
}
}

document.addEventListener('DOMContentLoaded', () => {
const fluidElements = new Map();

document.querySelectorAll('[data-aura-flow]').forEach(element => {
const animation = new FluidAnimation(element);
fluidElements.set(element, animation);
});

const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.nodeType === 1 && node.matches('[data-aura-flow]:not([data-aura-flow-initialized])')) {
const animation = new FluidAnimation(node);
fluidElements.set(node, animation);
node.dataset.auraFlowInitialized = 'true';
}
});

mutation.removedNodes.forEach(node => {
if (node.nodeType === 1 && fluidElements.has(node)) {
const animation = fluidElements.get(node);
animation.destroy();
fluidElements.delete(node);
}
});
});
});

observer.observe(document.body, {
childList: true,
subtree: true
});

document.addEventListener('bricks-lazy-load', () => {
document.querySelectorAll('[data-aura-flow]:not([data-aura-flow-initialized])').forEach(element => {
const animation = new FluidAnimation(element);
fluidElements.set(element, animation);
element.dataset.auraFlowInitialized = 'true';
});
});
});
})();`;
            }

            function generateFullSectionJSON() {
                // Function to generate unique 6-character IDs
    function generateUniqueId() {
        const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
        let result = '';
        for (let i = 0; i < 6; i++) {
            result += chars.charAt(Math.floor(Math.random() * chars.length));
        }
        return result;
    }

                // Generate unique IDs for each element
    const sectionId = generateUniqueId();
    const containerId = generateUniqueId();
    const codeId = generateUniqueId();
    const attributeId = generateUniqueId();

                // Only include basic data-aura-flow attribute
    const dataAttributes = [
        { "id": attributeId, "name": "data-aura-flow" }
    ];

                // Get generated JavaScript code
    const rawJsCode = generateJavaScriptCode();
    
                // JSON.stringify will automatically handle correct escaping
    const jsCode = rawJsCode;

                // Create complete Bricks Builder JSON structure
    const bricksJson = {
        "content": [
            {
                "id": sectionId,
                "name": "section",
                "parent": 0,
                "children": [containerId, codeId],
                "settings": {
                    "_height": "500",
                    "_justifyContent": "center",
                    "_background": {
                        "color": {
                            "hex": "#000000"
                        }
                    },
                    "_attributes": dataAttributes
                },
                "label": "Aura Flow Section"
            },
            {
                "id": containerId,
                "name": "container",
                "parent": sectionId,
                "children": [],
                "settings": {},
                "label": ""
            },
            {
                "id": codeId,
                "name": "code",
                "parent": sectionId,
                "children": [],
                "settings": {
                    "javascriptCode": jsCode,
                    "executeCode": true,
                    "_display": "none"
                },
                "label": "Aura Flow JS"
            }
        ],
        "source": "bricksCopiedElements",
        "sourceUrl": "https://bricksfusion.com/configurator/aura-flow",
        "version": "2.0.1",
        "globalClasses": [],
        "globalElements": []
    };

                // Return formatted JSON
    return JSON.stringify(bricksJson, null, 2);
}

            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 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 `hsl(${Math.round(h * 360)}, ${Math.round(s * 100)}%, ${Math.round(l * 100)}%)`;
            }

            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 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 'opacity':
                            fluidConfig.opacity = defaultValue;
                            break;
                        case 'intensity':
                            fluidConfig.intensity = defaultValue;
                            break;
                        case 'glow':
                            fluidConfig.glow = defaultValue;
                            break;
                        case 'electric':
                            fluidConfig.electric = defaultValue;
                            break;
                        case 'radius':
                            fluidConfig.radius = defaultValue;
                            break;
                        case 'speed':
                            fluidConfig.speed = defaultValue;
                            break;
                        case 'pulse-speed':
                            fluidConfig.pulseSpeed = defaultValue;
                            break;
                        case 'transition':
                            fluidConfig.transition = defaultValue;
                            break;
                    }
                    
                    initFluidAnimation();
                    showNotification(`${parameterId.replace(/-/g, ' ')} reset to default`);
                }
            };

            function generateRandomAuraFlow() {
                const randomColors = Array.from({ length: 3 }, () => generateRandomColor());
                
                fluidConfig.colors = randomColors;
                updateColorInputs();
                initFluidAnimation();
                showNotification('Random aura flow generated!');
            }

            function updateColorInputs() {
                for (let i = 1; i <= 3; i++) {
                    const color = fluidConfig.colors[i - 1];
                    const colorInput = document.getElementById(`color${i}`);
                    const hexInput = document.getElementById(`color${i}-hex`);
                    const hslInput = document.getElementById(`color${i}-hsl`);
                    
                    if (colorInput && hexInput && hslInput) {
                        colorInput.value = color;
                        hexInput.value = color;
                        hslInput.value = hexToHsl(color);
                        
                        // Update color picker container background
                        const container = colorInput.closest('.color-picker-container');
                        if (container) {
                            container.style.setProperty('--current-color', color);
                        }
                        
                        hexInput.classList.remove('invalid');
                        hslInput.classList.remove('invalid');
                    }
                }
            }

            function initializeUI() {
                initFluidAnimation();
                
                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-aura-flow');
                });

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

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

                document.getElementById('randomize-aura-flow').addEventListener('click', () => {
                    generateRandomAuraFlow();
                });

                // Background selector for preview
                const backgroundPicker = document.getElementById('preview-background-picker');
                const previewContainer = document.getElementById('aura-flow-preview');

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

                // Set initial background color
                previewContainer.style.backgroundColor = '#000000';

                document.getElementById('reset-colors').addEventListener('click', () => {
                    fluidConfig.colors = [...defaultConfig.colors];
                    updateColorInputs();
                    initFluidAnimation();
                    showNotification('Colors reset to default');
                });

                document.getElementById('reset-effects').addEventListener('click', () => {
                    fluidConfig.intensity = defaultConfig.intensity;
                    fluidConfig.glow = defaultConfig.glow;
                    fluidConfig.electric = defaultConfig.electric;
                    fluidConfig.radius = defaultConfig.radius;
                    
                    document.getElementById('intensity').value = defaultConfig.intensity;
                    document.getElementById('glow').value = defaultConfig.glow;
                    document.getElementById('electric').value = defaultConfig.electric;
                    document.getElementById('radius').value = defaultConfig.radius;
                    
                    document.getElementById('intensity-value').textContent = defaultConfig.intensity;
                    document.getElementById('glow-value').textContent = defaultConfig.glow;
                    document.getElementById('electric-value').textContent = defaultConfig.electric;
                    document.getElementById('radius-value').textContent = defaultConfig.radius;
                    
                    initFluidAnimation();
                    showNotification('Effect settings reset');
                });

                document.getElementById('reset-animation').addEventListener('click', () => {
                    fluidConfig.speed = defaultConfig.speed;
                    fluidConfig.pulseSpeed = defaultConfig.pulseSpeed;
                    fluidConfig.transition = defaultConfig.transition;
                    
                    document.getElementById('speed').value = defaultConfig.speed;
                    document.getElementById('pulse-speed').value = defaultConfig.pulseSpeed;
                    document.getElementById('transition').value = defaultConfig.transition;
                    
                    document.getElementById('speed-value').textContent = defaultConfig.speed;
                    document.getElementById('pulse-speed-value').textContent = defaultConfig.pulseSpeed;
                    document.getElementById('transition-value').textContent = defaultConfig.transition;
                    
                    initFluidAnimation();
                    showNotification('Animation settings reset');
                });

                document.getElementById('reset-advanced').addEventListener('click', () => {
                    fluidConfig.autoMovement = defaultConfig.autoMovement;
                    fluidConfig.performanceMode = defaultConfig.performanceMode;
                    
                    document.getElementById('auto-movement').checked = defaultConfig.autoMovement;
                    document.getElementById('performance-mode').checked = defaultConfig.performanceMode;
                    
                    initFluidAnimation();
                    showNotification('Advanced settings reset');
                });

                const colorInputs = document.querySelectorAll('input[type="color"]');
                colorInputs.forEach((input, index) => {
                    const colorIndex = index + 1;
                    const hexInput = document.getElementById(`color${colorIndex}-hex`);
                    const hslInput = document.getElementById(`color${colorIndex}-hsl`);
                    
                    hslInput.value = hexToHsl(input.value);
                    
                    // Initialize color picker container background
                    const container = input.closest('.color-picker-container');
                    if (container) {
                        container.style.setProperty('--current-color', input.value);
                    }
                    
                    input.addEventListener('input', () => {
                        const color = input.value;
                        hexInput.value = color;
                        hslInput.value = hexToHsl(color);
                        hexInput.classList.remove('invalid');
                        hslInput.classList.remove('invalid');
                        
                        // Update color picker container background
                        const container = input.closest('.color-picker-container');
                        if (container) {
                            container.style.setProperty('--current-color', color);
                        }
                        
                        fluidConfig.colors[index] = color;
                        initFluidAnimation();
                    });
                    
                    hexInput.addEventListener('input', (e) => {
                        let hex = e.target.value;
                        
                        hex = formatHex(hex);
                        e.target.value = hex;
                        
                        if (isValidHex(hex)) {
                            input.value = hex;
                            hslInput.value = hexToHsl(hex);
                            
                            // Update color picker container background
                            const container = input.closest('.color-picker-container');
                            if (container) {
                                container.style.setProperty('--current-color', hex);
                            }
                            
                            fluidConfig.colors[index] = hex;
                            e.target.classList.remove('invalid');
                            hslInput.classList.remove('invalid');
                            initFluidAnimation();
                        } else {
                            e.target.classList.add('invalid');
                        }
                    });
                    
                    hexInput.addEventListener('blur', (e) => {
                        if (!isValidHex(e.target.value)) {
                            e.target.value = input.value;
                            e.target.classList.remove('invalid');
                        }
                    });
                    
                    hslInput.addEventListener('input', (e) => {
                        let hsl = e.target.value;
                        
                        if (isValidHsl(hsl)) {
                            const hex = hslToHex(hsl);
                            if (hex) {
                                input.value = hex;
                                hexInput.value = hex;
                                
                                // Update color picker container background
                                const container = input.closest('.color-picker-container');
                                if (container) {
                                    container.style.setProperty('--current-color', hex);
                                }
                                
                                fluidConfig.colors[index] = hex;
                                e.target.classList.remove('invalid');
                                hexInput.classList.remove('invalid');
                                initFluidAnimation();
                                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) {
                                    input.value = hex;
                                    hexInput.value = hex;
                                    fluidConfig.colors[index] = hex;
                                    e.target.classList.remove('invalid');
                                    hexInput.classList.remove('invalid');
                                    initFluidAnimation();
                                    return;
                                }
                            }
                        }
                        
                        if (!isValidHsl(e.target.value)) {
                            e.target.value = hexToHsl(input.value);
                            e.target.classList.remove('invalid');
                        }
                    });
                });

                const rangeInputs = document.querySelectorAll('input[type="range"]');
                rangeInputs.forEach(input => {
                    let valueElement;
                    
                    switch (input.id) {
                        case 'pulse-speed':
                            valueElement = document.getElementById('pulse-speed-value');
                            break;
                        default:
                            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 'opacity':
                                fluidConfig.opacity = parseFloat(input.value);
                                break;
                            case 'intensity':
                                fluidConfig.intensity = parseFloat(input.value);
                                break;
                            case 'glow':
                                fluidConfig.glow = parseFloat(input.value);
                                break;
                            case 'electric':
                                fluidConfig.electric = parseFloat(input.value);
                                break;
                            case 'radius':
                                fluidConfig.radius = parseFloat(input.value);
                                break;
                            case 'speed':
                                fluidConfig.speed = parseFloat(input.value);
                                break;
                            case 'pulse-speed':
                                fluidConfig.pulseSpeed = parseFloat(input.value);
                                break;
                            case 'transition':
                                fluidConfig.transition = parseFloat(input.value);
                                break;
                        }
                        
                        initFluidAnimation();
                    });
                });

                document.getElementById('auto-movement').addEventListener('change', function() {
                    fluidConfig.autoMovement = this.checked;
                    initFluidAnimation();
                });
                
                document.getElementById('performance-mode').addEventListener('change', function() {
                    fluidConfig.performanceMode = this.checked;
                    initFluidAnimation();
                });

                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':
                                generateRandomAuraFlow();
                                break;
                            case 'b':
                                document.getElementById('preview-background-picker').click();
                                break;
                        }
                    }
                });

                updateColorInputs();
                
                setTimeout(() => {
                    showNotification('BricksFusion Aura Flow Configurator loaded!');
                }, 500);

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

                function loadConfiguration() {
                    try {
                        const saved = localStorage.getItem('bricksfusion-aura-flow-config');
                        if (saved) {
                            const savedConfig = JSON.parse(saved);
                            Object.assign(fluidConfig, savedConfig);
                            
                            savedConfig.colors.forEach((color, index) => {
                                document.getElementById(`color${index + 1}`).value = color;
                                document.getElementById(`color${index + 1}-hex`).value = color;
                                document.getElementById(`color${index + 1}-hsl`).value = hexToHsl(color);
                            });
                            
                            document.getElementById('opacity').value = savedConfig.opacity;
                            document.getElementById('intensity').value = savedConfig.intensity;
                            document.getElementById('glow').value = savedConfig.glow;
                            document.getElementById('electric').value = savedConfig.electric;
                            document.getElementById('radius').value = savedConfig.radius;
                            document.getElementById('speed').value = savedConfig.speed;
                            document.getElementById('pulse-speed').value = savedConfig.pulseSpeed;
                            document.getElementById('transition').value = savedConfig.transition;
                            document.getElementById('auto-movement').checked = savedConfig.autoMovement;
                            document.getElementById('performance-mode').checked = savedConfig.performanceMode;
                            
                            document.getElementById('opacity-value').textContent = savedConfig.opacity;
                            document.getElementById('intensity-value').textContent = savedConfig.intensity;
                            document.getElementById('glow-value').textContent = savedConfig.glow;
                            document.getElementById('electric-value').textContent = savedConfig.electric;
                            document.getElementById('radius-value').textContent = savedConfig.radius;
                            document.getElementById('speed-value').textContent = savedConfig.speed;
                            document.getElementById('pulse-speed-value').textContent = savedConfig.pulseSpeed;
                            document.getElementById('transition-value').textContent = savedConfig.transition;
                            
                            initFluidAnimation();
                        }
                    } catch (e) {
                    }
                }

                const originalInitFluidAnimation = initFluidAnimation;
                initFluidAnimation = function() {
                    originalInitFluidAnimation();
                    saveConfiguration();
                };

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

Aura Flow

Creates a fluid, glowing energy effect that follows your mouse with electric trails and pulsing light. Perfect for premium hero sections and interactive showcases.

Move your mouse here

Colors

Color 1, 2, 3 color picker

Choose 3 colors that will blend together in the fluid animation. The colors mix and flow creating an aurora-like effect.

Default: Blue, Cyan, Light Blue

Appearance

Opacity 0.0-1.0

How transparent the entire effect is. 1.0 is fully visible, 0.5 is half transparent, 0.0 is invisible.

Default: 0.9

Intensity 0.5-3.0

How bright and strong the colors appear. Higher values make it more vibrant and glowing.

Default: 1.0

Glow 0.3-2.0

Size of the glowing halo around the mouse cursor. Larger values create a bigger, softer glow.

Default: 0.8

Electric Effect 0.0-3.0

Strength of the lightning-like trails that follow the mouse when you move it. Higher = more intense electric effect.

Default: 1.2

Animation

Speed 0.3-3.0

Overall animation speed. Affects how fast the fluid moves and swirls. Lower = slower and calmer.

Default: 1.0

Pulse Speed 2.0-15.0

How fast the light pulses and breathes. Higher values create faster, more energetic pulsing.

Default: 8.0

Mouse Smoothness 0.01-0.3

How smoothly the effect follows your mouse. Lower = smoother and laggier, higher = snappier and more responsive.

Default: 0.08

Advanced

Radius 50-300

Size of the main fluid area. Larger values spread the effect across a bigger area.

Default: 100

Performance

This element uses WebGL for advanced graphics rendering, making it resource-intensive. Use it sparingly on a page - ideally just one instance per page. It may affect performance on older devices or computers. The effect automatically adjusts to 30fps on mobile devices to save battery.