Skins & motion
One grammar, two renderings, and choreography that plays everywhere.
Chapter complete
2,450
import "@objectifthunes/royal-games-ui/tokens.css";
import { SkinProvider, useSkin } from "@objectifthunes/royal-games-ui";
<SkinProvider defaultSkin="enamel">
<App />
</SkinProvider>
// anywhere below:
const { skin, setSkin } = useSkin();
setSkin(skin === "enamel" ? "gloss" : "enamel");Enamel draws every component with a dark contour, a gold bevel frame and a matte material face. Gloss renders the same grammar borderless, gradients, extrusion shadows and a glossy cap. The stylesheet keys everything on data-rg-skin, so switching skins is one attribute, no re-render of your tree.
Both skins, side by side
2,450
2,450
Motion is everywhere
import { useEntranceMotion } from "@objectifthunes/royal-games-ui";
const { ref, playing, replay } = useEntranceMotion<HTMLDivElement>();
<div
ref={ref}
className={playing ? "rg-entering rg-play" : undefined}
>
<Coin decorative={false} title="Coin" size="large" />
<Gem decorative={false} title="Gem" size="large" />
</div>
<Button width="wide" onClick={replay}>Replay entrance</Button>There is no motion module to opt into, every preview on this site is a live motion scope, and so is every package Screen. useEntranceMotion owns a local choreography scope and exposes its active state; replay() restarts that scope. The ▶ MOTION control in the header replays the whole page. Reduced motion is respected by the package.