Last active
December 10, 2025 16:45
-
-
Save Mariusthvdb/6e43803973505483a4d418d4e20c0a8b to your computer and use it in GitHub Desktop.
card-mod-themes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ########################################################################################## | |
| # https://community.home-assistant.io/t/card-mod-super-charge-your-themes/212176/419 | |
| # My 'Custom header' card-mod theme: | |
| # - Enables individual color customization for view icons. | |
| # - Provides an optional replacement for the default three-dots options menu. | |
| # - Supports configuration of left-side menu icons, including animations, color schemes, | |
| # and notification badges. | |
| # - Allows definition of custom background images or colors to override the default | |
| # theme background. | |
| # | |
| # https://community.home-assistant.io/t/card-mod-super-charge-your-themes/212176/1236 | |
| # most interface elements are now set using the new Kiosk-mode | |
| # https://github.com/NemesisRE/kiosk-mode | |
| # using Custom sidebar https://github.com/elchininet/custom-sidebar/discussions/163 | |
| # | |
| # @mariusthvdb last_update 20251210 | |
| # versions: | |
| # HA 2025.12.2 | |
| # Kiosk-mode 9.0.2 | |
| # Custom-sidebar 10.7.3 | |
| # Card_mod 4.2.0-beta1 | |
| # Fold-entity-row 2.3.2-dcapslock.3 | |
| # Auto-entities 1.16.1-dcapslock.8 | |
| # | |
| # credits to all mentioned repo code-owners and maintainers without whom none of this | |
| # would be possible, special thanks to @dcapslock for card-mod fixes and development of | |
| # auto-entities and fold-entity-row | |
| # | |
| ########################################################################################## | |
| theme-mods: | |
| ########################################################################################## | |
| # make the Yaml list scroll to a better height, add warning color | |
| # https://github.com/thomasloven/lovelace-card-mod/issues/486 | |
| ########################################################################################## | |
| # requires 4.0.0 | |
| # set a color to the Reload YAML card and make it scrollable | |
| card-mod-developer-tools-yaml: | | |
| developer-yaml-config $ ha-card:nth-of-type(2) $: | | |
| :host slot { | |
| display: block; | |
| padding-top: 5px; | |
| height: 600px; | |
| overflow: scroll; | |
| color: var(--warning-color); | |
| font-weight: 600; | |
| } | |
| # requires 4.0.0, test settings, not yet in use, but functional | |
| # card-mod-config-yaml: | | |
| # .: | | |
| # :host { | |
| # --app-header-background-color: orange; | |
| # --card-background-color: orange; | |
| # --primary-background-color: orange; | |
| # --mdc-text-field-fill-color: lightblue; | |
| # --mdc-select-fill-color: lightblue; | |
| # /*--sidebar-background-color: orange;*/ | |
| # --data-table-background-color: orange; | |
| # --primary-color: purple; | |
| # } | |
| # ha-config-integrations { | |
| # --app-header-background-color: green; | |
| # --card-background-color: green; | |
| # --primary-background-color: green; | |
| # --mdc-text-field-fill-color: lightorange; | |
| # --mdc-select-fill-color: lightorange; | |
| # --sidebar-background-color: green; | |
| # --data-table-background-color: green; | |
| # --primary-color: purple; | |
| # } | |
| # requires 4.0.0 | |
| # card-mod-top-app-bar-fixed: | | |
| # :host { | |
| # --app-header-background-color: orange; | |
| # background-color: orange; | |
| # } | |
| # requires 4.0.0 | |
| # card-mod-developer-tools: | | |
| # :host { | |
| # --app-header-background-color: orange; | |
| # --card-background-color: orange; | |
| # --primary-background-color: orange; | |
| # --mdc-text-field-fill-color: lightblue; | |
| # --mdc-select-fill-color: lightblue; | |
| # /*--sidebar-background-color: orange;*/ | |
| # --data-table-background-color: orange; | |
| # --primary-color: purple; | |
| # --code-editor-gutter-color: lightblue; | |
| # } | |
| # developer-tools-router { | |
| # background-color: orange; | |
| # } | |
| # requires 4.0.0 | |
| card-mod-panel-custom-yaml: | | |
| browser-mod-panel: | | |
| :host { | |
| /* --card-background-color: green;*/ | |
| /*--primary-background-color: green;*/ | |
| --mdc-text-field-fill-color: lightorange; | |
| --mdc-select-fill-color: lightorange; | |
| /*--sidebar-background-color: green;*/ | |
| --data-table-background-color: lightgray; | |
| --primary-text-color: purple; | |
| --secondary-text-color: green; | |
| --ha-config-card-border-radius: var(--ha-card-border-radius); | |
| } | |
| browser-mod-panel $ ha-top-app-bar-fixed $: | | |
| :host { | |
| /* --app-header-background-color: green !important; */ | |
| background: var(--lovelace-background); | |
| } | |
| .mdc-top-app-bar__title { | |
| color: purple; | |
| } | |
| #actions { | |
| color: green !important; | |
| } | |
| .mdc-top-app-bar { | |
| /*color: purple;*/ | |
| background: var(--header-background); | |
| } | |
| # set a left margin on all type section labels (also in folds) and align with | |
| # fold-entity-row label margin (set in theme) | |
| # reduce margin-top above divider to not make section above show taller than fold-entity-row height | |
| # apply styling to the fold-entity-row icon, which now supports ripple (custom edition @dcapslock) | |
| card-mod-row-yaml: | | |
| .: | | |
| :host(.type-section) .divider { | |
| margin-top: 0px; | |
| background-color: var(--primary-color) | |
| } | |
| /* stock type: section */ | |
| :host(.type-section) .label { | |
| margin-left: var(--section-label-margin-left); | |
| color: var(--success-color); | |
| font-style: italic; | |
| } | |
| /* stock type: section inside fold-entity-row */ | |
| :host(.type-fold-entity-row-section:not([role="switch"])) .label { | |
| text-align: center; | |
| color: var(--info-color); | |
| font-style: italic; | |
| } | |
| :host(.type-fold-entity-row-section:not([role="switch"])) .divider { | |
| background: var(--warning-color); | |
| } | |
| ha-icon-button $: | | |
| mwc-icon-button { | |
| --mdc-ripple-color: var(--primary-color); {# defaults to color of icon, with opacity as per vars below #} | |
| --mdc-ripple-hover-opacity: 0.2; {# defaults 0.04 #} | |
| --mdc-ripple-focus-opacity: 0.6; {# defaults 0.12 #} | |
| } | |
| card-mod-glance: | | |
| :host { | |
| transition: none !important; | |
| } | |
| ########################################################################################## | |
| # make badges mask image less obtrusive | |
| # decrease gap in header, between markdowns and badges | |
| ########################################################################################## | |
| card-mod-view-yaml: | | |
| :first-child $: | |
| hui-view-header: | |
| $: | | |
| {# reduce gap between badges and section below #} | |
| .layout { | |
| gap: 8px !important; | |
| } | |
| {# make the overlay at the border of the scroller less obtrusive #} | |
| .badges.scroll { | |
| mask-image: linear-gradient( | |
| 90deg, | |
| transparent 0%, | |
| black 1.5%, | |
| black 98.5%, | |
| transparent 100% | |
| ) !important; | |
| } | |
| {# move badges to the left, remove bigger padding from default | |
| in card-mod-root-yaml with ha-tab-padding-x #} | |
| .badges-scroll hui-view-badges { | |
| --badge-padding: 4px !important; | |
| } | |
| .: | | |
| /* {# card_mod.debug #} */ | |
| {% set feest = is_state('binary_sensor.feest_alerts','on') %} | |
| {% set seizoen = states('sensor.season_astronomical') %} | |
| {% set donker = is_state('binary_sensor.donker_thema','on') %} | |
| {% set extension = '_donker' if donker else '' %} | |
| {% set path = panel.viewUrlPath %} | |
| hui-view { | |
| {% if path == 'welkom' %} | |
| {% if is_state('input_boolean.home_mode_party','on') %} | |
| background: repeat url('/local/modes/party.png'); | |
| {% endif %} | |
| {% elif path in ['weer','buienradar','weer_cams'] %} | |
| {% if is_state('input_boolean.weer_view_background','on') %} | |
| background: | |
| repeat url({{state_attr('camera.buienradar','entity_picture')}}) fixed; | |
| {% endif %} | |
| {% elif path in ['feest','familie_overzicht','kalender'] %} | |
| {% if feest %} background: repeat url('/local/images/balloons.png') fixed; | |
| {% endif %} | |
| {% elif path == 'tijd' %} | |
| background: repeat url('/local/season/{{seizoen}}_2.png') fixed; | |
| {% elif path in ['onderweg','proximity'] %} | |
| background: | |
| center/cover no-repeat url('/local/wallpapers/map{{extension}}.png') fixed; | |
| {% elif path == 'xbox' %} | |
| /*background: | |
| center/cover no-repeat url('/local/xbox/xbox-animated-background.gif') fixed;*/ | |
| {% endif %} | |
| } | |
| hui-view-background { | |
| {% if path == 'plafond_spots' %} | |
| background: center / cover no-repeat url('/local/images/areas/plafond.jpg') fixed; | |
| filter: {{'grayscale()' if is_state('light.plafond','off') else 'none' }} | |
| {% endif %} | |
| } | |
| :host { | |
| {% set panelUrlPath = panel.panelUrlPath if 'panelUrlPath' in panel else '' %} | |
| {% if panelUrlPath == 'ui-utiliteiten' %} | |
| --ha-view-sections-column-max-width: 100%; | |
| {% endif %} | |
| } | |
| ########################################################################################## | |
| # instead of using the theme option on a view, and set dedicated card-mod theme to the | |
| # view, see xxx-background themes at the bottom of this file, we can now, | |
| # (from version 4.0.0), set a generic template on the hui-view in card-mod-view-yaml | |
| # This will be more efficient, as the modifications are less intrusive than reloading | |
| # the full themes. | |
| ########################################################################################## | |
| ########################################################################################## | |
| # to align notification badges on their right side (with the core notification use | |
| # left: calc(var(--app-drawer-width,248px) - 22px); | |
| # transform: translateX(-100%); | |
| # -32px aligns with the middle of the core notification badge, and around that the | |
| # translateX(-50%) centers. | |
| # no more use of complex calculations based on string length in notification. | |
| ########################################################################################## | |
| ########################################################################################## | |
| # most of the sidebar settings are now in custom plugin custom-sidebar | |
| # https://github.com/elchininet/custom-sidebar | |
| # config https://gist.github.com/Mariusthvdb/e41957dc6f66d9764e0480030c9bd386 | |
| ########################################################################################## | |
| card-mod-sidebar-yaml: | | |
| .: | | |
| {%- set alerts = states('sensor.marquee_alerts')|int(0) %} | |
| {% set style_badge_not_expanded %} | |
| position: absolute; | |
| box-sizing: border-box; | |
| min-width: 20px; | |
| border-radius: 24px; | |
| font-weight: 400; | |
| line-height: 20px; | |
| text-align: center; | |
| left: 26px; | |
| font-size: 10px; | |
| bottom: 20px; | |
| padding: 0px 2px; | |
| transform: translateX(-25%); | |
| {% endset %} | |
| {# notification badge on collapsed menu icon #} | |
| :host(:not([expanded])) .menu ha-icon-button:after { | |
| content: "{{- alerts if alerts > 0 }}"; | |
| {{style_badge_not_expanded}} | |
| color: ivory; | |
| background: var(--alert-color); | |
| } | |
| ha-md-list-item$: | | |
| {% set afval = states('sensor.afvalwijzer_vandaag')|default('Geen')|capitalize %} | |
| {% set beweging_buiten = is_state('binary_sensor.camera_beweging_buiten','on') %} | |
| {% set core = is_state('update.home_assistant_core_update','on') %} | |
| {% set noti = states('sensor.config_notifications')|int(0) > 0 %} | |
| {% set feest = is_state('binary_sensor.feest_alerts','on') %} | |
| {% set gereed = is_state('binary_sensor.huis_ramen_deuren_puien_veilig','on') %} | |
| {% set gevaar = is_state('binary_sensor.rook_co_lekkage','on') %} | |
| {% set lek = is_state('binary_sensor.watermeter_leak_detected','on') %} | |
| {% set vent = is_state('input_boolean.ventilate','on') %} | |
| @keyframes blink { 50% { opacity: 0.2; } } | |
| @keyframes spin { from { transform: rotate(0deg); } | |
| to { transform: rotate(360deg); } | |
| } | |
| @keyframes pulse { | |
| 0% { opacity: 0.8; transform: scale(0.2); } | |
| 80% { opacity: 0; transform: scale(1.2); } | |
| 100% { opacity: 0; transform: scale(2.2); } | |
| } | |
| a[href='/ui-data'] { | |
| animation: {{'blink 2.5s ease infinite' if lek else 'none'}}; | |
| } | |
| a[href='/ui-data'] ::slotted(:is(ha-svg-icon, ha-icon)) { | |
| animation: {{'spin 3s infinite linear' if lek else 'none'}}; | |
| } | |
| a[href='/ui-familie'] ::slotted(:is(ha-svg-icon, ha-icon)) { | |
| animation: {{'blink 2s ease infinite,spin 3s infinite linear' if feest | |
| else 'none'}}; | |
| } | |
| {# different animation when not expanded because of spinning badge #} | |
| :host(:not([expanded])) a[href=='/ui-familie'] ::slotted(:is(ha-svg-icon, ha-icon)) { | |
| animation: {{'blink 2.5s ease infinite' if feest else 'none'}}; | |
| } | |
| a[href='/ui-instellingen'] ::slotted(:is(ha-svg-icon, ha-icon)) { | |
| animation: {{'blink 2s ease infinite' if vent else 'none'}}; | |
| } | |
| a[href='/ui-develop'] ::slotted(:is(ha-svg-icon, ha-icon)) { | |
| animation: {{'blink 2s ease infinite' if core or noti else 'none'}}; | |
| } | |
| a[href='/ui-cctv'] { | |
| animation: {{'blink 2.5s ease infinite' if beweging_buiten else 'none'}}; | |
| } | |
| ########################################################################################## | |
| # set classes for card-headers, with and without margin (used for starting entities | |
| # cards with fold-entity-rows) | |
| # https://community.home-assistant.io/t/card-mod-add-css-styles-to-any-lovelace-card/120744/2458 | |
| ########################################################################################## | |
| # style chips in header/footer buttons, and other places in the UI (/config settings etc) | |
| # commenting the section below, because now too powerful for now #} | |
| # also modifies other chips, so back to modifying individual chips in cards #} | |
| card-mod-assist-chip: | | |
| :host { | |
| /*border: 1px solid var(--primary-color); | |
| box-shadow: var(--box-shadow-chip); | |
| --secondary-text-color: var(--primary-color); | |
| --primary-text-color: var(--primary-color); | |
| border-radius: var(--ha-card-border-radius) !important; | |
| --_label-text-weight: bold !important;*/ | |
| } | |
| .leading.icon { | |
| /*justify-content: space-between;*/ | |
| /*margin-left: 0px;*/ | |
| } | |
| # create 'header' like efect on the energy-distribution. | |
| # combine with headers on all other energy cards below | |
| card-mod-grid-section-yaml: | | |
| .type-energy-distribution $ ha-card $: | | |
| .card-header { | |
| background: var(--header-background); | |
| color: var(--text-color-off) !important; | |
| font-size: 20px !important; | |
| padding: 4px 12px !important; | |
| margin: 0 0 16px 0 !important; | |
| } | |
| <<: &card-mod-card-yaml | |
| card-mod-card-yaml: | | |
| hui-buttons-header-footer: | |
| $: | | |
| .divider { | |
| margin: 8px 0 0 0 !important; | |
| } | |
| hui-buttons-header-footer $ hui-buttons-base: | |
| $: | | |
| .ha-scrollbar { | |
| justify-content: space-evenly; | |
| height: 50px; | |
| align-content: center; | |
| /*margin: -16px 0px 0px 0px;*/ | |
| padding: 0 !important; | |
| } | |
| {# commenting the section below, because now in card-mod-assist-chip: #} | |
| {# which is way more generic, so beware this also modifies other chips #} | |
| ha-assist-chip { | |
| /*border: 1px solid var(--primary-color); | |
| border-radius: var(--ha-card-border-radius); | |
| --secondary-text-color: var(--primary-color); | |
| --primary-text-color: var(--primary-color); | |
| --_label-text-weight: bold; | |
| box-shadow: var(--box-shadow-chip);*/ | |
| } | |
| ha-assist-chip state-badge { | |
| /*justify-content: space-between; | |
| margin-left: 4px;*/ | |
| } | |
| .: | | |
| {# create headers like on all other cards in config, | |
| combine with grid-yaml above. | |
| still requires text-color adjustment on the total-energy chip in header #} | |
| :host(:is(.class-header-margin, | |
| .type-energy-devices-graph, | |
| .type-energy-devices-detail-graph, | |
| .type-energy-solar-graph, | |
| .type-energy-water-graph, | |
| .type-energy-sources-table, | |
| .type-power-sources-graph, | |
| .type-energy-usage-graph, | |
| .type-energy-gas-graph)) .card-header, | |
| .class-header-margin .card-header { | |
| background: var(--header-background); | |
| color: var(--text-color-off); | |
| font-weight: 400; | |
| font-size: 20px; | |
| padding: 4px 12px; | |
| margin: 0 0 16px 0px; | |
| } | |
| {# also create header on date-picker, | |
| a bit too tall because ha-card still remains #} | |
| :host(:is(.type-energy-date-selection)) .card-content { | |
| background: var(--header-background); | |
| color: var(--text-color-off); | |
| font-weight: 400; | |
| font-size: 20px; | |
| height: 48px !important; | |
| padding: 0px 12px; | |
| } | |
| :host(:is(.type-energy-date-selection)) ha-card { | |
| background: var(--header-background) !important; | |
| } | |
| {% set kerst = is_state('input_select.theme','Kerst') %} | |
| {# https://community.home-assistant.io/t/card-mod-super-charge-your-themes/212176/2133?u=mariusthvdb #} | |
| :host(.class-heading) .container { | |
| background: var(--header-background); | |
| --ha-heading-card-title-color: var(--text-color-off); | |
| --ha-heading-card-title-font-size: 20px; | |
| --ha-heading-card-title-font-weight: 400; | |
| height: 48px; | |
| padding: 0 12px; | |
| box-shadow: var(--ha-card-box-shadow); | |
| } | |
| :host(.class-heading-alert) .container { | |
| background: var(--alert-background); | |
| --ha-heading-card-title-color: var(--alert-text-color); | |
| --ha-heading-card-title-font-size: 20px; | |
| --ha-heading-card-title-font-weight: 400; | |
| height: 48px; | |
| padding: 0 12px; | |
| } | |
| :host(.class-heading-no-color) .container { | |
| --ha-heading-card-title-font-size: 20px; | |
| --ha-heading-card-title-font-weight: 400; | |
| height: 48px; | |
| padding: 0 12px; | |
| box-shadow: var(--ha-card-box-shadow); | |
| } | |
| :host(.class-header-icon) .card-header .icon { | |
| padding-left: 0; | |
| padding-right: 4px; | |
| /* color: pink; */ | |
| } | |
| :host(.class-header-margin) .card-header, | |
| .class-header-margin .card-header { | |
| background: var(--header-background); | |
| color: var(--text-color-off); | |
| font-weight: 400; | |
| font-size: 20px; | |
| padding: 4px 12px; | |
| margin: 0 0 16px 0px; | |
| } | |
| /*:host(.class-header-margin) ha-card, | |
| ha-card.class-header-margin { | |
| box-shadow: var(--box-shadow); | |
| } | |
| :host(.class-header-margin) ha-card .card-content, | |
| ha-card.class-header-margin .card-content { | |
| max-height: {{states('input_number.max_scroll_hoogte')|int(0)}}px; | |
| overflow-y: scroll; | |
| overflow-x: none; | |
| }*/ | |
| :host(.class-header-margin-no-color) .card-header { | |
| font-weight: 400; | |
| font-size: 20px; | |
| padding: 4px 12px; | |
| margin: 0 0 16px 0px; | |
| } | |
| :host(.class-header-no-margin) .card-header { | |
| background: var(--header-background); | |
| color: var(--text-color-off); | |
| font-weight: 400; | |
| font-size: 20px; | |
| padding: 4px 12px; | |
| margin: 0 0 8px 0px; {# for dcapslock fold-entity-row #} | |
| } | |
| :host(.class-header-no-margin-no-color) .card-header { | |
| font-weight: 400; | |
| font-size: 20px; | |
| padding: 4px 12px; | |
| margin: 0 0 8px 0px; {# for dcapslock fold-entity-row #} | |
| } | |
| :host(.class-clock) ha-card { | |
| background-color: red !important; | |
| border-radius: 20px !important; | |
| } | |
| :host(.type-clock) ha-card { | |
| background-color: red !important; | |
| border-radius: 20px !important; | |
| } | |
| ha-card { | |
| transition: none !important; | |
| overflow: {{'hidden' if is_state('input_boolean.hide_card_overflow','on')}}; | |
| background: {{'repeat url("/local/season/kerst_smurfen.png")' if kerst}}; | |
| } | |
| {{ "ha-card::before | |
| { | |
| content: ''; | |
| background: top / contain no-repeat url('/local/season/snow.png'); | |
| height: 16%; | |
| position: absolute; | |
| left: -1%; | |
| width: 102%; | |
| top: -30px; | |
| }" | |
| if kerst}} | |
| /* {{ "ha-card::after | |
| { | |
| content: ''; | |
| backdrop-filter: blur(20px); | |
| background: top / contain no-repeat url('/local/season/lightchain.png'); | |
| height: 24%; | |
| position: absolute; | |
| width: 100%; | |
| bottom: 48px; | |
| }" | |
| if kerst }} */ | |
| ########################################################################################## | |
| # Set the animation of the currently selected tab icon, color and icon itself are/ | |
| # set below the .: section to prevent background animation | |
| # https://community.home-assistant.io/t/card-mod-super-charge-your-themes/212176/1094 | |
| # https://community.home-assistant.io/t/card-mod-add-css-styles-to-any-lovelace-card/120744/5174 | |
| # https://github.com/thomasloven/lovelace-card-mod/issues/268 | |
| # https://community.home-assistant.io/t/2025-5-two-million-strong-and-getting-better/886760/217?u=mariusthvdb | |
| # https://community.home-assistant.io/t/2025-7-thats-the-question/907169/45?u=mariusthvdb | |
| ########################################################################################## | |
| card-mod-root-yaml: | | |
| .header: | | |
| {# remove action buttons, except the download button in Energy panels, where | |
| Kiosk-mode doesnt apply. Also new Home panel #} | |
| {% set panelUrlPath = panel.panelUrlPath if 'panelUrlPath' in panel else '' %} | |
| {% if panelUrlPath in ['energy','home'] %} | |
| .action-items #button-0 { | |
| display: {{'none' if is_state('input_boolean.hide_add_to_home_assistant','on')}}; | |
| } | |
| .action-items #button-1 { | |
| display: {{'none' if is_state('input_boolean.hide_search','on')}}; | |
| } | |
| .action-items #button-2 { | |
| display: {{'none' if is_state('input_boolean.hide_assistant','on')}}; | |
| } | |
| .action-items #button-3 { | |
| display: {{'none' if is_state('input_boolean.hide_energy_download_button','on')}}; | |
| } | |
| {% endif %} | |
| ha-tab-group-tab { | |
| /*text-transform: uppercase !important;*/ | |
| } | |
| .toolbar { | |
| padding-left: 1px !important; | |
| } | |
| .header ha-tab-group$: | | |
| wa-button[name='chevron-left'], wa-icon[name='chevron-right'] { | |
| display: {{'none' if is_state('input_boolean.toon_chevrons','off')}}; | |
| } | |
| {# Optionally set tab padding per device width. Only mobile. #} | |
| @media (orientation: portrait) and (max-width: 569px) { | |
| :host { | |
| --ha-tab-padding-start: 0.8rem !important; | |
| --ha-tab-padding-end: 0.8rem !important; | |
| } | |
| @media (min-width: 570px) { | |
| :host { | |
| --ha-tab-padding-start: 1.2rem !important; | |
| --ha-tab-padding-end: 1.2rem !important; | |
| } | |
| ha-tab-group-tab[aria-label='Ventilatoren'] ha-icon$: | | |
| ha-svg-icon { | |
| transition: opacity 0.5s; | |
| {% set vent = is_state('input_boolean.ventilate','on') %} | |
| animation: {{'spin 1s infinite linear' if vent else 'none'}} | |
| } | |
| @keyframes spin { | |
| from {transform:rotate(0deg);} | |
| to {transform:rotate(360deg);} | |
| } | |
| ha-tab-group-tab[aria-label='Vijver'] ha-icon$: | | |
| ha-svg-icon { | |
| {% set pomp = is_state('switch.vijverpompen','on') %} | |
| animation: {{'spin 3s infinite linear' if pomp else 'none'}}; | |
| } | |
| @keyframes spin { | |
| from {transform:rotate(0deg);} | |
| to {transform:rotate(360deg);} | |
| } | |
| ha-tab-group-tab[aria-label='Weer'] ha-icon$: | | |
| ha-svg-icon { | |
| {% set alarm = is_state('binary_sensor.meteoalarm_brabant','on') %} | |
| animation: {{'blink 2s ease infinite' if alarm else 'none'}}; | |
| } | |
| @keyframes blink { | |
| 50% {opacity: 0.2;} | |
| } | |
| ha-tab-group-tab[aria-label='Kalender'] ha-icon$: | | |
| ha-svg-icon { | |
| {% set feest = is_state('binary_sensor.feest_alerts','on') %} | |
| animation: {{'spin 3s infinite linear' if feest else 'none'}}; | |
| } | |
| @keyframes spin { | |
| from {transform:rotate(0deg);} | |
| to {transform:rotate(360deg);} | |
| } | |
| ha-tab-group-tab[aria-label='Feest'] ha-icon$: | | |
| ha-svg-icon { | |
| {% set feest = is_state('binary_sensor.feest_alerts','on') %} | |
| animation: {{'spin 3s infinite linear' if feest else 'none'}}; | |
| } | |
| @keyframes spin { | |
| from {transform:rotate(0deg);} | |
| to {transform:rotate(360deg);} | |
| } | |
| ha-tab-group-tab[aria-label='Water'] ha-icon$: | | |
| {% set lek = is_state('binary_sensor.watermeter_leak_detected','on') %} | |
| ha-svg-icon { | |
| animation: {{'spin 3s infinite linear' if lek else 'none'}}; | |
| } | |
| @keyframes spin { | |
| from {transform:rotate(0deg);} | |
| to {transform:rotate(360deg);} | |
| } | |
| ha-tab-group-tab[aria-label='Samenvatting'] ha-icon$: | | |
| ha-svg-icon { | |
| {% set kritiek = states('sensor.hubs_samenvatting')|int(-1) > 0 or | |
| states('sensor.kritieke_schakelaars_samenvatting')|int(-1) > 0 %} | |
| animation: {{'pulse 2s ease 0s infinite normal' if kritiek else 'none'}}; | |
| } | |
| @keyframes pulse { | |
| 0% {opacity: 0.8;transform: scale(0.2);} | |
| 80% {opacity: 0;transform: scale(1.2);} | |
| 100% {opacity: 0;transform: scale(2.2);} | |
| } | |
| .: | | |
| {# center the view tabs when in potrait mode to make 1 column visually #} | |
| @media (orientation: portrait) or (max-width: 850px) { | |
| .toolbar ha-tab-group::part(tabs) { | |
| justify-content: center; | |
| } | |
| } | |
| {% set kerst = is_state('input_select.theme','Kerst') %} | |
| {% set feest = is_state('binary_sensor.feest_alerts','on') %} | |
| {% set lek = is_state('binary_sensor.watermeter_leak_detected','on') %} | |
| {% set vent = is_state('input_boolean.ventilate','on') %} | |
| {% set pomp = is_state('switch.vijverpompen','on') %} | |
| {% set netto = states('sensor.netto_verbruik')|int(0) %} | |
| {% set meteo = is_state('binary_sensor.meteoalarm_brabant','on') %} | |
| {% set alerts = states('sensor.alerts_notifying')|int(0) > 0 %} | |
| {% set motion = is_state('binary_sensor.motion_sensors_all','on') %} | |
| {% set symbol = states('sensor.buienradar_symbol') %} | |
| {% set temp = states('sensor.ws_5500_outdoor_temperature')|default(-100) %} | |
| {% set template = is_state('input_boolean.menu_options_template','on') %} | |
| {% set wekker = is_state('binary_sensor.wekker_voor_morgen','on') %} | |
| {% set donker_thema = is_state('binary_sensor.donker_thema','on') %} | |
| {% set verwarming = is_state('binary_sensor.opentherm_heating','on') or | |
| is_state('binary_sensor.mill_heater_aan','on') %} | |
| {# Hide the first button +, now in Kiosk-mode #} | |
| /* ha-button-menu:nth-of-type(1) { | |
| display: none; | |
| } */ | |
| {# Set the three-dots transparency, to allow replacement template text #} | |
| ha-button-menu:nth-of-type(2) ha-icon-button { | |
| color: {{'transparent' if template}}; | |
| pointer-events: {{'none' if template}}; | |
| display: inline-flex; {# required in Safari to center the text, Chrome ok without #} | |
| cursor: context-menu; {# set here, because doesnt work in the ::after pseudo-element below #} | |
| /* background: yellow; */ {# test to see the element #} | |
| } | |
| {# Optionally set a replacement template text #} | |
| ha-button-menu:nth-of-type(2) ha-icon-button::after { | |
| content: "{%- set sym = symbol|truncate(21,False,'') -%} | |
| {%- if template -%} {{- sym}} | {{temp}} °C | |
| {%- endif -%}"; | |
| color: {{'var(--app-header-text-color)' if donker else 'var(--primary-color)'}}; | |
| /* visibility: visible; */ {# no longer required? #} | |
| /* position: absolute; */ {# no longer required? #} | |
| pointer-events: auto; | |
| /* cursor: context-menu; */ {# doesnt work here, so set it in actual element above... #} | |
| /* right: 0;*/ {# no longer required? #} | |
| align-self: center; | |
| /* white-space: nowrap; */ {# no longer required? #} | |
| /* background: orange; */ {# test to see the element #} | |
| } | |
| {# Set the toolbar background and generic icon color #} | |
| .header, .toolbar { | |
| background: {%- if kerst -%} url('/local/wallpapers/snow.mp4') | |
| {%- elif donker_thema -%} var(--lovelace-background) | |
| {%- else -%} var(--header-background); | |
| {%- endif -%}; | |
| color: var(--app-header-text-color); | |
| } | |
| ha-tab-group-tab:hover { | |
| --icon-primary-color: var(--primary-color); | |
| background: var(--lovelace-background); | |
| } | |
| {# Set the color of the currently selected tab | |
| Set size of the currently selected tab icon #} | |
| ha-tab-group-tab[aria-selected=true] { | |
| --ha-tab-active-text-color: oklch(from var(--primary-color) calc(l + .5) c h); | |
| border: 1px solid var(--primary-color); | |
| /*background: var(--lovelace-background);*/ | |
| --mdc-icon-size: {{states('input_number.active_icon_size')|int(24)}}px; | |
| height: calc(var(--header-height) - 2px); | |
| display: flex; | |
| } | |
| {# This hides the help button when in edit mode #} | |
| a.menu-link[target='_blank'] { | |
| {% if is_state('input_boolean.hide_edit_mode_help','on') %} | |
| visibility: hidden; | |
| margin-right: -30px; | |
| {% endif %} | |
| } | |
| {# Dynamically set the color and icons of individual tabs #} | |
| ha-tab-group-tab[aria-label='Wekker instellingen'] { | |
| color: {{'var(--alert-color)' if wekker else 'var(--success-color)'}}; | |
| } | |
| ha-tab-group-tab[aria-label='Welkom'] { | |
| --card-mod-icon: {{'mdi:home-alert' if alerts }}; | |
| /* background: url('/local/devices/hue_home.png'); */ | |
| color: {{'var(--alert-color)' if alerts else 'var(--success-color)'}}; | |
| } | |
| ha-tab-group-tab[aria-label='Samenvatting'] { | |
| {%- if states('sensor.hubs_samenvatting')|int(-1) > 0 or | |
| states('sensor.kritieke_schakelaars_samenvatting')|int(-1) > 0 %} | |
| --card-mod-icon: mdi:alert; | |
| color: var(--alert-color); | |
| {%- endif %} | |
| } | |
| ha-tab-group-tab[aria-label='Beweging'] { | |
| --card-mod-icon: {{'mdi:motion-sensor' if motion}}; | |
| color: {{'var(--alert-color)' if motion}}; | |
| } | |
| ha-tab-group-tab[aria-label='Alarm'] { | |
| --card-mod-icon: {{states('sensor.alarm_panel_icon')|default('mdi:help')}}; | |
| color: {{states('sensor.alarm_panel_icon_color')|default('pink')}}; | |
| } | |
| ha-tab-group-tab[aria-label='Verwarming'] { | |
| --card-mod-icon: mdi:{{'radiator' if verwarming else 'radiator-off'}}; | |
| color: {{'var(--alert-color)' if verwarming}}; | |
| } | |
| ha-tab-group-tab[aria-label='Frontend'] { | |
| /*--card-mod-icon-color: url('/local/gradients/gradients.svg#linearBackgroundLight'); | |
| background: var(--rainbow-radial); | |
| /* Clip the background to the text shape */ | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent;*/ | |
| } | |
| ha-tab-group-tab[aria-label='Updates'] { | |
| {%- set update = integration_entities('hacs') | |
| |select('search','update.') | |
| |select('is_state','on')|list|count > 0 or | |
| is_state('update.home_assistant_core_update','on') %} | |
| --card-mod-icon: mdi:package{{'-up' if update}}; | |
| color: {{'var(--alert-color)' if update }}; | |
| } | |
| ha-tab-group-tab[aria-label='Kalender'] { | |
| --card-mod-icon: {{'mdi:party-popper' if feest}}; | |
| color: {{'var(--warning-color)' if feest else | |
| states('sensor.afval_kleur') if states('sensor.afval_kleur') != 'gray' | |
| else 'var(--alert-color)' if wekker}}; | |
| } | |
| ha-tab-group-tab[aria-label='Familie overzicht'] { | |
| color: {{states('sensor.presence_color')|default('pink')}}; | |
| } | |
| ha-tab-group-tab[aria-label='Feest'] { | |
| color: {{'var(--warning-color)' if feest}}; | |
| } | |
| ha-tab-group-tab[aria-label='Klimaat'] { | |
| color: {{states('sensor.inside_temperature_color_name')|default('pink')}}; | |
| } | |
| ha-tab-group-tab[aria-label='Rolluiken'] { | |
| --card-mod-icon: mdi:window-shutter{{'-alert' if | |
| not has_value('cover.slaapkamers') | |
| else '-open' if is_state('cover.slaapkamers','open')}}; | |
| } | |
| ha-tab-group-tab[aria-label='Verlichting'] { | |
| {% set lampen = states('sensor.lampen_samenvatting')|int(-1) %} | |
| --card-mod-icon: mdi:lightbulb-group{{'-off' if lampen == 0 }}; | |
| color: {{'var(--active-color)' if lampen > 0 }}; | |
| /* background: {{'var(--hover-color)' if lampen > 0 }}; */ | |
| } | |
| ha-tab-group-tab[aria-label='Weer'] { | |
| --card-mod-icon: {{states('sensor.meteoalarm_icon') | |
| if meteo else states('sensor.weather_icon')}}; | |
| color: {{'var(--alert-color)' if meteo else | |
| states('sensor.temperature_color_name')}}; | |
| } | |
| ha-tab-group-tab[aria-label='Energie'] { | |
| color: {{'brown' if netto >= 0 else 'var(--power-color)'}}; | |
| } | |
| ha-tab-group-tab[aria-label='Zonne-energie'] { | |
| color: {{'var(--power-color)' if netto < 0}}; | |
| } | |
| ha-tab-group-tab[aria-label='Water'] { | |
| --card-mod-icon: {{'mdi:pipe-leak' if lek}}; | |
| color: {%- if lek %} var(--alert-color) | |
| {%- elif is_state('binary_sensor.watermeter_update_available','on') %} | |
| blue | |
| {%- endif %}; | |
| } | |
| ha-tab-group-tab[aria-label='Ventilatoren'] { | |
| color: {{'var(--alert-color)' if vent }}; | |
| } | |
| ha-tab-group-tab[aria-label='Vijver'] { | |
| color: {{'lightseagreen' if pomp}}; | |
| } | |
| ha-tab-group-tab[aria-label='Tijd'] { | |
| --card-mod-icon: {{state_attr('sensor.hour_icon','icon')}}; | |
| color: {{'var(--state-sun-below_horizon-color)' | |
| if is_state('binary_sensor.donker_buiten','on') else | |
| 'deepskyblue'}}; | |
| } | |
| ha-tab-group-tab[aria-label='Home Assistant'] { | |
| color: var(--ha-color); | |
| } | |
| ########################################################################################## | |
| # modify the more-info dialog, breadcrumbs and set a blur | |
| ########################################################################################## | |
| card-mod-more-info-yaml: | | |
| ha-dialog-header: | | |
| {# adding this, because Kiosk-mode does not apply to /config dashboards #} | |
| .breadcrumb { | |
| {% if is_state('input_boolean.hide_dialog_header_breadcrumb_navigation','on') %} | |
| display: none !important | |
| {% endif %}; | |
| } | |
| ha-more-info-info $ more-info-content $: | |
| more-info-input_boolean,more-info-switch,more-info-siren $: | |
| ha-state-control-toggle $: | | |
| ha-control-switch { | |
| --control-switch-border-radius: var(--border-radius-square) !important; | |
| --control-switch-thickness: var(--more-info-control-thickness) !important; | |
| } | |
| more-info-fan $: | |
| ha-control-select-menu $: | | |
| .select-anchor { | |
| border-radius: var(--border-radius-square) !important; | |
| } | |
| ha-state-control-fan-speed $: | | |
| ha-control-slider { | |
| --control-slider-border-radius: var(--border-radius-square) !important; | |
| --control-slider-thickness: var(--more-info-control-thickness) !important; | |
| } | |
| ha-state-control-fan-speed $ ha-control-slider $: | | |
| .slider .slider-track-bar::after { | |
| border-radius: var(--border-radius-square) !important; /* --slider-track-bar-border-radius*/ | |
| } | |
| .tooltip { | |
| border-radius: var(--border-radius-square) !important; | |
| background: var(--card-background-color) !important; | |
| /*color: var(--primary-text-color) !important;*/ | |
| } | |
| more-info-alarm_control_panel $: | |
| ha-state-control-alarm_control_panel-modes $: | | |
| ha-control-select { | |
| --control-select-border-radius: var(--border-radius-square) !important; | |
| --control-select-thickness: var(--more-info-control-thickness) !important; | |
| } | |
| more-info-cover $: | |
| ha-state-control-cover-position $: | | |
| ha-control-slider { | |
| --control-slider-border-radius: var(--border-radius-square) !important; | |
| --control-slider-thickness: var(--more-info-control-thickness) !important; | |
| } | |
| ha-state-control-cover-position $ ha-control-slider $: | | |
| .slider .slider-track-bar::after { | |
| border-radius: var(--border-radius-square) !important; /* --slider-track-bar-border-radius*/ | |
| } | |
| .tooltip { | |
| border-radius: var(--border-radius-square) !important; | |
| background: var(--card-background-color) !important; | |
| /*color: var(--primary-text-color) !important;*/ | |
| } | |
| more-info-light $: | |
| ha-state-control-light-brightness $: | | |
| ha-control-slider { | |
| --control-slider-border-radius: var(--border-radius-square) !important; | |
| --control-slider-thickness: var(--more-info-control-thickness) !important; | |
| } | |
| ha-state-control-light-brightness $ ha-control-slider $: | | |
| .slider .slider-track-bar::after { | |
| border-radius: var(--border-radius-square) !important; | |
| } | |
| .tooltip { | |
| border-radius: var(--border-radius-square) !important; | |
| background: var(--card-background-color) !important; | |
| /*color: var(--primary-text-color) !important;*/ | |
| } | |
| light-color-rgb-picker $: | | |
| .native-color-picker { | |
| color: var(--primary-color) !important; | |
| } | |
| light-color-temp-picker $: | | |
| ha-control-slider { | |
| --control-slider-border-radius: var(--border-radius-square) !important; | |
| --control-slider-thickness: var(--more-info-control-thickness) !important; | |
| /*--control-slider-background: red !important; | |
| --control-slider-color: red !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: var(--border-radius-square) !important; | |
| } | |
| .tooltip { | |
| border-radius: var(--border-radius-square) !important; | |
| background: var(--card-background-color) !important; | |
| /*color: var(--primary-text-color) !important;*/ | |
| } | |
| ha-control-select-menu $: | | |
| .select-anchor { | |
| border-radius: var(--border-radius-square) !important; | |
| } | |
| $: | | |
| .mdc-dialog { | |
| backdrop-filter: blur(17px) !important; | |
| -webkit-backdrop-filter: blur(17px) !important; | |
| } | |
| .mdc-dialog .mdc-dialog__content { | |
| /*padding: var(--dialog-content-padding, 24px);*/ | |
| } | |
| ########################################################################################## | |
| # modify ha-dialog, ha-md-dialog, ha-wa-dialog (will be some in 2025.11) or ha-drawer | |
| # card-mod theme variable is card-mod-dialog and class applied to dialog element is the | |
| # parent element with any ha- stripped off, then prefix with type (similar to cards). | |
| # e.g. hui-dialog-create-card will have class type-dialog-create-card. | |
| ########################################################################################## | |
| card-mod-dialog-yaml: | | |
| $: | | |
| :host(.type-dialog-box) wa-dialog::part(dialog)::backdrop { | |
| backdrop-filter: blur(17px); /* blurs whole screen background */ | |
| } | |
| {% set donker = is_state('binary_sensor.donker_thema','on') %} | |
| {% set titel = params.title if 'title' in params else '' %} | |
| {% set ha = titel == 'Home Assistant herstarten?' %} | |
| {% set sy = titel =='Systeem herstarten?' %} | |
| {% set bkgrnd = 'var(--background-color-off)' if donker else | |
| 'var(--card-background-color)' %} | |
| :host(.type-dialog-box) wa-dialog::part(dialog) { | |
| background: | |
| {% if ha %} linear-gradient(90deg, var(--warning-color) 0%, var(--primary-color) 100%); | |
| {% elif sy %} linear-gradient(90deg, var(--error-color) 0%, var(--primary-color) 100%); | |
| {% else %} var(--lovelace-background-linear); | |
| {% endif %}; | |
| /*{% if ha %} var(--warning-color) | |
| {% elif sy %} var(--error-color) | |
| {% else %} {{bkgrnd}} | |
| {% endif %};*/ | |
| --primary-text-color: | |
| {% if ha %} white | |
| {% elif sy %} black | |
| {% else %} | |
| {{'var(--text-color-off)' if donker else 'var(--primary-text-color)'}} | |
| {% endif %}; | |
| box-shadow: var(--box-shadow); | |
| } | |
| :host(.type-dialog-restart) { | |
| --card-background-color: none; | |
| --input-fill-color: none; | |
| } | |
| :host(.type-dialog-restart) wa-dialog::part(dialog) { | |
| background: var(--lovelace-background-linear); | |
| } | |
| .: | | |
| .type-quick-bar { | |
| --mdc-theme-surface: var(--header-background); | |
| max-height: {{states('input_number.max_scroll_hoogte')|int(300)}}px; | |
| } | |
| # no longer use below, as al moved to the main dialog modification | |
| # {% set donker = is_state('binary_sensor.donker_thema','on') %} | |
| # {# card_mod.debug #} | |
| # ha-wa-dialog { | |
| # /*--card-background-color: linear-gradient(90deg,rgba(42, 123, 155, 1) 0%, rgba(87, 199, 133, 1) 50%, rgba(237, 221, 83, 1) 100%);*/ | |
| # } | |
| # {% set titel = params.title if 'title' in params else '' %} | |
| # /*{% if titel == 'Home Assistant herstarten?' %} | |
| # ha-wa-dialog.type-dialog-box { | |
| # --card-background-color: var(--warning-color); | |
| # {% elif titel == 'Systeem herstarten?' %} | |
| # ha-wa-dialog.type-dialog-box { | |
| # --card-background-color: var(--alert-color); | |
| # } | |
| # {% endif %}*/ | |
| # | |
| # {% set titel = params.title if 'title' in params else '' %} | |
| # {% set ha = titel == 'Home Assistant herstarten?' %} | |
| # {% set sy = titel =='Systeem herstarten?' %} | |
| # {% set bkgrnd = 'var(--background-color-off)' if donker else | |
| # 'var(--card-background-color)' %} | |
| # ha-wa-dialog.type-dialog-box { | |
| # --card-background-color: | |
| # {% if ha %} var(--warning-color) | |
| # {% elif sy %} var(--error-color) | |
| # {% else %} {{bkgrnd}} | |
| # {% endif %}; | |
| # --primary-text-color: | |
| # {% if ha %} black | |
| # {% elif sy %} white | |
| # {% else %} | |
| # {{'var(--text-color-off)' if donker else 'var(--primary-text-color)'}} | |
| # {% endif %}; | |
| # } | |
| # below background themes no longer used, because with card-mod 4.0.0 we can set | |
| # modifications to the Panel variable like panel.viewUrlPath directly | |
| # see: https://github.com/thomasloven/lovelace-card-mod/tree/v4.0?tab=readme-ov-file#templates | |
| # without anything further, these themed backgrounds break primary-text-color and | |
| # secondary-text-color in themes, because they need to have anything from the base themes | |
| # in the theme itself. | |
| # It does not cascade (or inherit), it gets replaced. Remember this is a view and | |
| # not the document. | |
| # So explicitly declaring them again in the mod themes fixes that | |
| # thanks @dcapslock for helping me out here | |
| # weather-background: | |
| # card-mod-theme: weather-background | |
| # <<: *card-mod-card-yaml | |
| # card-mod-view: | | |
| # {# card_mod.debug #} | |
| # hui-view { | |
| # {% if is_state('input_boolean.weer_view_background','on') %} | |
| # background: repeat url({{state_attr('camera.buienradar','entity_picture')}}) fixed; | |
| # {% endif %} | |
| # } | |
| # <<: &prim_sec | |
| # primary-text-color: var(--primary-text-color) | |
| # secondary-text-color: var(--secondary-text-color) | |
| # | |
| # feest-background: | |
| # card-mod-theme: feest-background | |
| # <<: *card-mod-card-yaml | |
| # card-mod-view: | | |
| # {% set feest = is_state('binary_sensor.feest_alerts','on') %} | |
| # hui-view { | |
| # {% if feest %} background: repeat url('/local/images/balloons.png') fixed; | |
| # {% endif %} | |
| # } | |
| # <<: *prim_sec | |
| # | |
| # seizoen-background: | |
| # card-mod-theme: seizoen-background | |
| # <<: *card-mod-card-yaml | |
| # card-mod-view: | | |
| # hui-view { | |
| # {% set seizoen = states('sensor.season_astronomical') %} | |
| # background: repeat url('/local/season/{{seizoen}}_2.png') fixed; | |
| # } | |
| # <<: *prim_sec | |
| # | |
| # map-background: | |
| # card-mod-theme: map-background | |
| # <<: *card-mod-card-yaml | |
| # card-mod-view: | | |
| # hui-view { | |
| # background: | |
| # {% set donker = is_state('binary_sensor.donker_thema','on') %} | |
| # {% set extension = '_donker' if donker else '' %} | |
| # center/cover no-repeat url('/local/wallpapers/map{{extension}}.png') fixed; | |
| # } | |
| # <<: *prim_sec |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment