Open demo

CSS code

HTML
<div class="dk"><span class="lbl">Dark KPI tiles</span>
<div class="dk-kpis">
  <article class="dk-card dk-kpi"><h3 class="dk-label">Uptime, 30 days</h3><p class="dk-value">99.98%</p><p class="dk-foot"><span class="dk-delta is-good"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>+0.03 pts</span>vs September</p></article>
  <article class="dk-card dk-kpi"><h3 class="dk-label">p95 latency</h3><p class="dk-value">182 ms</p><p class="dk-foot"><span class="dk-delta is-good"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M19 12l-7 7-7-7"/></svg>−24 ms</span>faster than yesterday</p></article>
  <article class="dk-card dk-kpi"><h3 class="dk-label">Error rate</h3><p class="dk-value">0.21%</p><p class="dk-foot"><span class="dk-delta is-bad"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>+0.05 pts</span>worse than yesterday</p></article>
  <article class="dk-card dk-kpi"><h3 class="dk-label">Requests today</h3><p class="dk-value">4.82M</p><p class="dk-foot"><span class="dk-delta is-neutral"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>+8.6%</span>vs last Friday</p></article>
</div></div>

<div class="dk"><span class="lbl">Latency chart with an SLO line</span>
<figure class="dk-card">
  <div class="dk-head"><div><h3 class="dk-title">p95 latency, all regions</h3><p class="dk-sub">Last 24 hours · peak 284 ms at 10:00</p></div>
    <p class="dk-key" aria-hidden="true"><span><i></i>p95</span><span><i class="is-slo"></i>SLO 300 ms</span></p></div>
  <div class="dk-plot">
    <svg viewBox="0 0 600 200" preserveAspectRatio="none" aria-hidden="true">
      <line class="grid" x1="0" x2="600" y1="200" y2="200" vector-effect="non-scaling-stroke"/><line class="grid" x1="0" x2="600" y1="109" y2="109" vector-effect="non-scaling-stroke"/>
      <path class="ar" d="M0 138.2L54.5 152.7L109.1 155.5L163.6 135.5L218.2 76.4L272.7 32.7L327.3 66.4L381.8 91.8L436.4 104.5L490.9 112.7L545.5 120L600 125.5L600 200L0 200Z"/><path class="ln" d="M0 138.2L54.5 152.7L109.1 155.5L163.6 135.5L218.2 76.4L272.7 32.7L327.3 66.4L381.8 91.8L436.4 104.5L490.9 112.7L545.5 120L600 125.5" vector-effect="non-scaling-stroke"/>
      <line class="slo" x1="0" x2="600" y1="18.2" y2="18.2" vector-effect="non-scaling-stroke"/>
    </svg>
    <div class="dk-y" aria-hidden="true"><span style="top:9.1%">300 ms</span><span style="top:54.5%">200 ms</span><span style="top:100%">100 ms</span></div>
    <span class="dk-slo-tag" style="top:9.1%" aria-hidden="true">SLO</span>
  </div>
  <div class="dk-x" aria-hidden="true"><span style="left:0">00:00</span><span style="left:36.4%">08:00</span><span style="left:72.7%">16:00</span><span style="left:100%">22:00</span></div>
  <div class="sr-only"><table><caption>p95 latency every two hours today, all regions. Objective: under 300 ms.</caption>
    <thead><tr><th scope="col">Time</th><th scope="col">p95 latency</th></tr></thead>
    <tbody>
          <tr><th scope="row">00:00</th><td>168 ms</td></tr>
          <tr><th scope="row">02:00</th><td>152 ms</td></tr>
          <tr><th scope="row">04:00</th><td>149 ms</td></tr>
          <tr><th scope="row">06:00</th><td>171 ms</td></tr>
          <tr><th scope="row">08:00</th><td>236 ms</td></tr>
          <tr><th scope="row">10:00</th><td>284 ms</td></tr>
          <tr><th scope="row">12:00</th><td>247 ms</td></tr>
          <tr><th scope="row">14:00</th><td>219 ms</td></tr>
          <tr><th scope="row">16:00</th><td>205 ms</td></tr>
          <tr><th scope="row">18:00</th><td>196 ms</td></tr>
          <tr><th scope="row">20:00</th><td>188 ms</td></tr>
          <tr><th scope="row">22:00</th><td>182 ms</td></tr>
    </tbody></table></div>
</figure></div>

