A system, seen as cloth

Draws a design system as cloth: rows are component families, columns are products, and the weave loosens where health drops.

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

Do and don't

Do: On Govern

Rendered by cloth-diagram.ts

Open example: A system, seen as cloth · Do: On Govern Use the full-page example to follow page links.

Health across products at a glance.

Do: Frayed edges with the legend

Rendered by cloth-diagram.ts

Open example: A system, seen as cloth · Do: Frayed edges with the legend Use the full-page example to follow page links.

Every colour has its word; the existing ambient effect is separately governed.

Don't: Without the sample tag

Rendered by cloth-diagram.ts

Open example: A system, seen as cloth · Don't: Without the sample tag Use the full-page example to follow page links.

It is not a client's data.

Don't: Section colours in cells

Rendered by cloth-diagram.ts

Open example: A system, seen as cloth · Don't: Section colours in cells Use the full-page example to follow page links.

Cell colours mean health only.

Rules

RuleWhyCheck
The a system, seen as cloth is drawn from the sample cloth data (apps/showcase/site/visuals/cloth-data.ts) at build time.A figure read from the real records cannot drift from them.Automated: npm run site:build (reads the data; fails if it is missing)
The legend names every band colour used.Colour alone never carries meaning.Automated: tests/unit/site-system.test.ts

API

PropTypeRequiredDefaultWhat it does
variantplain | frayNo"plain"Plain uses one knot pulse (2412 ms); fray adds one frayed-edge cycle (3204 ms). Both retain the same sample data and selection controls.
langen | jaNo"en"The selected cloth sample text remains English in either page locale; its root is explicitly lang=en. No native Japanese translation is claimed.

Contract details

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

Identity

AspectValue
Idcloth-diagram
LayerOrganisms
Categoryfigure
OwnerSite system lead
Statusstable
Version1.0.0
Sourceapps/showcase/site/system/organisms/cloth-diagram.ts (private repository; the contract and the render function are this one module)
VersionDateChange
1.0.02026-10-26A system, seen as cloth, drawn at build time from the sample cloth data (apps/showcase/site/visuals/cloth-data.ts).

Use when

  • Govern and Organisations, where the page explains health across products. Why: One picture shows where a system is loose across products.

Do not use when

  • As a real client's health map. Why: It is sample data, tagged as such.

Anatomy

PartWhat it is
rootfigure.visual (cloth)
maptable.cloth with one cell per family and product
legendBand legend with words
sideThread card for the selected cell

Made of: figure-frame, band-word, table, tag, caption.

Used in: pages directly.

Variants

VariantWhenWhy
plainDefault sample health map.Static weave density and text retain the health meaning; plain adds one knot pulse (2412 ms).
frayThe existing frayed-edge illustration is requested.It adds one authored edge cycle (3204 ms) while the managed root is visible; reduced motion, interruption and fallback remain still.

States

StateRendered or not applicable
defaultComplete cloth
hoverA cell outlines.
focus-visibleMarked cells are buttons with the --focus ring.
activeEvery native cell button updates aria-pressed and its selected explanatory card.
disabledNot applicable: All authored cells are selectable; no disabled variant is provided.
loadingThe build-time sample map/card/list stays readable while its managed native chunk loads.
emptyNot applicable: Always data.
errorCaught chunk or native initialization failure restores the original sample map/card/list; the host records failure and remount may retry.
currentThe selected cell, shown in the thread card.
visitedNot applicable: Not links.
expandedThe thread card shows the picked cell.

Tokens

