Andromeda Pro · Foundation

The primitives

Every Andromeda Pro component is built from the values on this page, read through three layers of tokens. This page is the what. The AI Brain teaches when and how to use each value.

Three layers

  1. 100
    200
    300
    400
    500

    Layer 1

    Primitives

    The neutral ladder and four hue families. A theme retunes these; a component never reads them.

  2. status.info.textbrand 500

    Layer 2

    Semantic

    Named roles such as status.danger.text. Every component reads this layer and only this one.

  3. Live

    Layer 3

    Component wires

    A --component-role variable in the one file that owns it, pointing at exactly one role. The wiring never leaves that file.

The neutral ladder

Thirteen grays, numbered by depth: 100 is the page ground, 1300 the strongest ink. Surfaces, borders and text are all roles pointing into this one ladder.

light

100
200
300
400
500
600
700
800
900
1000
1100
1200
1300

dark

100
200
300
400
500
600
700
800
900
1000
1100
1200
1300

Four hue families

Five stops each, 100 through 500, plus two alphas and a guaranteed-contrast on ink. The ramp itself is the same in both themes; what flips is which stop a role points at, shown further down. Color is never the only channel: a tone always rides with a glyph, a position or a label.

Brand

the live series, the primary action

light

dark

Success

this moved the good way

light

dark

Warning

caution, degraded, restricted

light

dark

Danger

loss, fault, threshold breach

light

dark

Semantic roles

Components never read a primitive. They say what they mean, in eight role groups:

textthe four inks: primary, secondary, muted, faint
surfacethe grounds and the interaction steps a fill climbs
borderthe hairline ladder, subtle to strong, plus the floating frame
statusfour tones × six roles: surface, border, text, on, onMuted, fill
actionwhat a control does: primary, secondary, danger, and their states
focusthe ring, the glow, and their invalid forms
selectionthe mark, the track, the selected edge
chartbaseline, live, context, threshold, grid, and the stacked ramp

How a family crosses the themes

When the theme flips, a role’s stop mirrors around the middle of its family: 100 and 500 swap, 200 and 400 swap, and 300 is the pivot. Fills stop at 200 rather than 100, because 100 barely stands off the light page. The one thing that overrules the mirror is WCAG. Where the mirrored value misses its contrast minimum on the light page ground it steps toward the deep end until it clears. That is why brand and success text reads 300 → 500 rather than 300 → 400: on the light ground their 400 stop measures 3.97 and 4.21, under the 4.5 that normal text requires, so they step again. Danger reaches 4.86 at 400 and stops there. Warning’s 400 measures 3.12, and its 500 clears 4.5 but reads as brown, so its words take an authored deep ochre, marked ink below, the most saturated amber that clears 4.5 (4.88). The mark row lands on 400 everywhere because a mark is a non-text object and needs 3.0, not 4.5. Both columns are resolved from the same functions the site paints with, so they cannot drift from what you see.

RoleBrandSuccessWarningDanger

Text

a status word, a value, a chart label

300 → 500
300 → 500
300 → ink
300 → 400

Secondary text

the quieter second line beside it

200 → 500
200 → 500
200 → ink
200 → 400

Foreground and borders

icons, dots, chart lines, frames

300 → 400
300 → 400
300 → 400
300 → 400

Background fill

a rail, a filled chip, a track

500 → 200
500 → 200
500 → 200
500 → 200

Every color, both themes

The whole set, dark on the left of each pair and light on the right. Enumerated from the live token set rather than listed by hand, so a color added to the system shows up here on its own. A pair marked same is deliberately theme invariant: a scrim darkens what is behind it whatever the theme, and a solid fill that carries pale text has to stay deep in both.

Neutrals

numbered by depth in the stack, not by lightness, so 100 is the page ground in both themes and the ladder never folds

neutral-100
neutral-200
neutral-300
neutral-400
neutral-500
neutral-600
neutral-700
neutral-800
neutral-900
neutral-1000
neutral-1100
neutral-1200
neutral-1300
neutral-scrimsame

Text

the four neutral inks

text-primary
text-secondary
text-muted
text-faint

Surfaces

grounds and the steps a fill climbs under the pointer

surface-floating
surface-scrimsame
surface-base
surface-raised
surface-overlay
surface-hover
surface-active
surface-alpha

Borders

the hairline ladder

border-floating
border-subtle
border-base
border-bright
border-strong

Brand ramp

the primitive stops every brand role points at

brand-100same
brand-200same
brand-300same
brand-400same
brand-500same
brand-alphasame
brand-alpha-strongsame
brand-onsame
brand-on-brightsame

Status

four tones, six roles each

