Skip to content

Themes

To complement the HA-LCARS system theme - LCARdS adds a token-based theme system for its cards. Instead of hardcoding colours and other default settings, we can reference named tokens that the active theme resolves at runtime. Currently the lcards-default theme is loaded at startup, but in the future new theme packs can be added to easily change the look of all the cards.


Built-in Themes

ThemeDescription
lcards-defaultStandard LCARS look

Themes are provided by content packs. See the Config Panel Pack Explorer to view all the tokens that theme provides.


Using Theme Tokens

Reference a token in card configs, such as a colour or size field using {theme:token.path}:

yaml
style:
  border:
    color: "{theme:colors.ui.primary}"
  card:
    color:
      background: "{theme:colors.ui.primary}"

Token Namespaces

Tokens are organized into namespaces. Browse all available tokens in the Config Panel Theme Browser tab.

Example: colors.ui.*

Semantic colours that map to UI roles. In the default theme, prefer HA-LCARS theme colours but provide LCARdS fallbacks:

Tokenlcards-default value
colors.ui.primaryvar(--lcars-ui-primary, var(--lcards-gray-medium))
colors.ui.secondaryvar(--lcars-ui-secondary, var(--lcards-gray-medium-light))
colors.ui.tertiaryvar(--lcars-ui-tertiary, var(--lcards-orange-medium-dark))
colors.ui.quaternaryvar(--lcars-ui-quaternary, var(--lcards-gray-dark))

LCARdS CSS Colour Palette

LCARdS injects a complete set of --lcards-<colour>-<shade> CSS variables at startup. These colours can be used anywhere and do not need to be in your HA-LCARS theme file.

Note: Colours shown are the green_alert (normal) mode baseline values. When an alert mode is active (e.g. red_alert, blue_alert), all variables are HSL-transformed automatically — you never need to change your references.


🟠 Orange

SwatchCSS VariableHexNotes
--lcards-orange-darkest / -05#d91604Canon
--lcards-orange-10#e01808Computed (interpolated)
--lcards-orange-dark / -20#ef1d10Canon
--lcards-orange-medium-dark / -30#e7442aCanon
--lcards-orange / -medium / -40#ff6753Canon (base orange)
--lcards-orange-50#ff715dComputed (interpolated)
--lcards-orange-60#ff7b66Computed (interpolated)
--lcards-orange-medium-light / -70#ff8470Canon
--lcards-orange-light / -80#ff977bCanon
--lcards-orange-lightest / -90#ffb399Canon
--lcards-orange-95#ffceb3Computed (extrapolated)

⚫ Gray

SwatchCSS VariableHexNotes
--lcards-gray-darkest / -05#1e2229Canon
--lcards-gray-10#232933Computed (interpolated)
--lcards-gray-dark / -20#2f3749Canon
--lcards-gray-medium-dark / -30#52596eCanon
--lcards-gray / -medium / -40#6d748cCanon (base gray)
--lcards-gray-50#7d849bComputed (interpolated)
--lcards-gray-60#8d94aaComputed (interpolated)
--lcards-gray-medium-light / -70#9ea5baCanon
--lcards-gray-light / -80#d2d5dfCanon
--lcards-gray-lightest / -90#f3f4f7Canon
--lcards-gray-95#f8f9fcComputed (extrapolated)
--lcards-moonlight#dfe1e8Near-white; used for text/labels (not part of the 11-stop scale)

🔵 Blue

SwatchCSS VariableHexNotes
--lcards-blue-darkest / -05#002241Canon
--lcards-blue-10#082b48Computed (interpolated)
--lcards-blue-dark / -20#1c3c55Canon
--lcards-blue-medium-dark / -30#2a7193Canon
--lcards-blue / -medium / -40#37a6d1Canon (base blue)
--lcards-blue-50#48b2dbComputed (interpolated)
--lcards-blue-60#58bee6Computed (interpolated)
--lcards-blue-medium-light / -70#67caf0Canon
--lcards-blue-light / -80#93e1ffCanon
--lcards-blue-lightest / -90#00eeeeCanon — electric cyan-teal accent, not a smooth continuation of the ramp (see Shade Scale note below)
--lcards-blue-95#44ffffComputed (extrapolated, neon/electric method — see note below)

🟢 Green

