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>Spotlight 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: #333333;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  justify-content: center;
  perspective: 1000px;
}

.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: #FF0099;
}

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

.toggle-switch {
  position: relative;
  display: inline-block;
  width: 46px;
  height: 24px;
  margin-right: 10px;
}

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

.toggle-slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(120, 120, 128, 0.32);
  transition: all 0.3s ease;
  border-radius: 30px;
}

.toggle-slider:before {
  position: absolute;
  content: "";
  height: 20px;
  width: 20px;
  left: 2px;
  bottom: 2px;
  background-color: white;
  transition: all 0.3s ease;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

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

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

.toggle-label {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  cursor: pointer;
}

.toggle-container {
  display: flex;
  align-items: center;
  margin-bottom: 15px;
}

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

.spotlight-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
}

.spotlight-element {
  position: absolute;
  top: -50%;
  left: -50%;
  width: 200%;
  height: 200%;
  background: radial-gradient(ellipse at center, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0.6) 10%, rgba(255,255,255,0.4) 20%, rgba(255,255,255,0.2) 30%, rgba(255,255,255,0.1) 40%, rgba(255,255,255,0) 60%);
  transform: scale(0.8);
  opacity: 0;
  filter: blur(8px);
  transition: all 1s ease;
}

.spotlight-element.active {
  transform: scale(1);
  opacity: 1;
}

@keyframes pulse {
  0% { opacity: 0.4; transform: scale(0.98); }
  100% { opacity: 0.6; transform: scale(1.02); }
}

.sparkle {
  position: absolute;
  width: 6px;
  height: 6px;
  background-color: white;
  border-radius: 50%;
  opacity: 0;
  filter: blur(1px);
  animation: sparkle 1.5s ease-in-out infinite;
}

