/*
Theme Name: Chronicle 19
Theme URI: https://chronicle19.com
Description: Tema-filho do Twenty Twenty-Five para o Chronicle 19.
Author: Chronicle 19
Template: twentytwentyfive
Version: 1.0.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: chronicle19
*/

/*
	Este ficheiro está deliberadamente vazio de CSS.

	No Twenty Twenty-Five a aparência vem do theme.json, não daqui.
	CSS só deve entrar neste ficheiro quando não houver forma de exprimir
	a mesma coisa em theme.json — tipicamente para os blocos próprios
	(hero, banner, eventos) que ainda vamos escrever.

	Nada de !important. Se for preciso um, o problema é estrutural.

	Regra à parte, confirmada por teste: qualquer bloco com Block Bindings
	(metadata.bindings na marcação) estiliza-se por classe aqui, nunca
	pelo painel do editor. Um estilo aplicado pelo painel a um bloco
	ligado é descartado em silêncio ao reabrir — confirmado com
	textTransform, provavelmente vale para outras propriedades também.
	Não é bug nosso; é o estado atual do Block Bindings no WordPress.
*/

/*
	Moldura do site: 1200px, centrada, com fundo branco por fora.

	Não é preciso overflow-x:hidden. Num tema de blocos com
	useRootPaddingAwareAlignments (o nosso caso), o alignfull do
	WordPress NÃO usa 100vw — o core gera apenas "max-width:none" mais
	margens negativas iguais ao padding lateral do contentor pai. Ou
	seja, alignfull ocupa 100% do contentor, seja ele qual for. Limitar
	o body a 1200px basta: o hero vai às bordas destes 1200px e não
	tenta ultrapassá-los.

	(A fórmula com 100vw e margens negativas que se encontra em muitos
	artigos é a técnica dos temas CLÁSSICOS, anterior ao theme.json.
	Não se aplica aqui.)
*/
html {
	background-color: #ffffff;

	/*
		Vermelho de erro.

		Não está na paleta do theme.json de propósito, e não é esquecimento:
		os arrays do theme.json são SUBSTITUÍDOS e não fundidos (§14), por
		isso acrescentar uma sexta cor obriga a redeclarar as cinco — e uma
		cor que só aparece em mensagens de validação não tem nada que fazer
		no selector de cores do editor, ao lado do fundo e do texto. É o
		mesmo raciocínio pelo qual o branco puro do hero também não está lá.

		Está aqui, em variável, porque tem DOIS consumidores: o resultado do
		painel da newsletter no header e as mensagens do formulário de
		contacto. Antes da sessão do contacto o valor estava escrito à mão
		numa regra só; duas cópias à mão de um valor fora da paleta divergem
		sempre, e a segunda é sempre a que fica esquecida.

		O valor não mudou: é o #b3261e que já lá estava.
	*/
	--c19-error: #b3261e;
}

body {
	max-width: 1200px;
	margin-inline: auto;
	background-color: var(--wp--preset--color--base);
}

/*
	Utilitária: transformação de maiúsculas.

	Existe porque "textTransform" no painel de Tipografia de um parágrafo
	ligado por Block Bindings não sobrevive à validação do editor — o
	estilo é descartado em silêncio ao reabrir o bloco. Uma classe simples
	não passa por esse mecanismo e fica estável.

	Usar em blocos ligados a chronicle19/event, campo start_month (que
	devolve o mês em minúsculas de propósito — ver functions.php).
*/
.u-caps {
	text-transform: uppercase;
}

/*
	Itálico para a parte final dos títulos de destaque (hero/banner).
	Mesma razão do .u-caps: um bloco com Block Bindings pode perder um
	estilo aplicado pelo painel do editor ao reabrir. Aqui o risco é
	maior — o itálico é a assinatura tipográfica do design.
*/
.u-italic {
	font-style: italic;
}

/*
	Esconde o título itálico do hero/banner quando o campo está vazio
	(artigo escolhido como destaque mas ainda não afinado — ver
	chronicle19/featured no functions.php). Sem isto, ficaria um
	elemento vazio a ocupar espaço na composição.
*/
.u-italic:empty {
	display: none;
}

/*
	LOGÓTIPO — texto + imagem.

	"CHRONICLE" é texto real (Playfair Display); o "19" é um SVG, porque
	nenhuma fonte livre reproduz o desenho dos algarismos do mockup —
	medimos várias e a mais próxima ficava a 12% de distância, com o "1"
	de remate horizontal em vez do inclinado do original.

	A compressão a 81% aproxima a largura das letras da do mockup, que
	era 20-25% mais estreito que qualquer candidata testada. O peso 500
	compensa parcialmente o efeito colateral: comprimir na horizontal
	afina as hastes verticais (as grossas, numa didone) e deixa as
	horizontais intactas, o que reduziria o contraste que define o
	estilo. O 600 compensava por inteiro mas ficava denso de mais;
	o 500 é o meio-termo escolhido a olho contra o mockup.

	Nota de layout: um elemento com transform:scaleX continua a ocupar a
	largura ORIGINAL na composição da página — encolhe visualmente mas a
	caixa não. Isso deixava um vazio entre "CHRONICLE" e o "19".

	Corrige-se com transform-origin à ESQUERDA (o texto encolhe nessa
	direcção, deixando o espaço morto todo à direita) mais uma margem
	negativa à direita que o recupera. A origem à direita faria o
	contrário: o espaço morto ficaria à esquerda e a margem empurraria
	o "19" para cima do texto.

	Efeito secundário desejável: a largura ocupada passa a ser
	W - 0,19W = 0,81W, que é exactamente a largura visual. Como a caixa
	coincide com o que se vê, o conjunto centra-se correctamente sem
	precisar de um contentor extra a cortar o excedente.

	A margem está em em, e NÃO em percentagem: uma margem percentual
	calcula-se sobre a largura do CONTENTOR, não sobre a do próprio
	elemento, e daria um valor errado que ainda variava com o tamanho do
	ecrã. Em em, calcula-se sobre o tamanho da letra e é estável.
	Medido: "CHRONICLE" em Playfair 500 ocupa 5,742em; os 19% de espaço
	morto são 1,09em. O letter-spacing acrescenta uma fracção que essa
	medição não inclui — afinar aqui se sobrar ou faltar um fio.
*/
.c19-brand {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.5rem;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.c19-brand:hover,
.c19-brand:focus {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

/*
	Logotipo completo.

	Substitui a construção antiga de texto HTML + 19.svg. O ficheiro mantém
	o mesmo URL quando o texto do SVG for convertido em paths, portanto a
	troca do upload não exige nova alteração ao template.

	A largura tem tecto em vez de valor fixo: preserva os 300px de referência
	no desktop e encolhe antes de poder forçar a largura de um telefone.
*/
.c19-logo-full {
	display: block;
	width: min(300px, 80vw);
	height: auto;
}

/*
	Assinatura, por baixo do logótipo. Escrita em caixa normal e posta
	em maiúsculas por CSS — texto todo em maiúsculas no HTML é lido
	letra a letra por alguns leitores de ecrã.
*/
.c19-tagline {
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-300);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--contrast);
	text-align: center;
}

/*
	Utilitária genérica: esconde qualquer bloco com esta classe quando
	fica mesmo vazio. Usar em blocos ligados a chronicle19/featured cujo
	valor pode não ter reserva nenhuma — por exemplo o lead, quando o
	artigo também não tem excerto nem conteúdo escrito (a reserva do
	lead cai para o excerto automático do WordPress, que por sua vez
	pode estar vazio num artigo ainda em rascunho).
*/
/*
	Botão da lupa, na barra do menu. Um <button> traz fundo, borda e
	padding do browser — aqui só queremos o ícone. É <button> e não <a>
	porque vai accionar um comportamento na própria página (abrir a
	pesquisa), não navegar para outro sítio.

	color:inherit mantém o currentColor do SVG a seguir a cor do texto à
	volta; line-height:0 evita que o botão fique mais alto que o ícone.
*/
/*
	.c19-icon-button é a classe de estilo, partilhada por todos os
	botões-ícone do header. A .c19-search-toggle serve só de âncora ao
	JavaScript e não deve ser usada noutro botão: o script procura a
	PRIMEIRA ocorrência dela na página, e uma segunda faria o clique
	ir parar ao botão errado.
*/
.c19-icon-button,
.c19-search-toggle {
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	color: inherit;
	cursor: pointer;
	display: flex;
	align-items: center;
	line-height: 0;
	transition: opacity 150ms ease;
}

.c19-icon-button:hover,
.c19-search-toggle:hover {
	opacity: 0.6;
}

.c19-icon-button:focus-visible,
.c19-search-toggle:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

/*
	Comutação dos ícones do botão (lupa <-> X) feita em CSS, a partir do
	aria-expanded que o script já mantém actualizado. Antes era o
	JavaScript a pôr e tirar o atributo hidden — frágil: se o script não
	arrancar, ficam os dois visíveis, e o WordPress pode limpar atributos
	ao gravar o bloco de HTML Personalizado. Assim o estado vive num sítio
	só e já está correcto antes de o JavaScript correr.
*/
.c19-search-toggle[aria-expanded="false"] [data-icon="close"],
.c19-search-toggle[aria-expanded="true"] [data-icon="search"] {
	display: none;
}

/*
	PESQUISA NO HEADER

	O menu e o painel de pesquisa ocupam a mesma zona da barra, um de
	cada vez. A troca é sequencial (fade-out de um, depois fade-in do
	outro) e não um cruzamento — ver a explicação no header-search.js.

	Estado por omissão: menu VISÍVEL, painel escondido. É o JavaScript
	que esconde, nunca o contrário. Se o script falhar ou não arrancar,
	o pior que acontece é a pesquisa não abrir — o menu continua lá.
	(Antes era ao contrário, e um erro no script deixava o header sem
	menu nenhum.)

	A duração aqui tem de coincidir com FADE_MS nesse ficheiro.
*/
.c19-navbar__menu,
.c19-search-panel {
	transition: opacity 180ms ease;
}

.c19-navbar__menu.is-fading,
.c19-search-panel.is-fading {
	opacity: 0;
}

/*
	Necessário porque o .c19-search-panel abaixo tem display:flex, e uma
	regra de display no CSS vence sempre o atributo hidden do HTML — sem
	isto, o painel nunca chegava a estar escondido.
*/
/*
	Altura fixa da barra do menu — nunca varia com o que está lá dentro.
	Sem isto, o painel de pesquisa (que tem padding no campo) fazia a
	barra crescer ao abrir, e o header saltava a meio da animação.

	Medido no mockup por selecção directa (não por média de linha, que
	fica distorcida onde há o ícone do hambúrguer): 52px de interior
	entre os dois filetes, mais os dois filetes de 1px = 54px.

	Valor absoluto, não escalado: ao contrário da tipografia, decidiu-se
	manter a altura da barra igual à do mockup independentemente da
	largura do site.

	box-sizing é border-box (padrão do WordPress) — a altura declarada
	já inclui as bordas, por isso o padding vertical da Row tem de ir a
	zero, senão comprime o interior abaixo dos 52px.
*/
.c19-navbar {
	height: 54px;
	align-items: center;
	border-top: 1px solid var(--wp--preset--color--rule);
	border-bottom: 1px solid var(--wp--preset--color--rule);
}

/*
	Enquanto a pesquisa está aberta, a barra inteira assume essa função —
	tudo o que não seja a pesquisa ou o botão de fechar desaparece. O
	script marca a Row com is-searching, e cada elemento a esconder
	reage a essa marca com a classe u-hide-on-search.

	Feito assim, e não com mais elementos no JavaScript, para que
	acrescentar uma peça nova ao header seja só pôr-lhe a classe — sem
	tocar no script.
*/
.is-searching .u-hide-on-search {
	opacity: 0;
	pointer-events: none;
	transition: opacity 180ms ease;
}

.c19-search-panel[hidden],
.c19-navbar__menu[hidden] {
	display: none;
}

.c19-search-panel {
	flex: 1 1 auto;
	width: 100%;
	display: flex;
	align-items: center;
}

.c19-search-panel form {
	display: flex;
	width: 100%;
	align-items: center;
	gap: 0.75rem;
}

/*
	Base comum dos campos públicos.

	Partilha-se apenas o que é realmente igual no header, no contacto e
	na página 404: fundo, caixa, padding, família, corpo e cor. A largura,
	o alinhamento e o filete ficam nos componentes, porque não têm o
	mesmo comportamento nos três contextos.
*/
.c19-search-panel input[type="search"],
.c19-contact__input,
.c19-not-found__search .wp-block-search__input {
	background: none;
	border: 0;
	border-radius: 0;
	padding: 0.25rem 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	color: var(--wp--preset--color--contrast);
	appearance: none;
}

/*
	Campo largo com texto centrado: o cursor começa a meio e o texto
	cresce para os dois lados. Sem caixa nem borda — o filete só aparece
	no foco, na mesma cor dos outros filetes do site.
*/
.c19-search-panel input[type="search"] {
	flex: 1;
	min-width: 0;
	text-align: center;
}

.c19-search-panel input[type="search"]::placeholder,
.c19-not-found__search .wp-block-search__input::placeholder {
	color: var(--wp--preset--color--muted);
}

.c19-search-panel input[type="search"]:focus {
	outline: none;
	border-bottom: 1px solid var(--wp--preset--color--rule);
}

/*
	Botão de submeter: uma lupa, não a palavra "SEARCH". No header fica
	ao lado do X; na 404 evita importar o botão-pílula do tema-pai para um
	formulário que segue a linguagem dos restantes campos do site.
*/
.c19-search-panel button[type="submit"],
.c19-not-found__search button[type="submit"] {
	background: none;
	border: 0;
	border-radius: 0;
	padding: 0;
	margin: 0;
	cursor: pointer;
	color: var(--wp--preset--color--muted);
	display: flex;
	align-items: center;
	line-height: 0;
}

.c19-search-panel button[type="submit"]:hover,
.c19-not-found__search button[type="submit"]:hover {
	color: var(--wp--preset--color--contrast);
}

.c19-search-panel button[type="submit"]:focus-visible,
.c19-not-found__search button[type="submit"]:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

/*
	O bloco Search do core traz um invólucro e um SVG próprios. Estas
	duas regras só neutralizam essa caixa e dão à lupa as mesmas dimensões
	da lupa escrita à mão no header.
*/
.c19-not-found__search .wp-block-search__inside-wrapper {
	display: flex;
	align-items: center;
	gap: 0.75rem;
	border: 0;
	padding: 0;
}

.c19-not-found__search .wp-block-search__button svg {
	width: 18px;
	height: 18px;
	min-width: 18px;
	min-height: 18px;
}

.c19-not-found__search .wp-block-search__input {
	flex: 1;
	min-width: 0;
}

/*
	NEWSLETTER NO HEADER

	Mesmo padrão da pesquisa: visível por omissão (o texto "Newsletter
	Subscribe"), o JavaScript é que esconde ao abrir o formulário — não
	o contrário. Vive na zona esquerda da faixa 1, sem altura fixa,
	porque essa faixa não tem a restrição de 54px que a barra do menu
	tem: pode crescer para o formulário compacto sem partir layout nenhum.

	(Este comentário estava DUPLICADO no ficheiro, em duas versões
	ligeiramente diferentes uma a seguir à outra. Fundido na sessão do
	contacto, sem alterar regra nenhuma.)

	Largura FIXA no contentor exterior (.c19-newsletter), não só no
	painel: sem isto, o formulário (mais largo que o texto que
	substitui) e a mensagem de erro (comprimento variável) faziam a
	coluna da Row crescer e encolher consoante o conteúdo, arrastando o
	logótipo e os ícones sociais consigo. Precisa de confirmação visual
	contra o mockup — 220px foi escolhido a olho, ainda por validar.
*/
.c19-newsletter {
	width: 220px;
}

.c19-newsletter__trigger {
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	color: var(--wp--preset--color--contrast);
	text-transform: uppercase;
	cursor: pointer;
	text-align: left;
}

.c19-newsletter__panel {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	width: 100%;
}

.c19-newsletter__panel[hidden] {
	display: none;
}

.c19-newsletter__panel form {
	display: flex;
	flex-direction: column;
	gap: 0.4rem;
}

.c19-newsletter__panel form[hidden] {
	display: none;
}

.c19-newsletter__panel input[type="email"] {
	background: none;
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--rule);
	border-radius: 0;
	padding: 0.25rem 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	color: var(--wp--preset--color--contrast);
	appearance: none;
}

.c19-newsletter__panel input[type="email"]::placeholder {
	color: var(--wp--preset--color--muted);
}

.c19-newsletter__panel input[type="email"]:focus {
	outline: none;
	border-bottom-color: var(--wp--preset--color--contrast);
}

/*
	Botão de submeter no estilo do antigo botão "SEARCH" (antes de ter
	virado lupa): texto pequeno, maiúsculas, sem fundo, alinhado à
	direita — não um botão preenchido a toda a largura, que pesava
	demais para um formulário deste tamanho.
*/
.c19-newsletter__panel button[type="submit"] {
	align-self: flex-end;
	margin-top: 0;
	padding: 0;
	background: none;
	color: var(--wp--preset--color--muted);
	border: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	cursor: pointer;
}

.c19-newsletter__panel button[type="submit"]:hover {
	color: var(--wp--preset--color--contrast);
}

.c19-newsletter__panel button[type="submit"]:disabled {
	opacity: 0.5;
	cursor: default;
}

.c19-newsletter__close {
	align-self: flex-end;
	background: none;
	border: 0;
	padding: 0;
	color: var(--wp--preset--color--muted);
	font-size: var(--wp--preset--font-size--size-100);
	cursor: pointer;
}

.c19-newsletter__result {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	color: var(--wp--preset--color--contrast);
	line-height: 1.5;
}

.c19-newsletter__result.is-error {
	color: var(--c19-error);
}

.u-hide-empty:empty {
	display: none;
}

/*
	DESTAQUES — hero e banner (bloco chronicle19/featured)

	São a mesma peça de desenho. Diferem em quatro coisas, todas aqui:
	alinhamento (alignfull / alignwide, tratado pelo core), altura,
	tamanho do título e espaçamento interior. Nenhuma delas é atributo do
	bloco — se fossem, sairiam como estilo em linha espalhado por
	instâncias, que foi o que encheu a build anterior de !important.

	Acrescentar um lugar de destaque novo é acrescentar
	.c19-featured--{nome} com min-height e font-size próprios, mais o
	nome em chronicle19_featured_slots() e um campo {nome}_post no SCF.

	MEDIÇÕES: feitas no mockup original de 1001px de largura, a 1:1 —
	píxel do mockup é píxel de CSS. A tipografia não escala com a largura
	do site, por isso não há rácios nem percentagens em nada que dependa
	do corpo de letra. As percentagens que restam são só do gradiente,
	que é decoração e não tem conteúdo dentro.
*/

/*
	O H1 invisível é o primeiro filho do main da homepage. Embora
	.screen-reader-text saia do fluxo com position:absolute, a regra de gap
	do layout constrained continua a contá-lo como irmão anterior e acrescenta
	19,2px ao hero. Anula-se só esse gap; os restantes intervalos do main
	continuam a ser governados pelas regras próprias de cada secção.
*/
.home main > .screen-reader-text + .c19-featured {
	margin-block-start: 0;
}

.c19-featured {
	/*
		Os quatro intervalos verticais, no mesmo sítio para poderem ser
		afinados de uma assentada contra a página publicada.

		Entre parênteses, a distância medida de tinta a tinta no mockup.
		Os valores das margens são menores porque uma caixa de linha
		estende-se para além da tinta — quanto, depende das métricas da
		fonte, que não consigo derivar com precisão suficiente. São
		portanto pontos de partida, não valores medidos.
	*/
	--c19-featured-gap-eyebrow: 14px;  /* eyebrow -> título   (tinta: 27px) */
	--c19-featured-gap-title: 14px;    /* título  -> filete   — igualado ao filete->lead, 12/08 */
	--c19-featured-gap-rule: 14px;     /* filete  -> lead     (tinta: 18px) */
	--c19-featured-gap-lead: 26px;     /* lead    -> CTA      (tinta: 32px) */

	/*
		Largura da faixa escura e recuo do texto. Medido: 320px de painel
		sólido no hero, ~265 no banner — mas a fotografia do banner é uma
		multidão à luz de velas, quase preta, e não permite separar o
		gradiente do que já era escuro. 300px é o valor único acordado
		para os dois.
	*/
	--c19-featured-box: 300px;
	--c19-featured-inset: 35px;

	position: relative;
	display: flex;

	/*
		stretch, não flex-start nem center — terceira tentativa em dois
		dias, e é a última das três causas possíveis.

		center (original): a folga entre a altura do texto e o
		min-height da faixa era repartida por cima E por baixo do
		painel, por cima do padding-block sem se notar — foi a causa dos
		50px "invisíveis" no hero apanhados a 13/08.

		flex-start (correcção seguinte): resolvia o padding-block deixar
		de ser adulterado, mas empurrava toda a folga para debaixo do
		CTA — o texto ficava encostado ao topo e o resto da faixa vazio,
		o que não era o desenho pretendido.

		stretch: o painel passa a ocupar a faixa inteira (em vez de só a
		altura do seu próprio conteúdo), e por dentro dele
		justify-content:space-between (ver .c19-featured__panel) reparte
		a folga pelos QUATRO intervalos internos — eyebrow→título,
		título→filete, filete→lead, lead→CTA. O padding-block continua a
		controlar só o topo e o fundo, sem lhe tocar.
	*/
	align-items: stretch;
	overflow: hidden;

	/*
		Cor de fundo por baixo da fotografia: enquanto a imagem não
		carrega, e nas bordas se alguma vez faltar imagem de destaque, o
		que aparece é o painel e não um rectângulo branco.
	*/
	background-color: var(--wp--preset--color--panel);
}

/*
	min-height e não height. Visualmente dá o mesmo com os textos
	previstos, mas o lead é um campo variável (160 caracteres no SCF
	contra os 124 do mockup) e o título de um artigo futuro pode partir
	numa linha a mais. Com height, o texto sairia da caixa ou seria
	cortado em silêncio; com min-height, a faixa cresce. A fotografia
	acompanha, porque está em object-fit: cover.

	Alturas medidas: 484px no hero, 277px no banner.
*/
.c19-featured--hero {
	min-height: 485px;
}

.c19-featured--banner {
	min-height: 275px;
}

/*
	A fotografia enche a caixa e o excedente é recortado. width e
	height a 100% anulam os atributos width/height que o WordPress
	escreve na tag — que continuam a fazer falta na marcação, para o
	browser reservar espaço antes de a imagem carregar.

	O object-position aqui é o do HERO. O banner sobrepõe-o logo a
	seguir — ver a regra .c19-featured--banner .c19-featured__image.
*/
.c19-featured__image {
	position: absolute;
	top: 0;
	bottom: 0;
	/*
		Correcção de 14/08, a pedido do designer: a fotografia deixou de
		estar por baixo da caixa (inset:0) e passou a começar exactamente
		onde a caixa acaba. A premissa anterior — caixa translúcida por
		cima de fotografia a toda a largura — estava errada; a caixa é
		sólida a sério e a fotografia só existe à direita dela.
	*/
	left: var(--c19-featured-box);
	right: 0;
	z-index: 0;
	height: 100%;
	object-fit: cover;
	object-position: center;
}

/*
	O banner ancora o recorte ao TOPO, não ao centro.

	Hero e banner partilham o mesmo ficheiro recortado à mão
	(`c19-landscape`, 1,907:1 — ver §9A), e foi essa a condição com que
	a partilha foi aceite: o hero fica com o enquadramento escolhido, o
	banner corta o que sobra por baixo em vez de comer metade de cada
	lado.

	A caixa do banner é muito mais achatada do que a do hero, por isso o
	corte é grande: a 1150px de largura sobram 850px para a imagem, onde
	o ficheiro de 1,907:1 mede 446px de altura contra os 275px da caixa.
	São 171px descartados, 38% da altura. Ao centro, isso eram ~85px
	fora de cima e ~85px fora de baixo — e era o que decapitava quem
	estivesse enquadrado no terço superior. Com `top`, os 171px saem
	todos por baixo e a margem superior do recorte manual fica intacta.

	O hero não leva isto: a caixa dele (900×484, 1,860:1) está a 12px do
	rácio do ficheiro, e ao centro esses 12px repartem-se por cima e por
	baixo sem consequência visível.

	Sem media query de propósito. Abaixo dos 700px a imagem passa a
	`aspect-ratio: 900 / 472`, que é exactamente o rácio do ficheiro:
	não há excedente, o `cover` não corta nada e esta declaração fica
	inerte. Entre 700 e 1050px o banner estreita mas mantém a composição
	horizontal, continua a cortar, e é aqui que a regra faz falta.
*/
.c19-featured--banner .c19-featured__image {
	object-position: top;
}

/*
	O gradiente é a camada que costura a fotografia (agora só à direita
	da caixa) à caixa sólida à esquerda. Vive por cima da fotografia e
	por baixo do texto, tal como antes.

	Correcção de 14/08 — mudança de premissa: até aqui a caixa era uma
	sobreposição translúcida por cima de uma fotografia a toda a largura,
	e o gradiente tinha de esvair a partir de uma opacidade quase total
	(90%, afinado em 12-13/08) para disfarçar essa sobreposição. Com a
	fotografia a começar só onde a caixa acaba, a caixa já é sólida a
	sério e deixou de haver sobreposição nenhuma para disfarçar — por
	isso o gradiente volta a ser simples: 100% opaco na borda da caixa,
	esvaindo para 0% aos 460px. O troço de 0 a var(--c19-featured-box)
	é irrelevante para o que se vê (fica escondido atrás da caixa, que
	tem z-index mais alto), mas mantém-se sólido nesse troço por
	limpeza, para quem vier a subir a caixa de z-index um dia não herdar
	uma faixa transparente ali por engano.

	Está em píxeis e não em percentagem de propósito — assim o banner
	(mais estreito) tem exactamente o mesmo esvaimento que o hero, em vez
	de um mais apertado.

	color-mix() e não rgba(): a cor do painel vem de uma variável do
	theme.json em hexadecimal, e não há forma de a converter para rgba()
	dentro do CSS sem a duplicar à mão numa segunda variável. color-mix()
	mistura a variável com "transparent" na percentagem pedida sem
	precisar de saber o valor por trás dela — e tem suporte em todos os
	browsers com que este tema já conta (Baseline desde 2023).
*/
.c19-featured::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
	background-image: linear-gradient(
		90deg in srgb,
		var(--wp--preset--color--panel) var(--c19-featured-box),
		color-mix(in srgb, var(--wp--preset--color--panel) 0%, transparent) 460px
	);
}

/*
	O painel do texto. box-sizing é border-box (padrão do WordPress), por
	isso os 300px já incluem o recuo de 35 — a coluna de texto fica com
	265px. É essa largura que faz o título partir em quatro linhas e o
	lead em três.

	Com stretch no contentor (ver acima), o painel passa a ocupar a
	altura da faixa inteira, não só a do seu próprio conteúdo. Por dentro
	dele, display:flex + flex-direction:column + justify-content:
	space-between repartem a folga pelos quatro intervalos internos —
	eyebrow→título, título→filete, filete→lead, lead→CTA — por cima dos
	valores mínimos que cada margin-top já define (ver
	--c19-featured-gap-*). O padding-block fica de fora dessa partilha:
	continua a ser só o topo e o fundo, sem se misturar com o resto.
*/
.c19-featured__panel {
	position: relative;
	z-index: 2;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	box-sizing: border-box;
	width: var(--c19-featured-box);
	padding-inline: var(--c19-featured-inset) 0;

	/*
		Fundo próprio, explícito — desde 14/08 a caixa é sólida a sério,
		não uma zona translúcida a viver da opacidade do ::before por
		trás. Sem isto o painel dependeria de o gradiente (que agora só
		garante opacidade total até à borda da caixa, ver
		.c19-featured::before) continuar a cobrir exactamente a mesma
		largura — acoplamento desnecessário entre duas regras que já não
		precisam de estar amarradas uma à outra.
	*/
	background-color: var(--wp--preset--color--panel);

	/*
		Branco puro, medido no mockup. Não está na paleta do theme.json
		porque a paleta é a do site em fundo creme, e uma sexta cor só
		para isto poluiria o seletor de cores de todos os blocos. Os
		arrays do theme.json são SUBSTITUÍDOS e não fundidos, por isso
		acrescentar uma cor obriga a redeclarar as cinco.
	*/
	color: #ffffff;
}

/*
	Correcção de 13/08: 40px hero, 30px banner. Não é medição do mockup —
	os 22/15 (metade da medição original) ficaram desarmoniosos depois de
	o align-items:stretch + space-between passar a repartir a folga pelos
	quatro intervalos internos; estes valores foram escolhidos a olho já
	com esse repartição em funcionamento.
*/
.c19-featured--hero .c19-featured__panel {
	padding-block: 40px;
}

.c19-featured--banner .c19-featured__panel {
	padding-block: 30px;
}

/*
	Eyebrow: a categoria do artigo. Escrito em caixa normal no HTML e
	posto em maiúsculas por CSS — texto todo em maiúsculas na marcação é
	lido letra a letra por alguns leitores de ecrã.

	Medido: 7px de altura de maiúscula, que em DM Sans (cap 0,70) dá
	11px de corpo — o size-100 que já existe.
*/
.c19-featured__eyebrow {
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1;
	letter-spacing: 0.1em;
	text-transform: uppercase;
}

/*
	Título. Medido: 38px de altura de maiúscula no hero e 26 no banner,
	que em Playfair (cap 0,70) dão 54px e 37px de corpo. O passo entre
	linhas medido é 56px no hero e 39 no banner — line-height 1,03 nos
	dois, que é adimensional e por isso serve os dois tamanhos.

	lining-nums porque o Playfair Display usa algarismos de estilo antigo
	por omissão, com o "9" a descer abaixo da linha de base. Num título
	de notícia com uma data ou um número, ficaria estranho.

	O font-weight não está fixado aqui de propósito: vem do theme.json
	(base 500) ou do Twenty Twenty-Five. Ver na página publicada e fixar
	aqui se o desenho pedir outro.
*/
.c19-featured__title {
	margin: var(--c19-featured-gap-eyebrow) 0 0;
	font-family: var(--wp--preset--font-family--playfair-display);
	line-height: 1.03;
	font-variant-numeric: lining-nums;
}

.c19-featured--hero .c19-featured__title {
	font-size: var(--wp--preset--font-size--size-800);
}

.c19-featured--banner .c19-featured__title {
	font-size: var(--wp--preset--font-size--size-600);
}

/*
	A parte itálica do título é um <em> dentro do mesmo <h2>, não um
	segundo bloco. É a diferença que justifica o bloco próprio: um valor
	entregue por Block Bindings é escapado e não pode trazer marcação,
	por isso o título teria de ser dois cabeçalhos e a árvore de
	cabeçalhos da página ficava errada.
*/
.c19-featured__title em {
	font-style: italic;
	font-weight: inherit;
}

/*
	Filete curto entre o título e o lead. No mockup só existe no hero;
	pô-lo também no banner foi decisão de desenho, contra o mockup — a
	assimetria não tinha justificação e parecia acidente de geração.

	Medido: 29px de largura, 2px de altura, e uma cor que sobre o painel
	dá cerca de 40% de branco.
*/
.c19-featured__rule,
.c19-article__rule {
	width: 29px;
	height: 2px;
}

.c19-featured__rule {
	margin: var(--c19-featured-gap-title) 0 0;
	background-color: rgba(255, 255, 255, 0.4);
}

/*
	Lead. Medido: 9px de altura de maiúscula, que dá 13px de corpo — o
	mesmo tamanho que a navegação, e por isso reutiliza o preset `nav`
	em vez de acrescentar mais um valor à escala. O nome do preset diz
	"navegação" e está a servir um parágrafo, o que é feio; a escala
	inteira está nomeada por sítio em vez de por tamanho, e renomeá-la
	é uma operação à parte, com o header fechado.

	O passo entre linhas medido é 20,7px sobre 13 de corpo: 1,6.

	Nota tipográfica, porque a pergunta há-de voltar: a 13px o lead tem
	corpo MAIOR que o eyebrow (11px) mas lê-se mais pequeno. O eyebrow é
	todo maiúsculas e ocupa a altura de maiúscula inteira (7,5px); o
	lead é caixa mista e o que domina a mancha é a altura-x (7px).
*/
.c19-featured__lead {
	margin: var(--c19-featured-gap-rule) 0 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.6;
}

/*
	CTA. A etiqueta é editável no SCF (campo cta_label, com reserva
	"Read the story"), por isso a seta NÃO faz parte do texto — é um
	pseudo-elemento. Assim quem escreve a etiqueta não tem de se lembrar
	de lá pôr uma seta, nem pode pôr duas.

	inline-block para o filete de baixo acompanhar a largura do texto em
	vez de atravessar o painel todo.

	Medido: 7px de altura de maiúscula (11px de corpo, igual ao eyebrow)
	e o filete 11px abaixo da tinta.
*/
/*
	Base estrutural comum aos três CTAs do site — hero/banner, "view all"
	do cabeçalho de secção, e o do card do Top Stories. Agrupados por
	seletor, não por classe própria (.c19-cta), porque uma classe nova
	obrigava a acrescentá-la em três marcações já construídas
	(homepage, /events/, render.php do featured) só para ganhar o
	mesmo resultado que o agrupamento já dá sem tocar em nenhuma delas.

	NÃO inclui tipografia: hero/banner mede 11px (size-100) e o "view
	all" mede 13px (size-200), medido no template — o handover regista
	11px para os dois, mas o template é que manda. Um base com font-size
	obrigava a mudar o aspeto de um dos dois componentes já aprovados só
	para os fazer coincidir. A tipografia fica em cada seletor, abaixo.
*/
.c19-featured__cta,
.c19-cta-link,
.c19-card__cta {
	display: inline-block;
	text-decoration: none;
}

.c19-featured__cta::after,
.c19-cta-link::after,
.c19-card__cta::after {
	content: "\2192"; /* seta para a direita */
	margin-left: 0.9em;
	letter-spacing: 0;
}

.c19-featured__cta:focus-visible,
.c19-card__cta:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

.c19-featured__cta {
	/*
		align-self:flex-start — necessário desde que .c19-featured__panel
		passou a flex column (13/08). Sem isto, o align-items:stretch por
		omissão da coluna esticaria o CTA à largura do painel inteiro, e
		o border-bottom deixaria de acompanhar só o texto para atravessar
		toda a caixa.
	*/
	align-self: flex-start;
	margin: var(--c19-featured-gap-lead) 0 0;
	padding-bottom: 8px;
	border-bottom: 1px solid rgba(255, 255, 255, 0.4);
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: #ffffff;
}

.c19-featured__cta:hover,
.c19-featured__cta:focus {
	color: #ffffff;
	border-bottom-color: #ffffff;
	text-decoration: none;
}

.c19-featured__cta:focus-visible {
	outline-color: #ffffff;
}

/*
	Intervalo entre itens do menu — fluido, não fixo.

	Antes estava um blockGap de 2rem no próprio bloco, na marcação. Com
	justifyContent:center, esse valor é um intervalo FIXO: não encolhe
	com a janela, e a quebra de linha chega assim que os nove itens mais
	os oito intervalos deixam de caber, sem aviso progressivo nenhum.

	2.67vw dá exactamente 32px quando o site está nos 1200px — o mesmo
	valor de antes, para não mudar o aspecto na largura de referência.
	Abaixo disso, a moldura acompanha a janela e o intervalo aperta na
	mesma proporção. Acima, a moldura pára nos 1200px e o tecto de 2rem
	impede o intervalo de continuar a abrir.

	O piso de 0.5rem é palpite — define a que largura a quebra volta a
	ser inevitável. Por confirmar contra o comportamento real.

	Especificidade dupla de propósito: o WordPress gera o gap numa classe
	de layout própria, com a mesma especificidade que uma classe simples
	nossa. Com um selector só, quem ganha dependeria da ordem de
	carregamento.

	NOTA: o blockGap de 2rem tem de sair da marcação do bloco, senão
	ficam dois sítios a definir o mesmo valor.
*/
.c19-navbar .c19-navbar__menu {
	gap: clamp(0.5rem, 2.67vw, 2rem);
}

