import type { Ranking } from "@dci/core"; import type { Metadata } from "next"; import Link from "next/link"; import { SectionNav } from "@/components/entity/section-nav"; import { Badge } from "@/components/ui/badge"; import { Card, CardBody, CardHeader, Page, PageHeader, Section } from "@/components/ui/card"; import { BarList } from "@/components/ui/charts"; import { EmptyState, OfflineNotice } from "@/components/ui/states"; import { api } from "@/lib/api"; import { fmtDate, fmtInt } from "@/lib/format"; import { routes } from "@/lib/routes"; import { pageMetadata } from "@/lib/seo"; import { SCOPE_LABEL, SCOPE_ORDER, firstSentence, fmtRankValue, rowHref } from "../ranking-format"; export const revalidate = 120; export const metadata: Metadata = pageMetadata({ title: "Rankings", description: "Countries, markets and operators ranked by facilities, known capacity and pipeline. Every MW-based ranking carries its coverage; entities below the coverage gate are excluded, not estimated.", path: routes.rankings(), }); /* Verbatim from docs/RANKINGS.md — “Definitions shared by all rankings”. */ const DEFINITIONS: Array<{ term: string; text: string }> = [ { term: "Known MW", text: "Σ over operational facilities of IT capacity, or total power when the operator publishes only that. Figures marked as estimates count only when no measured figure exists for the facility, and the facility is flagged mw_is_estimate. We never impute MW to facilities without a published or filed figure." }, { term: "Pipeline MW", text: "Σ over facilities not yet operational of planned power (or IT/total power when no planned figure is published), split into planned MW (planning statuses) and construction MW (under construction)." }, { term: "Coverage", text: "Facilities with any MW figure ÷ facilities." }, { term: "Coverage gate", text: "MW-based and per-capita rankings exclude entities with fewer than 5 facilities or coverage below 35 % (minCoverage), so that thin data does not produce spurious leaders. Count-based rankings have no gate." }, { term: "Delta", text: "Rank change versus the previous snapshot of the same ranking (positive = moved up)." }, ]; function RankingCard({ r }: { r: Ranking }) { const top = (r.rows ?? []).slice(0, 3); return (
  • {r.label} {r.unit}

    {firstSentence(r.methodology ?? "")}

    {r.total > 0 ? ( {fmtInt(r.total)} {r.total === 1 ? "entity" : "entities"} ranked ) : ( {/mw|per/i.test(r.unit) ? "No entity meets the coverage gate yet" : "No rows computed yet"} )} Computed {fmtDate(r.computedAt)} Full ranking →
    {top.length > 0 && (
    ({ label: row.name, value: row.value, href: rowHref(row, r.scope), rank: row.rank, coverage: row.coverage, display: fmtRankValue(row.value, r.unit) }))} showRank />
    )}
  • ); } export default async function RankingsPage() { const list = await api.rankings(); const ok = list.length > 0; const groups = SCOPE_ORDER.map((scope) => ({ scope, items: list.filter((r) => r.scope === scope).sort((a, b) => a.label.localeCompare(b.label)) })).filter((g) => g.items.length); return ( {!ok && } {ok && ({ id: g.scope, label: SCOPE_LABEL[g.scope], count: g.items.length }))} className="mb-4" />} {!ok && }

    Method Known / published figures only — every MW value is the sum of figures a source published or filed (containment-aware: a campus and its buildings are never both counted); entities without a figure are absent, not estimated. MW-based rankings apply a coverage gate (≥ 5 facilities and ≥ 35 % of them with a figure), so a short list means thin disclosure, not few players. Count-based rankings have no gate. AI, project and IXP rankings appear here as soon as the worker computes them.

    {groups.map((g) => (
      {g.items.map((r) => ( ))}
    ))}
    {DEFINITIONS.map((d) => (
    {d.term}
    {d.text}
    ))}

    Facility = a live record (merged duplicates excluded), any status. Operational = operational, partially operational or expansion. Under construction = under_construction. Planned = rumored, proposed, announced, permitting, approved or delayed.{" "} Full methodology

    ); }