How To Keep Card Full Of Text - But Scroll When Text Doesn't Fit - Keeping Card 100% Full Of Text

I have asked this question also on Discord but thought I would try here also…

I am looking to have scrolling text (name of the current playing song) scroll if it doesn’t fit in the text space (card), keeping the space 100% full at all times. In other words, when it scrolls, it only scrolls until the last character is visible. Then it stops scrolling for a brief pause, then scrolls the opposite way until the first character can be seen in the card. Then pause, and repeat… I can’t figure it out.

Attached is the code I have so far that is close but not quite there yet.

Also, one more note, I do not want it to scroll if the text fits the space.

Can anyone help me with this?

sample2

  - type: custom:hui-element
    card_type: vertical-stack
    cards:
      - type: conditional
        conditions:
          - condition: state
            entity: media_player.spotify_plus_colton_2
            state: playing
        card:
          type: custom:html-card
          view_layout:
            position: main
          picture_elements_mode: true
          ignore_line_breaks: true
          content: >
            <div class="scroll-container" style="width: 780px !important;
            height: 45px !important; overflow: hidden !important; white-space:
            nowrap !important; position: relative !important;">
              <div class="scroll-text">
                <span style="color: #1ed760; font-weight: bold !important; font-size: 40px !important; white-space: nowrap !important; display: inline-block !important;" id="scroll-content">[[ sensor.current_song_playing ]]</span>
              </div>
            </div>

            <style>
              .scroll-container {
                width: 780px !important;
                overflow: hidden !important;  /* Important: keep this hidden */
                line-height: 40px !important;
                height: 40px !important;
                background: transparent !important;
                white-space: nowrap !important;
                position: relative !important;
              }

              .scroll-text {
                display: inline-block !important;
                position: relative !important;
                white-space: nowrap !important;
                animation: scroll-left 20s linear infinite; /* Initial animation */
              }

              @keyframes scroll-left {
                0% {
                  transform: translateX(0);
                }
                50% {
                  transform: translateX(-50%);  /* Move all the way to the left */
                }
                100% {
                  transform: translateX(0);  /* Move back to the right */
                }
              }
            </style>

            <script>
              (function() {
                window.addEventListener('load', function() {
                  const scrollContainer = document.querySelector('.scroll-container');
                  const scrollText = document.querySelector('.scroll-text');
                  const scrollContent = document.getElementById('scroll-content');

                  if (scrollContent.scrollWidth > scrollContainer.clientWidth) {
                    // Calculate animation duration based on content width and container width
                    const contentWidth = scrollContent.scrollWidth;
                    const containerWidth = scrollContainer.clientWidth;
                    const scrollDistance = contentWidth + containerWidth; // Total distance to scroll (content + space)
                    const baseDuration = 10; // Base duration in seconds (adjust as needed)
                    const calculatedDuration = baseDuration * (scrollDistance / containerWidth);

                    // Update animation duration
                    scrollText.style.animationDuration = calculatedDuration + 's';

                    // Check if the animation is already running and restart it if needed
                    if (scrollText.style.animationPlayState !== 'running') {
                      scrollText.style.animationPlayState = 'running';
                    }
                  } else {
                    scrollText.style.animation = 'none';
                    scrollText.style.transform = 'translateX(0)'; // Ensure text stays in place if it fits
                    scrollText.style.paddingLeft = '0';
                  }
                });
              })();
            </script>
          card_mod:
            style: |
              ha-card {
                background: none !important;
                padding: 0px !important;
                padding-left: 100%;
                padding-right: 100%;
              }
    style:
      top: 58px
      left: 59.898%

** Update: I was able to get it to scroll to the end and to the beginning like I wanted, but now my problem is, it scrolls even the short text also, which I don’t want. In other words, if the text fits the container, no scrolling, if there is overflow; scrolling back and forth.
clideo_editor_90ec16574d84424f99341a48e0885a79

  - type: custom:hui-element
    card_type: vertical-stack
    cards:
      - type: conditional
        conditions:
          - condition: state
            entity: media_player.spotify_plus_colton_2
            state: playing
        card:
          type: custom:html-card
          view_layout:
            position: main
          picture_elements_mode: true
          ignore_line_breaks: true
          content: >
            <div class="scroll-container" style="width: 780px !important;
            height: 45px !important; overflow: hidden !important; white-space:
            nowrap !important; position: relative !important;">
              <div class="scroll-text">
                <span style="color: #1ed760; font-weight: bold !important; font-size: 40px !important; white-space: nowrap !important; display: inline-block !important;" id="scroll-content">
                  [[ sensor.current_song_playing ]]
                </span>
              </div>
            </div> <style>
              .scroll-container {
                width: 780px !important;
                overflow: hidden !important;
                line-height: 40px !important;
                height: 40px !important;
                background: transparent !important;
                white-space: nowrap !important;
                position: relative !important;
              }
              .scroll-text {
                display: inline-block !important;
                position: relative !important;
                white-space: nowrap !important;
                animation: scroll-left-right 20s ease-in-out infinite;
              }
              @keyframes scroll-left-right {
                0% { transform: translateX(0); } /* Start at the beginning */
                40% { transform: translateX(calc(-100% + 780px)); } /* Scroll to the left */
                50% { transform: translateX(calc(-100% + 780px)); } /* Pause at the left */
                90% { transform: translateX(0); } /* Scroll back to the beginning */
                100% { transform: translateX(0); } /* Pause at the beginning */
              }
            </style> <script>
              (function() {
                window.addEventListener('load', function() {
                  const scrollContainer = document.querySelector('.scroll-container');
                  const scrollText = document.querySelector('.scroll-text');
                  const scrollContent = document.getElementById('scroll-content');
                  if (scrollContent.scrollWidth > scrollContainer.clientWidth) {
                    // Dynamically adjust keyframe scroll positions
                    const contentWidth = scrollContent.scrollWidth;
                    const containerWidth = scrollContainer.clientWidth;
                    const distance = contentWidth - containerWidth;
                    const styleSheet = document.styleSheets[0];
                    const keyframes = `
                      @keyframes scroll-left-right {
                        0% { transform: translateX(0); }
                        40% { transform: translateX(-${distance}px); }
                        50% { transform: translateX(-${distance}px); }
                        90% { transform: translateX(0); }
                        100% { transform: translateX(0); }
                      }
                    `;
                    styleSheet.insertRule(keyframes, styleSheet.cssRules.length);
                  } else {
                    scrollText.style.animation = 'none'; // If text fits, no animation needed
                  }
                });
              })();
            </script>
          card_mod:
            style: |
              ha-card {
                background: none !important;
                padding-left: 100%;
                padding-right: 100%;
              }
    style:
      top: 58px
      left: 59.898%
    card_mod:
      style: |
        ha-card {
          background: none !important;
        }