Mushroom Cards - Build a beautiful dashboard easily šŸ„ (Part 1)

You could create a script that selects your source then sets the volume. Then call the script from tap_action.

This is not te complete code of the card right? can we have that? missing the charging icon and distance entity in your above code?

You probably thought I had forgotten about this but Iā€™ve had it at the back of my mind :wink:.

This is a progress bar around a Mushroom Icon. Values need to be converted to 100%. My example is for a volume bar, but you could show the progress/value of whatever you wanted. I think it would be ideal for showing a countdown/days till due indicator.

Mushroom Icon Progress Bar:

Mushroom Icon Progress Bar

type: custom:mushroom-template-card
icon: mdi:volume-high
primary: Volume
icon_color: blue
entity: input_number.lounge_pc_volume
secondary: '{{ (states(entity) |float * 100) | round(0) }}%'
card_mod:
  style:
    mushroom-shape-icon$: |
      .shape {
        background: radial-gradient(var(--card-background-color) 60%, transparent 0%), conic-gradient(rgb(var(--rgb-cyan)) {{ (states(config.entity) |  float * 100) | round(0) }}% 0%, var(--card-background-color) 0% 100%);
      }
      .shape:after {
        content: "";
        height: 100%;
        width: 100%;
        position: absolute;
        border-radius: 50%;
        background: rgba(var(--rgb-{{ config.icon_color }}), 0.2);
      }
28 Likes

It certainly would be ideal. Would then need a way to handle a countdown timer which is reset when required.

Which is something I havenā€™t looked into since I mentioned it some while ago

Yes you can! Use a view on panel mode, in there a vertical stack. You can add a header first and a footer last, content goes in the middle in a layout card.

You need to put mod-cards around the header/footer in order to apply ā€œposition: sticky; top: 0;ā€ css.

Screenshot of some of my views portrait & landscape, with sticky header & footer:





If thereā€™s interest Iā€™ll publish my config soon. Trying to deduplicate as much yaml as possible, and heavily using lovelace_gen (no button/decluttering/configtemplate cards at all!)

todo (if you know how, please let me know!):

  • [x] Move to grid layout while keeping masonry like auto placement of cards
  • [ ] Fix primary in main room cards to fit better.
  • [ ] Somehow get rid of sticky backgrounds or make main overflow visible (they all have background: none, but sometimes itā€™s still visible)
5 Likes

Thank you rhysb, is working perfekt and lokks good for me:

Screen_20221120-115245

@Mobiledude and @Jarne_Roussard here is the code for the card:

