Theming and dark mode
Hololink UI is themed with CSS custom properties. Components read semantic tokens (--s-*) and never raw colours, so you theme by changing token values. Custom properties and color-scheme both inherit into Shadow DOM, so the changes reach every component below the element you set them on. Load the global stylesheet first, as described in Installation.
Light and dark
Section titled “Light and dark”Every themed colour is declared once with the CSS light-dark() function:
--s-color-bg-surface: light-dark(var(--p-color-neutral-0), var(--p-color-neutral-900));light-dark() picks its first value when the element’s computed color-scheme is light, and its second when it is dark. The global stylesheet sets color-scheme: light dark on :root, so by default Hololink UI follows the visitor’s OS setting. There is no separate dark stylesheet to load.
Force a scheme
Section titled “Force a scheme”Set data-theme to light or dark on <html> or on any container. The global stylesheet maps it to color-scheme, which inherits to everything inside.
<!-- Whole page --><html data-theme="dark"> ...</html>
<!-- One region only --><section data-theme="dark"> <holo-card card-title="Always dark"></holo-card></section>To let users toggle, set the attribute from script and persist the choice yourself:
document.documentElement.dataset.theme = 'dark';This site works the same way: the theme switcher sets data-theme on <html>.
Demo: a container forced to dark
Section titled “Demo: a container forced to dark”The left panel is forced to light and the right one to dark, whatever your OS or site theme is. The components inside change without any extra code.
<div data-theme="dark" style="background: var(--s-color-bg-app); color: var(--s-color-text-primary)"> <holo-button label="Primary" variant="primary"></holo-button> <holo-badge variant="success">Success</holo-badge></div>The container needs its own background and color. data-theme only changes which branch of light-dark() resolves, it does not paint a background.
Override semantic tokens
Section titled “Override semantic tokens”To re-brand, redeclare --s-* tokens on :root for the whole app, or on any container for one region. Override the token, not the component.
:root { --s-color-bg-interactive: light-dark(#0f766e, #2dd4bf); --s-color-bg-interactive-hover: light-dark(#115e59, #5eead4); --s-color-text-link: light-dark(#0f766e, #2dd4bf); --s-color-text-link-hover: light-dark(#115e59, #5eead4); --s-color-border-interactive: light-dark(#14b8a6, #2dd4bf);}Use light-dark() in your override too, so the accent still adapts to the theme. Keep contrast in mind: the default interactive pair is checked against WCAG 2.2 AA in both themes. If you change a colour, check these pairings: --s-color-text-on-interactive on --s-color-bg-interactive (4.5:1), and --s-color-bg-interactive and --s-color-border-interactive on the surface they sit on (3:1).
Demo: a re-branded container
Section titled “Demo: a re-branded container”Teal replaces the indigo accent inside the right-hand panel only. The left panel is the default for comparison.
<div class="brand-teal"> <holo-button label="Primary" variant="primary"></holo-button> <holo-link href="#">A link</holo-link></div>
<style> .brand-teal { --s-color-bg-interactive: light-dark(#0f766e, #2dd4bf); --s-color-bg-interactive-hover: light-dark(#115e59, #5eead4); --s-color-text-link: light-dark(#0f766e, #2dd4bf); --s-color-text-link-hover: light-dark(#115e59, #5eead4); --s-color-border-interactive: light-dark(#14b8a6, #2dd4bf); }</style>The primitives (--p-*) are not for overriding. They define values; the semantic tokens map them to roles. See Design tokens.
Per-component hooks
Section titled “Per-component hooks”When you need to change one component without touching a token that many components share, use its hook. Hooks are named --holo-<component>-<prop>. Each one falls back to a semantic token, for example:
border-radius: var(--holo-badge-radius, var(--s-radius-pill));Set the hook on the element or an ancestor:
holo-badge { --holo-badge-radius: 0; --holo-badge-padding: 0.25em 1em;}Square
This alert uses two hooks.
<holo-badge variant="info" style="--holo-badge-radius: 0; --holo-badge-padding: 0.25em 1em">Square</holo-badge><holo-alert variant="warning" heading="Custom hook" style="--holo-alert-radius: 0; --holo-alert-padding: 1.5rem">This alert uses two hooks.</holo-alert>Each component page lists its hooks under CSS custom properties in its API reference (for example, Alert). Prefer a token override when you want a change everywhere, and a hook when you want it in one place.