mirror of
https://github.com/Anashost/HA-Animated-cards.git
synced 2026-07-27 04:16:55 +00:00
3c254ce3e7
Replace old image with a new screenshot in the documentation.
144 KiB
144 KiB
🏠 Home Assistant Animated Badges and Buttons Maker
{\color{yellow}For \space Normal \space Entities}
Custom Button/Badge Card
type: custom:mushroom-chips-card
chips:
- type: template
entity: sensor.your_entity_here
icon: mdi:bell-ring
content: Button
alignment: end
card_mod:
style: >
ha-card {
/* ================================ */
/* USER CONFIG HERE */
/* ================================ */
/* 1. ACTIVE STATES */
{% set active_states = ['on'] %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '15px' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '15px' %}
/* 3. SIZING */
{% set icon_size = '16px' %}
{% set text_size = '13px' %}
{% set badge_height = '10px' %}
{% set border_radius = '5px' %}
{% set border_thickness = '0.5px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = 'white' %}
{% set active_icon = 'white' %}
{% set active_text = 'white' %}
{% set active_border = 'white' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = 'grey' %}
{% set inactive_icon = 'grey' %}
{% set inactive_text = 'darkgrey' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'none' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */
{% set anim_duration_sec = 1 %}
{% set anim_delay_sec = 1 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set is_active = current_state in active_states %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or config.chips[0].content |
length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
Templates
icon & icon color
{% if states(entity) in ['on'] %}
{% else %}
{% endif %}
icon & icon color (multiple states)
{% if states(entity) in ['on', 'off', 'etc'] %}
{% else %}
{% endif %}
content
{{states(entity)}}
{\color{yellow}For \space Numeric \space Entities}
Custom Button/Badge Card
type: custom:mushroom-chips-card
chips:
- type: template
entity: sensor.your_(NUMERIC)_entity_here
icon: mdi:battery-alert
content: Badge
alignment: end
card_mod:
style: >
ha-card {
/* ================================== */
/* USER CONFIG HERE */
/* ================================== */
/* 1. ACTIVE STATE (NUMERIC) */
{% set threshold_below = 20 %}
{% set threshold_above = false %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '10px' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '5px' %}
/* 3. SIZING */
{% set icon_size = '18px' %}
{% set text_size = '12px' %}
{% set badge_height = '5px' %}
{% set border_radius = '10px' %}
{% set border_thickness = '1px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = '#a63a3a' %}
{% set active_icon = 'white' %}
{% set active_text = 'white' %}
{% set active_border = '#ab1c1c' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = 'grey' %}
{% set inactive_icon = 'grey' %}
{% set inactive_text = 'darkgrey' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'none' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */
{% set anim_duration_sec = 2 %}
{% set anim_delay_sec = 5 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set state_num = current_state | float(-99999) %}
{% set check_below = threshold_below | string | lower != 'false' %}
{% set check_above = threshold_above | string | lower != 'false' %}
{% set is_active_below = check_below and state_num != -99999 and state_num <= (threshold_below | float(-99999)) %}
{% set is_active_above = check_above and state_num != -99999 and state_num >= (threshold_above | float(-99999)) %}
{% set is_active = is_active_below or is_active_above %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or config.chips[0].content |
length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
Templates
icon & icon color
{% if states(entity)|float <= 20 %}
{% elif states(entity)|float <= 50 %}
{% else %}
{% endif %}
content
{{states(entity)|float|round(0)}}
{\color{yellow}Examples}
Note
Here are example cards with custom buttons and badges. Some of them use advanced templates that you can use to create your own custom card. More examples will be added over time.
Balcony cards
type: custom:vertical-stack-in-card
cards:
- type: custom:mushroom-entity-card
entity: cover.balcony_shades
primary_info: name
secondary_info: none
icon: ""
tap_action:
action: more-info
icon_color: white
name: Shades
card_mod:
style:
.: |
ha-card {
/* --- CONFIGURATION --- */
{% set icon_size = '65px' %}
{% set reverse_awning = false %}
/* Visual Limits */
{% set limit_min_height = 10 %}
{% set limit_max_height = 77 %}
/* Colors */
{% set color_sky_day = '#263238' %}
{% set color_sky_night = '#263238' %}
{% set color_canvas_1 = '#fa811e' %}
{% set color_canvas_2 = '#cfd8dc' %}
{% set color_hem_bar = '#b0bec5' %}
/* Dimensions */
{% set window_width = '45%' %}
{% set card_height = '135px' %}
{% set error_red = 'darkgray' %}
/* --- LOGIC --- */
{% set status = states(config.entity) %}
{% if status in ['unavailable', 'unknown'] %}
/* ERROR STATE: Set Red BG and hide awning */
{% set current_bg = error_red %}
{% set draw_height = 0 %}
{% set is_moving = False %}
{% else %}
/* NORMAL STATE: Calculate position */
{% set pos = state_attr(config.entity, 'current_position') | default(0) | int %}
{% set current_bg = color_sky_night if pos < 10 else color_sky_day %}
{% set percent_closed = (pos / 100) if reverse_awning else ((100 - pos) / 100) %}
{% set draw_height = limit_min_height + ((limit_max_height - limit_min_height) * percent_closed) %}
{% set is_moving = True if status in ['opening', 'closing'] else False %}
{% endif %}
/* --- CSS VARS --- */
--c-window-bg: {{ current_bg }};
--c-canvas-1: {{ color_canvas_1 }};
--c-canvas-2: {{ color_canvas_2 }};
--c-hem-bar: {{ color_hem_bar }};
--v-icon-size: {{ icon_size }};
--v-roller-height: {{ draw_height }}%;
--v-window-width: {{ window_width }};
--v-card-height: {{ card_height }};
--icon-animation: {{ 'gentle-pulse 2s infinite ease-in-out' if is_moving else 'none' }};
/* --- STYLES --- */
padding-right: calc( {{ window_width }} + 10px ) !important;
position: relative;
height: var(--v-card-height) !important;
transition: height 0.4s;
overflow: hidden;
}
ha-card::after {
content: '';
position: absolute;
top: 12px; bottom: 12px; right: 12px;
width: var(--v-window-width);
border-radius: 4px;
box-shadow: inset 0 0 5px rgba(0,0,0,0.3);
background-color: var(--c-window-bg);
background-image:
linear-gradient(to top, var(--c-hem-bar) 0px, var(--c-hem-bar) 6px, rgba(0,0,0,0.2) 6px, transparent 7px),
repeating-linear-gradient(to right, var(--c-canvas-1) 0px, var(--c-canvas-1) 10px, var(--c-canvas-2) 10px, var(--c-canvas-2) 20px);
background-size: 100% var(--v-roller-height);
background-repeat: no-repeat;
background-position: top center;
transition: background-size 0.8s cubic-bezier(0.25, 1, 0.5, 1), background-color 1s ease;
z-index: 1 ;
}
ha-card::before {
content: '';
position: absolute;
bottom: 12px; right: 12px;
height: 20px;
width: var(--v-window-width);
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
pointer-events: none;
z-index: 2;
background-image:
linear-gradient(to bottom, #455a64 0px, #455a64 4px, transparent 4px),
repeating-linear-gradient(to right, transparent 0px, transparent 10px, #607d8b 10px, #607d8b 12px);
}
mushroom-state-info$: |
.container {
position: absolute !important;
top: 10px;
left: calc(var(--v-icon-size) + 5px);
width: auto;
}
mushroom-shape-icon$: |
.shape {
--icon-size: var(--v-icon-size) !important;
position: absolute !important;
top: -75px !important;
left: -18px !important;
animation: var(--icon-animation) !important;
z-index: 1;
}
@keyframes gentle-pulse {
0% { transform: scale(1); box-shadow: 0 0 0 0 rgba(var(--rgb-state-cover), 0.3); }
50% { transform: scale(1.1); box-shadow: 0 0 8px 0 rgba(var(--rgb-state-cover), 0.6); }
100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(var(--rgb-state-cover), 0.3); }
}
- type: custom:mushroom-chips-card
chips:
- type: template
entity: cover.balcony_shades
icon: |-
{% if states(entity) in ['closing'] %}
mdi:arrow-down-bold-circle-outline
{% else %}
mdi:arrow-down-circle
{% endif %}
tap_action:
action: perform-action
perform_action: cover.close_cover
target:
entity_id: cover.balcony_shades
data: {}
alignment: end
card_mod:
style: >
ha-card {
/* ================================ */
/* USER CONFIG HERE */
/* ================================ */
/* 1. ACTIVE STATES */
{% set active_states = ['closing'] %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '55%' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '84.5%' %}
/* 3. SIZING */
{% set icon_size = '30px' %}
{% set text_size = '12px' %}
{% set badge_height = '7px' %}
{% set border_radius = '10px' %}
{% set border_thickness = '0.5px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = 'lightblue' %}
{% set active_icon = 'white' %}
{% set active_text = 'white' %}
{% set active_border = 'transparent' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = 'grey' %}
{% set inactive_icon = 'white' %}
{% set inactive_text = 'white' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'none' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.9 %} /* 0.1 to 1 */
{% set anim_duration_sec = 1 %}
{% set anim_delay_sec = 0 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set is_active = current_state in active_states %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or config.chips[0].content
| length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
- type: custom:mushroom-chips-card
chips:
- type: template
entity: cover.balcony_shades
icon: |-
{% if states(entity) in ['opening', 'closing'] %}
mdi:stop-circle-outline
{% else %}
mdi:stop-circle
{% endif %}
tap_action:
action: perform-action
perform_action: cover.stop_cover
target:
entity_id: cover.balcony_shades
data: {}
alignment: end
card_mod:
style: >
ha-card {
/* ================================ */
/* USER CONFIG HERE */
/* ================================ */
/* 1. ACTIVE STATES */
{% set active_states = ['opening', 'closing'] %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '55%' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '69%' %}
/* 3. SIZING */
{% set icon_size = '30px' %}
{% set text_size = '12px' %}
{% set badge_height = '7px' %}
{% set border_radius = '10px' %}
{% set border_thickness = '0.5px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = '#ff5454' %}
{% set active_icon = 'white' %}
{% set active_text = 'white' %}
{% set active_border = 'transparent' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = 'grey' %}
{% set inactive_icon = 'white' %}
{% set inactive_text = 'white' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'none' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.9 %} /* 0.1 to 1 */
{% set anim_duration_sec = 1 %}
{% set anim_delay_sec = 0 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set is_active = current_state in active_states %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or config.chips[0].content
| length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
- type: custom:mushroom-chips-card
chips:
- type: template
entity: cover.balcony_shades
icon: |-
{% if states(entity) in ['opening'] %}
mdi:arrow-up-bold-circle-outline
{% else %}
mdi:arrow-up-circle
{% endif %}
tap_action:
action: perform-action
perform_action: cover.open_cover
target:
entity_id: cover.balcony_shades
data: {}
alignment: end
card_mod:
style: >
ha-card {
/* ================================ */
/* USER CONFIG HERE */
/* ================================ */
/* 1. ACTIVE STATES */
{% set active_states = ['opening'] %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '55%' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '54%' %}
/* 3. SIZING */
{% set icon_size = '30px' %}
{% set text_size = '12px' %}
{% set badge_height = '7px' %}
{% set border_radius = '10px' %}
{% set border_thickness = '0.5px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = 'lightblue' %}
{% set active_icon = 'white' %}
{% set active_text = 'white' %}
{% set active_border = 'transparent' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = 'grey' %}
{% set inactive_icon = 'white' %}
{% set inactive_text = 'white' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'none' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.9 %} /* 0.1 to 1 */
{% set anim_duration_sec = 1 %}
{% set anim_delay_sec = 0 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set is_active = current_state in active_states %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or config.chips[0].content
| length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
TEMP & Humidity
type: horizontal-stack
cards:
- type: custom:vertical-stack-in-card
cards:
- type: custom:mushroom-entity-card
entity: sensor.livingroom_temperature
tap_action:
action: more-info
icon: mdi:thermometer
name: Temperature
primary_info: state
secondary_info: name
card_mod:
style:
mushroom-shape-icon$: |
.shape {
{# ========== CONFIG ========== #}
{% set temp = states('sensor.livingroom_temperature') | float(0) %}
{# ------------------------------------------- #}
{# TEMPERATURE → COLOR + EFFECT PRESETS #}
{# ------------------------------------------- #}
{# DEFAULTS (will be overridden by ranges) #}
{% set rgb = '0,140,255' %}
{% set anim = 'temp-cold-breathe' %}
{% set glow_anim = 'temp-cold-glow' %}
{% set halo_anim = 'temp-cold-halo' %}
{% set duration = 4.0 %}
{% set intensity = 0.5 %}
{# RANGES / COLORS #}
{# You can change temp numbers below if needed #}
{% if temp < 16 %}
{# BLUE #}
{% set rgb = '0,140,255' %}
{% set anim = 'temp-cold-breathe' %}
{% set glow_anim = 'temp-cold-glow' %}
{% set halo_anim = 'temp-cold-halo' %}
{% set duration = 4.4 %}
{% set intensity = 0.4 %}
{% elif temp < 18 %}
{# YELLOW #}
{% set rgb = '255,210,40' %}
{% set anim = 'temp-cool-wave' %}
{% set glow_anim = 'temp-cool-glow' %}
{% set halo_anim = 'temp-cool-halo' %}
{% set duration = 3.4 %}
{% set intensity = 0.55 %}
{% elif temp < 20 %}
{# ORANGE #}
{% set rgb = '255,150,40' %}
{% set anim = 'temp-comfy-breathe' %}
{% set glow_anim = 'temp-comfy-glow' %}
{% set halo_anim = 'temp-comfy-halo' %}
{% set duration = 3.0 %}
{% set intensity = 0.6 %}
{% elif temp < 22 %}
{# DARK ORANGE #}
{% set rgb = '255,115,20' %}
{% set anim = 'temp-warm-pulse' %}
{% set glow_anim = 'temp-warm-glow' %}
{% set halo_anim = 'temp-warm-halo' %}
{% set duration = 2.4 %}
{% set intensity = 0.8 %}
{% else %}
{# RED #}
{% set rgb = '255,40,40' %}
{% set anim = 'temp-hot-shimmer' %}
{% set glow_anim = 'temp-hot-glow' %}
{% set halo_anim = 'temp-hot-halo' %}
{% set duration = 2.0 %}
{% set intensity = 1.0 %}
{% endif %}
{# Apply variables #}
--temp-rgb: {{ rgb }};
--temp-intensity: {{ intensity }};
--shape-animation: {{ anim }} {{ duration }}s ease-in-out infinite;
--temp-glow-animation: {{ glow_anim }} {{ (duration * 0.9) | round(2) }}s ease-in-out infinite;
--temp-halo-animation: {{ halo_anim }} {{ (duration * 1.15) | round(2) }}s ease-in-out infinite;
opacity: 1;
/* Icon color follows the temperature */
--icon-color: rgba({{ rgb }}, 1);
/* 🔧 KILL THE THEME BLUE & MAKE SHAPE NEUTRAL */
background-color: rgba(77, 77, 77,0.1) !important;
box-shadow: none !important;
border: 1px solid rgba(255,255,255,0.06);
position: relative;
transform-origin: 50% 60%;
animation: var(--shape-animation);
}
/* Glow layers */
.shape::before,
.shape::after {
content: '';
position: absolute;
border-radius: inherit;
pointer-events: none;
}
.shape::before {
inset: -8px;
animation: var(--temp-glow-animation);
}
.shape::after {
inset: -22px;
animation: var(--temp-halo-animation);
mix-blend-mode: screen;
}
/* ========== COLD ========== */
@keyframes temp-cold-breathe {
0% { transform: scale(0.96); }
50% { transform: scale(1.03); }
100% { transform: scale(0.96); }
}
@keyframes temp-cold-glow {
0% {
box-shadow:
0 0 20px 0 rgba(var(--temp-rgb), 0.6),
0 0 34px 6 rgba(var(--temp-rgb), 0.55);
}
50% {
box-shadow:
0 0 30px 4 rgba(var(--temp-rgb), 0.95),
0 0 50px 10px rgba(var(--temp-rgb), 0.85);
}
100% {
box-shadow:
0 0 20px 0 rgba(var(--temp-rgb), 0.6),
0 0 34px 6 rgba(var(--temp-rgb), 0.55);
}
}
@keyframes temp-cold-halo {
0% {
box-shadow:
0 0 80px 20px rgba(var(--temp-rgb), 0.35),
0 -20px 80px -14px rgba(220, 240, 255, 0.55);
}
50% {
box-shadow:
0 0 130px 36px rgba(var(--temp-rgb), 0.5),
0 -34px 100px -8px rgba(240, 250, 255, 0.8);
}
100% {
box-shadow:
0 0 80px 20px rgba(var(--temp-rgb), 0.35),
0 -20px 80px -14px rgba(220, 240, 255, 0.55);
}
}
/* ========== COOL ========== */
@keyframes temp-cool-wave {
0% { transform: translateX(0); }
25% { transform: translateX(-1px); }
50% { transform: translateX(1px) translateY(-1px); }
75% { transform: translateX(-1px); }
100% { transform: translateX(0); }
}
@keyframes temp-cool-glow {
0% {
box-shadow:
0 0 22px 0 rgba(var(--temp-rgb), 0.6),
0 0 34px 4 rgba(var(--temp-rgb), 0.7);
}
50% {
box-shadow:
0 0 28px 2 rgba(var(--temp-rgb), 0.95),
0 0 48px 12px rgba(var(--temp-rgb), 0.85);
}
100% {
box-shadow:
0 0 22px 0 rgba(var(--temp-rgb), 0.6),
0 0 34px 4 rgba(var(--temp-rgb), 0.7);
}
}
@keyframes temp-cool-halo {
0% {
box-shadow:
0 0 90px 26px rgba(var(--temp-rgb), 0.35),
0 18px 80px -12px rgba(0, 220, 255, 0.35);
}
50% {
box-shadow:
0 0 140px 42px rgba(var(--temp-rgb), 0.45),
0 30px 110px -10px rgba(0, 255, 255, 0.5);
}
100% {
box-shadow:
0 0 90px 26px rgba(var(--temp-rgb), 0.35),
0 18px 80px -12px rgba(0, 220, 255, 0.35);
}
}
/* ========== COMFY ========== */
@keyframes temp-comfy-breathe {
0% { transform: scale(0.98); }
50% { transform: scale(1.05); }
100% { transform: scale(0.98); }
}
@keyframes temp-comfy-glow {
50% {
box-shadow:
0 0 26px 4 rgba(var(--temp-rgb), 0.9),
0 0 42px 10px rgba(var(--temp-rgb), 0.85);
}
}
@keyframes temp-comfy-halo {
50% {
box-shadow:
0 0 120px 40px rgba(var(--temp-rgb), 0.45),
0 26px 80px -10px rgba(180,255,200,0.5);
}
}
/* ========== WARM ========== */
@keyframes temp-warm-pulse {
0% { transform: scale(1); }
50% { transform: scale(1.07); }
100% { transform: scale(1); }
}
@keyframes temp-warm-glow {
50% {
box-shadow:
0 0 30px 4 rgba(var(--temp-rgb), 0.95),
0 0 54px 14px rgba(var(--temp-rgb), 0.9);
}
}
@keyframes temp-warm-halo {
50% {
box-shadow:
0 0 140px 48px rgba(var(--temp-rgb), 0.55),
0 26px 100px -10px rgba(255,210,150,0.5);
}
}
/* ========== HOT ========== */
@keyframes temp-hot-shimmer {
0% { transform: scale(1); filter: blur(0); }
50% { transform: scale(1.08); filter: blur(0.6px); }
100% { transform: scale(1); filter: blur(0); }
}
@keyframes temp-hot-glow {
50% {
box-shadow:
0 0 34px 6 rgba(var(--temp-rgb), 1),
0 0 62px 14px rgba(var(--temp-rgb), 0.95);
}
}
@keyframes temp-hot-halo {
50% {
box-shadow:
0 0 160px 60px rgba(var(--temp-rgb), 0.6),
0 34px 120px -12px rgba(255,150,100,0.6);
}
}
.: |
mushroom-shape-icon {
--icon-size: 64px;
--icon-color: rgba(var(--hum-rgb),1) !important;
display: flex;
margin: -18px 0 10px -20px !important;
padding-right: 22px;
padding-bottom: 25px;
}
ha-card {
clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 14px));
/* FONT SIZE & SPACING SETTINGS */
--card-primary-font-size: 1.3rem !important;
/* Increases vertical space between primary and secondary */
--card-primary-line-height: 1.3 !important;
}
- type: custom:vertical-stack-in-card
cards:
- type: custom:mini-graph-card
entities:
- sensor.livingroom_temperature
hours_to_show: 24
line_width: 5
show:
name: false
icon: false
state: false
labels: false
legend: false
color_thresholds:
- value: 0
color: blue
- value: 18
color: lightblue
- value: 20
color: orange
- value: 22
color: red
card_mod:
style: |
ha-card {
background: none;
box-shadow: none;
opacity: 50%;
border: none;
width: 250px;
mask-image: radial-gradient(
ellipse at center,
rgba(0,0,0,1) 0%,
rgba(0,0,0,0) 90%
);
}
card_mod:
style:
.: |
ha-card {
background: none;
box-shadow: none;
border: none;
margin: 8px 12px;
position: absolute;
bottom: -10px;
right: -10px;
}
- type: custom:mushroom-chips-card
chips:
- type: template
entity: sensor.livingroom_mi_battery
icon: |-
{% if states(entity)|float<=20 %}
mdi:battery-20
{% elif states(entity)|float<=50 %}
mdi:battery-50
{% else %}
mdi:battery
{% endif %}
content: "{{states(entity)|float|round(0)}}%"
icon_color: |-
{% if states(entity)|float<=25 %}
red
{% elif states(entity)|float<=75 %}
orange
{% else %}
green
{% endif %}
alignment: end
card_mod:
style: >
ha-card {
/* ================================== */
/* USER CONFIG HERE */
/* ================================== */
/* 1. ACTIVE STATE (NUMERIC) */
{% set threshold_below = 20 %}
{% set threshold_above = false %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '10px' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '0%' %}
/* 3. SIZING */
{% set icon_size = '10px' %}
{% set text_size = '8px' %}
{% set badge_height = '3px' %}
{% set border_radius = '7px' %}
{% set border_thickness = '1px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = 'grey' %}
{% set active_icon = 'white' %}
{% set active_text = 'darkgrey' %}
{% set active_border = 'transparent' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = 'grey' %}
{% set inactive_icon = 'red' %}
{% set inactive_text = 'white' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'flash' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */
{% set anim_duration_sec = 2 %}
{% set anim_delay_sec = 5 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set state_num = current_state | float(-99999) %}
{% set check_below = threshold_below | string | lower != 'false' %}
{% set check_above = threshold_above | string | lower != 'false' %}
{% set is_active_below = check_below and state_num != -99999 and state_num <= (threshold_below | float(-99999)) %}
{% set is_active_above = check_above and state_num != -99999 and state_num >= (threshold_above | float(-99999)) %}
{% set is_active = is_active_below or is_active_above %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or
config.chips[0].content | length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0
%}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
- type: custom:vertical-stack-in-card
cards:
- type: custom:mushroom-entity-card
entity: sensor.livingroom_humidity
tap_action:
action: more-info
icon: mdi:water-percent
name: Humidity
primary_info: state
secondary_info: name
card_mod:
style:
mushroom-shape-icon$: |
.shape {
{# ========== CONFIG ========== #}
{% set hum = states('sensor.livingroom_humidity') | float(0) %}
{# DEFAULTS #}
{% set rgb = '120,210,255' %}
{% set anim = 'hum-good-breathe' %}
{% set glow_anim = 'hum-good-glow' %}
{% set halo_anim = 'hum-good-halo' %}
{% set duration = 3.2 %}
{# RANGES
< 40 -> BAD (dark blue)
40-60 -> GOOD (light blue)
> 60 -> MIDDLE / humid (medium blue)
#}
{% if hum < 40 %}
{# BAD - dry - dark blue #}
{% set rgb = '0,80,200' %}
{% set anim = 'hum-bad-pulse' %}
{% set glow_anim = 'hum-bad-glow' %}
{% set halo_anim = 'hum-bad-halo' %}
{% set duration = 2.8 %}
{% elif hum <= 60 %}
{# GOOD - light blue #}
{% set rgb = '120,210,255' %}
{% set anim = 'hum-good-breathe' %}
{% set glow_anim = 'hum-good-glow' %}
{% set halo_anim = 'hum-good-halo' %}
{% set duration = 3.4 %}
{% else %}
{# MIDDLE / humid - medium blue #}
{% set rgb = '40,140,255' %}
{% set anim = 'hum-mid-wave' %}
{% set glow_anim = 'hum-mid-glow' %}
{% set halo_anim = 'hum-mid-halo' %}
{% set duration = 3.0 %}
{% endif %}
--hum-rgb: {{ rgb }};
--shape-animation: {{ anim }} {{ duration }}s ease-in-out infinite;
--hum-glow-animation: {{ glow_anim }} {{ (duration * 0.9) | round(2) }}s ease-in-out infinite;
--hum-halo-animation: {{ halo_anim }} {{ (duration * 1.1) | round(2) }}s ease-in-out infinite;
/* Icon color follows humidity color */
--icon-color: rgba({{ rgb }}, 1);
/* Neutral pill so theme blue does not leak through */
background-color: rgba(77,77,77,0.2) !important;
box-shadow: none !important;
border: 1px solid rgba(255,255,255,0.06);
opacity: 1;
position: relative;
transform-origin: 50% 60%;
animation: var(--shape-animation);
}
/* Glow layers */
.shape::before,
.shape::after {
content: '';
position: absolute;
border-radius: inherit;
pointer-events: none;
}
.shape::before {
inset: -8px;
animation: var(--hum-glow-animation);
}
.shape::after {
inset: -22px;
animation: var(--hum-halo-animation);
mix-blend-mode: screen;
}
/* ========== GOOD - light blue ========== */
@keyframes hum-good-breathe {
0% { transform: scale(0.98); }
50% { transform: scale(1.04); }
100% { transform: scale(0.98); }
}
@keyframes hum-good-glow {
0% {
box-shadow:
0 0 18px 0 rgba(var(--hum-rgb), 0.55),
0 0 30px 4 rgba(var(--hum-rgb), 0.6);
}
50% {
box-shadow:
0 0 24px 4 rgba(var(--hum-rgb), 0.9),
0 0 44px 10px rgba(var(--hum-rgb), 0.85);
}
100% {
box-shadow:
0 0 18px 0 rgba(var(--hum-rgb), 0.55),
0 0 30px 4 rgba(var(--hum-rgb), 0.6);
}
}
@keyframes hum-good-halo {
0% {
box-shadow:
0 0 80px 24px rgba(var(--hum-rgb), 0.35),
0 18px 70px -12px rgba(180,230,255,0.3);
}
50% {
box-shadow:
0 0 120px 40px rgba(var(--hum-rgb), 0.45),
0 26px 90px -10px rgba(200,240,255,0.45);
}
100% {
box-shadow:
0 0 80px 24px rgba(var(--hum-rgb), 0.35),
0 18px 70px -12px rgba(180,230,255,0.3);
}
}
/* ========== MIDDLE / humid - medium blue ========== */
@keyframes hum-mid-wave {
0% { transform: translateX(0); }
25% { transform: translateX(-1px); }
50% { transform: translateX(1px) translateY(-1px); }
75% { transform: translateX(-1px); }
100% { transform: translateX(0); }
}
@keyframes hum-mid-glow {
0% {
box-shadow:
0 0 20px 0 rgba(var(--hum-rgb), 0.6),
0 0 32px 4 rgba(var(--hum-rgb), 0.7);
}
50% {
box-shadow:
0 0 28px 3 rgba(var(--hum-rgb), 0.95),
0 0 48px 10px rgba(var(--hum-rgb), 0.85);
}
100% {
box-shadow:
0 0 20px 0 rgba(var(--hum-rgb), 0.6),
0 0 32px 4 rgba(var(--hum-rgb), 0.7);
}
}
@keyframes hum-mid-halo {
0% {
box-shadow:
0 0 90px 26px rgba(var(--hum-rgb), 0.4),
0 18px 80px -12px rgba(80,190,255,0.35);
}
50% {
box-shadow:
0 0 135px 42px rgba(var(--hum-rgb), 0.5),
0 28px 105px -10px rgba(100,210,255,0.5);
}
100% {
box-shadow:
0 0 90px 26px rgba(var(--hum-rgb), 0.4),
0 18px 80px -12px rgba(80,190,255,0.35);
}
}
/* ========== BAD - dry - dark blue ========== */
@keyframes hum-bad-pulse {
0% { transform: scale(0.97); }
40% { transform: scale(1.03); }
100% { transform: scale(0.97); }
}
@keyframes hum-bad-glow {
0% {
box-shadow:
0 0 18px 0 rgba(var(--hum-rgb), 0.6),
0 0 28px 4 rgba(var(--hum-rgb), 0.7);
}
50% {
box-shadow:
0 0 26px 4 rgba(var(--hum-rgb), 0.95),
0 0 44px 12px rgba(var(--hum-rgb), 0.9);
}
100% {
box-shadow:
0 0 18px 0 rgba(var(--hum-rgb), 0.6),
0 0 28px 4 rgba(var(--hum-rgb), 0.7);
}
}
@keyframes hum-bad-halo {
0% {
box-shadow:
0 0 80px 22px rgba(var(--hum-rgb), 0.45),
0 18px 75px -10px rgba(0,70,160,0.5);
}
50% {
box-shadow:
0 0 130px 40px rgba(var(--hum-rgb), 0.6),
0 26px 100px -8px rgba(0,90,190,0.65);
}
100% {
box-shadow:
0 0 80px 22px rgba(var(--hum-rgb), 0.45),
0 18px 75px -10px rgba(0,70,160,0.5);
}
}
.: |
mushroom-shape-icon {
--icon-size: 64px;
--icon-color: rgba(var(--hum-rgb),1) !important;
display: flex;
margin: -18px 0 10px -20px !important;
padding-right: 22px;
padding-bottom: 25px;
}
ha-card {
clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 14px));
/* FONT SIZE & SPACING SETTINGS */
--card-primary-font-size: 1.2rem !important;
/* Increases vertical space between primary and secondary */
--card-primary-line-height: 1.3 !important;
}
- type: custom:vertical-stack-in-card
cards:
- type: custom:mini-graph-card
entities:
- sensor.livingroom_humidity
line_color: lightblue
line_width: 5
hours_to_show: 24
show:
name: false
icon: false
state: false
labels: false
legend: false
card_mod:
style: |
ha-card {
background: none;
box-shadow: none;
opacity: 50%;
border: none;
width: 250px;
mask-image: radial-gradient(
ellipse at center,
rgba(0,0,0,1) 0%,
rgba(0,0,0,0) 90%
);
}
card_mod:
style:
.: |
ha-card {
background: none;
box-shadow: none;
border: none;
margin: 8px 12px;
position: absolute;
bottom: -10px;
right: -10px;
}
- type: custom:mushroom-chips-card
chips:
- type: template
entity: sensor.livingroom_mi_battery
icon: |-
{% if states(entity)|float<=20 %}
mdi:battery-20
{% elif states(entity)|float<=50 %}
mdi:battery-50
{% else %}
mdi:battery
{% endif %}
content: "{{states(entity)|float|round(0)}}%"
icon_color: |-
{% if states(entity)|float<=25 %}
red
{% elif states(entity)|float<=75 %}
orange
{% else %}
green
{% endif %}
alignment: end
card_mod:
style: >
ha-card {
/* ================================== */
/* USER CONFIG HERE */
/* ================================== */
/* 1. ACTIVE STATE (NUMERIC) */
{% set threshold_below = 20 %}
{% set threshold_above = false %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '10px' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '0%' %}
/* 3. SIZING */
{% set icon_size = '10px' %}
{% set text_size = '8px' %}
{% set badge_height = '3px' %}
{% set border_radius = '7px' %}
{% set border_thickness = '1px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = 'grey' %}
{% set active_icon = 'white' %}
{% set active_text = 'darkgrey' %}
{% set active_border = 'transparent' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = 'grey' %}
{% set inactive_icon = 'red' %}
{% set inactive_text = 'white' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'flash' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */
{% set anim_duration_sec = 2 %}
{% set anim_delay_sec = 5 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set state_num = current_state | float(-99999) %}
{% set check_below = threshold_below | string | lower != 'false' %}
{% set check_above = threshold_above | string | lower != 'false' %}
{% set is_active_below = check_below and state_num != -99999 and state_num <= (threshold_below | float(-99999)) %}
{% set is_active_above = check_above and state_num != -99999 and state_num >= (threshold_above | float(-99999)) %}
{% set is_active = is_active_below or is_active_above %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or
config.chips[0].content | length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0
%}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
Motion Sensor
type: custom:vertical-stack-in-card
cards:
- type: custom:mushroom-entity-card
entity: binary_sensor.pir_gate_occupancy
name: Motion Sensor
icon: mdi:motion-sensor
primary_info: name
secondary_info: state
tap_action:
action: more-info
icon_color: light-grey
card_mod:
style:
.: |
ha-card {
/* ========================== */
/* USER CONFIG */
/* ========================== */
/* 1. What state the animation? */
{% set active_state = 'Detected' %}
/* 2. Icon Size */
--custom-icon-size: 68px;
/* 3. Colors (RGB) */
{% set color_detected = '255, 50, 50' %} /* Redd */
{% set color_scanning = '0, 200, 255' %} /* Blue */
/* 4. Badge Text */
{% set text_detected = 'DETECTED' %}
{% set text_scanning = 'SCANNING' %}
/* ========================== */
{% set is_active = states(config.entity) == active_state %}
{% if is_active %}
{% set color = color_detected %}
{% set badge = text_detected %}
{% set bg_image = 'radial-gradient(circle at center, rgba('~color~', 0.15) 0%, transparent 70%)' %}
{% else %}
{% set color = color_scanning %}
{% set badge = text_scanning %}
{% set bg_image = 'none' %}
{% endif %}
/* --- CSS VARIABLES PASSING --- */
--sonar-color: {{ color }};
--sonar-bg: {{ bg_image }};
--badge-text: "{{ badge }}";
/* Animation Selectors */
--anim-sweep: {{ 'block' if not is_active else 'none' }};
--anim-pulse: {{ 'block' if is_active else 'none' }};
/* --- CORE CARD STYLING --- */
background-image: var(--sonar-bg) !important;
transition: background-image 0.5s ease;
border-radius: 12px;
border: none;
overflow: hidden;
}
/* --- STATUS BADGE (Top Right) --- */
ha-card::before {
content: var(--badge-text);
position: absolute;
top: 10px; right: 10px;
font-size: 10px;
font-weight: 900;
letter-spacing: 1px;
color: rgb(var(--sonar-color));
background: rgba(var(--sonar-color), 0.15);
border: 1px solid rgba(var(--sonar-color), 0.3);
box-shadow: 0 0 10px rgba(var(--sonar-color), 0.2);
padding: 3px 8px;
border-radius: 6px;
z-index: 2;
}
/* --- BOTTOM SCAN BAR --- */
ha-card::after {
content: '';
position: absolute;
bottom: 0; left: 0; right: 0;
height: 4px;
background: rgb(var(--sonar-color));
box-shadow: 0 0 15px rgb(var(--sonar-color));
opacity: {{ '1' if is_active else '0.5' }};
transition: all 0.5s ease;
}
mushroom-shape-icon$: |
.shape {
/* PASS VARIABLES */
--shape-color: var(--sonar-color);
--icon-size: var(--custom-icon-size) !important;
/* GEOMETRY FIXES */
width: var(--icon-size) !important;
height: var(--icon-size) !important;
border-radius: 50% !important;
background: transparent !important;
/* Positioning */
position: relative;
display: flex;
align-items: center;
justify-content: center;
overflow: visible !important;
/* Static "HUD" Ring */
border: 2px solid rgba(var(--shape-color), 0.2);
box-shadow: inset 0 0 15px rgba(var(--shape-color), 0.1);
transition: border-color 0.3s ease;
}
/* --- ANIMATION: RADAR SWEEP (SCANNING) --- */
.shape::before {
content: '';
display: var(--anim-sweep);
position: absolute;
inset: -2px; /* Cover the border */
border-radius: 50%;
background: conic-gradient(
from 0deg,
transparent 0deg,
transparent 270deg,
rgba(var(--shape-color), 0.1) 280deg,
rgba(var(--shape-color), 1) 360deg
);
animation: radar-spin 2.5s linear infinite;
z-index: 1;
}
/* --- ANIMATION: SHOCKWAVE (DETECTED) --- */
.shape::after {
content: '';
display: var(--anim-pulse);
position: absolute;
inset: 0;
border-radius: 50%;
z-index: 0;
animation: sonar-shockwave 2s infinite;
}
/* ICON STYLING */
ha-icon {
position: relative;
z-index: 5;
color: rgba(var(--shape-color), 1) !important;
filter: drop-shadow(0 0 8px rgba(var(--shape-color), 0.8));
transition: color 0.3s ease;
}
/* --- KEYFRAMES --- */
@keyframes radar-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes sonar-shockwave {
0% { box-shadow: 0 0 0 0 rgba(var(--shape-color), 0.8), 0 0 0 0 rgba(var(--shape-color), 0.8); }
40% { box-shadow: 0 0 0 20px rgba(var(--shape-color), 0.3), 0 0 0 0 rgba(var(--shape-color), 0.8); }
80% { box-shadow: 0 0 0 40px rgba(var(--shape-color), 0), 0 0 0 20px rgba(var(--shape-color), 0); }
100% { box-shadow: 0 0 0 0 rgba(var(--shape-color), 0), 0 0 0 0 rgba(var(--shape-color), 0); }
}
- type: custom:mushroom-chips-card
chips:
- type: template
entity: sensor.pir_gate_battery
tap_action:
action: none
icon: |-
{% if states(entity)|float<=20 %}
mdi:battery-20
{% elif states(entity)|float<=50 %}
mdi:battery-50
{% elif states(entity)|float<=75 %}
mdi:battery-70
{% else %}
mdi:battery
{% endif %}
content: "{{states(entity)|float|round(0)}}%"
hold_action:
action: none
double_tap_action:
action: none
icon_color: |-
{% if states(entity)|float<=20 %}
red
{% elif states(entity)|float<=50 %}
yellow
{% elif states(entity)|float<=75 %}
orange
{% else %}
green
{% endif %}
alignment: end
card_mod:
style: >
ha-card {
/* ================================== */
/* USER CONFIG HERE */
/* ================================== */
/* 1. ACTIVE STATE (NUMERIC) */
{% set threshold_below = 20 %}
{% set threshold_above = false %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '10px' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '85px' %}
/* 3. SIZING */
{% set icon_size = '17px' %}
{% set text_size = '11px' %}
{% set badge_height = '4px' %}
{% set border_radius = '5px' %}
{% set border_thickness = '1px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = 'grey' %}
{% set active_icon = 'white' %}
{% set active_text = 'darkgrey' %}
{% set active_border = 'transparent' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = 'grey' %}
{% set inactive_icon = 'red' %}
{% set inactive_text = 'white' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'flash' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */
{% set anim_duration_sec = 2 %}
{% set anim_delay_sec = 5 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set state_num = current_state | float(-99999) %}
{% set check_below = threshold_below | string | lower != 'false' %}
{% set check_above = threshold_above | string | lower != 'false' %}
{% set is_active_below = check_below and state_num != -99999 and state_num <= (threshold_below | float(-99999)) %}
{% set is_active_above = check_above and state_num != -99999 and state_num >= (threshold_above | float(-99999)) %}
{% set is_active = is_active_below or is_active_above %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or config.chips[0].content
| length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
Light card
type: custom:vertical-stack-in-card
cards:
- type: custom:mushroom-light-card
card_mod:
style:
mushroom-shape-icon$: ""
.: |
mushroom-shape-icon {
--icon-size: 60px;
display: flex;
margin: -18px 0px 0px -18px !important;
}
ha-card {
clip-path: inset(0 0 0 0 round var(--ha-card-border-radius, 12px));
}
entity: light.right_led
fill_container: true
use_light_color: true
show_color_temp_control: true
collapsible_controls: false
show_color_control: true
show_brightness_control: true
tap_action:
action: toggle
icon: mdi:drag-vertical
double_tap_action:
action: none
hold_action:
action: more-info
name: " Right LED"
- type: custom:mushroom-chips-card
chips:
- type: template
entity: sensor.your_entity_here
icon: mdi:party-popper
tap_action:
action: perform-action
perform_action: script.your_script_here
target: {}
alignment: end
card_mod:
style: >
ha-card {
/* ================================ */
/* USER CONFIG HERE */
/* ================================ */
/* 1. ACTIVE STATES */
{% set active_states = ['on', 'off'] %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '5%' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '22%' %}
/* 3. SIZING */
{% set icon_size = '25px' %}
{% set text_size = '12px' %}
{% set badge_height = '7px' %}
{% set border_radius = '10px' %}
{% set border_thickness = '0.5px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = 'red' %}
{% set active_icon = 'white' %}
{% set active_text = 'white' %}
{% set active_border = 'white' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = '#d980f5' %}
{% set inactive_icon = 'white' %}
{% set inactive_text = 'white' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'none' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */
{% set anim_duration_sec = 1 %}
{% set anim_delay_sec = 1 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set is_active = current_state in active_states %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or config.chips[0].content
| length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
- type: custom:mushroom-chips-card
chips:
- type: template
entity: sensor.your_entity_here
icon: mdi:fire
tap_action:
action: perform-action
perform_action: script.your_script_here
target: {}
alignment: end
card_mod:
style: >
ha-card {
/* ================================ */
/* USER CONFIG HERE */
/* ================================ */
/* 1. ACTIVE STATES */
{% set active_states = ['on', 'off'] %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '5%' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '12%' %}
/* 3. SIZING */
{% set icon_size = '25px' %}
{% set text_size = '12px' %}
{% set badge_height = '7px' %}
{% set border_radius = '10px' %}
{% set border_thickness = '0.5px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = 'red' %}
{% set active_icon = 'white' %}
{% set active_text = 'white' %}
{% set active_border = 'white' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = '#ff7800' %}
{% set inactive_icon = 'white' %}
{% set inactive_text = 'white' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'none' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */
{% set anim_duration_sec = 1 %}
{% set anim_delay_sec = 1 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set is_active = current_state in active_states %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or config.chips[0].content
| length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
- type: custom:mushroom-chips-card
chips:
- type: template
entity: sensor.your_entity_here
icon: mdi:white-balance-auto
tap_action:
action: perform-action
perform_action: script.your_script_here
target: {}
alignment: end
card_mod:
style: >
ha-card {
/* ================================ */
/* USER CONFIG HERE */
/* ================================ */
/* 1. ACTIVE STATES */
{% set active_states = ['on', 'off'] %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '5%' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '2%' %}
/* 3. SIZING */
{% set icon_size = '25px' %}
{% set text_size = '12px' %}
{% set badge_height = '7px' %}
{% set border_radius = '10px' %}
{% set border_thickness = '0.5px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = 'red' %}
{% set active_icon = 'white' %}
{% set active_text = 'white' %}
{% set active_border = 'white' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = '#f5d45c' %}
{% set inactive_icon = 'white' %}
{% set inactive_text = 'white' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'none' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */
{% set anim_duration_sec = 1 %}
{% set anim_delay_sec = 1 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set is_active = current_state in active_states %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or config.chips[0].content
| length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}
Mail card
type: custom:vertical-stack-in-card
cards:
- type: custom:mushroom-entity-card
entity: input_boolean.mail_arrived
name: Mailbox
icon: mdi:mailbox
secondary_info: none
tap_action:
action: none
icon_color: orange
primary_info: name
card_mod:
style:
.: |
ha-card {
/* ========================== */
/* USER CONFIG */
/* ========================== */
/* 1. Define ACTIVE State */
{% set active_state = 'on' %}
/* 2. icon size */
--set-icon-size: 68px;
/* 3. Custom Badge TEXT? */
{% set active_badge_text = 'YOU\'VE GOT MAIL' %}
{% set empty_badge_text = 'NO MAIL' %}
/* 4. Custom color? (RGB) */
{% set color_active = '255, 190, 50' %} /* Orange */
{% set color_empty = '158, 158, 158' %} /* Grey */
/* ========================== */
{% set has_mail = states(config.entity) == active_state %}
/* 2. Status & Colors */
{% if has_mail %}
{% set state = 'mail' %}
{% set color = color_active %}
{% set badge = active_badge_text %}
{% else %}
{% set state = 'empty' %}
{% set color = color_empty %}
{% set badge = empty_badge_text %}
{% endif %}
/* CSS VARS */
--mb-color: {{ color }};
--mb-badge: "{{ badge }}";
/* Animation Selectors */
--anim-mail-drop: {{ 'block' if state == 'mail' else 'none' }};
--icon-move: {{ 'flag-wave 2s ease-in-out infinite' if state == 'mail' else 'none' }};
/* --- CORE CARD STYLING --- */
background: var(--card-background-color, #1c1c1c);
border-radius: var(--ha-card-border-radius, 12px) !important;
/* Keeps the bar inside the rounded corners */
overflow: hidden;
transition: all 0.5s ease;
position: relative;
}
/* --- BOTTOM HIGHLIGHT BAR --- */
ha-card::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
height: 4px;
width: 100%;
/* Dynamic Colors based on State */
background: rgb(var(--mb-color));
box-shadow: 0 0 15px rgb(var(--mb-color));
transition: background 0.5s ease, box-shadow 0.5s ease;
opacity: 1; /* Always visible now */
z-index: 1;
}
mushroom-shape-icon$: |
.shape {
background: rgba(var(--mb-color), 0.15) !important;
--icon-size: var(--set-icon-size) !important;
position: relative;
overflow: hidden; /* Hide the letter before it drops in */
transition: background 0.3s ease;
}
/* -------------------------------------- */
/* ANIMATION: THE BIG FALLING LETTER */
/* -------------------------------------- */
.shape::before {
content: '';
display: var(--anim-mail-drop);
position: absolute;
/* --- BIGGER ENVELOPE SIZE --- */
width: 28px; height: 18px;
/* White Envelope Body */
background: #fff;
border-radius: 3px;
/* Center it horizontally */
left: calc(50% - 14px);
/* The Envelope Flap (Triangle) details */
background-image: linear-gradient(135deg, transparent 50%, #ccc 50%),
linear-gradient(225deg, transparent 50%, #ccc 50%);
background-size: 50% 100%;
background-repeat: no-repeat;
background-position: 0 0, 100% 0;
box-shadow: 0 4px 6px rgba(0,0,0,0.4);
/* Run Animation */
animation: mail-drop 1.5s ease-in-out infinite;
}
/* -------------------------------------- */
/* ANIMATION: ICON MOVEMENT */
/* -------------------------------------- */
ha-icon {
color: rgb(var(--mb-color)) !important;
transition: color 0.3s ease;
animation: var(--icon-move);
z-index: 2;
}
/* --- KEYFRAMES --- */
@keyframes mail-drop {
0% { top: -30px; opacity: 0; transform: rotate(-10deg); }
30% { opacity: 1; transform: rotate(0deg); }
60% { top: 50%; opacity: 1; transform: rotate(5deg); }
100% { top: 65%; opacity: 0; transform: rotate(0deg); }
}
@keyframes flag-wave {
0%, 100% { transform: rotate(0deg); }
25% { transform: rotate(-10deg); }
75% { transform: rotate(5deg); }
}
- type: custom:mushroom-chips-card
chips:
- type: template
entity: input_boolean.mail_arrived
icon: |-
{% if states(entity) in ['on'] %}
mdi:bell
{% else %}
mdi:bell-cancel
{% endif %}
content: |-
{% if states(entity) in ['on'] %}
ARRIVED AT {{ as_timestamp(states[entity].last_changed) | timestamp_custom('%H:%M') }}
{% else %}
NO MAIL
{% endif %}
alignment: end
card_mod:
style: >
ha-card {
/* ================================ */
/* USER CONFIG HERE */
/* ================================ */
/* 1. ACTIVE STATES */
{% set active_states = ['on'] %}
/* 2. POSITIONING */
{% set pos_y = 'top' %}
{% set pos_y_val = '30%' %}
{% set pos_x = 'right' %}
{% set pos_x_val = '1%' %}
/* 3. SIZING */
{% set icon_size = '20px' %}
{% set text_size = '12px' %}
{% set badge_height = '5px' %}
{% set border_radius = '10px' %}
{% set border_thickness = '0.9px' %}
/* 4. COLORS (HEX, RGB, Color Name) */
/* --- Active --- */
{% set active_bg = '#ffbc2c' %}
{% set active_icon = 'orange' %}
{% set active_text = '#ffffff' %}
{% set active_border = 'orange' %}
{% set active_opacity = 0.3 %}
/* --- Inactive --- */
{% set inactive_bg = 'grey' %}
{% set inactive_icon = 'grey' %}
{% set inactive_text = 'white' %}
{% set inactive_border = 'transparent' %}
{% set inactive_opacity = 0.3 %}
/* 5. ANIMATIONS */
/* Options: pulse, shake, wobble */
/* flash, heartbeat, swing, vibrate */
{% set anim_type = 'shake' %}
/* true = 24/7, false = only when active */
{% set always_animate = false %}
{% set anim_intensity_sec = 0.5 %} /* 0.1 to 1 */
{% set anim_duration_sec = 1 %}
{% set anim_delay_sec = 1 %}
/* ================================== */
/* USER CONFIG END (DONT TOUCH BELOW) */
/* ================================== */
{% set current_state = states(config.chips[0].entity) %}
{% set is_active = current_state in active_states %}
{% if is_active %}
{% set current_bg = active_bg %}
{% set current_icon = active_icon %}
{% set current_text = active_text %}
{% set current_border = active_border %}
{% set current_op = active_opacity %}
{% set current_anim = anim_type %}
{% else %}
{% set current_bg = inactive_bg %}
{% set current_icon = inactive_icon %}
{% set current_text = inactive_text %}
{% set current_border = inactive_border %}
{% set current_op = inactive_opacity %}
{% set current_anim = anim_type if always_animate else 'none' %}
{% endif %}
{% set master_cycle = anim_duration_sec + anim_delay_sec %}
{% set iterations = (anim_duration_sec / anim_intensity_sec) | round(0, 'floor') | int if anim_intensity_sec > 0 else 0 %}
{% set step_percent = (anim_intensity_sec / master_cycle) * 100 if master_cycle > 0 else 0 %}
--chip-padding: {{ badge_height }};
--chip-border-radius: {{ border_radius }};
--chip-border-width: 0px !important;
--ha-card-border-width: 0px !important;
--chip-box-shadow: 0 0 0 {{ border_thickness }} {{ current_border }} !important;
--text-color: {{ current_icon }} !important;
--color: {{ current_icon }} !important;
--chip-background: color-mix(in srgb, {{ current_bg }}, transparent {{ (1 - current_op) * 100 }}%) !important;
--chip-font-size: {{ text_size }} !important;
--chip-icon-size: {{ icon_size }} !important;
--mdc-icon-size: {{ icon_size }} !important;
--chip-height: auto !important;
--primary-text-color: {{ current_text }} !important;
--secondary-text-color: {{ current_text }} !important;
position: absolute !important;
{{ pos_y }}: {{ pos_y_val }};
{{ pos_x }}: {{ pos_x_val }};
z-index: 1;
border: none !important;
border-radius: {{ border_radius }} !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.2);
overflow: visible !important;
will-change: transform;
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
animation: anim-{{ config.chips[0].entity | replace('.', '-') }}-{{ anim_type }} {{ master_cycle }}s infinite linear;
{% endif %}
}
ha-state-icon, ha-icon {
display: flex;
align-items: center;
justify-content: center;
width: {{ icon_size }} !important;
height: {{ icon_size }} !important;
}
{% if config.chips[0].content is not defined or config.chips[0].content
| length == 0 %}
ha-card { padding: 5px !important; border-radius: 50% !important; aspect-ratio: 1/1; justify-content: center; }
.content { display: none; }
{% else %}
ha-card { padding: 0 10px !important; }
.content { padding-left: 5px; font-weight: bold; }
{% endif %}
{% if current_anim != 'none' and iterations > 0 and master_cycle > 0 %}
@keyframes anim-{{ config.chips[0].entity | replace('.', '-') }}-{{
anim_type }} {
{% for i in range(iterations) %}
{% set t = i * step_percent %}
{% if anim_type == 'pulse' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'shake' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.25) }}% { transform: rotateZ(-10deg); }
{{ t + (step_percent * 0.75) }}% { transform: rotateZ(10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'flash' %}
{{ t + 0 }}% { opacity: 1; }
{{ t + (step_percent * 0.5) }}% { opacity: 0; }
{{ t + step_percent }}% { opacity: 1; }
{% elif anim_type == 'wobble' %}
{{ t + 0 }}% { transform: translate3d(0%, 0, 0); }
{{ t + (step_percent * 0.3) }}% { transform: translate3d(-15%, 0, 0) rotateZ(-5deg); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(10%, 0, 0) rotateZ(3deg); }
{{ t + step_percent }}% { transform: translate3d(0%, 0, 0); }
{% elif anim_type == 'heartbeat' %}
{{ t + 0 }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.25) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + (step_percent * 0.5) }}% { transform: scale3d(1, 1, 1); }
{{ t + (step_percent * 0.75) }}% { transform: scale3d(1.15, 1.15, 1); }
{{ t + step_percent }}% { transform: scale3d(1, 1, 1); }
{% elif anim_type == 'swing' %}
{{ t + 0 }}% { transform: rotateZ(0deg); }
{{ t + (step_percent * 0.4) }}% { transform: rotateZ(15deg); }
{{ t + (step_percent * 0.8) }}% { transform: rotateZ(-10deg); }
{{ t + step_percent }}% { transform: rotateZ(0deg); }
{% elif anim_type == 'vibrate' %}
{{ t + 0 }}% { transform: translate3d(0, 0, 0); }
{{ t + (step_percent * 0.2) }}% { transform: translate3d(-2px, 2px, 0); }
{{ t + (step_percent * 0.4) }}% { transform: translate3d(-2px, -2px, 0); }
{{ t + (step_percent * 0.6) }}% { transform: translate3d(2px, 2px, 0); }
{{ t + (step_percent * 0.8) }}% { transform: translate3d(2px, -2px, 0); }
{{ t + step_percent }}% { transform: translate3d(0, 0, 0); }
{% endif %}
{% endfor %}
}
{% endif %}