type: custom:vertical-stack-in-card
mode: vertical
cards:
  - type: custom:mushroom-chips-card
    card_mod:
      style: |
        ha-card {
          --chip-font-size: 0.3em;
          --chip-icon-size: 0.6em;
          --chip-border-width: 0;
          --chip-box-shadow: none;
          --chip-background: none;
          --chip-border: none;
          --chip-spacing: none;
          --chip-font-weight: normal;
        }
    alignment: justify
    chips:
      - type: template
        entity: person.YourName
        content: |-
          {% if is_state('person.YourName','home') %}
            {% set last_changed = states('sensor.tmp_person_time_arrived_home_YourName') | as_datetime %}
          {% else %}
            {% set last_changed = states('sensor.tmp_person_time_left_home_YourName') | as_datetime %}
          {% endif %}
          {% if last_changed < today_at() - timedelta(days=1) %}
            {{ as_timestamp(last_changed) | timestamp_custom('%d.%m. %H:%M') }}
          {% elif last_changed < today_at() %}
            {{ as_timestamp(last_changed) | timestamp_custom('Gest. %H:%M') }}
          {% else %}
            {{ as_timestamp(last_changed) | timestamp_custom('%H:%M')}}
          {% endif %}
        icon: |-
          {% if is_state('person.YourName','home') %}
            mdi:airplane-landing
          {% else %}
            mdi:airplane-takeoff
          {% endif %}
        icon_color: |-
          {% if is_state('person.YourName','home') %}
            green
          {% else %}
            red
          {% endif %}
        tap_action:
          action: none
      - type: template
        entity: sensor.tmp_person_distance_from_home_YourName
        content: >-
          {{- states('sensor.tmp_person_distance_from_home_YourName') -}} {{- " "
          -}} {{-
          state_attr('sensor.tmp_person_distance_from_home_YourName','unit_of_measurement')
          -}}
        icon: mdi:map-marker-distance
        icon_color: >-
          {% set km = states('sensor.tmp_person_distance_from_home_YourName') |
          int %} {% if km > 100 %} red {% elif km > 50 %} orange {% elif km > 10
          %} yellow {% elif km == 0 %} green {% else %} grey {% endif %}
        tap_action:
          action: more-info
  - type: custom:mushroom-template-card
    card_mod:
      style: |
        ha-card {
          --font-size: 0.5em;
          --icon-size: 5em;  
          --badge-icon-size: 1.15em;
          --badge-size: 1.15em;
          --spacing: none;
          --font-weight: normal;
        }
        mushroom-badge-icon {
          --icon-color: rgb(var(--rgb-card-background-color));
        }
    fill_container: true
    entity: person.YourName
    layout: vertical
    multiline_secondary: true
    picture: /local/pictures/EmojiYourName.png
    primary: '{{- states(''sensor.tmp_person_zonestatus_YourName'') -}}'
    secondary: >-
      {{- "LastSeen: " -}} {{- states('sensor.tmp_person_lastseen_YourName') -}}
      {{- "\n" -}} {{ states('sensor.tmp_person_lastseenlocation_YourName') -}}
    badge_icon: '{{- state_attr(''sensor.tmp_person_zonestatus_YourName'',''icon'') -}}'
    badge_color: |-
      {% if is_state('sensor.tmp_person_zonestatus_YourName','Home') %}
        green
      {% elif is_state('sensor.tmp_person_zonestatus_YourName','Unbekannt') %}
        red
      {% else %}
        orange
      {% endif %}
    tap_action:
      action: more-info
  - type: custom:mushroom-chips-card
    card_mod:
      style: |
        ha-card {
          --chip-font-size: 0.25em;
          --chip-icon-size: 0.5em;
          --chip-border-width: 0;
          --chip-box-shadow: none;
          --chip-background: none;
          --chip-border: none;
          --chip-spacing: none;
          --chip-font-weight: normal;
        }
    alignment: center
    chips:
      - type: template
        entity: sensor.iphonebattery_state
        content_info: none
        icon: |-
          {% if is_state('sensor.iphonebattery_state','Charging') %}
            mdi:power-plug
          {% else %}
            mdi:power-plug-off
          {% endif %}
        icon_color: |-
          {% if is_state('sensor.iphonebattery_state','Charging') %}
            green
          {% else %}
            grey
          {% endif %}
        tap_action:
          action: more-info
      - type: template
        entity: sensor.iphonebattery_level
        content_info: none
        icon: >-
          {% set bl = states('sensor.iphonebattery_level') | int %}
          {% if bl < 10 %} mdi:battery-outline {% elif bl < 20 %} mdi:battery-10
          {% elif bl < 30 %} mdi:battery-20 {% elif bl < 40 %} mdi:battery-30 {%
          elif bl < 50 %} mdi:battery-40 {% elif bl < 60 %} mdi:battery-50 {%
          elif bl < 70 %} mdi:battery-60 {% elif bl < 80 %} mdi:battery-70 {%
          elif bl < 90 %} mdi:battery-80 {% elif bl < 100 %} mdi:battery-90 {%
          elif bl == 100 %} mdi:battery {% else %} mdi:battery-unknown {% endif
          %}
        icon_color: >-
          {% set bl = states('sensor.iphonebattery_level') | int %}
          {% if bl < 10 %} red {% elif bl < 20 %} red {% elif bl < 30 %} orange
          {% elif bl < 40 %} orange {% elif bl < 50 %} yellow {% elif bl < 60 %}
          yellow {% elif bl < 70 %} green {% elif bl < 80 %} green {% elif bl <
          90 %} green {% elif bl < 100 %} green {% elif bl == 100 %} green {%
          else %} grey {% endif %}
        tap_action:
          action: more-info
      - type: template
        entity: sensor.tmp_person_homewlan_YourName
        content_info: none
        icon: |-
          {% if is_state('sensor.tmp_person_homewlan_YourName','on') %}
            mdi:wifi
          {% else %} 
            mdi:wifi-off
          {% endif %}
        icon_color: |-
          {% if is_state('sensor.tmp_person_homewlan_YourName','on') %}
            green
          {% else %} 
            grey
          {% endif %}
        tap_action:
          action: more-info

14 Likes

great can you share your :

