šŸ”¹ Card-mod - Super-charge your themes!

Easy to address. As per general card_mod targetting, some times it needs to be broken to the point where the changes happen. In this case, the changes happen under ha-more-info-light, so the following will work. I have included some styling for the brightness silder as well.

  card-mod-more-info-yaml: |
    ha-more-info-info $ more-info-content $ more-info-light $:
      ha-state-control-light-brightness $: |
        ha-control-slider {
          --control-slider-background: red !important;
          --control-slider-color: red !important;
          --control-slider-thickness: 200px;
          --control-slider-border-radius: 9999px;
        }

      ha-state-control-light-brightness $ ha-control-slider $: |
        .slider {
          --handle-size: 0px;
        }
        .slider .slider-track-bar {
          --slider-track-bar-border-radius: 0px;
        }

      light-color-temp-picker $: |
        ha-control-slider {
          --control-slider-background: red !important;
          --control-slider-color: red !important;
          --control-slider-thickness: 200px;
          --control-slider-border-radius: 9999px;
        }

      light-color-temp-picker $ ha-control-slider $: |
        .slider {
          --handle-size: 0px;
        }
        .slider .slider-track-cursor {
          --cursor-size: 3px;
          background: yellow !important;
        }

nice!

I did this with that, and need to add several !important again

    ha-more-info-info $ more-info-content $ more-info-light $:
      ha-state-control-light-brightness $: |
        ha-control-slider {
          --control-slider-thickness: 85px !important;
          --control-slider-border-radius: 0 !important;
        }

      ha-state-control-light-brightness $ ha-control-slider $: |
        .slider .slider-track-bar::after {
          border-radius: 0 !important;
        }

      light-color-temp-picker $: |
        ha-control-slider {
          /*--control-slider-background: red !important;
          --control-slider-color: red !important;*/
          --control-slider-thickness: 85px !important;
          --control-slider-border-radius: 0 !important;
        }

      light-color-temp-picker $ ha-control-slider $: |
        .slider {
          --handle-size: 10px;
        }
        .slider .slider-track-cursor {
          /*--cursor-size: 3px;*/
          /*background: yellow !important;*/
        }
        .slider .slider-track-cursor::after {
          border-radius: 0 !important;
        }

      ha-control-select-menu $: |
        .select-anchor {
          border-radius: 0 !important;
        }

also note the .slider .slider-track-cursor::after for the track handle again.

one thing I really need it that popup balloon to be styled, as currently in my dark themes I cant see that at all, in any popup, so I hope that can be generic… kelvin, color, brightness…

also, its still not applied to all, because check this light with a color wheel:

Add in a selector for light-color-rgb-picker so card_mod has something to find when color picker active. Otherwise it will give up and then stop all further searches when things change.

Without this, you will see it picks up the change if you don’t stay on color picker for long. But if you pause, then card_mod sill stop further searches.

  card-mod-more-info-yaml: |
    ha-more-info-info $ more-info-content $ more-info-light $:
      ha-state-control-light-brightness $: |
        ha-control-slider {
          --control-slider-thickness: 85px !important;
          --control-slider-border-radius: 0 !important;
        }

      ha-state-control-light-brightness $ ha-control-slider $: |
        .slider .slider-track-bar::after {
          border-radius: 0 !important;
        }

      light-color-temp-picker $: |
        ha-control-slider {
          /*--control-slider-background: red !important;
          --control-slider-color: red !important;*/
          --control-slider-thickness: 85px !important;
          --control-slider-border-radius: 0 !important;
        }

      light-color-temp-picker $ ha-control-slider $: |
        .slider {
          --handle-size: 10px;
        }
        .slider .slider-track-cursor {
          /*--cursor-size: 3px;*/
          /*background: yellow !important;*/
        }
        .slider .slider-track-cursor::after {
          border-radius: 0 !important;
        }

      light-color-rgb-picker $: |
        .color-container {
          /* nothing specific */
        }

Style .tooltip which is silbling to .slider. So add .tooltip whereever you have .slider.

E.g.

