15

Analytics

Data Visualization Builder Component

A complete charting system for adoption analytics, reporting dashboards, and admin data views. All charts use the six-color brand palette, DM Sans typography, and consistent grid/axis styling. Charts are built with inline SVG for maximum portability.

Supported chart types: vertical bar, grouped bar, stacked bar, horizontal bar, line, donut, KPI strip, bullet chart, top assets, trending assets, emerging trends, top themes, sentiment, quotes, data table.

If the chart type you need is not in that list (scatter, treemap, heatmap, waterfall, radar, etc.) — do not hand-roll a custom SVG chart. Present the user with two choices:
(A) Use the closest supported chart type (name it) and note the trade-off.
(B) Flag the gap to the design system owner as a gap that may need a new chart builder.

KPI Strip — Stat Cards Component

The primary unit for surfacing metrics at the top of any dashboard or report page. Each card shows a single number, a label, and an optional delta indicator.

Tokens: Container=white card, --radius-card, --border-default · Label=10px 500 uppercase 1px tracking #aaa · Value=28px DM Sans 400 --color-alpine · Delta up=--color-uinta · Delta down=--color-canyonlands · Neutral=#aaa · Use --color-arches on the value itself when the number is a warning metric.

Vertical Bar Chart Component

Used for comparing discrete categories or time-series values. Bar fill uses --chart-1 (Alpine) by default; a second series uses --chart-2 (Wasatch).

Spec: Bar fill=--chart-1 · Corner radius=3px · Value label: 11px DM Sans 500, Alpine, 4px above bar · Axis labels: 10px #aaa · Grid: dashed 4/3 --chart-grid · Axis line: --chart-axis · Reference line: --color-arches dashed · viewBox aspect: 640×240

Grouped Bar Chart Component

Two series side-by-side per category. Use for period-over-period comparisons. First series=--chart-1, second=--chart-2.

Spec: Groups spaced with 20px gap between clusters · Series gap=4px within group · Legend: 10px dot (2px radius), 11px DM Sans, body text · Same grid/axis rules as vertical bar

Stacked Bar Chart Component

Shows part-to-whole relationships within each category. Up to 4 segments per bar using --chart-1 through --chart-4.

Spec: Bar height 24px · Segments: 1px gap, no border-radius on inner segments · Label col: 130px right-aligned, 12px DM Sans · Value col: 36px right-aligned, 12px medium · Segment colors in order: muted Alpine tint / --chart-2 / --chart-4 / --color-canyonlands

Horizontal Bar Chart Component

Best for ranked lists with long category labels. Bars grow left to right; track uses --chart-grid as background.

Spec: Track height=12px, radius=pill · Fill radius=pill · Label col=130px · Value col=36px · Use --chart-4 (Uinta green) for high performers ≥80%, --chart-1 (Alpine) for mid range, --color-arches for at-risk rows below threshold

Line Chart Component

Time-series trends. Up to 3 lines using --chart-1, --chart-2, --chart-3. Dots on data points. Area fill is the series color at 8% opacity.

Spec: Line weight=2px · Data dots=3.5px radius, white fill + series stroke · Terminal dot=4px filled · Area fill=series color at 8–1% gradient · Dashed line for secondary/comparison series (6/3 dash) · All coordinates computed as y=baseline−(value×scale)

Data Detail Table Component

The primary structure for drilling into row-level data. Extends the base table with numeric alignment, trend indicators, inline mini-bars, and status chips. Sortable headers use Alpine on hover.

Spec: Outer wrapper=.chart-card with padding:0 — title/subtitle sit in a 20px 24px padded header above the table · Table border-top separates header from rows · Table bg=white (set on .data-table-wrap) · Column headers: 10px 500 uppercase 1.2px tracking #888 · Header row bg=--color-salt · Body cells: 13px DM Sans body · Numeric cells: right-aligned, tabular-nums · Trend up=--color-uinta · Trend down=--color-canyonlands · Progress bar: 100px, system progress tokens · Footer: Salt bg, 12px #888, pagination controls

Donut / Proportion Chart Component

For part-to-whole proportions with ≤5 segments. Center shows the primary metric. Legend on the right with exact values.

Spec: SVG circle r=42, stroke-width=16 (inner r=26, outer r=58) · Circumference=263.9px · Segments built with stroke-dasharray + stroke-dashoffset · Rotation offset=-90° for 12 o'clock start · Center: 18px 500 metric value + 9px label · Donut width 120px · Legend right-aligned, bold 12px value

