NationBuilder - How to upgrade donation code

In October 2025, NationBuilder has repleased upgraded donation page changes. These changes added support for new features:

NationBuilder documentation on upgrading:

This upgraded added much needed support for new functionality - but also unintentionally introduced some bugs into our donation code. Follow the steps below to upgrade a NationBuilder Public Theme site split before 17 February 2026 (All sites after that should be working fine as that is when the public theme was updated).

Our Public Theme donation templates are staged and our sites use Bootstrap v4 - so there are a combination of changes we need to apply.

#1. Add comments to irrelevant and deprecated code

Update the following message to the current date. We will paste this at the top of deprecated, un-used, and irrelevant SCSS files - if they exist.

/*
 * ⚠️ DEPRECATION NOTICE ⚠️
 * -----------------------------------------------------------------------
 * DATE ADDED: 17 February 2026
 *
 * STATUS: This file is flagged for removal.
 *
 * 🚨 DO NOT MODIFY: Any changes made here will likely be lost.
 * Please migrate styles to the new architecture instead.
 *
 * 🗑️ EXPIRATION: If you are reading this after 17 February 2027,
 * this file has officially overstayed its welcome. Please delete
 * it and remove any remaining imports.
 * -----------------------------------------------------------------------
 */

Paste this into the top of the deprecated, un-used, and irrelevant Liquid HTML files - if they exist.


2. Create new require files

_z_template_2_panel.scss

Create a new file in the current theme: _z_template_2_panel.scss with contents:

NOTE: The color variables at the top will likely need to be tweaked for your given theme:

/*
*
* _z_template_2_panels.scss
*
*/

// ************************************* //
// ************ VARIABLES ************** //
// ************************************* //

// Extracted Hardcoded Colors
$donation-hover-bg:       rgba(255, 192, 0, 0.5) !default;
$donation-hover-text:     #303030 !default;
$donation-active-bg:      #ffc000 !default;
$donation-active-text:    #ffffff !default;
$donation-gradient-rgb:   rgba(243, 242, 242, 0) !default; // Used for RGBA transparency

// Existing Logic Variables
$panel-form-wrapper-bg-color:                 $primary !default;
$panel-form-wrapper-h4-color:                 $light !default;
$panel-form-wrapper-text-color:               $light !default;
$panel-form-wrapper-btn-primary-action-color: $secondary !default;
$panel-form-wrapper-btn-secondary-acion-color: $tertiary !default;

// ************************************* //
// *********** BEGIN 2-PANEL *********** //
// ************************************* //

.left-panel {
  display: flex;
  flex-direction: column;

  .social-share-container {
    margin-top: auto !important;
  }

  img {
    max-width: 100%;
    height: auto;
  }
}

@media (min-width: 992px) {
  .left-panel, .right-panel {
    margin: inherit;
  }
}

.panel-form-wrapper {
  background-color: $panel-form-wrapper-bg-color;

  h4 { color: $panel-form-wrapper-h4-color; }

  p, span, label, strong {
    color: $panel-form-wrapper-text-color;
  }

  .btn-primary-action {
    @include button-variant($panel-form-wrapper-btn-primary-action-color, $panel-form-wrapper-btn-primary-action-color);
    color: $primary !important;
  }

  .btn-secondary-action {
    @include button-variant($panel-form-wrapper-btn-secondary-acion-color, $panel-form-wrapper-btn-secondary-acion-color);
  }
}

.right-panel {
  img {
    max-width: 100%;
    height: auto;
  }

  &.page-has-feature {
    z-index: 1;
    margin-top: 1rem;

    @include media-breakpoint-up(lg) {
      margin-top: -375px;
    }
  }
}

.panel-form-detail-wrapper {
  background: $gray-300;
  border-radius: 5px;

  .panel-form-detail-container {
    position: relative;

    .panel-form-detail-wrapper-overlay {
      position: absolute;
      width: 100%;
      height: 160px;
      bottom: 0;
      z-index: 1;

      // Using the extracted RGB variable for the gradient
      background-image: linear-gradient(top, $donation-gradient-rgb 0%, $gray-300 100%);
      background-image: -webkit-linear-gradient(top, $donation-gradient-rgb 0%, $gray-300 100%);
      background-image: -ms-linear-gradient(top, $donation-gradient-rgb 0%, $gray-300 100%);
    }

    .panel-form-detail-signer {
      background-color: $white;
      border-radius: 5px;
      color: $gray-800;
      font-size: 0.875rem;
    }
  }
}

.panel-form-divider {
  background-color: $gray-500;
  height: 1px;
  width: 100%;
}

.progress {
  height: 12px;
  border-radius: 6px;

  &-bar {
    background-clip: border-box;
    background: -webkit-linear-gradient(left, $progressbar-0, $progressbar-100);
    background: linear-gradient(to right, $progressbar-0, $progressbar-100);
  }
}

// ****************************************** //
// ************* BEGIN DONATION ************* //
// ****************************************** //

.page-pages-show-donation-wide,
.page-pages-show-donation-v2-wide {

  .radio-inline {
    display: flex;
    flex-wrap: wrap;
    margin-right: -15px;
    margin-left: -15px;

    label.radio {
      background: $white !important;
      border-radius: 30px !important;
      border: 1px solid $white !important;
      color: $gray-700 !important;
      cursor: pointer !important;
      width: 100% !important;
      display: flex;
      justify-content: center;
      align-items: center;

      &:hover {
        background: $donation-hover-bg !important;
        color: $donation-hover-text !important;
      }
    }

    input[type="radio"]:checked + label {
      color: $donation-active-text !important;
      background-color: $donation-active-bg !important;
      border-color: $donation-active-bg !important;
    }
  }

  .custom-control-inline {
    width: 50% !important;
    margin: 0 !important;
    padding: 15px !important;

    .custom-control-label { margin: 0 !important; }
  }

  .custom-radio {
    .custom-control-label::before {
      display: block !important;
      position: absolute !important;
      left: -9999px !important;
    }
    .custom-control-input:checked ~ .custom-control-label::after {
      background-image: none !important;
    }
  }

  .progress-stages .progress-stage .btn-process-donation {
    border: none !important;
    font-size: unset !important;
  }

  #donation_card_expires_on_1i {
    margin-bottom: 1rem;
  }
}

3. Copy and paste in new versions of files

For the most part the following files should just be copy-paste upates. However - please do proceed with caution. It is recommended to do a code-diff between your site's current file and this new updated version of the file. These sites may have been customized since splitting from the Public Theme - in which case you won't want to accidentally remove any client specific functionality.

1. _staged-donations.scss

Do a code-diff and compare - but should be a simple copy and paste.

When comparing - it should just be adding some margin/padding overrides to label.radio.

$staged-donation-error-text-size: 20px;
$staged-donation-error-text-color: red;

label[for='donation_amount_other'],
input#donation_amount_other.text {
  display: block;
  margin-left: 0;
  margin-top: 10px;
}

#donation-amount-container {
  padding-bottom: 15px;
}

.page-pages-show-donation-wide, .page-pages-show-donation-v2-wide {
  .donation_form .form-wrap {
    margin-bottom: 1.25em;
  }
  .progress-indicator-stages {
    list-style-type: none;
    padding: 0 0 15px 0;
    margin: 0 auto;
    width: auto;
    text-align: center;
    li {
      display: inline-block;
      position: relative;
      margin-right: 32px;
      white-space: nowrap;
      width: 51px;
      &:after {
        content: " ";
        width: 42px;
        height: 0;
        border-bottom: 1px solid #ccc;
        position: absolute;
        top: 45px;
        left: 47px;
      }
      &:last-child {
        margin-right: 0;
        &:after {
          display: none;
        }
      }
      .stage-label {
        font-size: 12px;
        font-weight: 600;
        position: relative;
        text-transform: uppercase;
      }
      &.stage-1 .stage-label {
        left: -1px;
      }
      &.stage-2 .stage-label {
        left: -8px;
      }
      &.stage-3 .stage-label {
        left: -3px;
      }
      .stage-count {
        position: relative;
        display: block;
        color: #fff;
        width: 47px;
        height: 47px;
        text-align: center;
        background: #f8f8f8;
        border: 1px solid #ccc;
        border-radius: 99px;
      }
      .stage-count-inner {
        width: 39px;
        height: 39px;
        left: 3px;
        top: 3px;
        line-height: 40px;
        display: block;
        position: relative;
        background: #ccc;
        position: relative;
        border-radius: 99px;
      }
      &.active .stage-count-inner {
        background: #999;
      }
      &.seen .stage-count-inner {
        background: #999;
        cursor: pointer;
      }
      &.completed .stage-count-inner {
        text-indent: -9999px;
        background: #999;
        cursor: pointer;
        &:before {
          color: #fff;
          position: absolute;
          width: 39px;
          line-height: 39px;
          z-index: 20;
          opacity: 1;
          text-align: center;
          top: 0;
          left: 0px;
          font-size: 1.25em;
          cursor: pointer;
          text-indent: 0;
        }
      }
      &.completed .stage-count {
        cursor: pointer;
      }
    }
  }
  .progress-stages {
    background-color: #f8f8f8;
    padding: 20px 15px;
    min-height: 402px;
    border-radius: 2px;
    select,
    textarea,
    input {
      font-size: 14px;
    }
    input[type="text"] {
    	width: 100%;
    }
    input {
      color: #333;
      &:invalid {
        border: 1px solid $staged-donation-error-text-color;
      }
    }

    .row.row-error {
      padding-top: $staged-donation-error-text-size;
      color: $staged-donation-error-text-color;
    }
    .row.row-error div.form-error {
      position: absolute;
      top: -$staged-donation-error-text-size;
      &.form-pass {
        color: green;
      }
    }
    .progress-stage {
      display: none;
      &.active {
        display: block;
      }
      .radio-inline {
        padding-left: 0;
      }
      .submit-button {
         width: auto;
      }
      label:not(.checkbox) input, input.text {
      	height: 34px;
        padding-left: 5px;
      }
    }
  }
  .progress-stage-button-prev {
    &:before {
      content:"\00ab\0000a0";
    }
  }
  .radio-inline {
    input[type="radio"] {
      display: block;
      position: absolute;
      left: -9999px;
    }
    label.radio {
      border-radius: 2px;
      background-color: #333;
      color: #ccc;
      display: inline-block;
      width: 80px;
      padding: 15px 5px;
      font-weight: bold;
      font-size: 19px;
      text-align: center;

      margin: 0 !important;
      padding: 15px !important;
    }
    input[type="radio"]:checked+label {
      background-color: #999;
      color: #fff;
    }
  }
}

.lt-ie9 .progress-indicator-stages li.stage-3:after {
  display:none;
}

#donation_billing_address_state {
  width: 100%;
}

.progress-stage-button-prev,
.progress-stage-button-next {
	display: inline-block;
  cursor: pointer;
}
a.progress-stage-button-prev {
  &:hover, &:focus, &:active {
      text-decoration: none;
      color: #333;
    }
    width: auto;
}
.progress-stage label[for*='donation_'].checkbox {
  margin-left: 20px;
  input {
    margin-top: .4rem;
    height: 12px;
  }
}

.page-pages-show-donation-wide .progress-stages input.validation-check,
.page-pages-show-donation-v2-wide .progress-stages input.validation-check {
  border: 1px solid #ccc;
}

/* iPhone style corrections */
.progress-stage {
  @media screen and (-webkit-min-device-pixel-ratio:0) {
    select,
    textarea,
    input,
    input:focus,
    input:hover {
      border: 1px solid #ccc;
      font-size: 16px !important;
    }
  }
}