/*
	Ponto de quebra do menu sobreposto (hambúrguer) — 815px.

	O bloco de Navegação usa um ponto fixo, compilado no CSS do core
	(o mixin break-small do Gutenberg): não é atributo do bloco, não
	está no painel, não há opção escondida. Com nove categorias em
	maiúsculas, esse valor é baixo de mais.

	815 e não 800: a quebra de linha dá-se aos 809px (medido com
	window.innerWidth, já com o clamp do intervalo activo). A media
	query tem de disparar ACIMA desse valor, senão haveria sempre uma
	faixa — entre 809 e o ponto escolhido — com o menu visível e já
	partido em duas linhas.

	Referência de como se chegou aqui: sem o clamp, a quebra dava-se
	aos 924px. O intervalo fluido ganhou 115px antes de ser preciso
	esconder o menu.

	Só a VISIBILIDADE muda aqui. Verificado no view.js do bloco: o
	JavaScript não consulta matchMedia nem innerWidth em lado nenhum —
	reage ao clique, alterna is-menu-open, gere o foco e o aria-modal,
	tudo independente da largura. Filtra até os elementos focáveis com
	checkVisibility({checkVisibilityCSS:true}), ou seja, pergunta ao CSS
	o que está visível. Esconder o menu por media query é comportamento
	suportado, não um contorno.

	As duas regras abaixo desfazem o que o core aplica acima do
	break-small: repõem o display:none do contentor (que já é o estado
	base dele) e voltam a mostrar o botão de abrir.
*/
@media (max-width: 815px) {
	/*
		O header mobile é uma pilha real, não o header desktop apertado:
		redes sociais → marca → newsletter (quando aberta) → navegação.
		As classes c19-header__* vivem nos Groups do template Header para
		não depender das classes wp-container-* geradas pelo WordPress.
	*/
	.c19-header__top {
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		padding: 20px 25px;
	}

	.c19-header__brand {
		order: 2;
		width: 100%;
		justify-content: center;
	}

	.c19-header__socials {
		order: 1;
		width: 100%;
		justify-content: center;
		padding-bottom: 24px;
	}

	.c19-header__socials .wp-block-social-links {
		flex-direction: row;
		flex-wrap: nowrap;
		justify-content: space-between;
		gap: 0;
		width: calc(100% + 16px);
		margin-inline: -8px;
	}

	/*
		O glifo continua pequeno; é só a caixa clicável que cresce. A caixa
		vai de 36px no telefone de 320px a 40px nos telefones correntes: os
		sete destinos continuam numa linha sem reduzir o padding do header.
	*/
	.c19-header__socials .wp-block-social-link-anchor {
		display: grid;
		place-items: center;
		width: clamp(36px, 10.25vw, 40px);
		height: clamp(36px, 10.25vw, 40px);
		padding: 0;
	}

	.c19-header__socials .wp-block-social-link-anchor svg {
		width: 24px;
		height: 24px;
	}

	.c19-header__newsletter {
		order: 3;
		width: 100%;
		margin-top: 14px;
	}

	/* O texto desktop não se repete: o ícone da barra é o trigger mobile. */
	.c19-header__newsletter .c19-newsletter__trigger {
		display: none;
	}

	.c19-header__newsletter .c19-newsletter,
	.c19-header__newsletter .c19-newsletter__panel {
		width: 100%;
	}

	.c19-header__newsletter .c19-newsletter__panel form {
		width: 100%;
	}

	.c19-header__newsletter .c19-newsletter__close {
		display: grid;
		place-items: center;
		width: 40px;
		height: 40px;
		font-size: 24px;
		line-height: 1;
	}

	/*
		O slot não deixa espaço quando o painel está fechado. :has() já é
		uma dependência aceite neste tema e evita acrescentar estado novo ao
		JavaScript só para resolver layout.
	*/
	.c19-header__newsletter:not(:has(.c19-newsletter__panel:not([hidden]))) {
		display: none;
	}

	.c19-logo-full {
		width: min(300px, 80vw);
	}

	.c19-tagline {
		max-width: 340px;
		margin-inline: auto;
	}

	/* A barra preserva os três controlos e aumenta apenas a área de toque. */
	.c19-navbar {
		padding-inline: 5px;
	}

	.c19-navbar > .c19-icon-button,
	.c19-navbar__menu .wp-block-navigation__responsive-container-open:not(.always-shown) {
		width: 44px;
		height: 44px;
		align-items: center;
		justify-content: center;
	}

	.c19-navbar__menu .wp-block-navigation__responsive-container:not(.hidden-by-default):not(.is-menu-open) {
		display: none;
	}

	.c19-navbar__menu .wp-block-navigation__responsive-container-open:not(.always-shown) {
		display: flex;
	}
}

/*
	Hover do menu de navegação: fade, igual ao dos botões-ícone
	(0,6 de opacidade, 150ms) — sem isto, o bloco de Navegação nativo
	mostra sublinhado por omissão no :hover, que não combina com o
	resto do header.
*/
.c19-navbar__menu a {
	transition: opacity 150ms ease;
}

.c19-navbar__menu a:hover,
.c19-navbar__menu a:focus {
	opacity: 0.6;
	text-decoration: none;
}

/*
	CTA de fundo claro — "view all events", "view all stories" e
	qualquer outro link do mesmo tipo fora do hero/banner. Sem
	sublinhado nem traço nenhum — só a seta como pseudo-elemento,
	tal como no CTA do hero/banner. O tamanho e a caixa alta já vêm
	do <p> que o envolve (size-200 + text-transform), não daqui.

	Hover em fade, igual aos ícones e ao menu, não ao border-bottom
	do CTA do hero/banner — este é o padrão do resto do site.
*/
.c19-cta-link {
	color: var(--wp--preset--color--contrast);
	transition: opacity 150ms ease;
}

.c19-cta-link:hover,
.c19-cta-link:focus {
	opacity: 0.6;
	color: var(--wp--preset--color--contrast);
}

.c19-cta-link:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

/* -------------------------------------------------------------------------
   Cabeçalho de secção — .c19-section-heading
   -------------------------------------------------------------------------
   Partilhado entre "UPCOMING EVENTS" e "TOP STORIES". Existe como classe
   própria, em vez de depender do elements.heading do theme.json, para que
   uma decisão futura sobre o título de artigo (também um heading) não
   arraste consigo o cabeçalho de secção sem ninguém querer. Os três
   "títulos" do site — hero/banner, secção, artigo — são papéis distintos;
   só porque hoje têm o mesmo valor não devem partilhar a mesma regra.

   Atributos replicados do bloco tal como estava: fontSize size-500 (o
   preset já trata disso via .has-size-500-font-size, não repetir aqui) e
   maiúsculas, que estava inline no bloco e passa a viver aqui.
   ---------------------------------------------------------------------- */
.c19-section-heading {
	font-family: var(--wp--preset--font-family--playfair-display);
	text-transform: uppercase;

	/*
		O Playfair Display usa algarismos de estilo antigo por omissão, e
		esses têm descendentes: o "9" cai abaixo da linha de base. Só se
		notou quando apareceu um cabeçalho de secção com números —
		"More from Chronicle 19", no fim do artigo.

		É a mesma correcção já aplicada ao dia do evento
		(.c19-event__day), pela mesma razão e na mesma família.

		Inócuo nos outros três cabeçalhos, que não têm algarismos, e
		evita que o próximo que tenha volte a apanhar o mesmo.
	*/
	font-variant-numeric: lining-nums;
}

/* -------------------------------------------------------------------------
   Cards — .c19-cards / .c19-card
   -------------------------------------------------------------------------
   Escrito como componente reutilizável desde já, a pensar na secção
   "Latest Stories" que vai usar a mesma grelha mais tarde — só o
   critério de seleção dos artigos muda (query_loop_block_query_vars
   diferente), nunca esta parte.

   Largura de card: NÃO é um valor fixo em CSS. Resulta de
   repeat(5,1fr) + column-gap sobre o alignwide de 1150px — se o
   wideSize mudar, a largura recalcula-se sozinha. (Para referência:
   com o gap de 10px abaixo, 1150 − 4×10 = 1110 ÷ 5 = 222px por card.)

   Ritmo vertical em variáveis, isoladas aqui porque os três valores são
   ESTIMATIVAS a partir de medidas ópticas do mockup (distância entre
   caixas de texto, não entre glifos) — o CSS mede caixa, o olho mediu
   tinta. Ajustar contra o publicado assim que o corpo/line-height do
   título (também por experimentar) estiver fechado.
*/
:root {
	--c19-cards-gap: 10px;
	--c19-cards-row-gap: 20px; /* medido no publicado — ver nota em .c19-cards */
	--c19-card-gap-eyebrow: 13px; /* alvo óptico: 15px, imagem → eyebrow */
	--c19-card-gap-title: 7px;    /* alvo óptico: 15px, eyebrow → título */
	--c19-card-gap-cta: 18px;     /* alvo óptico: 25px, título → cta (mínimo) */
}

/*
	row-gap existe para a Latest Stories, que corre até 10 artigos em
	duas linhas de 5. O Top Stories tem uma linha só — um row-gap sem
	segunda linha não produz efeito nenhum, por isso a propriedade fica
	no componente partilhado em vez de num modificador.

	20px, medido pelo utilizador no publicado: é a distância entre o
	filete do cabeçalho de secção e o topo do primeiro card. O intervalo
	entre linhas de cards passa a repetir esse valor, em vez de ter um
	só para ele.

	Substituiu um 15px de partida, rejeitado a olho contra o publicado.
*/
.c19-cards {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	column-gap: var(--c19-cards-gap);
	row-gap: var(--c19-cards-row-gap);
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
	Reset do blockGap do WordPress. O Post Template recebe a classe
	is-layout-flow e aplica margin-block-start a todos os <li> exceto
	o primeiro (:where(.is-layout-flow) > * + *) — mesmo com o display
	substituído por grid aqui em cima. Sem isto, o primeiro card fica
	mais acima que os outros quatro na mesma linha, porque só eles
	levam a margem extra. Mesma armadilha já registada no handover
	(§14) e já resolvida uma vez em .c19-events__list > li — esqueceu-se
	de repetir aqui.
*/
/*
	min-width: 0 — o que torna verdadeira a afirmação do comentário acima,
	de que a largura do card resulta da grelha e não do conteúdo.

	Um `1fr` resolve-se como `minmax(auto, 1fr)`, e o mínimo `auto` de um
	item de grelha é o seu tamanho MIN-CONTENT: a menor largura em que o
	conteúdo cabe sem transbordar. Basta um conteúdo indivisível — uma
	linha com `white-space: nowrap`, um URL colado num título, um nome
	composto sem hífen — para o min-content passar a ser maior que a
	coluna, e a coluna cede.

	O `overflow: hidden` de um descendente NÃO trava isto: o overflow só
	anula o mínimo automático quando é declarado no PRÓPRIO item de grelha
	ou flex, e aqui está vários níveis abaixo.

	Apanhado na listagem, com o eyebrow de nove categorias em nowrap: em
	vez de cortar com reticências, a coluna crescia até a linha inteira
	caber. Fica na classe base por decisão do utilizador — o efeito na
	homepage é que um título com uma palavra muito longa passa a ser
	cortado pelo line-clamp em vez de alargar a coluna, que é a intenção
	declarada do componente.
*/
.c19-cards > li {
	margin: 0;
	min-width: 0;
}

/*
	Cada célula é uma coluna flex de altura 100% — o grid estica todos
	os <li> à altura do mais alto por omissão (align-items:stretch), e
	esta coluna reparte essa altura: o CTA fica sempre no fundo
	(margin-top:auto no __cta), mesmo quando o título tem menos linhas
	que o card ao lado. É o mesmo problema, e a mesma solução, do
	painel do hero/banner (§10 do handover) — só que aqui a folga
	sobra entre o título e o CTA, não entre os quatro blocos do painel.
*/
.c19-card {
	display: flex;
	flex-direction: column;
	height: 100%;
	margin: 0;
}

.c19-card__image {
	aspect-ratio: 4 / 5;
	width: 100%;
	height: auto;
	object-fit: cover;
	margin: 0;
}

/*
	Eyebrow: mesmo tratamento tipográfico do eyebrow do hero/banner
	(Montserrat, size-100, tracking 0,1em, maiúsculas), reutilizado por
	decisão — só a cor muda, porque aqui o fundo é claro. A categoria
	em si vem de chronicle19_get_primary_category(), o MESMO critério
	já usado no hero (primeiro termo por ordem alfabética), para que um
	artigo mostre a mesma categoria onde quer que apareça na homepage.
*/
.c19-card__eyebrow {
	margin: var(--c19-card-gap-eyebrow) 0 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast);
}

/*
	Título: H3 (ver nota de nível no handover — o cabeçalho da secção é
	H2, o card não pode saltar para H1). Montserrat porque é o mesmo
	papel do <h1> do artigo — decisão de Agosto, precisamente para
	evitar Playfair e Garamond justapostos no card.

	size-400 (20px) é ponto de partida por experimentação, não medição:
	o size-700 (40px) está provado errado por aritmética (coluna ~222px
	não cabe um título a 40px) e o valor antigo medido no mockup (~19px)
	aponta para aqui. Se 20px ficar bem, o size-700 fica sem
	consumidor e pode sair da escala.

	line-height também por afinar junto com o corpo — mexer nos dois
	ao mesmo tempo, não um de cada vez, porque o efeito visual dos dois
	juntos é o que importa, não cada um isolado.

	-webkit-line-clamp:3 trunca títulos longos com reticências, para o
	CTA nunca ficar espremido contra o fundo do card em vez de assentar
	nele com folga.
*/
.c19-card__title {
	margin: var(--c19-card-gap-title) 0 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-400);
	font-weight: 500; /* o elements.h3 do theme.json força 700 a QUALQUER
		<h3> do site — este título é <h3> só pela árvore de
		acessibilidade (é o único abaixo do <h2> da secção), mas o
		papel é o do H1 do artigo (decisão de Agosto), que não leva
		peso a mais. Sem esta declaração explícita, herdava o 700. */
	line-height: 1.25;
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.c19-card__title a {
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	transition: opacity 150ms ease;
}

/*
	CTA do card: mesma tipografia do "view all" (size-200 — o card não
	tem um <p> a envolver o link, por isso o tamanho vem daqui em vez
	de ser herdado), mas com traço, como o do hero/banner — o mockup
	mostra "READ MORE" sublinhado nos cards.

	margin-top:auto empurra o CTA para o fundo da coluna flex do card —
	ver a nota junto a .c19-card acima.
*/
.c19-card__cta {
	margin-top: auto;
	padding-top: var(--c19-card-gap-cta);
	padding-bottom: 8px;
	width: fit-content;
	border-bottom: 1px solid var(--wp--preset--color--rule);
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast);
	transition: opacity 150ms ease, border-color 150ms ease;
}

/*
	Hover: pairar sobre o título OU o CTA acende os dois — a imagem não
	reage (decisão explícita: não é clicável). :has() já está em uso
	no ficheiro (ver .c19-events mais abaixo), mesma técnica.
*/
.c19-card:has(.c19-card__title a:hover) .c19-card__title a,
.c19-card:has(.c19-card__cta:hover) .c19-card__title a {
	opacity: 0.6;
}

.c19-card:has(.c19-card__title a:hover) .c19-card__cta,
.c19-card:has(.c19-card__cta:hover) .c19-card__cta {
	opacity: 0.6;
	border-bottom-color: var(--wp--preset--color--contrast);
}

/*
	Mobile: deliberadamente por fazer, tal como a faixa de eventos só
	tem breakpoints até 620px (ver handover, "Por fazer" → Mobile). Uma
	grelha de 5 colunas a 390px não funciona e não há mockup para o
	desenho certo — fica registado, não escondido.

	Nota: quando a sessão de mobile chegar, o breakpoint escrito aqui
	serve as duas secções ao mesmo tempo (Top Stories e Latest Stories),
	porque partilham este componente. A Latest Stories tem duas linhas em
	vez de uma, o que muda quantos cards sobram numa grelha de 4 ou 3
	colunas — 10 divide por 5 e por 2, não por 4 nem por 3.
*/

/* -------------------------------------------------------------------------
   Secção "Latest Stories" — .c19-latest
   -------------------------------------------------------------------------
   Só o invólucro. A grelha e os cards são os mesmos do Top Stories
   (.c19-cards / .c19-card, acima) — a única diferença entre as duas
   secções é QUAIS artigos aparecem, e isso decide-se no PHP, não aqui.

   Existe pela mesma razão que .c19-events existe: embrulhar o cabeçalho
   e o Query Loop para o :has() os poder esconder aos dois de uma vez.
   É "align":"full" + "layout":"constrained", a receita do <main>, para
   o alignwide dos filhos continuar a medir-se contra o mesmo contexto e
   não fechar em 660px.
   ---------------------------------------------------------------------- */

/*
	Secção vazia = esconder tudo, cabeçalho incluído. Ao contrário do
	Top Stories, isto é mesmo preciso: o Top Stories tem preenchimento
	cronológico e por isso só fica vazio se o site não tiver artigo
	nenhum; a Latest Stories exclui sempre os do hero, do banner e do
	Top Stories ("batota"), e com poucos artigos publicados essa
	exclusão pode esvaziá-la legitimamente. A homepage precisa de 12
	artigos para encher as três secções (2 + 5 + 5) e 17 para as encher
	com a Latest a 10.

	Mesma técnica e mesma ressalva de .c19-events: :has() é baseline
	desde finais de 2023, por confirmar no ambiente da Bluehost ao mesmo
	tempo que o resto.
*/
.c19-latest:not(:has(.c19-cards li)) {
	display: none;
}

/* -------------------------------------------------------------------------
   Faixa "Upcoming Events" — .c19-events
   -------------------------------------------------------------------------
   Query Loop sobre o CPT `event`, filtrado e ordenado no PHP (ver
   functions.php, secção 3). Este ficheiro não decide QUAIS eventos
   aparecem nem por que ordem — só a apresentação.

   .c19-events embrulha o cabeçalho da secção (já existente, partilhado
   com o Top Stories) e o Query Loop, só para o :has() abaixo poder
   esconder os dois de uma vez quando não há eventos futuros. É
   "align":"full" + "layout":"constrained", a mesma receita do <main>,
   para o alignwide dos filhos lá dentro continuar a medir-se contra o
   mesmo contexto e não fechar em 660px.
   ---------------------------------------------------------------------- */

/*
	Zero eventos = esconder a secção inteira (cabeçalho incluído), por
	decisão. Sem eventos, o Post Template não emite <li> nenhum — não é
	preciso ir ao PHP para o saber.

	:has() é baseline desde finais de 2023. Tal como o color-mix() do
	hero (§10 do handover), fica por confirmar que nada no ambiente da
	Bluehost o quebra — verificar ao mesmo tempo que se verificar o
	resto desta secção.
*/
.c19-events:not(:has(.c19-events__list li)) {
	display: none;
}

/*
	A grelha. Largura de célula alvo: 190px, medida directamente no
	mockup (951px alignwide ÷ 5 = 190,2px). Máximo 5 colunas — não 6:
	as 6 cabiam na moldura real por coincidência aritmética (1150px ÷
	6 = 191,7px, quase o mesmo valor), mas o mockup só foi desenhado
	para 5, e 6 nomes/localizações compridos ao mesmo tempo não davam
	espaço nenhum. Ver nota em .c19-event__name/__place mais abaixo.

	column-gap:31px é o separador entre eventos — real, no grid
	exterior, não simulado com uma coluna extra dentro de cada evento
	(essa versão anterior tirava 31px só à largura útil dos eventos
	2-5, deixando o 1º com mais espaço que os outros; foi isto que
	desalinhou a largura do texto entre eventos). Com column-gap, o
	CSS reparte o espaço de forma igual por todas as 5 células,
	independentemente da posição.

	<ul> nativa do Post Template: reset de list-style/margin/padding.
	Os <li> são as células da grelha.
*/
.c19-events__list {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	column-gap: 31px;
	margin: 0;
	padding: 0;
	list-style: none;
}