for brightness

  card-mod-more-info-yaml: |
    ha-more-info-info $ more-info-content $ more-info-light $:
      ha-state-control-light-brightness $: |
        ha-control-slider {
          --control-slider-thickness: 85px !important;
          --control-slider-border-radius: 0 !important;
        }

      ha-state-control-light-brightness $ ha-control-slider $: |
        .slider .slider-track-bar::after {
          border-radius: 0 !important;
        }
        .tooltip {
          border-radius: 0 !important;
          color: red !important;
          background: black !important;
        }

At ha-control-select element style the variables --control-select-border-radius and --control-select-button-border-radius. There are other --control-select-... vars like --control-select-thickness, --control-select-background and --control-select-background-opacity

Not sure if its my formatting but none of this new code will work for me. Feel like it might be bad formatting cuz it stopped working after pasting in the new code…

It’s alot of code maybe that’s why and I could just simplify it I just don’t know how too.

  card-mod-more-info-yaml: |
    ha-more-info-info $ more-info-content $ more-info-light $:
      ha-state-control-light-brightness $: |
        ha-control-slider {
          --control-slider-thickness: 170px !important;
          --control-slider-border-radius: 9999px !important;
        }

      ha-state-control-light-brightness $ ha-control-slider $: |
        .slider .slider-track-bar::after {
          border-radius: 9999px !important;
        }
        .tooltip {
          border-radius: 12px !important;
          color: red !important;
          background: black !important;
        }

      light-color-temp-picker $: |
        ha-control-slider {
          /*--control-slider-background: red !important;
          --control-slider-color: red !important;*/
          --control-slider-thickness: 170px !important;
          --control-slider-border-radius: 9999px !important;
        }

      light-color-temp-picker $ ha-control-slider $: |
        .slider {
          --handle-size: 5px;
        }
        .slider .slider-track-cursor {
          /*--cursor-size: 3px;*/
          /*background: yellow !important;*/
        }
        .slider .slider-track-cursor::after {
          border-radius: 30px !important;
        }

      light-color-rgb-picker $: |
        .color-container {
          /* nothing specific */
        }

    ha-more-info-info $ more-info-content $ more-info-light $ ha-more-info-light-favorite-colors $: |
      .container {
        flex-wrap: nowrap !important;
        overflow-x: scroll !important;
        justify-content: flex-start !important;
      }

    ha-more-info-info $ more-info-content $ more-info-light $ ha-control-select-menu $: |
      .select-anchor {
        border-radius: 30px !important;
      }

    ha-more-info-info $ more-info-content $ more-info-input_boolean $ ha-state-control-toggle $: |
      ha-control-switch  {
        --control-switch-border-radius: 9999px !important;
        --control-switch-thickness: 170px !important;
      }

    ha-more-info-info $ more-info-content $ more-info-fan $ ha-state-control-fan-speed $: |
      ha-control-slider {
        --control-slider-border-radius: 9999px !important;
        --control-slider-thickness: 170px !important;
      }

    ha-more-info-info $ more-info-content $ more-info-fan $ ha-state-control-fan-speed $ ha-control-slider $: |
      .slider .slider-track-bar {
        --slider-track-bar-border-radius: 9999px !important;
      }

    ha-more-info-info $ more-info-content $ more-info-fan $ ha-control-select-menu $: |
      .select-anchor {
        border-radius: 9999px !important;
      }

    ha-more-info-info $ more-info-content $ more-info-fan $ ha-state-control-fan-speed $ ha-control-slider $: |
      .slider .slider-track-bar::after {
        border-radius: 9999px !important;
      }

    ha-more-info-info $ more-info-content $ more-info-siren $ ha-state-control-toggle $: |
      ha-control-switch {
        --control-switch-border-radius: 9999px !important;
        --control-switch-thickness: 170px !important;
      }

nice, adding card-background-color there helps:

        .tooltip {
          border-radius: 0 !important;
          /*color: var(--primary-text-color) !important;*/
          background: var(--card-background-color) !important;
        }

