The dashboard recipe · button-card + card-mod

The look,
open-sourced.

People keep asking what theme the wall panel uses. It isn't one you can install — it's a recipe. One custom-button-card template builds every everyday tile; card-mod dresses every other card to match; and a tiny theme sets the palette. Here's the whole thing: the tile YAML to copy, the handful of cards that do the work, and the colours.

custom:button-card card-mod layout-card one shared template

1shared template
10HACS cards
70tiles it builds
18pxradius, everywhere
01 · The recipe

Three ingredients, one surface

Every tile you see is one of these three things. Get them right and the whole dashboard looks like it was designed as one piece — because, in effect, it was designed once.

One button-card template

The lights, stat tiles, action buttons, alarm state and zone tiles are all custom:button-card, and they all inherit a single base template. Change the gradient once and all sixty change together.

card-mod for the rest

The charts, the doorbell video, the solar power-flow, the media cards — other people's cards that can't be a button-card. card-mod forces the same gradient, 18 px radius, border and glow onto them, so they blend in.

A theme for the palette

A small HA theme file sets nothing but the base colours behind everything. All the character — the gradients, the amber glow, the motion — lives in per-card CSS, not the theme.

02 · How it fits together

Two lanes, one consistent surface

Everything on screen arrives by one of two routes — but both end up wearing the same coat.

The everyday tiles get their look for free from the template; card-mod is what makes the charts and video look like they belong.
03 · Anatomy of a tile

What makes one tile tick

This is the light tile, "on". Five parts do all the work — and four of them come straight from the shared template, so you write them once.

  • 01The card. A 155° gradient, an 18 px radius, a hairline border and a deep drop-shadow. Every tile on the dashboard is this shell.
  • 02The grid. grid-template-areas stacks the icon, name, state and label — swap the areas and the same tile becomes wide or compact.
  • 03The state block. One state: rule says "when this is on, go amber and glow." That single block is the whole personality.
  • 04The keyframes. extra_styles injects a @keyframes pulse, so an active tile breathes rather than just sitting there.
  • 05The behaviour. Tap toggles, hold opens more-info — the only two lines that aren't about looks.
04 · Copy it

One tile, whole and self-contained

This is the exact tile above, flattened so it needs nothing but button-card. Add a Manual card, paste, change the entity. Recolour the hex values and it's yours.

decs-light-tile.yaml
# A single "DECS" light tile — needs only custom:button-card (HACS).
# Toggles a light/switch; glows amber and pulses softly when it's on.
type: custom:button-card
entity: light.lounge_corner_lamp        # ← any light or switch
name: Corner lamp
label: Lounge
icon: mdi:floor-lamp
show_state: true
show_label: true
tap_action:
  action: toggle
hold_action:
  action: more-info
styles:
  card:
    - padding: 14px 10px
    - border-radius: 18px
    - border: 1px solid rgba(255,255,255,.12)
    - background: "linear-gradient(155deg, #1a2431 0%, #0e1621 100%)"
    - box-shadow: "0 14px 34px -20px rgba(0,0,0,.8)"
    - transition: "border-color .25s ease, box-shadow .25s ease"
    - overflow: hidden
  grid:
    - grid-template-areas: '"i" "n" "s" "l"'
    - grid-template-rows: min-content min-content min-content min-content
    - grid-gap: 2px
  icon:
    - width: 38px
    - height: 38px
    - color: "#4f5d6b"
    - transition: "all .3s ease"
  name:  [font-size: 14px, font-weight: 600, color: "#eff4f9", margin-top: 6px]
  state: [font-size: 12px, color: "#6b7a89"]
  label: [font-size: 10px, text-transform: uppercase, letter-spacing: .08em, color: "#5b6875", margin-top: 2px]