status-success-surfacesame
status-success-border
status-success-on
status-success-on-muted
status-success-text
status-success-fill
status-success-mark
status-success-areasame
status-warning-surfacesame
status-warning-border
status-warning-on
status-warning-on-muted
status-warning-text
status-warning-fill
status-warning-mark
status-warning-areasame
status-danger-surfacesame
status-danger-border
status-danger-on
status-danger-on-muted
status-danger-text
status-danger-fill
status-danger-mark
status-danger-areasame
status-info-surfacesame
status-info-border
status-info-on
status-info-on-muted
status-info-text
status-info-fill
status-info-mark
status-info-areasame

Actions

what a control does

action-primarysame
action-primary-hoversame
action-primary-pressedsame
action-primary-bordersame
action-primary-border-hoversame
action-on-primarysame
action-secondary
action-secondary-hover
action-secondary-pressed
action-secondary-border
action-secondary-border-hover
action-on-secondary
action-ghost-hover
action-ghost-pressed
action-on-ghost
action-on-ghost-hover
action-dangersame
action-danger-hoversame
action-danger-bordersame
action-danger-border-hoversame
action-on-dangersame
action-danger-text-hover
action-active-text
action-active-glow

Focus

the ring and its glow

focus-ring
focus-ring-invalidsame

Selection

checked, selected, current

selection-border
selection-border-hover
selection-surfacesame
selection-mark
selection-tracksame

Chart ink

roles, not series numbers

chart-baseline
chart-live
chart-context
chart-thresholdsame
chart-compare
chart-grid
chart-cursor
chart-axis
chart-stack1
chart-stack2same
chart-stack3
chart-stack4

Gradients

composed values, swapped stop by stop

gradient-brand-fade
gradient-brand-sweep
gradient-surface-soft

Accessibility

Contrast is checked by a script in both themes, not judged by eye, and it is the one thing here that overrules a design decision, including the family pivot above. The rest is written into the system’s rules, so every component follows it the same way.

4.5 : 1

Normal text

Anything under 24px, or under 18.66px bold. Almost all of our text. WCAG 1.4.3.

3.0 : 1

Large text and non-text

Display sizes, and the status icons, dots and borders, the chart lines and the focus ring. WCAG 1.4.3 and 1.4.11.

10 : 1

Measured headroom

The script checks the 4.5 floor. Measured, the primary, secondary and muted text inks sit above 10:1 in both themes, past the 7:1 of AAA.

Focus you can see

Reached by keyboard, every control shows one 1px ring from the focus token, in place of the browser default. An invalid field gets a red ring instead.

Full keyboard use

Menus move with the arrow keys, Home and End. The drawer keeps focus inside while open and hands it back when it closes. The date picker moves by day, week and month. Escape closes what opened.

Reduced motion

When a visitor asks their system for less motion, entrances and cascades turn off, state feedback stays, and animated objects hold a still frame.

Color is never the only signal

Every state a reader has to tell apart also carries an icon, a dot, a label, an arrow or a dash. Success and warning look almost the same to some color-blind readers; the second signal is what they read.

Touch targets

On touch screens the tappable area grows to 40px while the control keeps its size on screen. In tight clusters it stops at 32px, so neighbors never overlap.

Rules per component

Every component lists its own accessibility behavior in its rules: the roles and labels it uses, its keys and its focus handling. An icon-only button, for one, must carry a label.

Typeface

One free, open-source face from Google Fonts carries every label, value and heading in the system.

Aa

Manrope

A modern geometric sans with open, even shapes that stay clear at small interface sizes and hold together at display sizes.

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789

regular 400medium 500semibold 600bold 700
Manrope on Google Fonts

The type ramp

A step names three values, not one: a size, its leading, and its tracking. Taking a step means taking all three. Tracking is a function of size here, open at the small end where letterforms crowd and pulled in at the display end where large type sets loose. Weight is the second axis and stays a component’s choice.

StepSpecimenSizeLine heightTracking
textXsAa10px / 0.625rem14px / 0.875rem0.14em / 14%
textSmAa12px / 0.75rem18px / 1.125rem0.08em / 8%
textMdAa14px / 0.875rem20px / 1.25rem0.02em / 2%
textLgAa16px / 1rem24px / 1.5rem0.02em / 2%
textXlAa18px / 1.125rem28px / 1.75rem0
text2xlAa20px / 1.25rem30px / 1.875rem0
displayXsAa24px / 1.5rem32px / 2rem-0.02em / -2%
displaySmAa30px / 1.875rem38px / 2.375rem-0.02em / -2%
displayMdAa36px / 2.25rem44px / 2.75rem-0.02em / -2%
displayLgAa48px / 3rem60px / 3.75rem-0.02em / -2%
displayXlAa60px / 3.75rem72px / 4.5rem-0.02em / -2%
display2xlAa72px / 4.5rem90px / 5.625rem-0.02em / -2%

Spacing

A 4px grid with one half-step. Control heights ride their own three-rung ladder (28 / 32 / 40) so fields, buttons and toggles in a row always agree.

1
4px
1.5
6px
2
8px
3
12px
4
16px
5
20px
6
24px
8
32px
10
40px
12
48px