had a hard time finding something actually useful there… :wink:

      light-color-rgb-picker $: |
        .native-color-picker {
          color: var(--primary-color) !important;
        }

works though, might become a bit complex for fixing that UI, but it gets the job done

also did some reorganizing the syntax, so it becomes easier to see which modification belongs to which element, and takes out all of the double paths…

  card-mod-more-info-yaml: |

    ha-more-info-info $ more-info-content $:

      more-info-light $:

        ha-state-control-light-brightness $: |
          ha-control-slider {
            --control-slider-thickness: 85px !important;
            --control-slider-border-radius: 0 !important;
          }

        ha-state-control-light-brightness $ ha-control-slider $: |
          .slider .slider-track-bar::after {
            border-radius: 0 !important;
          }
          .tooltip {
            border-radius: 0 !important;
            /*color: var(--primary-text-color) !important;*/
            background: var(--card-background-color) !important;
          }

        light-color-rgb-picker $: |
          .native-color-picker {
            color: var(--primary-color) !important;
          }

        light-color-temp-picker $: |
          ha-control-slider {
            /*--control-slider-background: red !important;
            --control-slider-color: red !important;*/
            --control-slider-thickness: 85px !important;
            --control-slider-border-radius: 0 !important;
          }

        light-color-temp-picker $ ha-control-slider $: |
          .slider {
            --handle-size: 4px;
          }
          .slider .slider-track-cursor {
            --cursor-size: 14px !important;
            /*background: yellow !important;*/
          }
          .slider .slider-track-cursor::after {
            border-radius: 0 !important;
          }
          .tooltip {
            border-radius: 0 !important;
            /*color: var(--primary-text-color) !important;*/
            background: var(--card-background-color) !important;
          }

        ha-control-select-menu $: |
          .select-anchor {
            border-radius: 0 !important;
          }

      more-info-input_boolean $:

        ha-state-control-toggle $: |
          ha-control-switch {
            --control-switch-border-radius: 0 !important;
            --control-switch-thickness: 85px !important;
          }

      more-info-siren $:

        ha-state-control-toggle $: |
          ha-control-switch {
            --control-switch-border-radius: 0 !important;
            --control-switch-thickness: 85px !important;
          }

      more-info-fan $:

        ha-control-select-menu $: |
          .select-anchor {
            border-radius: 0 !important;
          }
        ha-state-control-fan-speed $: |
          ha-control-slider {
            --control-slider-border-radius: 0 !important;
            --control-slider-thickness: 85px !important;
          }

        ha-state-control-fan-speed $ ha-control-slider $: |

          .slider .slider-track-bar::after {
            border-radius: 0 !important; /* --slider-track-bar-border-radius*/
          }
          .tooltip {
            border-radius: 0 !important;
            /*color: var(--primary-text-color) !important;*/
            background: var(--card-background-color) !important;
          }

:bulb: Bring a custom layout to Sections dashboard :bulb:

Now card_mod supports Section grid and stack cards, I was thinking if it is possible to bring a custom layout to a Section Dashboard, thus replacing the new for layout-card. Below is my preliminry afternoon’s investigation.

A. Use theme to style card-mod-view. Not mandatory, but makes the main wrapper and container have no padding or margin, so you can style all those with card_mod on the Section you will use on the Dashboard.

Theming for card-mod-view