@keyframes sparkle {
  0%, 100% { opacity: 0; transform: scale(0); }
  50% { opacity: 1; transform: scale(1); }
}
  </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">Spotlight</span>
    </nav>
    
    <div class="action-buttons">
      <div class="data-attribute-display" id="quick-attribute" title="Click to copy data attribute">
        data-spotlight
      </div>
      <button class="action-btn primary" id="download-config" title="Copy JavaScript code" 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" data-protection-animation="true">
        <span>📦</span>
        Copy Full Section
      </button>
    </div>
  </div>

  <div class="container">
    <div class="page-header">
      <h1 class="page-title">Spotlight</h1>
      <p class="page-subtitle">Interactive spotlight animations for Bricks Builder</p>
    </div>

    <div class="instructions-toggle">
      <div class="instructions-card" id="instructions-card">
        <div class="instructions-header" id="instructions-toggle">
          <div class="instructions-title">
            How to Use & Code Information
          </div>
          <span class="toggle-icon">▼</span>
        </div>
        <div class="instructions-content" id="instructions-content">
          <div class="instructions-grid">
            <div class="how-to-use">
              <ol>
                <li>Customize your spotlight 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 and paste the JavaScript</li>
                <li>To add the effect to any section: go to <strong>Section → Style → Attributes</strong>, add <code>data-spotlight</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="spotlight-preview" data-spotlight>
          <div class="preview-content">Interactive Spotlight Preview</div>
          <div class="preview-controls">
            <button class="preview-btn" id="randomize-spotlight" 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="#333333" title="Change Preview Background">
            </div>
          </div>
        </div>
      </section>

      <section class="controls-section">
        <div class="card">
          <div class="card-heading">
            Spotlight Color
            <div class="card-actions">
              <button class="card-action-btn" id="reset-color" title="Reset Color">↺</button>
            </div>
          </div>
          <div class="card-content">
            <div class="color-list">
              <div class="color-row">
                <div class="color-picker-container">
                  <input type="color" id="spotlight-color" value="#FF0099">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HEX</span>
                  <input type="text" class="color-input hex-input" id="spotlight-color-hex" value="#FF0099" placeholder="#FFFFFF">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HSL</span>
                  <input type="text" class="color-input hsl-input" id="spotlight-color-hsl" placeholder="hsl(0, 100%, 50%)">
                </div>
              </div>
            </div>
          </div>
        </div>

        <div class="card">
          <div class="card-heading">
            Effect Settings
            <div class="card-actions">
              <button class="card-action-btn" id="reset-effects" title="Reset Effect Settings">↺</button>
            </div>
          </div>
          <div class="card-content">
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">Spotlight Effect</span>
              </div>
              <select id="spotlight-effect">
                <option value="soft">Soft Natural Light</option>
                <option value="harsh">Harsh Spotlight</option>
                <option value="window">Window Light</option>
                <option value="ambient">Ambient Glow</option>
              </select>
            </div>
            
            <div class="control-group" id="angle-control" style="display: none;">
              <div class="control-label">
                <span class="label-text">
                  Light Direction
                  <span class="help-tooltip" title="Direction the light is coming from">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="light-angle-value">45</span>°</span>
                  <button class="reset-btn" onclick="resetParameter('light-angle', 45)">↺</button>
                </div>
              </div>
              <input type="range" id="light-angle" min="0" max="360" step="5" value="45">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Spotlight Intensity
                  <span class="help-tooltip" title="Controls the brightness of the spotlight effect">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="spotlight-intensity-value">0.8</span></span>
                  <button class="reset-btn" onclick="resetParameter('spotlight-intensity', 0.8)">↺</button>
                </div>
              </div>
              <input type="range" id="spotlight-intensity" min="0.1" max="1" step="0.05" value="0.8">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text" id="size-label-text">
                  Spotlight Size
                  <span class="help-tooltip" title="Adjust the size of the spotlight relative to element">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="spotlight-size-value">150</span>%</span>
                  <button class="reset-btn" onclick="resetParameter('spotlight-size', 150)">↺</button>
                </div>
              </div>
              <input type="range" id="spotlight-size" min="50" max="300" step="10" value="150">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Blur Amount
                  <span class="help-tooltip" title="Add blur for a softer spotlight effect">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="blur-amount-value">8</span>px</span>
                  <button class="reset-btn" onclick="resetParameter('blur-amount', 8)">↺</button>
                </div>
              </div>
              <input type="range" id="blur-amount" min="0" max="20" step="1" value="8">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Animation Duration
                  <span class="help-tooltip" title="Duration of the spotlight animation">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="animation-duration-value">1</span>s</span>
                  <button class="reset-btn" onclick="resetParameter('animation-duration', 1)">↺</button>
                </div>
              </div>
              <input type="range" id="animation-duration" min="0.5" max="3" step="0.1" value="1">
            </div>
          </div>
        </div>

        <div class="card">
          <div class="card-heading">
            Sparkle Settings
            <div class="card-actions">
              <button class="card-action-btn" id="reset-sparkles" title="Reset Sparkle Settings">↺</button>
            </div>
          </div>
          <div class="card-content">
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">Enable Sparkles</span>
              </div>
              <div class="toggle-container">
                <label class="toggle-switch">
                  <input type="checkbox" id="sparkles-enabled" checked>
                  <span class="toggle-slider"></span>
                </label>
                <span class="toggle-label" for="sparkles-enabled">
                  Add magical sparkle effects to the spotlight
                </span>
              </div>
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Sparkle Count
                  <span class="help-tooltip" title="Number of sparkles that appear initially">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="sparkle-count-value">5</span></span>
                  <button class="reset-btn" onclick="resetParameter('sparkle-count', 5)">↺</button>
                </div>
              </div>
              <input type="range" id="sparkle-count" min="0" max="20" step="1" value="5">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Sparkle Frequency
                  <span class="help-tooltip" title="Chance of new sparkles appearing during animation">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="sparkle-frequency-value">30</span>%</span>
                  <button class="reset-btn" onclick="resetParameter('sparkle-frequency', 30)">↺</button>
                </div>
              </div>
              <input type="range" id="sparkle-frequency" min="10" max="100" step="10" value="30">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Sparkle Size
                  <span class="help-tooltip" title="Size of individual sparkles">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="sparkle-size-value">6</span>px</span>
                  <button class="reset-btn" onclick="resetParameter('sparkle-size', 6)">↺</button>
                </div>
              </div>
              <input type="range" id="sparkle-size" min="2" max="12" step="1" value="6">
            </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">Trigger Type</span>
              </div>
              <select id="trigger-type">
                <option value="scroll">Scroll Trigger</option>
                <option value="hover">Hover Effect</option>
                <option value="load">Load Immediately</option>
              </select>
            </div>
            
            <div class="control-group" id="scroll-settings">
              <div class="control-label">
                <span class="label-text">Scroll Start Position</span>
                <span class="value-text"><span id="scroll-start-value">top bottom</span></span>
              </div>
              <select id="scroll-start">
                <option value="top bottom">When element enters viewport</option>
                <option value="center bottom">When element is centered bottom</option>
                <option value="top center">When element reaches center</option>
                <option value="top top">When element reaches top</option>
              </select>
              
              <div class="control-label" style="margin-top: 1rem;">
                <span class="label-text">Scroll End Position</span>
                <span class="value-text"><span id="scroll-end-value">bottom top</span></span>
              </div>
              <select id="scroll-end">
                <option value="bottom top">When element leaves viewport</option>
                <option value="bottom center">When element centered top</option>
                <option value="center top">When element passes center</option>
                <option value="bottom bottom">When element reaches bottom</option>
              </select>
              
              <div class="control-label" style="margin-top: 1rem;">
                <span class="label-text">Reverse on Scroll</span>
              </div>
              <div class="toggle-container">
                <label class="toggle-switch">
                  <input type="checkbox" id="reverse-enabled" checked>
                  <span class="toggle-slider"></span>
                </label>
                <span class="toggle-label" for="reverse-enabled">
                  Reverse animation when scrolling up
                </span>
              </div>
            </div>
          </div>
        </div>
      </section>
    </div>
  </div>

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

  <script>
    document.addEventListener('DOMContentLoaded', function() {
      let spotlightConfig = {
        customColor: '#FF0099',
        spotlightIntensity: 0.8,
        spotlightSize: 150,
        blurAmount: 8,
        animationDuration: 1,
        sparklesEnabled: true,
        sparkleCount: 5,
        sparkleFrequency: 30,
        sparkleSize: 6,
        triggerType: 'hover',
        scrollStart: 'top bottom',
        scrollEnd: 'bottom top',
        reverseEnabled: true,
        effectType: 'soft',
        lightAngle: 45
      };

      const defaultConfig = { ...spotlightConfig };

      let activeSpotlight = null;
      let spotlightAnimation = null;
      
      function initSpotlightEffect() {
        const sections = document.querySelectorAll('[data-spotlight]:not([data-spotlight-initialized="true"])');
        
        sections.forEach((section) => {
          const customColor = section.hasAttribute('data-spotlight-color') 
            ? section.getAttribute('data-spotlight-color') 
            : spotlightConfig.customColor;
            
          const spotlightIntensity = section.hasAttribute('data-spotlight-intensity') 
            ? parseFloat(section.getAttribute('data-spotlight-intensity')) 
            : spotlightConfig.spotlightIntensity;
            
          const spotlightSize = section.hasAttribute('data-spotlight-size') 
            ? parseInt(section.getAttribute('data-spotlight-size')) 
            : spotlightConfig.spotlightSize;
            
          const blurAmount = section.hasAttribute('data-spotlight-blur') 
            ? parseInt(section.getAttribute('data-spotlight-blur')) 
            : spotlightConfig.blurAmount;
            
          const animationDuration = section.hasAttribute('data-spotlight-duration') 
            ? parseFloat(section.getAttribute('data-spotlight-duration')) 
            : spotlightConfig.animationDuration;
            
          const sparklesEnabled = section.hasAttribute('data-sparkles-enabled') 
            ? section.getAttribute('data-sparkles-enabled') === 'true' 
            : spotlightConfig.sparklesEnabled;
            
          const sparkleCount = section.hasAttribute('data-sparkle-count') 
            ? parseInt(section.getAttribute('data-sparkle-count')) 
            : spotlightConfig.sparkleCount;
            
          const sparkleFrequency = section.hasAttribute('data-sparkle-frequency') 
            ? parseInt(section.getAttribute('data-sparkle-frequency')) 
            : spotlightConfig.sparkleFrequency;
            
          const sparkleSize = section.hasAttribute('data-sparkle-size') 
            ? parseInt(section.getAttribute('data-sparkle-size')) 
            : spotlightConfig.sparkleSize;
            
          const triggerType = section.hasAttribute('data-trigger-type') 
            ? section.getAttribute('data-trigger-type') 
            : spotlightConfig.triggerType;
            
          const scrollStart = section.hasAttribute('data-scroll-start') 
            ? section.getAttribute('data-scroll-start') 
            : spotlightConfig.scrollStart;
            
          const scrollEnd = section.hasAttribute('data-scroll-end') 
            ? section.getAttribute('data-scroll-end') 
            : spotlightConfig.scrollEnd;
            
          const reverseEnabled = section.hasAttribute('data-reverse-enabled') 
            ? section.getAttribute('data-reverse-enabled') === 'true' 
            : spotlightConfig.reverseEnabled;
            
          const effectType = section.hasAttribute('data-effect-type') 
            ? section.getAttribute('data-effect-type') 
            : spotlightConfig.effectType;
            
          const lightAngle = section.hasAttribute('data-light-angle') 
            ? parseInt(section.getAttribute('data-light-angle')) 
            : spotlightConfig.lightAngle;
            
          const options = {
            customColor,
            spotlightIntensity,
            spotlightSize,
            blurAmount,
            animationDuration,
            sparklesEnabled,
            sparkleCount,
            sparkleFrequency,
            sparkleSize,
            triggerType,
            scrollStart,
            scrollEnd,
            reverseEnabled,
            effectType,
            lightAngle
          };
          
          setupSpotlightEffect(section, options);
          section.dataset.spotlightInitialized = 'true';
          
          if (section.id === 'spotlight-preview') {
            activeSpotlight = { element: section, options };
            Object.assign(spotlightConfig, options);
          }
        });
      }
      
      function setupSpotlightEffect(element, options) {
        if (window.getComputedStyle(element).position === 'static') {
          element.style.position = 'relative';
        }
        
        element.style.overflow = 'hidden';
        
        element.spotlightOptions = options;
        element.spotlightParticles = [];
        element.sparkleInterval = null;
        
        resetTextEnhancements(element);
        
        const wrapper = document.createElement('div');
        wrapper.className = 'spotlight-wrapper';
        
        const spotlight = document.createElement('div');
        spotlight.className = 'spotlight-element';
        
        applySpotlightStyles(spotlight, options);
        wrapper.appendChild(spotlight);
        element.appendChild(wrapper);
        
        if (options.effectType === 'window') {
          setupTextEnhancement(element, options);
        }
        
        if (options.sparklesEnabled) {
          const sparkleArea = document.createElement('div');
          sparkleArea.className = 'sparkle-area';
          sparkleArea.style.cssText = `
            position: absolute;
            width: 100%;
            height: 100%;
            left: 0;
            top: 0;
            overflow: hidden;
            pointer-events: none;
          `;
          
          if (options.effectType === 'window') {
            const size = options.spotlightSize;
            sparkleArea.style.width = `${size * 0.8}%`;
            sparkleArea.style.height = `${size * 0.8}%`;
            sparkleArea.style.left = `${(100 - size * 0.8) / 2}%`;
            sparkleArea.style.top = `${(100 - size * 0.8) / 2}%`;
            sparkleArea.style.transform = `rotate(${options.lightAngle}deg)`;
          }
          
          wrapper.appendChild(sparkleArea);
          
          for (let i = 0; i < options.sparkleCount; i++) {
            createSparkle(sparkleArea, options);
          }
        }
        
        setupSpotlightTrigger(element, spotlight, options);
        
        element._cleanupSpotlight = () => {
          if (element.sparkleInterval) {
            clearInterval(element.sparkleInterval);
          }
          if (wrapper.parentNode) {
            wrapper.parentNode.removeChild(wrapper);
          }
          element.dataset.spotlightInitialized = 'false';
        };
      }

      function updateConfig(element, newOptions) {
        if (!element || !element.spotlightOptions) return;
        
        Object.assign(element.spotlightOptions, newOptions);
        
        const wrapper = element.querySelector('.spotlight-wrapper');
        const spotlight = wrapper?.querySelector('.spotlight-element');
        
        if (spotlight) {
          applySpotlightStyles(spotlight, element.spotlightOptions);
        }
        
        const sparkleArea = wrapper?.querySelector('.sparkle-area');
        if (sparkleArea && element.spotlightOptions.sparklesEnabled) {
          if (element.spotlightOptions.effectType === 'window') {
            const size = element.spotlightOptions.spotlightSize;
            sparkleArea.style.width = `${size * 0.8}%`;
            sparkleArea.style.height = `${size * 0.8}%`;
            sparkleArea.style.left = `${(100 - size * 0.8) / 2}%`;
            sparkleArea.style.top = `${(100 - size * 0.8) / 2}%`;
            sparkleArea.style.transform = `rotate(${element.spotlightOptions.lightAngle}deg)`;
          }
        }
        
        if (element.spotlightOptions.effectType === 'window') {
          setupTextEnhancement(element, element.spotlightOptions);
        }
      }
      
      function applySpotlightStyles(spotlight, options) {
        const size = options.spotlightSize;
        let offsetX = 0;
        let offsetY = 0;
        
        spotlight.style.filter = `blur(${options.blurAmount}px)`;
        spotlight.style.transition = `all ${options.animationDuration}s ease`;
        
        if (options.effectType === 'soft') {
          spotlight.style.width = `${size * 1.2}%`;
          spotlight.style.height = `${size * 1.2}%`;
          
          const angle = options.lightAngle * (Math.PI / 180);
          offsetX = Math.cos(angle) * (size * 0.05);
          offsetY = Math.sin(angle) * (size * 0.05);
          
          spotlight.style.left = `${(100 - size * 1.2) / 2 - offsetX}%`;
          spotlight.style.top = `${(100 - size * 1.2) / 2 - offsetY}%`;
          spotlight.style.transform = 'scale(0.9)';
          spotlight.style.mixBlendMode = 'soft-light';
          spotlight.style.background = createGradient(options.customColor, options.spotlightIntensity);
        } 
        else if (options.effectType === 'harsh') {
          spotlight.style.width = `${size * 0.8}%`;
          spotlight.style.height = `${size * 0.8}%`;
          
          const angle = options.lightAngle * (Math.PI / 180);
          offsetX = Math.cos(angle) * (size * 0.15);
          offsetY = Math.sin(angle) * (size * 0.15);
          
          spotlight.style.left = `${(100 - size * 0.8) / 2 - offsetX}%`;
          spotlight.style.top = `${(100 - size * 0.8) / 2 - offsetY}%`;
          spotlight.style.transform = 'scale(0.8)';
          spotlight.style.mixBlendMode = 'lighten';
          spotlight.style.background = createDirectionalGradient(options.customColor, options.spotlightIntensity);
        } 
        else if (options.effectType === 'window') {
          const angle = options.lightAngle;
          const diagonalLength = Math.sqrt(2) * 100 * 1.5;
          
          spotlight.style.width = `${diagonalLength}%`;
          spotlight.style.height = `${options.spotlightSize}%`;
          spotlight.style.left = `${(100 - diagonalLength) / 2}%`;
          spotlight.style.top = `${(100 - options.spotlightSize) / 2}%`;
          spotlight.style.transform = `rotate(${angle}deg)`;
          spotlight.style.transformOrigin = 'center center';
          spotlight.style.mixBlendMode = 'screen';
          spotlight.style.background = createCinematicGradient(options.customColor, options.spotlightIntensity);
          
          const r = parseInt(options.customColor.substr(1, 2), 16);
          const g = parseInt(options.customColor.substr(3, 2), 16);
          const b = parseInt(options.customColor.substr(5, 2), 16);
          spotlight.style.boxShadow = `0 0 ${options.blurAmount * 2}px rgba(${r}, ${g}, ${b}, 0.15)`;
        } 
        else if (options.effectType === 'ambient') {
          spotlight.style.width = `170%`;
          spotlight.style.height = `170%`;
          spotlight.style.left = `-35%`;
          spotlight.style.top = `-35%`;
          spotlight.style.opacity = `0`;
          spotlight.style.mixBlendMode = 'soft-light';
          spotlight.style.animation = `pulse ${options.animationDuration * 5}s infinite alternate ease-in-out`;
          spotlight.style.background = createAmbientGradient(options.customColor, options.spotlightIntensity);
        }
      }
      
      function setupSpotlightTrigger(element, spotlight, options) {
        if (options.triggerType === 'hover') {
          element.addEventListener('mouseenter', () => {
            activateSpotlight(spotlight, options);
            if (options.sparklesEnabled) {
              startSparkleAnimation(element, options);
            }
          });
          
          element.addEventListener('mouseleave', () => {
            deactivateSpotlight(spotlight, options);
            if (element.sparkleInterval) {
              clearInterval(element.sparkleInterval);
              element.sparkleInterval = null;
            }
          });
        } else if (options.triggerType === 'load') {
          setTimeout(() => {
            activateSpotlight(spotlight, options);
            if (options.sparklesEnabled) {
              startSparkleAnimation(element, options);
            }
          }, 100);
        }
      }
      
      function activateSpotlight(spotlight, options) {
        spotlight.style.opacity = '1';
        
        if (options.effectType === 'window') {
          spotlight.style.transform = `rotate(${options.lightAngle}deg)`;
        } else if (options.effectType === 'soft') {
          spotlight.style.transform = 'scale(1.05)';
        } else if (options.effectType === 'harsh') {
          spotlight.style.transform = 'scale(0.95)';
        } else {
          spotlight.style.transform = 'scale(1)';
        }
      }
      
      function deactivateSpotlight(spotlight, options) {
        spotlight.style.opacity = '0';
        
        if (options.effectType === 'window') {
          spotlight.style.transform = `rotate(${options.lightAngle}deg)`;
        } else if (options.effectType === 'soft') {
          spotlight.style.transform = 'scale(0.9)';
        } else if (options.effectType === 'harsh') {
          spotlight.style.transform = 'scale(0.8)';
        } else {
          spotlight.style.transform = 'scale(0.9)';
        }
      }
      
      function updateSpotlightPreview() {
        const preview = document.getElementById('spotlight-preview');
        if (!preview) return;
        
        updateConfig(preview, spotlightConfig);
        updateEffectTypeUI();
        updateColorInputs();
        saveConfiguration();
      }
      
      function updateEffectTypeUI() {
        const angleControl = document.getElementById('angle-control');
        const sizeLabel = document.getElementById('size-label-text');
        
        if (spotlightConfig.effectType === 'window') {
          angleControl.style.display = 'block';
          sizeLabel.textContent = 'Beam Width';
        } else {
          angleControl.style.display = 'none';
          sizeLabel.textContent = 'Spotlight Size';
        }
      }

      function createGradient(color, intensity) {
        const r = parseInt(color.substr(1, 2), 16);
        const g = parseInt(color.substr(3, 2), 16);
        const b = parseInt(color.substr(5, 2), 16);
        
        return `radial-gradient(
          circle at center,
          rgba(${r}, ${g}, ${b}, ${intensity}) 0%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.9}) 5%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.85}) 10%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.7}) 20%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.5}) 35%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.25}) 50%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.1}) 65%,
          rgba(${r}, ${g}, ${b}, 0) 80%
        )`;
      }
      
      function createDirectionalGradient(color, intensity) {
        const r = parseInt(color.substr(1, 2), 16);
        const g = parseInt(color.substr(3, 2), 16);
        const b = parseInt(color.substr(5, 2), 16);
        
        return `radial-gradient(
          circle at center,
          rgba(${r + 30 > 255 ? 255 : r + 30}, ${g + 30 > 255 ? 255 : g + 30}, ${b + 30 > 255 ? 255 : b + 30}, ${intensity * 1.2}) 0%,
          rgba(${r}, ${g}, ${b}, ${intensity}) 10%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.8}) 20%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.5}) 30%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.2}) 40%,
          rgba(${r}, ${g}, ${b}, 0) 50%
        )`;
      }
      
      function createCinematicGradient(color, intensity) {
        const r = parseInt(color.substr(1, 2), 16);
        const g = parseInt(color.substr(3, 2), 16);
        const b = parseInt(color.substr(5, 2), 16);
        
        const warmerR = Math.min(255, r + 15);
        const warmerG = Math.min(255, g + 5);
        const coolerB = Math.max(0, b - 5);
        
        return `linear-gradient(
          to right,
          rgba(${r}, ${g}, ${b}, 0) 0%,
          rgba(${warmerR}, ${warmerG}, ${coolerB}, ${intensity * 0.2}) 15%,
          rgba(${warmerR}, ${warmerG}, ${coolerB}, ${intensity * 0.9}) 50%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.2}) 85%,
          rgba(${r}, ${g}, ${b}, 0) 100%
        )`;
      }
      
      function createAmbientGradient(color, intensity) {
        const r = parseInt(color.substr(1, 2), 16);
        const g = parseInt(color.substr(3, 2), 16);
        const b = parseInt(color.substr(5, 2), 16);
        
        return `radial-gradient(
          ellipse at center,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.25}) 0%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.2}) 30%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.15}) 50%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.1}) 70%,
          rgba(${r}, ${g}, ${b}, ${intensity * 0.05}) 85%,
          rgba(${r}, ${g}, ${b}, 0) 100%
        )`;
      }
      
      function createSparkle(container, options) {
        const sparkle = document.createElement('div');
        sparkle.className = 'sparkle';
        
        let sparkleSize = options.sparkleSize;
        let x, y;
        
        if (options.effectType === 'soft') {
          sparkleSize *= 1.2;
          sparkle.style.filter = `blur(${Math.max(1, options.blurAmount / 4)}px)`;
          sparkle.style.backgroundColor = 'white';
        } 
        else if (options.effectType === 'harsh') {
          sparkleSize *= 0.8;
          sparkle.style.filter = `blur(0.5px)`;
          sparkle.style.backgroundColor = '#fff';
          sparkle.style.boxShadow = `0 0 3px rgba(255, 255, 255, 0.8)`;
        }
        else if (options.effectType === 'window') {
          sparkleSize *= (Math.random() * 0.5 + 0.3);
          sparkle.style.filter = `blur(${Math.random() * 1.5 + 0.5}px)`;
          
          x = Math.random() * 40 + 30;
          y = Math.random() * 90 + 5;
          
          const r = parseInt(options.customColor.substr(1, 2), 16);
          const g = parseInt(options.customColor.substr(3, 2), 16);
          const b = parseInt(options.customColor.substr(5, 2), 16);
          sparkle.style.backgroundColor = `rgba(${Math.min(255, r + 30)}, ${Math.min(255, g + 20)}, ${b}, 1)`;
          
          sparkle.style.left = `${x}%`;
          sparkle.style.top = `${y}%`;
          
          const duration = Math.random() * 3 + 1.5;
          sparkle.style.animation = `sparkle ${duration}s ease-in-out`;
          
          container.appendChild(sparkle);
          setTimeout(() => sparkle.remove(), duration * 1000);
          return;
        }
        else if (options.effectType === 'ambient') {
          sparkleSize *= (Math.random() * 0.4 + 0.3);
          sparkle.style.filter = `blur(${Math.random() * 2 + 1}px)`;
          sparkle.style.backgroundColor = 'rgba(255, 255, 255, 0.7)';
        }
        
        sparkle.style.width = `${sparkleSize}px`;
        sparkle.style.height = `${sparkleSize}px`;
        sparkle.style.borderRadius = '50%';
        sparkle.style.position = 'absolute';
        sparkle.style.opacity = '0';
        
        if (!x) x = Math.random() * 60 + 20;
        if (!y) y = Math.random() * 60 + 20;
        
        sparkle.style.left = `${x}%`;
        sparkle.style.top = `${y}%`;
        
        const duration = Math.random() * 1 + 0.5;
        sparkle.style.animation = `sparkle ${duration * 1.5}s ease-in-out`;
        
        container.appendChild(sparkle);
        setTimeout(() => sparkle.remove(), duration * 1500);
      }
      
      function startSparkleAnimation(element, options) {
        if (element.sparkleInterval) {
          clearInterval(element.sparkleInterval);
        }
        
        const sparkleArea = element.querySelector('.sparkle-area');
        if (!sparkleArea) return;
        
        element.sparkleInterval = setInterval(() => {
          if (Math.random() < options.sparkleFrequency / 100) {
            createSparkle(sparkleArea, options);
          }
        }, 500);
      }

      function setupTextEnhancement(element, options) {
        const textElements = element.querySelectorAll('h1, h2, h3, h4, h5, h6, p, span, div:not(.spotlight-wrapper):not(.sparkle-area)');
        
        if (textElements.length > 0) {
          element.classList.add('has-spotlight-text-enhancement');
          
          textElements.forEach(textEl => {
            if (textEl.textContent.trim() !== '') {
              textEl.classList.add('spotlight-enhanced-text');
              
              const originalStyles = {
                textShadow: textEl.style.textShadow || '',
                color: textEl.style.color || '',
                transition: textEl.style.transition || ''
              };
              
              textEl._originalTextStyles = originalStyles;
              textEl.style.transition = `all ${options.animationDuration * 1.2}s ease`;
            }
          });
        }
      }

      function resetTextEnhancements(container) {
        const textElements = container.querySelectorAll('h1, h2, h3, h4, h5, h6, p, span');
        
        textElements.forEach(textEl => {
          if (textEl._originalTextStyles) {
            textEl.style.color = textEl._originalTextStyles.color;
            textEl.style.textShadow = textEl._originalTextStyles.textShadow;
          }
        });
      }

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

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

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

      function generateFullSectionJSON() {
  // Generar IDs únicos para todos los elementos
  const sectionId = generateUniqueId();
  const containerId = generateUniqueId();
  const textId = generateUniqueId();
  const codeId = generateUniqueId();

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

  // Crear el objeto JSON completo de Bricks Builder
  const bricksJSON = {
    "content": [
      {
        "id": sectionId,
        "name": "section",
        "parent": 0,
        "children": [containerId, codeId],
        "settings": {
          "_height": "500",
          "_attributes": [
            {
              "id": generateUniqueId(),
              "name": "data-spotlight"
            }
          ],
          "_justifyContent": "center",
          "_background": {
            "color": {
              "hex": "#000000"
            }
          }
        },
        "label": "Spotlight Section"
      },
      {
        "id": containerId,
        "name": "container",
        "parent": sectionId,
        "children": [textId],
        "settings": {
          "_alignItems": "center",
          "_overflow": "hidden"
        }
      },
      {
        "id": textId,
        "name": "text-basic",
        "parent": containerId,
        "children": [],
        "settings": {
          "text": "Spotlight",
          "tag": "span",
          "_typography": {
            "color": {
              "hex": "#ffffff"
            },
            "font-weight": "400"
          }
        }
      },
      {
        "id": codeId,
        "name": "code",
        "parent": sectionId,
        "children": [],
        "settings": {
          "javascriptCode": jsCode,
          "executeCode": true,
          "_display": "none"
        },
        "label": "Spotlight JS"
      }
    ],
    "source": "bricksCopiedElements",
    "sourceUrl": "https://test.bricksfusion.com",
    "version": "2.0.1",
    "globalClasses": [],
    "globalElements": []
  };

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

      function generateJavaScriptCode() {
        return `(function() {
  class SpotlightEffect {
    constructor() {
      if (window.SpotlightEffectInstance) {
        return window.SpotlightEffectInstance;
      }
      window.SpotlightEffectInstance = this;
      
      this.gsap = null;
      this.ScrollTrigger = null;
      this.isGSAPLoaded = false;
      
      this.config = {
        customColor: "${spotlightConfig.customColor}",
        spotlightIntensity: ${spotlightConfig.spotlightIntensity},
        spotlightSize: ${spotlightConfig.spotlightSize},
        blurAmount: ${spotlightConfig.blurAmount},
        animationDuration: ${spotlightConfig.animationDuration},
        sparklesEnabled: ${spotlightConfig.sparklesEnabled},
        sparkleCount: ${spotlightConfig.sparkleCount},
        sparkleFrequency: ${spotlightConfig.sparkleFrequency},
        sparkleSize: ${spotlightConfig.sparkleSize},
        triggerType: "${spotlightConfig.triggerType}",
        scrollStart: "${spotlightConfig.scrollStart}",
        scrollEnd: "${spotlightConfig.scrollEnd}",
        reverseEnabled: ${spotlightConfig.reverseEnabled},
        effectType: "${spotlightConfig.effectType}",
        lightAngle: ${spotlightConfig.lightAngle}
      };
      
      this.initialized = false;
      this.initialize();
    }

    async initialize() {
      if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => this.initializeEffects());
      } else {
        this.initializeEffects();
      }
      this.setupObservers();
    }

    async initializeEffects() {
      if (this.initialized) return;
      this.initialized = true;
      
      if (this.config.triggerType === 'scroll') {
        await this.loadGSAP();
      }
      
      this.setupEffects();
    }
    
    async loadGSAP() {
      if (this.isGSAPLoaded) return;
      
      try {
        if (!window.gsap) {
          await this.loadScript('https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js');
        }
        if (!window.ScrollTrigger) {
          await this.loadScript('https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/ScrollTrigger.min.js');
        }
        
        this.gsap = window.gsap;
        this.ScrollTrigger = window.ScrollTrigger;
        this.gsap.registerPlugin(this.ScrollTrigger);
        this.isGSAPLoaded = true;
      } catch (error) {
        
      }
    }
    
    loadScript(src) {
      return new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.src = src;
        script.onload = resolve;
        script.onerror = reject;
        document.head.appendChild(script);
      });
    }

    setupObservers() {
      const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
          mutation.addedNodes.forEach(node => {
            if (node.nodeType === 1) {
              if (node.hasAttribute('data-spotlight')) {
                this.setupEffect(node);
              } else if (node.querySelectorAll) {
                node.querySelectorAll('[data-spotlight]').forEach(el => {
                  this.setupEffect(el);
                });
              }
            }
          });
        });
      });

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

    setupEffects() {
      document.querySelectorAll('[data-spotlight]').forEach(element => {
        if (!element.hasAttribute('data-spotlight-initialized')) {
          this.setupEffect(element);
        }
      });
    }

    setupEffect(element) {
      if (element.hasAttribute('data-spotlight-initialized')) return;

      const options = {
        customColor: element.getAttribute('data-spotlight-color') || this.config.customColor,
        spotlightIntensity: parseFloat(element.getAttribute('data-spotlight-intensity')) || this.config.spotlightIntensity,
        spotlightSize: parseInt(element.getAttribute('data-spotlight-size')) || this.config.spotlightSize,
        blurAmount: parseInt(element.getAttribute('data-spotlight-blur')) || this.config.blurAmount,
        animationDuration: parseFloat(element.getAttribute('data-spotlight-duration')) || this.config.animationDuration,
        sparklesEnabled: element.getAttribute('data-sparkles-enabled') !== null ? 
          element.getAttribute('data-sparkles-enabled') === 'true' : this.config.sparklesEnabled,
        sparkleCount: parseInt(element.getAttribute('data-sparkle-count')) || this.config.sparkleCount,
        sparkleFrequency: parseInt(element.getAttribute('data-sparkle-frequency')) || this.config.sparkleFrequency,
        sparkleSize: parseInt(element.getAttribute('data-sparkle-size')) || this.config.sparkleSize,
        triggerType: element.getAttribute('data-trigger-type') || this.config.triggerType,
        scrollStart: element.getAttribute('data-scroll-start') || this.config.scrollStart,
        scrollEnd: element.getAttribute('data-scroll-end') || this.config.scrollEnd,
        reverseEnabled: element.getAttribute('data-reverse-enabled') !== null ?
          element.getAttribute('data-reverse-enabled') === 'true' : this.config.reverseEnabled,
        effectType: element.getAttribute('data-effect-type') || this.config.effectType,
        lightAngle: parseInt(element.getAttribute('data-light-angle')) || this.config.lightAngle
      };

      element.style.position = 'relative';
      element.style.overflow = 'hidden';

      if (options.effectType === 'window') {
        this.setupTextEnhancement(element, options);
      }

      const wrapper = document.createElement('div');
      wrapper.style.cssText = \`
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        overflow: hidden;
        pointer-events: none;
      \`;
      element.appendChild(wrapper);

      const spotlight = document.createElement('div');
      const size = options.spotlightSize;
      spotlight.style.cssText = \`
        position: absolute;
        opacity: 0;
        filter: blur(\${options.blurAmount}px);
        transition: all \${options.animationDuration}s ease;
      \`;
      
      if (options.effectType === 'soft') {
        spotlight.style.width = \`\${size * 1.2}%\`;
        spotlight.style.height = \`\${size * 1.2}%\`;
        
        const angle = options.lightAngle * (Math.PI / 180);
        const offsetX = Math.cos(angle) * (size * 0.05);
        const offsetY = Math.sin(angle) * (size * 0.05);
        
        spotlight.style.left = \`\${(100 - size * 1.2) / 2 - offsetX}%\`;
        spotlight.style.top = \`\${(100 - size * 1.2) / 2 - offsetY}%\`;
        spotlight.style.transform = 'scale(0.9)';
        spotlight.style.mixBlendMode = 'soft-light';
        spotlight.style.background = this.createGradient(options.customColor, options.spotlightIntensity);
      } 
      else if (options.effectType === 'harsh') {
        spotlight.style.width = \`\${size * 0.8}%\`;
        spotlight.style.height = \`\${size * 0.8}%\`;
        
        const angle = options.lightAngle * (Math.PI / 180);
        const offsetX = Math.cos(angle) * (size * 0.15);
        const offsetY = Math.sin(angle) * (size * 0.15);
        
        spotlight.style.left = \`\${(100 - size * 0.8) / 2 - offsetX}%\`;
        spotlight.style.top = \`\${(100 - size * 0.8) / 2 - offsetY}%\`;
        spotlight.style.transform = 'scale(0.8)';
        spotlight.style.mixBlendMode = 'lighten';
        spotlight.style.background = this.createDirectionalGradient(options.customColor, options.spotlightIntensity);
      } 
      else if (options.effectType === 'window') {
        const angle = options.lightAngle;
        const diagonalLength = Math.sqrt(2) * 100 * 1.5;
        
        spotlight.style.width = \`\${diagonalLength}%\`;
        spotlight.style.height = \`\${options.spotlightSize}%\`;
        spotlight.style.left = \`\${(100 - diagonalLength) / 2}%\`;
        spotlight.style.top = \`\${(100 - options.spotlightSize) / 2}%\`;
        spotlight.style.transform = \`rotate(\${angle}deg)\`;
        spotlight.style.transformOrigin = 'center center';
        spotlight.style.mixBlendMode = 'screen';
        spotlight.style.background = this.createCinematicGradient(options.customColor, options.spotlightIntensity);
        
        spotlight.style.boxShadow = \`0 0 \${options.blurAmount * 2}px rgba(\${parseInt(options.customColor.substr(1, 2), 16)}, \${parseInt(options.customColor.substr(3, 2), 16)}, \${parseInt(options.customColor.substr(5, 2), 16)}, 0.15)\`;
      } 
      else if (options.effectType === 'ambient') {
        spotlight.style.width = \`170%\`;
        spotlight.style.height = \`170%\`;
        spotlight.style.left = \`-35%\`;
        spotlight.style.top = \`-35%\`;
        spotlight.style.opacity = \`0\`;
        spotlight.style.mixBlendMode = 'soft-light';
        spotlight.style.animation = \`pulse \${options.animationDuration * 5}s infinite alternate ease-in-out\`;
        spotlight.style.background = this.createAmbientGradient(options.customColor, options.spotlightIntensity);
      }
      
      wrapper.appendChild(spotlight);

      const sparklesContainer = document.createElement('div');
      sparklesContainer.style.cssText = \`
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        overflow: hidden;
        pointer-events: none;
      \`;
      
      if (options.effectType === 'window') {
        sparklesContainer.style.width = \`\${size * 0.8}%\`;
        sparklesContainer.style.height = \`\${size * 0.8}%\`;
        sparklesContainer.style.left = \`\${(100 - size * 0.8) / 2}%\`;
        sparklesContainer.style.top = \`\${(100 - size * 0.8) / 2}%\`;
        sparklesContainer.style.transform = \`rotate(\${options.lightAngle}deg)\`;
      }
      
      wrapper.appendChild(sparklesContainer);

      if (options.sparklesEnabled) {
        for (let i = 0; i < options.sparkleCount; i++) {
          this.createSparkle(sparklesContainer, options);
        }
      }

      if (options.triggerType === 'hover') {
        element.addEventListener('mouseenter', () => {
          spotlight.style.opacity = '1';
          if (options.effectType === 'window') {
            spotlight.style.transform = \`rotate(\${options.lightAngle}deg)\`;
          } else if (options.effectType === 'soft') {
            spotlight.style.transform = 'scale(1.05)';
          } else if (options.effectType === 'harsh') {
            spotlight.style.transform = 'scale(0.95)';
          } else {
            spotlight.style.transform = 'scale(1)';
          }
          
          if (options.sparklesEnabled) {
            this.startSparkleAnimation(sparklesContainer, options);
          }
        });
        
        element.addEventListener('mouseleave', () => {
          spotlight.style.opacity = '0';
          if (options.effectType === 'window') {
            spotlight.style.transform = \`rotate(\${options.lightAngle}deg)\`;
          } else if (options.effectType === 'soft') {
            spotlight.style.transform = 'scale(0.9)';
          } else if (options.effectType === 'harsh') {
            spotlight.style.transform = 'scale(0.8)';
          } else {
            spotlight.style.transform = 'scale(0.9)';
          }
          
          if (sparklesContainer.sparkleInterval) {
            clearInterval(sparklesContainer.sparkleInterval);
            sparklesContainer.sparkleInterval = null;
          }
        });
      } else if (options.triggerType === 'load') {
        setTimeout(() => {
          spotlight.style.opacity = '1';
          if (options.effectType === 'window') {
            spotlight.style.transform = \`rotate(\${options.lightAngle}deg)\`;
          } else if (options.effectType === 'soft') {
            spotlight.style.transform = 'scale(1.05)';
          } else if (options.effectType === 'harsh') {
            spotlight.style.transform = 'scale(0.95)';
          } else {
            spotlight.style.transform = 'scale(1)';
          }
          
          if (options.sparklesEnabled) {
            this.startSparkleAnimation(sparklesContainer, options);
          }
        }, 100);
      } else if (options.triggerType === 'scroll' && this.gsap && this.ScrollTrigger) {
        const transformValue = options.effectType === 'window' 
          ? \`rotate(\${options.lightAngle}deg)\` 
          : options.effectType === 'soft'
            ? 'scale(1.05)'
            : options.effectType === 'harsh'
              ? 'scale(0.95)'
              : 'scale(1)';
        
        this.gsap.to(spotlight, {
          opacity: 1,
          transform: transformValue,
          duration: options.animationDuration,
          ease: "power2.out",
          scrollTrigger: {
            trigger: element,
            start: options.scrollStart,
            end: options.scrollEnd,
            toggleActions: options.reverseEnabled ? "play none none reverse" : "play none none none",
            onUpdate: (self) => {
              if (options.sparklesEnabled && self.isActive && Math.random() < options.sparkleFrequency / 100) {
                this.createSparkle(sparklesContainer, options);
              }
              
              if (options.effectType === 'window' && element.classList.contains('has-spotlight-text-enhancement')) {
                const textElements = element.querySelectorAll('.spotlight-enhanced-text');
                const progress = self.progress;
                
                if (textElements.length > 0) {
                  const r = parseInt(options.customColor.substr(1, 2), 16);
                  const g = parseInt(options.customColor.substr(3, 2), 16);
                  const b = parseInt(options.customColor.substr(5, 2), 16);
                  
                  textElements.forEach(textEl => {
                    if (self.isActive && progress > 0.1) {
                      this.enhanceText(textEl, r, g, b, options.spotlightIntensity * progress);
                    } else {
                      this.resetTextEnhancement(textEl);
                    }
                  });
                }
              }
            }
          }
        });
      }

      element.setAttribute('data-spotlight-initialized', 'true');
    }
    
    createGradient(color, intensity) {
      const r = parseInt(color.substr(1, 2), 16);
      const g = parseInt(color.substr(3, 2), 16);
      const b = parseInt(color.substr(5, 2), 16);
      
      return \`radial-gradient(
        ellipse at center,
        rgba(\${r}, \${g}, \${b}, \${intensity}) 0%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.9}) 5%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.85}) 10%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.7}) 20%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.5}) 35%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.25}) 50%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.1}) 65%,
        rgba(\${r}, \${g}, \${b}, 0) 80%
      )\`;
    }
    
    createDirectionalGradient(color, intensity) {
      const r = parseInt(color.substr(1, 2), 16);
      const g = parseInt(color.substr(3, 2), 16);
      const b = parseInt(color.substr(5, 2), 16);
      
      return \`radial-gradient(
        circle at center,
        rgba(\${r + 30 > 255 ? 255 : r + 30}, \${g + 30 > 255 ? 255 : g + 30}, \${b + 30 > 255 ? 255 : b + 30}, \${intensity * 1.2}) 0%,
        rgba(\${r}, \${g}, \${b}, \${intensity}) 10%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.8}) 20%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.5}) 30%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.2}) 40%,
        rgba(\${r}, \${g}, \${b}, 0) 50%
      )\`;
    }
    
    createCinematicGradient(color, intensity) {
      const r = parseInt(color.substr(1, 2), 16);
      const g = parseInt(color.substr(3, 2), 16);
      const b = parseInt(color.substr(5, 2), 16);
      
      const warmerR = Math.min(255, r + 15);
      const warmerG = Math.min(255, g + 5);
      const coolerB = Math.max(0, b - 5);
      
      return \`linear-gradient(
        to right,
        rgba(\${r}, \${g}, \${b}, 0) 0%,
        rgba(\${warmerR}, \${warmerG}, \${coolerB}, \${intensity * 0.2}) 15%,
        rgba(\${warmerR}, \${warmerG}, \${coolerB}, \${intensity * 0.9}) 50%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.2}) 85%,
        rgba(\${r}, \${g}, \${b}, 0) 100%
      )\`;
    }
    
    createAmbientGradient(color, intensity) {
      const r = parseInt(color.substr(1, 2), 16);
      const g = parseInt(color.substr(3, 2), 16);
      const b = parseInt(color.substr(5, 2), 16);
      
      return \`radial-gradient(
        ellipse at center,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.25}) 0%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.2}) 30%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.15}) 50%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.1}) 70%,
        rgba(\${r}, \${g}, \${b}, \${intensity * 0.05}) 85%,
        rgba(\${r}, \${g}, \${b}, 0) 100%
      )\`;
    }
    
    createSparkle(container, options) {
      const sparkle = document.createElement('div');
      
      if (options.effectType === 'soft') {
        sparkle.style.cssText = \`
          position: absolute;
          width: \${options.sparkleSize * 1.2}px;
          height: \${options.sparkleSize * 1.2}px;
          border-radius: 50%;
          opacity: 0;
          filter: blur(\${Math.max(1, options.blurAmount / 4)}px);
          background-color: white;
        \`;
      } 
      else if (options.effectType === 'harsh') {
        sparkle.style.cssText = \`
          position: absolute;
          width: \${options.sparkleSize * 0.8}px;
          height: \${options.sparkleSize * 0.8}px;
          border-radius: 50%;
          opacity: 0;
          filter: blur(0.5px);
          background-color: #fff;
          box-shadow: 0 0 3px rgba(255, 255, 255, 0.8);
        \`;
      }
      else if (options.effectType === 'window') {
        const sparkleSize = options.sparkleSize * (Math.random() * 0.5 + 0.3);
        
        sparkle.style.cssText = \`
          position: absolute;
          width: \${sparkleSize}px;
          height: \${sparkleSize}px;
          border-radius: 50%;
          opacity: 0;
          filter: blur(\${Math.random() * 1.5 + 0.5}px);
        \`;
        
        const x = Math.random() * 40 + 30;
        const y = Math.random() * 90 + 5;
        
        const r = parseInt(options.customColor.substr(1, 2), 16);
        const g = parseInt(options.customColor.substr(3, 2), 16);
        const b = parseInt(options.customColor.substr(5, 2), 16);
        
        sparkle.style.backgroundColor = \`rgba(\${Math.min(255, r + 30)}, \${Math.min(255, g + 20)}, \${b}, 1)\`;
        sparkle.style.left = \`\${x}%\`;
        sparkle.style.top = \`\${y}%\`;
        
        const duration = Math.random() * 3 + 1.5;
        sparkle.style.animation = \`sparkle \${duration}s ease-in-out\`;
        
        container.appendChild(sparkle);
        setTimeout(() => sparkle.remove(), duration * 1000);
        return;
      }
      else if (options.effectType === 'ambient') {
        const sparkleSize = options.sparkleSize * (Math.random() * 0.4 + 0.3);
        
        sparkle.style.cssText = \`
          position: absolute;
          width: \${sparkleSize}px;
          height: \${sparkleSize}px;
          border-radius: 50%;
          opacity: 0;
          filter: blur(\${Math.random() * 2 + 1}px);
          background-color: rgba(255, 255, 255, 0.7);
        \`;
      }
      else {
        sparkle.style.cssText = \`
          position: absolute;
          width: \${options.sparkleSize}px;
          height: \${options.sparkleSize}px;
          border-radius: 50%;
          opacity: 0;
          filter: blur(1px);
          background-color: white;
        \`;
      }
      
      if (options.effectType !== 'window') {
        const x = Math.random() * 60 + 20;
        const y = Math.random() * 60 + 20;
        const duration = Math.random() * 1 + 0.5;
        
        sparkle.style.left = \`\${x}%\`;
        sparkle.style.top = \`\${y}%\`;
        sparkle.style.animation = \`sparkle \${duration * 1.5}s ease-in-out\`;
        
        container.appendChild(sparkle);
        setTimeout(() => sparkle.remove(), duration * 1500);
      }
    }
    
    startSparkleAnimation(container, options) {
      if (container.sparkleInterval) {
        clearInterval(container.sparkleInterval);
      }
      
      container.sparkleInterval = setInterval(() => {
        if (Math.random() < options.sparkleFrequency / 100) {
          this.createSparkle(container, options);
        }
      }, 500);
    }
    
    setupTextEnhancement(element, options) {
      const textElements = element.querySelectorAll('h1, h2, h3, h4, h5, h6, p, span, div:not(.spotlight-wrapper):not(.sparkle-area)');
      
      const r = parseInt(options.customColor.substr(1, 2), 16);
      const g = parseInt(options.customColor.substr(3, 2), 16);
      const b = parseInt(options.customColor.substr(5, 2), 16);
      
      if (textElements.length > 0) {
        element.classList.add('has-spotlight-text-enhancement');
        
        textElements.forEach(textEl => {
          if (textEl.textContent.trim() !== '') {
            textEl.classList.add('spotlight-enhanced-text');
            
            const originalStyles = {
              textShadow: textEl.style.textShadow || '',
              color: textEl.style.color || '',
              transition: textEl.style.transition || ''
            };
            
            textEl._originalTextStyles = originalStyles;
            textEl.style.transition = \`all \${options.animationDuration * 1.2}s ease\`;
            
            if (options.triggerType === 'hover') {
              element.addEventListener('mouseenter', () => {
                this.enhanceText(textEl, r, g, b, options.spotlightIntensity);
              });
              
              element.addEventListener('mouseleave', () => {
                this.resetTextEnhancement(textEl);
              });
            } else if (options.triggerType === 'load') {
              setTimeout(() => {
                this.enhanceText(textEl, r, g, b, options.spotlightIntensity);
              }, 100);
            }
          }
        });
      }
    }
    
    enhanceText(textEl, r, g, b, intensity) {
      const shadowColor = \`rgba(\${Math.min(255, r + 50)}, \${Math.min(255, g + 50)}, \${Math.min(255, b + 50)}, \${intensity * 0.8})\`;
      
      textEl.style.textShadow = \`0 0 10px \${shadowColor}, 0 0 20px \${shadowColor}, 0 0 30px \${shadowColor}\`;
      
      const computedStyle = window.getComputedStyle(textEl);
      const currentColor = computedStyle.color;
      
      if (this.isColorDark(currentColor)) {
        textEl.style.color = \`rgba(\${Math.min(255, r + 200)}, \${Math.min(255, g + 200)}, \${Math.min(255, b + 200)}, 1)\`;
      }
    }
    
    resetTextEnhancement(textEl) {
      if (textEl._originalTextStyles) {
        textEl.style.textShadow = textEl._originalTextStyles.textShadow;
        textEl.style.color = textEl._originalTextStyles.color;
      }
    }
    
    isColorDark(color) {
      const rgbMatch = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*[\d.]+)?\)/);
      if (rgbMatch) {
        const r = parseInt(rgbMatch[1]);
        const g = parseInt(rgbMatch[2]);
        const b = parseInt(rgbMatch[3]);
        
        const brightness = (r * 299 + g * 587 + b * 114) / 1000;
        return brightness < 128;
      }
      return false;
    }
  }

  const style = document.createElement('style');
  style.textContent = \`
    @keyframes sparkle {
      0%, 100% { opacity: 0; transform: scale(0); }
      50% { opacity: 1; transform: scale(1); }
    }
    
    @keyframes pulse {
      0% { opacity: 0.4; transform: scale(0.98); }
      100% { opacity: 0.6; transform: scale(1.02); }
    }
  \`;
  document.head.appendChild(style);

  const initSpotlight = () => {
    if (!window.spotlightEffect) {
      window.spotlightEffect = new SpotlightEffect();
    }
  };

  initSpotlight();

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initSpotlight);
  }
  window.addEventListener('load', initSpotlight);
  document.addEventListener('rocket-after-load', initSpotlight);
  setTimeout(initSpotlight, 1000);
})();`;
      }

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

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

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

      window.resetParameter = function(parameterId, defaultValue) {
        const element = document.getElementById(parameterId);
        if (element) {
          element.value = defaultValue;
          const valueElement = document.getElementById(`${parameterId}-value`);
          if (valueElement) {
            valueElement.textContent = defaultValue;
          }
          
          switch (parameterId) {
            case 'light-angle':
              spotlightConfig.lightAngle = defaultValue;
              break;
            case 'spotlight-intensity':
              spotlightConfig.spotlightIntensity = defaultValue;
              break;
            case 'spotlight-size':
              spotlightConfig.spotlightSize = defaultValue;
              break;
            case 'blur-amount':
              spotlightConfig.blurAmount = defaultValue;
              break;
            case 'animation-duration':
              spotlightConfig.animationDuration = defaultValue;
              break;
            case 'sparkle-count':
              spotlightConfig.sparkleCount = defaultValue;
              break;
            case 'sparkle-frequency':
              spotlightConfig.sparkleFrequency = defaultValue;
              break;
            case 'sparkle-size':
              spotlightConfig.sparkleSize = defaultValue;
              break;
          }
          
          updateSpotlightPreview();
          showNotification(`${parameterId.replace(/-/g, ' ')} reset to default`);
        }
      };

      function generateRandomSpotlight() {
        spotlightConfig.customColor = generateRandomColor();
        spotlightConfig.spotlightIntensity = Math.random() * 0.8 + 0.2;
        spotlightConfig.spotlightSize = Math.floor(Math.random() * 250) + 50;
        spotlightConfig.blurAmount = Math.floor(Math.random() * 20);
        spotlightConfig.animationDuration = Math.random() * 2.5 + 0.5;
        spotlightConfig.sparkleCount = Math.floor(Math.random() * 20);
        spotlightConfig.sparkleFrequency = Math.floor(Math.random() * 90) + 10;
        spotlightConfig.sparkleSize = Math.floor(Math.random() * 10) + 2;
        spotlightConfig.effectType = ['soft', 'harsh', 'window', 'ambient'][Math.floor(Math.random() * 4)];
        spotlightConfig.lightAngle = Math.floor(Math.random() * 360);
        
        document.getElementById('spotlight-color').value = spotlightConfig.customColor;
        document.getElementById('spotlight-intensity').value = spotlightConfig.spotlightIntensity;
        document.getElementById('spotlight-size').value = spotlightConfig.spotlightSize;
        document.getElementById('blur-amount').value = spotlightConfig.blurAmount;
        document.getElementById('animation-duration').value = spotlightConfig.animationDuration;
        document.getElementById('sparkle-count').value = spotlightConfig.sparkleCount;
        document.getElementById('sparkle-frequency').value = spotlightConfig.sparkleFrequency;
        document.getElementById('sparkle-size').value = spotlightConfig.sparkleSize;
        document.getElementById('spotlight-effect').value = spotlightConfig.effectType;
        document.getElementById('light-angle').value = spotlightConfig.lightAngle;
        
        document.getElementById('spotlight-intensity-value').textContent = spotlightConfig.spotlightIntensity.toFixed(2);
        document.getElementById('spotlight-size-value').textContent = spotlightConfig.spotlightSize;
        document.getElementById('blur-amount-value').textContent = spotlightConfig.blurAmount;
        document.getElementById('animation-duration-value').textContent = spotlightConfig.animationDuration.toFixed(1);
        document.getElementById('sparkle-count-value').textContent = spotlightConfig.sparkleCount;
        document.getElementById('sparkle-frequency-value').textContent = spotlightConfig.sparkleFrequency;
        document.getElementById('sparkle-size-value').textContent = spotlightConfig.sparkleSize;
        document.getElementById('light-angle-value').textContent = spotlightConfig.lightAngle;
        
        updateColorInputs();
        updateSpotlightPreview();
        showNotification('Random spotlight generated!');
      }

      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 updateColorInputs() {
        const colorInput = document.getElementById('spotlight-color');
        const hexInput = document.getElementById('spotlight-color-hex');
        const hslInput = document.getElementById('spotlight-color-hsl');
        
        if (colorInput && hexInput && hslInput) {
          colorInput.value = spotlightConfig.customColor;
          hexInput.value = spotlightConfig.customColor;
          hslInput.value = `hsl(${hexToHsl(spotlightConfig.customColor).h}, ${hexToHsl(spotlightConfig.customColor).s}%, ${hexToHsl(spotlightConfig.customColor).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', spotlightConfig.customColor);
          }
        }
      }

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

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

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

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

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

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

        previewContainer.style.backgroundColor = '#333333';

        document.getElementById('reset-color').addEventListener('click', () => {
          spotlightConfig.customColor = defaultConfig.customColor;
          updateColorInputs();
          updateSpotlightPreview();
          showNotification('Color reset to default');
        });

        document.getElementById('reset-effects').addEventListener('click', () => {
          spotlightConfig.effectType = defaultConfig.effectType;
          spotlightConfig.lightAngle = defaultConfig.lightAngle;
          spotlightConfig.spotlightIntensity = defaultConfig.spotlightIntensity;
          spotlightConfig.spotlightSize = defaultConfig.spotlightSize;
          spotlightConfig.blurAmount = defaultConfig.blurAmount;
          spotlightConfig.animationDuration = defaultConfig.animationDuration;
          
          document.getElementById('spotlight-effect').value = defaultConfig.effectType;
          document.getElementById('light-angle').value = defaultConfig.lightAngle;
          document.getElementById('spotlight-intensity').value = defaultConfig.spotlightIntensity;
          document.getElementById('spotlight-size').value = defaultConfig.spotlightSize;
          document.getElementById('blur-amount').value = defaultConfig.blurAmount;
          document.getElementById('animation-duration').value = defaultConfig.animationDuration;
          
          document.getElementById('light-angle-value').textContent = defaultConfig.lightAngle;
          document.getElementById('spotlight-intensity-value').textContent = defaultConfig.spotlightIntensity;
          document.getElementById('spotlight-size-value').textContent = defaultConfig.spotlightSize;
          document.getElementById('blur-amount-value').textContent = defaultConfig.blurAmount;
          document.getElementById('animation-duration-value').textContent = defaultConfig.animationDuration;
          
          updateSpotlightPreview();
          showNotification('Effect settings reset');
        });

        document.getElementById('reset-sparkles').addEventListener('click', () => {
          spotlightConfig.sparklesEnabled = defaultConfig.sparklesEnabled;
          spotlightConfig.sparkleCount = defaultConfig.sparkleCount;
          spotlightConfig.sparkleFrequency = defaultConfig.sparkleFrequency;
          spotlightConfig.sparkleSize = defaultConfig.sparkleSize;
          
          document.getElementById('sparkles-enabled').checked = defaultConfig.sparklesEnabled;
          document.getElementById('sparkle-count').value = defaultConfig.sparkleCount;
          document.getElementById('sparkle-frequency').value = defaultConfig.sparkleFrequency;
          document.getElementById('sparkle-size').value = defaultConfig.sparkleSize;
          
          document.getElementById('sparkle-count-value').textContent = defaultConfig.sparkleCount;
          document.getElementById('sparkle-frequency-value').textContent = defaultConfig.sparkleFrequency;
          document.getElementById('sparkle-size-value').textContent = defaultConfig.sparkleSize;
          
          updateSpotlightPreview();
          showNotification('Sparkle settings reset');
        });

        document.getElementById('reset-advanced').addEventListener('click', () => {
          spotlightConfig.triggerType = defaultConfig.triggerType;
          spotlightConfig.scrollStart = defaultConfig.scrollStart;
          spotlightConfig.scrollEnd = defaultConfig.scrollEnd;
          spotlightConfig.reverseEnabled = defaultConfig.reverseEnabled;
          
          document.getElementById('trigger-type').value = defaultConfig.triggerType;
          document.getElementById('scroll-start').value = defaultConfig.scrollStart;
          document.getElementById('scroll-end').value = defaultConfig.scrollEnd;
          document.getElementById('reverse-enabled').checked = defaultConfig.reverseEnabled;
          
          document.getElementById('scroll-start-value').textContent = defaultConfig.scrollStart;
          document.getElementById('scroll-end-value').textContent = defaultConfig.scrollEnd;
          
          updateSpotlightPreview();
          showNotification('Advanced settings reset');
        });

        const colorInput = document.getElementById('spotlight-color');
        const hexInput = document.getElementById('spotlight-color-hex');
        const hslInput = document.getElementById('spotlight-color-hsl');
        
        updateColorInputs();
        
        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');
          spotlightConfig.customColor = color;
          
          const colorPickerContainer = colorInput.closest('.color-row').querySelector('.color-picker-container');
          colorPickerContainer.style.setProperty('--selected-color', color);
          
          updateSpotlightPreview();
        });
        
        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}%)`;
            spotlightConfig.customColor = 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);
            
            updateSpotlightPreview();
          } 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;
              spotlightConfig.customColor = 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);
              
              updateSpotlightPreview();
              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;
                spotlightConfig.customColor = hex;
                e.target.classList.remove('invalid');
                hexInput.classList.remove('invalid');
                updateSpotlightPreview();
                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) {
              let displayValue = input.value;
              if (input.id === 'light-angle') {
                displayValue += '°';
              } else if (input.id === 'blur-amount') {
                displayValue += 'px';
              } else if (input.id === 'animation-duration') {
                displayValue += 's';
              } else if (input.id === 'spotlight-size') {
                displayValue += '%';
              } else if (input.id === 'sparkle-frequency') {
                displayValue += '%';
              } else if (input.id === 'sparkle-size') {
                displayValue += 'px';
              }
              valueElement.textContent = displayValue;
            }
            
            switch (input.id) {
              case 'light-angle':
                spotlightConfig.lightAngle = parseInt(input.value);
                break;
              case 'spotlight-intensity':
                spotlightConfig.spotlightIntensity = parseFloat(input.value);
                break;
              case 'spotlight-size':
                spotlightConfig.spotlightSize = parseInt(input.value);
                break;
              case 'blur-amount':
                spotlightConfig.blurAmount = parseInt(input.value);
                break;
              case 'animation-duration':
                spotlightConfig.animationDuration = parseFloat(input.value);
                break;
              case 'sparkle-count':
                spotlightConfig.sparkleCount = parseInt(input.value);
                break;
              case 'sparkle-frequency':
                spotlightConfig.sparkleFrequency = parseInt(input.value);
                break;
              case 'sparkle-size':
                spotlightConfig.sparkleSize = parseInt(input.value);
                break;
            }
            
            updateSpotlightPreview();
          });
        });

        document.getElementById('spotlight-effect').addEventListener('change', function() {
          spotlightConfig.effectType = this.value;
          updateSpotlightPreview();
        });

        document.getElementById('sparkles-enabled').addEventListener('change', function() {
          spotlightConfig.sparklesEnabled = this.checked;
          document.getElementById('sparkle-count').disabled = !this.checked;
          document.getElementById('sparkle-frequency').disabled = !this.checked;
          document.getElementById('sparkle-size').disabled = !this.checked;
          updateSpotlightPreview();
        });

        document.getElementById('trigger-type').addEventListener('change', function() {
          spotlightConfig.triggerType = this.value;
          const scrollSettings = document.getElementById('scroll-settings');
          scrollSettings.style.display = this.value === 'scroll' ? 'block' : 'none';
          updateSpotlightPreview();
        });

        document.getElementById('scroll-start').addEventListener('change', function() {
          spotlightConfig.scrollStart = this.value;
          document.getElementById('scroll-start-value').textContent = this.value;
          updateSpotlightPreview();
        });

        document.getElementById('scroll-end').addEventListener('change', function() {
          spotlightConfig.scrollEnd = this.value;
          document.getElementById('scroll-end-value').textContent = this.value;
          updateSpotlightPreview();
        });

        document.getElementById('reverse-enabled').addEventListener('change', function() {
          spotlightConfig.reverseEnabled = this.checked;
          updateSpotlightPreview();
        });

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

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

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

        function loadConfiguration() {
          try {
            const saved = localStorage.getItem('bricksfusion-spotlight-config');
            if (saved) {
              const savedConfig = JSON.parse(saved);
              Object.assign(spotlightConfig, savedConfig);
              
              document.getElementById('spotlight-color').value = savedConfig.customColor;
              document.getElementById('spotlight-intensity').value = savedConfig.spotlightIntensity;
              document.getElementById('spotlight-size').value = savedConfig.spotlightSize;
              document.getElementById('blur-amount').value = savedConfig.blurAmount;
              document.getElementById('animation-duration').value = savedConfig.animationDuration;
              document.getElementById('sparkles-enabled').checked = savedConfig.sparklesEnabled;
              document.getElementById('sparkle-count').value = savedConfig.sparkleCount;
              document.getElementById('sparkle-frequency').value = savedConfig.sparkleFrequency;
              document.getElementById('sparkle-size').value = savedConfig.sparkleSize;
              document.getElementById('trigger-type').value = savedConfig.triggerType;
              document.getElementById('scroll-start').value = savedConfig.scrollStart;
              document.getElementById('scroll-end').value = savedConfig.scrollEnd;
              document.getElementById('reverse-enabled').checked = savedConfig.reverseEnabled;
              document.getElementById('spotlight-effect').value = savedConfig.effectType;
              document.getElementById('light-angle').value = savedConfig.lightAngle;
              
              document.getElementById('spotlight-intensity-value').textContent = savedConfig.spotlightIntensity;
              document.getElementById('spotlight-size-value').textContent = savedConfig.spotlightSize;
              document.getElementById('blur-amount-value').textContent = savedConfig.blurAmount;
              document.getElementById('animation-duration-value').textContent = savedConfig.animationDuration;
              document.getElementById('sparkle-count-value').textContent = savedConfig.sparkleCount;
              document.getElementById('sparkle-frequency-value').textContent = savedConfig.sparkleFrequency;
              document.getElementById('sparkle-size-value').textContent = savedConfig.sparkleSize;
              document.getElementById('light-angle-value').textContent = savedConfig.lightAngle;
              document.getElementById('scroll-start-value').textContent = savedConfig.scrollStart;
              document.getElementById('scroll-end-value').textContent = savedConfig.scrollEnd;
              
              updateColorInputs();
              updateSpotlightPreview();
            }
          } catch (e) {
          }
        }

        const originalUpdateSpotlightPreview = updateSpotlightPreview;
        updateSpotlightPreview = function() {
          originalUpdateSpotlightPreview();
          saveConfiguration();
        };

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

