Dashboard

Analytics for growing stores

See what sells, and why

Revenue, conversion and the whole funnel in one calm dashboard. Connect your store in two minutes.

14 days free · No credit card

@use 'sprucecss/scss/spruce' as *;

.hero-dashboard-block {
  background-image: radial-gradient(ellipse at 50% 0%, #{color-alpha('primary', 0.14)}, transparent 60%);
  overflow: hidden;
  padding-block: spacer-clamp('xl', 'xxl') 0;

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

  &__content {
    align-items: center;
    display: flex;
    flex-direction: column;
    gap: spacer('m');
    margin-inline: auto;
    max-inline-size: 46rem;
    text-align: center;

    > * {
      margin: 0;
    }
  }

  &__eyebrow {
    background-color: color-alpha('primary', 0.12);
    border-radius: radius('pill');
    color: color('primary');
    font-size: config('font-size-sm', $typography);
    font-weight: 700;
    padding: spacer('xxs') spacer('s');
  }

  &__title {
    font-size: responsive-font-size(4rem, 40, '5vw + 1rem');
    letter-spacing: -0.03em;
  }

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

  &__actions {
    display: flex;
    flex-wrap: wrap;
    gap: spacer('xs');
    justify-content: center;
  }

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

  // A browser window cut off at the bottom edge of the block.
  &__frame {
    background-color: color('surface');
    border: config('border-width-base', $display) solid color('border');
    border-block-end: 0;
    border-start-end-radius: radius('lg');
    border-start-start-radius: radius('lg');
    box-shadow: shadow('xl');
    inline-size: 100%;
    margin-inline: auto;
    max-block-size: 34rem;
    max-inline-size: 64rem;
    overflow: hidden;
    position: relative;
    user-select: none;

    // Fade the bottom into the page.
    &::after {
      background-image: linear-gradient(to top, #{color('background')}, transparent);
      block-size: 6rem;
      content: '';
      inset-block-end: 0;
      inset-inline: 0;
      position: absolute;
    }
  }

  &__bar {
    align-items: center;
    background-color: color('surface-muted');
    border-block-end: config('border-width-base', $display) solid color('border');
    display: flex;
    gap: spacer('s');
    padding: spacer('xs') spacer('s');
  }

  &__dots {
    display: flex;
    gap: 6px;

    span {
      background-color: color('border-strong');
      block-size: 0.65rem;
      border-radius: radius('pill');
      inline-size: 0.65rem;
    }
  }

  &__url {
    background-color: color('background');
    border-radius: radius('sm');
    color: color('muted');
    flex: 0 1 22rem;
    font-size: 0.75rem;
    margin-inline: auto;
    overflow: hidden;
    padding: 2px spacer('s');
    text-align: center;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  &__screen {
    display: grid;
    gap: spacer('m');
    padding: spacer('m');

    > * {
      margin: 0 !important;
    }
  }
}
<section class="hero-dashboard-block" aria-labelledby="hero-dashboard-title">
    <div class="container">
        <div class="hero-dashboard-block__inner">
            <div class="hero-dashboard-block__content">
                <p class="hero-dashboard-block__eyebrow">Analytics for growing stores</p>
                <h1 class="hero-dashboard-block__title" id="hero-dashboard-title">See what sells, and why</h1>
                <p class="hero-dashboard-block__lead">Revenue, conversion and the whole funnel in one calm dashboard. Connect your store in two minutes.</p>
                <div class="hero-dashboard-block__actions">
                    <a class="btn btn--primary btn--lg" href="#">Start free trial</a>
                    <a class="btn btn--secondary btn--lg" href="#">Book a demo</a>
                </div>
                <p class="hero-dashboard-block__note">14 days free · No credit card</p>
            </div><div class="hero-dashboard-block__frame" aria-hidden="true" inert>
                <div class="hero-dashboard-block__bar">
                    <span class="hero-dashboard-block__dots"><span></span><span></span><span></span></span>
                    <span class="hero-dashboard-block__url">app.example.com/overview</span>
                </div>
                <div class="hero-dashboard-block__screen">
                    <section class="metric-grid" aria-labelledby="metric-grid-title">
                        <header class="metric-grid__header">
                            <h2 class="metric-grid__title" id="metric-grid-title">Overview</h2>
                            <p class="metric-grid__period">Last 30 days</p>
                        </header>
                        <ul class="metric-grid__list" role="list">
                            <li class="metric-grid__item metric-grid__item--good">
                                <p class="metric-grid__label">Revenue</p>
                                <p class="metric-grid__value">$48,290</p>
                                <p class="metric-grid__delta">
                                    <svg class="metric-grid__arrow metric-grid__arrow--up" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 19V5"/><path d="m5 12 7-7 7 7"/></svg>
                                    <span><span class="sr-only">Up </span>12.4%</span>
                                    <span class="metric-grid__compare">vs. previous period</span>
                                </p>
                                <svg class="metric-grid__sparkline" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true" focusable="false">
                                    <polyline points="0,68 9.09,60 18.18,64 27.27,52 36.36,56 45.45,44 54.55,48 63.64,36 72.73,40 81.82,28 90.91,30 100,16"/>
                                </svg>
                            </li>
                            <li class="metric-grid__item metric-grid__item--good">
                                <p class="metric-grid__label">Orders</p>
                                <p class="metric-grid__value">1,284</p>
                                <p class="metric-grid__delta">
                                    <svg class="metric-grid__arrow metric-grid__arrow--up" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 19V5"/><path d="m5 12 7-7 7 7"/></svg>
                                    <span><span class="sr-only">Up </span>8.1%</span>
                                    <span class="metric-grid__compare">vs. previous period</span>
                                </p>
                                <svg class="metric-grid__sparkline" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true" focusable="false">
                                    <polyline points="0,60 9.09,56 18.18,62 27.27,50 36.36,54 45.45,48 54.55,42 63.64,46 72.73,38 81.82,40 90.91,34 100,30"/>
                                </svg>
                            </li>
                            <li class="metric-grid__item metric-grid__item--bad">
                                <p class="metric-grid__label">Conversion rate</p>
                                <p class="metric-grid__value">3.2%</p>
                                <p class="metric-grid__delta">
                                    <svg class="metric-grid__arrow metric-grid__arrow--down" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 19V5"/><path d="m5 12 7-7 7 7"/></svg>
                                    <span><span class="sr-only">Down </span>0.4 pt</span>
                                    <span class="metric-grid__compare">vs. previous period</span>
                                </p>
                                <svg class="metric-grid__sparkline" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true" focusable="false">
                                    <polyline points="0,30 9.09,34 18.18,32 27.27,40 36.36,38 45.45,42 54.55,46 63.64,44 72.73,50 81.82,48 90.91,52 100,54"/>
                                </svg>
                            </li>
                            <li class="metric-grid__item metric-grid__item--good">
                                <p class="metric-grid__label">Refunds</p>
                                <p class="metric-grid__value">23</p>
                                <p class="metric-grid__delta">
                                    <svg class="metric-grid__arrow metric-grid__arrow--down" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M12 19V5"/><path d="m5 12 7-7 7 7"/></svg>
                                    <span><span class="sr-only">Down </span>18%</span>
                                    <span class="metric-grid__compare">vs. previous period</span>
                                </p>
                                <svg class="metric-grid__sparkline" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true" focusable="false">
                                    <polyline points="0,36 9.09,40 18.18,34 27.27,48 36.36,44 45.45,52 54.55,50 63.64,58 72.73,54 81.82,62 90.91,64 100,70"/>
                                </svg>
                            </li>
                        </ul>
                    </section>
                    <figure class="funnel-chart" aria-labelledby="funnel-chart-title">
                        <figcaption class="funnel-chart__header">
                            <span class="funnel-chart__title" id="funnel-chart-title">Checkout funnel</span>
                            <span class="funnel-chart__period">This week</span>
                        </figcaption>
                        <ol class="funnel-chart__steps">
                            <li class="funnel-chart__step" style="--value: 100%;">
                                <span class="funnel-chart__label">Visited the store</span>
                                <span class="funnel-chart__bar" aria-hidden="true"></span>
                                <span class="funnel-chart__numbers"><strong>24,810</strong> <span>100%</span></span>
                            </li>
                            <li class="funnel-chart__step" style="--value: 62%;">
                                <span class="funnel-chart__label">Viewed a product</span>
                                <span class="funnel-chart__bar" aria-hidden="true"></span>
                                <span class="funnel-chart__numbers"><strong>15,382</strong> <span>62%</span></span>
                                <span class="funnel-chart__drop">38% drop-off from the previous step</span>
                            </li>
                            <li class="funnel-chart__step" style="--value: 24%;">
                                <span class="funnel-chart__label">Added to cart</span>
                                <span class="funnel-chart__bar" aria-hidden="true"></span>
                                <span class="funnel-chart__numbers"><strong>5,954</strong> <span>24%</span></span>
                                <span class="funnel-chart__drop">61% drop-off from the previous step</span>
                            </li>
                            <li class="funnel-chart__step" style="--value: 11%;">
                                <span class="funnel-chart__label">Started checkout</span>
                                <span class="funnel-chart__bar" aria-hidden="true"></span>
                                <span class="funnel-chart__numbers"><strong>2,729</strong> <span>11%</span></span>
                                <span class="funnel-chart__drop">54% drop-off from the previous step</span>
                            </li>
                            <li class="funnel-chart__step" style="--value: 5.2%;">
                                <span class="funnel-chart__label">Purchased</span>
                                <span class="funnel-chart__bar" aria-hidden="true"></span>
                                <span class="funnel-chart__numbers"><strong>1,290</strong> <span>5.2%</span></span>
                                <span class="funnel-chart__drop">53% drop-off from the previous step</span>
                            </li>
                        </ol>
                    </figure>
                </div>
            </div>
        </div>
    </div>
</section>

Dashboard

On this page

A product hero for a SaaS: the headline and the calls to action above a browser window that shows the real dashboard, built from live components instead of a screenshot.

Technical Details

  • It combines the Metric Grid and the Funnel Chart inside a browser frame. Because they're real components, the preview follows the dark mode and every design style, and it's sharp on every screen.
  • The preview is a picture of the product, not part of the page content: the frame is aria-hidden="true" and inert, so screen readers skip it and its links can't be focused. The headline and the lead describe the product instead.
  • The frame is cut off at the bottom of the block (a maximum height and a fade into the background), so it works as a teaser of a longer screen.
  • The title is the page's h1; use this block once, at the top.
  • Override the copy with heroDashboardBlock, and the preview data with metricGrid and funnelChart objects.

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.