2. _stripe.scss

Do a code-diff and compare - but should be a simple copy and paste.

When comparing - changes again should be minimal - should only be setting the height and border on .StripeElement.

// On Donation v2 pages you will also need to update the JavaScript styles
// For more information on how to do that visit https://nationbuilder.com/how_to_style_payment_fields

.StripeElement {
  @extend .form-control;
  padding-top: 0.475rem; // fix for input alignment
  height: auto; // Such that StripeElement doesn't break out of cc-info div
  border: none;
}
.StripeElement--empty {

}
.StripeElement--focus {
  color: $input-focus-color;
  background-color: $input-focus-bg;
  border-color: $input-focus-border-color;
  outline: 0;
  box-shadow: $input-focus-box-shadow;
}
.StripeElement--invalid {
  border-color: $danger;
  box-shadow: 0 0 0 $input-focus-width rgba($danger, .25);
}

3. _z_pages_show_donation_v2_wide_form.html

Do a code-diff and compare - but should be a simple copy and paste.

This is where most of the changes happen. Adding recaptcha,tweaks to donation frequency liquid, tweaks to input HTML structure, adding in custom field via tag support, adding in new no_employer field, adding new "Payment method" HTML, Changing liquid card to payments, updated script at bottom of file.

{% comment %}
<!--
  * For Purpose Custom Theme
  *
  * _z_pages_show_donation_v2_wide_form.html
  *
  * Custom Donation Template
  *
  * NOTE: This file last updated February 2026 - view upgrade notes here:
  * https://mauhanga.forpurpose.nz/docs/fp-admin/nationbuilder-upgrade-donation-code/
  *
