Custom card: Room Card

Did you check, if decluttering-card could be a solution to avoid duplicate code?

sorry… what’s that? another mod? :thinking:

I would not call it another mod, but in my case, it’s helping me a lot to avoid duplicate code.

Thanks I didn’t know it

Anyway I solved adding a card-mod theme, so with 1 yaml file I can easily modify all :wink: :+1:

link to the code šŸ”¹ Card-mod - Add css styles to any lovelace card - #8041 by crc-error79

Now I can start playing modding cards and adding other themes for mobile etc

Here a work-in-progress updated version

He all,

Does anyone have a room card that incorporates the simple thermostat card.

Would love some very simple like this.

And

This

In one card

Many thanks

hello , Would you be so kind if you can share the custom room card code?

Ciao, sure this is my theme (css)
you can find the instruction for the theme here: šŸ”¹ Card-mod - Add css styles to any lovelace card - #8041 by crc-error79

this is the code with last modifications

mercurio-theme:
  card-mod-theme: mercurio-theme
  card-mod-card: |
    ha-card.type-custom-room-card {

      /* varibili colore */
      /*
      --rp-card-ombra-testo: rgba(22, 22, 22, 0.2);
      --rp-content-main-entity-brd: rgba(22, 22, 22, 0.1);
      --rp-content-icon-box-entity-bg-luci-on: rgba(22, 22, 22, 0.2);
      --rp-content-icon-box-bg: rgba(22, 22, 22, 0.2);

      --rp-card-header-bg: rgba(212, 212, 212, 0.5);
      --rp-card-bottom-bg: rgba(212, 212, 212, 0.3);
      --rp-content-main-entity-bg: rgba(212, 212, 212, 0.1);
      --rp-content-main-entity-bg-luci-on: rgba(212, 212, 212, 0.5);
      --rp-content-main-entity-bg-antifurto-nok: rgba(212, 212, 212, 0.4);
      */

      /* colore fisso */
      --rp-content-icon-box-testo-luci-on: rgba(171, 145, 97, 1);
      --rp-card-bg: rgba(234, 238, 246, 0.1);
      --rp-content-main-testo: rgba(56, 56, 56, 1);
      --rp-content-icon-box-bg-luci-on: rgba(255, 212, 132, 1.0);
      --rp-content-main-ico-antifurto: rgba(190, 49, 68, 0.8);
      --rp-content-main-ico-bg: rgba(252, 252, 252, 0.9);
      --rp-content-main-ico-brd: rgba(212, 212, 212, 0.5);

      /* override */
      --mdc-icon-size: 100%;
      --state-light-inactive-color: rgba(158, 158, 158, 1);
      --state-switch-inactive-color: rgba(158, 158, 158, 1);

      /* inizio css */
      overflow: hidden;
      min-height: 222px;
      background-color: var(--rp-card-bg);
      display: flex;
      flex-direction: column;

      .card-header {
        /* text-shadow: 1px 1px 4px var(--rp-card-ombra-testo);  */
        padding: 4px 12px;
        margin: 0px;
        min-height: 52px;
        line-height: normal;
        background: var(--rp-card-header-bg);
        font-weight: 300;
        display: flex;
        flex-direction: row; 
        align-items: flex-start;
        position: relative; 

        .title {
          overflow-wrap: normal;
          word-break: normal;
          white-space: normal;
          opacity: 0.9;
          padding: 0px;
          display: flex;
          flex-direction: column;
          justify-content: center;
        }

        .entities-info-row {
          display: flex;
          top: 4px;
          right: 0px;
          position: relative;
          margin: 0px 0px 0 auto;
          padding: 0px;
          flex-direction: column;
          align-items: flex-end;

          .entity {
            font-size: 18px;
            opacity: 0.9;
            margin: 0px 0px 0 8px;
            padding: 0px;            
          }

          .icon-entity {
            width: 24px;
            height: 24px;
            background-color: var(--rp-content-main-ico-bg);
            border: 1px solid var(--rp-content-main-entity-brd);
            border-radius: 51%;
            display: flex;
            justify-content: center;
          }

          .icon-small {
            line-height: normal;
            max-height: 20px;
            color: var(--rp-content-main-ico-antifurto);
          }
        }
      }

      .content-main {
        margin: 10px 0px;
        padding: 0 20px 10px 20px;
        box-sizing: border-box;
        z-index: 1;

        .entity {
          background: var(--rp-content-main-entity-bg);
          border: 1px solid var(--rp-content-main-entity-brd);
          border-radius: 8px;
          min-width: 108px;
          margin: 10px 16px 0px 0;
          min-height: 80px;
          padding: 0px;
          box-sizing: border-box;

          span {
            margin: 4px 0 2px 0;
            display: inline-block;
            padding: 0px;
            font-size: 100%;
            overflow-wrap: normal;
            word-break: normal;
            white-space: normal;
          }

          div {
            padding: 4px;
            margin: 4px auto 8px auto;
            width: 60px;
            height: 60px;
            background-color: var(--rp-content-main-ico-bg);
            border-radius: 32px;
            border: 1px solid;
            border-color: var(--rp-content-main-ico-brd);
            display: flex;
            box-sizing: border-box;
            justify-content: center;

            .icon-small {
              height: auto;
              width: 32px;
              margin: auto;
              justify-content: center;
            }
          }
        }
      }

      .content-icon-box-bg {
        border-radius: 51%;
        height: 90px;
        width: 90px;
        margin: 0 -20px -28px 0;
        position: absolute;
        right: 0;
        bottom: 0;
        padding: 0px;
        z-index: 1;
        background-color: white;
      }

      .content-icon-box {
        background-size: 48% auto;
        border-radius: 51%;
        height: 90px;
        width: 90px;
        margin: 0 -20px -28px 0;
        position: absolute;
        right: 0;
        bottom: 0;
        padding: 0px;
        z-index: 1;
        background-color: var(--rp-content-icon-box-bg);
        background-repeat: no-repeat;
        background-position: center;

        /* luci accese */
        .entity {
          background-size: 48% auto;
          border-radius: 51%;
          width: 100%;
          height: 100%;
          margin: auto;
          padding: 0px;
          justify-content: center;
          background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 19A2.93 2.93 0 0 0 7.17 20H6A1 1 0 0 1 5 19V18H7M10 19A1 1 0 0 0 11 20H13A1 1 0 0 0 14 19V18H10M4 16A1 1 0 0 0 5 17H7V14.88A6.92 6.92 0 0 1 5 10A6.79 6.79 0 0 1 5.68 7A4 4 0 0 0 4 14.45M17 19A2.93 2.93 0 0 1 16.83 20H18A1 1 0 0 0 19 19V18H17M17 10A5 5 0 0 1 15 14V16A1 1 0 0 1 14 17H10A1 1 0 0 1 9 16V14A5 5 0 1 1 17 10M15 10A3 3 0 1 0 11 12.82V15H13V12.82A3 3 0 0 0 15 10M18.32 7A6.79 6.79 0 0 1 19 10A6.92 6.92 0 0 1 17 14.88V17H19A1 1 0 0 0 20 16V14.45A4 4 0 0 0 18.32 7Z" fill="rgba(45, 45, 45, 0.4)" /> </svg>');          
          background-color: var(--rp-content-icon-box-entity-bg-luci-on);
          background-repeat: no-repeat;
          background-position: center;

          span:first-child {
            margin: 0 0;
            padding: 0px;
            font-size: 0.92em;
            width: 100%;
            display: block;
            position: absolute;
            top: 24px;
            main: 0px;
          }

          span {
            margin: 6px 0 0 0;
            padding: 0px;
            font-size: 20px;
            display: block;
            width: 100%;
            color: var(--rp-content-icon-box-testo-luci-on);
          }
        }
      }

      .content-alarm-box {
        margin-top: auto;
        width: 100%;
        padding: 0px;
        z-index: 0;
        background-color: var(--rp-card-bottom-bg);
        min-height: 20px;

        .entity {
          width: 80px;
          margin: 0px;
          padding: 4px 0 2px 0;
          box-sizing: border-box;

          span {
            margin: 0px 4px;
            line-height: normal;
            display: inline-block;
            font-size: 95%;
            padding: 0px;
            overflow-wrap: normal;
            word-break: normal;
            white-space: normal;
          }

          div {
            padding: 0px;
            margin: 0px auto;
            width: 40px;
            height: 40px;
            background-color: var(--rp-content-main-ico-bg);
            border-radius: 22px;
            border: 1px solid;
            border-color: var(--rp-content-main-ico-brd);
            display: flex;
            box-sizing: border-box;
            justify-content: center;
            align-items: center;
          }

          .icon-small {
            width: 24px;
            height: 24px;
            line-height: normal;
            color: var(--rp-content-main-ico-antifurto);
          }
        }
      }
    } 

