O Lighthouse aponta Image elements do not have explicit width and height e, no celular, o texto desce de repente quando a foto termina de carregar. Em quase todo tema que eu abro a causa é a mesma: um <img> montado na mão dentro do template, com a URL saindo de get_the_post_thumbnail_url().
Essa função devolve só a URL, mais nada. Sem os atributos width e height o navegador não tem como reservar o espaço antes do download: ele renderiza o texto colado e empurra tudo pra baixo depois. Esse empurrão é o CLS.
Deixe o WordPress escrever as dimensões
Troque a tag manual por wp_get_attachment_image(). Ela lê os metadados do anexo e devolve width, height, srcset e sizes prontos:
<?php
echo wp_get_attachment_image(
get_post_thumbnail_id( get_the_ID() ),
'large',
false,
array( 'class' => 'card-thumb' )
);
No upload o WordPress grava largura e altura reais de cada tamanho em _wp_attachment_metadata, e é de lá que a função tira os números. Com os dois atributos no HTML o navegador já segura o buraco do tamanho certo. Dentro do loop, the_post_thumbnail( 'large' ) faz o mesmo serviço.
Uma coisa que eu não passo mais no array de atributos: 'loading' => 'lazy'. Desde a 6.3 quem decide loading e fetchpriority é a wp_get_loading_optimization_attributes(), e forçar lazy marca a imagem como fora da viewport. Na primeira imagem da página isso tira o fetchpriority="high" e piora o LCP enquanto você conserta o CLS.
A armadilha da imagem esmagada
Agora o height virou um número fixo no HTML. Se o layout for fluido, a largura encolhe no celular e a altura não acompanha, deixando a foto achatada. O par que resolve mora no style.css do tema:
.card-thumb {
width: 100%;
height: auto;
aspect-ratio: 16 / 9;
object-fit: cover;
}
O height: auto devolve a proporção pro CSS sem apagar os atributos que o navegador usou pra reservar o espaço, e o aspect-ratio só vale enquanto a altura estiver em auto. Rode o Lighthouse em modo mobile depois de publicar: o aviso some e o CLS cai junto.
Se travou nisso e precisa de ajuda, me chama aqui.