Skip to main content

Overview

Country briefs are comprehensive, single-screen intelligence dossiers that synthesize all intelligence modules for a specific country. Clicking any country on the map opens a full-page brief with live data, AI-generated analysis, and actionable intelligence.

Brief Structure

Each country brief follows a two-column layout optimized for situational awareness:

Left Column: Analysis & News

Animated SVG score ring (0–100) with:
  • Overall CII score with color-coded severity
  • Four component breakdown bars (Unrest, Conflict, Security, Information)
  • Severity badge: low (0-30), normal (31-50), elevated (51-65), high (66-80), critical (81-100)
  • Trend indicator: rising ↑, stable →, falling ↓
Implementation: src/components/CountryBrief.tsx renders the score using src/services/country-instability.ts
LLM-generated analysis with:
  • Synthesized summary of current situation
  • Key developments and implications
  • Inline citation anchors [1][8] that scroll to corresponding news items
  • Generated by configured provider (Ollama local / Groq / OpenRouter)
  • Language-aware: generates summary in active UI language
Cache strategy: Redis 24h TTL with composite key summary:v3:{mode}:{variant}:{lang}:{hash}
8 most relevant headlines filtered by country relevance:
  • Threat-level color-coded borders (critical: red, high: orange, medium: yellow)
  • Source and time-ago metadata
  • Click to open full article
Relevance filtering: Uses negative-match algorithm where headlines mentioning another country’s alias earlier in the title are excluded to prevent cross-contamination.Example: “Venezuela announces Washington sanctions” would appear in Venezuela brief, NOT US brief, because “Venezuela” appears before “Washington”.

Right Column: Signals & Infrastructure

Real-time chip indicators for:
  • 📢 Protests (count from ACLED)
  • ✈️ Military aircraft (ADS-B tracking)
  • ⚓ Naval vessels (AIS + USNI fleet data)
  • 🌐 Internet outages (Cloudflare Radar)
  • 🔥 Satellite fires (NASA FIRMS thermal hotspots)
  • 🌍 Earthquakes M4.5+ (USGS)
  • 👥 Displacement flows (UNHCR refugees + asylum seekers)
  • 🌡️ Climate stress (ERA5 temperature/precipitation anomalies)
  • 💥 Active strikes (GDELT + Iran attack events)
  • 📈 Stock market index (1-week % change)
D3.js-rendered event chart with:
  • 4 severity-coded lanes (protest, conflict, natural, military)
  • Interactive tooltips on hover
  • Responsive resizing for different screen widths
  • Visual density shows event clustering over time
Top 3 Polymarket contracts by volume:
  • Probability bars (0-100%)
  • External links to market pages
  • 3-tier JA3 bypass (browser-direct → Tauri native TLS → cloud proxy)
Nearby critical infrastructure within 600km of country centroid:
  • 🛢️ Oil & gas pipelines
  • 🌊 Undersea cables (with landing points)
  • 💻 AI datacenters (111 major clusters)
  • 🎖️ Military bases (220+ from 9 operators)
  • ☢️ Nuclear facilities & gamma irradiators
  • ⚓ Strategic ports (83 ports: container, oil, LNG, naval, mixed, bulk)
Distance calculation: Haversine formula from country centroid, ranked by proximity.

Country Alias Mapping

Each curated country has an alias map for accurate news attribution:
{
  code: 'US',
  name: 'United States',
  aliases: [
    'united states', 'usa', 'america', 'american',
    'washington', 'pentagon', 'biden', 'trump'
  ]
}
See full list in src/config/countries.ts

Export Options

Every brief is exportable in three formats:

JSON

Structured data with all scores, signals, and headlines. Includes CII component breakdown, signal counts by type, and full event metadata.

CSV

Flattened tabular format for Excel analysis. One row per country with all metrics as columns.

PNG Image

Rendered screenshot of the brief for sharing. Includes QR code linking back to live dashboard.
Print/PDF support: Native browser print dialog produces clean PDF output with all charts and data preserved.

Universal Country Coverage

Every country with incoming event data receives a live CII score automatically, not just the 23 curated tier-1 nations.
Non-curated countries use sensible default baselines:
  • Default baseline risk: 15 (on 0-100 scale)
  • Default event multiplier: 1.0
  • Display names: Resolved via Intl.DisplayNames API
Example: If a protest event is detected in Kenya (not in curated list), Kenya automatically gets:
  • A calculated CII score based on the protest data
  • A full country brief page (click Kenya on map)
  • Available news, markets, and infrastructure data

Implementation Details

briefPageRoute
string
default:"/brief/:countryCode"
URL pattern for country brief pages. Example: /brief/IR opens Iran’s intelligence dossier.
Shareable story URLs: /story?c=<country>&t=<type> with dynamic Open Graph meta tags.Social preview cards: The /api/og-story endpoint generates 1200×630px SVG cards on-the-fly showing:
  • Country name and flag
  • CII score gauge arc with threat-level coloring
  • 0–100 score bar
  • Signal indicator chips (threats, military, markets, convergence)
Bot detection uses user-agent regex for 10+ known crawlers (Twitter, Facebook, LinkedIn, Telegram, Discord, Reddit, WhatsApp).
cacheStrategy
object
  • AI summaries: Redis 24h TTL, deduplicated by headline hash
  • CII scores: Recalculated on every data refresh (every 5-15 minutes depending on source)
  • Prediction markets: 30-second client-side cache
  • Infrastructure data: Static, loaded at startup

Multi-Platform Sharing

const twitterText = `🚨 ${countryName} Intelligence Brief

📊 Instability Index: ${score}/100 (${level})
🎯 Active Signals: ${signalCount}
⚠️ Threats: ${threatCount}

${topHeadline}

Live dashboard: ${url}`;

Local-First Country Detection

Map clicks resolve to countries using a client-side spatial lookup (no network call):
  1. Bounding box pre-filter — each country polygon is wrapped in bbox [minLon, minLat, maxLon, maxLat]. Points outside are rejected instantly.
  2. Ray-casting algorithm — for points inside bbox, cast ray along positive x-axis. Odd number of polygon edge intersections = inside.
  3. MultiPolygon support — countries with non-contiguous territories (US with Alaska/Hawaii, Indonesia with islands) use MultiPolygon geometries.
Performance: Sub-millisecond detection entirely in browser. GeoJSON data is preloaded at startup and cached for session. Fallback chain: Local geometry → Hardcoded bounding boxes → Network reverse-geocoding (rare)

Example Brief Data

{
  "country": "IR",
  "name": "Iran",
  "cii": {
    "score": 72,
    "level": "high",
    "trend": "rising",
    "change24h": 8,
    "components": {
      "unrest": 45,
      "conflict": 68,
      "security": 82,
      "information": 75
    }
  },
  "signals": {
    "protests": 12,
    "militaryFlights": 24,
    "militaryVessels": 8,
    "internetOutages": 3,
    "satelliteFires": 5,
    "strikes": 18,
    "gpsJamming": "high",
    "convergenceScore": 85
  },
  "topHeadlines": [
    {
      "title": "Iran vows retaliation after strikes on military sites",
      "threat": "critical",
      "source": "Reuters",
      "time": "2 hours ago"
    },
    {
      "title": "IRGC moves naval assets to Strait of Hormuz",
      "threat": "high",
      "source": "AP",
      "time": "5 hours ago"
    }
  ],
  "infrastructure": {
    "pipelines": 8,
    "underseaCables": 2,
    "militaryBases": 14,
    "nuclearFacilities": 3,
    "ports": 6
  },
  "marketSentiment": "bearish",
  "stockIndex": {
    "name": "TEDPIX",
    "change7d": -12.4
  }
}

Key Files

  • src/components/CountryBrief.tsx — Main brief UI component
  • src/services/country-instability.ts — CII calculation engine
  • src/services/story-data.ts — Brief data aggregation
  • src/services/story-renderer.ts — PNG export rendering
  • src/config/countries.ts — Curated country configurations
  • api/og-story.ts — Dynamic Open Graph image generation

Build docs developers (and LLMs) love