{% comment %}
  bundle-breaks.liquid
  Main product + up to 3 addon products per radio option.
  id="bundle-deals-{section.id}" → ProductForm.bundleDeals.formVariants = [{id,quantity},...]

  Usage: {% render 'bundle-breaks', block: block, product: product, product_form_id: product_form_id %}
{% endcomment %}

{%- liquid
  assign bb_main_variant = product.selected_or_first_available_variant
  assign bb_main_price   = bb_main_variant.price
  assign bb_main_compare = bb_main_variant.compare_at_price | default: bb_main_price
  if bb_main_compare < bb_main_price
    assign bb_main_compare = bb_main_price
  endif

  assign bb_variants_available = product.variants | map: 'available'
  assign bb_variants_opt1      = product.variants | map: 'option1'
  assign bb_variants_opt2      = product.variants | map: 'option2'
  assign bb_variants_opt3      = product.variants | map: 'option3'

  assign bb_has_badge = false
  if block.settings.option_1_badge != blank or block.settings.option_2_badge != blank or block.settings.option_3_badge != blank or block.settings.option_4_badge != blank
    assign bb_has_badge = true
  endif
-%}

{% style %}
#BundleBreaks-{{ section.id }}-{{ block.id }} {
  --bb-radius: {{ block.settings.border_radius | divided_by: 10.0 }}rem;
  --bb-bw:     {{ block.settings.border_width  | divided_by: 10.0 }}rem;
  --bb-img-sz: {{ block.settings.image_size }}px;
  margin-top:    {{ block.settings.margin_top    | divided_by: 10.0 }}rem;
  margin-bottom: {{ block.settings.margin_bottom | divided_by: 10.0 }}rem;
}

{% if block.settings.use_custom_colors %}
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-option {
  background:   {{ block.settings.unselected_bg     | default: 'rgba(0,0,0,0.02)' }};
  border-color: {{ block.settings.unselected_border | default: 'rgba(0,0,0,0.15)' }};
  color:        {{ block.settings.unselected_text   | default: 'inherit' }};
}
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-container input[type="radio"]:checked + .bb-option {
  background:   {{ block.settings.selected_bg     | default: 'rgba(0,0,0,0.06)' }};
  border-color: {{ block.settings.selected_border | default: 'rgb(0,0,0)' }};
}
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-option::before {
  border-color: {{ block.settings.unselected_border | default: 'rgba(0,0,0,0.2)' }};
}
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-container input[type="radio"]:checked + .bb-option::before {
  background:   {{ block.settings.selected_border | default: 'rgb(0,0,0)' }};
  border-color: {{ block.settings.unselected_bg   | default: '#fff' }};
  box-shadow: 0 0 0 0.1rem {{ block.settings.selected_border | default: 'rgb(0,0,0)' }};
}
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-option__price,
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-product-row__price {
  color: {{ block.settings.price_color | default: '#000000' }};
}
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-option__compare,
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-product-row__compare,
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-free-gift__strike {
  color: {{ block.settings.compare_price_color | default: '#999999' }};
  opacity: 1;
}
{% else %}
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-option__price,
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-product-row__price {
  color: rgb(var(--color-base-{{ block.settings.color_scheme }}));
}
{% endif %}

{% if block.settings.enable_custom_compare_price_color and block.settings.use_custom_colors == false %}
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-option__compare,
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-product-row__compare,
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-free-gift__strike {
  color: {{ block.settings.compare_at_price_color }};
  opacity: 1;
}
{% endif %}

{% if block.settings.gift_footer_bg != blank or block.settings.gift_footer_text_color != blank or block.settings.gift_footer_border_color != blank %}
#BundleBreaks-{{ section.id }}-{{ block.id }} .bb-free-gift {
  {% if block.settings.gift_footer_bg != blank %}background: {{ block.settings.gift_footer_bg }};{% endif %}
  {% if block.settings.gift_footer_border_color != blank %}border-top-color: {{ block.settings.gift_footer_border_color }};{% endif %}
  {% if block.settings.gift_footer_text_color != blank %}color: {{ block.settings.gift_footer_text_color }};{% endif %}
}
{% endif %}
{% endstyle %}

<div
  id="BundleBreaks-{{ section.id }}-{{ block.id }}"
  class="bundle-breaks {{ block.settings.visibility }}{% unless block.settings.use_custom_colors %} accent-color-{{ block.settings.color_scheme }}{% endunless %}"
  data-section="{{ section.id }}"
  data-main-variant-id="{{ bb_main_variant.id }}"
  data-remove-addons="{{ block.settings.remove_addons_on_main_removed }}"
  {{ block.shopify_attributes }}
