The Triumph design system, recalibrated for long-session dashboards. Same green. Same identity. Calmed slate canvas, Inter doing the work Fabiola was never built for, dashboard-tight spacing, restrained chroma.
The strict Triumph kit was built for sponsor decks, programs, posters, kits. Those carry well at distance with high saturation and big display type. Drag the same tokens onto a 27" monitor at desk distance for six hours and they fight the data. Four specific failures, four targeted fixes in this system.
Page #020022 + surface #002855, both saturated navy. No neutral, no hierarchy. Cards floated as the decorated panel, not as content lifted out of a calm canvas. Fix: chroma-0.013 slate canvas with four lift-steps.
Fabiola Capitals is a single-weight display face designed for poster sizes. On a dashboard h3 at 22px it cramps, all-caps strokes turn heavy, and it competes with the data. Fix: Fabiola reserved for the page hero, Inter for h2 through h4.
Navy 0.13, green 0.18, sky 0.13, lime 0.20, all stacked on a near-black bg with no neutral. The brand green at full saturation is correct, the canvas behind it is what made it scream. Fix: keep Triumph green at exact brand chroma (0.182, #61a631), sit it on a calm slate canvas. Brand-accurate, dashboard-comfortable.
Section padding maxed at 4.25rem read like museum gallery walls. A dashboard with twenty widgets feels disassembled. Fix: section padding tops out at 6rem at widest viewport, interior rhythm tightened to the design.seantippen scale.
Soft slate canvas with a 0.013-chroma whisper of navy hue. Triumph green
at the exact Brandpad value (#61a631) so anything that needs to
read as on-brand for a customer does. Greenville Blue family for the
secondary, lightened to read on dark. A four-color decorative rotation.
All values in OKLCH so light mode is a clean inversion, not a separate palette.
Per global rule, decorative accents rotate through green, royal blue, coral, and soft purple. Yellow and lime are status-only.
The canonical Brandpad values stay available as --brand-* for logo lockups and brand strips. They are not used as chrome.
The single biggest fix versus the strict brand. Fabiola Capitals lives on the page hero. Inter does the rest. The discipline is brutal and not optional. Fabiola at 22px on a dashboard h3 is the source of half the ugliness in this codebase.
Body copy uses Inter at the base size with relaxed leading. Comfortable at desk distance for hours. The grayish-blue secondary text reduces eye fatigue versus pure white on the slate canvas.
Dashboard-tight rhythm. Fluid values that scale gracefully from laptop to widescreen without spreading thin.
Solid for primary actions, outline for secondary, ghost for tertiary. Lift two pixels on hover, never scale.
Underline-only by default. Accent underline expands from the center on focus. Block inputs for forms where structure matters.
Badges for status tags. Pills with leading dot for live state indicators.
KPI markers use a left border that rotates through the four decorative accents. No card wrapper. The number is the hero, the chrome stays out of the way.
Default surface, 1px border, dashboard chrome.
Lifted surface for emphasis, with shadow.
Hover lifts two pixels, tightens the border.
Bare structure. No card wrapper. Monospace tabular numerals so columns align. Row hover tints accent-subtle. Total row gets a thicker top border and lifted background.
| Match | Date | Tickets | Revenue | Delta |
|---|---|---|---|---|
| Greenville Triumph vs. Charlotte | May 9 | 3,241 | $94,820 | +12.4% |
| Greenville Triumph vs. Tampa Bay | May 16 | 2,887 | $81,114 | +8.1% |
| Greenville Triumph vs. Asheville | May 30 | 3,612 | $108,930 | +21.7% |
| Greenville Triumph vs. Charleston | Jun 6 | 2,194 | $58,490 | -4.2% |
| Total | 11,934 | $343,354 | +9.5% |
Tabs for view-level navigation. Segmented for time ranges or mode switches. Both underline-active, both keyboard-navigable.
Chart.js 4.4.7. Series colors via tok('--green'), tok('--blue'), etc. Hex literals only, because the Canvas API cannot resolve CSS custom properties.
Anti-patterns from the strict brand that landed on dashboards by mistake.
Single-weight display face cramps at UI sizes. Inter does this job. Fabiola earns one appearance per page, on the hero.
Triumph navy is a poster color. Sitting cards on it floods the field with chroma and kills hierarchy. Use the slate canvas instead.
Reserved for status UI only. Default decorative rotation is green, royal blue, coral, soft purple.
Flat surface plus optional noise grain. Small decorative gradients on a KPI top bar are fine. Radial blobs are banned.
Layout shifts cascade through grids. Lift two pixels and increase shadow.
Reach for the token. The Chart.js exception is the only exception, because Canvas does not resolve CSS variables.
Link the token sheet and the components sheet in the head of every Triumph dashboard. Single-file dashboards also pull Inter and JetBrains Mono from Google Fonts directly. Fabiola loads from this domain via @font-face already declared in tokens.css.
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300..900&family=JetBrains+Mono:wght@500;600;700&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://dashboards.greenvilletriumph.club/tokens.css"> <link rel="stylesheet" href="https://dashboards.greenvilletriumph.club/components.css">
/* CSS */ .card { background: var(--color-surface); border: 1px solid var(--color-border); padding: var(--space-md); } // Chart.js — hex literal because Canvas cannot read CSS vars const tok = (k) => getComputedStyle(document.documentElement).getPropertyValue(k).trim(); chart.data.datasets[0].borderColor = tok('--green');
| URL | Purpose |
|---|---|
| tokens.css | CSS custom properties: colors, type, spacing, motion |
| components.css | Component patterns: buttons, badges, tables, KPIs, tabs, toasts |
| /fonts/Fabiola-Capitals.otf | Fabiola Capitals OTF (served from design.greenvilletriumph.club, CORS open) |