{% set last_changed = states('sensor.tmp_person_time_arrived_home_YourName') | as_datetime %}
          {% else %}
            {% set last_changed = states('sensor.tmp_person_time_left_home_YourName

sensors please

1 Like

Can you please share your code for the weather above your ā€œGood Morning, Avi!ā€? :slight_smile:

Thanks!
Works great, but know i also want it for :

                      - type: "custom:mushroom-template-card"
                        primary: Washing Machine
                        entity: input_select.dishwasher_status
                        secondary: |-
                          {% if states(entity) == 'on' %}
                            {{ states('sensor.dishwasher_electric_consumption_w') | round(0) }} W
                          {% else %}
                            Off
                          {% endif %}
                        icon: mdi:dishwasher
                        icon_color: "{{ 'blue' if is_state(entity, 'On') else 'disabled' }}"
                        tap_action:
                          action: none
                        card_mod:
                          style:
                            mushroom-shape-icon$: |
                              state-badge {
                                {{ 'animation: bounce 1.5s ease-in-out infinite, wash 1s ease-in-out infinite;' if is_state('input_select.dishwasher_status', 'On') }}
                                transform-origin: 50% 75%;
                              }
                              @keyframes bounce {
                                0%, 20%, 50%, 80%, 100% {transform: translateY(0); } 
                                40% { transform: translateY(-1.2px) rotate(5deg); } 
                                60% { transform: translateY(-1.1px) rotate(-4deg); } 
                              } 
                              @keyframes wash {
                                50%  { clip-path: polygon(0 0, 0 100%, 35% 100%, 35% 75%, 35% 60%, 55% 42%, 60% 50%, 60% 70%, 30% 73%, 35% 100%, 100% 100%, 100% 0); }
                              }

its hard :confused:

@rhysb
Trial and error did the trick :slight_smile:
But how do i get the icon blue?

                            mushroom-shape-icon$: |
                              ha-icon {
                                {{ '--icon-animation: bounce 1.5s ease-in-out infinite, wash 1s ease-in-out infinite;' if is_state('input_select.dishwasher_status', 'On') }}
                                transform-origin: 50% 75%;
                              }
                              @keyframes bounce {
                                0%, 20%, 50%, 80%, 100% {transform: translateY(0); } 
                                40% { transform: translateY(-1.2px) rotate(5deg); } 
                                60% { transform: translateY(-1.1px) rotate(-4deg); } 
                              } 
                              @keyframes wash {
                                50%  { clip-path: polygon(0 0, 0 100%, 35% 100%, 35% 75%, 35% 60%, 55% 42%, 60% 50%, 60% 70%, 30% 73%, 35% 100%, 100% 100%, 100% 0); }
                              }
                              .: |
                              ha-card {
                                align-items: flex-end;
                                background: none;
                                --ha-card-box-shadow: 0px;
                              }
1 Like

Amazing tip. Added that in above and works like a charm!

Played with the original code to match my current nav. bar that was sitting at the top. Very useful for mobile. Fyi, All thatā€™s needed for the nav bar to be at the bottom aka sticky nav-bar is the last ā€˜card-modā€™ parameter I believe. Finished product and code below in case anyone wants it:

type: custom:vertical-stack-in-card
horizontal: true
cards:
  - type: custom:mushroom-chips-card
    alignment: center
    chips:
      - type: template
        entity: zone.home
        icon: mdi:home-account
        icon_color: orange
        content: Home
        tap_action:
          action: navigate
          navigation_path: home-view
      - type: template
        content: 'Living Room '
        icon: mdi:sofa-outline
        icon_color: blue
        entity: switch.lr_switch_group
        tap_action:
          action: navigate
          navigation_path: living_room-view
        hold_action:
          action: toggle
      - type: template
        entity: switch.kr_switch_group
        icon: mdi:table-chair
        content: Kitchen
        icon_color: green
        tap_action:
          action: navigate
          navigation_path: kitchen-view
        hold_action:
          action: toggle
      - type: template
        content: Bedroom
        tap_action:
          action: navigate
          navigation_path: bedroom-view
        icon_color: pink
        entity: switch.br_switch_group
        icon: mdi:bed-queen-outline
        hold_action:
          action: toggle
      - type: template
        entity: switch.bar_switch_group
        icon: mdi:bathtub-outline
        icon_color: yellow
        content: 'Bathroom '
        tap_action:
          action: navigate
          navigation_path: bathroom-view
        hold_action:
          action: toggle
      - type: template
        entity: light.lar_laundry_room
        icon: mdi:washing-machine
        icon_color: teal
        content: Laundry
        tap_action:
          action: navigate
          navigation_path: laundry-room
      - type: template
        icon: mdi:weather-sunny
        icon_color: purple
        tap_action:
          action: navigate
          navigation_path: porch-view
        content: Porch
        entity: switch.pr_switch_group
        hold_action:
          action: toggle
      - type: template
        icon: mdi:network-pos
        icon_color: orange
        content: Network
        tap_action:
          action: navigate
          navigation_path: /mushroom-creation/network
        entity: sensor.cr_cr_speedtest_download
card_mod:
  style: |
    :host {
      z-index: 999;
      position: sticky;
      position: -webkit-sticky;
      bottom: 0;
    }
    ha-card {
      background: none;
      --ha-card-box-shadow: 0px;
      padding-bottom: 25px;

    }
1 Like

sorry to ask if this is repeated, but wich sensor/integration generate this sensor?
tks!

These are great, was looking for this, suggestions on where to add them if you donā€™t want to do them on every single card? I know I could edit the theme but I use the Mushroom theme and so that will get overwritten with each update, and then if I copy it and make my own, I wonā€™t get theme updates like the one recently that fixed the border issueā€¦ I also donā€™t like how adding it to cards breaks the visual editor for changes and looking at settings

1 Like

Hi Andrea. What sensors ? Can you specify.

Can you use this with input_datetime maybe to achieve a resetable countdown to a date?

Home Assistant custom animated weather page.

  • animated gifs and icons that is dependable according to the weather conditions.
  • One page for all your weather needs.
  • 5 day weather forecast
  • ability to receive data from your own sensors including the pws.
  • Full dynamic structure.

Everything you need for the installation:

Note: icons and gifā€™s download details are also added in a zip file where you can download easily.

ezgif-3-8a11ed4948

2

9 Likes

Brilliant !

Iā€™ll echo the request of others: any chance of sharing your full config, please ?

2 Likes

Yes, It just depends how you want to reset the reminder.

Hereā€™s a simple one for 30 days. Hold runs a script to reset to 30 days from now.

Mushroom Reminder:

Mushroom Reminder

type: custom:mushroom-template-card
icon: mdi:timer
primary: Days to Reminder
icon_color: grey
secondary: >-
  {{ (states(entity) | as_datetime | as_local - now()).days + 1 }}
  days
hold_action:
  action: call-service
  service: script.reset_reminder
  data: {}
  target: {}
entity: input_datetime.reminder_date
card_mod:
  style:
    mushroom-shape-icon$: |
      .shape {
        background: radial-gradient(var(--card-background-color) 60%, transparent 0%), conic-gradient(rgb(var(--rgb-blue)) {{ ((states(config.entity) | as_datetime | as_local - now()).days + 1) / 30 * 100 }}% 0%, var(--card-background-color) 0% 100%);
      }
      .shape:after {
        content: "";
        height: 100%;
        width: 100%;
        position: absolute;
        border-radius: 50%;
        background: rgba(var(--rgb-{{ config.icon_color }}), 0.2);
      }

Reset Reminder Script:

alias: Reset Reminder
sequence:
  - service: input_datetime.set_datetime
    data:
      datetime: "{{ now() + timedelta(days=30) }}"
    target:
      entity_id: input_datetime.reminder_date
mode: single

And for the festive season :santa:

Mushroom Christmas Countdown:

Mushroom Days to Christmas

type: custom:mushroom-template-card
icon: mdi:pine-tree
primary: Days to Christmas
icon_color: green
secondary: >-
  {{ (states('input_datetime.christmas') | as_datetime | as_local - now()).days + 1 }} days
card_mod:
  style:
    mushroom-shape-icon$: |
      .shape {
        background: radial-gradient(var(--card-background-color) 60%, transparent 0%), conic-gradient(rgb(var(--rgb-red)) {{ ((states('input_datetime.christmas') | as_datetime | as_local - now()).days + 1) / 365 * 100 }}% 0%, var(--card-background-color) 0% 100%);
      }
      .shape:after {
        content: "";
        height: 100%;
        width: 100%;
        position: absolute;
        border-radius: 50%;
        background: rgba(var(--rgb-{{ config.icon_color }}), 0.2);
      }
29 Likes

Mushroom Animations :mushroom: - Part 5

Mushroom Chip Animations

Mushroom Chip Animated Scene

Chip Animated Scene
type: custom:mushroom-chips-card
chips:
  - type: template
    icon: mdi:mushroom
    icon_color: red
  - type: template
    icon: mdi:snail
    icon_color: brown
  - type: template
    icon: mdi:flower
    icon_color: amber
  - type: template
    icon: mdi:butterfly
    icon_color: cyan
card_mod:
  style:
    mushroom-template-chip:nth-child(1)$: |
      ha-icon {
        animation: bump 10s infinite;
        transform-origin: 50% 100%;
      }
      @keyframes bump {
        0% { transform: translateX(0); }
        1% { transform: translateX(-0.6px) rotate(-9deg); }
        2% { transform: translateX(0.5px) rotate(7deg); }
        3% { transform: translateX(-0.3px) rotate(-5deg); }
        4% { transform: translateX(0.2px) rotate(3deg); }
        5% { transform: translateX(0); }
      }
    mushroom-template-chip:nth-child(2)$: |
      ha-icon {
        animation: slip 0.5s linear infinite alternate;
        transform-origin: 100% 100%;
      }
      @keyframes slip {
        from { transform: scale(1.05, 0.9);}
        to { transform: scale(0.9, 1.05); }
      }
    mushroom-template-chip:nth-child(3)$: |
      ha-icon {
        animation: bump 10s infinite;
        transform-origin: 50% 100%;
      }
      @keyframes bump {
        50% { transform: translateX(0); }
        51% { transform: translateX(-0.6px) rotate(-9deg); }
        52% { transform: translateX(0.5px) rotate(7deg); }
        53% { transform: translateX(-0.3px) rotate(-5deg); }
        54% { transform: translateX(0.2px) rotate(3deg); }
        55% { transform: translateX(0); }
      }
    mushroom-template-chip:nth-child(4)$: |
      ha-icon {
        animation: flutter 5s infinite alternate;
      }
      @keyframes flutter {
        0% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg); }
        10% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg) scalex({{ range(3, 7) | random / 10 }}); }
        20% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg); }
        30% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg) scalex({{ range(3, 7) | random / 10 }}); }
        40% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg); }
        50% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg) scalex({{ range(3, 7) | random / 10 }}); }
        60% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg); }
        70% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg) scalex({{ range(3, 7) | random / 10 }}); }
        80% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg); }
        90% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg) scalex({{ range(3, 7) | random / 10 }}); }
        100% { transform: translate({{ range(-20, 20) | random / 10 }}px, {{ range(-20, 20) | random / 10 }}px) rotate({{ range(-15, 15) | random }}deg); }
      }
    .: |
      .chip-container {
        background: radial-gradient(circle, rgba(var(--rgb-light-blue), 0.1) 0%, transparent 100%);
        border-bottom: 3px dotted rgba(var(--rgb-green));
        border-radius: 20%;
        box-shadow: 0 5px 1px 0.1px rgba(var(--rgb-green), 0.2)
      }
      mushroom-template-chip:nth-child(2) {
        animation: slide 10s ease-in-out infinite;
      }
      @keyframes slide {
        0% { transform: translate(0px, 0px) rotateY(0deg); }
        50% { transform: translate(100px, 0px) rotateY(0deg); }
        50.1% { transform: translate(100px, 0px) rotateY(180deg); }
        100% { transform: translate(0px, 0px) rotateY(180deg); }
      }
      mushroom-template-chip:nth-child(3) {
          transform: translate(100px);
      }
      mushroom-template-chip:nth-child(4) {
          animation: by {{ range(5, 15) | random }}s ease infinite;
      }
      @keyframes by {
        0% { transform: translate(100px, 0px); }
        50% { transform: translate({{ range(110, 150) | random }}px, 0px); }
        100% { transform: translate(100px, 0px); }
      }