>
  {% if block.settings.headline != blank %}
    <h3 class="bb-headline">{{ block.settings.headline }}</h3>
  {% endif %}

  <bundle-breaks
    id="bundle-deals-{{ section.id }}"
    class="bb-container{% if bb_has_badge %} bb-has-badge{% endif %}{% if block.settings.show_all_open %} bb-always-open{% endif %}"
    data-section="{{ section.id }}"
    data-money-format="{{ shop.money_format | escape }}"
  >

  {%- for opt_i in (1..4) -%}
    {%- liquid
      if opt_i == 1
        assign opt_en      = block.settings.option_1_enabled
        assign opt_label   = block.settings.option_1_label
        assign opt_cap     = block.settings.option_1_caption
        assign opt_badge   = block.settings.option_1_badge
        assign opt_bcol    = block.settings.option_1_badge_color
        assign opt_bstyle  = block.settings.option_1_badge_style
        assign opt_layout  = block.settings.option_1_layout
        assign opt_pct     = block.settings.option_1_pct_off
        assign opt_fix     = block.settings.option_1_fixed_off
        assign opt_a1      = block.settings.option_1_addon_1
        assign opt_a1p     = block.settings.option_1_addon_1_pct
        assign opt_a1dtype = block.settings.option_1_addon_1_discount_type
        assign opt_a1fix   = block.settings.option_1_addon_1_fixed
        assign opt_a1f     = block.settings.option_1_addon_1_free
        assign opt_a2      = block.settings.option_1_addon_2
        assign opt_a2p     = block.settings.option_1_addon_2_pct
        assign opt_a2dtype = block.settings.option_1_addon_2_discount_type
        assign opt_a2fix   = block.settings.option_1_addon_2_fixed
        assign opt_a2f     = block.settings.option_1_addon_2_free
        assign opt_a3      = block.settings.option_1_addon_3
        assign opt_a3p     = block.settings.option_1_addon_3_pct
        assign opt_a3dtype = block.settings.option_1_addon_3_discount_type
        assign opt_a3fix   = block.settings.option_1_addon_3_fixed
        assign opt_a3f     = block.settings.option_1_addon_3_free
        assign opt_gp      = block.settings.option_1_gift_product
        assign opt_gt      = block.settings.option_1_gift_text
        assign opt_gi      = block.settings.option_1_gift_image
        assign opt_gs      = block.settings.option_1_gift_strike
        assign opt_presel  = 'option_1'
      elsif opt_i == 2
        assign opt_en      = block.settings.option_2_enabled
        assign opt_label   = block.settings.option_2_label
        assign opt_cap     = block.settings.option_2_caption
        assign opt_badge   = block.settings.option_2_badge
        assign opt_bcol    = block.settings.option_2_badge_color
        assign opt_bstyle  = block.settings.option_2_badge_style
        assign opt_layout  = block.settings.option_2_layout
        assign opt_pct     = block.settings.option_2_pct_off
        assign opt_fix     = block.settings.option_2_fixed_off
        assign opt_a1      = block.settings.option_2_addon_1
        assign opt_a1p     = block.settings.option_2_addon_1_pct
        assign opt_a1dtype = block.settings.option_2_addon_1_discount_type
        assign opt_a1fix   = block.settings.option_2_addon_1_fixed
        assign opt_a1f     = block.settings.option_2_addon_1_free
        assign opt_a2      = block.settings.option_2_addon_2
        assign opt_a2p     = block.settings.option_2_addon_2_pct
        assign opt_a2dtype = block.settings.option_2_addon_2_discount_type
        assign opt_a2fix   = block.settings.option_2_addon_2_fixed
        assign opt_a2f     = block.settings.option_2_addon_2_free
        assign opt_a3      = block.settings.option_2_addon_3
        assign opt_a3p     = block.settings.option_2_addon_3_pct
        assign opt_a3dtype = block.settings.option_2_addon_3_discount_type
        assign opt_a3fix   = block.settings.option_2_addon_3_fixed
        assign opt_a3f     = block.settings.option_2_addon_3_free
        assign opt_gp      = block.settings.option_2_gift_product
        assign opt_gt      = block.settings.option_2_gift_text
        assign opt_gi      = block.settings.option_2_gift_image
        assign opt_gs      = block.settings.option_2_gift_strike
        assign opt_presel  = 'option_2'
      elsif opt_i == 3
        assign opt_en      = block.settings.option_3_enabled
        assign opt_label   = block.settings.option_3_label
        assign opt_cap     = block.settings.option_3_caption
        assign opt_badge   = block.settings.option_3_badge
        assign opt_bcol    = block.settings.option_3_badge_color
        assign opt_bstyle  = block.settings.option_3_badge_style
        assign opt_layout  = block.settings.option_3_layout
        assign opt_pct     = block.settings.option_3_pct_off
        assign opt_fix     = block.settings.option_3_fixed_off
        assign opt_a1      = block.settings.option_3_addon_1
        assign opt_a1p     = block.settings.option_3_addon_1_pct
        assign opt_a1dtype = block.settings.option_3_addon_1_discount_type
        assign opt_a1fix   = block.settings.option_3_addon_1_fixed
        assign opt_a1f     = block.settings.option_3_addon_1_free
        assign opt_a2      = block.settings.option_3_addon_2
        assign opt_a2p     = block.settings.option_3_addon_2_pct
        assign opt_a2dtype = block.settings.option_3_addon_2_discount_type
        assign opt_a2fix   = block.settings.option_3_addon_2_fixed
        assign opt_a2f     = block.settings.option_3_addon_2_free
        assign opt_a3      = block.settings.option_3_addon_3
        assign opt_a3p     = block.settings.option_3_addon_3_pct
        assign opt_a3dtype = block.settings.option_3_addon_3_discount_type
        assign opt_a3fix   = block.settings.option_3_addon_3_fixed
        assign opt_a3f     = block.settings.option_3_addon_3_free
        assign opt_gp      = block.settings.option_3_gift_product
        assign opt_gt      = block.settings.option_3_gift_text
        assign opt_gi      = block.settings.option_3_gift_image
        assign opt_gs      = block.settings.option_3_gift_strike
        assign opt_presel  = 'option_3'
      elsif opt_i == 4
        assign opt_en      = block.settings.option_4_enabled
        assign opt_label   = block.settings.option_4_label
        assign opt_cap     = block.settings.option_4_caption
        assign opt_badge   = block.settings.option_4_badge
        assign opt_bcol    = block.settings.option_4_badge_color
        assign opt_bstyle  = block.settings.option_4_badge_style
        assign opt_layout  = block.settings.option_4_layout
        assign opt_pct     = block.settings.option_4_pct_off
        assign opt_fix     = block.settings.option_4_fixed_off
        assign opt_a1      = block.settings.option_4_addon_1
        assign opt_a1p     = block.settings.option_4_addon_1_pct
        assign opt_a1dtype = block.settings.option_4_addon_1_discount_type
        assign opt_a1fix   = block.settings.option_4_addon_1_fixed
        assign opt_a1f     = block.settings.option_4_addon_1_free
        assign opt_a2      = block.settings.option_4_addon_2
        assign opt_a2p     = block.settings.option_4_addon_2_pct
        assign opt_a2dtype = block.settings.option_4_addon_2_discount_type
        assign opt_a2fix   = block.settings.option_4_addon_2_fixed
        assign opt_a2f     = block.settings.option_4_addon_2_free
        assign opt_a3      = block.settings.option_4_addon_3
        assign opt_a3p     = block.settings.option_4_addon_3_pct
        assign opt_a3dtype = block.settings.option_4_addon_3_discount_type
        assign opt_a3fix   = block.settings.option_4_addon_3_fixed
        assign opt_a3f     = block.settings.option_4_addon_3_free
        assign opt_gp      = block.settings.option_4_gift_product
        assign opt_gt      = block.settings.option_4_gift_text
        assign opt_gi      = block.settings.option_4_gift_image
        assign opt_gs      = block.settings.option_4_gift_strike
        assign opt_presel  = 'option_4'
      endif
    -%}

    {%- unless opt_en -%}{%- continue -%}{%- endunless -%}

    {%- liquid
      assign pct_left    = 100.0 | minus: opt_pct | divided_by: 100.0
      assign fixed_cents = opt_fix | times: 100
      assign opt_total   = bb_main_price   | times: pct_left | minus: fixed_cents
      assign opt_compare = bb_main_compare | plus: 0

      if opt_a1 != blank
        assign av1    = opt_a1.first_available_variant
        assign a1_pl  = 100.0 | minus: opt_a1p | divided_by: 100.0
        if opt_a1f
          assign a1_price = 0
        elsif opt_a1dtype == 'fixed'
          assign a1_fix_cents = opt_a1fix | times: 100
          assign a1_price = av1.price | minus: a1_fix_cents | at_least: 0
        else
          assign a1_price = av1.price | times: a1_pl
        endif
        assign a1_cmp = av1.compare_at_price | default: av1.price
        if a1_cmp < av1.price
          assign a1_cmp = av1.price
        endif
        assign opt_total   = opt_total   | plus: a1_price
        assign opt_compare = opt_compare | plus: a1_cmp
      endif
      if opt_a2 != blank
        assign av2    = opt_a2.first_available_variant
        assign a2_pl  = 100.0 | minus: opt_a2p | divided_by: 100.0
        if opt_a2f
          assign a2_price = 0
        elsif opt_a2dtype == 'fixed'
          assign a2_fix_cents = opt_a2fix | times: 100
          assign a2_price = av2.price | minus: a2_fix_cents | at_least: 0
        else
          assign a2_price = av2.price | times: a2_pl
        endif
        assign a2_cmp = av2.compare_at_price | default: av2.price
        if a2_cmp < av2.price
          assign a2_cmp = av2.price
        endif
        assign opt_total   = opt_total   | plus: a2_price
        assign opt_compare = opt_compare | plus: a2_cmp
      endif
      if opt_a3 != blank
        assign av3    = opt_a3.first_available_variant
        assign a3_pl  = 100.0 | minus: opt_a3p | divided_by: 100.0
        if opt_a3f
          assign a3_price = 0
        elsif opt_a3dtype == 'fixed'
          assign a3_fix_cents = opt_a3fix | times: 100
          assign a3_price = av3.price | minus: a3_fix_cents | at_least: 0
        else
          assign a3_price = av3.price | times: a3_pl
        endif
        assign a3_cmp = av3.compare_at_price | default: av3.price
        if a3_cmp < av3.price
          assign a3_cmp = av3.price
        endif
        assign opt_total   = opt_total   | plus: a3_price
        assign opt_compare = opt_compare | plus: a3_cmp
      endif
    -%}

    {%- assign radio_id = 'bb-' | append: section.id | append: '-' | append: block.id | append: '-' | append: opt_i -%}
    {%- assign opt_layout_class = opt_layout | default: 'horizontal' -%}

    {%- comment -%} Wrapper: position:relative + overflow:visible so badge overflows the card {%- endcomment -%}
    <div class="bb-option-wrap bb-option-wrap--badge-style-{{ opt_bstyle | default: '3' }}{% if opt_badge != blank %} bb-option-wrap--has-badge{% endif %}">

      {%- if opt_badge != blank -%}
        <p class="bb-option__badge color-{{ opt_bcol | default: 'accent-1' }}">
          {%- if opt_bstyle == '6' -%}
            <span class="bb-option__badge-inner">{{ opt_badge }}</span>
          {%- else -%}
            {{ opt_badge }}
          {%- endif -%}
        </p>
      {%- endif -%}

      <input
        type="radio"
        id="{{ radio_id }}"
        name="bb_option_{{ section.id }}_{{ block.id }}"
        value="{{ opt_i }}"
        data-bb-opt="{{ opt_i }}"
        {% if block.settings.preselected == opt_presel %}checked{% endif %}
      >
      <label
        class="bb-option bb-option--products-{{ opt_layout_class }}"
        for="{{ radio_id }}"
        data-bb-opt="{{ opt_i }}"
        data-bb-main-price="{{ bb_main_price }}"
        data-bb-pct-left="{{ pct_left }}"
        data-bb-fixed-off="{{ fixed_cents }}"
        data-bb-addon-price="{{ opt_total | minus: bb_main_price | times: pct_left | plus: 0 | round }}"
        data-bb-total="{{ opt_total | round }}"
        data-bb-compare="{{ opt_compare | round }}"
      >

      {%- comment -%} Header: label + prices {%- endcomment -%}
      <div class="bb-option__header">
        <div class="bb-option__header-left">
          <span class="bb-option__label">
            {%- if opt_label != blank -%}{{ opt_label }}{%- else -%}Buy {{ opt_i }}x{%- endif -%}
          </span>
          {%- if opt_cap != blank -%}
            <span class="bb-option__caption">{{ opt_cap }}</span>
          {%- endif -%}
        </div>
        <div class="bb-option__price-block">
          <span class="bb-option__price bb-opt-total-js">{{ opt_total | money }}</span>
          {%- if opt_compare > opt_total -%}
            <span class="bb-option__compare bb-opt-compare-js">{{ opt_compare | money }}</span>
          {%- endif -%}
        </div>
      </div>

      {%- comment -%} Product list — revealed when checked {%- endcomment -%}
{%- liquid
  assign opt_addon_count = 0
  if opt_a1 != blank
    assign opt_addon_count = opt_addon_count | plus: 1
  endif
  if opt_a2 != blank
    assign opt_addon_count = opt_addon_count | plus: 1
  endif
  if opt_a3 != blank
    assign opt_addon_count = opt_addon_count | plus: 1
  endif
-%}
      <div class="bb-products bb-products--{{ opt_layout_class }}{% if opt_layout == 'vertical' and opt_addon_count >= 2 %} bb-products--v3{% endif %}">

        {%- comment -%} ── MAIN PRODUCT ── {%- endcomment -%}
        {%- assign main_key = 'id_' | append: opt_i | append: '_0' -%}
        <div class="bb-product-row bundle-deals__product-js" data-opt="{{ opt_i }}">
          <input
            type="checkbox"
            class="bundle-deals__checkbox-js visually-hidden"
            checked
            data-id="{{ bb_main_variant.id }}"
            data-handle="{{ product.handle }}"
            data-price="{{ bb_main_price | times: pct_left | minus: fixed_cents }}"
            data-compare-price="{{ bb_main_compare }}"
            data-index="0"
            data-id-index="{{ main_key }}"
            data-opt="{{ opt_i }}"
          >
          {%- if block.settings.show_images -%}
            {%- assign main_img = bb_main_variant.featured_image | default: product.featured_image -%}
            {%- if main_img != blank -%}
              <div class="bb-product-row__img-wrap bundle-deals__media-item-container-js">
                <img
                  src="{{ main_img | image_url: width: 400 }}"
                  alt="{{ main_img.alt | escape }}"
                  class="bb-product-row__img bundle-deals__media-item-img-js"
                  loading="lazy"
                >
              </div>
            {%- endif -%}
          {%- endif -%}
          <div class="bb-product-row__info">
            <p class="bb-product-row__title">{{ product.title }}</p>
            <div class="bb-product-row__prices">
              <span class="bb-product-row__price bundle-deals__price-js">
                {{- bb_main_price | times: pct_left | minus: fixed_cents | money -}}
              </span>
              {%- if bb_main_compare > bb_main_price -%}
                <span class="bb-product-row__compare bundle-deals__compare-price-js">
                  {{- bb_main_compare | money -}}
                </span>
              {%- endif -%}
            </div>
            {%- comment -%} Variant picker — exact quantity-breaks structure {%- endcomment -%}
            {%- unless product.has_only_default_variant -%}
              <div
                class="bb-variant-picker quantity-break__variants bundle-deals__variant-selects-js"
                data-index="0"
                data-id-index="{{ main_key }}"
                data-percentage-left="{{ pct_left }}"
                data-fixed-discount="{{ fixed_cents }}"
                data-opt="{{ opt_i }}"
              >
                <div
                  class="quantity-break__selector-item quantity-break__selector-item--variant-images-none"
                  data-select-index="0"
                  data-selected-id="{{ bb_main_variant.id }}"
                >
                  {%- for option in product.options_with_values -%}
                    <div class="select select--small no-background color-{{ settings.pickers_color_scheme }} accent-color-{{ settings.pickers_overlay_color }} accent-2-color-{{ settings.pickers_text_color }}">
                      <select
                        class="quantity-break__variant-select select__select variant-dropdown"
                        name="options[{{ option.name | escape }}]"
                        data-product-id="{{ bb_main_variant.id }}"
                      >
                        {%- for value in option.values -%}
                          {%- liquid
                            assign bb_oc = ''
                            assign bb_od = true
                            assign bb_oe = false
                            for o1 in bb_variants_opt1
                              case option.position
                                when 1
                                  if bb_variants_opt1[forloop.index0] == value
                                    assign bb_oe = true
                                    if bb_variants_available[forloop.index0]
                                      assign bb_od = false
                                    endif
                                  endif
                                when 2
                                  if o1 == bb_main_variant.option1 and bb_variants_opt2[forloop.index0] == value
                                    assign bb_oe = true
                                    if bb_variants_available[forloop.index0]
                                      assign bb_od = false
                                    endif
                                  endif
                                when 3
                                  if o1 == bb_main_variant.option1 and bb_variants_opt2[forloop.index0] == bb_main_variant.option2 and bb_variants_opt3[forloop.index0] == value
                                    assign bb_oe = true
                                    if bb_variants_available[forloop.index0]
                                      assign bb_od = false
                                    endif
                                  endif
                              endcase
                            endfor
                            if bb_oe == false
                              assign bb_oc = 'non-existent'
                            elsif bb_od == true
                              assign bb_oc = 'unavailable'
                            endif
                          -%}
                          <option
                            value="{{ value | escape }}"
                            {% if option.selected_value == value %}selected="selected"{% endif %}
                            class="{{ bb_oc }}"
                          >
                            {%- if bb_od -%}
                              {{- 'products.product.value_unavailable' | t: option_value: value -}}
                            {%- else -%}
                              {{- value -}}
                            {%- endif %}
                          </option>
                        {%- endfor -%}
                      </select>
                      {% render 'icon-caret' %}
                    </div>
                  {%- endfor -%}
                </div>
                <script type="application/json">{{ product.variants | json }}</script>
              </div>
            {%- endunless -%}
          </div>
        </div>

        {%- comment -%} ── ADDON PRODUCTS ── {%- endcomment -%}
        {%- for addon_i in (1..3) -%}
          {%- liquid
            if addon_i == 1
              assign cur_prod  = opt_a1
              assign cur_pl    = a1_pl
              assign cur_free  = opt_a1f
              assign cur_price = a1_price
              assign cur_cmp   = a1_cmp
              assign cur_av    = av1
              assign cur_dtype = opt_a1dtype
              assign cur_fix   = opt_a1fix | times: 100 | default: 0
            elsif addon_i == 2
              assign cur_prod  = opt_a2
              assign cur_pl    = a2_pl
              assign cur_free  = opt_a2f
              assign cur_price = a2_price
              assign cur_cmp   = a2_cmp
              assign cur_av    = av2
              assign cur_dtype = opt_a2dtype
              assign cur_fix   = opt_a2fix | times: 100 | default: 0
            elsif addon_i == 3
              assign cur_prod  = opt_a3
              assign cur_pl    = a3_pl
              assign cur_free  = opt_a3f
              assign cur_price = a3_price
              assign cur_cmp   = a3_cmp
              assign cur_av    = av3
              assign cur_dtype = opt_a3dtype
              assign cur_fix   = opt_a3fix | times: 100 | default: 0
            endif
          -%}
          {%- if cur_prod == blank -%}{%- continue -%}{%- endif -%}
          {%- assign slot_key = 'id_' | append: opt_i | append: '_' | append: addon_i -%}
          {%- liquid
            assign cur_va  = cur_prod.variants | map: 'available'
            assign cur_vo1 = cur_prod.variants | map: 'option1'
            assign cur_vo2 = cur_prod.variants | map: 'option2'
            assign cur_vo3 = cur_prod.variants | map: 'option3'
          -%}

          <div class="bb-divider" aria-hidden="true">
            <span class="bb-divider__icon">+</span>
          </div>

          <div class="bb-product-row bundle-deals__product-js" data-opt="{{ opt_i }}">
            <input
              type="checkbox"
              class="bundle-deals__checkbox-js visually-hidden"
              checked
              data-id="{{ cur_av.id }}"
              data-handle="{{ cur_prod.handle }}"
              data-price="{{ cur_price }}"
              data-compare-price="{{ cur_cmp }}"
              data-index="{{ addon_i }}"
              data-id-index="{{ slot_key }}"
              data-opt="{{ opt_i }}"
            >
            {%- if block.settings.show_images -%}
              {%- assign addon_img = cur_av.featured_image | default: cur_prod.featured_image -%}
              {%- if addon_img != blank -%}
                <div class="bb-product-row__img-wrap bundle-deals__media-item-container-js">
                  <img
                    src="{{ addon_img | image_url: width: 400 }}"
                    alt="{{ addon_img.alt | escape }}"
                    class="bb-product-row__img bundle-deals__media-item-img-js"
                    loading="lazy"
                  >
                </div>
              {%- endif -%}
            {%- endif -%}
            <div class="bb-product-row__info">
              <p class="bb-product-row__title">{{ cur_prod.title }}</p>
              <div class="bb-product-row__prices">
                {%- if cur_free -%}
                  <span class="bb-product-row__price bundle-deals__price-js">
                    {{- block.settings.free_text | default: 'FREE' -}}
                  </span>
                  <span class="bb-product-row__compare bundle-deals__compare-price-js">
                    {{- cur_av.price | money -}}
                  </span>
                {%- else -%}
                  <span class="bb-product-row__price bundle-deals__price-js">{{- cur_price | money -}}</span>
                  {%- if cur_cmp > cur_price -%}
                    <span class="bb-product-row__compare bundle-deals__compare-price-js">{{- cur_cmp | money -}}</span>
                  {%- endif -%}
                {%- endif -%}
              </div>
              {%- comment -%} Addon variant picker — exact quantity-breaks structure {%- endcomment -%}
              {%- unless cur_prod.has_only_default_variant -%}
                <div
                  class="bb-variant-picker quantity-break__variants bundle-deals__variant-selects-js"
                  data-index="{{ addon_i }}"
                  data-id-index="{{ slot_key }}"
                  data-percentage-left="{{ cur_pl }}"
                  data-fixed-discount="{{ cur_fix }}"
                  data-opt="{{ opt_i }}"
                >
                  <div
                    class="quantity-break__selector-item quantity-break__selector-item--variant-images-none"
                    data-select-index="0"
                    data-selected-id="{{ cur_av.id }}"
                  >
                    {%- for option in cur_prod.options_with_values -%}
                      <div class="select select--small no-background color-{{ settings.pickers_color_scheme }} accent-color-{{ settings.pickers_overlay_color }} accent-2-color-{{ settings.pickers_text_color }}">
                        <select
                          class="quantity-break__variant-select select__select variant-dropdown"
                          name="options[{{ option.name | escape }}]"
                          data-product-id="{{ cur_av.id }}"
                        >
                          {%- for value in option.values -%}
                            {%- liquid
                              assign bb_oc = ''
                              assign bb_od = true
                              assign bb_oe = false
                              for o1 in cur_vo1
                                case option.position
                                  when 1
                                    if cur_vo1[forloop.index0] == value
                                      assign bb_oe = true
                                      if cur_va[forloop.index0]
                                        assign bb_od = false
                                      endif
                                    endif
                                  when 2
                                    if o1 == cur_av.option1 and cur_vo2[forloop.index0] == value
                                      assign bb_oe = true
                                      if cur_va[forloop.index0]
                                        assign bb_od = false
                                      endif
                                    endif
                                  when 3
                                    if o1 == cur_av.option1 and cur_vo2[forloop.index0] == cur_av.option2 and cur_vo3[forloop.index0] == value
                                      assign bb_oe = true
                                      if cur_va[forloop.index0]
                                        assign bb_od = false
                                      endif
                                    endif
                                endcase
                              endfor
                              if bb_oe == false
                                assign bb_oc = 'non-existent'
                              elsif bb_od == true
                                assign bb_oc = 'unavailable'
                              endif
                            -%}
                            <option
                              value="{{ value | escape }}"
                              {% if option.selected_value == value %}selected="selected"{% endif %}
                              class="{{ bb_oc }}"
                            >
                              {%- if bb_od -%}
                                {{- 'products.product.value_unavailable' | t: option_value: value -}}
                              {%- else -%}
                                {{- value -}}
                              {%- endif %}
                            </option>
                          {%- endfor -%}
                        </select>
                        {% render 'icon-caret' %}
                      </div>
                    {%- endfor -%}
                  </div>
                  <script type="application/json">{{ cur_prod.variants | json }}</script>
                </div>
              {%- endunless -%}
            </div>
          </div>
        {%- endfor -%}

      </div>{%- comment -%} /.bb-products {%- endcomment -%}

      {%- comment -%}
        FREE GIFT FOOTER — full-width bar attached to the card bottom.
        Negative horizontal margins bleed to the card edges; negative bottom
        margin pulls it flush with the card padding.
        Always rendered (CSS hides until checked).
      {%- endcomment -%}
      {%- if opt_gp != blank -%}
        <div class="bb-free-gift"{% if opt_gp != blank %} data-gift-variant-id="{{ opt_gp.first_available_variant.id }}" data-gift-handle="{{ opt_gp.handle }}"{% endif %}>
          {%- if opt_gp != blank -%}
            {%- if opt_gp.featured_image != blank and block.settings.show_images -%}
              <img src="{{ opt_gp.featured_image | image_url: width: 160 }}" alt="{{ opt_gp.featured_image.alt | escape }}" loading="lazy" class="bb-free-gift__img">
            {%- endif -%}
            <p class="bb-free-gift__label">
              {{ opt_gt | default: '+ FREE Gift:' }} {{ opt_gp.title }}
            </p>
            {%- assign gp_v      = opt_gp.first_available_variant -%}
            {%- assign gp_strike = gp_v.compare_at_price | default: gp_v.price -%}
            {%- if gp_strike > 0 -%}
              <span class="bb-free-gift__strike">{{ gp_strike | money }}</span>
            {%- endif -%}
          {%- else -%}
            {%- if opt_gi != blank and block.settings.show_images -%}
              <img src="{{ opt_gi | image_url: width: 160 }}" alt="" loading="lazy" class="bb-free-gift__img">
            {%- endif -%}
            <p class="bb-free-gift__label">{{ opt_gt }}</p>
            {%- if opt_gs != blank -%}
              <span class="bb-free-gift__strike">{{ opt_gs }}</span>
            {%- endif -%}
          {%- endif -%}
        </div>
      {%- endif -%}

      </label>
    </div>{%- comment -%} /.bb-option-wrap {%- endcomment -%}
  {%- endfor -%}

  </bundle-breaks>