# state-based overrides — this block is what makes it glow when "on"
state:
  - value: "on"
    styles:
      card:
        - border-color: rgba(255,182,56,.55)
        - animation: decs-glow 2.4s ease-in-out infinite
        - background: "radial-gradient(120% 110% at 50% 0%, rgba(255,182,56,.22), transparent 55%), linear-gradient(155deg, #1a2431 0%, #0e1621 100%)"
      icon:
        - color: "#ffb638"
        - filter: "drop-shadow(0 0 10px rgba(255,182,56,.75))"
      state: [color: "#ffb638", font-weight: 600]
  - value: unavailable
    styles: {card: [opacity: .45]}
# the keyframes for the pulse (button-card injects this for you)
extra_styles: |
  @keyframes decs-glow {
    0%, 100% { box-shadow: 0 14px 34px -20px rgba(0,0,0,.8), 0 0 0 1px rgba(255,182,56,.35); }
    50%      { box-shadow: 0 14px 34px -20px rgba(0,0,0,.8), 0 0 24px 2px rgba(255,182,56,.55); }
  }

Wall-panel note: on the real dashboard the styling lives once in a button_card_templates block and every tile just says template: decs_light — so this whole thing collapses to five lines per tile. The version above is deliberately flattened so it stands alone.

05 · Write it once

How sixty tiles stay identical

The secret to the consistency isn't discipline — it's inheritance. The look is defined in one place; every tile points at it and adds only what's different.

the pattern
# 1 — define the look ONCE, at the top of the dashboard
button_card_templates:
  decs_tile:            # the base: gradient, radius, shadow, fonts
    styles: { ... }
  decs_light:           # a variant that extends the base
    template: decs_tile   # ← inherits everything above
    tap_action: { action: toggle }
    state: [ { value: "on", styles: { ... amber glow ... } } ]

# 2 — then every tile is just five lines
- type: custom:button-card
  template: decs_light    # ← all the styling, for free
  entity: switch.chair_lamp
  name: Chair lamp
  label: Lounge

Variants, not copies

A stat tile, a light, a big alarm-state tile, a zone tile — each is a small variant that starts from decs_tile and changes only its grid and its state colours. One edit to the base ripples through the lot.

Built by a script

On the wall panel a small Python builder stamps the tab bar into every view and injects the one line each tile needs to fill its grid cell — so the YAML stays hand-readable and the layout stays exact.

06 · The card roster

Ten cards do everything

All from HACS. The first two are the workhorses; the rest each own one job on the dashboard.

button-card workhorse
Every everyday tile. Templates, JS value templates, per-state styling and the keyframe animations all live here.
card-mod workhorse
Arbitrary CSS on any card. This is what drags the charts, video and media cards into the same visual language.
layout-card layout
custom:grid-layout pins every card to a cell of a 100-vh grid, so each tab is exactly one screen and never scrolls.
mushroom ui
The tab-pill bar, the "active now" chips, and the compact media-player cards on the Media tab.
mini-graph-card charts
The little temperature and humidity sparklines nested inside the heating tiles.
apexcharts-card charts
The solar tab's hourly kWh chart with the battery line overlaid.
power-flow-card-plus solar
The animated PV → house / battery / grid diagram, dots moving at a rate that tracks the watts.
advanced-camera-card video
The doorbell and front-door live streams, cover-cropped so there are no black bars.
auto-entities logic
The chips that only exist while something's actually on — lights, plugs, whatever's playing.
kiosk-mode chrome
Hides Home Assistant's own header and sidebar, so the panel is nothing but the dashboard.
07 · The palette

Nine colours, tuned for a dark wall

Deliberately muted so it's calm in a hallway at night, with one warm accent that does the talking. Swap the accent and the whole panel changes character.

#1a2431→#0e1621
tile gradient
#eff4f9
primary text
#95a4b5
muted text
#ffb638
accent · amber
#39d98a
good · green
#ff5a5a
alert · red
#7986ff
night · violet
#5cc8ff
info · blue
#ff7a45
heat · warm

Take it

Not a theme to install — a recipe to make your own.

One button-card template, card-mod on everything else, a small palette, and a builder to keep it all pinned to the screen. Copy the tile above, point it at your own entity, and recolour it in a minute. If you build something with it, that's the whole idea.

button-card + card-mod·one shared template·see it live on the Wall panel