Weiß jemand, wie ich dieses Design hinbekomme?

Guten Tag,

ich habe heute ein nettes Tile-Card Design gesehen, zum steuern eines Fernsehers.
Man sieht den Media Player und darunter eine kleine Auswahl an Quellen, zwischen denen man wechseln kann.

Ich habe leider nicht herausgefunden, wie man das so umsetzen kann mit diesem Design.
Also wie ich den Media Player einbinde, weiß ich natürlich.
Aber wie bekomme ich diese Tile-Card mit den verschiedenen Quellen hin und den Laut, Leiser und Mute Button.

Weiß das zufällig jemand und könnte mir dabei Helfen? (Bild im Anhang)

Ich würde mich sehr über eine Antwort freuen.

Lieben Gruß
Marvin

Hi, ich nehme stark an, dass es eine custom-card aus HACS ist.

Ansonsten muss man viel basteln. Ich hatte mir meine mal so gestaltet. Rechts kann auf Lautstärke umgestellt werden.

type: custom:vertical-stack-in-card
card_mod:
  style: |
    ha-card {
      position: relative;
      overflow: hidden;
      box-shadow: rgba(0, 0, 0, 0.4) 0px 2px 4px, rgba(0, 0, 0, 0.3) 0px 7px
                  13px -3px, rgba(0, 0, 0, 0.2) 0px -3px 0px inset !important;
      border: none;
    } 
    ha-card::before {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: url({{ state_attr('media_player.wohnzimmer', 'entity_picture') }}) no-repeat center center;
      background-size: cover;
      filter: blur(30px);
      z-index: 0;
      opacity: {% if is_state('media_player.wohnzimmer', 'playing') %} 1 {% else %} 0 {% endif %};
      transition: opacity 0.5s ease;
    }
