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>Plasma 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);
            will-change: contents;
        }

        .preview-container canvas {
            will-change: contents;
            transform: translateZ(0);
            backface-visibility: hidden;
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

        .card-content {
            padding: 1.5rem;
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        @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">Plasma Flow</span>
        </nav>
        
        <div class="action-buttons">
            <div class="data-attribute-display" id="quick-attribute" title="Click to copy data attribute">
                data-plasma-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">Plasma Flow</h1>
            <p class="page-subtitle">Interactive WebGL effects 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 plasma flow effect 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 container: go to <strong>Section → Style → Attributes</strong>, add <code>data-plasma-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="plasma-preview" data-plasma-flow="true">
                    <div class="preview-content">Interactive Plasma Flow Preview</div>
                    <div class="preview-controls">
                        <button class="preview-btn" id="randomize-plasma" 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="#252525" title="Change Preview Background (B)">
                        </div>
                    </div>
                </div>
            </section>

            <section class="controls-section">
                <div class="card">
                    <div class="card-heading">
                        Line Color
                        <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="line-color" value="#6633cc">
                                </div>
                                <div class="color-input-group">
                                    <span class="color-label">HEX</span>
                                    <input type="text" class="color-input hex-input" id="line-color-hex" value="#6633cc" placeholder="#FFFFFF">
                                </div>
                                <div class="color-input-group">
                                    <span class="color-label">HSL</span>
                                    <input type="text" class="color-input hsl-input" id="line-color-hsl" placeholder="hsl(0, 100%, 50%)">
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-heading">
                        Flow Settings
                        <div class="card-actions">
                            <button class="card-action-btn" id="reset-flow" title="Reset Flow Settings">↺</button>
                        </div>
                    </div>
                    <div class="card-content">
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Animation Speed
                                    <span class="help-tooltip" title="Speed of the plasma flow animation">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="animation-speed-value">0.5</span></span>
                                    <button class="reset-btn" onclick="resetParameter('animation-speed', 0.5)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="animation-speed" min="0.1" max="2.0" step="0.1" value="0.5">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Intensity
                                    <span class="help-tooltip" title="Overall intensity of the plasma effect">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="intensity-value">1.0</span></span>
                                    <button class="reset-btn" onclick="resetParameter('intensity', 1.0)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="intensity" min="0.1" max="3.0" step="0.1" value="1.0">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Line Width
                                    <span class="help-tooltip" title="Thickness of the plasma lines">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="line-width-value">1.0</span></span>
                                    <button class="reset-btn" onclick="resetParameter('line-width', 1.0)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="line-width" min="0.2" max="3.0" step="0.1" value="1.0">
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-heading">
                        Advanced Options
                        <div class="card-actions">
                            <button class="card-action-btn" id="reset-advanced" title="Reset Advanced Settings">↺</button>
                        </div>
                    </div>
                    <div class="card-content">
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">Blend Mode</span>
                            </div>
                            <select id="blend-mode">
                                <option value="normal">Normal</option>
                                <option value="multiply">Multiply</option>
                                <option value="screen">Screen</option>
                                <option value="overlay">Overlay</option>
                                <option value="soft-light">Soft Light</option>
                                <option value="hard-light">Hard Light</option>
                                <option value="color-dodge">Color Dodge</option>
                                <option value="color-burn">Color Burn</option>
                                <option value="difference">Difference</option>
                                <option value="exclusion">Exclusion</option>
                            </select>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </div>

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

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            let plasmaFlowConfig = {
                speed: 0.5,
                intensity: 1.0,
                lineWidth: 1.0,
                lineColor: "#6633cc",
                blendMode: "normal"
            };

            const defaultConfig = { ...plasmaFlowConfig };

            let previewInstance = null;
            
            function hexToHsl(hex) {
                const r = parseInt(hex.slice(1, 3), 16) / 255;
                const g = parseInt(hex.slice(3, 5), 16) / 255;
                const b = parseInt(hex.slice(5, 7), 16) / 255;
                
                const max = Math.max(r, g, b);
                const min = Math.min(r, g, b);
                let h, s, l = (max + min) / 2;
                
                if (max === min) {
                    h = s = 0;
                } else {
                    const d = max - min;
                    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
                    switch (max) {
                        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
                        case g: h = (b - r) / d + 2; break;
                        case b: h = (r - g) / d + 4; break;
                    }
                    h /= 6;
                }
                
                return {
                    h: Math.round(h * 360),
                    s: Math.round(s * 100),
                    l: Math.round(l * 100)
                };
            }

            function hslToHex(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 hexToRgb(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;
                return [r, g, b];
            }
            
            class PlasmaFlow {
                constructor(container, options = {}) {
                    this.container = container;
                    this.canvas = document.createElement('canvas');
                    this.gl = null;
                    this.program = null;
                    this.animationId = null;
                    this.startTime = Date.now();
                    this.isDestroyed = false;
                    
                    this.config = {
                        speed: options.speed || 0.5,
                        intensity: options.intensity || 1.0,
                        lineWidth: options.lineWidth || 1.0,
                        lineColor: options.lineColor || "#6633cc",
                        blendMode: options.blendMode || "normal"
                    };
                    
                    this.init();
                }
                
                init() {
                    this.setupCanvas();
                    this.initWebGL();
                    this.animate();
                }
                
                setupCanvas() {
                    this.canvas.style.position = 'absolute';
                    this.canvas.style.top = '0';
                    this.canvas.style.left = '0';
                    this.canvas.style.width = '100%';
                    this.canvas.style.height = '100%';
                    this.canvas.style.pointerEvents = 'none';
                    this.canvas.style.zIndex = '1';
                    this.canvas.style.mixBlendMode = this.config.blendMode;
                    
                    this.container.style.position = this.container.style.position || 'relative';
                    this.container.appendChild(this.canvas);
                    
                    this.resizeCanvas();
                }
                
                resizeCanvas() {
                    const rect = this.container.getBoundingClientRect();
                    const width = rect.width;
                    const height = rect.height;
                    
                    const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || window.innerWidth <= 768;
                    const baseDpr = window.devicePixelRatio || 1;
                    const dpr = isMobile ? baseDpr * 0.7 : baseDpr;
                    
                    this.canvas.width = width * dpr;
                    this.canvas.height = height * dpr;
                    this.canvas.style.width = width + 'px';
                    this.canvas.style.height = height + 'px';
                    
                    if (this.gl) {
                        this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
                    }
                }
                
                initWebGL() {
                    this.gl = this.canvas.getContext('webgl', { 
                        alpha: true, 
                        premultipliedAlpha: false,
                        antialias: true 
                    });
                    
                    if (!this.gl) {
                        return;
                    }
                    
                    this.gl.enable(this.gl.BLEND);
                    this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
                    
                    const vsSource = `
                        attribute vec4 aVertexPosition;
                        void main() {
                            gl_Position = aVertexPosition;
                        }
                    `;
                    
                    const fsSource = `
                        precision highp float;
                        uniform vec2 iResolution;
                        uniform float iTime;
                        uniform float iSpeed;
                        uniform float iIntensity;
                        uniform vec3 iLineColor;
                        uniform float iLineWidth;

                        const float gridSmoothWidth = 0.015;
                        const float scale = 5.0;
                        const float lineAmplitude = 1.0;
                        const float lineFrequency = 0.2;
                        const float warpFrequency = 0.5;
                        const float warpAmplitude = 1.0;
                        const float offsetFrequency = 0.5;
                        const float minOffsetSpread = 0.6;
                        const float maxOffsetSpread = 2.0;
                        const int linesPerGroup = 16;

                        float drawCircle(vec2 pos, float radius, vec2 coord) {
                            return smoothstep(radius + gridSmoothWidth, radius, length(coord - pos));
                        }

                        float drawSmoothLine(float pos, float halfWidth, float t) {
                            return smoothstep(halfWidth, 0.0, abs(pos - t));
                        }

                        float drawCrispLine(float pos, float halfWidth, float t) {
                            return smoothstep(halfWidth + gridSmoothWidth, halfWidth, abs(pos - t));
                        }

                        float random(float t) {
                            return (cos(t) + cos(t * 1.3 + 1.3) + cos(t * 1.4 + 1.4)) / 3.0;
                        }

                        float getPlasmaY(float x, float horizontalFade, float offset, float speed) {
                            return random(x * lineFrequency + iTime * speed) * horizontalFade * lineAmplitude + offset;
                        }

                        void main() {
                            vec2 fragCoord = gl_FragCoord.xy;
                            vec2 uv = fragCoord.xy / iResolution.xy;
                            vec2 space = (fragCoord - iResolution.xy / 2.0) / iResolution.x * 2.0 * scale;

                            float horizontalFade = 1.0 - (cos(uv.x * 6.28) * 0.5 + 0.5);
                            float verticalFade = 1.0 - (cos(uv.y * 6.28) * 0.5 + 0.5);

                            float warpSpeed = 0.2 * iSpeed;
                            space.y += random(space.x * warpFrequency + iTime * warpSpeed) * warpAmplitude * (0.5 + horizontalFade);
                            space.x += random(space.y * warpFrequency + iTime * warpSpeed + 2.0) * warpAmplitude * horizontalFade;

                            vec4 lines = vec4(0.0);
                            vec4 lineColor = vec4(iLineColor, 1.0);

                            for(int l = 0; l < linesPerGroup; l++) {
                                float normalizedLineIndex = float(l) / float(linesPerGroup);
                                float offsetTime = iTime * iSpeed * 1.33;
                                float offsetPosition = float(l) + space.x * offsetFrequency;
                                float rand = random(offsetPosition + offsetTime) * 0.5 + 0.5;
                                float halfWidth = mix(0.01 * iLineWidth, 0.2 * iLineWidth, rand * horizontalFade) / 2.0;
                                float offset = random(offsetPosition + offsetTime * (1.0 + normalizedLineIndex)) * mix(minOffsetSpread, maxOffsetSpread, horizontalFade);
                                float linePosition = getPlasmaY(space.x, horizontalFade, offset, iSpeed);
                                float line = drawSmoothLine(linePosition, halfWidth, space.y) / 2.0 + drawCrispLine(linePosition, halfWidth * 0.15, space.y);

                                float circleX = mod(float(l) + iTime * iSpeed, 25.0) - 12.0;
                                vec2 circlePosition = vec2(circleX, getPlasmaY(circleX, horizontalFade, offset, iSpeed));
                                float circle = drawCircle(circlePosition, 0.01, space) * 4.0;

                                line = line + circle;
                                lines += line * lineColor * rand * iIntensity;
                            }

                            vec4 fragColor = lines;
                            fragColor.a = lines.r * verticalFade;

                            gl_FragColor = fragColor;
                        }
                    `;
                    
                    this.program = this.createShaderProgram(vsSource, fsSource);
                    if (!this.program) return;
                    
                    const positionBuffer = this.gl.createBuffer();
                    this.gl.bindBuffer(this.gl.ARRAY_BUFFER, positionBuffer);
                    const positions = [-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0];
                    this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(positions), this.gl.STATIC_DRAW);
                    
                    this.programInfo = {
                        attribLocations: {
                            vertexPosition: this.gl.getAttribLocation(this.program, 'aVertexPosition'),
                        },
                        uniformLocations: {
                            resolution: this.gl.getUniformLocation(this.program, 'iResolution'),
                            time: this.gl.getUniformLocation(this.program, 'iTime'),
                            speed: this.gl.getUniformLocation(this.program, 'iSpeed'),
                            intensity: this.gl.getUniformLocation(this.program, 'iIntensity'),
                            lineColor: this.gl.getUniformLocation(this.program, 'iLineColor'),
                            lineWidth: this.gl.getUniformLocation(this.program, 'iLineWidth')
                        }
                    };
                    
                    this.positionBuffer = positionBuffer;
                }
                
                createShaderProgram(vsSource, fsSource) {
                    const vertexShader = this.loadShader(this.gl.VERTEX_SHADER, vsSource);
                    const fragmentShader = this.loadShader(this.gl.FRAGMENT_SHADER, fsSource);
                    
                    if (!vertexShader || !fragmentShader) return null;
                    
                    const shaderProgram = this.gl.createProgram();
                    this.gl.attachShader(shaderProgram, vertexShader);
                    this.gl.attachShader(shaderProgram, fragmentShader);
                    this.gl.linkProgram(shaderProgram);
                    
                    if (!this.gl.getProgramParameter(shaderProgram, this.gl.LINK_STATUS)) {
                        return null;
                    }
                    
                    return shaderProgram;
                }
                
                loadShader(type, source) {
                    const shader = this.gl.createShader(type);
                    this.gl.shaderSource(shader, source);
                    this.gl.compileShader(shader);
                    
                    if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
                        this.gl.deleteShader(shader);
                        return null;
                    }
                    return shader;
                }
                
                updateOptions(options) {
                    Object.assign(this.config, options);
                    if (options.blendMode && this.canvas) {
                        this.canvas.style.mixBlendMode = options.blendMode;
                    }
                }
                
                animate() {
                    if (this.isDestroyed || !this.gl || !this.program) return;
                    
                    const currentTime = (Date.now() - this.startTime) / 1000;
                    
                    this.gl.clearColor(0.0, 0.0, 0.0, 0.0);
                    this.gl.clear(this.gl.COLOR_BUFFER_BIT);
                    
                    this.gl.useProgram(this.program);
                    
                    const lineColorRgb = hexToRgb(this.config.lineColor);
                    
                    this.gl.uniform2f(this.programInfo.uniformLocations.resolution, this.canvas.width, this.canvas.height);
                    this.gl.uniform1f(this.programInfo.uniformLocations.time, currentTime);
                    this.gl.uniform1f(this.programInfo.uniformLocations.speed, this.config.speed);
                    this.gl.uniform1f(this.programInfo.uniformLocations.intensity, this.config.intensity);
                    this.gl.uniform3f(this.programInfo.uniformLocations.lineColor, ...lineColorRgb);
                    this.gl.uniform1f(this.programInfo.uniformLocations.lineWidth, this.config.lineWidth);
                    
                    this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
                    this.gl.vertexAttribPointer(this.programInfo.attribLocations.vertexPosition, 2, this.gl.FLOAT, false, 0, 0);
                    this.gl.enableVertexAttribArray(this.programInfo.attribLocations.vertexPosition);
                    
                    this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
                    
                    this.animationId = requestAnimationFrame(() => this.animate());
                }
                
                destroy() {
                    this.isDestroyed = true;
                    
                    if (this.animationId) {
                        cancelAnimationFrame(this.animationId);
                    }
                    
                    if (this.canvas && this.canvas.parentNode) {
                        this.canvas.parentNode.removeChild(this.canvas);
                    }
                    
                    this.gl = null;
                    this.program = null;
                }
            }
            
            function initializePreview() {
                const container = document.getElementById('plasma-preview');
                if (previewInstance) {
                    previewInstance.destroy();
                }
                
                previewInstance = new PlasmaFlow(container, plasmaFlowConfig);
            }
            
            function updatePreview() {
                plasmaFlowConfig.speed = parseFloat(document.getElementById('animation-speed').value);
                plasmaFlowConfig.intensity = parseFloat(document.getElementById('intensity').value);
                plasmaFlowConfig.lineWidth = parseFloat(document.getElementById('line-width').value);
                plasmaFlowConfig.blendMode = document.getElementById('blend-mode').value;
                
                if (previewInstance) {
                    previewInstance.updateOptions(plasmaFlowConfig);
                }
                
                saveConfiguration();
            }

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

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

            function generateFullSectionJSON() {
  // Generar IDs únicos
  const sectionId = generateUniqueId();
  const containerId = generateUniqueId();
  const codeId = generateUniqueId();
  const attributeId = generateUniqueId();
  
  // Obtener el código JavaScript generado
  const jsCode = generateJavaScriptCode();
  
  // Crear la estructura JSON completa
  const fullSectionData = {
    "content": [
      {
        "id": sectionId,
        "name": "section",
        "parent": 0,
        "children": [containerId, codeId],
        "settings": {
          "_attributes": [
            {
              "id": attributeId,
              "name": "data-plasma-flow"
            }
          ],
          "_height": "500",
          "_justifyContent": "center",
          "_background": {
            "color": {
              "hex": "#000000"
            }
          }
        },
        "label": "Plasma Section"
      },
      {
        "id": containerId,
        "name": "container",
        "parent": sectionId,
        "children": [],
        "settings": {}
      },
      {
        "id": codeId,
        "name": "code",
        "parent": sectionId,
        "children": [],
        "settings": {
          "javascriptCode": jsCode,
          "executeCode": true,
          "_display": "none"
        },
        "label": "Plasma JS"
      }
    ],
    "source": "bricksCopiedElements",
    "sourceUrl": "https://bricksfusion.com",
    "version": "2.0.1",
    "globalClasses": [],
    "globalElements": []
  };
  
  return JSON.stringify(fullSectionData, null, 2);
}

            function generateJavaScriptCode() {
                return "(function() {\n" +
                "  'use strict';\n" +
                "  \n" +
                "  window.PlasmaFlowAnimation = window.PlasmaFlowAnimation || {};\n" +
                "  \n" +
                "  const PlasmaFlow = {\n" +
                "    instances: new Map(),\n" +
                "    \n" +
                "    vsSource: `\n" +
                "      attribute vec4 aVertexPosition;\n" +
                "      void main() {\n" +
                "        gl_Position = aVertexPosition;\n" +
                "      }\n" +
                "    `,\n" +
                "    \n" +
                "    fsSource: `\n" +
                "      precision highp float;\n" +
                "      uniform vec2 iResolution;\n" +
                "      uniform float iTime;\n" +
                "      uniform float iSpeed;\n" +
                "      uniform float iIntensity;\n" +
                "      uniform vec3 iLineColor;\n" +
                "      uniform float iLineWidth;\n" +
                "      \n" +
                "      const float gridSmoothWidth = 0.015;\n" +
                "      const float scale = 5.0;\n" +
                "      const float lineAmplitude = 1.0;\n" +
                "      const float lineFrequency = 0.2;\n" +
                "      const float warpFrequency = 0.5;\n" +
                "      const float warpAmplitude = 1.0;\n" +
                "      const float offsetFrequency = 0.5;\n" +
                "      const float minOffsetSpread = 0.6;\n" +
                "      const float maxOffsetSpread = 2.0;\n" +
                "      const int linesPerGroup = 16;\n" +
                "      \n" +
                "      float drawCircle(vec2 pos, float radius, vec2 coord) {\n" +
                "        return smoothstep(radius + gridSmoothWidth, radius, length(coord - pos));\n" +
                "      }\n" +
                "      \n" +
                "      float drawSmoothLine(float pos, float halfWidth, float t) {\n" +
                "        return smoothstep(halfWidth, 0.0, abs(pos - t));\n" +
                "      }\n" +
                "      \n" +
                "      float drawCrispLine(float pos, float halfWidth, float t) {\n" +
                "        return smoothstep(halfWidth + gridSmoothWidth, halfWidth, abs(pos - t));\n" +
                "      }\n" +
                "      \n" +
                "      float random(float t) {\n" +
                "        return (cos(t) + cos(t * 1.3 + 1.3) + cos(t * 1.4 + 1.4)) / 3.0;\n" +
                "      }\n" +
                "      \n" +
                "      float getPlasmaY(float x, float horizontalFade, float offset, float speed) {\n" +
                "        return random(x * lineFrequency + iTime * speed) * horizontalFade * lineAmplitude + offset;\n" +
                "      }\n" +
                "      \n" +
                "      void main() {\n" +
                "        vec2 fragCoord = gl_FragCoord.xy;\n" +
                "        vec2 uv = fragCoord.xy / iResolution.xy;\n" +
                "        vec2 space = (fragCoord - iResolution.xy / 2.0) / iResolution.x * 2.0 * scale;\n" +
                "        \n" +
                "        float horizontalFade = 1.0 - (cos(uv.x * 6.28) * 0.5 + 0.5);\n" +
                "        float verticalFade = 1.0 - (cos(uv.y * 6.28) * 0.5 + 0.5);\n" +
                "        \n" +
                "        float warpSpeed = 0.2 * iSpeed;\n" +
                "        space.y += random(space.x * warpFrequency + iTime * warpSpeed) * warpAmplitude * (0.5 + horizontalFade);\n" +
                "        space.x += random(space.y * warpFrequency + iTime * warpSpeed + 2.0) * warpAmplitude * horizontalFade;\n" +
                "        \n" +
                "        vec4 lines = vec4(0.0);\n" +
                "        vec4 lineColor = vec4(iLineColor, 1.0);\n" +
                "        \n" +
                "        for(int l = 0; l < linesPerGroup; l++) {\n" +
                "          float normalizedLineIndex = float(l) / float(linesPerGroup);\n" +
                "          float offsetTime = iTime * iSpeed * 1.33;\n" +
                "          float offsetPosition = float(l) + space.x * offsetFrequency;\n" +
                "          float rand = random(offsetPosition + offsetTime) * 0.5 + 0.5;\n" +
                "          float halfWidth = mix(0.01 * iLineWidth, 0.2 * iLineWidth, rand * horizontalFade) / 2.0;\n" +
                "          float offset = random(offsetPosition + offsetTime * (1.0 + normalizedLineIndex)) * mix(minOffsetSpread, maxOffsetSpread, horizontalFade);\n" +
                "          float linePosition = getPlasmaY(space.x, horizontalFade, offset, iSpeed);\n" +
                "          float line = drawSmoothLine(linePosition, halfWidth, space.y) / 2.0 + drawCrispLine(linePosition, halfWidth * 0.15, space.y);\n" +
                "          \n" +
                "          float circleX = mod(float(l) + iTime * iSpeed, 25.0) - 12.0;\n" +
                "          vec2 circlePosition = vec2(circleX, getPlasmaY(circleX, horizontalFade, offset, iSpeed));\n" +
                "          float circle = drawCircle(circlePosition, 0.01, space) * 4.0;\n" +
                "          \n" +
                "          line = line + circle;\n" +
                "          lines += line * lineColor * rand * iIntensity;\n" +
                "        }\n" +
                "        \n" +
                "        vec4 fragColor = lines;\n" +
                "        fragColor.a = lines.r * verticalFade;\n" +
                "        \n" +
                "        gl_FragColor = fragColor;\n" +
                "      }\n" +
                "    `,\n" +
                "    \n" +
                "    loadShader: function(gl, type, source) {\n" +
                "      const shader = gl.createShader(type);\n" +
                "      gl.shaderSource(shader, source);\n" +
                "      gl.compileShader(shader);\n" +
                "      \n" +
                "      if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n" +
                "        gl.deleteShader(shader);\n" +
                "        return null;\n" +
                "      }\n" +
                "      return shader;\n" +
                "    },\n" +
                "    \n" +
                "    initShaderProgram: function(gl, vsSource, fsSource) {\n" +
                "      const vertexShader = this.loadShader(gl, gl.VERTEX_SHADER, vsSource);\n" +
                "      const fragmentShader = this.loadShader(gl, gl.FRAGMENT_SHADER, fsSource);\n" +
                "      \n" +
                "      if (!vertexShader || !fragmentShader) return null;\n" +
                "      \n" +
                "      const shaderProgram = gl.createProgram();\n" +
                "      gl.attachShader(shaderProgram, vertexShader);\n" +
                "      gl.attachShader(shaderProgram, fragmentShader);\n" +
                "      gl.linkProgram(shaderProgram);\n" +
                "      \n" +
                "      if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {\n" +
                "        return null;\n" +
                "      }\n" +
                "      \n" +
                "      return shaderProgram;\n" +
                "    },\n" +
                "    \n" +
                "    parseColor: function(colorString) {\n" +
                "      if (colorString.startsWith('#')) {\n" +
                "        const r = parseInt(colorString.slice(1, 3), 16) / 255;\n" +
                "        const g = parseInt(colorString.slice(3, 5), 16) / 255;\n" +
                "        const b = parseInt(colorString.slice(5, 7), 16) / 255;\n" +
                "        return [r, g, b];\n" +
                "      }\n" +
                "      return [0.4, 0.2, 0.8];\n" +
                "    },\n" +
                "    \n" +
                "    createInstance: function(element) {\n" +
                "      if (this.instances.has(element)) {\n" +
                "        this.destroyInstance(element);\n" +
                "      }\n" +
                "      \n" +
                "      const canvas = document.createElement('canvas');\n" +
                "      canvas.style.cssText = 'position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; mix-blend-mode: " + plasmaFlowConfig.blendMode + ";';\n" +
                "      \n" +
                "      const originalPosition = getComputedStyle(element).position;\n" +
                "      if (originalPosition === 'static') {\n" +
                "        element.style.position = 'relative';\n" +
                "      }\n" +
                "      \n" +
                "      element.appendChild(canvas);\n" +
                "      \n" +
                "      const gl = canvas.getContext('webgl', {\n" +
                "        alpha: true,\n" +
                "        premultipliedAlpha: false,\n" +
                "        antialias: true\n" +
                "      });\n" +
                "      \n" +
                "      if (!gl) {\n" +
                "        canvas.remove();\n" +
                "        return;\n" +
                "      }\n" +
                "      \n" +
                "      gl.enable(gl.BLEND);\n" +
                "      gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n" +
                "      \n" +
                "      const shaderProgram = this.initShaderProgram(gl, this.vsSource, this.fsSource);\n" +
                "      if (!shaderProgram) {\n" +
                "        canvas.remove();\n" +
                "        return;\n" +
                "      }\n" +
                "      \n" +
                "      const positionBuffer = gl.createBuffer();\n" +
                "      gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n" +
                "      const positions = [-1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0];\n" +
                "      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);\n" +
                "      \n" +
                "      const programInfo = {\n" +
                "        program: shaderProgram,\n" +
                "        attribLocations: {\n" +
                "          vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),\n" +
                "        },\n" +
                "        uniformLocations: {\n" +
                "          resolution: gl.getUniformLocation(shaderProgram, 'iResolution'),\n" +
                "          time: gl.getUniformLocation(shaderProgram, 'iTime'),\n" +
                "          speed: gl.getUniformLocation(shaderProgram, 'iSpeed'),\n" +
                "          intensity: gl.getUniformLocation(shaderProgram, 'iIntensity'),\n" +
                "          lineColor: gl.getUniformLocation(shaderProgram, 'iLineColor'),\n" +
                "          lineWidth: gl.getUniformLocation(shaderProgram, 'iLineWidth')\n" +
                "        },\n" +
                "      };\n" +
                "      \n" +
                "      const instance = {\n" +
                "        element,\n" +
                "        canvas,\n" +
                "        gl,\n" +
                "        programInfo,\n" +
                "        positionBuffer,\n" +
                "        config: {\n" +
                "          speed: " + plasmaFlowConfig.speed + ",\n" +
                "          intensity: " + plasmaFlowConfig.intensity + ",\n" +
                "          lineColor: '" + plasmaFlowConfig.lineColor + "',\n" +
                "          lineWidth: " + plasmaFlowConfig.lineWidth + ",\n" +
                "          blendMode: '" + plasmaFlowConfig.blendMode + "'\n" +
                "        },\n" +
                "        startTime: Date.now(),\n" +
                "        animationId: null\n" +
                "      };\n" +
                "      \n" +
                "      const resizeCanvas = () => {\n" +
                "        const rect = element.getBoundingClientRect();\n" +
                "        const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || window.innerWidth <= 768;\n" +
                "        const baseDpr = window.devicePixelRatio || 1;\n" +
                "        const dpr = isMobile ? baseDpr * 0.7 : baseDpr;\n" +
                "        \n" +
                "        canvas.width = rect.width * dpr;\n" +
                "        canvas.height = rect.height * dpr;\n" +
                "        canvas.style.width = rect.width + 'px';\n" +
                "        canvas.style.height = rect.height + 'px';\n" +
                "        gl.viewport(0, 0, canvas.width, canvas.height);\n" +
                "      };\n" +
                "      \n" +
                "      resizeCanvas();\n" +
                "      \n" +
                "      const render = () => {\n" +
                "        if (!this.instances.has(element)) return;\n" +
                "        \n" +
                "        const currentTime = (Date.now() - instance.startTime) / 1000;\n" +
                "        \n" +
                "        gl.clearColor(0.0, 0.0, 0.0, 0.0);\n" +
                "        gl.clear(gl.COLOR_BUFFER_BIT);\n" +
                "        \n" +
                "        gl.useProgram(programInfo.program);\n" +
                "        \n" +
                "        const lineColorRgb = this.parseColor(instance.config.lineColor);\n" +
                "        \n" +
                "        gl.uniform2f(programInfo.uniformLocations.resolution, canvas.width, canvas.height);\n" +
                "        gl.uniform1f(programInfo.uniformLocations.time, currentTime);\n" +
                "        gl.uniform1f(programInfo.uniformLocations.speed, instance.config.speed);\n" +
                "        gl.uniform1f(programInfo.uniformLocations.intensity, instance.config.intensity);\n" +
                "        gl.uniform3f(programInfo.uniformLocations.lineColor, ...lineColorRgb);\n" +
                "        gl.uniform1f(programInfo.uniformLocations.lineWidth, instance.config.lineWidth);\n" +
                "        \n" +
                "        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);\n" +
                "        gl.vertexAttribPointer(programInfo.attribLocations.vertexPosition, 2, gl.FLOAT, false, 0, 0);\n" +
                "        gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);\n" +
                "        \n" +
                "        gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);\n" +
                "        \n" +
                "        instance.animationId = requestAnimationFrame(render);\n" +
                "      };\n" +
                "      \n" +
                "      instance.animationId = requestAnimationFrame(render);\n" +
                "      this.instances.set(element, instance);\n" +
                "      \n" +
                "      let resizeTimeout;\n" +
                "      window.addEventListener('resize', () => {\n" +
                "        clearTimeout(resizeTimeout);\n" +
                "        resizeTimeout = setTimeout(resizeCanvas, 250);\n" +
                "      });\n" +
                "      \n" +
                "      return instance;\n" +
                "    },\n" +
                "    \n" +
                "    destroyInstance: function(element) {\n" +
                "      const instance = this.instances.get(element);\n" +
                "      if (!instance) return;\n" +
                "      \n" +
                "      if (instance.animationId) {\n" +
                "        cancelAnimationFrame(instance.animationId);\n" +
                "      }\n" +
                "      \n" +
                "      if (instance.canvas && instance.canvas.parentNode) {\n" +
                "        instance.canvas.remove();\n" +
                "      }\n" +
                "      \n" +
                "      this.instances.delete(element);\n" +
                "    },\n" +
                "    \n" +
                "    init: function() {\n" +
                "      const elements = document.querySelectorAll('[data-plasma-flow]');\n" +
                "      elements.forEach(element => this.createInstance(element));\n" +
                "      \n" +
                "      if (window.MutationObserver) {\n" +
                "        const observer = new MutationObserver(mutations => {\n" +
                "          mutations.forEach(mutation => {\n" +
                "            mutation.addedNodes.forEach(node => {\n" +
                "              if (node.nodeType === 1) {\n" +
                "                if (node.hasAttribute && node.hasAttribute('data-plasma-flow')) {\n" +
                "                  this.createInstance(node);\n" +
                "                }\n" +
                "                node.querySelectorAll('[data-plasma-flow]').forEach(el => {\n" +
                "                  this.createInstance(el);\n" +
                "                });\n" +
                "              }\n" +
                "            });\n" +
                "            \n" +
                "            mutation.removedNodes.forEach(node => {\n" +
                "              if (node.nodeType === 1 && this.instances.has(node)) {\n" +
                "                this.destroyInstance(node);\n" +
                "              }\n" +
                "            });\n" +
                "          });\n" +
                "        });\n" +
                "        \n" +
                "        observer.observe(document.body, {\n" +
                "          childList: true,\n" +
                "          subtree: true,\n" +
                "          attributes: true,\n" +
                "          attributeFilter: ['data-plasma-flow']\n" +
                "        });\n" +
                "      }\n" +
                "    }\n" +
                "  };\n" +
                "  \n" +
                "  if (document.readyState === 'loading') {\n" +
                "    document.addEventListener('DOMContentLoaded', () => PlasmaFlow.init());\n" +
                "  } else {\n" +
                "    PlasmaFlow.init();\n" +
                "  }\n" +
                "  \n" +
                "  window.PlasmaFlowAnimation = PlasmaFlow;\n" +
                "})();"
            }

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

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

            function generateRandomPlasma() {
                plasmaFlowConfig.speed = Math.random() * 1.9 + 0.1;
                plasmaFlowConfig.intensity = Math.random() * 2.9 + 0.1;
                plasmaFlowConfig.lineWidth = Math.random() * 2.8 + 0.2;
                plasmaFlowConfig.lineColor = generateRandomColor();
                plasmaFlowConfig.blendMode = ['normal', 'multiply', 'screen', 'overlay', 'soft-light', 'hard-light', 'color-dodge', 'color-burn', 'difference', 'exclusion'][Math.floor(Math.random() * 10)];
                
                document.getElementById('animation-speed').value = plasmaFlowConfig.speed;
                document.getElementById('intensity').value = plasmaFlowConfig.intensity;
                document.getElementById('line-width').value = plasmaFlowConfig.lineWidth;
                document.getElementById('line-color').value = plasmaFlowConfig.lineColor;
                document.getElementById('blend-mode').value = plasmaFlowConfig.blendMode;
                
                document.getElementById('animation-speed-value').textContent = plasmaFlowConfig.speed.toFixed(1);
                document.getElementById('intensity-value').textContent = plasmaFlowConfig.intensity.toFixed(1);
                document.getElementById('line-width-value').textContent = plasmaFlowConfig.lineWidth.toFixed(1);
                
                updateColorInputs();
                updatePreview();
                showNotification('Random plasma flow generated!');
            }

            function updateColorInputs() {
                const colorInput = document.getElementById('line-color');
                const hexInput = document.getElementById('line-color-hex');
                const hslInput = document.getElementById('line-color-hsl');
                
                if (colorInput && hexInput && hslInput) {
                    colorInput.value = plasmaFlowConfig.lineColor;
                    hexInput.value = plasmaFlowConfig.lineColor;
                    hslInput.value = 'hsl(' + hexToHsl(plasmaFlowConfig.lineColor).h + ', ' + hexToHsl(plasmaFlowConfig.lineColor).s + '%, ' + hexToHsl(plasmaFlowConfig.lineColor).l + '%)';
                    
                    hexInput.classList.remove('invalid');
                    hslInput.classList.remove('invalid');
                    
                    const colorPickerContainer = colorInput.closest('.color-row').querySelector('.color-picker-container');
                    if (colorPickerContainer) {
                        colorPickerContainer.style.setProperty('--selected-color', plasmaFlowConfig.lineColor);
                    }
                }
            }

            window.resetParameter = function(parameterId, defaultValue) {
                const element = document.getElementById(parameterId);
                if (element) {
                    element.value = defaultValue;
                    const valueElement = document.getElementById(parameterId + '-value');
                    if (valueElement) {
                        valueElement.textContent = defaultValue;
                    }
                    
                    switch (parameterId) {
                        case 'animation-speed':
                            plasmaFlowConfig.speed = defaultValue;
                            break;
                        case 'intensity':
                            plasmaFlowConfig.intensity = defaultValue;
                            break;
                        case 'line-width':
                            plasmaFlowConfig.lineWidth = defaultValue;
                            break;
                    }
                    
                    updatePreview();
                    showNotification(parameterId.replace(/-/g, ' ') + ' reset to default');
                }
            };

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

            function loadConfiguration() {
                try {
                    const saved = localStorage.getItem('bricksfusion-plasma-config');
                    if (saved) {
                        const savedConfig = JSON.parse(saved);
                        Object.assign(plasmaFlowConfig, savedConfig);
                        
                        document.getElementById('animation-speed').value = savedConfig.speed;
                        document.getElementById('intensity').value = savedConfig.intensity;
                        document.getElementById('line-width').value = savedConfig.lineWidth;
                        document.getElementById('line-color').value = savedConfig.lineColor;
                        document.getElementById('blend-mode').value = savedConfig.blendMode;
                        
                        document.getElementById('animation-speed-value').textContent = savedConfig.speed;
                        document.getElementById('intensity-value').textContent = savedConfig.intensity;
                        document.getElementById('line-width-value').textContent = savedConfig.lineWidth;
                        
                        updateColorInputs();
                        updatePreview();
                    }
                } catch (e) {
                }
            }

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

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

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

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

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

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

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

                previewContainer.style.backgroundColor = '#252525';

                document.getElementById('reset-colors').addEventListener('click', () => {
                    plasmaFlowConfig.lineColor = defaultConfig.lineColor;
                    
                    document.getElementById('line-color').value = defaultConfig.lineColor;
                    
                    updateColorInputs();
                    updatePreview();
                    showNotification('Colors reset to default');
                });

                document.getElementById('reset-flow').addEventListener('click', () => {
                    plasmaFlowConfig.speed = defaultConfig.speed;
                    plasmaFlowConfig.intensity = defaultConfig.intensity;
                    plasmaFlowConfig.lineWidth = defaultConfig.lineWidth;
                    
                    document.getElementById('animation-speed').value = defaultConfig.speed;
                    document.getElementById('intensity').value = defaultConfig.intensity;
                    document.getElementById('line-width').value = defaultConfig.lineWidth;
                    
                    document.getElementById('animation-speed-value').textContent = defaultConfig.speed;
                    document.getElementById('intensity-value').textContent = defaultConfig.intensity;
                    document.getElementById('line-width-value').textContent = defaultConfig.lineWidth;
                    
                    updatePreview();
                    showNotification('Flow settings reset');
                });

                document.getElementById('reset-advanced').addEventListener('click', () => {
                    plasmaFlowConfig.blendMode = defaultConfig.blendMode;
                    
                    document.getElementById('blend-mode').value = defaultConfig.blendMode;
                    
                    updatePreview();
                    showNotification('Advanced settings reset');
                });

                const colorInput = document.getElementById('line-color');
                const hexInput = document.getElementById('line-color-hex');
                const hslInput = document.getElementById('line-color-hsl');
                
                hslInput.value = 'hsl(' + hexToHsl(colorInput.value).h + ', ' + hexToHsl(colorInput.value).s + '%, ' + hexToHsl(colorInput.value).l + '%)';
                
                colorInput.addEventListener('input', () => {
                    const color = colorInput.value;
                    hexInput.value = color;
                    hslInput.value = 'hsl(' + hexToHsl(color).h + ', ' + hexToHsl(color).s + '%, ' + hexToHsl(color).l + '%)';
                    hexInput.classList.remove('invalid');
                    hslInput.classList.remove('invalid');
                    plasmaFlowConfig.lineColor = color;
                    
                    const colorPickerContainer = colorInput.closest('.color-row').querySelector('.color-picker-container');
                    colorPickerContainer.style.setProperty('--selected-color', color);
                    
                    updatePreview();
                });
                
                hexInput.addEventListener('input', (e) => {
                    let hex = e.target.value;
                    
                    hex = formatHex(hex);
                    e.target.value = hex;
                    
                    if (isValidHex(hex)) {
                        colorInput.value = hex;
                        hslInput.value = 'hsl(' + hexToHsl(hex).h + ', ' + hexToHsl(hex).s + '%, ' + hexToHsl(hex).l + '%)';
                        plasmaFlowConfig.lineColor = hex;
                        e.target.classList.remove('invalid');
                        hslInput.classList.remove('invalid');
                        
                        const colorPickerContainer = colorInput.closest('.color-row').querySelector('.color-picker-container');
                        colorPickerContainer.style.setProperty('--selected-color', hex);
                        
                        updatePreview();
                    } else {
                        e.target.classList.add('invalid');
                    }
                });
                
                hexInput.addEventListener('blur', (e) => {
                    if (!isValidHex(e.target.value)) {
                        e.target.value = colorInput.value;
                        e.target.classList.remove('invalid');
                    }
                });
                
                hslInput.addEventListener('input', (e) => {
                    let hsl = e.target.value;
                    
                    if (isValidHsl(hsl)) {
                        const hex = hslToHex(hsl);
                        if (hex) {
                            colorInput.value = hex;
                            hexInput.value = hex;
                            plasmaFlowConfig.lineColor = hex;
                            e.target.classList.remove('invalid');
                            hexInput.classList.remove('invalid');
                            
                            const colorPickerContainer = colorInput.closest('.color-row').querySelector('.color-picker-container');
                            colorPickerContainer.style.setProperty('--selected-color', hex);
                            
                            updatePreview();
                            return;
                        }
                    }
                    
                    e.target.classList.add('invalid');
                });
                
                hslInput.addEventListener('blur', (e) => {
                    let hsl = e.target.value;
                    
                    if (!isValidHsl(hsl) && hsl.trim()) {
                        const formatted = formatHsl(hsl);
                        if (isValidHsl(formatted)) {
                            e.target.value = formatted;
                            const hex = hslToHex(formatted);
                            if (hex) {
                                colorInput.value = hex;
                                hexInput.value = hex;
                                plasmaFlowConfig.lineColor = hex;
                                e.target.classList.remove('invalid');
                                hexInput.classList.remove('invalid');
                                updatePreview();
                                return;
                            }
                        }
                    }
                    
                    if (!isValidHsl(e.target.value)) {
                        e.target.value = 'hsl(' + hexToHsl(colorInput.value).h + ', ' + hexToHsl(colorInput.value).s + '%, ' + hexToHsl(colorInput.value).l + '%)';
                        e.target.classList.remove('invalid');
                    }
                });

                const rangeInputs = document.querySelectorAll('input[type="range"]');
                rangeInputs.forEach(input => {
                    const valueElement = document.getElementById(input.id + '-value');
                    
                    if (valueElement) {
                        valueElement.textContent = input.value;
                    }
                    
                    input.addEventListener('input', () => {
                        if (valueElement) {
                            valueElement.textContent = input.value;
                        }
                        
                        switch (input.id) {
                            case 'animation-speed':
                                plasmaFlowConfig.speed = parseFloat(input.value);
                                break;
                            case 'intensity':
                                plasmaFlowConfig.intensity = parseFloat(input.value);
                                break;
                            case 'line-width':
                                plasmaFlowConfig.lineWidth = parseFloat(input.value);
                                break;
                        }
                        
                        updatePreview();
                    });
                });

                document.getElementById('blend-mode').addEventListener('change', function() {
                    plasmaFlowConfig.blendMode = this.value;
                    updatePreview();
                });

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

                updateColorInputs();
                loadConfiguration();
                
                setTimeout(() => {
                    showNotification('Bricksfusion Plasma Flow Configurator loaded!');
                }, 500);
            }
            
            initializeUI();
        });
    </script>
