Instagram Brand Manual

Components

Charts

Charts organise data to communicate information with clarity, insight, and visual appeal. In the Instagram system, chart chrome stays quiet while colour, motion, and labels help people understand what changed and why it matters.

Creator analyticsLast 7 days · Accounts reached
72K+18.4%

Overview

Charts turn raw metrics into decisions

Charts highlight key information in a dataset. They help people understand patterns, compare values, track change, monitor progress, and decide what to do next.

Creator analytics

Show the post formats, audience segments, and posting windows that move performance.

Post reach

Compare how feed posts, reels, carousels, and collaborations travel across audiences.

Engagement trends

Track likes, comments, shares, saves, replies, and profile actions over time.

Audience growth

Reveal follower growth, churn, geographic shifts, and active-hour patterns.

Ad performance

Monitor spend, impressions, click-through rate, conversions, and cost per result.

Story interactions

Understand taps forward, exits, replies, sticker taps, and completion rate.

Anatomy

Every chart has a job, a structure, and a reading path

A chart is more than marks inside a box. It needs a plot, scale, labels, legends, annotations, and accessibility labels that all support the same message.

Reach by content format
Last 28 days, accounts reached
80K60K40K20K
ReelsPostsStoriesAds
Reels drove the largest lift after remix sharing increased.
Organic reachPaid reach

Plot area

The bounded space where values are encoded. Keep it larger than supporting chrome.

Marks

Bars, lines, points, areas, stacks, and combinations that encode the dataset.

Axes

Scales that map values or categories to position.

Ticks

Small reference stops that divide an axis into readable intervals.

Grid lines

Quiet reference lines for comparison; they should never dominate the marks.

Axis value labels

Short labels that clarify units, dates, or categories.

Titles

The chart's main message in plain language.

Subtitles

Scope, date range, unit, or comparison context.

Annotations

Direct notes on notable shifts, peaks, or anomalies.

Legends

A decoding key for colour, texture, or shape when direct labels are not enough.

Accessibility labels

Programmatic names, summaries, mark labels, and interactive value announcements.

Marks

Choose marks by the question people need answered

Instagram charts should use the simplest mark that communicates the insight. Brand colour and motion can add energy, but the mark must carry the meaning first.

Bar Marks

When to use
Use bars to compare discrete categories, rankings, or short time buckets such as post reach by format.
Communicates best
Bars communicate magnitude and difference quickly because every mark shares a common baseline.
Mistakes to avoid
Do not truncate the baseline when magnitude comparison is the main message. Avoid dense labels on every bar in compact cards.
Instagram treatment
Use flat rounded rectangles, subtle grid lines, and one Instagram gradient or tokenized accent for the selected series. Colour, shape, labels, and motion should support comprehension before they express style.

Line Marks

When to use
Use lines for continuous change over time, such as audience growth, weekly reach, or story completion rate.
Communicates best
Lines communicate direction, pace, turning points, and trend continuity.
Mistakes to avoid
Do not imply precision with too many points or use a line for unrelated categories.
Instagram treatment
Use a confident 2px to 3px stroke, rounded joins, compact points only where inspection is useful, and no heavy chart frame. Colour, shape, labels, and motion should support comprehension before they express style.

Point Marks

When to use
Use points to show individual observations, outliers, or relationships between two measures.
Communicates best
Points communicate distribution, clusters, and exceptions without hiding the original observations.
Mistakes to avoid
Do not rely on colour alone to distinguish groups; shape, label, or position must help.
Instagram treatment
Use circular targets with a larger invisible hit area so touch and keyboard inspection feel forgiving. Colour, shape, labels, and motion should support comprehension before they express style.

Area Marks

When to use
Use areas to emphasize accumulated volume or the weight of a trend, such as total impressions over a campaign window.
Communicates best
Areas communicate scale and continuity when the filled region has a meaningful baseline.
Mistakes to avoid
Do not stack many translucent areas or let the fill obscure labels and grid lines.
Instagram treatment
Use a soft Instagram gradient fill under a clear line, with opacity low enough to keep data readable. Colour, shape, labels, and motion should support comprehension before they express style.

Stacked Marks

When to use
Use stacked marks when the total and the contribution of each segment both matter.
Communicates best
Stacks communicate composition, such as reach from followers, non-followers, ads, and shares.
Mistakes to avoid
Do not compare inner segments across many stacks unless the chart also provides labels or summaries.
Instagram treatment
Use compact rounded stacks, clear legends, and restrained separators between segments. Colour, shape, labels, and motion should support comprehension before they express style.

Combined Marks

When to use
Use combined marks when two related measures need one shared context, such as reach bars plus engagement-rate line.
Communicates best
Combined marks communicate relationship and divergence between volume and rate.
Mistakes to avoid
Do not combine unrelated metrics or use dual axes without explicit units and labels.
Instagram treatment
Give each metric a distinct mark shape and label so colour is supportive, not required. Colour, shape, labels, and motion should support comprehension before they express style.

Axes

Axis ranges should make comparison honest

Axes define what difference means. Keep them stable when people compare charts, and only make them dynamic when the page explains the narrower focus.

