Mushroom Cards - Build a beautiful dashboard easily 🍄 (Part 1)

Oh, that’s it. Thanks)

1 Like

Gave you a hint before :grinning_face_with_smiling_eyes:. Your tap_action is in the wrong place, you can’t have it on a condition. It needs to be on the card or chip of the conditional, like this:

      - type: conditional
        conditions:
          - entity: binary_sensor.wek_couch_prasenz
            state: 'on'
        chip:
          type: template
          icon_color: red
          tap_action:
            action: more-info
          card_mod:
            style: |
              ha-card {
                animation: blink 1s linear infinite;
              }
              @keyframes blink {
                50% {opacity: 0;}
              }  
          icon: mdi:motion-sensor

Looks Ok :thinking:. Is what you have not working?

in the screen, the background is set to white only to show what I’m looking for,
the conditional background (depending on aqi state) is not working for me

Oh, I see. You are using the Mushroom color names. CSS will only recognize the HTML color names, but these may be a bit different to the Mushroom ones.

You can use the Mushroom color names like this:

card_mod:
  style:
    mushroom-shape-icon$: |
      ha-icon {
        --icon-animation: molecule 2s ease-in-out infinite;
        transform-origin: 50% 75%;
      }
      @keyframes molecule {
        0%, 100% { transform: rotate(-15deg); }
        50% { transform: rotate(15deg); }
      }
    .: |
      ha-card { 
        background: rgba(var(--rgb-primary-text-color), 0.1);
        width: 80px;
        border-radius: 35px;
        margin-left: auto;
        margin-right: auto;
        margin-top: 4px;
        margin-bottom: -10px;
      }
      :host {
        --mush-icon-size: 60px;
      }

      ha-card:after {
        {% set background_color = states(config.entity) | int %}
        background: var(--
        {%- if background_color > 90 -%} 
          green
        {%- elif background_color > 60 -%}
          light-green
        {%- elif background_color > 50 -%}
          lime
        {%- elif background_color > 40 -%}
          yellow
        {%- elif background_color > 30 -%}
          amber
        {%- elif background_color > 20 -%}
          orange
        {%- elif background_color > 10 -%}
          deep-orange
        {%- else -%}
          red
        {%- endif -%}-color);

        content: "{{ states(config.entity) }}";
        position: absolute;
        display: flex;
        justify-content: center;
        align-items: center;
        color: var(--card-background-color);
        font-weight: bolder;
        border-radius: 50%;
        top: 5px;
        right: -1px;
        width: 26px;
        height: 26px;
        font-size: 15px; 
      }

Something to go with my Mushroom Welcome Card, a Mushroom Person Pop-up.

Mushroom Person Pop-up Card:

type: custom:mushroom-chips-card
chips:
  - type: entity
    entity: person.rhys
    content_info: none
    use_entity_picture: true
    tap_action:
      action: fire-dom-event
      browser_mod:
        service: browser_mod.popup
        data:
          title: Rhys
          content:
            type: vertical-stack
            cards:
              - type: custom:mushroom-entity-card
                entity: person.rhys
                layout: horizontal
                icon_type: entity-picture
                primary_info: state
                secondary_info: last-changed
                tap_action:
                  action: none
                hold_action:
                  action: none
                card_mod:
                  style:
                    mushroom-shape-avatar$: |
                      .picture {

                        /* Style shadow ring around person avatar */                              
                        box-shadow: 0px 0px 4px 2px var(--state-person);
                        margin-right: var(--mush-title-spacing, 12px);
                      }
                    .: |
                      ha-card {

                        /* Remove default card styling */
                        --ha-card-background: none;
                        box-shadow: none;
                        --ha-card-border-width: 0;

                        /* Increase icon size */
                        --icon-size: 72px;

                        /* Center card */
                        margin: auto;
                        width: fit-content;

                        /* Add padding to bottom of card */
                        padding: 0px 0px var(--mush-title-spacing, 12px) 0px !important;
                        
                        /* Make card non-responsive to select and pointer */
                        user-select: none;
                        pointer-events: none;
                        
                        transition: all 0s;
                      }
                      :host {

                        /* Define Person State colors. Can be added to theme */
                        --state-person-home: var(--green-color);
                        --state-person-not-home: var(--red-color);
                        --state-person-zone: var(--blue-color);
                        --state-person-unknown: var(--grey-color);

                        /* Set Person State color */
                        --state-person:
                        {% if is_state(config.entity, ['home', 'not_home', 'unknown']) %}
                          var(--state-person-{{ states(config.entity) | replace('_', '-') }})
                        {% else %}
                          var(--state-person-zone)
                        {% endif %};

                        /* Match styling to Mushroom Title */
                        --mush-card-primary-font-size: var(--mush-title-font-size, 24px);
                        --mush-card-primary-font-weight: var(--mush-title-font-weight, normal);
                        --mush-card-primary-line-height: var(--ush-title-line-height, 1.2);
                        --mush-card-secondary-font-size: var(--mush-title-font-size, 16px);
                        --mush-card-secondary-font-weight: var(--mush-title-font-weight, normal);
                        --mush-card-secondary-line-height: var(--ush-title-line-height, 1.2);
                      }
              - type: history-graph
                entities:
                  - entity: person.rhys
                    name: ' '
                hours_to_show: 24
                title: Timeline
                card_mod:
                  style:
                    $: |
                      .card-header {

                        /* Style timeline title */
                        padding: 0px 24px !important;
                        font-size: var(--mush-card-primary-font-size, 14px) !important;
                        font-weight: var(--mush-card-primary-font-weight, bold) !important;
                        line-height: var(--mush-card-primary-line-height, 1.5) !important;
                        color: var(--primary-text-color) !important;
                      }
                    .: |
                      ha-card {

                        /* Remove default card styling */
                        --ha-card-box-shadow: none;
                        --ha-card-background: none;
                        --ha-card-border-width: 0;
                        user-select: none;
                      }
                      .content {

                        /* Add padding on right */
                        padding: 0px 24px !important;
                      }
                # Hide if distance to home is 0. 
              - type: horizontal-stack
                cards:
                  - type: conditional
                    conditions:
                      - entity: sensor.rhys_travel_time_to_home
                        state_not: '0'
                    card:
                      type: custom:mushroom-template-card
                      primary: >-
                        {{ states(entity) }} {{ state_attr(entity,
                        'unit_of_measurement') }}
                      secondary: >-
                        {{ state_attr(entity, 'distance') | round(1) }}
                        km
                      icon: mdi:map-marker-path
                      entity: sensor.rhys_travel_time_to_home
                      layout: vertical
                      icon_color: purple
                      tap_action:
                        action: none
                      hold_action:
                        action: none
                      double_tap_action:
                        action: none
                      card_mod:
                        style:
                          mushroom-state-info$: |
                            .primary:after {

                              /* Add destination details */
                              content: "\Ato Home";
                              white-space: pre;
                              text-overflow: ellipsis;
                            }
                          .: |
                            ha-card {

                              /* Remove default card styling */
                              --ha-card-background: none;
                              --ha-card-box-shadow: none;
                              --ha-card-border-width: 0;

                              /* Center card on row */
                              width: fit-content;
                              margin: auto;

                              /* Make card non-responsive to select and pointer */
                              user-select: none;
                              pointer-events: none;
                            }
                # Hide if distance to work is 0.
              - type: horizontal-stack
                cards:
                  - type: conditional
                    conditions:
                      - entity: sensor.rhys_travel_time_to_work
                        state_not: '0'
                    card:
                      type: custom:mushroom-template-card
                      primary: >-
                        {{ states(entity) }} {{ state_attr(entity,
                        'unit_of_measurement') }}
                      secondary: >-
                        {{ state_attr(entity, 'distance') | round(1) }}
                        km
                      icon: mdi:map-marker-path
                      entity: sensor.rhys_travel_time_to_work
                      layout: vertical
                      icon_color: purple
                      tap_action:
                        action: none
                      hold_action:
                        action: none
                      double_tap_action:
                        action: none
                      card_mod:
                        style:
                          mushroom-state-info$: |
                            .primary:after {

                              /* Add destination details */
                              content: "\Ato Work";
                              white-space: pre;
                              text-overflow: ellipsis;
                            }
                          .: |
                            ha-card {

                              /* Remove default card styling */
                              --ha-card-background: none;
                              --ha-card-box-shadow: none;
                              --ha-card-border-width: 0;

                              /* Center card on row */
                              width: fit-content;
                              margin: auto;

                              /* Make card non-responsive to select and pointer */
                              user-select: none;
                              pointer-events: none;
                            }
                  - type: custom:mushroom-template-card
                    primary: '{{ states(entity) }}%'
                    secondary: >
                      {{ 'charging' if
                      is_state('binary_sensor.rhys_phone_is_charging',
                      'on' ) else 'discharging' }}
                    icon: >
                      {% set battery_level = (states(entity) | int / 10)
                      | round(0) | int * 10 %}

                      {% if battery_level == 100 %}
                        mdi:battery
                      {% elif battery_level > 0 %}
                        mdi:battery-{{ battery_level }}
                      {% else %}
                        mdi:battery-alert-variant-outline
                      {% endif %}
                    icon_color: |-
                      {% set battery_level = states(entity) | int %}
                      {% if battery_level > 90 %} 
                        green
                      {% elif battery_level > 60 %}
                        light-green
                      {% elif battery_level > 50 %}
                        lime
                      {% elif battery_level > 40 %}
                        yellow
                      {% elif battery_level > 30 %}
                        amber
                      {% elif battery_level > 20 %}
                        orange
                      {% elif battery_level > 10 %}
                        deep-orange
                      {% else %}
                        red
                      {% endif %} 
                    entity: sensor.rhys_phone_battery_level
                    layout: vertical
                    badge_icon: >-
                      {% if
                      is_state('binary_sensor.rhys_phone_is_charging',
                      'on') %}
                        mdi:lightning-bolt
                      {% elif states(entity) | int < 10 %} 
                        mdi:exclamation-thick
                      {% endif %}
                    badge_color: >-
                      {{ 'red' if states(entity) | int < 10 else
                      'light-blue' }}
                    tap_action:
                      action: none
                    hold_action:
                      action: none
                    double_tap_action:
                      action: none
                    card_mod:
                      style:
                        mushroom-shape-icon$: |
                          .shape {

                            /* Radial progress bar */
                            background: radial-gradient(var(--card-background-color) 60%, 
                                                        transparent calc(60% + 1px)), 
                                        conic-gradient(var(--icon-color) {{ states(config.entity) }}% 0%, 
                                                        var(--card-background-color) 0% 100%);
                          }
                          .shape:after {

                            /* Add back icon shape */
                            content: "";
                            height: 100%;
                            width: 100%;
                            position: absolute;
                            border-radius: var(--icon-border-radius);
                            background: var(--shape-color);
                          }
                          ha-icon {

                            /* Icon charging animation */
                            {{ '--icon-animation: charge 3s linear infinite;' if is_state('binary_sensor.rhys_phone_is_charging', 'on') }}
                          }
                          @keyframes charge {
                            0%, 80% { clip-path: inset(0 0 0 0); }
                            10% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 84%, 34% 84%, 34% 100%, 100% 100%, 100% 0%); }
                            20% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 74%, 34% 74%, 34% 100%, 100% 100%, 100% 0%); }
                            30% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 64%, 34% 64%, 34% 100%, 100% 100%, 100% 0%); }
                            40% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 54%, 34% 54%, 34% 100%, 100% 100%, 100% 0%); }
                            50% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 44%, 34% 44%, 34% 100%, 100% 100%, 100% 0%); }
                            60% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 34%, 34% 34%, 34% 100%, 100% 100%, 100% 0%); }
                            70% { clip-path: polygon(0% 0%, 0% 100%, 34% 100%, 34% 24%, 67% 24%, 67% 24%, 34% 24%, 34% 100%, 100% 100%, 100% 0%); }
                          }
                        .: |
                          ha-card {

                            /* Remove default card styling */
                            --ha-card-background: none;
                            --ha-card-box-shadow: none;
                            --ha-card-border-width: 0;

                            /* Center card on row */
                            width: fit-content;
                            margin: auto;

                            /* Make card non-responsive to select and pointer */
                            user-select: none;
                            pointer-events: none;
                          }
                    # Hide if not connected to WiFi.
                  - type: conditional
                    conditions:
                      - entity: sensor.rhys_phone_wifi_connection
                        state_not: <not connected>
                    card:
                      type: custom:mushroom-template-card
                      primary: >-
                        {{ states('sensor.rhys_phone_wifi_connection')
                        }}
                      secondary: >-
                        {% set signal_level = states(entity) | int %} {%
                        if signal_level != -1 %} 
                          {{ signal_level }} dBm
                        {% endif %}
                      icon: >-
                        {% set signal_level = states(entity) | int | abs
                        %} {% if signal_level > 90 %} 
                          mdi:wifi-strength-outline
                        {% elif signal_level > 80 %} 
                          mdi:wifi-strength-1
                        {% elif signal_level > 70 %}
                          mdi:wifi-strength-2
                        {% elif signal_level > 60 %}
                          mdi:wifi-strength-3
                        {% elif signal_level > 1 %}
                          mdi:wifi-strength-4
                        {% else %}
                          mdi:wifi-strength-off
                        {% endif %}
                      entity: sensor.rhys_phone_wifi_signal_strength
                      layout: vertical
                      fill_container: false
                      icon_color: cyan
                      tap_action:
                        action: none
                      hold_action:
                        action: none
                      double_tap_action:
                        action: none
                      card_mod:
                        style: |
                          ha-card {

                            /* Remove default card styling */
                            --ha-card-background: none;
                            --ha-card-box-shadow: none;
                            --ha-card-border-width: 0;

                            /* Center card on row */
                            width: fit-content;
                            margin: auto;

                            /* Make card non-responsive to select and pointer */
                            user-select: none;
                            pointer-events: none;
                          }
              - type: custom:mushroom-chips-card
                chips:
                  - type: template
                    tap_action:
                      action: none;
                    hold_action:
                      action: call-service
                      service: notify.mobile_app_rhys_phone
                      data:
                        message: Ringing phone...
                        title: Find Phone
                        data:
                          ttl: 0
                          importance: high
                          priority: high
                          tag: Find
                          channel: alarm_stream
                    icon: mdi:target
                    icon_color: red
                    content: Find Phone
                alignment: center
                card_mod:
                  style: |
                    ha-card {

                      /* Style Chip like Mushroom button */
                      --chip-background: rgba(var(--rgb-red), 0.2);
                      --chip-border-radius: var(--mush-control-border-radius, 12px);
                      --chip-height: var(--mush-control-height, 42px);
                      --chip-box-shadow: none;
                      user-select: none;
                    }
                    ha-card:active {

                      /* Add effect to give feedback on button press */
                      --chip-background: rgba(var(--rgb-red), 0.4);
                    }
              - type: map
                entities:
                  - entity: person.rhys
                dark_mode: false
                hours_to_show: 24
                aspect_ratio: '4:3'
                card_mod:
                  style:
                    ha-map $ ha-entity-marker $: |
                      .marker {

                        /* Style person marker & adjust position to avoid blocking waypoints */
                        border: 3px solid var(--state-person) !important;
                        border-radius: 50% 50% 50% 0px !important;
                        transform: rotate(-45deg) translate(50%, -50%);
                        overflow: visible !important;
                        background: var(--state-person) !important;
                      }
                      .entity-picture {

                        /* Correct orientation of person avatar */
                        transform: rotate(45deg);
                        border-radius: 50%;
                      }
                    ha-map $: |
                      path:first-child { 

                        /* Style accuracy radius */
                        stroke: var(--state-person);
                        fill: color-mix(in srgb, var(--state-person) 50%, transparent);
                        stroke-width: 0px;
                      }
                      path:nth-child(even) {

                        /* Styling for waypoints */
                        stroke: var(--purple-color);
                        stroke-width: 4px;
                      }
                      path:nth-child(odd):not(:first-child) { 

                        /* Styling for lines */
                        stroke: var(--purple-color);
                        stroke-width: 4px;
                      }

                      .leaflet-control-attribution {

                        /* Style attribution text */
                        background: rgba(var(--rgb-card-background-color), 0.4) !important;
                        font-size: 10px;
                      }
                      .leaflet-container a {

                        /* Set color of zoom icons & attribution text */
                        color: var(--secondary-text-color);
                      }

                      .leaflet-control-zoom-in,
                      .leaflet-control-zoom-out {

                        /* Style zoom buttons like Chips */
                        border-radius: var(--mush-chip-border-radius, 19px) !important;
                        padding: 3px;
                        background: rgb(var(--rgb-secondary-text-color), 0.2) !important;
                        margin: 8px 12px 0px;
                        border: var(--ha-card-border-width, 1px) solid var(--ha-card-border-color, var(--divider-color, #e0e0e0)) !important;
                      } 
                      .leaflet-top {

                        /* Move zoom buttons to bottom of map */
                        bottom: 0px !important;
                      }
                      .leaflet-control-zoom {

                        /* Allow buttons to be moved */
                        position: absolute !important;

                        /* Adjust spacing for border */
                        bottom: calc(2 * var(--ha-card-border-width, 1px) + 56px);
                        
                        /* Remove extra margin */
                        margin: 0px !important;

                        /* Remove zoom control border */
                        border: none !important;
                      }
                      .leaflet-container:after {

                        /* Fade out map at top */
                        content: "";
                        position: absolute;
                        height: 100%;
                        width: 100%;
                        background: linear-gradient(to top, transparent 65%, var(--card-background-color));
                      }
                    ha-icon-button $ mwc-icon-button $: |
                      button {

                        /* Size center button to match Chip */
                        height: var(--mush-chip-height, 36px) !important;
                        width: var(--mush-chip-height, 36px) !important;
                        --mdc-icon-size: 22px;
                      }
                    .: |
                      ha-card {

                        /* Remove default card styling without affecting child elements */
                        box-shadow: none;
                        border-width: 0;
                        border-radius: 0px 0px var(--ha-card-border-radius, 12px) var(--ha-card-border-radius, 12px);
                        
                        transition: all 0s;
                      }
                      :host {

                        /* Define Person State colors. Can be added to theme */
                        --state-person-home: var(--green-color);
                        --state-person-not-home: var(--red-color);
                        --state-person-zone: var(--blue-color);
                        --state-person-unknown: var(--grey-color);

                        /* Set person state color */
                        --state-person:
                        {% if is_state(config.entities[0].entity, ['home', 'not_home', 'unknown']) %}
                          var(--state-person-{{ states(config.entities[0].entity) | replace('_', '-') }})
                        {% else %}
                          var(--state-person-zone)
                        {% endif %};
                      }
                      ha-icon-button {

                        /* Position center button */
                        bottom: 12px;
                        left: 12px !important;
                        top: auto !important;

                        /* Style center button to match Chip */
                        color: var(--deep-orange-color) !important;
                        background: color-mix(in srgb, var(--deep-orange-color) 20%, transparent);
                        border-radius: var(--mush-chip-border-radius, 19px);
                        border: var(--ha-card-border-width, 1px) solid var(--ha-card-border-color, var(--divider-color, #e0e0e0)) !important;
                      }
          card_mod:
            style: |
              :host {

                /* Remove border from poup */
                --popup-padding-x: 0px;
                --popup-padding-y: 0px;
                --popup-min-width: 450px;
              }
              .content {

                /* Remove extra bottom border */
                margin: -18px -24px -24px !important;
              }
    card_mod:
      style: |

        /* Color border around avatar to show person status */
        ha-card {
          --chip-background:
          {% if is_state(config.entity, ['home', 'not_home', 'unknown']) %}
            rgb(var(--rgb-state-person-{{ states(config.entity) | replace('_', '-') }} ))
          {% else %}
            rgb(var(--rgb-state-person-zone))
          {% endif %};
        } 

        /* Slightly enlarge & bring to front on hover */
        ha-card:hover {
          transform: scale(1.2);
          transform-origin: top center;
          z-index: 1;
          transition: all 1s;
        }

62 Likes

wow that looks fantastic! I have person cards on my dash, so I will try and use your code. Keep up the great work you do. – thank you

1 Like

thanks for your reply, I am only just getting started and I do just copy other peoples code.
at what point in my code should I copy it too? I have tried using it next to the icon: field, that didnt work, Does it require its own line with a prefix before? Any other help you are able to give would be appeciated.
edit . after the | you have “iif” is this correct or should it be “if”

It goes into the icon: field where you currently have mdi:lock. You’ll need to put it in quotes or paste it in the Visual Editor and it will do that for you.

iif is an alternate way of doing an if statement.

2 Likes

very nicely made & I just have a question how did you make this sensor?

1 Like

Waze integration.

1 Like

ok thanks how did you do the departure point is this from your work to home or from where you are at the moment ?

It’s from wherever I currently am and hides when I’m home.

Origin: person.rhys
Destination: zone.home

1 Like

Wow, much cleaner for sure! I tried to add some logic around the icon but it doesn’t seem to like it though, just shows no icon? Same for icon color too.

    type: custom:mushroom-entity-card
    entity: binary_sensor.hall_motion_sensor_occupancy
    secondary_info: last-updated
    name: Hall Motion
    icon: |-
      {% if is_state("binary_sensor.hall_motion_sensor_occupancy", 'off') %}
        mdi:motion-sensor-off
      {% elif is_state("binary_sensor.hall_motion_sensor_occupancy", 'on') %}   
        mdi:motion-sensor
      {% endif %}
    card_mod:
      style:
        mushroom-state-info$: |
          .secondary:before {
            content: "{{ 'Detected' if is_state(config.entity, 'on') else 'Clear' }} / ";
          }
1 Like

No, it’s an entity card so you can’t template it. The Icon should automatically change with motion already. Same for color. Are you wanting to do something different?

thanks man

1 Like

Sorry I missed that you’d changed it to an entity card. I see the icon and colour changes anyway. The idea I had was it would be green when clear and red when detected. The icon is actually fine the way it is.

That’s easy enough:

type: custom:mushroom-entity-card
entity: binary_sensor.lounge_motion_occupancy
secondary_info: last-updated
name: Lounge Motion
icon_color: red
card_mod:
  style:
    mushroom-state-info$: |
      .secondary:before {
        content: "{{ 'detected' if is_state(config.entity, 'on') else 'clear' }} / ";
      }
    .: |
      :host {
        --mush-rgb-disabled: var(--rgb-green);
      }
3 Likes

Could be possible to use something similar to decluttering card with this?

The code is repetitive for every person that you wanted to be added.

Yes, should work fine.