-->
{% endcomment %}

  <h4>Donate</h4>

  {% if page.donation_v2.has_amount_goal? %}

    <p>Our goal is to raise {{ page.donation_v2.amount_goal_format }}</p>

    <div class="mb-3">
      <div class="progress">
        <div class="progress-bar" role="progressbar" style="width: {{ page.donation_v2.percent_of_amount_goal | times:100 }}%;" aria-valuenow="{{ page.donation_v2.percent_of_amount_goal | times:100 }}" aria-valuemin="0" aria-valuemax="100">
          {% comment %}
          <!--
            {% if page.donations_count < 2 %}
              <span class="px-1 text-muted">Just started</span>
            {% else %}
              {{ page.donations_amount_format }} <span class="sr-only">raised</span>
            {% endif %}
          -->
          {% endcomment %}
        </div>
      </div>
      {% comment %}<!--<small class="text-muted">Raised goal of {{ page.donation_v2.amount_goal_format }}</small>-->{% endcomment %}
    </div>

  {% elsif page.donation_v2.has_donor_goal? %}

    <p>Our goal is to raise {{ page.donation_v2.donor_goal }} donations</p>

    <div class="mb-3">
      <div class="progress">
        <div class="progress-bar" role="progressbar" style="width: {{ page.donation_v2.percent_of_donor_goal | times:100 }}%;" aria-valuenow="{{ page.donation_v2.percent_of_donor_goal | times:100 }}" aria-valuemin="0" aria-valuemax="100">
          {% comment %}
          <!--
            {% if page.donations_count < 2 %}
              <span class="px-1 text-muted">Just started</span>
            {% else %}
              {{ page.donations_count }} <span class="sr-only">donors</span>
            {% endif %}
          -->
          {% endcomment %}
        </div>
      </div>
      {% comment %}<!--<small class="text-muted">Donor goal of {{ page.donation_v2.donor_goal }}</small>-->{% endcomment %}
    </div>
  {% endif %}

  {% form_for donation %}
    <div class="form-wrap pt-3">
      <div class="form">

        {% if page.donation_v2.has_merchant_account? == false %}
          <div class="mb-4">
            <span class="red"><strong>No payment processor:</strong> This page will not work until you add a payment processor</span>
          </div>
        {% elsif page.donation_v2.merchant_account.is_test_mode? %}
          <div class="mb-4">
            <span class="red"><strong>Testing mode:</strong> Transactions will not be processed. Use your regular credit card to test, you will not actually be charged.</span>
          </div>
        {% endif %}

        <div class="row">
          <div class="col-sm-12 mt-4">
            <div class="form-progress-indicator">
              <ul class="progress-indicator-stages clearfix">
                <li class="progress-indicator-stage stage-1 active"><span class="stage-count"><span class="stage-count-inner">1</span></span></li>
                <li class="progress-indicator-stage stage-2"><span class="stage-count"><span class="stage-count-inner">2</span></span></li>
                <li class="progress-indicator-stage stage-3"><span class="stage-count"><span class="stage-count-inner">3</span></span></li>
              </ul>
            </div>
          </div>
        </div>

        <div class="panel-form-divider mt-3 mb-4"></div>

        <div class="form-errors">{% error_messages_for donation %}</div>
        <div id="recaptcha_checkbox"></div>

        <div class="progress-stages">
          <div class="progress-stage stage-1 active" data-stageID="1">
            {% if request.current_order %}
              {% for item in request.current_order.items %}
                {% if item.num_time_periods and item.time_period_type %}
                  {{ item.quantity }} {{ item.name }} @ {{ item.amount }} - billed automatically every {{ item.num_time_periods }} {{item.time_period_type }}
                {% else %}
                  {{ item.quantity }} {{ item.name }} @ {{ item.amount }}
                {% endif %}
              {% endfor %}
              <a href="{{ page.donation_v2.clear_order_url }}">Clear order</a>
            {% else %}

              {% if page.donation_v2.show_frequency_radio_buttons? %}
                <div class="row donation-v2-options">
                  <div class="col-12">
                    <label class="font-weight-bolder mb-0">Donation frequency</label>
                    <div class="donation-v2-occurence-radio radio-inline">
                      <div class="form-group d-flex w-100">
                        {{ page.donation_v2.recurring_radio_buttons }}
                      </div>
                    </div>
                  </div>
                </div>
              {% endif %}

              {% if page.donation_v2.donation_frequency == "monthly" %}
                <div class="row card-monthly">
                  <div class="col-sm-12 mb-2"><label class="font-weight-bolder mb-0">Donation frequency:</label> monthly</div>
                </div>
              {% endif %}

              <div class="row">
                <div class="col-sm-12">
                  {% if page.donation_v2.amount_in_cents != 0 %}
                    <!-- 30 March 2022 - Eric fix - adding "single-amount" class here and id "donation_amount_other_input"  -->
                    <input id="donation_amount_other_input" type="text" name="donation[amount]" class="form-control text nb_donation_v2_amount" style="display:none; visibility:hidden;" value="{{ page.donation_v2.amount_formatted | replace: '$', '' }}">
                    <h4 class="mb-2">{{ page.donation_v2.amount_formatted }}</h4>
                  {% else %}

                  <label class="font-weight-bolder mb-0">Donation amount</label>
                    <div class="radio-inline donation-v2-amounts mb-4">{{ page.donation_v2.form_amount_options }}</div>
                  {% endif %}

                  {% if page.donation_v2.accepts_variable_amounts? %}
                    <div class="row donation-v2-options">
                      <div class="col-12">
                        <div class="form-group">
                          {{ page.donation_v2.amount_other }}
                        </div>
                      </div>
                    </div>
                  {% endif %}

                </div>
              </div>
            {% endif %}

            <div class="mt-3"><a href="#" class="progress-stage-button-next button btn btn-primary-action w-100 mt-3">Continue</a></div>
          </div><!-- .progress-stage-1 -->

          <div class="progress-stage stage-2" data-stageID="2">

            <div class="row">
              <div class="col-sm-12 donation-amount-container mb-3">
                <strong>Donation amount: <span class="donation-amount"></span></strong>
                <div class="donation-frequency"></div>
              </div>
            </div>

            <div class="row">
              <div class="col-sm-12">
                <div class="form-group">
                  <label class="sr-only" for="donation_email">Email</label>
                  {% email_field "email", class:"form-control text validation-check", placeholder:"Email", required:"required" %}</div>
              </div>

              <div class="col-sm-12">
                <div class="form-group">
                  <label class="sr-only" for="donation_first_name">First Name</label>
                  {% text_field "first_name", class:"form-control text", placeholder:"First name" %}
                </div>
              </div>

              <div class="col-sm-12">
                <div class="form-group">
                  <label class="sr-only" for="donation_last_name">Last Name</label>
                  {% text_field "last_name", class:"form-control text", placeholder:"Last name" %}
                </div>
              </div>

              <div id="address-info">

                <div class="col-sm-12">
                  <div class="form-group">
                    <label for="">Billing Address</label>
                  <label class="sr-only" for="donation_billing_address_country_code">Country</label>
                    {% select_field "billing_address.country_code", page.donation_v2.countries, "code", "name", class:"form-control select", placeholder:"Country" %}
                    {% comment %}<!-- collection_select "billing_address.country_code", page.donation_v2.countries, "code", "name", class:"select form-control" -->{% endcomment %}
                  </div>
                </div>

                <div class="col-sm-12">
                  <div class="row">
                    <div class="col-sm-12">
                      <div class="form-group">
                        <label class="sr-only" for="donation_billing_address_address1">Address 1</label>
                        {% text_field "billing_address.address1", class:"form-control text validation-check", placeholder:"Address 1", required:"required" %}
                      </div>
                    </div>
                  </div>
                  <div class="row">
                    <div class="col-sm-12">
                      <div class="form-group">
                        <label class="sr-only" for="donation_billing_address_address2">Address 2</label>
                        {% text_field "billing_address.address2", class:"form-control text", placeholder:"Address 2" %}
                      </div>
                    </div>
                  </div>
                  <div class="row">
                    <div class="col-sm-12">
                      <div class="form-group">
                        <label class="sr-only" for="donation_billing_address_address3">Address 3</label>
                        {% text_field "billing_address.address3", class:"form-control text not-us-or-canada hide", placeholder:"Address 3" %}
                      </div>
                    </div>
                  </div>
                </div>

                <div class="col-sm-12">
                  <div class="form-group">
                    <label class="sr-only" for="donation_billing_address_city">City</label>
                    {% text_field "billing_address.city", class:"form-control text validation-check", placeholder:"City", required:"required" %}
                  </div>
                </div>

                <div class="col-sm-12 us-or-canada us-only hide">
                  <div class="form-group">
                    <label class="sr-only" for="donation_billing_address_state">State</label>
                    {% select_field "billing_address.state", page.donation_v2.us_states, "code", "name", class:"form-control select", placeholder:"State" %}
                    {% comment %}<!-- collection_select "billing_address.state", page.donation_v2.us_states, "code", "name", class:"form-control select", placeholder:"State" -->{% endcomment %}
                  </div>
                </div>

                <div class="col-sm-12 us-or-canada canada-only hide">
                  <div class="form-group">
                    <label class="sr-only" for="donation_billing_address_state">State</label>
                    {% text_field "billing_address.state", class:"form-control text", placeholder:"State" %}
                  </div>
                </div>

                <div class="col-sm-12">
                  <div class="form-group">
                    <label class="sr-only" for="donation_billing_address_zip">Postal Code</label>
                    {% text_field "billing_address.zip", class:"form-control text validation-check", placeholder:"Postal code", required:"required" %}
                  </div>
                </div>

                <div class="col-sm-12">
                  <div class="form-group">
                    <label class="sr-only" for="donation_billing_address_phone_number">Phone</label>
                    {% phone_field "billing_address.phone_number", class:"form-control text", placeholder:"Phone" %}
                  </div>
                </div>

              </div>

              {% comment %}<!-- custom form field - specific tag -->{% endcomment %}
              {% assign page_tags_list = "#" %}
              {% for tag in page.tags %}
                {% assign page_tags_list = "#" | append:tag.slug | append:"#" | append:page_tags_list %}
              {% endfor %}
              {% if page_tags_list contains "#custom_field_" %}
                {% for tag in page.tags %}
                  {% if tag.slug contains "custom_field_" %}
                    {% assign custom_slug = tag.slug | split:"custom_field_" | last %}
                    {% include "z_tag_custom_field" %}
                  {% endif %}
                {% endfor %}
              {% endif %}

              <div class="form-group col-md-12">
                <div class="custom-control custom-checkbox">
                  {% check_box "email_opt_in", class:"form-control custom-control-input" %}
                  <label class="custom-control-label small" for="donation_email_opt_in">Send me email updates</label>
                </div>
              </div>

              {% if page.donation_v2.merchant_account.is_employer_and_occupation_required? %}

                {% comment %}<!-- 2026 Donation V2 Upgrade: Required no_employer checkbox -->{% endcomment %}
                <div class="col-sm-12">
                  <div class="form-group">
                    <div class="custom-control custom-checkbox">
                      {% check_box "no_employer", class:"form-control custom-control-input" %}
                      <label class="custom-control-label small" for="donation_no_employer">
                        I do not have an employer
                      </label>
                    </div>
                  </div>
                </div>

                {% comment %}<!-- Existing employer field -->{% endcomment %}
                <div class="col-sm-12">
                  <div class="form-group">
                    <label for="donation_employer">Employer</label>
                    {% text_field "employer", class:"text form-control", required:"required" %}
                  </div>
                </div>

                {% comment %}<!-- Existing occupation field -->{% endcomment %}
                <div class="col-sm-12">
                  <div class="form-group">
                    <label for="donation_occupation">Occupation</label>
                    {% text_field "occupation", class:"text form-control", required:"required" %}
                  </div>
                </div>

                {% if page.donation_v2.merchant_account.is_employer_address_required? %}
                  <div class="col-sm-12">
                    <div class="form-group">
                      <label for="donation_work_address_country">Employer Country</label>{% collection_select "work_address.country_code", page.donation_v2.countries, "code", "name", class:"select", required:"required" %}
                    </div>
                  </div>
                  <div class="col-sm-12">
                    <div class="form-group">
                      <label for="donation_work_address_address1">Employer Address</label>
                      {% text_field "work_address.address1", class:"text form-control", required:"required" %}
                      {% text_field "work_address.address2", class:"text form-control" %}
                      {% text_field "work_address.address3", class:"text form-control work-not-us-or-canada hide" %}
                    </div>
                  </div>
                  <div class="col-sm-4">
                    <div class="form-group">
                      <label for="donation_work_address_city">Employer City</label>{% text_field "work_address.city", class:"text form-control", required:"required" %}
                    </div>
                  </div>
                  <div class="col-sm-5 work-us-or-canada">
                    <div class="form-group">
                      <label for="donation_work_address_state">State</label>{% text_field "work_address.state", class:"text form-control", required:"required" %}
                    </div>
                  </div>
                  <div class="col-sm-3">
                    <div class="form-group">
                      <label for="donation_work_address_zip">Postal code</label>{% text_field "work_address.zip", class:"text form-control", required:"required" %}
                    </div>
                  </div>
                {% elsif page.donation_v2.merchant_account.is_employer_city_required? %}
                  <div class="col-sm-12">
                    <div class="form-group">
                      <label for="donation_work_address_country">Employer Country</label>{% collection_select "work_address.country_code", page.donation_v2.countries, "code", "name", class:"select", required:"required" %}
                    </div>
                  </div>
                  <div class="col-sm-4">
                    <div class="form-group">
                      <label for="donation_work_address_city">Employer City</label>{% text_field "work_address.city", class:"text form-control", required:"required" %}
                    </div>
                  </div>
                  <div class="col-sm-5 work-us-or-canada hide">
                    <div class="form-group">
                      <label for="donation_work_address_state">State</label>{% text_field "work_address.state", class:"text form-control", required:"required" %}
                    </div>
                  </div>
                  <div class="col-sm-3">
                    <div class="form-group">
                      <label for="donation_work_address_zip">Postal code</label>{% text_field "work_address.zip", class:"text form-control", required:"required" %}
                    </div>
                  </div>
                {% endif %}
                <div class="col-sm-12">
                  <div class="form-group">
                    <div class="my-2">Law requires we ask for your employer and occupation. If you don't have an employer or are retired, put N/A, and if you are self-employed put "self-employed" in employer and describe your occupation.</div>
                  </div>
                </div>
              {% endif %}

              {% if page.donation_v2.merchant_account.is_corporate_contribution_required? %}
                <div class="col-sm-12 input-checkbox">
                  <div class="checkbox">
                    <label class="checkbox" for="donation_is_corporate_contribution">{% check_box "is_corporate_contribution", class:"checkbox" %} This is a contribution from a business.</label>
                  </div>
                </div>
              {% endif %}

              {% for cf in custom_fields.donation %}
                {% assign custom_field = cf[1] %}
                {% assign custom_field_id = 'custom_values.' | append: custom_field.slug %}
                  <div class="col-sm-12">
                    {% if custom_field.is_text? %}
                      <label for="donation_custom_values_{{ custom_field.slug }}_custom">{{ custom_field.name }}</label>
                      {% text_field custom_field_id, class:"text" %}
                    {% elsif custom_field.is_number? %}
                      <label for="donation_custom_values_{{ custom_field.slug }}_custom">{{ custom_field.name }}</label>
                      {% number_field custom_field_id, class:"text" %}
                    {% elsif custom_field.is_boolean? %}
                      <div class="checkbox">
                        <label class="checkbox" for="donation_custom_values_{{ custom_field.slug }}_custom">{% check_box custom_field_id, class:"checkbox" %} {{ custom_field.name }}</label>
                      </div>
                    {% elsif custom_field.is_multiple_choice? %}
                      <div class="form-group">
                        <label for="donation_custom_values_{{ custom_field.slug }}_custom">{{ custom_field.name }}</label>
                        {% collection_select custom_field_id, custom_fields.donation[custom_field.slug].multiple_choice_options, class:"select form-control" %}
                      </div>
                    {% endif %}
                  </div>
              {% endfor %}

              {% if page.donation_v2.merchant_account.is_taxable? %}
                <div class="col-sm-12 form-group">Contributions are <i>not</i> tax deductible.</div>
              {% else %}
                <div class="col-sm-12 form-group">Contributions are tax deductible.</div>
              {% endif %}
            </div>

            <div class="mt-3">
              <a href="#" class="progress-stage-button-next button btn btn-primary-action w-100 mb-2">Continue</a>
              <a href="#" class="progress-stage-button-prev btn btn-secondary-action w-100">Back</a>
            </div>
          </div><!-- .progress-stage-2 -->

          <div class="progress-stage stage-3" data-stageID="3">

            <div class="row">
              <div class="col-sm-12 donation-amount-container mb-3">
                <strong>Donation amount: <span class="donation-amount"></span></strong>
                <div class="donation-frequency"></div>
              </div>
            </div>

            <!-- Required for express checkout / direct debit -->
            <div id="submitted-payment-method" class="row">
              <div class="col-sm-12">
                <p>
                  Payment method information has been saved.
                  <button type="button"
                    class="btn btn-link change-submitted-payment-method d-block btn-primary-action mt-3">
                    Change payment method
                  </button>
                </p>
              </div>
            </div>

            <div id="cc-info" class="row">
              <div class="col-sm-12">
                <label>Payment details</label>
                <div class="card-field">
                  {% payment_field 'payments' %}
                </div>
              </div>
            </div>

            <div class="row pt-3">
              <div class="col-sm-12">
                {% if page.donation_v2.merchant_account.has_contribution_rules? %}
                  <label for="is_confirmation_text mt-4"><strong>Contribution rules</strong></label>
                  {{ page.donation_v2.merchant_account.contribution_rules }}
                  <div class="checkbox">
                    <label for="donation_is_confirmed" class="checkbox mt-2">{% check_box "is_confirmed", class:"checkbox" %} I confirm that the above statements are true and accurate.</label>
                  </div>
                {% endif %}
                {% comment %}<!-- NOTE: Do not comment this out - if anything just wrap in a "d-none" div to hide - as removing from the form makes it default to true - even though the checkbox defaults to unchecked. If you do this activity will be private and not accessible by feeds -->{% endcomment %}
                {% if site.ask_to_publish_to_stream? %}
                  <div class="custom-control custom-checkbox">
                    {% check_box "is_private", class:"form-control custom-control-input" %}
                    <label class="custom-control-label small" for="donation_is_private">Don't publish my donation on the website.</label>
                  </div>
                {% endif %}
              </div>
            </div>
            <div class="row">
              <div class="col-sm-12 submit-container">
                <div class="donation-v2-amount mt-3">
                  {% if request.current_order %}
                    <span>{{ page.donation_v2.ticket_purchase_total }}</span>
                  {% else %}
                    {% comment %}<!-- 14 Feb - adding "d-none" to hide -->{% endcomment %}
                    <span class="font-weight-bolder d-none">
                      {% if page.donation_v2.confirmation_amount %}
                        <span>Donation amount: </span>
                        <span>{{ page.donation_v2.currency_symbol }}</span><span class="nb_donation_v2_amount">{{ page.donation_v2.confirmation_amount }}</span>
                      {% else %}
                        <!--<span class="hidden">{{ page.donation_v2.currency_symbol }}</span><span class="nb_donation_v2_amount">Please select an amount</span>-->
                      {% endif %}

                      {% if page.donation_v2.interval_monthly? %}
                        <div class="nb_donation_v2_interval font-weight-bolder mt-2">
                          paid monthly
                        </div>
                      {% elsif page.donation_v2.interval_annual? %}
                        <div class="nb_donation_v2_interval font-weight-bolder mt-2">
                          paid annually
                        </div>
                      {% endif %}

                    </span>
                  {% endif %}
                </div>

                <div class="mt-3">
                  {% if request.current_order %}
                    {% submit_tag "Process payment", class:"submit-button btn-process-donation btn btn-primary-action w-100 mb-2" %}
                  {% else %}
                    {% submit_tag "Donate now", class:"submit-button btn-process-donation btn btn-primary-action w-100 mb-2" %}
                  {% endif %}
                  <a class="progress-stage-button-prev btn btn-secondary-action w-100" href="#">Back</a>
                </div>
              </div>
              <div class="form-submit"></div>
            </div>

          </div><!-- .progress-stage-3 -->
        </div><!-- .progress-stages -->
      </div><!-- .form -->
    </div><!-- .form-wrap -->

  {% endform_for %}


{% comment %}<!-- START - For Purpose staged donation form enhancement scripts 17 November 2025 -->{% endcomment %}
<script>
  document.addEventListener("DOMContentLoaded", initDonationFormUI);

  // Initialize donation form
  function initDonationFormUI() {
    initOtherAmountUI();
    toggleOtherInputVisibility();
    attachRadioListeners();
    attachScrollTriggerListeners();
    applyURLAmountPreset();
  }

  // Styling and placeholders
  function initOtherAmountUI() {
    const currencySymbol = document.querySelector(".currency-symbol");
    if (currencySymbol) {
      currencySymbol.textContent = "Other $";
      currencySymbol.id = "donation_amount_other_input_label";
    }

    const otherInput = document.getElementById("donation_amount_other_input");
    if (otherInput) {
      otherInput.placeholder = "0.00";
      otherInput.setAttribute("aria-labelledby", "donation_amount_other_input_label");
    }
  }

  // Show/hide the "Other" input container
  function toggleOtherInputVisibility() {
    const otherRadio = document.getElementById("donation_amount_other");
    const container = document.querySelector(".donation-other-input-container");

    if (!otherRadio || !container) return;

    if (otherRadio.checked) {
      container.classList.add("visible");
    } else {
      container.classList.remove("visible");
    }
  }

  // Smooth scroll to top of donation form
  function scrollToForm(triggerElement) {
    // Don’t scroll if the trigger was "other"
    if (triggerElement && triggerElement.id === "donation_amount_other") return;

    const form = document.querySelector(".donation_form");
    if (!form) return;

    setTimeout(() => {
      form.scrollIntoView({ behavior: "smooth", block: "start" });
    }, 20);
  }

  // Amount Radio button event listeners
  function attachRadioListeners() {
    const radios = document.querySelectorAll("input[name='donation[amount_option]']");
    radios.forEach(radio => {
      radio.addEventListener("change", () => {
        toggleOtherInputVisibility();
        scrollToForm(radio);
      });
    });
  }

  // Stage button event listeners
  function attachScrollTriggerListeners() {
    const triggers = document.querySelectorAll(
      ".progress-stage-button-next, .progress-stage-button-prev, .stage-count"
    );

    triggers.forEach(btn => {
      btn.addEventListener("click", scrollToForm);
    });
  }

  // Handle preset donation amount via querystring ( Ex: ?amount=50 )
  function applyURLAmountPreset() {
    const params = new URLSearchParams(window.location.search);
    const amount = params.get("amount");
    if (!amount) return;

    const radio = document.getElementById("donation_amount_" + amount);
    const label = document.querySelector(`label[for="donation_amount_${amount}"]`);

    if (radio) {
      radio.checked = true;
      toggleOtherInputVisibility();
    }

    if (label) {
      label.click(); // triggers your step progression logic
    }

    scrollToForm();
  }
</script>
{% comment %}<!-- END - For Purpose staged donation form enhancement scripts 17 November 2025 -->{% endcomment %}

<script>
  NB.payments.elementOptions = {
    style: {
      base: {
        fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
        fontSize: '16px'
      }
    }
  };
</script>

<script src="/assets/liquid/theme_donation_v2.js"></script>

4. _z_pages_show_donation_wide_form.html

Do a code-diff and compare - but should be a simple copy and paste.

Changes here likely aren't major - maybe just some class tweaks and adding in custom field via tag support.

NOTE: This template is for normal Donate pages - not v2 pages - which don't typically get used anymore. If your site uses normal Donate pages - please test thoroughly. This new donation page "Update" via NationBuilder only specifies v2 - I'm unsure if these new features will ever come to v1.

{% comment %}
<!--
  * For Purpose Custom Theme
  *
  * _z_pages_show_donation_wide_form.html
  *
  * Custom Donation Template
  *
  * - this is based on the Nationbulder staged donation kit:
  * https://support.nationbuilder.com/en/articles/2340987-implement-a-staged-donation-form-for-the-bootstrap-theme
  *
  *
-->
{% endcomment %}


  <h4 class="mb-4">Donate</h4>

  {% if page.donation.has_amount_goal? %}
    <p>Our goal is to raise {{ page.donation.amount_goal_format }}</p>
    <div class="mb-3">
      <div class="progress">
        <div class="progress-bar" role="progressbar" style="width: {{ page.donation.percent_of_amount_goal | times:100 }}%;" aria-valuenow="{{ page.donation.percent_of_amount_goal | times:100 }}" aria-valuemin="0" aria-valuemax="100"></div>
      </div>
    </div>

  {% elsif page.donation.has_donor_goal? %}

    <p>Our goal is to raise {{ page.donation.donor_goal }} donations</p>

    <div class="mb-3">
      <div class="progress">
        <div class="progress-bar" role="progressbar" style="width: {{ page.donation.percent_of_donor_goal | times:100 }}%;" aria-valuenow="{{ page.donation.percent_of_donor_goal | times:100 }}" aria-valuemin="0" aria-valuemax="100">
        </div>
      </div>
    </div>
  {% endif %}

  {% form_for donation %}
      <div class="form-wrap">
        <div class="form">

          {% if page.donation.has_merchant_account? == false %}
          <div class="mb-4">
            <span class="red"><strong>No bank account:</strong> This page will not work until you add a bank account</span>
          </div>
          {% elsif page.donation.merchant_account.is_test_mode? %}
          <div class="mb-4">
            <span class="red"><strong>Testing mode:</strong> Transactions will not be processed. Use your regular credit card to test, you will not actually be charged.</span>
          </div>
          {% endif %}

          <div class="row">
            <div class="col-sm-12">
              <div class="form-progress-indicator">
                <ul class="progress-indicator-stages clearfix">
                  <li class="progress-indicator-stage stage-1 active"><span class="stage-count"><span class="stage-count-inner">1</span></span></li>
                  <li class="progress-indicator-stage stage-2"><span class="stage-count"><span class="stage-count-inner">2</span></span></li>
                  <li class="progress-indicator-stage stage-3"><span class="stage-count"><span class="stage-count-inner">3</span></span></li>
                </ul>
              </div>
            </div>
          </div>

          <div class="panel-form-divider mt-3 mb-4"></div>

          <div class="progress-stages">
            <div class="progress-stage stage-1 active" data-stageID="1">
              {% if request.current_order %}
                {% for item in request.current_order.items %}
                  {% if item.num_time_periods and item.time_period_type %}
                    {{ item.quantity }} {{ item.name }} @ {{ item.amount }} - billed automatically every {{ item.num_time_periods }} {{item.time_period_type }}
                  {% else %}
                    {{ item.quantity }} {{ item.name }} @ {{ item.amount }}
                  {% endif %}
                {% endfor %}
                <a href="{{ page.donation.clear_order_url }}">Clear order</a>
              {% elsif page.donation.donation_frequency == "monthly" %}
                {% if page.donation.amount_in_cents != 0 %}
                  <div class="row">
                    <div class="col-sm-12 mb-2">Your credit card will be billed automatically every month</div>
                  </div>
                  <h4 class="mb-2">{{ page.donation.amount_formatted }}</h4>
                {% else %}
                  <div class="row">
                    <div class="col-sm-12 mb-2">Your credit card will be billed automatically every month</div>
                  </div>
                  <div class="radio-inline">{{ page.donation.form_amount_options }}</div>
                {% endif %}
              {% else %}
                {% if page.donation.max_installments > 1 %}
                  <label for="num_installments" class="mb-2">I want to pay the following in {% collection_select "num_installments", page.donation.installment_collection, class:"select" %} installments</label>
                {% endif %}
                {% if page.donation.amount_in_cents != 0 %}
                  <h4 class="mb-2">{{ page.donation.amount_formatted }}</h4>
                {% else %}
                  <div class="radio-inline mb-2">{{ page.donation.form_amount_options }}</div>
                {% endif %}
              {% endif %}

              <div class="mt-3"><a href="#" class="progress-stage-button-next button btn btn-primary-action w-100 mt-3">Continue</a></div>

            </div>{% comment %}<!-- .progress-stage-1 -->{% endcomment %}

            <div class="progress-stage stage-2" data-stageID="2">

              <div class="container">

                <div class="row">
                  <div class="col-sm-12 donation-amount-container mb-3">
                    <strong>Donation amount: <span class="donation-amount"></span></strong>
                  </div>
                </div>

                <div class="row">
                  <div class="col-sm-12"><div class="form-group">{% text_field "first_name", class:"form-control text", placeholder:"First name" %}</div></div>
                  <div class="col-sm-12"><div class="form-group">{% text_field "last_name", class:"form-control text", placeholder:"Last name" %}</div></div>
                </div>

                <div class="row">
                  <div class="col-sm-12">
                    <div class="form-group">
                      <label for="">Billing Address</label>
                      {% select_field "billing_address.country_code", page.donation.countries, "code", "name", class:"form-control select", placeholder:"Country" %}
                      {% comment %}<!-- collection_select "billing_address.country_code", page.donation.countries, "code", "name", class:"form-control select", placeholder:"Country" -->{% endcomment %}
                    </div>
                  </div>
                </div>

                <div class="row">
                  <div class="col-sm-12">
                      <div class="row">
                        <div class="col-sm-12">
                          <div class="form-group">
                            {% text_field "billing_address.address1", class:"form-control text validation-check", placeholder:"Address 1", required:"required" %}
                          </div>
                        </div>
                      </div>
                      <div class="row">
                        <div class="col-sm-12">
                          <div class="form-group">
                            {% text_field "billing_address.address2", class:"form-control text", placeholder:"Address 2" %}
                          </div>
                        </div>
                      </div>
                      <div class="row">
                        <div class="col-sm-12">
                          <div class="form-group">
                            {% text_field "billing_address.address3", class:"form-control text not-us-or-canada hide", placeholder:"Address 3" %}
                          </div>
                        </div>
                      </div>
                  </div>
                </div>

                <div class="row">
                  <div class="col-sm-12">
                    <div class="row">
                      <div class="col-sm-12">
                        <div class="form-group">
                          {% text_field "billing_address.city", class:"form-control text validation-check", placeholder:"City", required:"required" %}
                        </div>
                      </div>
                      <div class="col-sm-12 us-or-canada us-only hide">
                        <div class="form-group">
                          {% select_field "billing_address.state", page.donation.us_states, "code", "name", class:"form-control select", placeholder:"State" %}
                          {% comment %}<!-- collection_select "billing_address.state", page.donation.us_states, "code", "name", class:"form-control select", placeholder:"State" -->{% endcomment %}
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="col-sm-12">
                    <div class="row">
                      <div class="col-sm-12 us-or-canada canada-only hide">
                        <div class="form-group">
                          {% text_field "billing_address.state", class:"form-control text", placeholder:"State" %}
                        </div>
                      </div>
                      <div class="col-sm-12">
                        <div class="form-group">
                          {% text_field "billing_address.zip", class:"form-control text validation-check", placeholder:"Postal code", required:"required" %}
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                <div class="row">
                  <div class="col-sm-12">
                    <div class="form-group">{% email_field "email", class:"form-control text validation-check", placeholder:"Email", required:"required" %}</div>
                  </div>
                  <div class="col-sm-12">
                    <div class="form-group">
                      {% phone_field "billing_address.phone_number", class:"form-control text", placeholder:"Phone" %}
                    </div>
                  </div>
                </div>

                {% comment %}<!-- custom form field - specific tag -->{% endcomment %}
                {% assign page_tags_list = "#" %}
                {% for tag in page.tags %}
                  {% assign page_tags_list = "#" | append:tag.slug | append:"#" | append:page_tags_list %}
                {% endfor %}
                {% if page_tags_list contains "#custom_field_" %}
                  {% for tag in page.tags %}
                    {% if tag.slug contains "custom_field_" %}
                      {% assign custom_slug = tag.slug | split:"custom_field_" | last %}
                      {% include "z_tag_custom_field" %}
                    {% endif %}
                  {% endfor %}
                {% endif %}

                <div class="form-row">
                  <div class="form-group col-md-12">
                    <div class="custom-control custom-checkbox">
                      {% check_box "email_opt_in", class:"form-control custom-control-input" %}
                      <label class="custom-control-label small" for="donation_email_opt_in">Send me email updates</label>
                    </div>
                  </div>
                </div>

                {% if page.donation.merchant_account.is_employer_and_occupation_required? %}
                <h4 class="mb-2 mt-3">Employer Info</h4>
                <div class="row">
                  <div class="col-sm-12"><div class="form-group">{% text_field "employer", class:"form-control text", placeholder:"Employer" %}</div></div>
                  <div class="col-sm-12"><div class="form-group">{% text_field "occupation", class:"form-control text", placeholder:"Occupation" %}</div></div>
                </div>
                {% if page.donation.merchant_account.is_employer_address_required? %}
                <div class="row">
                  <div class="col-sm-12">
                    <div class="form-group">
                      {% select_field "work_address.country_code", page.donation.countries, "code", "name", class:"form-control select", placeholder:"Employer country" %}
                      {% comment %}<!-- collection_select "work_address.country_code", page.donation.countries, "code", "name", class:"form-control select", placeholder:"Employer country" --> {% endcomment %}
                    </div>
                  </div>
                </div>
                <div class="row">
                  <div class="col-sm-12">
                    <div class="form-group">
                      {% text_field "work_address.address1", class:"form-control text", placeholder:"Employer address 1" %}
                      {% text_field "work_address.address2", class:"form-control text", placeholder:"Employer address 2" %}
                      {% text_field "work_address.address3", class:"form-control text work-not-us-or-canada hide", placeholder:"Employer address 3" %}
                    </div>
                  </div>
                </div>
                <div class="row">
                  <div class="col-sm-12">
                    <div>
                      {% text_field "work_address.city", class:"form-control text", placeholder:"City" %}
                    </div>
                  </div>
                  <div class="col-sm-12 work-us-or-canada">
                    <div class="form-group">
                      {% text_field "work_address.state", class:"form-control text", placeholder:"State" %}
                    </div>
                  </div>
                  <div class="col-sm-12">
                    <div class="form-group">
                      {% text_field "work_address.zip", class:"form-control text", placeholder:"Postal code" %}
                    </div>
                  </div>
                </div>

                {% elsif page.donation.merchant_account.is_employer_city_required? %}
                <div class="row">
                  <div class="col-sm-12">
                    <div class="form-group">
                      {% select_field "work_address.country_code", page.donation.countries, "code", "name", class:"form-control select", placeholder:"Employer country" %}
                      {% comment %}<!-- collection_select "work_address.country_code", page.donation.countries, "code", "name", class:"form-control select", placeholder:"Employer country" -->{% endcomment %}
                    </div>
                  </div>
                </div>
                <div class="row">
                  <div class="col-sm-12">
                    <div class="form-group">
                      {% text_field "work_address.city", class:"form-control text", placeholder:"City" %}
                    </div>
                  </div>
                  <div class="col-sm-12 work-us-or-canada hide">
                    <div class="form-group">
                      {% text_field "work_address.state", class:"form-control text", placeholder:"State" %}
                    </div>
                  </div>
                  <div class="col-sm-12">
                    <div class="form-group">
                      {% text_field "work_address.zip", class:"form-control text", placeholder:"Postal code" %}
                    </div>
                  </div>
                </div>
                {% endif %}

                <div class="row">
                  <div class="col-sm-12">
                    <div class="form-group">
                      <div class="my-2">Law requires we ask for your employer and occupation. If you don't have an employer or are retired, put N/A, and if you are self-employed put "self-employed" in employer and describe your occupation.</div>
                    </div>
                  </div>
                </div>

                {% endif %}

                {% if page.donation.merchant_account.is_corporate_contribution_required? %}

                {% comment %}
                <!-- NOTE: the code below is untested so keeping the original here as backup-->
                  <!--
                    <div class="row">
                      <div class="col-sm-12 input-checkbox">
                        <div class="form-group">
                          <label for="donation_is_corporate_contribution">{% check_box "is_corporate_contribution", class:"form-control checkbox" %} This is a contribution from a business.</label>
                        </div>
                      </div>
                    </div>
                  -->
                {% endcomment %}
                <div class="form-row">
                  <div class="form-group col-md-12">
                    <div class="custom-control custom-checkbox">
                      {% check_box "is_corporate_contribution", class:"form-control custom-control-input" %}
                      <label class="custom-control-label" for="donation_is_corporate_contribution"> This is a contribution from a business.</label>
                    </div>
                  </div>
                </div>
                {% endif %}

              </div>

              {% for cf in custom_fields.donation %}
              {% assign custom_field = cf[1] %}
              {% assign custom_field_id = 'custom_values.' | append: custom_field.slug %}

              <div class="row custom-donation-field">
                <div class="col-sm-12">
                  <div class="form-group">
                    {% if custom_field.is_text? or custom_field.is_number? %}
                    {% text_field custom_field_id, class:"form-control text", placeholder:custom_field.name %}
                    {% elsif custom_field.is_boolean? %}
                    <label class="custom-control-label" for="donation_custom_values_{{ custom_field.slug }}_custom">{% check_box custom_field_id, class:"form-control custom-control-input" %} {{ custom_field.name }}</label>
                    {% elsif custom_field.is_multiple_choice? %}
                    <label for="donation_custom_values_{{ custom_field.slug }}_custom">{{ custom_field.name }}</label>
                    {% collection_select custom_field_id, custom_fields.donation[custom_field.slug].multiple_choice_options, class:"select" %}
                    {% endif %}
                  </div>
                </div>
              </div>
              {% endfor %}

              <div class="mt-3">
                <a href="#" class="progress-stage-button-next button btn btn-primary-action w-100 mb-2">Continue</a>
                <a href="#" class="progress-stage-button-prev btn btn-secondary-action w-100">Back</a>
              </div>

            </div>{% comment %}<!-- .progress-stage-2 -->{% endcomment %}

            <div class="progress-stage stage-3" data-stageID="3">

              <div class="row">
                <div class="col-sm-12 donation-amount-container mb-3">
                  <strong>Donation amount: <span class="donation-amount"></span></strong>
                </div>
              </div>
              {% if page.donation.has_merchant_account? and page.donation.merchant_account.is_paypal_express? == false %}
              <div class="row">
                <div class="col-sm-12">
                  <div class="form-group">
                    {% text_field "card_number", class:"form-control text", placeholder:"Credit card number" %}
                  </div>
                </div>
                <div class="col-sm-12 cc"><div class="form-group">{{ page.donation.merchant_account.accepted_card_icons }}</div></div>
              </div>

              <div class="row">
                <div class="col-sm-12"><div class="form-group"><label for="donation_card_expires_on">Expires</label>{{ page.donation.form_card_expires_on }}</div></div>
              </div>

              <div class="row">
                <div class="col-sm-12">
                  <div class="form-group">
                    {% text_field "card_verification", class:"form-control text", placeholder:"Security code" %}
                  </div>
                </div>
              </div>
              {% endif %}

              <div class="row">
                <div class="col-sm-12">
                  <div class="form-group">
                    {% if page.donation.merchant_account.has_contribution_rules? %}
                      <label for="is_confirmation_text"><strong>Contribution rules</strong></label>
                      {{ page.donation.merchant_account.contribution_rules }}
                      <label for="donation_is_confirmed" class="checkbox mt-3">{% check_box "is_confirmed", class:"form-control checkbox" %} I confirm that the above statements are true and accurate.</label>
                    {% endif %}

                    {% if page.donation.merchant_account.is_de? %}
                      <label for="donation_is_de_confirmed" class="checkbox">{% check_box "is_de_confirmed", class:"form-control checkbox" %}
                        I agree to the Democracy Engine
                        <a href="http://www.democracyengine.com/subscriber_tos" target="_new">Terms of Service</a>
                        and
                        <a href="http://www.democracyengine.com/subscriber_privacy_policy" target="_new">Privacy Policy</a>. You will not receive any emails from them, they just deliver your donation to us.
                      </label>
                    {% endif %}

                    {% comment %}<!-- NOTE: Do not comment this out - if anything just wrap in a "d-none" div to hide - as removing from the form makes it default to true - even though the checkbox defaults to unchecked. If you do this activity will be private and not accessible by feeds -->{% endcomment %}
                    {% if site.ask_to_publish_to_stream? %}
                      <div class="row">
                        <div class="form-group col-md-12">
                          <div class="custom-control custom-checkbox">
                            {% check_box "is_private", class:"form-control custom-control-input" %}
                            <label class="custom-control-label small" for="donation_is_private">Don't publish my donation on the website.</label>
                          </div>
                        </div>
                      </div>
                    {% endif %}
                  </div>

                  {% if page.donation.has_merchant_account? and page.donation.merchant_account.is_paypal_express? %}
                    <div class="mt-3">
                      {% submit_tag "Continue to Paypal", class:"success-button btn-primary-action w-100" %}
                      <div class="mt-4">{{ page.donation.merchant_account.accepted_card_icons }}</div>
                      <a class="progress-stage-button-prev btn btn-secondary-action w-100" href="#">Back</a>
                    </div>
                  {% else %}
                    <div class="row tax-info">
                      {% if page.donation.merchant_account.is_taxable? %}
                        <div class="col-sm-12 form-group">Contributions are <i>not</i> tax deductible.</div>
                      {% else %}
                        <div class="col-sm-12 form-group">Contributions are tax deductible.</div>
                      {% endif %}
                    </div>

                    <div class="mt-3">
                      {% submit_tag "Process Donation", class:"submit-button btn-process-donation btn btn-primary-action w-100 mb-2" %}
                      <a class="progress-stage-button-prev btn btn-secondary-action w-100" href="#">Back</a>
                    </div>
                  {% endif %}

                  <div class="form-errors">{% error_messages_for donation %}</div>

                </div>
              </div>

            </div>{% comment %}<!-- .progress-stage-3 -->{% endcomment %}

          </div>{% comment %}<!-- .progress-stages -->{% endcomment %}

        </div>{% comment %}<!-- .form -->{% endcomment %}

      </div>{% comment %}<!-- .form-wrap -->{% endcomment %}

      {% endform_for %}


{% comment %}
<!--
  NOTE: The script below will grab the "amount" passed through the querystring
  from the donate module and select it in the donation form on page load
-->
{% endcomment %}

<script>
  $(document).ready(function () {
    var amount = GetParameterValues('amount');

    if(typeof amount !== "undefined") {
      var amountInput = document.querySelector("[value='" + amount + "']");

      // check the input
      amountInput.checked = true;

      // click the label to advance
      $('[for=donation_amount_' + amount + ']').click();
    }

    function GetParameterValues(param) {
      var url = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
      for (var i = 0; i < url.length; i++) {
        var urlparam = url[i].split('=');
        if (urlparam[0] == param) {
          return urlparam[1];
        }
      }
    }
  });
</script>

5. _z_staged_donations.scss

Do a code-diff and compare - but should be a simple copy and paste.

You should be fine copying and pasting this one in easy - just note that there are some CSS variables at the top you may want to tweak based on your site's theme colors.

/*!
 *
 * For Purpose Custom Theme
 *
 * _z_staged_donations.scss
 *
 */

// ************************************* //
// ************ VARIABLES ************** //
// ************************************* //

$staged-donation-accent:         #ffc000 !default;
$staged-donation-accent-muted:   rgba(255, 192, 0, 0.5) !default;
$staged-donation-transition:     opacity 200ms ease !default;