SwatchCSS VariableHexNotes
--lcards-green-darkest / -05#0c2a15Canon
--lcards-green-10#0b2e16Computed (interpolated)
--lcards-green-dark / -20#083717Canon
--lcards-green-medium-dark / -30#095320Canon
--lcards-green / -medium / -40#266239Canon (base green)
--lcards-green-50#306d43Computed (interpolated)
--lcards-green-60#3b784eComputed (interpolated)
--lcards-green-medium-light / -70#458359Canon
--lcards-green-light / -80#80bb93Canon
--lcards-green-lightest / -90#b8e0c1Canon
--lcards-green-95#cdf6d6Computed (extrapolated)

🟡 Yellow

SwatchCSS VariableHexNotes
--lcards-yellow-darkest / -05#70602cCanon
--lcards-yellow-10#847131Computed (interpolated)
--lcards-yellow-dark / -20#ac943bCanon
--lcards-yellow-medium-dark / -30#d2bf50Canon
--lcards-yellow / -medium / -40#f9ef97Canon (base yellow)
--lcards-yellow-50#fbf3a8Computed (interpolated)
--lcards-yellow-60#fdf6b9Computed (interpolated)
--lcards-yellow-medium-light / -70#fffac9Canon
--lcards-yellow-light / -80#e7e6deCanon — desaturates toward beige, not a smooth continuation of the ramp (see Shade Scale note below)
--lcards-yellow-lightest / -90#f5f5dcCanon — warm white / cream
--lcards-yellow-95#fbfbe2Computed (extrapolated)

Shade Scale

Each colour family carries two parallel naming schemes for the same 11-stop scale, which lines up 1:1 with Home Assistant's own --ha-color-<family>-<tone> tonal system (05/10/20/30/40/50/60/70/80/90/95):

Named shadeNumeric toneDescriptionOrigin
-darkest-05Deepest / near-black toneCanon — hand-picked Picard-screen colour
(none — numeric only)-10Computed — interpolated between -05 and -20
-dark-20Dark variantCanon
-medium-dark-30Between dark and midCanon
(base / -medium)-40Core reference colour — --lcards-<colour>, --lcards-<colour>-medium, and --lcards-<colour>-40 all resolve to the same valueCanon
(none — numeric only)-50Computed — interpolated between -40 and -70
(none — numeric only)-60Computed — interpolated between -40 and -70
-medium-light-70Between mid and lightCanon
-light-80Light variantCanon
-lightest-90Palest tone at the original 7-stop scaleCanon
(none — numeric only)-95Lightest of allComputed — extrapolated beyond -90 using a neon/electric method (holds hue and chroma from -lightest, only lightness moves toward white — chosen over a fade-to-white approach because LCARS palettes read as vibrant even at their palest steps)

The 7 named/canon stops (-darkest through -lightest) are the original, hand-authored Picard-screen colours and are never altered. The 4 numeric-only stops (-10, -50, -60, -95) were added later, computed in OKLCH colour space and anchored to the canon values, purely to give Home Assistant's own semantic colour system (--ha-color-*) the same 11-stop resolution it expects — see ha-css-vars.md for how these feed the HA-LCARS Picard theme profiles. Generated by scripts/generate-lcards-palette-scale.js.

Not every family's canon stops form a perfectly smooth ramp — blue's -lightest is a deliberately vibrant electric-cyan accent rather than a pale tint, and yellow's -light/-lightest desaturate toward a parchment/beige tone. These are original design choices in the canon palette, not artifacts of the computed stops.

Gray also includes --lcards-moonlight — a near-white warm gray used for text, labels, and chart axes (not part of the 11-stop scale).


Usage

css
/* Direct reference */
color: var(--lcards-blue-light);

/* Prefer HA-LCARS theme variable, fall back to lcards palette */
color: var(--lcars-orange, var(--lcards-orange-medium));

/* With hex fallback */
color: var(--lcards-orange-medium, #ff6753);

HA-LCARS Theme Profiles

LCARdS ships ready-made theme profiles that extend HA-LCARS using the --lcards-* palette as the single source of truth. They remap both the HA-LCARS chrome variables and the HA core colour tokens (--ha-color-*) so that stock HA components, LCARdS cards, and the HA-LCARS chrome all share the same palette — including alert-mode hue rotations.

HA-LCARS Theme Profiles