<div class="dk"><span class="lbl">Region status and error budget</span>
<div class="dk-split">
  <section class="dk-card" aria-labelledby="dk-reg-title">
    <div class="dk-head"><div><h3 class="dk-title" id="dk-reg-title">Regions</h3><p class="dk-sub">3 of 4 fully operational</p></div><a href="#">Status page</a></div>
    <ul class="dk-regions">
      <li><span class="dk-st is-warn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 9v4M12 17h.01"/><path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/></svg>Degraded</span><div><p class="dk-rg">eu-west-1 <span>Ireland</span></p><p class="dk-meta">p95 284 ms at peak</p></div></li>
      <li><span class="dk-st is-ok"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Operational</span><div><p class="dk-rg">us-east-1 <span>Virginia</span></p><p class="dk-meta">p95 141 ms</p></div></li>
      <li><span class="dk-st is-ok"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Operational</span><div><p class="dk-rg">ap-south-1 <span>Mumbai</span></p><p class="dk-meta">p95 163 ms</p></div></li>
      <li><span class="dk-st is-info"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.8-3.8a6 6 0 0 1-7.9 7.9l-6.9 6.9a2.1 2.1 0 0 1-3-3l6.9-6.9a6 6 0 0 1 7.9-7.9z"/></svg>Maintenance</span><div><p class="dk-rg">sa-east-1 <span>São Paulo</span></p><p class="dk-meta">Tonight 22:00–23:00 UTC</p></div></li>
    </ul>
  </section>
  <section class="dk-card" aria-labelledby="dk-bud-title">
    <div class="dk-head"><div><h3 class="dk-title" id="dk-bud-title">Error budget</h3><p class="dk-sub">October · 99.9% availability objective</p></div></div>
    <div class="dk-budget">
      <div class="dk-ring" role="progressbar" aria-labelledby="dk-bud-title" aria-valuemin="0" aria-valuemax="100" aria-valuenow="62" aria-valuetext="62% of the error budget left">
        <svg viewBox="0 0 100 100" aria-hidden="true"><circle class="trk" cx="50" cy="50" r="42"/><circle class="bar" cx="50" cy="50" r="42" pathLength="100"/></svg>
        <span aria-hidden="true">62%<small>left</small></span></div>
      <dl>
        <div><dt>Budget left</dt><dd>26 min 47 s of 43 min 12 s</dd></div>
        <div><dt>Burn rate, last 24 h</dt><dd>1.4× (above 1×)</dd></div>
        <div><dt>Runs out at this rate</dt><dd>Oct 29</dd></div>
      </dl>
    </div>
  </section>
</div></div>
CSS
/* Dark dashboard widgets: an ops view on a near-black ground. Text and marks are checked for contrast on the
   card colour; deltas and statuses are words and icons, not colours alone. The latency chart is a static SVG
   with HTML axis labels (so the text never scales) and a visually hidden table holding the same numbers. */
