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>Cherry Blossom Configurator - BricksFusion</title>
  <style>
    :root {
  --background: #000;
  --card-bg: #1e1e1e;
  --card-bg-hover: #252525;
  --text-primary: #f2f2f7;
  --text-secondary: #8e8e93;
  --accent: #ef6013;
  --accent-hover: #c64c0c;
  --border: #2c2c2e;
  --shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
  --track: #2c2c2e;
  --thumb: #ef6013;
  --card-radius: 16px;
  --input-radius: 8px;
  --button-radius: 12px;
  --transition: all 0.25s ease;
  --font: 'Inter', BlinkMacSystemFont, "San Francisco", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --action-bar-height: 70px;
  --success: #28a745;
  --warning: #ffc107;
  --danger: #dc3545;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: var(--font);
  background-color: var(--background);
  color: var(--text-primary);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  padding-bottom: var(--action-bar-height);
}

.action-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  height: var(--action-bar-height);
  background: linear-gradient(145deg, #1a1a1a, #0f0f0f);
  border-top: 1px solid var(--border);
  z-index: 1000;
  display: flex;
  align-items: center;
  padding: 0 1.5rem;
  gap: 1rem;
  box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(10px);
}

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

.breadcrumb-item {
  color: var(--text-secondary);
  font-size: var(--text-xs);
  font-weight: 500;
  text-decoration: none;
  transition: var(--transition);
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
}

.breadcrumb-item:hover {
  color: var(--text-primary);
  background-color: rgba(255, 255, 255, 0.05);
}

.breadcrumb-item.active {
  color: var(--accent);
  background-color: rgba(239, 96, 19, 0.1);
}

.breadcrumb-separator {
  color: var(--text-secondary);
  font-size: var(--text-xs);
  opacity: 0.5;
}

