TypeScript 97.5%
SQL 1.4%
Python 0.8%
1/**2 * Shared chart styling. All colors are CSS variables so charts follow light/dark themes.3 * Success/failed use status tokens (they *mean* good/bad); every chart pairs color with4 * a text legend and a table twin so identity is never carried by color alone.5 */6export const CHART_COLORS = {7 accent: "var(--accent)",8 success: "var(--success)",9 danger: "var(--danger)",10 warning: "var(--warning)",11 info: "var(--info)",12 muted: "var(--fg-subtle)",13 faint: "var(--border-strong)",14 grid: "var(--border)",15 surface: "var(--bg-elevated)",16 cursor: "var(--bg-muted)",17} as const;1819/** Network classes get a fixed color per entity: residential (live) is emphasized, the rest are neutral. */20export const NETWORK_COLORS: Record<string, string> = {21 residential: CHART_COLORS.accent,22 datacenter: CHART_COLORS.muted,23 isp: CHART_COLORS.faint,24 mobile: CHART_COLORS.info,25};2627export const AXIS_TICK = { fill: "var(--fg-subtle)", fontSize: 11, fontFamily: "var(--font-mono)" } as const;2829export const CHART_MARGIN = { top: 8, right: 8, bottom: 0, left: 0 } as const;3031export function formatTick(iso: string, bucket: "hour" | "day"): string {32 const d = new Date(iso);33 if (bucket === "hour") return new Intl.DateTimeFormat("en-US", { hour: "numeric", timeZone: "UTC" }).format(d);34 return new Intl.DateTimeFormat("en-US", { month: "short", day: "numeric", timeZone: "UTC" }).format(d);35}3637export function formatBucketLabel(iso: string, bucket: "hour" | "day"): string {38 const d = new Date(iso);39 if (bucket === "hour") return `${new Intl.DateTimeFormat("en-US", { month: "short", day: "numeric", hour: "numeric", timeZone: "UTC" }).format(d)} UTC`;40 return new Intl.DateTimeFormat("en-US", { weekday: "short", month: "short", day: "numeric", timeZone: "UTC" }).format(d);41}42