# DataCenterIndex — Design system (apps/web) Industrial, precise, authoritative. Our World in Data × a terminal for digital infrastructure × a global infrastructure map. The UI is **image-free** (SVG only), **mobile-first** (320–430 px first), light by default with a true dark theme (`next-themes`, class strategy). What we avoid: generic SaaS cards, neon/cyberpunk, fake terminals, heavy gradients, oversized heroes, giant rounded rectangles, card soup, dual-axis charts, rainbow palettes. ## Tokens (`apps/web/src/app/globals.css`, Tailwind v4 `@theme`) | Token | Light | Dark | Use | |---|---|---|---| | `--paper` / `bg-paper` | `#f5f4f1` | `#0b0f14` | page background | | `--surface` / `bg-surface` | `#ffffff` | `#10161d` | panels, table header, sheets | | `--surface-2`, `--surface-3` | `#efeeea`, `#e6e4df` | `#161d25`, `#1d252e` | hover rows, skeletons, bar tracks | | `--ink` … `--ink-4` | `#0b0f14 → #9a9fa5` | `#eceae5 → #5b6168` | text hierarchy (ink, ink-2 body, ink-3 meta, ink-4 hint) | | `--hair`, `--hair-2` | `#e3e1dc`, `#c9c6bf` | `#1f272f`, `#2f3941` | 1 px borders (never shadows) | | `--accent`, `--accent-ink`, `--accent-soft` | `#c8541a` | `#e8763a` | THE accent: pipeline, emphasis, primary CTA, live dot | Status scale (validated with the dataviz six-checks: lightness-separated blue/violet; every colour ships with a label): | Tone | Statuses | Light | Dark | |---|---|---|---| | `st-operational` | operational, partially_operational, expansion | `#1f6b3a` | `#3fa465` | | `st-construction` | under_construction | `#b87a0a` | `#d4962a` | | `st-planned` | announced, proposed | `#5f8fc4` | `#7fb0e6` | | `st-permitting` | permitting, approved | `#5b3f8f` | `#8a6bc9` | | `st-delayed` | delayed | `#a94a2a` | `#d9704a` | | `st-closed` | cancelled, closed | `#858a90` | `#6f757c` | | `st-rumored` | rumored (drawn **dotted**) | `#8f95a0` | `#7b828c` | | `st-unknown` | unknown | `#b3b6ba` | `#4d545b` | Mapping lives in `lib/labels.ts` (`STATUS_TONE`, `STATUS_LABEL`, `statusVar()`); the map reads the CSS variables at runtime so it follows the theme. ### Claim-first visual language (2026-09-12, §76–78) One vocabulary for every figure, shared by badges, tables, the evidence drawer, the map legend and the OG images: | Dimension | Values (label) | Rendering | Component | |---|---|---|---| | Status / stage | Operational · Partially operational · Under construction · Approved · Permitting · Announced · Proposed · Rumored (dotted) · Delayed · Cancelled · Closed | dot in the status tone + exact label; the same tones colour project stages (`StageBadge`), funnel bars and map markers | `StatusBadge`, `StageBadge`, `StatusDot` | | Confidence | Verified · High · Moderate · Estimated · Unverified | 4-dot meter in ink (never red/amber): **Moderate must not look alarming** — only *Estimated* uses the warn dot colour | `ConfidenceBadge` | | Source / provenance kind | OPERATOR · GOVERNMENT · UTILITY · FILING · REGISTRY · CLOUD (primary, filled dot) — DATASET · NEWS · SECONDARY · COMMUNITY (secondary, hollow dot) | upper-case tracked label; hover / focus tooltip shows source name, published, retrieved and whether an archived copy exists | `SourceBadge` (client) | | Scope | Building · Facility · Campus (site scopes, filled square) — Metro · Country · Portfolio · Company-wide · Scope unknown (hollow dashed square) | non-site scopes are never summed into a record; they appear under “Figures not assigned to this site” | `ScopeBadge` | | Semantics | IT capacity · Critical power · Total power · Planned · Grid connection · Utility · Ultimate build-out · Phase capacity (+ investment predicates) | small caps label under every MW figure so “300 MW” always says what it measures | `SemanticsLabel`, `semanticsLabel()` | | Authority tier | A–E **for this field** (never a universal source rank) | mono letter in a hairline box, tooltip with the tier meaning | `TierMark` | | Significance | Major (accent) · Medium · Minor | 3 bars; only *major* uses the accent | `SignificanceBadge`, `SignificanceMark` | | AI evidence | confirmed · likely · associated | accent diamond + “AI” (+ level when not confirmed) | `AiMark` | | Winner | “shown” | tiny accent-soft chip on the observation / claim backing the displayed value | provenance table, claims table, drawer | | Extraction method | Structured data · Parser · Sentence extraction · Human-reviewed · Model-assisted · Method not recorded | derived from `method` / `parserName` via `extractionKind()` | evidence drawer | Honesty states: an unknown figure is `—` with the reason underneath (“Not published by any source”, “No expansion figure published”, “date not published”), never `0`; empty API layers render the API `note`; totals carry their coverage caveat (“MW published for 6 % of facilities — lower bound”); planned figures and estimates carry `≈`. **Evidence drawer** (`components/evidence`, §24/§80): wrap any important figure in `` (dotted underline, real `