cards:
  - type: horizontal-stack
    cards:
      - type: custom:vertical-stack-in-card
        card_mod:
          style: |
            ha-card {
              background: transparent !important;
              border: none !important;
              border-radius: none !important;
              box-shadow: none !important;
              z-index: 1 !important; /* Über dem Hintergrund */
            }
        cards:
          - type: horizontal-stack
            cards:
              - type: conditional
                conditions:
                  - entity: media_player.wohnzimmer
                    state: playing
                card:
                  type: custom:button-card
                  entity: media_player.wohnzimmer
                  show_state: false
                  show_name: false
                  show_icon: false
                  show_entity_picture: true
                  size: 120px
                  card_mod:
                    style: |
                      ha-card {
                        background: transparent !important;
                        border: 0px !important;
                        border-radius: 0px !important;
                        padding: 15px !important;
                        z-index: 1 !important; /* Über dem Hintergrund */
                      }
                      #img-cell {
                        display: flex !important;
                        align-items: flex-start !important;
                        justify-content: flex-start !important;
                        margin: 0 !important;
                      }
              - type: conditional
                conditions:
                  - entity: media_player.wohnzimmer
                    state: paused
                card:
                  type: markdown
                  content: |
                    ## Echo Gruppe Wohnzimmer
                  card_mod:
                    style: |
                      ha-card {
                        background: transparent !important;
                        border: 0px !important;
                        border-radius: none !important;
                        box-shadow: none;
                        padding: 15px;
                        font-size: 12px !important;
                        z-index: 1 !important; /* Über dem Hintergrund */
                      }
              - type: conditional
                conditions:
                  - entity: media_player.wohnzimmer
                    state: idle
                card:
                  type: markdown
                  content: |
                    ## Echo Gruppe Wohnzimmer
                  card_mod:
                    style: |
                      ha-card {
                        background: transparent !important;
                        border: none !important;
                        border-radius: none !important;
                        box-shadow: none;
                        font-size: 12px !important;
                        z-index: 1 !important; /* Über dem Hintergrund */
                      }
              - type: conditional
                conditions:
                  - entity: media_player.wohnzimmer
                    state: standby
                card:
                  type: markdown
                  content: |
                    ## Echo Gruppe Wohnzimmer
                  card_mod:
                    style: |
                      ha-card {
                        background: none;
                        border: none;
                        border-radius: none;
                        box-shadow: none;
                        padding: 20px;
                        font-size: 12px !important;
                        z-index: 1 !important; /* Über dem Hintergrund */
                      }
      - type: picture
        image: /local/bilder/echogruppe.png
        aspect_ratio: 1/1
        card_mod:
          style: |
            ha-card {
              background: none;
              border: none;
              border-radius: none;
              box-shadow: none;
              width: 150px;
              height: 150px;
              margin-left: auto;
              z-index: 1 !important; /* Über dem Hintergrund */
            }
  - type: custom:vertical-stack-in-card
    card_mod:
      style: |
        ha-card {
          border: none !important;
          z-index: 1 !important; /* Über dem Hintergrund */
        }
    cards:
      - type: custom:mushroom-media-player-card
        entity: media_player.wohnzimmer
        media_controls:
          - play_pause_stop
          - next
          - previous
        volume_controls:
          - volume_mute
          - volume_buttons
          - volume_set
        show_volume_level: true
        collapsible_controls: false
        use_media_info: true
        icon: mdi:cast-audio
        card_mod:
          style: |
            ha-card {
              background: none !important;
              border: none !important;
              box-shadow: none;
              z-index: 1 !important; /* Über dem Hintergrund */
            }
      - type: custom:mushroom-chips-card
        card_mod:
          style: |
            ha-card {
              margin-bottom: 8px !important; 
              z-index: 1 !important; /* Über dem Hintergrund */
            }
        alignment: center
        chips:
          - type: entity
            entity: script.bb_radio_skript_fur_echo_wohnzimmer_gruppe
            tap_action:
              action: toggle
            content_info: name
            name: BB Radio
          - type: entity
            entity: script.radio_fritz_skript_fur_echo_wohnzimmer_gruppe
            tap_action:
              action: toggle
            content_info: name
            name: Fritz
          - type: entity
            entity: script.bb_radio_skript_fur_echo_wohnzimmer_gruppe
            tap_action:
              action: toggle
            content_info: name
            name: Radio 1
          - type: entity
            entity: script.radio_berliner_rundfunk_skript_fur_echo_wohnzimmer_gruppe
            tap_action:
              action: toggle
            content_info: name
            name: 91,4

Vielleicht wird auch so etwas wie die mushroom-media-card genutzt. Über Card-Mod kann man da sicherlich auch etwas zusammenbauen.

2 „Gefällt mir“

Schau doch mal im HACS unter „Custom Features for Home Assistant Cards“
Da findest du recht weit unten das „Example 4“ dass sollte schon so ziemlich das sein, was Du suchst.
Der Code dazu steht auch darunter (Brauchst Du nur aufklappen :wink:)

1 „Gefällt mir“

off-topic on:

. . . . . . . . it’s Fritz . . . . . it’s fresh :sunglasses:

  • habe soeben mal probegehört - gefällt mir!
  • Auch wenn die Lokalbeiträge für’n NRW-ler nicht sooo interessant sind.
  • Aber - gute Mucke!
  • Allerdings starte ich den Stream per Alexa, die haut das über 'n vernetzten Amplifier raus.
  • Danke für die Inspiration. :pray:
1 „Gefällt mir“

Genau danach habe ich gesucht. Vielen Dank.
Hab es mal versucht ein wenig zu ändern, damit ich auch „Netflix“ darüber Steuern kann.

Hab es mal so gemacht.

type: tile
entity: media_player.wohnzimmer_fernseher
color: green
layout_options:
  grid_columns: 4
  grid_rows: 3