.action-buttons {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.action-btn {
  padding: 0.6rem 1rem;
  background-color: var(--card-bg);
  color: var(--text-primary);
  font-family: var(--font);
  font-size: var(--text-xs);
  font-weight: 500;
  border: 1px solid var(--border);
  border-radius: var(--button-radius);
  cursor: pointer;
  transition: var(--transition);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  text-decoration: none;
  white-space: nowrap;
}

.action-btn:hover {
  background-color: var(--card-bg-hover);
  border-color: var(--accent);
  transform: translateY(-1px);
}

.action-btn.primary {
  background: linear-gradient(90deg, var(--accent), #ff8c51);
  border-color: var(--accent);
  color: white;
}

.action-btn.primary:hover {
  background: linear-gradient(90deg, var(--accent-hover), #e67a3f);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(239, 96, 19, 0.3);
}

.data-attribute-display {
  background-color: rgba(50, 50, 50, 0.8);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
  font-size: var(--text-xs);
  color: #ff8c51;
  cursor: pointer;
  transition: var(--transition);
  user-select: all;
}

.data-attribute-display:hover {
  background-color: rgba(239, 96, 19, 0.2);
  border-color: var(--accent);
}

.container {
  max-width: 100%;
  margin: 0 auto;
  padding: 2rem 1.5rem;
}

.page-header {
  text-align: center;
  margin-bottom: 2rem;
}

.page-title {
  font-size: 2.5rem;
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: 0.5rem;
  background: linear-gradient(90deg, var(--accent), #ff8c51);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

.page-subtitle {
  font-size: var(--text-s);
  color: var(--text-secondary);
  font-weight: 500;
}

.instructions-toggle {
  margin-bottom: 2rem;
}

.instructions-card {
  background-color: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--card-radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  transition: var(--transition);
}

.instructions-header {
  padding: 1rem 1.5rem;
  cursor: pointer;
  transition: var(--transition);
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid transparent;
}

.instructions-header:hover {
  background-color: var(--card-bg-hover);
}

.instructions-card.expanded .instructions-header {
  border-bottom-color: var(--border);
}

.instructions-title {
  font-size: var(--text-s);
  font-weight: 600;
}

.toggle-icon {
  font-size: 1.2em;
  transition: transform 0.3s ease;
}

.toggle-icon.expanded {
  transform: rotate(180deg);
}

.instructions-content {
  padding: 0 1.5rem;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease, padding 0.3s ease;
}

.instructions-content.show {
  max-height: 500px;
  padding: 1.5rem;
}

.instructions-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem;
}

.how-to-use ol {
  padding-left: 1.5rem;
}

.how-to-use li {
  margin-bottom: 0.75rem;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  line-height: 1.6;
}

.how-to-use strong {
  color: var(--text-primary);
  font-weight: 600;
}

.how-to-use code {
  background-color: rgba(50, 50, 50, 0.5);
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
  font-size: var(--text-xs);
  color: #ff8c51;
}

.content {
  display: grid;
  grid-template-columns: 1fr 500px;
  gap: 2rem;
  align-items: start;
}

.preview-section {
  position: sticky;
  top: 2rem;
}

.controls-section {
  max-width: 500px;
}

.card {
  background-color: var(--card-bg);
  border-radius: var(--card-radius);
  box-shadow: var(--shadow);
  overflow: hidden;
  margin-bottom: 1.5rem;
  border: 1px solid var(--border);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.4);
}

.preview-container {
  height: 400px;
  width: 100%;
  position: relative;
  overflow: hidden;
  border-radius: var(--card-radius);
  background-color: #000000;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

.card-content {
  padding: 1.5rem;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

.color-random-btn {
  padding: 0.4rem;
  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);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
}

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

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

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

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

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

@media (max-width: 1200px) {
  .content {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }
  
  .preview-section {
    position: static;
  }
  
  .controls-section {
    max-width: 100%;
  }
}

@media (max-width: 768px) {
  .action-bar {
    flex-direction: column;
    height: auto;
    min-height: var(--action-bar-height);
    padding: 0.75rem;
  }
  
  .breadcrumb {
    order: 1;
    width: 100%;
  }
  
  .action-buttons {
    order: 2;
    width: 100%;
    justify-content: center;
    flex-wrap: wrap;
  }
  
  body {
    padding-bottom: calc(var(--action-bar-height) + 20px);
  }
  
  .notification {
    bottom: calc(var(--action-bar-height) + 2rem);
    max-width: 280px;
    transform: translate(-50%, 250px);
  }
  
  .notification.show {
    transform: translate(-50%, 0);
    opacity: 1;
  }
  
  .color-row {
    flex-direction: column;
    align-items: stretch;
    gap: 1rem;
    padding: 1rem;
  }
  
  .color-picker-container {
    align-self: center;
    margin-bottom: 0.5rem;
  }
  
  .color-input-group {
    align-items: stretch;
  }
  
  .hex-input,
  .hsl-input {
    width: 100%;
  }

  
  .preview-container {
    height: 300px;
  }
  
  .data-attribute-display {
    font-size: 10px;
    padding: 0.4rem 0.6rem;
  }
  
  .action-btn {
    font-size: 11px;
    padding: 0.5rem 0.8rem;
  }
  
  .page-title {
    font-size: 2rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

button:focus-visible,
input:focus-visible,
.action-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-track {
  background: var(--background);
}

::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--accent);
}

.loading {
  opacity: 0.6;
  pointer-events: none;
  position: relative;
}

.loading::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 20px;
  height: 20px;
  margin: -10px 0 0 -10px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}
  </style>
</head>
<body>
  <div class="action-bar">
    <nav class="breadcrumb">
      <a href="https://bricksfusion.com" class="breadcrumb-item">Home</a>
      <span class="breadcrumb-separator">›</span>
      <a href="https://bricksfusion.com/visual-effects/" class="breadcrumb-item">Visual effects</a>
      <span class="breadcrumb-separator">›</span>
      <span class="breadcrumb-item active">Cherry Blossom</span>
    </nav>
    
    <div class="action-buttons">
      <div class="data-attribute-display" id="quick-attribute" title="Click to copy data attribute">
        data-cherry-blossom
      </div>
      <button class="action-btn primary" id="download-config" title="Copy JavaScript code (Ctrl+D)" data-protection-animation="true">
        <span>📋</span>
        Copy JS
      </button>
      <button class="action-btn" id="copy-full-section" title="Copy complete section JSON for Bricks Builder (Ctrl+S)" data-protection-animation="true">
        <span>📦</span>
        Copy Full Section
      </button>
    </div>
  </div>

  <div class="container">
    <div class="page-header">
      <h1 class="page-title">Cherry Blossom</h1>
      <p class="page-subtitle">Interactive falling petals animation 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 cherry blossom animation using the controls below</li>
                <li>Click <strong>Copy JS</strong> to copy the JavaScript code to clipboard</li>
                <li>In Bricks Builder, add a <strong>Code</strong> element</li>
                <li>Paste or upload the JavaScript code</li>
                <li>To add the effect to any section: go to <strong>Section → Style → Attributes</strong>, add <code>data-cherry-blossom</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="cherry-preview" data-cherry-blossom="true">
          <div class="preview-content">Interactive Cherry Blossom Preview</div>
          <div class="preview-controls">
            <button class="preview-btn" id="randomize-cherry" title="Randomize (R)">🎲</button>
            <div class="background-selector-wrapper">
              <button class="preview-btn background-selector-btn" id="background-selector">
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polygon points="12,2 2,7 12,12 22,7"/>
                  <polyline points="2,17 12,22 22,17"/>
                  <polyline points="2,12 12,17 22,12"/>
                </svg>
              </button>
              <input type="color" id="preview-background-picker" class="hidden-color-input" value="#000000" title="Change Preview Background (B)">
            </div>
          </div>
        </div>
      </section>

      <section class="controls-section">
        <div class="card">
          <div class="card-heading">
            Petal Colors
            <div class="card-actions">
              <button class="card-action-btn" id="reset-colors" title="Reset Colors">↺</button>
            </div>
          </div>
          <div class="card-content">
            <div class="color-list">
              <div class="color-row">
                <div class="color-picker-container">
                  <input type="color" id="petal-color-0" value="#ffdbf0">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HEX</span>
                  <input type="text" class="color-input hex-input" id="petal-color-hex-0" value="#ffdbf0" placeholder="#FFFFFF">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HSL</span>
                  <input type="text" class="color-input hsl-input" id="petal-color-hsl-0" placeholder="hsl(0, 100%, 50%)">
                </div>
                <div class="color-actions">
                  <button class="color-random-btn" title="Random Color" onclick="randomizeColor(0)">🎲</button>
                </div>
              </div>
              <div class="color-row">
                <div class="color-picker-container">
                  <input type="color" id="petal-color-1" value="#ffc6e5">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HEX</span>
                  <input type="text" class="color-input hex-input" id="petal-color-hex-1" value="#ffc6e5" placeholder="#FFFFFF">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HSL</span>
                  <input type="text" class="color-input hsl-input" id="petal-color-hsl-1" placeholder="hsl(0, 100%, 50%)">
                </div>
                <div class="color-actions">
                  <button class="color-random-btn" title="Random Color" onclick="randomizeColor(1)">🎲</button>
                </div>
              </div>
              <div class="color-row">
                <div class="color-picker-container">
                  <input type="color" id="petal-color-2" value="#ffa6d9">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HEX</span>
                  <input type="text" class="color-input hex-input" id="petal-color-hex-2" value="#ffa6d9" placeholder="#FFFFFF">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HSL</span>
                  <input type="text" class="color-input hsl-input" id="petal-color-hsl-2" placeholder="hsl(0, 100%, 50%)">
                </div>
                <div class="color-actions">
                  <button class="color-random-btn" title="Random Color" onclick="randomizeColor(2)">🎲</button>
                </div>
              </div>
              <div class="color-row">
                <div class="color-picker-container">
                  <input type="color" id="petal-color-3" value="#ff8ac4">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HEX</span>
                  <input type="text" class="color-input hex-input" id="petal-color-hex-3" value="#ff8ac4" placeholder="#FFFFFF">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HSL</span>
                  <input type="text" class="color-input hsl-input" id="petal-color-hsl-3" placeholder="hsl(0, 100%, 50%)">
                </div>
                <div class="color-actions">
                  <button class="color-random-btn" title="Random Color" onclick="randomizeColor(3)">🎲</button>
                </div>
              </div>
              <div class="color-row">
                <div class="color-picker-container">
                  <input type="color" id="petal-color-4" value="#f97dbd">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HEX</span>
                  <input type="text" class="color-input hex-input" id="petal-color-hex-4" value="#f97dbd" placeholder="#FFFFFF">
                </div>
                <div class="color-input-group">
                  <span class="color-label">HSL</span>
                  <input type="text" class="color-input hsl-input" id="petal-color-hsl-4" placeholder="hsl(0, 100%, 50%)">
                </div>
                <div class="color-actions">
                  <button class="color-random-btn" title="Random Color" onclick="randomizeColor(4)">🎲</button>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div class="card">
          <div class="card-heading">
            Animation Settings
            <div class="card-actions">
              <button class="card-action-btn" id="reset-animation" title="Reset Animation Settings">↺</button>
            </div>
          </div>
          <div class="card-content">
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Petal Count
                  <span class="help-tooltip" title="Number of petals in the animation">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="petal-count-value">30</span></span>
                  <button class="reset-btn" onclick="resetParameter('petal-count', 30)">↺</button>
                </div>
              </div>
              <input type="range" id="petal-count" min="10" max="100" step="5" value="30">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Petal Size Min
                  <span class="help-tooltip" title="Minimum size of petals">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="petal-size-min-value">20</span>px</span>
                  <button class="reset-btn" onclick="resetParameter('petal-size-min', 20)">↺</button>
                </div>
              </div>
              <input type="range" id="petal-size-min" min="10" max="30" step="1" value="20">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Petal Size Max
                  <span class="help-tooltip" title="Maximum size of petals">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="petal-size-max-value">40</span>px</span>
                  <button class="reset-btn" onclick="resetParameter('petal-size-max', 40)">↺</button>
                </div>
              </div>
              <input type="range" id="petal-size-max" min="30" max="60" step="1" value="40">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Fall Speed Min
                  <span class="help-tooltip" title="Minimum falling speed">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="fall-speed-min-value">1</span></span>
                  <button class="reset-btn" onclick="resetParameter('fall-speed-min', 1)">↺</button>
                </div>
              </div>
              <input type="range" id="fall-speed-min" min="0.5" max="2" step="0.1" value="1">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Fall Speed Max
                  <span class="help-tooltip" title="Maximum falling speed">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="fall-speed-max-value">3</span></span>
                  <button class="reset-btn" onclick="resetParameter('fall-speed-max', 3)">↺</button>
                </div>
              </div>
              <input type="range" id="fall-speed-max" min="2" max="5" step="0.1" value="3">
            </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">
                  Swing Range
                  <span class="help-tooltip" title="How much petals swing left and right">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="swing-range-value">2</span></span>
                  <button class="reset-btn" onclick="resetParameter('swing-range', 2)">↺</button>
                </div>
              </div>
              <input type="range" id="swing-range" min="0.5" max="5" step="0.5" value="2">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Rotation Speed
                  <span class="help-tooltip" title="Speed of petal rotation">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="rotation-speed-value">2</span></span>
                  <button class="reset-btn" onclick="resetParameter('rotation-speed', 2)">↺</button>
                </div>
              </div>
              <input type="range" id="rotation-speed" min="0.5" max="4" step="0.5" value="2">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Opacity Min
                  <span class="help-tooltip" title="Minimum opacity of petals">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="opacity-min-value">0.6</span></span>
                  <button class="reset-btn" onclick="resetParameter('opacity-min', 0.6)">↺</button>
                </div>
              </div>
              <input type="range" id="opacity-min" min="0.2" max="0.7" step="0.1" value="0.6">
            </div>
            
            <div class="control-group">
              <div class="control-label">
                <span class="label-text">
                  Opacity Max
                  <span class="help-tooltip" title="Maximum opacity of petals">ℹ</span>
                </span>
                <div class="value-display">
                  <span class="value-text"><span id="opacity-max-value">0.9</span></span>
                  <button class="reset-btn" onclick="resetParameter('opacity-max', 0.9)">↺</button>
                </div>
              </div>
              <input type="range" id="opacity-max" min="0.7" max="1" step="0.1" value="0.9">
            </div>
          </div>
        </div>
      </section>
    </div>
  </div>

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

  <script>
    document.addEventListener('DOMContentLoaded', function() {
      let cherryConfig = {
        petalCount: 30,
        petalSizeMin: 20,
        petalSizeMax: 40,
        colors: ['#ffdbf0', '#ffc6e5', '#ffa6d9', '#ff8ac4', '#f97dbd'],
        speedMin: 1,
        speedMax: 3,
        swingRange: 2,
        rotationSpeed: 2,
        opacityMin: 0.6,
        opacityMax: 0.9
      };

      const defaultConfig = { ...cherryConfig };

      let activeCherryBlossom = null;
      
      function initCherryBlossomFlow() {
        const sections = document.querySelectorAll('[data-cherry-blossom]:not([data-cherry-initialized="true"])');
        
        sections.forEach((section) => {
          const petalCount = section.hasAttribute('data-cherry-petal-count') 
            ? parseInt(section.getAttribute('data-cherry-petal-count')) 
            : cherryConfig.petalCount;
            
          const petalSizeMin = section.hasAttribute('data-cherry-petal-size-min') 
            ? parseFloat(section.getAttribute('data-cherry-petal-size-min')) 
            : cherryConfig.petalSizeMin;
            
          const petalSizeMax = section.hasAttribute('data-cherry-petal-size-max') 
            ? parseFloat(section.getAttribute('data-cherry-petal-size-max')) 
            : cherryConfig.petalSizeMax;
            
          const speedMin = section.hasAttribute('data-cherry-speed-min') 
            ? parseFloat(section.getAttribute('data-cherry-speed-min')) 
            : cherryConfig.speedMin;
            
          const speedMax = section.hasAttribute('data-cherry-speed-max') 
            ? parseFloat(section.getAttribute('data-cherry-speed-max')) 
            : cherryConfig.speedMax;
            
          const swingRange = section.hasAttribute('data-cherry-swing-range') 
            ? parseFloat(section.getAttribute('data-cherry-swing-range')) 
            : cherryConfig.swingRange;
            
          const rotationSpeed = section.hasAttribute('data-cherry-rotation-speed') 
            ? parseFloat(section.getAttribute('data-cherry-rotation-speed')) 
            : cherryConfig.rotationSpeed;
            
          const opacityMin = section.hasAttribute('data-cherry-opacity-min') 
            ? parseFloat(section.getAttribute('data-cherry-opacity-min')) 
            : cherryConfig.opacityMin;
            
          const opacityMax = section.hasAttribute('data-cherry-opacity-max') 
            ? parseFloat(section.getAttribute('data-cherry-opacity-max')) 
            : cherryConfig.opacityMax;
            
          const options = {
            petalCount,
            petalSizeMin,
            petalSizeMax,
            colors: cherryConfig.colors,
            speedMin,
            speedMax,
            swingRange,
            rotationSpeed,
            opacityMin,
            opacityMax
          };
          
          setupCherryBlossomFlow(section, options);
          section.dataset.cherryInitialized = 'true';
          
          if (section.id === 'cherry-preview') {
            activeCherryBlossom = { element: section, options };
            cherryConfig = {
              petalCount: options.petalCount,
              petalSizeMin: options.petalSizeMin,
              petalSizeMax: options.petalSizeMax,
              colors: options.colors,
              speedMin: options.speedMin,
              speedMax: options.speedMax,
              swingRange: options.swingRange,
              rotationSpeed: options.rotationSpeed,
              opacityMin: options.opacityMin,
              opacityMax: options.opacityMax
            };
          }
        });
      }
      
      function setupCherryBlossomFlow(element, options) {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        
        element.appendChild(canvas);
        
        if (window.getComputedStyle(element).position === 'static') {
          element.style.position = 'relative';
        }
        
        Object.assign(canvas.style, {
          position: 'absolute',
          top: '0',
          left: '0',
          width: '100%',
          height: '100%',
          pointerEvents: 'none'
        });
        
        canvas.width = element.clientWidth;
        canvas.height = element.clientHeight;
        
        element.cherryCanvas = canvas;
        element.cherryCtx = ctx;
        element.cherryPetals = [];
        element.animationFrame = null;
        
        for (let i = 0; i < options.petalCount; i++) {
          element.cherryPetals.push(createPetal(canvas.width, canvas.height, options));
        }
        
        startCherryAnimation(element, options);
      }
      
      function createPetal(width, height, options) {
        const size = getRandomBetween(options.petalSizeMin, options.petalSizeMax);
        return {
          x: Math.random() * width,
          y: Math.random() * -height,
          size: size,
          color: options.colors[Math.floor(Math.random() * options.colors.length)],
          speed: getRandomBetween(options.speedMin, options.speedMax),
          swing: 0,
          swingSpeed: getRandomBetween(0.1, 0.3) * (Math.random() > 0.5 ? 1 : -1),
          swingRange: options.swingRange * Math.random(),
          rotation: Math.random() * 360,
          rotationSpeed: getRandomBetween(0.5, options.rotationSpeed) * (Math.random() > 0.5 ? 1 : -1),
          opacity: getRandomBetween(options.opacityMin, options.opacityMax)
        };
      }
      
      function getRandomBetween(min, max) {
        return min + Math.random() * (max - min);
      }
      
      function startCherryAnimation(element, options) {
        let lastTime = 0;
        const fpsInterval = 1000 / 60;
        
        function animate(currentTime) {
          element.animationFrame = requestAnimationFrame(animate);
          
          const deltaTime = currentTime - lastTime;
          if (deltaTime < fpsInterval) return;
          
          lastTime = currentTime - (deltaTime % fpsInterval);
          
          element.cherryCtx.clearRect(0, 0, element.cherryCanvas.width, element.cherryCanvas.height);
          
          element.cherryPetals.forEach(petal => {
            updatePetal(petal, element.cherryCanvas.width, element.cherryCanvas.height, deltaTime / 16, options);
            drawPetal(petal, element.cherryCtx);
          });
        }
        
        element.animationFrame = requestAnimationFrame(animate);
        
        const observer = new IntersectionObserver((entries) => {
          entries.forEach(entry => {
            if (entry.isIntersecting) {
              if (!element.animationFrame) {
                element.animationFrame = requestAnimationFrame(animate);
              }
            } else {
              if (element.animationFrame) {
                cancelAnimationFrame(element.animationFrame);
                element.animationFrame = null;
              }
            }
          });
        }, { threshold: 0 });
        
        observer.observe(element);
        
        element._cleanupCherry = () => {
          if (element.animationFrame) {
            cancelAnimationFrame(element.animationFrame);
          }
          observer.disconnect();
          if (element.cherryCanvas && element.cherryCanvas.parentNode) {
            element.cherryCanvas.parentNode.removeChild(element.cherryCanvas);
          }
          element.dataset.cherryInitialized = 'false';
        };
      }
      
      function updatePetal(petal, width, height, deltaTime, options) {
        petal.y += petal.speed * deltaTime;
        petal.swing += petal.swingSpeed * deltaTime;
        petal.x += Math.sin(petal.swing) * petal.swingRange;
        petal.rotation += petal.rotationSpeed * deltaTime;
        
        if (petal.y > height + petal.size) {
          petal.y = -petal.size;
          petal.x = Math.random() * width;
          petal.color = options.colors[Math.floor(Math.random() * options.colors.length)];
          petal.size = getRandomBetween(options.petalSizeMin, options.petalSizeMax);
          petal.speed = getRandomBetween(options.speedMin, options.speedMax);
          petal.opacity = getRandomBetween(options.opacityMin, options.opacityMax);
        }
        
        if (petal.x < -petal.size || petal.x > width + petal.size) {
          petal.x = Math.random() * width;
        }
      }
      
      function drawPetal(petal, ctx) {
        ctx.save();
        ctx.translate(petal.x, petal.y);
        ctx.rotate(petal.rotation * Math.PI / 180);
        
        ctx.globalAlpha = petal.opacity;
        ctx.fillStyle = petal.color;
        
        ctx.beginPath();
        
        const s = petal.size / 2;
        ctx.moveTo(0, -s * 0.5);
        ctx.bezierCurveTo(s * 0.5, -s * 1.1, s * 1.1, -s * 0.3, 0, s * 0.6);
        ctx.bezierCurveTo(-s * 1.1, -s * 0.3, -s * 0.5, -s * 1.1, 0, -s * 0.5);
        
        ctx.fill();
        ctx.restore();
      }
      
      function updateCherryPreview() {
        const previews = ['cherry-preview'];
        
        previews.forEach(previewId => {
          const preview = document.getElementById(previewId);
          if (!preview) return;
          
          if (preview._cleanupCherry) {
            preview._cleanupCherry();
          }
          
          preview.setAttribute('data-cherry-blossom', 'true');
          preview.setAttribute('data-cherry-petal-count', cherryConfig.petalCount);
          preview.setAttribute('data-cherry-petal-size-min', cherryConfig.petalSizeMin);
          preview.setAttribute('data-cherry-petal-size-max', cherryConfig.petalSizeMax);
          preview.setAttribute('data-cherry-speed-min', cherryConfig.speedMin);
          preview.setAttribute('data-cherry-speed-max', cherryConfig.speedMax);
          preview.setAttribute('data-cherry-swing-range', cherryConfig.swingRange);
          preview.setAttribute('data-cherry-rotation-speed', cherryConfig.rotationSpeed);
          preview.setAttribute('data-cherry-opacity-min', cherryConfig.opacityMin);
          preview.setAttribute('data-cherry-opacity-max', cherryConfig.opacityMax);
        });
        
        initCherryBlossomFlow();
      }

      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 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": {
          "_justifyContent": "center",
          "_background": {
            "color": {
              "hex": "#000000"
            }
          },
          "_attributes": [
            {
              "id": "wif87y",
              "name": "data-cherry-blossom"
            }
          ]
        },
        "label": "Blossom Section"
      },
      {
        "id": containerId,
        "name": "container",
        "parent": sectionId,
        "children": [],
        "settings": {
          "_alignItems": "center"
        },
        "label": "Container"
      },
      {
        "id": codeId,
        "name": "code",
        "parent": sectionId,
        "children": [],
        "settings": {
          "javascriptCode": jsCode,
          "executeCode": true,
          "_display": "none"
        },
        "label": "Blossom JS"
      }
    ],
    "source": "bricksCopiedElements",
    "sourceUrl": "https://test.bricksfusion.com",
    "version": "2.0.1",
    "globalClasses": [],
    "globalElements": []
  };
  
  return JSON.stringify(bricksJSON, null, 2);
}

      function generateJavaScriptCode() {
        const colorsString = cherryConfig.colors.map(color => `'${color}'`).join(', ');
        
        return `(function(window) {
  const EnhancedCherryBlossomAnimation = {
    instances: [],
    config: {
      petalCount: ${cherryConfig.petalCount},
      petalSizeMin: ${cherryConfig.petalSizeMin},
      petalSizeMax: ${cherryConfig.petalSizeMax},
      colors: [${colorsString}],
      speedMin: ${cherryConfig.speedMin},
      speedMax: ${cherryConfig.speedMax},
      swingRange: ${cherryConfig.swingRange},
      rotationSpeed: ${cherryConfig.rotationSpeed},
      opacityMin: ${cherryConfig.opacityMin},
      opacityMax: ${cherryConfig.opacityMax}
    },
    init: function(options = {}) {
      const defaultOptions = {
        selector: '[data-cherry-blossom]',
        colorAttr: 'data-cherry-colors'
      };
      const config = { ...defaultOptions, ...options };

      const initInstances = () => {
        document.querySelectorAll(config.selector).forEach(element => {
          if (!element.hasAttribute('data-cherry-initialized')) {
            this.createInstance(element, config);
            element.setAttribute('data-cherry-initialized', 'true');
          }
        });
      };

      initInstances();
      setTimeout(initInstances, 100);
      window.addEventListener('load', initInstances);

      const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
          if (mutation.type === 'childList') {
            initInstances();
          }
        });
      });

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

    createInstance: function(element, config) {
      const canvas = document.createElement('canvas');
      const ctx = canvas.getContext('2d');
      element.appendChild(canvas);

      if (window.getComputedStyle(element).position === 'static') {
        element.style.position = 'relative';
      }

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

      const instance = {
        element,
        canvas,
        ctx,
        width: 0,
        height: 0,
        cherryPetals: [],
        petalCount: this.config.petalCount,
        lastTime: 0,
        fpsInterval: 1000 / 60,

        resizeCanvas: function() {
          this.width = this.element.clientWidth;
          this.height = this.element.clientHeight;
          this.canvas.width = this.width;
          this.canvas.height = this.height;
        },

        createPetals: function() {
          this.cherryPetals = [];
          for (let i = 0; i < this.petalCount; i++) {
            this.cherryPetals.push(new CherryPetal(this));
          }
        },

        animate: function(currentTime) {
          requestAnimationFrame(this.animate.bind(this));
          const deltaTime = currentTime - this.lastTime;
          if (deltaTime < this.fpsInterval) return;
          this.lastTime = currentTime - (deltaTime % this.fpsInterval);

          this.ctx.clearRect(0, 0, this.width, this.height);
          this.cherryPetals.forEach(petal => {
            petal.update(deltaTime);
            petal.draw();
          });
        },

        resize: function() {
          this.resizeCanvas();
          this.createPetals();
        }
      };

      class CherryPetal {
        constructor(instance) {
          this.instance = instance;
          this.reset();
        }

        reset() {
          this.x = Math.random() * this.instance.width;
          this.y = Math.random() * -this.instance.height;
          this.size = this.getRandomBetween(EnhancedCherryBlossomAnimation.config.petalSizeMin, EnhancedCherryBlossomAnimation.config.petalSizeMax);
          this.color = EnhancedCherryBlossomAnimation.config.colors[Math.floor(Math.random() * EnhancedCherryBlossomAnimation.config.colors.length)];
          this.speed = this.getRandomBetween(EnhancedCherryBlossomAnimation.config.speedMin, EnhancedCherryBlossomAnimation.config.speedMax);
          this.swing = 0;
          this.swingSpeed = this.getRandomBetween(0.1, 0.3) * (Math.random() > 0.5 ? 1 : -1);
          this.swingRange = EnhancedCherryBlossomAnimation.config.swingRange * Math.random();
          this.rotation = Math.random() * 360;
          this.rotationSpeed = this.getRandomBetween(0.5, EnhancedCherryBlossomAnimation.config.rotationSpeed) * (Math.random() > 0.5 ? 1 : -1);
          this.opacity = this.getRandomBetween(EnhancedCherryBlossomAnimation.config.opacityMin, EnhancedCherryBlossomAnimation.config.opacityMax);
        }

        getRandomBetween(min, max) {
          return min + Math.random() * (max - min);
        }

        update(deltaTime) {
          const factor = deltaTime / 16;
          
          this.y += this.speed * factor;
          this.swing += this.swingSpeed * factor;
          this.x += Math.sin(this.swing) * this.swingRange;
          this.rotation += this.rotationSpeed * factor;
          
          if (this.y > this.instance.height + this.size) {
            this.reset();
          }
          
          if (this.x < -this.size || this.x > this.instance.width + this.size) {
            this.x = Math.random() * this.instance.width;
          }
        }

        draw() {
          const { ctx } = this.instance;

          ctx.save();
          ctx.translate(this.x, this.y);
          ctx.rotate(this.rotation * Math.PI / 180);
          
          ctx.globalAlpha = this.opacity;
          ctx.fillStyle = this.color;
          
          ctx.beginPath();
          
          const s = this.size / 2;
          ctx.moveTo(0, -s * 0.5);
          ctx.bezierCurveTo(s * 0.5, -s * 1.1, s * 1.1, -s * 0.3, 0, s * 0.6);
          ctx.bezierCurveTo(-s * 1.1, -s * 0.3, -s * 0.5, -s * 1.1, 0, -s * 0.5);
          
          ctx.fill();
          ctx.restore();
        }
      }

      instance.resizeCanvas();
      instance.createPetals();
      instance.animate(0);

      let resizeTimeout;
      window.addEventListener('resize', () => {
        clearTimeout(resizeTimeout);
        resizeTimeout = setTimeout(() => instance.resize(), 250);
      });

      this.instances.push(instance);
    }
  };

  window.EnhancedCherryBlossomAnimation = EnhancedCherryBlossomAnimation;
  EnhancedCherryBlossomAnimation.init();
})(window);`;
      }

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

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

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

      function 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}%)`;
      }

      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 'petal-count':
              cherryConfig.petalCount = defaultValue;
              break;
            case 'petal-size-min':
              cherryConfig.petalSizeMin = defaultValue;
              break;
            case 'petal-size-max':
              cherryConfig.petalSizeMax = defaultValue;
              break;
            case 'fall-speed-min':
              cherryConfig.speedMin = defaultValue;
              break;
            case 'fall-speed-max':
              cherryConfig.speedMax = defaultValue;
              break;
            case 'swing-range':
              cherryConfig.swingRange = defaultValue;
              break;
            case 'rotation-speed':
              cherryConfig.rotationSpeed = defaultValue;
              break;
            case 'opacity-min':
              cherryConfig.opacityMin = defaultValue;
              break;
            case 'opacity-max':
              cherryConfig.opacityMax = defaultValue;
              break;
          }
          
          updateCherryPreview();
          showNotification(`${parameterId.replace(/-/g, ' ')} reset to default`);
        }
      };

      window.randomizeColor = function(index) {
        const newColor = generateRandomColor();
        cherryConfig.colors[index] = newColor;
        
        const colorInput = document.getElementById(`petal-color-${index}`);
        const hexInput = document.getElementById(`petal-color-hex-${index}`);
        const hslInput = document.getElementById(`petal-color-hsl-${index}`);
        const colorPicker = colorInput.closest('.color-row').querySelector('.color-picker-container');
        
        colorInput.value = newColor;
        hexInput.value = newColor;
        hslInput.value = `hsl(${hexToHsl(newColor).h}, ${hexToHsl(newColor).s}%, ${hexToHsl(newColor).l}%)`;
        colorPicker.style.setProperty('--selected-color', newColor);
        
        hexInput.classList.remove('invalid');
        hslInput.classList.remove('invalid');
        
        updateCherryPreview();
        showNotification(`Color ${index + 1} randomized!`);
      };

      function generateRandomCherry() {
        cherryConfig.petalCount = Math.floor(Math.random() * 90) + 10;
        cherryConfig.petalSizeMin = Math.floor(Math.random() * 20) + 10;
        cherryConfig.petalSizeMax = Math.floor(Math.random() * 30) + 30;
        cherryConfig.speedMin = Math.random() * 1.5 + 0.5;
        cherryConfig.speedMax = Math.random() * 3 + 2;
        cherryConfig.swingRange = Math.random() * 4.5 + 0.5;
        cherryConfig.rotationSpeed = Math.random() * 3.5 + 0.5;
        cherryConfig.opacityMin = Math.random() * 0.5 + 0.2;
        cherryConfig.opacityMax = Math.random() * 0.3 + 0.7;
        
        for (let i = 0; i < 5; i++) {
          cherryConfig.colors[i] = generateRandomColor();
        }
        
        document.getElementById('petal-count').value = cherryConfig.petalCount;
        document.getElementById('petal-size-min').value = cherryConfig.petalSizeMin;
        document.getElementById('petal-size-max').value = cherryConfig.petalSizeMax;
        document.getElementById('fall-speed-min').value = cherryConfig.speedMin;
        document.getElementById('fall-speed-max').value = cherryConfig.speedMax;
        document.getElementById('swing-range').value = cherryConfig.swingRange;
        document.getElementById('rotation-speed').value = cherryConfig.rotationSpeed;
        document.getElementById('opacity-min').value = cherryConfig.opacityMin;
        document.getElementById('opacity-max').value = cherryConfig.opacityMax;
        
        document.getElementById('petal-count-value').textContent = cherryConfig.petalCount;
        document.getElementById('petal-size-min-value').textContent = cherryConfig.petalSizeMin;
        document.getElementById('petal-size-max-value').textContent = cherryConfig.petalSizeMax;
        document.getElementById('fall-speed-min-value').textContent = cherryConfig.speedMin;
        document.getElementById('fall-speed-max-value').textContent = cherryConfig.speedMax;
        document.getElementById('swing-range-value').textContent = cherryConfig.swingRange;
        document.getElementById('rotation-speed-value').textContent = cherryConfig.rotationSpeed;
        document.getElementById('opacity-min-value').textContent = cherryConfig.opacityMin;
        document.getElementById('opacity-max-value').textContent = cherryConfig.opacityMax;
        
        updateColorInputs();
        updateCherryPreview();
        showNotification('Random cherry blossom generated!');
      }

      function updateColorInputs() {
        for (let i = 0; i < 5; i++) {
          const colorInput = document.getElementById(`petal-color-${i}`);
          const hexInput = document.getElementById(`petal-color-hex-${i}`);
          const hslInput = document.getElementById(`petal-color-hsl-${i}`);
          const colorPicker = colorInput.closest('.color-row').querySelector('.color-picker-container');
          
          colorInput.value = cherryConfig.colors[i];
          hexInput.value = cherryConfig.colors[i];
          hslInput.value = `hsl(${hexToHsl(cherryConfig.colors[i]).h}, ${hexToHsl(cherryConfig.colors[i]).s}%, ${hexToHsl(cherryConfig.colors[i]).l}%)`;
          colorPicker.style.setProperty('--selected-color', cherryConfig.colors[i]);
          
          hexInput.classList.remove('invalid');
          hslInput.classList.remove('invalid');
        }
      }

      function initializeUI() {
        initCherryBlossomFlow();
        
        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-cherry-blossom');
        });

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

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

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

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

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

        previewContainer.style.backgroundColor = '#000000';

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

        document.getElementById('reset-animation').addEventListener('click', () => {
          cherryConfig.petalCount = defaultConfig.petalCount;
          cherryConfig.petalSizeMin = defaultConfig.petalSizeMin;
          cherryConfig.petalSizeMax = defaultConfig.petalSizeMax;
          cherryConfig.speedMin = defaultConfig.speedMin;
          cherryConfig.speedMax = defaultConfig.speedMax;
          
          document.getElementById('petal-count').value = defaultConfig.petalCount;
          document.getElementById('petal-size-min').value = defaultConfig.petalSizeMin;
          document.getElementById('petal-size-max').value = defaultConfig.petalSizeMax;
          document.getElementById('fall-speed-min').value = defaultConfig.speedMin;
          document.getElementById('fall-speed-max').value = defaultConfig.speedMax;
          
          document.getElementById('petal-count-value').textContent = defaultConfig.petalCount;
          document.getElementById('petal-size-min-value').textContent = defaultConfig.petalSizeMin;
          document.getElementById('petal-size-max-value').textContent = defaultConfig.petalSizeMax;
          document.getElementById('fall-speed-min-value').textContent = defaultConfig.speedMin;
          document.getElementById('fall-speed-max-value').textContent = defaultConfig.speedMax;
          
          updateCherryPreview();
          showNotification('Animation settings reset');
        });

        document.getElementById('reset-advanced').addEventListener('click', () => {
          cherryConfig.swingRange = defaultConfig.swingRange;
          cherryConfig.rotationSpeed = defaultConfig.rotationSpeed;
          cherryConfig.opacityMin = defaultConfig.opacityMin;
          cherryConfig.opacityMax = defaultConfig.opacityMax;
          
          document.getElementById('swing-range').value = defaultConfig.swingRange;
          document.getElementById('rotation-speed').value = defaultConfig.rotationSpeed;
          document.getElementById('opacity-min').value = defaultConfig.opacityMin;
          document.getElementById('opacity-max').value = defaultConfig.opacityMax;
          document.getElementById('swing-range-value').textContent = defaultConfig.swingRange;
          document.getElementById('rotation-speed-value').textContent = defaultConfig.rotationSpeed;
          document.getElementById('opacity-min-value').textContent = defaultConfig.opacityMin;
          document.getElementById('opacity-max-value').textContent = defaultConfig.opacityMax;
          
          updateCherryPreview();
          showNotification('Advanced settings reset');
        });

        for (let i = 0; i < 5; i++) {
          const colorInput = document.getElementById(`petal-color-${i}`);
          const hexInput = document.getElementById(`petal-color-hex-${i}`);
          const hslInput = document.getElementById(`petal-color-hsl-${i}`);
          const colorPicker = colorInput.closest('.color-row').querySelector('.color-picker-container');
          
          hslInput.value = `hsl(${hexToHsl(colorInput.value).h}, ${hexToHsl(colorInput.value).s}%, ${hexToHsl(colorInput.value).l}%)`;
          colorPicker.style.setProperty('--selected-color', colorInput.value);
          
          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');
            cherryConfig.colors[i] = color;
            colorPicker.style.setProperty('--selected-color', color);
            updateCherryPreview();
          });
          
          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}%)`;
              cherryConfig.colors[i] = hex;
              e.target.classList.remove('invalid');
              hslInput.classList.remove('invalid');
              colorPicker.style.setProperty('--selected-color', hex);
              updateCherryPreview();
            } 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;
                cherryConfig.colors[i] = hex;
                e.target.classList.remove('invalid');
                hexInput.classList.remove('invalid');
                colorPicker.style.setProperty('--selected-color', hex);
                updateCherryPreview();
                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;
                  cherryConfig.colors[i] = hex;
                  e.target.classList.remove('invalid');
                  hexInput.classList.remove('invalid');
                  colorPicker.style.setProperty('--selected-color', hex);
                  updateCherryPreview();
                  return;
                }
              }
            }
            
            if (!isValidHsl(e.target.value)) {
              e.target.value = `hsl(${hexToHsl(colorInput.value).h}, ${hexToHsl(colorInput.value).s}%, ${hexToHsl(colorInput.value).l}%)`;
              e.target.classList.remove('invalid');
            }
          });
        }

        const rangeInputs = document.querySelectorAll('input[type="range"]');
        rangeInputs.forEach(input => {
          const valueElement = document.getElementById(`${input.id}-value`);
          
          if (valueElement) {
            valueElement.textContent = input.value;
          }
          
          input.addEventListener('input', () => {
            if (valueElement) {
              valueElement.textContent = input.value;
            }
            
            switch (input.id) {
              case 'petal-count':
                cherryConfig.petalCount = parseInt(input.value);
                break;
              case 'petal-size-min':
                cherryConfig.petalSizeMin = parseFloat(input.value);
                break;
              case 'petal-size-max':
                cherryConfig.petalSizeMax = parseFloat(input.value);
                break;
              case 'fall-speed-min':
                cherryConfig.speedMin = parseFloat(input.value);
                break;
              case 'fall-speed-max':
                cherryConfig.speedMax = parseFloat(input.value);
                break;
              case 'swing-range':
                cherryConfig.swingRange = parseFloat(input.value);
                break;
              case 'rotation-speed':
                cherryConfig.rotationSpeed = parseFloat(input.value);
                break;
              case 'opacity-min':
                cherryConfig.opacityMin = parseFloat(input.value);
                break;
              case 'opacity-max':
                cherryConfig.opacityMax = parseFloat(input.value);
                break;
            }
            
            updateCherryPreview();
          });
        });

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

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

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

        function loadConfiguration() {
          try {
            const saved = localStorage.getItem('bricksfusion-cherry-config');
            if (saved) {
              const savedConfig = JSON.parse(saved);
              Object.assign(cherryConfig, savedConfig);
              
              document.getElementById('petal-count').value = savedConfig.petalCount;
              document.getElementById('petal-size-min').value = savedConfig.petalSizeMin;
              document.getElementById('petal-size-max').value = savedConfig.petalSizeMax;
              document.getElementById('fall-speed-min').value = savedConfig.speedMin;
              document.getElementById('fall-speed-max').value = savedConfig.speedMax;
              document.getElementById('swing-range').value = savedConfig.swingRange;
              document.getElementById('rotation-speed').value = savedConfig.rotationSpeed;
              document.getElementById('opacity-min').value = savedConfig.opacityMin;
              document.getElementById('opacity-max').value = savedConfig.opacityMax;
              
              document.getElementById('petal-count-value').textContent = savedConfig.petalCount;
              document.getElementById('petal-size-min-value').textContent = savedConfig.petalSizeMin;
              document.getElementById('petal-size-max-value').textContent = savedConfig.petalSizeMax;
              document.getElementById('fall-speed-min-value').textContent = savedConfig.speedMin;
              document.getElementById('fall-speed-max-value').textContent = savedConfig.speedMax;
              document.getElementById('swing-range-value').textContent = savedConfig.swingRange;
              document.getElementById('rotation-speed-value').textContent = savedConfig.rotationSpeed;
              document.getElementById('opacity-min-value').textContent = savedConfig.opacityMin;
              document.getElementById('opacity-max-value').textContent = savedConfig.opacityMax;
              
              updateColorInputs();
              updateCherryPreview();
            }
          } catch (e) {
          }
        }

        const originalUpdateCherryPreview = updateCherryPreview;
        updateCherryPreview = function() {
          originalUpdateCherryPreview();
          saveConfiguration();
        };

        loadConfiguration();
      }
      
      initializeUI();
    });
  </script>