Spotlight

Creates dramatic light rays that illuminate your content like a stage spotlight. Perfect for hero sections, product showcases, and adding cinematic atmosphere to your pages.

Spotlight Effect

Move your mouse to see the rays follow your cursor

Appearance

Rays Origin position selection

Where the light rays come from. Top-center creates classic stage lighting, while side positions create dramatic angular rays.

Options: Top Center, Top Left, Top Right, Left, Right, Bottom Left, Bottom Center, Bottom Right

Default: Top Center

Rays Color color picker

Color of the light rays. White is classic spotlight, blue creates moonlight, yellow/orange gives warm stage lighting vibes.

Default: White (#ffffff)

Light Properties

Light Spread 0.1-3.0

How wide the light beam spreads. Lower = tight focused beam like a laser, higher = wide soft wash of light.

Default: 1.0

Ray Length 0.5-3.0

How far the rays extend across your section. Short rays keep light near the origin, long rays fill the entire space.

Default: 2.0

Fade Distance 0.1-2.0

How quickly the light fades away from the source. Lower = fades fast and stays near origin, higher = light travels further before fading.

Default: 1.0

Saturation 0.0-2.0

Color intensity of the rays. 0 is grayscale/black and white, 1.0 is normal, 2.0 is super vibrant and saturated.

Default: 1.0

Animation

Rays Speed 0.1-3.0

How fast the rays animate and shimmer. Slow creates gentle movement, fast makes it more energetic and dynamic.

Default: 1.0

Pulsating on/off

Makes the light intensity pulse rhythmically like a heartbeat. Great for drawing attention or creating breathing life into the effect.

Default: Off

Effects

Noise Amount 0.0-1.0

Adds film grain or dust particles to the rays. Makes it look more vintage or atmospheric, like light cutting through fog.

Default: 0.0 (no noise)

Distortion 0.0-1.0

Makes the rays wavy and organic instead of straight. Creates heat wave effects or dreamy, surreal atmosphere.

Default: 0.0 (straight rays)

Mouse Interaction

Follow Mouse on/off

Makes the light rays follow your mouse cursor. Creates an interactive spotlight that tracks visitor movement across the section.

Default: On

Mouse Influence 0.0-1.0

How much the mouse affects ray direction. 0 means mouse has no effect, 1.0 means rays point directly at cursor. Try 0.1-0.3 for subtle interaction.

Default: 0.1

Performance

This element uses WebGL shaders for realistic light rendering, making it the most resource-intensive effect in Bricksfusion. Use it strategically on hero sections or key moments. Avoid using multiple spotlights on the same page. On mobile devices, the effect automatically adjusts quality to maintain smooth performance.