Here I am using a template to only apply to the view with viewUrlPath of test-layout.

  card-mod-view-yaml: |
    hui-sections-view $: |
      {# card_mod.debug #}
      {% set viewUrlPath = panel.viewUrlPath if 'viewUrlPath' in panel else '' %}
      {% if viewUrlPath == 'test-layout' %}
      .wrapper {
        max-width: unset;
        padding: 0px;
        margin: 0px;
      }
      .wrapper > .container {
        padding: 0px;
        margin: 0px;
      }
      {% endif %}

B. Dashboard YAML. Place a Section, 1 section max wide, edit in Yaml to add the initial code to allow for grid-template-areas etc. My example uses a few areas, with a footer that sticks to the bottom.

Base Section YAML
type: grid
cards: []
card_mod:
  style: |
    .container {
      padding: 0 10px;
      height: calc(100vh - 56px);
      --base-column-count: 1;
    }
    @media (min-width: 601px) 
    {
      .container {
        grid-template-columns: 2fr 2fr 2fr 2fr 2fr 2fr;
        grid-template-rows: min-content min-content 1fr min-content;
        grid-template-areas: 'title title title title title title' 
                            'a a b b b b'
                            'z z z z z z'
                            'footer footer footer footer footer footer';
      }
    }
    @media (max-width: 600px) 
    {
      .container {
        grid-template-columns: 1fr;
        grid-template-rows: min-content min-content min-content 1fr min-content;
        grid-template-areas: 'title' 
                             'b' 
                             'a'
                             'z'
                             'footer';
      }
    }
    div.card:has(.area-title) {
      grid-area: title;
    }
    div.card:has(.area-a) {
      grid-area: a;
    }
    div.card:has(.area-b) {
      grid-area: b;
    }
    div.card:has(.area-footer) {
      grid-area: footer;
    }

C. Add some container cards or just a single card. Container cards card_mod supports are grid and vertical-stack and horizontal-stack. For the card you add, use card_mod to set a class that matches the div.card:has(.area-X). e.g. in my example I have area-title matching grid-template-area title. Use whatever suits.

Example also shows the footer as a horizontal-stack that switches to vertical on small screen width.

Cards
  - type: heading
    heading: New section
    heading_style: title
    card_mod:
      class: area-title
  - square: false
    type: grid
    cards:
      - type: markdown
        content: Grid - A
    columns: 1
    card_mod:
      class: area-a
  - type: vertical-stack
    cards:
      - type: markdown
        content: Vertical Stack - B
      - type: tile
        entity: sensor.backup_backup_manager_state
        vertical: false
        features_position: bottom
    card_mod:
      class: area-b
  - type: horizontal-stack
    cards:
      - type: markdown
        content: Footer - Horizontal Stack
      - type: markdown
        content: Footer
      - type: markdown
        content: Footer
    card_mod:
      class: area-footer
      style: |
        @media (max-width: 600px) {
          #root {
            flex-direction: column;
          }
        }

Putting it all together

Full Section YAML

The main Section is the only card, with all cards within the Section

type: grid
cards:
  - type: heading
    heading: New section
    heading_style: title
    card_mod:
      class: area-title
  - square: false
    type: grid
    cards:
      - type: markdown
        content: Grid - A
    columns: 1
    card_mod:
      class: area-a
  - type: vertical-stack
    cards:
      - type: markdown
        content: Vertical Stack - B
      - type: tile
        entity: sensor.backup_backup_manager_state
        vertical: false
        features_position: bottom
    card_mod:
      class: area-b
  - type: horizontal-stack
    cards:
      - type: markdown
        content: Footer - Horizontal Stack
      - type: markdown
        content: Footer
      - type: markdown
        content: Footer
    card_mod:
      class: area-footer
      style: |
        @media (max-width: 600px) {
          #root {
            flex-direction: column;
          }
        }
card_mod:
  style: |
    .container {
      padding: 0 10px;
      height: calc(100vh - 56px);
      --base-column-count: 1;
    }
    @media (min-width: 601px) 
    {
      .container {
        grid-template-columns: 2fr 2fr 2fr 2fr 2fr 2fr;
        grid-template-rows: min-content min-content 1fr min-content;
        grid-template-areas: 'title title title title title title' 
                            'a a b b b b'
                            'z z z z z z'
                            'footer footer footer footer footer footer';
      }
    }
    @media (max-width: 600px) 
    {
      .container {
        grid-template-columns: 1fr;
        grid-template-rows: min-content min-content min-content 1fr min-content;
        grid-template-areas: 'title' 
                             'b' 
                             'a'
                             'z'
                             'footer';
      }
    }
    div.card:has(.area-title) {
      grid-area: title;
    }
    div.card:has(.area-a) {
      grid-area: a;
    }
    div.card:has(.area-b) {
      grid-area: b;
    }
    div.card:has(.area-footer) {
      grid-area: footer;
    }