Use zero as the lower bound for bars and other length-based comparisons. A truncated bar baseline can exaggerate small differences. For line charts, a non-zero lower bound is acceptable when the chart is about variation inside a range, but the subtitle or annotation must say so.

Tick density should match the available plot width. Use familiar sequences such as 0, 25K, 50K, 75K or 0%, 25%, 50%, 75%, 100%. Keep grid lines subtle and align the chart edges with nearby text, cards, and controls so the chart feels integrated with the surrounding Instagram interface.

Fixed range

Use a fixed range when people compare the same metric across posts, creators, or time windows.

025K50K75K

Dynamic range

Use a dynamic range when the chart's job is to reveal small movement inside a narrow performance band.

7.0%7.5%8.0%8.5%

Compact labels

Use short labels in cards: 1.2K, 4 PM, Mon, Q3, or 8.4%. Expand the unit in the subtitle.

MonWedFriSun
Last 28 days · accounts reached
025K50K75K

Responsive web

Keep four familiar ticks, full labels, and enough plot width for comparison.

Reach · 28 days
050K

Mobile web

Reduce tick density and show the summary before the chart, not after a tooltip.

Stories+12.8%

Embedded cards

Use a spark chart plus the actual value; omit low-value axis chrome.

Descriptive content

Write the message before drawing the chart

Every chart should have a clear main message before people inspect the details. Titles, subtitles, annotations, summaries, labels, and legends should reduce interpretation work.

Title

Lead with the insight: Reels drove the largest reach lift, not Reach by format.

Subtitle

State scope and unit: Last 28 days, accounts reached.

Annotation

Name the cause or event: Remix sharing increased after launch week.

Summary

Give a text version of the takeaway for complex charts and screen readers.

Legend

Use direct labels when possible; use a legend only when it makes comparison easier.

Tone

Use Instagram language that is specific, optimistic, and concrete: Saves rose fastest among carousel posts.

Interaction

Inspection should clarify, not hide the truth

Hover, tap, focus, and scrubbing can reveal exact values, but critical information must remain visible without interaction.

Story interactions

Thu: 25K reach, 1.2K engagements
1.2K

Hover and tap

Highlight the nearest mark and show a value tooltip. Tap should pin the selection until another mark is chosen.

Scrubbing

Let the entire plot area act as the target on touch screens; the visible point can stay small.

Selected marks

Use shape, border, label, or position in addition to colour.

Keyboard

Order focus by reading direction. Arrow keys or range controls can support sequential inspection.

Reduced motion

Disable animated drawing and looping pulse effects. Preserve instant state changes.

Tooltips

Keep values short, include units, and ensure the same information is available in text.

Colour

Use the documented palette without inventing chart hues

Data marks should use semantic Instagram tokens. Reserve the brand gradient for whole-surface treatments and gradient examples, matching the Colour manual instead of creating partial chart-only ramps.

Primary emphasis

Use the exact five-stop spectrum for whole-surface brand moments, not a new chart-specific gradient.

Neutral comparison

Use secondary text, separators, highlights, and elevated backgrounds for inactive series and reference values.

Secondary cues

Pair semantic colour with labels, shape, separators, texture, direct annotations, or selected outlines.

Accessibility

Charts need more than one image alt label

Accessible charts expose purpose, structure, values, and interaction state. Treat the text summary as part of the chart, not an afterthought.

Purpose

Chart showing how story interactions changed across the last seven days.

Axis

Horizontal axis: day of week. Vertical axis: account reach, from 0 to 30 thousand.

Mark

Saturday: 29.2K reach and 1.4K engagements, highest engagement in the week.

Grouped mark

Reels: 42K follower reach, 30K non-follower reach, 8K paid reach.

Legend

Gradient bars show organic reach. Grey bars show paid reach.

Interactive value

Selected value: Thursday, 24.6K reach, 1.2K engagements.

Screen readers

Use labelled figures, summaries, and interactive mark labels. Do not expose only an unlabeled SVG.

Keyboard navigation

Make marks or an equivalent scrubber reachable in logical order.

Reduced motion

Remove animated drawing, shimmer, pulse, and looped transitions unless the user opts in.

High contrast

Preserve visible borders, selected states, and labels when gradients flatten.

Non-colour interpretation

Use text labels, patterns, separators, annotations, and direct values for meaning.

Good label

Saturday: 29.2K reach and 1.4K engagements, highest engagement in the week.

Accessible chart markup
<figure aria-labelledby="reach-title" aria-describedby="reach-summary">
  <h3 id="reach-title">Reels drove the largest reach lift</h3>
  <p id="reach-summary">
    Last 28 days. Reels reached 72K accounts, posts reached 48K,
    stories reached 34K, and ads reached 64K.
  </p>
  <div role="img" aria-label="Bar chart comparing reach by format">
    <button aria-label="Reels, 72 thousand accounts reached">72K</button>
    <button aria-label="Posts, 48 thousand accounts reached">48K</button>
    <button aria-label="Stories, 34 thousand accounts reached">34K</button>
    <button aria-label="Ads, 64 thousand accounts reached">64K</button>
  </div>