</div>

{% style %}
/* Headline */
.bb-headline {
  font-size: 1.6rem;
  font-weight: 700;
  margin-bottom: 1.2rem;
}

/* Outer wrapper stack */
.bb-container {
  display: grid;
  grid-template-columns: 1fr;
  row-gap: 0.85rem;
  position: relative;
}

/* ── Hidden radio inputs ──────────────────────────────────── */
.bb-container input[type="radio"] {
  opacity: 0;
  width: 0;
  height: 0;
  cursor: pointer;
  position: absolute;
}

/* ══════════════════════════════════════════════════════════════
   Option card
   ══════════════════════════════════════════════════════════════ */
.bb-option {
  display: flex;
  flex-direction: column;
  padding: 1.4rem 1.75rem 0 4rem;
  cursor: pointer;
  border-radius: var(--bb-radius, 1rem);
  background: rgba(var(--accent-color), 0.02);
  border: solid var(--bb-bw, 0.2rem) rgba(var(--accent-color), 0.3);
  position: relative;
  overflow: hidden; /* clips the free-gift bar to the card's rounded corners */
  transition: background 0.15s, border-color 0.15s;
}
/* Header always has bottom padding */
.bb-option__header { padding-bottom: 1.4rem; }

@media (hover: hover) {
  .bb-option:hover {
    background: rgba(var(--accent-color), 0.1);
    border-color: rgb(var(--accent-color));
  }
}
.bb-container input[type="radio"]:checked + .bb-option {
  background: rgba(var(--accent-color), 0.08);
  border-color: rgb(var(--accent-color));
}