.dk{--dk-bg:#111827;--dk-line:#243045;--dk-ink:#e5e7eb;--dk-muted:#9aa4b2;--dk-accent:#60a5fa;--dk-series:#3987e5;
  --dk-good:#4ade80;--dk-bad:#f87171;--dk-warn:#fbbf24;--dk-info:#93c5fd;color:var(--dk-ink);color-scheme:dark}
.dk-card{background:var(--dk-bg);border:1px solid var(--dk-line);border-radius:16px;padding:18px;min-width:0;box-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 10px 30px rgba(0,0,0,.35)}
.dk-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px}
.dk-label{font-size:.8rem;font-weight:600;color:var(--dk-muted)}
.dk-value{font-size:1.8rem;font-weight:750;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.2;margin:4px 0 6px}
.dk-foot{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:.78rem;color:var(--dk-muted)}
.dk-delta{display:inline-flex;align-items:center;gap:3px;padding:1px 8px 1px 6px;border-radius:999px;font-weight:700;font-variant-numeric:tabular-nums;border:1px solid currentColor}
.dk-delta svg{width:13px;height:13px}
.dk-delta.is-good{color:var(--dk-good)}
.dk-delta.is-bad{color:var(--dk-bad)}
.dk-delta.is-neutral{color:var(--dk-info)}
.dk-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap;margin-bottom:14px}
.dk-title{font-size:1rem;font-weight:700}
.dk-sub{font-size:.8rem;color:var(--dk-muted)}
.dk-key{display:flex;gap:14px;font-size:.76rem;color:var(--dk-muted)}
.dk-key span{display:inline-flex;align-items:center;gap:6px}
.dk-key i{width:16px;height:0;border-top:2px solid var(--dk-series)}
.dk-key i.is-slo{border-top:2px dashed var(--dk-warn)}
/* chart */
.dk-plot{position:relative;height:190px;margin-left:46px}
.dk-plot svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.dk-plot .grid{stroke:var(--dk-line);stroke-width:1}
.dk-plot .slo{stroke:var(--dk-warn);stroke-width:1.5;stroke-dasharray:5 4}
.dk-plot .ln{fill:none;stroke:var(--dk-series);stroke-width:2.5;stroke-linejoin:round;stroke-linecap:round}
.dk-plot .ar{fill:var(--dk-series);opacity:.16}
.dk-y span{position:absolute;right:calc(100% + 8px);transform:translateY(-50%);font-size:.7rem;color:var(--dk-muted);white-space:nowrap;font-variant-numeric:tabular-nums}
.dk-slo-tag{position:absolute;right:0;transform:translateY(-120%);font-size:.7rem;font-weight:700;color:var(--dk-warn)}
.dk-x{position:relative;height:22px;margin:6px 0 0 46px;font-size:.7rem;color:var(--dk-muted);font-variant-numeric:tabular-nums}
.dk-x span{position:absolute;top:0;transform:translateX(-50%)}
.dk-x span:first-child{transform:none}
.dk-x span:last-child{transform:translateX(-100%)}
/* status + budget */
.dk-split{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:14px}
.dk-regions{list-style:none}
.dk-regions li{display:grid;grid-template-columns:118px 1fr;gap:12px;align-items:center;padding:11px 0;border-top:1px solid var(--dk-line)}
.dk-st{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;font-weight:700}
.dk-st svg{width:15px;height:15px;flex:none}
.dk-st.is-ok{color:var(--dk-good)}
.dk-st.is-warn{color:var(--dk-warn)}
.dk-st.is-info{color:var(--dk-info)}
.dk-rg{font-size:.88rem;font-weight:600;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.dk-rg span{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-weight:400;color:var(--dk-muted);margin-left:4px}
.dk-meta{font-size:.76rem;color:var(--dk-muted)}
.dk-budget{display:flex;align-items:center;gap:20px}
.dk-ring{position:relative;flex:none;width:118px;height:118px}
.dk-ring svg{width:100%;height:100%;transform:rotate(-90deg)}
.dk-ring circle{fill:none;stroke-width:11}
.dk-ring .trk{stroke:var(--dk-line)}
.dk-ring .bar{stroke:var(--dk-series);stroke-linecap:round;stroke-dasharray:62 100;transition:stroke-dasharray .6s}
.dk-ring span{position:absolute;inset:0;display:grid;place-content:center;text-align:center;font-size:1.35rem;font-weight:750;line-height:1.1}
.dk-ring small{display:block;font-size:.68rem;font-weight:500;color:var(--dk-muted)}
.dk-budget dl{display:grid;gap:8px;font-size:.8rem}
.dk-budget dt{color:var(--dk-muted)}
.dk-budget dd{font-weight:700;font-variant-numeric:tabular-nums}
.dk a{color:var(--dk-accent);font-weight:600;text-decoration:none;border-radius:4px}
.dk a:hover{text-decoration:underline}
.dk a:focus-visible{outline:2px solid var(--dk-accent);outline-offset:2px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
@media (prefers-reduced-motion:reduce){.dk-ring .bar{transition:none}}

Bootstrap 5 code

Requires: Bootstrap 5.3.8 CSS

HTML
<div class="dk" data-bs-theme="dark"><span class="lbl">Dark KPI tiles</span>
<div class="row row-cols-1 row-cols-sm-2 row-cols-lg-4 g-3">
  <div class="col"><article class="card dk-card h-100"><div class="card-body"><h3 class="dk-label mb-0">Uptime, 30 days</h3><p class="dk-value">99.98%</p><p class="dk-foot d-flex align-items-center flex-wrap gap-2 mb-0"><span class="badge rounded-pill dk-delta is-good"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>+0.03 pts</span>vs September</p></div></article></div>
  <div class="col"><article class="card dk-card h-100"><div class="card-body"><h3 class="dk-label mb-0">p95 latency</h3><p class="dk-value">182 ms</p><p class="dk-foot d-flex align-items-center flex-wrap gap-2 mb-0"><span class="badge rounded-pill dk-delta is-good"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M19 12l-7 7-7-7"/></svg>−24 ms</span>faster than yesterday</p></div></article></div>
  <div class="col"><article class="card dk-card h-100"><div class="card-body"><h3 class="dk-label mb-0">Error rate</h3><p class="dk-value">0.21%</p><p class="dk-foot d-flex align-items-center flex-wrap gap-2 mb-0"><span class="badge rounded-pill dk-delta is-bad"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>+0.05 pts</span>worse than yesterday</p></div></article></div>
  <div class="col"><article class="card dk-card h-100"><div class="card-body"><h3 class="dk-label mb-0">Requests today</h3><p class="dk-value">4.82M</p><p class="dk-foot d-flex align-items-center flex-wrap gap-2 mb-0"><span class="badge rounded-pill dk-delta is-neutral"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>+8.6%</span>vs last Friday</p></div></article></div>
</div></div>

<div class="dk" data-bs-theme="dark"><span class="lbl">Latency chart with an SLO line</span>
<figure class="card dk-card"><div class="card-body">
  <div class="dk-head"><div><h3 class="dk-title mb-0">p95 latency, all regions</h3><p class="dk-sub mb-0">Last 24 hours · peak 284 ms at 10:00</p></div>
    <p class="dk-key mb-0" aria-hidden="true"><span><i></i>p95</span><span><i class="is-slo"></i>SLO 300 ms</span></p></div>
  <div class="dk-plot">
    <svg viewBox="0 0 600 200" preserveAspectRatio="none" aria-hidden="true">
      <line class="grid" x1="0" x2="600" y1="200" y2="200" vector-effect="non-scaling-stroke"/><line class="grid" x1="0" x2="600" y1="109" y2="109" vector-effect="non-scaling-stroke"/>
      <path class="ar" d="M0 138.2L54.5 152.7L109.1 155.5L163.6 135.5L218.2 76.4L272.7 32.7L327.3 66.4L381.8 91.8L436.4 104.5L490.9 112.7L545.5 120L600 125.5L600 200L0 200Z"/><path class="ln" d="M0 138.2L54.5 152.7L109.1 155.5L163.6 135.5L218.2 76.4L272.7 32.7L327.3 66.4L381.8 91.8L436.4 104.5L490.9 112.7L545.5 120L600 125.5" vector-effect="non-scaling-stroke"/>
      <line class="slo" x1="0" x2="600" y1="18.2" y2="18.2" vector-effect="non-scaling-stroke"/>
    </svg>
    <div class="dk-y" aria-hidden="true"><span style="top:9.1%">300 ms</span><span style="top:54.5%">200 ms</span><span style="top:100%">100 ms</span></div>
    <span class="dk-slo-tag" style="top:9.1%" aria-hidden="true">SLO</span>
  </div>
  <div class="dk-x" aria-hidden="true"><span style="left:0">00:00</span><span style="left:36.4%">08:00</span><span style="left:72.7%">16:00</span><span style="left:100%">22:00</span></div>
  <div class="visually-hidden"><table><caption>p95 latency every two hours today, all regions. Objective: under 300 ms.</caption>
    <thead><tr><th scope="col">Time</th><th scope="col">p95 latency</th></tr></thead>
    <tbody>
          <tr><th scope="row">00:00</th><td>168 ms</td></tr>
          <tr><th scope="row">02:00</th><td>152 ms</td></tr>
          <tr><th scope="row">04:00</th><td>149 ms</td></tr>
          <tr><th scope="row">06:00</th><td>171 ms</td></tr>
          <tr><th scope="row">08:00</th><td>236 ms</td></tr>
          <tr><th scope="row">10:00</th><td>284 ms</td></tr>
          <tr><th scope="row">12:00</th><td>247 ms</td></tr>
          <tr><th scope="row">14:00</th><td>219 ms</td></tr>
          <tr><th scope="row">16:00</th><td>205 ms</td></tr>
          <tr><th scope="row">18:00</th><td>196 ms</td></tr>
          <tr><th scope="row">20:00</th><td>188 ms</td></tr>
          <tr><th scope="row">22:00</th><td>182 ms</td></tr>
    </tbody></table></div>
</div></figure></div>

<div class="dk" data-bs-theme="dark"><span class="lbl">Region status and error budget</span>
<div class="row g-3">
  <div class="col-md-6"><section class="card dk-card h-100" aria-labelledby="dk-reg-title"><div class="card-body">
    <div class="dk-head"><div><h3 class="dk-title mb-0" id="dk-reg-title">Regions</h3><p class="dk-sub mb-0">3 of 4 fully operational</p></div><a href="#">Status page</a></div>
    <ul class="list-group list-group-flush dk-regions">
      <li class="list-group-item"><span class="dk-st is-warn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 9v4M12 17h.01"/><path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/></svg>Degraded</span><div><p class="dk-rg mb-0">eu-west-1 <span>Ireland</span></p><p class="dk-meta mb-0">p95 284 ms at peak</p></div></li>
      <li class="list-group-item"><span class="dk-st is-ok"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Operational</span><div><p class="dk-rg mb-0">us-east-1 <span>Virginia</span></p><p class="dk-meta mb-0">p95 141 ms</p></div></li>
      <li class="list-group-item"><span class="dk-st is-ok"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Operational</span><div><p class="dk-rg mb-0">ap-south-1 <span>Mumbai</span></p><p class="dk-meta mb-0">p95 163 ms</p></div></li>
      <li class="list-group-item"><span class="dk-st is-info"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.8-3.8a6 6 0 0 1-7.9 7.9l-6.9 6.9a2.1 2.1 0 0 1-3-3l6.9-6.9a6 6 0 0 1 7.9-7.9z"/></svg>Maintenance</span><div><p class="dk-rg mb-0">sa-east-1 <span>São Paulo</span></p><p class="dk-meta mb-0">Tonight 22:00–23:00 UTC</p></div></li>
    </ul>
  </div></section></div>
  <div class="col-md-6"><section class="card dk-card h-100" aria-labelledby="dk-bud-title"><div class="card-body">
    <div class="dk-head"><div><h3 class="dk-title mb-0" id="dk-bud-title">Error budget</h3><p class="dk-sub mb-0">October · 99.9% availability objective</p></div></div>
    <div class="dk-budget">
      <div class="dk-ring" role="progressbar" aria-labelledby="dk-bud-title" aria-valuemin="0" aria-valuemax="100" aria-valuenow="62" aria-valuetext="62% of the error budget left">
        <svg viewBox="0 0 100 100" aria-hidden="true"><circle class="trk" cx="50" cy="50" r="42"/><circle class="bar" cx="50" cy="50" r="42" pathLength="100"/></svg>
        <span aria-hidden="true">62%<small>left</small></span></div>
      <dl>
        <div><dt>Budget left</dt><dd>26 min 47 s of 43 min 12 s</dd></div>
        <div><dt>Burn rate, last 24 h</dt><dd>1.4× (above 1×)</dd></div>
        <div><dt>Runs out at this rate</dt><dd>Oct 29</dd></div>
      </dl>
    </div>
  </div></section></div>
</div></div>
CSS
/* Bootstrap in data-bs-theme="dark": .card, .badge, .list-group and .visually-hidden, with a few rules for the chart and ring.
   Dark dashboard widgets: an ops view on a near-black ground. Text and marks are checked for contrast on the
   card colour; deltas and statuses are words and icons, not colours alone. The latency chart is a static SVG
   with HTML axis labels (so the text never scales) and a visually hidden table holding the same numbers. */
.dk{--dk-bg:#111827;--dk-line:#243045;--dk-ink:#e5e7eb;--dk-muted:#9aa4b2;--dk-accent:#60a5fa;--dk-series:#3987e5;
  --dk-good:#4ade80;--dk-bad:#f87171;--dk-warn:#fbbf24;--dk-info:#93c5fd;color:var(--dk-ink);color-scheme:dark}
.dk{--bs-body-bg:#0b1120;--bs-body-color:#e5e7eb;--bs-border-color:#243045}
.dk-card{--bs-card-bg:var(--dk-bg);--bs-card-border-color:var(--dk-line);--bs-card-border-radius:16px;--bs-card-spacer-x:18px;--bs-card-spacer-y:18px;--bs-card-color:var(--dk-ink);min-width:0;margin:0;box-shadow:0 1px 0 rgba(255,255,255,.04) inset,0 10px 30px rgba(0,0,0,.35)}
.dk-kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px}
.dk-label{font-size:.8rem;font-weight:600;color:var(--dk-muted)}
.dk-value{font-size:1.8rem;font-weight:750;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.2;margin:4px 0 6px}
.dk-foot{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:.78rem;color:var(--dk-muted)}
.dk-delta{display:inline-flex;align-items:center;gap:3px;padding:2px 8px 2px 6px;font-size:.78rem;font-weight:700;background:transparent;font-variant-numeric:tabular-nums;border:1px solid currentColor}
.dk-delta svg{width:13px;height:13px}
.dk-delta.is-good{color:var(--dk-good)}
.dk-delta.is-bad{color:var(--dk-bad)}
.dk-delta.is-neutral{color:var(--dk-info)}
.dk-head{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;flex-wrap:wrap;margin-bottom:14px}
.dk-title{font-size:1rem;font-weight:700}
.dk-sub{font-size:.8rem;color:var(--dk-muted)}
.dk-key{display:flex;gap:14px;font-size:.76rem;color:var(--dk-muted)}
.dk-key span{display:inline-flex;align-items:center;gap:6px}
.dk-key i{width:16px;height:0;border-top:2px solid var(--dk-series)}
.dk-key i.is-slo{border-top:2px dashed var(--dk-warn)}
/* chart */
.dk-plot{position:relative;height:190px;margin-left:46px}
.dk-plot svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.dk-plot .grid{stroke:var(--dk-line);stroke-width:1}
.dk-plot .slo{stroke:var(--dk-warn);stroke-width:1.5;stroke-dasharray:5 4}
.dk-plot .ln{fill:none;stroke:var(--dk-series);stroke-width:2.5;stroke-linejoin:round;stroke-linecap:round}
.dk-plot .ar{fill:var(--dk-series);opacity:.16}
.dk-y span{position:absolute;right:calc(100% + 8px);transform:translateY(-50%);font-size:.7rem;color:var(--dk-muted);white-space:nowrap;font-variant-numeric:tabular-nums}
.dk-slo-tag{position:absolute;right:0;transform:translateY(-120%);font-size:.7rem;font-weight:700;color:var(--dk-warn)}
.dk-x{position:relative;height:22px;margin:6px 0 0 46px;font-size:.7rem;color:var(--dk-muted);font-variant-numeric:tabular-nums}
.dk-x span{position:absolute;top:0;transform:translateX(-50%)}
.dk-x span:first-child{transform:none}
.dk-x span:last-child{transform:translateX(-100%)}
/* status + budget */
.dk-split{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:14px}
.dk-regions{--bs-list-group-bg:transparent;--bs-list-group-border-color:var(--dk-line);--bs-list-group-color:var(--dk-ink);--bs-list-group-item-padding-x:0;--bs-list-group-item-padding-y:11px}
.dk-regions .list-group-item{border-top:1px solid var(--dk-line);display:grid;grid-template-columns:118px 1fr;gap:12px;align-items:center;padding:11px 0;border-top:1px solid var(--dk-line)}
.dk-st{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;font-weight:700}
.dk-st svg{width:15px;height:15px;flex:none}
.dk-st.is-ok{color:var(--dk-good)}
.dk-st.is-warn{color:var(--dk-warn)}
.dk-st.is-info{color:var(--dk-info)}
.dk-rg{font-size:.88rem;font-weight:600;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.dk-rg span{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-weight:400;color:var(--dk-muted);margin-left:4px}
.dk-meta{font-size:.76rem;color:var(--dk-muted)}
.dk-budget{display:flex;align-items:center;gap:20px}
.dk-ring{position:relative;flex:none;width:118px;height:118px}
.dk-ring svg{width:100%;height:100%;transform:rotate(-90deg)}
.dk-ring circle{fill:none;stroke-width:11}
.dk-ring .trk{stroke:var(--dk-line)}
.dk-ring .bar{stroke:var(--dk-series);stroke-linecap:round;stroke-dasharray:62 100;transition:stroke-dasharray .6s}
.dk-ring span{position:absolute;inset:0;display:grid;place-content:center;text-align:center;font-size:1.35rem;font-weight:750;line-height:1.1}
.dk-ring small{display:block;font-size:.68rem;font-weight:500;color:var(--dk-muted)}
.dk-budget dl{display:grid;gap:8px;font-size:.8rem;margin:0}
.dk-budget dd{margin:0}
.dk-budget dt{color:var(--dk-muted)}
.dk-budget dd{font-weight:700;font-variant-numeric:tabular-nums}
.dk a{color:var(--dk-accent);font-weight:600;text-decoration:none;border-radius:4px}
.dk a:hover{text-decoration:underline}
.dk a:focus-visible{outline:2px solid var(--dk-accent);outline-offset:2px}
@media (prefers-reduced-motion:reduce){.dk-ring .bar{transition:none}}

Tailwind 4 code

Requires: Tailwind CSS 4

HTML
<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-dk-muted uppercase">Dark KPI tiles</span>
<div class="grid grid-cols-[repeat(auto-fit,minmax(210px,1fr))] gap-3.5">
  <article class="min-w-0 rounded-2xl border border-dk-line bg-dk-bg p-[18px] shadow-[inset_0_1px_0_rgba(255,255,255,.04),0_10px_30px_rgba(0,0,0,.35)]"><h3 class="text-[.8rem] font-semibold text-dk-muted">Uptime, 30 days</h3><p class="mt-1 mb-1.5 text-[1.8rem] leading-[1.2] font-[750] tracking-[-.02em] tabular-nums">99.98%</p><p class="flex flex-wrap items-center gap-2 text-[.78rem] text-dk-muted"><span class="inline-flex items-center gap-[3px] rounded-full border border-current py-px pr-2 pl-1.5 font-bold tabular-nums text-dk-good"><svg class="size-[13px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>+0.03 pts</span>vs September</p></article>
  <article class="min-w-0 rounded-2xl border border-dk-line bg-dk-bg p-[18px] shadow-[inset_0_1px_0_rgba(255,255,255,.04),0_10px_30px_rgba(0,0,0,.35)]"><h3 class="text-[.8rem] font-semibold text-dk-muted">p95 latency</h3><p class="mt-1 mb-1.5 text-[1.8rem] leading-[1.2] font-[750] tracking-[-.02em] tabular-nums">182 ms</p><p class="flex flex-wrap items-center gap-2 text-[.78rem] text-dk-muted"><span class="inline-flex items-center gap-[3px] rounded-full border border-current py-px pr-2 pl-1.5 font-bold tabular-nums text-dk-good"><svg class="size-[13px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 5v14M19 12l-7 7-7-7"/></svg>−24 ms</span>faster than yesterday</p></article>
  <article class="min-w-0 rounded-2xl border border-dk-line bg-dk-bg p-[18px] shadow-[inset_0_1px_0_rgba(255,255,255,.04),0_10px_30px_rgba(0,0,0,.35)]"><h3 class="text-[.8rem] font-semibold text-dk-muted">Error rate</h3><p class="mt-1 mb-1.5 text-[1.8rem] leading-[1.2] font-[750] tracking-[-.02em] tabular-nums">0.21%</p><p class="flex flex-wrap items-center gap-2 text-[.78rem] text-dk-muted"><span class="inline-flex items-center gap-[3px] rounded-full border border-current py-px pr-2 pl-1.5 font-bold tabular-nums text-dk-bad"><svg class="size-[13px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>+0.05 pts</span>worse than yesterday</p></article>
  <article class="min-w-0 rounded-2xl border border-dk-line bg-dk-bg p-[18px] shadow-[inset_0_1px_0_rgba(255,255,255,.04),0_10px_30px_rgba(0,0,0,.35)]"><h3 class="text-[.8rem] font-semibold text-dk-muted">Requests today</h3><p class="mt-1 mb-1.5 text-[1.8rem] leading-[1.2] font-[750] tracking-[-.02em] tabular-nums">4.82M</p><p class="flex flex-wrap items-center gap-2 text-[.78rem] text-dk-muted"><span class="inline-flex items-center gap-[3px] rounded-full border border-current py-px pr-2 pl-1.5 font-bold tabular-nums text-dk-info"><svg class="size-[13px]" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>+8.6%</span>vs last Friday</p></article>
</div></div>

<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-dk-muted uppercase">Latency chart with an SLO line</span>
<figure class="min-w-0 rounded-2xl border border-dk-line bg-dk-bg p-[18px] shadow-[inset_0_1px_0_rgba(255,255,255,.04),0_10px_30px_rgba(0,0,0,.35)]">
  <div class="mb-3.5 flex flex-wrap items-start justify-between gap-3"><div><h3 class="text-base font-bold">p95 latency, all regions</h3><p class="text-[.8rem] text-dk-muted">Last 24 hours · peak 284 ms at 10:00</p></div>
    <p class="flex gap-3.5 text-[.76rem] text-dk-muted" aria-hidden="true"><span class="inline-flex items-center gap-1.5"><i class="w-4 border-t-2 border-dk-series"></i>p95</span><span class="inline-flex items-center gap-1.5"><i class="w-4 border-t-2 border-dashed border-dk-warn"></i>SLO 300 ms</span></p></div>
  <div class="relative ml-[46px] h-[190px]">
    <svg class="absolute inset-0 size-full overflow-visible" viewBox="0 0 600 200" preserveAspectRatio="none" aria-hidden="true">
      <line class="stroke-dk-line" x1="0" x2="600" y1="200" y2="200" vector-effect="non-scaling-stroke"/><line class="stroke-dk-line" x1="0" x2="600" y1="109" y2="109" vector-effect="non-scaling-stroke"/>
      <path class="fill-dk-series opacity-16" d="M0 138.2L54.5 152.7L109.1 155.5L163.6 135.5L218.2 76.4L272.7 32.7L327.3 66.4L381.8 91.8L436.4 104.5L490.9 112.7L545.5 120L600 125.5L600 200L0 200Z"/><path class="fill-none stroke-dk-series [stroke-width:2.5] [stroke-linecap:round] [stroke-linejoin:round]" d="M0 138.2L54.5 152.7L109.1 155.5L163.6 135.5L218.2 76.4L272.7 32.7L327.3 66.4L381.8 91.8L436.4 104.5L490.9 112.7L545.5 120L600 125.5" vector-effect="non-scaling-stroke"/>
      <line class="stroke-dk-warn [stroke-dasharray:5_4] [stroke-width:1.5]" x1="0" x2="600" y1="18.2" y2="18.2" vector-effect="non-scaling-stroke"/>
    </svg>
    <div aria-hidden="true"><span class="absolute right-[calc(100%+8px)] -translate-y-1/2 text-[.7rem] whitespace-nowrap text-dk-muted tabular-nums top-[9.1%]">300 ms</span><span class="absolute right-[calc(100%+8px)] -translate-y-1/2 text-[.7rem] whitespace-nowrap text-dk-muted tabular-nums top-[54.5%]">200 ms</span><span class="absolute right-[calc(100%+8px)] -translate-y-1/2 text-[.7rem] whitespace-nowrap text-dk-muted tabular-nums top-full">100 ms</span></div>
    <span class="absolute top-[9.1%] right-0 -translate-y-[120%] text-[.7rem] font-bold text-dk-warn" aria-hidden="true">SLO</span>
  </div>
  <div class="relative mt-1.5 ml-[46px] h-[22px] text-[.7rem] text-dk-muted tabular-nums" aria-hidden="true"><span class="absolute left-0">00:00</span><span class="absolute left-[36.4%] -translate-x-1/2">08:00</span><span class="absolute left-[72.7%] -translate-x-1/2">16:00</span><span class="absolute left-full -translate-x-full">22:00</span></div>
  <div class="sr-only"><table><caption>p95 latency every two hours today, all regions. Objective: under 300 ms.</caption>
    <thead><tr><th scope="col">Time</th><th scope="col">p95 latency</th></tr></thead>
    <tbody>
          <tr><th scope="row">00:00</th><td>168 ms</td></tr>
          <tr><th scope="row">02:00</th><td>152 ms</td></tr>
          <tr><th scope="row">04:00</th><td>149 ms</td></tr>
          <tr><th scope="row">06:00</th><td>171 ms</td></tr>
          <tr><th scope="row">08:00</th><td>236 ms</td></tr>
          <tr><th scope="row">10:00</th><td>284 ms</td></tr>
          <tr><th scope="row">12:00</th><td>247 ms</td></tr>
          <tr><th scope="row">14:00</th><td>219 ms</td></tr>
          <tr><th scope="row">16:00</th><td>205 ms</td></tr>
          <tr><th scope="row">18:00</th><td>196 ms</td></tr>
          <tr><th scope="row">20:00</th><td>188 ms</td></tr>
          <tr><th scope="row">22:00</th><td>182 ms</td></tr>
    </tbody></table></div>
</figure></div>

<div><span class="mb-4 block text-[.72rem] tracking-[.12em] text-dk-muted uppercase">Region status and error budget</span>
<div class="grid grid-cols-[repeat(auto-fit,minmax(min(100%,300px),1fr))] gap-3.5">
  <section class="min-w-0 rounded-2xl border border-dk-line bg-dk-bg p-[18px] shadow-[inset_0_1px_0_rgba(255,255,255,.04),0_10px_30px_rgba(0,0,0,.35)]" aria-labelledby="dk-reg-title">
    <div class="mb-3.5 flex flex-wrap items-start justify-between gap-3"><div><h3 class="text-base font-bold" id="dk-reg-title">Regions</h3><p class="text-[.8rem] text-dk-muted">3 of 4 fully operational</p></div><a href="#" class="rounded font-semibold text-dk-accent no-underline hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-dk-accent">Status page</a></div>
    <ul>
      <li class="grid grid-cols-[118px_1fr] items-center gap-3 border-t border-dk-line py-[11px]"><span class="inline-flex items-center gap-1.5 text-[.78rem] font-bold text-dk-warn"><svg class="size-[15px] flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 9v4M12 17h.01"/><path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/></svg>Degraded</span><div><p class="font-mono text-[.88rem] font-semibold">eu-west-1 <span class="ml-1 font-sans font-normal text-dk-muted">Ireland</span></p><p class="text-[.76rem] text-dk-muted">p95 284 ms at peak</p></div></li>
      <li class="grid grid-cols-[118px_1fr] items-center gap-3 border-t border-dk-line py-[11px]"><span class="inline-flex items-center gap-1.5 text-[.78rem] font-bold text-dk-good"><svg class="size-[15px] flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Operational</span><div><p class="font-mono text-[.88rem] font-semibold">us-east-1 <span class="ml-1 font-sans font-normal text-dk-muted">Virginia</span></p><p class="text-[.76rem] text-dk-muted">p95 141 ms</p></div></li>
      <li class="grid grid-cols-[118px_1fr] items-center gap-3 border-t border-dk-line py-[11px]"><span class="inline-flex items-center gap-1.5 text-[.78rem] font-bold text-dk-good"><svg class="size-[15px] flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Operational</span><div><p class="font-mono text-[.88rem] font-semibold">ap-south-1 <span class="ml-1 font-sans font-normal text-dk-muted">Mumbai</span></p><p class="text-[.76rem] text-dk-muted">p95 163 ms</p></div></li>
      <li class="grid grid-cols-[118px_1fr] items-center gap-3 border-t border-dk-line py-[11px]"><span class="inline-flex items-center gap-1.5 text-[.78rem] font-bold text-dk-info"><svg class="size-[15px] flex-none" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.8-3.8a6 6 0 0 1-7.9 7.9l-6.9 6.9a2.1 2.1 0 0 1-3-3l6.9-6.9a6 6 0 0 1 7.9-7.9z"/></svg>Maintenance</span><div><p class="font-mono text-[.88rem] font-semibold">sa-east-1 <span class="ml-1 font-sans font-normal text-dk-muted">São Paulo</span></p><p class="text-[.76rem] text-dk-muted">Tonight 22:00–23:00 UTC</p></div></li>
    </ul>
  </section>
  <section class="min-w-0 rounded-2xl border border-dk-line bg-dk-bg p-[18px] shadow-[inset_0_1px_0_rgba(255,255,255,.04),0_10px_30px_rgba(0,0,0,.35)]" aria-labelledby="dk-bud-title">
    <div class="mb-3.5 flex flex-wrap items-start justify-between gap-3"><div><h3 class="text-base font-bold" id="dk-bud-title">Error budget</h3><p class="text-[.8rem] text-dk-muted">October · 99.9% availability objective</p></div></div>
    <div class="flex items-center gap-5">
      <div class="relative size-[118px] flex-none" role="progressbar" aria-labelledby="dk-bud-title" aria-valuemin="0" aria-valuemax="100" aria-valuenow="62" aria-valuetext="62% of the error budget left">
        <svg class="size-full -rotate-90" viewBox="0 0 100 100" aria-hidden="true"><circle class="fill-none stroke-dk-line [stroke-width:11]" cx="50" cy="50" r="42"/><circle class="fill-none stroke-dk-series [stroke-width:11] [stroke-linecap:round] [stroke-dasharray:62_100] transition-[stroke-dasharray] duration-600 motion-reduce:transition-none" cx="50" cy="50" r="42" pathLength="100"/></svg>
        <span class="absolute inset-0 grid place-content-center text-center text-[1.35rem] leading-[1.1] font-[750]" aria-hidden="true">62%<small class="block text-[.68rem] font-medium text-dk-muted">left</small></span></div>
      <dl class="grid gap-2 text-[.8rem]">
        <div><dt class="text-dk-muted">Budget left</dt><dd class="font-bold tabular-nums">26 min 47 s of 43 min 12 s</dd></div>
        <div><dt class="text-dk-muted">Burn rate, last 24 h</dt><dd class="font-bold tabular-nums">1.4× (above 1×)</dd></div>
        <div><dt class="text-dk-muted">Runs out at this rate</dt><dd class="font-bold tabular-nums">Oct 29</dd></div>
      </dl>
    </div>
  </section>
</div></div>
CSS
@theme {
  --color-dk-bg: #111827;
  --color-dk-line: #243045;
  --color-dk-ink: #e5e7eb;
  --color-dk-muted: #9aa4b2;
  --color-dk-accent: #60a5fa;
  --color-dk-series: #3987e5;
  --color-dk-good: #4ade80;
  --color-dk-bad: #f87171;
  --color-dk-warn: #fbbf24;
  --color-dk-info: #93c5fd;
}

About this set

An ops dashboard on a near-black ground, where light-theme greys and blues lose contrast. Dark KPI tiles shows uptime, p95 latency, error rate and request volume, each with an outlined delta pill that pairs a signed number and an arrow with words like faster than yesterday or worse than yesterday. The latency chart with an SLO line plots p95 latency over 24 hours as a static SVG area chart with a dashed 300 ms objective; the axis labels are HTML positioned in percentages, so the plot stretches to any width while the text keeps its size, and a visually hidden table holds all twelve readings. Region status and error budget pairs a region list whose statuses read Operational, Degraded or Maintenance with an icon each, and an error budget ring showing 62% left with the minutes remaining, burn rate and the date it runs out at this rate. Use it for monitoring, infrastructure or any night-mode admin. Every colour was checked for contrast on the card colour, and the Bootstrap version runs in data-bs-theme=”dark”. No JavaScript.

What’s included

  • Dark KPI tiles with outlined delta pills
  • Static SVG latency chart with a dashed SLO line
  • HTML axis labels that never scale with the chart
  • Visually hidden data table behind the chart
  • Region status list and error budget ring
  • Bootstrap version uses data-bs-theme="dark"

Accessibility

Text, pills and status words are checked against the dark card colour. The chart is hidden from screen readers and its readings are in a captioned table that is visually hidden but present. Statuses and deltas use words and icons as well as colour, the error budget ring is a labelled progressbar with a value text, and the link has a visible focus outline.

Customise it

Change the --dk- custom properties on .dk for the card, lines, text, series and status colours. In Tailwind edit the dk colours in the @theme block; in Bootstrap the same properties sit beside Bootstrap's dark-mode variables.