Billing Overview

Billing

Invoices

DateDescriptionAmountStatusDownload
Team plan, annual (10 seats)$490.00PaidPDF, invoice from March 14, 2026
3 additional seats (prorated)$61.25PaidPDF, invoice from November 2, 2025
Team plan, annual (7 seats)$343.00RefundedPDF, invoice from March 14, 2025
@use 'sprucecss/scss/spruce' as *;

.billing-overview {
  @include layout-stack('m');

  &__title {
    font-size: font-size('h4');
  }

  &__cards {
    display: grid;
    gap: spacer('m');
    grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
  }

  &__card {
    background-color: color('surface');
    border: config('border-width-base', $display) solid color('border');
    border-radius: radius('lg');
    display: flex;
    flex-direction: column;
    gap: spacer('xs');
    padding: spacer('m');

    > p {
      margin: 0;
    }

    &--plan {
      border-color: color-alpha('primary', 0.4);
      box-shadow: inset 0 10px 0 color('primary');
    }
  }

  &__label {
    color: color('muted');
    font-size: config('font-size-sm', $typography);
    font-weight: 600;
  }

  &__plan {
    align-items: center;
    color: color('heading');
    display: flex;
    font-family: config('font-family-heading', $typography);
    font-size: font-size('h3');
    font-weight: config('font-weight-heading', $typography);
    gap: spacer('xs');

    .badge {
      font-family: config('font-family-base', $typography);
      font-size: config('font-size-sm', $typography);
    }
  }

  &__price strong {
    color: color('heading');
  }

  &__note {
    color: color('muted');
    font-size: config('font-size-sm', $typography);
  }

  &__method {
    align-items: center;
    display: flex;
    gap: spacer('s');

    p {
      display: flex;
      flex-direction: column;
      margin: 0;
    }
  }

  &__brand {
    align-items: center;
    background-color: hsl(232deg 70% 32%);
    block-size: 2rem;
    border-radius: radius('sm');
    color: hsl(0deg 0% 100%);
    display: flex;
    font-size: 0.75rem;
    font-style: italic;
    font-weight: 800;
    inline-size: 3rem;
    justify-content: center;
    letter-spacing: 0.04em;
  }

  &__number {
    color: color('heading');
    font-weight: 600;
  }

  &__actions {
    display: flex;
    flex-wrap: wrap;
    gap: spacer('xs');
    margin-block-start: auto;
    padding-block-start: spacer('xs');
  }

  &__history {
    @include layout-stack('s');
  }

  &__subtitle {
    font-size: font-size('h5');
  }

  &__table {
    font-size: config('font-size-sm', $typography);

    td {
      white-space: nowrap;
    }

    td:nth-child(3) {
      font-variant-numeric: tabular-nums;
    }

    td:last-child {
      text-align: end;
    }
  }
}
<section class="billing-overview" aria-labelledby="billing-overview-title">
    <h2 class="billing-overview__title" id="billing-overview-title">Billing</h2>
    <div class="billing-overview__cards">
        <article class="billing-overview__card billing-overview__card--plan" aria-labelledby="billing-plan-title">
            <p class="billing-overview__label" id="billing-plan-title">Current plan</p>
            <p class="billing-overview__plan">Team <span class="badge badge--primary">Annual</span></p>
            <p class="billing-overview__price"><strong>$490</strong> per year · 10 seats</p>
            <p class="billing-overview__note">Renews on <time datetime="2027-03-14">March 14, 2027</time></p>
            <div class="billing-overview__actions">
                <a class="btn btn--primary btn--sm" href="#">Change plan</a>
                <a class="btn btn--ghost-primary btn--sm" href="#">Cancel subscription</a>
            </div>
        </article>
        <article class="billing-overview__card" aria-labelledby="billing-payment-title">
            <p class="billing-overview__label" id="billing-payment-title">Payment method</p>
            <div class="billing-overview__method">
                <span class="billing-overview__brand" aria-hidden="true">VISA</span>
                <p><span class="billing-overview__number">Visa ending in 4242</span> <span class="billing-overview__note">Expires 08/2028</span></p>
            </div>
            <p class="billing-overview__note">Invoices go to <strong>billing@acme.com</strong></p>
            <div class="billing-overview__actions">
                <a class="btn btn--secondary btn--sm" href="#">Update card</a>
                <a class="btn btn--ghost-primary btn--sm" href="#">Edit billing details</a>
            </div>
        </article>
    </div>
    <div class="billing-overview__history">
        <h3 class="billing-overview__subtitle">Invoices</h3>
        <div class="table-responsive">
            <table class="table billing-overview__table">
                <thead>
                    <tr>
                        <th scope="col">Date</th>
                        <th scope="col">Description</th>
                        <th scope="col">Amount</th>
                        <th scope="col">Status</th>
                        <th scope="col"><span class="sr-only">Download</span></th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td><time datetime="2026-03-14">Mar 14, 2026</time></td>
                        <td>Team plan, annual (10 seats)</td>
                        <td>$490.00</td>
                        <td><span class="badge badge--success">Paid</span></td>
                        <td><a href="#">PDF<span class="sr-only">, invoice from March 14, 2026</span></a></td>
                    </tr>
                    <tr>
                        <td><time datetime="2025-11-02">Nov 2, 2025</time></td>
                        <td>3 additional seats (prorated)</td>
                        <td>$61.25</td>
                        <td><span class="badge badge--success">Paid</span></td>
                        <td><a href="#">PDF<span class="sr-only">, invoice from November 2, 2025</span></a></td>
                    </tr>
                    <tr>
                        <td><time datetime="2025-03-14">Mar 14, 2025</time></td>
                        <td>Team plan, annual (7 seats)</td>
                        <td>$343.00</td>
                        <td><span class="badge badge--warning">Refunded</span></td>
                        <td><a href="#">PDF<span class="sr-only">, invoice from March 14, 2025</span></a></td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</section>

Billing Overview

The billing page of an account: the current plan and its renewal, the payment method and the invoice history.

Anatomy

  • .billing-overview__cards: the __card--plan (plan, price, renewal date and actions) and the payment method __card.
  • .billing-overview__history: the invoices in a .table with a status Badge and a download link.

Accessibility and Usability

  • Every card is an article labeled by its own label (aria-labelledby), so the regions have names.
  • The download links all say "PDF" visually, so each has hidden text with the date ("PDF, invoice from March 14, 2026"); a list of identical link names is useless out of context.
  • The status badges are words (Paid, Refunded), not only colors.
  • The renewal date is a time element with a machine-readable datetime.

Technical Details

  • The cards fill the row with an auto-fit grid (18rem minimum); their actions are pushed to the bottom (margin-block-start: auto), so the buttons line up.
  • The card brand mark is a placeholder; use the card network's logo from your payment provider.
  • The table scrolls inside .table-responsive on small screens.

Documentation

Learn about Spruce CSS through our extensive documentation.

Components

Explore our UI library of accessible components built with Spruce CSS.

Blocks and Pages

Full-width page blocks and complete page templates, ready to copy.

Find us on GitHub

Did you find a bug? Have an idea or a question? Please open an issue to help us develop the project.