.c19-events__list > li {
	margin: 0;
	padding: 20px 0 0;
}

/*
	Estrutura de um evento — grid de 2 linhas × 3 colunas:

	  ┌────────┬───┬──────────┐
	  │  mês   │   │          │   linha 1 (col 1 só)
	  ├────────┼───┼──────────┤
	  │  dia   │ | │  texto   │   linha 2
	  └────────┴───┴──────────┘
	    auto    31px   1fr

	A coluna 1 (mês + dia) tem largura automática: o grid dimensiona-a
	pelo mais largo dos dois conteúdos que lá estão — o dia, sempre
	(confirmado). O mês, com text-align:center, fica centrado nessa
	mesma largura sem precisar de saber o valor em px.

	A coluna 2 (31px) é só para o filete: 1px de traço, centrado
	(justify-self:center) numa faixa de 31px dá exactamente 15px de
	cada lado — a regra [15px][filete][15px] pedida, sem padding
	nenhum a somar à parte.

	O filete é um pseudo-elemento (::after) posicionado só na linha 2,
	não na .c19-event inteira — por isso não sobe até ao mês e não
	precisa de altura fixa: um item de grid sem altura própria estica
	por omissão (align-items:stretch) até à altura da própria linha,
	que aqui é a altura do dia.
*/
.c19-event {
	display: grid;
	grid-template-columns: auto 31px 1fr;
	grid-template-rows: auto auto;
	row-gap: 4px;
}

/*
	Mês: mesmo tratamento visual dos outros rótulos pequenos em
	maiúsculas do site (eyebrow, CTA do hero) — 11px, tracking 0,1em.
	A caixa alta vem do .u-caps na marcação, não daqui: o campo de
	ligação devolve minúsculas de propósito (ver functions.php e a
	nota já existente acima, junto ao .u-caps).
*/
.c19-event__month {
	grid-column: 1;
	grid-row: 1;
	margin: 0;
	text-align: center;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	font-weight: 600;
	letter-spacing: 0.1em;
	color: var(--wp--preset--color--contrast);
}

/*
	Dia: numeral serifado. lining-nums porque o Playfair Display usa
	algarismos de estilo antigo por omissão (o "9" desce abaixo da
	linha) — armadilha já confirmada no handover. Sem padding nem
	borda — o espaçamento e o filete vivem na coluna 2 do grid, não
	aqui.
*/
.c19-event__day {
	grid-column: 1;
	grid-row: 2;
	margin: 0;
	font-family: var(--wp--preset--font-family--playfair-display);
	font-size: var(--wp--preset--font-size--size-600);
	font-variant-numeric: lining-nums;
	line-height: 1;
	color: var(--wp--preset--color--contrast);
}

.c19-event::after {
	content: "";
	grid-column: 2;
	grid-row: 2;
	justify-self: center;
	width: 1px;
	background: var(--wp--preset--color--rule);
}

/*
	Separador entre eventos: agora vive dentro do grid de cada evento
	(::before), não no <li> — por isso fica confinado à linha 2, tal
	como o filete interno acima, e já não sobe até ao mês.

	grid-column:1 + justify-self:start coloca-o encostado ao início
	da coluna do dia (o bordo esquerdo do próprio .c19-event);
	margin-left:-15px empurra-o para fora da caixa, para dentro do
	column-gap de 31px que separa as células no grid exterior. Sai da
	caixa mas não afecta a largura da coluna 1: como não altera
	grid-template-columns nem desloca o dia/mês/texto, a largura útil
	continua igual em todos os eventos — o problema anterior (1º
	evento com mais espaço que os outros) não volta.

	Só a partir do 2º evento — o primeiro não tem nada à esquerda.
*/
.c19-events__list > li:not(:first-child) .c19-event::before {
	content: "";
	grid-column: 1;
	grid-row: 2;
	justify-self: start;
	margin-left: -15px;
	width: 1px;
	background: var(--wp--preset--color--rule);
}

.c19-event__body {
	grid-column: 3;
	grid-row: 2;
	display: flex;
	flex-direction: column;
	min-width: 0; /* permite quebra de linha em vez de transbordar a célula */
	margin: 0;
	gap: 2px;
}

/*
	Nome e localização: mesmo tamanho, mesma cor, tal como medido no
	mockup — não há hierarquia visual entre os dois, só a ordem. Um
	deles poder vir a passar a var(--wp--preset--color--muted) fica em
	aberto (por experimentar).

	Uma linha cada, com reticências independentes — nome comprido e
	localização comprida são dois problemas diferentes (campos SCF
	diferentes) e um não pode empurrar o outro nem esticar a célula.
	Uma linha é o que o mockup mostrava nos dois; 2 linhas por campo é
	possível trocando white-space:nowrap por -webkit-line-clamp:2, se
	1 linha cortar cedo de mais na prática.
*/
.c19-event__name,
.c19-event__place {
	margin: 0;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.55;
	color: var(--wp--preset--color--contrast);
}

/* -------------------------------------------------------------------------
   Página /events/ — listagem completa, .c19-events-list
   -------------------------------------------------------------------------
   Cada evento é uma peça editorial vertical: nome, imagem de paisagem,
   data, local e descrição. A ordem está na marcação, não é simulada
   com `order` no CSS.

   A imagem e a descrição são opcionais. A primeira desaparece pelo
   filtro chronicle19_hide_empty_event_image() no functions.php; a segunda
   usa .u-hide-empty. Nenhuma deixa caixa ou intervalo residual.

   O nome é um link para /events/#event-{ID}. O functions.php converte o
   permalink do CPT e acrescenta o id correspondente ao <li> emitido pelo
   Post Template. Assim o mesmo bloco core/post-title funciona na homepage
   e nesta listagem sem URLs escritas à mão.
   ---------------------------------------------------------------------- */
.c19-events-list {
	margin: 0;
	padding: 0;
	list-style: none;
}

.c19-events-list > li {
	border-bottom: 1px solid var(--wp--preset--color--rule);
}

.c19-events-list > li:first-child {
	border-top: 1px solid var(--wp--preset--color--rule);
}

.c19-events-list__row {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 0;
	padding: 32px 0 40px;
}

.c19-events-list .c19-events-list__title {
	margin: 0 0 18px;
	font-family: var(--wp--preset--font-family--playfair-display);
	font-size: var(--wp--preset--font-size--size-500);
	font-weight: 400;
	line-height: 1.15;
	color: var(--wp--preset--color--contrast);
}

.c19-events-list__title a {
	color: inherit;
	text-decoration: none;
}

.c19-events-list__title a:hover,
.c19-events-list__title a:focus-visible {
	text-decoration: underline;
}

.c19-events-list__image {
	width: 100%;
	aspect-ratio: 1800 / 944;
	margin: 0 0 18px;
	overflow: hidden;
}

.c19-events-list__image img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.c19-events-list__body {
	display: flex;
	flex-direction: column;
	align-items: stretch;
	gap: 0;
}

.c19-events-list__meta {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 4px;
}

.c19-events-list .c19-events-list__date {
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.4;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}

.c19-events-list .c19-events-list__place {
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.4;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}

.c19-events-list .c19-events-list__excerpt {
	max-width: 753px;
	margin: 18px 0 0;
	font-family: var(--wp--preset--font-family--eb-garamond);
	font-size: var(--wp--preset--font-size--size-400);
	font-weight: 400;
	line-height: 1.4;
	color: var(--wp--preset--color--contrast);
}

/*
	O H1 vem do template Pages, fora do conteúdo da página. A classe no
	body é acrescentada pelo functions.php apenas em /events/, para não
	mudar os H1 das restantes páginas que usam o mesmo template.

	Não se declara margem: o intervalo cabeçalho→lista continua a ser o
	mesmo block gap de 19,1875px medido nas listagens de artigos.
*/
.c19-events-page main > .wp-block-group > .wp-block-post-title {
	font-family: var(--wp--preset--font-family--playfair-display);
}

/* -------------------------------------------------------------------------
   Listagens de artigos — /stories/, arquivos e pesquisa
   -------------------------------------------------------------------------
   Três templates (Blog Home, All Archives, Search) partilham uma parte de
   template, `story-list`, que traz o Query Loop, a grelha, a paginação e o
   estado vazio. A única coisa que difere entre os três é o cabeçalho da
   página, que fica em cada template porque são blocos DIFERENTES (texto
   fixo no /stories/, core/query-title tipo archive no arquivo, tipo search
   na pesquisa) e não o mesmo bloco com texto diferente.

   Os cards são os MESMOS do Top Stories e da Latest Stories. A tipografia
   é rigorosamente igual à da homepage, por decisão do utilizador — o
   assistente propôs subir o título de 20px para 24px, por a coluna passar
   de 222px para 377px, e foi recusado. Fica registado que essa proposta
   era expectativa e não medição, e que se desfaz ou confirma em segundos
   contra a página publicada: se um dia se quiser mexer, é uma linha no
   modificador abaixo, e não toca na homepage.

   O modificador só carrega GRELHA. Tudo o que aqui se acrescentar de
   tipografia divide o componente em dois — e um componente com duas
   personalidades é como se perde a consistência entre a homepage e o
   arquivo sem ninguém decidir isso.

   O clamp de 3 linhas do título deixa de disparar quase nunca: a 377px e
   20px cabem cerca de 31 caracteres por linha, portanto só corta acima dos
   ~90. Passou de mecanismo a rede de segurança, como o aspectRatio do
   bloco da imagem.
   ---------------------------------------------------------------------- */

/*
	Cabeçalho de página — mesmo grupo do cabeçalho de secção da homepage
	(filete em baixo, "space-between"), com um <h1> em vez de um <h2>.

	SUPOSIÇÃO NÃO PEDIDA, removível sozinha: os 40px de folga acima. Na
	homepage o hero encosta à barra de navegação e está bem, porque é uma
	imagem a sangrar; um <h1> encostado à navegação fica apertado. Não há
	mockup para esta página e nenhum valor foi medido. Afinar contra o
	publicado, ou apagar a regra se não fizer falta.
*/
.c19-page-heading {
	margin-top: 40px;
}

/*
	Grelha: três colunas em vez de cinco.

	Redefine as variáveis do componente em vez de repetir as propriedades —
	as regras de .c19-cards já as consomem, e assim há um sítio só onde os
	intervalos estão escritos.

	Para referência: 1150 − 2×20 = 1110 ÷ 3 = 370px por card. É por isto que
	o `c19-card` foi registado a 380×475 (ver functions.php, secção 10, e
	handover §9A): esta página é o consumidor para que esse tamanho foi
	dimensionado, e os 380px declarados no atributo `sizes` — errados na
	homepage, onde a caixa mede 222px — aqui estão certos.

	Os 20/40px foram propostos pelo assistente e aceites sem medição. São
	pontos de partida: o 10px da homepage foi escolhido a olho para cards de
	222px, e a 370px é provável que ficasse apertado.
*/
.c19-cards--listing {
	--c19-cards-gap: 20px;
	--c19-cards-row-gap: 40px;
	--c19-card-gap-excerpt: 10px; /* SUPOSIÇÃO: título → excerto */
	grid-template-columns: repeat(3, 1fr);
}

/*
	Eyebrow: aqui mostra TODAS as categorias do artigo, não a principal.
	Vem do bloco nativo core/post-terms (um <div>, não um <p>), com " | "
	como separador e cada termo em link.

	Porquê todas, ao contrário da homepage: um artigo pode ter várias
	categorias, e num arquivo os links dão navegação lateral, que é
	precisamente o que falta a uma página de arquivo.

	Uma linha com reticências, por decisão. Fica no modificador e não na
	classe base: na homepage o eyebrow é sempre um nome só e não parte
	linha nenhuma — pôr `nowrap` na base seria mudar a homepage para
	resolver um problema que ela não tem.
*/
.c19-cards--listing .c19-card__eyebrow {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/*
	O nowrap acima NÃO chega sozinho, e a razão não é óbvia. O
	core/post-terms envolve cada separador num <span> próprio e o core
	dá-lhe white-space:pre-wrap, para preservar os espaços à volta do
	separador (wp-includes/blocks/post-terms/style.css, o ficheiro tem
	duas regras e esta é uma delas).

	O white-space não é imposto aos filhos: cada elemento tem o seu valor
	computado. O nowrap do <div> impede quebras no texto dele, mas o
	<span> do separador volta a permitir quebra dentro de si — e ele
	contém espaços. Por isso a linha partia SEMPRE a seguir a um "|" e
	nunca a meio de um nome de categoria, que é o sintoma que denunciou
	o mecanismo.

	Especificidade (0,3,0) contra os (0,2,0) do core. Sem !important.

	Os espaços à volta do "|" mantêm-se: o nowrap colapsa sequências de
	espaços mas não apaga um espaço único entre dois elementos inline, e
	o separador está escrito como " | " na marcação.
*/
.c19-cards--listing .c19-card__eyebrow .wp-block-post-terms__separator {
	white-space: nowrap;
}

/*
	Links dos termos. `color: inherit` para herdarem a cor do eyebrow em vez
	da cor de link do tema — visualmente o eyebrow continua a ser um bloco
	só, e é o cursor que revela que são clicáveis.

	O hover do card NÃO foi reescrito, ao contrário do que o assistente
	tinha anunciado: as regras :has() existentes referem .c19-card__cta, que
	aqui não existe, por isso não encontram nada e não fazem nada. O hover
	do título continua a funcionar tal e qual. Só faltava dar reacção
	própria aos links das categorias, que é o que estas duas regras fazem.
*/
.c19-card__eyebrow a {
	color: inherit;
	text-decoration: none;
	transition: opacity 150ms ease;
}

.c19-card__eyebrow a:hover,
.c19-card__eyebrow a:focus {
	color: inherit;
	opacity: 0.6;
}

.c19-card__eyebrow a:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 2px;
}

/*
	Excerto. O texto vem da ligação chronicle19/post → lead, que segue a
	cadeia do hero: display_lead → excerto escrito à mão → primeiras
	palavras do conteúdo (functions.php, secção 8).

	O corte é feito em PHP, pelo "Character Limit" do campo display_lead no
	SCF — 160 caracteres à data, valor PARTILHADO com o hero por decisão
	explícita e aceite como primeira versão. Não se usou o core/post-excerpt
	precisamente por causa disto: o excerptLength desse bloco só trunca
	excertos GERADOS, e deixa passar inteiro um excerto escrito à mão.

	O line-clamp é rede de segurança para o dia em que esse limite subir,
	não o mecanismo principal.

	SUPOSIÇÃO NÃO PEDIDA: a cor `muted`. Ficou por decidir; escolheu-se por
	coerência com a listagem de eventos, que também põe o texto secundário
	em muted. Trocar por `contrast` é uma linha.
*/
.c19-card__excerpt {
	margin: var(--c19-card-gap-excerpt) 0 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.5;
	color: var(--wp--preset--color--muted);
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/*
	Data, no lugar que o "READ MORE" ocupa na homepage: fundo do card,
	empurrada pelo margin-top:auto da coluna flex, de modo a assentar na
	mesma linha em cards de alturas diferentes.

	Reutiliza --c19-card-gap-cta apesar de o nome dizer "cta": é o mesmo
	intervalo, do último bloco de texto para o elemento de fundo. Renomear a
	variável obrigaria a mexer no componente partilhado, e o valor é o
	mesmo.

	SEM traço por baixo, ao contrário do CTA. Sublinhar texto que não é
	clicável é enganador — o fundo do card fica mais leve do que na
	homepage, e isso é consequência da decisão, não descuido.
*/
.c19-card__date {
	margin-top: auto;
	padding-top: var(--c19-card-gap-cta);
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--muted);
}

/*
	Paginação — anterior/seguinte, sem números.

	Decisão do utilizador, com uma razão que também é a razão de ser fácil
	de mudar depois: com poucos artigos, uma fila de números revela que o
	site está a começar. Quando houver páginas que cheguem, acrescenta-se o
	bloco core/query-pagination-numbers no meio, dentro da parte de
	template — os URLs são os mesmos (/stories/page/2/) nos dois casos, não
	há nada a migrar, e a alteração serve os três templates de uma vez.

	A regra do :last-child existe porque na primeira página não há "Newer
	stories": sem ela, o "Older stories" saltava para a esquerda em vez de
	ficar à direita. O core traz uma regra equivalente; esta fica escrita
	por não se poder confiar num detalhe de folha de estilo de terceiros
	para o alinhamento não saltar.
*/
.c19-pagination {
	margin-top: 40px; /* SUPOSIÇÃO: não medido, afinar contra o publicado */
}

.c19-pagination .wp-block-query-pagination-next:last-child {
	margin-left: auto;
}

.c19-pagination a {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	transition: opacity 150ms ease;
}

.c19-pagination a:hover,
.c19-pagination a:focus {
	color: var(--wp--preset--color--contrast);
	opacity: 0.6;
}

.c19-pagination a:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

/*
	Estado vazio.

	O bloco core/query-no-results não traz texto nenhum — os três da
	homepage têm um parágrafo em branco lá dentro. A mensagem que o site
	mostra hoje numa pesquisa sem resultados ("Sorry, but nothing was
	found…") é do search.html do Twenty Twenty-Five e desaparece no momento
	em que o nosso template o substitui.

	Duas frases no mesmo bloco, porque a parte é partilhada e os contextos
	não são iguais: numa categoria ainda sem artigos — provável no
	lançamento, com nove categorias — convidar o leitor a "tentar outra
	pesquisa" que ele nunca fez seria absurdo.

	As body classes `search` e `category` são escritas pelo body_class() do
	WordPress, também nos temas de blocos. É o mecanismo que o core fornece
	para isto, e não um contorno.
*/
.c19-no-results {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	color: var(--wp--preset--color--contrast);
}

.c19-no-results a {
	color: inherit;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
	transition: opacity 150ms ease;
}

.c19-no-results a:hover,
.c19-no-results a:focus {
	color: inherit;
	opacity: 0.6;
}

.c19-no-results a:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

body:not(.search) .c19-no-results--search {
	display: none;
}

body.search .c19-no-results--browse {
	display: none;
}

/*
	Mobile: por fazer, como o resto do site. O breakpoint que se escrever
	aqui é independente do da homepage — três colunas partem-se de maneira
	diferente de cinco, e 12 artigos por página dividem por 3, por 2 e por
	1, o que dá mais saídas do que a grelha da homepage tem.
*/

/* -------------------------------------------------------------------------
   Artigo — template "Single Post"
   -------------------------------------------------------------------------
   Substituiu o bloco provisório que estava aqui e que assentava nas
   classes que os blocos nativos do Twenty Twenty-Five costumam gerar,
   sem template real por baixo. Duas dessas regras sobreviveram sem
   alteração, por continuarem certas: a família do .wp-block-post-title
   e a do corpo do artigo.

   LARGURAS — de onde saem, para ninguém as ir medir ao mockup e concluir
   que estão erradas.

   O cabeçalho fecha por aritmética. A imagem é o tamanho registado
   c19-article (753×531), a margem entre as duas colunas é 30px, e o
   conjunto ocupa o alignwide:

       367 + 30 + 753 = 1150

   COMO SE CHEGOU AQUI, porque a margem mudou três vezes. Começou em
   15px (coluna de 452), subiu para 100 (coluna de 367) para apertar o
   título, e o problema não desapareceu — só mudou de eixo, de altura
   para largura. A medição do publicado explicou porquê: o que fazia o
   conteúdo parecer perdido não era a densidade do título, era a coluna
   de texto pesar 35% do par texto+imagem contra os 30% do mockup.

   A correcção foi passar 70px da margem para a IMAGEM, mantendo a
   coluna: o texto passa a 32,8% do par. A coluna de 367 não muda,
   portanto o número de linhas do título e do lead não muda, e não há
   risco de o cabeçalho passar a transbordar os 531 de altura.

   Os 367px não estão escritos em lado nenhum: a primeira coluna leva
   1fr e recalcula-se sozinha se a margem mudar outra vez.

   MEDIDO NO PUBLICADO, e é o que sustenta tudo isto: título de 88
   caracteres = 6 linhas com passo de 39px; linha mais longa a 341px
   numa caixa de 367 (93%); lead de 5 linhas; folga entre o lead e o
   bloco de autor = 55px. As duas colunas acabavam à mesma altura,
   portanto nunca houve excesso vertical — havia excesso horizontal.

   RESSALVA, contra a recomendação do assistente, que preferia 50px de
   margem: a 30px, uma linha de título que encha a caixa fica a 30px da
   fotografia. Contrapartida aceite pelo utilizador — o lead tem 250
   caracteres de tecto e serve de folga quando um título crescer. Note-se
   que essa folga é VERTICAL: não resolve um título que roce a imagem na
   horizontal. Se isso acontecer, a saída é a margem, não a largura da
   imagem, que estará fixada no ficheiro.

   DESVIO DELIBERADO AO MOCKUP: lá a fotografia sangra até à margem
   direita da página; aqui pára no alignwide. Consequência da decisão de
   usar o tamanho registado com largura fixa, tomada de olhos abertos.

   O corpo sai de proporções medidas no mockup e convertidas para 1150
   (moldura de conteúdo do mockup: 942px, confirmada pela faixa preta da
   newsletter em 41→982 e pelos cards em 45→976):

       111 + 552 + 75 + 1 + 75 + 225 + 111 = 1150

   Os 552px não são só o que a proporção dá: são também 74 caracteres por
   linha em EB Garamond a 20px, medindo a fonte real (0,3747em por
   caractere sobre uma amostra de prosa inglesa). Fica no topo do
   intervalo clássico de 45–75 e abaixo do tecto de 80 da WCAG 1.4.8. O
   mockup e o conforto de leitura apontam para o mesmo sítio, o que não
   era garantido.

   Os 75px das duas margens do índice foram escolhidos a olho pelo
   utilizador, contra os 153/83 que a proporção do mockup dava. O índice
   absorveu a diferença: 225px em vez dos 140 proporcionais.
   ---------------------------------------------------------------------- */

/*
	Tipografia base do conteúdo. Vinha do bloco provisório e mantém-se
	sem alteração — era das poucas coisas que estavam certas por
	inferência.

	ATENÇÃO ao alcance desta regra, descoberto nesta sessão e contrário
	ao que o handover dizia: o .wp-block-post-content é o mesmo bloco nas
	PÁGINAS e nos artigos. Ou seja, o corpo de uma página de texto (uma
	política de privacidade, por exemplo) também é EB Garamond a 20px.

	Isso tem uma consequência ainda por resolver, registada aqui para não
	se perder: a essa família e a esse tamanho, o contentSize de 660px dá
	88 caracteres por linha, acima do tecto de 80 da WCAG 1.4.8. A revisão
	do contentSize (handover §5) aponta portanto para BAIXAR, não subir.
	Fica para a sessão que tratar das páginas.

	O line-height a 1,4 é o valor que já estava computado (28px sobre
	20px, medido no publicado). Passa a estar declarado, para deixar de
	depender do que o Twenty Twenty-Five herda.

	Alargada para "li" e "blockquote": a regra original só apanhava "p".
	Uma lista (<ul>/<ol>) fica em Montserrat por omissão, porque o <li>
	é irmão do parágrafo, não descendente — não herda nada da regra
	de cima. Não é bug, é selector incompleto; corrigido quando
	apareceu o primeiro artigo com uma lista.
*/
.wp-block-post-title {
	font-family: var(--wp--preset--font-family--montserrat);
}

.wp-block-post-content p,
.wp-block-post-content li,
.wp-block-post-content blockquote {
	font-family: var(--wp--preset--font-family--eb-garamond);
	font-size: var(--wp--preset--font-size--size-400);
	font-weight: 400;
	line-height: 1.4;
}

/*
	Inline prose links need a persistent affordance: hover does not exist on
	touch screens and is not available to keyboard users. Component links such
	as buttons and arrow CTAs keep their own established treatment.
*/
.wp-block-post-content :is(p, li, blockquote) a:not(.wp-block-button__link):not(.c19-cta-link) {
	color: inherit;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
	transition: opacity 150ms ease;
}

.wp-block-post-content :is(p, li, blockquote) a:not(.wp-block-button__link):not(.c19-cta-link):hover,
.wp-block-post-content :is(p, li, blockquote) a:not(.wp-block-button__link):not(.c19-cta-link):focus {
	color: inherit;
	opacity: 0.6;
}

.wp-block-post-content :is(p, li, blockquote) a:not(.wp-block-button__link):not(.c19-cta-link):focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

@media (hover: none), (pointer: coarse) {
	.wp-block-post-content :is(p, li, blockquote) a:not(.wp-block-button__link):not(.c19-cta-link):active,
	.c19-no-results a:active {
		opacity: 0.6;
	}
}

.wp-block-post-date,
.wp-block-post-author,
.wp-block-post-author-name,
.wp-block-post-terms {
	font-family: var(--wp--preset--font-family--montserrat);
}

/*
	Intervalos verticais do cabeçalho: 30px entre categoria, título,
	filete e lead. Valor do utilizador.

	Não são os do painel do hero (14/14/14/26), que era o ponto de
	partida da primeira versão. Faz sentido que divirjam: no hero os
	quatro blocos repartem uma faixa de 485px com o texto todo pequeno;
	aqui a coluna é mais alta, o título é muito maior, e o mesmo 14px
	lia-se como aperto.
*/
:root {
	--c19-article-gap-eyebrow: 30px; /* eyebrow → título */
	--c19-article-gap-title: 30px;   /* título  → filete */
	--c19-article-gap-rule: 30px;    /* filete  → lead   */
}

/*
	Reset do blockGap. Obrigatório e não cosmético: qualquer Group com
	layout default recebe a regra do WordPress
	`:root :where(.is-layout-flow) > * { margin-block-start: 1.2rem }`,
	que dá 19,2px a todos os filhos menos o primeiro — mesmo quando o
	display é substituído por grid ou flex aqui.

	Foi a armadilha que desalinhou a faixa de eventos e, mais tarde, os
	cards do Top Stories, por se ter zerado campo a campo em vez de zerar
	o componente inteiro (§14 do handover). Aqui zera-se de uma vez, e as
	margens verdadeiras são declaradas a seguir, regra a regra.

	Vem ANTES das regras específicas de propósito: têm todas a mesma
	especificidade (0,1,0) e a ordem é que decide.
*/
.c19-article__header > *,
.c19-article__intro > *,
.c19-article__author > *,
.c19-article__byline > *,
.c19-article__meta > *,
.c19-article__figure > *,
.c19-article__body > *,
.c19-related > * {
	margin-block-start: 0;
	margin-block-end: 0;
}

/* -------------------------------------------------------------------------
   Cabeçalho
   ---------------------------------------------------------------------- */

/*
	A coluna da imagem tem largura fixa porque o ficheiro tem largura
	fixa: 683px é o tamanho registado c19-article, não um valor de
	desenho. A coluna do texto leva 1fr e absorve arredondamentos.

	min-width: 0 na coluna de texto pela armadilha já registada no
	handover (§14): o mínimo automático de um item de grelha é o seu
	min-content, e um título com uma palavra longa alargaria a coluna em
	vez de partir a palavra.
*/
.c19-article__header {
	display: grid;
	grid-template-columns: 1fr 753px;
	column-gap: 30px;
	align-items: stretch;
}

/*
	Duas âncoras, não uma repartição.

	A coluna divide-se em dois grupos: categoria, título, filete e lead
	colados ao TOPO, com os intervalos declarados entre eles; bloco de
	autor e ícones sociais colados ao FUNDO. O que expande é só o espaço
	entre os dois — ou seja, o espaço a seguir ao lead.

	Consegue-se com margin-block-start:auto no bloco de autor, que
	absorve toda a folga da coluna e empurra o que vem a seguir. É a
	mesma receita do margin-top:auto do .c19-card__cta.

	NÃO se usa justify-content:space-between, que era o que estava aqui
	na primeira versão e estava errado: esse reparte a folga por TODOS os
	intervalos, afastando também a categoria do título e o título do
	filete. O painel do hero quer isso — quatro blocos a repartir a faixa
	toda —; este cabeçalho não.

	É por isto que um artigo sem lead deixa um espaço em branco no meio
	em vez de subir o bloco de autor: comportamento pedido.

	A altura da coluna é ditada pela coluna direita, que é a imagem MAIS
	a legenda. Não há altura fixa escrita em lado nenhum — um artigo sem
	legenda encolhe a linha para a altura da imagem e isto continua a
	funcionar.
*/
.c19-article__intro {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

/*
	Categorias. Todas, separadas por " | ", como nos cards das listagens —
	o mesmo bloco core/post-terms e o mesmo tratamento tipográfico do
	eyebrow do hero e dos cards.

	Sem nowrap nem reticências, ao contrário da listagem: aqui a coluna
	tem 452px e não 370, e cortar categorias no topo de um artigo é pior
	do que deixá-las passar para uma segunda linha.
*/
.c19-article__eyebrow {
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1.4;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast);
}

.c19-article__eyebrow a {
	color: inherit;
	text-decoration: none;
}

.c19-article__eyebrow a:hover,
.c19-article__eyebrow a:focus {
	text-decoration: underline;
}

/*
	Título. Montserrat, e o tamanho vem do elements.h1 do theme.json
	(size-600, 36px) — não se declara aqui.

	O mockup mostra uma serifa maior (passo de linha medido: 48–51px, o
	que dá um corpo de 44–47px). Manteve-se Montserrat a 36px por decisão
	explícita de respeitar a arquitectura de três títulos já fixada
	(handover §5): o corpo do artigo é EB Garamond, e um título em
	Playfair por cima justapunha duas serifas diferentes na mesma coluna.
	A diferença face ao mockup é esperada, não regressão.
*/
.c19-article__header .wp-block-post-title {
	margin: var(--c19-article-gap-eyebrow) 0 0;
	font-family: var(--wp--preset--font-family--montserrat);
	line-height: 1.1;
}

/*
	Filete curto entre o título e o lead. Mesmas dimensões do filete do
	hero — ver a regra agrupada mais acima, onde a largura e a altura
	vivem uma só vez.

	A cor é que diverge, e tem de divergir: a do hero é branco a 40%,
	porque vive sobre o painel preto. Aqui o fundo é claro e usa-se o
	`rule`, o mesmo dos filetes de secção.

	POR VERIFICAR no publicado: o `rule` é #D8D5D0 sobre um fundo
	#fdfdfd. É pouco contraste para um traço de 2px que no hero é
	elemento de destaque, e pode simplesmente desaparecer.
*/
.c19-article__rule {
	margin: var(--c19-article-gap-title) 0 0;
	border: 0;
	background-color: var(--wp--preset--color--rule);
}

/*
	Lead. Vem da ligação chronicle19/post → display_lead, que devolve SÓ
	o campo do SCF — sem a cadeia display_lead → excerto → conteúdo que
	as listagens usam.

	A razão é do artigo e não se transfere: cair para o excerto
	automático aqui seria imprimir as primeiras palavras do corpo
	imediatamente acima do corpo.

	.u-hide-empty no parágrafo: sem lead não há folga a mais, mas o bloco
	de autor continua encostado ao fundo.
*/
.c19-article__lead {
	margin: var(--c19-article-gap-rule) 0 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.6;
	color: var(--wp--preset--color--contrast);
}

/* -------------------------------------------------------------------------
   Bloco de autor
   ---------------------------------------------------------------------- */

/*
	Avatar à esquerda, texto à direita, ícones por baixo. É montagem de
	blocos nativos mais o bloco próprio dos ícones — não um bloco único —
	por coerência com o resto do projecto: os cards, o cabeçalho de secção
	e as listagens são todos montagem.

	O avatar vem do core (core/avatar), e a imagem local do autor entra
	pelo filtro get_avatar() do plugin instalado.

	margin-block-start:auto é o que cola este bloco (e os ícones a seguir,
	que são irmãos) ao fundo da coluna. Está escrito na propriedade
	lógica, e não em margin-top, de propósito: é a mesma propriedade que o
	reset do blockGap lá em cima zera, por isso ganha por ordem sem
	depender de como o browser resolve uma física contra uma lógica.
*/
.c19-article__author {
	margin-block-start: auto;
	display: grid;
	grid-template-columns: auto 1fr;
	column-gap: 12px;
	align-items: center;
}

.c19-article__author .wp-block-avatar img {
	display: block;
	border-radius: 50%;
}

.c19-article__byline {
	min-width: 0;
}

/*
	"BY" antes do nome.

	Vem do atributo `byline` do bloco core/post-author, e não de um
	::before em CSS: é texto que o site emite para o leitor, e nesse caso
	pertence ao DOM — fica no Site Editor para quem quiser mudar, e
	sobrevive a uma folha de estilos que não carregue.

	O preço são as três linhas abaixo, que desfazem o desenho por omissão
	do core: ele empilha o byline por cima do nome (width:100%) e
	encolhe-o a metade (font-size:0.5em), que é o aspecto de "assinatura
	de blogue" e não o desta página. Nenhuma precisa de !important — o
	seletor com a classe do contentor chega.
*/
.c19-article__byline .wp-block-post-author {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.5;
	letter-spacing: 0.08em;
	color: var(--wp--preset--color--contrast);
}

.c19-article__byline .wp-block-post-author__content {
	display: flex;
	flex-wrap: wrap;
	gap: 0.4em;
	flex-grow: 0;
	flex-basis: auto;
}

.c19-article__byline .wp-block-post-author__byline {
	width: auto;
	font-size: inherit;
}

.c19-article__byline .wp-block-post-author__name {
	margin: 0;
}

.c19-article__byline .wp-block-post-author__name a {
	color: inherit;
	text-decoration: none;
}

/*
	Data e tempo de leitura na mesma linha, separados por um ponto médio,
	e MAIS PEQUENOS que o nome do autor — decisão do utilizador.

	Os dois degraus são size-200 (13px) para o nome e size-100 (11px)
	para esta linha. O nome subiu de 11 para 13 porque a escala não tem
	nada abaixo dos 11: manter o nome a 11 obrigaria a acrescentar um
	degrau novo, e o handover (§5) regista a decisão de não criar degraus
	sem necessidade.

	Nota de medição, para quem comparar com o mockup: lá as duas linhas
	medem 8px e 12px de tinta, o que sugeriria a segunda MAIOR. Não é
	conclusivo — a segunda linha tem uma vírgula, que desce abaixo da
	linha de base e infla a medida. Não consigo dizer daqui qual é maior
	no mockup; o que está aqui é a decisão, não uma leitura.

	O separador é CSS e não texto: o tempo de leitura vem por ligação
	(chronicle19/post → read_time) e uma ligação devolve um valor só, sem
	possibilidade de misturar texto literal (§12). No ::before do segundo
	elemento desaparece sozinho quando não há tempo de leitura — o
	read_time devolve string vazia e o .u-hide-empty esconde o elemento
	inteiro, ::before incluído.
*/
.c19-article__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	color: var(--wp--preset--color--muted);
}

/*
	O tamanho é declarado nos FILHOS e não só no contentor, e isso não é
	zelo a mais: um valor herdado perde para qualquer declaração directa
	no elemento, mesmo que essa declaração tenha especificidade zero.
	Basta o Twenty Twenty-Five ou o core declararem font-size para o
	.wp-block-post-date — e declaram, dentro de um :where() — para a data
	ignorar o tamanho do contentor e ficar no valor deles.

	Foi exactamente o que aconteceu na primeira versão: o nome do autor
	obedecia (tinha regra directa) e a data não (contava com herança).

	.c19-article__meta .wp-block-post-date é (0,2,0), o que chega para
	vencer as regras do global stylesheet sem !important.
*/
.c19-article__meta,
.c19-article__meta .wp-block-post-date,
.c19-article__meta .wp-block-post-date time,
.c19-article__read-time {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1.5;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.c19-article__meta > * {
	margin: 0;
}

.c19-article__read-time::before {
	content: "•";
	margin: 0 0.5em;
}

/*
	Ícones sociais do autor. Os SVG vêm do core (os mesmos do
	core/social-links que o header já usa), a 24×24 e sem `fill`
	declarado — a cor herda, e por isso o hover faz-se aqui.

	SUPOSIÇÃO NÃO PEDIDA, removível sozinha: os 18px de caixa e os 16px
	de intervalo. Não há medida do mockup para isto.
*/
.c19-author-social {
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
	margin: 18px 0 0;
	padding: 0;
	list-style: none;
}

.c19-author-social__item {
	margin: 0;
}

.c19-author-social__link {
	display: block;
	color: var(--wp--preset--color--contrast);
}

.c19-author-social__link svg {
	display: block;
	width: 18px;
	height: 18px;
	fill: currentColor;
}

.c19-author-social__link:hover,
.c19-author-social__link:focus {
	color: var(--wp--preset--color--muted);
}

/*
	The wrapper is transparent on desktop, so the existing author/social
	composition and its bottom anchoring remain unchanged. On smaller screens
	it becomes the author row and also holds the article-index trigger.
*/
.c19-article__mobile-meta {
	display: flex;
	flex-direction: column;
	margin-block-start: auto;
}

.c19-article-index-toggle,
.c19-article-index-close {
	display: none;
	margin: 0;
}

/* -------------------------------------------------------------------------
   Imagem do cabeçalho e legenda
   ---------------------------------------------------------------------- */

/*
	A coluna direita é imagem + legenda, e é ela que dita a altura da
	linha — daí o bloco de autor da coluna esquerda assentar ao nível do
	fim da legenda, e não ao nível do fim da imagem.

	O aspect-ratio repete o rácio do tamanho registado. Não é mecanismo:
	o ficheiro já vem em 683×531 e o object-fit não tem nada a cortar. É
	rede de segurança para as imagens antigas que ainda não conseguem
	gerar o tamanho — a mesma função que o aspect-ratio tem nos cards.
*/
.c19-article__figure {
	min-width: 0;
}

.c19-article__figure .wp-block-post-featured-image img {
	aspect-ratio: 753 / 531;
	width: 100%;
	height: auto;
	object-fit: cover;
	display: block;
}

/*
	Legenda da imagem. Vem por ligação (chronicle19/post →
	featured_caption), porque o core/post-featured-image emite a imagem e
	mais nada — a legenda da anexação não faz parte do bloco.
*/
.c19-article__caption {
	margin: 10px 0 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1.5;
	color: var(--wp--preset--color--muted);
}

/* -------------------------------------------------------------------------
   Corpo e índice
   ---------------------------------------------------------------------- */

/*
	O bloco corpo+índice mede 928px e centra-se dentro do alignwide.

	CENTRA-SE POR justify-content E NÃO POR max-width + margin-inline,
	que foi a primeira versão e NÃO FUNCIONAVA. A razão é a armadilha do
	costume: o core declara

	    .is-layout-constrained > .alignwide { max-width: wide-size }

	com especificidade (0,2,0), contra os (0,1,0) de um max-width nosso.
	O contentor ficava com 1150px, a grelha ocupava 928 e alinhava ao
	início — porque justify-content em grelha é `start` por omissão — e o
	margin-inline:auto centrava um bloco de 1150 dentro de 1150, ou seja
	não fazia nada. O resultado publicado era o corpo encostado à
	esquerda, com 222px de vazio só do lado direito.

	O justify-content distribui as COLUNAS dentro do contentor, seja qual
	for a largura que o core lhe imponha. Não compete com nada, e por
	isso não precisa de especificidade nenhuma.

	PORQUE CENTRADO, que é decisão de desenho e não arrumação: o corpo
	está entalado entre dois blocos de largura total — o cabeçalho acima
	e o "More from" abaixo, ambos a 1150. Um bloco estreito nessa
	posição, se encostar a um dos lados, lê-se como erro de alinhamento e
	não como estreitamento deliberado.

	O argumento contrário existe e é legítimo: alinhar à esquerda daria
	continuidade ao eixo do título e uma margem viva coerente. Só ganha
	quando o bloco estreito fecha a composição, ou quando tudo à volta
	partilha a mesma margem esquerda — não é o caso, porque o elemento
	dominante da página, a fotografia, está ancorado à direita.

	PARA REVERTER para o alinhamento à esquerda basta trocar
	`justify-content: center` por `start`. Não é preciso mais nada.

	A coluna direita tem 301px = 1 (filete) + 75 (recuo) + 225 (índice).
	O filete não é uma coluna da grelha: é o border-left do próprio
	índice, e é assim que ele acompanha o elemento em vez de correr a
	altura toda da linha — que é o que o mockup mostra.

	SUPOSIÇÃO NÃO PEDIDA: os 60px de folga acima. Não há medida.
*/
.c19-article__body {
	display: grid;
	grid-template-columns: 552px 301px;
	column-gap: 75px;
	justify-content: center;
	margin-top: 60px;
}

/*
	Aqui está a razão de o corpo do artigo poder viver numa coluna
	estreita sem partir.

	O layout constrained do WordPress aplica max-width com as variáveis
	globais: contentSize aos filhos normais, wideSize ao .alignwide. Elas
	valem 660px e 1150px em todo o site, e 1150 numa coluna de 552 faria
	o bloco tentar ser mais largo que a coluna — e, pelo mínimo
	automático da grelha (§14), a coluna cederia em vez de o cortar.

	Redefini-las localmente resolve sem !important e sem lutar contra o
	core: as regras dele continuam iguais, passam é a consumir os nossos
	valores. Uma imagem alignwide no meio de um artigo alinha-se com a
	coluna de texto, que é o comportamento decidido.
*/
.c19-article__content {
	--wp--style--global--content-size: 552px;
	--wp--style--global--wide-size: 552px;
	min-width: 0;
}

/*
	Capitular no primeiro parágrafo, por CSS e não pelo dropCap do bloco.

	Depender de o autor marcar a opção no painel significa que metade dos
	artigos sairia sem ela — e a decisão é de desenho do template, não de
	quem escreve.

	SUPOSIÇÃO NÃO PEDIDA: as três linhas de altura. O valor sai do
	mockup a olho, não de medição.

	first-of-type e não first-child: se o artigo começar por uma imagem
	ou por um cabeçalho, a capitular continua a cair no primeiro
	parágrafo, que é onde se quer.
*/
.c19-article__content .wp-block-post-content > p:first-of-type::first-letter {
	float: left;
	font-family: var(--wp--preset--font-family--eb-garamond);
	font-size: 3.2em;
	line-height: 0.82;
	padding: 0.05em 0.08em 0 0;
	font-weight: 400;
}

/*
	Os <h2> do corpo levam scroll-margin-top por causa das âncoras do
	índice: sem isto, saltar para uma secção deixa o cabeçalho colado ao
	topo exacto da janela.
*/
.c19-article__content .wp-block-post-content h2 {
	scroll-margin-top: 40px;
}

/*
	Índice.

	align-self: start é obrigatório e não é cosmético: por omissão os
	itens de grelha são `stretch`, o item ocupa a linha toda e o sticky
	fica sem folga para deslizar — não dá erro, simplesmente não funciona.

	O max-height mais o overflow-y resolvem o índice mais alto que a
	janela sem precisar de o tratar como um caso à parte: com poucas
	entradas não aparece barra nenhuma e o comportamento é o do sticky
	simples; com muitas, ganha scroll interno em vez de ficar preso pelo
	topo com o fim inalcançável.

	O overflow aqui NÃO parte o sticky. O que o parte é overflow num
	ANTEPASSADO — e não há nenhum: o style.css regista, logo no topo, a
	decisão de não usar overflow-x:hidden no body.

	SUPOSIÇÃO NÃO PEDIDA: os 40px de `top`. Ponto de partida, a afinar.
*/
.c19-article__aside {
	min-width: 0;
}

.c19-article-index {
	position: sticky;
	top: 40px;
	align-self: start;
	max-height: calc(100vh - 80px);
	overflow-x: hidden;
	overflow-y: auto;
	overscroll-behavior: contain;
	border-left: 1px solid var(--wp--preset--color--rule);
	padding-left: 75px;
}

/*
	O rótulo tem o tamanho do eyebrow das categorias, por decisão.
*/
.c19-article-index__label {
	margin: 0 0 16px;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1.4;
	letter-spacing: 0.1em;
	color: var(--wp--preset--color--contrast);
}

.c19-article-index__list {
	margin: 0;
	padding: 0;
	list-style: none;
}

/*
	Filetes a separar as entradas. São eles que dão estrutura ao bloco
	quando as entradas têm alturas diferentes — a 225px e 13px cabem ~34
	caracteres por linha, portanto uns cabeçalhos ocupam uma linha e
	outros duas. Sem os filetes, essa irregularidade lê-se como desalinho.
*/
.c19-article-index__item + .c19-article-index__item {
	border-top: 1px solid var(--wp--preset--color--rule);
}

/*
	SUPOSIÇÃO NÃO PEDIDA: os 13px (size-200) das entradas e os 14px de
	recuo. Nenhum foi medido.
*/
.c19-article-index__link {
	display: block;
	padding: 14px 0;
	overflow-wrap: anywhere;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.4;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.c19-article-index__item:first-child .c19-article-index__link {
	padding-top: 0;
}

.c19-article-index__link:hover,
.c19-article-index__link:focus {
	color: var(--wp--preset--color--muted);
}

.c19-article-index__link:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 2px;
}

/* -------------------------------------------------------------------------
   Article sharing — external SVG icons in assets/img
   ------------------------------------------------------------------------- */
.c19-share[hidden],
.c19-share .c19-share__action[hidden] {
	display: none;
}

.c19-share {
	margin-top: 40px;
	padding-top: 20px;
	border-top: 1px solid var(--wp--preset--color--rule);
	color: var(--wp--preset--color--contrast);
}

.c19-share__label {
	display: block;
	font-size: 13px;
	line-height: 1.3;
	letter-spacing: .08em;
	text-transform: uppercase;
}

.c19-share__actions {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 10px;
}

.c19-share .c19-share__action {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	margin: 0;
	padding: 0;
	border: 0;
	border-radius: 0;
	background: transparent;
	color: inherit;
	text-decoration: none;
	box-shadow: none;
	cursor: pointer;
}

.c19-share .c19-share__action:hover,
.c19-share .c19-share__action:focus-visible {
	color: var(--wp--preset--color--muted);
}

.c19-share .c19-share__action:focus-visible {
	outline: 2px solid currentColor;
	outline-offset: 2px;
}

.c19-share__icon {
	display: block;
	width: 20px;
	height: 20px;
	background-color: currentColor;
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

.c19-share__icon--facebook { -webkit-mask-image: url("assets/img/facebook.svg"); mask-image: url("assets/img/facebook.svg"); }
.c19-share__icon--bluesky { -webkit-mask-image: url("assets/img/bluesky.svg"); mask-image: url("assets/img/bluesky.svg"); }
.c19-share__icon--mastodon { -webkit-mask-image: url("assets/img/mastodon.svg"); mask-image: url("assets/img/mastodon.svg"); }
.c19-share__icon--threads { -webkit-mask-image: url("assets/img/threads.svg"); mask-image: url("assets/img/threads.svg"); }
.c19-share__icon--x { -webkit-mask-image: url("assets/img/x.svg"); mask-image: url("assets/img/x.svg"); }
.c19-share__icon--chain { -webkit-mask-image: url("assets/img/chain.svg"); mask-image: url("assets/img/chain.svg"); }
.c19-share__icon--device-share { -webkit-mask-image: url("assets/img/device-share.svg"); mask-image: url("assets/img/device-share.svg"); }

.c19-share__status:not(:empty) {
	display: block;
	margin-top: 6px;
	font-size: 13px;
}

/* -------------------------------------------------------------------------
   Comentários do artigo — .c19-comments
   -------------------------------------------------------------------------
   Bloco nativo core/comments, dentro da coluna de 552px do artigo.

	A classe fica no bloco-raiz do template, em vez de se estilizar
	.wp-block-comments globalmente: o WordPress pode usar o mesmo bloco noutro
	contexto e este desenho pertence ao artigo. A tipografia também fica toda
	aqui. Os presets `small` e `eb-garamond` foram retirados dos blocos-filhos
	no template porque os presets do core saem com `!important` e fariam do
	painel uma segunda fonte de verdade.

	Não há regras para o antigo moderador de IA. O componente cobre apenas a
	marcação nativa do WordPress e os dois campos de subscrição que o Jetpack
	acrescenta ao formulário.
   ---------------------------------------------------------------------- */

.c19-comments {
	margin-top: 60px;
	color: var(--wp--preset--color--contrast);
}

.c19-section {
	margin-top: 40px;
}

.c19-section.c19-share {
	padding-top: 0;
	border-top: 0;
}

.c19-section .c19-share__actions {
	margin-top: 0;
}

.c19-contribute__heading .c19-contribute__link {
	display: inline-block;
	padding-bottom: 8px;
	border-bottom: 1px solid var(--wp--preset--color--rule);
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
	transition: opacity 150ms ease, border-color 150ms ease;
}

.c19-contribute__heading .c19-contribute__link:hover,
.c19-contribute__heading .c19-contribute__link:focus {
	opacity: 0.6;
	border-bottom-color: var(--wp--preset--color--contrast);
}

.c19-contribute__heading .c19-contribute__link:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

/*
	O título dinâmico mostra só a contagem (`3 Responses`), não repete o
	título inteiro do artigo. Playfair e size-500 são a mesma receita dos
	cabeçalhos de secção; o filete faz a transição entre artigo e discussão.
*/
.c19-comments .wp-block-comments-title {
	margin: 0;
	padding-bottom: 10px;
	border-bottom: 1px solid var(--wp--preset--color--rule);
	font-family: var(--wp--preset--font-family--playfair-display);
	font-size: var(--wp--preset--font-size--size-500);
	font-weight: 400;
	line-height: 1.2;
	font-variant-numeric: lining-nums;
	text-transform: uppercase;
}

/*
	A lista e as listas de respostas são estrutura, não listas editoriais.
	O reset é local para não tocar nos <ol>/<ul> dentro do texto do artigo.
*/
.c19-comments .wp-block-comment-template,
.c19-comments .wp-block-comment-template .children {
	margin: 0;
	padding: 0;
	list-style: none;
}

.c19-comments .wp-block-comment-template > .comment {
	margin: 0;
	padding: 30px 0;
	border-bottom: 1px solid var(--wp--preset--color--rule);
}

/*
	Cada nível ganha 30px, mas só dentro dos 552px da coluna. Cinco níveis
	a 40px, o valor comum das receitas do core, deixariam o texto reduzido a
	uma tira. A media query mais abaixo baixa este recuo novamente em ecrãs
	estreitos.
*/
.c19-comments .wp-block-comment-template .children {
	margin-left: 30px;
}

.c19-comments .wp-block-comment-template .children > .comment {
	margin: 0;
	padding: 30px 0 0;
}

/*
	O bloco Columns é apenas a grelha avatar/conteúdo. Zerar as margens evita
	que o blockGap do core some espaço vertical ao padding decidido acima.
*/
.c19-comments .wp-block-comment-template .wp-block-columns {
	gap: 15px;
	margin: 0;
}

.c19-comments .wp-block-avatar img {
	display: block;
	border-radius: 50%;
}

.c19-comments .wp-block-comment-author-name {
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	font-weight: 600;
	line-height: 1.4;
}

.c19-comments .wp-block-comment-author-name + .wp-block-group {
	gap: 10px;
	margin: 2px 0 0;
}

.c19-comments .wp-block-comment-date,
.c19-comments .wp-block-comment-edit-link,
.c19-comments .wp-block-comment-reply-link,
.c19-comments .comment-awaiting-moderation {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1.5;
}

.c19-comments .wp-block-comment-date,
.c19-comments .wp-block-comment-date a {
	color: var(--wp--preset--color--muted);
}

.c19-comments .wp-block-comment-edit-link a,
.c19-comments .wp-block-comment-reply-link a {
	color: var(--wp--preset--color--contrast);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 3px;
}

.c19-comments .wp-block-comment-edit-link a:hover,
.c19-comments .wp-block-comment-edit-link a:focus,
.c19-comments .wp-block-comment-reply-link a:hover,
.c19-comments .wp-block-comment-reply-link a:focus {
	color: var(--wp--preset--color--muted);
}

.c19-comments .wp-block-comment-content {
	margin-top: 14px;
	font-family: var(--wp--preset--font-family--eb-garamond);
	font-size: var(--wp--preset--font-size--size-400);
	line-height: 1.5;
}

.c19-comments .wp-block-comment-content > * {
	margin-top: 0;
	margin-bottom: 0;
}

.c19-comments .wp-block-comment-content > * + * {
	margin-top: 1em;
}

.c19-comments .wp-block-comment-reply-link {
	margin-top: 14px;
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.c19-comments .comment-awaiting-moderation {
	margin: 12px 0 0;
	padding-left: 12px;
	border-left: 2px solid var(--wp--preset--color--rule);
	color: var(--wp--preset--color--muted);
	font-style: normal;
}

/* Paginação, quando o volume ultrapassar o limite configurado no core. */
.c19-comments .wp-block-comments-pagination {
	display: flex;
	flex-wrap: wrap;
	gap: 15px;
	align-items: center;
	margin: 30px 0 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	text-transform: uppercase;
	letter-spacing: 0.08em;
}

.c19-comments .wp-block-comments-pagination a {
	color: var(--wp--preset--color--contrast);
}

/* -------------------------------------------------------------------------
   Formulário de comentário
   ---------------------------------------------------------------------- */

.c19-comments .comment-respond {
	margin-top: 50px;
}

/* Sem comentários, o formulário é o primeiro filho: o espaço entre secções
   vem apenas de .c19-section. Remove também o padding global de 30px. */
.wp-block-comments.c19-section > .comment-respond:first-child {
	margin-top: 0;
	padding-top: 0;
}

/*
	O título do formulário e os títulos das secções de partilha e contributo
	partilham o mesmo desenho.
*/
.c19-comments .comment-reply-title,
.c19-section__title {
	margin: 0 0 30px;
	padding-bottom: 10px;
	border-bottom: 1px solid var(--wp--preset--color--rule);
	font-family: var(--wp--preset--font-family--playfair-display);
	font-size: var(--wp--preset--font-size--size-500);
	font-weight: 400;
	line-height: 1.2;
	text-transform: uppercase;
}

.c19-comments .comment-reply-title small {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	font-weight: 500;
	letter-spacing: 0.08em;
}

.c19-comments .comment-reply-title small a {
	margin-left: 12px;
	color: var(--wp--preset--color--muted);
}

.c19-comments .comment-form {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

/*
	A regra geral do post-content daria EB Garamond a 20px a estes parágrafos.
	Aqui são instruções e controlos, por isso usam a linguagem Montserrat dos
	outros formulários do site.
*/
.c19-comments .comment-form > p {
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.6;
}

.c19-comments .comment-form label {
	display: block;
	margin-bottom: 6px;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	letter-spacing: 0.08em;
	text-transform: uppercase;
}

.c19-comments .comment-form input[type="text"],
.c19-comments .comment-form input[type="email"],
.c19-comments .comment-form input[type="url"],
.c19-comments .comment-form textarea {
	box-sizing: border-box;
	width: 100%;
	padding: 8px 0;
	border: 0;
	border-bottom: 1px solid var(--wp--preset--color--rule);
	border-radius: 0;
	background: transparent;
	color: var(--wp--preset--color--contrast);
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.6;
}

.c19-comments .comment-form textarea {
	min-height: 180px;
	font-family: var(--wp--preset--font-family--eb-garamond);
	font-size: var(--wp--preset--font-size--size-400);
	resize: vertical;
}

.c19-comments .comment-form input[type="text"]:focus,
.c19-comments .comment-form input[type="email"]:focus,
.c19-comments .comment-form input[type="url"]:focus,
.c19-comments .comment-form textarea:focus {
	outline: none;
	border-bottom-color: var(--wp--preset--color--contrast);
}

.c19-comments .comment-form input[type="text"]:focus-visible,
.c19-comments .comment-form input[type="email"]:focus-visible,
.c19-comments .comment-form input[type="url"]:focus-visible,
.c19-comments .comment-form textarea:focus-visible,
.c19-comments .comment-form input[type="submit"]:focus-visible,
.c19-comments .wp-block-comment-edit-link a:focus-visible,
.c19-comments .wp-block-comment-reply-link a:focus-visible,
.c19-comments .wp-block-comments-pagination a:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

/* Checkbox nativo e textos de subscrição acrescentados pelo Jetpack. */
.c19-comments .comment-form-cookies-consent,
.c19-comments .comment-subscription-form {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: 8px;
	align-items: start;
}

.c19-comments .comment-form-cookies-consent label,
.c19-comments .comment-subscription-form label {
	margin: 0;
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1.5;
	letter-spacing: 0;
	text-transform: none;
}

.c19-comments .comment-form input[type="checkbox"] {
	margin-top: 0.2em;
	accent-color: var(--wp--preset--color--contrast);
}

/*
	Reserva o espaço do widget antes de o iframe da Cloudflare chegar, para o
	botão não saltar. O aviso sem JavaScript usa a mesma linguagem discreta dos
	erros e instruções do formulário.
*/
.c19-comments__turnstile {
	min-height: 65px;
}

.c19-comments__turnstile-note {
	margin: 0;
	padding-left: 12px;
	border-left: 2px solid var(--wp--preset--color--rule);
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1.5;
}

/*
	Mesma linguagem do submit da página de contacto: acção textual, sem
	caixa preenchida nem cantos redondos que não existem no resto do site.
*/
.c19-comments .comment-form input[type="submit"] {
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	font-weight: 500;
	line-height: 1.5;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	cursor: pointer;
}

.c19-comments .comment-form input[type="submit"]:hover,
.c19-comments .comment-form input[type="submit"]:focus {
	color: var(--wp--preset--color--contrast);
}

@media (max-width: 600px) {
	.c19-comments .wp-block-comment-template .children {
		margin-left: 15px;
	}

	.c19-comments .wp-block-comment-template .wp-block-columns {
		flex-wrap: nowrap;
	}
}

/* -------------------------------------------------------------------------
   "More from Chronicle 19"
   ---------------------------------------------------------------------- */

/*
	Reutiliza .c19-cards e .c19-card sem alterações — três colunas, como
	a listagem. O que muda é só a imagem.

	Ao contrário do .c19-cards--listing, que carrega SÓ grelha por regra
	(handover §11D), este modificador toca na imagem: é o único sítio do
	site onde os cards são paisagem.

	O ficheiro é o c19-landscape (1,907:1), que a 370px de largura daria
	194px de altura. A caixa a 2:1 corta 5% — praticamente nada. O mockup
	mostra uma faixa bem mais estreita (medida: 299×99, ou seja 3,02:1),
	que cortaria 37% da altura de um recorte que o contribuidor enquadrou
	a pensar no hero. Ficou nos 2:1 por decisão, para experimentar
	primeiro o corte mínimo.

	NENHUM tamanho novo foi registado, e não deve ser: um sétimo tamanho
	obrigaria a refazer à mão os recortes do arquivo todo (§9A).
*/
.c19-cards--related {
	--c19-cards-gap: 20px;
	--c19-cards-row-gap: 40px;
	grid-template-columns: repeat(3, 1fr);
}

.c19-cards--related .c19-card__image {
	aspect-ratio: 2 / 1;
}

/*
	Declarado também no descendente por segurança. O core/post-featured-image
	põe o className no <figure> e o aspectRatio do bloco na <img>, e a
	marcação leva os dois — esta regra existe para o caso de a classe cair
	no elemento que não esperávamos, e não faz mal nenhum quando cai no
	esperado.
*/
.c19-cards--related .c19-card__image img {
	aspect-ratio: 2 / 1;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/*
	SUPOSIÇÃO NÃO PEDIDA: os 80px de folga acima da secção.
*/
.c19-related {
	margin-top: 80px;
}

/* -------------------------------------------------------------------------
   Página de contacto — .c19-contact
   -------------------------------------------------------------------------
   Bloco chronicle19/contact-form (functions.php, secção 26).

   NÃO INVENTA LINGUAGEM NENHUMA. Todo o vocabulário de formulário deste
   ficheiro já existia no painel da newsletter do header: campo sem caixa
   nem borda, só um filete em baixo na cor `rule`; Montserrat a size-200;
   foco a passar o filete a `contrast`; botão como texto em maiúsculas a
   size-100 com tracking de 0,08em, sem fundo. Aqui é o mesmo, em ponto
   maior.

   Foi decisão explícita não desenhar um formulário "de site" — com caixas,
   cantos redondos e um botão preenchido —, porque nada no resto do site se
   parece com isso.
   ---------------------------------------------------------------------- */

/*
	SUPOSIÇÃO NÃO PEDIDA: a largura de 552px.

	É o valor da coluna de texto do artigo (§17), reutilizado em vez de se
	inventar um número novo. Sem isto o bloco herdaria o contentSize de
	660px — que o handover §22 já marca para DESCER, por dar 88 caracteres
	por linha. Um formulário não tem o problema da medida de leitura, mas
	também não ganha nada em ser largo.

	Não foi medido contra nada. Afinar contra o publicado.
*/
.c19-contact {
	display: flex;
	flex-direction: column;
	gap: 30px;
	max-width: 552px;
	margin-inline: auto;
}

/*
	Zerar a margem em TODOS os filhos, e não campo a campo. É a lição do
	§14 sobre o blockGap: o espaçamento é do contentor (o `gap` acima), e
	qualquer margem herdada — do TT5, do core, do browser — soma-se a ele
	sem se ver de onde veio.
*/
.c19-contact > * {
	margin: 0;
}

/*
	------------------------------------------------------------------
	PORQUE É QUE AS REGRAS DE PARÁGRAFO ABAIXO LEVAM `.c19-contact` À
	FRENTE
	------------------------------------------------------------------

	O bloco é inserido DENTRO da Página, ou seja dentro do
	core/post-content. E este ficheiro tem, mais acima:

		.wp-block-post-content p,
		.wp-block-post-content li,
		.wp-block-post-content blockquote { EB Garamond, 20px, 1.4 }

	Essa regra tem especificidade (0,1,1) — uma classe e um elemento — e
	uma classe sozinha, (0,1,0), perde para ela. Sem o prefixo, a
	introdução, o aviso e a nota de privacidade saíam todos em EB Garamond
	a 20px no meio de um formulário em Montserrat.

	NÃO É UM SINTOMA TRATADO COM CSS: a regra de cima está certa e é
	deliberada — o §5 regista que apanha as Páginas de propósito, porque o
	corpo de uma política de privacidade também deve ser Garamond. O que
	aqui se faz é o que se faz a qualquer componente que viva dentro do
	conteúdo: prefixá-lo com a sua própria raiz. É a mesma técnica que o
	`.c19-article__content .wp-block-post-content h2` já usa neste
	ficheiro. Não há `!important` nenhum e a regra de cima fica intacta.

	CORRECÇÃO ESTRUTURAL FEITA AO MESMO TEMPO, e essa não é CSS: os
	campos do formulário eram `<p>` e passaram a `<div>` no render.php.
	Um parágrafo que envolve um <label>, um <input> e uma mensagem de erro
	nunca foi um parágrafo — era só o hábito dos formulários antigos. Com
	isso, os únicos <p> que restam dentro do bloco são os quatro de texto
	a sério, e são exactamente estes.
*/

/*
	Reutiliza .c19-section-heading (Playfair, maiúsculas, lining-nums) e o
	preset size-500, exactamente como o <h1> das listagens (§11D). Não se
	criou um quarto papel de título — o §5 avisa que os três papéis só se
	mantêm distintos enquanto ninguém acrescentar regras por coincidência
	de valor.

	SUPOSIÇÃO NÃO PEDIDA, removível sozinha: o filete por baixo. No
	/stories/ vem do border do Group na marcação; aqui tem de estar em CSS
	porque este cabeçalho é dinâmico (leva o nome do autor) e não pode ser
	um core/heading.

	A cor `rule` sobre o `base` #fdfdfd é pouco contraste — é a mesma
	ressalva que o §17 já regista para o filete do artigo, e vale aqui
	pela mesma razão.
*/
.c19-contact__heading {
	padding-bottom: 10px;
	border-bottom: 1px solid var(--wp--preset--color--rule);
}

.c19-contact .c19-contact__intro {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.6;
	color: var(--wp--preset--color--contrast);
}

/*
	Avisos — erro, sucesso e o de autor indisponível.

	Filete de 2px à esquerda e nada mais: sem fundo, sem caixa, sem ícone.
	Os 2px são os mesmos do .c19-featured__rule, que é o único filete
	"grosso" do site. Uma caixa preenchida seria o primeiro elemento com
	fundo de cor em todo o Chronicle 19.
*/
.c19-contact__notice {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.6;
	border-left: 2px solid var(--wp--preset--color--rule);
	padding-left: 15px;
}

.c19-contact .c19-contact__notice p {
	margin: 0;
}

.c19-contact__notice.is-error {
	border-left-color: var(--c19-error);
	color: var(--c19-error);
}

.c19-contact__notice.is-success {
	border-left-color: var(--wp--preset--color--contrast);
	color: var(--wp--preset--color--contrast);
}

.c19-contact__notice.is-info {
	color: var(--wp--preset--color--muted);
}

.c19-contact__form {
	display: flex;
	flex-direction: column;
	gap: 24px;
}

/*
	Nome e e-mail lado a lado, assunto e mensagem a toda a largura.

	SUPOSIÇÃO NÃO PEDIDA: os 20/24px de intervalo, e a própria decisão de
	pôr dois campos por linha. Nenhum foi medido.

	O min-width: 0 nas células não é decorativo — num grid, `1fr` é
	`minmax(auto, 1fr)` e esse `auto` é min-content, portanto um input com
	um `size` implícito grande faz a coluna ceder em vez de o campo
	encolher. É a mesma armadilha do §14 que já mordeu as listagens.
*/
.c19-contact__grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	column-gap: 20px;
	row-gap: 24px;
}

.c19-contact__field {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: 0;
	min-width: 0;
}

.c19-contact__field--full {
	grid-column: 1 / -1;
}

.c19-contact__label {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast);
}

/*
	O contacto e a 404 têm o mesmo filete persistente e a mesma altura de
	linha. A base visual comum está junto da pesquisa do header; ficam aqui
	apenas as propriedades que estes dois contextos partilham entre si.

	Os estados de erro e a textarea continuam exclusivos do contacto.
*/
.c19-contact__input,
.c19-not-found__search .wp-block-search__input {
	width: 100%;
	border-bottom: 1px solid var(--wp--preset--color--rule);
	line-height: 1.6;
}

.c19-contact__input:focus,
.c19-not-found__search .wp-block-search__input:focus {
	outline: none;
	border-bottom-color: var(--wp--preset--color--contrast);
}

/*
	SUPOSIÇÃO NÃO PEDIDA: a altura mínima da caixa de mensagem. O `rows=8`
	da marcação já dá o mesmo resultado na maioria dos browsers; isto é a
	garantia. `resize: vertical` e não `both` — horizontal partia a
	grelha.
*/
textarea.c19-contact__input {
	min-height: 180px;
	resize: vertical;
}

.c19-contact__field.is-invalid .c19-contact__label {
	color: var(--c19-error);
}

.c19-contact__field.is-invalid .c19-contact__input {
	border-bottom-color: var(--c19-error);
}

.c19-contact__error {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	color: var(--c19-error);
}

/*
	HONEYPOT.

	Escondido para pessoas, presente para robôs. NÃO se usa `display:
	none` nem `visibility: hidden` de propósito: os robôs que valem alguma
	coisa reconhecem os dois e saltam o campo. Esta receita — 1px, clip e
	overflow — deixa o campo no fluxo e no DOM tal como qualquer outro.

	O tabindex="-1" está na marcação e tira-o da tabulação; o aria-hidden
	tira-o do leitor de ecrã. Nenhum utilizador legítimo lhe chega.

	NÃO APAGAR JULGANDO QUE É CÓDIGO MORTO. Sem esta regra o campo aparece
	no meio do formulário a pedir "Leave this field empty", e quem o
	preencher tem a mensagem descartada em silêncio.
*/
.c19-contact__hp {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

/*
	Widget do Turnstile (functions.php, 26.4).

	Quase nada: o widget traz o seu próprio desenho, vem num iframe da
	Cloudflare e não se estiliza por fora. O que aqui está é só o espaço que
	ele ocupa no fluxo do formulário — o `gap` do .c19-contact__form já trata
	da distância aos vizinhos.

	O `data-size="flexible"` faz o widget acompanhar a largura do contentor
	em vez dos 300px fixos por omissão. Os 65px de altura são os que a
	Cloudflare documenta; declarar `min-height` evita o salto de layout entre
	o momento em que o <div> está vazio e o momento em que o iframe entra.

	SUPOSIÇÃO NÃO PEDIDA: os 65px. Não foram medidos contra o publicado.
*/
.c19-contact__turnstile {
	min-height: 65px;
}

.c19-contact__actions {
	display: flex;
}

/*
	Receita do botão do painel da newsletter. SUPOSIÇÃO NÃO PEDIDA: o
	alinhamento à esquerda. No header o botão está a flex-end porque a
	coluna tem 220px; aqui, por baixo de uma caixa de mensagem de 552px, à
	direita fica longe do sítio para onde o olho vem.
*/
.c19-contact__submit {
	padding: 0;
	background: none;
	border: 0;
	color: var(--wp--preset--color--muted);
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	cursor: pointer;
}

.c19-contact__submit:hover {
	color: var(--wp--preset--color--contrast);
}

.c19-contact__submit:focus-visible,
.c19-contact__input:focus-visible,
.c19-not-found__search .wp-block-search__input:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

/*
	O <p> que envolve o link de regresso. Sem isto herdava o Garamond de
	20px da regra do post-content (ver a nota acima) e arrastava o link
	consigo — o .c19-cta-link não declara família nenhuma, herda-a de onde
	estiver.
*/
.c19-contact .c19-contact__back {
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	line-height: 1.6;
}

.c19-contact .c19-contact__privacy {
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	line-height: 1.6;
	color: var(--wp--preset--color--muted);
}

.c19-contact .c19-contact__privacy a {
	color: inherit;
	text-decoration: underline;
}

/* -------------------------------------------------------------------------
   Responsive article
   ---------------------------------------------------------------------- */

/* -------------------------------------------------------------------------
   Responsive homepage hero
   ---------------------------------------------------------------------- */

@media (max-width: 699px) {
	.c19-featured--hero {
		flex-direction: column;
		min-height: 0;
		overflow: hidden;
	}

	/* The image keeps its editorial crop. Its transparent mask reveals the
	   hero's black background and creates the horizontal transition band. */
	.c19-featured--hero .c19-featured__image {
		position: relative;
		inset: auto;
		order: 1;
		display: block;
		width: 100%;
		height: auto;
		aspect-ratio: 900 / 472;
		object-fit: cover;
		-webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 72px), transparent 100%);
		mask-image: linear-gradient(to bottom, #000 calc(100% - 72px), transparent 100%);
	}

	.c19-featured--hero::before {
		display: none;
	}

	.c19-featured--hero .c19-featured__panel {
		order: 2;
		justify-content: flex-start;
		width: 100%;
		padding: 20px 25px 36px;
	}

	.c19-featured--hero .c19-featured__lead {
		text-wrap: wrap;
	}

	.c19-featured--banner {
		flex-direction: column;
		width: calc(100% - 50px);
		min-height: 0;
		margin-inline: auto;
		overflow: hidden;
	}

	.c19-featured--banner .c19-featured__image {
		position: relative;
		inset: auto;
		order: 1;
		display: block;
		width: 100%;
		height: auto;
		aspect-ratio: 900 / 472;
		object-fit: cover;
		-webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 72px), transparent 100%);
		mask-image: linear-gradient(to bottom, #000 calc(100% - 72px), transparent 100%);
	}

	.c19-featured--banner::before {
		display: none;
	}

	.c19-featured--banner .c19-featured__panel {
		order: 2;
		justify-content: flex-start;
		width: 100%;
		padding: 20px 25px 36px;
	}

	.c19-featured--banner .c19-featured__lead {
		text-wrap: wrap;
	}
}

/* -------------------------------------------------------------------------
   Responsive category archives — reference listing
   ---------------------------------------------------------------------- */

@media (max-width: 1050px) {
	body.home main > .wp-block-group.alignwide,
	body.home main > .wp-block-query.alignwide {
		width: calc(100% - 50px);
		margin-inline: auto;
	}

	body.home .c19-latest > .wp-block-group.alignwide,
	body.home .c19-latest > .wp-block-query.alignwide {
		width: 100%;
		margin-inline: 0;
	}

	body.home main > .wp-block-query.alignwide > .c19-cards,
	body.home .c19-latest .c19-cards {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 20px;
		row-gap: 40px;
	}
}

@media (max-width: 699px) {
	body.home main > .wp-block-query.alignwide > .c19-cards,
	body.home .c19-latest .c19-cards {
		grid-template-columns: minmax(0, 1fr);
	}
}

@media (max-width: 1050px) {
	body.home .c19-events > .wp-block-group.alignwide,
	body.home .c19-events > .wp-block-query.alignwide {
		width: 100%;
		margin-inline: 0;
	}

	body.home .c19-events__list {
		display: flex;
		gap: 20px;
		overflow-x: auto;
		overflow-y: hidden;
		padding: 0 0 16px;
		scroll-snap-type: x mandatory;
		scroll-padding-inline: 0;
		overscroll-behavior-inline: contain;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: thin;
	}

	body.home .c19-events__list > li,
	body.home .c19-events__list > li:nth-child(n + 4),
	body.home .c19-events__list > li:nth-child(n + 5) {
		display: block;
		flex: 0 0 clamp(260px, 72vw, 340px);
		min-width: 0;
		scroll-snap-align: start;
	}

	body.home .c19-events__list > li:not(:first-child) .c19-event::before {
		margin-left: -10px;
	}
}

@media (min-width: 600px) and (max-width: 1050px) {
	body.home .c19-events__list > li,
	body.home .c19-events__list > li:nth-child(n + 4),
	body.home .c19-events__list > li:nth-child(n + 5) {
		flex-basis: calc((100% - 40px) / 2.25);
	}
}

@media (max-width: 1050px) {
	.c19-events-list .c19-events-list__excerpt {
		text-wrap: wrap;
	}

	.c19-contact {
		-webkit-text-size-adjust: 100%;
		text-size-adjust: 100%;
	}

	body.page .wp-block-post-content .c19-contact .c19-contact__label,
	body.page .wp-block-post-content .c19-contact .c19-contact__privacy {
		font-size: var(--wp--preset--font-size--size-100);
	}

	body.page .wp-block-post-content .c19-contact .c19-contact__label {
		line-height: 1.4;
	}

	body.page .wp-block-post-content .c19-contact .c19-contact__privacy {
		line-height: 1.6;
	}
}

@media (max-width: 1050px) {
	:is(body.blog, body.category, body.tag, body.author, body.date, body.search) .c19-page-heading,
	:is(body.blog, body.category, body.tag, body.author, body.date, body.search) main > .wp-block-template-part.alignwide,
	body.page-template-top-stories .c19-page-heading,
	body.page-template-top-stories main > .wp-block-query.alignwide {
		width: calc(100% - 50px);
		margin-inline: auto;
	}

	:is(body.blog, body.category, body.tag, body.author, body.date, body.search-results, body.page-template-top-stories) .c19-cards--listing {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		column-gap: 20px;
		row-gap: 40px;
	}
}

@media (max-width: 699px) {
	:is(body.blog, body.category, body.tag, body.author, body.date, body.search-results, body.page-template-top-stories) .c19-cards--listing {
		grid-template-columns: minmax(0, 1fr);
	}
}

@media (max-width: 1050px) {
	.c19-article__header {
		display: grid;
		grid-template-columns: minmax(0, 1fr);
		row-gap: 0;
	}

	/* Expose the intro children to the header grid so the featured image can
	   sit between the title and the lead without duplicating any content. */
	.c19-article__intro {
		display: contents;
	}

	.c19-article__eyebrow {
		order: 1;
	}

	.c19-article__header .wp-block-post-title {
		order: 2;
	}

	.c19-article__figure {
		order: 3;
		margin-top: 24px;
	}

	.c19-article__lead {
		order: 4;
		justify-self: stretch;
		width: 100%;
		max-width: none;
		box-sizing: border-box;
		margin-top: 24px;
		text-wrap: wrap;
	}

	.c19-article__mobile-meta {
		order: 5;
		display: grid;
		grid-template-columns: minmax(0, 1fr) 44px;
		column-gap: 20px;
		align-items: center;
		margin-top: 28px;
	}

	.c19-article__mobile-meta .c19-article__author,
	.c19-article__mobile-meta .c19-author-social {
		grid-column: 1;
	}

	.c19-article__mobile-meta .c19-article__author {
		grid-row: 1;
		margin-block-start: 0;
	}

	.c19-article__mobile-meta .c19-author-social {
		grid-row: 2;
	}

	.c19-article-index-toggle {
		grid-column: 2;
		grid-row: 1 / span 2;
		align-self: end;
		display: grid;
		place-items: center;
		width: 44px;
		height: 44px;
		padding: 0;
		border: 0;
		border-radius: 0;
		background: transparent;
		color: var(--wp--preset--color--contrast);
		cursor: pointer;
	}

	.c19-article-index-toggle svg,
	.c19-article-index-close svg {
		display: block;
		width: 24px;
		height: 24px;
		stroke: currentColor;
	}

	.c19-article-index-toggle:focus-visible,
	.c19-article-index-close:focus-visible {
		outline: 2px solid currentColor;
		outline-offset: 2px;
	}

	.c19-article__rule {
		order: 6;
		width: 100%;
		height: 1px;
		margin-top: 32px;
	}

	.c19-article__body {
		grid-template-columns: minmax(0, 1fr);
		margin-top: 32px;
	}

	.c19-article__content {
		--wp--style--global--content-size: 100%;
		--wp--style--global--wide-size: 100%;
		width: 100%;
	}

	.c19-article__content .wp-block-post-content p,
	.c19-article__content .wp-block-post-content li,
	.c19-article__content .wp-block-post-content blockquote {
		font-size: 20px;
		line-height: 1.5;
	}

	.c19-article__aside {
		position: fixed;
		z-index: 100001;
		top: 0;
		right: 0;
		bottom: 0;
		width: min(88vw, 420px);
		background: var(--wp--preset--color--base);
		box-shadow: 0 0 0 100vmax rgb(0 0 0 / 45%);
		transform: translateX(110%);
		visibility: hidden;
		transition: transform 180ms ease, visibility 0s linear 180ms;
	}

	.c19-article__aside.is-open {
		transform: translateX(0);
		visibility: visible;
		transition-delay: 0s;
	}

	.c19-article-index-close {
		position: absolute;
		z-index: 1;
		top: 18px;
		right: 18px;
		display: grid;
		place-items: center;
		width: 44px;
		height: 44px;
		padding: 0;
		border: 0;
		background: transparent;
		color: var(--wp--preset--color--contrast);
		cursor: pointer;
	}

	.c19-article-index {
		position: static;
		max-height: 100dvh;
		height: 100%;
		box-sizing: border-box;
		border-left: 0;
		padding: 76px 24px 32px;
	}

	html.c19-index-open,
	html.c19-index-open body {
		overflow: hidden;
	}

	.c19-comments {
		width: 100%;
	}

	.c19-comments .wp-block-comment-content {
		font-size: 20px;
		line-height: 1.5;
	}

	.c19-related {
		margin-top: 64px;
	}

	.c19-cards--related {
		display: flex;
		gap: 16px;
		overflow-x: auto;
		overflow-y: hidden;
		padding: 0 0 16px;
		scroll-snap-type: x mandatory;
		scroll-padding-inline: 0;
		overscroll-behavior-inline: contain;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: thin;
	}

	.c19-cards--related > li {
		flex: 0 0 clamp(260px, 72vw, 340px);
		min-width: 0;
		scroll-snap-align: start;
	}
}

@media (max-width: 600px) {
	body.error404 .c19-not-found > .wp-block-columns > .wp-block-column:first-child {
		display: flex;
		justify-content: center;
	}

	body.error404 .c19-not-found > .wp-block-columns > .wp-block-column:first-child .wp-block-image {
		width: 80%;
	}

	body.error404 .c19-not-found > .wp-block-columns > .wp-block-column:last-child {
		text-wrap: wrap;
	}

	body.page .wp-block-post-content :is(p, li, blockquote) {
		font-size: 20px;
		line-height: 1.5;
	}

	.c19-contact__grid {
		grid-template-columns: minmax(0, 1fr);
	}

	.c19-article__header .wp-block-post-title {
		font-size: clamp(1.75rem, 8vw, 2.25rem);
	}

	.c19-article__figure .wp-block-post-featured-image img {
		aspect-ratio: auto;
	}

	.c19-related > .wp-block-group {
		align-items: flex-start;
		gap: 10px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.c19-article__aside {
		transition: none;
	}
}

/* -------------------------------------------------------------------------
   Rodapé — .c19-footer
   -------------------------------------------------------------------------
   O rodapé deixou de ser uma faixa preta e passou a ser uma zona clara e
   arejada, como o cabeçalho. O que o separa do conteúdo é um filete, não
   uma mancha de cor. "Como o cabeçalho" quer dizer arejado, não igual: o
   rodapé é deliberadamente mais discreto, e por isso mantém o logótipo a
   120px e a assinatura em size-200, contra os 300px e size-300 do topo.

   O filete, a margem, o espaçamento interno, o intervalo de 8px entre
   logótipo e assinatura e o alinhamento horizontal das duas colunas estão
   todos nos ATRIBUTOS DOS BLOCOS, não aqui — ver o preâmbulo deste
   ficheiro. Só desce a este ficheiro o que o editor não sabe exprimir.

   Três notas que custaram uma tentativa falhada cada:

   O FILETE VIVE NO GROUP EXTERIOR, não no interior marcado alignfull. Um
   alignfull ocupa 100% do contentor onde está, e o interior está dentro de
   um alignwide. Medido a 1200px: interior 1135px, exterior 1185px, e a
   .c19-navbar do cabeçalho 1185px. Só o exterior alinha com o cabeçalho.

   OS 40px SÃO margin-top E NÃO padding-top. A borda vem antes do padding:
   com padding, o filete encosta ao conteúdo da página e os 40px abrem-se
   do lado errado. É também o mecanismo que a homepage já usa para separar
   secções (.c19-latest, .c19-events e o cabeçalho de Top Stories, todos
   com margin-top no próprio bloco).

   O justify-content VERTICAL NÃO É EXPRIMÍVEL NO BLOCO. Num group flex
   vertical, o atributo `justifyContent` do WordPress mapeia para
   align-items — o eixo transversal. Não há atributo para o eixo principal,
   e é por isso que os dois space-between abaixo estão em CSS e não na
   marcação.
   ------------------------------------------------------------------------- */

/*
	A linha do rodapé estica as duas colunas à mesma altura, para o
	copyright poder descer até ao fundo e alinhar com o último item do
	menu. Sem stretch, cada coluna teria a altura do seu conteúdo e o
	space-between abaixo não teria espaço nenhum para distribuir.
*/
.c19-footer__row {
	align-items: stretch;
}

.c19-footer__brandbox {
	justify-content: space-between;
}

.c19-footer__meta {
	justify-content: space-between;
}

/*
	RESET DE MARGENS, obrigatório e já esquecido uma vez nesta secção.

	A assinatura traz margin-top: 13px do WordPress. Num contentor flex as
	margens dos filhos SOMAM-SE ao gap em vez de o substituírem, portanto o
	blockGap de 8px do bloco dava 21px reais. É a mesma armadilha da §11A e
	da §14, e a regra de lá aplica-se aqui sem alteração: este reset faz-se
	sempre a par de qualquer grid ou flex novo.
*/
.c19-footer__brand-group > * {
	margin: 0;
}

/*
	Logótipo do rodapé.

	Classe própria, e não a .c19-logo-full do cabeçalho, precisamente para
	NÃO herdar o min(300px, 80vw) de lá. Aqui o valor é fixo: 120px é
	pequeno o suficiente para não precisar de encolher em ecrã nenhum.

	A altura acompanha o rácio do ficheiro (674×106) e está declarada no
	HTML, não aqui, para o browser reservar o espaço antes de o SVG chegar.
*/
.c19-footer__logo {
	display: block;
	width: 120px;
	height: auto;
}

/*
	display:block e não inline-block.

	Com inline-block, o <a> gera uma caixa de linha anónima que herda o
	line-height do contentor e acrescenta espaço por baixo da imagem — e o
	line-height:0 aqui declarado aplica-se ao <a>, não a essa caixa.
	Medido: 32px entre logótipo e assinatura com inline-block, 8px com
	block.
*/
.c19-footer__brand {
	display: block;
	line-height: 0;
}

/*
	Copyright.

	Estilizado aqui por obrigação, não por escolha: o parágrafo está ligado
	à fonte chronicle19/date (secção 29 do functions.php) e a §12 é
	categórica — um estilo aplicado pelo painel do editor a um bloco ligado
	é descartado em silêncio ao reabrir.
*/
.c19-footer__copyright {
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-100);
	color: var(--wp--preset--color--contrast);
}

/* -------------------------------------------------------------------------
   Responsive footer
   -------------------------------------------------------------------------
   Abaixo de 1050px a composição passa de duas colunas para uma pilha
   centrada: logótipo, assinatura, ícones sociais, menu e copyright.

   1050px e não os 815px que a .c19-tagline usa: o 815 é o ponto do
   hambúrguer do cabeçalho, calibrado para as nove categorias, e não tem
   nada que ver com o rodapé. O rodapé segue a convenção do resto do site.
   ------------------------------------------------------------------------- */

@media (max-width: 1050px) {
	.c19-footer__row {
		flex-direction: column;
		align-items: center;
		text-align: center;
		gap: 20px;
	}

	/*
		display:contents é o que permite ao copyright chegar ao fim.

		Ele vive dentro do brandbox, para no desktop poder descer ao fundo
		da coluna esquerda. Os ícones sociais e o menu vivem no meta, que é
		IRMÃO do brandbox — e `order` só reordena entre irmãos do mesmo
		contentor. Com display:contents o brandbox deixa de gerar caixa, os
		seus filhos passam a contar como filhos directos da linha, e só
		então o copyright pode passar para depois do menu.

		Seguro num <div> sem semântica própria: display:contents remove a
		caixa, não o elemento da árvore de acessibilidade.

		O CONTEXTO .c19-footer NÃO É DECORATIVO — é o que faz a regra
		ganhar. O core declara `body .is-layout-flex { display: flex }`,
		que é (0,1,1). Um `.c19-footer__brandbox` sozinho é (0,1,0) e
		PERDE: o brandbox continuava a ser caixa flex, o copyright ficava
		preso lá dentro e nenhum `order` o tirava de lá. Com o contexto
		fica (0,2,0) e ganha, sem !important.

		É a mesma armadilha da versão 20, quando a regra dos eventos perdeu
		por não ter o contexto do body. É a única das quinze declarações
		desta secção que precisa de reforço — as outras catorze foram
		verificadas uma a uma contra o valor computado no publicado.
	*/
	.c19-footer .c19-footer__brandbox {
		display: contents;
	}

	.c19-footer__brand-group {
		order: 1;
		align-items: center;
	}

	.c19-footer__meta {
		order: 2;
		width: 100%;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: 16px;
	}

	.c19-footer__copyright {
		order: 3;
	}

	/*
		Contexto pelo mesmo motivo do brandbox, mas por precaução e não por
		falha observada. O bloco declara justifyContent:right, que o core
		serve como `.wp-container-core-social-links-is-layout-XXX
		{justify-content:flex-end}` — (0,1,0), exactamente a mesma
		especificidade que `.c19-footer__socials` sozinho. Num empate ganha
		quem for impressa depois, e a ordem entre o style.css do tema e os
		estilos de layout do core não é nossa para garantir. Com o contexto
		deixa de haver empate.
	*/
	.c19-footer .c19-footer__socials {
		justify-content: center;
		width: 100%;
	}

	/*
		Desfaz a coluna que o layout vertical do bloco de Navegação impõe.

		A regra do core é .wp-block-navigation.is-vertical
		.wp-block-navigation__container (0,2,1). Esta é (0,3,0) e ganha na
		cascata sem !important — que é o que o preâmbulo deste ficheiro
		pede. Mantém-se o is-vertical na marcação: no desktop é ele que
		empilha os quatro links.
	*/
	.c19-footer__menu.is-vertical .wp-block-navigation__container {
		flex-direction: row;
		flex-wrap: wrap;
		justify-content: center;
		align-items: baseline;
	}

	/*
		Separador entre itens, na linguagem já usada no eyebrow dos cards
		(core/post-terms com separador "|").

		Gerado em ::after do <li> e não como conteúdo real: assim fica
		preso ao item que o antecede, e se a linha partir o "|" fica no fim
		da linha anterior em vez de abrir a seguinte. É o inverso da
		armadilha do core/post-terms, que envolve cada separador num <span>
		com white-space: pre-wrap e parte sempre logo a seguir.

		Estimado a 11px: quatro itens ocupam cerca de 250px e cinco cerca
		de 300px, portanto uma linha só até perto dos 360px de ecrã. A
		quebra é rede de segurança, não o caso normal.
	*/
	.c19-footer__menu .wp-block-navigation-item:not(:last-child)::after {
		content: "|";
		margin-inline: 0.6em;
		color: var(--wp--preset--color--rule);
	}
}

/* -------------------------------------------------------------------------
   Página Authors

   O cabeçalho de cada autor mantém duas colunas em todas as larguras: a
   fotografia dá a altura normal da linha, enquanto o nome e os ícones podem
   partir dentro da coluna direita. A biografia e o CTA ocupam a largura toda.
   ------------------------------------------------------------------------- */

.c19-authors {
	margin-block-start: 40px;
}

.c19-authors__author {
	padding-block: 40px;
	border-top: 1px solid var(--wp--preset--color--rule);
}

.c19-authors__author:first-child {
	border-top: 0;
}

.c19-authors__identity {
	display: grid;
	grid-template-columns: 160px minmax(0, 1fr);
	column-gap: 32px;
	align-items: stretch;
	min-height: 160px;
}

.c19-authors__photo {
	line-height: 0;
}

.c19-authors__avatar {
	display: block;
	box-sizing: border-box;
	width: 160px;
	height: 160px;
	border: 1px solid var(--wp--preset--color--rule);
	border-radius: 50%;
	object-fit: cover;
}

.c19-authors__details {
	display: flex;
	min-width: 0;
	flex-direction: column;
	justify-content: space-between;
}

.c19-authors__name {
	margin: 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-500);
	font-weight: 500;
	line-height: 1.5;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--wp--preset--color--contrast);
}