and this is the code for a card

type: custom:room-card
title: Cam. Roberto
icon: mdi:sofa-outline
show_icon: false
tap_action:
  action: navigate
  navigation_path: /dashboard-piano-primo/camera-roberto
card_mod:
  style: |
    ha-card {

      /* varibili colore */
      --rp-card-ombra-testo: rgba(22, 64, 77, 0.2);
      --rp-content-main-entity-brd: rgba(22, 64, 77, 0.1);
      --rp-content-icon-box-entity-bg-luci-on: rgba(22, 64, 77, 0.2);
      --rp-content-icon-box-bg: rgba(22, 64, 77, 0.2);

      --rp-card-header-bg: rgba(166, 205, 198, 0.5);
      --rp-card-bottom-bg: rgba(166, 205, 198, 0.3);
      --rp-content-main-entity-bg: rgba(166, 205, 198, 0.1);
      --rp-content-main-entity-bg-luci-on: rgba(166, 205, 198, 0.5);
      --rp-content-main-entity-bg-antifurto-nok: rgba(166, 205, 198, 0.5);

      .content-icon-box {
        background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 14C8.66 14 10 12.66 10 11C10 9.34 8.66 8 7 8C5.34 8 4 9.34 4 11C4 12.66 5.34 14 7 14M7 10C7.55 10 8 10.45 8 11C8 11.55 7.55 12 7 12C6.45 12 6 11.55 6 11C6 10.45 6.45 10 7 10M19 7H11V15H3V5H1V20H3V17H21V20H23V11C23 8.79 21.21 7 19 7M21 15H13V9H19C20.1 9 21 9.9 21 11Z" fill="rgba(22, 64, 77, 0.6)" /> </svg>');

        /* luci accese */
        /*
        .entity {
          background-image: url('data:image/svg+xml;utf-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 14C8.66 14 10 12.66 10 11C10 9.34 8.66 8 7 8C5.34 8 4 9.34 4 11C4 12.66 5.34 14 7 14M7 10C7.55 10 8 10.45 8 11C8 11.55 7.55 12 7 12C6.45 12 6 11.55 6 11C6 10.45 6.45 10 7 10M19 7H11V15H3V5H1V20H3V17H21V20H23V11C23 8.79 21.21 7 19 7M21 15H13V9H19C20.1 9 21 9.9 21 11Z" fill="rgba(45, 45, 45, 0.4)" /> </svg>');
        }  
        */
      }
    }