// ************************************* //
// *********** STAGED PROGRESS ********* //
// ************************************* //

.progress-stages {
  background-color: unset !important;
  padding: unset !important;
}

.progress-indicator-stages {
  list-style-type: none;
  padding: 0 0 15px 0;
  margin: 0 auto;
  width: auto;
  text-align: center;

  li {
    display: inline-block;
    position: relative;
    margin-right: 32px;
    white-space: nowrap;
    width: 51px;

    &:after {
      content: " ";
      width: 42px;
      height: 0;
      border-bottom: unset !important;
      position: absolute;
      top: 45px;
      left: 47px;
    }

    &:last-child {
      margin-right: 0;
      &:after { display: none; }
    }

    .stage-label {
      font-size: 12px;
      font-weight: 600;
      position: relative;
      text-transform: uppercase;
    }

    &.stage-1 .stage-label { left: -1px; }
    &.stage-2 .stage-label { left: -8px; }
    &.stage-3 .stage-label { left: -3px; }

    .stage-count {
      position: relative;
      display: block;
      color: $white;
      width: 51px !important;
      height: 51px !important;
      text-align: center;
      background: none !important;
      border: none !important;
      border-radius: 99px;
    }

    &.active { background: unset !important; }

    .stage-count-inner {
      width: 51px !important;
      height: 51px !important;
      left: 0 !important;
      top: 0 !important;
      line-height: 51px !important;
      display: block;
      position: relative;
      background: none !important;
      border: 1px solid $white !important;
      border-radius: 99px;
    }

    &.seen .stage-count-inner {
      color: $gray-800 !important;
      background: $white !important;
      cursor: pointer;
    }

    &.completed .stage-count-inner {
      text-indent: 0 !important;
      color: $gray-800 !important;
      background: $staged-donation-accent-muted !important; // Extracted Variable
      cursor: pointer;

      &:before {
        color: $gray-800 !important;
        position: absolute;
        width: 39px;
        line-height: 39px;
        z-index: 20;
        opacity: 1;
        text-align: center;
        top: 0;
        left: 0px;
        font-size: 1.25em;
        cursor: pointer;
        text-indent: 0 !important;
      }
    }

    &.active .stage-count-inner {
      color: $gray-800 !important;
      background: $staged-donation-accent !important; // Extracted Variable
    }

    &.completed .stage-count {
      color: $gray-800 !important;
      cursor: pointer;
    }
  }
}

// ************************************* //
// *********** DONATION FORM *********** //
// ************************************* //

.donation-amount-container {
  margin-bottom: 1rem;
}

label[for='donation_amount_other'] {
  margin-left: 15px !important;
}

#donation_amount_other {
  width: 100% !important;
  margin-right: 15px !important;
  margin-left: 15px !important;
}

span.currency-symbol {
  border: none !important;
  background: none !important;
  padding: 0 0.5rem 0 0 !important;
}

#donation_amount_other_input {
  border-top-left-radius: 0.25rem;
  border-bottom-left-radius: 0.25rem;
}

.donation-v2-occurence-radio {
  fieldset {
    display: inline-flex;
    flex-direction: column !important;

    .custom-control.custom-radio.custom-control-inline {
      width: 100% !important;
    }
  }
}

.donation_form {
  .donation-v2-occurence-radio fieldset {
    display: flex;
    width: 100%;
  }

  .donation-other-input-container {
    margin-top: 1.5rem;
  }
}

/* Animated State */
.donation-other-input-container {
  overflow: hidden;
  opacity: 0;
  transition: $staged-donation-transition;

  &.visible {
    opacity: 1;
  }
}

#recaptcha-input {
  margin-bottom: 1rem;
}

6. pages_show_donation_v2_wide.html

Copy and paste. Here we are just replacing the commented out "old" un-modified NationBuilder code (used as a back-up / reference when tweaking our customized version) with the commented out "new" un-modified NationBuilder code.

{% comment %}
<!--
  * For Purpose Custom Theme
  *
  * This page redirects to a custom wide version of the template as the sidebar is not used in this theme.
  *
  * The original template can be restored by removing the include tag and comments below.
-->
{% endcomment %}
{% comment %}<!-- include "z_pages_show_donation_v2_wide" -->{% endcomment %}

{% comment %}<!-- check tags for single column override -->{% endcomment %}

{% assign page_layout_single_column = false %}
{% if page.tags_count > 0 %}
  {% for tag in page.tags %}
    {% if tag.slug == "page_layout_single_column" %}
      {% assign page_layout_single_column = true %}
    {% endif %}
  {% endfor %}
{% endif %}

{% if page_layout_single_column %}
  {% include "z_template_1_panel_layout" %}
{% else %}
  {% include "z_template_2_panel_layout" %}
{% endif %}

{% comment %}
<!--
<div id="content" class="container-fluid">
  <div class="row {% unless site.has_background_image? %}justify-content-center{% endunless %}">
    <div class="col-12 col-lg-6 bg-white p-0">
      <div class="container py-4 px-md-5" style="max-width:740px;">
        <div class="row">
          <div class="col">
            <a class="navbar-brand mb-4" href="/" style="max-width: 200px;">
              {% if site.has_meta_image? %}
              <img src="{{ site.meta_image_url }}" class="navbar-brand-img mw-100" alt="{{ site.name }}">
              {% else %}
              {{ site.name }}
              {% endif %}
            </a>
            {% if page.headline.size > 0 %}
            <h1>{{ page.headline }}</h1>
            {% endif %}

            < !-- Optional goals and page content section -- >
            {% if page.donation_v2.content.size > 0 %}
            {{ page.donation_v2.content }}
            {% endif %}

            {% if page.donation_v2.has_amount_goal? %}
            <div class="mb-3">
              {% include "progress"
              percent: page.donation_v2.percent_of_amount_goal,
              count: page.donations_count,
              amount: page.donations_amount_format,
              goal: page.donation_v2.amount_goal_format,
              label: "raised"
              %}
            </div>
            {% elsif page.donation_v2.has_donor_goal? %}
            <div class="mb-3">
              {% include "progress"
              percent: page.donation_v2.percent_of_donor_goal,
              count: page.donors_count,
              goal: page.donation_v2.donor_goal,
              label: "donors"
              %}
            </div>
            {% endif %}
            < !-- END goals and page content section -- >

            {% form_for donation %}
            <div class="form">
              <div class="form-errors">{% error_messages_for donation %}</div>

              {% if page.donation_v2.has_merchant_account? == false %}
              <p class="text-danger"><strong>No payment processor:</strong> This page will not work until you add a
                payment processor</p>
              {% elsif page.donation_v2.merchant_account.is_test_mode? %}
              <p class="text-danger"><strong>Testing mode:</strong> Transactions will not be processed. Use <u><a
                    href="https://stripe.com/docs/testing#cards" class="red">testing cards</a></u> only.</p>
              {% endif %}

              {% if request.current_order %}
              <div class="card my-4">
                <div class="card-body">
                  <h3>Your order</h3>
                  <ul class="ticket-list">
                    {% for item in request.current_order.items %}
                    <li>
                      {% if item.num_time_periods and item.time_period_type %}
                      {{ item.quantity }} {{ item.name }} @ {{ item.amount }} - billed automatically every {{
                      item.num_time_periods }} {{item.time_period_type }}
                      {% else %}
                      {{ item.quantity }} {{ item.name }} @ {{ item.amount }}
                      {% endif %}
                    </li>
                    {% endfor %}
                  </ul>
                </div>
                <div class="card-footer">
                  <a class="clear-order" href="{{ page.donation_v2.clear_order_url }}">Clear order</a>
                </div>
              </div>
              {% else %}
              <fieldset aria-labelledby="cc-disclaimer">
                <legend>Amount</legend>
                <div class="form-row flex-column">
                  {% if page.donation_v2.amount_in_cents != 0 %}
                  <div class="form-group col-md-8">
                    <p class="h2 single-amount mb-0">{{ page.donation_v2.amount_formatted }}</p>
                  </div>
                  {% else %}
                  <div class="form-group col-md-8">
                    <div class="donation-v2-amounts">
                      {{ page.donation_v2.form_amount_options }}
                    </div>
                  </div>
                  {% endif %}
                  <div
                    class="form-row align-items-center {% if page.donation_v2.accepts_variable_amounts? == false %}single-amount-any-frequency{% endif %}">
                    {% if page.donation_v2.accepts_variable_amounts? %}
                    <div class="form-group">
                      {{ page.donation_v2.amount_other }}
                    </div>
                    {% endif %}
                    {% if page.donation_v2.donation_frequency == "monthly" %}
                    <div class="form-group col card-monthly">
                      <span class="text-secondary">Paid monthly</span>
                    </div>
                    {% elsif page.donation_v2.donation_frequency == "annual" %}
                    <div class="form-group col card-monthly">
                      <span class="text-secondary">Paid annually</span>
                    </div>
                    {% endif %}
                  </div>
                </div>
              </fieldset>
              <div
                class="form-row align-items-center donation-v2-options {% if page.donation_v2.accepts_variable_amounts? == false %}single-amount-any-frequency{% endif %}">
                {% if page.donation_v2.show_frequency_radio_buttons? %}
                <div class="form-group col">
                  <div class="donation-v2-occurence-radio radio-inline clearfix">
                    {{ page.donation_v2.recurring_radio_buttons }}
                  </div>
                </div>
                {% endif %}
              </div>
              {% endif %}

              <div data-payment-disclaimer>
                <p id="cc-disclaimer">Please select or enter an amount</p>
              </div>

              <hr>

              < !-- StripeElement section-- >
              <div id="submitted-payment-method" class="row">
                <div class="col-sm-12">
                  <p>Payment method information has been saved. <button type="button"
                      class="btn btn-link change-submitted-payment-method">Change payment method</button></p>
                </div>
              </div>

              <div id="cc-info" class="row">
                <div class="col-sm-12">
                  <div class="form-group">
                    {% payment_field 'payments' %}
                  </div>
                </div>
              </div>

              <small id="apple-pay-notice">If you use Apple Pay, your confirmation prompt may refer to our payment
                processor, "NationBuilder"</small>
              < !-- END StripeElement section-- >

              < !-- Name and address section, employer and occupation section, corporate contribution section, custom fields section, taxable section -- >
              <fieldset>
                <legend>Your information</legend>
                <div class="row">
                  <div id="demographics-info">
                    <div class="form-row">
                      <div class="form-group col-md-6">
                        <label for="donation_first_name">First Name</label>
                        {% text_field "first_name", class: "form-control", required: "required" %}
                      </div>
                      <div class="form-group col-md-6">
                        <label for="donation_last_name">Last Name</label>
                        {% text_field "last_name", class: "form-control", required: "required" %}
                      </div>
                    </div>
                    <div class="form-group">
                      <label for="donation_email">Email</label>
                      {% email_field "email", class: "form-control", required: "required" %}
                    </div>
                    <div class="form-group">
                      <label for="donation_billing_address_phone_number">Phone</label>
                      {% phone_field "billing_address.phone_number", class:"form-control" %}
                    </div>
                  </div> < !-- /demographics-info -- >

                  <div id="address-info">
                    <div class="form-group">
                      <label for="donation_billing_address_country_code">Country</label>
                      {% select_field "billing_address.country_code", page.donation_v2.countries, "code", "name",
                      class:"form-control" %}
                    </div>
                    <div class="form-group">
                      <label for="donation_billing_address_address1">Billing Address</label>
                      {% text_field "billing_address.address1", class:"form-control" %}
                      {% text_field "billing_address.address2", class:"form-control mt-2 text" %}
                      {% text_field "billing_address.address3", class:"form-control mt-2 text not-us-or-canada hide" %}
                    </div>
                    <div class="form-row">
                      <div class="form-group col-md-4">
                        <label for="donation_billing_address_city">City</label>
                        {% text_field "billing_address.city", class:"form-control" %}
                      </div>
                      <div class="form-group col-md-4 us-or-canada us-only hide">
                        <label for="donation_state">State</label>
                        {% select_field "billing_address.state", page.donation_v2.us_states, "code", "name",
                        class:"form-control" %}
                      </div>
                      <div class="form-group col-md-4 us-or-canada canada-only hide">
                        <label for="donation_billing_address_state">State</label>
                        {% text_field "billing_address.state", class:"form-control" %}
                      </div>
                      <div class="form-group col-md-4">
                        <label for="donation_billing_address_zip">Postal code</label>
                        {% text_field "billing_address.zip", class:"form-control" %}
                      </div>
                    </div>
                  </div> < !-- /#address-info -- >

                  < !-- employer and occupation section -- >
                  {% if page.donation_v2.merchant_account.is_employer_and_occupation_required? %}
                  <div class="form-group w-100">
                    <div class="custom-control custom-checkbox">
                      {% check_box "no_employer", class:"custom-control-input checkbox" %}
                      <label class="custom-control-label" for="donation_no_employer">I do not have an employer</label>
                    </div>
                  </div>
                  <div class="form-row">
                    <div class="form-group col-md-6">
                      <label for="donation_employer">Employer</label>
                      {% text_field "employer", class:"form-control", required:"required" %}
                    </div>
                    <div class="form-group col-md-6">
                      <label for="donation_occupation">Occupation</label>
                      {% text_field "occupation", class:"form-control", required:"required" %}
                    </div>
                  </div>
                  {% if page.donation_v2.merchant_account.is_employer_address_required? %}
                  <div class="form-group">
                    <label for="donation_work_address_country">Employer Country</label>
                    {% select_field "work_address.country_code", page.donation_v2.countries, "code", "name",
                    class:"select", required:"required" %}
                  </div>
                  <div class="form-group">
                    <label for="donation_work_address_address1">Employer Address</label>
                    {% text_field "work_address.address1", class:"form-control", required:"required" %}
                    {% text_field "work_address.address2", class:"form-control mt-2" %}
                    {% text_field "work_address.address3", class:"form-control mt-2 work-not-us-or-canada hide" %}
                  </div>
                  <div class="form-group">
                    <label for="donation_work_address_city">Employer City</label>
                    {% text_field "work_address.city", class:"form-control", required:"required" %}
                  </div>
                  <div class="form-row">
                    <div class="form-group col-md-6 work-us-or-canada">
                      <label for="donation_work_address_state">State</label>
                      {% text_field "work_address.state", class:"form-control", required:"required" %}
                    </div>
                    <div class="form-group col-md-6">
                      <label for="donation_work_address_zip">Postal code</label>
                      {% text_field "work_address.zip", class:"form-control", required:"required" %}
                    </div>
                  </div>
                  {% elsif page.donation_v2.merchant_account.is_employer_city_required? %}
                  <div class="form-group">
                    <label for="donation_work_address_country">Employer Country</label>
                    {% select_field "work_address.country_code", page.donation_v2.countries, "code", "name",
                    class:"select", required:"required" %}
                  </div>
                  <div class="form-row">
                    <div class="form-group col-md-4">
                      <label for="donation_work_address_city">Employer City</label>
                      {% text_field "work_address.city", class:"form-control", required:"required" %}
                    </div>
                    <div class="form-group col-md-5 work-us-or-canada hide">
                      <label for="donation_work_address_state">State</label>
                      {% text_field "work_address.state", class:"form-control", required:"required" %}
                    </div>
                    <div class="form-group col-md-3">
                      <label for="donation_work_address_zip">Postal code</label>
                      {% text_field "work_address.zip", class:"form-control", required:"required" %}
                    </div>
                  </div>
                  {% endif %}
                  <div class="form-group">
                    <p class="text-secondary">
                      Law requires we ask for your employer and occupation. If you do not have an employer or are
                      retired, check "I do not have an employer". If you are self-employed put "self-employed" in
                      employer and describe your occupation.
                    </p>
                  </div>
                  {% endif %}
                  < !-- END employer and occupation section -- >

                  < !-- corporate contribution section -- >
                  {% if page.donation_v2.merchant_account.is_corporate_contribution_required? %}
                  <div class="form-group">
                    <div class="custom-control custom-checkbox">
                      {% check_box "is_corporate_contribution", class:"custom-control-input checkbox" %}
                      <label class="custom-control-label checkbox" for="donation_is_corporate_contribution">This is a
                        contribution from a business.</label>
                    </div>
                  </div>
                  {% endif %}
                  < !-- END corporate contribution section -- >

                  < !-- custom fields section -- >
                  {% for cf in custom_fields.donation %}
                  {% assign custom_field = cf[1] %}
                  {% assign custom_field_id = 'custom_values.' | append: custom_field.slug %}

                  <div class="form-group">
                    {% if custom_field.is_text? %}
                    <label for="donation_custom_values_{{ custom_field.slug }}_custom">{{ custom_field.name }}</label>
                    {% text_field custom_field_id, class:"form-control" %}
                    {% elsif custom_field.is_number? %}
                    <label for="donation_custom_values_{{ custom_field.slug }}_custom">{{ custom_field.name }}</label>
                    {% number_field custom_field_id, class:"form-control" %}
                    {% elsif custom_field.is_boolean? %}
                    <div class="custom-control custom-checkbox">
                      {% check_box custom_field_id, class:"custom-control-input checkbox" %}
                      <label class="custom-control-label checkbox"
                        for="donation_custom_values_{{ custom_field.slug }}_custom">{{ custom_field.name }}</label>
                    </div>
                    {% elsif custom_field.is_multiple_choice? %}
                    <label for="donation_custom_values_{{ custom_field.slug }}_custom">{{ custom_field.name }}</label>
                    {% select_field custom_field_id, custom_fields.donation[custom_field.slug].multiple_choice_options,
                    class:"select" %}
                    {% endif %}
                  </div>
                  {% endfor %}
                  < !-- END custom fields section -- >

                  < !-- taxable section -- >
                  <div class="form-group">
                    <span class="text-secondary">
                      {% if page.donation_v2.merchant_account.is_taxable? %}
                      Contributions are <i>not</i> tax deductible.
                      {% else %}
                      Contributions are tax deductible.
                      {% endif %}
                    </span>
                  </div>
                  < !-- END taxable section -- >
                </div> < !-- /.row -- >
              </fieldset>
              < !-- END name and address section, employer and occupation section, corporate contribution section, custom fields section, taxable fieldset -- >

              < !-- contribution rules and recaptcha section, total and form submit -- >
              <fieldset>
                <div class="form-group">
                  {% if page.donation_v2.merchant_account.has_contribution_rules? %}
                  <label for="is_confirmation_text"><strong>Contribution rules</strong></label>
                  {{ page.donation_v2.merchant_account.contribution_rules }}
                  <div class="custom-control custom-checkbox">
                    {% check_box "is_confirmed", class:"custom-control-input checkbox" %}
                    <label for="donation_is_confirmed" class="custom-control-label checkbox">I confirm that the above
                      statements are true and accurate.</label>
                  </div>
                  {% endif %}
                  {% unless page.show_consent_form? %}
                  <div class="form-group">
                    <div class="custom-control custom-checkbox">
                      {% check_box "email_opt_in", class:"custom-control-input" %}
                      <label class="custom-control-label" for="donation_email_opt_in">Send email updates</label>
                    </div>
                  </div>
                  {% endunless %}
                  {% if site.ask_to_publish_to_stream? and page.show_stream? %}
                  <div class="custom-control custom-checkbox">
                    {% check_box "is_private", class:"custom-control-input checkbox" %}
                    <label for="donation_is_private" class="custom-control-label checkbox">Don't publish my donation on
                      the website.</label>
                  </div>
                  {% endif %}
                </div>

                {% if page.show_consent_form? %}
                <hr>
                {% include "consent_form" %}
                {% endif %}
                <hr>

                <div id="recaptcha_checkbox"></div>

                <div class="form-group">
                  <div class="submit-container">
                    <div class="donation-v2-amount d-flex align-items-center my-4 text-success">
                      {% if request.current_order %}
                      <span class="h2 mb-0 mr-1">{{ page.donation_v2.ticket_purchase_total }}</span>
                      {% else %}
                      {% if page.donation_v2.confirmation_amount %}
                      <span class="pt-1 align-self-start">{{ page.donation_v2.currency_symbol }}</span>
                      <span class="nb_donation_v2_amount h2 mb-0 mr-1">{{ page.donation_v2.confirmation_amount }}</span>
                      {% else %}
                      <span class="hidden hide pt-1 align-self-start">{{ page.donation_v2.currency_symbol }}</span>
                      <span class="nb_donation_v2_amount h2 mb-0 mr-1"><strong class="h6 text-danger">Total will show
                          here after an amount has been selected</strong></span>
                      {% endif %}
                      {% if page.donation_v2.donation_frequency == "one-time" %}
                      {% elsif page.donation_v2.donation_frequency == "monthly" %}
                      <p class="text-muted nb_donation_v2_interval mb-0" data-placeholder="paid monthly">paid monthly
                      </p>
                      {% elsif page.donation_v2.donation_frequency == "annual" %}
                      <p class="text-muted nb_donation_v2_interval mb-0" data-placeholder="paid annually">paid annually
                      </p>
                      {% else %}
                      <p class="text-muted nb_donation_v2_interval mb-0" data-placeholder="paid monthly">{% if
                        page.donation_v2.interval_monthly? %}paid monthly{% endif %}</p>
                      <p class="text-muted nb_donation_v2_interval mb-0" data-placeholder="paid annually">{% if
                        page.donation_v2.interval_annual? %}paid annually{% endif %}</p>
                      {% endif %}
                      {% endif %}
                    </div>
                    <div class="mt-4">
                      {% if request.current_order %}
                      {% submit_tag "Process payment", class:"btn btn-primary btn-lg submit-button" %}
                      {% else %}
                      {% submit_tag "Donate now", class:"btn btn-primary btn-lg submit-button" %}
                      {% endif %}
                    </div>
                  </div>
                </div>
              </fieldset>
              < !-- END contribution rules and recaptcha section, total and form submit -- >
            </div> < !--/.form -- >
            {% endform_for %}
          </div> < !-- /.col -- >
        </div> < !-- /.row -- >
      </div>< !-- /.container -- >
      {% if site.has_background_image? %}
      <div class="row">
        <div class="col">
          {% include "footer" %}
        </div>
      </div>
      {% endif %}
    </div> < !--/.col -- >
  </div>< !-- /.row -- >
</div>< !--/.container-fluid -- >

{% unless site.has_background_image? %}
{% include "footer" %}
{% endunless %}

<script>
  NB.payments.elementOptions = {
    style: {
      base: {
        fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
        fontSize: '16px'
      }
    }
  };
</script>

<script src="/assets/liquid/theme_donation_v2.js"></script>

-->
{% endcomment %}

7. staged-donations.js

Copy and paste. Update will add in functionality to scroll-to-top when validation error occurs.