</figure>

Best practices

Best Practices

Data first

Make the data more prominent than supporting chrome; axes, containers, and legends exist to clarify the marks.

Subtle reference lines

Keep grid lines quiet and use familiar tick sequences such as 0, 25K, 50K, 75K.

Compact width

Maximise plot width in compact layouts before adding extra panels, controls, or decorative frames.

Visible change

Make important changes noticeable with a direct label, annotation, or selected mark treatment.

No hidden essentials

Never require interaction to reveal the critical value, decision, or warning.

Clear alignment

Align chart edges with surrounding text, cards, and controls so the surface feels native to Instagram.

Concise labels

Keep labels short, concrete, and close to the thing they describe.

Actual values

Use actual numbers and units rather than subjective descriptions such as good, low, or impressive.

Unambiguous formats

Avoid ambiguous dates and units; write Jun 29, 4 PM, 29.2K reach, or 8.4% completion.

Text summaries

Use summaries for complex charts so people understand the takeaway before inspecting details.

Do

  • Make the data more prominent than supporting chrome.
  • Keep grid lines subtle and use familiar tick sequences.
  • Maximise plot width in compact layouts and align charts with surrounding content.
  • Use actual values, clear units, concise labels, and summaries for complex charts.
  • Make important changes noticeable with labels or annotations.

Don’t

  • Never require interaction to reveal critical information.
  • Do not use ambiguous date or unit formats.
  • Do not make colour the only way to understand a group, state, or trend.
  • Do not add dashboard chrome that competes with the marks.

Platform

Platform Considerations

The same chart should adapt its density and inspection model to the surface it lives in.

Responsive web

Let the plot width grow first. Move legends below the chart before shrinking label text.

Mobile web

Prefer one insight, one chart, and one inspection gesture. Keep touch targets larger than the visible mark.

Desktop

Support richer comparison: hover, keyboard focus, visible legends, and persistent selected values.

Embedded cards

Use glanceable summaries and a compact spark chart. Never hide the only important number in a tooltip.

Implementation

Implementation Notes

Build charts from reusable primitives so anatomy, accessibility, interaction, and token usage stay consistent across analytics surfaces.

Reusable chart primitive example
import PageContainer from "@/components/docs/PageContainer";
import Section from "@/components/docs/Section";
import ChartInspector from "./ChartInspector";
import styles from "./charts.module.css";

function ChartPage({ children }) {
  return <PageContainer>{children}</PageContainer>;
}

function ChartHero({ title, summary, children }) {
  return (
    <section className={styles.hero} aria-labelledby="chart-page-title">
      <div>
        <h1 id="chart-page-title">{title}</h1>
        <p>{summary}</p>
      </div>
      {children}
    </section>
  );
}

function ChartLegend({ items }) {
  return (
    <div className={styles.legend} aria-label="Chart legend">
      {items.map((item) => <span key={item.label}>{item.label}</span>)}
    </div>
  );
}

function ChartAccessibilityNote({ children }) {
  return <aside className={styles.accessNote}>{children}</aside>;
}

export default function CreatorReachChart({ data }) {
  const maxReach = Math.max(...data.map((datum) => datum.reach));

  return (
    <ChartPage>
      <ChartHero
        title="Reels drove the largest reach lift"
        summary="Last 28 days, accounts reached by content format."
      >
        <ChartInspector />
      </ChartHero>
      <Section title="Reach by format">
        <figure aria-labelledby="reach-title" aria-describedby="reach-summary">
          <h3 id="reach-title">Reels drove the largest reach lift</h3>
          <p id="reach-summary">
            Last 28 days, accounts reached. Reels reached 72K accounts,
            the highest value in the range.
          </p>
          <div className="chart-bars" aria-label="Reach by content format">
            {data.map((datum) => (
              <button
                key={datum.id}
                type="button"
                className="chart-mark"
                style={{ "--height": (datum.reach / maxReach) * 100 + "%" }}
                aria-label={datum.format + ", " + datum.reach.toLocaleString() + " accounts reached"}
              >
                <span>{datum.label}</span>
              </button>
            ))}
          </div>
          <ChartLegend items={[{ label: "Organic reach" }, { label: "Paid reach" }]} />
        </figure>
        <ChartAccessibilityNote>
          Keep the takeaway available as text; interaction only adds precision.
        </ChartAccessibilityNote>
      </Section>
    </ChartPage>
  );
}
Chart primitive CSS
.chart-bars {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-items: flex-end;
  gap: 12px;
  min-height: 180px;
  border-bottom: 1px solid rgb(var(--ig-separator));
}

.chart-mark {
  height: var(--height);
  min-height: 28px;
  border: 0;
  border-radius: var(--radius-md) var(--radius-md) 0 0;
  background: rgba(var(--ig-secondary-text), 0.32);
  transition: transform 150ms cubic-bezier(0, 0, .1, 1);
}

.chart-mark[aria-current="true"],
.chart-mark:hover,
.chart-mark:focus-visible {
  background: rgb(var(--ig-primary-button));
  transform: translateY(-3px);
}