rows:
  - entities:
      - entity: null
        show_name: false
        show_icon: false
        show_state: false
    content_alignment: icon-box-bg
  - entities:
      - entity: sensor.luci_accese_camera_roberto
        show_name: false
        show_icon: false
        show_state: true
        styles:
          template: |
            if (entity.state > 0) 
              return 'background-color: var(--rp-content-icon-box-bg-luci-on)';
        hide_if:
          conditions:
            - condition: below
              value: 1
    content_alignment: icon-box
  - entities:
      - entity: light.hue_luce_comodino_camera_roberto
        show_icon: true
        state_color: true
        name: comodino
        tap_action:
          action: toggle
        hold_action:
          action: more-info
        styles:
          template: |
            if (entity.state == 'on') 
              return 'background-color: var(--rp-content-main-entity-bg-luci-on)';
      - entity: light.ikea_lampada_libreria_camera_roberto
        show_icon: true
        state_color: true
        name: libreria
        tap_action:
          action: toggle
        hold_action:
          action: more-info
        styles:
          template: |
            if (entity.state == 'on') 
              return 'background-color:  var(--rp-content-main-entity-bg-luci-on)';          
      - entity: light.hue_luce_televisione_camera_roberto
        show_icon: true
        state_color: true
        name: TV
        tap_action:
          action: toggle
        hold_action:
          action: more-info
        styles:
          template: |
            if (entity.state == 'on') 
              return 'background-color:  var(--rp-content-main-entity-bg-luci-on)';          
      - entity: light.hue_luce_letto_camera_roberto
        show_icon: true
        state_color: true
        name: letto
        tap_action:
          action: toggle
        hold_action:
          action: more-info
        styles:
          template: |
            if (entity.state == 'on') 
               return 'background-color:  var(--rp-content-main-entity-bg-luci-on)';          
      - entity: light.hue_luce_scrivania_studio
        show_icon: true
        state_color: true
        name: scrivania
        tap_action:
          action: toggle
        hold_action:
          action: more-info
        styles:
          template: |
            if (entity.state == 'on') 
              return 'background-color:  var(--rp-content-main-entity-bg-luci-on)';          
      - entity: light.scrivania_luci_tavolo
        show_icon: true
        state_color: true
        name: tavolo
        tap_action:
          action: toggle
        hold_action:
          action: more-info
        styles:
          template: |
            if (entity.state == 'on') 
              return 'background-color:  var(--rp-content-main-entity-bg-luci-on)';          
    content_alignment: main
  - entities:
      - entity: binary_sensor.konnected_8d4324_konnected_sec_2_zona_11
        name: porta finestra
        show_icon: true
        hide_if:
          conditions:
            - condition: equals
              value: "off"
        styles:
          template: |
            if (entity.state == 'on') 
              return 'background-color: var(--rp-content-main-entity-bg-antifurto-nok); --paper-item-icon-color: var(--rp-content-main-ico-antifurto);';
      - entity: binary_sensor.konnected_8d4324_konnected_sec_2_zona_07
        name: finestra bagno
        show_icon: true
        hide_if:
          conditions:
            - condition: equals
              value: "off"
        styles:
          template: |
            if (entity.state == 'on') 
              return 'background-color: var(--rp-content-main-entity-bg-antifurto-nok); --paper-item-icon-color: var(--rp-content-main-ico-antifurto);';
    content_alignment: alarm-box
