Neon Lovelace UI & Theme for tablets

So in my popup is a picture element with button cards & a few graphs, and that blur / background is achieved by styling the button card underneath the collection of elements with a backdrop filter:

- type: custom:button-card
  style:
    top: 0px
    left: 0px
    transform: translate(0%, 0%)
  tap_action:
    action: none
  styles:
    card:
      - box-shadow: none
      - background-color: rgba(175, 191, 223, 0.25)
      - border-radius: 10px
      - height: 648px
      - width: 1152px
      - backdrop-filter: blur(20px)
      - '-webkit-backdrop-filter': blur(20px)

Hope that helps :v::sunglasses:

1 Like

Hi @nfs I really like your spotify media player layout. Love the way that is really orderly.

2 questions.

Box.png is a picture element. Can you share that file oo how it is created?

Maybe its possible to share a little bit more code. So it is better to make a bigger picture.

Thanks in advance.

The box.png is just a transparent image file, you can generally use whatever size (e.g. make it 1x1 pixels), I just created it in a free image manipulation tool. There are several other button cards nested in there as well inside the picture element for the Playlist labels, the icons above the grid, etc.

There’s a pastebin link in one of my posts above which has an example of a smaller spotify player, which works the same way (three spotify cards inside a swipe card).

Here’s how I have the larger spotify card inside the picture element:

- type: picture-elements
  image: /local/box.png
  elements:
    - type: custom:spotify-card
      style:
        top: 38px
        left: 0px
        transform: translate(0%, 0%)
      spotify_entity: media_player.spotify_neal
      default_device: Office Mini
      playlist_type: default
      account: default
      always_play_random_song: true
      shuffle: true
      hide_top_header: true
      hide_currently_playing: true
      hide_connect_devices: true
      hide_warning: true
      display_style: grid
      limit: 12
      grid_covers_per_row: '4'
      card_mod:
        style: |
          ha-card {
            background: transparent;
            padding: 2px 0px 0px !important;
            width: 710px;
            overflow: visible !important;
          }
          #content {
            border: 0px !important;
            background-color: transparent !important;
            padding: 0px !important;
            overflow: visible !important;
          }
          #footer > div.footer__right {
            display: none !important;
          }
          #footer > div.dropdown-wrapper > div.controls > div {
            height: 28px;
            width: 28px;
          }
          #footer > div.dropdown-wrapper > div.controls > div > div {
            display: none;
          }
          .grid-item {
            border-radius: 10px;
            box-shadow: 2px 3px 15px -3px rgba(0, 0, 0, 0.3) !important;
            transition-duration: 0.25s;
          } 
          .grid-item-album-image.playing {
            border-radius: 10px !important;
            box-shadow: 0px 0px 20px rgba(175, 191, 223, 1) !important;
          }
          .grid-item:hover {
            box-shadow: 0px 0px 17px #afbfdf !important;
            transition-duration: 0.5s;
          } 
          .grid-item-album-image > img {
            border-radius: 10px;
          }
          .dropdown {
            border-radius: 10px !important;
            max-height: none !important;
            box-shadow: none !important;
          } 
          .dropdown-content.dropdown > p {
            font-weight: 300;    
            color: #afbfdf;
          } 
          .dropdown-content.dropdown > a {
            font-weight: 300;
            border-radius: 10px;
          } 
          .dropdown-content.dropdown > a:hover {  
            background: #41445f;
          }

Hi @nfs, I love you Spotify dashboard. Can you please share the entire code.

Thanks

1 Like

Trying to get this setup, but only a few weeks into HA. Do you drop this into config.yaml or under themes or elsewhere and call it from config.yaml?

This looks great. Are you able to share your lovelace code? A little more in-line with what I’m looking to do than the original and I’m still pretty fresh to card mod and CSS and trying to muddle my way into something lol.

@Turbo4door @limestar,

Sorry, after a while I changed to another dashboard. Don’t have the code anymore.
I know I fixed it with a lot of changing in the CSS, so thats the only way to go I guess.

Is there a chance to get your code?

@danieljarhult have you had any issues with your spotify player with state switch lately?
I don’t get the spotify custom card with playlists anymore, not 100% but seems to coincide with latest updates of either HA/spotcast/spotify card, I have the latest so the card works on other dashboards without all the fancy stuff
 If I enter the dashboard when something is already playing and then pause it will flip to the card, but if I enter the dashboard when idle, it won’t.

Hello, I have not updated HA for a while so i am not having any problems right now. In the past i know that the flip animation in the state switch has caused some problems, so first try to disable that and see if it helps. Otherwise my suggestion would be to just skip the whole flip thing because there is also album art in the “more music” + button.

Curious if you found a solution to this issue, I’m experiencing the exact same. Strange thing is if I copy the card to a new view it works without issue.

Loving the dashboard, learned a lot from it.
I too are having problems with the media card, removing the transition didn’t help. I’ve now edited it too also showing when Plex is playing, nested 3 conditional cards inside a horizontal stack. Now it works again.

Can you explain how I can edit the width of a popup card. I can adjust the height, but cannot edit the width
 so now every popup I use is either edited from the home/person popup, of from the light popup card you use

Thanks

Glad you like it ! To make a popup larger you can add “large:true” when calling browser_mod.

          browser_mod:
            command: popup
            large: true

But you already know that :slight_smile: Browser mod only has two modes for this i think.

