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;
}

React code

Requires: React 19, Tailwind CSS 4

JSX
// Dark ops dashboard: KPI tiles, a p95 latency area chart with an SLO line (static SVG plus a
// visually hidden data table), region status and an error-budget ring. Colours come from the
// dk-* @theme tokens in the CSS block; status always pairs an icon with a word.
// Usage: <DarkOpsWidgets kpis={[…]} latency={[{ time, ms }]} regions={[…]} budget={{…}} />
import { useId } from 'react';

const TONE = { good: 'text-dk-good', bad: 'text-dk-bad', info: 'text-dk-info', warn: 'text-dk-warn' };
const ARROW = { up: 'M12 19V5M5 12l7-7 7 7', down: 'M12 5v14M19 12l-7 7-7-7' };

const defaultKpis = [
  { title: 'Uptime, 30 days', value: '99.98%', delta: '+0.03 pts', dir: 'up', tone: 'good', note: 'vs September' },
  { title: 'p95 latency', value: '182 ms', delta: '−24 ms', dir: 'down', tone: 'good', note: 'faster than yesterday' },
  { title: 'Error rate', value: '0.21%', delta: '+0.05 pts', dir: 'up', tone: 'bad', note: 'worse than yesterday' },
  { title: 'Requests today', value: '4.82M', delta: '+8.6%', dir: 'up', tone: 'info', note: 'vs last Friday' },
];

const defaultLatency = [
  { time: '00:00', ms: 168 }, { time: '02:00', ms: 152 }, { time: '04:00', ms: 149 }, { time: '06:00', ms: 171 },
  { time: '08:00', ms: 236 }, { time: '10:00', ms: 284 }, { time: '12:00', ms: 247 }, { time: '14:00', ms: 219 },
  { time: '16:00', ms: 205 }, { time: '18:00', ms: 196 }, { time: '20:00', ms: 188 }, { time: '22:00', ms: 182 },
];