Adding Animations to Chips

Adding an animation to a Mushroom Chip is a bit more complicated than a normal Mushroom Card. You have the Chips ā€˜parentā€™ and multiple Chip ā€˜childrenā€™. The card_mod can be applied differently to each.

To the Chip

The simplest method is to add the card_mod to the Chip. The disadvantage of doing this is that we canā€™t address the icon directly, so animations such as clip-path will not work and we canā€™t have any text on the Chip. This method also breaks the GUI editor of the Chips, so you have to configure with YAML.

Chip Animation
type: custom:mushroom-chips-card
chips:
  - type: template
    icon: mdi:mushroom
    icon_color: red
    card_mod:
      style: |
        .content {
          animation: boing 3s ease infinite;
          transform-origin: 50% 90%;
        }
        @keyframes boing {
          0% { transform: scale3d(1, 1, 1); }
          7% { transform: scale3d(1.25, 0.75, 1); }
          10% { transform: scale3d(0.75, 1.25, 1); }
          12% { transform: scale3d(1.15, 0.85, 1); }
          16% { transform: scale3d(0.95, 1.05, 1); }
          19% { transform: scale3d(1.05, 0.95, 1); }
          25% { transform: scale3d(1, 1, 1); }
        }       
  - type: template
    icon: mdi:mushroom
    icon_color: red
    card_mod:
      style: |
        .content {
          animation: spin 3s ease 1.5s infinite;
        }
        @keyframes spin {
          100% { transform: rotate(360deg); }
        } 

