Hi guys a made a weather card with the custom animations from @dimitri.landerloos Mushroom Cards - Build a beautiful dashboard easily š (Part 1) - #7717 by dimitri.landerloos
With his help and a few tweaks itās here let me know what you guys think of it.
The card uses card mod and Muschroom cards. And on top of that it is build for the Openweathermap service and the Sun service. But feel free to make it suit your own wheater provider.

It has support for the following wheater conditions:
- clear-night
- cloudy
- exceptional
- fog
- hail
- lightning
- lightning-rainy
- partlycloudy (daytime and nighttime with diffrent animations)
- pouring
- rainy
- snowy
- snowy-rainy
- sunny
- windy
- windy-variant (wind with clouds)
type: custom:mushroom-template-card
primary: '{{ states(''sensor.openweathermap_condition'') | title }}'
icon: >-
{% set icons = {
'clear-night': 'mdi:weather-night',
'cloudy': 'mdi:weather-cloudy',
'exceptional': 'mdi:weather-cloudy-alert',
'fog': 'mdi:weather-fog',
'hail': 'mdi:weather-hail',
'lightning': 'mdi:weather-lightning',
'lightning-rainy': 'mdi:weather-lightning-rainy',
'partlycloudy': 'mdi:weather-partly-cloudy' if is_state('sun.sun', 'above_horizon') else 'mdi:weather-night-partly-cloudy',
'pouring': 'mdi:weather-pouring',
'rainy': 'mdi:weather-rainy',
'snowy': 'mdi:weather-snowy',
'snowy-rainy': 'mdi:weather-snowy-rainy',
'sunny': 'mdi:weather-sunny',
'windy': 'mdi:weather-windy',
'windy-variant': 'mdi:weather-windy-variant'
} %}
{{ icons.get(states('sensor.openweathermap_condition'),
'mdi:help-circle') }}
icon_color: >-
{% set colors = {
'clear-night': 'amber',
'cloudy': 'grey',
'exceptional': 'red',
'fog': 'grey',
'hail': 'grey',
'lightning': 'dark-grey',
'lightning-rainy': 'dark-grey',
'partlycloudy': 'orange',
'pouring': 'blue',
'rainy': 'light-blue',
'snowy': 'grey',
'snowy-rainy': 'grey',
'sunny': 'amber',
'windy': 'light-blue',
'windy-variant': 'cyan'
} %}
{{ colors.get(states('sensor.openweathermap_condition'), 'white')
}}
secondary: >-
{{ (states('sensor.openweathermap_temperature') | float) |
round(1, default=0) | string | replace('.', ',') }} °C feels like
{{ (states('sensor.openweathermap_feels_like_temperature') |
float) | round(1, default=0) | string | replace('.', ',') }} °C
grid_options:
columns: 12
rows: 1
tap_action:
action: more-info
entity: sensor.openweathermap_temperature
card_mod:
style: |
ha-state-icon {
{% set condition = states('sensor.openweathermap_condition') %}
{% if condition == 'clear-night' %}
animation: moon 10s linear infinite, stars 5s linear infinite;
{% elif condition == 'cloudy' %}
animation: cloudy 10s ease-in-out infinite;
{% elif condition == 'exceptional' %}
animation: exceptional 400ms ease-in-out infinite;
{% elif condition == 'fog' %}
animation: cloudy 10s ease-in-out infinite, fog 4s infinite;
{% elif condition == 'hail' %}
animation: cloudy 10s ease-in-out infinite, hail 2s infinite;
{% elif condition == 'lightning' %}
animation: cloudy 10s ease-in-out infinite, lightning 4s infinite;
{% elif condition == 'lightning-rainy' %}
animation: cloudy 10s ease-in-out infinite, lightning-rainy 4s infinite;
{% elif condition == 'partlycloudy' %}
{% if is_state('sun.sun', 'above_horizon') %}
animation: cloudy 10s ease-in-out infinite, sun-partly 2s infinite;
{% else %}
position: relative;
z-index: 1;
animation: cloudy 10s ease-in-out infinite;
/* animation: cloudy 10s ease-in-out infinite, moon-partly 10s linear infinite; */
{% endif %}
{% elif condition == 'pouring' %}
animation: cloudy 10s ease-in-out infinite, pouring 1s infinite;
{% elif condition == 'rainy' %}
animation: cloudy 10s ease-in-out infinite, rainy 1.5s infinite;
{% elif condition == 'snowy' %}
animation: cloudy 10s ease-in-out infinite, snowy 4s infinite;
{% elif condition == 'snowy-rainy' %}
animation: cloudy 10s ease-in-out infinite, snowy-rainy 4s infinite;
{% elif condition == 'sunny' %}
animation: sunny 8s ease-in-out infinite alternate;
{% elif condition == 'windy' %}
animation: windy 10s ease-in-out infinite;
transform-origin: 15% 50%
{% elif condition == 'windy-variant' %}
animation: cloudy 10s ease-in-out infinite, windy-variant 5s infinite;
{% endif %}
}
ha-state-icon::after {
content: "";
position: absolute;
inset: 0;
background-color: rgba(73,52,22,1);
clip-path: polygon(0 58%, 27% 58%, 34% 47%, 44% 42%, 55% 42%, 69% 47%, 74% 64%, 100% 67%, 100% 0, 0 0);
opacity: 0;
{% set condition = states('sensor.openweathermap_condition') %}
{% if condition == 'partlycloudy' %}
{% if is_state('sun.sun', 'below_horizon') %}
animation: moon-partly 5s ease-in-out infinite alternate 1s; /* vertraagde fade-in */
{% endif %}
{% endif %}
z-index: 2;
pointer-events: none;
}
@keyframes moon {
0%, 100% { transform: rotate(12deg); }
30% { transform: rotate(-6deg); }
45% { transform: rotate(8deg); }
75% { transform: rotate(-10deg); }
}
@keyframes moon-partly {
to {
opacity: 1;
}
}
@keyframes stars {
0%, 3.1%, 14.1% { clip-path: inset(0 0 0 0); }
3% { clip-path: polygon(1% 1%, 0% 99%, 99% 100%, 99% 62%, 68% 62%, 62% 44%, 76% 34%, 100% 34%, 99% 0%); }
14% { clip-path: polygon(1% 1%, 0% 99%, 99% 100%, 100% 25%, 51% 45%, 38%, 34%, 36% 0); }
}
@keyframes cloudy {
0%, 100% { transform: translateX(3px); }
30% { transform: translateX(-1px); }
45% { transform: translateX(1.5px); }
75% { transform: translateX(-3.2px); }
}
@keyframes exceptional {
0%, 100% { transform: translate(0, 0)}
20% { transform: translate(0px, -0.3px)}
40% { transform: translate(0px, 0.3px)}
60% { transform: translate(0px, 0.3px)}
80% { transform: translate(0px, -0.3px)}
}
@keyframes fog {
0%, 26%, 76%, 100% { clip-path: inset(0 0 0 0); }
25% { clip-path: polygon(0 0, 100% 0, 100% 59%, 60% 59%, 60% 74%, 100% 74%,100% 100%, 0 100%); }
75% { clip-path: polygon(0 0, 100% 0, 100% 100%, 26% 100%, 26% 76%, 0 76%);}
}
@keyframes hail {
0%, 26%, 51%, 76%, 100% { clip-path: inset(0 0 0 0); }
25% { clip-path: polygon(0 0, 100% 0, 100% 100%, 62% 100%, 47% 69%, 56% 55%, 43% 43%, 31% 58%, 48% 68%, 63% 100%, 0 100%); }
50% { clip-path: polygon(0 0, 100% 0, 100% 100%, 62% 100%, 61% 86%, 74% 74%, 61% 60%, 46% 69%, 60% 87%, 63% 100%, 0 100%); }
75% { clip-path: polygon(0 0, 100% 0, 100% 100%, 47% 100%, 56% 83%, 42% 68%, 27% 81%, 37% 100%, 0 100%); }
}
@keyframes lightning {
0%, 10%, 12.1%, 15%, 18.1%, 20%, 100% { color: rgb(var(--rgb-dark-grey)); clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 72% 71%, 61% 34%, 41% 35%, 29% 87%, 0% 100%);}
10.1%, 12%, 15.1%, 18% { color: rgb(var(--rgb-white)); clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%); }
}
@keyframes lightning-rainy {
0%, 10%, 12.1%, 15%, 18.1%, 20%, 49.9% { color: rgb(var(--rgb-dark-grey)); clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 73% 62%, 77% 54%, 60% 36%, 38% 36%, 20% 51%, 23% 63%, 0% 100%);}
10.1%, 12%, 15.1%, 18% { color: rgb(var(--rgb-white)); clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 73% 62%, 77% 54%, 60% 36%, 38% 36%, 61% 44%, 47% 100%, 0% 100%); }
50%, 100%{ color: rgb(var(--rgb-dark-grey)); clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 40% 99%, 58% 47%, 60% 36%, 38% 36%, 20% 51%, 23% 63%, 0% 100%); }
}
@keyframes sun-partly {
50% { clip-path: polygon(0 67%, 18% 55%, 16% 31%, 41% 12%, 67% 24%, 77% 59%, 100% 64%, 100% 100%, 0 100%); }
}
@keyframes pouring {
0%, 50%, 100% { clip-path: inset(0 0 0 0); }
25% { clip-path: polygon(0 0, 100% 0, 100% 83%, 54% 83%, 62% 47%, 47% 46%, 38% 83%, 0 83%); }
75% { clip-path: polygon(0 0, 100% 0, 100% 70%, 75% 70%, 80% 48%, 63% 48%,
54% 94%, 32% 94%, 46% 46%, 30% 46%, 23% 72%, 0 72%); }
}
@keyframes rainy {
50% { clip-path: polygon(0 0, 100% 0, 100% 73%, 71% 73%, 50% 39%, 29% 73%, 0 73%); }
}
@keyframes snowy {
50% { clip-path: polygon(0 0, 100% 0, 100% 100%, 65% 100%, 76% 73%, 57% 49%, 34% 56%, 26% 79%, 37% 100%, 0 100%); }
51% { clip-path: inset(0 0 0 0); }
}
@keyframes snowy-rainy {
0%, 32%, 100% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 79% 100%, 77% 71%, 70% 44%, 26% 43%, 13% 67%, 14% 100%, 0% 100%); }
33%, 65.9% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 59% 100%, 56% 75%, 70% 44%, 26% 43%, 13% 67%, 14% 100%, 0% 100%); }
66%, 99.9% { clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 79% 100%, 77% 71%, 70% 44%, 45% 39%, 62% 59%, 51% 100%, 0% 100%); }
}
@keyframes sunny {
70% { transform: rotate(360deg) scale(1); }
80% { transform: scale(1); }
90% { transform: scale(1.15); }
100% { transform: scale(1); }
}
@keyframes windy {
0%, 100% { transform: scaleX(1.2); }
30% { transform: scaleX(0.9); }
45% { transform: scaleX(1.1); }
75% { transform: scaleX(0.8); }
}
@keyframes windy-variant {
0%, 50%, 100% { clip-path: inset(0 0 0 0); }
25% { clip-path: inset(0 0 37% 0); }
}