features_position: bottom
vertical: false
features:
  - type: custom:service-call
    entries:
      - type: selector
        entity_id: media_player.wohnzimmer_fernseher
        options:
          - type: button
            icon: mdi:netflix
            option: Netflix
            tap_action:
              action: perform-action
              perform_action: media_player.select_source
              data:
                option: Netflix
              target:
                entity_id: media_player.wohnzimmer_fernseher
            styles: |-
              :host {
                --color: var(--red-color);
              }


Leider kommt folgender Fehler:

Die Aktion media_player/select_source konnte nicht ausgeführt werden. extra keys not allowed @ data[‚option‘]’

Hat jemand eventuell eine Idee, wie ich diesen Fehler behebe?

LG
Marvin

Ich denke Du musst die Angabe für data: option: quoten.
Also 'Netflix' anstelle von Netflix

Hat leider nichts verändert. Gleiches Problem wie vorher.
Finde leider auch Online nichts nützliches.

Nutzt Du denn „type: custom:custom-features-card“ ?

Bei mir sieht dein Code mit der „type: custom:custom-features-card“ so aus:

Warum da nur das N angezeigt wird, weiß ich auch nicht…

:rofl: Jetzt hab ich´s verstanden! Ist das Logo! :see_no_evil:

Hatte es als „Tile“, weil es so in der HACS Anleitung stand.
Hab es jetzt mal so gemacht wie du.

Hab den Fehler tatsächlich auch gefunden. Statt options musste ich source nutzen.

So sieht der Code jetzt aus:

type: custom:custom-features-card
color: green
layout_options:
  grid_columns: 4
  grid_rows: 3
features_position: bottom
vertical: false
features:
  - type: custom:service-call
    entries:
      - type: selector
        entity_id: media_player.wohnzimmer_fernseher
        options:
          - type: button
            icon: mdi:netflix
            source: Netflix
            tap_action:
              action: perform-action
              perform_action: media_player.select_source
              data:
                source: Netflix
              target:
                entity_id: media_player.wohnzimmer_fernseher
            styles: |-
              :host {
                --color: var(--red-color);
              }
            entity_id: media_player.wohnzimmer_fernseher

Funktioniert auch wunderwar.
Meine Frage jetzt noch, weiß jemand zufällig, ob man die Aktuelle Quelle Farbig hinterlegen kann, so wie ich es als Beispiel gezeigt habe, ganz am Anfang in dem Screenshot.

In der HACS Anleitung wird es zwar auch dargestellt, aber wenn ich das genau so machen, zeigt er mir nur die verschiedenen „Quellen“ die ich zur Auswahl hab an, aber nicht, welche grad Aktiv ist.

Da hab ich auf die Schnelle auch keine Idee, aber wenn Du da weiterkommst, gerne teilen.
Probiere da gerade auch rum.

Wenn du es farbig haben willst kannst du am besten beim service call den selector nehmen. Und dann mit einem Input select arbeiten. Evtl müsstest du dann einen Helfer und eine Automation dafür erstellen.
Hier mal ein Beispiel was dein Screenshot nahe kommt. Nun fehlt nur noch die Lautstärke/Mute Buttons.
Benötigte custom cards sind vertical stack in card und Customer features card. die hast du ja aber bereits wie ich gesehen habe.

type: custom:vertical-stack-in-card
cards:
  - type: media-control
    entity: media_player.schlafzimmer
  - type: custom:custom-features-card
    features:
      - type: custom:service-call
        entries:
          - type: selector
            entity_id: input_select.harmony_hub
            options:
              - icon: mdi:power
                type: button
                entity_id: input_select.harmony_hub
                option: Ausschalten
                tap_action:
                  action: call-service
                  service: input_select.select_option
                  data:
                    option: Ausschalten
                  target:
                    entity_id: input_select.harmony_hub
              - icon: si:appletv
                type: button
                entity_id: input_select.harmony_hub
                option: Apple TV
                tap_action:
                  action: call-service
                  service: input_select.select_option
                  data:
                    option: Apple TV
                  target:
                    entity_id: input_select.harmony_hub
              - icon: mdi:nintendo-switch
                type: button
                entity_id: input_select.harmony_hub
                option: Nintendo Switch
                tap_action:
                  action: call-service
                  service: input_select.select_option
                  data:
                    option: Nintendo Switch
                  target:
                    entity_id: input_select.harmony_hub
              - icon: mdi:sony-playstation
                type: button
                entity_id: input_select.harmony_hub
                option: Playstation
                tap_action:
                  action: call-service
                  service: input_select.select_option
                  data:
                    option: Playstation
                  target:
                    entity_id: input_select.harmony_hub
            haptics: true

