15 CSS Number Counter Animations
Brutalist Finance Terminal
Raw high-contrast trading-desk dashboard with a live scrolling ticker tape, a featured portfolio counter, scanline overlay and neon-yellow progress bars. IBM Plex Mono and Bebas Neue carry the brutalist tone.
Brutalist Finance Terminal the 10th of 15 designs in the 15 CSS Number Counter Animations collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<div class="cnc-bft">
<div class="cnc-bft-grid">
<div class="cnc-bft-ticker">
<div class="cnc-bft-ticker-inner">
<span>NASDAQ +2.41%</span><span>DOW +0.87%</span><span>S&P500 +1.23%</span>
<span>BTC $68,420</span><span>ETH $3,810</span><span>GOLD $2,341/oz</span>
<span>VIX 14.2</span><span>10Y YIELD 4.38%</span><span>DXY 104.1</span>
<span>NASDAQ +2.41%</span><span>DOW +0.87%</span><span>S&P500 +1.23%</span>
<span>BTC $68,420</span><span>ETH $3,810</span><span>GOLD $2,341/oz</span>
<span>VIX 14.2</span><span>10Y YIELD 4.38%</span><span>DXY 104.1</span>
</div>
</div>
<div class="cnc-bft-stat cnc-bft-featured">
<span class="cnc-bft-index">01 · Portfolio Value</span>
<div class="cnc-bft-number">
<span class="cnc-bft-prefix">$</span>
<span class="cnc-num" data-target="2847391">0</span>
</div>
<div class="cnc-bft-label">Total AUM · All Positions</div>
<div class="cnc-bft-progress-line"><div class="cnc-bft-progress-fill"></div></div>
<div class="cnc-bft-sub">Updated 0.3s ago · 24h change: +$48,210</div>
</div>
<div class="cnc-bft-stat cnc-bft-danger">
<span class="cnc-bft-badge cnc-bft-down">▼ SHORT</span>
<span class="cnc-bft-index">02 · Drawdown</span>
<div class="cnc-bft-number">
<span class="cnc-num" data-target="4.7" data-decimals="1">0</span>
<span class="cnc-bft-suffix">%</span>
</div>
<div class="cnc-bft-label">Max Drawdown · 30D</div>
<div class="cnc-bft-progress-line"><div class="cnc-bft-progress-fill"></div></div>
</div>
<div class="cnc-bft-stat">
<span class="cnc-bft-badge cnc-bft-up">▲ LONG</span>
<span class="cnc-bft-index">03 · Win Rate</span>
<div class="cnc-bft-number">
<span class="cnc-num" data-target="78">0</span>
<span class="cnc-bft-suffix">%</span>
</div>
<div class="cnc-bft-label">Closed Trades · YTD</div>
<div class="cnc-bft-progress-line"><div class="cnc-bft-progress-fill"></div></div>
</div>
<div class="cnc-bft-stat">
<span class="cnc-bft-index">04 · Sharpe Ratio</span>
<div class="cnc-bft-number">
<span class="cnc-num" data-target="2.38" data-decimals="2">0</span>
</div>
<div class="cnc-bft-label">Risk-Adjusted Return</div>
<div class="cnc-bft-progress-line"><div class="cnc-bft-progress-fill"></div></div>
</div>
<div class="cnc-bft-stat">
<span class="cnc-bft-index">05 · Open Positions</span>
<div class="cnc-bft-number">
<span class="cnc-num" data-target="312">0</span>
</div>
<div class="cnc-bft-label">Across 14 Exchanges</div>
<div class="cnc-bft-progress-line"><div class="cnc-bft-progress-fill"></div></div>
</div>
</div>
</div> .cnc-bft {
--bft-black: #0a0a0a;
--bft-white: #f0ede8;
--bft-yellow: #ffe600;
--bft-red: #ff2d2d;
--bft-gray: #1c1c1c;
--bft-mid: #333;
position: relative;
display: flex; align-items: center; justify-content: center;
padding: 40px 20px;
background: var(--bft-black);
color: var(--bft-white);
font-family: 'IBM Plex Mono', monospace;
overflow: hidden;
}
.cnc-bft::before {
content: '';
position: absolute; inset: 0;
background: repeating-linear-gradient(
0deg, transparent, transparent 2px,
rgba(0,0,0,0.15) 2px, rgba(0,0,0,0.15) 4px);
pointer-events: none; z-index: 100;
}
.cnc-bft-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0;
width: 980px;
border: 3px solid var(--bft-white);
}
.cnc-bft-stat {
border: 1.5px solid var(--bft-mid);
padding: 36px 28px 28px;
position: relative; overflow: hidden;
transition: background 0.1s;
}
.cnc-bft-stat:hover { background: var(--bft-gray); }
.cnc-bft-stat::after {
content: ''; position: absolute;
bottom: 0; left: 0; width: 100%; height: 3px;
background: var(--bft-yellow);
transform: scaleX(0); transform-origin: left;
transition: transform 0.4s ease;
}
.cnc-bft-stat:hover::after { transform: scaleX(1); }
.cnc-bft-featured {
grid-column: span 2;
background: var(--bft-yellow);
color: var(--bft-black);
border-color: var(--bft-yellow);
}
.cnc-bft-featured .cnc-bft-label,
.cnc-bft-featured .cnc-bft-sub { color: var(--bft-black); opacity: 0.6; }
.cnc-bft-danger { border-top: 4px solid var(--bft-red); }
.cnc-bft-index {
font-size: 10px; letter-spacing: 3px; text-transform: uppercase;
opacity: 0.35; margin-bottom: 20px; display: block;
}
.cnc-bft-number {
font-family: 'Bebas Neue', sans-serif;
font-size: clamp(56px, 7vw, 88px);
line-height: 1; letter-spacing: -1px;
display: flex; align-items: baseline; gap: 4px;
}
.cnc-bft-featured .cnc-bft-number { font-size: clamp(72px, 9vw, 120px); }
.cnc-bft-prefix, .cnc-bft-suffix {
font-size: 0.38em;
font-family: 'IBM Plex Mono', monospace;
font-weight: 700; letter-spacing: 2px;
align-self: flex-end; padding-bottom: 0.15em;
}
.cnc-bft-label {
font-size: 10px; letter-spacing: 4px; text-transform: uppercase;
opacity: 0.45; margin-top: 12px;
}
.cnc-bft-sub {
font-size: 11px; opacity: 0.35; margin-top: 6px; letter-spacing: 1px;
}
.cnc-bft-badge {
position: absolute; top: 14px; right: 14px;
font-size: 9px; letter-spacing: 2px; text-transform: uppercase;
padding: 3px 8px; border: 1px solid currentColor; opacity: 0.5;
}
.cnc-bft-up { color: #39ff14; }
.cnc-bft-down { color: var(--bft-red); }
.cnc-bft-ticker {
grid-column: span 3;
background: var(--bft-yellow);
color: var(--bft-black);
padding: 8px 0; overflow: hidden; position: relative;
font-size: 11px; letter-spacing: 3px;
text-transform: uppercase; font-weight: 700;
}
.cnc-bft-ticker-inner {
display: flex; gap: 60px;
animation: cnc-bft-ticker 18s linear infinite;
white-space: nowrap; width: max-content;
}
@keyframes cnc-bft-ticker {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
.cnc-bft-progress-line {
height: 2px; background: rgba(255,255,255,0.08);
margin-top: 16px; position: relative; overflow: hidden;
}
.cnc-bft-progress-fill {
height: 100%; background: var(--bft-yellow);
animation: cnc-bft-fillBar 1.5s ease forwards;
transform-origin: left; transform: scaleX(0);
}
.cnc-bft-featured .cnc-bft-progress-fill { background: var(--bft-black); }
@keyframes cnc-bft-fillBar { to { transform: scaleX(1); } }
.cnc-bft-stat:nth-child(2) .cnc-bft-progress-fill { animation-delay: 0.3s; width: 73%; }
.cnc-bft-stat:nth-child(3) .cnc-bft-progress-fill { animation-delay: 0.5s; width: 91%; }
.cnc-bft-stat:nth-child(4) .cnc-bft-progress-fill { animation-delay: 0.7s; width: 47%; }
.cnc-bft-stat:nth-child(5) .cnc-bft-progress-fill { animation-delay: 0.9s; width: 85%; }
.cnc-bft-stat:nth-child(6) .cnc-bft-progress-fill { animation-delay: 1.1s; width: 62%; }
@media (prefers-reduced-motion: reduce) {
.cnc-bft-ticker-inner, .cnc-bft-progress-fill { animation: none; }
} (function () {
function easeOut(t) { return 1 - Math.pow(1 - t, 4); }
document.querySelectorAll('.cnc-bft .cnc-num').forEach(function (el) {
var target = parseFloat(el.dataset.target);
var decimals = parseInt(el.dataset.decimals || 0, 10);
var duration = 1800;
var start = performance.now();
function tick(now) {
var t = Math.min((now - start) / duration, 1);
var val = easeOut(t) * target;
el.textContent = decimals > 0
? val.toFixed(decimals)
: Math.floor(val).toLocaleString();
if (t < 1) requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
});
})(); More from 15 CSS Number Counter Animations
Stock Price TickerFitness Step CounterBioluminescent Health TrackerArt Deco Real EstateCyberpunk Gaming HUDSwiss SaaS AnalyticsSpace Mission ControlFundraising Arc MeterPodcast Flip CounterProduct Launch CountdownCommunity MilestoneCO₂ Sustainability Impact
View the full collection →