PartToken
cell.colourthe band colour of the cell's own health (a mark with its word in the legend)
legend.font--type-small
--cloth-diagram-gap-space-9var(--space-9)
--cloth-diagram-gap-space-10var(--space-10)
--cloth-diagram-padding-bottom-space-3var(--space-3)
--cloth-diagram-font-type-labelvar(--type-label)
--cloth-diagram-padding-space-1var(--space-1)
--cloth-diagram-padding-space-2var(--space-2)
--cloth-diagram-font-type-small-strongvar(--type-small-strong)
--cloth-diagram-padding-right-space-4var(--space-4)
--cloth-diagram-font-size-fs-labelvar(--fs-label)
--cloth-diagram-border-radius-radiusvar(--radius)
--cloth-diagram-outline-focusvar(--focus)
--cloth-diagram-outline-inkvar(--ink)
--cloth-diagram-right-space-2var(--space-2)
--cloth-diagram-top-space-2var(--space-2)
--cloth-diagram-background-surfacevar(--surface)
--cloth-diagram-box-shadow-inkvar(--ink)
--cloth-diagram-animation-dur-weavevar(--dur-weave)
--cloth-diagram-animation-ease-standardvar(--ease-standard)
--cloth-diagram-gap-space-4var(--space-4)
--cloth-diagram-gap-space-7var(--space-7)
--cloth-diagram-margin-top-space-6var(--space-6)
--cloth-diagram-font-size-fs-smallvar(--fs-small)
--cloth-diagram-margin-top-space-7var(--space-7)
--cloth-diagram-gap-space-5var(--space-5)
--cloth-diagram-padding-space-4var(--space-4)
--cloth-diagram-border-top-linevar(--line)
--cloth-diagram-margin-top-space-2var(--space-2)
--cloth-diagram-background-maddervar(--madder)
--cloth-diagram-background-saffronvar(--saffron)
--cloth-diagram-text-decoration-color-linevar(--line)
--cloth-diagram-transition-dur-weavevar(--dur-weave)
--cloth-diagram-transition-ease-standardvar(--ease-standard)
--cloth-diagram-transition-delay-dur-fastvar(--dur-fast)
--cloth-diagram-transition-delay-dur-moderatevar(--dur-moderate)
--cloth-diagram-transition-delay-dur-slowvar(--dur-slow)
--cloth-diagram-background-cottonvar(--cotton)
--cloth-diagram-padding-space-7var(--space-7)
--cloth-diagram-border-top-maddervar(--madder)
--cloth-diagram-border-top-color-saffronvar(--saffron)
--cloth-diagram-border-top-color-tealvar(--teal)
--cloth-diagram-border-top-color-indigovar(--indigo)
--cloth-diagram-font-size-fs-bodyvar(--fs-body)
--cloth-diagram-margin-space-3var(--space-3)
--cloth-diagram-margin-space-5var(--space-5)
--cloth-diagram-color-ink-2var(--ink-2)
--cloth-diagram-margin-top-space-5var(--space-5)

Layout

AspectValue
breakpointsRequired review at 390, 768, 1024 and 1440 px; execution is not implied by this declaration; the figure reflows to one column under 768 px.
wrappingLabels wrap; drawings scale to the column.
textExpansionJapanese labels are 20 to 40% longer and wrap inside their cells.

Spacing and rhythm

AspectValue
internalInside the Figure frame's --space-7 padding.
external--space-9 above and below in prose.
rhythmAfter the text whose claim it proves.

Motion

AspectValue
movesRows weave in once on first view; loose markers pulse once (2412 ms), and fray adds one edge cycle (3204 ms). Both cycles finish at their original static pose.
triggerScrolled into view.
duration--dur-weave per row
easing--ease-standard
interruptibleHidden/offscreen/live reduced preference settles the entrance and consumes ambient motion, with no automatic restart. Disposal restores still fallback.
reducedShown complete.
whyWeaving in shows the metaphor: health is how tightly the cloth holds.

Runtime and reuse

  1. stylesheet: /css/site.css. Built Site tokens, core and registered element CSS; preserve modes, focus and responsive rules.

  2. stylesheet: /css/demos.css. Existing legacy demo styles where the rendered specimen uses them.

  3. font: /fonts/. Self-hosted files referenced by Site @font-face, with licences; Japanese locale overrides remain applicable.

  4. Static fallback: Original build-time specimen remains readable before loading and after chunk/initialization failure; enhancement controls retain authored hidden state.

  5. Configured initializer: apps/showcase/site/visuals/cloth.ts#init. The host owns transactional static-markup restoration and runtime state.

  6. Consumer module (imports relative to the configured source root):
    import { createRuntimeHost } from "./src/workflows/runtime-host";
    import { SITE_RUNTIMES } from "./apps/showcase/site/runtime-registry";
    const definition = SITE_RUNTIMES.find(entry => entry.binding.id === "cloth");
    if (!definition || definition.binding.lifecycle.kind !== "managed") throw new Error("Managed runtime binding unavailable");
    const host = createRuntimeHost([definition]);
    export function mountRuntime(container: ParentNode) { return host.mountAll(container); }
  7. After inserting the rendered markup, call mountRuntime(container) for the container holding [data-visual="cloth"]. Retain the returned disposal function and call it before removing, replacing or remounting, including every Storybook args render. The configured host restores captured static markup/attributes on disposal or caught load/initialization failure; retry starts a fresh managed remount.

Accessibility passport

AspectValue
rolefigure, named by its caption
nameThe caption, and a text alternative for any drawing
keyboardNot interactive unless stated.
focusLinks inside are in reading order.
screenReaderReads the figure's text and caption; drawings have role=img with a description.
contrastInk on surface 14:1; dyes used only as marks with their words.
targetNot a target.

Content

SlotLengthVoice
caption2 sentencesWhat rows, columns and weave mean

Good: “Each row is a component family and each column a product. Colour and weave show health.”

Bad: “Your system”

Japanese: Sample chart, cell descriptions and repair details retain the source English and are marked lang=en; Japanese coverage remains open.

Icons and illustrations

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

Decisions and exceptions

Usage

24 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.