Danke für die Antwort.
Wie genau meinst du das mit „Helfer“ und „Automation“.

Bin noch relativ neu im Bereich HA unterwegs ^^

Hi, ich hab das so ähnlich beim ATV/Denon. Wenn das Programm gestartet wird, erscheint oben links das Bild von der Serie oder Film mit einer Zeitleiste.
Das sollte so auch mit einem Radioprogramm oder Streamingdienst (Spotify o.a.) gehen.

type: custom:vertical-stack-in-card
cards:
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        entity: media_player.wohnzimmer
        triggers_update:
          - sensor.now_second
          - media_player.wohnzimmer
        name: |
          [[[
            const a = entity?.attributes || {};
            const app = (a.app_name || a.source || '').toLowerCase();
            const title = a.media_title || a.media_station || '';
            if (app.includes('zattoo')) {
              // Bei Zattoo liefert tvOS oft keine Titel/Sender-Daten.
              return title || 'Zattoo';
            }
            return title || '—';
          ]]]
        label: |
          [[[
            const a = entity?.attributes || {};
            const app = (a.app_name || a.source || '').toLowerCase();
            const type = a.media_content_type || '';
            if (app.includes('zattoo')) {
              // Klarer Hinweis statt leerem Label
              return (a.media_title || a.media_station)
                ? 'Zattoo'
                : 'Zattoo • Kanalinfos nicht verfügbar';
            }
            const appName = a.app_name || a.source || '';
            return appName && type ? `${appName} • ${type}` : (appName || type || '');
          ]]]
        show_label: true
        show_icon: false
        show_state: false
        tap_action:
          action: more-info
        hold_action:
          action: more-info
        styles:
          card:
            - border-radius: 10px
            - border: none
            - height: 200px
            - padding: 16px
            - font-family: poppins_regular
            - background: |
                [[[
                  const a   = entity?.attributes || {};
                  const art = a.entity_picture || a.media_image_url || a.entity_picture_local || '';
                  const app = (a.app_name || a.source || '').toLowerCase();

                  // 1) Wenn echtes Artwork vorhanden: verwende es
                  if (art) {
                    return `linear-gradient(to bottom, rgba(0,0,0,0.25), rgba(0,0,0,0.7)), url("${art}") center / cover no-repeat`;
                  }

                  // 2) Zattoo aktiv, aber kein Artwork → lokales Platzhalterbild verwenden
                  if (app.includes('zattoo')) {
                    const localZ = "/local/pictures/zattoo-card-image.png";
                    return `linear-gradient(to bottom, rgba(0,0,0,0.25), rgba(0,0,0,0.7)), url("${localZ}") center / cover no-repeat`;
                  }

                  // 3) Fallback: lila Verlauf
                  return 'linear-gradient(130deg, #4F46A3 0%, #413A86 100%)';
                ]]]
          grid:
            - grid-template-areas: "\"n\" \"l\" \"progress\""
            - grid-template-rows: auto auto auto
            - row-gap: 6px
          name:
            - grid-area: "n"
            - color: "#FFFFFF"
            - font-size: 18px
            - font-weight: 600
            - justify-self: start
            - white-space: normal
            - line-height: 1.25
            - overflow: hidden
            - display: "-webkit-box"
            - "-webkit-line-clamp": 2
            - "-webkit-box-orient": vertical
            - text-shadow: 0 1px 2px rgba(0,0,0,0.5)
          label:
            - grid-area: l
            - color: "#FFFFFF"
            - opacity: 0.9
            - font-size: 14px
            - justify-self: start
            - white-space: normal
            - line-height: 1.2
            - overflow: hidden
            - display: "-webkit-box"
            - "-webkit-line-clamp": 1
            - "-webkit-box-orient": vertical
            - text-shadow: 0 1px 2px rgba(0,0,0,0.45)
          custom_fields:
            progress:
              - grid-area: progress
              - align-self: end
              - width: 100%
        custom_fields:
          progress: |
            [[[
              const a = entity?.attributes || {};
              const dur = Number(a.media_duration || 0);
              if (dur <= 0) { return ''; }   // Live-TV: meist keine Dauer → keine Leiste
              let pos = Number(a.media_position || 0);
              const upd = Date.parse(a.media_position_updated_at || '');
              if (!isNaN(upd)) pos += Math.max(0, (Date.now() - upd) / 1000);
              const pct = Math.max(0, Math.min(100, (pos / dur) * 100));
              const mmss = s => { s = Math.max(0, Math.floor(s)); const m = Math.floor(s/60); const sec = s % 60; return `${m}:${sec.toString().padStart(2,'0')}`; };
              return `
                <div class="np-wrap">
                  <div class="bar"><div class="fill" style="width:${pct}%;"></div></div>
                  <div class="times"><span>${mmss(pos)}</span><span>${mmss(dur)}</span></div>
                </div>
              `;
            ]]]
        card_mod:
          style: >
            :host { flex: 3.2 1 0 !important; min-width: 0; }  /* Linke Karte
            breiter */

            ha-card { font-family: poppins_regular !important; }

            .np-wrap { width: 100%; }

            .bar {
              width: 100%; height: 6px; border-radius: 999px;
              background: rgba(255,255,255,0.35);
              overflow: hidden; margin-top: 6px;
            }

            .bar .fill {
              height: 100%; border-radius: 999px;
              background: rgba(255,255,255,0.95);
              transition: width 0.25s linear;
            }

            .times {
              display: flex; justify-content: space-between;
              color: #FFFFFF; opacity: 0.9; font-size: 12px; margin-top: 6px;
            }
      - type: vertical-stack
        cards:
          - square: false
            type: grid
            cards:
              - type: custom:button-card
                entity: media_player.wohnzimmer
                icon: mdi:power
                show_name: false
                tap_action:
                  action: call-service
                  service: media_player.toggle
                  target:
                    entity_id: media_player.wohnzimmer
                styles:
                  card:
                    - border-radius: 10px
                    - padding: 10px
                    - height: 60px
                  icon:
                    - color: "#FFFFFF"
                state:
                  - value: "off"
                    styles:
                      card:
                        - background: "linear-gradient(100deg, #C50D22 0%, #A70C1E 100%)"
                  - value: idle
                    styles:
                      card:
                        - background: "linear-gradient(100deg, #C50D22 0%, #A70C1E 100%)"
                  - value: standby
                    styles:
                      card:
                        - background: "linear-gradient(100deg, #C50D22 0%, #A70C1E 100%)"
                  - value: playing
                    styles:
                      card:
                        - background: "linear-gradient(100deg, #4BC67A 0%, #41AA69 100%)"
              - type: custom:button-card
                entity: media_player.avr_wohnzimmer_2
                show_name: false
                icon: mdi:volume-high
                show_state: true
                state_display: |
                  [[[
                    if (!entity || !entity.attributes) return '—';
                    const v = (entity.attributes.volume_level != null)
                      ? Math.round(entity.attributes.volume_level * 100) + '%'
                      : '—';
                    return v;
                  ]]]
                styles:
                  card:
                    - margin-top: 2px
                    - border-radius: 10px
                    - padding: 10px
                    - height: 60px
                    - background: |
                        [[[
                          if (!entity || entity.attributes.volume_level == null) {
                            return "linear-gradient(100deg, #9495E0 0%, #8182C3 100%)";
                          }
                          const vol = Math.round(entity.attributes.volume_level * 100);
                          return `linear-gradient(90deg, #4BC67A 0%, #41AA69 ${vol}%, #9495E0 ${vol}%, #8182C3 100%)`;
                        ]]]
                  grid:
                    - grid-template-areas: "\"i s\""
                    - grid-template-columns: 1fr 1fr
                    - grid-template-rows: 1fr
                    - align-items: center
                  icon:
                    - color: "#FFFFFF"
                    - width: 27px
                    - margin-left: "-10px"
                  state:
                    - color: "#FFFFFF"
                    - font-family: poppins_medium
                    - font-size: 16px
              - type: custom:button-card
                icon: mdi:volume-mute
                tap_action:
                  action: call-service
                  service: media_player.volume_mute
                  data:
                    is_volume_muted: true
                  target:
                    entity_id: media_player.avr_wohnzimmer_2
                hold_action:
                  action: call-service
                  service: media_player.volume_mute
                  data:
                    is_volume_muted: false
                  target:
                    entity_id: media_player.avr_wohnzimmer_2
                styles:
                  card:
                    - margin-top: 2px
                    - border-radius: 10px
                    - padding: 10px
                    - height: 60px
                    - background: "linear-gradient(100deg, #9495E0 0%, #8182C3 100%)"
                  icon:
                    - color: "#FFFFFF"
            columns: 1
        card_mod:
          style: >
            :host { flex: 1 1 0 !important; min-width: 0; }  /* rechte Spalte
            schlanker */
    card_mod:
      style: >
        #root { gap: 12px; align-items: flex-start; }  /* Abstand zwischen
        links/rechts */
  - type: custom:gap-card
    height: 10
  - square: false
    type: grid
    cards:
      - type: custom:button-card
        entity: media_player.wohnzimmer
        show_name: false
        show_entity_picture: true
        entity_picture: /local/logos/netflix.png
        tap_action:
          action: call-service
          service: media_player.select_source
          data:
            source: Netflix
          target:
            entity_id: media_player.wohnzimmer
        styles:
          card:
            - border-radius: 10px
            - height: 60px
            - background: |
                [[[
                  const a = entity?.attributes || {};
                  const app = (a.app_name || a.source || '').toLowerCase();
                  const isOn = entity?.state && entity.state !== 'off' && entity.state !== 'idle';

                  // AVR Quelle prüfen
                  const avr = states["media_player.avr_wohnzimmer_2"];
                  const avrSource = (avr?.attributes?.source || "").toLowerCase();

                  if (isOn && avrSource.includes("xbox")) {
                    return 'linear-gradient(100deg, #A0A0A0 0%, #707070 100%)'; // Grau wenn AVR Xbox
                  }
                  if (isOn && app.includes("netflix")) {
                    return 'linear-gradient(100deg, #4BC67A 0%, #41AA69 100%)'; // Grün für Netflix
                  }
                  return 'linear-gradient(100deg, #9495E0 0%, #8182C3 100%)';     // Standard
                ]]]
          entity_picture:
            - width: 80px
            - object-fit: contain
            - margin-top: 3px
      - type: custom:button-card
        entity: media_player.wohnzimmer
        name: Amazon
        show_entity_picture: true
        show_name: false
        entity_picture: /local/icons/amazon_video.png
        tap_action:
          action: call-service
          service: media_player.select_source
          data:
            source: Prime Video
          target:
            entity_id: media_player.wohnzimmer
        styles:
          card:
            - border-radius: 10px
            - height: 60px
            - background: |
                [[[
                  const a = entity?.attributes || {};
                  const app = (a.app_name || a.source || '').toLowerCase();
                  const isOn = entity?.state && entity.state !== 'off' && entity.state !== 'idle';
                  return (isOn && app.includes('prime video'))
                    ? 'linear-gradient(100deg, #4BC67A 0%, #41AA69 100%)'
                    : 'linear-gradient(100deg, #9495E0 0%, #8182C3 100%)';
                ]]]
          entity_picture:
            - width: 80px
            - height: 50px
            - object-fit: contain
            - margin-top: 5px
          name:
            - color: "#FFFFFF"
            - font-family: poppins_regular
            - font-size: 12px
      - type: custom:button-card
        entity: media_player.wohnzimmer
        name: TV-Stream
        show_entity_picture: true
        show_name: false
        entity_picture: /local/icons/zattoo_logo.png
        tap_action:
          action: call-service
          service: media_player.select_source
          data:
            source: Zattoo | TV Streaming App
          target:
            entity_id: media_player.wohnzimmer
        hold_action:
          action: more-info
        styles:
          card:
            - border-radius: 10px
            - height: 60px
            - background: |
                [[[
                  const a = entity?.attributes || {};
                  const app = (a.app_name || a.source || '').toLowerCase();
                  const isOn = entity?.state && entity.state !== 'off' && entity.state !== 'idle';
                  return (isOn && app.includes('zattoo'))
                    ? 'linear-gradient(100deg, #4BC67A 0%, #41AA69 100%)'  // aktiv
                    : 'linear-gradient(100deg, #9495E0 0%, #8182C3 100%)'; // inaktiv
                ]]]
          entity_picture:
            - width: 80px
            - height: 40px
            - margin-top: "-3px"
            - object-fit: contain
          name:
            - color: "#FFFFFF"
            - font-family: poppins_regular
            - font-size: 12px
      - type: custom:button-card
        entity: media_player.wohnzimmer
        name: YouTube
        show_entity_picture: true
        show_name: false
        entity_picture: /local/logos/youtube.png
        tap_action:
          action: call-service
          service: media_player.select_source
          data:
            source: YouTube
          target:
            entity_id: media_player.wohnzimmer
        styles:
          card:
            - border-radius: 10px
            - height: 60px
            - background: |
                [[[
                  const a = entity?.attributes || {};
                  const app = (a.app_name || a.source || '').toLowerCase();
                  const isOn = entity?.state && entity.state !== 'off' && entity.state !== 'idle';
                  return (isOn && app.includes('youtube'))
                    ? 'linear-gradient(100deg, #4BC67A 0%, #41AA69 100%)'
                    : 'linear-gradient(100deg, #9495E0 0%, #8182C3 100%)';
                ]]]
          entity_picture:
            - width: 85px
            - height: 45px
            - object-fit: contain
          name:
            - color: "#FFFFFF"
            - font-family: poppins_regular
            - font-size: 12px
    columns: 4
  - type: custom:gap-card
    height: 10
  - square: false
    type: grid
    cards:
      - type: custom:button-card
        entity: media_player.avr_wohnzimmer_2
        show_name: false
        show_entity_picture: true
        entity_picture: /local/logos/appletv.png
        tap_action:
          action: call-service
          service: media_player.select_source
          data:
            source: Apple TV
          target:
            entity_id: media_player.avr_wohnzimmer_2
        hold_action:
          action: more-info
        styles:
          card:
            - border-radius: 10px
            - height: 60px
            - padding: 12px
            - background: |
                [[[
                  // Aktiv (grün), wenn der AVR an ist und Quelle "Apple TV" gewählt ist
                  const on = entity && entity.state && entity.state !== 'off' && entity.state !== 'idle';
                  const src = (entity?.attributes?.source || '').toLowerCase();
                  return (on && src.includes('apple'))
                    ? 'linear-gradient(100deg, #4BC67A 0%, #41AA69 100%)'
                    : 'linear-gradient(100deg, #9495E0 0%, #8182C3 100%)';
                ]]]
          entity_picture:
            - width: 50px
            - object-fit: contain
            - margin-top: "-3px"
          name:
            - color: "#FFFFFF"
            - font-family: poppins_regular
            - font-size: 12px
            - margin-top: "-5px"
      - type: custom:button-card
        entity: media_player.avr_wohnzimmer_2
        show_name: false
        show_entity_picture: true
        entity_picture: /local/logos/xbox.png
        tap_action:
          action: call-service
          service: media_player.select_source
          data:
            source: XBox
          target:
            entity_id: media_player.avr_wohnzimmer_2
        hold_action:
          action: more-info
        styles:
          card:
            - border-radius: 10px
            - height: 60px
            - padding: 12px
            - background: |
                [[[
                  // Aktiv (grün), wenn der AVR an ist und Quelle "XBox" gewählt ist
                  const on = entity && entity.state && entity.state !== 'off' && entity.state !== 'idle';
                  const src = (entity?.attributes?.source || '').toLowerCase();
                  return (on && src.includes('xbox'))
                    ? 'linear-gradient(100deg, #4BC67A 0%, #41AA69 100%)'
                    : 'linear-gradient(100deg, #9495E0 0%, #8182C3 100%)';
                ]]]
          entity_picture:
            - width: 70px
            - object-fit: contain
      - type: custom:button-card
        entity: media_player.avr_wohnzimmer_2
        show_name: false
        show_entity_picture: true
        entity_picture: /local/icons/phono.png
        tap_action:
          action: call-service
          service: media_player.select_source
          data:
            source: Phono
          target:
            entity_id: media_player.avr_wohnzimmer_2
        hold_action:
          action: more-info
        styles:
          card:
            - border-radius: 10px
            - height: 60px
            - padding: 12px
            - background: |
                [[[
                  // Aktiv (grün), wenn der AVR an ist und Quelle "Phono" gewählt ist
                  const on = entity && entity.state && entity.state !== 'off' && entity.state !== 'idle';
                  const src = (entity?.attributes?.source || '').toLowerCase();
                  return (on && src.includes('phono'))
                    ? 'linear-gradient(100deg, #4BC67A 0%, #41AA69 100%)'
                    : 'linear-gradient(100deg, #9495E0 0%, #8182C3 100%)';
                ]]]
          entity_picture:
            - width: 36px
            - object-fit: contain
      - type: custom:button-card
        entity: media_player.avr_wohnzimmer_2
        show_name: false
        show_entity_picture: true
        entity_picture: /local/logos/denon_heos.png
        tap_action:
          action: call-service
          service: media_player.select_source
          data:
            source: HEOS Music
          target:
            entity_id: media_player.avr_wohnzimmer_2
        hold_action:
          action: more-info
        styles:
          card:
            - border-radius: 10px
            - height: 60px
            - padding: 12px
            - background: |
                [[[
                  // Aktiv (grün), wenn der AVR an ist und Quelle "Heos" gewählt ist
                  const on = entity && entity.state && entity.state !== 'off' && entity.state !== 'idle';
                  const src = (entity?.attributes?.source || '').toLowerCase();
                  return (on && src.includes('heos'))
                    ? 'linear-gradient(100deg, #4BC67A 0%, #41AA69 100%)'
                    : 'linear-gradient(100deg, #9495E0 0%, #8182C3 100%)';
                ]]]
          entity_picture:
            - width: 70px
            - object-fit: contain
    columns: 4
card_mod:
  style: |
    ha-card {
      border-radius: 25px;
      border: none;
      padding: 15px;
      height: 370px;
      background: linear-gradient(150deg, #4F46A3 0%, #413A86 100%);
      box-shadow: 3px 8px 8px#ABBCB8;
      overflow: visible;
      margin-left: 4px;
    }