HatchedDocs
Reference

Theme tokens

Every CSS variable the widget loader honors — what it does, default value in light and dark mode, and how to override it from the script tag or at runtime.

The widget loader exposes a single contract for visual customization: a flat set of --hw-* CSS custom properties. Every widget reads from these variables — recolor them once and every mounted widget picks up the new palette without touching the loader bundle.

This page lists every variable the loader writes, how it maps to the underlying token system, and how to override it at three different levels.

How overrides flow

The loader resolves theme tokens in this order, last write wins:

  1. Built-in defaultslight or dark palette baked into the loader.
  2. data-theme-vars — JSON-encoded --hw-* map on the script tag (set once when you paste the embed).
  3. window.HatchedWidgets.remount({ themeVars }) — runtime overrides pushed from your host page after the embed has mounted. See the Runtime configuration guide for details.

Any key that does not begin with --hw- is dropped by the loader's style serializer, so you can't accidentally leak host-page CSS variables into the shadow DOM. Pass strings only; the loader does not parse JS values.

Try it

The playground writes overrides into a mock widget styled with the same tokens as the production loader. Adjust a token to see exactly which surface it controls, then copy the script tag at the bottom into your real embed.

Tokens
Preview widget
Daily streak
14days
6 more to your next milestone
On a roll
Copy as data-theme-vars
<script
  src="https://cdn.hatched.live/widget.js"
  data-embed-token="EMBED_OR_SESSION_TOKEN"
  data-theme="light"
  data-theme-vars='{"--hw-accent":"#FF6B4A"}'
  defer
></script>

Reference

Surfaces

VariableLightDarkWhat it controls
--hw-bg#FAF7F2#0D0B08Outer widget shell background
--hw-bg-elevated#FEFCF8#1A1814Elevated panels (popovers, sheets)
--hw-surface#FFFFFF#2A241ACard backgrounds inside the shell
--hw-surface-muted#F4EFE6#1A1814Secondary chip / neutral pill background
--hw-overlayrgba(13,11,8,0.48)rgba(0,0,0,0.72)Modal scrim

Borders

VariableLightDarkWhat it controls
--hw-border#E0D7C3#3D3629Default card and shell border
--hw-border-strong#CFC9BE#5A5246Hover/active borders

Text

VariableLightDarkWhat it controls
--hw-text#1A1814#FEFCF8Default body text
--hw-text-secondary#5A5246#ECE5D6Sub-headings, secondary labels
--hw-text-muted#7E7668#A8A196Meta text, captions
--hw-on-accent#FFFFFF#0D0B08Text drawn on top of --hw-accent

Accent (primary brand color)

The accent ramp is what most tenants override first. Pick a brand hue for --hw-accent, derive a darker --hw-accent-strong for hover and a tinted --hw-accent-soft for chips/pills.

VariableLightDarkWhat it controls
--hw-accent#FF6B4A#FF8562Primary buttons, key chips, progress fills
--hw-accent-strong#E84F30#FFA284Hover, focus, active states
--hw-accent-soft#FFE4D8rgba(255,133,98,0.16)Soft fills, badge backgrounds, ghost rows

Semantic colors

VariableLightDarkWhat it controls
--hw-positive#12E8A0#5FFFC6Success states, completed progress
--hw-positive-soft#C9FFECrgba(45,255,185,0.16)Success chip backgrounds
--hw-info#6E7BFF#8E99FFInformational toasts and tags
--hw-warn#F5A800#FFC427Warning ribbons, "at risk" cues
--hw-danger#F84C5C#FF7C87Destructive actions, error toasts
--hw-yolk#FFC427#FFC427The Hatched egg yolk (rarely overridden)

Geometry

VariableDefaultWhat it controls
--hw-radius16pxOuter shell radius
--hw-card-radius12pxCard / panel radius
--hw-button-radius8pxButtons, chips
--hw-density-scale1Multiplier on vertical rhythm (try 0.85 for compact, 1.15 for relaxed)
--hw-pad-shell16pxShell padding
--hw-pad-card12pxCard padding
--hw-gap12pxDefault flex/grid gap inside widgets

Typography

The loader ships Geist for body copy and Gluten for the playful display family by default. Override these to inherit the host site's fonts — the loader injects the fallback chain you provide; it does not bundle additional webfonts.