Full Dashboard view YAML
type: sections
title: Test Layout
path: test-layout
max_columns: 1
sections:
  - type: grid
    cards:
      - type: heading
        heading: New section
        heading_style: title
        card_mod:
          class: area-title
      - square: false
        type: grid
        cards:
          - type: markdown
            content: Grid - A
        columns: 1
        card_mod:
          class: area-a
      - type: vertical-stack
        cards:
          - type: markdown
            content: Vertical Stack - B
          - type: tile
            entity: sensor.backup_backup_manager_state
            vertical: false
            features_position: bottom
        card_mod:
          class: area-b
      - type: horizontal-stack
        cards:
          - type: markdown
            content: Footer - Horizontal Stack
          - type: markdown
            content: Footer
          - type: markdown
            content: Footer
        card_mod:
          class: area-footer
          style: |
            @media (max-width: 600px) {
              #root {
                flex-direction: column;
              }
            }
    card_mod:
      style: |
        .container {
          padding: 0 10px;
          height: calc(100vh - 56px);
          --base-column-count: 1;
        }
        @media (min-width: 601px) 
        {
          .container {
            grid-template-columns: 2fr 2fr 2fr 2fr 2fr 2fr;
            grid-template-rows: min-content min-content 1fr min-content;
            grid-template-areas: 'title title title title title title' 
                                'a a b b b b'
                                'z z z z z z'
                                'footer footer footer footer footer footer';
          }
        }
        @media (max-width: 600px) 
        {
          .container {
            grid-template-columns: 1fr;
            grid-template-rows: min-content min-content min-content 1fr min-content;
            grid-template-areas: 'title' 
                                 'b' 
                                 'a'
                                 'z'
                                 'footer';
          }
        }
        div.card:has(.area-title) {
          grid-area: title;
        }
        div.card:has(.area-a) {
          grid-area: a;
        }
        div.card:has(.area-b) {
          grid-area: b;
        }
        div.card:has(.area-footer) {
          grid-area: footer;
        }
cards: []

This may be starter for what you want in a Section coming from layout_card, be it simply to adjust card order when on small screen etc.

If you have any question on possibilities, I am very happy to discuss further.

Screenshots of example


Not sure if it is the issue, but you will be best to move these under ha-more-info-info $ more-info-content $ more-info-light $:

Perhaps related to card-mod-themes, if not editable via normal theme,

but wth is the black color coming from nowadays in header and footer of restart window?

image

computed color

image

but

striked out, that means overwritten. But from where, why and how?

image

from shadow root is not helpful either.

@Mariusthvdb , Thanks a lot I was thinking that as .type-clock is also a class, it was possble to use it.
No I don’t have so many clock in ma dashboards but it was a simple example :-). I also use Card_mod with streamline to minimize the code and to factorize sure.
Thanks a lot.

So uh figured it out with the help of Gemini and even styled normal switch entities, thank you guys.