To the Chips

The more complex but correct method is to add the card_mod to the Chips (parent) and then address each Chip (child). This is done by referencing the mushroom-<chip-type>-chip:nth-child(x) where x is the number of the Chip and <chip-type> is type of Chip, such as template, entity, light etc. So, if I wanted to reference the 5th Entity Chip I would use mushroom-entity-chip:nth-child(5) or the 2nd Template Chip mushroom-template-chip:nth-child(2). The functionality of the GUI editor is retained with this method.

Chips Animation
type: custom:mushroom-chips-card
chips:
  - type: template
    icon: mdi:mushroom
    icon_color: red
  - type: template
    content: Mushroom
    icon: mdi:mushroom
    icon_color: red
  - type: light
    entity: light.rocket_man
    icon: mdi:rocket-launch
    name: Rocket Man
    content_info: name
card_mod:
  style:
    mushroom-template-chip:nth-child(1)$: |
      ha-icon {
        animation: boing 3s ease infinite;
        transform-origin: 50% 90%;
      }
      @keyframes boing {
        0% { transform: scale3d(1, 1, 1); }
        7% { transform: scale3d(1.25, 0.75, 1); }
        10% { transform: scale3d(0.75, 1.25, 1); }
        12% { transform: scale3d(1.15, 0.85, 1); }
        16% { transform: scale3d(0.95, 1.05, 1); }
        19% { transform: scale3d(1.05, 0.95, 1); }
        25% { transform: scale3d(1, 1, 1); }
      }       
    mushroom-template-chip:nth-child(2)$: |
      ha-icon {
        animation: spin 3s ease 1.5s infinite;
      }
      @keyframes spin {
        100% { transform: rotate(360deg); }
      }       
    mushroom-light-chip:nth-child(3)$: |
      ha-icon {
        {{ 'animation: thrust 100ms infinite, motion 3s ease-in-out infinite;' if is_state('light.rocket_man', 'on') }}
      }
      @keyframes thrust {
        0% { clip-path: polygon(0 0, 0 47%, 22% 57%, 28% 63%, 0 91%, 11% 100%, 37% 73%, 45% 77%, 55% 100%, 100% 100%, 100% 0%); }
        33% { clip-path: polygon(0 0, 0 47%, 24% 59%, 42% 76%, 54% 100%, 100% 100%, 100% 0); }
        66% { clip-path: polygon(0 0, 0 92%, 28% 64%, 36% 72%, 9% 100%, 100% 100%, 100% 0%); }
      }
      @keyframes motion {
        0%, 100% { transform: translateY(-2px) translateX(-3px); }
        50% { transform: translateY(3px) translateX(2px); }
      }

