Please, does anyone have any advice?Thx alot
since there is no forcast attributes in the weather entity, this part is not working anymore.
How do I fix it?
Yes it not working for me too after the new update.
Backward-incompatible changes
The previously deprecated forecast
attribute of weather entities, has now been removed. Use the [weather.get_forecasts
] service to get the forecast data instead.
this is what did to solve.
created a new sensor for the forecast only
configuration.yaml
template:
# My Weather Entities Daily
- trigger:
- platform: state
entity_id: weather.home
action:
- service: weather.get_forecasts
data:
type: daily
target:
entity_id: weather.home
response_variable: daily
sensor:
- name: Weather Forecast Daily
icon: mdi:weather-cloudy
state: "{{ daily['weather.home'].forecast[0].condition }}"
attributes:
forecast: "{{ daily['weather.home'].forecast }}"
sidebar.yaml
....
weather: >
{% set entity = 'weather.home' %}
{% set entity_forcast = 'sensor.weather_forecast_daily' %}
{% if not is_state(entity, 'unknown') %}
{% set temp = state_attr(entity, 'temperature') | round %}
{% set precip = state_attr(entity_forcast, 'forecast')[0]['precipitation'] | round %}
Outside: {{ temp }}°C <br> {{- 'No risk of rain' if precip == 0
else precip | string + '% Rain \u2614\uFE0F' }}
{% else %}
Weather Unavailable...
{% endif %}
...
Oh nice thanks for sharing!.. I will try it
Hey all,
i copied the git-hub-rep of matt and adapted the dashboard for my needs. It works very well.
I tried to make a template for covers/shades with a touch circle like it is in the light/circle template.
I thought that i was able to change everything i need to change, that this will work, but the functionallity is not complete.
works:
- show cover position in card
doesn’t work: - mouse icon grab on click
- sending the values and move the cover
Here is my code and what i changed:
First i made a cover.yaml in button_card_templates folder:
cover:
template:
- base
- circle
- loader
double_tap_action:
action: fire-dom-event
browser_mod:
service: browser_mod.popup
data:
title: >
[[[
return !entity || entity.attributes.friendly_name;
]]]
card_mod:
style:
#popup header
.:
content:
type: entities
card_mod:
style: |
#states {
padding-top: 0.5em;
}
entities: >
[[[
if (entity) {
let covers = [],
id = Boolean(entity.attributes.entity_id)
? [entity.entity_id].concat(entity.attributes.entity_id)
: [entity.entity_id];
for (let i = 0; i < id.length; i++) {
covers.push({
"type": "custom:mushroom-cover-card",
"entity": id[i],
"fill_container": false,
"primary_info": "name",
"secondary_info": "state",
"icon_type": "icon",
"show_brshow_position_control": true
});
}
return covers;
}
]]]
variables:
circle_input: >
[[[
if (entity) {
// if cover group get brightness from child to remove bounce
let child = entity.attributes.entity_id,
current_position = child && states[child[0]].attributes.current_position
? states[child[0]].attributes.current_position
: entity.attributes.current_position;
return current_position === 0
? 1
: current_position
}
]]]
circle_input_unit: '%'
after that i added part for covers in circle.yaml
circle:
styles:
card:
- --c-stroke-color-on: '#b0b0b0'
- --c-stroke-color-off: none
- --c-fill-color-on: none
- --c-fill-color-off: rgba(255,255,255,0.04)
- --c-stroke-width: 2.3
- --c-stroke-width-dragging: 4
- --c-font-color: '#97989c'
- --c-font-size: 14px
- --c-unit-font-size: 10.5px
- --c-font-weight: 700
- --c-letter-spacing: -0.02rem
custom_fields:
circle:
- display: initial
- width: 88%
- margin: -3% 2% 0 0
- justify-self: end
- opacity: 1
custom_fields:
circle: >
[[[
if (entity) {
let r = 22.1,
c = r * 2 * Math.PI,
tspan = '<tspan dx=".2" dy="-.4">',
domain = entity.entity_id.split('.')[0],
state = variables.state_on,
input = variables.circle_input || ' ',
unit = variables.circle_input_unit || ' ';
/* * * * * * * * * * * * * * * * * *
* *
* CIRCLE *
* *
* * * * * * * * * * * * * * * * * */
let circle = (state, input, unit) => {
return `
<svg viewBox="0 0 50 50">
<style>
circle {
transform: rotate(-90deg);
transform-origin: 50% 50%;
stroke-dasharray: ${c};
stroke-dashoffset: ${typeof input === 'number' && c - input / 100 * c};
stroke-width: var(--c-stroke-width);
stroke: ${state ? 'var(--c-stroke-color-on)' : 'var(--c-stroke-color-off)'};
fill: ${state ? 'var(--c-fill-color-on)' : 'var(--c-fill-color-off)'};
}
text {
font-size: var(--c-font-size);
font-weight: var(--c-font-weight);
letter-spacing: var(--c-letter-spacing);
fill: var(--c-font-color);
}
tspan {
font-size: var(--c-unit-font-size);
}
#circle_value, tspan {
text-anchor: middle;
dominant-baseline: central;
}
</style>
<circle id="circle_stroke" cx="25" cy="25" r="${r}"/>
<text id="circle_value" x="50%" y="52%">${input}${tspan}${unit}</tspan></text>
</svg>
${domain === 'light' && `
<input id="circle_slider" type="range" min="0" max="100" value="${input}">
`}
`;
}
/* * * * * * * * * * * * * * * * * *
* *
* LIGHT *
* *
* * * * * * * * * * * * * * * * * */
if (domain === 'light') {
// wait 0ms for shadow dom
setTimeout(() => {
// then get elements
let elt = this.shadowRoot,
circle_slider = elt.getElementById('circle_slider'),
circle_value = elt.getElementById('circle_value'),
circle_stroke = elt.getElementById('circle_stroke');
// approximate position of thumb relative to circle
circle_slider.style.top = `${(circle_slider.value - 50) / 1.66 - 1}%`;
// debug position
let debug = false;
if (debug) circle_slider.style.opacity = 0.3;
// pass each event to handler
['click', 'input', 'mousedown', 'mouseup', 'touchstart', 'touchend'].forEach((event) => {
circle_slider.addEventListener(event, handler, { passive: true })
});
function handler(event) {
// "this" refers to slider
if (event.target === this) {
// bypass button-card tap_action
event.stopPropagation();
// update circle_value
circle_value.innerHTML = `${this.value}${tspan}${unit}</tspan>`;
// update stroke
circle_stroke.style.strokeDashoffset = c - this.value / 100 * c;
circle_stroke.style.strokeWidth = 'var(--c-stroke-width-dragging)';
// set cursor while dragging
if (event.type === 'mousedown' || event.type === 'input') {
this.style.cursor = 'grabbing';
} else {
this.style.cursor = 'grab';
}
// reset stroke width if value doesn't change
if (input == this.value && (event.type === 'click' || event.type === 'touchend'))
circle_stroke.style.strokeWidth = 'var(--c-stroke-width)';
// on release
if (event.type === 'mouseup' || event.type === 'touchend') {
// display loader if brightness is 0
if (circle_slider.value == 0 && elt.getElementById('loader')) {
elt.getElementById('loader').style.display = 'initial';
elt.getElementById('circle').style.display = 'none';
}
// set brightness
hass.callService('light', 'turn_on', {
entity_id: entity.entity_id,
brightness_pct: this.value
});
}
}
}
}, 0);
return circle(state, input, unit);
}
/* * * * * * * * * * * * * * * * * *
* *
* COVER *
* *
* * * * * * * * * * * * * * * * * */
else if (domain === 'cover') {
// wait 0ms for shadow dom
setTimeout(() => {
// then get elements
let elt = this.shadowRoot,
circle_slider = elt.getElementById('circle_slider'),
circle_value = elt.getElementById('circle_value'),
circle_stroke = elt.getElementById('circle_stroke');
// approximate position of thumb relative to circle
circle_slider.style.top = `${(circle_slider.value - 50) / 1.66 - 1}%`;
// debug position
let debug = false;
if (debug) circle_slider.style.opacity = 0.3;
// pass each event to handler
['click', 'input', 'mousedown', 'mouseup', 'touchstart', 'touchend'].forEach((event) => {
circle_slider.addEventListener(event, handler, { passive: true })
});
function handler(event) {
// "this" refers to slider
if (event.target === this) {
// bypass button-card tap_action
event.stopPropagation();
// update circle_value
circle_value.innerHTML = `${this.value}${tspan}${unit}</tspan>`;
// update stroke
circle_stroke.style.strokeDashoffset = c - this.value / 100 * c;
circle_stroke.style.strokeWidth = 'var(--c-stroke-width-dragging)';
// set cursor while dragging
if (event.type === 'mousedown' || event.type === 'input') {
this.style.cursor = 'grabbing';
} else {
this.style.cursor = 'grab';
}
// reset stroke width if value doesn't change
if (input == this.value && (event.type === 'click' || event.type === 'touchend'))
circle_stroke.style.strokeWidth = 'var(--c-stroke-width)';
// on release
if (event.type === 'mouseup' || event.type === 'touchend') {
// display loader if position is 0
if (circle_slider.value == 0 && elt.getElementById('loader')) {
elt.getElementById('loader').style.display = 'initial';
elt.getElementById('circle').style.display = 'none';
}
// set position
hass.callService('cover', 'set_cover_position', {
entity_id: entity.entity_id,
position: this.value
});
}
}
}
}, 0);
return circle(state, input, unit);
}
/* * * * * * * * * * * * * * * * * *
* *
* PERSON *
* *
* * * * * * * * * * * * * * * * * */
else if (domain === 'person') {
let time = c => {
let s = (c/1e3),
m = (c/6e4),
h = (c/36e5),
d = (c/864e5);
return s < 60
? parseInt(s) + 's'
: m < 60 ? parseInt(m) + 'm'
: h < 24 ? parseInt(h) + 'h'
: parseInt(d) + 'd';
};
let input = states[variables.retain] === undefined || states[variables.retain].state === 'unavailable'
? time(Date.now() - Date.parse(entity.last_changed))
: time(Date.now() - Date.parse(states[variables.retain].state)),
unit = ' ';
return circle(state, input, unit);
}
/* * * * * * * * * * * * * * * * * *
* *
* CLIMATE *
* *
* * * * * * * * * * * * * * * * * */
else if (domain === 'climate') {
return circle(state, input, unit);
}
/* * * * * * * * * * * * * * * * * *
* *
* OTHER *
* *
* * * * * * * * * * * * * * * * * */
else if (variables.state_on) {
return circle(state, input, unit);
}
}
]]]
There is one thing i am not able to work with (in circle.yaml):
let circle = (state, input, unit) => {
return `
<svg viewBox="0 0 50 50">
<style>
circle {
transform: rotate(-90deg);
transform-origin: 50% 50%;
stroke-dasharray: ${c};
stroke-dashoffset: ${typeof input === 'number' && c - input / 100 * c};
stroke-width: var(--c-stroke-width);
stroke: ${state ? 'var(--c-stroke-color-on)' : 'var(--c-stroke-color-off)'};
fill: ${state ? 'var(--c-fill-color-on)' : 'var(--c-fill-color-off)'};
}
text {
font-size: var(--c-font-size);
font-weight: var(--c-font-weight);
letter-spacing: var(--c-letter-spacing);
fill: var(--c-font-color);
}
tspan {
font-size: var(--c-unit-font-size);
}
#circle_value, tspan {
text-anchor: middle;
dominant-baseline: central;
}
</style>
<circle id="circle_stroke" cx="25" cy="25" r="${r}"/>
<text id="circle_value" x="50%" y="52%">${input}${tspan}${unit}</tspan></text>
</svg>
${domain === 'light' && `
<input id="circle_slider" type="range" min="0" max="100" value="${input}">
`}
The problem for me is that the covers do not have a state which is on or off like lights.
At last from ui-lovelace.yaml the custom button card:
- type: custom:button-card
entity: cover.jalousie_fenster_wohnzimmer
name: Jalousien
state_display: >
[[[
if (variables.state === 'playing') {
return 'läuft';
}
if (variables.state === true) {
return variables.translate_unknown;
}
]]]
double_tap_action:
!include popup/wohnzimmer_tv.yaml
template:
- cover
- base
Can anyone help me to find out what i have done wrong?
Thank you very much.
BR Marc
Great job on this!
I have been using it for a while and works fine.
However, I cannot seem to figure out how to change the opacity of buttons and colour fonts in general.
Eg. when i change from 0.25 to 0.6 as described below nothing happens. I would think the buttons would become less transparent when the device is not activated but they doesnt.
base:
template:
- settings
- tilt
- extra_styles
variables:
state_on: >
[[[ return ['on', 'home', 'cool', 'fan_only', 'playing', 'unlocked', 'open', 'heat_cool', 'cleaning'].indexOf(!entity || entity.state) !== -1; ]]]
state: >
[[[ return !entity || entity.state; ]]]
entity_id: >
[[[ return !entity || entity.entity_id; ]]]
entity_picture: >
[[[ return !entity || entity.attributes.entity_picture; ]]]
timeout: >
[[[ return !entity || Date.now() - Date.parse(entity.last_changed); ]]]
is_youtube: >
[[[
let is_youtube = entity?.attributes?.app_id === 'com.google.ios.youtube',
sensor = this?._config?.triggers_update,
media_title = entity?.attributes?.media_title,
watching_title = states[sensor]?.attributes?.title;
if (is_youtube && media_title === watching_title) {
return true;
}
]]]
aspect_ratio: 1/1
show_state: true
show_icon: false
state_display: >
[[[ if (variables.state === true) return variables.translate_unknown; ]]]
tap_action:
ui_sound_tablet: |
[[[
let screensaver = states[variables.entity_tablet] === undefined ||
states[variables.entity_tablet].state;
if (variables.state === 'off' && screensaver === 'off') {
hass.callService('media_player', 'play_media', {
entity_id: variables.entity_browser_mod,
media_content_id: '/local/sound/on.m4a',
media_content_type: 'music'
});
}
if (variables.state_on && screensaver === 'off') {
hass.callService('media_player', 'play_media', {
entity_id: variables.entity_browser_mod,
media_content_id: '/local/sound/off.m4a',
media_content_type: 'music'
});
}
]]]
card_bounce: |
[[[
// add animation
if (this.getElementsByTagName("style").length === 0) {
// phone condition
let mq = window.matchMedia('(max-width: 800px)').matches;
let style = document.createElement('style');
style.innerHTML = `
@keyframes card_bounce {
0% { transform: scale(1); }
10% { transform: scale(${ mq ? '0.92' : '0.94' }); }
25% { transform: scale(1); }
30% { transform: scale(${ mq ? '0.96' : '0.98' }); }
100% { transform: scale(1); }
}
`;
this.appendChild(style);
}
// duration
let duration = 800;
// animate
this.style.animation = `card_bounce ${duration}ms cubic-bezier(0.22, 1, 0.36, 1)`;
// reset
window.setTimeout(() => { this.style.animation = "none"; }, duration + 100)
]]]
action: toggle
haptic: medium
double_tap_action:
haptic: success
hold_action:
action: block
styles:
grid:
- grid-template-areas: |
"icon circle"
"n n"
"s s"
- grid-template-columns: repeat(2, 1fr)
- grid-template-rows: auto repeat(2, min-content)
- gap: 1.3%
- align-items: start
- will-change: transform
name:
- justify-self: start
- line-height: 121%
state:
- justify-self: start
- line-height: 115%
card:
- border-radius: var(--button-card-border-radius)
- border-width: 0
- -webkit-tap-highlight-color: rgba(0,0,0,0)
- transition: none
- --mdc-ripple-color: >
[[[
return variables.state_on
? 'rgb(0, 0, 0)'
: '#97989c';
]]]
- color: >
[[[
return variables.state_on
? '#4b5254'
: '#97989c';
]]]
- background-color: >
[[[
return variables.state_on
? 'rgba(255, 255, 255, 0.85)'
: 'rgba(115, 115, 115, 0.25)';
]]]
From:
- background-color: >
[[[
return variables.state_on
? 'rgba(255, 255, 255, 0.85)'
: 'rgba(115, 115, 115, 0.25)';
]]]
to:
- background-color: >
[[[
return variables.state_on
? 'rgba(255, 255, 255, 0.85)'
: 'rgba(115, 115, 115, 0.6)';
]]]
I have tried making a quick restart and even cleared my browser cache and cookies.
Hi, I have a problem with the sensor:
- trigger:
- platform: state
entity_id: weather.forecast_home
action:
- service: weather.get_forecast
data:
type: daily
target:
entity_id: weather.forecast_home
response_variable: daily
sensor:
- name: Weather Forecast Daily
unique_id: weather_forecast_daily
icon: mdi:weather-cloudy
state: "{{ daily['weather.forecast_home'].forecast[0].condition }}"
attributes:
forecast: "{{ daily['weather.forecast_home'].forecast }}"
the service works:
but I cant understand what I do wrong…
Hi I followed your guide but I didn’t get it to work Any idea whats wrong?
#################################################
# #
# SIDEBAR #
# #
#################################################
- type: vertical-stack
view_layout:
grid-area: sidebar
cards:
- type: custom:button-card
entity: sensor.template_sidebar
template: sidebar
- type: conditional
conditions:
- entity: input_boolean.laundry_display
state: 'on'
card:
type: custom:button-card
entity: timer.laundry
double_tap_action:
action: call-service
service: input_boolean.turn_off
service_data:
entity_id: input_boolean.laundry_display
template: laundry
- type: custom:decluttering-card
template: climate_card
variables:
- title: Schlafizmmer
- entity_display: sensor.espresense_bt_sensor_a4c1389600b7_temperature
- entity_temperature: sensor.espresense_bt_sensor_a4c1389600b7_temperature
- entity_valve: sensor.espresense_bt_sensor_a4c1381278a0_temperature
#################################################
# #
# VARDAGSRUM #
# #
#################################################
Sorry for another stupid question but how do I get a background image over the whole screen?
have you install decluttering card? if yes, clear cache and reload resource etc.
Yes. I have rebooted, cleared cache and also rebootet my proxmox server. Nothing
Apparently I’m too stupid to understand it. Could you explain to a dumb guy like me how exactly you integrated the icons with a code snippet? Thanks a lot
Did u manage to include the code correctly because I have exactly the same problem.
whats yoru issue?
I really love your chips section at the top and the header on the right side, is there a way you could share how you created them?? I would like to use them. Hope to hear from you!
Hi,
First thank you for this !
I would like change some icons. But i don’t know how, coult you show me how to add a custom icon.
Is it possible to put a PNG image ?
Thanks
this is not that easy . Either you work your way through his great (and thanks for your sharing!) GIT or you try a “simpler” approach first, as I’ve already copied and integrated some of these things I liked from @VietNgoc GIT.
Footer bottom:
Footer adaption for having the “chip” card at the bottom or top.
lovelace.yaml:
#portrait
"(max-width: 1200px)":
grid-gap: calc(var(--custom-layout-card-padding) * 0.9)
grid-template-columns: repeat(4, 1fr) 0
grid-template-rows: 0 repeat(3, fit-content(100%)) 0fr
grid-template-areas: |
". . . . ."
"footer footer footer footer ."
"sidebar vardagsrum studio sovrum ."
"sidebar media övrigt hemma ."
cards:
#################################################
# #
# FOOTER #
# #
#################################################
- type: horizontal-stack
view_layout:
grid-area: footer
cards:
- type: custom:button-card
name: Papa
tap_action: !include popup/hemma_mattias.yaml
entity: person.michael
template:
- chips
styles:
icon:
- padding: 3px
- background-color: null
- width: 50%
triggers_update: sensor.time
- type: custom:button-card
name: Kameras
entity: alarm_control_panel.blink_schweden
tap_action: !include popup/blink.yaml
icon: >
[[[
const state = states['alarm_control_panel.blink_schweden'].state;
return state === 'armed_away' ? 'mdi:shield-home' : 'mdi:shield-off';
]]]
template:
- chips
state_display: >
[[[
let state = states['alarm_control_panel.blink_schweden'].state;
if (state == 'armed_away') return 'Aktiv';
if (state == 'disarmed') return 'Aus';
return '';
]]]
styles:
icon:
- color: >
[[[
return variables.state_on
? 'green'
: '#97989c';
]]]
- type: custom:button-card
name: Pi-Hole
entity: switch.pi_hole
tap_action: !include popup/avm.yaml
icon: mdi:pi-hole
template:
- chips
state_display: >
[[[
let state = states['switch.pi_hole'].state;
if (state == 'on') return 'Aktiv';
if (state == 'off') return 'Aus';
return '';
]]]
styles:
icon:
- color: >
[[[
return variables.pihole
? 'green'
: '#97989c';
]]]
- type: custom:button-card
name: Lichter
entity: sensor.current_lights_on_test
tap_action: !include popup/unten.yaml
icon: >
[[[
return parseInt(states['sensor.current_lights_on_test'].state) > 0
? 'mdi:lightbulb-group'
: 'mdi:lightbulb-group-off';
]]]
template:
- chips
state_display: >
[[[
let lightCount = parseInt(states['sensor.current_lights_on_test'].state);
if (lightCount == 0) return 'Alles aus';
if (lightCount == 1) return '1 Licht an';
return `${lightCount} Lichter an`;
]]]
styles:
icon:
- color: >
[[[
return variables.state_on
? '#3182b7'
: '#97989c';
]]]
- type: custom:button-card
name: Media
entity: sensor.currently_playing
icon: >
[[[
return parseInt(states['sensor.currently_playing'].state) > 0
? 'mdi:television-speaker-off'
: 'mdi:television-speaker';
]]]
tap_action: !include popup/currently_playing.yaml
template:
- chips
state_display: >
[[[
if (variables.playing == '0 Playing') return 'None';
else return variables.playing;
]]]
styles:
icon:
- color: >
[[[
return variables.playing
? '#3182b7'
: '#97989c';
]]]
- type: custom:button-card
name: Ambilight
entity: light.tv_wohnzimmer_ambilight
icon: >
[[[
const state = states['light.tv_wohnzimmer_ambilight'].state;
return state === 'on' ? 'mdi:television-ambient-light' : 'phu:lightstrip-tv-off';
]]]
template:
- chips
state_display: >
[[[
let state = states['light.tv_wohnzimmer_ambilight'].state;
if (state == 'on') return 'An';
if (state == 'off') return 'Aus';
return '';
]]]
styles:
icon:
- color: >
[[[
return variables.state_on
? '#3182b7'
: '#97989c';
]]]
tap_action:
action: toggle
- type: custom:button-card
name: Batterie
entity: sensor.devices_with_low_battery
icon: >
[[[
return parseInt(states['sensor.devices_with_low_battery'].state) > 0
? 'mdi:battery-alert'
: 'mdi:battery';
]]]
tap_action: !include popup/lowbattery.yaml
template:
- chips
state_display: >
[[[
let batteryCount = parseInt(states['sensor.devices_with_low_battery'].state);
if (batteryCount== 0) return '0 Leer';
if (batteryCount== 1) return '1 Leer';
return `${batteryCount} Leer`;
]]]
styles:
icon:
- color: >
[[[
return variables.battery
? '#cc2323'
: '#97989c';
]]]
- type: custom:button-card
name: Processor
entity: sensor.system_monitor_processor_use
show_icon: true
template:
- chip_system
tap_action:
!include popup/system.yaml
you need to adapt the chip.yaml to your system variables/sensor, for example:
chips:
template:
- settings
- tilt
- extra_styles
variables:
# state_on: >
# [[[ return ['on', 'home', 'Normal', 'armed_away', 'Night', 'Aktiv', 'cool', 'fan_only', 'unlocked', 'open', 'streaming', 'yes', '1'].indexOf(!entity || entity.state) !== -1; ]]]
state_on: >
[[[
const state = entity ? entity.state : null;
const numState = Number(state);
return ['on', 'home', 'Normal', 'armed_away', 'Night', 'Aktiv', 'cool', 'fan_only', 'unlocked', 'open', 'streaming', 'yes'].includes(state) ||
(!isNaN(numState) && numState >= 1);
]]]
state: >
[[[ return !entity || entity.state; ]]]
light_on: >
[[[ return states['sensor.current_lights_on_test'].state;]]]
battery: >
[[[ return states['sensor.devices_with_low_battery'].state;]]]
playing: >
[[[ return states['sensor.currently_playing'].attributes.device_playing; ]]]
pihole: >
[[[ return states['switch.pi_hole'].state;]]]
good luck, Michael
PS: As new user I´m only allowed to add one example picture.
Guys it’s time to move to ha-fusion add-on.
Is a simple official integration that let you built cool dashboard with no effort.
Is still in beta but enough stable from experience.
Well developed by @Mattias_Persson. Thank you so much
For anyone with a missing/black Background after updating to Home Assistant 2024.05. Change the following in tablet.yaml and restart Home-Assistant afterwards or reload the themes via frontend.reload_themes.
Before:
card-mod-root: |
#view {
background: url('/local/background.png');
background-size: cover;
}
After:
card-mod-root: |
#view {
background: url('/local/background.png') !important;
background-size: cover !important;
}