VariableDefaultWhat it controls
--hw-font-body'Geist', 'Inter', system-ui, sans-serifBody text
--hw-font-display'Gluten', 'DynaPuff', 'Fraunces', serifHeadlines, ceremony copy
--hw-font-mono'Geist Mono', 'JetBrains Mono', ui-monospace, monospaceCode, tokens, numeric counters
--hw-font-base14pxBody size
--hw-font-title20pxSection headings
--hw-font-meta12pxCaption text
--hw-font-eyebrow10pxUppercase eyebrows

Other geometry primitives

VariableDefaultWhat it controls
--hw-avatar64pxAvatar / buddy portrait square
--hw-tile-min140pxMinimum tile width in marketplace / grid widgets
--hw-bar-h8pxProgress bar height
--hw-btn-pad-y8pxButton vertical padding
--hw-btn-pad-x16pxButton horizontal padding
--hw-shell-max360pxWidest the shell will grow before clamping
--hw-shadow0 1px 2px rgba(13,11,8,0.04), 0 1px 1px rgba(13,11,8,0.02)Card shadow

Alias tokens (you don't need to set these)

A handful of widgets reference parallel token names that resolve to the canonical tokens above. You never have to set them — override the canonical token and the alias follows automatically. They exist only so older widget styles keep working; listing them here so nothing looks "missing".

AliasResolves to
--hw-color-primary / --hw-color-primary-strong / --hw-color-primary-soft--hw-accent / --hw-accent-strong / --hw-accent-soft
--hw-text-primary / --hw-text-default--hw-text
--hw-border-default / --hw-border-subtle--hw-border
--hw-path-accent--hw-accent (Path widget node ramp)
--hw-radius-card / --hw-radius-button--hw-card-radius / --hw-button-radius
--hw-color-text-inverse / --hw-color-surface-inverse--hw-bg / --hw-text

Optional overrides (no loader default)

These tokens are not written by the loader's :host block, so they have no Light/Dark default of their own. They are only read as the first choice in a var() fallback chain — leave them unset and the listed fallback applies; set them with data-theme-vars (or remount) to take control of that one surface.

VariableFalls back toWhat it controls
--hw-bg-sunken--hw-bgInset wells (progress trays, code blocks)
--hw-shell#FEFCF8 (literal)Chrome layering used by the dressing animation SVG
--hw-skeleton-base--hw-bg-sunken, then --hw-bgSkeleton placeholder base
--hw-skeleton-shine--hw-bg-elevated, then --hw-bgSkeleton shimmer highlight

Setting tokens from the script tag

The simplest path: pass a data-theme-vars attribute on the loader script. The value is JSON, keys are CSS variable names, values are strings.

<script
  src="https://cdn.hatched.live/widget.js"
  data-embed-token="EMBED_OR_SESSION_TOKEN"
  data-theme="light"
  data-theme-vars='{"--hw-accent":"#5B5BFF","--hw-accent-strong":"#3F3FFF","--hw-accent-soft":"#E4E4FF","--hw-radius":"20px"}'
  defer
></script>

<div data-hatched-mount="buddy"></div>

Keys without the --hw- prefix are dropped on parse — there is no way to leak unrelated host-page variables.

Setting tokens at runtime

When the host application is an SPA and the embed has already mounted, push new tokens through the public API:

window.HatchedWidgets.remount({
  themeVars: {
    '--hw-accent': '#5B5BFF',
    '--hw-accent-strong': '#3F3FFF',
    '--hw-accent-soft': '#E4E4FF',
  },
});

remount() re-runs mount discovery and updates the in-memory config — already-mounted widgets receive the new tokens via their shadow-DOM style elements, no flicker.

Tips

  • Light + dark with one accent ramp. Override --hw-accent, --hw-accent-strong, and --hw-accent-soft once with data-theme-vars and the loader keeps the rest of the palette in sync with data-theme.
  • Densify a sidebar embed. Set --hw-density-scale: 0.85 to drop the vertical rhythm without rewriting every widget's spacing.
  • Match host fonts. Override --hw-font-body and --hw-font-display with the host site's fallback chain. The loader does not load additional webfonts — the host page is responsible for serving them.
  • Round buttons but square cards. Tokens are independent: pick --hw-button-radius: 9999px for pill buttons while keeping --hw-card-radius: 8px.

Companion docs