.c19-authors__socials {
	display: flex;
	flex-wrap: wrap;
	gap: 16px;
	margin: 20px 0 0;
	padding: 0;
	list-style: none;
}

.c19-authors__social-item {
	margin: 0;
}

.c19-authors .c19-authors__social-link {
	display: block;
	padding: 0;
	border: 0;
	background: none;
	color: var(--wp--preset--color--contrast);
	text-decoration: none;
}

.c19-authors__social-link svg {
	display: block;
	width: 20px;
	height: 20px;
	fill: currentColor;
}

.c19-authors .c19-authors__social-link:hover,
.c19-authors .c19-authors__social-link:focus {
	color: var(--wp--preset--color--muted);
}

.c19-authors .c19-authors__social-link:focus-visible {
	outline: 2px solid var(--wp--preset--color--contrast);
	outline-offset: 4px;
}

.c19-authors__bio {
	margin-block-start: 24px;
}

.c19-authors__bio > :first-child {
	margin-block-start: 0;
}

.c19-authors__bio > :last-child {
	margin-block-end: 0;
}

.wp-block-post-content p.c19-authors__action {
	margin: 24px 0 0;
	font-family: var(--wp--preset--font-family--montserrat);
	font-size: var(--wp--preset--font-size--size-200);
	font-weight: 500;
	line-height: 1.4;
	letter-spacing: -0.1px;
	text-transform: uppercase;
	text-align: right;
}

.c19-authors__empty {
	margin-block-start: 40px;
}

@media (max-width: 600px) {
	.c19-authors {
		margin-block-start: 30px;
	}

	.c19-authors__author {
		padding-block: 30px;
	}

	.c19-authors__identity {
		grid-template-columns: 104px minmax(0, 1fr);
		column-gap: 18px;
		min-height: 104px;
	}

	.c19-authors__avatar {
		width: 104px;
		height: 104px;
	}

	.c19-authors__socials {
		gap: 12px;
		margin-block-start: 12px;
	}

	.c19-authors__bio,
	.c19-authors__action {
		margin-block-start: 20px;
	}
}
