@use 'sprucecss/scss/spruce' as *;
.metric-grid {
@include layout-stack('m');
&__header {
align-items: baseline;
display: flex;
flex-wrap: wrap;
gap: spacer('xxs') spacer('s');
justify-content: space-between;
}
&__title {
font-size: font-size('h4');
}
&__period {
color: color('muted');
font-size: config('font-size-sm', $typography);
margin-block: 0;
}
&__list {
display: grid;
gap: spacer('m');
grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
list-style: none;
padding: 0;
> li {
margin-block: 0;
}
}
&__item {
--metric-color: #{color('success', 'alert')};
background-color: color('surface');
border: config('border-width-base', $display) solid color('border');
border-radius: radius('lg');
display: grid;
gap: spacer('xxs');
padding: spacer('m');
&--bad {
--metric-color: #{color('danger', 'alert')};
}
> p {
margin: 0;
}
}
&__label {
color: color('muted');
font-size: config('font-size-sm', $typography);
font-weight: 600;
}
&__value {
color: color('heading');
font-family: config('font-family-heading', $typography);
font-size: font-size('h3');
font-variant-numeric: tabular-nums;
font-weight: config('font-weight-heading', $typography);
}
&__delta {
align-items: center;
color: var(--metric-color);
display: flex;
flex-wrap: wrap;
font-size: config('font-size-sm', $typography);
font-weight: 700;
gap: 0 spacer('xxs');
}
&__arrow {
block-size: 1em;
inline-size: 1em;
&--down {
rotate: 180deg;
}
}
&__compare {
color: color('muted');
font-weight: 400;
}
&__sparkline {
block-size: 2.5rem;
inline-size: 100%;
margin-block-start: spacer('xs');
overflow: visible;
polyline {
fill: none;
stroke: var(--metric-color);
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 2.5;
vector-effect: non-scaling-stroke;
}
}
}
[dir='rtl'] .metric-grid__sparkline {
scale: -1 1;
}
<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>