Color
On this page
Core palette
Usage:
| Token | Role |
|---|---|
navy-900 |
outer canvas |
navy-800 |
elevated surfaces · panels and cards |
navy-700 |
input fields · secondary panels |
navy-600 |
borders and dividers at rest |
steel-500 → steel-300 |
strokes, inactive indicators, metadata text |
fog-200 |
body text on dark |
fog-100 |
primary headings |
white |
critical emphasis only |
Accent
Electric blue is load-bearing. It signals “this is the active thing,” “this is friendly force,” “this is the FDT brand.” Use it sparingly - a page with three electric-blue accents beats a page with fifteen.
Glow - the signature atmospheric element
Glow is a first-class design element, not an effect. It is the visual vocabulary that makes a screen feel live - active, sensing, engaged. A primary button has a halo. An acquired target has a bloom. A radar sweep leaves a trail. Glow is how the system says “this is happening now.”
Rules:
- Monochromatic only. All glows are in the accent hue (
--electric-500or--electric-300). No multi-color, no rainbow, no gradient glows. - Soft, not neon. Glows are atmospheric halos with gaussian falloff - never sharp-edged, never CRT bloom, never Tron lines. If a glow has a visible edge, it is wrong.
- Functional, not decorative. Glow indicates a state (active, live, acquired, engaged) or a signal (sensor return, radar sweep, target lock). A glow on a static element that isn’t doing anything is wrong.
- Intensity scales with context. Corporate surfaces use the lower end of the scale and only on primary hero elements. Product surfaces use the full range - active UI, ambient radar, acquire moments.
- No drop shadows, ever. Glow replaces shadow entirely. If you’d reach for a shadow to establish depth, establish it through opacity and border contrast instead, and reserve glow for live states.
| Token | Value | Use |
|---|---|---|
--glow-xs |
0 0 8px --electric-500 @ 20% |
Hover state on buttons, focus ring on inputs |
--glow-sm |
0 0 16px --electric-500 @ 30% |
Active primary CTA, selected nav item |
--glow-md |
0 0 32px --electric-500 @ 35% |
Acquire bracket, active radar track, hero CTA |
--glow-lg |
0 0 64px --electric-500 @ 40% |
Hero element ambient halo, splash surfaces |
--glow-xl |
0 0 128px --electric-300 @ 35% |
Mission-start moments, full-screen ambient sweeps |
The glow scale is where corporate and product registers differ. Corporate surfaces draw from --glow-xs through --glow-md. Product surfaces use the full range and layer glows (ambient --glow-lg behind content, --glow-md on active elements, --glow-xs on hover states).
Semantic / status
These mirror NATO APP-6D affiliation colors and are shared across corporate and product surfaces:
Status colors are muted variants of their pure forms. The red is not fire-engine red; the yellow is not highlighter yellow. They sit alongside the navy palette without shouting. Semantic colors never take a glow - glow is reserved for the accent.
Note: --caution (amber) is load-bearing for advisory signaling - event announcements, program classification labels, and training-construct markers all use this hue. --friendly shares its hex with --electric-500; the meaning is context-dependent (brand accent vs. tactical affiliation).
Text-safe variants
--electric-500 (4.1:1 on navy-900) and --hostile (4.2:1) fail WCAG AA for body text. Both pass large-text / UI thresholds but must not be used as inline prose color. The system provides dedicated text variants:
| Token | Hex | On navy-900 |
Use |
|---|---|---|---|
--electric-400 |
#4A8DFF |
5.8:1 ✓ AA | Body-text links, inline accent text, link underlines |
--electric-300 |
#7BA9FF |
7.9:1 ✓ AAA | Emphasized text, critical links, footnote markers |
--hostile-400 |
#EE5050 |
5.3:1 ✓ AA | Error message text, validation copy, destructive link text |
The 500-level tokens remain the brand anchor - fills, borders, glow peaks, large display headings, button backgrounds. The 400-level text tokens exist only because running text needs 4.5:1 to be readable, and the brand hue at 500 doesn’t clear that bar.
Fills never need a text variant - --neutral and --caution at 500 both pass AA as text on navy backgrounds without adjustment.
Topographic
For maps, heatmaps, and elevation-derived visualizations, use a restrained topographic ramp derived from survey-map conventions - low-saturation tans, olives, and slates. Contour lines use --steel-400 at 30% opacity.
Colorways
Three canonical surface compositions cover 90% of what the system produces.
1 - Corporate hero (FDT marketing surfaces):
Tokens: navy-900 canvas · grid overlay at fog-100 @ 4% · electric-500 eyebrow + primary CTA with glow-md · fog-100 heading · fog-200 body · navy-800 / steel-500 secondary button. Ambient electric-500 @ 8% wash in the top-right corner adds atmospheric depth without committing to full glow.
2 - Program card (Defense Programs grid):
Tokens: navy-800 card fill · navy-600 border at rest, electric-500 border + glow-sm on hover/focus (middle card) · classification badge uses caution (external) or electric-500 (FDT-controlled) at 15% fill + 100% stroke · status badge uses semantic color at 15% fill + 100% stroke · wordmark in fog-100, descriptor in steel-300, body in fog-200.
3 - Status badge set (the full classification + status vocabulary):
The same anatomy covers everything: a bordered pill with 15% semantic fill, 100% semantic stroke, and an uppercase label in the matching color. Only the color token and the label text change.
WebAwesome token mapping
The system compiles to WebAwesome’s token shape so wa-* components theme correctly without per-component overrides. FDT’s named tokens are the source of truth; the --wa-* tokens are aliases pointing at them.
Semantic groups
WebAwesome organizes color into five groups - brand, neutral, success, warning, danger. FDT maps as:
/* Brand - electric blue */
--wa-color-brand-50: #7BA9FF; /* electric-300 · AAA text on navy-900 (7.9:1) */
--wa-color-brand-40: #4A8DFF; /* electric-400 · AA body text on dark (5.8:1) */
--wa-color-brand-30: #1D6EF5; /* electric-500 ← primary · fills & large text only */
--wa-color-brand-20: #1456C7; /* electric-600 */
--wa-color-brand-10: #0D3A8A; /* electric-700 (derived) */
/* Neutral - navy → steel → fog */
--wa-color-neutral-0: #0A1220; /* navy-900 */
--wa-color-neutral-5: #0F1A2E; /* navy-800 */
--wa-color-neutral-10: #16243D; /* navy-700 */
--wa-color-neutral-15: #1E3050; /* navy-600 */
--wa-color-neutral-25: #3A4A66; /* steel-500 */
--wa-color-neutral-40: #5A6D8A; /* steel-400 · UI/metadata only, not body text */
--wa-color-neutral-60: #8A9BB4; /* steel-300 · body-text safe (6.5:1 on navy-900) */
--wa-color-neutral-85: #C5D1E2; /* fog-200 */
--wa-color-neutral-95: #E8EEF7; /* fog-100 */
--wa-color-neutral-100: #FFFFFF; /* white */
/* Success - neutral green (APP-6D friendly-neutral) */
--wa-color-success-40: #2FA85A; /* fill + text · 6.3:1 on navy-900 */
/* Warning - caution amber */
--wa-color-warning-40: #F2B535; /* fill + text · 10.4:1 on navy-900 */
/* Danger - hostile red */
--wa-color-danger-40: #EE5050; /* hostile-400 · AA body text on dark (5.3:1) */
--wa-color-danger-30: #E0322C; /* hostile · fills & large text only */
Note: WebAwesome’s scale is inverted - 100 = pure white, 0 = pure black. FDT’s named scale (navy-900 = darkest) follows the more conventional direction. Both are documented so there’s no surprise.
Surface tokens (elevation-aware, dark-theme):
--wa-color-surface-raised: var(--wa-color-neutral-10); /* navy-700 · dialogs, popovers */
--wa-color-surface-default: var(--wa-color-neutral-5); /* navy-800 · cards, panels */
--wa-color-surface-lowered: var(--wa-color-neutral-0); /* navy-900 · canvas, wells */
Text tokens
--wa-color-text-normal: var(--wa-color-neutral-95); /* fog-100 */
--wa-color-text-quiet: var(--wa-color-neutral-85); /* fog-200 */
--wa-color-text-subtle: var(--wa-color-neutral-60); /* steel-300 */
--wa-color-text-disabled: var(--wa-color-neutral-40); /* steel-400 */
--wa-color-text-link: var(--wa-color-brand-40); /* electric-400 · AA body (5.8:1) */
--wa-color-text-error: var(--wa-color-danger-40); /* hostile-400 · AA body (5.3:1) */
Focus and borders
--wa-focus-ring-color: var(--wa-color-brand-30);
--wa-focus-ring-width: 2px;
--wa-focus-ring-offset: 2px;
--wa-focus-ring: var(--wa-focus-ring-width) solid var(--wa-focus-ring-color);
/* FDT adds a glow layer on top of the standard WebAwesome focus ring: */
--fdt-focus-glow: var(--fdt-glow-sm);
FDT-specific extensions (no WebAwesome equivalent) retain the --fdt-* prefix:
--fdt-glow-xs, --fdt-glow-sm, --fdt-glow-md, --fdt-glow-lg, --fdt-glow-xl
--fdt-grid-overlay-opacity (0.03)
--fdt-radar-sweep-opacity (0.25)
--fdt-breakpoint-sm/md/lg/xl
--fdt-classification-sensitive (--wa-color-warning-30)
--fdt-classification-controlled (--wa-color-brand-30)
Convention rule
Use --wa-* when a WebAwesome component consumes the value. Use --fdt-* for extensions WebAwesome has no concept of (glows, tactical textures, classification semantics, breakpoints). Never prefix with --color-* or bare names - the prefix is the namespace.
Theme file
All of the above lives in fdt-theme.css, scoped to :root, .wa-dark so WebAwesome’s light/dark switching picks it up. A future .wa-light theme would override the surface and text tokens; the brand and semantic hues would stay.