function BuilderSection({ cart = [], setCart, isCartOpen, setIsCartOpen }) {
  const [format, setFormat] = React.useState('starter');
  // quantities: { [colorName]: number } - only keys with value > 0 are "selected"
  const [quantities, setQuantities] = React.useState({});

  const formatOptions = {
    starter: { label: 'Starter Palette', max: 3, price: 50, desc: '3 colors · $50 MXN' },
    full: { label: 'Full Palette', max: 6, price: 95, desc: '6 colors · $95 MXN' },
    godet: { label: 'Individual Godet', max: 1, price: 20, desc: '1 color · $20 MXN' },
  };

  const currentFormat = formatOptions[format];
  const maxSlots = currentFormat.max;
  const price = currentFormat.price;

  // Total godets currently in the tray
  const totalSelected = Object.values(quantities).reduce((sum, n) => sum + n, 0);

  // Colors that have at least 1 godet
  const selectedColors = Object.entries(quantities)
    .filter(([, qty]) => qty > 0)
    .map(([name]) => name);

  // Increment: only if there's room
  const increment = (name) => {
    const current = quantities[name] || 0;
    if (totalSelected >= maxSlots) return; // palette is full
    setQuantities(prev => ({ ...prev, [name]: current + 1 }));
  };

  // Decrement: remove key when reaching 0
  const decrement = (name) => {
    const current = quantities[name] || 0;
    if (current <= 0) return;
    const next = current - 1;
    setQuantities(prev => {
      const updated = { ...prev, [name]: next };
      if (next === 0) delete updated[name];
      return updated;
    });
  };

  // Remove a color entirely from tray
  const removeColor = (name) => {
    setQuantities(prev => {
      const updated = { ...prev };
      delete updated[name];
      return updated;
    });
  };

  // Reset when format changes (trim to max)
  React.useEffect(() => {
    setQuantities(prev => {
      let total = 0;
      const trimmed = {};
      for (const [name, qty] of Object.entries(prev)) {
        const take = Math.min(qty, maxSlots - total);
        if (take > 0) { trimmed[name] = take; total += take; }
        if (total >= maxSlots) break;
      }
      return trimmed;
    });
  }, [format]);

  const ready = totalSelected === maxSlots;

  // Build expanded color list for tray (each godet is one slot)
  const traySlots = [];
  for (const [name, qty] of Object.entries(quantities)) {
    for (let i = 0; i < qty; i++) traySlots.push(name);
  }

  const handleAddToCart = () => {
    if (!ready || !setCart) return;
    const newItem = {
      id: Date.now(),
      format,
      formatLabel: currentFormat.label,
      price,
      colors: traySlots
    };
    setCart(prev => [...prev, newItem]);
    setQuantities({});
    setIsCartOpen && setIsCartOpen(true);
  };

  const handleRemoveFromCart = (id) => {
    if (setCart) setCart(prev => prev.filter(item => item.id !== id));
  };

  // Build WhatsApp Message
  const cartText = cart.map(item => {
    const colorList = [...item.colors].sort().reduce((acc, c) => {
      const found = acc.find(x => x.name === c);
      if (found) found.qty++;
      else acc.push({ name: c, qty: 1 });
      return acc;
    }, []).map(x => x.qty > 1 ? `${x.name} ×${x.qty}` : x.name).join(', ');
    return `• 1x ${item.formatLabel} (${colorList})`;
  }).join('%0A');
  const cartTotal = cart.reduce((sum, item) => sum + item.price, 0);
  const waMsg = `Hello, I'd like to place an order:%0A%0A${cartText}%0A%0ATotal: $${cartTotal} MXN. Is it available?`;
  const waUrl = `https://wa.me/522941040210?text=${waMsg}`;

  return (
    <section id="builder" style={{ background: 'var(--paper-cream)', padding: 'clamp(3rem, 8vh, 6rem) clamp(1.5rem, 6vw, 6rem)' }}>
      <SectionReveal>
        <h2 style={{
          fontFamily: 'var(--font-identity)', fontWeight: 600, fontSize: 'clamp(36px, 4vw, 48px)',
          color: 'var(--ink-dark)', textAlign: 'center', marginBottom: 8,
        }}>Build my palette.</h2>
        <p style={{
          fontFamily: 'var(--font-ui)', fontSize: 16, color: 'var(--ink-dark)',
          textAlign: 'center', marginBottom: 32,
        }}>Choose your format and colors. Orders ship in our handmade kraft boxes.</p>
      </SectionReveal>

      {/* Format toggle */}
      <SectionReveal delay={100}>
        <div style={{ display: 'flex', justifyContent: 'center', gap: 12, marginBottom: 40, flexWrap: 'wrap' }}>
          {Object.entries(formatOptions).map(([key, opt]) => (
            <button key={key} onClick={() => setFormat(key)} style={{
              fontFamily: 'var(--font-ui)', fontWeight: 500, fontSize: 13,
              background: format === key ? 'var(--flower-pink)' : 'transparent',
              color: format === key ? 'var(--paper-cream)' : 'var(--ink-dark)',
              border: format === key ? 'none' : '1px solid var(--ink-dark)',
              borderRadius: 2, padding: '10px 20px', cursor: 'pointer', transition: 'all 0.2s',
            }}>{opt.desc}</button>
          ))}
        </div>
      </SectionReveal>

      <SectionReveal delay={200}>
        <div style={{
          display: 'grid', gridTemplateColumns: 'minmax(0, 1.2fr) minmax(0, 0.8fr)',
          gap: 40, maxWidth: 820, margin: '0 auto', alignItems: 'start',
        }} className="builder-grid">

          {/* Kraft tray + wet palette */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            {/* Kraft tray */}
            <div style={{
              backgroundColor: '#C8A86E', borderRadius: 6, padding: '24px 20px 20px',
              backgroundImage: `repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,0.015) 2px, rgba(0,0,0,0.015) 3px),
                repeating-linear-gradient(90deg, transparent, transparent 4px, rgba(0,0,0,0.008) 4px, rgba(0,0,0,0.008) 5px)`,
              boxShadow: '0 4px 20px rgba(0,0,0,0.1)',
            }}>
              <div style={{
                display: 'grid', gridTemplateColumns: format === 'godet' ? '1fr' : `repeat(3, 1fr)`,
                gap: 16, justifyItems: 'center', marginBottom: 18,
              }}>
                {Array.from({ length: maxSlots }).map((_, i) => {
                  const colorName = traySlots[i];
                  const colorData = colorName ? COLORS_DATA.find(c => c.name === colorName) : null;
                  return (
                    <div key={i} style={{ position: 'relative' }}>
                      {colorData ? (
                        <div style={{ position: 'relative' }}>
                          <Godet dry={colorData.dry} wet={colorData.wet} size={48} onClick={() => removeColor(colorData.name)} />
                          <button onClick={() => removeColor(colorData.name)} style={{
                            position: 'absolute', top: -3, right: -3, width: 18, height: 18,
                            borderRadius: '50%', background: 'var(--flower-pink)', color: 'var(--paper-cream)',
                            border: 'none', fontSize: 11, cursor: 'pointer', zIndex: 5,
                            display: 'flex', alignItems: 'center', justifyContent: 'center',
                          }}>×</button>
                        </div>
                      ) : (
                        <div style={{
                          width: 56, height: 56, borderRadius: '50%',
                          border: '2px dashed var(--water-turquoise)',
                          opacity: 0.5, animation: 'pulse 2s ease-in-out infinite',
                        }}></div>
                      )}
                    </div>
                  );
                })}
              </div>

              {/* Logo on tray */}
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8 }}>
                <XochiatlLogo size={30} mono={false} />
                <span style={{ fontFamily: 'var(--font-identity)', fontWeight: 600, fontSize: 13, color: 'var(--flower-pink)', letterSpacing: '0.1em' }}>XOCHIATL</span>
              </div>
            </div>

            {/* Wet palette: how it paints */}
            <div style={{
              background: 'white', borderRadius: 4, padding: '16px 20px',
              border: '1px solid rgba(34,34,51,0.08)',
              opacity: selectedColors.length > 0 ? 1 : 0.4, transition: 'opacity 0.4s',
            }}>
              <p style={{
                fontFamily: 'var(--font-ui)', fontSize: 10, color: 'var(--water-turquoise)',
                letterSpacing: '0.15em', textTransform: 'uppercase', marginBottom: 12,
              }}>How it paints on paper</p>
              <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
                {selectedColors.length === 0 ? (
                  <span style={{ fontFamily: 'var(--font-ui)', fontSize: 12, color: 'rgba(34,34,51,0.35)', fontStyle: 'italic' }}>
                    Select colors above to preview their painted look
                  </span>
                ) : (
                  selectedColors.map(name => {
                    const c = COLORS_DATA.find(x => x.name === name);
                    return (
                      <div key={name} style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
                        <div style={{
                          width: 32, height: 32, borderRadius: '50%',
                          background: `radial-gradient(circle at 35% 35%, color-mix(in srgb, ${c.wet} 55%, white), ${c.wet} 60%, color-mix(in srgb, ${c.wet} 75%, black) 100%)`,
                          boxShadow: `0 0 0 1px rgba(0,0,0,0.08), 0 2px 6px ${c.wet}44`,
                        }}></div>
                        <span style={{ fontFamily: 'var(--font-ui)', fontSize: 9, color: 'rgba(34,34,51,0.5)', textAlign: 'center' }}>{name}</span>
                      </div>
                    );
                  })
                )}
              </div>
              {selectedColors.length > 0 && (
                <p style={{ fontFamily: 'var(--font-ui)', fontSize: 10, color: 'rgba(34,34,51,0.35)', marginTop: 10, lineHeight: 1.5 }}>
                  These are the colors that appear on paper: they differ from what you see in the cap. That is the surprise.
                </p>
              )}
            </div>
          </div>

          {/* Color picker with quantity counter */}
          <div>
            <p style={{ fontFamily: 'var(--font-ui)', fontSize: 13, color: 'var(--ink-dark)', marginBottom: 16, fontWeight: 500 }}>
              Select your colors ({totalSelected}/{maxSlots}):
            </p>

            <style>{`
              .color-tile {
                display: flex;
                flex-direction: column;
                align-items: center;
                gap: 6;
                border-radius: 4px;
                padding: 12px 8px 8px;
                cursor: pointer;
                transition: all 0.2s;
                position: relative;
                overflow: hidden;
              }
              .qty-bar {
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 6px;
                margin-top: 6px;
                height: 28px;
                width: 100%;
              }
              .qty-btn {
                width: 22px;
                height: 22px;
                border-radius: 50%;
                border: none;
                cursor: pointer;
                font-size: 14px;
                font-weight: 700;
                display: flex;
                align-items: center;
                justify-content: center;
                transition: all 0.15s;
                flex-shrink: 0;
                line-height: 1;
              }
              .qty-btn:active { transform: scale(0.9); }
              .qty-btn-minus {
                background: rgba(199,46,102,0.12);
                color: var(--flower-pink);
              }
              .qty-btn-minus:hover { background: rgba(199,46,102,0.25); }
              .qty-btn-plus {
                background: var(--flower-pink);
                color: var(--paper-cream);
              }
              .qty-btn-plus:hover { background: #a8244f; }
              .qty-btn-plus:disabled {
                background: rgba(199,46,102,0.25);
                cursor: not-allowed;
              }
            `}</style>

            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 10 }}>
              {COLORS_DATA.map(c => {
                const qty = quantities[c.name] || 0;
                const isSelected = qty > 0;
                const isFull = totalSelected >= maxSlots;

                return (
                  <div key={c.name} className="color-tile" style={{
                    background: isSelected ? 'rgba(199,46,102,0.07)' : 'transparent',
                    border: isSelected ? '2px solid var(--flower-pink)' : '1px solid rgba(34,34,51,0.15)',
                    paddingBottom: isSelected ? '8px' : '12px',
                  }}>
                    {/* Main tile: clicking on godet or name adds 1 */}
                    <div
                      onClick={() => increment(c.name)}
                      style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 6, cursor: isFull && !isSelected ? 'not-allowed' : 'pointer', width: '100%' }}
                    >
                      <div style={{
                        width: 36, height: 36, borderRadius: '50%',
                        background: `radial-gradient(circle at 35% 35%, color-mix(in srgb, ${c.dry} 60%, white), ${c.dry} 55%, color-mix(in srgb, ${c.dry} 80%, black) 100%)`,
                        boxShadow: isSelected ? `0 0 0 2px var(--flower-pink)` : '0 0 0 2px #A8A8A8',
                        transition: 'box-shadow 0.2s',
                      }}></div>
                      <span style={{ fontFamily: 'var(--font-ui)', fontSize: 11, color: 'var(--ink-dark)' }}>{c.name}</span>
                    </div>

                    {/* Quantity counter: only visible when qty > 0 */}
                    {isSelected && (
                      <div className="qty-bar">
                        <button
                          className="qty-btn qty-btn-minus"
                          onClick={(e) => { e.stopPropagation(); decrement(c.name); }}
                          aria-label={`Remove one ${c.name} godet`}
                        >−</button>

                        <span style={{
                          fontFamily: 'var(--font-ui)', fontWeight: 600, fontSize: 14,
                          color: 'var(--flower-pink)', minWidth: 16, textAlign: 'center',
                        }}>{qty}</span>

                        <button
                          className="qty-btn qty-btn-plus"
                          onClick={(e) => { e.stopPropagation(); increment(c.name); }}
                          disabled={isFull}
                          aria-label={`Add one ${c.name} godet`}
                        >+</button>
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </SectionReveal>

      {/* Summary + CTA */}
      <SectionReveal delay={300}>
        <div style={{ maxWidth: 600, margin: '36px auto 0', textAlign: 'center' }}>
          {ready ? (
            <div style={{ display: 'flex', gap: 12, justifyContent: 'center', flexWrap: 'wrap' }}>
              <button onClick={handleAddToCart} style={{
                fontFamily: 'var(--font-ui)', fontWeight: 500, fontSize: 15,
                background: 'var(--flower-pink)', color: 'var(--paper-cream)',
                border: 'none', borderRadius: 2, padding: '14px 36px',
                cursor: 'pointer', transition: 'background 0.3s',
              }}>
                Add to Cart →
              </button>
            </div>
          ) : (
            <div style={{
              display: 'inline-block', fontFamily: 'var(--font-ui)', fontWeight: 500, fontSize: 15,
              background: 'rgba(199,46,102,0.35)', color: 'var(--paper-cream)',
              borderRadius: 2, padding: '14px 36px',
              cursor: 'not-allowed', transition: 'background 0.3s',
            }}>
              {totalSelected === 0
                ? `Select ${maxSlots} color${maxSlots !== 1 ? 's' : ''} to order`
                : `Add ${maxSlots - totalSelected} more godet${maxSlots - totalSelected !== 1 ? 's' : ''} to order`}
            </div>
          )}
          
          {cart.length > 0 && (
            <div style={{ marginTop: 24 }}>
              <button onClick={() => setIsCartOpen && setIsCartOpen(true)} style={{
                fontFamily: 'var(--font-ui)', fontWeight: 600, fontSize: 14,
                background: 'none', color: 'var(--ink-dark)', textDecoration: 'underline',
                border: 'none', cursor: 'pointer',
              }}>
                View Cart ({cart.length} item{cart.length !== 1 ? 's' : ''})
              </button>
            </div>
          )}

          <p style={{ fontFamily: 'var(--font-ui)', fontSize: 11, color: 'rgba(34,34,51,0.4)', marginTop: 24 }}>
            No online checkout. Orders are placed directly via WhatsApp for a personal, zero-friction experience.
          </p>
        </div>
      </SectionReveal>

      {/* Cart Summary Modal */}
      {isCartOpen && (
        <div style={{
          position: 'fixed', inset: 0, zIndex: 9995, background: 'rgba(34,34,51,0.7)',
          display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24,
        }} onClick={() => setIsCartOpen && setIsCartOpen(false)}>
          <div style={{
            background: 'var(--paper-cream)', borderRadius: 4, padding: 40,
            maxWidth: 500, width: '100%', position: 'relative', maxHeight: '90vh', overflowY: 'auto'
          }} onClick={e => e.stopPropagation()}>
            <h3 style={{ fontFamily: 'var(--font-identity)', fontWeight: 600, fontSize: 28, color: 'var(--ink-dark)', marginBottom: 8 }}>
              Your Cart
            </h3>
            
            {cart.length === 0 ? (
              <p style={{ fontFamily: 'var(--font-ui)', fontSize: 14, color: 'var(--ink-dark)', opacity: 0.7, marginBottom: 24 }}>
                Your cart is empty. Add a palette or godet to get started.
              </p>
            ) : (
              <>
                <p style={{ fontFamily: 'var(--font-ui)', fontSize: 14, color: 'var(--ink-dark)', marginBottom: 24, lineHeight: 1.6 }}>
                  Review your items before confirming via WhatsApp.
                </p>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 16, marginBottom: 24 }}>
                  {cart.map(item => {
                    // Group colors with quantities for display
                    const grouped = [...item.colors].sort().reduce((acc, c) => {
                      const found = acc.find(x => x.name === c);
                      if (found) found.qty++;
                      else acc.push({ name: c, qty: 1 });
                      return acc;
                    }, []);

                    return (
                      <div key={item.id} style={{ background: 'white', border: '1px solid rgba(34,34,51,0.1)', borderRadius: 4, padding: 16, position: 'relative' }}>
                        <button onClick={() => handleRemoveFromCart(item.id)} style={{
                          position: 'absolute', top: 12, right: 12, background: 'none', border: 'none',
                          color: 'var(--flower-pink)', fontSize: 20, cursor: 'pointer', opacity: 0.7
                        }}>×</button>
                        <div style={{ marginBottom: 8, paddingRight: 24 }}>
                          <h4 style={{ fontFamily: 'var(--font-ui)', fontWeight: 600, fontSize: 15, color: 'var(--ink-dark)' }}>
                            {item.formatLabel}
                          </h4>
                          <span style={{ fontFamily: 'var(--font-ui)', fontWeight: 500, fontSize: 14, color: 'var(--flower-pink)' }}>
                            ${item.price} MXN
                          </span>
                        </div>
                        <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
                          {grouped.map(({ name: cName, qty }, idx) => {
                            const colorDef = COLORS_DATA.find(x => x.name === cName);
                            return (
                              <div key={idx} style={{
                                display: 'inline-flex', alignItems: 'center', gap: 6,
                                fontFamily: 'var(--font-ui)', fontSize: 12, color: 'rgba(34,34,51,0.7)',
                                background: 'var(--paper-cream)', padding: '4px 8px', borderRadius: 20
                              }}>
                                <span style={{ width: 10, height: 10, borderRadius: '50%', background: colorDef?.dry }}></span>
                                {cName}{qty > 1 ? ` ×${qty}` : ''}
                              </div>
                            );
                          })}
                        </div>
                      </div>
                    );
                  })}
                </div>
                
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24, padding: '16px 0', borderTop: '2px solid rgba(34,34,51,0.1)' }}>
                  <span style={{ fontFamily: 'var(--font-ui)', fontWeight: 500, fontSize: 16, color: 'var(--ink-dark)' }}>Total</span>
                  <span style={{ fontFamily: 'var(--font-identity)', fontWeight: 600, fontSize: 24, color: 'var(--ink-dark)' }}>${cartTotal} MXN</span>
                </div>

                <a href={waUrl} target="_blank" rel="noopener noreferrer" onClick={() => {
                  setIsCartOpen && setIsCartOpen(false);
                  if (setCart) setCart([]);
                }} style={{
                  display: 'block', textAlign: 'center', width: '100%', fontFamily: 'var(--font-ui)', fontWeight: 500, fontSize: 15,
                  background: 'var(--flower-pink)', color: 'var(--paper-cream)', textDecoration: 'none',
                  border: 'none', borderRadius: 2, padding: '14px', cursor: 'pointer', marginBottom: 12
                }}>Confirm on WhatsApp →</a>

                <div style={{ textAlign: 'center' }}>
                  <button onClick={() => setIsCartOpen && setIsCartOpen(false)} style={{
                    background: 'none', border: 'none', color: 'var(--ink-dark)',
                    fontFamily: 'var(--font-ui)', fontSize: 13, textDecoration: 'underline',
                    cursor: 'pointer', opacity: 0.7
                  }}>Continue exploring the shop</button>
                </div>
              </>
            )}

            <button onClick={() => setIsCartOpen && setIsCartOpen(false)} style={{
              position: 'absolute', top: 12, right: 16, background: 'none', border: 'none',
              fontSize: 24, color: 'var(--ink-dark)', cursor: 'pointer', opacity: 0.5,
            }}>×</button>
          </div>
        </div>
      )}

      <style>{`
        @media (max-width: 768px) { .builder-grid { grid-template-columns: 1fr !important; } }
      `}</style>
    </section>
  );
}

window.BuilderSection = BuilderSection;