const REGION_STATUS = {
  degraded: { label: 'Degraded', tone: 'warn', icon: <><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" /></> },
  operational: { label: 'Operational', tone: 'good', icon: <path d="M20 6 9 17l-5-5" /> },
  maintenance: { label: 'Maintenance', tone: 'info', icon: <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" /> },
};

const defaultRegions = [
  { id: 'eu-west-1', place: 'Ireland', status: 'degraded', note: 'p95 284 ms at peak' },
  { id: 'us-east-1', place: 'Virginia', status: 'operational', note: 'p95 141 ms' },
  { id: 'ap-south-1', place: 'Mumbai', status: 'operational', note: 'p95 163 ms' },
  { id: 'sa-east-1', place: 'São Paulo', status: 'maintenance', note: 'Tonight 22:00–23:00 UTC' },
];

const defaultBudget = {
  objective: 'October · 99.9% availability objective', left: 62,
  facts: [
    { term: 'Budget left', value: '26 min 47 s of 43 min 12 s' },
    { term: 'Burn rate, last 24 h', value: '1.4× (above 1×)' },
    { term: 'Runs out at this rate', value: 'Oct 29' },
  ],
};

const panel = '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)]';
const label = 'mb-4 block text-[.72rem] tracking-[.12em] text-dk-muted uppercase';
const svgProps = { viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2.5', strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': 'true' };

function KpiTile({ kpi: k }) {
  return (
    <article className={panel}>
      <h3 className="text-[.8rem] font-semibold text-dk-muted">{k.title}</h3>
      <p className="mt-1 mb-1.5 text-[1.8rem] leading-[1.2] font-[750] tracking-[-.02em] tabular-nums">{k.value}</p>
      <p className="flex flex-wrap items-center gap-2 text-[.78rem] text-dk-muted">
        <span className={`inline-flex items-center gap-[3px] rounded-full border border-current py-px pr-2 pl-1.5 font-bold tabular-nums ${TONE[k.tone]}`}>
          <svg className="size-[13px]" {...svgProps}><path d={ARROW[k.dir]} /></svg>{k.delta}
        </span>
        {k.note}
      </p>
    </article>
  );
}

// Static area chart in a 600×200 box; y runs from `min` (bottom) to `max` (top) milliseconds.
function LatencyChart({ points, slo = 300, min = 100, max = 320, ticks = [300, 200, 100], timeLabels = [0, 4, 8, 11] }) {
  const r1 = (v) => Math.round(v * 10) / 10;
  const x = (i) => r1((i * 600) / (points.length - 1));
  const y = (ms) => r1(200 - ((ms - min) / (max - min)) * 200);
  const line = points.map((p, i) => `${i ? 'L' : 'M'}${x(i)} ${y(p.ms)}`).join('');
  const peak = points.reduce((a, p) => (p.ms > a.ms ? p : a), points[0]);
  const pct = (v) => `${r1(v)}%`;
  return (
    <figure className={panel}>
      <div className="mb-3.5 flex flex-wrap items-start justify-between gap-3">
        <div><h3 className="text-base font-bold">p95 latency, all regions</h3><p className="text-[.8rem] text-dk-muted">Last 24 hours · peak {peak.ms} ms at {peak.time}</p></div>
        <p className="flex gap-3.5 text-[.76rem] text-dk-muted" aria-hidden="true">
          <span className="inline-flex items-center gap-1.5"><i className="w-4 border-t-2 border-dk-series" />p95</span>
          <span className="inline-flex items-center gap-1.5"><i className="w-4 border-t-2 border-dashed border-dk-warn" />SLO {slo} ms</span>
        </p>
      </div>
      <div className="relative ml-[46px] h-[190px]">
        <svg className="absolute inset-0 size-full overflow-visible" viewBox="0 0 600 200" preserveAspectRatio="none" aria-hidden="true">
          <line className="stroke-dk-line" x1="0" x2="600" y1="200" y2="200" vectorEffect="non-scaling-stroke" />
          <line className="stroke-dk-line" x1="0" x2="600" y1={y(200)} y2={y(200)} vectorEffect="non-scaling-stroke" />
          <path className="fill-dk-series opacity-16" d={`${line}L600 200L0 200Z`} />
          <path className="fill-none stroke-dk-series [stroke-width:2.5] [stroke-linecap:round] [stroke-linejoin:round]" d={line} vectorEffect="non-scaling-stroke" />
          <line className="stroke-dk-warn [stroke-dasharray:5_4] [stroke-width:1.5]" x1="0" x2="600" y1={y(slo)} y2={y(slo)} vectorEffect="non-scaling-stroke" />
        </svg>
        <div aria-hidden="true">
          {ticks.map((t) => (
            <span key={t} className="absolute right-[calc(100%+8px)] -translate-y-1/2 text-[.7rem] whitespace-nowrap text-dk-muted tabular-nums" style={{ top: pct(y(t) / 2) }}>{t} ms</span>
          ))}
        </div>
        <span className="absolute right-0 -translate-y-[120%] text-[.7rem] font-bold text-dk-warn" style={{ top: pct(y(slo) / 2) }} aria-hidden="true">SLO</span>
      </div>
      <div className="relative mt-1.5 ml-[46px] h-[22px] text-[.7rem] text-dk-muted tabular-nums" aria-hidden="true">
        {timeLabels.map((i, n) => {
          const edge = n === 0 ? '' : n === timeLabels.length - 1 ? '-translate-x-full' : '-translate-x-1/2';
          return <span key={i} className={`absolute ${edge}`} style={{ left: pct((i / (points.length - 1)) * 100) }}>{points[i].time}</span>;
        })}
      </div>
      <div className="sr-only">
        <table>
          <caption>p95 latency every two hours today, all regions. Objective: under {slo} ms.</caption>
          <thead><tr><th scope="col">Time</th><th scope="col">p95 latency</th></tr></thead>
          <tbody>{points.map((p) => <tr key={p.time}><th scope="row">{p.time}</th><td>{p.ms} ms</td></tr>)}</tbody>
        </table>
      </div>
    </figure>
  );
}

function Regions({ regions }) {
  const titleId = useId();
  const ok = regions.filter((r) => r.status !== 'degraded').length;
  return (
    <section className={panel} aria-labelledby={titleId}>
      <div className="mb-3.5 flex flex-wrap items-start justify-between gap-3">
        <div><h3 className="text-base font-bold" id={titleId}>Regions</h3><p className="text-[.8rem] text-dk-muted">{ok} of {regions.length} fully operational</p></div>
        <a href="#" className="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>
        {regions.map((r) => {
          const s = REGION_STATUS[r.status];
          return (
            <li key={r.id} className="grid grid-cols-[118px_1fr] items-center gap-3 border-t border-dk-line py-[11px]">
              <span className={`inline-flex items-center gap-1.5 text-[.78rem] font-bold ${TONE[s.tone]}`}><svg className="size-[15px] flex-none" {...svgProps}>{s.icon}</svg>{s.label}</span>
              <div>
                <p className="font-mono text-[.88rem] font-semibold">{r.id} <span className="ml-1 font-sans font-normal text-dk-muted">{r.place}</span></p>
                <p className="text-[.76rem] text-dk-muted">{r.note}</p>
              </div>
            </li>
          );
        })}
      </ul>
    </section>
  );
}

function ErrorBudget({ budget: b }) {
  const titleId = useId();
  return (
    <section className={panel} aria-labelledby={titleId}>
      <div className="mb-3.5 flex flex-wrap items-start justify-between gap-3"><div><h3 className="text-base font-bold" id={titleId}>Error budget</h3><p className="text-[.8rem] text-dk-muted">{b.objective}</p></div></div>
      <div className="flex items-center gap-5">
        <div className="relative size-[118px] flex-none" role="progressbar" aria-labelledby={titleId} aria-valuemin={0} aria-valuemax={100} aria-valuenow={b.left} aria-valuetext={`${b.left}% of the error budget left`}>
          <svg className="size-full -rotate-90" viewBox="0 0 100 100" aria-hidden="true">
            <circle className="fill-none stroke-dk-line [stroke-width:11]" cx="50" cy="50" r="42" />
            <circle className="fill-none stroke-dk-series [stroke-width:11] [stroke-linecap:round] transition-[stroke-dasharray] duration-600 motion-reduce:transition-none" style={{ strokeDasharray: `${b.left} 100` }} cx="50" cy="50" r="42" pathLength="100" />
          </svg>
          <span className="absolute inset-0 grid place-content-center text-center text-[1.35rem] leading-[1.1] font-[750]" aria-hidden="true">{b.left}%<small className="block text-[.68rem] font-medium text-dk-muted">left</small></span>
        </div>
        <dl className="grid gap-2 text-[.8rem]">
          {b.facts.map((f) => (
            <div key={f.term}><dt className="text-dk-muted">{f.term}</dt><dd className="font-bold tabular-nums">{f.value}</dd></div>
          ))}
        </dl>
      </div>
    </section>
  );
}

export default function DarkOpsWidgets({ kpis = defaultKpis, latency = defaultLatency, regions = defaultRegions, budget = defaultBudget }) {
  return (
    <div className="flex flex-col gap-[46px] text-dk-ink">
      <div><span className={label}>Dark KPI tiles</span>
        <div className="grid grid-cols-[repeat(auto-fit,minmax(210px,1fr))] gap-3.5">{kpis.map((k) => <KpiTile key={k.title} kpi={k} />)}</div>
      </div>
      <div><span className={label}>Latency chart with an SLO line</span><LatencyChart points={latency} /></div>
      <div><span className={label}>Region status and error budget</span>
        <div className="grid grid-cols-[repeat(auto-fit,minmax(min(100%,300px),1fr))] gap-3.5"><Regions regions={regions} /><ErrorBudget budget={budget} /></div>
      </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.