var StagedDonations = StagedDonations || {};

$(document).ready(function(){

  function isIOS() {
    return /iPhone|iPad|iPod/i.test(navigator.userAgent);
  }

  (function(){

    this.updateDonationAmount = function(amount) {
      var donation = this.formatDonationAmount(amount);
      $('.donation-amount').text(donation);
    }
    this.formatDonationAmount = function(amount) {
      var donation = Number(amount).toFixed(2);
      return '$' + donation.toString();
    }

    this.updateContainerHeight = function(height) {
      $('.progress-stages').animate({'min-height':height},300);
    }

    this.updateProgressIndicator = function(indicator, direction) {
      var current = indicator.find('.active');
      var next = current.next();
      var previous = current.prev();
      if (direction && current.next().length) { // direction = 0 if going backwards, 1 if going forwards
        current.addClass('completed').find('.stage-count-inner').addClass('icon-tick');
        current.removeClass('active');
        next.addClass('active');
        next.addClass('seen');
      } else if (!direction && current.prev().length) {
        current.removeClass('active');
        previous.addClass('active');
      } else {
        // do nothing
      }
    }

    this.updateProgressStages = function(stages, direction) {
      var ns = this;
      var current = stages.find('.active');
      var next = current.next();
      var previous = current.prev();
      if ($('.row-error input:invalid').length === 0 ) {
        $('.row-error').removeClass('row-error');
      }
      if (direction && current.next().length) { // direction = 0 if going backwards, 1 if going forwards
        current.hide('slide',{direction:'left',easing:'easeInBack'},300,function(){
          $(this).removeClass('active');
          current.next().show('slide',{direction:'left'},300,function(){$(this).addClass('active');});
        });
      } else if (!direction && current.prev().length) {
        current.hide('slide',{direction:'left',easing:'easeInBack'},function(){$(this).removeClass('active');
          current.prev().show('slide',{direction:'left'},300,function(){$(this).addClass('active');});
        });
      } else {
        // do nothing
      }
    }

    this.triggerAlert = function(alertMessage, insertBefore) {
      var message = '<div class="form-error">'+alertMessage+'</div>';
      if (insertBefore.prev().hasClass('form-error')) {
        return;
      }
      insertBefore.closest('.row').addClass('row-error');
      insertBefore.before(message);

      $([document.documentElement, document.body]).animate({
        scrollTop: $(".form-error").offset().top
      }, 500);
    }

    this.removeAlerts = function() {
      $('.form-error').remove();
      $('.error').each(function(){
        $(this).removeClass('error');
      });
    }

    this.validateEmail = function() {
      var email = $('#donation_email');
      var re = /\S+@\S+\.\S+/;
      if (re.test(email.val()) || email.siblings('.form-error').length) {
        return true;
      } else {
        email.removeClass('validation-check');
        this.triggerAlert(email.attr('placeholder') + ' is required', email);
        return false;
      }
    }

    this.validateRequiredFields = function(num) {
      var query = '.stage-' + num + ' :invalid';
      var validationNodes = document.querySelectorAll(query);
      for (var i = 0; i < validationNodes.length; i++) {
        validationNodes[i].classList.remove('validation-check');
        var $nodeId = "#"+validationNodes[i].id;
        if ($nodeId !== 'donation_email' || !isIOS()) {
          this.triggerAlert(validationNodes[i].placeholder + ' is required', $($nodeId));
        } else {
          this.validateEmail();
          $('#donation_email').keyup(this.validateEmail());
        }
        if (validationNodes.length - i === 1) {
          return false;
        }
      }
      return true;
    }


    this.validateDonations = function(currentStage) {
      var donationAmount = parseFloat($('#donation_amount_other').val());
      switch (currentStage) {
        case "1":
          if ((donationAmount < 0.01) && ($('.progress-stage input[type="radio"]:checked').length == 0)) {
            $('#donation_amount_other').addClass('error');
            this.triggerAlert("Invalid donation amount",$('#donation_amount_other'));
            return false;
          } else {
            return this.validateRequiredFields(1);
          }
          break;
        case "2":
          return this.validateRequiredFields(2);
          break;
        case "3":
          return this.validateRequiredFields(3);
          break;
        default:
          return true;
      }
    }

  }).apply(StagedDonations);

  if ($('.progress-indicator-stages').length) {

    var progressIndicator = $('.progress-indicator-stages');
    var progressStages = $('.progress-stages');

    // Stage indicator click functions
    $('.progress-indicator-stages .stage-count').each(function(){$(this).click(function(event){
      event.preventDefault();
      if (!$(this).parent().hasClass('active')) {
        if ($(this).parent().hasClass('completed') || $(this).parent().hasClass('seen')) {
          var clickedIndicatorStageClass = $.grep($(this).parent().attr("class").split(" "), function(v, i){
            return v.indexOf('stage-') === 0;
          }).join();
          var currentActiveIndicator = progressIndicator.find('.active');
          var desiredProgressStage = progressStages.children('.'+clickedIndicatorStageClass);
          var currentActiveStage = progressStages.find('.active');
          currentActiveIndicator.removeClass('active');
          $(this).parent().addClass('active');
          currentActiveStage.hide('slide',{direction:'left',easing:'easeInBack'},300,function(){
            $(this).removeClass('active');
            desiredProgressStage.show('slide',{direction:'left'},300,function(){$(this).addClass('active');});
          });
        }
      }
    });});

    // Amount populator
    $('.stage-1 label').on('click', function() {
      var donation = $(this).text();
      $('.donation-amount').text(donation);
    });
    $('#donation_amount_other').on('change', function() {
      var donation = $(this).val();
      StagedDonations.updateDonationAmount(donation);
    });

    // Enter keystroke
    // if enter on stages 1 and 2 updateProgressStages
    $('.stage-1 input, .stage-2 input').keypress(function(e){
      if ( e.which == 13 ) {
        e.preventDefault();
        var currentStage = $('.progress-stage.active').attr('data-stageid');
        var isValid = StagedDonations.validateDonations(currentStage);
        if (isValid) {
          StagedDonations.removeAlerts();
          StagedDonations.updateProgressIndicator(progressIndicator, 1);
          StagedDonations.updateProgressStages(progressStages, 1);
        } else {
          progressIndicator.find('.active').removeClass('completed').find('.stage-count-inner').removeClass('icon-tick');
          progressIndicator.find('.active').next().removeClass('seen');
        }
      }
     });

 		var validationSet = document.getElementsByClassName('validation-check');
    var mutationConfig = { attributes: true };

      var observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        var ariaInvalid = mutation.attributeName === 'aria-invalid';
        var validClass = mutation.target.classList.contains('user-success');
        if (ariaInvalid && validClass) {
          mutation.target.previousSibling.classList.add('form-pass');
        }
      });
    });

      // validationSet is a NodeList, therefore you must use a for loop
    for (var i = 0; i < validationSet.length; i++) {
      observer.observe(validationSet.item(i), mutationConfig);
    }


    // Prev and next stage actions on form
    $('.progress-stage-button-next').each(function(){$(this).click(function(event){
      event.preventDefault();
      StagedDonations.removeAlerts();
      var currentStage = $('.progress-stage.active').attr('data-stageid');
      var isValid = StagedDonations.validateDonations(currentStage);
      if (isValid) {
        StagedDonations.updateProgressIndicator(progressIndicator, 1);
        StagedDonations.updateProgressStages(progressStages, 1);
      } else {
        progressIndicator.find('.active').removeClass('completed').find('.stage-count-inner').removeClass('icon-tick');
        progressIndicator.find('.active').next().removeClass('seen');
      }
    });});

    $('.progress-stages .radio').each(function(){$(this).click(function(event){
      StagedDonations.updateProgressIndicator(progressIndicator, 1);
      StagedDonations.updateProgressStages(progressStages, 1);
    });});

    $('.progress-stage-button-prev').each(function(){$(this).click(function(event){
      event.preventDefault();
      StagedDonations.removeAlerts();
      StagedDonations.updateProgressIndicator(progressIndicator, 0);
      StagedDonations.updateProgressStages(progressStages, 0);
    });});

    progressStages.find('input[type="submit"]').click(function(event){
      progressIndicator.find('.active').addClass('completed').find('.stage-count-inner').addClass('icon-tick');
    });

  }

});

8. staged-donations-v2.js

Copy and paste. Update will add in functional for scroll-to-top when validation error occurs. There is also some logic in regards to showing selected "frequency" on second and third stages - but currently commented out.

4. Manually update specifc files

These pages - which vary greatly between sites - are too risky to just copy and paste the updated file. These must be manually reviewed and updated - luckily the changes are minor!

1. _z_theme.scss

Comment out this line towards the bottom of the file:

//@import "z_staged-donations"; // 11 November 2025 - style overrides for new donations

and add in this line around the same spot:

@import "z_template_2_panels";

Now add this line higher up in the file - just above the "module specific SASS files":

// overriding staged-donations.scss with our own stylings
@import "z_staged_donations";

2. theme.scss

Comment out these import statements (towards the top)

/*
 * Nationbuilder staged donations kit base styling
 */
 /*
@import "staged-donations";
@import "staged-donations-v2";

Paste in the following at the bottom - just above the @import 'z_theme';


/* reCaptcha
-----------------------------------------------*/
.grecaptcha-badge {
  z-index: 9994;
}

/* Express payment options
-----------------------------------------------*/
#payment-methods {
  display: none;
  .StripeElement {
    border: 0;
    padding: 0;
    box-shadow: none;
  }
}

#cc-request-button {
  padding-top: 1rem;
  button {
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 4px;
    width: 100%;
    height: 40px;
  }
}

#credit-card-icon {
  display: inline-block;
  background-image: url("/assets/icons/ic_creditcard.svg");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 32px 32px;
  width: 32px;
  height: 32px;
  margin-right: 0.5em;
}

#selected-payment-method {
  display: none;
  border-radius: 2px;
  text-align: center;
  div {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  p {
    font-size: 1em;
  }
  a {
    font-size: 1em;
  }
}

#payment-method-icon {
  display: inline-block;
  background-image: url("/assets/icons/ic_expresspay-other.svg");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 40px 24px;
  width: 40px;
  height: 24px;
  margin-right: 1em;
  &[data-type="apple_pay"] {
    background-image: url("/assets/icons/ic_applepay.svg");
  }
  &[data-type="google_pay"] {
    background-image: url("/assets/icons/ic_googlepay.svg");
  }
}

#submitted-payment-method,
#demographics-read-only,
#address-read-only,
#apple-pay-notice,
#your-info,
#cc-info {
  display: none;
}

#edit-demographics,
#edit-address {
  float: right;
}

.address-line {
  display: block;
}

@import "staged-donations";

5. Test in preview mode

Everything should be looking pretty good - you may need to tweak some of the variables for button and radio styling (default/hover/active states, color, background color, etc).
Compare the normal donate URL to the ?preview donate URL.

If styling still isn't right

If things still aren't looking good - you may need to check for other SCSS which is styling the donation code. For example - on UMedics - i saw that old code in _z_z_eric.scss was impacting the code. This would be the first place to look in any other sites.

Stuck?

Ask Eric for help as he wrote this. Feel free to add any useful notes here - cheers!

Future improvements

When time allows try and tidy up all these various styling changes - could be even better if we could isolate them to a single file - and extract out the SCSS variables and have them live with other ones for simpler customization.

Sites / Themes converted

To try and keep track of things here - when you convert a theme for a site - please add it to the list below: