v1.1.1

Stats Card

Displays key metrics and statistics in a compact card format.

Default

Stat cards with label, value, and change indicator.

html

Total Revenue

$45,231

+12.5% from last month

Total Users

2,350

+8.2% from last month

Bounce Rate

24.3%

-3.2% from last month
<div class="vt-grid vt-grid-cols-1 vt-sm:grid-cols-3 vt-gap-4">
  <!-- Revenue -->
  <div class="vt-card vt-p-6">
    <p class="vt-text-sm vt-text-foreground-muted">Total Revenue</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">$45,231</p>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-2">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-up vt-w-3.5 vt-h-3.5 vt-text-info-fill">
        <path d="m5 12 7-7 7 7"></path><path d="M12 19V5"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-info-fill">+12.5%</span>
      <span class="vt-text-xs vt-text-foreground-muted vt-ml-1">from last month</span>
    </div>
  </div>
  <!-- Users -->
  <div class="vt-card vt-p-6">
    <p class="vt-text-sm vt-text-foreground-muted">Total Users</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">2,350</p>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-2">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-up vt-w-3.5 vt-h-3.5 vt-text-info-fill">
        <path d="m5 12 7-7 7 7"></path><path d="M12 19V5"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-info-fill">+8.2%</span>
      <span class="vt-text-xs vt-text-foreground-muted vt-ml-1">from last month</span>
    </div>
  </div>
  <!-- Bounce Rate -->
  <div class="vt-card vt-p-6">
    <p class="vt-text-sm vt-text-foreground-muted">Bounce Rate</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">24.3%</p>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-2">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-down vt-w-3.5 vt-h-3.5 vt-text-error-fill">
        <path d="M12 5v14"></path><path d="m19 12-7 7-7-7"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-error-fill">-3.2%</span>
      <span class="vt-text-xs vt-text-foreground-muted vt-ml-1">from last month</span>
    </div>
  </div>
</div>

With Icons

Stat cards with a decorative icon in a colored background.

html

Revenue

$45,231

+20.1%

Users

2,350

+15.3%

Engagement

68.7%

-2.4%
<div class="vt-grid vt-grid-cols-1 vt-sm:grid-cols-3 vt-gap-4">
  <!-- Revenue with icon -->
  <div class="vt-card vt-p-6">
    <div class="vt-flex vt-items-start vt-justify-between">
      <div>
        <p class="vt-text-sm vt-text-foreground-muted">Revenue</p>
        <p class="vt-text-2xl vt-font-bold vt-mt-1">$45,231</p>
      </div>
      <div class="vt-rounded-lg vt-bg-info-fill/10 vt-p-3">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-circle-dollar-sign vt-w-5 vt-h-5 vt-text-info-fill">
          <circle cx="12" cy="12" r="10"></circle><path d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8"></path><path d="M12 18V6"></path>
        </svg>
      </div>
    </div>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-3">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-up vt-w-3.5 vt-h-3.5 vt-text-info-fill">
        <path d="m5 12 7-7 7 7"></path><path d="M12 19V5"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-info-fill">+20.1%</span>
    </div>
  </div>
  <!-- Users with icon -->
  <div class="vt-card vt-p-6">
    <div class="vt-flex vt-items-start vt-justify-between">
      <div>
        <p class="vt-text-sm vt-text-foreground-muted">Users</p>
        <p class="vt-text-2xl vt-font-bold vt-mt-1">2,350</p>
      </div>
      <div class="vt-rounded-lg vt-bg-info-fill/10 vt-p-3">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-users vt-w-5 vt-h-5 vt-text-info-fill">
          <path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path><path d="M16 3.128a4 4 0 0 1 0 7.744"></path><path d="M22 21v-2a4 4 0 0 0-3-3.87"></path><circle cx="9" cy="7" r="4"></circle>
        </svg>
      </div>
    </div>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-3">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-up vt-w-3.5 vt-h-3.5 vt-text-info-fill">
        <path d="m5 12 7-7 7 7"></path><path d="M12 19V5"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-info-fill">+15.3%</span>
    </div>
  </div>
  <!-- Engagement with icon -->
  <div class="vt-card vt-p-6">
    <div class="vt-flex vt-items-start vt-justify-between">
      <div>
        <p class="vt-text-sm vt-text-foreground-muted">Engagement</p>
        <p class="vt-text-2xl vt-font-bold vt-mt-1">68.7%</p>
      </div>
      <div class="vt-rounded-lg vt-bg-warning-fill/10 vt-p-3">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-trending-up vt-w-5 vt-h-5 vt-text-warning-fill">
          <path d="M16 7h6v6"></path><path d="m22 7-8.5 8.5-5-5L2 17"></path>
        </svg>
      </div>
    </div>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-3">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-down vt-w-3.5 vt-h-3.5 vt-text-error-fill">
        <path d="M12 5v14"></path><path d="m19 12-7 7-7-7"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-error-fill">-2.4%</span>
    </div>
  </div>
</div>

Compact

Smaller stat cards in a 4-column layout for dashboards.

html

Revenue

$12.4k

+12.5%

Orders

1,463

+8.2%

Customers

894

-3.1%

Avg. Value

$84.50

+4.6%
<div class="vt-grid vt-grid-cols-2 vt-sm:grid-cols-4 vt-gap-3">
  <div class="vt-card vt-p-4">
    <p class="vt-text-xs vt-text-foreground-muted">Revenue</p>
    <p class="vt-text-lg vt-font-bold vt-mt-0.5">$12.4k</p>
    <span class="vt-text-xs vt-font-medium vt-text-info-fill">+12.5%</span>
  </div>
  <div class="vt-card vt-p-4">
    <p class="vt-text-xs vt-text-foreground-muted">Orders</p>
    <p class="vt-text-lg vt-font-bold vt-mt-0.5">1,463</p>
    <span class="vt-text-xs vt-font-medium vt-text-info-fill">+8.2%</span>
  </div>
  <div class="vt-card vt-p-4">
    <p class="vt-text-xs vt-text-foreground-muted">Customers</p>
    <p class="vt-text-lg vt-font-bold vt-mt-0.5">894</p>
    <span class="vt-text-xs vt-font-medium vt-text-error-fill">-3.1%</span>
  </div>
  <div class="vt-card vt-p-4">
    <p class="vt-text-xs vt-text-foreground-muted">Avg. Value</p>
    <p class="vt-text-lg vt-font-bold vt-mt-0.5">$84.50</p>
    <span class="vt-text-xs vt-font-medium vt-text-info-fill">+4.6%</span>
  </div>
</div>

With Sparkline

Stat cards with a small inline SVG sparkline chart.

html

Revenue

$45,231

+20.1%

Users

2,350

+15.3%

Bounce Rate

24.3%

-3.2%
<div class="vt-grid vt-grid-cols-1 vt-sm:grid-cols-3 vt-gap-4">
  <!-- Revenue sparkline -->
  <div class="vt-card vt-p-6">
    <p class="vt-text-sm vt-text-foreground-muted">Revenue</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">$45,231</p>
    <div class="vt-mt-3">
      <svg class="vt-w-full vt-h-10" viewBox="0 0 120 40" fill="none" preserveAspectRatio="none">
        <polyline points="0,35 10,30 20,32 30,25 40,28 50,20 60,22 70,15 80,18 90,10 100,12 110,5 120,8" stroke="hsl(var(--info-fill))" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"></polyline>
        <polyline points="0,35 10,30 20,32 30,25 40,28 50,20 60,22 70,15 80,18 90,10 100,12 110,5 120,8 120,40 0,40" fill="hsl(var(--info-fill) / 0.1)" stroke="none"></polyline>
      </svg>
    </div>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-2">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-up vt-w-3.5 vt-h-3.5 vt-text-info-fill">
        <path d="m5 12 7-7 7 7"></path><path d="M12 19V5"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-info-fill">+20.1%</span>
    </div>
  </div>
  <!-- Users sparkline -->
  <div class="vt-card vt-p-6">
    <p class="vt-text-sm vt-text-foreground-muted">Users</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">2,350</p>
    <div class="vt-mt-3">
      <svg class="vt-w-full vt-h-10" viewBox="0 0 120 40" fill="none" preserveAspectRatio="none">
        <polyline points="0,30 10,28 20,25 30,27 40,20 50,22 60,18 70,20 80,15 90,17 100,12 110,10 120,8" stroke="hsl(var(--info-fill))" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"></polyline>
        <polyline points="0,30 10,28 20,25 30,27 40,20 50,22 60,18 70,20 80,15 90,17 100,12 110,10 120,8 120,40 0,40" fill="hsl(var(--info-fill) / 0.1)" stroke="none"></polyline>
      </svg>
    </div>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-2">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-up vt-w-3.5 vt-h-3.5 vt-text-info-fill">
        <path d="m5 12 7-7 7 7"></path><path d="M12 19V5"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-info-fill">+15.3%</span>
    </div>
  </div>
  <!-- Bounce rate sparkline -->
  <div class="vt-card vt-p-6">
    <p class="vt-text-sm vt-text-foreground-muted">Bounce Rate</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">24.3%</p>
    <div class="vt-mt-3">
      <svg class="vt-w-full vt-h-10" viewBox="0 0 120 40" fill="none" preserveAspectRatio="none">
        <polyline points="0,10 10,12 20,15 30,13 40,18 50,16 60,22 70,20 80,25 90,23 100,28 110,30 120,32" stroke="hsl(var(--error-fill))" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"></polyline>
        <polyline points="0,10 10,12 20,15 30,13 40,18 50,16 60,22 70,20 80,25 90,23 100,28 110,30 120,32 120,40 0,40" fill="hsl(var(--error-fill) / 0.1)" stroke="none"></polyline>
      </svg>
    </div>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-2">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-down vt-w-3.5 vt-h-3.5 vt-text-error-fill">
        <path d="M12 5v14"></path><path d="m19 12-7 7-7-7"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-error-fill">-3.2%</span>
    </div>
  </div>
</div>

With Progress

Stat cards with a progress bar showing completion.

html

Storage Used

75%

7.5 GB of 10 GB

Tasks Complete

42%

21 of 50 tasks

Monthly Goal

92%

$46k of $50k

<div class="vt-grid vt-grid-cols-1 vt-sm:grid-cols-3 vt-gap-4">
  <!-- Storage -->
  <div class="vt-card vt-p-6">
    <p class="vt-text-sm vt-text-foreground-muted">Storage Used</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">75%</p>
    <p class="vt-text-xs vt-text-foreground-muted vt-mt-1">7.5 GB of 10 GB</p>
    <div class="vt-mt-3">
      <div class="vt-progress">
        <div class="vt-progress-bar vt-inline-c311217ce1"></div>
      </div>
    </div>
  </div>
  <!-- Tasks -->
  <div class="vt-card vt-p-6">
    <p class="vt-text-sm vt-text-foreground-muted">Tasks Complete</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">42%</p>
    <p class="vt-text-xs vt-text-foreground-muted vt-mt-1">21 of 50 tasks</p>
    <div class="vt-mt-3">
      <div class="vt-progress">
        <div class="vt-progress-bar vt-inline-d2d9157b02"></div>
      </div>
    </div>
  </div>
  <!-- Goal -->
  <div class="vt-card vt-p-6">
    <p class="vt-text-sm vt-text-foreground-muted">Monthly Goal</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">92%</p>
    <p class="vt-text-xs vt-text-foreground-muted vt-mt-1">$46k of $50k</p>
    <div class="vt-mt-3">
      <div class="vt-progress">
        <div class="vt-progress-bar vt-inline-ceecf0acec"></div>
      </div>
    </div>
  </div>
</div>

Colored

Stat cards with colored left borders for visual categorization.

html

Revenue

$45,231

+20.1% from last month

Growth

+12.5%

+2.3% from last month

Engagement

68.7%

-1.8% from last month

Churn Rate

2.4%

+0.5% from last month
<div class="vt-grid vt-grid-cols-1 vt-sm:grid-cols-2 vt-gap-4">
  <!-- Revenue - blue -->
  <div class="vt-card vt-p-6 vt-border-l-4 vt-border-l-info-fill">
    <p class="vt-text-sm vt-text-foreground-muted">Revenue</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">$45,231</p>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-2">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-up vt-w-3.5 vt-h-3.5 vt-text-info-fill">
        <path d="m5 12 7-7 7 7"></path><path d="M12 19V5"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-info-fill">+20.1%</span>
      <span class="vt-text-xs vt-text-foreground-muted vt-ml-1">from last month</span>
    </div>
  </div>
  <!-- Growth - green -->
  <div class="vt-card vt-p-6 vt-border-l-4 vt-border-l-success-fill">
    <p class="vt-text-sm vt-text-foreground-muted">Growth</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">+12.5%</p>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-2">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-up vt-w-3.5 vt-h-3.5 vt-text-info-fill">
        <path d="m5 12 7-7 7 7"></path><path d="M12 19V5"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-info-fill">+2.3%</span>
      <span class="vt-text-xs vt-text-foreground-muted vt-ml-1">from last month</span>
    </div>
  </div>
  <!-- Engagement - orange -->
  <div class="vt-card vt-p-6 vt-border-l-4 vt-border-l-warning-fill">
    <p class="vt-text-sm vt-text-foreground-muted">Engagement</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">68.7%</p>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-2">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-down vt-w-3.5 vt-h-3.5 vt-text-error-fill">
        <path d="M12 5v14"></path><path d="m19 12-7 7-7-7"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-error-fill">-1.8%</span>
      <span class="vt-text-xs vt-text-foreground-muted vt-ml-1">from last month</span>
    </div>
  </div>
  <!-- Churn - red -->
  <div class="vt-card vt-p-6 vt-border-l-4 vt-border-l-error-fill">
    <p class="vt-text-sm vt-text-foreground-muted">Churn Rate</p>
    <p class="vt-text-2xl vt-font-bold vt-mt-1">2.4%</p>
    <div class="vt-flex vt-items-center vt-gap-1 vt-mt-2">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="lucide lucide-arrow-down vt-w-3.5 vt-h-3.5 vt-text-error-fill">
        <path d="M12 5v14"></path><path d="m19 12-7 7-7-7"></path>
      </svg>
      <span class="vt-text-xs vt-font-medium vt-text-error-fill">+0.5%</span>
      <span class="vt-text-xs vt-text-foreground-muted vt-ml-1">from last month</span>
    </div>
  </div>
</div>

Guidelines

KPI tile: muted label, bold value, success/error trend line. Compose in a 2–4 column grid at the top of dashboards.

Total Revenue

$45,231

+12.5%
Do
Lead with a muted label, then a bold value and a trend line.

Total Revenue

$45,231

Don't
Don't make the label louder than the value it describes.

API Reference

All CSS classes available for the Stats Card component.

Class Type Description
vt-rounded-2xl Base Card border radius for stat cards
vt-border vt-border-border-default Base Default card border
vt-p-6 Base Standard card padding
vt-p-4 Size Compact card padding for smaller variants
vt-text-2xl vt-font-bold Typography Main stat value styling
vt-text-lg vt-font-bold Typography Compact stat value styling
vt-text-sm vt-text-foreground-muted Typography Stat label text styling
vt-text-xs vt-font-medium vt-text-info-fill Indicator Positive trend indicator text
vt-text-xs vt-font-medium vt-text-error-fill Indicator Negative trend indicator text
vt-bg-info-fill/10 Modifier Tinted icon background container
vt-border-l-4 vt-border-l-info-fill Modifier Colored left border accent for categorization
vt-progress-bar Progress Progress bar fill styling
vt-progress Progress Progress bar track (Progress component)

Accessibility

Keyboard and screen reader support.

Feature Details
Semantics Use dl/dt/dd elements for label-value pairs in stat cards
Updates Dynamic stat values should use aria-live="polite" for announcements
Icons Decorative trend icons should have aria-hidden="true"
Context Trend indicators need sr-only text like "Increased by 12%"
Built with: