AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL unreviewed MIT Self-run

Faostat Infographic

skill-berba-q-faostat-skills-infographic · by berba-q

Use when the user wants a modern, non-expert-facing visual summary of FAOSTAT data on a single page — an infographic, one-pager, visual summary, explainer card, or shareable graphic for social, pitch decks, or press use. The deliverable is a standalone HTML file with inline SVG (optional PNG/PDF export). Aesthetic — Visual Capitalist / Our World in Data explainer cards / Statista — bold typograph…

No reviews yet
0 installs
4 views
0.0% view→install

Install

$ agentstack add skill-berba-q-faostat-skills-infographic

Open-source listing, not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Dangerous shell/eval execution.

What it can access

  • Network access No
  • Filesystem access Used
  • Shell / process execution Used
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Reliability & compatibility

Not yet reviewed
0 installs to date
no reviews yet
5mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Faostat Infographic? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

FAOSTAT Infographic

Build a single-page infographic from FAOSTAT data for a non-expert audience. The reader should grasp the main point in under 10 seconds and the supporting detail in under 30. Aesthetic cue: modern data journalism (Visual Capitalist, OWID explainer cards, Statista) — not FAO yearbooks.

Prerequisites

Before starting, confirm the FAOSTAT MCP tools are available: faostat_get_data, faostat_search_codes, faostat_list_groups, faostat_list_domains, faostat_get_rankings. If not, stop and tell the user this skill requires the FAOSTAT MCP server.

Invariants

Cross-skill invariants (all six — violations are skill bugs):

  1. FILTER vs DISPLAY codes. faostat_get_data takes FILTER codes (e.g., 2510 for Production). faostat_get_rankings takes DISPLAY codes (e.g., 5510). Never invert.
  2. Year syntax. Comma-separated lists only ('2010,2011,...,2023'); colon ranges return empty in practice.
  3. Element filter required on every faostat_get_data call.
  4. TCL for national trade aggregates, TM only for partner breakdowns. Never sum TM rows to reconstruct national totals.
  5. China composite default (Apr 2026 user preference). For any country-level number or ranking, default to composite China (area 351). Offer China, mainland (41) as an opt-in. Flag the choice in the source footer. Map carve-out: if the main visual is a choropleth, the map uses the disaggregation path (area 41 on the CHN polygon; HKG 96 / MAC 128 / TWN 214 on their own polygons). Never blend the two in the same figure.
  6. faostat_get_rankings HTTP-500 fallback. If the call fails, reconstruct by pulling faostat_get_data across all reporting countries and sorting client-side. Note the fallback in the source footer.
  7. Element and item code resolution. Never use a hardcoded numeric element or item code as the primary value in a faostat_get_data call. Always resolve at runtime: faostat_search_codes(domain_code='', dimension_id='element', query='') for elements; faostat_search_codes(domain_code='', dimension_id='item', query='') for items. Numeric codes shown in reference tables and code examples are verified hints — use them to validate the search result, not as the authoritative source. Domain letter-codes (QCL, TCL, GT, EM, FBS, FS…) are stable and may be used directly.

Infographic-specific invariants:

  1. One hero stat. There is exactly one hero number on the page — the most surprising single figure. If you're torn between two, push the second into the supporting-stats row.
  2. One main visual per layout mode. Two modes:
  • Poster mode (default): one chart/map/flow diagram total. A second visual becomes a plain bulleted list or small numeric table — no bar-width indicators, no sparklines.
  • Narrative mode (opt-in): the topic warrants multiple sections — e.g., a trade infographic with (1) global volume hero → (2) top exporters bar chart → (3) trade route flow map. Each section has its own sub-headline and one visual element. Activate when the user's topic is inherently multi-angle OR when they explicitly ask. In narrative mode the hero still appears once at the top; each section's visual is smaller than the hero section. Maximum 3 sections before the takeaway.
  1. Jargon only in the source footer. AR5, AR5 GWP-100, CAGR, n.e.c., FILTER code, DISPLAY code, LULUCF, bare CO2eq, kt/Mt/Gt on first reference, and numeric FAOSTAT element/item codes stay in the source footer. Not in visual titles, subtitles, chart labels, captions, or headlines.
  2. Ten-second test. Read the page aloud in 10 seconds — can a non-expert recite the main point? If not, shrink the headline or enlarge the hero.
  3. No FAO branding. Retain CC-BY-4.0 data attribution ("Data: FAOSTAT (FAO), CC-BY-4.0"), but do not reproduce the FAO logo, "Food and Agriculture Organization of the United Nations" masthead, ISSN, "FAO Statistics Division" stamp, or "Required citation: FAO. …" line. The infographic is the analyst's, not FAO's.

Visual system

Palettes (skill auto-picks by topic; user can override)

| palette | background | hero | accent | text | secondary | fits | |---|---|---|---|---|---|---| | Ember | #0B0B0F | #F6A33F | #FF5C39 | #F3F3F1 | #6D6D74 | climate, emissions, trade, shocks | | Meadow | #F6F5EF | #2E7D4F | #E8A03D | #1F2420 | #6B6E67 | production, food security, nutrition | | Ink | #FAFAFA | #1B1F3A | #E23E57 | #1B1F3A | #7A7D87 | prices, indicators, economic angles |

Topic routing: emissions / temperature / trade disruption → Ember. Crops / livestock / food security / undernourishment → Meadow. Producer prices / CPI / indicators → Ink. If ambiguous, ask the user once.

Typography (fixed)

  • Hero stat: Space Grotesk 700 (or Inter 900 fallback), 120–180 px on desktop, 72–96 px on mobile.
  • Headline: Space Grotesk 700, 40–56 px desktop / 28–36 mobile, ≤ 10 words, plain English.
  • Supporting stats: Space Grotesk 700 for the number, Inter 500 for the caption.
  • Body / takeaway: Inter 400 italic for the takeaway, Inter 400 for everything else.
  • Numbers: IBM Plex Mono 500 for small inline stats inside chart labels (helps numeric alignment).

One font family loaded via Google Fonts (https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;700&family=Inter:wght@400;500;700;900&family=IBM+Plex+Mono:wght@500&display=swap).

Hierarchy (fixed, in page order)

  1. Hero stat — one number, as big as it dares (≥ 30 % of viewport height on desktop). Unit spelled out ("16.5 billion tonnes of CO₂-equivalent", not "16.5 Gt CO₂eq").
  2. Headline — one sentence, ≤ 10 words.
  3. Supporting stats row — 2–4 numbers with a Lucide icon each and a one-line caption. No more than 4.
  4. Main visual — exactly one chart, map, or flow diagram per section. Default layout has one section. Narrative mode (multi-section) adds intermediate sections — see invariant 9.
  5. Takeaway — one italic sentence, plain-English "so-what" framing.
  6. Source footer — "Data: FAOSTAT (FAO), accessed [Month YYYY]. Licence: CC-BY-4.0. Domains: [codes]. China: [composite 351 / mainland 41 per user opt-in / disaggregated for map]."

Everything on one scrollable HTML document, mobile-responsive. The page can be as tall as the story requires — "one page" means no pagination, not one viewport. Max content width 720 px; hero and main visual full-bleed to 1200 px.

Iconography

Inline Lucide SVG icons (MIT licensed, ≤ 1 kB each). Fetch from https://cdn.jsdelivr.net/npm/lucide-static@latest/icons/.svg at build time and paste the SVG inline. Icon colour = palette accent. Icon size: 32 px next to supporting stats, 48 px next to the main visual title.

Two-tier icon selection rule: choose by stat type first (what kind of number is this?), then by domain (what is it about?) when the stat type doesn't resolve it.

Stat-type icons (use these before anything domain-specific):

| Stat type | Icon | Notes | |---|---|---| | Monetary value (USD, EUR, etc.) | banknote | Any dollar/price figure. Do NOT use ship for export value. | | Growth rate / percentage change | trending-up or trending-down | Sign-aware: use trending-down for negative. | | Share / concentration / % of total | pie-chart | "59% shipped by top 5" → pie-chart, not ship. | | Record / all-time peak | flame | "2024 was the peak year" → flame, not calendar. | | Ranking / #1 / leader | trophy | "Russia is the top exporter" → trophy. | | Milestone / threshold crossed | zap | Sudden change, tipping point. | | Count / number of entities | hash | "10 countries account for…" | | Year / time reference (non-record) | calendar | Only when the year itself is the fact, not the record it holds. | | Physical quantity shipped/moved | package | Export volume (tonnes, litres). NOT shipship is the vessel. |

Domain icons (use when the stat type is already resolved by the Lucide icon above, or when you need a second icon):

| Domain | Icon | |---|---| | Agrifood emissions / GHG | cloud | | Crop production | wheat | | Trade route / logistics | ship (only for the concept of shipping, e.g. a section header) | | Temperature / warming | thermometer-sun | | Producer price / CPI | coins | | Yield / efficiency | sprout | | Livestock | beef | | Water | droplet | | Land | mountain | | Food security / hunger | utensils | | Forest / land cover | trees |

Design principles

These principles are extracted from best-in-class data journalism infographics. Apply them every time:

  1. Narrative arc. Every infographic tells a complete arc: scale the problem → show the data → land the implication. Plan the arc in Step 2 before pulling data. If the data doesn't support the arc, reframe — don't just display numbers.
  2. Progressive disclosure. A reader stopping after 5 s gets the hero. One stopping after 15 s gets the supporting stats. One reading fully gets the chart and takeaway. Each layer adds detail without requiring the previous layer to be re-read.
  3. Data-ink ratio. Remove every visual element that doesn't carry a data signal. No decorative borders, no 3-D effects, no unnecessary tick marks, no legend if labels on the data suffice.
  4. Icon as cognitive anchor. Icons beside supporting stats aren't decoration — they help readers recall the number later. Every supporting stat gets exactly one Lucide icon; the icon carries semantic meaning (not generic icons like star or check).
  5. Whitespace as structure. Margins and padding do the job of dividers. Don't add horizontal rules or coloured bands — generous padding between sections is cleaner.
  6. Typography does the heavy lifting. The hero number should be readable from arm's length. If a reader needs to lean in to read the hero, it's too small.

Animations (HTML only)

Scroll-triggered, zero external dependencies — IntersectionObserver + CSS transitions + inline JS. Every animation must respect prefers-reduced-motion: reduce via a single early-return guard.

Hero counter — the hero number counts from 0 to its final value over 1.2 s (ease-out cubic). Store the numeric portion in data-value on .hero-stat; keep unit and prefix in separate `` elements so only the digit string animates.

Supporting-stats cascade — each .stat card starts invisible (opacity: 0; transform: translateY(16px)) and transitions in with a 100 ms stagger as the section enters the viewport.

Bar chart draw — each bar ` starts at width="0" (or height="0"` for horizontal). Set the target dimension via a CSS custom property; transition to it over 0.8 s with 50 ms per-bar stagger.

Line chart draw — set stroke-dasharray equal to the path's getTotalLength() at paint time; start stroke-dashoffset at that same value and transition to 0 over 1.4s cubic-bezier(0.25, 1, 0.5, 1). Triggered by an IntersectionObserver adding .visible.

Hero glow pulse (Ember palette only) — a repeating box-shadow keyframe on the hero stat container. Fades an amber glow in and out over 2 s. Omit on Meadow and Ink — those topics don't warrant urgency drama.

Trade route arcs + moving icons — for flow maps. Three layered animations:

  1. Arc draw: stroke-dashoffset transitions from full path length to 0, staggered 200 ms per route, 1.2 s each.
  2. Icon travel: CSS offset-path matching the arc's Bézier definition; offset-rotate: auto keeps the icon facing the direction of travel.
  3. Pulse dot at destination: a small circle at the importer centroid scales from 0 → 1.4 → 1 (transform: scale) when the icon arrives, timed via animation-delay.
/* Arc draw-on */
.trade-arc {
  stroke-dasharray: var(--arc-len);   /* set via JS: el.style.setProperty('--arc-len', path.getTotalLength()) */
  stroke-dashoffset: var(--arc-len);
  transition: stroke-dashoffset 1.2s cubic-bezier(.4,0,.2,1);
}
.trade-arc.visible { stroke-dashoffset: 0; }