Chart Color Palette & Usage Rules

Chart 1
Alpine — Primary series, default bars
Chart 2
Wasatch — Secondary series, comparison
Chart 3
Timpanogos — Separates Alpine & Uinta
Chart 4
Arches — Copper, tertiary
Chart 5
Uinta — Success / high performance
Chart 6
Bonneville — Light accent, backgrounds
Chart palette rules: Always use series colors in order (1→2→3…) — never skip. Greens separation rule: Timpanogos (--chart-3) sits between Alpine (--chart-1) and Uinta (--chart-5) in the numbered sequence — they are never adjacent. If a 2-series chart would pair Alpine and Uinta directly, substitute Timpanogos for one of them. Use --color-canyonlands only for error/critical data (never as a chart series color). Use --color-arches for warning thresholds. Never use BSI Yellow as a chart fill — invisible on Salt (1.09:1). Axis lines: --chart-axis rgba(0,0,0,.12) · Grid lines: --chart-grid rgba(0,0,0,.06) dashed · Labels: 10px #aaa · All chart cards: white bg, --radius-card, --border-default, 20px×24px padding.

Top Assets by Starts Component

Compact ranked list of the top N assets by a primary metric. Each row is a filled pill bar — the asset name sits inside the fill, the count floats to the right of the track. A different series color per row helps fast visual scanning without needing a legend. Use in dashboard summary panels.

Spec: Row structure: label (13px DM Sans 500 --text-primary) + count (12px 500 tabular-nums) on top row · Bar (12px height, --radius-pill) full-width below · Track bg=rgba(Alpine,.07) · Series colors in order per row (chart-1→2→3→4) · Footer: count label left (#888) + Wasatch ghost link right (padding:0) · Works for any asset type by swapping the subtitle and icon

Trending Assets List Component

A scannable list of recently high-momentum content. Each row shows asset type icon, asset name, and a right-aligned completion rate badge color-coded to performance tier. No bars — the badge alone communicates quality. "View more" links to the full report. Use in sidebar widgets and dashboard summary cards.

Spec: Row height driven by padding: var(--space-3) top+bottom · Asset icon: 32px rounded square, --agent-bg fill, Alpine icon · Title: 13px DM Sans 500, truncated · Trend icon (between title and badge): fa-arrow-trend-up = Uinta green (momentum increasing) · fa-minus = --text-muted (stable, conflicting signals, or insufficient data) · fa-arrow-trend-down = Canyonlands red (momentum declining) · 13px for directional arrows, 11px for minus · Completion badge right-aligned pill: ≥80% = Uinta · 60–79% = Arches · <60% = Canyonlands · Trend icon color is independent of badge color — an asset can be trending up while still in the Arches range (improving from worse), or trending down while still Uinta (declining from high) · "View more" = Wasatch ghost link

Variant — Trending Survey Questions

Survey question variant of the Trending List. Each row carries two information layers: the question text and a sub-row with survey frequency, sentiment direction, and response volume direction. The right-aligned trend icon synthesises both signals into a single overall momentum read — the same icon language as the asset variant. Includes a time-range filter in the card header.

Trending Questions Last 30 Days
Survey questions gaining or losing traction
How do you find the onboarding process?
Appears in 5 surveys | Sentiment | Responses
Improving
What features would you like to see next?
Appears in 4 surveys | Sentiment | Responses
Mixed
Is the platform easy to navigate?
Appears in 3 surveys | Sentiment | Responses
Declining
How useful are the recommended learning paths?
Appears in 2 surveys | Sentiment | Responses
Improving
Survey questions variant differences from asset variant: No content-type icon (questions don't have a visual type) · Two-line row: question text (13px 500) + sub-row (11px muted) · Sub-row: survey frequency + Sentiment direction + Responses direction, separated by --border-default pipe dividers · Inline direction indicators: fa-arrow-up = Uinta (--color-uinta) · fa-arrow-down = Canyonlands (--color-canyonlands) · fa-minus = muted · Overall right-edge trend icons use the same palette colors for visual consistency · Right-aligned overall trend icon synthesises both signals: both up = fa-arrow-trend-up Uinta · both down = fa-arrow-trend-down Canyonlands · conflicting = fa-minus muted · Overall trend icon: 16px (vs 13px in asset variant) to compensate for no icon square · Time period baked into chart title ("Last 30 Days") rather than a filter control · Row padding: var(--space-4) top+bottom (vs var(--space-3) in asset variant — more breathing room for the two-line row)

Assets Needing Attention Component

Surfaces underperforming or at-risk content with clear severity tiering. Each row shows a title with colored diagnostic subtext (starts + completion rate) and a slim action button on the right. Two severity levels: Warning (Arches) for moderate risk, Critical (Canyonlands) for severe. Rows are separated by a simple gray rule — no background containers — keeping the list light and scannable.

Spec: Row layout: display:flex;align-items:center;justify-content:space-between · Row padding: var(--space-4) 0 · Row separator: border-bottom:1px solid var(--border-default) (last row has no bottom border) · Title: 13px DM Sans 500, --text-primary · Subtext: 12px DM Sans 500, severity color (Warning=--color-arches, Critical=--color-canyonlands) · Action button: filled severity color, white text, --radius-pill, 11px 500, padding:4px 12px · Header count pill: severity text + 10% opacity bg · Use buildAttentionList() via .bsn-attention-list-mount — never hardcode.

Usage — Reusable Component

NEVER hardcode Assets Needing Attention HTML. Use the mount point — buildAttentionList() renders the component on DOMContentLoaded.

<div class="bsn-attention-list-mount" data-bsn-attention-list='{
  "title": "Videos Needing Attention",
  "subtitle": "High starts but low completion — review content",
  "badge": "2 critical · 1 warning",
  "badgeSeverity": "critical",
  "items": [
    {"label":"Advanced Pivot Tables",         "meta":"1,247 starts · 23% completion", "severity":"warning",  "action":"Review"},
    {"label":"PowerPoint Animations Deep Dive","meta":"892 starts · 31% completion",   "severity":"warning",  "action":"Review"},
    {"label":"SharePoint Site Architecture",  "meta":"756 starts · 18% completion",   "severity":"critical", "action":"Review"}
  ]
}'></div>
Property Type Required Description
titlestringyesChart-card title (chart-title class).
subtitlestringnoChart-card subtitle (chart-subtitle class).
badgestringnoSeverity summary shown in the header (e.g. "2 critical · 1 warning").
badgeSeveritystringno"warning" or "critical". Controls badge text color and background. Default "critical".
itemsarrayyesArray of row objects. Each has label, meta, severity, action.
items[].labelstringyesAsset or content name. Rendered at 13px, DM Sans 500, --text-primary.
items[].metastringyesDiagnostic subtext shown in severity color (e.g. "1,247 starts · 23% completion").
items[].severitystringyes"warning" → Arches · "critical" → Canyonlands. Controls subtext color and button fill.
items[].actionstringnoButton label. Default "Review".
classstringnoExtra CSS classes on the outer .chart-card wrapper.

Emerging Trends Component

Week-over-week performance shifts surfaced by BrainStorm AI. Each metric shows the comparison period, a large delta value with direction icon, and an optional count of assets driving the trend. Positive momentum uses Uinta green; negative uses Canyonlands. A "Surging assets" count shows how many assets are driving the trend. Use in summary dashboards and AI insight reports.

Spec: Metric label: 11px 500 uppercase .5px tracking #aaa · Period: 12px DM Sans body · Delta value: 26px DM Sans 400, tight letter-spacing, Uinta (positive) or Canyonlands (negative) · Direction icon: fa-arrow-up/fa-arrow-down, same color as delta · Count value (asset tallies): 32px DM Sans 400, Wasatch blue (neutral informational) · Row divider: --border-default · Footer link: Wasatch ghost · Up to 3–4 metrics per card before scrolling

Bullet Chart — Industry Benchmark Component

The recommended chart type for benchmarking an organization's metric against reference values (industry average, top performers, target). Three information layers read left-to-right: qualitative range bands in the background show performance zones, a primary measure bar shows the organization's current value, and a thin comparative marker shows the target or benchmark. Cleaner and more information-dense than side-by-side bar charts for this use case.

Why bullet charts for benchmarking: A bullet chart encodes three values (your score, a reference line, and a qualitative zone) in the space of a single bar — no side-by-side columns, no dual axes, no visual noise. Each row reads as a sentence: "Completion Rate is 68% — above industry average (56%) but below top performers (78%)."

Spec: Label col = 108px right-aligned, 11px DM Sans 500 Alpine · Sub-label = 9px #aaa · Chart area = x:116 to 620 (504px span = 5.04px per %) · Qualitative bands: rgba(Alpine) at .04 / .07 / .11 / .17 — 4 zones: Below average (0–45%), Average (45–65%), Good (65–75%), Top performer (75–100%) · Primary measure bar = 14px height, rx=2 · Bar color: Uinta (≥75%), Alpine (65–75%), Arches (<65%) — encodes status semantically · Industry average marker = 2.5px solid Arches vertical line · Top performer marker = 2px dashed Wasatch vertical line · Row pitch = 56px · Row dividers = --chart-grid · X axis = --chart-axis · Zone labels: 8–9px #aaa below axis · All text: DM Sans

Top Themes Across Surveys Component

Top Themes Across Surveys is an AI-generated synthesis of recurring patterns found across all survey responses — not a single survey, question, or moment in time. It answers the question: "What are users consistently telling us across many surveys?" This is not a sentiment score and not a count of responses. It's a pattern-detection layer built on top of raw survey data, designed to surface recurring signals and directional themes while avoiding over-claiming statistical precision.

Strong Signal — shows up frequently and consistently across surveys
Moderate Signal — recurring but less dominant
Early Signal — emerging pattern worth watching
What this component is: An AI-generated synthesis of recurring patterns across all survey responses. Not a sentiment score, not a response count — a pattern-detection layer that answers "What are users consistently telling us across many surveys?" Designed to surface directional signals without over-claiming statistical precision.

Signal tiers: ●●● Strong = shows up frequently and consistently · ●●○ Moderate = recurring but less dominant · ●○○ Early = emerging pattern worth watching. Tiers are not a percentage scale — they encode frequency and cross-survey consistency. Hover each dot cluster to see the tier definition.

Spec: Chart card, padding:0 · Row = flex, align-items:center, padding 16px 20px · Theme text: 13px DM Sans 400, --text-body · Signal label: 11px 500 Alpine, min-width:100px right-aligned · Signal dots: 10px circles, 1.5px Alpine border, Alpine fill when active, 3px gap · Count: 13px 500 Alpine tabular-nums · Users icon: fa-solid fa-users 14px #ccc · Row hover: rgba(Alpine,.03) · Row divider: --border-default · Footer: --surface-subtle, Wasatch ghost link · Tooltip: white bg, --shadow-md, 11px, 180px wide, arrow pointing down to dot cluster

Sentiment Breakdown — Horizontal Bar Variant Component

A variant of the horizontal bar chart for displaying sentiment distribution. Uses the same row structure as the standard hbar — label column, pill track, right-aligned percentage value — with a face icon added at the far right as an at-a-glance emotional signal. The percentage and face icon share the same color as the bar fill.

Sentiment Breakdown variant differences from standard hbar: Face icon (inline SVG, 22px) appended after the hbar-value column, color-matched to the bar fill. No new CSS classes needed — uses .hbar-row, .hbar-track, .hbar-fill, .hbar-value unchanged.

Color encoding: Positive = --color-uinta (Uinta green) · Neutral = --color-arches (Arches copper) · Negative = --color-canyonlands (Canyonlands dark red). Bar fill, % value, and face stroke all share the same color token per row.

Face SVG paths: Happy mouth: M8,14.5 Q12,18 16,14.5 (curves up) · Neutral mouth: line x1=8.5 x2=15.5 y=15.5 · Sad mouth: M8,17 Q12,13.5 16,17 (curves down). All faces: circle r=10, eye circles r=1.5, stroke-width 1.5px, fill=none on outer circle.

What Users Are Saying Component

A simple verbatim quote list surfacing representative user responses from surveys. No scores, no categorization — raw voice of the user. Pairs naturally with the Sentiment Breakdown chart and the Top Themes component to complete the "How Users Feel" cluster. Quotes use italic body text to signal verbatim content. Opening quotation marks are decorative and oversized to anchor the visual rhythm.

Use in context: Designed to sit alongside Sentiment Breakdown and Top Themes Across Surveys as a "How Users Feel" cluster — the three charts together provide quantitative distribution (Sentiment), pattern synthesis (Top Themes), and raw voice (What Users Are Saying). Never use fabricated quotes — all content must come from actual survey responses.

Spec: Chart card padding:0 · Quote row: flex, gap=12px, padding 20px · Opening curly quote: 28px Georgia serif, Arches at 40% opacity, line-height .8 — decorative anchor only · Quote text: 13px DM Sans italic, --text-body, line-height 1.6 · Row divider: --border-default · Row hover: rgba(Alpine,.03) · Footer: --surface-subtle · "View more" = Wasatch ghost link · No sentiment tagging or icons per row — this component intentionally presents unfiltered voice; tagging is handled by Sentiment Breakdown