FN-6680: fix Command Center mobile chart layouts

Fix Command Center chart rendering and visual rhythm on constrained mobile layouts.

- Bound chart primitives, text labels, and grid tracks so mobile Command Center charts do not overflow, collapse, or steal scrolling.
- Normalize stat, table, team, and system chart card surfaces around shared dashboard spacing, border, radius, and surface tokens.
- Add CSS regression coverage and documentation for mobile chart layout limits beyond jsdom.
- Add a patch changeset for the published dashboard bundle.

Files changed:
 .../fn-6680-command-center-mobile-chart-fix.md     |  5 ++
 docs/dashboard-guide.md                            |  3 +-
 docs/testing.md                                    |  3 +
 .../components/command-center/CommandCenter.css    | 16 +++--
 .../CommandCenter.mobile-chart-layout.test.ts      | 72 ++++++++++++++++++++++
 .../__tests__/CommandCenter.mobile-scroll.test.tsx |  4 ++
 .../command-center/areas/SystemStatsArea.css       | 14 ++++-
 .../app/components/command-center/areas/areas.css  | 19 +++---
 .../components/command-center/charts/charts.css    | 45 +++++++++++++-
 9 files changed, 156 insertions(+), 25 deletions(-)

Fusion-Task-Id: FN-6680

Fusion-Task-Lineage: 4dc731c4-6408-4b05-84f7-916bbc572a5d
This commit is contained in:
gsxdsm
2026-06-18 23:08:08 -07:00
parent d6e2f920e4
commit fe207ca960
9 changed files with 156 additions and 25 deletions

View File

@@ -0,0 +1,5 @@
---
"@runfusion/fusion": patch
---
Fix Command Center mobile chart rendering by bounding chart label/track layouts in real mobile engines and normalizing chart/card/table border spacing across the dashboard bundle.

View File

@@ -678,8 +678,9 @@ Features:
Rendering invariants: Rendering invariants:
- On mobile (`max-width: 768px`), `.cc-tabpanel` remains the sole vertical scroll owner for every chart-bearing tab. Shared chart primitives (`Bar`, `StackedBar`, `Sparkline`, `LineChart`, `RadialGauge`, `Funnel`, and `TokenSeriesChart`) must shrink within the tabpanel, keep non-zero usable height, avoid stretch/clipping artifacts, and never introduce a competing vertical overflow container. - On mobile (`max-width: 768px`), `.cc-tabpanel` remains the sole vertical scroll owner for every chart-bearing tab. Shared chart primitives (`Bar`, `StackedBar`, `Sparkline`, `LineChart`, `RadialGauge`, `Funnel`, and `TokenSeriesChart`) must shrink within the tabpanel, keep non-zero usable height, avoid stretch/clipping artifacts, and never introduce a competing vertical overflow container.
- Mobile chart text must not rely on min-content luck: bar labels, values, token-series axis labels, funnel headers, radial labels, legends, and chart tracks need explicit `min-inline-size: 0`, wrapping, or ellipsis rules so long model/agent/repo labels cannot crush the track or create hidden horizontal overflow in a real browser.
- On tablet (`min-width: 769px` and `max-width: 1024px`), `.project-content`, `.command-center`, and `.cc-tabpanel` keep the same definite flex/min-height scroll-owner chain, while the live strip and chart grids collapse before they can create document-level horizontal overflow. - On tablet (`min-width: 769px` and `max-width: 1024px`), `.project-content`, `.command-center`, and `.cc-tabpanel` keep the same definite flex/min-height scroll-owner chain, while the live strip and chart grids collapse before they can create document-level horizontal overflow.
- Command Center stat cards, overview chart cards, live strips, table wrappers, Team chart panels, token-series plots, and gauge/chart cards share the same tokenized rhythm: `--border-width` borders, `--radius-md` radii, and `--space-*` gaps/padding. Area-specific accents may use `color-mix(...)`, but layout, border, radius, text color, and motion must stay on design tokens. - Command Center stat cards, overview chart cards, live strips, table wrappers, Team chart panels, token-series plots, system control cards, and gauge/chart cards share the same tokenized rhythm: `--space-3` gaps/padding for card-like surfaces, `--border-width` borders, `--radius-md` radii, and `--surface-1` backgrounds. Area-specific accents may use `color-mix(...)`, but layout, border, radius, text color, and motion must stay on design tokens.
Data states: Data states:
- Overview shows a loading state while core analytics settle, then shows `No usage data yet. Run some agents to populate the Command Center.` only after the selected range has settled with no core usage data. - Overview shows a loading state while core analytics settle, then shows `No usage data yet. Run some agents to populate the Command Center.` only after the selected range has settled with no core usage data.