</body>
</html>
Plasma Flow - Bricksfusion
HEAVY

Plasma Flow

Creates flowing plasma wave patterns with animated glowing lines. Features organic flowing movements that pulse and undulate continuously. Moving particles travel along the plasma lines creating dynamic trails. Choose your line color and customize blend modes for different visual effects. Perfect for sci-fi backgrounds, hero sections, or creating energy-themed atmospheres.

Plasma Flow

Flowing plasma waves with animated particles.

Appearance

Line Color Color picker

Color of the plasma lines and particles. Choose any color to match your design theme and create different energy moods.

Default: Purple

Blend Mode Mix style

How the plasma blends with content behind it. Normal for standard layering. Screen for glowing additive effect. Multiply for darker blending. Experiment to find your perfect look.

Default: Normal

Animation

Flow Speed Slow to Fast

How quickly the plasma waves move and particles travel. Lower creates slow, hypnotic flow. Higher produces rapid, energetic movement.

Default: Moderate

Visual

Brightness Dim to Intense

Overall brightness and glow intensity of the plasma effect. Lower creates subtle, ambient lighting. Higher produces bold, vibrant energy.

Default: Normal (1.0)

Line Thickness Thin to Thick

Width of the plasma wave lines. Lower creates delicate, fine streams. Higher makes bold, prominent waves.

Default: Normal (1.0)

Performance

This effect uses WebGL with custom vertex and fragment shaders for GPU-accelerated rendering. Creates procedural plasma patterns using mathematical wave functions. Features animated particles that follow plasma flow paths. Includes WebGL context loss handling for stability. Very resource intensive - limit to 1 instance per page. Not recommended for mobile devices or low-end hardware.