Skip to content

Styling & Animation ​

Style layers ​

Every cell gets its style from up to six layers. Later layers win, key by key:

OrderLayerApplies to
1Theme defaultsEvery cell: theme text colour, right-aligned, 24px Antonio
2styleEvery cell
3Header defaults, then header_styleRows with header: true
4columns[i].styleColumn i (counting from 0)
5Row styleOne row ({ values: [...], style: {...} })
6Cell styleOne cell (a cell object)
yaml
type: custom:lcards-data-grid
data_mode: data
rows:
  - values: [Sensor, Reading]
    header: true
  - [Inside, sensor.living_room_temperature]
  - values: [Outside, sensor.outdoor_temperature]
    style:
      background: var(--lcars-blue)
  - - Battery
    - value: sensor.phone_battery
      style:
        color: var(--lcars-yellow)
        font_weight: 700
grid:
  grid-template-columns: 1fr 1fr
style:
  font_size: 18px
  color: var(--lcars-african-violet)
columns:
  - style:
      align: left
header_style:
  color: var(--lcars-orange)

Rule patches from the rules engine apply to the grid-wide style.

Style keys ​

Every layer takes the same keys. Numbers become pixels, except font_weight and line_height.

KeyExampleDescription
colorvar(--lcars-orange)Text colour, or a state map
backgroundtransparentBackground colour, or a state map
font_size18 or 1.2remFont size
font_familyAntonio, sans-serifFont
font_weight700 or boldWeight
alignleftHorizontal alignment: left, center, right (default right)
align_itemsflex-startVertical alignment inside the cell
padding4px 8pxSpace inside the cell (default 4px)
text_transformuppercasenone, uppercase, lowercase, capitalize
letter_spacing0.05emLetter spacing
line_height1.2Line height
white_spacenormalnowrap (default) cuts long text with an ellipsis; normal, pre-wrap or pre-line wrap it
border_width, border_color, border_style1, var(--lcars-gray), solidCell border
border_radius4Rounded corners

Any other CSS property works too, written in snake_case: border_bottom_color, opacity, text_shadow, and so on.

Colours accept everything in Colours: var(--lcars-...), hex, theme: tokens and computed colours such as alpha(var(--lcars-orange), 0.2).

Header rows ​

Header rows start from the theme's header look (bold, uppercase, 16px, a 2px divider underneath) before header_style applies. To drop the divider:

yaml
header_style:
  border_bottom_width: 0

Grid layout ​

grid takes CSS Grid properties for the grid container. Column widths are the usual place to start:

PropertyExampleDescription
grid-template-columns120px 1fr 80pxColumn widths. Default: equal columns. In decorative mode this also sets the number of columns.
grid-template-rowsrepeat(8, auto)Row heights. In decorative mode this also sets the number of rows.
gap8pxSpace between cells (default 8px)
row-gap, column-gap2pxSpace between rows, or columns, only
justify-items, align-itemscenterWhere cells sit inside their grid area
justify-content, align-contentspace-betweenWhere the whole grid sits inside the card
grid-auto-flowcolumnFill order
grid-auto-rows, grid-auto-columns40pxSize of rows or columns beyond the templates

repeat(N, size) and minmax(min, max) work as in CSS. Numbers in gaps become pixels.


The cascade ​

The cascade is the LCARS colour wave that rolls through the rows: each row holds a bright colour, snaps briefly to a dark one, flashes pale and repeats, every row on its own timing. Add it with the cascade-color animation preset:

yaml
type: custom:lcards-data-grid
data_mode: decorative
format: digit
grid:
  grid-template-rows: repeat(8, auto)
  grid-template-columns: repeat(10, 1fr)
  gap: 0px
style:
  font_size: 18px
animations:
  - trigger: on_load
    preset: cascade-color
    params:
      pattern: niagara
      colors:
        start: var(--lcars-orange)
        text: var(--lcars-red)
        end: var(--lcars-yellow)
ParamDefaultDescription
patterndefaultRow timing: default (the original mixed rhythm), niagara (smooth, even), fast, or custom
speed_multiplier12 runs twice as fast, 0.5 half as fast
duration-One cycle length in ms for every row (overrides the pattern and speed_multiplier)
timing-Per-row timing for pattern: custom: a list of { duration, delay } (ms and seconds), repeated for further rows
colorstheme cascade colours{ start, text, end } (or a list of three): the long bright hold, the short dark snap, the pale flash
easelinearEasing between colours

A custom rhythm:

yaml
animations:
  - trigger: on_load
    preset: cascade-color
    params:
      pattern: custom
      timing:
        - { duration: 3000, delay: 0.1 }   # row 1
        - { duration: 2000, delay: 0.2 }   # row 2
        - { duration: 4000, delay: 0.3 }   # row 3, then the list repeats

The cascade animates the text colour, so cells under a cascade ignore their own text color (backgrounds still apply). It works in both modes. Other animation presets work on the grid as a whole; to target cells, use selectors such as .grid-cell[data-row="0"].

In the Configuration Studio, the preview leaves animations off until you press the animation button in its toolbar.


Highlighting changes ​

highlight_changes briefly animates cells whose value just changed: an entity update in data mode, or a refresh in decorative mode.

yaml
highlight_changes: true            # pulse, 500 ms
yaml
highlight_changes:
  preset: glow                     # pulse or glow
  duration: 600
  params:
    color: var(--lcars-orange)
    blur_max: 8
  max_cells: 20                    # at most this many at once (default: all, up to 100)
OptionDefaultDescription
presetpulseAny animation preset; pulse and glow suit this best
duration500Length in ms; the cell animates out and back
easeoutQuadEasing
params-Preset params, e.g. max_scale: 1.08 for pulse, color and blur_max for glow
max_cellsall (up to 100)Limit for large grids

Filters ​

filters applies CSS filters (blur, brightness, hue rotation, ...) to the whole grid. See Filters; SVG filters don't apply to this card.

yaml
filters:
  - type: brightness
    value: 0.8