/* ── Radio dot — mirrors .quantity-breaks--show-indicator ─── */
.bb-option::before {
  content: "";
  display: block;
  width: 1.5rem;
  height: 1.5rem;
  position: absolute;
  left: 2rem;
  top: 2.55rem;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: solid 0.2rem rgba(var(--accent-color), 0.3);
  transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.bb-container input[type="radio"]:checked + .bb-option::before {
  border-color: rgb(var(--color-background));
  background: rgb(var(--accent-color));
  box-shadow: 0 0 0 0.1rem rgb(var(--accent-color));
}

/* ── Option wrapper — position:relative so badge can escape overflow:hidden on card ── */
.bb-option-wrap {
  position: relative;
}
/* Style 3: tab above — wrapper needs top margin to reveal the tab */
.bb-option-wrap--badge-style-3.bb-option-wrap--has-badge {
  margin-top: 2rem;
}

/* ── Badge — anchored to .bb-option-wrap, sits outside the card's overflow:hidden ── */
.bb-option__badge {
  position: absolute;
  font-weight: var(--font-body-weight-bold);
  font-size: var(--badge-font-size, 1.5rem);
  line-height: var(--badge-line-height, 1.6);
  /* Style 1 default: rotated corner sticker */
  top: -1.8rem;
  right: -0.5rem;
  transform: rotate(3deg);
  margin: 0;
  padding: 0 0.7em;
  border-radius: var(--badge-border-radius, 0.2em);
  z-index: 3;
  pointer-events: none;
}
/* Style 2: centred on top border, no rotation */
.bb-option-wrap--badge-style-2 .bb-option__badge {
  transform: translateY(-50%);
  top: 0;
  right: 1.5rem;
}
/* Style 3: tab sitting above the card (default) */
.bb-option-wrap--badge-style-3 .bb-option__badge {
  top: 0;
  right: 1.5rem;
  transform: translateY(-100%);
  border-radius: var(--badge-border-radius, 0.2em) var(--badge-border-radius, 0.2em) 0 0;
  font-size: 1.4rem;
}
/* Style 4: flat corner, no rotation */
.bb-option-wrap--badge-style-4 .bb-option__badge {
  top: -1.8rem;
  right: -0.5rem;
  transform: rotate(0deg);
}

/* ── Style 6: Kaching-style notched ribbon, top-right ──────── */
.bb-option-wrap--badge-style-6.bb-option-wrap--has-badge {
  margin-top: 6px; /* Changed from 10px */
}

.bb-option-wrap--badge-style-6 .bb-option__badge {
  position: absolute;
  top: -8px;
  right: var(--bb-radius, 1rem);
  left: auto;
  transform: none;
  margin: 0;
  padding: 0;
  background: transparent;
  border-radius: 0;
  font-size: 0;
  line-height: 0;
  overflow: visible;
}

.bb-option-wrap--badge-style-6 .bb-option__badge-inner {
  display: block;
  position: relative;
  margin: 0 8px;
  padding: 6px 8px;
  border-bottom-left-radius: 5px;
  border-bottom-right-radius: 5px;
  font-size: 1.2rem;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  color: rgb(var(--color-foreground));
  background-color: rgb(var(--color-background));
}

.bb-option-wrap--badge-style-6 .bb-option__badge-inner::before {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: -8px;
  width: 0;
  height: 0;
  border-bottom: 8px solid rgb(var(--color-background));
  border-left: 8px solid transparent;
  filter: brightness(0.7);
}

.bb-option-wrap--badge-style-6 .bb-option__badge-inner::after {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  right: -8px;
  width: 0;
  height: 0;
  border-bottom: 8px solid rgb(var(--color-background));
  border-right: 8px solid transparent;
  filter: brightness(0.7);
}

/* ── Header row ──────────────────────────────────────────── */
.bb-option__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  min-height: 2.2rem;
}
.bb-option__header-left {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  flex: 1;
}
.bb-option__label   { font-size: 1.6rem; font-weight: 700; line-height: 1.2; }
.bb-option__caption { font-size: 1.3rem; opacity: 0.6; line-height: 1.2; }
.bb-option__price-block {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.3rem;
  flex-shrink: 0;
}
.bb-option__price   { font-size: 1.6rem; font-weight: 700; line-height: 1; color: rgb(var(--accent-color)); }
.bb-option__compare { font-size: 1.3rem; text-decoration: line-through; line-height: 1; opacity: 0.5; }