/* Icon travel — offset-path set inline per route */
.trade-icon {
  offset-rotate: auto;
  animation: _travel var(--dur, 5s) linear var(--delay, 0s) infinite;
}
@keyframes _travel {
  0%   { offset-distance: 0%;   opacity: 0; }
  5%   { opacity: 1; }
  95%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 0; }
}

/* Destination pulse */
.dest-dot {
  animation: _pulse 0.4s ease-out var(--arrive-delay, 4.8s) both;
}
@keyframes _pulse {
  0%   { transform: scale(0); opacity: 1; }
  70%  { transform: scale(1.4); }
  100% { transform: scale(1); opacity: 0.6; }
}

Standard JS boilerplate (inline ` at end of `):

document.addEventListener('DOMContentLoaded', () => {
  if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;

  const io = new IntersectionObserver((entries) => {
    entries.forEach(e => {
      if (!e.isIntersecting) return;
      e.target.classList.add('visible');
      if (e.target.classList.contains('hero-stat')) _counter(e.target);
      if (e.target.dataset.draw) _drawPath(e.target);
      io.unobserve(e.target);
    });
  }, { threshold: 0.15 });

  document.querySelectorAll('.hero-stat, .stat, [data-draw]').forEach(el => io.observe(el));

  function _counter(el) {
    const end = parseFloat(el.dataset.value);
    const decimals = (String(end).split('.')[1] ?? '').length;
    const t0 = performance.now();
    (function tick(now) {
      const p = Math.min((now - t0) / 1200, 1);
      const v = (end * (1 - Math.pow(1 - p, 3))).toFixed(decimals);
      el.querySelector('.counter-value').textContent = v;
      if (p  { el.style.strokeDashoffset = 0; });
  }
});

CSS additions inside ``:

@media (prefers-reduced-motion: no-preference) {
  .stat { opacity: 0; transform: translateY(16px);
          transition: opacity .5s ease, transform .5s ease; }
  .stat.visible { opacity: 1; transform: none; }
  .stat:nth-child(2) { transition-delay: .1s; }
  .stat:nth-child(3) { transition-delay: .2s; }
  .stat:nth-child(4) { transition-delay: .3s; }

  /* Ember palette hero pulse */
  body.palette-ember .hero-stat {
    animation: _glow 2s ease-in-out infinite;
  }
  @keyframes _glow {
    0%, 100% { box-shadow: 0 0 0 transparent; }
    50%       { box-shadow: 0 0 52px rgba(246,163,63,.30); }
  }
}

Add class="palette-ember" (or palette-meadow / palette-ink) to `` to activate the correct palette-scoped animation rules.

Workflow

Step 1 — Gather parameters

Ask the user (via AskUserQuestion if Cowork, inline otherwise) for anything not specified:

  • Topic / angle
  • Time window (endpoint year + optional start year for a change framing)
  • Scope: global (default) / a region / a country
  • Palette preference (Ember / Meadow / Ink / auto-pick)
  • Output format preferences: HTML only (default), + PNG, + PDF, + companion CSV

Proceed without a second clarifying round — one is enough. Pick sensible defaults for anything still unspecified.

Step 2 — Design the hero message

From the topic, identify the single most striking stat. Rules of thumb:

  • Biggest delta over the window (e.g., "+127 % in aquaculture output since 2000", "+48.8 % in pre- and post-production emissions since 2001", "wheat yield in the EU grew 3× faster than Sub-Saharan Africa over 30 years")
  • Most extreme ratio (e.g., "4× gap in cattle-meat emissions intensity between Africa and Europe", "top 5 countries account for 72 % of global wheat production")
  • Most surprising ranking (e.g., "India overtook the US as the world's top rice exporter in 2021", "top 10 emitters = 55 % of world total")
  • A number at the edge of intuition (e.g., "815 million people undernourished — roughly 1 in 10", "16.5 billion tonnes of CO₂-equivalent", "Brazil's soybean exports tripled in 20 years")

This becomes the hero + headline. Draft both before pulling data — if the narrative falls apart on the numbers, rewrite.

Step 3 — Plan supporting stats and visual

2–4 suppo

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.