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>Status Pulse 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: 800px;
            padding: 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;
        }

        .attributes-table {
            margin-top: 1rem;
            width: 100%;
            border-collapse: collapse;
            font-size: var(--text-xs);
        }

        .attributes-table th,
        .attributes-table td {
            text-align: left;
            padding: 0.5rem;
            border-bottom: 1px solid var(--border);
        }

        .attributes-table th {
            color: var(--accent);
            font-weight: 600;
        }

        .attributes-table td {
            color: var(--text-secondary);
        }

        .attributes-table code {
            background-color: rgba(50, 50, 50, 0.5);
            padding: 0.2rem 0.4rem;
            border-radius: 3px;
            font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
            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: #252525;
            border: 1px solid var(--border);
            box-shadow: var(--shadow);
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 2rem;
        }

        .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: relative;
            z-index: 2;
            display: inline-flex;
            align-items: center;
            font-size: 1.75rem;
            color: var(--text-primary);
            font-weight: 500;
        }

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

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

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

        .color-picker-container {
            position: relative;
            width: 40px;
            height: 40px;
            border-radius: 8px;
            overflow: hidden;
            border: 2px solid var(--border);
            cursor: pointer;
            transition: var(--transition);
            flex-shrink: 0;
            background: linear-gradient(45deg, #f0f0f0 25%, transparent 25%), 
                        linear-gradient(-45deg, #f0f0f0 25%, transparent 25%), 
                        linear-gradient(45deg, transparent 75%, #f0f0f0 75%), 
                        linear-gradient(-45deg, transparent 75%, #f0f0f0 75%);
            background-size: 8px 8px;
            background-position: 0 0, 0 4px, 4px -4px, -4px 0px;
        }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        input[type="text"],
        input[type="number"],
        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);
        }

        input[type="text"]:focus,
        input[type="number"]:focus,
        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;
        }

        .status-pulse-dot {
            position: relative;
            display: inline-block;
            border-radius: 50%;
            vertical-align: middle;
        }

        @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);
        }
    </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/visual-effects/" class="breadcrumb-item">Visual effects</a>
            <span class="breadcrumb-separator">›</span>
            <span class="breadcrumb-item active">Status Pulse</span>
        </nav>
        
        <div class="action-buttons">
            <div class="data-attribute-display" id="quick-attribute" title="Click to copy data attribute">
                data-pulse-dot
            </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">Status Pulse</h1>
            <p class="page-subtitle">Interactive status indicators 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 & Customization Attributes
                    </div>
                    <span class="toggle-icon">▼</span>
                </div>
                <div class="instructions-content" id="instructions-content">
                    <div class="how-to-use">
                        <ol>
                            <li>Customize your status pulse 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 the JavaScript code</li>
                            <li>To add the effect to any text element: go to <strong>Section → Style → Attributes</strong>, add <code>data-pulse-dot</code> as attribute name (leave value empty)</li>
                            <li><strong>NEW:</strong> You can now customize each pulse individually using the attributes below!</li>
                        </ol>
                        
                        <h3 style="margin-top: 1.5rem; margin-bottom: 1rem; color: var(--accent);">Individual Element Customization</h3>
                        <p style="margin-bottom: 1rem; color: var(--text-secondary);">Each element with <code>data-pulse-dot</code> can be customized using these additional attributes:</p>
                        
                        <table class="attributes-table">
                            <thead>
                                <tr>
                                    <th>Attribute</th>
                                    <th>Description</th>
                                    <th>Example Value</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr>
                                    <td><code>data-pulse-size</code></td>
                                    <td>Size of the dot in pixels</td>
                                    <td><code>12</code></td>
                                </tr>
                                <tr>
                                    <td><code>data-pulse-color</code></td>
                                    <td>Color of the pulse</td>
                                    <td><code>#ff0000</code></td>
                                </tr>
                                <tr>
                                    <td><code>data-pulse-speed</code></td>
                                    <td>Animation speed in seconds</td>
                                    <td><code>2.0</code></td>
                                </tr>
                                <tr>
                                    <td><code>data-pulse-scale</code></td>
                                    <td>Maximum scale of pulse</td>
                                    <td><code>2.5</code></td>
                                </tr>
                                <tr>
                                    <td><code>data-pulse-opacity</code></td>
                                    <td>Core opacity (0-100)</td>
                                    <td><code>80</code></td>
                                </tr>
                                <tr>
                                    <td><code>data-pulse-spacing</code></td>
                                    <td>Space between dot and text</td>
                                    <td><code>12</code></td>
                                </tr>
                                <tr>
                                    <td><code>data-pulse-shadow-enabled</code></td>
                                    <td>Enable/disable glow (true/false)</td>
                                    <td><code>false</code></td>
                                </tr>
                                <tr>
                                    <td><code>data-pulse-shadow-blur</code></td>
                                    <td>Glow intensity in pixels</td>
                                    <td><code>15</code></td>
                                </tr>
                                <tr>
                                    <td><code>data-pulse-animation-style</code></td>
                                    <td>Animation type</td>
                                    <td><code>grow</code>, <code>fade</code>, <code>both</code>, <code>double</code></td>
                                </tr>
                                <tr>
                                    <td><code>data-pulse-timing-function</code></td>
                                    <td>CSS timing function</td>
                                    <td><code>ease-in-out</code></td>
                                </tr>
                                <tr>
                                    <td><code>data-pulse-pause-hover</code></td>
                                    <td>Pause on hover (true/false)</td>
                                    <td><code>true</code></td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>

        <div class="content">
            <section class="preview-section">
                <div class="preview-container" id="pulse-preview" data-pulse-dot="true">
                    <div class="preview-content">Interactive Status Pulse Preview</div>
                    <div class="preview-controls">
                        <button class="preview-btn" id="randomize-pulse" title="Randomize (R)">🎲</button>
                    </div>
                </div>
            </section>

            <section class="controls-section">
                <div class="card">
                    <div class="card-heading">
                        Pulse Appearance
                        <div class="card-actions">
                            <button class="card-action-btn" id="reset-appearance" title="Reset Appearance">↺</button>
                        </div>
                    </div>
                    <div class="card-content">
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Pulse Size
                                    <span class="help-tooltip" title="Size of the status indicator dot">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="pulse-size-value">8</span>px</span>
                                    <button class="reset-btn" onclick="resetParameter('pulse-size', 8)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="pulse-size" min="4" max="20" step="1" value="8">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">Pulse Color</span>
                            </div>
                            <div class="color-row">
                                <div class="color-picker-container">
                                    <input type="color" id="pulse-color" value="#22c55e">
                                </div>
                                <div class="color-input-group">
                                    <span class="color-label">HEX</span>
                                    <input type="text" class="color-input hex-input" id="pulse-color-hex" value="#22c55e" placeholder="#FFFFFF">
                                </div>
                                <div class="color-input-group">
                                    <span class="color-label">HSL</span>
                                    <input type="text" class="color-input hsl-input" id="pulse-color-hsl" placeholder="hsl(0, 100%, 50%)">
                                </div>
                            </div>
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Core Opacity
                                    <span class="help-tooltip" title="Opacity of the main dot">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="pulse-opacity-value">100</span>%</span>
                                    <button class="reset-btn" onclick="resetParameter('pulse-opacity', 100)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="pulse-opacity" min="50" max="100" step="5" value="100">
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-heading">
                        Animation Settings
                        <div class="card-actions">
                            <button class="card-action-btn" id="reset-animation" title="Reset Animation Settings">↺</button>
                        </div>
                    </div>
                    <div class="card-content">
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Animation Speed
                                    <span class="help-tooltip" title="Duration of one pulse cycle">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="pulse-speed-value">1.5</span>s</span>
                                    <button class="reset-btn" onclick="resetParameter('pulse-speed', 1.5)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="pulse-speed" min="0.5" max="3" step="0.1" value="1.5">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Pulse Scale
                                    <span class="help-tooltip" title="Maximum size of the pulse effect">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="pulse-scale-value">2</span>x</span>
                                    <button class="reset-btn" onclick="resetParameter('pulse-scale', 2)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="pulse-scale" min="1.5" max="3" step="0.1" value="2">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">Animation Style</span>
                            </div>
                            <select id="animation-style">
                                <option value="fade" selected>Fade Out</option>
                                <option value="grow">Grow Only</option>
                                <option value="both">Grow and Fade</option>
                                <option value="double">Double Pulse</option>
                            </select>
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">Timing Function</span>
                            </div>
                            <select id="timing-function">
                                <option value="cubic-bezier(0.4, 0, 0.6, 1)" selected>Smooth</option>
                                <option value="linear">Linear</option>
                                <option value="ease-in-out">Ease In Out</option>
                                <option value="cubic-bezier(0.68, -0.55, 0.265, 1.55)">Bounce</option>
                            </select>
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-heading">
                        Advanced Options
                        <div class="card-actions">
                            <button class="card-action-btn" id="reset-advanced" title="Reset Advanced Settings">↺</button>
                        </div>
                    </div>
                    <div class="card-content">
                        <div class="switch-container">
                            <span class="switch-label">Enable Glow Shadow</span>
                            <label class="switch">
                                <input type="checkbox" id="shadow-enabled" checked>
                                <span class="slider"></span>
                            </label>
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Shadow Blur
                                    <span class="help-tooltip" title="Intensity of the glow effect">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="shadow-blur-value">10</span>px</span>
                                    <button class="reset-btn" onclick="resetParameter('shadow-blur', 10)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="shadow-blur" min="0" max="20" step="1" value="10">
                        </div>
                        
                        <div class="control-group">
                            <div class="control-label">
                                <span class="label-text">
                                    Spacing
                                    <span class="help-tooltip" title="Space between pulse and text">ℹ</span>
                                </span>
                                <div class="value-display">
                                    <span class="value-text"><span id="spacing-value">8</span>px</span>
                                    <button class="reset-btn" onclick="resetParameter('spacing', 8)">↺</button>
                                </div>
                            </div>
                            <input type="range" id="spacing" min="4" max="16" step="1" value="8">
                        </div>
                        
                        <div class="switch-container">
                            <span class="switch-label">Pause on Hover</span>
                            <label class="switch">
                                <input type="checkbox" id="pause-on-hover">
                                <span class="slider"></span>
                            </label>
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </div>

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

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            let pulseConfig = {
                size: 8,
                color: '#22c55e',
                speed: 1.5,
                scale: 2,
                opacity: 100,
                animationStyle: 'fade',
                timingFunction: 'cubic-bezier(0.4, 0, 0.6, 1)',
                shadowEnabled: true,
                shadowBlur: 10,
                spacing: 8,
                pauseOnHover: false
            };

            const defaultConfig = { ...pulseConfig };
            let currentPulseElement = null;

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

            function initStatusPulse() {
                const elements = document.querySelectorAll('[data-pulse-dot]:not([data-pulse-initialized="true"])');
                
                elements.forEach(element => {
                    createPulseElement(element);
                    element.dataset.pulseInitialized = 'true';
                });
            }

            function createPulseElement(element) {
                const dot = document.createElement('span');
                dot.className = 'status-pulse-dot';
                const opacity = pulseConfig.opacity / 100;
                
                dot.style.cssText = `
                    position: relative;
                    display: inline-block;
                    width: ${pulseConfig.size}px;
                    height: ${pulseConfig.size}px;
                    background: ${pulseConfig.color};
                    border-radius: 50%;
                    margin-right: ${pulseConfig.spacing}px;
                    vertical-align: middle;
                    opacity: ${opacity};
                    ${pulseConfig.shadowEnabled ? `box-shadow: 0 0 ${pulseConfig.shadowBlur}px ${pulseConfig.color};` : ''}
                `;

                createPulseAnimation(dot);

                if (pulseConfig.pauseOnHover) {
                    element.addEventListener('mouseenter', () => pauseAnimation(dot));
                    element.addEventListener('mouseleave', () => resumeAnimation(dot));
                }

                element.insertBefore(dot, element.firstChild);
                element.style.display = 'inline-flex';
                element.style.alignItems = 'center';

                updateAnimationStyles();

                if (element.id === 'pulse-preview') {
                    currentPulseElement = dot;
                }
            }

            function createPulseAnimation(dot) {
                if (pulseConfig.animationStyle === 'fade' || pulseConfig.animationStyle === 'double') {
                    const pulseCount = pulseConfig.animationStyle === 'double' ? 2 : 1;
                    
                    for (let i = 0; i < pulseCount; i++) {
                        const pulse = document.createElement('span');
                        pulse.style.cssText = `
                            position: absolute;
                            left: 0;
                            top: 0;
                            width: 100%;
                            height: 100%;
                            background: inherit;
                            border-radius: inherit;
                            animation: pulseFade${pulseConfig.size} ${pulseConfig.speed}s ${pulseConfig.timingFunction} infinite;
                            ${pulseConfig.animationStyle === 'double' && i === 1 ? `animation-delay: ${pulseConfig.speed / 2}s;` : ''}
                        `;
                        dot.appendChild(pulse);
                    }
                } else if (pulseConfig.animationStyle === 'grow') {
                    dot.style.animation = `pulseGrow${pulseConfig.size} ${pulseConfig.speed}s ${pulseConfig.timingFunction} infinite`;
                } else if (pulseConfig.animationStyle === 'both') {
                    const pulse = document.createElement('span');
                    pulse.style.cssText = `
                        position: absolute;
                        left: 0;
                        top: 0;
                        width: 100%;
                        height: 100%;
                        background: inherit;
                        border-radius: inherit;
                        animation: pulseBoth${pulseConfig.size} ${pulseConfig.speed}s ${pulseConfig.timingFunction} infinite;
                    `;
                    dot.appendChild(pulse);
                }
            }

            function pauseAnimation(dot) {
                dot.style.animationPlayState = 'paused';
                dot.querySelectorAll('span').forEach(span => {
                    span.style.animationPlayState = 'paused';
                });
            }

            function resumeAnimation(dot) {
                dot.style.animationPlayState = 'running';
                dot.querySelectorAll('span').forEach(span => {
                    span.style.animationPlayState = 'running';
                });
            }

            function updateAnimationStyles() {
                document.querySelectorAll('.pulse-animation-style').forEach(el => el.remove());
                
                const style = document.createElement('style');
                style.className = 'pulse-animation-style';
                
                let animations = '';
                
                if (pulseConfig.animationStyle === 'fade' || pulseConfig.animationStyle === 'double') {
                    animations += `
                        @keyframes pulseFade${pulseConfig.size} {
                            0% { transform: scale(1); opacity: ${pulseConfig.opacity / 100}; }
                            100% { transform: scale(${pulseConfig.scale}); opacity: 0; }
                        }
                    `;
                }
                
                if (pulseConfig.animationStyle === 'grow') {
                    animations += `
                        @keyframes pulseGrow${pulseConfig.size} {
                            0%, 100% { transform: scale(1); }
                            50% { transform: scale(${pulseConfig.scale}); }
                        }
                    `;
                }
                
                if (pulseConfig.animationStyle === 'both') {
                    animations += `
                        @keyframes pulseBoth${pulseConfig.size} {
                            0% { transform: scale(1); opacity: ${pulseConfig.opacity / 100}; }
                            50% { transform: scale(${pulseConfig.scale}); opacity: ${pulseConfig.opacity / 200}; }
                            100% { transform: scale(1); opacity: ${pulseConfig.opacity / 100}; }
                        }
                    `;
                }
                
                style.textContent = animations;
                document.head.appendChild(style);
            }

            function updateConfig() {
                if (currentPulseElement) {
                    const opacity = pulseConfig.opacity / 100;
                    
                    currentPulseElement.style.width = `${pulseConfig.size}px`;
                    currentPulseElement.style.height = `${pulseConfig.size}px`;
                    currentPulseElement.style.background = pulseConfig.color;
                    currentPulseElement.style.marginRight = `${pulseConfig.spacing}px`;
                    currentPulseElement.style.opacity = opacity;
                    currentPulseElement.style.boxShadow = pulseConfig.shadowEnabled ? 
                        `0 0 ${pulseConfig.shadowBlur}px ${pulseConfig.color}` : '';

                    currentPulseElement.innerHTML = '';
                    createPulseAnimation(currentPulseElement);
                    updateAnimationStyles();
                }
            }

            function updatePreview() {
                document.querySelectorAll('.status-pulse-dot').forEach(el => el.remove());
                document.querySelectorAll('[data-pulse-initialized]').forEach(el => {
                    el.removeAttribute('data-pulse-initialized');
                });
                initStatusPulse();
            }

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

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

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

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

            function 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 generateRandomColor() {
                return '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0');
            }

            function generateFullSectionJSON() {
                const sectionId = generateUniqueId();
                const containerId = generateUniqueId();
                const divId = generateUniqueId();
                const textId = generateUniqueId();
                const codeId = generateUniqueId();

                const jsCode = generateJavaScriptCode();

                const bricksJSON = {
                    "content": [
                        {
                            "id": sectionId,
                            "name": "section",
                            "parent": 0,
                            "children": [containerId, codeId],
                            "settings": {
                                "_height": "500",
                                "_justifyContent": "center"
                            }
                        },
                        {
                            "id": containerId,
                            "name": "container",
                            "parent": sectionId,
                            "children": [divId],
                            "settings": {
                                "_alignItems": "center",
                                "_overflow": "hidden"
                            }
                        },
                        {
                            "id": divId,
                            "name": "div",
                            "parent": containerId,
                            "children": [textId],
                            "settings": {
                                "_attributes": [
                                    {
                                        "id": "jvsdgw",
                                        "name": "data-pulse-dot"
                                    }
                                ],
                                "_padding": {
                                    "top": "10",
                                    "left": "20",
                                    "right": "20",
                                    "bottom": "10"
                                },
                                "_border": {
                                    "radius": {
                                        "top": "15",
                                        "right": "15",
                                        "bottom": "15",
                                        "left": "15"
                                    },
                                    "width": {
                                        "top": "1",
                                        "right": "1",
                                        "bottom": "1",
                                        "left": "1"
                                    },
                                    "style": "solid",
                                    "color": {
                                        "hex": "#e3e3e3"
                                    }
                                }
                            }
                        },
                        {
                            "id": textId,
                            "name": "text-basic",
                            "parent": divId,
                            "children": [],
                            "settings": {
                                "text": "Status pulse",
                                "tag": "span",
                                "_typography": {
                                    "color": {
                                        "hex": "#000000"
                                    }
                                }
                            }
                        },
                        {
                            "id": codeId,
                            "name": "code",
                            "parent": sectionId,
                            "children": [],
                            "settings": {
                                "javascriptCode": jsCode,
                                "executeCode": true,
                                "_display": "none"
                            },
                            "label": "Status pulse JS"
                        }
                    ],
                    "source": "bricksCopiedElements",
                    "sourceUrl": "https://test.bricksfusion.com",
                    "version": "2.0.1",
                    "globalClasses": [],
                    "globalElements": []
                };

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

            function generateJavaScriptCode() {
                return `function createPulseDot() {
    const elements = document.querySelectorAll('[data-pulse-dot]:not([data-pulse-initialized])');
    
    elements.forEach(element => {
        element.setAttribute('data-pulse-initialized', 'true');
        
        // Get custom attributes or use defaults
        const size = element.getAttribute('data-pulse-size') || '${pulseConfig.size}';
        const color = element.getAttribute('data-pulse-color') || '${pulseConfig.color}';
        const speed = element.getAttribute('data-pulse-speed') || '${pulseConfig.speed}';
        const scale = element.getAttribute('data-pulse-scale') || '${pulseConfig.scale}';
        const opacityRaw = element.getAttribute('data-pulse-opacity') || '${pulseConfig.opacity}';
        const opacity = parseInt(opacityRaw) / 100;
        const spacing = element.getAttribute('data-pulse-spacing') || '${pulseConfig.spacing}';
        const shadowEnabled = element.getAttribute('data-pulse-shadow-enabled') !== null ? 
            element.getAttribute('data-pulse-shadow-enabled') === 'true' : ${pulseConfig.shadowEnabled};
        const shadowBlur = element.getAttribute('data-pulse-shadow-blur') || '${pulseConfig.shadowBlur}';
        const animationStyle = element.getAttribute('data-pulse-animation-style') || '${pulseConfig.animationStyle}';
        const timingFunction = element.getAttribute('data-pulse-timing-function') || '${pulseConfig.timingFunction}';
        const pauseOnHover = element.getAttribute('data-pulse-pause-hover') !== null ? 
            element.getAttribute('data-pulse-pause-hover') === 'true' : ${pulseConfig.pauseOnHover};
        
        // Create dot element
        const dot = document.createElement('span');
        dot.className = 'status-pulse-dot';
        dot.style.cssText = \`
            position: relative;
            display: inline-block;
            width: \${size}px;
            height: \${size}px;
            background: \${color};
            border-radius: 50%;
            margin-right: \${spacing}px;
            vertical-align: middle;
            opacity: \${opacity};
            \${shadowEnabled ? \`box-shadow: 0 0 \${shadowBlur}px \${color};\` : ''}
        \`;
        
        // Generate unique animation name
        const animationId = 'pulse_' + Math.random().toString(36).substr(2, 9);
        
        // Create animations based on style
        let keyframes = '';
        if (animationStyle === 'fade') {
            keyframes = \`
                @keyframes \${animationId} {
                    0% { transform: scale(1); opacity: \${opacity}; }
                    100% { transform: scale(\${scale}); opacity: 0; }
                }
            \`;
            const pulse = document.createElement('span');
            pulse.style.cssText = \`
                position: absolute;
                left: 0;
                top: 0;
                width: 100%;
                height: 100%;
                background: inherit;
                border-radius: inherit;
                animation: \${animationId} \${speed}s \${timingFunction} infinite;
            \`;
            dot.appendChild(pulse);
        } else if (animationStyle === 'grow') {
            keyframes = \`
                @keyframes \${animationId} {
                    0%, 100% { transform: scale(1); }
                    50% { transform: scale(\${scale}); }
                }
            \`;
            dot.style.animation = \`\${animationId} \${speed}s \${timingFunction} infinite\`;
        } else if (animationStyle === 'both') {
            keyframes = \`
                @keyframes \${animationId} {
                    0% { transform: scale(1); opacity: \${opacity}; }
                    50% { transform: scale(\${scale}); opacity: \${opacity / 2}; }
                    100% { transform: scale(1); opacity: \${opacity}; }
                }
            \`;
            const pulse = document.createElement('span');
            pulse.style.cssText = \`
                position: absolute;
                left: 0;
                top: 0;
                width: 100%;
                height: 100%;
                background: inherit;
                border-radius: inherit;
                animation: \${animationId} \${speed}s \${timingFunction} infinite;
            \`;
            dot.appendChild(pulse);
        } else if (animationStyle === 'double') {
            keyframes = \`
                @keyframes \${animationId} {
                    0% { transform: scale(1); opacity: \${opacity}; }
                    100% { transform: scale(\${scale}); opacity: 0; }
                }
            \`;
            for (let i = 0; i < 2; i++) {
                const pulse = document.createElement('span');
                pulse.style.cssText = \`
                    position: absolute;
                    left: 0;
                    top: 0;
                    width: 100%;
                    height: 100%;
                    background: inherit;
                    border-radius: inherit;
                    animation: \${animationId} \${speed}s \${timingFunction} infinite;
                    \${i === 1 ? \`animation-delay: \${parseFloat(speed) / 2}s;\` : ''}
                \`;
                dot.appendChild(pulse);
            }
        }
        
        // Inject keyframes
        if (keyframes) {
            const style = document.createElement('style');
            style.textContent = keyframes;
            document.head.appendChild(style);
        }
        
        // Add pause on hover functionality
        if (pauseOnHover) {
            element.addEventListener('mouseenter', () => {
                dot.style.animationPlayState = 'paused';
                dot.querySelectorAll('span').forEach(span => {
                    span.style.animationPlayState = 'paused';
                });
            });
            
            element.addEventListener('mouseleave', () => {
                dot.style.animationPlayState = 'running';
                dot.querySelectorAll('span').forEach(span => {
                    span.style.animationPlayState = 'running';
                });
            });
        }
        
        // Insert dot and setup element display
        element.insertBefore(dot, element.firstChild);
        element.style.display = 'inline-flex';
        element.style.alignItems = 'center';
    });
}

// Initialize on DOM ready or immediately if already loaded
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', createPulseDot);
} else {
    createPulseDot();
}

// Also run on dynamic content changes (optional)
const observer = new MutationObserver(() => {
    createPulseDot();
});

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

            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();
                
                if (sectionJSON) {
                    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');
                            }
                        });
                } else {
                    showNotification('Failed to generate section JSON', 'error');
                }
            }

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

            window.resetParameter = function(parameterId, defaultValue) {
                const element = document.getElementById(parameterId);
                if (element) {
                    element.value = defaultValue;
                    const valueElement = document.getElementById(`${parameterId}-value`);
                    if (valueElement) {
                        valueElement.textContent = defaultValue;
                    }
                    
                    switch (parameterId) {
                        case 'pulse-size':
                            pulseConfig.size = defaultValue;
                            break;
                        case 'pulse-opacity':
                            pulseConfig.opacity = defaultValue;
                            break;
                        case 'pulse-speed':
                            pulseConfig.speed = defaultValue;
                            break;
                        case 'pulse-scale':
                            pulseConfig.scale = defaultValue;
                            break;
                        case 'shadow-blur':
                            pulseConfig.shadowBlur = defaultValue;
                            break;
                        case 'spacing':
                            pulseConfig.spacing = defaultValue;
                            break;
                    }
                    
                    updateConfig();
                    showNotification(`${parameterId.replace(/-/g, ' ')} reset to default`);
                }
            };

            function generateRandomPulse() {
                const randomColors = [generateRandomColor()];
                
                pulseConfig.color = randomColors[0];
                pulseConfig.size = Math.floor(Math.random() * (20 - 4) + 4);
                pulseConfig.speed = Math.round((Math.random() * (3 - 0.5) + 0.5) * 10) / 10;
                pulseConfig.scale = Math.round((Math.random() * (3 - 1.5) + 1.5) * 10) / 10;
                
                document.getElementById('pulse-color').value = pulseConfig.color;
                document.getElementById('pulse-color-hex').value = pulseConfig.color;
                document.getElementById('pulse-color-hsl').value = hexToHsl(pulseConfig.color);
                document.getElementById('pulse-size').value = pulseConfig.size;
                document.getElementById('pulse-speed').value = pulseConfig.speed;
                document.getElementById('pulse-scale').value = pulseConfig.scale;
                
                document.getElementById('pulse-size-value').textContent = pulseConfig.size;
                document.getElementById('pulse-speed-value').textContent = pulseConfig.speed;
                document.getElementById('pulse-scale-value').textContent = pulseConfig.scale;
                
                const container = document.getElementById('pulse-color').closest('.color-picker-container');
                if (container) {
                    container.style.setProperty('--current-color', pulseConfig.color);
                }
                
                updateConfig();
                showNotification('Random pulse generated!');
            }

            function initializeUI() {
                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-pulse-dot');
                });

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

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

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

                document.getElementById('reset-appearance').addEventListener('click', () => {
                    pulseConfig.size = defaultConfig.size;
                    pulseConfig.color = defaultConfig.color;
                    pulseConfig.opacity = defaultConfig.opacity;
                    
                    document.getElementById('pulse-size').value = defaultConfig.size;
                    document.getElementById('pulse-color').value = defaultConfig.color;
                    document.getElementById('pulse-color-hex').value = defaultConfig.color;
                    document.getElementById('pulse-color-hsl').value = hexToHsl(defaultConfig.color);
                    document.getElementById('pulse-opacity').value = defaultConfig.opacity;
                    
                    document.getElementById('pulse-size-value').textContent = defaultConfig.size;
                    document.getElementById('pulse-opacity-value').textContent = defaultConfig.opacity;
                    
                    const container = document.getElementById('pulse-color').closest('.color-picker-container');
                    if (container) {
                        container.style.setProperty('--current-color', defaultConfig.color);
                    }
                    
                    updateConfig();
                    showNotification('Appearance settings reset');
                });

                document.getElementById('reset-animation').addEventListener('click', () => {
                    pulseConfig.speed = defaultConfig.speed;
                    pulseConfig.scale = defaultConfig.scale;
                    pulseConfig.animationStyle = defaultConfig.animationStyle;
                    pulseConfig.timingFunction = defaultConfig.timingFunction;
                    
                    document.getElementById('pulse-speed').value = defaultConfig.speed;
                    document.getElementById('pulse-scale').value = defaultConfig.scale;
                    document.getElementById('animation-style').value = defaultConfig.animationStyle;
                    document.getElementById('timing-function').value = defaultConfig.timingFunction;
                    
                    document.getElementById('pulse-speed-value').textContent = defaultConfig.speed;
                    document.getElementById('pulse-scale-value').textContent = defaultConfig.scale;
                    
                    updateConfig();
                    showNotification('Animation settings reset');
                });

                document.getElementById('reset-advanced').addEventListener('click', () => {
                    pulseConfig.shadowEnabled = defaultConfig.shadowEnabled;
                    pulseConfig.shadowBlur = defaultConfig.shadowBlur;
                    pulseConfig.spacing = defaultConfig.spacing;
                    pulseConfig.pauseOnHover = defaultConfig.pauseOnHover;
                    
                    document.getElementById('shadow-enabled').checked = defaultConfig.shadowEnabled;
                    document.getElementById('shadow-blur').value = defaultConfig.shadowBlur;
                    document.getElementById('spacing').value = defaultConfig.spacing;
                    document.getElementById('pause-on-hover').checked = defaultConfig.pauseOnHover;
                    
                    document.getElementById('shadow-blur-value').textContent = defaultConfig.shadowBlur;
                    document.getElementById('spacing-value').textContent = defaultConfig.spacing;
                    
                    updateConfig();
                    showNotification('Advanced settings reset');
                });

                const colorInput = document.getElementById('pulse-color');
                const hexInput = document.getElementById('pulse-color-hex');
                const hslInput = document.getElementById('pulse-color-hsl');
                const container = colorInput.closest('.color-picker-container');
                
                hslInput.value = hexToHsl(colorInput.value);
                if (container) {
                    container.style.setProperty('--current-color', colorInput.value);
                }
                
                colorInput.addEventListener('input', () => {
                    const color = colorInput.value;
                    hexInput.value = color;
                    hslInput.value = hexToHsl(color);
                    
                    if (container) {
                        container.style.setProperty('--current-color', color);
                    }
                    
                    pulseConfig.color = color;
                    updateConfig();
                });
                
                hexInput.addEventListener('input', (e) => {
                    let hex = e.target.value;
                    
                    if (!hex.startsWith('#')) {
                        hex = '#' + hex;
                    }
                    
                    if (hex.length > 7) {
                        hex = hex.substring(0, 7);
                    }
                    
                    e.target.value = hex.toUpperCase();
                    
                    if (isValidHex(hex)) {
                        colorInput.value = hex;
                        hslInput.value = hexToHsl(hex);
                        
                        if (container) {
                            container.style.setProperty('--current-color', hex);
                        }
                        
                        pulseConfig.color = hex;
                        e.target.classList.remove('invalid');
                        updateConfig();
                    } else {
                        e.target.classList.add('invalid');
                    }
                });
                
                hslInput.addEventListener('input', (e) => {
                    const hsl = e.target.value;
                    
                    if (isValidHsl(hsl)) {
                        const hex = hslToHex(hsl);
                        if (hex) {
                            colorInput.value = hex;
                            hexInput.value = hex;
                            
                            if (container) {
                                container.style.setProperty('--current-color', hex);
                            }
                            
                            pulseConfig.color = hex;
                            e.target.classList.remove('invalid');
                            updateConfig();
                            return;
                        }
                    }
                    
                    e.target.classList.add('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 'pulse-size':
                                pulseConfig.size = parseInt(input.value);
                                break;
                            case 'pulse-opacity':
                                pulseConfig.opacity = parseInt(input.value);
                                break;
                            case 'pulse-speed':
                                pulseConfig.speed = parseFloat(input.value);
                                break;
                            case 'pulse-scale':
                                pulseConfig.scale = parseFloat(input.value);
                                break;
                            case 'shadow-blur':
                                pulseConfig.shadowBlur = parseInt(input.value);
                                break;
                            case 'spacing':
                                pulseConfig.spacing = parseInt(input.value);
                                break;
                        }
                        
                        updateConfig();
                    });
                });

                document.getElementById('animation-style').addEventListener('change', function() {
                    pulseConfig.animationStyle = this.value;
                    updatePreview();
                });
                
                document.getElementById('timing-function').addEventListener('change', function() {
                    pulseConfig.timingFunction = this.value;
                    updatePreview();
                });
                
                document.getElementById('shadow-enabled').addEventListener('change', function() {
                    pulseConfig.shadowEnabled = this.checked;
                    updateConfig();
                });
                
                document.getElementById('pause-on-hover').addEventListener('change', function() {
                    pulseConfig.pauseOnHover = this.checked;
                    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':
                                generateRandomPulse();
                                break;
                        }
                    }
                });

                function saveConfiguration() {
                    try {
                        localStorage.setItem('bricksfusion-pulse-config', JSON.stringify(pulseConfig));
                    } catch (e) {
                        // Silently fail if localStorage is not available
                    }
                }

                function loadConfiguration() {
                    try {
                        const saved = localStorage.getItem('bricksfusion-pulse-config');
                        if (saved) {
                            const savedConfig = JSON.parse(saved);
                            Object.assign(pulseConfig, savedConfig);
                            
                            document.getElementById('pulse-size').value = savedConfig.size;
                            document.getElementById('pulse-color').value = savedConfig.color;
                            document.getElementById('pulse-color-hex').value = savedConfig.color;
                            document.getElementById('pulse-color-hsl').value = hexToHsl(savedConfig.color);
                            document.getElementById('pulse-opacity').value = savedConfig.opacity;
                            document.getElementById('pulse-speed').value = savedConfig.speed;
                            document.getElementById('pulse-scale').value = savedConfig.scale;
                            document.getElementById('animation-style').value = savedConfig.animationStyle;
                            document.getElementById('timing-function').value = savedConfig.timingFunction;
                            document.getElementById('shadow-enabled').checked = savedConfig.shadowEnabled;
                            document.getElementById('shadow-blur').value = savedConfig.shadowBlur;
                            document.getElementById('spacing').value = savedConfig.spacing;
                            document.getElementById('pause-on-hover').checked = savedConfig.pauseOnHover;
                            
                            document.getElementById('pulse-size-value').textContent = savedConfig.size;
                            document.getElementById('pulse-opacity-value').textContent = savedConfig.opacity;
                            document.getElementById('pulse-speed-value').textContent = savedConfig.speed;
                            document.getElementById('pulse-scale-value').textContent = savedConfig.scale;
                            document.getElementById('shadow-blur-value').textContent = savedConfig.shadowBlur;
                            document.getElementById('spacing-value').textContent = savedConfig.spacing;
                            
                            const container = document.getElementById('pulse-color').closest('.color-picker-container');
                            if (container) {
                                container.style.setProperty('--current-color', savedConfig.color);
                            }
                            
                            updatePreview();
                        }
                    } catch (e) {
                        // Silently fail if localStorage is not available
                    }
                }

                const originalUpdateConfig = updateConfig;
                updateConfig = function() {
                    originalUpdateConfig();
                    saveConfiguration();
                };

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

                loadConfiguration();
                
                setTimeout(() => {
                    showNotification('✅ BricksFusion Status Pulse Configurator loaded! All parameters now work correctly.');
                }, 500);
            }

            initStatusPulse();
            initializeUI();
        });
    </script>
</body>
</html>
Status Pulse - Bricksfusion
LIGHTWEIGHT

Status Pulse

Adds an animated pulsing dot to show live status indicators. Perfect for "Online", "Live", "Recording", or any real-time status display.

Online Status
Online
Live Streaming
Live
Processing
Processing
Available
Available

Appearance

Dot Size 4-20px

Size of the pulsing dot. Smaller dots are subtle and professional, larger ones are more attention-grabbing.

Default: 8px

Dot Color color picker

Color of the status dot. Green for online/active, red for live/recording, blue for processing, yellow for busy/away.

Default: Green (#22c55e)

Opacity 0-100%

How see-through the dot is. 100 is fully solid, lower values make it more transparent and subtle.

Default: 100%

Spacing 0-20px

Gap between the dot and your text. Adjust to match your design needs.

Default: 8px

Glow Shadow on/off

Adds a soft glow around the dot that matches its color. Makes it more visible and eye-catching.

Default: On

Shadow Blur 0-30px

Size of the glow effect. Higher values create a bigger, softer glow around the dot.

Default: 10px

Animation

Animation Style fade / grow / both / double

Type of pulse animation. Fade expands and fades out, Grow scales the dot itself, Both combines fading with growing, Double creates two overlapping pulses.

Default: Fade

Speed 0.5-5.0 seconds

How fast the pulse animation cycles. Lower is quicker and more urgent, higher is slower and calmer.

Default: 1.5s

Scale 1.0-4.0

How much bigger the pulse grows. 1.0 means no growth, 2.0 doubles in size, 3.0 triples. Larger values are more dramatic.

Default: 2.0

Timing Function easing selection

Animation curve that controls the motion feel. Ease creates natural movement, Linear is constant speed, Custom lets you fine-tune with cubic-bezier.

Default: Ease (cubic-bezier(0.4, 0, 0.6, 1))

Behavior

Pause on Hover on/off

Stops the pulse animation when someone hovers over it. Useful when you want the status to be readable without distraction.

Default: Off

Performance

This element is extremely lightweight and uses only CSS animations. You can use dozens of status pulses on a single page without any performance concerns. Perfect for user lists, notification systems, and real-time dashboards.