/* ── Product list — hidden until checked ─────────────────── */
.bb-products {
  height: 0;
  overflow: hidden;
  padding-top: 0;
  padding-bottom: 0;
}
.bb-container input[type="radio"]:checked + .bb-option .bb-products,
.bb-always-open .bb-option .bb-products {
  height: auto;
  padding-top: 0;
  padding-bottom: 1.4rem;
}

/* ── HORIZONTAL layout: products stacked vertically ─────── */
.bb-products--horizontal {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* ── VERTICAL layout: products side-by-side ─────────────── */
.bb-products--vertical {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 0;
}

/* ══════════════════════════════════════════════════════════════
   Divider — heavy line + large circle + icon
   ══════════════════════════════════════════════════════════════ */
/* HORIZONTAL divider (between stacked rows) */
.bb-products--horizontal .bb-divider {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 0.1rem 0;
}
.bb-products--horizontal .bb-divider::before,
.bb-products--horizontal .bb-divider::after {
  content: "";
  flex: 1;
  height: 2px;
  background: rgba(var(--color-foreground), 0.15);
}
/* VERTICAL divider (between side-by-side columns) */
.bb-products--vertical .bb-divider {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  gap: 0.5rem;
  padding: 0 0.3rem;
}
.bb-products--vertical .bb-divider::before,
.bb-products--vertical .bb-divider::after {
  content: "";
  width: 2px;
  flex: 1;
  background: rgba(var(--color-foreground), 0.15);
}
/* The + circle icon */
.bb-divider__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.8rem;
  height: 2.8rem;
  min-width: 2.8rem;
  border-radius: 50%;
  border: 2px solid rgba(var(--color-foreground), 0.2);
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1;
  padding-bottom: 0.1rem; /* compensate for + glyph descender offset */
  color: rgba(var(--color-foreground), 0.45);
  background: rgb(var(--color-background));
  flex-shrink: 0;
}


/* ══════════════════════════════════════════════════════════════
   Product row
   ══════════════════════════════════════════════════════════════ */

/* HORIZONTAL row — image left, info right */
.bb-products--horizontal .bb-product-row {
  display: flex;
  align-items: flex-start;
  gap: 1.4rem;
  padding: 0.8rem 0;
}

/* VERTICAL row — image top, info below, centred */
.bb-products--vertical .bb-product-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  flex: 1;
  min-width: 0;
  padding: 0.4rem 0.5rem;
}

.bb-product-row__img-wrap { flex-shrink: 0; }
.bb-product-row__img {
  width: var(--bb-img-sz, 70px);
  height: var(--bb-img-sz, 70px);
  object-fit: contain;
  border-radius: 0.6rem;
  display: block;
}
.bb-products--vertical .bb-product-row__img {
  /* Slightly bigger in vertical/card view */
  width: calc(var(--bb-img-sz, 70px) * 1.3);
  height: calc(var(--bb-img-sz, 70px) * 1.3);
}