</body>
</html>
Cherry Blossom - Bricksfusion
MEDIUM

Cherry Blossom

Creates beautiful falling cherry blossom petals that drift and rotate naturally. Perfect for spring themes, romantic sections, or adding an elegant touch to hero areas.

Cherry Blossom

Watch the delicate petals fall and drift naturally across your content.

Petals

Petal Count 5-100

Number of petals on screen. More petals create a denser snowfall effect. Keep under 50 for best performance.

Default: 30

Petal Size Min 10-50 pixels

Minimum size of petals. Smaller petals look more delicate and distant.

Default: 20

Petal Size Max 20-80 pixels

Maximum size of petals. Larger petals appear closer and more prominent. Mix sizes for natural depth.

Default: 40

Colors color picker array

Colors for the petals. Multiple colors create variety. Traditional cherry blossoms are pink, but you can use any colors for different flowers.

Default: Pink tones

Animation

Speed Min 0.5-5.0

Minimum falling speed. Slower speeds create gentle, dreamy movement.

Default: 1.0

Speed Max 1.0-8.0

Maximum falling speed. Faster speeds add energy. Varying speeds creates natural randomness.

Default: 3.0

Swing Range 0.5-5.0

How much petals drift side to side. Higher values create more horizontal movement, like wind.

Default: 2.0

Rotation Speed 0.5-5.0

How fast petals spin. Higher values create more rotation. Moderate values look most natural.

Default: 2.0

Appearance

Opacity Min 0.1-1.0

Minimum transparency of petals. Lower values make some petals more subtle and distant.

Default: 0.6

Opacity Max 0.3-1.0

Maximum transparency of petals. Higher values make prominent petals more visible and vibrant.

Default: 0.9

Performance

This element uses HTML5 Canvas with custom petal shapes drawn using bezier curves. It automatically pauses when scrolled out of view and adapts to window resizing. Keep petal count under 50 for optimal performance.