You can try to mess around in the theme file. maybe if you add “width” it will work, i have not tried it myself so i am not shur
 but if it works i think it will make all popups 500 px in width :

      .mdc-dialog .mdc-dialog__container .mdc-dialog__surface {
        box-shadow: none !important;
        background: none;
        width: 500px;
        border-radius: var(--ha-card-border-radius);

thanks for your reply. I figured it out. If you change large to true, you can use width under styles > card to make it smaller. If large is false, you can’t make it bigger without scrollbar. Then when you adjust the width, the popup isn’t centered. You can correct this using left or right under card settings. Only when you want to close the popup, hitboxes are off. Now I use ‘auto_close : true’ to correct this.

(edit) nevermind: auto close is usefull for popup with information. not with buttons
(edit2) : using below works better

    style:
      .: |
        :host .content {
          align: center !important;

         } 
      $: |
        .mdc-dialog .mdc-dialog__container .mdc-dialog__surface {

          width: 800px;
        } 
1 Like

Nice find :beers:

Thank you for helping so far! I really made progress

We hope you have time soon lol 


Is it possible to get the code of the tablet?

wow, I find your work fantastic. Could you share your full code?

2 Likes

Hi there

Maybe someone can point me in the right direction.
I dont get managed transparent popups with the new browser_mod: option.
It seems, the popup always uses the color defined in my UserProfile.

Is there a Problem in the neon.yaml or in the lovelace config?

Any help is really appreciated

2 Likes

As I’m not in Sweden, is there a way to use a different Weather for this?

@cyberphox
You have to do the translation to your prefered language manually by your own.
Imo this is not that much work to do.
Below there is a german and english translated card if this helps for you. Or are you talking about something different?

German

type: custom:button-card
entity: weather.openweathermap
view_layout:
  grid-area: weather
entity_picture: /local/images/weather/clear-night.svg
show_entity_picture: true
tap_action:
  action: fire-dom-event
  browser_mod:
    command: popup
    title: Wetter
    hide_header: true
    card:
      type: custom:button-card
      name: Wetter
      tap_action:
        action: navigate
        navigation_path: '#empty'
      entity_picture: /local/images/weather/cloudy.png
      entity: weather.openweathermap
      show_entity_picture: true
      styles:
        card:
          - box-shadow: '-5px 4px 10px rgba(0, 0, 0, 0.2)'
          - border-radius: 10px
          - height: 500px
          - background-color: transparent
        img_cell:
          - z-index: 2
        icon:
          - width: 70%
        name:
          - z-index: 2
          - position: absolute
          - font-size: 45px
          - font-weight: lighter
          - justify-self: start
          - left: 25px
          - top: 20px
          - color: var(--secondary-text-color)
        custom_fields:
          blur:
            - z-index: 1
            - top: 0%
            - border-radius: 10px
            - left: 0%
            - width: 100%
            - height: 100%
            - position: absolute
            - background-color: rgba(0, 0, 0, 0.1)
            - backdrop-filter: blur(20px)
            - '-webkit-backdrop-filter': blur(20px)
          templates:
            - z-index: 2
            - position: absolute
            - left: 10px
            - top: 60px
            - width: 100%
          forecast:
            - z-index: 2
            - position: absolute
            - bottom: 0%
            - width: 100%
      state:
        - value: hail
          entity_picture: /local/images/weather/snow.png
        - value: windy
          entity_picture: /local/images/weather/wind.png
        - value: windy-variant
          entity_picture: /local/images/weather/wind.png
        - value: lightning-rainy
          entity_picture: /local/images/weather/lightning.png
        - value: lightning
          entity_picture: /local/images/weather/lightning.png
        - value: pouring
          entity_picture: |
            [[[
              if (states['sun.sun'].state == "below_horizon")
                return '/local/images/weather/rainevening.png';
              else if (states['sun.sun'].state == "above_horizon")
                return '/local/images/weather/rain.png';
            ]]]
        - value: rainy
          entity_picture: |
            [[[
              if (states['sun.sun'].state == "below_horizon")
                return '/local/images/weather/rainevening.png';
              else if (states['sun.sun'].state == "above_horizon")
                return '/local/images/weather/rain.png';
            ]]]
        - value: sunny
          entity_picture: |
            [[[
              if (states['sun.sun'].state == "below_horizon")
                return '/local/images/weather/clear-night.svg';
                else if (states['sun.sun'].state == "above_horizon")
                return '/local/images/weather/sunny.svg';
              ]]]
        - value: cloudy
          entity_picture: /local/images/weather/cloudy.png
        - value: partlycloudy
          entity_picture: |
            [[[
                if (states['sun.sun'].state == "below_horizon")
                  return '/local/images/weather/cloudyevening.png';
                else if (states['sun.sun'].state == "above_horizon")
                  return '/local/images/weather/partlycloudy.svg';
            ]]]
        - value: snowy
          entity_picture: /local/images/weather/snow.png
        - value: snowy-rainy
          entity_picture: /local/images/weather/snow.png
      custom_fields:
        blur: |
          <div></div> 
        templates:
          card:
            type: markdown
            card_mod:
              style: |
                ha-card {
                  --ha-card-background: transparent;
                  text-align: left; }
            content: >
              <font size="2px"> {% if states('weather.openweathermap') ==
              "partlycloudy" %} Es ist teilweise bewölkt. {% elif
              states('weather.openweathermap') == "cloudy" %} Es ist bewölkt. {%
              elif states('weather.openweathermap') == "sunny" %} Sonnig. {%
              elif states('weather.openweathermap') == "rainy" %} Regenjacke
              anziehen, es regnet. {% elif states('weather.openweathermap') ==
              "pouring" %} Regenjacke anziehen, es regnet in Strömen. {% elif
              states('weather.openweathermap') == "snowy" %} Heute schneit es.
              {% elif states('weather.openweathermap') == "snowy-rainy" %}
              Schneeregen. {% elif states('weather.openweathermap') == "hail" %}
              Achten Sie auf Hagel. {% elif states('weather.openweathermap') ==
              "windy" %} Hut ab, es ist windig. {% elif
              states('weather.openweathermap') == "lightning" %} Achten Sie auf
              den Blitz, es donnert. {% elif states('weather.openweathermap') ==
              "lightning-rainy" %} Es donnert und regnet. {% elif
              states('weather.openweathermap') == "windy-variant" %} Halte
              deinen Hut, es ist windig. {% elif
              states('weather.openweathermap') == "fog" %} Es ist neblig. {%
              endif %} Die Außentemperatur ist {{
              states.weather.openweathermap.attributes.temperature }}°C. Die
              Luftfeuchtigkeit ist {{
              states.weather.openweathermap.attributes.humidity }}% und der Wind
              blÀst mit {{ states.weather.openweathermap.attributes.wind_speed
              }}km/h. 
        forecast:
          card:
            type: markdown
            card_mod:
              style: |
                ha-card {
                  --ha-card-background: transparent;
                  text-align: left; }
            content: >
              <font size="2px"> <b>Morgen:</b> <br> Max., {{
              states.weather.openweathermap.attributes.forecast[1]['temperature']
              }} C°. Min., {{
              states.weather.openweathermap.attributes.forecast[1]['templow'] }}
              C°. <br> Es wird {{
              states.weather.openweathermap.attributes.forecast[1]['condition']
              }}. <br> <b>Übermorgen:</b><br>  Max., {{
              states.weather.openweathermap.attributes.forecast[2]['temperature']
              }} C°. Min, {{
              states.weather.openweathermap.attributes.forecast[2]['templow'] }}
              C°. <br> Es wird {{
              states.weather.openweathermap.attributes.forecast[2]['condition']
              }}.
  haptic: heavy
  animation_card: |
    [[[
      const animation_speed_ms = 900;
      const animation = `card_bounce ${animation_speed_ms}ms cubic-bezier(0.22, 1, 0.36, 1)`;
      this.shadowRoot.getElementById("card").style.animation = animation;
      window.setTimeout(() => {
        this.shadowRoot.getElementById("card").style.animation = "none";
      }, animation_speed_ms)
    ]]]
extra_styles: |
  @keyframes card_bounce {
    0% {
      transform: scale(1);
    }
    15% {
      transform: scale(0.9);
    }
    25% {
      transform: scale(1);
    }
    30% {
      transform: scale(0.98);
    }
    100% {
  transform: scale(1);
    }
  }   
show_state: false
show_name: false
show_label: true
styles:
  grid:
    - grid-template-areas: '"n i" "s i" "l i"'
    - grid-template-columns: 1fr 45%
  card:
    - background: transparent
    - border-radius: 0px 0px 10px 10px
    - margin-top: '-20px'
    - '--mdc-ripple-press-opacity': 0
    - height: 140px
  icon:
    - width: 80%
state:
  - value: hail
    entity_picture: /local/images/weather/snow.png
  - value: windy
    entity_picture: /local/images/weather/wind.png
  - value: windy-variant
    entity_picture: /local/images/weather/wind.png
  - value: lightning-rainy
    entity_picture: /local/images/weather/lightning.png
  - value: lightning
    entity_picture: /local/images/weather/lightning.png
  - value: pouring
    entity_picture: |
      [[[
        if (states['sun.sun'].state == "below_horizon")
          return '/local/images/weather/rainevening.png';
        else if (states['sun.sun'].state == "above_horizon")
          return '/local/images/weather/rain.png';
      ]]]
  - value: fog
    entity_picture: /local/fog.svg
  - value: rainy
    entity_picture: |
      [[[
        if (states['sun.sun'].state == "below_horizon")
          return '/local/images/weather/rainevening.png';
        else if (states['sun.sun'].state == "above_horizon")
          return '/local/images/weather/rain.png';
      ]]]
  - value: sunny
    entity_picture: |
      [[[
        if (states['sun.sun'].state == "below_horizon")
          return '/local/images/weather/clear-night.svg';
        else if (states['sun.sun'].state == "above_horizon")
          return '/local/images/weather/sunny.svg';
      ]]]
  - value: cloudy
    entity_picture: /local/images/weather/cloudy.png
  - value: partlycloudy
    entity_picture: |
      [[[
        if (states['sun.sun'].state == "below_horizon")
          return '/local/images/weather/cloudyevening.png';
        else if (states['sun.sun'].state == "above_horizon")
          return '/local/images/weather/partlycloudy.svg';
      ]]]
  - value: snowy
    entity_picture: /local/images/weather/snow.png
  - value: snowy-rainy
    entity_picture: /local/weather/snow.png

English

type: custom:button-card
entity: weather.openweathermap
view_layout:
  grid-area: weather
entity_picture: /local/images/weather/clear-night.svg
show_entity_picture: true
tap_action:
  action: fire-dom-event
  browser_mod:
    command: popup
    title: Wetter
    hide_header: true
    card:
      type: custom:button-card
      name: Wetter
      tap_action:
        action: navigate
        navigation_path: '#empty'
      entity_picture: /local/images/weather/cloudy.png
      entity: weather.openweathermap
      show_entity_picture: true
      styles:
        card:
          - box-shadow: '-5px 4px 10px rgba(0, 0, 0, 0.2)'
          - border-radius: 10px
          - height: 500px
          - background-color: transparent
        img_cell:
          - z-index: 2
        icon:
          - width: 70%
        name:
          - z-index: 2
          - position: absolute
          - font-size: 45px
          - font-weight: lighter
          - justify-self: start
          - left: 25px
          - top: 20px
          - color: var(--secondary-text-color)
        custom_fields:
          blur:
            - z-index: 1
            - top: 0%
            - border-radius: 10px
            - left: 0%
            - width: 100%
            - height: 100%
            - position: absolute
            - background-color: rgba(0, 0, 0, 0.1)
            - backdrop-filter: blur(20px)
            - '-webkit-backdrop-filter': blur(20px)
          templates:
            - z-index: 2
            - position: absolute
            - left: 10px
            - top: 60px
            - width: 100%
          forecast:
            - z-index: 2
            - position: absolute
            - bottom: 0%
            - width: 100%
      state:
        - value: hail
          entity_picture: /local/images/weather/snow.png
        - value: windy
          entity_picture: /local/images/weather/wind.png
        - value: windy-variant
          entity_picture: /local/images/weather/wind.png
        - value: lightning-rainy
          entity_picture: /local/images/weather/lightning.png
        - value: lightning
          entity_picture: /local/images/weather/lightning.png
        - value: pouring
          entity_picture: |
            [[[
              if (states['sun.sun'].state == "below_horizon")
                return '/local/images/weather/rainevening.png';
              else if (states['sun.sun'].state == "above_horizon")
                return '/local/images/weather/rain.png';
            ]]]
        - value: rainy
          entity_picture: |
            [[[
              if (states['sun.sun'].state == "below_horizon")
                return '/local/images/weather/rainevening.png';
              else if (states['sun.sun'].state == "above_horizon")
                return '/local/images/weather/rain.png';
            ]]]
        - value: sunny
          entity_picture: |
            [[[
              if (states['sun.sun'].state == "below_horizon")
                return '/local/images/weather/clear-night.svg';
                else if (states['sun.sun'].state == "above_horizon")
                return '/local/images/weather/sunny.svg';
              ]]]
        - value: cloudy
          entity_picture: /local/images/weather/cloudy.png
        - value: partlycloudy
          entity_picture: |
            [[[
                if (states['sun.sun'].state == "below_horizon")
                  return '/local/images/weather/cloudyevening.png';
                else if (states['sun.sun'].state == "above_horizon")
                  return '/local/images/weather/partlycloudy.svg';
            ]]]
        - value: snowy
          entity_picture: /local/images/weather/snow.png
        - value: snowy-rainy
          entity_picture: /local/images/weather/snow.png
      custom_fields:
        blur: |
          <div></div> 
        templates:
          card:
            type: markdown
            card_mod:
              style: |
                ha-card {
                  --ha-card-background: transparent;
                  text-align: left; }
            content: >
              <font size="2px"> {% if states('weather.openweathermap') ==
              "partlycloudy" %} It is partly cloudy. {% elif
              states('weather.openweathermap') == "cloudy" %} It's cloudy. {%
              elif states('weather.openweathermap') == "sunny" %} Sunny. {%
              elif states('weather.openweathermap') == "rainy" %} Wear a rain jacket, it's raining.
              {% elif states('weather.openweathermap') ==
              "pouring" %} Wear a rain jacket, it's pouring rain. {% elif
              states('weather.openweathermap') == "snowy" %} It's snowing today.
              {% elif states('weather.openweathermap') == "snowy-rainy" %}
              Sleet. {% elif states('weather.openweathermap') == "hail" %}
              Watch out for hail. {% elif states('weather.openweathermap') ==
              "windy" %} Hats off, it's windy. {% elif
              states('weather.openweathermap') == "lightning" %} Watch out for the lightning,
               there's thunder. {% elif states('weather.openweathermap') ==
              "lightning-rainy" %} It's thundering and raining. {% elif
              states('weather.openweathermap') == "windy-variant" %} Hold your hat, it's windy. {% elif
              states('weather.openweathermap') == "fog" %} It is foggy. {%
              endif %} The outside temperature is {{
              states.weather.openweathermap.attributes.temperature }}°C. The humidity is {{
              states.weather.openweathermap.attributes.humidity }}% and the wind blows at {{ states.weather.openweathermap.attributes.wind_speed
              }}km/h. 
        forecast:
          card:
            type: markdown
            card_mod:
              style: |
                ha-card {
                  --ha-card-background: transparent;
                  text-align: left; }
            content: >
              <font size="2px"> <b>Tomorrow:</b> <br> Max., {{
              states.weather.openweathermap.attributes.forecast[1]['temperature']
              }} C°. Min., {{
              states.weather.openweathermap.attributes.forecast[1]['templow'] }}
              C°. <br> It will be {{
              states.weather.openweathermap.attributes.forecast[1]['condition']
              }}. <br> <b>The day after tomorrow:</b><br>  Max., {{
              states.weather.openweathermap.attributes.forecast[2]['temperature']
              }} C°. Min, {{
              states.weather.openweathermap.attributes.forecast[2]['templow'] }}
              C°. <br> It will be {{
              states.weather.openweathermap.attributes.forecast[2]['condition']
              }}.
  haptic: heavy
  animation_card: |
    [[[
      const animation_speed_ms = 900;
      const animation = `card_bounce ${animation_speed_ms}ms cubic-bezier(0.22, 1, 0.36, 1)`;
      this.shadowRoot.getElementById("card").style.animation = animation;
      window.setTimeout(() => {
        this.shadowRoot.getElementById("card").style.animation = "none";
      }, animation_speed_ms)
    ]]]
