Roles grid

Every role as a colour tile: the role, what changes for them, where they meet Loom, and an arrow to their page.

Organism · stable · v1.0.0 · owner: Site system lead · contract 19 of 20 points (open: figma)

Do and don't

Do: Six roles

Rendered by roles-grid.ts

Open example: Roles grid · Do: Six roles Use the full-page example to follow page links.

Find your role.

Do: Where you meet Loom

Rendered by roles-grid.ts

Open example: Roles grid · Do: Where you meet Loom Use the full-page example to follow page links.

Concrete.

Don't: State colours

Rendered by roles-grid.ts

Open example: Roles grid · Don't: State colours Use the full-page example to follow page links.

Tile colour is structure, cycling the dyes.

Don't: Vague wins

Rendered by roles-grid.ts

Open example: Roles grid · Don't: Vague wins Use the full-page example to follow page links.

Say what changes.

Rules

RuleWhyCheck
Tiles cycle the dyes in a fixed order.Colour is structure; no role is ranked by colour.Automated: tests/unit/site-system.test.ts

API

PropTypeRequiredDefaultWhat it does
roleslistYesRoles: label, text, href, meet.

Contract details

The full contract: identity, anatomy, variants, states, tokens, layout, motion, accessibility, content, tests

Identity

AspectValue
Idroles-grid
LayerOrganisms
Categorynavigation
OwnerSite system lead
Statusstable
Version1.0.0
Sourceapps/showcase/site/system/organisms/roles-grid.ts (private repository; the contract and the render function are this one module)
VersionDateChange
1.0.02026-10-26Roles grid as one module: its markup moved out of the page builder (scripts/site) into the system.

Use when

  • The landing's roles section. Why: Each reader finds their role in one glance.

Do not use when

  • On role pages. Why: The Role switcher does that job quietly.

Anatomy

PartWhat it is
rootul.roles-grid
tileli.field-<colour> with a: b.rg-role, span.rg-win, span.rg-meet, span.rg-go (aria-hidden arrow)

Made of: dye-field, text.

Used in: roles-section.

Variants

VariantWhenWhy
defaultWherever the page declaration places it.One shape per job keeps pages predictable.

States

StateRendered or not applicable
defaultdefault
hoverThe tile tints by 10%, the arrow moves and the line underlines.
focus-visibleA 3 px currentColor outline inset by 6 px.
activeNot applicable: A link.
disabledNot applicable: Every role has a page.
loadingNot applicable: Build time.
emptyNot applicable: Skipped when empty.
errorNot applicable: No data that can fail.
currentNot applicable: Not on role pages.
visitedNot applicable: Tile text keeps its colour for contrast.
expandedNot applicable: Does not open.

Tokens

PartToken
tile.background--field-bg (cycling indigo, madder, saffron, teal, ink)
role.font--type-small-strong
win.font--type-h3
@hover.tintcolor-mix --field-fg 10%
--roles-grid-gap-space-2var(--space-2)
--roles-grid-gap-space-4var(--space-4)
--roles-grid-padding-space-8var(--space-8)
--roles-grid-padding-space-7var(--space-7)
--roles-grid-transition-dur-moderatevar(--dur-moderate)
--roles-grid-transition-ease-standardvar(--ease-standard)
--roles-grid-font-type-small-strongvar(--type-small-strong)
--roles-grid-font-type-h3var(--type-h3)
--roles-grid-letter-spacing-ls-h3var(--ls-h3)
--roles-grid-font-type-smallvar(--type-small)
--roles-grid-transform-space-2var(--space-2)
--roles-grid-padding-space-6var(--space-6)
--roles-grid-padding-space-5var(--space-5)
--roles-grid-font-type-bodyvar(--type-body)
--roles-grid-font-weight-weight-strongvar(--weight-strong)
--roles-grid-background-field-bgvar(--field-bg)
--roles-grid-color-field-fgvar(--field-fg)
--roles-grid-background-field-fgvar(--field-fg)
--roles-grid-color-field-fg-2var(--field-fg-2)

Layout

AspectValue
breakpointsRequired review at 390, 768, 1024 and 1440 px; execution is not implied by this declaration; columns stack under 768 px; the wrap keeps a 16 px gutter on phones.
wrappingText wraps; nothing scrolls sideways.
textExpansionJapanese runs 20 to 40% longer; headings break between phrases (jaBreaks) and blocks grow downwards.

Spacing and rhythm

AspectValue
internal--space-8 padding per tile.
external2 px seams.
rhythmUnder the roles heading.

Motion

AspectValue
movesThe arrow, --space-2 to the right.
triggerHover with a fine pointer.
duration--dur-moderate
easing--ease-standard
interruptibleYes.
reducedNo movement; the underline still shows.
whyA cue that the tile is the link.

Runtime and reuse

  1. Render-only element; mount any registered child enhancements separately. Preserve required Site CSS, fonts, responsive and locale rules from nativeElement.

Accessibility passport

AspectValue
rolea landmark or list, as stated in its parts
nameIts visible text
keyboardLinks and buttons inside, in reading order.
focusThe --focus ring on every link and button inside.
screenReaderRead in source order; decorative weaving is aria-hidden.
contrastInk on cotton 14:1; text on every dye field 4.5:1 or better (checked by check-brand).
targetLinks and buttons are 44 px tall.

Content

SlotLengthVoice
role3 wordsThe role
win1 sentenceWhat changes for them

Good: “Design-system leads · Decisions stay made.”

Bad: “For you”

Japanese: Roles from landing.ja.md.

Icons and illustrations

None: this element uses no icon or illustration of its own.

Decisions and exceptions

Usage

50 uses across the built pages (measured by npm run site:system).

Tests

AspectValue
unittests/unit/site-system.test.ts: renders every do and don't example through the registry and checks the classes it owns
visualNot yet: there are no screenshot baselines; the Library page is checked for sideways scroll at 1440 px by tests/site/system.spec.ts
a11ytests/site/system.spec.ts: axe (0 serious or critical) on the element's Library page in light and dark
parityscripts/site/system/check.ts: Library examples are rendered by the same render function the site imports

Figma

not-yet: The Loom Site Figma library is the last stage of the plan; this element is not mapped yet.

Open in Storybook

Start with a conversation about your system.

We read your system, show you what we found, and agree with your team what to fix first.