.bb-product-row__info { flex: 1; min-width: 0; }
.bb-products--vertical .bb-product-row__info {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.bb-product-row__title {
  font-size: 1.3rem;
  font-weight: 600;
  line-height: 1.35;
  margin: 0 0 0.35rem;
}
.bb-products--horizontal .bb-product-row__title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bb-products--vertical .bb-product-row__title {
  text-align: center;
}

.bb-product-row__prices {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.bb-products--vertical .bb-product-row__prices, .bb-products--grid .bb-product-row__prices { justify-content: center; }
.bb-product-row__price   { font-size: 1.35rem; font-weight: 700; color: rgb(var(--accent-color)); }
.bb-product-row__compare { font-size: 1.2rem;  text-decoration: line-through; color: rgba(var(--color-foreground), 0.45); }

/* ── GRID layout: 2 products per row ─────────────────────── */
.bb-products--grid {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0;
}
/* Product rows: each takes ~half width */
.bb-products--grid > .bb-product-row {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  flex: 1 1 calc(50% - 3rem);
  min-width: 0;
  padding: 0.4rem 0.5rem;
}
.bb-products--grid > .bb-product-row .bb-product-row__img {
  width: calc(var(--bb-img-sz, 70px) * 1.3);
  height: calc(var(--bb-img-sz, 70px) * 1.3);
}
.bb-products--grid > .bb-product-row .bb-product-row__info {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.bb-products--grid > .bb-product-row .bb-product-row__title { text-align: center; }
/* Within-row dividers: vertical line */
.bb-products--grid > .bb-divider {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  flex-shrink: 0;
  width: 3rem;
  gap: 0;
  padding: 0;
}
.bb-products--grid > .bb-divider::before,
.bb-products--grid > .bb-divider::after {
  content: "";
  flex: 1;
  width: 2px;
  background: rgba(var(--color-foreground), 0.15);
}
/* Within-row dividers: hide the + circle, just show the line */
.bb-products--grid > .bb-divider:nth-child(2) .bb-divider__icon,
.bb-products--grid > .bb-divider:nth-child(6) .bb-divider__icon {
  display: none;
}

/* Row-break divider (child 4): becomes horizontal full-width rule */
.bb-products--grid > .bb-divider:nth-child(4) {
  flex: 1 1 100%;
  width: 100%;
  flex-direction: row;
  align-self: auto;
  padding: 0.6rem 0;
}
.bb-products--grid > .bb-divider:nth-child(4)::before,
.bb-products--grid > .bb-divider:nth-child(4)::after {
  flex: 1;
  height: 2px;
  width: auto;
}

/* ── VERTICAL + 3 ADDONS: 2-on-top, 1-below-centered ────── */
.bb-products--v3 {
  flex-wrap: wrap;
  align-items: flex-start;
}
.bb-products--v3 > .bb-product-row:nth-child(-n+5),
.bb-products--v3 > .bb-divider:nth-child(-n+5) {
  flex-shrink: 0;
}
.bb-products--v3 > .bb-divider:nth-child(6) {
  flex: 1 1 100%;
  width: 100%;
  flex-direction: row;
  padding: 0.8rem 0;
}
.bb-products--v3 > .bb-divider:nth-child(6)::before,
.bb-products--v3 > .bb-divider:nth-child(6)::after {
  content: "";
  flex: 1;
  height: 2px;
  width: auto;
  background: rgba(var(--color-foreground), 0.15);
}
.bb-products--v3 > .bb-divider:nth-child(6) .bb-divider__icon {
  flex-shrink: 0;
}
.bb-products--v3 > .bb-product-row:nth-child(7) {
  flex: 0 0 auto;
  width: 33%;
  align-self: flex-start;
  margin-left: auto;
  margin-right: auto;
}
.bb-products--v3 > .bb-product-row:nth-child(7) .bb-product-row__prices {
  justify-content: center;
}

/* Mobile: apply same layout on mobile too */
@media screen and (max-width: 749px) {
  .bb-products--vertical.bb-products--v3 > .bb-divider:nth-child(6) {
    flex: 1 1 100%;
    width: 100%;
    flex-direction: row;
    padding: 0.8rem 0;
  }
  .bb-products--vertical.bb-products--v3 > .bb-divider:nth-child(6)::before,
  .bb-products--vertical.bb-products--v3 > .bb-divider:nth-child(6)::after {
    content: "";
    flex: 1;
    height: 2px;
    width: auto;
    background: rgba(var(--color-foreground), 0.15);
  }
  .bb-products--vertical.bb-products--v3 > .bb-product-row:nth-child(7) {
    width: 45%;
    margin-left: auto;
    margin-right: auto;
  }
}

/* Variant picker */
.bb-variant-picker {
  margin-top: 0.5rem;
  height: auto !important;
  overflow: visible !important;
  padding-top: 0 !important;
}

/* ══════════════════════════════════════════════════════════════
   Mobile — max-width: 749px  (matches quantity-breaks breakpoint)
   ══════════════════════════════════════════════════════════════ */
@media screen and (max-width: 749px) {

  /* Tighten left padding so content fits on narrow screens */
  .bb-option {
    padding-left: 3rem;
  }

  /* Shift radio dot to match new padding */
  .bb-option::before {
    left: 1.5rem;
  }

  /* Free-gift bleed must match the reduced left padding */
  .bb-free-gift {
    margin-left: -3rem;
  }

  /* Allow title to wrap rather than truncate on mobile */
  .bb-products--horizontal .bb-product-row__title {
    white-space: normal;
    overflow: visible;
    text-overflow: unset;
  }
}

/* ══════════════════════════════════════════════════════════════
   Free Gift Footer — full-width bar flush with card edges
   The card has padding: 1.4rem 1.75rem 0 4rem
   So we bleed: left -4rem, right -1.75rem, bottom 0
   overflow:hidden on .bb-option clips it to the border-radius
   ══════════════════════════════════════════════════════════════ */
.bb-free-gift {
  display: none;
  align-items: center;
  gap: 1rem;
  /* Pull to card edges: left bleeds 4rem (asymmetric padding), right 1.75rem */
  margin: 0 -1.75rem 0 -4rem;
  padding: 0.9rem 1.75rem 0.9rem 2rem;
  background: rgba(var(--color-foreground), 0.06);
  border-top: 2px solid rgba(var(--color-foreground), 0.1);
  /* border-radius not needed — parent overflow:hidden handles it */
}
.bb-container input[type="radio"]:checked + .bb-option .bb-free-gift,
.bb-always-open .bb-option .bb-free-gift {
  display: flex;
}

.bb-free-gift__img {
  width: 3.8rem;
  height: 3.8rem;
  object-fit: contain;
  border-radius: 0.5rem;
  flex-shrink: 0;
}
.bb-free-gift__label {
  flex: 1;
  font-size: 1.3rem;
  font-weight: 600;
  margin: 0;
}
.bb-free-gift__strike {
  font-size: 1.3rem;
  text-decoration: line-through;
  opacity: 0.45;
  flex-shrink: 0;
}
{% endstyle %}

<script>
(function () {
  if (customElements.get('bundle-breaks')) return;

  class BundleBreaks extends HTMLElement {
    connectedCallback() {
      this.formVariants  = [];
      this._activeOpt    = null;
      this._giftVariantIds = new Set(); // tracks which variant IDs are gifts (no selling_plan)

      this._radios = Array.from(
        this.closest('.bb-container').querySelectorAll('input[type="radio"][name^="bb_option_"]')
      );
      this._radios.forEach(r => r.addEventListener('change', () => this._onRadioChange(r)));

      this.querySelectorAll('.bundle-deals__variant-selects-js').forEach(p => {
        p.addEventListener('change', () => this._onVariantChange(p));
      });

      // Stay in sync with main product variant selector
      if (typeof subscribe !== 'undefined' && typeof PUB_SUB_EVENTS !== 'undefined') {
        subscribe(PUB_SUB_EVENTS.variantChange, (data) => {
          if (data?.data?.variant && data.sectionId === this.dataset.section) {
            this._onMainVariantChange(data.data.variant);
          }
        });
      }

      // Subscription widget price sync
      this._setupSubscriptionSync();

      // Selling plan injection: watch ProductForm's variants div for rewrites
      this._setupSellingPlanInjector();

      // Cart listener: remove addons when main product is removed from cart
      this._setupCartRemovalListener();

      const checked = this._radios.find(r => r.checked);
      if (checked) this._onRadioChange(checked);

      // Re-dispatch after price updater has initialised (it defers 200ms on DOMContentLoaded).
      // This ensures the correct pre-selected option price shows on page load even when a
      // non-first option is pre-selected.
      setTimeout(() => {
        if (this._activeOpt) this._dispatchOptionChange();
      }, 350);
    }

    // ── Radio / option selection ─────────────────────────────────
    _onRadioChange(radio) {
      this._activeOpt = radio.dataset.bbOpt;
      this._rebuildFormVariants();
      this._dispatchOptionChange();
    }

    _dispatchOptionChange() {
      if (!this._activeOpt) return;
      const label = this.querySelector('.bb-option[data-bb-opt="' + this._activeOpt + '"]');
      if (!label) return;
      // Use the live total from the label — updated by _updateOptionHeaderTotal
      const totalCents   = parseFloat(label.dataset.bbTotal   || '0');
      const compareCents = parseFloat(label.dataset.bbCompare || '0');
      const subData = this._getSubscriptionData();
      let displayCents = totalCents;
      if (subData) {
        const mainPrice      = parseFloat(label.dataset.bbMainPrice || '0');
        const pct            = parseFloat(label.dataset.bbPctLeft   || '1');
        const fix            = parseFloat(label.dataset.bbFixedOff  || '0');
        const addonPrice     = parseFloat(label.dataset.bbAddonPrice || '0');
        const mainDiscounted = Math.round(mainPrice * pct - fix);
        displayCents = this._applySubDiscount(mainDiscounted, subData) + addonPrice;
      }
      document.dispatchEvent(new CustomEvent('bb:option-change', {
        detail: {
          sectionId:    this.dataset.section,
          totalCents:   Math.round(displayCents),
          compareCents: Math.round(compareCents)
        }
      }));
    }

    _rebuildFormVariants() {
      if (!this._activeOpt) return;

      // Collect all product checkboxes for the active option
      const cbs = Array.from(
        this.querySelectorAll(`.bundle-deals__checkbox-js[data-opt="${this._activeOpt}"]`)
      );
      const map = {};
      cbs.forEach(cb => {
        const id = String(cb.dataset.id);
        if (!id) return;
        map[id] ? map[id].quantity++ : (map[id] = { id, quantity: 1 });
      });
      this.formVariants = Object.values(map).reverse();

      // Track the main product variant ID (data-index="0") so the fetch
      // interceptor can apply selling_plan to exactly the right item
      const mainCb = this.querySelector(
        `.bundle-deals__checkbox-js[data-opt="${this._activeOpt}"][data-index="0"]`
      );
      this._mainVariantId = mainCb ? String(mainCb.dataset.id) : null;

      // Clear gift tracking then re-populate
      this._giftVariantIds = new Set();

      // Append gift product variant if this option has one
      const label = this.querySelector(`.bb-option[data-bb-opt="${this._activeOpt}"]`);
      if (label) {
        const giftDiv = label.querySelector('.bb-free-gift[data-gift-variant-id]');
        if (giftDiv) {
          const giftId = giftDiv.dataset.giftVariantId;
          if (giftId) {
            this.formVariants.push({ id: giftId, quantity: 1 });
            this._giftVariantIds.add(giftId); // gifts never get a selling_plan
          }
        }
      }
    }

    // ── Variant picker change ────────────────────────────────────
    _onVariantChange(picker) {
      const opt      = picker.dataset.opt;
      const idx      = picker.dataset.index;
      const selects  = Array.from(picker.querySelectorAll('select'));
      const selected = selects.map(s => s.value);
      const variants = JSON.parse(picker.querySelector('[type="application/json"]').textContent);

      // Update availability states on sibling dropdowns
      if (typeof updateVariantStatuses === 'function') {
        const selectorItem = picker.querySelector('.quantity-break__selector-item');
        const firstChecked = selectorItem ? selectorItem.querySelector(':checked') : null;
        if (firstChecked) {
          updateVariantStatuses(
            variants.filter(v => firstChecked.value === v.option1),
            [...picker.querySelectorAll('.select--small')]
          );
        }
      }

      const matched = variants.find(v =>
        !v.options.map((o, i) => selected[i] === o).includes(false)
      );
      if (!matched) {
        if (typeof findAvailableVariant === 'function') {
          findAvailableVariant(picker, selected, false, true, false);
        }
        return;
      }

      // Update hidden checkbox data-id and price for cart submission + header recalc
      const cb = this.querySelector(
        `.bundle-deals__checkbox-js[data-opt="${opt}"][data-index="${idx}"]`
      );
      if (cb) {
        cb.dataset.id = String(matched.id);
        // Apply the picker's discount to the new variant's price and store it
        // so _updateOptionHeaderTotal reads the correct current price
        const cbPct = parseFloat(picker.dataset.percentageLeft || '1');
        const cbFix = parseFloat(picker.dataset.fixedDiscount  || '0');
        cb.dataset.price        = String(Math.round(matched.price * cbPct - cbFix));
        cb.dataset.comparePrice = String(matched.compare_at_price && matched.compare_at_price > matched.price ? matched.compare_at_price : matched.price);
      }

      // Keep _mainVariantId in sync when the main product variant changes
      if (idx === '0' && opt === this._activeOpt) {
        this._mainVariantId = String(matched.id);
      }

      // Update price and thumbnail in the product row
      const row = picker.closest('.bb-product-row');
      if (row) {
        const pct = parseFloat(picker.dataset.percentageLeft || '1');
        const fix = parseFloat(picker.dataset.fixedDiscount  || '0');
        const np  = Math.round(matched.price * pct - fix);
        const nc  = matched.compare_at_price ? parseInt(matched.compare_at_price) : matched.price;
        const fmt = this.dataset.moneyFormat || '';
        const pe  = row.querySelector('.bundle-deals__price-js');
        const ce  = row.querySelector('.bundle-deals__compare-price-js');
        const ie  = row.querySelector('.bundle-deals__media-item-img-js');
        if (pe) pe.textContent = _bbFmt(np, fmt);
        if (ce) ce.textContent = nc > np ? _bbFmt(nc, fmt) : '';
        if (ie && matched.featured_image?.src) ie.src = matched.featured_image.src;
      }

      // For the main product (index 0), update the page gallery AND store new base price on labels
      if (idx === '0') {
        if (matched.featured_media) {
          const sectionId = this.dataset.section;
          const mediaId   = sectionId + '-' + matched.featured_media.id;
          document.querySelectorAll('[id^="MediaGallery-' + sectionId + '"]').forEach(gallery => {
            if (typeof gallery.setActiveMedia === 'function') {
              gallery.setActiveMedia(mediaId, true);
            }
          });
        }
        // Update stored main price on all option labels so subscription recalculation uses the right base
        const newPrice = matched.price;
        const newCompare = matched.compare_at_price || matched.price;
        this.querySelectorAll('.bb-option[data-bb-opt]').forEach(lbl => {
          lbl.dataset.bbMainPrice    = newPrice;
          lbl.dataset.bbMainCompare  = newCompare;
          // Recalculate total for this option using stored pct/fixed
          const pct = parseFloat(lbl.dataset.bbPctLeft || '1');
          const fix = parseFloat(lbl.dataset.bbFixedOff || '0');
          const addonPrice = parseFloat(lbl.dataset.bbAddonPrice || '0');
          const newTotal   = Math.round(newPrice * pct - fix) + addonPrice;
          lbl.dataset.bbTotal   = newTotal;
          lbl.dataset.bbCompare = Math.round(newCompare + addonPrice);
        });
        // Re-run subscription update so header prices stay correct
        this._updateAllOptionPrices();
      }

      if (opt === this._activeOpt) this._rebuildFormVariants();

      // Always update the header total for the option whose variant changed,
      // regardless of whether it is the active (selected) option — options may
      // be visible via bb-always-open even when not selected.
      this._updateOptionHeaderTotal(opt);
    }

    _updateOptionHeaderTotal(optNum) {
      const label = this.querySelector(`.bb-option[data-bb-opt="${optNum}"]`);
      if (!label) return;

      // Sum prices from all product checkboxes for this option
      let total      = 0;
      let compare    = 0;
      let liveAddon  = 0; // sum of addon (index > 0) current prices

      this.querySelectorAll(`.bundle-deals__checkbox-js[data-opt="${optNum}"]`).forEach(cb => {
        const price    = parseFloat(cb.dataset.price        || '0');
        const cmpPrice = parseFloat(cb.dataset.comparePrice || '0');
        total   += price;
        compare += cmpPrice > price ? cmpPrice : price;
        // Addons are index > 0 (main product is index 0, gift has no price impact)
        if (cb.dataset.index !== '0') liveAddon += price;
      });

      // Update the stored total and live addon price on the label
      label.dataset.bbTotal      = Math.round(total);
      label.dataset.bbCompare    = Math.round(compare);
      label.dataset.bbAddonPrice = Math.round(liveAddon); // keep in sync for _updateAllOptionPrices

      const fmt     = this.dataset.moneyFormat || '';
      const subData = this._getSubscriptionData();
      let displayTotal = total;

      if (subData) {
        // Subscription discount applies to main product only — use live addon price
        const mainPrice      = parseFloat(label.dataset.bbMainPrice || '0');
        const pct            = parseFloat(label.dataset.bbPctLeft   || '1');
        const fix            = parseFloat(label.dataset.bbFixedOff  || '0');
        const mainDiscounted = Math.round(mainPrice * pct - fix);
        displayTotal = this._applySubDiscount(mainDiscounted, subData) + liveAddon;
      }

      const totalEl   = label.querySelector('.bb-opt-total-js');
      const compareEl = label.querySelector('.bb-opt-compare-js');
      if (totalEl) totalEl.textContent = _bbFmt(Math.round(displayTotal), fmt);
      if (compareEl) {
        if (compare > Math.round(displayTotal)) {
          compareEl.textContent = _bbFmt(Math.round(compare), fmt);
          compareEl.style.display = '';
        } else {
          compareEl.style.display = 'none';
        }
      }

      // If this is the active option, update the page price block too
      if (optNum === this._activeOpt) this._dispatchOptionChange();
    }

    _onMainVariantChange(variant) {
      this.querySelectorAll('.bundle-deals__checkbox-js[data-index="0"]').forEach(cb => {
        cb.dataset.id = String(variant.id);
        const row = cb.closest('.bb-product-row');
        if (row && variant.featured_image?.src) {
          const img = row.querySelector('.bundle-deals__media-item-img-js');
          if (img) img.src = variant.featured_image.src;
        }
      });
      // Keep _mainVariantId in sync
      this._mainVariantId = String(variant.id);
      this.querySelectorAll('.bundle-deals__variant-selects-js[data-index="0"]').forEach(picker => {
        Array.from(picker.querySelectorAll('select')).forEach((sel, i) => {
          if (variant.options?.[i]) sel.value = variant.options[i];
        });
      });
      this._rebuildFormVariants();
    }

    // ── Cart removal listener ────────────────────────────────────
    _setupCartRemovalListener() {
      const wrapper = this.closest('[data-remove-addons]');
      if (!wrapper || wrapper.dataset.removeAddons !== 'true') return;

      this._bbRemovingAddons = false;

      const getMainHandle = () => {
        const mainCb = this.querySelector(
          `.bundle-deals__checkbox-js[data-opt="${this._activeOpt}"][data-index="0"]`
        );
        return mainCb ? mainCb.dataset.handle : null;
      };

      const getCartItems = () =>
        document.querySelector('cart-drawer-items') || document.querySelector('cart-items');

      const removeAddonsByHandle = () => {
        if (this._bbRemovingAddons) return;

        const mainHandle = getMainHandle();
        if (!mainHandle) return;

        const mainCartEl = document.querySelector('.cart-item--product-' + mainHandle);
        if (mainCartEl) return;

        const addonHandles = [];
        this.querySelectorAll(`.bundle-deals__checkbox-js[data-opt="${this._activeOpt}"]`).forEach(cb => {
          if (cb.dataset.index !== '0' && cb.dataset.handle) {
            addonHandles.push(cb.dataset.handle);
          }
        });
        const giftDiv = this.querySelector(`.bb-option[data-bb-opt="${this._activeOpt}"] .bb-free-gift[data-gift-handle]`);
        if (giftDiv && giftDiv.dataset.giftHandle && !addonHandles.includes(giftDiv.dataset.giftHandle)) {
          addonHandles.push(giftDiv.dataset.giftHandle);
        }

        if (!addonHandles.length) return;

        const cartItems = getCartItems();
        if (!cartItems) {
          console.warn('[BB] cart-drawer-items element not found');
          return;
        }

        this._bbRemovingAddons = true;
        console.log('[BB] Main product removed — removing addons with handles:', addonHandles);

        const removeNext = (handles) => {
          if (!handles.length) {
            this._bbRemovingAddons = false;
            return;
          }
          const handle = handles[0];
          const cartEl = document.querySelector('.cart-item--product-' + handle);
          if (!cartEl) {
            removeNext(handles.slice(1));
            return;
          }
          const lineIndex = cartEl.dataset.index;
          console.log('[BB] Removing handle', handle, 'at line', lineIndex);
          cartItems.updateQuantity(lineIndex, 0);
          const onUpdated = () => {
            document.removeEventListener('cartQuantityUpdated', onUpdated);
            removeNext(handles.slice(1));
          };
          document.addEventListener('cartQuantityUpdated', onUpdated, { once: true });
        };

        removeNext(addonHandles);
      };

      let _bbDebounce = null;
      document.addEventListener('cartQuantityUpdated', () => {
        if (this._bbRemovingAddons) return;
        clearTimeout(_bbDebounce);
        _bbDebounce = setTimeout(removeAddonsByHandle, 150);
      });
    }

    // ── Selling plan injection ───────────────────────────────────
    _setupSellingPlanInjector() {
      if (window.__bbFetchPatched) return;
      window.__bbFetchPatched = true;

      const origFetch = window.fetch;
      window.fetch = function(url, options) {
        if (typeof url === 'string' && url.includes('/cart/add')) {
          const body = options && options.body;
          if (body instanceof FormData) {
            const bb = document.querySelector('bundle-breaks[data-section]');
            if (bb && typeof bb._getSellingPlanId === 'function') {
              const planId = bb._getSellingPlanId();
              if (planId) {
                const keysToProcess = [];
                for (const key of body.keys()) {
                  const m = key.match(/^items\[(\d+)\]\[id\]$/);
                  if (m) keysToProcess.push(m[1]);
                }
                keysToProcess.forEach(function(idx) {
                  const variantId = String(body.get('items[' + idx + '][id]'));
                  if (!bb._mainVariantId || variantId !== bb._mainVariantId) return;
                  if (bb._giftVariantIds && bb._giftVariantIds.has(variantId)) return;
                  if (body.has('items[' + idx + '][selling_plan]')) return;
                  body.append('items[' + idx + '][selling_plan]', planId);
                  console.log('[BB] injected selling_plan', planId, 'for main variant', variantId, 'at index', idx);
                });

                console.log('[BB] Full cart/add payload:');
                for (const [k, v] of body.entries()) console.log('  ' + k + ' = ' + v);
              } else {
                console.log('[BB] cart/add: no selling plan active, sending as-is');
              }
            }
          }
        }
        const result = origFetch.apply(this, arguments);
        if (typeof url === 'string' && url.includes('/cart/add')) {
          result.then(function(r) {
            return r.clone().json().then(function(j) {
              if (j.status) console.log('[BB] cart/add ERROR:', JSON.stringify(j));
            }).catch(function() {});
          }).catch(function() {});
        }
        return result;
      };
    }

    _getSellingPlanId() {
      const sectionId = this.dataset.section;

      const productForm = document.getElementById('product-form-' + sectionId);
      if (productForm) {
        const spInput = productForm.querySelector('input[name="selling_plan"]');
        console.log('[BB] selling_plan input:', spInput, 'value:', spInput && spInput.value);
        if (spInput && spInput.value && spInput.value.trim() !== '') return spInput.value;
      }

      const widget =
        document.querySelector('#SubscriptionWidget-' + sectionId) ||
        document.querySelector('theme-subscription-widget') ||
        document.querySelector('[id*="SubscriptionWidget"]');
      if (!widget) { console.log('[BB] no subscription widget found'); return null; }

      const isBoxSelected    = !!widget.querySelector('.subscription__box--subscription.subscription__box--selected');
      const isToggleSelected = !!widget.querySelector('.subscription__toggle-option[data-type="subscription"].subscription__toggle-option--selected');
      console.log('[BB] sub selected - box:', isBoxSelected, 'toggle:', isToggleSelected);
      if (!isBoxSelected && !isToggleSelected) return null;

      console.log('[BB] widget.selectedPlanId:', widget.selectedPlanId);
      if (widget.selectedPlanId) return widget.selectedPlanId;

      const freqRadio = widget.querySelector('input.subscription__frequency-input:checked');
      if (freqRadio && freqRadio.dataset.sellingPlanId) return freqRadio.dataset.sellingPlanId;

      const freqDropdown = widget.querySelector('select[id*="SubscriptionFrequency"]');
      if (freqDropdown) {
        const opt = freqDropdown.options[freqDropdown.selectedIndex];
        if (opt && opt.dataset.sellingPlanId) return opt.dataset.sellingPlanId;
      }

      console.log('[BB] could not resolve selling plan id');
      return null;
    }

    // ── Subscription widget sync ─────────────────────────────────
    _setupSubscriptionSync() {
      const sectionId = this.dataset.section;

      const getWidget = () =>
        document.querySelector(`#SubscriptionWidget-${sectionId}`) ||
        document.querySelector('theme-subscription-widget') ||
        document.querySelector('[id*="SubscriptionWidget"]');

      const widget = getWidget();
      if (!widget) return;

      widget.addEventListener('click', () => {
        setTimeout(() => this._updateAllOptionPrices(), 80);
      });

      widget.addEventListener('change', () => {
        setTimeout(() => this._updateAllOptionPrices(), 80);
      });

      const observer = new MutationObserver(() => {
        this._updateAllOptionPrices();
      });
      observer.observe(widget, { attributes: true, subtree: true, attributeFilter: ['class', 'data-selected'] });
    }

    _getSubscriptionData() {
      const widget =
        document.querySelector(`#SubscriptionWidget-${this.dataset.section}`) ||
        document.querySelector('theme-subscription-widget') ||
        document.querySelector('[id*="SubscriptionWidget"]');

      if (!widget) return null;

      const isBoxSelected    = widget.querySelector('.subscription__box--subscription.subscription__box--selected') !== null;
      const isToggleSelected = widget.querySelector('.subscription__toggle-option[data-type="subscription"].subscription__toggle-option--selected') !== null;
      if (!isBoxSelected && !isToggleSelected) return null;

      const updatePrices = widget.getAttribute('data-update-prices') === 'true';
      if (!updatePrices) return null;

      let discountType  = widget.getAttribute('data-discount-type');
      let discountValue = parseFloat(widget.getAttribute('data-discount-value') || '0');

      const freqDropdown = widget.querySelector('select[id*="SubscriptionFrequency"]');
      const freqRadio    = widget.querySelector('input.subscription__frequency-input:checked');

      let planPrice        = null;
      let planComparePrice = null;

      if (freqDropdown) {
        const opt = freqDropdown.options[freqDropdown.selectedIndex];
        planPrice        = parseFloat(opt.getAttribute('data-price'));
        planComparePrice = parseFloat(opt.getAttribute('data-compare-price'));
        const pdt = opt.getAttribute('data-discount-type');
        const pdv = parseFloat(opt.getAttribute('data-discount-value'));
        if (pdt) discountType  = pdt;
        if (pdv) discountValue = pdv;
      } else if (freqRadio) {
        planPrice        = parseFloat(freqRadio.getAttribute('data-price'));
        planComparePrice = parseFloat(freqRadio.getAttribute('data-compare-price'));
        const pdt = freqRadio.getAttribute('data-discount-type');
        const pdv = parseFloat(freqRadio.getAttribute('data-discount-value'));
        if (pdt) discountType  = pdt;
        if (pdv) discountValue = pdv;
      }

      return { isSubscription: true, discountType, discountValue, planPrice, planComparePrice };
    }

    _applySubDiscount(pricePerUnit, subData) {
      if (!subData) return pricePerUnit;

      if (subData.planPrice !== null && !isNaN(subData.planPrice)) {
        return subData.planPrice;
      }

      if (subData.discountType === 'percentage') {
        return Math.round(pricePerUnit * (1 - subData.discountValue / 100));
      }
      if (subData.discountType === 'fixed_amount') {
        return Math.max(0, pricePerUnit - subData.discountValue * 100);
      }
      if (subData.discountType === 'price') {
        return subData.discountValue * 100;
      }
      return pricePerUnit;
    }

    _updateAllOptionPrices() {
      const subData = this._getSubscriptionData();
      const fmt = this.dataset.moneyFormat || '';

      this.querySelectorAll('.bb-option[data-bb-opt]').forEach(label => {
        const mainPrice   = parseFloat(label.dataset.bbMainPrice   || '0');
        const pct         = parseFloat(label.dataset.bbPctLeft      || '1');
        const fix         = parseFloat(label.dataset.bbFixedOff     || '0');
        const addonPrice  = parseFloat(label.dataset.bbAddonPrice   || '0');
        const baseCompare = parseFloat(label.dataset.bbCompare      || '0');

        const mainDiscounted = Math.round(mainPrice * pct - fix);

        let displayTotal;
        if (subData) {
          const mainAfterSub = this._applySubDiscount(mainDiscounted, subData);
          displayTotal = mainAfterSub + addonPrice;
        } else {
          displayTotal = mainDiscounted + addonPrice;
        }

        const totalEl   = label.querySelector('.bb-opt-total-js');
        const compareEl = label.querySelector('.bb-opt-compare-js');

        if (totalEl)   totalEl.textContent   = _bbFmt(displayTotal, fmt);

        if (compareEl) {
          const originalTotal = mainDiscounted + addonPrice;
          const comparePrice  = subData ? originalTotal : baseCompare;
          if (comparePrice > displayTotal) {
            compareEl.textContent = _bbFmt(comparePrice, fmt);
            compareEl.style.display = '';
          } else {
            compareEl.style.display = 'none';
          }
        }
      });
      this._dispatchOptionChange();
    }
  }

  customElements.define('bundle-breaks', BundleBreaks);

  function _bbFmt(cents, format) {
    return (typeof Shopify !== 'undefined' && Shopify.formatMoney)
      ? Shopify.formatMoney(cents, format)
      : '$' + (cents / 100).toFixed(2);
  }
})();
</script>