extra_styles: |
  @keyframes card_bounce {
    0% {
      transform: scale(1);
    }
    15% {
      transform: scale(0.9);
    }
    25% {
      transform: scale(1);
    }
    30% {
      transform: scale(0.98);
    }
    100% {
  transform: scale(1);
    }
  }   
show_state: false
show_name: false
show_label: true
styles:
  grid:
    - grid-template-areas: '"n i" "s i" "l i"'
    - grid-template-columns: 1fr 45%
  card:
    - background: transparent
    - border-radius: 0px 0px 10px 10px
    - margin-top: '-20px'
    - '--mdc-ripple-press-opacity': 0
    - height: 140px
  icon:
    - width: 80%
state:
  - value: hail
    entity_picture: /local/images/weather/snow.png
  - value: windy
    entity_picture: /local/images/weather/wind.png
  - value: windy-variant
    entity_picture: /local/images/weather/wind.png
  - value: lightning-rainy
    entity_picture: /local/images/weather/lightning.png
  - value: lightning
    entity_picture: /local/images/weather/lightning.png
  - value: pouring
    entity_picture: |
      [[[
        if (states['sun.sun'].state == "below_horizon")
          return '/local/images/weather/rainevening.png';
        else if (states['sun.sun'].state == "above_horizon")
          return '/local/images/weather/rain.png';
      ]]]
  - value: fog
    entity_picture: /local/fog.svg
  - value: rainy
    entity_picture: |
      [[[
        if (states['sun.sun'].state == "below_horizon")
          return '/local/images/weather/rainevening.png';
        else if (states['sun.sun'].state == "above_horizon")
          return '/local/images/weather/rain.png';
      ]]]
  - value: sunny
    entity_picture: |
      [[[
        if (states['sun.sun'].state == "below_horizon")
          return '/local/images/weather/clear-night.svg';
        else if (states['sun.sun'].state == "above_horizon")
          return '/local/images/weather/sunny.svg';
      ]]]
  - value: cloudy
    entity_picture: /local/images/weather/cloudy.png
  - value: partlycloudy
    entity_picture: |
      [[[
        if (states['sun.sun'].state == "below_horizon")
          return '/local/images/weather/cloudyevening.png';
        else if (states['sun.sun'].state == "above_horizon")
          return '/local/images/weather/partlycloudy.svg';
      ]]]
  - value: snowy
    entity_picture: /local/images/weather/snow.png
  - value: snowy-rainy
    entity_picture: /local/weather/snow.png

2 Likes