Even More Mushroom Card Icon Animations

Mushroom Monitor Animation

Monitor Animation
type: custom:mushroom-template-card
icon: mdi:monitor
icon_color: purple
primary: Monitor
card_mod:
  style:
    mushroom-shape-icon$: |
      ha-icon:before {
        content: "";
        position: absolute;
        width: 40%;
        height: 30%;
        margin: 6%;
        animation: refresh 300ms linear infinite;
      }
      @keyframes refresh { 
        0% { background: linear-gradient(180deg, rgba(var(--rgb-{{ config.icon_color }}), 0.2) 0%, transparent 50%, transparent 100%); }
        25% { background: linear-gradient(180deg, transparent 0%, rgba(var(--rgb-{{ config.icon_color }}), 0.2) 25%, transparent 100%); }
        50% { background: linear-gradient(180deg, transparent 0%, rgba(var(--rgb-{{ config.icon_color }}), 0.2) 50%, transparent 100%); }
        75% { background: linear-gradient(180deg, transparent 0%, rgba(var(--rgb-{{ config.icon_color }}), 0.2) 75%, transparent 100%); }
        100% { background: linear-gradient(180deg, transparent 0%, transparent 50%, rgba(var(--rgb-{{ config.icon_color }}), 0.2) 100%); }
      }

Mushroom Email Animation

Email Animation
type: custom:stack-in-card
cards:
  - type: custom:mushroom-template-card
    icon: mdi:email
    icon_color: orange
    primary: Email
    card_mod:
      style:
        mushroom-shape-icon$: |
          ha-icon {
            --icon-animation: email 4s infinite;
          }
          @keyframes email {
            0%, 32%, 100% { opacity: 1; }
            33%, 99% { opacity: 0; }
          }
  - type: custom:mushroom-template-card
    icon: mdi:email-open
    icon_color: orange
    card_mod:
      style:
        mushroom-shape-icon$: |
          ha-icon {
            --icon-animation: email-open 4s infinite;
          }
          @keyframes email-open {
            0%, 32%, 100% { opacity: 0; }
            33%, 65% { opacity: 1; }
            66% { opacity: 0; }
          }
          .shape {
            --shape-color: none;
          }
        .: |
          ha-card {
            width: 66px;
            top: -66px;
          }
  - type: custom:mushroom-template-card
    icon: mdi:email-newsletter
    icon_color: orange
    card_mod:
      style:
        mushroom-shape-icon$: |
          ha-icon {
            --icon-animation: email-newsletter 4s infinite;
          }
          @keyframes email-newsletter {
            0%, 65% { opacity: 0; }
            66% { opacity: 1; }
          }
          .shape {
            --shape-color: none;
          }
        .: |
          ha-card {
            width: 66px;
            top: -132px;
          }
card_mod:
  style: |
    ha-card {
      height: 66px;
    }

Mushroom Email #2 Animation

Email #2 Animation
type: custom:stack-in-card
cards:
  - type: custom:mushroom-template-card
    icon: mdi:email
    icon_color: orange
    primary: 'Email #2'
    card_mod:
      style:
        mushroom-shape-icon$: |
          ha-icon {
            --icon-animation: email 2s infinite;
          }
          @keyframes email {
            0%, 49%, 100% { opacity: 1; }
            50%, 99% { opacity: 0; }
          }
  - type: custom:mushroom-template-card
    icon: mdi:email-open
    icon_color: orange
    card_mod:
      style:
        mushroom-shape-icon$: |
          ha-icon {
            --icon-animation: email-open 2s infinite;
          }
          @keyframes email-open {
            0%, 49%, 100% { opacity: 0; }
            50%, 99% { opacity: 1; }
          }
          .shape {
            --shape-color: none;
          }
        .: |
          ha-card {
            width: 66px;
            top: -66px;
          }
card_mod:
  style: |
    ha-card {
      height: 66px;
    }

Mushroom Christmas Tree #2 Animation

