Configuration
Everything is set in charpente.config.ts. defineCharpente only types the object.
import { defineCharpente } from 'charpente'
export default defineCharpente({ defaultTheme: 'solid', timeZone: 'Europe/Paris', schedule: [{ theme: 'christmas', from: '12-15', to: '12-31' }], motion: ['pulse', 'shimmer'], timing: { delay: 120, stagger: 40 }, colorScheme: { dark: '[data-theme="dark"]', tokens: { light: { base: '#e5e7eb' }, dark: { base: '#2a2d34' }, }, }, themes: { brume: { extends: 'solid', tokens: { base: 'rgba(96, 165, 250, 0.28)' }, paint: { media: { style: { borderRadius: '50%' } }, }, }, }, motions: { rebond: { duration: '1.2s', keyframes: { '0%, 100%': { transform: 'translateY(0)' }, '50%': { transform: 'translateY(-3px)' }, }, }, },})Top-level options
Section titled “Top-level options”| Option | Type | Default | Role |
|---|---|---|---|
defaultTheme |
string | 'solid' |
Theme of areas without data-charpente-theme. |
schedule |
ScheduleEntry[] |
[] |
Seasonal slots, see the calendar. |
timeZone |
string (IANA) | runtime time zone | Time zone used to read today’s date in schedule. |
motion |
string or string[] | 'shimmer' |
Default motion(s). 'none' disables. |
timing |
Timing |
{ delay: 120, stagger: 0 } |
Default delay and offset. |
reveal |
number | 0 |
Delay in ms between two nested levels when content appears after loading. 0 fades the first level only. Local setting with --charpente-reveal. |
initial |
boolean or number | off | Vite only. Serves the page already marked as loading, so no content flashes before your scripts run. The page is released when your code takes over, or that many ms after the load event (true means 3000). Needs inline scripts to be allowed by your CSP. |
scope |
'element' or 'page' |
'element' |
Where the wrappers and setLoading put the loading state by default: on their own element, or on the whole page (<html>). Local setting with the scope prop. |
themesDir |
string | 'themes' |
Folder scanned for themes: each subfolder with a theme.ts file is declared under its folder name. |
shapes |
Record<string, ShapeDef> |
{} |
Layered shapes to register by name for paint.shape, see layered shapes. |
colorScheme |
ColorScheme |
system media query | Dark mode and per-mode tokens. |
themes |
Record<string, ThemeDef> |
{} |
Adds themes, or replaces a built-in theme of the same name. |
motions |
Record<string, MotionDef> |
{} |
Adds motions, or replaces a built-in motion. |
timing
Section titled “timing”| Key | Default | Role |
|---|---|---|
delay |
120 ms |
Wait before the skeleton appears. Overridable with --charpente-delay. |
stagger |
0 ms |
Delay added per rank among siblings. Overridable with --charpente-stagger. |
colorScheme
Section titled “colorScheme”Without dark, dark tokens apply through @media (prefers-color-scheme: dark). With dark, they apply to the element matching the selector, for example the html element carrying data-theme="dark".
colorScheme: { dark: '[data-theme="dark"]', tokens: { dark: { base: '#1f2937', strong: '#374151' } },}| Key | Type | Role |
|---|---|---|
dark |
CSS selector | Replaces the media query with a selector. |
tokens.light |
Tokens | Overrides light-mode tokens, set on :root. |
tokens.dark |
Tokens | Overrides dark-mode tokens. |
Themes
Section titled “Themes”A theme has these optional fields: extends, tokens, paint, hover, hoverMotion and motion (the name of the motion it runs by default). With extends, the theme inherits the parent’s tokens, paints and hover: tokens are merged, paints are merged type by type, and within style key by key. fill and size replace the parent’s.
Import a single theme
Section titled “Import a single theme”Built-in theme names in theme: work with the Vite plugin and the CLI, which build the CSS in Node and ship no JavaScript. In a browser or React Native, compile and nativeTheme come from charpente/lite, which only knows solid: import the themes you use from charpente/themes, one export each, and the bundler drops the rest.
import { compile } from charpente/liteimport { cyberpunk } from charpente/themes
const { css } = compile({ themes: { cyberpunk }, defaultTheme: cyberpunk })A name that is not imported throws an error that points to charpente/themes. Measured with esbuild, minified:
| Bundle | Size | Gzip |
|---|---|---|
compile from charpente (18 themes) |
24.2 kB | 7.7 kB |
compile from charpente/lite with one theme |
14.6 kB | 5.7 kB |
nativeTheme from charpente |
14.8 kB | 4.3 kB |
nativeTheme from charpente/lite |
4.2 kB | 1.8 kB |
One theme alone from charpente/themes |
0.5 kB | 0.3 kB |
Tokens
Section titled “Tokens”--charpente-* CSS variables usable in fill and style. A token defined in a theme applies to areas of that theme, whether the mode is light or dark.
| Token | Light | Dark | Usage |
|---|---|---|---|
base |
#e5e7eb |
#2a2d34 |
Main color of the skeleton. |
strong |
#c4c8d0 |
#454a55 |
Outlines, patterns, subtle accents. |
shine |
rgba(255, 255, 255, 0.7) |
rgba(255, 255, 255, 0.08) |
Glint color of shimmer. |
accent |
#0891b2 |
#22d3ee |
First decoration color. |
accent2 |
#c026d3 |
#e879f9 |
Second decoration color. |
A --charpente-radius variable (0.35em) is also set on :root, used by solid for its corners.
Paint per leaf type
Section titled “Paint per leaf type”A “leaf” is an element that is painted as a single piece. paint assigns a paint to each of the four types:
| Type | Elements concerned |
|---|---|
text |
Any element without child elements (a paragraph, a heading, a link, a cell), except media and controls. |
media |
img, svg, video, canvas, picture, iframe. |
control |
button, input, select, textarea. |
block |
Elements marked data-charpente-block: the element is painted as one block and its children are hidden. |
| Key | Type | Role |
|---|---|---|
fill |
string | Comma-separated background layers (background-image). Default: a flat var(--charpente-base) fill. |
size |
string | Size of each layer, in the same order (background-size). auto for an unspecified layer. |
position |
string | Position of each layer (background-position), 0 0 by default. A layer can use calc(var(--charpente-flow) * 96px) to move with an ambient motion. |
repeat |
string | Repeat of each layer (background-repeat), repeat by default. no-repeat pins a layer such as a moon in a corner. |
style |
Record<string, string> |
Added CSS declarations: borderRadius, clipPath, outline, or an --x variable. |
themes: { stripes: { extends: 'solid', paint: { text: { fill: 'repeating-linear-gradient(to bottom, var(--charpente-base) 0 0.8lh, transparent 0.8lh 1lh)', style: { borderRadius: '2px' }, }, media: { fill: 'radial-gradient(circle, var(--charpente-strong) 1.4px, transparent 2px), linear-gradient(var(--charpente-base), var(--charpente-base))', size: '8px 8px, auto', }, }, },}hover changes the look of a skeleton shape while the pointer is over it. It is set per leaf type, like paint, and only the types you name change. The fields are those of a paint (fill, size, style) plus radius and border, which take the same values as in the short format.
| Key | Type | Role |
|---|---|---|
hover |
string or per type | A token name ('strong', 'accent'…) or a color paints every type with it. An object gives fill, size, style, radius and border per type. |
hoverMotion |
'pause', 'faster' or 'none' |
What the animation does under the pointer: stop, run faster (--charpente-hover-fast, default 600ms), or nothing. Default none. |
motion |
string | The motion used by default for this theme when the area has no data-charpente-motion, for instance crt. Inherited with extends. |
themes: { survol: { extends: 'solid', hover: 'accent' }, 'survol-fin': { extends: 'brume', hover: { text: { fill: 'linear-gradient(var(--charpente-accent), var(--charpente-accent))', radius: '999px' }, media: { border: '3px solid var(--charpente-accent)' }, control: { style: { opacity: '0.6' } }, block: { fill: 'linear-gradient(var(--charpente-accent2), var(--charpente-accent2))' }, }, hoverMotion: 'pause', },}A short introduction spanning two or three lines, to show how text is painted line by line.
Details:
- The rules apply to the automatic mode and to the faithful mode: the captured zones (
data-charpente-capture) react as a whole, and their text and media layers take the hover paint. - They sit inside
@media (hover: hover), so touch screens never see them. The hovered shapes receive pointer events, and aninertarea never receives any: leaveinertoff the area (keeparia-busy) when you want hover, knowing that a loading link or button under the pointer can then be clicked. The framework wrappers always setinert, so hover is for hand-written markup for now. - The change is eased over
--charpente-hover-ms(default150ms). The easing is dropped when the user prefers reduced motion. - With
extends,hoveris merged type by type and key by key likepaint, andhoverMotionis inherited. - React Native has no hover:
nativeThemeignores both fields.
Motions
Section titled “Motions”| Key | Default | Role |
|---|---|---|
duration |
required | Duration of one cycle, for example '1.4s'. |
easing |
'ease-in-out' |
CSS timing function. |
iterations |
'infinite' |
Number of cycles. |
layer |
none | Background layer overlaid on the leaves, used by shimmer for its glint. |
keyframes |
required | Animation steps: from, to or percentages, each with its declarations. |
container |
none | Keyframes applied to the loading container next to the leaf keyframes, as glitch does. |
overlay |
none | A layer drawn over the loading container: style for its static look, duration and keyframes for its movement, which stops under reduced motion. Used by crt. |
motions: { blink: { duration: '900ms', easing: 'steps(2, end)', iterations: 'infinite', keyframes: { from: { opacity: '1' }, to: { opacity: '0.4' }, }, },}Configuration errors
Section titled “Configuration errors”The compiler fails with an explicit message in these cases:
- an unknown theme in
defaultTheme,extendsorschedule; - a theme that extends itself, directly or in a loop;
- an unknown motion in
motion; - a
scheduledate that is not inMM-DDform; - an unknown time zone in
timeZone.
It warns, without failing, when two default motions animate the same property: the last one wins.
Exposed CSS variables
Section titled “Exposed CSS variables”| Variable | Role |
|---|---|
--charpente-delay |
Local delay, with unit (200ms). |
--charpente-stagger |
Local offset, with unit. |
--charpente-base, -strong, -shine, -accent, -accent2 |
Tokens, overridable on any element of the area. |
--charpente-radius |
Radius of solid. |
--charpente-hover-ms |
Duration of the hover transition, with unit (default 150ms). |
--charpente-hover-fast |
Cycle duration with hoverMotion: 'faster' (default 600ms). |