View File

@@ -64,6 +64,9 @@ pnpm --filter @fusion/dashboard test:build # built client output contra
Run `test:deep` when changing broad dashboard architecture, shared modal/view infrastructure, or route registration. Run `test:browser-smoke` for layout/responsive/navigation/modal/CSS changes. Run `test:build` for Vite output, lazy-loading, chunking, or client-dist changes. Run `test:deep` when changing broad dashboard architecture, shared modal/view infrastructure, or route registration. Run `test:browser-smoke` for layout/responsive/navigation/modal/CSS changes. Run `test:build` for Vite output, lazy-loading, chunking, or client-dist changes.
<!-- FNXC:CommandCenterTesting 2026-06-18-23:10: FN-6680 proved Command Center mobile chart regressions can pass jsdom because jsdom does not compute flex/grid layout, aspect-ratio, clamp(), min-content shrinking, overflow widths, or resolved heights. -->
Command Center responsive chart fixes need evidence beyond jsdom. Keep the jsdom scroll-owner tests for rule/structure coverage, but pair them with `packages/dashboard/app/components/command-center/__tests__/CommandCenter.mobile-chart-layout.test.ts`, which reads the co-located Command Center CSS files directly and asserts the mobile shrink/height/border rules that real layout depends on. For visible defects, also capture a real browser/device (or headless Chrome/Blink) reproduction with `scrollWidth > clientWidth`, zero/clipped `clientHeight`, or stretch measurements; do not close a Command Center mobile chart bug on jsdom-green assertions alone.
The shared mobile/tablet overflow-containment net lives at `packages/dashboard/app/__tests__/dashboard-overflow-containment.test.tsx`. It covers board/kanban columns, task-detail modal shell, workflow/simple workflow editors, and Activity Log modal at mobile, tablet, and landscape-phone breakpoints. Run it directly when touching dashboard viewport containment or shared modal/workflow CSS: The shared mobile/tablet overflow-containment net lives at `packages/dashboard/app/__tests__/dashboard-overflow-containment.test.tsx`. It covers board/kanban columns, task-detail modal shell, workflow/simple workflow editors, and Activity Log modal at mobile, tablet, and landscape-phone breakpoints. Run it directly when touching dashboard viewport containment or shared modal/workflow CSS:
```bash ```bash

View File

@@ -94,13 +94,13 @@ The Command Center must remain scrollable on mobile inside the overflow-hidden .
.cc-stat-grid { .cc-stat-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--space-20) * 2)), 1fr));
gap: var(--space-3); gap: var(--space-3);
} }
/* /*
FNXC:CommandCenterStyling 2026-06-18-00:00: FNXC:CommandCenterStyling 2026-06-18-22:38:
Command Center chart/stat surfaces share one tokenized card rhythm so new chart areas do not drift in border, radius, or spacing when Team/System/agent-runs render together (FN-6664). FN-6680 standardizes the Command Center card rhythm across overview, area, table, team, and system chart surfaces: use --space-3 padding/gaps, --border-width solid --border-subtle, --radius-md, and --surface-1 so mobile and tablet charts do not look like separate components.
*/ */
.cc-stat-card { .cc-stat-card {
display: flex; display: flex;
@@ -169,13 +169,13 @@ The GitHub closed-at backfill control lives inside the existing Fixed by Fusion
} }
/* /*
FNXC:CommandCenterStyling 2026-06-18-00:00: FNXC:CommandCenterStyling 2026-06-18-22:31:
Command Center live/chart containers must shrink inside the mobile tabpanel without creating a second scroll owner or clipping chart height (FN-6664). FN-6680 keeps the FN-6664 live/chart shrink contract but replaces hardcoded track minima with spacing tokens after real Blink mobile probing showed jsdom cannot catch min-content overflow or crushed chart tracks.
*/ */
.cc-live-strip { .cc-live-strip {
position: relative; position: relative;
display: grid; display: grid;
grid-template-columns: minmax(10rem, 1fr) minmax(16rem, 2fr) minmax(10rem, 1fr); grid-template-columns: minmax(calc(var(--space-20) * 2), 1fr) minmax(calc((var(--space-20) * 3) + var(--space-4)), 2fr) minmax(calc(var(--space-20) * 2), 1fr);
align-items: center; align-items: center;
gap: var(--space-3); gap: var(--space-3);
padding: var(--space-3); padding: var(--space-3);
@@ -231,7 +231,6 @@ Command Center live/chart containers must shrink inside the mobile tabpanel with
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--space-1); gap: var(--space-1);
min-inline-size: 0;
padding: var(--space-2); padding: var(--space-2);
border-radius: var(--radius-sm); border-radius: var(--radius-sm);
background: color-mix(in srgb, var(--surface-2) 70%, transparent); background: color-mix(in srgb, var(--surface-2) 70%, transparent);
@@ -334,7 +333,6 @@ Overview charts must use dashboard tokens only and keep motion decorative; anima
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: var(--space-3); gap: var(--space-3);
min-inline-size: 0;
padding: var(--space-3); padding: var(--space-3);
border: var(--border-width) solid var(--border-subtle); border: var(--border-width) solid var(--border-subtle);
border-radius: var(--radius-md); border-radius: var(--radius-md);
@@ -459,7 +457,7 @@ The Command Center subtree previously had no tablet tier, so at 769px–1024px t
.cc-stat-grid, .cc-stat-grid,
.cc-area .cc-stat-grid { .cc-area .cc-stat-grid {
grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr)); grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(var(--space-20) * 2)), 1fr));
} }
} }

View File

@@ -0,0 +1,72 @@
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
function readCommandCenterCss(): string {
return [
readFileSync(join(__dirname, "..", "CommandCenter.css"), "utf-8"),
readFileSync(join(__dirname, "..", "charts", "charts.css"), "utf-8"),
readFileSync(join(__dirname, "..", "areas", "areas.css"), "utf-8"),
readFileSync(join(__dirname, "..", "areas", "SystemStatsArea.css"), "utf-8"),
].join("\n");
}
function extractMobileMediaBlocks(content: string): string {
const blocks: string[] = [];
const regex = /@media[^{}]*\(max-width:\s*768px\)[^{}]*\{/g;
let match: RegExpExecArray | null;
while ((match = regex.exec(content)) !== null) {
const startIdx = match.index + match[0].length;
let braceCount = 1;
let endIdx = startIdx;
while (braceCount > 0 && endIdx < content.length) {
if (content[endIdx] === "{") braceCount++;
if (content[endIdx] === "}") braceCount--;
endIdx++;
}
if (braceCount === 0) blocks.push(content.slice(startIdx, endIdx - 1));
}
return blocks.join("\n");
}
describe("CommandCenter.mobile-chart-layout.css", () => {
const cssContent = readCommandCenterCss();
const mobileCss = extractMobileMediaBlocks(cssContent);
it("reads the co-located Command Center styles instead of the top-level css fixture", () => {
expect(cssContent).toContain("FN-6680");
expect(cssContent).toContain(".cc-token-series-axis");
expect(cssContent).toContain(".cc-system-chart-grid");
});
it("keeps chart primitives and text-bearing children shrink-bounded for real mobile layout", () => {
expect(cssContent).toMatch(/\.cc-token-series-axis,[\s\S]*\.cc-funnel-stage\s*\{[\s\S]*min-inline-size:\s*0;[\s\S]*max-inline-size:\s*100%/);
expect(cssContent).toMatch(/\.cc-bar-label\s*\{[^}]*min-inline-size:\s*0;[^}]*overflow:\s*hidden;[^}]*text-overflow:\s*ellipsis/);
expect(cssContent).toMatch(/\.cc-bar-track\s*\{[^}]*min-inline-size:\s*0/);
expect(cssContent).toMatch(/\.cc-bar-value\s*\{[^}]*min-inline-size:\s*0;[^}]*overflow-wrap:\s*anywhere/);
});
it("pins the corrected mobile bar row template without a competing scroll owner", () => {
expect(mobileCss).toMatch(/\.cc-bar-row\s*\{[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\)\s+minmax\(var\(--space-12\),\s*2fr\);[^}]*align-items:\s*start/);
expect(mobileCss).toMatch(/\.cc-bar-value\s*\{[^}]*grid-column:\s*1\s*\/\s*-1;[^}]*max-inline-size:\s*100%/);
expect(cssContent).not.toMatch(/\.cc-(?:bar|line|radial|sparkline|token-series|funnel)[^{]*\{[^}]*overflow-y:\s*(?:auto|scroll)/);
});
it("keeps line, token-series, radial, team, and system charts non-collapsing at mobile", () => {
expect(mobileCss).toMatch(/\.cc-line-chart\s*\{[^}]*block-size:\s*clamp\(var\(--space-16\),\s*44vw,\s*calc\(var\(--space-20\)\s*\+\s*var\(--space-12\)\)\);[^}]*aspect-ratio:\s*auto/);
expect(mobileCss).toMatch(/\.cc-token-series-plot\s*\{[^}]*block-size:\s*clamp\(var\(--space-14\),\s*38vw,\s*calc\(var\(--space-20\)\s*\+\s*var\(--space-12\)\)\)/);
expect(mobileCss).toMatch(/\.cc-radial-gauge-ring\s*\{[^}]*inline-size:\s*clamp\(var\(--space-20\),\s*44vw,\s*var\(--space-32\)\)/);
expect(mobileCss).toMatch(/\.cc-team-chart-grid\s*\{[^}]*min-inline-size:\s*0;[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\)/);
expect(mobileCss).toMatch(/\.cc-system-chart-grid\s*\{[^}]*grid-template-columns:\s*minmax\(0,\s*1fr\)/);
});
it("normalizes chart/card/table border rhythm with design tokens only", () => {
expect(cssContent).toMatch(/\.cc-stat-card\s*\{[^}]*padding:\s*var\(--space-3\);[^}]*border:\s*var\(--border-width\)\s+solid\s+var\(--border-subtle\);[^}]*border-radius:\s*var\(--radius-md\);[^}]*background:\s*var\(--surface-1\)/);
expect(cssContent).toMatch(/\.cc-table-wrap\s*\{[^}]*border:\s*var\(--border-width\)\s+solid\s+var\(--border-subtle\);[^}]*border-radius:\s*var\(--radius-md\);[^}]*background:\s*var\(--surface-1\);[^}]*overflow-x:\s*auto;[^}]*overflow-y:\s*hidden/);
expect(cssContent).toMatch(/\.cc-system-vitest-card\s*\{[^}]*border:\s*var\(--border-width\)\s+solid\s+var\(--border-subtle\);[^}]*border-radius:\s*var\(--radius-md\);[^}]*background:\s*var\(--surface-1\)/);
});
});

View File

@@ -303,6 +303,7 @@ function assertScrollOwnerContract(panel: HTMLElement) {
} }
function assertNoChartScrollSteal(panel: HTMLElement) { function assertNoChartScrollSteal(panel: HTMLElement) {
// FN-6680: jsdom does not compute real flex/grid layout, so this guards rule presence and scroll-owner structure only; the CSS-string regression plus Blink audit cover actual mobile pixel layout.
const chartContainers = panel.querySelectorAll<HTMLElement>( const chartContainers = panel.querySelectorAll<HTMLElement>(
".cc-bar-chart, .cc-bar-row, .cc-sparkline, .cc-line-chart, .cc-radial-gauge, .cc-funnel, .cc-token-series, .cc-token-series-plot, .cc-overview-chart-card, .cc-team-chart-panel, .cc-stat-card", ".cc-bar-chart, .cc-bar-row, .cc-sparkline, .cc-line-chart, .cc-radial-gauge, .cc-funnel, .cc-token-series, .cc-token-series-plot, .cc-overview-chart-card, .cc-team-chart-panel, .cc-stat-card",
); );
@@ -402,6 +403,9 @@ describe("CommandCenter mobile scroll regression (FN-6595)", () => {
expect(styles).toContain(".cc-radial-gauge-ring"); expect(styles).toContain(".cc-radial-gauge-ring");
expect(styles).toContain("inline-size: clamp(var(--space-20), 44vw, var(--space-32))"); expect(styles).toContain("inline-size: clamp(var(--space-20), 44vw, var(--space-32))");
expect(styles).toContain("min-inline-size: 0"); expect(styles).toContain("min-inline-size: 0");
expect(styles).toContain(".cc-token-series-axis");
expect(styles).toContain("overflow-wrap: anywhere");
expect(styles).toContain("grid-template-columns: minmax(0, 1fr)");
}); });
it("keeps the same flex-fill scroll-owner contract outside the mobile breakpoint", () => { it("keeps the same flex-fill scroll-owner contract outside the mobile breakpoint", () => {

View File

@@ -1,6 +1,6 @@
/* /*
FNXC:CommandCenter 2026-06-18-00:00: FNXC:CommandCenter 2026-06-18-22:31:
The Command Center System area replaces the standalone System Stats modal with graph-heavy telemetry while preserving the Command Center mobile scroll contract; keep area-specific styling layout-only and avoid nested overflow containers so .cc-tabpanel remains the sole vertical scroller. The Command Center System area replaces the standalone System Stats modal with graph-heavy telemetry while preserving the Command Center mobile scroll contract; FN-6680 keeps System chart grids shrink-bounded because jsdom cannot prove real mobile gauge/sparkline layout.
*/ */
.cc-system-refresh { .cc-system-refresh {
@@ -21,6 +21,7 @@ The Command Center System area replaces the standalone System Stats modal with g
} }
.cc-system-chart-grid { .cc-system-chart-grid {
min-inline-size: 0;
display: grid; display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
gap: var(--space-3); gap: var(--space-3);
@@ -40,12 +41,19 @@ The Command Center System area replaces the standalone System Stats modal with g
color: var(--text-muted); color: var(--text-muted);
} }
/*
FNXC:CommandCenterStyling 2026-06-18-22:38:
System control cards sit beside chart/stat cards, so FN-6680 gives them the same tokenized border, radius, surface, gap, and padding rhythm instead of relying on incidental global .card styling.
*/
.cc-system-vitest-card { .cc-system-vitest-card {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
gap: var(--space-3); gap: var(--space-3);
padding: var(--space-3); padding: var(--space-3);
border: var(--border-width) solid var(--border-subtle);
border-radius: var(--radius-md);
background: var(--surface-1);
} }
.cc-system-vitest-card .btn { .cc-system-vitest-card .btn {
@@ -103,7 +111,7 @@ The Command Center System area replaces the standalone System Stats modal with g
} }
.cc-system-chart-grid { .cc-system-chart-grid {
grid-template-columns: 1fr; grid-template-columns: minmax(0, 1fr);
} }
.cc-system-vitest-card, .cc-system-vitest-card,

View File

@@ -15,8 +15,8 @@ Area headings, table metadata, and empty states use --text-muted so the analytic
} }
/* /*
FNXC:CommandCenterStyling 2026-06-18-00:00: FNXC:CommandCenterStyling 2026-06-18-22:31:
Chart-bearing Command Center areas use one tokenized section rhythm and logical shrink bounds so mobile charts stay inside .cc-tabpanel without scroll-steal (FN-6664). FN-6680 preserves the FN-6664 section rhythm while adding real-layout shrink guarantees: jsdom missed mobile min-content pressure, so chart-bearing sections must bound their inline axis before shared chart primitives render labels, tables, or gauges.
*/ */
.cc-area-section { .cc-area-section {
display: flex; display: flex;
@@ -44,7 +44,7 @@ Chart-bearing Command Center areas use one tokenized section rhythm and logical
/* Reuse the shell's stat-grid/stat-card look. */ /* Reuse the shell's stat-grid/stat-card look. */
.cc-area .cc-stat-grid { .cc-area .cc-stat-grid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr)); grid-template-columns: repeat(auto-fill, minmax(min(100%, calc(var(--space-20) * 2)), 1fr));
gap: var(--space-3); gap: var(--space-3);
} }
@@ -105,8 +105,8 @@ The Tokens area needs a real hour/day/week control and live token-number motion.
/* ---- Tables ---- */ /* ---- Tables ---- */
/* /*
FNXC:CommandCenterStyling 2026-06-18-00:00: FNXC:CommandCenterStyling 2026-06-18-22:38:
Command Center table-heavy chart areas share the same border/radius rhythm as chart cards while keeping horizontal table overflow scoped to the table wrapper, not the mobile tabpanel vertical scroll owner (FN-6664). FN-6680 keeps table-heavy chart areas on the same --border-width/--border-subtle/--radius-md/--surface-1 rhythm as chart cards while preserving the one allowed horizontal overflow owner: .cc-table-wrap.
*/ */
.cc-table-wrap { .cc-table-wrap {
max-inline-size: 100%; max-inline-size: 100%;
@@ -205,8 +205,8 @@ Command Center table-heavy chart areas share the same border/radius rhythm as ch
} }
/* /*
FNXC:CommandCenterStyling 2026-06-18-16:57: FNXC:CommandCenterStyling 2026-06-18-22:38:
The Team view must use dashboard design tokens only, preserve .cc-tabpanel as the scroll owner on mobile, reuse the shared .status-dot convention for live state, and keep any decorative motion duration-token based with reduced-motion disabled. The Team view must use dashboard design tokens only, preserve .cc-tabpanel as the scroll owner on mobile, and match the shared card rhythm (--space-3 gap/padding, --border-width solid --border-subtle, --radius-md, --surface-1) while keeping decorative motion duration-token based with reduced-motion disabled.
*/ */
.cc-team-chart-grid { .cc-team-chart-grid {
display: grid; display: grid;
@@ -285,7 +285,7 @@ Tablet Command Center areas share the FN-6679 overflow fix with the shell: area
*/ */
@media (min-width: 769px) and (max-width: 1024px) { @media (min-width: 769px) and (max-width: 1024px) {
.cc-area .cc-stat-grid { .cc-area .cc-stat-grid {
grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr)); grid-template-columns: repeat(auto-fit, minmax(min(100%, calc(var(--space-20) * 2)), 1fr));
} }
.cc-team-chart-grid { .cc-team-chart-grid {
@@ -300,7 +300,8 @@ Tablet Command Center areas share the FN-6679 overflow fix with the shell: area
@media (max-width: 768px) { @media (max-width: 768px) {
.cc-team-chart-grid { .cc-team-chart-grid {
grid-template-columns: 1fr; min-inline-size: 0;
grid-template-columns: minmax(0, 1fr);
} }
.cc-team-spark-panel { .cc-team-spark-panel {

View File

@@ -11,17 +11,19 @@ Chart labels and legends must use --text-muted so command-center CSS stays align
*/ */
/* /*
FNXC:CommandCenterStyling 2026-06-18-00:00: FNXC:CommandCenterStyling 2026-06-18-22:31:
Command Center charts must render within the mobile tabpanel without overflow scroll-steal, zero-height collapse, or stretch; every primitive opts into logical shrink bounds before area layouts compose it (FN-6664). FN-6680 re-checked FN-6664 in a real Blink layout engine because jsdom does not compute grid/flex min-content sizes. Chart primitives and their text-bearing children need explicit logical shrink bounds so long labels cannot crush tracks or create hidden horizontal overflow inside the mobile tabpanel.
*/ */
.cc-bar-chart, .cc-bar-chart,
.cc-stacked-bar, .cc-stacked-bar,
.cc-sparkline, .cc-sparkline,
.cc-token-series, .cc-token-series,
.cc-token-series-plot, .cc-token-series-plot,
.cc-token-series-axis,
.cc-line-chart, .cc-line-chart,
.cc-radial-gauge, .cc-radial-gauge,
.cc-funnel { .cc-funnel,
.cc-funnel-stage {
min-inline-size: 0; min-inline-size: 0;
max-inline-size: 100%; max-inline-size: 100%;
} }
@@ -44,6 +46,7 @@ Command Center charts must render within the mobile tabpanel without overflow sc
} }
.cc-bar-label { .cc-bar-label {
min-inline-size: 0;
font-size: var(--font-size-sm); font-size: var(--font-size-sm);
color: var(--text-muted); color: var(--text-muted);
overflow: hidden; overflow: hidden;
@@ -52,6 +55,7 @@ Command Center charts must render within the mobile tabpanel without overflow sc
} }
.cc-bar-track { .cc-bar-track {
min-inline-size: 0;
position: relative; position: relative;
block-size: var(--space-3); block-size: var(--space-3);
background: var(--surface-2); background: var(--surface-2);
@@ -67,9 +71,12 @@ Command Center charts must render within the mobile tabpanel without overflow sc
} }
.cc-bar-value { .cc-bar-value {
min-inline-size: 0;
font-size: var(--font-size-sm); font-size: var(--font-size-sm);
font-variant-numeric: tabular-nums; font-variant-numeric: tabular-nums;
color: var(--text-primary); color: var(--text-primary);
overflow-wrap: anywhere;
text-align: end;
} }
/* ---- StackedBar ---- */ /* ---- StackedBar ---- */
@@ -103,11 +110,13 @@ Command Center charts must render within the mobile tabpanel without overflow sc
} }
.cc-stacked-legend-item { .cc-stacked-legend-item {
min-inline-size: 0;
display: flex; display: flex;
align-items: center; align-items: center;
gap: var(--space-1); gap: var(--space-1);
font-size: var(--font-size-sm); font-size: var(--font-size-sm);
color: var(--text-muted); color: var(--text-muted);
overflow-wrap: anywhere;
} }
.cc-stacked-swatch { .cc-stacked-swatch {
@@ -185,6 +194,17 @@ The token-over-time chart is live-updated and animated, but the motion is decora
font-variant-numeric: tabular-nums; font-variant-numeric: tabular-nums;
} }
.cc-token-series-axis span {
min-inline-size: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cc-token-series-axis span:last-child {
text-align: end;
}
@keyframes cc-token-series-rise { @keyframes cc-token-series-rise {
from { from {
transform: scaleY(0.82); transform: scaleY(0.82);
@@ -275,6 +295,7 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us
/* ---- RadialGauge ---- */ /* ---- RadialGauge ---- */
.cc-radial-gauge { .cc-radial-gauge {
min-inline-size: 0;
display: grid; display: grid;
place-items: center; place-items: center;
gap: var(--space-2); gap: var(--space-2);
@@ -325,8 +346,10 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us
} }
.cc-radial-gauge-label { .cc-radial-gauge-label {
max-inline-size: 100%;
color: var(--text-muted); color: var(--text-muted);
font-size: var(--font-size-sm); font-size: var(--font-size-sm);
overflow-wrap: anywhere;
text-align: center; text-align: center;
} }
@@ -373,12 +396,26 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us
} }
.cc-funnel-header { .cc-funnel-header {
min-inline-size: 0;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
gap: var(--space-2);
font-size: var(--font-size-sm); font-size: var(--font-size-sm);
color: var(--text-muted); color: var(--text-muted);
} }
.cc-funnel-label,
.cc-funnel-conversion,
.cc-funnel-value {
min-inline-size: 0;
overflow-wrap: anywhere;
}
.cc-funnel-conversion {
flex: 0 1 auto;
text-align: end;
}
.cc-funnel-conversion { .cc-funnel-conversion {
font-variant-numeric: tabular-nums; font-variant-numeric: tabular-nums;
} }
@@ -425,11 +462,13 @@ Line-chart motion is decorative, token-timed, and disabled for reduced-motion us
@media (max-width: 768px) { @media (max-width: 768px) {
.cc-bar-row { .cc-bar-row {
grid-template-columns: minmax(0, 1fr) minmax(var(--space-12), 2fr); grid-template-columns: minmax(0, 1fr) minmax(var(--space-12), 2fr);
align-items: start;
} }
.cc-bar-value { .cc-bar-value {
grid-column: 1 / -1; grid-column: 1 / -1;
justify-self: end; justify-self: end;
max-inline-size: 100%;
} }
.cc-radial-gauge-ring { .cc-radial-gauge-ring {