Christmas Tree #2 Animation
type: custom:stack-in-card
cards:
  - type: custom:mushroom-template-card
    icon: mdi:pine-tree
    icon_color: green
    primary: 'Christmas Tree #2'
  - type: custom:mushroom-template-card
    icon: mdi:star-four-points
    icon_color: yellow
    primary: Star
    card_mod:
      style:
        mushroom-shape-icon$: |
          ha-icon {
            --icon-animation: star 8s ease infinite alternate;
          }
          @keyframes star {
            0%, 100% { transform: translateY(-10px) rotate(0deg) scale(0.4); }
            50% { transform: translateY(-10px) rotate(360deg) scale(0.6); }
          }
          .shape {
            --shape-color: none;
          }
        .: |
          ha-card {
            width: 66px;
            top: -66px;
          }
  - type: custom:mushroom-template-card
    icon: mdi:grain
    icon_color: red
    card_mod:
      style:
        mushroom-shape-icon$: |
          ha-icon {
            --icon-animation: flash 2s steps(1) infinite, lights 2s infinite;
            clip-path: polygon(51% 15%, 24% 74%, 74% 74%);
          }
          @keyframes flash {
            50% { transform: rotateY(180deg); }
          }
          @keyframes lights {
            0%, 100% {--icon-color: rgb(var(--rgb-red)); }
            6.25% { --icon-color: rgb(var(--rgb-deep-orange)); }
            12.5% { --icon-color: rgb(var(--rgb-orange)); }
            18.75% { --icon-color: rgb(var(--rgb-amber)); }
            25% { --icon-color: rgb(var(--rgb-yellow)); }
            31.25% { --icon-color: rgb(var(--rgb-lime)); }
            37.5% { --icon-color: rgb(var(--rgb-light-green)); }
            43.75% { --icon-color: rgb(var(--rgb-green)); }
            50% { --icon-color: rgb(var(--rgb-teal)); }
            56.25% { --icon-color: rgb(var(--rgb-cyan)); }
            62.5% { --icon-color: rgb(var(--rgb-light-blue)); }
            68.75% { --icon-color: rgb(var(--rgb-blue)); }
            75% { --icon-color: rgb(var(--rgb-indigo)); }
            81.25% { --icon-color: rgb(var(--rgb-deep-purple)); }
            87.5% { --icon-color: rgb(var(--rgb-purple)); }
            93.75% { --icon-color: rgb(var(--rgb-pink)); }
          }
          .shape {
            --shape-color: none;
          }
        .: |
          ha-card {
            width: 66px;
            top: -132px;
          }
  - type: custom:mushroom-template-card
    icon: mdi:gift
    icon_color: red
    card_mod:
      style:
        mushroom-shape-icon$: |
          ha-icon {
            --icon-animation: surprise 4s ease infinite;
          }
          @keyframes surprise {
            0%, 20%, 100% { transform: translateY(0); }
            2.5% { transform: translateY(-2px) rotate(-27deg); }
            5% { transform: translateY(-2px) rotate(21deg); }
            7.5% { transform: translateY(-2px) rotate(-15deg); }
            10% { transform: translateY(-2px) rotate(9deg); }
            12.5% { transform: translateY(0); }
            15% { transform: translateY(-1.2px) }
          }
          .shape {
            --shape-color: none;
            --icon-size: 18px;
            top: 18px;
            left: 18px;
          }
        .: |
          ha-card {
            width: 66px;
            top: -198px;
          }
card_mod:
  style: |
    ha-card {
      height: 66px;
    }

Mushroom 3D Printing Animation

3D Printing Animation
type: custom:stack-in-card
cards:
  - type: custom:mushroom-template-card
    icon: mdi:printer-3d-nozzle
    icon_color: cyan
    primary: 3D Printing
    card_mod:
      style:
        mushroom-shape-icon$: |
          ha-icon {
            clip-path: inset(83% 72% 0 0);
          }
        .: |
          ha-card {
            --ha-card-border-width: 0;
          }
  - type: custom:mushroom-template-card
    icon: mdi:printer-3d-nozzle
    icon_color: cyan
    primary: ''
    card_mod:
      style:
        mushroom-shape-icon$: |
          ha-icon {
            --icon-animation: print 1s linear infinite alternate;
          }
          @keyframes print {
            0% { transform: translateX(4px); }
            30% { clip-path: polygon(0 0, 100% 0%, 100% 100%, 0 100%, 0 26%); }
            100% { transform: translateX(-4px); clip-path: polygon(0 0, 100% 0%, 100% 100%, 40% 100%, 0 26%); }
          }
          .shape {
            --shape-color: none;
          }
        .: |
          ha-card {
            width: 66px;
            top: -66px;
            --ha-card-border-width: 0;
          }
card_mod:
  style: |
    ha-card {
      height: 66px;
    }

Mushroom 3D Printer Animation

3D Printer Animation
type: custom:mushroom-template-card
primary: 3D Printer
icon: mdi:printer-3d
icon_color: light-blue
card_mod:
  style:
    mushroom-shape-icon$: |
      ha-icon {
        --icon-animation: print 2s infinite;
      }
      @keyframes print {
        0%, 100% { clip-path: polygon(0 0, 0 51%, 20% 51%, 51% 33%, 81% 53%, 100% 53%, 100% 0); }
        10% { clip-path: polygon(0 0, 0 100%, 49% 100%, 85% 83%, 49% 98%, 50% 89%, 51% 82%, 46% 79%, 36% 73%, 17% 82%, 20% 50%, 51% 33%, 81% 52%, 100% 52%, 100% 0); }
        20% { clip-path: polygon(0 0, 0 100%, 100% 100%, 85% 83%, 66% 73%, 56% 79%, 51% 83%, 46% 79%, 36% 73%, 17% 82%, 20% 50%, 51% 33%, 81% 52%, 100% 52%, 100% 0); }
        30% { clip-path: polygon(0 0, 0 100%, 100% 100%, 85% 83%, 66% 73%, 54% 69%, 50% 61%, 45% 69%, 36% 73%, 17% 82%, 20% 50%, 51% 33%, 81% 52%, 100% 52%, 100% 0); }
        40% { clip-path: polygon(0 0, 0 100%, 100% 100%, 85% 83%, 66% 73%, 54% 69%, 50% 61%, 45% 69%, 34% 63%, 25% 54%, 20% 50%, 51% 33%, 81% 52%, 100% 52%, 100% 0); }
        50% { clip-path: polygon(0 0, 0 100%, 100% 100%, 76% 51%, 66% 63%, 54% 69%, 50% 61%, 45% 69%, 34% 63%, 25% 54%, 20% 50%, 51% 33%, 81% 52%, 100% 52%, 100% 0); }
        60% { clip-path: polygon(0 0, 0 100%, 100% 100%, 76% 51%, 66% 63%, 55% 69%, 50% 61%, 39% 55%, 32% 55%, 25% 54%, 20% 50%, 51% 33%, 81% 52%, 100% 52%, 100% 0); }
        70% { clip-path: polygon(0 0, 0 100%, 100% 100%, 76% 51%, 68% 53%, 60% 55%, 50% 61%, 39% 55%, 32% 55%, 25% 54%, 20% 50%, 51% 33%, 81% 52%, 100% 52%, 100% 0); }
        80% { clip-path: polygon(0 0, 0 100%, 100% 100%, 76% 51%, 68% 53%, 60% 55%, 50% 61%, 50% 50%, 51% 37%, 31% 44%, 30% 35%, 51% 33%, 81% 52%, 100% 52%, 100% 0); }
        90% { clip-path: polygon(0 0, 0 100%, 100% 100%, 77% 51%, 67% 42%, 64% 34%, 56% 34%, 50% 36%, 39% 40%, 31% 44%, 30% 35%, 41% 33%, 85% 53%, 100% 52%, 100% 0); }
      }

Mushroom Auto Fix #2 Animation

Auto Fix #2 Animation
type: custom:mushroom-template-card
icon: mdi:auto-fix
icon_color: cyan
primary: 'Auto Fix #2'
card_mod:
  style:
    mushroom-shape-icon$: |
      ha-icon {
        --icon-animation: sparkle 2s linear infinite, kadabra 2s ease-in-out infinite;
       transform-origin: 10% 90%
      }
      @keyframes sparkle {
        0%, 68%, 100% { clip-path: polygon(0% 100%, 1% 75%, 56% 22%, 80% 43%, 26% 100%); }
        69%, 74%, 79%, 85% { clip-path: inset(0 0 0 0); }
        70% { clip-path: polygon(0 100%, 0 76%, 75% 0, 100% 0, 100% 100%); }
        75% { clip-path: polygon(0 100%, 0 0, 39% 0, 100% 62%, 100% 100%); }
        80% { clip-path: polygon(0 100%, 0 0, 100% 0, 100% 26%, 25% 100%); }
      } 
      @keyframes kadabra {
        0%, 65%, 100% { transform: rotate(-15deg); }
        70% { transform: rotate(20deg); }
        75% { transform: rotate(15deg); }
        80% { transform: rotate(25deg); }
      }

Mushroom Vroom Animation

Vroom Animation
type: custom:mushroom-template-card
icon: mdi:car-hatchback
icon_color: red
primary: Vroom
card_mod:
  style:
    mushroom-shape-icon$: |
      ha-icon {
        --icon-animation: vroom 2s ease-in-out infinite;
      }
      .shape {
        clip-path: inset(0 0 0 0);
      }
      @keyframes vroom {
        49% { opacity: 1;}
        50% { transform: translate(32px); opacity: 0; }
        51% { transform: translate(-32px); opacity: 0; }
        52% { opacity: 1; }
      }

Mushroom Double Garage Animation

Double Garage Animation
type: custom:mushroom-template-card
primary: Double Garage
icon: mdi:garage-variant
icon_color: amber
card_mod:
  style:
    mushroom-shape-icon$: |
      ha-icon {
        --icon-animation: door 3s steps(1) infinite alternate; 
      }
      @keyframes door {
        0% { clip-path: inset(0 0 0 0); }
        25%  { clip-path: polygon(0 0, 0 100%, 19% 100%, 19% 74%, 81% 74%, 81% 100%, 100% 100%, 100% 0); }
        50%  { clip-path: polygon(0 0, 0 100%, 19% 100%, 19% 60%, 81% 60%, 81% 100%, 100% 100%, 100% 0); }
        75% { clip-path: polygon(0 0, 0 100%, 19% 100%, 19% 48%, 81% 48%, 81% 100%, 100% 100%, 100% 0); }
      }

:point_right: Continued in Part 1, Part 2, Part 3 & Part 4

58 Likes

Iā€™ve added some instructions on adding the active animations to your theme.

I use a custom theme under the themes directory so that it doesnā€™t get overwritten when there is an update. The Mushroom Cards are designed to work without a theme file, so you are not missing anything by not using the Mushroom Theme. The Mushroom Themes just allow you to change the defaults if you want to have something different.

The card_mod in my examples does not break the GUI editor. If it is breaking for you, check that you have followed the examples correctly.

2 Likes