У стилей есть приоритет. Когда несколько стилей задают какое-нибудь свойство у одного и того же элемента (в данном случае цвет), то браузер решает какой из цветов выбрать, ориентируясь на приоритет этих стилей.
#links a { ... } - самый низкий
#links a:hover { ... } - выше предыдущего, потому что более точный (чем больше в селекторе id, классов, псевдоклассов и т.д., тем приортитет выше)
<a style="...">...</a> - самый высокий приоритет у стиля в HTML элементе, выше него может быть только, если поставить префикс !important (не рекомендуется так делать)
Ошибка: у тебя приоритет у стиля после таймаута самый высокий, он перекрывает даже цвет по наведению мыши.
Решение:
1) добавить ещё один стиль, туда переписать цвета из JS
#links.after-timeout a { ... }
2) в JS вместо изменения стиля элемента, добавить класс родительскому контейнеру (чтобы не перебирать все элементы)
const links = document.querySelector('#links');
setTimeout(() => links.classList.add('after-timeout'), 500);
3) Теперь приоритет стиля, добавленного на шаге 1 и стиля при наведении мышкой одинаковый. Приоритетом в данном случае будет пользоваться стиль, идущий последним в css файле. Но это не очевидно, и лучше добавить ещё селекторов, чтобы повысить приоритет.
#links a:hover, #links.after-timeout a:hover { ... }
Однако у меня есть JS код который медленно меняет цвет заднего фона этих ссылок: Как видно, измение цвета происходит через 500 миллисекунд посл прогрузки страницы, и в эти 500 миллисекунд :hover работает нормально, однако когда цвет начинет меняться, :hover перестает работать польностью. Как починить?