Offer

What you get

Two ways to learn, one bundle

Read at your own pace, then watch every technique built from scratch.

  • The book

    Modern CSS, Explained

    Value: $49

    A practical guide from the cascade to a complete design system.

    pages
    380
    chapters
    14
    code samples
    120
    • PDF, EPUB and Kindle
    • Copy-paste code samples
    • Free updates for every edition

    See the chapters

  • The video course

    Modern CSS, Built

    Value: $149

    Watch every technique from the book built in real projects.

    lessons
    64
    of video
    12 h
    projects
    6
    • 4K video with subtitles
    • Source code for every lesson
    • Watch online or download

    Browse the lessons

Together Regular price: $198 Bundle price: $129

Get both in the Complete bundle and save $69.

See the bundles
@use 'sprucecss/scss/spruce' as *;

.offer-block {
  padding-block: spacer-clamp('xl', 'xxl');

  &__inner {
    display: flex;
    flex-direction: column;
    gap: spacer('l');
  }

  &__items {
    display: grid;
    gap: spacer('m');
    list-style: none;
    margin: 0;
    padding: 0;

    @include breakpoint('md') {
      grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    // The items sit side by side: clear the stack margins of the base list style.
    > li {
      margin-block: 0;
    }
  }

  &__item {
    background-color: color('surface');
    border: config('border-width-base', $display) solid color('border');
    border-radius: radius('lg');
    box-shadow: shadow('sm');
    padding: spacer-clamp('m', 'l');
    @include layout-stack('m');
  }

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

  &__icon {
    align-items: center;
    background-color: color-alpha('primary', 0.12);
    block-size: 3rem;
    border-radius: radius('md');
    color: color('primary');
    display: flex;
    flex-shrink: 0;
    inline-size: 3rem;
    justify-content: center;

    .block-icon {
      block-size: 1.5rem;
      inline-size: 1.5rem;
    }
  }

  &__heading {
    flex-grow: 1;
    @include layout-stack('xxs'); // kicker, title
  }

  &__kicker {
    color: color('primary');
    font-size: config('font-size-sm', $typography);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }

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

  &__value {
    color: color('muted');
    font-weight: 700;
    margin-block: 0;
  }

  &__text {
    color: color('muted');
  }

  &__facts {
    border-block: config('border-width-base', $display) solid color('border');
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    padding-block: spacer('s');
  }

  &__fact {
    display: flex;
    flex-direction: column-reverse;

    dt {
      color: color('muted');
      font-size: config('font-size-sm', $typography);
      font-weight: 400;
    }

    dd {
      color: color('heading');
      font-family: config('font-family-heading', $typography);
      font-size: font-size('h3');
      font-weight: config('font-weight-heading', $typography);
      line-height: 1.2;
      margin: 0;
    }
  }

  &__features {
    list-style: none;
    padding: 0;
    @include layout-stack('xs');

    li {
      align-items: center;
      display: flex;
      gap: spacer('xs');
    }

    .block-icon {
      block-size: 1rem;
      color: color('primary');
      flex-shrink: 0;
      inline-size: 1rem;
    }
  }

  &__more a {
    font-weight: 700;
  }

  &__total {
    align-items: center;
    background-color: color-alpha('primary', 0.08);
    border: config('border-width-base', $display) dashed color('primary');
    border-radius: radius('lg');
    display: flex;
    flex-wrap: wrap;
    gap: spacer('s') spacer('m');
    padding: spacer('m') spacer-clamp('m', 'l');
  }

  &__sum {
    align-items: baseline;
    color: color('heading');
    display: flex;
    font-weight: 700;
    gap: spacer('xs');
    margin-block: 0;

    del {
      color: color('muted');
      font-weight: 400;
    }

    strong {
      font-family: config('font-family-heading', $typography);
      font-size: font-size('h3');
    }
  }

  &__save {
    color: color('muted');
    flex-grow: 1;
    margin-block: 0;
  }
}
<section class="offer-block" aria-labelledby="offer-title">
    <div class="container">
        <div class="offer-block__inner">
            <header class="block-heading">
                <p class="block-heading__eyebrow">What you get</p>
                <h2 class="block-heading__title" id="offer-title">Two ways to learn, one bundle</h2>
                <p class="block-heading__text">Read at your own pace, then watch every technique built from scratch.</p>
            </header>
            <ul class="offer-block__items" role="list">
                <li class="offer-block__item">
                    <div class="offer-block__header">
                        <span class="offer-block__icon" aria-hidden="true"><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20V2H6.5A2.5 2.5 0 0 0 4 4.5v15z"/><path d="M4 19.5A2.5 2.5 0 0 0 6.5 22H20v-5"/>
</svg>
</span>
                        <div class="offer-block__heading">
                            <p class="offer-block__kicker">The book</p>
                            <h3 class="offer-block__title">Modern CSS, Explained</h3>
                        </div>
                        <p class="offer-block__value"><span class="sr-only">Value: </span>$49</p>
                    </div>
                    <p class="offer-block__text">A practical guide from the cascade to a complete design system.</p>
                    <dl class="offer-block__facts">
                        <div class="offer-block__fact">
                            <dt>pages</dt>
                            <dd>380</dd>
                        </div>
                        <div class="offer-block__fact">
                            <dt>chapters</dt>
                            <dd>14</dd>
                        </div>
                        <div class="offer-block__fact">
                            <dt>code samples</dt>
                            <dd>120</dd>
                        </div>
                    </dl>
                    <ul class="offer-block__features" role="list">
                        <li><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5"/>
</svg>
 PDF, EPUB and Kindle</li>
                        <li><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5"/>
</svg>
 Copy-paste code samples</li>
                        <li><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5"/>
</svg>
 Free updates for every edition</li>
                    </ul>
                    <p class="offer-block__more"><a href="#book-preview">See the chapters</a></p>
                </li>
                <li class="offer-block__item">
                    <div class="offer-block__header">
                        <span class="offer-block__icon" aria-hidden="true"><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="m22 8-6 4 6 4V8z"/><rect width="14" height="12" x="2" y="6" rx="2"/>
</svg>
</span>
                        <div class="offer-block__heading">
                            <p class="offer-block__kicker">The video course</p>
                            <h3 class="offer-block__title">Modern CSS, Built</h3>
                        </div>
                        <p class="offer-block__value"><span class="sr-only">Value: </span>$149</p>
                    </div>
                    <p class="offer-block__text">Watch every technique from the book built in real projects.</p>
                    <dl class="offer-block__facts">
                        <div class="offer-block__fact">
                            <dt>lessons</dt>
                            <dd>64</dd>
                        </div>
                        <div class="offer-block__fact">
                            <dt>of video</dt>
                            <dd>12 h</dd>
                        </div>
                        <div class="offer-block__fact">
                            <dt>projects</dt>
                            <dd>6</dd>
                        </div>
                    </dl>
                    <ul class="offer-block__features" role="list">
                        <li><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5"/>
</svg>
 4K video with subtitles</li>
                        <li><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5"/>
</svg>
 Source code for every lesson</li>
                        <li><svg class="block-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
<path d="M20 6 9 17l-5-5"/>
</svg>
 Watch online or download</li>
                    </ul>
                    <p class="offer-block__more"><a href="#video-library">Browse the lessons</a></p>
                </li>
            </ul>
            <div class="offer-block__total">
                <p class="offer-block__sum">
                    Together
                    <del><span class="sr-only">Regular price: </span>$198</del>
                    <strong><span class="sr-only">Bundle price: </span>$129</strong>
                </p>
                <p class="offer-block__save">Get both in the Complete bundle and save $69.</p>
                <a class="btn btn--primary" href="#pricing">See the bundles</a>
            </div>
        </div>
    </div>
</section>

Offer

On this page

The offer of a product bundle at a glance: one card per product (a book, a video course) with its key numbers, what's included and its value, then the bundle price that adds them up.

Technical Details

  • Every product is a list item with an h3; the key numbers are a description list (dt label, dd value) shown value first with column-reverse, so they're read in a natural order.
  • The regular and the bundle price have hidden "Regular price" and "Bundle price" labels, because a strikethrough isn't announced.
  • The links jump to the sections that go deeper (the chapters, the lessons) and the button to the pricing (#pricing).
  • Override the content with offerBlock.

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.