# Cohesion

The two rendering paths are meant to be invisible to a reader. An Astro part
ships no JavaScript and a React component ships Radix behavior, but a button
is the same button either way: the same radius, the same edge, the same focus
ring, the same row height.

This page is where that is checked rather than asserted. Each pair is the Astro
part on the left and its React counterpart on the right, with the same content
in both, so a value that has drifted shows up as a step between the columns.
The docs suite measures the button pair on every run; everything else is read
by eye.

Two vocabularies do not pair one for one, and the page does not pretend they
do. `Button` calls its outlined step `secondary` where shadcn calls it
`outline`, and `Badge`'s tinted advisory tones — info, success, warning — have
no shadcn counterpart, so only the three shapes that do correspond are shown.

Astro

Primary
Secondary
Ghost
Danger

Small
Medium
Disabled

Astro

Neutral
Accent
Danger

Small
Medium

Astro

Consuming the package

The Astro parts take their data through props, so nothing in them knows
what a product or a demo is.

Read the guide

Skip

Astro

Astro

## What holds the pairs together

Nothing on this page is drawn twice. The shape, the edge, the ring and the
motion all come from the same tokens; what differs is only which file reads
them.

- `shadcn.css` aliases every shadcn variable onto a hub token, and names the
  scales shadcn writes against — the radius ladder, the type ramp, the spacing
  unit, the three motion steps — so a generated class cannot introduce a value
  the hub has not already named.
- The control heights are tokens, `--helia-control-sm`, `--helia-control-md`
  and `--helia-control-lg`. A recipe and a class string that both read one of
  them land on the same row.
- The focus ring is one outline: 2px at a 2px offset, drawn in
  `--helia-focus-ring-color`, whether it arrives as `.helia-focus-ring` or as
  `focus-visible:outline-2`.
- `shadcn add` rewrites the file it regenerates. Re-run
  `node packages/helia-ui/scripts/rename-token-prefix.mjs --root .` after an
  add to put the token-mapped class strings back.