info_entities:
  - entity: sensor.hue_motion_sensor_camera_roberto_temperature
    format: precision1
  - entity: binary_sensor.hue_motion_sensor_camera_roberto_occupancy
    show_icon: true
    hide_if:
      conditions:
        - condition: equals
          value: "off"

this is the result (I did some updates)

Hello, once i installed the card, i try to enter de code, but it says:
ā€œEditor visual no compatibleā€.
When i enter the code nothing happens, it appears white.
What can i do?

I fixed it! I erase the card, installed again and reset

Is there a way of making the Title: change colors depending on the state of the main entity of the card? I’ve tried using Conditions and was not successful and not even sure that’s how it’s done or if card_mod is needed? Any assistance is greatly appreciated.

type: custom:room-card
entity: switch.all_3rdreality_smartplugs
title: Smartplugs
show_icon: true
state_color: false
content_alignment: right
icon:
  template:
    styles: >
      if (entity.state == 'on') return 'color: darkorange'; else return 'color:
      rgb(255,165,0,15%)';
    icon: >
      if (entity.state == 'on') return 'mdi:connection'; else return
      'mdi:connection';
tap_action:
  action: none
  content_alignment: right
entities:
  - entity: switch.energizer_plug_1
    name: E1
    show_icon: true
    show_state: false
    tap_action:
      action: toggle
    styles:
      "--paper-item-icon-color": white;
    icon:
      template:
        styles: >
          if (entity.state == 'on') return 'color: darkorange'; else return
          'color: rgb(255,165,0,15%)';
  - entity: switch.energizer_plug_2
    name: E2
    show_icon: true
    show_state: false
    tap_action:
      action: toggle
    styles:
      "--paper-item-icon-color": white;
    icon:
      template:
        styles: >
          if (entity.state == 'on') return 'color: darkorange'; else return
          'color: rgb(255,165,0,15%)';

You need card mod for that. Conditions are only for the entities in the card. Not the title

Appreciate your reply! I love this card.
Do you happen to know where I’d put this within card_mod? I thought it would go under my ā€œ.titleā€ section but the ā€œdivā€ section is actually changing the color of the text?

div {
      padding: 3px;
      font-variant: small-caps;
      color: red;
    }
    .title{
      font-weight: bold;
      font-size: 23.5px;
      !border: 1px solid red;
      margin-top: -15px;
      margin-left: -22px !important;
      width: 275px;
      padding-left: 15px;
      --mdc-icon-size: 55px;
    }

You can check this with developer tools in your browser.

Im not near a pc atm so I thought I would tell you how to find out yourself :slight_smile:

I guess I’m not savvy enough to know how to obtain where/what that code should look like or go. Going to the development tools within the browser didn’t really help for me as I always struggled to get webhooks to work correctly. The Title styling when the main entity is on/off is the only missing piece for me. Any assistance is greatly appreciated.

card_mod:
  style: |
    .title {
    }

Should work. Never have been that great with card_mod tbh

Does anyone have any ideas how to add a glow to the icon? Or other creative solution

I can’t see the light icon when it has turned white.

When I apply my theme, it’s worse because the off colour for the theme is white as well.
Untitled2
Door Light and Fan are off; as a reference.

And to make it even worse, the light starts off as pure white when power is cut and then restored.

I tried out a box shadow but alas the svg canvas is significantly larger than the icon itself and the icon isn’t centered within it.
Untitled3

I’ve noticed that the background size does not match the icon as well. I would maybe try manually setting the color using conditions?

I’m trying to set a background image for the entire card depending on which media player is running.

Unfortunately, I can’t get it to work and need your help.

card_styles:
  template: >
    if (media_player.192_168_1_80 == 'playing') return 'background-image: url(${states["media_player.schlafen"].attributes.entity_picture})';
    else return 'background-image: url(some url to a picture)';

Of course, I’ve also made a few other unsuccessful attempts without a template, using {% if is_state or [[[ if (entity.state.

I only managed to do it with a fixed media player image:

type: custom:room-card
title: Schlafen
entity: no.entity
icon: mdi:sleep
show_icon: true
card_styles:
  background-image: >-
    url('/api/media_player_proxy/media_player.192_168_1_8?token=mYtOkEn')
  background-size: cover;
  background-position: right;
  background-repeat: no-repeat;

Is there a way to shrink the distance between an icon and its state in the entity row? I can’t seem to find the correct CSS style to do this.

I ended up figured it out.

card_mod:
  style: |
    .entities-row .entity .icon-small{
      height: 10px;
    }