Apparently it said I was calling the same path multiple times which was throwing it off and why it wasn’t working so it simplified that part… oops lol

  card-mod-more-info-yaml: |
    # --- LIGHT DOMAIN CONTROLS ---
    ha-more-info-info $ more-info-content $ more-info-light $:
      # 1. Brightness Slider
      ha-state-control-light-brightness $: |
        ha-control-slider {
          --control-slider-thickness: 170px !important;
          --control-slider-border-radius: 9999px !important;
        }
      
      # 2. Brightness Slider Internals
      ha-state-control-light-brightness $ ha-control-slider $: |
        .slider .slider-track-bar::after {
          border-radius: 9999px !important;
        }
        .tooltip {
          border-radius: 12px !important;
          color: gold !important;
          background: var(--card-background-color) !important;
        }

      # 3. Color Temp Slider
      light-color-temp-picker $: |
        ha-control-slider {
          --control-slider-thickness: 170px !important;
          --control-slider-border-radius: 9999px !important;
        }

      # 4. Color Temp Slider Internals
      light-color-temp-picker $ ha-control-slider $: |
        .slider {
          --handle-size: 10px !important;
        }
        .slider .slider-track-cursor::after {
          border-radius: 30px !important;
        }

      # 5. RGB Picker
      light-color-rgb-picker $: |
        .native-color-picker {
          color: var(--primary-color) !important;
        }

      # 6. Favorite Colors
      ha-more-info-light-favorite-colors $: |
        .container {
          flex-wrap: nowrap !important;
          overflow-x: scroll !important;
          justify-content: flex-start !important;
        }

      # 7. Light Effect Select Menu
      ha-control-select-menu $: |
        .select-anchor {
          border-radius: 30px !important;
        }

    # --- TOGGLE / INPUT BOOLEAN ---
    ha-more-info-info $ more-info-content $ more-info-input_boolean $ ha-state-control-toggle $: |
      ha-control-switch  {
        --control-switch-border-radius: 9999px !important;
        --control-switch-thickness: 170px !important;
      }

    # --- FAN DOMAIN CONTROLS ---
    ha-more-info-info $ more-info-content $ more-info-fan $:
      # 1. Fan Speed Control
      ha-state-control-fan-speed $: |
        ha-control-slider {
          --control-slider-border-radius: 9999px !important;
          --control-slider-thickness: 170px !important;
        }

      # 2. Fan Speed Slider Internals (MERGED BOTH SECTIONS HERE)
      ha-state-control-fan-speed $ ha-control-slider $: |
        .slider .slider-track-bar {
          --slider-track-bar-border-radius: 9999px !important;
        }
        .slider .slider-track-bar::after {
          border-radius: 9999px !important;
        }

      # 3. Fan Preset Menu
      ha-control-select-menu $: |
        .select-anchor {
          border-radius: 9999px !important;
        }

    # --- SIREN DOMAIN CONTROLS ---
    ha-more-info-info $ more-info-content $ more-info-siren $ ha-state-control-toggle $: |
      ha-control-switch {
        --control-switch-border-radius: 9999px !important;
        --control-switch-thickness: 170px !important;
      }

    # --- SWITCH DOMAIN CONTROLS ---
    ha-more-info-info $ more-info-content $ more-info-switch $ ha-state-control-toggle $: |
      ha-control-switch {
        --control-switch-border-radius: 9999px !important;
        --control-switch-thickness: 170px !important;
      }

Nice, good to Gemini is switched on in this regards :wink:

did you see the edit I did in my post above, effectively tightening those selectors :wink:

you got to be careful as there are so many modifications now, broking 1 can break them all…

side note: got to be honest, I do see some animation on the mods kicking in. would be so much beter if we could use theme vars for the features set once, and apply to all. especially those border radius and thickness, which seem generic to all elements

Strange one - a quick look at code and I can’t explain. In Chrome you can hover over the computed color and get an arrow to click through to where CSS value is computed.

Yes, this is, what I tried well and and it is pointing only to the striked out and the cancastext above in the screenshot.

OK. It should go to the slot where class is .header-title with color: var(--ha-dialog-header-title-color, var(--primary-text-color));

in my search to generically style this headers, I had set

    ha-dialog-header-title-color: var(--primary-text-color)

in my generic theme settings, just this morning…

returning this in combination with the mods we did earlier

no such thing as coincidence…

its a pity it doesnt immediately set the x there, so that requires yet another mod, if seen from the restart dialogs

Is it fixed black on your systems as well? Without any variable?

In general theme? And this is changing the font color of this special dialog?

I’m really wondering if this is really a hard coded color here and I have to mod it or if there is something wring or miss only a fitting theme variable? Esp. as there seem to be one but is striked out at this place

yes, see

ha-dialog-header-title-color: red #var(--primary-text-color)

also on the button-card, which uses the ha-dialog

general, as in the section I use in all my themes

  <<: &generic

    ha-dialog-header-title-color: red #var(--primary-text-color)
    markdown-table-border-color: transparent

#     ha-dialog-surface-background: var(--lovelace-background-linear)
    card-mod-theme: theme-mods