/* ============================================================
 * sda-extra.css — camada do tema sobre o main.css do design.
 *
 * O main.css é sincronizado 1:1 com o tema de referência (sopro) e
 * não deve ser editado aqui. Tudo o que o sopro-dalma acrescenta por
 * cima (Fase 63 Batch 7: loader, drawer mobile, sliders, carrosséis
 * mobile, selos rotativos) vive neste ficheiro.
 * ============================================================ */

/* ------------------------------------------------------------
 * PRODUÇÃO — o main.css fixa `body { min-width: 1920px }` como
 * scaffolding da fase de validação pixel-perfect ("o canvas
 * desktop é fixo a 1920"). Em produção o canvas é fluido: a
 * grelha de 1400px centra-se e o decor full-bleed é clipado no
 * limite do viewport — zero sidescroll em qualquer largura.
 * ------------------------------------------------------------ */

html {
	/* hidden é fallback para browsers sem `clip`; onde clip existe, vence. */
	overflow-x: hidden;
	overflow-x: clip;
}

body {
	min-width: 0;
}

/* Abaixo de 1920 o canvas inteiro (header + conteúdo + footer) centra-se
   como uma faixa de 1920px — todas as coordenadas absolutas do mock
   resolvem contra ela, pelo que header, secções full-bleed e .seccao-inner
   ficam alinhados entre si em qualquer largura. Como a faixa é sempre
   MAIOR que o viewport, os fundos full-bleed continuam a cobrir tudo. */
/* O design tem dois layouts: desktop (canvas fixo de 1920) e mobile (390,
   a partir dos 430px para baixo). Entre os dois, ESCALA-SE o canvas para
   caber no ecrã em vez de o cortar — antes a faixa de 1920 era centrada e
   as laterais perdiam-se sem hipótese de lá chegar (o scroll horizontal
   está bloqueado). Escalar resolve isso e, de caminho, o site deixa de
   parecer "aumentado" em portáteis, que era queixa do cliente.

   `zoom` (e não `transform: scale`) porque afecta o layout: as alturas
   acompanham e não sobra espaço em branco no fim da página.

   ATENÇÃO ao limite inferior: abaixo dos 430px o main.css entra no seu
   próprio canvas mobile (coordenadas na casa dos 0-390px) e não pode
   levar nem faixa nem zoom, senão o conteúdo sai todo do ecrã. */
@media (min-width: 430.02px) and (max-width: 1919.98px) {
	/* O `zoom` em si é posto pelo script inline do <head>
	   (sda_escala_canvas em inc/enqueue.php): tem de ser um número, e
	   `calc(100vw / 1920)` devolveria um comprimento. */

	.site-header,
	.site-content,
	.site-footer {
		position: relative;
		width: 1920px;
		max-width: none;
		margin-inline: 0;
		padding-inline: 0;
		box-sizing: border-box;
	}
}

/* Acima de 1920 o canvas volta a ser a faixa de 1920px, agora aumentada pelo
   mesmo `zoom` (até 1,5, ou seja 2880px de ecrã). Sem isto o cabeçalho, o
   conteúdo e o rodapé esticavam a toda a largura e as coordenadas absolutas
   do desenho ficavam presas à esquerda. Acima dos 2880px a faixa centra-se.
   A 1920 exactos não muda nada (a faixa já tem 1920px). */
@media (min-width: 1920.02px) {
	.site-header,
	.site-content,
	.site-footer {
		position: relative;
		width: 1920px;
		max-width: none;
		margin-inline: 0;
		padding-inline: 0;
		box-sizing: border-box;
	}
}

@media (min-width: 2880.02px) {
	.site-header,
	.site-content,
	.site-footer {
		margin-inline: auto;
	}
}

/* Abaixo do ponto de encaixe o canvas escalado ainda não cabe: aí é
   preferível deixar chegar ao conteúdo a escondê-lo. */
@media (min-width: 430.02px) and (max-width: 1199.98px) {
	html {
		overflow-x: auto;
	}
}

/* ------------------------------------------------------------
 * HEADER FIXO NO SCROLL — sticky ao topo (pedido do cliente);
 * z-index acima do conteúdo, abaixo do drawer (1200/1300) e do
 * loader (9999). O popup do mini-cart (1400) vive DENTRO deste
 * contexto e acompanha o header ao rolar. A sombra só aparece
 * fora do topo (classe posta pelo main.js) para manter o topo
 * da página pixel-igual à maqueta.
 * ------------------------------------------------------------ */

.site-header {
	position: sticky;
	top: 0;
	z-index: 1000;
}

body.sda-header-colada .site-header {
	box-shadow: 0 6px 24px rgba(72, 56, 70, 0.12);
}

/* ------------------------------------------------------------
 * LOADER — overlay creme com logo; na home, reveal em arco
 * (mask-composite: subtract — técnica da v1.x portada).
 * ------------------------------------------------------------ */

.sda-loader {
	position: fixed;
	inset: 0;
	z-index: 9999;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: var(--cor-creme, #FFF5DE);
	transition: opacity 400ms ease-out, visibility 0s linear 400ms;
}

.sda-loader__mark {
	display: block;
	width: clamp(200px, 24vw, 320px);
	/* Wordmark horizontal (264×40): sem height:auto o atributo height=40
	   do <img> fixava a altura e espalmava o logo ao escalar a largura. */
	height: auto;
	animation: sda-loader-pulse 1.6s ease-in-out infinite;
}

@keyframes sda-loader-pulse {
	0%, 100% { opacity: 0.55; transform: scale(1); }
	50%      { opacity: 1;    transform: scale(1.04); }
}

body.home .sda-loader {
	align-items: flex-start;
	padding-top: clamp(4rem, 12vh, 10rem);
	-webkit-mask-image:
		linear-gradient(#fff, #fff),
		url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 260'><path d='M0 260 L0 100 A100 100 0 0 1 200 100 L200 260 Z' fill='white'/></svg>");
	mask-image:
		linear-gradient(#fff, #fff),
		url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 260'><path d='M0 260 L0 100 A100 100 0 0 1 200 100 L200 260 Z' fill='white'/></svg>");
	-webkit-mask-repeat: no-repeat, no-repeat;
	mask-repeat: no-repeat, no-repeat;
	-webkit-mask-position: 0 0, center 62%;
	mask-position: 0 0, center 62%;
	-webkit-mask-size: 100% 100%, 0 0;
	mask-size: 100% 100%, 0 0;
	-webkit-mask-composite: source-out;
	mask-composite: subtract;
	transition: none;
}

body.home .sda-loader__mark {
	animation: sda-home-mark-fade 1.4s ease-out forwards;
	animation-delay: 0.8s;
	animation-play-state: paused;
}

body.home.is-loaded .sda-loader {
	animation:
		sda-loader-arch-grow 2.6s cubic-bezier(0.65, 0, 0.35, 1) forwards,
		sda-loader-fadeout 500ms ease-out 2.6s forwards;
	pointer-events: none;
}

body.home.is-loaded .sda-loader__mark {
	animation-play-state: running;
}

@keyframes sda-loader-arch-grow {
	from {
		-webkit-mask-size: 100% 100%, 0 0;
		mask-size: 100% 100%, 0 0;
		-webkit-mask-position: 0 0, center 62%;
		mask-position: 0 0, center 62%;
	}
	to {
		-webkit-mask-size: 100% 100%, 340vmax 340vmax;
		mask-size: 100% 100%, 340vmax 340vmax;
		-webkit-mask-position: 0 0, center center;
		mask-position: 0 0, center center;
	}
}

@keyframes sda-loader-fadeout {
	from { opacity: 1; }
	to   { opacity: 0; visibility: hidden; }
}

@keyframes sda-home-mark-fade {
	from { opacity: 1; }
	to   { opacity: 0; }
}

body:not(.home).is-loaded .sda-loader {
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
}

/* ------------------------------------------------------------
 * LISTAS SIMPLES (pesquisa e 404) — reaproveitam as classes das páginas
 * legais, que no mock têm alturas fixas calibradas para conteúdo
 * conhecido (secção 1597px, bloco 330px). Com resultados de comprimento
 * variável ficavam buracos enormes e o último resultado tapado.
 * ------------------------------------------------------------ */

.sda-lista-simples {
	height: auto;
	padding-bottom: 120px;
}

.sda-lista-simples .seccao-conteudo-legal__coluna {
	position: relative;
	left: auto;
	top: auto;
	margin: 0 auto;
	padding-top: 48px;
}

.sda-lista-simples .bloco-legal {
	position: relative;
	left: auto;
	top: auto;
	height: auto;
	margin: 0 0 40px;
}

.sda-lista-simples .bloco-legal__subtitulo,
.sda-lista-simples .bloco-legal__texto {
	position: static;
	width: auto;
	margin: 0;
}

.sda-lista-simples .bloco-legal__subtitulo {
	margin-bottom: 12px;
}

/* Títulos dos resultados: o mock nunca previu link aqui. */
.sda-lista-simples .bloco-legal__subtitulo a {
	color: inherit;
	text-decoration: none;
}

.sda-lista-simples .bloco-legal__subtitulo a:hover {
	color: var(--cor-primaria, #A787A3);
}

.sda-lista-simples__contagem {
	margin: 0 0 32px;
	font: 400 18px/28px var(--fonte-corpo, sans-serif);
	color: var(--cor-titulos-tom, #8E9193);
}

/* O form de pesquisa do estado vazio é absoluto (desenhado para outra
   secção) — aqui entra em fluxo, por baixo da mensagem. */
.sda-lista-simples__pesquisa {
	position: relative;
	min-height: 90px;
	margin-top: 24px;
}

.sda-lista-simples__pesquisa .seccao-formulario__form--pesquisa,
.sda-lista-simples__pesquisa .seccao-formulario__campo {
	position: relative;
	left: auto;
	top: auto;
	width: 100%;
	max-width: 600px;
}

/* Paginação da pesquisa e do index.php (2.56.1). Passou do
   `the_posts_pagination()`, que saía sem estilo (letra do navegador,
   ligações azuis sublinhadas), ao componente do blog
   (template-parts/paginacao-artigos.php), e os números, o círculo da página
   actual, as reticências e as setas vêm das regras do blog. Aqui fica só o
   lugar: em fluxo por baixo do último resultado (os 24px juntam-se aos 40 do
   bloco e ficam 40, perto dos 42 do desenho do blog entre o último cartão e
   o círculo), e com a largura da coluna dos resultados (968) em vez dos 912
   da coluna dos cartões do blog (main.css), para a fila ficar centrada
   nela. */
.sda-lista-simples .seccao-artigos-paginacao {
	position: relative;
	left: auto;
	top: auto;
	width: auto;
	margin-top: 24px;
}

/* Selos: a propriedade `rotate` compõe ANTES de `transform`, por isso
   nos selos que se posicionam com translate a rotação passava a órbita.
   Passar o posicionamento para a propriedade `translate` (que compõe
   ANTES da rotação) devolve a rotação ao próprio eixo. */
.terapia-sobre-leonardo__selo,
.qs-sobre-leonardo__selo,
.home-sobre-leonardo__selo {
	transform: none;
	translate: -50% -50%;
}

/* ------------------------------------------------------------
 * ÁREA DE CLIENTE — endpoints sem desenho no mock (editar conta e
 * moradas). O WooCommerce injecta o seu markup no fluxo normal,
 * enquanto o menu lateral é absoluto: os dois ocupavam a mesma área e
 * o texto ficava ilegível. Aqui o conteúdo do endpoint ganha a coluna
 * da direita e tipografia do tema.
 * ------------------------------------------------------------ */

/* O wrapper tem de ficar NEUTRO (estático, sem margens) nas páginas que o
   mock desenha — painel, encomendas, ver encomenda —, senão passa a ser o
   ancestral posicionado dos cartões absolutos e estes saem da grelha.
   Só os endpoints crus do WC (editar conta, moradas) ganham coluna. */
.conta-conteudo .woocommerce-MyAccount-content {
	position: static;
	margin: 0;
	max-width: none;
}

.conta-conteudo .woocommerce-MyAccount-content:has(form.woocommerce-EditAccountForm),
.conta-conteudo .woocommerce-MyAccount-content:has(form.edit-account),
.conta-conteudo .woocommerce-MyAccount-content:has(.woocommerce-Address),
.conta-conteudo .woocommerce-MyAccount-content:has(.woocommerce-address-fields) {
	margin-left: 433px;
	padding-bottom: 64px;
	max-width: 968px;
	font: 400 18px/28px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

/* A secção tem altura fixa do mock; com estes endpoints cresce. */
.conta-conteudo:has(.woocommerce-MyAccount-content .woocommerce-EditAccountForm),
.conta-conteudo:has(.woocommerce-MyAccount-content form.edit-account),
.conta-conteudo:has(.woocommerce-MyAccount-content .woocommerce-Address) {
	height: auto;
	min-height: 620px;
	padding-bottom: 80px;
}

.conta-conteudo .woocommerce-MyAccount-content h2,
.conta-conteudo .woocommerce-MyAccount-content h3,
.conta-conteudo .woocommerce-MyAccount-content legend {
	margin: 0 0 20px;
	font: 500 26px/34px var(--fonte-corpo, sans-serif);
	text-transform: uppercase;
	color: var(--cor-primaria, #A787A3);
}

.conta-conteudo .woocommerce-MyAccount-content p {
	margin: 0 0 18px;
}

.conta-conteudo .woocommerce-MyAccount-content label {
	display: block;
	margin-bottom: 6px;
	font: 500 15px/22px var(--fonte-corpo, sans-serif);
	text-transform: uppercase;
	color: var(--cor-titulos-tom, #8E9193);
}

.conta-conteudo .woocommerce-MyAccount-content input[type="text"],
.conta-conteudo .woocommerce-MyAccount-content input[type="email"],
.conta-conteudo .woocommerce-MyAccount-content input[type="tel"],
.conta-conteudo .woocommerce-MyAccount-content input[type="password"],
.conta-conteudo .woocommerce-MyAccount-content select,
.conta-conteudo .woocommerce-MyAccount-content textarea {
	width: 100%;
	max-width: 460px;
	height: 44px;
	padding: 0 0 8px;
	box-sizing: border-box;
	background: none;
	border: 0;
	border-bottom: 1px solid var(--cor-cinza-medio, #A4A7A9);
	font: 400 18px/26px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

/* REVISÃO v5, R39 — «as restantes secções e páginas também têm os botões
   desformados». A área de cliente tinha desenho próprio: 210x56 com 28px
   de padding, contra os 251x61 de todos os outros botões do site. E a
   regra vence a genérica por especificidade, (0,5,1) contra (0,3,1), por
   isso nem as medidas nem o centrado lhe chegavam — medido em
   `/minha-conta/edit-address/billing/`: 212x56 a 1920 e, em mobile, 251x50
   encostado a x=23 em vez de centrado em 69,5.
   Existe porque o conteúdo da conta é markup do WooCommerce, sem as
   classes do tema. Passa a repetir as medidas do site em vez de inventar
   as suas. */
.conta-conteudo .woocommerce-MyAccount-content button:not(.produto-card *):not(.conta-desejos *),
.conta-conteudo .woocommerce-MyAccount-content input[type="submit"] {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: 251px;
	max-width: 100%;
	height: 61px;
	margin-top: 12px;
	padding: 0;
	background: var(--cor-primaria, #A787A3);
	border: 0;
	border-radius: 12px;
	font: 500 16px/18px var(--fonte-corpo, sans-serif);
	text-transform: uppercase;
	color: #ffffff;
	cursor: pointer;
}

.conta-conteudo .woocommerce-MyAccount-content a:not(.botao-principal):not(.botao-contorno):not(.produto-card *) {
	color: var(--cor-primaria, #A787A3);
}

/* Lista de encomendas: o mock posiciona apenas 3 cartões (top -3/396/795)
   e a partir da 4.ª ficavam todas empilhadas em cima da última. O passo
   é 399px — calculado a partir do índice que o template já imprime. */
.conta-encomenda {
	top: calc(-3px + (var(--sda-enc-i, 0) * 399px));
}

/* A altura da secção das encomendas é impressa pelo próprio template
   (woocommerce/myaccount/orders.php), a partir do nº real de cartões. */

/* Badge "Cancelada": branco sobre #FFA2A3 dá 1,92:1, muito abaixo do
   mínimo AA. O CLAUDE.md já prevê texto em text-dark sobre os pastéis. */
.conta-badge--cancelada {
	color: var(--cor-footer, #483846);
}

/* ------------------------------------------------------------
 * CARDS DE PRODUTO — o mock desenhou um preço único; com preços reais
 * do WooCommerce aparecem <del>+<ins> (promoções) e o link "Carrinho"
 * que o WC injecta depois de adicionar.
 * ------------------------------------------------------------ */

/* Aviso curto junto ao card/ficha (stock insuficiente, erro do add). */
.sda-aviso-produto {
	position: absolute;
	left: 22px;
	right: 22px;
	bottom: -34px;
	z-index: 3;
	margin: 0;
	font: 500 15px/22px var(--fonte-corpo, sans-serif);
	color: var(--cor-primaria, #A787A3);
}

/* Avisos do WooCommerce dentro da grelha. */
.sda-notices {
	position: relative;
	padding-top: 24px;
}

/* Link "Ver carrinho" injectado pelo WC — não faz parte do design. */
.produto-card .added_to_cart {
	display: none;
}

/* Promoção: o par riscado+actual não cabe nos 121px que o mock reserva
   antes da pill do stepper. Com o seletor aberto mostra-se só o preço
   actual (o riscado tapava o botão "−"). */
.produto-card--no-carrinho .produto-card__preco del {
	display: none;
}

.produto-card__preco del {
	margin-right: 6px;
	opacity: 0.6;
}

/* O <ins> do WooCommerce vem sublinhado pelo browser. */
.produto-card__preco ins,
.produto-ficha__preco ins,
.header-carrinho-painel ins {
	text-decoration: none;
	background: none;
	color: inherit;
}

/* ------------------------------------------------------------
 * MINI-CARRINHO — o painel do design (.header-carrinho-painel) está
 * calibrado para UMA linha. Com carrinho real cada linha extra desce
 * 108px (--sda-mc-i, posto no template) e o painel, o total e os
 * botões crescem na mesma medida (--sda-mc-extra).
 * ------------------------------------------------------------ */

/* ------------------------------------------------------------
 * DROPDOWNS DO MENU — o design desenhou um só (Terapias, 4 itens).
 * O cliente quer apenas Astrologia e Tarot, e o mesmo tratamento em
 * Actividades (os dois cursos): a caixa encolhe para 2 itens (o mock
 * reservava 25px depois do último) e Actividades ganha o mesmo hover.
 * ------------------------------------------------------------ */

.header-submenu {
	height: 117px;
}

.header-menu__actividades:hover .header-submenu {
	display: block;
}

/* Teclado: o dropdown também abre com foco dentro do item. */
.header-menu__terapias:focus-within .header-submenu,
.header-menu__actividades:focus-within .header-submenu {
	display: block;
}

/* Teclado: o painel também abre com foco dentro do wrap. */
.header-carrinho-wrap:focus-within .header-carrinho-painel {
	display: block;
}

/* Fechado por Escape: o foco volta ao ícone e o :focus-within reabria o
   painel. A classe (posta pelo main.js) trava até haver nova intenção. */
.header-carrinho-wrap.fechado:focus-within .header-carrinho-painel {
	display: none;
}

/* Cada linha é um wrapper posicionado: os filhos mantêm as coordenadas
   exactas do design e o wrapper é que desce. */
.header-carrinho-painel__item {
	position: absolute;
	left: 0;
	right: 0;
	top: 0;
	height: 124px;
	transform: translateY(calc(var(--sda-mc-i, 0) * 108px));
}

/* --sda-mc-extra é posto no PAINEL pelo main.js (conta as linhas depois
   de cada fragment) — as custom properties herdam para baixo, por isso
   total e botões acompanham. */
.header-carrinho-painel {
	height: calc(252px + var(--sda-mc-extra, 0px));
}

.header-carrinho-painel__total,
.header-carrinho-painel__total-valor {
	top: calc(139px + var(--sda-mc-extra, 0px));
}

.header-carrinho-painel__botao {
	top: calc(176px + var(--sda-mc-extra, 0px));
}

.header-carrinho-painel__nome a {
	color: inherit;
	text-decoration: none;
}

.header-carrinho-painel__nome {
	display: -webkit-box;
	-webkit-line-clamp: 3;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Estado vazio: o painel encolhe (classe posta pelo main.js) mantendo a
   largura do design — o padding não pode somar à width fixa. */
.header-carrinho-painel.vazio {
	height: auto;
	padding: 28px 32px;
	box-sizing: border-box;
}

.woocommerce-mini-cart__empty-message {
	margin: 0;
	font: 500 16px/22px var(--fonte-corpo, sans-serif);
	color: var(--cor-footer, #483846);
}

/* ------------------------------------------------------------
 * MENU MÓVEL — painel de ecrã inteiro (revisão v5, R122: «a
 * estrutura do menu não corresponde ao que está no XD»).
 *
 * Era um drawer de 368 encostado à direita, com 11 itens
 * alinhados à esquerda e sem logótipo. Passa a painel opaco a
 * cobrir o viewport, com a barra do cabeçalho repetida no topo,
 * cinco itens centrados, filete, linha de conta e pastilha Loja.
 * ------------------------------------------------------------ */

.sda-drawer {
	position: fixed;
	inset: 0;
	z-index: 1300;
	display: flex;
	flex-direction: column;
	background-color: #ffffff;
	/* Sem `transform`: com o painel deslocado, focar um alvo lá
	   dentro dava ao browser motivo para arrastar a página até ele.
	   Fecho por opacidade, que não desloca nada. */
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.25s ease, visibility 0s linear 0.25s;
}

body.sda-drawer-aberto .sda-drawer {
	opacity: 1;
	visibility: visible;
	transition: opacity 0.25s ease, visibility 0s linear 0s;
}

/* O painel usa as coordenadas absolutas da tela de 390. Acima de
   430 a tela passa a 1920 e ficaria um menu de 390 encolhido no
   canto. O JS fecha-o no `resize`, mas isto garante que nem por um
   frame — ou com o JS em baixo — ele chega a aparecer. */
@media (min-width: 431px) {
	.sda-drawer {
		display: none;
	}
}

/* --- topo: a barra do cabeçalho, repetida --- */

.sda-drawer__topo {
	position: relative;
	flex-shrink: 0;
	/* A mesma altura da barra em mobile: medi `offsetHeight` 64 nas
	   três larguras. */
	height: 64px;
}

/* As coordenadas são as do `.header-logo` a ≤430: medi 16,5/20,5 e
   150×23 de canvas a 360, 390 e 430. */
.sda-drawer__logo {
	position: absolute;
	left: 16.5px;
	top: 20.5px;
	display: block;
	line-height: 0;
}

.sda-drawer__logo img {
	display: block;
	width: 150px;
	height: 23px;
}

/* O X ocupa o lugar do hamburger: mesmo centro (medi x=350 w=22 →
   361; y=25 h=14 → 32), mesma largura de risco (22) e mesma
   espessura (2). A caixa é de 48 de canvas porque 48 × 0,923 = 44,3
   reais a 360 — os 44 medidos onde contam, em píxeis reais. */
.sda-drawer__fechar {
	box-sizing: border-box;
	position: absolute;
	left: 337px;
	top: 8px;
	width: 48px;
	height: 48px;
	margin: 0;
	padding: 0;
	border: 0;
	background: none;
	cursor: pointer;
}

.sda-drawer__fechar span {
	position: absolute;
	left: 13px;
	top: 23px;
	width: 22px;
	height: 2px;
	border-radius: 1px;
	background-color: var(--cor-primaria, #A787A3);
}

.sda-drawer__fechar span:nth-child(1) {
	transform: rotate(45deg);
}

.sda-drawer__fechar span:nth-child(2) {
	transform: rotate(-45deg);
}

/* --- corpo: o que rola quando o ecrã é baixo --- */

/* 23px de cada lado dão a coluna útil de 344 do mock. O corpo é o
   único que rola, para o logótipo e o X ficarem sempre à vista. */
.sda-drawer__corpo {
	box-sizing: border-box;
	flex-grow: 1;
	display: flex;
	flex-direction: column;
	align-items: center;
	padding: 24px 23px 32px;
	overflow-y: auto;
	overscroll-behavior: contain;
}

.sda-drawer__lista {
	width: 100%;
	flex-shrink: 0;
	display: flex;
	flex-direction: column;
	row-gap: 12px;
	list-style: none;
	margin: 0;
	padding: 0;
}

/* `box-sizing: border-box` é obrigatório: o tema não tem reset e o
   default é `content-box` (medi-o no body), onde o `min-height` se
   aplica só à caixa de conteúdo — estes 64 dariam 80 com o padding
   por cima. O alvo é a linha inteira, 344 × 64 de canvas. */
.sda-drawer__lista a {
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 64px;
	padding: 8px;
	font: 500 20px/28px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
	text-align: center;
	text-decoration: none;
	text-transform: none;
}

/* #696969 sobre branco dá 5,49:1. A primária dá 3,16:1 e não serve
   como cor de texto — nem no hover: uso o tom do rodapé, #483846,
   que dá 10,88:1. */
.sda-drawer__lista a:hover,
.sda-drawer__lista a:focus-visible,
.sda-drawer__conta:hover,
.sda-drawer__conta:focus-visible {
	color: var(--cor-footer, #483846);
}

/* A página actual não pode ficar igual ao hover, ou «estou aqui» e
   «tenho o dedo em cima» passam a ser o mesmo pixel. Leva sublinhado
   além da cor. */
.sda-drawer__lista a.ativo {
	color: var(--cor-footer, #483846);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 6px;
}

/* O foco visível do tema não chega aqui: a regra global só cobre
   .site-header, .site-content e .site-footer. */
.sda-drawer a:focus-visible,
.sda-drawer button:focus-visible {
	outline: 2px solid var(--cor-primaria, #A787A3);
	outline-offset: 2px;
}

.sda-drawer__filete {
	width: 100%;
	height: 1px;
	flex-shrink: 0;
	border: 0;
	background-color: var(--cor-cinza-claro, #D6D7D9);
	margin: 24px 0 0;
}

.sda-drawer__conta {
	box-sizing: border-box;
	display: flex;
	align-items: center;
	justify-content: center;
	column-gap: 12px;
	width: 100%;
	min-height: 64px;
	flex-shrink: 0;
	margin-top: 12px;
	padding: 8px;
	font: 500 20px/28px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
	text-align: center;
	text-decoration: none;
}

.sda-drawer__conta img {
	display: block;
	width: 22px;
	height: 22px;
	flex-shrink: 0;
}

/* A mesma pastilha do resto do site (251 × 50, raio 12, 18/600
   uppercase, fundo `--cor-primaria`). Mantenho a cor da marca de
   propósito: um lilás só para aqui daria dois botões LOJA de cores
   diferentes a um toque de distância. O contraste do par
   branco/#A787A3 é 3,16:1 e é um problema de todas as pastilhas do
   site, não deste menu — ver a nota para o Francisco. */
.sda-drawer__loja {
	box-sizing: border-box;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 251px;
	height: 50px;
	flex-shrink: 0;
	margin-top: 24px;
	border-radius: 12px;
	background-color: var(--cor-primaria, #A787A3);
	color: #ffffff;
	font: 600 18px/36px var(--fonte-corpo, sans-serif);
	letter-spacing: 0;
	text-transform: uppercase;
	text-decoration: none;
}

.sda-drawer__loja:hover,
.sda-drawer__loja:focus-visible {
	background-color: var(--cor-rosa, #ECC6C0);
	color: var(--cor-footer, #483846);
}

/* ------------------------------------------------------------
 * TRINCO DE SCROLL — partilhado pelo menu móvel, pelo modal de
 * login e pela folha de resumo do curso.
 *
 * Só a RAIZ. O `overflow: hidden` que estava também no `body`
 * fazia do body um contentor de scroll, e o `position: sticky` do
 * cabeçalho passava a colar-se a ESSE contentor, que nunca rola:
 * medi o `.site-header` a cair de y=0 para y=-1200 nas três
 * larguras móveis e em 1280/1920. Só na raiz, o cabeçalho fica em
 * y=0 e o `scrollY` mantém-se em 1200 durante o trinco — nada de
 * `position: fixed` no body, que colapsaria o documento de 5999
 * para 844 e refaseava a textura da página inteira.
 * ------------------------------------------------------------ */

html.sda-scroll-lock {
	overflow: hidden;
}

/* ------------------------------------------------------------
 * SLIDERS (hero da home + banner da loja) — crossfade entre
 * imagens irmãs; com 1 só imagem o mecanismo fica inerte.
 * ------------------------------------------------------------ */

.home-hero__foto[data-sda-slide][aria-hidden="true"],
.loja-banner__imagem[data-sda-slide][aria-hidden="true"] {
	opacity: 0;
	pointer-events: none;
}

.home-hero__foto[data-sda-slide],
.loja-banner__imagem[data-sda-slide] {
	transition: opacity 0.4s ease;
}

/* Sliders de painéis (terapias na home, testemunhos): cada slide é um
   wrapper sem posição própria (os filhos continuam ancorados à secção
   do mock) — o crossfade é do wrapper inteiro. */
.home-terapias__slide,
.seccao-testemunhos__slide,
.home-hero__slide {
	transition: opacity 0.5s ease;
}

.home-terapias__slide[aria-hidden="true"],
.seccao-testemunhos__slide[aria-hidden="true"],
.home-hero__slide[aria-hidden="true"] {
	opacity: 0;
	pointer-events: none;
}

/* Wishlist na ficha de produto: o fundo branco base da ficha
   (.produto-ficha__favorito, regra posterior no main.css) anulava o
   estado activo do coração — sem feedback visual ao clicar. */
.produto-ficha__favorito.produto-card__desejos--ativo {
	background: var(--cor-primaria, #A787A3);
}

/* Tabs de curso sem painel no Figma (3º ano astro, 1º ano tarot):
   ficam visíveis mas assinaladas como indisponíveis até haver conteúdo. */
.curso-estrutura-tab[aria-disabled="true"] {
	opacity: 0.45;
	cursor: not-allowed;
}

/* Opt-in da newsletter: visto ao marcar (o botão-checkbox do design
   não tinha estado visual nem handler — o main.js alterna aria-checked). */
.seccao-newsletter__optin-caixa[aria-checked="true"] {
	background: #ffffff url("../img/loja/conta-checkbox-visto.svg") center / 14px 14px no-repeat;
}

/* Modal de login — o card do design (o Figma desenha-o sobre a loja:
   é um popup). O card reutiliza as classes do mock (.login-card,
   absolute left:50% top:241) dentro de um overlay fixed. */
.sda-login-modal {
	position: fixed;
	inset: 0;
	z-index: 1500;
	overflow-y: auto;
}

.sda-login-modal__overlay {
	position: absolute;
	inset: 0;
	background: rgba(72, 56, 70, 0.5);
}

/* Erros do checkout em flow (slot preenchido pelo main.js no
   checkout_error) + backstop: nada de notices dentro do form absoluto. */
.checkout-erro {
	width: 1400px;
	margin: 32px auto 0;
	padding: 0;
	list-style: none;
	font: 400 22px/36px var(--fonte-corpo, sans-serif);
	color: var(--cor-titulos-tom, #8E9193);
}

.checkout-erro li {
	margin: 0;
}

form.checkout .woocommerce-NoticeGroup,
form.checkout > .woocommerce-error,
form.checkout > .woocommerce-message,
form.checkout > .woocommerce-info {
	display: none;
}


/* Dots do banner da loja passaram de span decorativo a botão real. */
.loja-banner__dot {
	padding: 0;
	border: none;
	cursor: pointer;
}

/* Ordenar por (loja): select invisível estendido sobre o visual do mock. */
.loja-produtos__ordenar-select {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	opacity: 0;
	cursor: pointer;
}

/* ------------------------------------------------------------
 * SELOS ROTATIVOS — rotação contínua 60s (comportamento v1.x).
 * ------------------------------------------------------------ */

/* A rotação usa a propriedade `rotate` (não `transform`) para NÃO
   esmagar os translates de posicionamento do main.css. */
.terapia-hero__simbolo-flor,
.curso-hero__simbolo-flor,
.proximas-actividades__simbolo,
.home-sobre-leonardo__selo,
.qs-sobre-leonardo__selo,
.terapia-sobre-leonardo__selo,
.curso-sobre-leonardo__selo {
	/* 60s era uma volta em cada minuto — o cliente descreveu-o como
	   «muitoooooo devagar» e tinha razão: a 6°/s a rotação lê-se como uma
	   imagem quase parada. 22s dá-lhe presença sem chamar a atenção. */
	animation: sda-selo-rotate 22s linear infinite;
}

@keyframes sda-selo-rotate {
	from { rotate: 0deg; }
	to   { rotate: 360deg; }
}

/* ------------------------------------------------------------
 * TICKER DA LOJA (home) — marquee em loop: duas listas idênticas
 * num track flex, translateX(-50%) infinito (seamless por
 * construção, independente das fontes). Itens são links reais
 * às categorias de produto.
 * ------------------------------------------------------------ */

.home-loja__ticker {
	overflow: clip;
}

.sda-ticker-track {
	display: flex;
	width: max-content;
	animation: sda-ticker-loop 26s linear infinite;
	will-change: transform;
}

.sda-ticker-track:hover {
	animation-play-state: paused;
}

.sda-ticker-lista {
	display: flex;
	align-items: center;
	gap: 60px;
	padding-right: 60px;
	flex-shrink: 0;
}

.sda-ticker-lista .home-loja__ticker-item,
.sda-ticker-lista .home-loja__ticker-brilho {
	position: static;
	flex-shrink: 0;
}

.home-loja__ticker-item {
	text-decoration: none;
}

@keyframes sda-ticker-loop {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

/* ------------------------------------------------------------
 * CARROSSÉIS MOBILE (home: loja, actividades, blog) — scroll-snap
 * horizontal com dots sincronizados por IntersectionObserver.
 * ------------------------------------------------------------ */

@media (max-width: 767px) {
	.sda-carrossel-mobile {
		display: flex !important;
		overflow-x: auto;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
		gap: 16px;
	}

	.sda-carrossel-mobile::-webkit-scrollbar {
		display: none;
	}

	.sda-carrossel-mobile > * {
		scroll-snap-align: center;
		flex: 0 0 88%;
	}
}

/* ------------------------------------------------------------
 * CONTEÚDO DINÂMICO — o mockup posiciona vários blocos em absoluto
 * calibrado para conteúdo fixo; estas regras põem esses blocos em
 * flow para aguentarem conteúdo real de comprimento variável.
 * ------------------------------------------------------------ */

/* Home: título dos cards de curso — o mock centrava os glifos com
   line-height 96px em top:201, o que os pousava sobre o fim da imagem
   (250px). Desce o título para a área branca. */
.home-actividades-card__titulo {
	top: 268px;
	line-height: 36px;
}

/* Home: interior dos cards de blog em flow — títulos reais de 1–2 linhas
   empurram meta e excerto (o mock fixava top por card e sobrepunha). */
.home-blog-card {
	padding-top: 279px;
	box-sizing: border-box;
}

.home-blog-card__titulo,
.home-blog-card__meta,
.home-blog-card__excerto {
	position: static;
	width: auto;
}

/* Selector composto de propósito: o main.css tem um reset agrupado
   `.home-blog p, .home-blog h3 { margin: 0 }` com especificidade (0,1,1)
   que ganharia à classe simples independentemente da ordem. */
.home-blog-card .home-blog-card__titulo {
	margin: 26px 30px 0;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.home-blog-card .home-blog-card__meta {
	margin: 12px 31px 0;
}

.home-blog-card .home-blog-card__excerto {
	margin: 25px 31px 0;
	display: -webkit-box;
	-webkit-line-clamp: 5;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

@media (max-width: 430px) {
	.pagina-home-final .home-blog-card {
		padding-top: 214px;
	}

	.pagina-home-final .home-blog-card__titulo,
	.pagina-home-final .home-blog-card__meta,
	.pagina-home-final .home-blog-card__excerto {
		width: auto;
		margin-left: 20.8px;
		margin-right: 20.8px;
	}
}

/* Contactos: secção dividida a meio (pedido do Francisco) — o texto fica
   na metade esquerda (largura 602 do mock, termina antes dos 700) e a
   coluna de contactos começa no meio do inner de 1400. Os dois ícones
   mantêm os centros alinhados (email 44px em 700; morada 32px em 706 →
   centro comum a 722) e o texto guarda os 30px de folga do mock. */
.seccao-onde-estamos__icone--email {
	left: 700px;
}

.seccao-onde-estamos__icone--morada {
	left: 706px;
}

.seccao-onde-estamos__contacto {
	left: 774px;
}

/* Mensagens de estado dos formulários: entravam em fluxo dentro de um
   container cujos irmãos são absolutos, e eram desenhadas POR CIMA dos
   campos (inscrição) e do título "Onde estamos" (contactos) — uma
   mensagem em fluxo não consegue empurrar um irmão absoluto. Passam a
   ocupar um lugar próprio, com o espaço reservado por :has(). */
.seccao-formulario__status {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	z-index: 3;
	margin: 0;
}

/* Inscrição: a mensagem fica acima do formulário e a secção cresce. */
.seccao-formulario:has(.seccao-formulario__status) {
	height: 583px;
}

.seccao-formulario:has(.seccao-formulario__status) .seccao-formulario__form {
	top: 72px;
}

/* Contactos: o formulário está noutra secção; a mensagem entra por baixo
   do bloco de contactos, onde há espaço livre no design. */
.seccao-onde-estamos .seccao-formulario__status {
	top: 330px;
}

/* Respiro antes da newsletter (pedido do Francisco — o mock calibrou
   estas três junções sem folga; ritmo das restantes páginas é ~130-180px):
   inscrição (secção do form com altura fixa 511 acaba no botão ENVIAR),
   contactos (40px) e blog (a base de .seccao-produtos-relacionados não
   tem o margin-bottom:150 que o artigo recebe via .pagina-artigo). */
.seccao-formulario {
	margin-bottom: 130px;
}

.seccao-onde-estamos {
	margin-bottom: 90px;
}

body.blog .seccao-produtos-relacionados {
	margin-bottom: 140px;
}

/* Blog: paginação em flow (evita números sobrepostos com N páginas). */
.seccao-artigos-paginacao {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 24px;
}

.seccao-artigos-paginacao-numero,
.seccao-artigos-paginacao-seguinte {
	position: static;
}

/* Loja: lista de categorias em flow (nomes longos quebram linha). */
.loja-filtro__lista {
	display: flex;
	flex-direction: column;
	gap: 16px;
	margin-top: 64px;
}

.loja-filtro__lista li {
	position: static;
}

/* Subfamílias por baixo de cada família (inc/categorias-codigo.php), um
   degrau para dentro e em letra mais pequena. A cor de «activo» do
   main.css (`li.ativo a`) apanhava também as subfamílias da família
   escolhida: aqui só o link da própria linha. */
.loja-filtro__sub {
	display: flex;
	flex-direction: column;
	gap: 6px;
	margin: 8px 0 0;
	padding: 0 0 0 16px;
	list-style: none;
}

.loja-filtro__lista .loja-filtro__sub li {
	font: 400 17px/22px var(--fonte-corpo);
}

.loja-filtro__lista li.ativo .loja-filtro__sub a {
	color: var(--cor-titulos-tom);
}

.loja-filtro__lista .loja-filtro__sub li.ativo a {
	color: var(--cor-primaria);
}

/* No telemóvel o filtro vem antes dos produtos, e as 8 famílias com as 29
   subfamílias faziam uma coluna de quase 1500px por cima deles. Ali só se
   vêem as famílias e, por baixo da que está escolhida (ou da que tem a
   subfamília escolhida), as suas subfamílias. */
@media (max-width: 430px) {
	.loja-filtro__familia:not(.ativo):not(.loja-filtro__familia--aberta) .loja-filtro__sub {
		display: none;
	}
}

/* Produto: descrição em flow (textos reais são mais longos que o mock)
   e título limitado a 2 linhas (o preço está absoluto a top fixo). */
.produto-descricao {
	height: auto;
	min-height: 544px;
	padding-bottom: 40px;
	box-sizing: border-box;
}

/* As tabs absolutas ancoram ao .seccao-inner (relative) — o padding
   empurra só o corpo estático e trava o margin-collapse. */
.produto-descricao .seccao-inner {
	padding-top: 131px;
}

.produto-descricao__corpo {
	position: static;
	margin: 0 0 40px 35px;
	width: auto;
	max-width: 1326px;
}

.produto-ficha__titulo {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

.produto-ficha__referencia a {
	color: inherit;
	text-decoration: none;
}

/* Artigo: comentários reais em flow (o mock posiciona exactamente 2). */
.artigo-comentarios {
	height: auto;
	padding-bottom: 48px;
}

.artigo-comentarios__titulo {
	position: static;
	margin: 0 0 32px;
}

/* Conteúdo real do editor: links e tabelas com estilos do tema
   (o mock não os define — caíam no default azul do browser). */
.artigo-conteudo__texto a {
	color: var(--cor-roxo, #A787A3);
}

.artigo-conteudo__texto table {
	border-collapse: collapse;
	margin: 16px 0;
}

.artigo-conteudo__texto th,
.artigo-conteudo__texto td {
	position: static;
	padding: 6px 32px 6px 0;
	text-align: left;
	line-height: 1.6;
}

.seccao-sidebar__banner-texto a {
	color: var(--cor-roxo, #A787A3);
}

.artigo-comentarios .artigo-comentario {
	position: relative;
	left: auto;
	top: auto;
	width: auto;
	height: auto;
	min-height: 130px;
	padding: 24px 24px 24px 140px;
	margin-bottom: 28px;
}

.artigo-comentarios .artigo-comentario__card {
	position: absolute;
	inset: 0 0 0 120px;
	width: auto;
	height: auto;
}

.artigo-comentarios .artigo-comentario__avatar {
	position: absolute;
	left: 0;
	top: 0;
	width: 109px;
	height: 110px;
	object-fit: cover;
}

.artigo-comentarios .artigo-comentario__nome,
.artigo-comentarios .artigo-comentario__data,
.artigo-comentarios .artigo-comentario__texto,
.artigo-comentarios .artigo-comentario__responder {
	position: relative;
	left: auto;
	top: auto;
	width: auto;
	z-index: 1;
	margin: 0 0 8px;
}

.artigo-comentarios .children {
	margin-left: 141px;
}

/* O WP não imprime o wrapper .children com o callback custom —
   a indentação das respostas vem do modificador do próprio card. */
.artigo-comentarios .artigo-comentario--resposta {
	margin-left: 141px;
}

/* Parágrafos do comentário sem as margens default do browser. */
.artigo-comentarios .artigo-comentario__texto p {
	margin: 0 0 8px;
}

/* Link "Responder": o WP imprime class="comment-reply-link" (o arg
   'class' de comment_reply_link não substitui a classe) — sem isto
   o link caía no azul sublinhado default do browser. */
.artigo-comentarios .comment-reply-link {
	position: relative;
	z-index: 1;
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-top: 4px;
	font: 600 15px/24px var(--fonte-corpo, sans-serif);
	letter-spacing: 0.04em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--cor-primaria, #A787A3);
}

/* Links que o WP injecta no formulário de comentários (cancelar resposta,
   editar perfil, sair, política) vinham no azul sublinhado do browser. */
.artigo-deixe-comentario a,
#respond a,
.sda-form__consent a {
	color: var(--cor-primaria, #A787A3);
	text-decoration: underline;
	text-underline-offset: 2px;
}

.artigo-deixe-comentario a:hover,
#respond a:hover,
.sda-form__consent a:hover {
	color: var(--cor-footer, #483846);
}

.artigo-comentarios .comment-reply-link:hover {
	color: var(--cor-footer, #483846);
}

.artigo-comentarios .comment-respond {
	position: relative;
	z-index: 1;
}

/* Responder a um comentário: o comment-reply.js do WP move o #respond
   para dentro da lista, e o interior do formulário — todo em absoluto
   calibrado contra o .seccao-inner da secção original — colapsava para
   o topo, tapando o cartão anterior e deixando o consent inalcançável.
   Neste contexto o formulário passa a fluxo normal. */
.artigo-comentarios #respond {
	position: relative;
	z-index: 2;
	margin: 8px 0 40px;
	padding: 24px 0 0;
}

.artigo-comentarios #respond .artigo-deixe-comentario__titulo,
.artigo-comentarios #respond .artigo-deixe-comentario__campo,
.artigo-comentarios #respond .sda-form__actions,
.artigo-comentarios #respond .artigo-deixe-comentario__rodape,
.artigo-comentarios #respond .sda-form__consent {
	position: static;
	left: auto;
	top: auto;
	width: auto;
}

.artigo-comentarios #respond .artigo-deixe-comentario__titulo {
	margin: 0 0 20px;
}

.artigo-comentarios #respond .artigo-deixe-comentario__campo {
	max-width: 640px;
	margin: 0 0 20px;
}

.artigo-comentarios #respond .artigo-deixe-comentario__campo textarea {
	height: 120px;
}

.artigo-comentarios #respond .sda-form__actions {
	display: flex;
	align-items: center;
	gap: 24px;
	flex-wrap: wrap;
	margin-top: 8px;
}

/* "Cancelar resposta" deixa de ficar por baixo do título. */
.artigo-comentarios #respond #cancel-comment-reply-link {
	display: inline-block;
	margin-left: 16px;
	font: 500 16px/24px var(--fonte-corpo, sans-serif);
	text-transform: none;
	color: var(--cor-primaria, #A787A3);
}

/* Comentário à espera de moderação. */
.artigo-comentario .comment-awaiting-moderation {
	position: relative;
	z-index: 1;
	display: block;
	margin: 4px 0 8px;
	font: italic 400 16px/24px var(--fonte-corpo, sans-serif);
	color: var(--cor-titulos-tom, #8E9193);
}

/* Formulário de comentário: honeypot invisível e consent no rodapé
   (as classes sda-form__* vêm do filter em inc/setup.php e perderam
   os estilos antigos na migração). */
.sda-form__honeypot {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.artigo-deixe-comentario .sda-form__actions {
	position: absolute;
	left: 0;
	top: 386px;
	display: flex;
	align-items: center;
	gap: 24px;
}

.artigo-deixe-comentario .sda-form__actions .artigo-deixe-comentario__rodape {
	position: static;
	display: flex;
	align-items: center;
	gap: 24px;
}

.sda-form__consent {
	display: inline-flex;
	align-items: center;
	gap: 12px;
	font: 400 18px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

/* ------------------------------------------------------------
 * CHECKOUT — campos com placeholder (design) em vez de label visível.
 * O mock media os campos VAZIOS do Figma: interpretou o texto cinzento
 * como label e deu ao input só a altura do risco (8-10px) — o texto
 * escrito não cabia. O label passa a screen-reader-only no template e
 * o input ocupa o bloco inteiro; o risco fica onde estava (~35px).
 * O selector duplicado empata a especificidade com os overrides
 * por campo do mock (.checkout-campo--nif input { height: 9px }, etc.)
 * e ganha por ordem de carregamento.
 * ------------------------------------------------------------ */

.checkout-campo.checkout-campo input {
	height: 35px;
	padding: 0 0 8px;
	box-sizing: border-box;
}

.checkout-notas.checkout-notas textarea {
	height: 84px;
	padding-top: 26px;
	box-sizing: border-box;
}

.checkout-campo input::placeholder,
.checkout-notas textarea::placeholder {
	font: 500 18px/26px var(--fonte-corpo, sans-serif);
	text-transform: uppercase;
	color: var(--cor-titulos-tom, #8E9193);
	opacity: 1;
}

/* Métodos de pagamento reais: o mock só posiciona multibanco/mbway/paypal;
   o "Pagamento na entrega" (cod) ocupa o slot da 2ª linha (o do mbway). */
.checkout-radio--cod {
	left: 915px;
	top: 620px;
}

.checkout-pagamento__nome--cod {
	top: 609px;
}

/* Checkboxes do checkout (criar conta, morada diferente, dados, termos):
   estado marcado com o visto do design (asset da área de conta). */
.checkout-check__caixa:has(input:checked) {
	background: #ffffff url("../img/loja/conta-checkbox-visto.svg") center / 14px 14px no-repeat;
}

/* Morada de envio alternativa — grelha espelhada da faturação, revelada
   pela checkbox "Enviar para uma morada diferente" (main.js põe a body
   class e mostra o bloco; as posições ficam sempre definidas). */
.checkout-campo--ship-nome { left: 0; top: 822px; width: 808.5px; }
.checkout-campo--ship-morada { left: 0; top: 886px; width: 808.5px; }
.checkout-campo--ship-porta { left: 0; top: 950px; width: 246px; }
.checkout-campo--ship-andar { left: 281.5px; top: 950px; width: 246px; }
.checkout-campo--ship-fracao { left: 563px; top: 950px; width: 246px; }
.checkout-campo--ship-codigo-postal { left: 0; top: 1014px; width: 375px; }
.checkout-campo--ship-localidade { left: 430px; top: 1014px; width: 379px; }

/* Com a morada aberta, as notas e a secção crescem (+224px). */
.pagina-checkout-morada .checkout-notas {
	top: 1096px;
}

.pagina-checkout-morada .checkout-conteudo {
	height: 1179.5px;
}

/* ------------------------------------------------------------
 * MENSAGENS DE ESTADO — design system Figma (node 0:14525):
 * texto simples Nunito 22/36 no tom dos títulos, sem caixas nem
 * ícones — sucesso E erro iguais; excepção: sucesso da loja em
 * primary semibold com o link "Ver carrinho" sublinhado.
 * ------------------------------------------------------------ */

.woocommerce-message,
.woocommerce-info,
.woocommerce-error,
.woocommerce-error li,
.seccao-formulario__status {
	margin: 0 0 24px;
	padding: 0;
	background: none;
	border: 0;
	list-style: none;
	font: 400 22px/36px var(--fonte-corpo, sans-serif);
	color: var(--cor-titulos-tom, #8E9193);
}

.woocommerce-message::before,
.woocommerce-info::before,
.woocommerce-error::before,
.woocommerce-error li::before {
	content: none;
}

.seccao-formulario__status--erro {
	color: var(--cor-titulos-tom, #8E9193);
}

.woocommerce-message a,
.woocommerce-info a,
.woocommerce-error a {
	color: inherit;
	text-decoration: underline;
}

/* Loja: sucesso do add-to-cart em primary semibold (Figma). */
.post-type-archive-product .woocommerce-message,
.tax-product_cat .woocommerce-message {
	font-weight: 600;
	color: var(--cor-primaria, #A787A3);
}

/* ------------------------------------------------------------
 * CARRINHO — visibilidade por estado. No mock cada estado era uma
 * PÁGINA separada só com o seu markup; o template funcional renderiza
 * os blocos todos e o CSS decide o que se vê:
 *  estado 1 (sem rates): link "Calcular custos de envio";
 *  estado 2 (calculador): só o formulário de morada;
 *  estado 3 (com rates): rádios + nota + "Alterar morada".
 * (Os rádios e o link calcular nunca coexistem no DOM — o PHP renderiza
 * um ou outro; o formulário é que existe sempre e tem de se esconder.)
 * ------------------------------------------------------------ */

body:not(.pagina-carrinho-2) .carrinho-envio__form {
	display: none;
}

/* Altura da secção por estado (mock: 441 / 830 / 658, calibrado para 2
   linhas) + delta das linhas extra vindo do template na custom property.
   Tem de ser CSS — inline ganharia às regras por body class e o estado 2
   ficava com a altura do 1, com a sidebar a transbordar para as secções
   seguintes. */
.carrinho-conteudo {
	height: calc(441px + var(--sda-carrinho-extra, 0px));
}

.pagina-carrinho-2 .carrinho-conteudo {
	height: calc(830px + var(--sda-carrinho-extra, 0px));
}

.pagina-carrinho-3 .carrinho-conteudo {
	height: calc(658px + var(--sda-carrinho-extra, 0px));
}

.pagina-carrinho-2 .carrinho-resumo__calcular,
.pagina-carrinho-2 .carrinho-envio-opcao__radio,
.pagina-carrinho-2 .carrinho-envio-opcao__nome,
.pagina-carrinho-2 .carrinho-envio-opcao__preco,
.pagina-carrinho-2 .carrinho-envio-opcao__nota,
.pagina-carrinho-2 .carrinho-envio-opcao__alterar {
	display: none;
}

/* ------------------------------------------------------------
 * REVISÃO DO CLIENTE (2026-08-10)
 * ------------------------------------------------------------ */

/* Home, bloco de terapias: o texto do slide estava a 18px enquanto o
   corpo das outras secções está a 26px. Com o texto maior, o parágrafo
   mais longo passou a encavalitar o botão — que desce o suficiente para
   o texto mais comprido (fica acima dos dots, a 685px). */
.home-terapias__slide-texto {
	font-size: 26px;
}

.home-terapias__slide-botao {
	top: 570px;
}

/* Cards de blog da home: a imagem, o título e a categoria também linkam. */
.home-blog-card__link-imagem {
	display: block;
}

.home-blog-card__titulo a,
.home-blog-card__meta a {
	color: inherit;
	text-decoration: none;
}

.home-blog-card__titulo a:hover,
.home-blog-card__meta a:hover {
	text-decoration: underline;
}

/* Footer: o crédito da Raquel saía no azul sublinhado do browser. */
.footer-copyright a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}

.footer-copyright a:hover {
	color: var(--cor-rosa, #ECC6C0);
}

/* Acordeões — ícones centrados no cabeçalho.
   O mock fixou os `top` assumindo que o 1.º item estava SEMPRE aberto
   (padding-top 0). Agora que qualquer item abre e fecha, esses valores
   deixaram de servir: um "−" num item que não o primeiro aparecia 49px
   acima do rótulo. Ancorar ao cabeçalho e centrar resolve em todos os
   estados. */
.accordion-faq-cabecalho,
.curso-como-funciona-cabecalho {
	position: relative;
}

.accordion-faq-item .accordion-faq-icone,
.accordion-faq-item:first-child .accordion-faq-icone--menos,
.accordion-faq-item:first-child .accordion-faq-icone--mais,
.accordion-faq-item.aberto .accordion-faq-icone--menos {
	top: 50%;
	transform: translateY(-50%);
}

.curso-como-funciona-icone {
	top: 50%;
	transform: translateY(-50%);
}

/* A abertura é animada em altura pelo main.js (transição real de
   expansão); aqui fica só o estado de partida do conteúdo. */
.accordion-faq-corpo,
.curso-como-funciona-painel {
	will-change: height;
}

/* Hero do curso: a flor a rodar fica no MESMO sítio da consulta de
   Astrologia (pedido do cliente, 2026-09-10). Medido na referência: o
   centro assenta na aresta ESQUERDA da foto, 81px acima do fundo — a
   altura (`top: 543px`, main.css:1256) já era igual nos quatro heros; só
   a horizontal divergia. Aqui o contentor `.curso-hero__imagens` é a caixa
   da própria foto, por isso o centro cai na aresta com metade dos 301px.
   Antes estava a -21.5px (centro 129px para DENTRO da foto), de um pedido
   anterior de «espelhar para a esquerda»; no Tarot havia ainda uma
   variante à direita (mais abaixo, agora retirada). Esta indicação do
   cliente substitui as duas. */
.curso-hero__simbolo-flor {
	left: -150.5px;
}

/* Formulários: o preenchimento deixa de estar em maiúsculas (os
   placeholders/labels mantêm o estilo do design). */
.seccao-formulario__campo input,
.seccao-formulario__campo textarea,
.artigo-deixe-comentario__campo input,
.artigo-deixe-comentario__campo textarea,
.checkout-campo input,
.checkout-notas textarea,
.login-card__campo {
	text-transform: none;
}

/* REVISÃO v5, R09 e R11 (PDF p.2) — «o coração não está a aparecer com
   contorno branco quando é marcado favorito», na grelha e na ficha.

   O desenho (Figma 0:19008, componente Botão Favorito) tem duas variantes:
   por defeito o coração sozinho, e no estado marcado um círculo cheio em
   #A787A3 com o coração a BRANCO. O que havia: o círculo mudava para roxo
   (main.css:4149) mas o coração continuava roxo — os SVGs têm
   `fill="#A787A3"` fixo — portanto desaparecia contra o próprio círculo.
   Uma correcção anterior tentou compensar com um anel branco à volta do
   botão, que o desenho não tem e que não resolvia o problema real.

   O coração é recolorido por filtro, como já se faz com a seta dos cards
   (fase 71): brightness(0) leva qualquer cor a preto e invert(1) a branco.
   Assim serve os dois SVGs (produto-coracao e favorito-coracao) sem
   duplicar ficheiros. */
.produto-card__desejos[aria-pressed="true"] img,
.produto-card__desejos--ativo img,
.produto-ficha__favorito[aria-pressed="true"] img,
.produto-ficha__favorito.produto-card__desejos--ativo img {
	filter: brightness(0) invert(1);
}

/* Cursos: bloco de reviews encostado à newsletter, sem espaço entre eles
   (o modificador --curso trazia 127px de margem inferior). */
.seccao-testemunhos--curso {
	margin-bottom: 0;
}

/* Avaliações do produto: o WooCommerce injecta o seu markup cru (lista
   de comentários + formulário) sem qualquer estilo do tema. */
.woocommerce-Reviews {
	font: 400 18px/28px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

.woocommerce-Reviews-title {
	margin: 0 0 24px;
	font: 500 26px/34px var(--fonte-corpo, sans-serif);
	text-transform: uppercase;
	color: var(--cor-primaria, #A787A3);
}

.woocommerce-Reviews .commentlist {
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce-Reviews .commentlist li.review {
	margin: 0 0 28px;
	padding: 0 0 24px;
	border-bottom: 1px solid var(--cor-cinza-claro, #D6D7D9);
}

.woocommerce-Reviews .comment-text {
	margin-left: 88px;
}

.woocommerce-Reviews .avatar {
	float: left;
	width: 64px;
	height: 64px;
	border-radius: 50%;
}

.woocommerce-Reviews .meta {
	margin: 0 0 8px;
	font: 500 16px/24px var(--fonte-corpo, sans-serif);
	color: var(--cor-footer, #483846);
}

.woocommerce-Reviews .meta time {
	color: var(--cor-titulos-tom, #8E9193);
}

.woocommerce-Reviews .description p {
	margin: 0 0 12px;
}

.woocommerce-Reviews #respond {
	margin-top: 32px;
}

.woocommerce-Reviews label {
	display: block;
	margin-bottom: 6px;
	font: 500 15px/22px var(--fonte-corpo, sans-serif);
	text-transform: uppercase;
	color: var(--cor-titulos-tom, #8E9193);
}

.woocommerce-Reviews input[type="text"],
.woocommerce-Reviews input[type="email"],
.woocommerce-Reviews textarea {
	width: 100%;
	max-width: 560px;
	padding: 8px 0;
	background: none;
	border: 0;
	border-bottom: 1px solid var(--cor-cinza-medio, #A4A7A9);
	font: 400 18px/26px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

/* REVISÃO v6, M9 — o botão «Enviar» das avaliações media 210×18px em mobile,
   encostado à esquerda: o `height: 56px` que aqui estava perdia para o
   `height: auto` do refluxo e a caixa desabava para a entrelinha. Passou a
   levar a classe `.botao-principal` pelo filtro
   `woocommerce_product_review_comment_form_args` (inc/woocommerce.php), e
   este bloco deixa de escrever `font` e `height` — com (0,2,0) ganhavam ao
   botão do site e o peso ficava em 500 e a caixa em 56 em desktop. */
.woocommerce-Reviews .submit {
	/* Só a margem. Tudo o resto vem do `.botao-principal` — enquanto este
	   bloco escrevia `background`, o hover ficava a meio: texto escuro
	   sobre a primária, 3,44:1, o único botão do site assim. */
	margin-top: 16px;
}

/* Imagens dentro do corpo do artigo: sem max-width, uma imagem grande do
   editor transbordava a coluna. */
.artigo-conteudo__texto img,
.artigo-conteudo__texto figure {
	max-width: 100%;
	height: auto;
	margin: 24px 0;
}

.artigo-conteudo__texto figure img {
	margin: 0;
	display: block;
}

.artigo-conteudo__texto figcaption {
	margin-top: 8px;
	font: 400 15px/22px var(--fonte-corpo, sans-serif);
	color: var(--cor-titulos-tom, #8E9193);
}

/* Alinhamentos do editor clássico nos artigos do site antigo (importados a
   16-10-2026): 102 têm a carta de tarot com `alignright` e um tem uma imagem
   com `aligncenter`. Sem estas regras a imagem ficava em linha com o texto,
   que começava junto à base dela. A carta flutua ao lado do texto; o
   `display: flow-root` faz o texto conter a imagem, para ela não descer
   para o que vem a seguir ao artigo. */
.artigo-conteudo__texto {
	display: flow-root;
}

.artigo-conteudo__texto .alignright {
	float: right;
	margin: 6px 0 16px 32px;
}

.artigo-conteudo__texto .alignleft {
	float: left;
	margin: 6px 32px 16px 0;
}

.artigo-conteudo__texto .aligncenter {
	display: block;
	margin-left: auto;
	margin-right: auto;
}

/* No telemóvel, uma carta de 166px a flutuar deixava menos de metade da
   coluna ao texto: fica por cima dele, encostada à esquerda como as outras
   imagens do conteúdo. Centrá-la obrigava a `!important`, porque o refluxo
   põe as margens laterais a 0 com doze classes de especificidade, e 97 das
   104 cartas não têm ligação à volta por onde a centrar. */
@media (max-width: 430px) {
	.artigo-conteudo__texto .alignright,
	.artigo-conteudo__texto .alignleft {
		float: none;
		display: block;
		margin-bottom: 16px;
	}
}

/* Coluna lateral do curso — grelha em vez de tops fixos.
   No mock cada linha da coluna tem um `top` absoluto calibrado à mão, e
   o Tarot (valores mais longos) tem um segundo jogo de 17 valores só
   para ele. Isso deixava a altura congelada em 785/942px: qualquer
   mudança de conteúdo — e os textos reais dos cursos ainda vêm do docx —
   obrigava a recalibrar tudo, e a coluna alta do Tarot não cabia no
   ecrã. Passa a grelha de duas colunas (ícone | valor) com o ritmo
   controlado por variáveis: a altura torna-se a soma real do conteúdo e
   encolhe ~55px no Tarot, o suficiente para caber num ecrã de 1080. */
/* Selector composto para vencer a altura fixa que o mock dá ao Tarot
   (`.pagina-curso-tarot-N .curso-sidebar { height: 942px }`) — com altura
   fixa a grelha ainda esticava as linhas para preencher o excedente. */
.curso-sidebar-coluna .curso-sidebar {
	/* Apertados face ao mock (eram 10 e 26) para a coluna caber no ecrã sem
	   scroll interno: no Curso de Tarot faltavam 87–116px conforme o ecrã, e
	   o botão de inscrição ficava abaixo da dobra da própria coluna. */
	--sda-sb-linha: 8px;    /* título ↔ valor, e entre valores do mesmo bloco */
	--sda-sb-bloco: 16px;   /* respiro extra antes de cada novo bloco */

	display: grid;
	grid-template-columns: 43px 1fr;
	align-items: start;
	align-content: start;
	row-gap: var(--sda-sb-linha);
	height: auto;
	top: var(--sda-sb-topo, 120px); /* 100 do header + 20 de folga; o main.js reduz-no quando não cabe */
}

.curso-sidebar .curso-sidebar__titulo,
.curso-sidebar .curso-sidebar__valor,
.curso-sidebar .curso-sidebar__icone,
.curso-sidebar .curso-sidebar__botao {
	position: static;
	top: auto;
	left: auto;
}

.curso-sidebar .curso-sidebar__titulo {
	grid-column: 1 / -1;
	margin-top: var(--sda-sb-bloco);
}

.curso-sidebar .curso-sidebar__titulo--data {
	margin-top: 0;
}

.curso-sidebar .curso-sidebar__icone {
	grid-column: 1;
	justify-self: start;
}

/* O pin é mais estreito e no mock estava recuado 9px para centrar. */
.curso-sidebar .curso-sidebar__icone--pin {
	margin-left: 9px;
}

.curso-sidebar .curso-sidebar__valor {
	grid-column: 2;
	width: auto;
	max-width: 274px; /* mantém as mesmas quebras de linha do design */
}

.curso-sidebar .curso-sidebar__botao {
	grid-column: 1 / -1;
	justify-self: start;
	margin-top: 30px;
}

/* Quando a barra não cabe abaixo do offset normal, o main.js reduz o
   `top` (podendo torná-lo negativo) em vez de lhe tirar o sticky. Assim
   ela continua a acompanhar a página e o botão de inscrição fica sempre
   visível — é o topo da barra que sai do ecrã, não o CTA.

   Antes isto punha `position: static` e a barra deixava de acompanhar a
   página. Medido no staging: no Curso de Tarot acontecia em TODOS os ecrãs
   realistas, incluindo 1920x1080, e no de Astrologia na maioria. A inversão
   que o tornava difícil de reproduzir é que o canvas escala por `zoom` a
   partir da LARGURA: num monitor maior a barra fica mais alta em píxeis
   reais sem que a janela cresça na mesma proporção, por isso quanto maior
   o ecrã, mais provável era perder o sticky.

   Tentei primeiro ancorar em baixo (`bottom: 24px`), mas o sticky-bottom
   precisa de espaço acima para deslocar o elemento e a barra já nasce
   colada ao topo da coluna: media 2 pontos de scroll visíveis em 12. */

/* ------------------------------------------------------------
 * BOTÕES — o que o design não define (hover do contorno e cor do
 * botão de lista foram corrigidos na fonte; fica aqui o foco).
 * ------------------------------------------------------------ */

/* Foco visível consistente (o default do browser é 1px auto; o padrão
   do projecto é 2px primary). */
.site-content a:focus-visible,
.site-content button:focus-visible,
.site-content input:focus-visible,
.site-content textarea:focus-visible,
.site-header a:focus-visible,
.site-header button:focus-visible,
.site-footer a:focus-visible {
	outline: 2px solid var(--cor-primaria, #A787A3);
	outline-offset: 2px;
}

/* Botões desactivados: sem cursor de acção nem hover. */
.botao-principal:disabled,
.botao-contorno:disabled,
.botao-lista[aria-disabled="true"] {
	cursor: not-allowed;
}

.botao-contorno:disabled:hover {
	background: none;
	color: var(--cor-primaria, #A787A3);
}

/* ------------------------------------------------------------
 * MOBILE DAS PÁGINAS SEM DESENHO PRÓPRIO
 *
 * O design só entregou layout mobile para a HOME (bloco @430px do
 * main.css, que cobre também header, footer, newsletter e testemunhos —
 * partilhados por todo o site). As restantes páginas mantinham as
 * coordenadas absolutas do canvas de 1920 e ficavam ilegíveis no
 * telemóvel (medido: 21/23 elementos fora do ecrã em contactos, 72/85
 * na loja, 92/101 no blog).
 *
 * Sem mockups mobile dessas páginas, a opção é REFLUIR: o interior das
 * secções passa a fluxo vertical na ordem do DOM, dentro de uma coluna
 * de 344px com margens de 23px — as mesmas medidas do mobile da home,
 * para a linguagem visual ser a mesma. Não é pixel-perfect a uma
 * maqueta (não existe), mas é coerente e utilizável.
 *
 * Quando chegarem os mockups mobile, cada página passa a ter o seu
 * bloco e sai desta regra genérica.
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* A home tem desenho próprio — não lhe tocar. */
	body:not(.pagina-home-final) .seccao-inner {
		width: 100%;
		padding-left: 23px;
		padding-right: 23px;
		box-sizing: border-box;
	}

	/* As secções do mock têm altura fixa calibrada a 1920. */
	body:not(.pagina-home-final) .site-content > section,
	body:not(.pagina-home-final) .site-content > div {
		height: auto;
		min-height: 0;
		margin-top: 0;
		padding-top: 28px;
		padding-bottom: 28px;
	}
	/* Grelhas passam a coluna única. */
	body:not(.pagina-home-final) .site-content [class$="__grelha"],
	body:not(.pagina-home-final) .site-content [class$="__lista"],
	body:not(.pagina-home-final) .site-content .seccao-artigos-lista {
		display: flex;
		flex-direction: column;
		gap: 0;
		padding: 0;
		list-style: none;
	}

	body:not(.pagina-home-final) .site-content img {
		max-width: 100%;
		height: auto;
	}

	/* Decoração calibrada ao canvas largo deixa de fazer sentido. */
	body:not(.pagina-home-final) .site-content [class*="__divisor"],
	body:not(.pagina-home-final) .site-content [class*="__fundo"] {
		display: none;
	}

	body:not(.pagina-home-final) .site-content p,
	body:not(.pagina-home-final) .site-content h1,
	body:not(.pagina-home-final) .site-content h2,
	body:not(.pagina-home-final) .site-content h3 {
		margin: 0 0 16px;
	}

	/* Login: o "cenário" da loja por trás do cartão é decoração de
	   desktop — em coluna estreita só empurrava o formulário 2000px
	   para baixo. */
	.login-cenario__loja,
	.login-cenario__overlay {
		display: none;
	}

	/* O desenho mobile do cartão de login vive todo junto no bloco de
	   R119, no fim do ficheiro — aqui ficava metade dele, e a metade que
	   não vencia o refluxo. */

	/* Alvos de toque mínimos nos controlos principais. */
	.site-content .botao-principal,
	.site-content .botao-contorno,
	.site-content .login-card__submeter,
	.site-content button[type="submit"] {
		min-height: 48px;
	}

	/* O reflow troca as larguras fixas do mock por `auto` e, como os
	   botões do design não têm padding horizontal (a largura fixa é que
	   fazia a folga), o texto ficava encostado às duas bordas. A home
	   fica de fora — tem larguras próprias no desenho mobile e, sendo
	   content-box, o padding somar-se-ia a elas. */
	/* Só o `.botao-lista` sobra: os outros quatro levam `padding-left` e
	   `padding-right` a zero, com `!important`, na regra do grupo — este
	   padding nunca chegou a pintar. */
	body:not(.pagina-home-final) .site-content .botao-lista {
		padding-left: 24px;
		padding-right: 24px;
	}

	/* A coluna lateral do curso não vive dentro do `.seccao-inner`, por
	   isso não herdava a goteira lateral e encostava à margem do ecrã. */
	body:not(.pagina-home-final) .curso-sidebar-coluna {
		box-sizing: border-box;
		padding-left: 23px;
		padding-right: 23px;
	}

	/* Painéis de ano em fluxo: as duas colunas do desenho (307 + 629)
	   somam 980px e não cabem — passam a uma só coluna empilhada. */
	body:not(.pagina-home-final) .curso-estrutura-painel--fluxo {
		grid-template-columns: 1fr;
		column-gap: 0;
		padding: 0;
	}

	body:not(.pagina-home-final) .curso-estrutura-painel--fluxo .curso-estrutura__rotulo,
	body:not(.pagina-home-final) .curso-estrutura-painel--fluxo .curso-estrutura__texto {
		grid-column: 1;
	}

	body:not(.pagina-home-final) .curso-estrutura-painel--fluxo .curso-estrutura__rotulo {
		margin-bottom: 12px;
	}

	body:not(.pagina-home-final) .curso-estrutura-painel--fluxo .curso-estrutura__separador {
		width: auto;
		margin: 28px 0;
	}

	body:not(.pagina-home-final) .curso-estrutura-painel--fluxo .curso-estrutura__painel-titulo {
		min-height: 0;
		margin-bottom: 28px;
	}
}

/* ------------------------------------------------------------
 * REDUCED MOTION — desliga tudo o que é contínuo/decorativo.
 * ------------------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
	.sda-loader,
	body.home .sda-loader,
	body.home.is-loaded .sda-loader {
		animation: none;
		transition: opacity 200ms linear, visibility 0s linear 200ms;
	}

	.sda-loader__mark,
	body.home .sda-loader__mark {
		animation: none;
	}

	body.home.is-loaded .sda-loader {
		opacity: 0;
		visibility: hidden;
	}

	.terapia-hero__simbolo-flor,
	.curso-hero__simbolo-flor,
	.proximas-actividades__simbolo,
	.home-sobre-leonardo__selo,
	.qs-sobre-leonardo__selo,
	.terapia-sobre-leonardo__selo,
	.curso-sobre-leonardo__selo,
	.home-loja__ticker.sda-ticker-activo {
		animation: none;
	}

	/* A regra de abertura tem mais especificidade (0,2,1) do que
	   `.sda-drawer` sozinho e ganhava mesmo aqui dentro: medi a opacidade
	   em 0,77 a 120 ms com o movimento reduzido activo. */
	.sda-drawer,
	body.sda-drawer-aberto .sda-drawer {
		transition: none;
	}
}

/* Acordeões no mobile — o reflow global põe tudo em `position: static`,
   e como os ícones são <span> inline acabavam colados ao fim do texto do
   título em vez de à direita. O cabeçalho passa a linha flex: rótulo à
   esquerda, ícone à direita e centrado na vertical, mesmo com o título
   a ocupar várias linhas. */
@media (max-width: 430px) {
	/* Os cabeçalhos estão fora do reflow global (ver o `:not()` acima):
	   sendo <button>, `width: auto` fá-los encolher ao conteúdo e o ícone
	   deixava de chegar à direita. Aqui recebem o tratamento certo. */
	body:not(.pagina-home-final) .site-content .accordion-faq-cabecalho,
	body:not(.pagina-home-final) .site-content .curso-como-funciona-cabecalho {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: 16px;
		width: 100%;
		height: auto;
		min-height: 0;
		box-sizing: border-box;
	}

	body:not(.pagina-home-final) .site-content .accordion-faq-icone,
	body:not(.pagina-home-final) .site-content .curso-como-funciona-icone {
		flex: 0 0 auto;
	}

	/* REVISÃO v5, R80 (PDF p.17) — «colocar margem superior e inferior
	   dentro de cada módulo do acordeão». Em desktop o respiro da pastilha
	   vem da altura fixa do cabeçalho (36px do topo ao glifo, 38 do glifo
	   ao fundo). Em mobile a regra acima troca essa altura por
	   `height: auto`, para o ícone chegar à direita com o rótulo em várias
	   linhas, e nem o item nem o cabeçalho têm padding vertical — o mock
	   dá-lhe `padding: 0 47px`. Medido a 390px: pastilha de 78px para um
	   rótulo de 3 linhas, com **1px** em cima e 1px em baixo.
	   Longhands e nunca o atalho `padding`, para não perder os 47px
	   laterais do mock.
	   NÃO juntar ao selector do FAQ acima: lá o respiro já vem do
	   `padding: 48.5px 0 43px` do próprio mock, e somar-lhe 24 daria 72,5. */
	body:not(.pagina-home-final) .site-content .curso-como-funciona-cabecalho {
		padding-top: 24px;
		padding-bottom: 24px;
	}
}

/* Painéis de ano em fluxo — 3º de Astrologia e 1º de Tarot.
   O Figma nunca desenhou estes dois anos, por isso não existem
   coordenadas absolutas para eles (os outros painéis têm um `top`
   calibrado à mão para cada rótulo, texto e separador). Calibrá-los
   agora significaria recalibrar tudo a cada correcção de texto, e são
   os programas mais longos do site. Ficam em grelha, com a mesma
   geometria horizontal do desenho — rótulo 307px, texto 629px a
   começar aos 354 — e o ritmo vertical dado pelo próprio conteúdo. */
/* O header é sticky com 100px: sem esta margem, o atalho da timeline
   (initTimelineCurso) faz scrollIntoView e deixa o título da secção e a
   própria linha de separadores por baixo dele. 232 = 100 do header + 96
   do H2 + 36 de folga; escala com o zoom do canvas, tal como tudo o
   resto. */
.curso-estrutura {
	scroll-margin-top: 232px;

	/* Altura de arranque da vista inicial de Astrologia (Próxima Edição),
	   que passou a painel em fluxo: o mockup fixa 1603px, calibrados para
	   o painel de 2025 que foi substituído. Sem isto a página pinta com a
	   secção curta e salta ~270px quando o main.js mede. Espelha o que o
	   `ajustarAlturaEstrutura()` calcula (1752 de conteúdo + 120 de
	   folga) — a rever se o texto da Próxima Edição mudar. As body
	   classes dos outros anos têm mais especificidade e continuam a
	   ganhar. */
	height: 1872px;
}

/* O `display` de autor ganha ao `display:none` que o browser dá ao
   atributo [hidden] — sem esta regra os painéis fechados continuavam a
   ser desenhados por cima do activo. */
.curso-estrutura-painel--fluxo[hidden] {
	display: none;
}

.curso-estrutura-painel--fluxo {
	display: grid;
	grid-template-columns: 307px 629px;
	column-gap: 44px;
	align-content: start;
	box-sizing: border-box;
	height: auto;
	/* Sem título de programa (a Próxima Edição), o 1.º rótulo arranca
	   exactamente onde o desenho o põe (--pe-1/--t1: 273px). */
	padding: 273px 0 0 3px;
}

/* Com título de programa, quem arranca é o título — e a variante
   `--programa` do desenho põe-no aos 148px, não aos 125px do título
   simples. 148 + 96 (caixa de uma linha) + 29 = os mesmos 273px. */
.curso-estrutura-painel--fluxo:has(.curso-estrutura__painel-titulo--programa) {
	padding-top: 148px;
}

.curso-estrutura-painel--fluxo .curso-estrutura__painel-titulo {
	position: static;
	grid-column: 1 / -1;
	max-width: 983px;
	/* O desenho fixa `nowrap` com line-height 96px porque os títulos que
	   desenhou cabiam numa linha; o do 3º ano tem 180 caracteres. O
	   `min-height` mantém a caixa de uma linha igual à do desenho e
	   deixa crescer quando é preciso. */
	white-space: normal;
	line-height: 42px; /* a mesma dos painéis desenhados */
	min-height: 96px;
	margin: 0 0 29px; /* 148 + 96 + 29 = 273, o topo do 1º rótulo */
}

.curso-estrutura-painel--fluxo .curso-estrutura__rotulo {
	position: static;
	grid-column: 1;
	width: auto;
	margin: 0;
}

.curso-estrutura-painel--fluxo .curso-estrutura__texto {
	position: static;
	grid-column: 2;
	width: auto;
	margin: 0;
}

/* Capítulo sem lista de conteúdos (no 1.º ano de Astrologia, «1. Introdução
   conceptual…» e «2. História da Astrologia (I)»): o rótulo ficava
   espremido nos 307px da coluna esquerda, a partir em quatro linhas, ao
   lado de uma coluna direita vazia. Pedido do cliente (2026-09-10): quando
   não há lista, o rótulo estende-se pela largura toda e a coluna da direita
   não existe. O marcador é o próprio DOM — o `<div class="…__texto">` só é
   escrito quando há conteúdo (single-sda_curso.php), por isso um rótulo sem
   um `__texto` a seguir ocupa as duas colunas. Em mobile a grelha já é de
   uma coluna e isto não muda nada. */
.curso-estrutura-painel--fluxo .curso-estrutura__rotulo:not( :has( + .curso-estrutura__texto ) ) {
	grid-column: 1 / -1;
}

.curso-estrutura-painel--fluxo .curso-estrutura__separador {
	position: static;
	grid-column: 1 / -1;
	width: 1105px;
	margin: 40px 0 44px -75px; /* -75 = os -72px do desenho, menos os 3 de padding */
}

/* O 4º nível de lista não existe no desenho (os painéis desenhados vão
   até "1." no 3º nível). Aparece só no 3º ano de Astrologia, sob "O
   Sol:" e "A Lua:", e leva travessão para não colidir com nenhuma das
   numerações acima. */
.curso-estrutura__subtopicos ol ol ol {
	margin: 0;
	padding-left: 28px;
	list-style: none;
}

/* Páginas de terapia — ordem trocada a pedido do cliente: o ensaio sobre
   a prática sobe para o lugar do "Sobre o Leonardo" e este passa para o
   fim (com "Saber Mais" para o site dele, como na home). O botão de
   marcação mantém-se neste ponto da página, agora dentro do ensaio —
   64px abaixo da 1.ª coluna, cujo comprimento difere nas duas terapias. */
.terapia-sobre-astrologia__botao {
	position: absolute;
	left: 0;
	top: 810px; /* Astrologia: 1.ª coluna acaba aos 746px */
}

.pagina-terapia-tarot .terapia-sobre-astrologia__botao {
	top: 666px; /* Tarot: 1.ª coluna acaba aos 602px */
}

/* Ritmo vertical da nova ordem: o ensaio herda o respiro de 130px que o
   "Sobre o Leonardo" tinha depois dos testemunhos (trazia só 47px, que
   eram o intervalo depois da citação), e o Leonardo, agora último, leva
   os 127px antes da newsletter que eram do ensaio. */
.terapia-sobre-astrologia {
	margin-top: 130px;
}

.terapia-sobre-leonardo {
	margin-bottom: 127px;
}

/* ------------------------------------------------------------
 * LOTE 4 — registo, favoritos, newsletter no checkout e Obrigado
 * ------------------------------------------------------------ */

/* Checkout: password da conta nova, à direita da checkbox "Criar conta"
   (mesma fila, por isso nada desliza quando aparece). */
.checkout-campo--conta-password {
	left: 430px;
	top: 636px;
	width: 379px;
}

/* No estado MB WAY (pagina-checkout-1) as checkboxes descem 64.5px —
   o campo acompanha a fila da checkbox que o revela. */
.pagina-checkout-1 .checkout-campo--conta-password {
	top: 700.5px;
}

/* Checkout: opt-in da newsletter por baixo dos termos, na coluna direita. */
.checkout-newsletter {
	top: 892px;
}

.pagina-checkout-1 .checkout-newsletter {
	top: 1143px;
}

/* Card de registo: reutiliza o login-card por inteiro; só o link de
   voltar dispensa a posição do "Criar Conta" original. */
.login-card--registo .login-card__link--criar a {
	text-decoration: underline;
}

/* O hook woocommerce_register_form imprime o texto de privacidade sem
   estilos (aparecia cru por cima do topo do cartão) — passa a nota
   pequena no espaço vazio entre o botão e o link de entrar. */
.login-card--registo .woocommerce-privacy-policy-text {
	position: absolute;
	left: 50%;
	top: 398px;
	transform: translateX(-50%);
	width: 460px;
	text-align: center;
}

.login-card--registo .woocommerce-privacy-policy-text p {
	margin: 0;
	font: 400 13px/19px var(--fonte-corpo, sans-serif);
	color: var(--cor-titulos-tom, #8E9193);
}

.login-card--registo .woocommerce-privacy-policy-text a {
	color: inherit;
	text-decoration: underline;
}

/* Conta — Lista de desejos: o conteúdo entra na coluna à direita do menu
   lateral (o wrapper é neutro e só as vistas conhecidas ganham coluna) e
   a secção deixa a altura fixa do mock para crescer com a lista. O WC
   emite a body class woocommerce-lista-de-desejos no endpoint. O desenho
   (0:6320) põe a coluna a x=645 com 1015px. */
.woocommerce-lista-de-desejos .woocommerce-MyAccount-content {
	margin-left: 385px;
	max-width: 1015px;
	padding-bottom: 64px;
}

.woocommerce-lista-de-desejos .conta-conteudo {
	height: auto;
	min-height: 620px;
	padding-bottom: 80px;
}

/* Conta — estados vazios das Encomendas e dos Descarregamentos.

   O mock só desenha os cartões de encomenda, que são absolutos dentro de
   .conta-encomenda. Sem encomendas não havia sítio para a mensagem: ela
   reutilizava .conta-encomenda__titulo (position:absolute; left:1px; top:0)
   e, como o wrapper do WC é position:static de propósito, ancorava na
   .seccao-inner — ou seja, por cima do menu lateral. O mesmo acontecia ao
   aviso nativo do WC no endpoint de descarregamentos, que não tem desenho.
   Ambos passam a ocupar a coluna da direita, como a lista de desejos. */
.conta-vazio {
	margin-left: 385px;
	max-width: 1015px;
	padding-bottom: 64px;
}

.conta-vazio__texto {
	margin: 25px 0 32px;
	font: 400 22px/36px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

.conta-vazio__accao {
	width: 295px;
}

/* A altura fixa do mock (2069.5px) serve os 3 cartões do desenho; sem
   conteúdo deixava mais de 900px de vazio por baixo. */
.conta-conteudo:has(.conta-vazio) {
	height: auto;
	min-height: 620px;
	padding-bottom: 80px;
}

.woocommerce-downloads .woocommerce-MyAccount-content {
	margin-left: 385px;
	max-width: 1015px;
	padding-bottom: 64px;
}

.woocommerce-downloads .conta-conteudo {
	height: auto;
	min-height: 620px;
	padding-bottom: 80px;
}


/* Conta — Lista de desejos (desenho 0:6320): lista vertical de linhas
   com separador, contador, paginação e botão para a loja. */
.conta-desejos__lista {
	margin: 25px 0 0;
	padding: 0;
	list-style: none;
}

.conta-desejos__item {
	position: relative;
	display: flex;
	gap: 32px;
	padding-bottom: 49px;
	margin-bottom: 49px;
	border-bottom: 1px solid #EAEBEC;
}

.conta-desejos__imagem-link {
	flex: 0 0 220px;
}

.conta-desejos__imagem {
	display: block;
	width: 220px;
	height: 220px;
	border-radius: 20px;
	object-fit: cover;
}

.conta-desejos__info {
	flex: 1;
	padding-top: 18px;
}

.conta-desejos__nome {
	max-width: 719px;
	margin: 0 0 16px;
	text-transform: none;
}

/* !important: as regras genéricas da área da conta (h3/a do mock) têm
   selectors absolutos que ganhavam à classe. */
/* `!important` em três propriedades só: a regra genérica da conta e o
   `h3` do mock ganham-lhes por selector. Os outros longhands que a
   taquigrafia `font` expandia, e o `text-transform` que o pai já dá, não
   mudavam um pixel. */
.conta-desejos__nome a {
	font-weight: 400 !important;
	font-size: 24px !important;
	line-height: 32px !important;
	font-family: var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969) !important;
	text-transform: none;
	text-decoration: none;
}

.conta-desejos__preco {
	display: block;
	margin-bottom: 26px;
	font: 500 28px/38px var(--fonte-corpo, sans-serif);
	color: var(--cor-primaria, #A787A3);
}

.conta-desejos__preco ins {
	text-decoration: none;
}

.conta-desejos__preco del {
	margin-right: 8px;
	font-size: 20px;
	color: var(--cor-titulos-tom, #8E9193);
}

.conta-desejos__accoes {
	display: flex;
	align-items: center;
	gap: 24px;
}

.conta-desejos__stepper {
	display: inline-flex;
	align-items: center;
	justify-content: space-between;
	width: 128px;
	height: 61px;
	padding: 0 16px;
	box-sizing: border-box;
	border: 1px solid var(--cor-cinza-medio, #A4A7A9);
	border-radius: 8px;
}

.conta-desejos__qtd-menos,
.conta-desejos__qtd-mais {
	padding: 0;
	background: none;
	border: 0;
	font: 400 24px/1 var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
	cursor: pointer;
}

.conta-desejos__qtd-valor {
	font: 400 22px/1 var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

.conta-desejos__carrinho {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 331px;
	height: 61px;
	box-sizing: border-box;
	border: 1px solid var(--cor-primaria, #A787A3);
	border-radius: 8px;
	font: 600 16px/1 var(--fonte-corpo, sans-serif);
	letter-spacing: 0.05em;
	text-transform: uppercase;
	text-decoration: none;
	/* Sem bandeira: a regra genérica da conta entrega a mesma cor por
	   especificidade. A do `:hover`, essa, FICA — sem ela o rótulo passa
	   a primária sobre fundo primário e desaparece. */
	color: var(--cor-primaria, #A787A3);
	transition: background 0.2s ease, color 0.2s ease;
}

.conta-desejos__carrinho:hover {
	background: var(--cor-primaria, #A787A3);
	color: #ffffff !important;
}

.conta-desejos__carrinho--esgotado {
	border-color: var(--cor-cinza-claro, #D6D7D9);
	color: var(--cor-cinza-medio, #A4A7A9) !important;
	cursor: not-allowed;
}

.conta-desejos__carrinho.added {
	display: none; /* o "ver carrinho" injectado pelo WC não faz parte do desenho */
}

/* REVISÃO v5, R17 (PDF p.3). O «Carrinho» que o cliente fotografou não
   está no nosso markup — é o estado PÓS-CLIQUE: o WooCommerce marca o
   botão com `.added` (que a regra acima esconde) e injecta ao lado um
   `<a class="added_to_cart wc-forward">`, cujo rótulo vem do filtro
   gettext "View cart" → "Carrinho" (inc/woocommerce.php:341). Esse link
   não era apanhado por nenhuma regra de tipografia e caía no default do
   browser: Times 16px. Fica como o cliente pediu — Nunito Regular,
   sublinhado, 18px (o projecto converte os pt do desenho 1:1 para px;
   ver `.botao-principal` a 18px em main.css:132). A cor primária já lhe
   chega pela regra de links da conta. */
.conta-desejos__accoes .added_to_cart {
	font: 400 18px/26px var(--fonte-corpo, sans-serif);
	letter-spacing: 0;
	text-transform: none;
	text-decoration: underline;
}

.conta-desejos__remover {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 61px;
	height: 61px;
	padding: 0;
	background: var(--cor-primaria, #A787A3);
	border: 0;
	border-radius: 50%;
	cursor: pointer;
}

.conta-desejos__remover img {
	/* O coração é quadrado em todos os SVG (viewBox 18x18 ou 22x22) e
	   todos trazem `preserveAspectRatio="none"` — uma caixa não-quadrada
	   estica o desenho. O markup traz width="24" height="21", o que o
	   alargava 14% na horizontal e o fazia ler mais gordo do que o da
	   ficha. O componente do Figma usa 22x22. */
	width: 22px;
	height: 22px;
	filter: brightness(0) invert(1);
}

.conta-desejos__rodape {
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin: 33px 0 0;
}

.conta-desejos__contador {
	margin: 0;
	font: 400 18px/26px var(--fonte-corpo, sans-serif);
	color: var(--cor-titulos-tom, #8E9193);
}

.conta-desejos__paginacao {
	display: flex;
	align-items: center;
	gap: 12px;
}

.conta-desejos__pagina {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 59px;
	height: 59px;
	border-radius: 50%;
	font: 400 22px/1 var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969) !important;
	text-decoration: none;
}

.conta-desejos__pagina--activa {
	border: 1px solid var(--cor-primaria, #A787A3);
	color: var(--cor-primaria, #A787A3) !important;
}

.conta-desejos__seguinte {
	font: 400 30px/1 var(--fonte-corpo, sans-serif);
	color: #727272 !important;
	text-decoration: none;
}

.conta-desejos__loja {
	display: inline-flex;
	margin: 81px 0 0;
	width: 295px;
}

.conta-desejos > .conta-desejos__loja {
	margin-left: calc(50% - 147.5px); /* centrado na coluna */
}

.conta-desejos__vazio {
	margin: 25px 0 32px;
	font: 400 22px/36px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

/* Página Obrigado — composta com o design system (não há desenho). */
.seccao-hero--obrigado .seccao-hero__titulo {
	white-space: nowrap;
}

.obrigado-mensagem {
	margin: 96px 0 40px;
}

.obrigado-mensagem p {
	max-width: 900px;
	margin: 0 0 24px;
	font: 400 26px/40px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

/* A secção de produtos herda a altura fixa do mock; com 4 cards (REVISÃO v6, D3) mantém-se — a grelha do desenho já acomoda 4, como no /blog/. */
.seccao-produtos-relacionados--obrigado {
	margin-bottom: 0;
}

.obrigado-artigo {
	margin: 40px 0 130px;
}

.obrigado-artigo__titulo {
	margin: 0 0 48px;
	font: 400 52px/62px var(--fonte-titulos, serif);
	color: var(--cor-primaria, #A787A3);
}

/* O card de artigo fixa 912px; o "Ler mais" reutiliza o estilo da lista. */
.obrigado-artigo .seccao-artigos-card {
	margin: 0;
}

/* ------------------------------------------------------------
 * CAMPANHA PIXEL-PERFECT (Figma P2, node 0:15381) — correcções
 * ------------------------------------------------------------ */

/* Carrinho: o link do nome do produto (introduzido no cart.php, o mock
   não o tinha) ficava com o azul default do browser. */
.carrinho-linha__nome a {
	color: inherit;
	text-decoration: none;
}

/* Artigo: o blockquote do conteúdo real ganha o cartão de citação do
   desenho (o mock só estilizava a .artigo-conteudo__citacao posicionada). */
.artigo-conteudo__texto blockquote {
	position: relative;
	margin: 48px 0;
	padding: 96px 60px 48px;
	background: rgba(255, 255, 255, 0.5);
	border-radius: 30px;
	text-align: center;
}

.artigo-conteudo__texto blockquote p {
	font: 600 22px/36px var(--fonte-corpo, sans-serif);
	color: var(--cor-primaria, #A787A3);
}

.artigo-conteudo__texto blockquote::before {
	content: '\201C';
	position: absolute;
	left: 50%;
	top: 8px;
	transform: translateX(-50%);
	font: 400 180px/1 var(--fonte-titulos, serif);
	color: var(--cor-primaria, #A787A3);
}

.artigo-conteudo__texto blockquote cite {
	display: block;
	margin-top: 16px;
	font: italic 400 18px/28px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

/* FAQ e Informação Legal: o conteúdo começava 24px acima do desenho. */
.faq-conteudo,
.seccao-conteudo-legal {
	padding-top: 24px;
}

/* Contactos: +50px de respiro antes da newsletter (Figma: 180.5). */
.seccao-onde-estamos {
	margin-bottom: 140px;
}

/* Inscrição: gap para a newsletter é 140 no desenho, não 130. */
.seccao-formulario {
	margin-bottom: 140px;
}

/* Placeholders em UPPERCASE como no desenho — só o placeholder: o texto
   que o utilizador escreve fica em caixa normal (pedido do cliente). */
.seccao-formulario input::placeholder,
.seccao-formulario textarea::placeholder,
.seccao-contactos-form input::placeholder,
.seccao-contactos-form textarea::placeholder,
.artigo-deixe-comentario input::placeholder,
.artigo-deixe-comentario textarea::placeholder {
	text-transform: uppercase;
	color: var(--cor-titulos-tom, #8E9193);
}

/* Checkout: excepção do desenho — as notas de encomenda são o único
   campo com placeholder em caixa normal. */
.checkout-notas textarea::placeholder {
	text-transform: none;
}

/* Cursos: separadores e linha das tabs no neutral-light do desenho
   (o #F0F0F0 do mock quase não se lia sobre o creme). */
.curso-estrutura__separador,
.curso-estrutura__linha-tabs {
	background: var(--cor-cinza-claro, #D6D7D9);
}

/* Cursos: o nav das tabs fica ACIMA dos painéis absolutos (que cobrem
   a faixa toda para hit-testing — um clique real aterrava no painel) e
   o sublinhado rosa da tab activa por cima da linha de base. As tabs
   continuam em absoluto (mock); só re-ancoram ao nav, que colapsa a
   altura 0 no topo do inner — geometria idêntica. */
.curso-estrutura nav {
	position: relative;
	z-index: 2;
}

.curso-estrutura-tab.ativo::after {
	z-index: 1;
}

/* Curso de Tarot: o desenho v2 punha a flor do hero no canto inferior
   DIREITO, distinguindo-o da Astrologia. Retirado a 2026-09-10 — o cliente
   pediu os dois cursos «com a mesma localização da consulta de Astrologia»
   (aresta esquerda); a regra única de `.curso-hero__simbolo-flor` acima
   passa a servir os dois. Fica o registo para quem procurar a variante. */

/* Curso: a coluna lateral mantém o empilhamento do mock — desliza por
   BAIXO da secção escura do Como Funciona no scroll (z 1 < 2), como o
   desenho faz. (Tentativas de a limitar ou elevar pioravam: com z-index
   passava por cima das tabs; com altura limitada o sticky transbordava
   a coluna curta do Tarot.) */

/* Ficha do produto: favorito é 61×61 no desenho (estava 57). */
.produto-ficha__favorito {
	width: 61px;
	height: 61px;
}

/* Card de produto: o coração dentro do círculo é 18px no desenho. */
.produto-card__desejos img {
	width: 18px;
	height: 16px;
}

/* Newsletter: a foto do sol tem 380px e os 4 cantos redondos no desenho
   — estava cortada 45px em baixo (queixa do cliente na 2.ª ronda). */
.seccao-newsletter__foto--sol {
	height: 380px;
	border-radius: 30px;
}

/* Blog: passo da paginação é ~66px no desenho (gap 24 dava 83). */
.seccao-artigos-paginacao {
	gap: 7px;
}

/* Artigo: separadores de tags/partilha no cinza médio do desenho. */
.artigo-tags-partilha__separador {
	background: var(--cor-cinza-medio, #A4A7A9);
}

/* Conta: item activo do menu também em uppercase. */
.conta-menu .ativo a {
	text-transform: uppercase;
}

/* Conta: títulos de secção no display do v2 (HV Simplicite ~50px,
   caixa normal, primária) — o mock trazia Nunito 26 uppercase. */
.conta-titulo,
.conta-ver__seccao {
	font: 400 50px/62px var(--fonte-titulos, serif);
	text-transform: none;
	color: var(--cor-primaria, #A787A3);
}

/* Loja: lista de categorias 4px acima (o mock punha-a aos 63px). */
.loja-filtro__lista {
	margin-top: 59px;
}

/* Testemunhos: o card do desenho tem ~507px (media 500). */
.seccao-testemunhos__card {
	min-height: 506px;
	box-sizing: border-box;
}

/* Home: título do card de actividades desce ~11px para centrar como a
   caixa de line-height 96 do desenho. */
.home-actividades-card__titulo {
	margin-top: 11px;
}

/* Header: o desenho define a barra como véu branco 0.8 com desfoque
   sobre a textura (Figma 0:15286). */
.site-header {
	background: rgba(255, 255, 255, 0.8);
	-webkit-backdrop-filter: blur(24px);
	backdrop-filter: blur(24px);
}

/* Painéis em fluxo no TAROT: o desenho do Tarot usa um ritmo mais
   apertado que o de Astrologia — título com caixa de 42px (não 96) e
   1.º rótulo aos 222px (148 + 42 + 32), separadores com 47/50 de
   respiro. Na Astrologia os valores base (273/40/44) é que batem. */
.pagina-curso-tarot-1 .curso-estrutura-painel--fluxo .curso-estrutura__painel-titulo,
.pagina-curso-tarot-2 .curso-estrutura-painel--fluxo .curso-estrutura__painel-titulo {
	min-height: 42px;
	margin-bottom: 32px;
}

.pagina-curso-tarot-1 .curso-estrutura-painel--fluxo .curso-estrutura__separador,
.pagina-curso-tarot-2 .curso-estrutura-painel--fluxo .curso-estrutura__separador {
	margin: 47px 0 50px -75px;
}

/* ------------------------------------------------------------
 * MOBILE (≤430px) — escala tipográfica e padrões da home
 * (instrução do Francisco: o desenho mobile só existe para a home;
 * as outras páginas adaptam-se ao estilo dela)
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* Escala da home: H1 44, H2 38, corpo 16/26 (no desktop o canvas
	   escala por zoom; aqui os tamanhos fixos de 1920 transbordavam —
	   H1 de 92px cortava "Astrologia" 60px fora do ecrã). */
	body:not(.pagina-home-final) .site-content h1 {
		font-size: 44px;
		line-height: 52px;
		white-space: normal;
	}

	body:not(.pagina-home-final) .site-content h2 {
		font-size: 38px;
		line-height: 46px;
		white-space: normal;
	}

	body:not(.pagina-home-final) .site-content h3 {
		font-size: 24px;
		line-height: 32px;
	}

	body:not(.pagina-home-final) .site-content p,
	body:not(.pagina-home-final) .site-content li,
	body:not(.pagina-home-final) .site-content blockquote p {
		font-size: 16px;
		line-height: 26px;
	}

	/* REVISÃO v5, R30 (PDF p.7) e R45 (PDF p.10) — título da página
	   centrado no telemóvel. O mock só desenhou, para estas páginas, um
	   hero de duas colunas no canvas de 1920: título em absoluto
	   encostado à goteira esquerda, parágrafo na coluna da direita. A
	   ≤430px o refluxo passa o título a bloco e ele fica colado aos 23px
	   (medido: «Quem Somos» 45,9px e «Terapias» 91,8px fora do centro).
	   As páginas que usam `.seccao-hero` — Contactos, Blog, FAQ — e todo
	   o desenho mobile da home já centram os títulos; alinho estas com
	   essa linguagem. Estendo às que o cliente não reportou mas têm o
	   mesmo defeito (/actividades/ −64,8px, /terapias/astrologia/
	   −46,7px, /terapias/tarot/ −87,7px), senão o site fica com três
	   alinhamentos de título diferentes em mobile.
	   Só mobile: em desktop o título É a coluna esquerda do hero, e
	   centrá-lo punha-o por cima do parágrafo da direita. */
	.qs-hero__titulo,
	h1.terapias-hero__titulo,
	.actividades-hero__titulo,
	.terapia-hero__titulo,
	.curso-hero__titulo {
		text-align: center;
	}

	/* O parágrafo de entrada acompanha o título, como na home, onde os
	   `__intro` são todos centrados no bloco @430px do main.css — um
	   título centrado sobre um parágrafo à esquerda lê-se pior do que
	   qualquer das duas opções puras. */
	.qs-hero__paragrafo,
	p.terapias-hero__paragrafo,
	.actividades-hero__paragrafo {
		text-align: center;
	}

	/* No print da p.10 o único título visível é o de cada consulta — o
	   h1 tinha ficado acima do enquadramento. Fica coerente com o hero.
	   Restrito à listagem: as mesmas classes servem a home, que tem
	   bloco próprio mais abaixo. */
	.pagina-lista-terapias .terapias-lista__titulo,
	.pagina-lista-terapias .terapias-lista__paragrafo {
		text-align: center;
	}

	/* Hero das terapias e cursos: cada par ícone+texto é um item, com
	   respiro entre itens (estavam colados numa linha corrida). */
	body:not(.pagina-home-final) .terapia-hero__meta,
	body:not(.pagina-home-final) .curso-hero__meta {
		display: flex;
		flex-direction: column;
		align-items: flex-start;
		gap: 12px;
		height: auto;
	}

	body:not(.pagina-home-final) .terapia-hero__meta-item,
	body:not(.pagina-home-final) .curso-hero__meta-item {
		display: flex;
		align-items: center;
		gap: 8px;
	}

	/* Loja: goteira da barra de portes e grelha em 2 colunas como a
	   secção de loja da home mobile. */
	body:not(.pagina-home-final) .loja-portes__texto {
		padding-left: 23px;
		padding-right: 23px;
		box-sizing: border-box;
	}

	body:not(.pagina-home-final) .loja-produtos__grelha {
		display: grid !important;
		/* minmax(0,1fr) e não 1fr: `1fr` é `minmax(auto, 1fr)` e a
		   largura mínima do conteúdo (nome + goteira) fazia a pista
		   crescer para além da sua quota — o cartão ia de 166 para 173. */
		grid-template-columns: repeat(2, minmax(0, 1fr));
		/* !important também no gap: o selector de reflow acrescenta
		   `.site-content` e vencia-o com `gap: 0`, deixando os cartões
		   encostados uns aos outros sem goteira nenhuma. */
		gap: 12px !important;
		align-items: start;
	}
	body:not(.pagina-home-final) .loja-ordenar,
	body:not(.pagina-home-final) .loja-ordenar button,
	body:not(.pagina-home-final) .loja-ordenar select {
		min-height: 44px;
	}

	/* Footer: o cabeçalho de cada acordeão ocupa a coluna toda para o
	   −/+ ficar encostado à direita (fazia shrink-wrap ao texto e o
	   ícone aterrava em cima das últimas letras). */
	.footer-coluna__titulo {
		position: relative;
		display: block;
		width: 100%;
	}

	/* Home mobile: a secção da loja mostra 2 produtos por vista, como
	   no desenho (o carrossel de 88% deixava 1 produto + uma nesga). */
	.home-loja__grelha.sda-carrossel-mobile {
		gap: 12px;
	}

	.home-loja__grelha.sda-carrossel-mobile > * {
		flex: 0 0 calc((100% - 12px) / 2);
	}
	/* Snap por página (dois cartões) e não por cartão: com o snap em
	   todos os filhos, um arrasto podia parar a meio, com meio produto
	   de cada página no ecrã e os dots sem corresponder a nada. */
	.home-loja__grelha.sda-carrossel-mobile > * {
		scroll-snap-align: none;
	}

	.home-loja__grelha.sda-carrossel-mobile > *:nth-child(odd) {
		scroll-snap-align: start;
	}

	/* R24 — a pista das actividades. O canvas mobile dava a caixa
	   (24, 373, 340x484) a um cartão só e escondia o do Tarot
	   (main.css:8169). A pista ocupa a largura toda com o mesmo recuo
	   lateral, e os dois cartões passam a caber lá dentro sem mudar de
	   sítio: o primeiro continua a abrir em x=24. */
	.pagina-home-final .home-actividades__pista {
		position: absolute;
		left: 0;
		top: 373px;
		width: 390px;
		height: 484px;
		display: flex;
		gap: 16px;
		padding: 0 24px;
		box-sizing: border-box;
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scroll-snap-type: x mandatory;
		scroll-padding-left: 24px;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
	}

	.pagina-home-final .home-actividades__pista::-webkit-scrollbar {
		display: none;
	}

	/* Desfaz o display:none do cartão do Tarot e tira os dois do
	   absoluto para entrarem na pista — os filhos de cada cartão
	   continuam a resolver contra ele, que se mantém posicionado. */
	.pagina-home-final .home-actividades-card--astrologia,
	.pagina-home-final .home-actividades-card--tarot {
		display: block;
		position: relative;
		left: auto;
		top: auto;
		flex: 0 0 340px;
		width: 340px;
		height: 484px;
		background: #ffffff;
		border-radius: 20px;
		scroll-snap-align: start;
	}

	/* Os dots das duas secções passaram de <span> a <button>: fora o
	   desenho nativo do browser. Um só reset serve os dois grupos. */
	button.home-loja__dot-mobile {
		position: relative;
		padding: 0;
		border: 0;
		-webkit-appearance: none;
		appearance: none;
		cursor: pointer;
	}

	button.home-loja__dot-mobile:focus-visible {
		outline: 2px solid var(--cor-primaria, #A787A3);
		outline-offset: 4px;
	}
}

/* "Como funciona" dos cursos: as alturas do mock (779/1104) eram
   calibradas ao texto do mockup — no conteúdo real deixavam a
   Metodologia do Tarot com ~470px de vazio (queixa do cliente) e
   CORTAVAM painéis maiores (overflow:hidden). Os itens abertos passam
   a abraçar o conteúdo. */
.curso-como-funciona-item.aberto,
.pagina-curso-tarot-1 .curso-como-funciona-item.aberto,
.pagina-curso-tarot-2 .curso-como-funciona-item.aberto {
	height: auto;
}

/* Mobile — afinações de colocação nas páginas de curso e terapia
   (print do Francisco: meta gigante, selo solto de 330px, timeline
   esparsa, títulos de acordeão com line-height do mock). */
@media (max-width: 430px) {
	/* Meta do hero: os valores são <span>, escapavam à escala dos <p>. */
	body:not(.pagina-home-final) .curso-hero__meta-texto,
	body:not(.pagina-home-final) .terapia-hero__meta-texto {
		font-size: 16px;
		line-height: 24px;
	}

	body:not(.pagina-home-final) .curso-hero__meta-icone,
	body:not(.pagina-home-final) .terapia-hero__meta-icone {
		width: 22px;
		height: 22px;
		flex: 0 0 auto;
	}

	/* Selo decorativo do hero: em fluxo ficava um bloco de 330px entre a
	   imagem e o resto — passa a 130px (escala do selo da home mobile)
	   sobreposto ao canto inferior-esquerdo da imagem. */
	body:not(.pagina-home-final) .curso-hero__simbolo-flor,
	body:not(.pagina-home-final) .terapia-hero__simbolo-flor {
		width: 130px !important;
		height: 130px !important;
		margin: -65px 0 0 23px;
	}

	/* Timeline dos anos: linha horizontal compacta com os pontos, em vez
	   da lista solta com ~100px entre itens. */
	body:not(.pagina-home-final) .site-content .curso-tabs-anos {
		height: auto;
		margin: 28px 0;
	}

	/* Report do Francisco, e R78 do PDF: «falta a linha a conectar os
	   pontos na timeline». A linha é um <span> vazio e, com o refluxo
	   global (position: static → display: inline, width/height: auto),
	   colapsa para 0x0 e não pinta um pixel. Passa a ser desenhada como
	   FUNDO da própria lista, à altura do centro dos pontos: o refluxo
	   mexe em caixa e posição, nunca em `background-*`, por isso o fundo
	   é imune e não precisa de `!important`. */
	body:not(.pagina-home-final) .site-content .curso-tabs-anos__lista {
		display: flex;
		flex-direction: row; /* um bloco anterior punha column */
		justify-content: space-between;
		gap: 8px;
		margin: 0;
		padding: 0;
		background-image: linear-gradient(var(--cor-primaria, #A787A3) 0 0);
		background-repeat: no-repeat;
		background-size: 100% 1.5px;
		background-position: 0 calc((18px - 1.5px) / 2); /* centro do ponto de 18px */
	}

	body:not(.pagina-home-final) .site-content .curso-tabs-anos__lista li {
		flex: 1;
	}

	body:not(.pagina-home-final) .site-content .curso-tabs-anos__tab {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 8px;
		/* `!important` medido: sem ele o refluxo esmagava a tab para
		   46,78px e os pontos ficavam desalinhados da linha. */
		width: 100% !important;
		height: auto;
	}

	/* !important: o selector do reflow global soma ~10 classes de
	   especificidade pelos :not() e esmaga larguras simples. */
	body:not(.pagina-home-final) .site-content .curso-tabs-anos__circulo {
		display: block;
		width: 18px !important;
		height: 18px !important;
		border-radius: 50%;
		background: var(--cor-rosa, #ECC6C0);
	}

	body:not(.pagina-home-final) .site-content .curso-tabs-anos__rotulo {
		width: auto;
		font-size: 15px;
		line-height: 22px;
		white-space: nowrap;
	}

	/* Tabs da "Estrutura do curso": barra compacta com quebra natural
	   (o mock espalha-as com line-height de 96px). */
	body:not(.pagina-home-final) .site-content .curso-estrutura nav {
		display: flex;
		flex-wrap: wrap;
		gap: 4px 20px;
		margin-bottom: 24px;
	}

	body:not(.pagina-home-final) .site-content .curso-estrutura-tab {
		width: auto;
		height: auto;
		font-size: 15px;
		line-height: 30px;
		white-space: nowrap;
	}

	/* REVISÃO v5, R82 (PDF p.17) — «na tab colocar apenas uma linha no
	   item seleccionado». Havia aqui um `text-decoration: underline` de
	   3px que pintava a 26–28px do topo da tab, e o `::after` do mock —
	   reancorado para mobile mais abaixo, no bloco «Sublinhado do
	   separador da estrutura do curso» — pinta a 35–37px. Eram duas
	   barras rosa com 6px de fundo entre elas, sondado a píxeis.
	   Fica o `::after`: é o indicador do desenho, é o mesmo que pinta em
	   desktop, e cobre a largura da tab. O sublinhado tipográfico sai. */

	/* Títulos dos acordeões: o mock centra glifos com line-height 96px —
	   em mobile parte em 4 linhas com vazios enormes. */
	/* REVISÃO v5, R52 (PDF p.12) — o terceiro selector estava aqui desde
	   o início e NUNCA chegou a pintar. `.terapia-como-funciona__item-titulo`
	   é um <h3>, e (0,2,1) perde para a escala genérica
	   `body:not(.pagina-home-final) .site-content h3 { font-size: 24px }`,
	   que vale (0,2,2). Resultado medido: os subtítulos da Consulta
	   («PRIMEIRA CONSULTA», «SEGUNDA CONSULTA E SEGUINTES») ficavam a
	   24px — 2px MAIORES do que os mesmos subtítulos em desktop (22px) e
	   1,5x o corpo de texto. Eram o único elemento destas páginas que
	   CRESCIA de desktop para mobile.
	   Qualifico com `.site-content h3` para chegar a (0,3,2) e o número
	   que já cá estava passar a valer. Os outros dois selectores do grupo
	   são <span> e já pintavam a 18/26 — este alinha-se com eles em vez
	   de inventar um terceiro tamanho para o mesmo papel.
	   O cliente escreveu «2pt deve ser suficiente, ou 4pt no máximo»,
	   partindo dos 24px: dá 22 ou, no limite, 20. Eu tinha ficado nos 18
	   do resto do site, que é 2px abaixo do que ele autorizou — e
	   deixava o subtítulo 4px MENOR em telemóvel do que em computador,
	   com um rácio de 1,125 sobre o corpo de texto (em desktop é 22/22).
	   O Francisco decidiu 20. É o limite do pedido e devolve-lhe a
	   leitura de cabeçalho: 4px acima do corpo, contra 2. */
	body:not(.pagina-home-final) .curso-como-funciona-item-titulo,
	body:not(.pagina-home-final) .accordion-faq-rotulo,
	body:not(.pagina-home-final) .site-content h3.terapia-como-funciona__item-titulo {
		font-size: 20px;
		line-height: 28px;
		white-space: normal;
	}
}

/* ------------------------------------------------------------
 * MOBILE — ritmo vertical (detector de elementos encostados)
 * O mock posicionava tudo em absoluto, por isso os elementos nunca
 * tiveram margens verticais; no reflow ficavam colados uns aos outros.
 * Regras por grupo, derivadas do varrimento de 17 páginas a 390px.
 * Os selos sobre as fotos (Leonardo, hero) ficam de fora — a
 * sobreposição é do desenho.
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* Heroes: faixa de meta com respiro, intro e CTA com folga da imagem. */
	body:not(.pagina-home-final) .site-content .terapia-hero__meta,
	body:not(.pagina-home-final) .site-content .curso-hero__meta {
		margin: 20px 0;
		padding: 4px 0;
	}

	body:not(.pagina-home-final) .site-content .terapia-hero__paragrafo,
	body:not(.pagina-home-final) .site-content .curso-hero__paragrafo {
		margin: 0 0 24px;
	}

	/* REVISÃO v5, R73 (PDF p.15) — o ponto decorativo de 8px do hero. No
	   mock vive em absoluto a meio da coluna esquerda; no refluxo cai
	   para o fluxo como <img> inline a seguir ao botão, gera uma caixa de
	   linha de 18px e aterra sozinho na goteira, a 4px do topo da
	   fotografia — lê-se como sujidade sobre a foto, não como decoração.
	   Dos 58px entre o botão e a imagem, 18 eram esta caixa de linha.
	   Sem lugar no desenho mobile, sai do fluxo; é decorativo (alt=""),
	   não há perda de conteúdo. */
	body:not(.pagina-home-final) .site-content .curso-hero__simbolo-pequeno,
	body:not(.pagina-home-final) .site-content .terapia-hero__simbolo-pequeno {
		display: none;
	}

	/* REVISÃO v5, R73 — folga entre o botão do hero e a imagem que se lhe
	   segue. O desenho não tem resposta: a 1920 o botão e a imagem são
	   duas colunas lado a lado e o empilhamento é do refluxo. Vou à única
	   fonte mobile que existe, o bloco @430 do mock na home, onde o mesmo
	   padrão mede 50 (VER LOJA → grelha) e 60 (DESCOBRIR → cartões).
	   Tinha fixado 60 para o manter abaixo dos 67 que separam SECÇÕES,
	   com o argumento de que uma folga DENTRO da mesma secção não pode
	   valer o mesmo que uma fronteira ENTRE secções. Ao re-medir, o
	   argumento não sobrevive ao pedido: o que lá estava eram 58, e 60 é
	   um aumento de 2px que ninguém vê. O que melhorou de facto foi
	   outra coisa — o ponto decorativo de 8px que aterrava a meio do vão
	   desapareceu —, mas a distância que o cliente aponta ficou na
	   prática igual. Entre a minha inferência a partir de um padrão
	   análogo e um pedido explícito dele, ganha o pedido: 67, que é o
	   ritmo de referência do projecto e um aumento que se lê.
	   O `28px` que aqui estava nunca chegou a pintar — o bloco genérico
	   dos botões impõe `margin-bottom: 40px !important`. Para o vencer é
	   preciso `!important` também; esta regra tem (0,4,1) contra (0,3,1),
	   por isso ganha. */
	/* O ponto R73 fala de «Página do Curso/Actividade»: a actividade
	   entra aqui pela mesma razão e com o mesmo valor. Lá o CTA nem era um
	   botão — vinha do vocabulário órfão `sda-btn` e saía um link azul do
	   browser —, e a folga até à imagem media 0,00px nas quatro larguras. */
	body:not(.pagina-home-final) .site-content .terapia-hero__conteudo .botao-principal,
	body:not(.pagina-home-final) .site-content .curso-hero__conteudo .botao-principal,
	body:not(.pagina-home-final) .site-content .sda-atividade-hero__content .sda-atividade-hero__cta {
		margin-top: 4px;
		margin-bottom: 67px !important;
	}

	/* Imagens de secção soltas em flow: folga antes do texto seguinte. */
	body:not(.pagina-home-final) .site-content .terapia-sobre-consulta__petala,
	body:not(.pagina-home-final) .site-content .terapia-sobre-astrologia__imagem,
	body:not(.pagina-home-final) .site-content .curso-sobre__imagem,
	body:not(.pagina-home-final) .site-content .curso-panorama__imagem,
	body:not(.pagina-home-final) .site-content .qs-historia__imagem,
	body:not(.pagina-home-final) .site-content .qs-palestra__foto,
	body:not(.pagina-home-final) .site-content .terapias-lista__foto,
	body:not(.pagina-home-final) .site-content .artigo-conteudo__capa,
	body:not(.pagina-home-final) .site-content .seccao-sidebar__banner-imagem,
	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-foto {
		margin-bottom: 20px;
	}

	/* Testemunhos: interior do card com respiro. */
	body:not(.pagina-home-final) .site-content .seccao-testemunhos__foto,
	body:not(.pagina-home-final) .site-content .seccao-testemunhos__estrelas {
		margin-bottom: 12px;
	}

	/* Citação: assinatura desencostada do bloco. */
	body:not(.pagina-home-final) .site-content .terapia-citacao__assinatura {
		margin-top: 16px;
		/* REVISÃO v5, R60 (PDF p.14): o 24px/96 do mock é a caixa vertical
		   de 1920, onde a assinatura é a única linha de uma faixa de 96.
		   A ≤430px sobravam quase 40px de banda vazia acima e abaixo da
		   tinta, e a assinatura ficava MAIOR do que a própria citação —
		   a mesma armadilha do R38: a citação é um <p> dentro de
		   <blockquote> e apanha duas regras da escala genérica mobile; a
		   assinatura é um <figcaption> e escapa-lhes. */
		font-size: 16px;
		line-height: 26px;
	}

	/* Loja: blocos da listagem separados; itens do filtro com folga. */
	body:not(.pagina-home-final) .site-content .loja-produtos__resultados {
		margin: 20px 0 12px;
	}

	body:not(.pagina-home-final) .site-content .loja-produtos__ordenar-form {
		margin-bottom: 20px;
	}

	body:not(.pagina-home-final) .site-content .loja-paginacao {
		margin-top: 28px;
	}

	body:not(.pagina-home-final) .site-content .loja-filtro__lista li + li {
		margin-top: 8px;
	}

	/* Cards de artigo (blog, Obrigado): categoria, ler mais e meta. */
	body:not(.pagina-home-final) .site-content .seccao-artigos-card-categoria {
		display: inline-block;
		margin-bottom: 10px;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-card-meta {
		margin-top: 10px;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-paginacao {
		margin: 24px 0 40px;
	}

	/* Sidebar do blog: blocos empilhados com separação clara. */
	body:not(.pagina-home-final) .site-content .seccao-sidebar > * + * {
		margin-top: 36px;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__recente + .seccao-sidebar__recente {
		margin-top: 20px;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__recente-miniatura {
		margin-bottom: 8px;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__recente-ler-mais {
		margin-top: 6px;
	}

	/* Artigo: cabeçalho. */
	body:not(.pagina-home-final) .site-content .artigo-cabecalho__categoria {
		display: inline-block;
		margin-bottom: 10px;
	}

	body:not(.pagina-home-final) .site-content .artigo-cabecalho__avatar {
		margin-bottom: 8px;
	}

	/* FAQ / Legal: menu lateral separado do conteúdo; itens do acordeão. */
	body:not(.pagina-home-final) .site-content .menu-lateral {
		margin-bottom: 28px;
	}

	body:not(.pagina-home-final) .site-content .accordion-faq-item + .accordion-faq-item {
		margin-top: 12px;
	}

	/* Contactos: ícone com folga do texto. */
	body:not(.pagina-home-final) .site-content .seccao-onde-estamos__icone {
		margin-bottom: 8px;
	}

	/* Actividades: excerto desencostado da meta. */
	body:not(.pagina-home-final) .site-content .card-actividade__excerto {
		margin-top: 12px;
	}

	/* Quem Somos. */
	body:not(.pagina-home-final) .site-content .categoria-card__rotulo {
		margin-top: 8px;
	}

	body:not(.pagina-home-final) .site-content .qs-palestra__data-formato {
		margin-bottom: 16px;
	}

	/* Honeypots: o reflow punha em fluxo o que estava escondido fora do
	   ecrã — um humano podia preenchê-lo e o comentário era engolido. */
	body:not(.pagina-home-final) .site-content .sda-form__honeypot,
	body:not(.pagina-home-final) .site-content .seccao-formulario__hp,
	body:not(.pagina-home-final) .site-content [class*="honeypot"] {
		display: none !important;
	}

	/* Cursos: respiro entre a estrutura e o panorama. */
	body:not(.pagina-home-final) .site-content .curso-panorama {
		margin-top: 36px;
	}

	/* Sidebar do blog: botão da palestra desencostado da data. */
	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-data-formato {
		margin-bottom: 16px;
	}

	/* Artigo: bloco tags/recomendar/partilhar/seguinte com ritmo. */
	body:not(.pagina-home-final) .site-content .artigo-tags-partilha__recomendar,
	body:not(.pagina-home-final) .site-content .artigo-tags-partilha__partilhar,
	body:not(.pagina-home-final) .site-content .artigo-tags-partilha__seguinte {
		margin-top: 20px;
	}

	body:not(.pagina-home-final) .site-content .artigo-tags-partilha__seguinte-titulo {
		margin-top: 8px;
	}
}

/* ------------------------------------------------------------
 * E2E FUNCIONAL — correcções de usabilidade
 * ------------------------------------------------------------ */

/* Steppers de quantidade: o mock desenha-os com 12x12 (glifos em ::before
   /::after) — alvo de toque minúsculo em desktop e ZERO em mobile, onde o
   reflow lhes tira as dimensões. Passam a ter área real sem mexer no
   desenho: o traço/cruz continua a ser o pseudo-elemento centrado. */
.produto-card__qtd-menos,
.produto-card__qtd-mais,
.produto-ficha__qtd-menos,
.produto-ficha__qtd-mais,
.carrinho-linha__qtd-menos,
.carrinho-linha__qtd-mais {
	box-sizing: content-box;
	padding: 12px;
	margin: -12px;
}

@media (max-width: 430px) {
	/* Controlos primários do header com alvo de toque decente (o
	   hamburger tinha 22x14). Os ícones do header são absolutos com
	   width/height do mock — o padding não cresce a caixa, por isso a
	   área vem de um pseudo-elemento expandido. */
	/* 32 de largura (medi os centros a 288,5, 323 e 361 de canvas — 34,5
	   de intervalo é o máximo que não rouba toques ao vizinho) por 48 de
	   altura, que é livre. Os 44 anteriores eram de CANVAS: a 360px valiam
	   40,6 reais. Com 48 de canvas dão 44,3 reais a 360. */
	.header-hamburger::after,
	.header-icone::after {
		content: "";
		position: absolute;
		left: 50%;
		top: 50%;
		width: 32px;
		height: 48px;
		transform: translate(-50%, -50%);
	}

	/* O carrinho é o único ícone do header que não É o elemento clicável:
	   é um <span> com um <a> lá dentro. O alvo de toque acima, sendo
	   pseudo-elemento do <span>, ficava POR CIMA do <a> e apanhava o
	   toque em vez dele — medido com `elementsFromPoint` e com toque a
	   sério: no telemóvel tocar no ícone não abria `/carrinho/`, só
	   accionava o `:hover` pegajoso que revela o painel. Em desktop
	   funcionava porque aí este pseudo-elemento não existe.
	   O alvo passa para o <a>, que é quem tem de o ter. */
	.header-icone--carrinho::after {
		content: none;
	}

	.header-carrinho-wrap > [data-sda-mini-cart-toggle] {
		display: block;
		position: relative;
	}

	.header-carrinho-wrap > [data-sda-mini-cart-toggle]::after {
		content: "";
		position: absolute;
		left: 50%;
		top: 50%;
		width: 32px;
		height: 48px;
		transform: translate(-50%, -50%);
	}

	.header-hamburger,
	.header-icone {
		overflow: visible;
	}

	/* Barra de pesquisa: no mobile usava as coordenadas do canvas de 1920
	   e ficava meia fora do ecrã, com o X inalcançável. */
	/* REVISÃO v5, R118 (PDF p.26) — «retirar a margem entre a barra e o
	   campo de pesquisa». Não é margem: o desenho põe o painel a
	   `top: 100px` porque a barra do canvas de 1920 mede 100px de altura.
	   Em mobile a barra mede 64, e os 36px de diferença aparecem como um
	   rasgo por onde se vê a página. O painel passa a assentar na barra.
	   Vale para 360, 390 e 430 — a barra mede 64 de canvas nas três. */
	.header-pesquisa {
		left: 0 !important;
		top: 64px;
		width: 100% !important;
		box-sizing: border-box;
		padding: 0 23px;
	}

	.header-pesquisa__campo,
	.header-pesquisa form {
		left: auto !important;
		width: 100% !important;
		max-width: calc(100% - 60px);
	}

	.header-pesquisa__fechar {
		left: auto !important;
		right: 16px !important;
	}

	/* REVISÃO v5, R120 (PDF p.27) — «retirar a margem entre a barra de menu
	   e o dropdown» — e R121 — «centrar o módulo».
	   A mesma causa do R118: o painel do mini-carrinho está a `top: 56px`
	   a contar do ícone (que está a `top: 24`), o que dá 80 — 16px abaixo
	   dos 64 da barra. E o `left: -335px` colocava-o a começar em -23, ou
	   seja 23px fora do ecrã à esquerda e 23px de folga à direita.
	   O painel mede 363 e o ecrã 390: para ficar centrado tem de começar
	   em (390 - 363) / 2 = 13,5. Como o `left` conta a partir do ícone,
	   que está em x = 312, fica 13,5 − 312 = −298,5.
	   Uma regra só para as duas correcções: são a mesma caixa. */
	.header-carrinho-painel {
		left: -298.5px;
		top: 40px;
	}

	/* A "ponte" invisível sobre o vão entre o ícone e o painel deixa de
	   ter vão para cobrir — e, encostada como fica, passaria a tapar 40px
	   da barra de menu, engolindo os toques nos ícones do header enquanto
	   o painel está aberto. */
	.header-carrinho-painel::before {
		display: none;
	}
}

/* Skip link (WCAG 2.4.1): fora do ecrã até receber foco. */
.sda-skip-link {
	position: absolute;
	left: -9999px;
	top: 0;
	z-index: 2000;
	padding: 12px 20px;
	background: var(--cor-primaria, #A787A3);
	border-radius: 0 0 12px 0;
	font: 600 16px/1 var(--fonte-corpo, sans-serif);
	color: #ffffff;
	text-decoration: none;
}

.sda-skip-link:focus {
	left: 0;
}

/* Recomendar artigo activo. */
.artigo-tags-partilha__recomendar--ativo img {
	filter: brightness(0) saturate(100%) invert(58%) sepia(9%) saturate(1042%) hue-rotate(255deg) brightness(94%) contrast(87%);
}

/* Sidebar do blog: a miniatura agora é link — sem sublinhado nem cor. */
.seccao-sidebar__recente-link {
	display: block;
	text-decoration: none;
}

/* ------------------------------------------------------------
 * ANIMAÇÕES RECUPERADAS DO TEMA PRÉ-MIGRAÇÃO (git 2b62d18)
 * A migração pixel-perfect trouxe o markup novo e deixou-as para
 * trás. Portadas para os selectores actuais.
 * ------------------------------------------------------------ */

/* Cards das 3 categorias: sobem, ganham sombra e revelam a seta.
   (Antes: .sda-blocks__item:hover + .sda-blocks__arrow, sections.css:283.) */
.categoria-card {
	transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.categoria-card:hover,
.categoria-card:focus-visible {
	transform: translateY(-4px);
	box-shadow: 0 18px 40px rgba(72, 56, 70, 0.16);
}

.categoria-card__seta {
	position: absolute;
	left: 50%;
	bottom: 26px;
	width: 26px;
	height: 14px;
	opacity: 0;
	/* O asset é branco (feito para fundo escuro) — recolorido para a
	   primária, que é a cor do rótulo do card. */
	filter: brightness(0) saturate(100%) invert(60%) sepia(11%) saturate(872%) hue-rotate(255deg) brightness(93%) contrast(88%);
	transform: translateX(-50%) translateX(-8px);
	transition: opacity 0.25s ease, transform 0.25s ease;
}

.categoria-card:hover .categoria-card__seta,
.categoria-card:focus-visible .categoria-card__seta {
	opacity: 1;
	transform: translateX(-50%) translateX(0);
}

/* Sem hover (touch): a seta fica visível — era o comportamento antigo. */
@media (hover: none) {
	.categoria-card__seta {
		opacity: 1;
		transform: translateX(-50%);
	}
}

/* As imagens com parallax precisam de compositor próprio. */
.home-boas-vindas__imagem--flores,
.home-boas-vindas__imagem--dente-leao,
.seccao-newsletter__foto--flor,
.seccao-newsletter__foto--sol,
.qs-historia__imagem--mao,
.qs-historia__imagem--por-do-sol {
	will-change: transform;
}

@media (prefers-reduced-motion: reduce) {
	.categoria-card,
	.categoria-card__seta {
		transition: none;
	}
}

/* ------------------------------------------------------------
 * IMAGENS DO CLIENTE (design/imagens-20-08)
 * As fotos passaram de PNG a JPEG (69,5 MB → 9,4 MB no conjunto).
 * Os seis fundos abaixo são declarados no main.css, que fica 1:1
 * com o tema espelho — por isso re-apontam-se aqui, na camada do
 * tema, em vez de se editar a folha espelhada.
 * ------------------------------------------------------------ */

.seccao-testemunhos--home {
	background-image: url("../img/site/home-testemunhos-fundo.jpg");
}

.seccao-testemunhos--terapia {
	background-image: url("../img/terapia/testemunhos-fundo.jpg");
}

.seccao-testemunhos--curso {
	background-image: url("../img/cursos/curso-testemunhos-fundo.jpg");
}

.curso-como-funciona {
	background-image: url("../img/cursos/curso-accordion-fundo.jpg");
}

.pagina-curso-tarot-1 .curso-como-funciona,
.pagina-curso-tarot-2 .curso-como-funciona {
	background-image: url("../img/cursos/curso-tarot-1-accordion-fundo.jpg");
}

@media (max-width: 430px) {
	.seccao-testemunhos--home {
		background-image: url("../img/site/hm-testemunhos-fundo.jpg");
	}
}

/* Formulário de inscrição — o mock desenha o campo "Curso" como <input>
   readonly, por isso o main.css não tem uma única regra para <select>. Ao
   trocá-lo por um selector real (fase 68, para deixar de inscrever toda a
   gente no primeiro curso) o controlo ficou com o desenho nativo do
   browser. Passa a ser igual aos campos irmãos (linha 1026 do main.css),
   com o chevron que o appearance:none remove. */
.seccao-formulario__campo select {
	display: block;
	width: 100%;
	height: 46px;
	margin-top: -8px;
	padding: 0 28px 0 0;
	appearance: none;
	background: url("../img/loja/select-chevron.svg") no-repeat right 2px center;
	background-size: 14px 7px;
	border: none;
	border-bottom: 1px solid var(--cor-texto-suave, #707070);
	border-radius: 0;
	box-sizing: content-box;
	font: 500 18px/26px var(--fonte-corpo, sans-serif);
	letter-spacing: 0;
	text-transform: uppercase;
	color: var(--cor-primaria, #A787A3);
	cursor: pointer;
}

.seccao-formulario__campo select:focus {
	outline: none;
	border-bottom-color: var(--cor-primaria, #A787A3);
}

/* A opção vazia faz de placeholder: mesmo tom dos placeholders irmãos. */
.seccao-formulario__campo select:invalid {
	color: var(--cor-titulos-tom, #8E9193);
}

.seccao-formulario__campo select option {
	text-transform: none;
	color: var(--cor-texto, #696969);
}

/* Formulário de comentários — o consentimento é injectado por
   inc/setup.php:298 com a classe sda-form__consent, do tema pré-migração,
   que ficou sem CSS no Batch 1: rendia a caixa nativa do browser a 11x11px.
   Alinha com o optin dos restantes formulários (main.css:1087), mas com
   borda, porque aqui o fundo é claro e a caixa branca desapareceria. O
   <label> envolve input e texto, por isso a área de toque é a linha toda. */
.sda-form__consent {
	display: flex;
	align-items: center;
	gap: 12px;
	min-height: 24px;
	margin: 16px 0 24px;
	font: 400 16px/24px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
	cursor: pointer;
}

.sda-form__consent input[type="checkbox"] {
	flex: 0 0 auto;
	appearance: none;
	width: 20px;
	height: 20px;
	margin: 0;
	background: #ffffff;
	border: 1px solid var(--cor-texto-suave, #707070);
	border-radius: 5px;
	cursor: pointer;
}

.sda-form__consent input[type="checkbox"]:checked {
	background: var(--cor-primaria, #A787A3);
	border-color: var(--cor-primaria, #A787A3);
}

.sda-form__consent input[type="checkbox"]:focus-visible {
	outline: 2px solid var(--cor-primaria, #A787A3);
	outline-offset: 2px;
}

.sda-form__consent a {
	color: var(--cor-primaria, #A787A3);
}

/* ------------------------------------------------------------
 * LOTE DOS ACHADOS MÉDIOS DA CAMPANHA E2E (fase 71)
 * ------------------------------------------------------------ */

/* Loja sem resultados: a grelha é flex, por isso o aviso ocupa a linha toda. */
.loja-produtos__vazio {
	flex: 1 0 100%;
	padding: 40px 0 0;
	text-align: center;
	list-style: none;
}

.loja-produtos__vazio-texto {
	margin: 0 0 28px;
	font: 400 22px/36px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

.loja-produtos__vazio-accao {
	display: inline-flex;
}

/* Produto esgotado: o card só perdia o ícone do carrinho, o que não se lê
   como "esgotado". Selo sobre a imagem, no canto oposto ao coração, mais
   a imagem esbatida. Fundo escuro da paleta porque o branco sobre o cinza
   médio não passa contraste AA. */
/* Alinhado com o selo que o mock já define para a ficha
   (`.produto-ficha__esgotado`, main.css:4771): salmão #ffa2a3, texto branco,
   cantos de 8. Eu tinha-lhe posto cinzento-escuro por minha conta, antes de
   reparar que o desenho já tinha cor própria para este estado. */
.produto-card__esgotado {
	position: absolute;
	left: 22px;
	top: 22px;
	z-index: 2;
	padding: 4px 14px;
	background: #ffa2a3;
	border-radius: 8px;
	font: 500 14px/24px var(--fonte-corpo, sans-serif);
	text-transform: uppercase;
	color: #ffffff;
}

.produto-card--esgotado .produto-card__imagem {
	opacity: 0.55;
}

.produto-card--esgotado .produto-card__preco {
	color: var(--cor-texto-suave, #707070);
}

/* Estrelas das avaliações. O CSS do WooCommerce está desactivado
   (woocommerce_enqueue_styles → array vazio), por isso o .star-rating ficava
   sem desenho nenhum e mostrava o texto de fallback do WC — "out of 5", em
   inglês. Desenhadas aqui com a técnica clássica das duas camadas: o fundo
   com as 5 estrelas vazias e, por cima, as cheias recortadas pela largura
   percentual que o WC põe inline no <span>. O texto fica empurrado para fora
   e escondido pelo overflow. */
.star-rating {
	position: relative;
	display: inline-block;
	overflow: hidden;
	width: 5.6em;
	height: 1.2em;
	font: 400 16px/1.2 var(--fonte-corpo, sans-serif);
	letter-spacing: 0.08em;
}

.star-rating::before {
	content: "\2605\2605\2605\2605\2605";
	position: absolute;
	left: 0;
	top: 0;
	color: var(--cor-cinza-claro, #d6d7d9);
}

.star-rating span {
	position: absolute;
	left: 0;
	top: 0;
	height: 0;
	padding-top: 1.2em; /* empurra o "out of 5" para fora da caixa */
	overflow: hidden;
}

.star-rating span::before {
	content: "\2605\2605\2605\2605\2605";
	position: absolute;
	left: 0;
	top: 0;
	color: var(--cor-primaria, #A787A3);
}

/* Selector de classificação do formulário de avaliação. O WC rende
   <a>1 of 5 stars</a> … e conta com o CSS dele para os transformar em
   estrelas e esconder o texto — como esse CSS está desactivado, apareciam
   cinco links em inglês. O texto vai para fora com text-indent e a estrela
   entra pelo ::before. As classes .selected/.active são postas pelo JS do
   WC (add-to-cart/single-product). */
.comment-form-rating p.stars {
	margin: 0 0 20px;
	line-height: 1;
}

.comment-form-rating p.stars a {
	position: relative;
	display: inline-block;
	width: 1.5em;
	height: 1.5em;
	margin: 0;
	overflow: hidden;
	text-indent: -999em;
	text-decoration: none;
	font-size: 22px;
}

.comment-form-rating p.stars a::before {
	content: "\2605";
	position: absolute;
	left: 0;
	top: 0;
	width: 1.5em;
	text-indent: 0;
	text-align: center;
	font-family: var(--fonte-corpo, sans-serif);
	color: var(--cor-cinza-claro, #d6d7d9);
	transition: color 0.15s ease;
}

/* Escolhido: cheias até à activa, vazias depois dela. */
.comment-form-rating p.stars.selected a::before {
	color: var(--cor-primaria, #A787A3);
}

.comment-form-rating p.stars.selected a.active ~ a::before {
	color: var(--cor-cinza-claro, #d6d7d9);
}

/* Hover ganha ao escolhido, para a pré-visualização funcionar. */
.comment-form-rating p.stars:hover a::before {
	color: var(--cor-rosa, #ecc6c0);
}

.comment-form-rating p.stars a:hover ~ a::before {
	color: var(--cor-cinza-claro, #d6d7d9);
}

.comment-form-rating p.stars a:focus-visible {
	outline: 2px solid var(--cor-primaria, #A787A3);
	outline-offset: 2px;
	text-indent: -999em;
}

/* Dentro das avaliações, a regra genérica `.woocommerce-Reviews label`
   (display:block + maiúsculas, feita para os rótulos NOME/EMAIL) apanhava
   também o consentimento e colava a caixa ao texto. Especificidade 0,2,0
   para repor o layout do optin sem tocar na regra genérica. */
.woocommerce-Reviews .sda-form__consent {
	display: flex;
	align-items: center;
	gap: 12px;
	margin: 16px 0 24px;
	font: 400 16px/24px var(--fonte-corpo, sans-serif);
	text-transform: none;
	color: var(--cor-texto, #696969);
}

/* Miniaturas da galeria: passaram a ser interactivas, por isso precisam de
   se ler como tal. O mock posiciona-as em absoluto, daí o role/tabindex no
   próprio <img> em vez de um <button> à volta. */
.produto-ficha__miniatura {
	cursor: pointer;
	transition: opacity 0.2s ease, outline-color 0.2s ease;
	outline: 2px solid transparent;
	outline-offset: 3px;
}

.produto-ficha__miniatura:hover {
	opacity: 0.85;
}

.produto-ficha__miniatura--activa {
	outline-color: var(--cor-primaria, #a787a3);
}

.produto-ficha__miniatura:focus-visible {
	outline-color: var(--cor-primaria, #a787a3);
}

/* Cartão de login em fluxo (confirmação de encomenda aberta sem sessão).
   O .login-card do mock é absoluto a top:241px, feito para a página de
   login inteira; os seus campos e botão são absolutos com top fixo, por
   isso o cartão TEM de manter os 583x560 — aqui só se lhe tira o
   posicionamento de página para ele entrar no meio do conteúdo. */
.login-card--inline {
	position: relative;
	left: auto;
	top: auto;
	transform: none;
	margin: 56px auto 96px;
}

/* O título do cartão só está desenhado como h1 no mock (h1.login-card__titulo);
   aqui é h2, para não competir com o h1 da página onde o formulário aparecer. */
h2.login-card__titulo {
	position: absolute;
	left: 0;
	top: 79px;
	width: 100%;
	margin: 0;
	font: 400 32px/42px var(--fonte-titulos, serif);
	text-align: center;
	color: var(--cor-primaria, #a787a3);
}

/* Confirmação aberta sem sessão: o WC imprime os avisos fora de qualquer
   contentor, encostados a x=0. Trazem-se para a largura do site. */
.woocommerce-order-received .woocommerce-notice,
.woocommerce-order-received .woocommerce-info,
.woocommerce-order-received .woocommerce-error {
	box-sizing: border-box;
	width: 1400px;
	max-width: calc(100% - 48px);
	margin: 0 auto 16px;
	padding-top: 56px;
	font: 400 22px/34px var(--fonte-corpo, sans-serif);
	text-align: center;
	color: var(--cor-texto, #696969);
}

.woocommerce-order-received .woocommerce-info + .woocommerce-notice,
.woocommerce-order-received .woocommerce-notice + .woocommerce-info {
	padding-top: 0;
}

/* Passo intermédio antes do scroll interno: aperta-se o ar entre as linhas
   em vez de esconder o fim da coluna. Aplicado pelo main.js só quando a
   coluna não cabe, e nunca em ecrãs com altura de sobra. Não corta
   informação nenhuma — só espaçamento. */
.curso-sidebar.sda-sb-compacta {
	--sda-sb-linha: 5px;
	--sda-sb-bloco: 10px;
}

.curso-sidebar.sda-sb-compacta .curso-sidebar__botao {
	margin-top: 14px;
}

/* Recurso da coluna do curso: quando nem assentada logo abaixo do header
   ela cabe, o resto alcança-se por scroll dentro da própria coluna. A
   altura vem do main.js em px do canvas — `vh` não acompanha o zoom da
   raiz e daria uma medida maior que o ecrã. */
.curso-sidebar.sda-sb-scroll {
	max-height: var(--sda-sb-max, none);
	overflow-y: auto;
	overscroll-behavior: contain;
}

/* Anel de foco do select da inscrição. O `appearance: none` levou-lhe o
   anel nativo e o `:focus { outline: none }` que copiei dos campos irmãos
   selou o problema — os inputs mudam a linha de baixo, que num select com
   chevron não chega para se ver o foco pelo teclado. */
.seccao-formulario__campo select:focus-visible {
	outline: 2px solid var(--cor-primaria, #a787a3);
	outline-offset: 3px;
	border-bottom-color: var(--cor-primaria, #a787a3);
}

/* !important: o selector de reflow do mobile soma ~10 classes e anula
   width/height de tudo o que esteja dentro do .site-content. Sem isto a
   caixa do consentimento ficava a 2x2px no telemóvel — a correcção só
   funcionava em desktop. */
@media (max-width: 430px) {
	.sda-form__consent input[type="checkbox"] {
		width: 20px !important;
		height: 20px !important;
		min-width: 20px !important;
		min-height: 20px !important;
		flex: 0 0 20px !important;
	}
}

/* ------------------------------------------------------------
 * MOBILE: o que eu acrescentei em `position: absolute` e o reflow anula.
 *
 * O selector de reflow (~10 classes) põe `position: static` em tudo o que
 * esteja dentro do .site-content. Quem depende de posicionamento absoluto
 * — selos sobre imagens, estrelas desenhadas em duas camadas — parte a
 * ≤430px enquanto continua bem em desktop. Daí o !important, que é a
 * excepção documentada do projecto para vencer o reflow.
 * ------------------------------------------------------------ */
@media (max-width: 430px) {

	/* Estrelas (display e formulário de avaliação): sem o contentor
	   posicionado, o ★ do ::before ancorava no VIEWPORT e ia parar ao topo
	   da página, deixando a classificação por desenhar. */
	.star-rating,
	.comment-form-rating p.stars a {
		position: relative !important;
	}

	.star-rating {
		display: inline-block !important;
		width: 5.6em !important;
		height: 1.2em !important;
		overflow: hidden !important;
	}

	.star-rating span,
	.star-rating::before,
	.star-rating span::before,
	.comment-form-rating p.stars a::before {
		position: absolute !important;
		left: 0 !important;
		top: 0 !important;
	}

	.comment-form-rating p.stars a {
		display: inline-block !important;
		width: 1.5em !important;
		height: 1.5em !important;
		overflow: hidden !important;
	}}

/* Steppers em mobile: os botões já tinham área de toque, mas o reflow
   tirava-lhes o `position`, e os traços do − e do + (pseudo-elementos
   absolutos, 12x2 e 2x12) passavam a resolver contra o VIEWPORT — os
   glifos desapareciam do botão e ia-se parar ao topo da página. Sem
   sinais de − e +, só se conseguia comprar 1 unidade. */
@media (max-width: 430px) {
	/* Centrar os traços dentro do botão de 20x20 (no mock o botão tem 12x12
	   e o pseudo-elemento assenta em 0/5). */
	body:not(.pagina-home-final) .site-content [class$="__qtd-menos"]::before,
	body:not(.pagina-home-final) .site-content [class$="__qtd-mais"]::before,
	body:not(.pagina-home-final) .site-content [class$="__qtd-mais"]::after {
		left: 50% !important;
		top: 50% !important;
		translate: -50% -50% !important;
	}
}

/* Cartões em mobile: a altura tem de vir do conteúdo.
   A regra que os põe a 100% de largura mantinha a altura fixa do mock
   (421px nos artigos, 476px nos produtos) com `overflow: hidden`. Numa
   coluna estreita o conteúdo cresce e era simplesmente cortado: medidos
   128–216px perdidos por cartão no arquivo do blog — título partido a
   meio, excerto e "Ler mais" invisíveis — e buracos de 144–181px na
   grelha da loja. Os cartões estão fora do reflow (para servirem de
   contexto de posicionamento), mas os filhos deles não, por isso já
   estão em fluxo e a altura automática assenta no conteúdo real. */
@media (max-width: 430px) {}

/* Recuperar palavra-passe (dois passos). Cartão em fluxo — o .login-card
   do mock tem os filhos em absoluto com `top` fixo e assume sempre dois
   campos mais botão, o que não serve a um formulário de um campo só. */
.recuperar {
	margin: 0 0 120px;
}

.recuperar__card {
	box-sizing: border-box;
	width: 583px;
	max-width: 100%;
	margin: 56px auto 0;
	padding: 48px 56px 40px;
	background: #ffffff;
	border-radius: 30px;
}

.recuperar__texto {
	margin: 0 0 32px;
	font: 400 18px/28px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

.recuperar__rotulo {
	display: block;
	margin: 0 0 8px;
	font: 500 15px/22px var(--fonte-corpo, sans-serif);
	text-transform: uppercase;
	color: var(--cor-titulos-tom, #8e9193);
}

.recuperar__campo {
	box-sizing: border-box;
	width: 100%;
	height: 52px;
	margin: 0 0 28px;
	padding: 0 20px;
	background: #f6f4f1;
	border: 1px solid transparent;
	border-radius: 26px;
	font: 400 18px/26px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

.recuperar__campo:focus {
	outline: none;
	border-color: var(--cor-primaria, #a787a3);
}

.recuperar__campo:focus-visible {
	outline: 2px solid var(--cor-primaria, #a787a3);
	outline-offset: 2px;
}

.recuperar__submeter {
	display: block;
	width: 100%;
	margin: 8px 0 0;
}

.recuperar__voltar {
	margin: 24px 0 0;
	text-align: center;
	font: 400 16px/24px var(--fonte-corpo, sans-serif);
}

.recuperar__voltar a {
	color: var(--cor-primaria, #a787a3);
}

@media (max-width: 430px) {
	.recuperar__card {
		padding: 32px 24px 28px;
	}
}

/* Quem Somos — bloco "Palestra Anual" em mobile.
   No desenho a foto é full-bleed e o texto (branco e creme) assenta em
   cima dela, escurecida pelo filtro. Em mobile o reflow tirava o
   `position` à foto: ela encolhia para uma faixa de 131px no topo e todo
   o texto caía por baixo, sobre o creme da página — título creme e
   subtítulo, orador e data em branco, tudo praticamente invisível. Só o
   botão se lia. Aqui a foto e o filtro voltam a cobrir a secção e o texto
   sobe para cima deles. */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .qs-palestra {
		position: relative !important;
		height: auto !important;
		min-height: 0 !important;
		padding: 56px 24px !important;
		overflow: hidden;
		text-align: center;
	}

	body:not(.pagina-home-final) .site-content .qs-palestra__foto,
	body:not(.pagina-home-final) .site-content .qs-palestra__filtro {
		position: absolute !important;
		left: 0 !important;
		top: 0 !important;
		width: 100% !important;
		height: 100% !important;
		max-width: none !important;
		margin: 0 !important;
		z-index: 0;
	}

	body:not(.pagina-home-final) .site-content .qs-palestra__foto {
		object-fit: cover;
	}

	/* O texto tem de pintar por cima: elementos posicionados pintam depois
	   do conteúdo em fluxo, portanto sem isto a foto tapava tudo. */
	body:not(.pagina-home-final) .site-content .qs-palestra__titulo,
	body:not(.pagina-home-final) .site-content .qs-palestra__subtitulo,
	body:not(.pagina-home-final) .site-content .qs-palestra__orador,
	body:not(.pagina-home-final) .site-content .qs-palestra__data-formato,
	body:not(.pagina-home-final) .site-content .qs-palestra__botao {
		position: relative !important;
		z-index: 1;
	}

	body:not(.pagina-home-final) .site-content .qs-palestra__data-formato {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 10px;
		flex-wrap: wrap;
	}

	body:not(.pagina-home-final) .site-content .qs-palestra__botao {
		display: inline-flex;
		/* 32 como o resto do padrão texto→botão (R41): o selector
		   `p + .botao-principal` não lhe chega porque o irmão anterior é
		   a `<div class="qs-palestra__data-formato">`. */
		margin-top: 32px;
	}

	/* REVISÃO v5, R38 (PDF p.9) — hierarquia de tamanhos. A regra
	   genérica de escala mobile (`.site-content p { font-size: 16px }`)
	   achata os três <p> deste bloco para 16px, mas a data/formato é uma
	   <div> e escapa-lhe: fica nos 26px/61 SemiBold do mock e passa a ser
	   o elemento mais forte da secção — 1,63x o título e o único a
	   negrito. Reponho a ordem do desktop (76/52/26/26 → 38/24/16/16),
	   com o orador e a data ao mesmo tamanho, distinguidos só pelo peso,
	   tal como a 1920. Medido: «PALESTRA ANUAL» a 38px ocupa 309,6 dos
	   342px úteis, sem transbordar em nenhuma das três larguras. */
	body:not(.pagina-home-final) .site-content .qs-palestra__titulo {
		font-size: 38px;
		line-height: 46px;
	}

	body:not(.pagina-home-final) .site-content .qs-palestra__subtitulo {
		font-size: 24px;
		line-height: 32px;
	}

	body:not(.pagina-home-final) .site-content .qs-palestra__orador {
		font-size: 16px;
		line-height: 26px;
	}

	/* O line-height de 61px é a caixa vertical do mock a 1920, onde a
	   linha é única; a 390px, com wrap, dava 132px de faixa vazia. */
	body:not(.pagina-home-final) .site-content .qs-palestra__data-formato {
		font-size: 16px;
		line-height: 26px;
	}

	/* O ponto separador media 0x0 em mobile: o refluxo dá-lhe
	   `width/height: auto` e um <span> vazio colapsa. */
	body:not(.pagina-home-final) .site-content .qs-palestra__ponto {
		flex: 0 0 auto !important;
		width: 6px !important;
		height: 6px !important;
	}
}

/* Carrosséis em mobile: os slides inactivos têm `opacity: 0` mas, com o
   reflow a tirar-lhes o `position`, continuam a ocupar altura em fluxo —
   medidos 369px de faixa lisa no banner da loja (3 x 123) e 1230px na
   secção de testemunhos dos cursos (3 x 410). Em desktop ficam empilhados
   em absoluto e o crossfade funciona; aqui não há sobreposição possível,
   por isso os inactivos saem mesmo do fluxo. O `aria-hidden` é posto pelo
   `ligarSlider()` (main.js), que já o mantém sincronizado. */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content [data-sda-slide][aria-hidden="true"] {
		display: none !important;
	}
}

/* Faixa branca do cartão de produto em mobile: mantinha a altura fixa do
   mock e um nome comprido transbordava o cartão (medidos 30px a sair num
   nome de 4 linhas numa coluna de 153px). Cresce com o conteúdo — os
   cartões da grelha ficam com alturas diferentes, o que é aceitável com
   `align-items: start` e goteira, e evita truncar nomes de produto. */
@media (max-width: 430px) {}

/* ------------------------------------------------------------
 * MÉDIOS E BAIXOS DO INVENTÁRIO DA CAMPANHA — quase todos com a mesma
 * raiz: o reflow tira o `position` e o que estava colocado em absoluto
 * para uma coluna larga vai parar ao sítio errado numa coluna estreita.
 * ------------------------------------------------------------ */
@media (max-width: 430px) {

	/* Seta dos 3 cards de categoria. Na home o card está fora do reflow, a
	   seta continuava absoluta na posição pensada para o card largo e caía
	   POR CIMA do rótulo (11 a 24px de sobreposição); no Quem Somos o card
	   entra no reflow, a seta ficava estática e órfã na margem esquerda, a
	   130-160px do rótulo centrado. Nos dois casos passa a assentar por
	   baixo do rótulo, centrada. */
	body:not(.pagina-home-final) .site-content .categoria-card__seta {
		position: static !important;
		display: block !important;
		width: 18px !important;
		height: auto !important;
		margin: 10px auto 0 !important;
	}

	/* Paginação da loja: o número activo tinha 14x30 com border-radius 50%,
	   ou seja uma elipse vertical em vez de um círculo, e a seta era
	   `display: inline` a ocupar a linha toda (318px). */
	body:not(.pagina-home-final) .site-content .loja-paginacao {
		display: flex;
		align-items: center;
		justify-content: center;
		gap: 10px;
	}

	body:not(.pagina-home-final) .site-content .loja-paginacao__pagina {
		display: inline-flex !important;
		align-items: center;
		justify-content: center;
		width: 32px !important;
		height: 32px !important;
		box-sizing: border-box;
	}

	body:not(.pagina-home-final) .site-content .loja-paginacao__seta {
		display: inline-flex !important;
		align-items: center;
		justify-content: center;
		width: 32px !important;
		height: 32px !important;
	}

	/* Campos dos formulários ocupavam 59% da coluna: os inputs caíam para a
	   largura por defeito do browser quando o reflow lhes tirou o width. */
	body:not(.pagina-home-final) .site-content .seccao-formulario__campo input,
	body:not(.pagina-home-final) .site-content .seccao-formulario__campo textarea,
	body:not(.pagina-home-final) .site-content .seccao-formulario__campo select {
		width: 100% !important;
		box-sizing: border-box;
	}

	/* Separadores da ficha de produto ficavam a 4px uns dos outros (260px em
	   desktop) e liam-se como uma frase. Ganham espaço e o activo passa a
	   ter sublinhado próprio — o `__sublinhado` deslizante do mock é
	   absoluto e em mobile ia parar ao sítio errado. */
	body:not(.pagina-home-final) .site-content .produto-descricao__tabs,
	body:not(.pagina-home-final) .site-content .produto-descricao {
		--sda-tabs-gap: 18px;
	}

	body:not(.pagina-home-final) .site-content .produto-descricao__tab {
		margin-right: 18px;
		padding-bottom: 6px;
		border-bottom: 2px solid transparent;
	}

	body:not(.pagina-home-final) .site-content .produto-descricao__tab[aria-current="true"] {
		border-bottom-color: var(--cor-rosa, #ecc6c0);
	}

	body:not(.pagina-home-final) .site-content .produto-descricao__sublinhado {
		display: none;
	}

	/* Sublinhado do separador da estrutura do curso: o ::after é absoluto e,
	   sem `position` no separador, perdia a âncora e aparecia como uma barra
	   rosa solta sobre o hero, a milhares de píxeis de distância. */
	body:not(.pagina-home-final) .site-content .curso-estrutura-tab {
		position: relative !important;
		padding-bottom: 8px;
	}

	body:not(.pagina-home-final) .site-content .curso-estrutura-tab::after {
		left: 0 !important;
		top: auto !important;
		bottom: 0 !important;
		width: 100% !important;
		transform: none !important;
	}

	/* A regra que aqui estava — `margin-top: 20px` no coração da ficha —
	   passou a ser código morto com o R110, que lhe dá linha própria
	   centrada. Ver o bloco «REVISÃO v5, R110» no fim do ficheiro. */

	/* Subtítulo da newsletter a 3-5px de um título de 38px. */
	body:not(.pagina-home-final) .site-content .seccao-newsletter__subtitulo {
		margin-top: 14px !important;
	}
}

/* Estes três não passam pelo reflow: a home tem desenho mobile próprio
   (.pagina-home-final) e ficava de fora do selector, e os separadores da
   ficha são absolutos no mock, pelo que margens não lhes tocam. */
@media (max-width: 430px) {

	/* Seta dos cards de categoria: é um afordance de HOVER (opacity: 0 no
	   mock, revelada em :hover/:focus-visible) que a fase 71 tornou
	   permanente em touch. Numa coluna estreita fica por cima do rótulo,
	   com 11 a 24px de sobreposição. Como em touch não há hover — e o
	   Figma não tem sequer estado hover desenhado para este card (node
	   0:3186) — deixa de ser pintada. O card continua todo tocável. */
	.categoria-card__seta {
		display: none !important;
	}

	/* Subtítulo da newsletter a 3px de um título de 38px. */
	.seccao-newsletter__subtitulo {
		margin-top: 14px !important;
	}

	/* Separadores da ficha de produto: no mock são `position: absolute` com
	   `left` fixos calculados para 1400px; numa coluna de 318 ficavam a 4px
	   uns dos outros e liam-se como uma frase corrida. Passam a fluir. */
	.produto-descricao__tab {
		position: static !important;
		display: inline-block !important;
		margin: 0 18px 12px 0 !important;
		padding-bottom: 6px !important;
		line-height: 1.4 !important;
		border-bottom: 2px solid transparent;
	}

	.produto-descricao__tab[aria-current="true"] {
		border-bottom-color: var(--cor-rosa, #ecc6c0);
	}

	.produto-descricao__linha,
	.produto-descricao__sublinhado {
		display: none !important;
	}
}

/* Fotos da listagem de terapias: o mock (main.css:7158) nunca lhes deu
   `border-radius`, e ficavam de cantos rectos enquanto as mesmas terapias
   na home usam 25px (`home-terapias__slide-imagem/-foto`) e todas as outras
   imagens do tema são arredondadas. É uma divergência DELIBERADA do mock,
   a pedido do Francisco — reverte-se apagando este bloco. */
.terapias-lista__foto {
	border-radius: 25px;
}

/* ------------------------------------------------------------
 * HOME — secção de terapias sem slider (pedido do Francisco).
 * Passa a mostrar as duas terapias lado a lado, igual à página de
 * listagem. O wrapper ocupa exactamente o sítio do antigo slider
 * (259/289, 1400 de largura, medido) e, sendo absoluto, serve de
 * contexto de posicionamento aos filhos `terapias-lista__*`, que assim
 * mantêm as coordenadas da listagem sem uma única alteração.
 * ------------------------------------------------------------ */
.home-terapias__lista {
	position: absolute;
	left: 259px;
	top: 289px;
	width: 1400px;
	height: 622px;
}

/* A secção encolhe: 289 do topo + 622 da lista. Eram 996px para o slider. */
.home-terapias {
	height: 911px;
}

/* O mock qualifica o título da listagem por tag (`h2.terapias-lista__titulo`,
   main.css:7175). Na home a mesma peça é `<h3>`, para não competir com o
   `<h2>` da secção — as regras são replicadas aqui em vez de se mexer no
   espelho. Valores idênticos aos do mock. */
h3.terapias-lista__titulo {
	position: absolute;
	width: 361px;
	margin: 0;
	font: 400 52px/62px var(--fonte-titulos, serif);
	color: var(--cor-primaria, #a787a3);
}

h3.terapias-lista__titulo--astrologia {
	left: 298px;
	top: 0;
}

h3.terapias-lista__titulo--tarot {
	left: 1039px;
	top: 100px;
}

/* Mobile da nova secção. A home tem desenho próprio (.pagina-home-final) e
   fica FORA do selector de reflow, por isso nada disto vem de graça: sem
   estas regras as coordenadas do canvas de 1920 persistiam e a secção saía
   toda do ecrã (medidos 9 elementos fora, com o wrapper a 1292px numa
   viewport de 360). Valores copiados do mobile da própria listagem —
   título 38/46, parágrafo 16/26, imagem a toda a largura. */
@media (max-width: 430px) {
	.pagina-home-final .home-terapias {
		height: auto;
		/* REVISÃO v5, R20 (PDF p.5): era 48px. Somado ao separador de 48px
		   do último botão e ao `margin-top: 71px` da Loja (main.css:8010),
		   dava 167px de canvas entre o SABER MAIS e o título «Conheça a
		   nossa Loja» — 2,5x o ritmo do resto da home mobile, que mede
		   67/67/68. Zerado aqui e no último botão, sobra exactamente o
		   margin-top da Loja: 71px, dentro do ritmo da página. */
		padding-bottom: 0;
	}

	.pagina-home-final .home-terapias__lista {
		position: static;
		left: auto;
		top: auto;
		width: auto;
		height: auto;
		margin: 0 24px;
		/* Deixa passar o título e a intro da secção, que continuam absolutos
		   no sítio que o desenho mobile lhes deu. */
		padding-top: 269px;
		/* REVISÃO v5, R19 (PDF p.5): o cliente pediu o título, o texto e o
		   botão dos cartões centrados, como já acontece na secção da Loja
		   logo a seguir (main.css:7863 e 8021 centram o título e a intro,
		   e 8026 centra o pill com `left: 90px` = (390−210)/2). Aqui os
		   filhos estão em fluxo, por isso basta herdarem o `text-align`:
		   apanha o h3, o parágrafo e também o botão, que é
		   `display: inline-flex` (main.css:121) e portanto uma caixa
		   inline centrada pela linha. As fotos são `display: block;
		   width: 100%` e ficam onde estavam. */
		text-align: center;
	}

	.pagina-home-final .home-terapias__lista .terapias-lista__foto {
		position: static;
		left: auto;
		top: auto;
		display: block;
		width: 100%;
		height: auto;
		margin: 0 0 24px;
	}

	.pagina-home-final .home-terapias__lista h3.terapias-lista__titulo {
		position: static;
		left: auto;
		top: auto;
		width: 100%;
		margin: 0 0 14px;
		font: 400 38px/46px var(--fonte-titulos, serif);
	}

	.pagina-home-final .home-terapias__lista .terapias-lista__paragrafo {
		position: static;
		left: auto;
		top: auto;
		width: 100%;
		margin: 0 0 20px;
		font: 400 16px/26px var(--fonte-corpo, sans-serif);
		color: var(--cor-texto, #696969);
	}

	.pagina-home-final .home-terapias__lista [class*="terapias-lista__botao"] {
		position: static;
		left: auto;
		top: auto;
		margin: 0 0 48px;
	}

	/* R20: os 48px acima separam a Astrologia do Tarot — a seguir ao
	   último são espaço morto antes da secção seguinte. Só o último
	   perde a margem, o afastamento entre as duas terapias mantém-se. */
	.pagina-home-final .home-terapias__lista > [class*="terapias-lista__botao"]:last-child {
		margin-bottom: 0;
	}
}

/* ------------------------------------------------------------
 * CURSO — barra fixa de inscrição (mobile e tablet).
 * Sobe quando o botão Inscrever da coluna lateral sai do ecrã; ver
 * initCursoBarraFixa() no main.js. Fora do canvas escalado: é chrome do
 * browser, não faz parte da maqueta, por isso usa px reais e não escala
 * com o `zoom` — é `position: fixed` no viewport.
 * ------------------------------------------------------------ */
.curso-barra {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 60;
	display: flex;
	align-items: center;
	gap: 12px;
	box-sizing: border-box;
	padding: 10px 16px calc(10px + env(safe-area-inset-bottom, 0px));
	background: #ffffff;
	border-top: 1px solid var(--cor-cinza-claro, #d6d7d9);
	box-shadow: 0 -4px 16px rgba(72, 56, 70, 0.10);
	/* O zoom inverso é posto pelo main.js — depende da largura da janela. */
}

.curso-barra[hidden] {
	display: none;
}

.curso-barra__resumo {
	flex: 1 1 auto;
	min-width: 0;
	padding: 4px 0;
	background: none;
	border: 0;
	text-align: left;
	cursor: pointer;
	font-family: var(--fonte-corpo, sans-serif);
}

/* A data parte em duas linhas quando não cabe, em vez de se cortar com
   reticências. Fase 113, item 16: o texto do botão da lista de espera vai
   até 20 caracteres e o botão cresce com ele (172px com «Inscrever» ou
   «Lista de espera», 205 a 207 com 20); medido a 390, «10 de Outubro de
   2026» precisa de 141 a 151px e ficava «10 de Outubro de 2…», sem o ano.
   A 360 já se cortava com qualquer texto. O botão não encolhe: a barra
   ganha uma linha (de 65 para 81px) e o último texto do rodapé continua
   por cima dela no fundo da página (medido a 360 e a 390, nos dois
   motores; a 430 cabe tudo numa linha). Numa linha, nada muda. O
   `balance` deixa «10 de Outubro» / «de 2026», em vez do ano sozinho na
   segunda linha. */
.curso-barra__data {
	display: block;
	font: 600 14px/18px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
	overflow: hidden;
	text-overflow: ellipsis;
	text-wrap: balance;
}

.curso-barra__formato {
	display: block;
	font: 400 12px/16px var(--fonte-corpo, sans-serif);
	color: var(--cor-titulos-tom, #8e9193);
	text-decoration: underline;
}

.curso-barra__botao {
	flex: 0 0 auto;
	width: auto;
	min-width: 132px;
	height: 44px;
	padding: 0 20px;
	font-size: 14px;
}

/* O rodapé não pode ficar por baixo da barra. */
body.sda-com-barra-curso {
	padding-bottom: 76px;
}

/* Folha com o resto da informação. */
.curso-folha {
	position: fixed;
	inset: 0;
	/* Um diálogo de ecrã inteiro tem de ficar acima do cabeçalho (1000).
	   Não se notava porque o trinco antigo arrancava o cabeçalho do ecrã. */
	z-index: 1400;
	display: flex;
	align-items: flex-end;
	background: rgba(72, 56, 70, 0.45);
}

.curso-folha[hidden] {
	display: none;
}

.curso-folha__painel {
	position: relative;
	box-sizing: border-box;
	width: 100%;
	max-height: 82vh;
	overflow-y: auto;
	overscroll-behavior: contain;
	padding: 28px 20px calc(24px + env(safe-area-inset-bottom, 0px));
	background: #ffffff;
	border-radius: 20px 20px 0 0;
}

.curso-folha__fechar {
	position: absolute;
	right: 12px;
	top: 12px;
	width: 44px;
	height: 44px;
	background: none;
	border: 0;
	cursor: pointer;
}

.curso-folha__fechar::before,
.curso-folha__fechar::after {
	content: "";
	position: absolute;
	left: 13px;
	top: 21px;
	width: 18px;
	height: 2px;
	background: var(--cor-texto, #696969);
}

.curso-folha__fechar:focus-visible,
.curso-barra__resumo:focus-visible {
	outline: 2px solid var(--cor-primaria, #a787a3);
	outline-offset: 2px;
	border-radius: 6px;
}

.curso-folha__fechar::before { transform: rotate(45deg); }
.curso-folha__fechar::after { transform: rotate(-45deg); }

.curso-folha__lista {
	margin: 8px 0 24px;
}

.curso-folha__lista dt {
	margin: 18px 0 4px;
	font: 600 13px/18px var(--fonte-corpo, sans-serif);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--cor-primaria, #a787a3);
}

.curso-folha__lista dd {
	margin: 0;
	font: 400 15px/23px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

.curso-folha__botao {
	display: flex;
	width: 100%;
	height: 48px;
}

/* Páginas legais com conteúdo real. O `.bloco-legal` do mock tem
   `height: 330px; overflow: hidden` — desenhado para quatro blocos curtos de
   texto de exemplo. Com conteúdo a sério cortava tudo aos 330px, a mesma
   armadilha dos cartões do arquivo do blog. Aqui a altura vem do conteúdo, e
   os elementos que o editor produz (h2, listas, links) ganham desenho. */
.bloco-legal--conteudo {
	height: auto;
	overflow: visible;
	border-bottom: 0;
	margin-bottom: 0;
	padding-bottom: 40px;
}

.bloco-legal--conteudo .bloco-legal__texto {
	margin-top: 0;
}

.bloco-legal--conteudo h2 {
	margin: 48px 0 20px;
	font: 500 26px/36px var(--fonte-corpo, sans-serif);
	text-transform: uppercase;
	color: var(--cor-texto, #696969);
}

.bloco-legal--conteudo h2:first-child {
	margin-top: 0;
}

.bloco-legal--conteudo h3 {
	margin: 32px 0 12px;
	font: 600 22px/32px var(--fonte-corpo, sans-serif);
	color: var(--cor-primaria, #a787a3);
}

.bloco-legal--conteudo p {
	margin: 0 0 20px;
}

.bloco-legal--conteudo ul,
.bloco-legal--conteudo ol {
	margin: 0 0 24px;
	padding-left: 24px;
}

.bloco-legal--conteudo li {
	margin-bottom: 10px;
}

/* As respostas do FAQ passaram a ter ligações no texto revisto do cliente
   (19-10-2026); sem esta regra saíam no azul do navegador. */
.bloco-legal--conteudo a,
.accordion-faq-corpo a {
	color: var(--cor-primaria, #a787a3);
	text-decoration: underline;
}

.bloco-legal--conteudo strong {
	font-weight: 600;
	color: var(--cor-texto, #696969);
}

/* ------------------------------------------------------------
 * REVISÃO v5, grupo A1 — botões desformatados em mobile.
 *
 * O cliente aponta-o 12 vezes (PDF pp. 5, 9, 10, 11, 13, 14, 15, 16, 21, 22)
 * como «corrigir a formatação do botão» e «centrar o botão». Medido: em
 * desktop TODOS os `.botao-principal` são 251x61 do canvas; a 360px variavam
 * entre 115x38 e 251x50, porque o reflow lhes tira `width` e `height` e cada
 * um encolhe para o seu texto. Uma correcção anterior acrescentou padding,
 * o que não resolve — só afasta o texto das bordas de um botão encolhido.
 *
 * Repõem-se as medidas do desenho e centra-se. O padding volta a zero: o
 * botão é content-box, e somar padding a uma largura fixa alargava-o.
 * 251px de canvas cabem na coluna de 344 do mobile.
 * ------------------------------------------------------------ */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .botao-principal,
	body:not(.pagina-home-final) .site-content .botao-contorno,
	body:not(.pagina-home-final) .site-content .login-card__submeter,
	body:not(.pagina-home-final) .site-content button[type="submit"] {
		/* !important: o selector de reflow soma ~11 classes e impõe
		   `width: auto; height: auto` a tudo dentro do .site-content. */
		display: flex;
		width: 251px !important;
		max-width: 100% !important;
		/* 50/16 e não 61/18: o mesmo botão media 61 aqui e 50 na home,
		   porque a home está fora do refluxo e tem o desenho mobile do
		   mock (main.css:7746), enquanto todas as outras páginas herdavam
		   os 61 do canvas de 1920 por omissão. Quem percorria home →
		   terapias via o CTA mudar de tamanho pelo caminho. Alinho pelo
		   único desenho mobile que a designer fez; 50 continua acima do
		   mínimo de toque de 44. */
		height: 50px !important;
		min-height: 50px !important;
		font-size: 16px;
		padding-left: 0 !important;
		padding-right: 0 !important;
		margin-left: auto !important;
		margin-right: auto !important;
		/* Folga por baixo: medido, o botão ficava colado ao elemento
		   seguinte (folga 0 em /terapias/ e no Quem Somos), quando em
		   desktop há 115 a 331px. O mock não tem margens verticais e o
		   reflow não as inventa. */
		margin-bottom: 40px !important;
		/* `border-box` e não `content-box`: o `.botao-contorno` tem 1px de
		   borda e ficava 253x52 contra os 251x50 dos preenchidos — dois
		   botões empilhados desalinhavam 1px na horizontal em todas as
		   páginas. E o user-agent dá `padding: 1px 6px` aos <button>, que
		   em content-box somava 2px à altura: o «Actualizar Carrinho»
		   media 52 contra os 50 do «Finalizar Compra». */
		box-sizing: border-box;
		padding-top: 0;
		padding-bottom: 0;
		/* Sem isto o botão encolhe quando partilha a linha com outro
		   elemento — era o que acontecia no formulário de contacto. */
		flex-shrink: 0;
	}

	/* Rodapé dos formulários: o botão e o check das políticas partilhavam a
	   linha, o que espremia o botão para 139px. O cliente pede o botão
	   centrado e o check ABAIXO dele (PDF p.22). */
	body:not(.pagina-home-final) .site-content .seccao-formulario__rodape {
		display: flex;
		flex-direction: column;
		align-items: center;
		gap: 20px;
	}

	body:not(.pagina-home-final) .site-content .seccao-formulario__optin {
		display: flex;
		align-items: center;
		/* O bloco ocupa a largura toda, por isso não basta centrá-lo: é
		   preciso centrar o CONTEÚDO, senão a caixa e o texto ficam
		   encostados à esquerda por baixo de um botão centrado. */
		justify-content: center;
		gap: 10px;
		margin: 0;
		text-align: left;
	}

	/* A regra de R21 que aqui estava — `justify-content: center` no
	   `.botao-lista` — era declaração MORTA e saiu: o elemento não é
	   contentor flex, e os dois filhos são absolutos. Ver o bloco
	   «R21 — botões com seta» no fim do ficheiro. */
}

/* ------------------------------------------------------------
 * REVISÃO v5, grupo A8 — «+» e «−» da quantidade desalinhados
 * (PDF p.2 página do produto, p.4 checkout, p.24 mobile).
 *
 * Regressão da fase 70: para dar área de toque aos steppers acrescentei
 * `padding: 12px; margin: -12px`, o que levou os botões de 12x12 para
 * 36x36 — mas os traços são pseudo-elementos absolutos calibrados para a
 * caixa pequena (`top: 5px; left: 0`), e passaram a assentar junto ao
 * topo. Medido na ficha: botão 36x36 com o glifo a 5px do topo.
 * Centram-se no botão, seja qual for o seu tamanho.
 * ------------------------------------------------------------ */
.produto-card__qtd-menos::before,
.produto-card__qtd-mais::before,
.produto-card__qtd-mais::after,
.produto-ficha__qtd-menos::before,
.produto-ficha__qtd-mais::before,
.produto-ficha__qtd-mais::after,
.carrinho-linha__qtd-menos::before,
.carrinho-linha__qtd-mais::before,
.carrinho-linha__qtd-mais::after,
.conta-desejos__qtd-menos::before,
.conta-desejos__qtd-mais::before,
.conta-desejos__qtd-mais::after {
	left: 50%;
	top: 50%;
	translate: -50% -50%;
}

/* REVISÃO v5, R22 (PDF p.5) — «não aparece o campo de quantidade quando
   carrego», na home em mobile. O main.js faz dois passos: o 1.º toque põe
   `--no-carrinho` e revela a quantidade, o 2.º adiciona ao carrinho. Mas o
   mock tem `.pagina-home-final .produto-card__quantidade { display: none
   !important }` (main.css:8088), que o mantinha escondido — o 1.º toque
   não produzia efeito visível nenhum. Revela-se quando o card está no
   estado --no-carrinho, que é exactamente o que o desenho previa. */
@media (max-width: 430px) {}

/* REVISÃO v5, R22 (PDF p.5) — «o botão do carrinho está esticado».
   Medido: a 1920 o ícone é 32x24, com o rácio do ficheiro (32x23); a 360
   ficava 17x24, ou seja comprimido a metade da largura e alto na mesma —
   é isso que se lê como esticado. Repõe-se a caixa do desenho e garante-se
   que a imagem nunca é deformada. */
@media (max-width: 430px) {}

/* REVISÃO v5, R102 (PDF p.22) — «falta o check nas políticas».
   Duas causas, ambas confirmadas por medição: em mobile a caixa media
   0x0, porque o reflow lhe anula width/height; e em qualquer tamanho é
   branca sem borda (main.css:1087, desenhada para o fundo rosa da
   newsletter), portanto invisível sobre o fundo claro do formulário.
   Ganha borda e volta a ter dimensão. */
.seccao-formulario__optin-caixa,
.seccao-newsletter__optin-caixa {
	border: 1px solid var(--cor-cinza-medio, #a4a7a9);
	box-sizing: border-box;
}

.seccao-formulario__optin-caixa:checked,
.seccao-newsletter__optin-caixa:checked {
	border-color: var(--cor-primaria, #a787a3);
}

.seccao-formulario__optin-caixa:focus-visible,
.seccao-newsletter__optin-caixa:focus-visible {
	outline: 2px solid var(--cor-primaria, #a787a3);
	outline-offset: 2px;
}

@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .seccao-formulario__optin-caixa,
	.pagina-home-final .seccao-newsletter__optin-caixa,
	body:not(.pagina-home-final) .site-content .seccao-newsletter__optin-caixa {
		width: 20px !important;
		height: 20px !important;
		min-width: 20px !important;
		min-height: 20px !important;
		flex: 0 0 20px !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5 — ritmo vertical da página de Contactos em mobile
 * (PDF p.22, R99/R100/R101/R102 e o report do Francisco).
 *
 * Medido a 360px antes de mexer: tudo a 16px, com duas excepções que se
 * notam — o ícone da localização a **4px** do mapa (lê-se como colado) e
 * dois saltos de **60px** à volta do botão, que o deixavam isolado do
 * formulário e o consentimento longe dele.
 *
 * Escala aplicada: 8 entre um ícone e o seu texto (são um par), 28 entre
 * grupos de contacto, 32 depois do mapa e antes do rodapé, 40 antes do
 * formulário, 16 entre o botão e o consentimento.
 * ------------------------------------------------------------ */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .seccao-onde-estamos__texto {
		margin-bottom: 28px;
	}

	body:not(.pagina-home-final) .site-content .seccao-onde-estamos__mapa {
		margin-bottom: 32px;
	}

	/* O ícone e o contacto que se lhe segue são um par: junta-se o par e
	   afasta-se do par seguinte. */
	body:not(.pagina-home-final) .site-content .seccao-onde-estamos__icone {
		margin-bottom: 8px;
	}

	body:not(.pagina-home-final) .site-content .seccao-onde-estamos__contacto--morada {
		margin-bottom: 28px;
	}

	body:not(.pagina-home-final) .site-content .seccao-onde-estamos__contacto--email {
		margin-bottom: 40px;
	}

	/* O botão deixa de ter a margem de 40px que damos aos outros: aqui o
	   espaçamento é do `gap` da coluna, e as duas coisas somavam 60px. */
	body:not(.pagina-home-final) .site-content .seccao-formulario__rodape {
		gap: 16px;
		margin-top: 32px;
	}

	body:not(.pagina-home-final) .site-content .seccao-formulario__rodape .botao-principal,
	body:not(.pagina-home-final) .site-content .seccao-formulario__rodape button[type="submit"] {
		margin-bottom: 0 !important;
	}

	/* Consentimento: com a largura toda disponível o texto enchia a linha e
	   a caixa ficava encostada à esquerda — parecia desalinhado mesmo com o
	   bloco centrado. Limitando a largura, o texto quebra antes e o conjunto
	   lê-se centrado por baixo do botão. */
	body:not(.pagina-home-final) .site-content .seccao-formulario__optin {
		/* !important: o reflow impõe `max-width: 100%` com ~11 classes. */
		width: auto !important;
		max-width: 260px !important;
		margin-left: auto !important;
		margin-right: auto !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, grupo A2 — margens de secção calibradas para desktop
 * a vazar para mobile (PDF pp. 13, 14, 15, 16, 17, 18, 21, 25).
 *
 * Decomposição do caso que o Francisco mostrou (botão → citação na
 * página da consulta, R59, 223px): 68 de sobra no fim da secção + **127
 * de margem inferior da secção** + 28 de padding da citação. O termo
 * dominante é a margem, que o mock define para o canvas de 1920.
 *
 * A referência é a própria home, que TEM desenho mobile: medida secção a
 * secção, o ritmo dela é 67–71px. É esse o valor que o cliente pede
 * («utiliza a margem do exemplo como referência»). Estas oito secções
 * tinham entre 75 e 156.
 * ------------------------------------------------------------ */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados,
	body:not(.pagina-home-final) .site-content .loja-produtos {
		margin-bottom: 68px !important;
	}

	/* REVISÃO v5 — as duas secções do selo saíram do grupo acima: desde
	   o R44 carregam mais 65px de `padding-bottom` no `.seccao-inner`,
	   para caber a metade do selo que fica fora da foto. Com os 68
	   davam 96px até à newsletter; 39 devolve os 67 de referência. */
	body:not(.pagina-home-final) .site-content .qs-sobre-leonardo,
	body:not(.pagina-home-final) .site-content .terapia-sobre-leonardo {
		margin-bottom: 39px !important;
	}

	/* REVISÃO v5, R86 (PDF p.18) — a secção do Leonardo do curso alinhada
	   com a do Quem Somos. O selo, o enquadramento e a tipografia já
	   estavam iguais (comparados ao pixel); faltava a fronteira de baixo.
	   A do Quem Somos é filha directa de `.site-content` e apanha os 28px
	   de `padding-bottom` do refluxo; a do curso vive dentro de
	   `.curso-corpo` e não apanha — é a mesma armadilha que já mordeu no
	   R44, onde só se compensou o lado de cima. Ficava o selo quase a
	   tocar na banda escura dos testemunhos. */
	body:not(.pagina-home-final) .site-content .curso-sobre-leonardo {
		margin-bottom: 39px !important;
	}

	/* A fronteira mais fora da banda de todo o site em mobile — 164px,
	   e a única onde o mobile é MAIOR que o desktop (141). Era o resto
	   dos 68 somados aos 28+28 do refluxo e aos 40 do botão. */
	body:not(.pagina-home-final) .site-content .terapia-sobre-astrologia {
		margin-bottom: 0 !important;
		/* REVISÃO v5, R57 (PDF p.13): a margem de cima tinha ficado a nu e
		   a fronteira até à imagem da árvore era só o `padding-top: 28px`
		   do refluxo — a mais apertada da página. 39 + 28 = 67, a
		   referência. Sem `!important`: (0,3,1) vence os (0,2,2) da regra
		   genérica das secções. */
		margin-top: 39px;
	}

	body:not(.pagina-home-final) .site-content .curso-sobre,
	body:not(.pagina-home-final) .site-content .curso-como-funciona,
	body:not(.pagina-home-final) .site-content .curso-sobre-leonardo {
		margin-top: 68px !important;
	}
}

/* REVISÃO v5, R07 (PDF p.1) — «colocar a seta à frente do nome» nos cards
   das 3 Áreas de Actuação. No mock a seta está numa linha própria por
   baixo do rótulo (`bottom: 26px` contra `bottom: 54px` do rótulo); o
   cliente quer-a ao lado do nome. O rótulo passa a caixa flex centrada e
   a seta entra nele como irmã, mantendo a revelação em hover.

   O `padding-left` repõe o centrado que esta correcção me tinha partido.
   Ao trazer a seta para o fluxo, ela passou a ocupar 26 + 12 = 38px na
   fila, e o texto — centrado dentro da fila, não dentro do card — ficou
   19px à esquerda do centro do card (medido: «TERAPIAS» e «ACTIVIDADES»
   a 143,5 num card de 325, cujo centro é 162,5). Reservar os mesmos 38px
   do lado oposto devolve o texto ao centro exacto do card, e fá-lo em
   repouso e em hover — sem salto quando a seta aparece.
   Em mobile a seta é `display: none` (bloco @430 mais abaixo), por isso
   lá a reserva sai também. */
.categoria-card__rotulo {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 12px;
	padding-left: 38px;
	box-sizing: border-box;
}

@media (max-width: 430px) {

	.categoria-card__rotulo {
		padding-left: 0;
	}
}

.categoria-card__seta {
	position: static;
	bottom: auto;
	left: auto;
	transform: none;
	margin: 0;
	flex: 0 0 auto;
}

.categoria-card:hover .categoria-card__seta,
.categoria-card:focus-visible .categoria-card__seta {
	transform: none;
}

/* REVISÃO v5, R08 (PDF p.1) — «colocar as tags longas numa só linha».
   «CONEXÕES SEMANAIS» quebrava dentro da pastilha. */
.seccao-sidebar__tag {
	white-space: nowrap;
}

/* REVISÃO v5, R10 (PDF p.2) — «na página do produto, falta arredondar os
   cantos da imagem do produto». O mock dá 30px à imagem do card na grelha
   (main.css:2892) mas deixa a da ficha a cantos rectos. Uniformiza-se,
   incluindo as miniaturas, que têm o mesmo tratamento. */
.produto-ficha__imagem {
	border-radius: 30px;
}

.produto-ficha__miniatura {
	border-radius: 16px;
}

/* REVISÃO v5, R13 (PDF p.2) — «o nome do botão também não está centrado».
   Medido: na horizontal está (desvio 0); o que o desloca é o
   `padding-bottom: 11px` que o mock dá ao botão, e que empurra o texto
   ~5px para cima dentro dos 61px de altura. */
.produto-ficha__comprar {
	padding-bottom: 0;
}

/* R14 — a frase que substitui o botão, com formatação de Body.
   A ficha do produto é canvas fixo com todos os filhos em `position:
   absolute`; um <p> em fluxo cai no canto superior-esquerdo da secção e
   fica escondido debaixo da galeria. Ocupa a linha do botão: mesmo `top`
   e mesma altura (61px), alinhada à esquerda da coluna (798px, onde o
   stepper estaria) em vez do left do botão, para não ficar um bloco de
   texto indentado sozinho no meio da coluna. Em mobile a regra de
   refluxo tem mais especificidade e devolve isto a fluxo normal. */
.produto-ficha__indisponivel {
	position: absolute;
	left: 798px;
	top: 425px;
	display: flex;
	align-items: center;
	width: 480px;
	min-height: 61px;
	margin: 0;
	font: 400 22px/36px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

/* REVISÃO v5 — o coração não está centrado no círculo (report do Francisco).
   Medido: na grelha o <img> está em `left: 9px; top: 11px` dentro de um
   botão de 40x40, quando o centro seria 11/12; na ficha em 17/17 num botão
   onde o centro seria 19,5. São valores fixos do mock, desviados 2 a 2,5px.
   O componente do Figma (0:19008) centra com `left: calc(50% + 0.5px)` e
   translate — é o que se faz aqui, para ficar centrado seja qual for o
   tamanho do botão ou do ícone. */
/* SÓ serve as duas instâncias cujo <img> está em `position: absolute`
   — nessas, o par left/top a 50% mais o translate centra seja qual for
   o tamanho do botão ou do ícone.
   A LISTA DE DESEJOS NÃO ENTRA AQUI, e era esse o defeito que o
   Francisco reportou: lá o <img> é estático e o botão já é flex
   centrado, portanto `left`/`top` eram inertes — mas `translate`
   aplica-se a qualquer elemento e empurrava o coração meia caixa para
   cima e para a esquerda. Medido: −12px / −10,5px num círculo de 61,
   com o centro do botão a não conter coração nenhum. */
.produto-card__desejos img,
.produto-ficha__favorito img {
	left: 50%;
	top: 50%;
	right: auto;
	bottom: auto;
	translate: -50% -50%;
}

/* O anel que o Francisco viu é o indicador de FOCO, e deve continuar a
   existir — confirmado que só aparece por teclado, não ao clique de rato.
   O que estava mal era a cor: a regra global usa a primária, e no estado
   marcado isso dá um anel roxo à volta de um círculo roxo. No coração
   marcado passa a branco, que contrasta com o círculo; no estado normal
   (círculo branco) mantém-se a primária. */
.produto-card__desejos[aria-pressed="true"]:focus-visible,
.produto-card__desejos--ativo:focus-visible,
.produto-ficha__favorito[aria-pressed="true"]:focus-visible,
.produto-ficha__favorito.produto-card__desejos--ativo:focus-visible {
	outline-color: #ffffff;
	outline-offset: -3px;
}

/* ------------------------------------------------------------
 * Ficha de produto no computador: título com mais de duas linhas e
 * descrição com mais de três (fase 119)
 * ------------------------------------------------------------ */

/* A coluna da direita é o canvas do desenho, com tudo em posições fixas: o
   título tem lugar para duas linhas e a descrição para três. Os nomes da loja
   são os títulos dos documentos do cliente, e 87 dos 164 passavam das duas
   linhas e saíam cortados com reticências (medido no staging a 1440, a
   19-10-2026); a descrição do incenso de nardo tinha quatro e tocava nos
   botões. O script logo a seguir à ficha (woocommerce/single-product.php)
   conta as linhas desenhadas e põe em --sda-ficha-titulo e
   --sda-ficha-descricao, em px do canvas, o que passa disso (62 por linha de
   título, 36 por linha de descrição); tudo o que vem a seguir desce essa
   medida, com os mesmos intervalos do desenho. Até duas e três linhas os
   desvios são 0 e a ficha fica igual ao píxel. Sem o script fica como antes
   (o corte a duas linhas). O telemóvel tem a coluna em fluxo e não entra. */
@media (min-width: 430.02px) {
	.produto-ficha--medida h1.produto-ficha__titulo {
		display: block;
		-webkit-line-clamp: none;
		overflow: visible;
	}

	.produto-ficha.produto-ficha--medida {
		height: calc(756px + var(--sda-ficha-titulo, 0px) + var(--sda-ficha-descricao, 0px));
	}

	.produto-ficha--medida p.produto-ficha__preco {
		top: calc(163px + var(--sda-ficha-titulo, 0px));
	}

	.produto-ficha--medida .produto-ficha__divisor--preco {
		top: calc(259px + var(--sda-ficha-titulo, 0px));
	}

	.produto-ficha--medida p.produto-ficha__descricao {
		top: calc(286px + var(--sda-ficha-titulo, 0px));
	}

	.produto-ficha--medida .produto-ficha__quantidade,
	.produto-ficha--medida .produto-ficha__comprar,
	.produto-ficha--medida .produto-ficha__indisponivel {
		top: calc(425px + var(--sda-ficha-titulo, 0px) + var(--sda-ficha-descricao, 0px));
	}

	.produto-ficha--medida .produto-ficha__favorito {
		top: calc(426px + var(--sda-ficha-titulo, 0px) + var(--sda-ficha-descricao, 0px));
	}

	.produto-ficha--medida p.produto-ficha__entrega {
		top: calc(514px + var(--sda-ficha-titulo, 0px) + var(--sda-ficha-descricao, 0px));
	}

	.produto-ficha--medida .produto-ficha__divisor--referencia {
		top: calc(640px + var(--sda-ficha-titulo, 0px) + var(--sda-ficha-descricao, 0px));
	}

	.produto-ficha--medida p.produto-ficha__referencia {
		top: calc(661px + var(--sda-ficha-titulo, 0px) + var(--sda-ficha-descricao, 0px));
	}
}

/* ------------------------------------------------------------
 * Ficha de produto em mobile
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* O clamp de 2 linhas existe para o canvas fixo do desktop, onde o
	   título tem uma caixa de altura fixa antes do preço. Em mobile a
	   coluna está em fluxo e não há nada a proteger — o clamp só corta o
	   nome do produto (medido: «Incenso em cone Backflow Pau Santo -
	   Tribal Soul» ficava em «Incenso em cone…»). */
	.produto-ficha__titulo {
		display: block;
		-webkit-line-clamp: none;
		overflow: visible;
	}
}

/* ------------------------------------------------------------
 * Conta — "Lista de Desejos" em caixa alta no menu lateral
 * ------------------------------------------------------------ */

/* REVISÃO v5, R16 (PDF p.3). O espelho do Figma liga o uppercase a
   todos os itens do menu (main.css:6493) e volta a desligá-lo só no
   terceiro (main.css:6512, `.conta-menu li:nth-child(3)`), que é
   precisamente a Lista de Desejos. Repunha-o através de
   `.pagina-conta-lista-desejos` (main.css:7118), classe de body que o
   tema nunca chega a imprimir — `sda_wc_body_classes()` dá
   `pagina-conta-dados-pessoais` a este endpoint. Resultado: o item saía
   em caixa normal em todas as páginas da conta menos na própria lista,
   onde a regra do item activo o salvava. Reponho para todos os estados,
   e devolvo o line-height aos 32px dos vizinhos — o mock tinha-o em 30
   e o ritmo do menu media 52/51/53 em vez de 52/52/52.
   Especificidade (0,2,1), igual à do main.css: ganha pela ordem da
   folha, e a ≤430px o refluxo (especificidade maior) continua a impor
   os seus 16px/26px. Sem !important, de propósito. */
.conta-menu li:nth-child(3) {
	text-transform: uppercase;
	line-height: 32px;
}

/* ------------------------------------------------------------
 * REVISÃO v5 — R31, R34 e R37: três fotografias fora em mobile
 * ------------------------------------------------------------ */

/* Nos prints de telemóvel o cliente pediu a remoção de:
     R31 (PDF p.7) — a mão turquesa com luz, entre o parágrafo de
       abertura e o primeiro texto da História ... --mao
     R34 (PDF p.8) — o pôr-do-sol alaranjado, logo a seguir ao título
       «O caminho de revelação» ................. --por-do-sol
     R37 (PDF p.9) — os dois pássaros do Propósito ...... --flores

   ARMADILHA, deixada aqui de propósito: no Propósito as classes e os
   ficheiros estão TROCADOS com as fotos. `--flores` /
   `qs-proposito-flores.jpg` são os PÁSSAROS; `--passaros` /
   `qs-proposito-passaros.jpg` é a rapariga com os dentes-de-leão, que
   fica (e é a que o R36 quer redimensionar). Verificado abrindo os
   ficheiros, não pelo nome.

   Escondo em vez de apagar o markup: reverte-se comentando o bloco, e
   não mexe no parallax — `sdaParallaxPar()` (main.js:1252 e 1258)
   procura estes selectores por querySelector e desiste do par inteiro
   se o primeiro não existir.

   Só a ≤430px, por autorização expressa do Francisco. Em mobile o
   refluxo já as tem em fluxo e o espaço fecha sozinho (medido: a folga
   entre o fundo do conteúdo e o da secção mantém-se em 44px na
   História e 28px no Propósito, sem resíduo). Em desktop estão em
   absoluto dentro de secções de altura fixa: o espaço não fecharia e,
   sem a mão e o pôr-do-sol, a metade esquerda da História ficaria
   vazia. */
@media (max-width: 430px) {
	.qs-historia__imagem--mao,
	.qs-historia__imagem--por-do-sol,
	.qs-proposito__imagem--flores {
		display: none;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R41 e R46 (PDF p.10) — margem entre o bloco de texto
 * e o botão, em mobile
 * ------------------------------------------------------------ */

/* Não são dois casos: são sete, e todos a 16,0px exactos, porque o
   valor não vem de nenhuma regra de secção — vem do ritmo genérico do
   refluxo (`.site-content p { margin: 0 0 16px }`). Em desktop estes
   botões são absolutos e a distância é a coordenada do canvas (67 no
   Quem Somos, 49 nas Terapias, 64 e 72 nas páginas de terapia); a
   ≤430px as coordenadas evaporam-se e sobra a margem do parágrafo,
   porque o botão não tem margin-top e o colapso dá max(16, 0).

   Alvo: a home tem desenho mobile do mock e aí o mesmo padrão mede 29
   (boas-vindas), 33 (loja) e 33 (actividades) — e o mobile do desenho
   não é uma escala do desktop, onde os mesmos três medem 133, 54 e 55.
   Fixo 32: dentro da banda do desenho e na grelha de 8 que o resto do
   mobile já usa.

   `margin-top` no botão, e não `margin-bottom` maior no parágrafo:
   assim COLAPSA com os 16px do parágrafo em vez de somar. Medido: o
   intervalo passa de 16 para 32 e a página cresce 16px por par, não
   32. Sem `!important` — o selector de refluxo impõe `margin-left` e
   `margin-right`, nunca `margin-top`. */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content p + .botao-principal,
	body:not(.pagina-home-final) .site-content p + .botao-contorno,
	body:not(.pagina-home-final) .site-content p + .botao-lista,
	body:not(.pagina-home-final) .site-content .terapia-como-funciona__item + .botao-principal {
		margin-top: 32px;
	}

	/* A barra lateral do curso é uma grelha: aí as margens não colapsam
	   e a regra acima somaria 2px aos 30 já calibrados (54 → 56). */
	body:not(.pagina-home-final) .site-content .curso-sidebar .curso-sidebar__botao {
		margin-top: 30px;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R25 (PDF p.6) e R44 (PDF p.10) — o selo da marca
 * em mobile
 * ------------------------------------------------------------ */

/* R25 (HOME). O bloco mobile do mock dá ao selo `left: 130px;
   top: 729px` — coordenadas do canto superior esquerdo na moldura de
   390. Só que a regra de desktop aplica `transform: translate(-50%,
   -50%)` (que eu troquei por `translate` mais acima, para a rotação
   girar sobre o próprio eixo) e essa declaração não vive dentro de
   nenhum @media: escorrega para o mobile e desloca o selo 65,5px para
   a esquerda e 65px para cima, deixando-o dentro da foto, no canto
   inferior esquerdo. Anulado o deslocamento, três valores independentes
   batem certo: o centro do selo cai em 195,5 (centro exacto da foto
   mobile), o centro vertical em 794 (base da foto: 793), e o intervalo
   até aos testemunhos passa de 135 para 70px — o ritmo mobile do
   próprio mock. O desenho mobile já pedia isto.

   R44 (Quem Somos, terapia, curso). O refluxo põe o selo em
   `position: static; width: auto` e o <img> volta ao tamanho
   intrínseco do SVG: 263x261, 67% da largura do ecrã. A rodar, a caixa
   chega a 371px e sai 31px pela esquerda, recortada pelo `overflow-x`
   do body — é o «cortado nos lados» do print. Passa a 131x130, que é a
   proporção do desenho (selo/foto = 0,376 em desktop; 131/343 = 0,382
   na única moldura mobile que existe, a da home), e à colocação que o
   R25 pede.

   O deslocamento faz-se com `margin`, NUNCA com `translate`:
   `translate` compõe antes de `rotate` e a animação deixaria de girar
   sobre o próprio eixo. */

/* Foco visível também nos botões do rodapé e afins — a regra geral só
   cobre <a>. */
.site-footer button:focus-visible {
	outline: 2px solid var(--cor-creme, #FFF5DE);
	outline-offset: 2px;
}

@media (max-width: 430px) {
	/* R25 — a home está fora do refluxo, por isso (0,2,0) chega. */
	.pagina-home-final .home-sobre-leonardo__selo {
		transform: none;
		translate: none;
	}

	/* R44 — reserva de espaço para a metade do selo que fica fora da
	   foto. Padding e não margin: no curso a secção não é filha directa
	   de `.site-content`, não apanha o padding do refluxo, e a margem
	   colapsava para fora da secção. */
	body:not(.pagina-home-final) .site-content .qs-sobre-leonardo .seccao-inner,
	body:not(.pagina-home-final) .site-content .terapia-sobre-leonardo .seccao-inner,
	body:not(.pagina-home-final) .site-content .curso-sobre-leonardo .seccao-inner {
		padding-bottom: 65px;
	}

	/* O refluxo põe tudo em `static` — sem isto o selo absoluto
	   ancorava no viewport. */
	body:not(.pagina-home-final) .site-content .qs-sobre-leonardo__media,
	body:not(.pagina-home-final) .site-content .terapia-sobre-leonardo__media,
	body:not(.pagina-home-final) .site-content .curso-sobre-leonardo__media {
		position: relative !important;
	}

	/* `top: 100%` é a base da foto (o selo está fora de fluxo, logo a
	   altura de __media é a da foto); a margem negativa de -65px sobe-o
	   meia altura, deixando o centro sobre a aresta. */
	body:not(.pagina-home-final) .site-content .qs-sobre-leonardo__selo,
	body:not(.pagina-home-final) .site-content .terapia-sobre-leonardo__selo,
	body:not(.pagina-home-final) .site-content .curso-sobre-leonardo__selo {
		position: absolute !important;
		left: 50% !important;
		top: 100% !important;
		right: auto !important;
		bottom: auto !important;
		width: 131px !important;
		height: 130px !important;
		max-width: none !important;
		transform: none !important;
		translate: none !important;
		margin: -65px 0 0 -65.5px !important;
	}

	/* REVISÃO v5, R71 (PDF p.15) — «reduzir o tamanho do logo, de modo a
	   ficar com a largura da imagem de referência da Home».
	   Tinha metade feito: estava centrado, mas com 130px, que herdou do
	   selo do Leonardo quando tratei este elemento como extra do R44 em
	   vez de o ler como ponto próprio. A «imagem de referência da Home»
	   que o cliente invoca é o dente-de-leão, que mede 205 de canvas, e
	   foi assim que traduzi a mesma frase no R32, no R36 e no R51. Aqui
	   ficava 37% abaixo. Passa a 205, como os outros três.
	   A rotação alarga a caixa envolvente para ~244, que continua a caber
	   nos 344 da coluna. */
	body:not(.pagina-home-final) .site-content .proximas-actividades__simbolo {
		display: block !important;
		width: 205px !important;
		height: 205px !important;
		margin: 0 auto !important;
	}

	.sda-atividade-hero__simbolo {
		width: 130px;
		height: 130px;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R28 e R29 (PDF p.7) — rodapé mobile
 * ------------------------------------------------------------ */

/* O mock desenhou o acordeão só como decoração: os traços −/+ são
   pseudo-elementos fixos POR COLUNA (Explorar tem sempre −, Apoio e
   Legal têm sempre +) e os links dessas duas colunas estão em
   `display: none` sem forma de os abrir — 8 links inalcançáveis no
   telemóvel, que é pior do que o cliente descreve. Não há uma única
   linha de JS ligada ao rodapé.

   Ao mesmo tempo o rodapé tem `height: 673px` fixo e o copyright acaba
   aos 690: 17px de texto branco a cair fora do fundo roxo, sobre o
   branco do body — some por completo. R28 e R29 estão ligados, porque
   mesmo corrigidos os 17px um acordeão a abrir não teria para onde
   crescer.

   As três colunas passam a fluxo vertical (o estado fechado reproduz as
   coordenadas do mock ao pixel), o rodapé passa a altura automática, e
   o bloco de baixo ancora ao FUNDO em vez do topo, pelo que acompanha
   os painéis sem mais cálculo. Sem `!important`: o rodapé está fora de
   `.site-content`, logo fora do selector de refluxo.

   ARMADILHA de cascata, para quem vier depois: `.footer-coluna li` tem
   `position: absolute` no main.css com especificidade (0,2,0). Qualquer
   override de posicionamento nos `li` do rodapé precisa de (0,3,0) no
   mínimo — a regra que já cá estava em `.footer-coluna__titulo` tinha o
   `position: relative` morto por isso mesmo. */
@media (max-width: 430px) {
	.site-footer {
		height: auto;
	}

	/* 266px = onde o mock começa a coluna Explorar. Em baixo, 124px de
	   divisor, pagamentos e respiro, mais a altura dos direitos
	   (--sda-rodape-direitos: 48px com duas linhas, 72px com três). Zero nas goteiras
	   laterais porque nas páginas com refluxo o `.seccao-inner` leva
	   23px e na home leva 0 — o rodapé não pode depender disso.
	   Se o bloco de cima (logo, descrição, redes) mudar de altura, o
	   266 tem de mudar com ele. */
	body .site-footer .seccao-inner {
		padding: 266px 0 calc(124px + var(--sda-rodape-direitos, 48px));
	}

	.site-footer .footer-coluna {
		position: static;
		width: 342px;
		margin-left: 24px;
	}

	/* Goteiras do mock: 23px depois de uma coluna aberta, 6px depois de
	   uma fechada. São dois valores diferentes no desenho, não uma
	   regra — replicados tal e qual para o estado fechado bater ao pixel. */
	.site-footer .footer-coluna + .footer-coluna {
		margin-top: 23px;
	}

	.site-footer .footer-coluna.esta-fechada + .footer-coluna {
		margin-top: 6px;
	}

	/* (0,3,0) para bater o `position: absolute` do main.css. O
	   font-size também: o mock só põe 16px na coluna Explorar. */
	.site-footer .footer-coluna li {
		position: static;
		font-size: 16px;
	}

	/* O título continua a ser bloco de contenção: os traços −/+ são
	   pseudo-elementos absolutos ancorados a ele. */
	.site-footer .footer-coluna li.footer-coluna__titulo {
		position: relative;
		display: block;
		width: 100%;
		cursor: pointer;
	}

	.site-footer .footer-coluna__titulo + li {
		margin-top: -5px;
	}

	/* Anulo o `display: none` fixo do mock: sem JS todas as colunas
	   ficam abertas, que é a direcção de falha segura — hoje, sem JS,
	   perdem-se 8 links. */
	.site-footer .footer-coluna--apoio li,
	.site-footer .footer-coluna--legal li {
		display: list-item;
	}

	/* A classe é posta pelo JS. É o único sítio que fecha um painel. */
	.site-footer .footer-coluna.esta-fechada li:not(.footer-coluna__titulo) {
		display: none;
	}

	.site-footer .footer-coluna__botao {
		display: block;
		width: 100%;
		padding: 0;
		border: 0;
		background: none;
		font: inherit;
		color: inherit;
		letter-spacing: inherit;
		text-align: left;
		cursor: pointer;
	}

	/* O traço vertical (o «+») deixa de depender de ser a coluna de
	   apoio ou legal e passa a depender do ESTADO. */
	.site-footer .footer-coluna--apoio .footer-coluna__titulo::before,
	.site-footer .footer-coluna--legal .footer-coluna__titulo::before {
		content: none;
	}

	.site-footer .footer-coluna.esta-fechada .footer-coluna__titulo::before {
		content: "";
		position: absolute;
		right: 7px;
		top: 10px;
		width: 2px;
		height: 16px;
		border-radius: 1px;
		background: var(--cor-creme, #FFF5DE);
	}

	/* Bloco de baixo ancorado ao FUNDO do rodapé — os valores são as
	   distâncias do mock medidas de baixo para cima. */
	.site-footer .footer-divisor {
		top: auto;
		bottom: calc(80.5px + var(--sda-rodape-direitos, 48px));
	}

	.site-footer p.footer-pagamentos {
		top: auto;
		bottom: calc(40px + var(--sda-rodape-direitos, 48px));
	}

	.site-footer .footer-pagamento-icone {
		top: auto;
		bottom: calc(45px + var(--sda-rodape-direitos, 48px));
	}

	.site-footer .footer-mbway {
		top: auto;
		bottom: calc(44px + var(--sda-rodape-direitos, 48px));
	}

	.site-footer p.footer-copyright--mobile {
		top: auto;
		bottom: 24px;
	}
}

/* Fase 113 (item 13) — dois autores na linha dos direitos: «Website por
   Raquel Design Studio & FCS Web Development». Numa linha só, a 18px, a
   tinta ia até 13px do MB Way; por isso, com titular e dois autores, o
   computador passa a duas linhas (titular em cima, autoria em baixo, ambas
   alinhadas à direita) e o rodapé cresce 24px de canvas (445 → 469) para
   manter os 31px de respiro do desenho. No telemóvel ficam três linhas e o
   bloco de baixo, que está ancorado ao fundo, reserva 72px em vez de 48.
   O par «& FCS Web Development» não parte por dentro. */
.footer-copyright__autor {
	white-space: nowrap;
}

@media (min-width: 430.02px) {
	.site-footer.site-footer--autoria-dupla {
		height: 469px;
	}
}

@media (max-width: 430px) {
	.site-footer.site-footer--autoria-dupla {
		--sda-rodape-direitos: 72px;
	}
}

/* Com duas linhas no computador, o contorno de foco de 2px com 2px de
   afastamento da ligação de baixo encostava às descendentes da linha de cima
   e lia-se como sublinhado dela; com 0 ainda se confundia. Fica 2px para
   dentro, e a ligação ganha 2px de margem interior dos lados (com a margem
   negativa a compensar, para o texto não se mexer), para o contorno cair na
   margem e não tapar a primeira e a última letra. No telemóvel as linhas têm
   mais espaço entre si e o contorno normal não toca na linha de cima. */
@media (min-width: 430.02px) {
	.site-footer--autoria-dupla .footer-copyright a:focus-visible {
		outline-offset: -2px;
		padding-inline: 2px;
		margin-inline: -2px;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5 — R33 (p.8), R40 (p.9) e R48 (p.10): ritmo vertical em
 * mobile, pela referência que o cliente desenhou na home
 * ------------------------------------------------------------ */

/* A referência está medida: fundo da imagem do dente-de-leão (1896) →
   topo de «Conheça as nossas Terapias» (1963) = 67px de canvas. É
   constante — a 360px de viewport dá 61,84 ÷ zoom 0,923 = 67,00. O
   ritmo da home inteira anda entre 67 e 71.

   O refluxo já dá a cada secção 28px de padding em cima e em baixo, o
   que rende 72px entre secções normais, dentro da banda; as fronteiras
   de secção do Quem Somos medem todas 72 e ficam como estão. Falham
   três sítios — e dois deles NÃO são fronteiras de secção, o que é a
   razão de não haver uma regra genérica que os apanhe. */
@media (max-width: 430px) {
	/* R40 — a Palestra Anual é a única secção full-bleed do site
	   refluído (varrimento de 16 páginas): a fotografia de fundo cobre
	   o próprio padding, por isso os 28px do refluxo ficam pintados por
	   baixo e não se vêem. Medido: 32px em cima, 28px em baixo. A folga
	   tem de ser margem, fora da caixa pintada. */
	body:not(.pagina-home-final) .site-content > .qs-palestra {
		/* 19 e não 39: o R37 esconde a imagem dos pássaros e promove a
		   da rapariga a último filho da secção anterior, e o R32 deu-lhe
		   `margin-bottom: 20px` — a secção já fecha com 48, não com 28.
		   Medido: com 39 dava 87. */
		margin-top: 19px;
		margin-bottom: 39px; /* 28 + 39 = 67, a referência exacta */
	}

	/* R33 — aqui a imagem FECHA um bloco e o título ABRE o seguinte,
	   dentro da mesma secção: é o mesmo par visual que o cliente mediu
	   na home, e media 24px contra os 67 de lá.
	   Regra pelo nome do título e não por `img + h2`: há 6 pares
	   imagem→título no site e em 5 deles a imagem PERTENCE ao título
	   que vem a seguir (as fotos das duas consultas, a pétala das
	   páginas de terapia, o banner da sidebar do blog). Uma regra
	   genérica corrigia este e partia os outros cinco. */
	body:not(.pagina-home-final) .site-content .qs-historia__titulo {
		/* 67 e não 43: assim que o R32 deu `display: block` à flor, a
		   margem dela (20px) passou a COLAPSAR com esta em vez de somar
		   aos 24px do gap de baseline do inline. Medido: com 43 dava 43. */
		margin-top: 67px;
	}

	/* R48 — em /terapias/ as duas consultas são irmãs planas dentro de
	   uma só secção, logo não há fronteira para o padding apanhar. O
	   separador media 40px contra os 16–24 do ritmo interno de cada
	   consulta, e por isso a foto do Tarot lia-se como parte do bloco
	   da Astrologia. Especificidade (0,4,1) para vencer o
	   `margin-bottom: 40px !important` da regra dos botões. */
	body:not(.pagina-home-final) .site-content .botao-principal.terapias-lista__botao--astrologia {
		margin-bottom: 67px !important;
	}

	/* Fora dos três pontos, apanhado no levantamento: a `.terapias-lista`
	   ainda traz 130px de margem inferior calibrados para o canvas de
	   1920, que a passagem anterior não apanhou. Somados aos 40 do botão
	   e aos 28 do padding davam 198px antes da newsletter, contra 115 na
	   home e 96 no Quem Somos. */
	body:not(.pagina-home-final) .site-content > .terapias-lista {
		margin-bottom: 47px;
	}

	/* Escadinha das listagens: a partir da terceira terapia ou do terceiro
	   curso, cada par de cartões é uma secção nova (sda_listagem_coluna()).
	   Em coluna, o padding das secções e a margem da lista das terapias
	   somavam-se entre linhas, e o terceiro cartão ficava mais afastado do
	   segundo do que o segundo do primeiro. Entre linhas tiro esse espaço e
	   dou ao botão do Tarot os 67px que o da Astrologia já tem (R48); a
	   última linha mantém o fecho de sempre antes da newsletter. */
	body:not(.pagina-home-final) .site-content > .terapias-lista:has(+ .terapias-lista),
	body:not(.pagina-home-final) .site-content > .actividades-lista:has(+ .actividades-lista) {
		margin-bottom: 0;
		padding-bottom: 0;
	}

	body:not(.pagina-home-final) .site-content > .terapias-lista + .terapias-lista,
	body:not(.pagina-home-final) .site-content > .actividades-lista + .actividades-lista {
		padding-top: 0;
	}

	body:not(.pagina-home-final) .site-content > .terapias-lista:has(+ .terapias-lista) .botao-principal.terapias-lista__botao--tarot {
		margin-bottom: 67px !important;
	}

	/* Com um número ímpar de terapias, a última linha tem só o cartão da
	   esquerda, e o botão dele é o último da linha: volta aos 40px de
	   todos os botões, para o fecho antes da newsletter ser o mesmo. */
	body:not(.pagina-home-final) .site-content > .terapias-lista .botao-principal.terapias-lista__botao--astrologia:last-child {
		margin-bottom: 40px !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R35 (PDF p.8) — «O que temos para si» com a estrutura
 * da home
 * ------------------------------------------------------------ */

/* O markup já era o certo: page-quem-somos.php tem a foto, o véu, o
   título, o texto e exactamente os mesmos três `.categoria-card` da
   home (diff literal contra front-page.php = zero diferenças). O que se
   perdia era só o CSS — em desktop a composição está de pé, mas o
   main.css não tem uma única regra para esta secção dentro do @media de
   430px, e por isso ela caía toda no refluxo genérico:
   `[class*="__fundo"] { display: none }` apagava a fotografia e o véu,
   e o interior dos cartões em fluxo devolvia o intrínseco de 860px aos
   ícones, limitado a 390 pelo `max-width: 100%` — três estampas de
   390x390 e uma secção de 1596px de altura.

   Reponho a composição do mock com as medidas do mobile da home, que é
   a referência que o cliente aponta: pastilha de 290x80 com o ícone a
   65x73 à esquerda e o rótulo a 20/36 à direita, passo de 88px. A foto
   acaba 128px acima do fim da pilha — metade dos 256px dos três
   módulos — para o segundo ficar a cavalo na aresta, como na home.

   Esta é a PRIMEIRA excepção à regra que esconde tudo o que casa com
   `[class*="__fundo"]`: aqui a «decoração» é o elemento estruturante da
   secção. `!important` é obrigatório — o refluxo pesa (0,12,1). */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .qs-o-que-temos {
		position: relative !important;
		height: auto !important;
		min-height: 0 !important;
		/* 23px laterais = os do resto da página; esta secção é a única
		   do Quem Somos sem `.seccao-inner`, que é onde eles vivem. */
		padding: 48px 23px 28px !important;
		/* O respiro exterior tem de ser MARGEM: com a fotografia em
		   absoluto a partir do topo da caixa, o padding fica pintado por
		   dentro dela e não conta como folga. Medido: sem estas duas, as
		   fronteiras com a História e com o Propósito caíam de 72 para
		   44 e 56. */
		margin-top: 23px;
		margin-bottom: 11px;
	}

	body:not(.pagina-home-final) .site-content .qs-o-que-temos__fundo,
	body:not(.pagina-home-final) .site-content .qs-o-que-temos__fundo-overlay {
		display: block !important;
		position: absolute !important;
		left: 0 !important;
		top: 0 !important;
		width: 100% !important;
		/* 156 = 28 do padding inferior + 128 de pilha a sobrar para fora. */
		height: calc(100% - 156px) !important;
		max-width: none !important;
		margin: 0 !important;
		z-index: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .qs-o-que-temos__fundo {
		object-fit: cover !important;
	}

	/* Conteúdo em fluxo pinta antes do que está posicionado: sem isto a
	   foto tapava o título e o texto. */
	body:not(.pagina-home-final) .site-content .qs-o-que-temos__titulo,
	body:not(.pagina-home-final) .site-content .qs-o-que-temos__paragrafo {
		position: relative !important;
		z-index: 1 !important;
	}

	body:not(.pagina-home-final) .site-content .qs-o-que-temos__titulo {
		margin: 0 0 16px !important;
	}

	body:not(.pagina-home-final) .site-content .qs-o-que-temos__paragrafo {
		margin: 0 0 40px !important;
	}

	/* Módulos: a pastilha do mobile da home, mesmo passo de 88px. */
	body:not(.pagina-home-final) .site-content .qs-o-que-temos .categoria-card {
		position: relative !important;
		z-index: 1 !important;
		display: block !important;
		box-sizing: border-box !important;
		width: 290px !important;
		height: 80px !important;
		margin: 0 auto 8px !important;
		padding: 0 !important;
		background: var(--cor-creme, #FFF5DE) !important;
		border-radius: 16px !important;
	}

	body:not(.pagina-home-final) .site-content .qs-o-que-temos .categoria-card--actividades {
		margin-bottom: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .qs-o-que-temos .categoria-card__icone {
		position: absolute !important;
		left: 18px !important;
		top: 4px !important;
		width: 65px !important;
		height: 73px !important;
		max-width: none !important;
		margin: 0 !important;
		object-fit: contain !important;
		mix-blend-mode: multiply !important;
	}

	body:not(.pagina-home-final) .site-content .qs-o-que-temos .categoria-card__rotulo {
		position: absolute !important;
		left: 98px !important;
		top: 22px !important;
		right: auto !important;
		bottom: auto !important;
		width: auto !important;
		margin: 0 !important;
		display: flex !important;
		align-items: center !important;
		justify-content: flex-start !important;
		font: 500 20px/36px var(--fonte-corpo, sans-serif) !important;
		letter-spacing: 0 !important;
		text-transform: uppercase !important;
		text-align: left !important;
		color: var(--cor-primaria, #A787A3) !important;
	}

	/* Como no mobile da home, onde a seta é `display: none`. A seta ao
	   lado do rótulo (R07) fica a valer só em desktop. */
	body:not(.pagina-home-final) .site-content .qs-o-que-temos .categoria-card__seta {
		display: none !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R32 (PDF p.8) e R36 (PDF p.9) — as duas fotografias do
 * Quem Somos à dimensão da imagem dourada da home
 * ------------------------------------------------------------ */

/* A referência que o cliente aponta é a imagem do dente-de-leão na home
   mobile: 205x304 de canvas, centrada. Sem regra mobile própria, o
   refluxo dava a estas duas `width: auto; height: auto` e o
   `max-width: 100%` deixava-as a ocupar os 344px do contentor com o
   rácio do ficheiro — medidos 344x443,5 e 344x407,7. Como o rácio de
   origem (0,776 e 0,844) é mais largo do que o da caixa de referência
   (0,674), o `object-fit: cover` corta as laterais: 15,4px de cada lado
   na flor, 25,7px na rapariga.

   ATENÇÃO ao nome, outra vez: `qs-proposito-passaros.jpg` é que mostra
   a RAPARIGA com flores. O alvo do R36 é o `--passaros`.

   `!important` em width/height/margens é a excepção documentada — o
   refluxo tem especificidade (0,11,1) e este selector chega a (0,3,1). */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .qs-historia__imagem--flor,
	body:not(.pagina-home-final) .site-content .qs-proposito__imagem--passaros {
		display: block;
		width: 205px !important;
		height: 304px !important;
		object-fit: cover;
		margin-left: auto !important;
		margin-right: auto !important;
		margin-bottom: 20px;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R26 e R27 (PDF p.6) — slider de testemunhos em mobile
 * ------------------------------------------------------------ */

/* Os dois pontos têm a mesma causa, e a causa é uma correcção nossa de
   DESKTOP que ficou sem media query: o `min-height: 506px` que demos ao
   card (o do Figma tem ~507 e o mock só dava 500) aplicava-se também a
   ≤430px, onde o desenho manda 399,5 — e `min-height` ganha sempre a
   `height`. O card esticava 106,5px, engolia os dots (ancorados à
   secção, aos 499) e o topo do módulo de classificação (560), acabando
   aos 576,5. Com o mesmo creme nas duas caixas, lia-se tudo como um
   bloco só: daí «os botões do slider têm de estar fora do módulo» (R27)
   e «falta margem entre o slider e o módulo da classificação» (R26).
   Reposto o valor do desenho, o card acaba aos 470, os dots ficam aos
   499 (29px de folga) e o módulo aos 560 — 48px depois dos dots. */
@media (max-width: 430px) {
	.pagina-home-final .seccao-testemunhos__card {
		min-height: 0;
		height: 399.5px;
	}

	/* Nas páginas sem desenho mobile próprio (terapia, curso) os dots
	   são <button> vazios e o refluxo colapsa-os a 0x0: o slider está
	   ligado mas não há alvo para o dedo. Os 24/48px repetem o ritmo do
	   desenho mobile da home, para o R26 ficar resolvido também aqui,
	   onde o módulo começava no mesmo y dos dots. */
	body:not(.pagina-home-final) .site-content .seccao-testemunhos__dot {
		width: 13px !important;
		height: 13px !important;
		flex: 0 0 13px;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__paginacao {
		justify-content: center;
		gap: 7.5px;
		margin-top: 24px;
		margin-bottom: 48px;
	}

	/* Área de toque de 29px sem mexer nos 13px do desenho (WCAG 2.5.8). */
	.seccao-testemunhos__dot {
		position: relative;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__dot {
		position: relative !important;
	}

	/* O fundo mobile apontava a um .png que não existe no repo — 404
	   medido. A regra que o re-aponta para o .jpg tinha especificidade
	   (0,1,0) e perdia para os (0,2,0) do mock. */
	.pagina-home-final .seccao-testemunhos--home {
		background-image: url("../img/site/hm-testemunhos-fundo.jpg");
	}
}

/* ------------------------------------------------------------
 * Header colado em mobile
 * ------------------------------------------------------------ */

/* Achado ao medir a revisão v5, e não está na lista do cliente — mas é
   a razão por que NENHUM print de telemóvel dele tem header. O
   `.site-header` é `position: sticky; top: 0`, e em desktop cola. A
   ≤430px não colava: medido, a scrollY=600 o header ia a y=-600 em
   todas as páginas.

   A causa é o `body { overflow-x: hidden }` do mock (main.css, dentro
   do @media de 430px). Um `overflow` diferente de `visible` num eixo
   faz o outro computar para `auto`, o que transforma o body num
   contentor de scroll — e o sticky passa a colar ao scrollport do
   body, que não scrolla, em vez de colar ao viewport.

   `clip` recorta na mesma mas NÃO cria contentor de scroll. O `<html>`
   já usa esta técnica mais acima. Browsers sem suporte a `clip`
   descartam a declaração e ficam com o `hidden` do mock — degradam
   para o comportamento actual, sem scroll horizontal.

   Medido depois em /, /quem-somos/ e /loja/ a 360, 390 e 430: header a
   y=0 com a página a 600 de scroll, `documentElement` da largura do
   ecrã, e zero scroll horizontal. */
@media (max-width: 430px) {
	body {
		overflow-x: clip;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R63 a R70 (PDF p.14 e p.15) — cartão de actividade
 * em mobile
 * ------------------------------------------------------------ */

/* R69 e R70 não são pontos novos: são o R64 e o R65 outra vez, no
   cartão da secção «Próximas Actividades». O cartão é um componente
   único (template-parts/card-actividade.php) instanciado três vezes,
   todas em /actividades/ — duas na lista e uma nas próximas. Uma regra
   por defeito resolve os quatro pontos.

   R63/R68 — os 4px entre a imagem e o título não são margem nenhuma: o
   refluxo tira o `position: absolute` à fotografia e ela volta a ser um
   `<img>` inline assente na linha de base de um `<a>` inline; o que se
   vê é o vão do descendente. Margens verticais em caixas inline não
   afectam o layout, por isso passam os dois a bloco — aí o vão
   desaparece e ficariam 0px — e só depois se dá a folga. 20px é o valor
   do cartão mobile do mock na home.
   A margem vai no `<a>` e NÃO na imagem: se ambos a levassem,
   colapsavam e o resultado era 20 na mesma — foi assim que duas frentes
   do diagnóstico chegaram a 24 e a 20 e se anularam em silêncio. */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .card-actividade > a:not(.card-actividade__saber-mais),
	body:not(.pagina-home-final) .site-content .card-actividade__imagem {
		display: block;
	}

	body:not(.pagina-home-final) .site-content .card-actividade > a:not(.card-actividade__saber-mais) {
		margin-bottom: 20px;
	}

	/* R64/R69 — o intervalo título→formador media 18px, mais do que o
	   ritmo interno do cartão. */
	body:not(.pagina-home-final) .site-content .card-actividade__titulo {
		margin-bottom: 8px;
	}

	/* R65/R70 — a data, o ícone do formato e o texto do formato saíam
	   colados («11 Out 2025[icone]Online e Presencial»): o mock põe cada
	   um em absoluto com `left` do canvas de 1920 e o refluxo deixa-os
	   em fluxo inline sem espaço nenhum.
	   `row-gap` explícito e NUNCA o atalho `gap`: o atalho reescreve o
	   row-gap e o valor passaria a depender da ordem no ficheiro — com
	   uma data mais comprida, 14px de altura de cartão decididos por
	   qual bloco foi colado primeiro. */
	body:not(.pagina-home-final) .site-content .card-actividade__meta {
		flex-wrap: wrap;
		column-gap: 22px;
		row-gap: 8px;
	}

	body:not(.pagina-home-final) .site-content .card-actividade__meta-item {
		gap: 14px;
	}

	body:not(.pagina-home-final) .site-content .card-actividade__meta-item--formato {
		gap: 12px;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R66 e R67 (PDF p.15) — «Próximas Actividades»
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* R66 — tem de ser PADDING e não margem. Esta é a única secção da
	   página com fundo próprio (véu branco a 40% sobre a textura do
	   body) e o «limite da secção» que o cliente aponta é a aresta desse
	   véu: uma margem ficava do lado de fora dela e a distância medida
	   não mudava um pixel. Medido: 28 → 67, a referência da home.
	   NOTA para quem vier depois: a aresta do véu tem 1,4% de diferença
	   de luminância contra a textura, ou seja é quase imperceptível num
	   screenshot. Fica registado que estes 39px extra dependem de uma
	   aresta que quase não se vê; se o cliente achar excessivo, é este
	   número que se baixa. */
	body:not(.pagina-home-final) .site-content > .proximas-actividades {
		padding-top: 67px;
	}

	/* R67 — os 16px não vinham da secção: vinham do ritmo genérico do
	   refluxo (`h2 { margin: 0 0 16px }`). 32 é o mesmo valor que o
	   R41/R46 fixou para o par «texto → elemento seguinte» em mobile.
	   Margem no título e não no cartão, porque o cartão é partilhado com
	   a lista, onde não há h2. */
	body:not(.pagina-home-final) .site-content .proximas-actividades__titulo {
		margin-bottom: 32px;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R50 (PDF p.11) e R51 (PDF p.12) — as duas fotografias
 * da página da Consulta, em mobile
 * ------------------------------------------------------------ */

/* R50 — a pétala é a metade esquerda de uma composição de duas colunas
   no canvas de 1920. Em mobile o refluxo empilha tudo, a composição
   desaparece, e ela passa a ser 419px de decoração pura ANTES do título
   da secção: 443px de scroll até ao primeiro texto útil. Escondida, à
   maneira das outras (por CSS, reversível numa linha).

   R51 — a imagem da rapariga com o véu não tem uma única regra em
   mobile: o refluxo dá-lhe `width: auto; max-width: 100%` e ela resolve
   para 344x471, 73% da altura de um ecrã de 390x844. Passa à referência
   que o cliente aponta, o dente-de-leão da home mobile: 205x304
   centrada. O `object-fit: cover` corta 8,52px de cada lado (o rácio
   nativo é 0,7304 contra 0,6743 da caixa) — verificado que a cara e a
   mão ficam inteiras.

   Vale para as duas páginas de consulta, que partilham a composição.
   Na do Tarot as fotografias são outras (uma bússola e uma magnólia,
   com os nomes de ficheiro trocados — ver o comentário no template).

   `!important` só onde é preciso: o `display: none` passa sem ele (o
   refluxo não declara `display`), mas `width`/`height`/margens laterais
   são impostos pelo refluxo e precisam. */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .terapia-sobre-consulta__petala {
		display: none;
	}

	body:not(.pagina-home-final) .site-content .terapia-sobre-consulta__veu {
		display: block;
		width: 205px !important;
		height: 304px !important;
		object-fit: cover;
		margin-left: auto !important;
		margin-right: auto !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R56 (PDF p.13) — cartão de testemunhos nas páginas
 * sem desenho mobile próprio
 * ------------------------------------------------------------ */

/* Medido: nada sai da caixa do cartão. O que se perdeu foi a GOTEIRA —
   o desenho fá-la só com `left`/`top` absolutos, o cartão nunca teve
   `padding`, e o refluxo põe tudo em `static; width: auto; height: auto`.
   Daí a foto a 128x128 (tamanho intrínseco do PNG) encostada ao vértice,
   o texto com 344 de largura a tocar os dois bordos, o logótipo Google
   na mesma linha das estrelas, e o módulo de classificação reduzido a
   uma tira de 36px em vez dos 184 do desenho.

   Repõe-se o cartão como bloco de contenção em fluxo e devolvem-se aos
   filhos as coordenadas do ÚNICO desenho mobile que existe para este
   componente — o da home. `!important` é a excepção documentada. */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .seccao-testemunhos__card {
		position: relative !important;
		height: 399.5px !important;
		min-height: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__foto {
		position: absolute !important;
		left: 33px !important;
		top: 39px !important;
		width: 64px !important;
		height: 64px !important;
		margin: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__nome {
		position: absolute !important;
		left: 103px !important;
		top: 37px !important;
		margin: 0 !important;
		white-space: nowrap !important;
		font: 600 18px/36px var(--fonte-corpo, sans-serif);
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__data {
		position: absolute !important;
		left: 104px !important;
		top: 68px !important;
		margin: 0 !important;
		white-space: nowrap !important;
		font: 500 14px/16px var(--fonte-corpo, sans-serif);
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__google {
		position: absolute !important;
		left: 252px !important;
		top: 68.5px !important;
		width: 59px !important;
		height: 18.5px !important;
		margin: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__estrelas {
		position: absolute !important;
		left: 33px !important;
		top: 120px !important;
		width: 93.7px !important;
		height: 17.5px !important;
		margin: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__texto {
		position: absolute !important;
		left: 33px !important;
		top: 151px !important;
		width: 277px !important;
		margin: 0 !important;
		font: 400 16px/26px var(--fonte-corpo, sans-serif);
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__avaliacoes {
		position: relative !important;
		height: 184px !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__rating {
		position: absolute !important;
		left: 96.8px !important;
		top: 28.5px !important;
		font: 600 26px/36px var(--fonte-corpo, sans-serif);
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__avaliacoes-estrelas {
		position: absolute !important;
		left: 144px !important;
		top: 35px !important;
		width: 106.7px !important;
		height: 22px !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__avaliacoes-texto {
		position: absolute !important;
		left: 91.4px !important;
		top: 63.5px !important;
		white-space: nowrap !important;
		font: 500 16px/26px var(--fonte-corpo, sans-serif);
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__avaliacoes-google {
		position: absolute !important;
		left: 203.6px !important;
		top: 69px !important;
		width: 51.6px !important;
		height: 16.2px !important;
	}

	/* Hoje o botão não é impresso (falta o URL das avaliações Google).
	   A regra fica preparada: o selector tem (0,4,1) e ganha ao bloco
	   genérico de botões, que é (0,3,1) e imporia 251x61 centrado. */
	body:not(.pagina-home-final) .site-content .seccao-testemunhos__avaliacoes .seccao-testemunhos__avaliacoes-botao {
		position: absolute !important;
		left: 34px !important;
		top: 102px !important;
		width: 277.5px !important;
		height: 50px !important;
		min-height: 50px !important;
		margin: 0 !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R60 (PDF p.14) — hierarquia da citação da Consulta
 * ------------------------------------------------------------ */

/* O cliente pede para trocar os tamanhos da citação e do autor. Medido:
   em desktop a hierarquia está certa (citação 42/52, autor 24/96 — a
   citação é 1,75x o autor); a ≤430px inverte-se para 0,67x. Reponho a
   ordem pelos degraus que o mobile já usa: 24/32 na citação (o do H3) e
   16/26 no autor (o do corpo, já na regra acima). */
@media (max-width: 430px) {
	/* A goteira de 23px vem do `.seccao-inner`, e esta secção não tem um
	   (o markup é section > figure > blockquote > p). Medido, a citação
	   corria de L2,4 a R387,6 — já hoje encosta ao bordo, e a 24px
	   ficaria a 8px dele. */
	body:not(.pagina-home-final) .site-content .terapia-citacao {
		box-sizing: border-box;
		padding-left: 23px;
		padding-right: 23px;
	}

	body:not(.pagina-home-final) .site-content .terapia-citacao__texto {
		font-size: 24px;
		line-height: 32px;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R21 (PDF p.5) — botões com a seta à frente
 * ------------------------------------------------------------ */

/* Report do Francisco: «o texto do botão Ver Loja não está alinhado».
   A correcção anterior não pegou, e a razão é estrutural: `.botao-lista`
   é `inline-block` (blockificado para `block`, porque as três
   instâncias são absolutas) e tanto o `<span>` do texto como o `<img>`
   da seta estão eles próprios em `position: absolute`, ancorados a
   `left: 35px` e `right: 34px`. Um `justify-content` num elemento que
   não é contentor flex é declaração morta, e filhos absolutos nunca
   entram no alinhamento flex. Era a única declaração de
   `justify-content` morta do site.

   O que se via: texto à esquerda, seta à direita e um buraco variável
   pelo meio — 39,9px em «Ver Loja», 19,7 em «Descobrir», 19,0 em «Ver
   Todos». Em «Ver Loja» o texto acabava aos 117 de um botão de 210: 93px
   quase vazios à direita contra 35 à esquerda.

   Passa a flex a sério, com os filhos de volta ao fluxo. `gap: 20px` é
   o buraco que o próprio desenho já dá aos dois rótulos mais longos, por
   isso em desktop só «Ver Loja» se mexe; os outros dois mudam menos de
   1px.

   `align-items: center` resolve de caminho o desalinhamento VERTICAL do
   mobile: a ≤430px a altura do botão cai de 61 para 50 mas os `top`
   absolutos continuam calibrados para os 61, e o conteúdo assentava 6px
   abaixo do centro (13 em cima, 1 em baixo). Passa a 7/7. */
.botao-lista {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 20px;
}

.botao-lista span,
.botao-lista img {
	position: static;
	left: auto;
	right: auto;
	top: auto;
	bottom: auto;
}

/* ------------------------------------------------------------
 * Separador ↔ texto em mobile (report do Francisco)
 * ------------------------------------------------------------ */

/* O separador das páginas de terapia não é um elemento: é o `border-top`
   do próprio `<article>` do conteúdo. Em desktop o artigo é absoluto e o
   `<h3>` que vem a seguir também tem coordenada própria, por isso o
   desenho abre 47 a 67px entre a linha e o rótulo. A ≤430px o refluxo põe
   os dois em `static` e o `<h3>` passa a ser o primeiro filho em fluxo de
   um bloco com borda no topo e sem padding: medido, 0px de caixa e 8,4px
   de tinta — e esses 8,4 não são folga nenhuma, são a meia-entrelinha do
   próprio rótulo.

   `padding-top` e não `margin-top` para o lado de dentro: como a linha é
   a BORDA do bloco, uma margem empurrava a linha para baixo junto com o
   rótulo e não abria nada entre os dois. O `margin-top` serve o outro
   lado e colapsa com os 16px do parágrafo anterior, por isso a página
   cresce 32 por item e não 48.

   32 é o passo que o mobile já usa entre bloco de texto e botão, fica
   entre os 16 dos parágrafos e os 67 das secções, e está na grelha de 8.

   É o único separador do site desenhado como borda de um bloco sem
   padding próprio — o do FAQ usa o mesmo padrão mas já traz
   `padding: 48.5px 0 43px`, que sobrevive ao refluxo. É por isso que o
   FAQ está bem e este não estava. */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .terapia-como-funciona__item {
		margin-top: 32px;
		padding-top: 32px;
	}
}

/* ------------------------------------------------------------
 * O coração dos favoritos em mobile (report do Francisco)
 * ------------------------------------------------------------ */

/* Report: «coração na lista de desejos está mal — verificar todos os
   casos onde este aparece». O inventário deu quatro classes e o estado
   em mobile era pior do que o do print de desktop: nos cartões da loja,
   do blog e do artigo o refluxo tirava-lhes o `position` e o círculo de
   40px virava uma ELIPSE de 30x23 solta entre a foto e a faixa; na
   ficha do produto ficava 22x25 com a imagem a transbordar.

   Uma regra só, de propósito: dois diagnósticos independentes propuseram
   selectores iguais com valores diferentes — um dava `display` sem
   `position`, o outro `position` sem `display` — e, consoante a ordem em
   que fossem colados, um anulava o outro em silêncio e o defeito voltava.

   18x18 na imagem porque o SVG tem `preserveAspectRatio="none"` e uma
   caixa não-quadrada estica o desenho; era por isso que, lado a lado, os
   corações não pareciam o mesmo ícone.

   `!important` verificado por remoção: sem ele o botão volta a 30x23
   estático. */
@media (max-width: 430px) {
	/* Ficha do produto: o círculo colapsava para 22x25. */
	body:not(.pagina-home-final) .site-content .produto-ficha__favorito {
		display: inline-flex !important;
		align-items: center;
		justify-content: center;
		width: 44px !important;
		height: 44px !important;
	}

	body:not(.pagina-home-final) .site-content .produto-ficha__favorito img {
		width: 20px !important;
		height: 20px !important;
	}

	/* Lista de desejos em telemóvel: o coração media 0x0 a x=498 num ecrã
	   de 390 — não havia forma de remover um item da lista. A causa NÃO
	   era a linha de acções (foi essa a primeira leitura, e estava
	   errada): é a foto do produto, com `flex: 0 0 220px` inencolhível,
	   que empurra a coluna de informação para x=275 e deixa 115px úteis.
	   A linha passa a poder quebrar e a foto a 120px. */
	body:not(.pagina-home-final) .site-content .conta-desejos__item {
		flex-wrap: wrap !important;
		gap: 16px !important;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__imagem-link {
		flex: 0 0 120px !important;
		width: 120px !important;
		height: auto !important;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__imagem {
		width: 120px !important;
		height: 120px !important;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__remover {
		flex: 0 0 44px;
		width: 44px;
		height: 44px !important;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__remover img {
		width: 20px !important;
		height: 20px !important;
	}

	/* Com a linha já a caber, sobravam dois apertos: o botão outline
	   ficava com 176x34 e o rótulo de duas linhas transbordava-o (medido
	   scrollHeight 35 contra clientHeight 32), e o stepper media 76x26,
	   abaixo do mínimo de toque. Os dois passam a abraçar o conteúdo com
	   respiro e 44px de altura de toque. */
	body:not(.pagina-home-final) .site-content .conta-desejos__carrinho {
		height: auto !important;
		min-height: 44px !important;
		padding: 8px 16px !important;
		line-height: 20px !important;
		text-align: center;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__stepper {
		gap: 12px;
		min-height: 44px !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R74 e R75 (PDF p.16) — a coluna de informação do
 * curso em mobile
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* R74 — `.curso-sidebar__titulo` é um <h3> e o valor do desenho
	   (22px/30) vive num selector de uma só classe, (0,1,0). Perde para
	   a escala genérica `.site-content h3 { font-size: 24px }`, que vale
	   (0,2,2) — o mesmo desencontro do R52. Medido: os cinco subtítulos
	   ficavam a 24px, 2px MAIORES do que em desktop, e o rácio contra o
	   valor ao lado subia de 1,00 para 1,50. Eram o único elemento da
	   barra a crescer do computador para o telemóvel.
	   A referência que o cliente deu é o «Como funciona» da página da
	   consulta — o R52. Este ficou nos 18 que o R52 tinha na altura, mas
	   depois o Francisco reabriu o R52 e subiu-o para 20/28, que é o
	   limite do que o cliente autorizara. Este acompanha: o ponto pede
	   explicitamente que os dois tenham o mesmo tamanho, e ficar em 18
	   deixava-os a divergir 2px. */
	body:not(.pagina-home-final) .site-content h3.curso-sidebar__titulo {
		font-size: 20px;
		line-height: 28px;
	}

	/* R75 — o ícone tinha tamanho absoluto e o texto tamanho relativo ao
	   ecrã: 32 contra 22 em desktop (1,45) passavam a 32 contra 16 em
	   mobile (2,00). Quem pinta os 32px em mobile não é o main.css — é o
	   `width/height: auto` do refluxo a deixar o tamanho intrínseco do
	   SVG; daí o `!important`.
	   Os SVG têm `preserveAspectRatio="none"`, portanto um par fora do
	   rácio ESTICA a arte: os valores do pin e da câmara não são
	   arredondados à sorte, são 22 x (14,5455/32) = 10 e
	   22 x (20,3636/32) = 14, exactos. */
	body:not(.pagina-home-final) .site-content .curso-sidebar .curso-sidebar__icone {
		width: 22px !important;
		height: 22px !important;
	}

	body:not(.pagina-home-final) .site-content .curso-sidebar .curso-sidebar__icone--pin {
		width: 10px !important;
		height: 22px !important;
		margin-left: 6px !important;
	}

	body:not(.pagina-home-final) .site-content .curso-sidebar .curso-sidebar__icone--camera {
		width: 22px !important;
		height: 14px !important;
	}

	/* A coluna dos ícones foi calibrada para 32px (43 − 32 = 11 de vão).
	   Com ícones de 22 o vão passaria a 21 e eles ficavam a flutuar longe
	   do texto. 33px devolve os mesmos 11 de desktop, e verifiquei que
	   não muda uma única quebra de linha. */
	body:not(.pagina-home-final) .site-content .curso-sidebar-coluna .curso-sidebar {
		grid-template-columns: 33px 1fr;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R87 (PDF p.19) — cartão de artigo, paginação e campo
 * de pesquisa do blog, em mobile
 * ------------------------------------------------------------ */

/* Mesma causa de sempre: o mock faz a goteira só com `left`/`top`
   absolutos, o cartão nunca teve `padding`, e o refluxo põe tudo em
   `static; width: auto` — os filhos encostam aos bordos e as imagens
   voltam ao tamanho intrínseco.

   Os números não são inventados: os 21px de goteira, os 216px de altura
   de imagem (344 x 214/341) e os 20px de imagem→texto saem todos do
   cartão de blog da HOME no bloco @430 do main.css, que é o único
   desenho mobile que existe para este componente. Os 64px do separador
   e os 32 de data→fundo são os do desktop, inalterados.

   A ordem importa e está reflectida aqui: o `display: block` no link da
   imagem entra ANTES da margem, senão a folga de baseline do inline
   (4px) somava-se e o valor deixava de ser determinístico. */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .seccao-artigos-card-categoria,
	body:not(.pagina-home-final) .site-content .seccao-artigos-card-titulo,
	body:not(.pagina-home-final) .site-content .seccao-artigos-card-excerto,
	body:not(.pagina-home-final) .site-content .seccao-artigos-card-ler-mais,
	body:not(.pagina-home-final) .site-content .seccao-artigos-card-separador,
	body:not(.pagina-home-final) .site-content .seccao-artigos-card-meta {
		margin-left: 21px !important;
		margin-right: 21px !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-card > a:first-child {
		display: block;
		margin-bottom: 20px;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-card-imagem {
		display: block;
		width: 100% !important;
		height: 216px !important;
		object-fit: cover;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-card-categoria {
		display: block;
		box-sizing: border-box;
		width: max-content !important;
		max-width: calc(100% - 42px) !important;
		margin-bottom: 10px;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-card-titulo {
		font-size: 20px;
		line-height: 28px;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-card-ler-mais {
		display: flex;
		width: max-content !important;
		margin-top: 24px;
		font-size: 16px;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-card-separador {
		width: 64px !important;
		margin-top: 24px;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-card-meta {
		margin-top: 16px;
		margin-bottom: 8px;
	}

	/* Paginação: 36px e não os 32 da loja — a 32 sobravam 3px entre o
	   algarismo de 22 e o anel de 2px, e o círculo lia-se apertado (é a
	   queixa do R109 noutra página). A 36 sobram 7, e os sete itens
	   continuam a caber (312 de 344). */
	body:not(.pagina-home-final) .site-content .seccao-artigos-paginacao {
		flex-wrap: wrap;
		column-gap: 10px;
		row-gap: 8px;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-paginacao-numero,
	body:not(.pagina-home-final) .site-content .seccao-artigos-paginacao-seguinte {
		display: inline-flex !important;
		align-items: center;
		justify-content: center;
		width: 36px !important;
		height: 36px !important;
		box-sizing: border-box;
	}

	/* Pesquisa: a lupa é absoluta e, sem `position` no contentor,
	   ancorava fora da pastilha. */
	body:not(.pagina-home-final) .site-content .seccao-sidebar__pesquisa {
		position: relative !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__pesquisa-campo {
		width: 100% !important;
		height: 53px !important;
		box-sizing: border-box;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__pesquisa-icone {
		position: absolute !important;
		left: 18px !important;
		top: 17.5px !important;
		width: 18px !important;
		height: 18px !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R87 e R88 (PDF p.19) — barra lateral do blog em mobile
 * ------------------------------------------------------------ */

/* Vale para a listagem, o artigo e o arquivo de categoria, que
   partilham o mesmo partial. */
@media (max-width: 430px) {
	/* «Recentes»: o refluxo tira `width/height` à miniatura e, com
	   `max-width: 100%`, ela resolve a largura ao contentor (344) e a
	   altura pela razão dos atributos HTML — 344x442. Reposta a linha do
	   desenho (miniatura à esquerda, texto à direita) com grelha e não
	   flex, porque o cartão não tem wrapper de texto e um flex punha
	   meta, título e «ler mais» lado a lado. */
	body:not(.pagina-home-final) .site-content .seccao-sidebar__recente {
		display: grid !important;
		grid-template-columns: 109px minmax(0, 1fr);
		grid-template-rows: auto auto auto;
		column-gap: 20px;
		width: 100% !important;
		min-height: 140px !important;
		padding-right: 16px !important;
		box-sizing: border-box !important;
		/* O canto direito da foto é quadrado e pintava por cima do canto
		   arredondado do cartão. */
		overflow: hidden;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__recente-link {
		grid-column: 1;
		grid-row: 1 / -1;
		display: block !important;
		width: 109px !important;
		height: 100% !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__recente-miniatura {
		width: 109px !important;
		height: 100% !important;
		max-width: none !important;
		margin: 0 !important;
		object-fit: cover;
	}

	/* 14px e não 16: a 16 a linha «19 Maio, 2026 . 4 Comentários» pede
	   221,5px e a coluna de texto tem 199 — quebrava sempre em duas. */
	body:not(.pagina-home-final) .site-content .seccao-sidebar__recente-meta {
		grid-column: 2;
		font-size: 14px;
		line-height: 22px;
		margin: 11px 0 4px !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__recente-titulo {
		grid-column: 2;
		margin: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__recente-ler-mais {
		grid-column: 2;
		justify-self: start;
	}

	/* Banner «Terapias»: o ficheiro da constelação é @2x (180x180) para
	   um desenho de 90x90 — sem `width` explícita voltava ao intrínseco
	   e pintava ao dobro. */
	body:not(.pagina-home-final) .site-content .seccao-sidebar__banner-terapias {
		display: grid !important;
		grid-template-columns: 90px minmax(0, 1fr);
		grid-template-rows: auto auto;
		column-gap: 16px;
		align-content: start;
		width: 100% !important;
		padding: 24px !important;
		box-sizing: border-box !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__banner-imagem {
		grid-column: 1;
		grid-row: 1 / -1;
		width: 90px !important;
		height: 90px !important;
		max-width: none !important;
		margin: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__banner-texto {
		grid-column: 2;
		margin: 8px 0 0 !important;
	}

	/* R88 — mesma causa e mesma correcção do bloco «Palestra Anual» do
	   Quem Somos: o refluxo tirava o `position` à fotografia, ela caía
	   para o fluxo no topo, e os textos creme e brancos aterravam sobre
	   a textura da página. Medido: 1,00:1 no título creme e 1,085:1 nos
	   brancos, contra os 4,5:1 que a WCAG 2.1 AA exige. A foto e o
	   filtro voltam a cobrir o cartão e o texto sobe por cima — sem o
	   `z-index` a foto tapava tudo, porque elementos posicionados pintam
	   depois do conteúdo em fluxo. */
	body:not(.pagina-home-final) .site-content .seccao-sidebar__card-palestra {
		position: relative !important;
		width: 100% !important;
		height: auto !important;
		min-height: 0 !important;
		padding: 48px 24px !important;
		box-sizing: border-box !important;
		overflow: hidden;
		text-align: center;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-foto,
	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-overlay {
		position: absolute !important;
		left: 0 !important;
		top: 0 !important;
		width: 100% !important;
		height: 100% !important;
		max-width: none !important;
		margin: 0 !important;
		z-index: 0;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-foto {
		object-fit: cover;
	}

	/* A 1920 o véu cobre só os 242 de cima dos 484, porque é lá que o
	   texto vive. Em mobile o texto ocupa o cartão todo, por isso o
	   gradiente estica e nunca chega a transparente. */
	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-overlay {
		background: linear-gradient(180deg, rgba(59, 58, 58, 0.85) 0%, rgba(59, 58, 58, 0.55) 100%) !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-titulo,
	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-subtitulo,
	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-orador,
	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-data-formato,
	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-botao {
		position: relative !important;
		z-index: 1;
	}

	/* Hierarquia — mesma armadilha do R38: a escala genérica mobile
	   achata os três <p> para 16px e o cartão fica sem ordem. Reposta a
	   do desktop (42/30/18/16 → 32/20/16/16). 32 e não os 38 do Quem
	   Somos porque aqui a caixa útil é 296px. */
	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-titulo {
		font-size: 32px;
		line-height: 40px;
		margin: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-subtitulo {
		font-size: 20px;
		line-height: 28px;
		margin: 4px 0 0 !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-orador {
		font-size: 16px;
		line-height: 26px;
		margin: 8px 0 0 !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-data-formato {
		font-size: 16px;
		line-height: 26px;
		flex-wrap: wrap;
		gap: 10px;
		margin: 8px 0 0 !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-ponto {
		flex: 0 0 auto !important;
		width: 6px !important;
		height: 6px !important;
	}

	/* Quatro classes de propósito: a regra genérica de botões impõe
	   `margin-bottom: 40px !important` com (0,3,1). Com três classes
	   ficava empate e a ordem no ficheiro decidia. */
	body:not(.pagina-home-final) .site-content .seccao-sidebar__card-palestra .seccao-sidebar__palestra-botao {
		display: inline-flex;
		margin-top: 32px;
		margin-bottom: 0 !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R77, R79, R81, R83 e R84 (PDF pp. 16–18) — margens da
 * página de curso em mobile
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* R77 — o botão é o ÚLTIMO elemento da coluna lateral: a folga
	   genérica de 40px estava a SOMAR-SE à fronteira de secção em vez de
	   a substituir. Zerada, sobram os 68 da secção, que é a referência.
	   `!important` porque a regra genérica também o tem; (0,4,1) vence. */
	body:not(.pagina-home-final) .site-content .curso-sidebar .curso-sidebar__botao {
		margin-bottom: 0 !important;
	}

	/* R79 — folga INTERIOR, e é interior porque o fundo é `cover` na
	   própria secção e pinta por dentro do padding. Os 110/130 são 5,7% e
	   6,8% de um canvas de 1920, mas 28% e 33% de um de 390. A folga
	   exterior fica onde está: 68 em cima, 67 em baixo pelo R81. */
	body:not(.pagina-home-final) .site-content .curso-como-funciona {
		padding-top: 55px;
		padding-bottom: 65px;
	}

	/* R81 — o desenho tem lá 121 e o desktop mede 122,3; em mobile o
	   `h2 { margin: 0 0 16px }` do refluxo mata o margin-top. A margem
	   colapsa para fora do `.seccao-inner` que embrulha o título (div sem
	   padding nem borda) e dá exactamente a fronteira certa. */
	body:not(.pagina-home-final) .site-content .curso-estrutura-curso-titulo {
		margin-top: 67px;
	}

	/* R83 + R84 — o mesmo intervalo visto de dois tipos de painel. Seis
	   valores medidos (4, 20, 30, 60, 72, 76) para a mesma relação.
	   Unificados em 38, metade exacta dos 76 que o cliente mediu.

	   (a) O `<p>` do bloco de texto fica com a margem presa dentro do
	   `.curso-estrutura__texto` nos painéis em grelha (grid item é BFC).
	   Anulada — mas só quando o bloco tem quem se lhe siga: no ÚLTIMO
	   bloco do painel essa margem é o que separa a Estrutura do panorama,
	   e sem o `:not(:last-child)` essa fronteira caía de 54 para 38. */
	body:not(.pagina-home-final) .site-content .curso-estrutura-painel .curso-estrutura__texto:not(:last-child) > p:last-child {
		margin-bottom: 0;
	}

	/* (b) A folga rótulo → texto passa do rótulo para o texto. Em grelha
	   as margens não colapsam e os 12 do rótulo somavam-se aos do
	   separador nos capítulos sem conteúdo. Em `margin-top` do texto vale
	   12 nos dois regimes. */
	body:not(.pagina-home-final) .site-content .curso-estrutura-painel .curso-estrutura__rotulo {
		margin-bottom: 0;
	}

	body:not(.pagina-home-final) .site-content .curso-estrutura-painel .curso-estrutura__texto {
		margin-top: 12px;
	}

	/* (c) O separador passa a ser o único responsável pela folga.
	   ARMADILHA, e a razão de ser 34 e não 17+17: o refluxo impõe
	   `height: auto` e o separador fica um bloco VAZIO. Um bloco vazio é
	   self-collapsing — nos painéis desenhados, que estão em fluxo de
	   blocos, `margin: 17px 0` colapsa nele próprio e dá 17, não 34; nos
	   painéis em grelha não colapsa e dá 34. Com a margem toda em cima dá
	   34 nos dois. */
	body:not(.pagina-home-final) .site-content .curso-estrutura-painel .curso-estrutura__separador {
		display: block;
		margin: 34px 0 0;
	}
}

/* ------------------------------------------------------------
 * Cartão de produto em mobile: goteira interior e grelha dos
 * relacionados (report do Francisco)
 * ------------------------------------------------------------ */

/* O cartão da HOME tem desenho mobile próprio e dá 12px de goteira
   interior à faixa. Nas páginas refluídas — loja, blog, artigo,
   carrinho, obrigado — a goteira era ZERO: o nome e o preço encostavam
   ao bordo esquerdo e o ícone do carrinho ao direito. Estava assim
   desde a migração; o `margin-left: auto` que dei hoje ao ícone só o
   tornou visível.

   E na secção de produtos relacionados havia um segundo problema: a
   grelha ficava numa só coluna e o cartão esticava para 344px, quando o
   desenho mobile do componente está calibrado para 166 — o nome corria
   de bordo a bordo em três linhas. Passa a duas colunas, como a loja. */
@media (max-width: 430px) {
	/* REVISÃO v5, R98 (PDF p.21) e R114 (PDF p.25) — «os produtos
	   relacionados devem ser um slider como o da home, em todas as
	   páginas com esta secção». A secção é escrita em QUATRO ficheiros
	   (o partial do blog/artigo/arquivos, a ficha de produto, o carrinho
	   e o obrigado) mas todos produzem o mesmo markup, por isso um
	   selector chega aos quatro. Passo de 178px, o mesmo da home. */
	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados__grelha {
		display: flex;
		flex-direction: row;
		align-items: start;
		gap: 12px;
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scroll-snap-type: x mandatory;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
	}

	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados__grelha::-webkit-scrollbar {
		display: none;
	}
	/* O refluxo dá `width/height: auto` ao `.screen-reader-text` que o
	   WooCommerce mete dentro do preço em promoção, e ele fica com 58px
	   reais. Em coluna era invisível; numa pista com `overflow-x: auto`
	   passava a scroll fantasma. */
	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados__grelha .screen-reader-text {
		position: absolute !important;
		width: 1px !important;
		height: 1px !important;
		margin: -1px !important;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap !important;
	}

	/* 30px é a folga medida na home entre o fundo dos cartões e o topo
	   dos dots. */
	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados__dots {
		display: flex;
		justify-content: center;
		gap: 7px;
		margin-top: 30px;
	}

	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados__dot {
		/* `position` e `height` com !important, verificados por remoção:
		   sem `position` o alvo de toque do ::after ancora no antepassado
		   errado; sem `height` o dot mede 0px de alto. */
		position: relative !important;
		height: 13px !important;
		width: 13px;
		flex: 0 0 13px;
		padding: 0;
		border: 0;
		border-radius: 50%;
		background: var(--cor-cinza-claro, #D6D7D9);
		-webkit-appearance: none;
		appearance: none;
		cursor: pointer;
	}

	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados__dot.ativo {
		background: var(--cor-rosa, #ECC6C0);
	}

	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados__dot:focus-visible {
		outline: 2px solid var(--cor-primaria, #A787A3);
		outline-offset: 4px;
	}

	/* Numa coluna de 142px úteis uma palavra comprida transborda em vez
	   de quebrar — visível nos produtos de teste, mas qualquer nome real
	   com uma palavra longa faria o mesmo. */
	body:not(.pagina-home-final) .site-content .produto-card__nome {
		overflow-wrap: break-word;
		/* Report do Francisco: «reduzir ligeiramente o tamanho dos títulos
		   dos produtos em mobile». Medido, era mais do que ligeiro — o
		   nome estava a 24px/32 em mobile contra 18/28 em desktop, ou
		   seja CRESCIA ao encolher o ecrã. É a mesma armadilha do R52, do
		   R60 e do R74: o nome é um <h3> e o valor do mock perde para a
		   escala genérica `.site-content h3 { font-size: 24px }`.
		   16/22 é o que o desenho mobile da home dá a este mesmo cartão —
		   o único desenho mobile que existe para o componente. */
		font-size: 16px;
		line-height: 22px;
	}}

/* ------------------------------------------------------------
 * REVISÃO v5, R89 a R92 (PDF p.20) — a página de artigo
 * ------------------------------------------------------------ */

/* R89 — a pastilha da categoria. Desktop E mobile, e em desktop o
   defeito é MAIOR do que o cliente reportou: o mock dá `width: 154px`
   fixo e ZERO padding, portanto a folga era o resto da caixa depois do
   texto. Com o nome real da categoria («CONEXÕES SEMANAIS», 194,5px de
   avanço a 18/600) já não cabe — quebra em duas linhas e transborda a
   pastilha rosa por cima e por baixo, com texto branco a cair sobre o
   creme. Só rebenta nessa categoria; «Terapias» e «Reflexão» cabem por
   sorte. A ≤430px o refluxo põe `width: auto` e a tinta encosta aos dois
   bordos (folga 0,00 / 0,00).
   Passa a largura de conteúdo com padding, como já faz o irmão
   `.seccao-artigos-card-categoria` — 12px a 14px de corpo = 0,857em;
   16px a 18px = 0,889em, a mesma proporção. */
.artigo-cabecalho__categoria {
	box-sizing: border-box;
	width: auto;
	max-width: 100%;
	padding: 0 16px;
}

@media (max-width: 430px) {
	/* `!important` só em width/max-width: são as duas propriedades que o
	   refluxo escreve. */
	body:not(.pagina-home-final) .site-content .artigo-cabecalho__categoria {
		display: inline-block;
		box-sizing: border-box;
		width: max-content !important;
		max-width: 100% !important;
		padding: 6px 16px;
		margin-bottom: 10px;
	}

	/* R90 — autor e data à frente do símbolo. Em desktop a linha existe
	   só como três coordenadas absolutas com o mesmo `top: 270px`. A
	   ≤430px o refluxo apaga position/left/top e sobra a ordem do DOM:
	   img inline + dois <p> de bloco, que empilham.
	   Reponho a linha em FLUXO e não em flex, de propósito: com flex a
	   meta é um item atómico e, se não couber, salta inteira para a linha
	   de baixo — medido, só cabia a 14px e com 3,4px de folga. Em inline,
	   um nome de autor comprido quebra no espaço seguinte e nunca
	   transborda a goteira. */
	body:not(.pagina-home-final) .site-content .artigo-cabecalho__avatar {
		display: inline-block;
		vertical-align: -0.35em;
		/* `!important` em width/height (o refluxo põe `auto` e o SVG
		   voltava aos 34,7px intrínsecos) e nas margens laterais — são as
		   que o refluxo escreve; sem ele o vão símbolo→autor ficava nos
		   4,4px do espaço de HTML colapsado. */
		width: 24px !important;
		height: 24px !important;
		margin-top: 0;
		margin-bottom: 0;
		margin-left: 0 !important;
		margin-right: 6px !important;
	}

	body:not(.pagina-home-final) .site-content .artigo-cabecalho__autor,
	body:not(.pagina-home-final) .site-content .artigo-cabecalho__meta {
		display: inline;
		margin-top: 0;
		margin-bottom: 0;
		/* 14/22: a 15 e a 16 a meta não cabe nos 344 de goteira. */
		font-size: 14px;
		line-height: 22px;
	}

	/* R91 — metade da folga data → imagem. Media 78,2px: 6,2 de
	   entrelinha + 16 da margem do <p> + 28 do padding do cabeçalho + 28
	   do padding do conteúdo. Depois do R90 a meta passa a inline e os 16
	   deixam de pintar, por isso o lever passa a ser o padding das duas
	   secções. Não mexo nos 28/28 genéricos — restrinjo às duas secções
	   do artigo. Resultado: 37,4px, 47,9% do original. */
	body:not(.pagina-home-final) .site-content .artigo-cabecalho {
		padding-bottom: 0;
	}

	body:not(.pagina-home-final) .site-content .artigo-conteudo {
		padding-top: 32px;
	}

	/* R92 — as aspas da citação. Elas EXISTEM e pintam bem a 1920. A
	   ≤430px o refluxo tira o `position: relative` ao <blockquote>; o
	   pseudo-elemento continua absoluto mas passa a resolver contra o
	   VIEWPORT — medido, um bloco de contenção de 390x1000 — e ia pintar
	   no topo do documento, 1342px acima da citação, por trás do
	   cabeçalho. Aquela mancha roxa que assomava por baixo do logótipo
	   era a aspa. É a mesma armadilha das estrelas e dos steppers.
	   Reponho o contexto e reescalo: os 96px de padding-top e os 180px de
	   glifo são a caixa de 912 do desktop; num cartão de 344 sobravam
	   96px de banda vazia e o texto ficava com 224px de coluna útil. */
	body:not(.pagina-home-final) .site-content .artigo-conteudo__texto blockquote {
		position: relative !important;
		padding: 60px 24px 32px;
	}

	body:not(.pagina-home-final) .site-content .artigo-conteudo__texto blockquote::before {
		font-size: 96px;
		line-height: 96px;
		top: 4px;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R95 e R96 (PDF p.21) — comentários e formulário de
 * comentário do artigo, em mobile
 * ------------------------------------------------------------ */

/* O mock desenha o comentário para 1920: avatar 109x110 em absoluto à
   esquerda, moldura deslocada 120px, texto a começar aos 174. A ≤430px
   o refluxo mata position/width/height/margin-left mas NÃO mexe no
   padding — sobrava o `padding-left: 140px` do mock a espremer o texto
   para 180px de coluna, o avatar voltava ao intrínseco (medido 180x182)
   e ia parar ao MEIO do cartão, e a moldura, sendo um <span>, colapsava
   para uma lasca de 2x20px. As respostas perdiam a indentação de 141px
   e ficavam indistinguíveis dos comentários de topo. */
@media (max-width: 430px) {
	/* Rótulos de secção: o mock dá-lhes 22/32 e a escala genérica de
	   mobile apanha-os como h2 e levava-os a 38/46 — «DEIXE O SEU
	   COMENTÁRIO» passava a duas linhas. */
	body:not(.pagina-home-final) .site-content .artigo-comentarios__titulo,
	body:not(.pagina-home-final) .site-content .artigo-deixe-comentario__titulo {
		font-size: 22px;
		line-height: 32px;
		margin: 0 0 20px;
	}

	body:not(.pagina-home-final) .site-content .artigo-comentario {
		position: relative !important;
		padding: 18px 20px 10px;
		margin-bottom: 20px;
	}

	/* A indentação de 141px do desktop é 41% da coluna. 24px chegam para
	   ler o encadeamento sem roubar largura ao texto. */
	body:not(.pagina-home-final) .site-content .artigo-comentario--resposta {
		margin-left: 24px !important;
	}

	/* A moldura volta a existir. `display` e `position` na MESMA regra:
	   o elemento é um <span> e as duas dependem uma da outra. */
	body:not(.pagina-home-final) .site-content .artigo-comentario__card {
		display: block;
		position: absolute !important;
		left: 0 !important;
		top: 0 !important;
		right: 0 !important;
		bottom: 0 !important;
		width: auto !important;
		height: auto !important;
		border-radius: 0 20px 20px 20px;
	}

	body:not(.pagina-home-final) .site-content .artigo-comentario__avatar {
		position: absolute !important;
		left: 20px !important;
		top: 18px !important;
		width: 56px !important;
		height: 56px !important;
		z-index: 1;
		border-radius: 10px;
		object-fit: cover;
	}

	/* `padding-left` e não `margin-left`: o refluxo zera as margens
	   laterais e o padding passa-lhe ao lado sem `!important`. 72 = 56 do
	   avatar + 16 de folga; as duas linhas somam 56, a altura do avatar,
	   por isso o texto nunca lhe passa por cima. */
	body:not(.pagina-home-final) .site-content .artigo-comentario__nome {
		padding-left: 72px;
		margin: 0;
		font-size: 18px;
		line-height: 28px;
		font-weight: 500;
	}

	body:not(.pagina-home-final) .site-content .artigo-comentario__data {
		padding-left: 72px;
		margin: 0 0 12px;
		font-size: 14px;
		line-height: 28px;
	}

	body:not(.pagina-home-final) .site-content .artigo-comentario__texto {
		margin: 0;
		font-size: 16px;
		line-height: 26px;
	}

	body:not(.pagina-home-final) .site-content .artigo-comentario__texto p {
		margin: 0 0 12px;
	}

	body:not(.pagina-home-final) .site-content .artigo-comentario__texto p:last-child {
		margin-bottom: 0;
	}

	/* Alvo de toque: o link «Responder» media 24px de altura. */
	body:not(.pagina-home-final) .site-content .artigo-comentario .comment-reply-link {
		min-height: 44px !important;
		align-items: center;
		margin-top: 2px;
	}

	/* R96 — o `width: 100%` do mock é (0,1,1) e morre no refluxo: o input
	   caía no `size` por omissão (208px) e o textarea em cols=20/rows=2
	   (215x53, contra 912x178 em desktop). A regra genérica de campos
	   desta revisão só nomeia `.seccao-formulario__campo`, por isso não
	   chegava aqui. 35 + 8 de padding + 1 do risco = 44 de alvo de toque. */
	body:not(.pagina-home-final) .site-content .artigo-deixe-comentario__campo input,
	body:not(.pagina-home-final) .site-content .artigo-deixe-comentario__campo textarea {
		width: 100% !important;
		height: 35px !important;
		padding: 8px 0 0;
		box-sizing: content-box;
	}

	/* Especificidade mais alta e não só a ordem: com as duas regras ao
	   mesmo nível, trocá-las de sítio deixaria o textarea com 35px de
	   altura em silêncio.

	   A especificidade vem agora da classe REPETIDA e não do antepassado
	   `.artigo-deixe-comentario`, e isso é o R96. O WordPress move o
	   `#respond` para dentro do comentário quando se carrega em
	   «responder» (é o que o comment-reply.js faz), o formulário perde
	   esse antepassado, e o textarea caía nos 35px da regra acima —
	   medido: 44px de caixa, contra os 129 do formulário principal. O
	   defeito só se via depois de o R95 estar corrigido, porque antes
	   ninguém conseguia sequer abrir a resposta. Presa à própria classe,
	   a altura acompanha o formulário para onde quer que ele vá. */
	body:not(.pagina-home-final) .site-content .artigo-deixe-comentario__campo.artigo-deixe-comentario__campo textarea {
		height: 120px !important;
	}

	body:not(.pagina-home-final) .site-content .artigo-deixe-comentario__campo {
		margin: 0 0 24px;
	}

	/* O botão e o consentimento partilhavam a linha — 251 + 24 + 115 =
	   390 numa coluna de 344 — e o consentimento saía 23px do ecrã,
	   recortado pelo `overflow-x`, com o texto cortado a meio em quatro
	   linhas. Mesmo padrão do rodapé dos formulários de contacto, com
	   outras classes. `gap: 0` escrito à mão: a regra base tem 24px e,
	   herdado, somaria aos 40 de margem do botão. */
	body:not(.pagina-home-final) .site-content .artigo-deixe-comentario .sda-form__actions,
	body:not(.pagina-home-final) .site-content .artigo-comentarios #respond .sda-form__actions {
		display: flex;
		flex-direction: column;
		align-items: stretch;
		gap: 0;
		margin-top: 32px;
	}

	body:not(.pagina-home-final) .site-content .artigo-deixe-comentario .artigo-deixe-comentario__rodape,
	body:not(.pagina-home-final) .site-content .artigo-comentarios #respond .artigo-deixe-comentario__rodape {
		display: flex;
		justify-content: center;
		gap: 0;
	}

	body:not(.pagina-home-final) .site-content .artigo-deixe-comentario .sda-form__consent,
	body:not(.pagina-home-final) .site-content .artigo-comentarios #respond .sda-form__consent {
		display: flex;
		align-items: center;
		gap: 10px;
		min-height: 44px !important;
		margin: 0;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R93 e R94 (PDF p.21) — gosto e partilha do artigo
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* R93 — margem interior do botão de gosto. O mock dá-lhe caixa fixa
	   de 86x53 para um conteúdo de 42x26 (coração 22 + gap 8 + contador
	   12): 22px de folga lateral e 13,5 em cima e em baixo. A folga NÃO
	   vem de padding — vem da caixa fixa, e o refluxo troca width/height
	   por `auto`. A caixa passa a shrink-to-fit e a única folga que
	   sobrava era o `padding: 1px 6px` por omissão que o Chrome dá a
	   qualquer <button>: 56x30, com o contador encostado à borda. Era
	   literalmente a margem interior do browser a fazer de desenho.
	   Devolvo a folga por padding, que o refluxo não declara — daí não
	   levar `!important`. De caminho o alvo de toque sobe de 27,8 para
	   44,4px reais a 360. */
	body:not(.pagina-home-final) .site-content .artigo-tags-partilha__recomendar {
		padding: 10px 18px;
	}

	/* R94 — «Partilhar» ao centro dos ícones. A 1920 o rótulo e os quatro
	   ícones vivem em absoluto na mesma caixa e os centros coincidem por
	   construção. O refluxo tira-lhes o absoluto e os cinco caem na mesma
	   caixa de linha: os SVG (44px intrínsecos) assentam na linha de
	   base, logo o centro do ícone fica 22px acima dela, enquanto o
	   centro óptico das maiúsculas do rótulo fica só ~6,3px acima. Dá os
	   16px de desvio que o cliente vê. O `column-gap` de 11px repõe de
	   caminho o ritmo horizontal do desenho — o inline só deixava 4px, o
	   espaço de palavra do markup.
	   Longhands e não o atalho `gap`, para o valor não passar a depender
	   da ordem no ficheiro. */
	body:not(.pagina-home-final) .site-content .artigo-tags-partilha__partilhar {
		display: flex;
		align-items: center;
		flex-wrap: wrap;
		column-gap: 11px;
		row-gap: 12px;
	}

	/* A imagem tem de sair da linha de base para o alinhamento fechar em
	   zero: com a <img> inline, a caixa de linha junta-lhe a descendente
	   do strut e sobravam 2px de desvio. */
	body:not(.pagina-home-final) .site-content .artigo-tags-partilha__social img {
		display: block;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R103, R104, R106 e R107 (PDF pp. 22–23) — a loja em
 * mobile: barra de portes, banner, filtros e ordenação
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* R103 — a barra de informação media 124px de canvas contra 60 em
	   desktop, com 30 de tinta em cima e 46 em baixo. A frase não cabe
	   numa linha (pede 537px, há 344), portanto as duas linhas ficam. O
	   que sai é o padding de 28 do refluxo e os 16px de margem que o
	   parágrafo herda da escala genérica — eram eles a desequilibrar.
	   12 + 52 + 12 = 76, com 14/14 de tinta. Longhands, para o atalho
	   `margin` não disputar as laterais com o refluxo. */
	body:not(.pagina-home-final) .site-content .loja-portes {
		padding-top: 12px;
		padding-bottom: 12px;
	}

	body:not(.pagina-home-final) .site-content .loja-portes__texto {
		margin-bottom: 0;
		text-align: center;
	}

	/* R104 — os dots do banner são <button> vazios e o refluxo
	   colapsava-os a 0x0: invisíveis e sem alvo. O `.click()` mudava o
	   slide, mas o clique do rato não — o `ligarSlider()` estava bem
	   ligado, era o CSS a apagar os alvos.
	   ARMADILHA: com `position: relative` os `left` de 0/34/68/102 do
	   mock (nth-child, canvas de 1920) voltam a valer e espalham os
	   dots — daí o `left/top: auto !important`. */
	body:not(.pagina-home-final) .site-content .loja-banner__dots {
		display: flex !important;
		justify-content: center;
		gap: 7px;
		width: auto !important;
		height: 13px !important;
	}

	body:not(.pagina-home-final) .site-content .loja-banner__dot {
		position: relative !important;
		left: auto !important;
		top: auto !important;
		flex: 0 0 13px;
		width: 13px !important;
		height: 13px !important;
		/* Branco com sombra é a linguagem de desktop, sobre a foto. Aqui
		   ficam sobre o cartão claro: passam a cinza/rosa, como todos os
		   dots do desenho mobile da home. */
		background: var(--cor-cinza-claro, #D6D7D9);
		box-shadow: none;
	}

	body:not(.pagina-home-final) .site-content .loja-banner__dot.ativo {
		background: var(--cor-rosa, #ECC6C0);
	}

	body:not(.pagina-home-final) .site-content .loja-banner__dot:focus-visible {
		outline: 2px solid var(--cor-primaria, #A787A3);
		outline-offset: 4px;
	}

	/* R104 — o banner deixava de ser hero em mobile: o refluxo punha a
	   imagem em `display: inline; height: auto` e ela caía para uma faixa
	   de 390x133 (o 2400x819 inteiro encolhido), com a legenda a escorrer
	   por baixo sobre a textura e o título a abrir em três linhas de
	   44px. Reponho o palco — foto de bordo a bordo com `object-fit:
	   cover` e a legenda num cartão translúcido por cima, que é o que o
	   desenho mobile da home faz no seu próprio hero (o valor de
	   `rgba(255,255,255,0.7767)` é o dele, não inventado). */
	body:not(.pagina-home-final) .site-content .loja-banner {
		position: relative !important;
		height: 440px !important;
		padding-top: 0;
		padding-bottom: 0;
		overflow: hidden;
	}

	body:not(.pagina-home-final) .site-content .loja-banner__imagem {
		position: absolute !important;
		left: 0 !important;
		top: 0 !important;
		width: 100% !important;
		height: 440px !important;
		object-fit: cover;
		/* `display: block` faz falta por dois motivos: tira os 4px de gap
		   de baseline do inline E deixa o `object-fit` ter efeito. */
		display: block !important;
	}

	/* Desde 20-10 cada slide tem o seu texto: o cartão é o `.loja-banner__texto`
	   de cada slide, e os slides ficam empilhados (o refluxo punha-os um
	   por baixo do outro, dentro de uma caixa de 440 com o resto cortado). */
	body:not(.pagina-home-final) .site-content .loja-banner__slide {
		position: absolute !important;
		left: 0 !important;
		top: 0 !important;
		width: 100% !important;
		height: 440px !important;
	}

	body:not(.pagina-home-final) .site-content .loja-banner__texto {
		position: absolute !important;
		left: 23px !important;
		top: 50% !important;
		width: 344px !important;
		box-sizing: border-box;
		/* `!important` porque o refluxo declara `transform: none`. */
		transform: translateY(-50%) !important;
		padding: 22px 20px 24px !important;
		background: rgba(255, 255, 255, 0.7767);
		border-radius: 20px;
		text-align: center;
		align-items: center;
	}

	/* No computador o texto é branco sobre a fotografia escurecida; no
	   cartão claro volta às cores do banner antigo. */
	body:not(.pagina-home-final) .site-content .loja-banner__sobretitulo {
		margin: 0 0 8px;
		font-size: 14px;
		line-height: 20px;
		color: var(--cor-primaria);
	}

	body:not(.pagina-home-final) .site-content .loja-banner__titulo {
		margin: 0;
		font-size: 28px;
		line-height: 34px;
		color: var(--cor-texto);
		text-wrap: balance;
	}

	/* As linhas do título foram escritas para os 76px do computador; a
	   344 de largura «Há perguntas que precisam» já não cabe numa linha e
	   a quebra forçada deixava «precisam» sozinho. Aqui parte onde couber. */
	body:not(.pagina-home-final) .site-content .loja-banner__titulo br {
		display: none;
	}

	body:not(.pagina-home-final) .site-content .loja-banner__subtitulo {
		margin: 10px 0 0;
		font-size: 16px;
		line-height: 24px;
		color: var(--cor-texto);
	}

	/* A 18px «Ver baralhos de tarot» passava dos 304 do cartão e partia em
	   duas linhas, com o botão a crescer para o dobro. A 16px, com menos
	   folga, o mais comprido dos quatro mede 275. A altura é a dos outros
	   botões do telemóvel (50; o refluxo deixava-o com a da linha, 36). */
	body:not(.pagina-home-final) .site-content .loja-banner .loja-banner__accao {
		height: 50px !important;
		margin-top: 18px;
		margin-left: auto !important;
		margin-right: auto !important;
		padding-left: 18px;
		padding-right: 18px;
		gap: 14px;
	}

	body:not(.pagina-home-final) .site-content .loja-banner__accao span {
		font-size: 16px;
		white-space: nowrap;
	}

	/* Os pontos saíram do cartão (cada slide tem o seu) e ficam no fundo da
	   fotografia, sobre todos. A sombra separa-os de uma foto clara. */
	body:not(.pagina-home-final) .site-content .loja-banner__controlos {
		position: absolute !important;
		left: 0 !important;
		right: 0 !important;
		top: auto !important;
		bottom: 18px !important;
		width: 100% !important;
	}

	body:not(.pagina-home-final) .site-content .loja-banner__controlos .loja-banner__dot {
		box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
	}

	/* R106 — o título CRESCEU de desktop para mobile: 22/30 no mock,
	   38/46 no telemóvel. É a armadilha do R38 ao contrário — aqui o
	   elemento É apanhado pela escala genérica, e essa escala é MAIOR do
	   que o valor do desenho. Medido: 343,2px de tinta numa coluna de
	   344, a 0,77px de partir em duas linhas.
	   O `margin-bottom: 0` é deliberado: sem ele os 16px que o h2 apanha
	   da regra genérica COLAPSAM com o margin-top da lista e o valor real
	   passa a ser o máximo dos dois, não a soma — qualquer número abaixo
	   de 16 seria silenciosamente ignorado. */
	body:not(.pagina-home-final) .site-content h2.loja-filtro__titulo {
		font-size: 22px;
		line-height: 30px;
		margin-bottom: 0;
	}

	/* R106 — os 59px de margem da lista não são folga desenhada: existem
	   para alinhar a caixa da <ul> com o `top: 59px` do primeiro <li>
	   absoluto do mock. Em mobile os <li> ficam em fluxo e os 59 tornam-se
	   folga inteira. */
	body:not(.pagina-home-final) .site-content .loja-filtro__lista {
		margin-top: 20px;
	}

	/* R107 — o refluxo tira o `position` aos quatro elementos do
	   controlo. O padding do mock nunca foi padding: vinha do `left: 20`
	   e `right: 19` dos filhos absolutos, e ao ficarem estáticos o rótulo
	   colava-se à borda. Pior: o <select> invisível saía de cima do
	   visual e passava a ser uma caixa inline À DIREITA do chevron — de
	   57 sondagens ao longo da pastilha só 16 acertavam nele, e tocar em
	   cima de «Ordenar por» não abria nada.
	   `position` e `display` na MESMA regra de propósito: em regras
	   separadas anulavam-se em silêncio, como já aconteceu nesta revisão.
	   52 e não 48 de altura porque a 360 o canvas escala por 0,923 e 48
	   dava 42,3px reais de alvo, abaixo dos 44. */
	body:not(.pagina-home-final) .site-content .loja-produtos__ordenar {
		position: relative !important;
		display: flex !important;
		align-items: center !important;
		justify-content: space-between !important;
		width: 100% !important;
		height: 52px !important;
		padding: 0 20px !important;
		box-sizing: border-box !important;
	}

	body:not(.pagina-home-final) .site-content .loja-produtos__ordenar img {
		flex: 0 0 20px !important;
		width: 20px !important;
		height: 10px !important;
	}

	body:not(.pagina-home-final) .site-content .loja-produtos__ordenar-select {
		position: absolute !important;
		inset: 0 !important;
		width: 100% !important;
		height: 100% !important;
		margin: 0 !important;
	}

	/* A fronteira até à listagem só se calcula DEPOIS do banner fechar:
	   antes eram 111px de creme vazio; com o banner a 440 caía para 25, o
	   mais apertado da página.
	   67 e NÃO 70: o R106 encolhe o título dos filtros e desloca o topo
	   da caixa +3px — com 70 dava 70,0 em vez dos 67 de referência. É o
	   único número desta ronda que muda por causa de outra correcção. */
	body:not(.pagina-home-final) .site-content .loja-produtos {
		padding-top: 67px;
	}
}

/* ------------------------------------------------------------
 * Cartão de produto: a faixa encosta à imagem (report do Francisco)
 * ------------------------------------------------------------ */

/* Report: «da p.23 os cards continuam desformatados, com margem entre a
   imagem e a parte inferior».

   Duas causas somadas, as duas do refluxo, e nenhuma existe na home
   porque lá o cartão tem desenho mobile próprio — a imagem e a faixa são
   absolutas e a faixa até SOBREPÕE a imagem em 14px.

   1) O link que embrulha a imagem é `inline`, portanto a sua caixa é uma
      caixa de LINHA: medida, 18px de altura para uma imagem de 166, com
      a imagem assente na linha de base. Os 8px que se viam entre a
      imagem e a faixa são a descendente dessa linha — não são margem
      nenhuma. É a mesma armadilha do cartão de actividade e do cartão do
      blog, ambos já corrigidos assim.

   2) O cartão trazia `padding-bottom: 24px`, que deixava 24px de branco
      por baixo da faixa. Na home a faixa vai até ao bordo. */
@media (max-width: 430px) {}

/* ------------------------------------------------------------
 * REVISÃO v5, R111, R112 e R113 (PDF pp. 24–25) — ficha de produto
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* R111 — o `padding-top: 131px` do inner da descrição reserva a faixa
	   dos separadores, que em DESKTOP são absolutos com `top: 0`. A
	   ≤430px eles passam a estáticos e entram no fluxo DEPOIS desse
	   padding — os 131px ficavam a pintar nada. Medido: 205px de canvas
	   entre «Categoria: …» e o primeiro separador, contra 139–167 em
	   desktop. Zerado, fica o ritmo normal de secção: 74. */
	body:not(.pagina-home-final) .site-content .produto-descricao .seccao-inner {
		padding-top: 0;
	}

	/* R112 — resposta à pergunta do cliente: dá, e é isto. Os três
	   separadores precisam de 472px de canvas numa linha e a coluna tem
	   344 — faltam 128. Fila única com scroll horizontal.
	   `overflow-x: auto` e não `scroll`: nos produtos sem «Como usar»
	   sobram dois separadores, medem 317 e cabem sem barra nenhuma.
	   `margin-top: -4px` e `padding-top: 4px` anulam-se — a fila fica
	   onde ficaria sem eles, e é isso que mantém intactos os 74px do
	   R111 —, e o padding devolve ao anel de foco os 4px que a caixa de
	   scroll lhe cortava. As margens laterais negativas levam a fila às
	   bordas do ecrã, para o corte se ler como corte e não como fim. */
	body:not(.pagina-home-final) .site-content .produto-descricao__tabs {
		display: flex !important;
		flex-wrap: nowrap !important;
		align-items: flex-end;
		column-gap: 22px;
		margin: -4px -23px 12px !important;
		padding: 4px 23px 8px !important;
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scroll-snap-type: x proximity;
		scrollbar-width: none;
	}

	body:not(.pagina-home-final) .site-content .produto-descricao__tabs::-webkit-scrollbar {
		display: none;
	}

	/* TEM de vir depois da regra que dá `margin: 0 18px 12px 0 !important`
	   aos separadores: com o `column-gap` no contentor, essa margem
	   SOMAVA-SE (38px de intervalo) e sobravam 18px mortos no fim. */
	body:not(.pagina-home-final) .site-content .produto-descricao__tab {
		flex: 0 0 auto !important;
		margin: 0 !important;
		scroll-snap-align: start;
		/* Para o separador que recebe foco não ir parar debaixo do
		   esbatimento. */
		scroll-margin-inline: 48px;
	}

	body:not(.pagina-home-final) .site-content .produto-descricao__tab:focus-visible {
		outline: 2px solid var(--cor-primaria, #A787A3);
		outline-offset: 2px;
	}

	/* Indicação de que há mais fora do ecrã. Máscara e não gradiente de
	   cor: o fundo é a textura creme e um degradê sólido não a
	   acompanharia. As classes são postas pelo main.js e caem sozinhas
	   quando a fila chega ao fim. */
	body:not(.pagina-home-final) .site-content .produto-descricao__tabs.tem-mais-a-direita {
		-webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 44px), transparent 100%);
		mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 44px), transparent 100%);
	}

	body:not(.pagina-home-final) .site-content .produto-descricao__tabs.tem-mais-a-esquerda {
		-webkit-mask-image: linear-gradient(to right, transparent 0, #000 44px, #000 100%);
		mask-image: linear-gradient(to right, transparent 0, #000 44px, #000 100%);
	}

	body:not(.pagina-home-final) .site-content .produto-descricao__tabs.tem-mais-a-esquerda.tem-mais-a-direita {
		-webkit-mask-image: linear-gradient(to right, transparent 0, #000 44px, #000 calc(100% - 44px), transparent 100%);
		mask-image: linear-gradient(to right, transparent 0, #000 44px, #000 calc(100% - 44px), transparent 100%);
	}

	/* R113 — não é o rótulo do separador (esse tem 22px em mobile e em
	   desktop): é o <h2> que o WooCommerce injecta DENTRO do painel, a
	   38/46 por causa da escala genérica de títulos de SECÇÃO. Este h2
	   não é um título de secção — é um subtítulo dentro de um painel, e
	   repete o rótulo do separador que está logo por cima.
	   24/32 é a casa do H3 mobile do tema e o equivalente fiel do
	   desktop (lá é 26 sobre corpo de 18 = 1,44x; aqui o corpo é 16). */
	body:not(.pagina-home-final) .site-content h2.woocommerce-Reviews-title {
		font-size: 24px;
		line-height: 32px;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R115 (PDF p.25) — «Carrinho: a página está desformatada»
 * ------------------------------------------------------------ */

@media (max-width: 430px) {
	/* PASSO 1 — o deslocamento das linhas, que é a causa-raiz. O cart.php
	   escreve `style="top: 74px"` / `196` / `318` em cada linha (74+122i,
	   geometria do canvas de 1920). A linha está na lista de excepções do
	   refluxo, fica `relative`, e o `top: auto` da regra de excepção perde
	   para o estilo INLINE. Só `!important` bate um inline. */
	body:not(.pagina-home-final) .site-content .carrinho-linha {
		top: 0 !important;
	}

	/* PASSO 2 — medidas. TODAS com `!important`: o refluxo é (0,11,1) e
	   impõe `width: auto; height: auto`. O `display` não precisa — o
	   refluxo não o escreve. */
	body:not(.pagina-home-final) .site-content .carrinho-linha__miniatura {
		width: 80px !important;
		height: 77px !important;
		object-fit: cover;
	}

	/* A pílula era `display: inline`, 113x20, com os botões de 44x44 a
	   sair-lhe pelos dois lados. `justify-content` e NUNCA o atalho
	   `gap`, que passaria a depender da ordem no ficheiro. */
	body:not(.pagina-home-final) .site-content .carrinho-linha__quantidade {
		display: inline-flex !important;
		align-items: center;
		justify-content: space-between;
		box-sizing: border-box;
		width: 120px !important;
		height: 48px !important;
		padding: 0 4px;
		vertical-align: middle;
	}

	/* Inline-level de propósito: o preço e o remover partilham a linha da
	   pílula, como em desktop. `display: block` punha-os em linhas
	   próprias E as margens passariam a colapsar em vez de somar. */
	body:not(.pagina-home-final) .site-content .carrinho-linha__preco {
		margin-left: 16px;
		vertical-align: middle;
	}

	/* Media 344x22: o <a> apanhava a linha toda e um toque em qualquer
	   ponto vazio dela APAGAVA o produto. */
	body:not(.pagina-home-final) .site-content .carrinho-linha__remover {
		display: inline-block !important;
		box-sizing: border-box;
		width: 44px !important;
		height: 44px !important;
		padding: 11px 13px;
		vertical-align: middle;
	}

	body:not(.pagina-home-final) .site-content .carrinho-cupao__campo,
	body:not(.pagina-home-final) .site-content .carrinho-envio__campo {
		display: block;
		box-sizing: border-box;
		width: 251px !important;
		max-width: 100% !important;
		height: 61px !important;
		padding: 0 0 0 20px;
		margin: 0 auto 16px !important;
		font-size: 18px;
		line-height: 59px;
	}

	body:not(.pagina-home-final) .site-content .carrinho-envio__campo--pais {
		position: relative !important;
	}

	body:not(.pagina-home-final) .site-content .carrinho-envio__campo--pais img {
		position: absolute !important;
		left: auto !important;
		right: 20px !important;
		top: 26px !important;
		width: 18px !important;
		height: 9px !important;
	}

	/* O rádio do método de envio media 0x0 — não havia forma de escolher
	   o envio no telemóvel. */
	body:not(.pagina-home-final) .site-content .carrinho-envio-opcao__radio {
		position: relative !important;
		display: inline-block;
		box-sizing: border-box;
		width: 20px !important;
		height: 20px !important;
		margin: 12px 0 4px !important;
		border: 1px solid var(--cor-cinza-medio, #A4A7A9);
		vertical-align: middle;
	}

	/* O ponto do estado seleccionado é um `::after` a 5/5, calibrado para
	   a caixa de 15 do desenho; na de 20 ficava descentrado. */
	body:not(.pagina-home-final) .site-content .carrinho-envio-opcao__radio::after {
		left: 7px;
		top: 7px;
	}

	/* Alvo de toque de 44x44 sem crescer a caixa pintada. */
	body:not(.pagina-home-final) .site-content .carrinho-envio-opcao__radio::before {
		content: "";
		position: absolute;
		left: 50%;
		top: 50%;
		width: 44px;
		height: 44px;
		translate: -50% -50%;
	}

	/* PASSO 3 — estado 2. O bloco genérico de botões, (0,3,1), impõe
	   `display: flex` e ganhava à regra do `.pagina-carrinho-2`, (0,2,0):
	   o «Calcular custos de envio» ficava POR CIMA do formulário que
	   acabara de abrir. Em desktop já estava certo. */
	body:not(.pagina-home-final).pagina-carrinho-2 .site-content .carrinho-resumo__calcular {
		display: none !important;
	}

	/* O texto mede 260px numa linha a 18px e o botão tem 251: parte em
	   duas linhas de 60 numa caixa de 61 de conteúdo. */
	body:not(.pagina-home-final) .site-content .carrinho-resumo__calcular {
		height: auto !important;
		min-height: 61px !important;
		padding-top: 12px;
		padding-bottom: 12px;
	}

	/* PASSO 4 — cabeçalhos órfãos: em coluna única não há colunas para
	   rotular. Fica «Produto(s)» como título do bloco. */
	body:not(.pagina-home-final) .site-content .carrinho-tabela__cabecalho--quantidade,
	body:not(.pagina-home-final) .site-content .carrinho-tabela__cabecalho--preco {
		display: none;
	}

	/* PASSO 5 — o ritmo, e SÓ DEPOIS de 1 a 4 estarem no sítio. */
	body:not(.pagina-home-final) .site-content .carrinho-linha {
		margin-bottom: 8px !important;
		padding-bottom: 16px !important;
	}

	body:not(.pagina-home-final) .site-content .carrinho-resumo__rotulo {
		display: inline-block;
		width: 47% !important;
		margin: 0 0 16px !important;
		vertical-align: baseline;
	}

	body:not(.pagina-home-final) .site-content .carrinho-resumo__valor {
		display: inline-block;
		width: 51% !important;
		margin: 0 0 16px !important;
		text-align: right;
		vertical-align: baseline;
	}

	/* «Envio» não tem valor emparelhado e o que se lhe segue é
	   block-level. Sem isto a margem deixa de colapsar com o
	   `margin-top: 32px` do botão seguinte e a folga passa de 32 para 48
	   — medido nos dois sentidos. */
	body:not(.pagina-home-final) .site-content .carrinho-resumo__rotulo--envio {
		display: block;
		width: auto !important;
		margin-bottom: 0 !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R108 (PDF p.23) — «os itens de produto estão
 * desformatados», na /loja/ em telemóvel
 * ------------------------------------------------------------ */

/* Medido: os nove cartões da grelha tinham CINCO alturas diferentes
   (310 / 304,8 / 286 / 282,8 / 260,8), os preços da mesma linha até
   44px desalinhados, e o ícone do carrinho numa linha só dele.

   Causa única com quatro consequências: o refluxo tira ao cartão toda a
   geometria, e o mock só o desenha em coordenadas absolutas do canvas de
   1920. Sem `aspect-ratio` a foto cai no rácio do ficheiro; sem caixa de
   altura fixa o nome empurra o preço; sem contexto de posicionamento o
   ícone do carrinho fica em fluxo; e o selo mantém coordenadas
   calibradas para 318px dentro de um cartão de 166.

   Devolve-se-lhe a geometria do desenho mobile que existe — o da home —
   mas em fluxo, para não voltar a truncar conteúdo como acontecia com as
   alturas fixas. */
@media (max-width: 430px) {
	/* O `.screen-reader-text` que o WooCommerce mete dentro do preço em
	   promoção: o refluxo dá-lhe `width/height: auto` e ele fica com caixa
	   real de 98x96, a sair 9,5px do cartão. Invisível por causa do
	   `clip-path`, mas conta para o `scrollWidth` — foi assim que apareceu
	   scroll fantasma no carrossel de relacionados. Aqui vale para todo o
	   conteúdo refluído. */
	body:not(.pagina-home-final) .site-content .screen-reader-text {
		position: absolute !important;
		width: 1px !important;
		height: 1px !important;
		margin: -1px !important;
		overflow: hidden;
		clip-path: inset(50%);
		white-space: nowrap !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R109 (PDF p.24) — «o círculo da paginação deve ser
 * mais aberto», /loja/ em telemóvel
 * ------------------------------------------------------------ */

/* Medido: com 32px de diâmetro e 2px de anel, a tinta do algarismo («1»
   a 22px de Nunito 600 mede 9,4 x 15,7 de tinta real, não os 13,2 do
   avanço) fica a 4,86px do anel na diagonal. Em desktop, com os 59px do
   desenho, essa mesma folga é 18,36 — o telemóvel tem 27% da folga do
   desenho, e é isso que se lê como apertado.

   44 e não os 36 que dei hoje ao blog: a 36 a folga radial passa de
   4,86 para 6,86, dois pixels por lado num círculo que o cliente já
   apontou. A 44 passa a 10,86, e 44 é o alvo de toque que o tema já usa
   no favorito da ficha e nos botões do stepper — a 32 o alvo real a
   360px media 29,5.

   O `flex-wrap` é obrigatório a 44: com sete páginas a fila precisa de
   368px e a coluna tem 344. A 32 nunca lá chegava, por isso nunca fez
   falta. */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .loja-paginacao {
		flex-wrap: wrap;
		column-gap: 10px;
		row-gap: 8px;
	}

	body:not(.pagina-home-final) .site-content .loja-paginacao__pagina,
	body:not(.pagina-home-final) .site-content .loja-paginacao__seta {
		width: 44px !important;
		height: 44px !important;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R110 (PDF p.24) — «corrigir a formatação do campo de
 * quantidade, do botão do carrinho e do botão de Favorito» na ficha
 * do produto em telemóvel
 * ------------------------------------------------------------ */

/* CAUSA RAIZ do campo de quantidade: o `.produto-ficha__quantidade` é
   um <span> e NUNCA tem `display` declarado — no desenho é o
   `position: absolute` que o torna um bloco. Em mobile o refluxo
   escreve `position: static`, o span volta a `inline`, e aí
   `width: auto` passa a ser a soma dos filhos inline (medido: 111,2
   com «1» e 124,4 com «14» — a caixa mudava de largura conforme o
   número) e `height: auto` a altura da fonte, 20px. A borda e o raio
   continuavam a pintar à volta desses 20px, com os botões de 44 a
   SAIR 17px por cima e 7px por baixo. Não se mexe nos 44 — dá-se-lhes
   caixa.

   COMPOSIÇÃO: os três em linha somam 128+251+61 e não cabem nos 344
   úteis. Medido: com o botão encolhido para os 168 que sobrariam,
   «ADICIONAR AO CARRINHO» só cabe a 12px — mais pequeno que o corpo de
   texto da própria página. Empilham-se e centram-se os três, e o botão
   fica nos 251x61/18px de todos os outros. Antes eram três
   alinhamentos diferentes no mesmo bloco. */
@media (max-width: 430px) {
	/* `!important` porque o refluxo impõe `width`/`height: auto`;
	   `display` e `padding` não são escritos por ele. */
	body:not(.pagina-home-final) .site-content .produto-ficha .produto-ficha__quantidade {
		display: flex;
		align-items: center;
		box-sizing: border-box;
		width: 128px !important;
		height: 50px !important;
		padding: 0;
		margin-left: auto !important;
		margin-right: auto !important;
	}

	/* Os 44x44 do alvo de toque não podem encolher. */
	body:not(.pagina-home-final) .site-content .produto-ficha .produto-ficha__qtd-menos,
	body:not(.pagina-home-final) .site-content .produto-ficha .produto-ficha__qtd-mais {
		flex: none;
	}

	/* `flex: 1 1 0` e não `auto`: assim o número ocupa o meio fixo e os
	   dois botões não se mexem, tenha o valor 1, 14 ou 99. */
	body:not(.pagina-home-final) .site-content .produto-ficha .produto-ficha__qtd-valor {
		flex: 1 1 0;
		min-width: 0;
		text-align: center;
	}

	/* O `margin-bottom: 40px` do grupo dos botões serve os que têm texto
	   a seguir; aqui a seguir vem o coração, e o par 16/24 dá-lhe linha
	   própria. Antes eram 60px por cima e 0 por baixo. */
	body:not(.pagina-home-final) .site-content .produto-ficha .produto-ficha__comprar {
		margin-top: 16px !important;
		margin-bottom: 0 !important;
	}

	/* `flex` e não `inline-flex`: em inline-flex as margens verticais não
	   colapsam e o coração ficava colado ao texto de entrega; em bloco,
	   `margin: auto` centra-o com o botão. */
	body:not(.pagina-home-final) .site-content .produto-ficha .produto-ficha__favorito {
		display: flex !important;
		margin: 24px auto !important;
	}
}

/* ------------------------------------------------------------
 * Galeria e selo da ficha do produto em mobile
 * ------------------------------------------------------------ */

/* GALERIA — «está a mostrar em lista».
 *
 * CAUSA: o refluxo escreve `width: auto; height: auto` em tudo, e a regra
 * genérica das imagens acrescenta `max-width: 100%`. Num <img>, `auto`
 * significa "o tamanho intrínseco do ficheiro" — os atributos width/120
 * height/116 do markup deixam de contar. Enquanto o WordPress serve o
 * corte `woocommerce_gallery_thumbnail` (100x100) a miniatura calha
 * pequena por sorte; assim que esse corte não existe — imagem original
 * mais pequena que o corte, biblioteca por regenerar, ou ficheiro
 * carregado antes de o WooCommerce registar o tamanho — o WordPress
 * devolve o ficheiro grande e a miniatura passa a valer os 344px da
 * coluna. As três fotos ficam do mesmo tamanho, empilhadas: a galeria
 * lê-se como uma lista.
 *
 * Aqui a galeria deixa de depender do ficheiro que o WordPress escolhe.
 * As proporções são as do desenho reduzidas à coluna de 344:
 * principal 640x621 -> 344x334; miniatura 120x116 -> 100x97.
 * `object-fit: cover` garante que qualquer ficheiro enche a caixa sem
 * distorcer. */
@media (max-width: 430px) {

	body:not(.pagina-home-final) .site-content .produto-ficha__imagem {
		display: block;
		width: 344px !important;
		height: 334px !important;
		object-fit: cover;
	}

	/* `vertical-align: top` porque em linha de base o <img> assenta na
	   linha do texto e sobra o espaço do descendente por baixo das duas
	   miniaturas. O intervalo entre elas é o espaço branco do markup
	   (~4px), equivalente aos 10px do canvas de 1920 à escala de 0,5375. */
	body:not(.pagina-home-final) .site-content .produto-ficha__miniatura {
		display: inline-block;
		width: 100px !important;
		height: 97px !important;
		margin-top: 10px;
		margin-bottom: 16px;
		object-fit: cover;
		vertical-align: top;
	}

	/* SELO ESGOTADO — «continua sem paddings».
	 *
	 * O mock desenha-o como caixa de 154x39 com `line-height: 39px` a
	 * fazer de centragem vertical (main.css:4771). O refluxo tira-lhe a
	 * largura e a altura e ele volta a ser um <span> em linha: num
	 * elemento em linha não substituído a altura da caixa é a do tipo de
	 * letra, o line-height não a estica e não há padding nenhum — o fundo
	 * fica colado às letras. Devolvo-lhe a caixa do desenho.
	 *
	 * O texto passa a escuro: branco sobre #FFA2A3 dá 1,92:1 e a WCAG AA
	 * pede 4,5; #483846 dá 5,67:1. É a mesma troca que já fiz no selo do
	 * cartão. Em desktop os dois continuam brancos, como no desenho. */
	body:not(.pagina-home-final) .site-content .produto-ficha__esgotado {
		display: inline-block;
		width: 154px !important;
		height: 39px !important;
		margin-top: 12px;
		margin-bottom: 8px;
		vertical-align: top;
		color: #483846;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R116 (PDF p.26) — checkout em mobile
 * ------------------------------------------------------------ */

/* Em mobile não era possível comprar. As cinco caixas de verificação
 * (criar conta, morada diferente, dados, termos, newsletter) e os rádios
 * (dois de envio, um por gateway de pagamento) são <label> vazios que o
 * desenho pinta com `width`/`height` em absoluto; o refluxo escreve-lhes
 * `position: static; width: auto; height: auto` e eles passam a medir
 * 0x0. O <input> real que lá vive dentro tem `class="screen-reader-text"`
 * — está reduzido a 1x1 de propósito — por isso não sobrava caixa
 * nenhuma para tocar. Medi com `elementFromPoint` nos nove: nenhum
 * devolvia o controlo.
 *
 * Consequência: o WooCommerce recusava a encomenda com «Por favor leia e
 * aceite os termos e condições», e o utilizador ficava preso ao método de
 * envio e de pagamento por omissão, sem os poder mudar.
 *
 * Resolvo-o com grelha e não com posicionamento. Cada fila — marcador,
 * nome e, quando existe, preço ou ícone — é uma grelha de duas ou três
 * colunas, e é a grelha que põe o quadrado à esquerda do texto. O
 * elemento que agrupa a fila (`.checkout-linha`) nasce no PHP: no
 * desenho de 1920 é um <div> estático e completamente inerte, porque os
 * filhos são absolutos e continuam a resolver contra o `.seccao-inner`.
 * Medi 131 elementos a 1920, 1536, 1280, 768 e 431, e comparei o PNG da
 * página inteira: zero diferenças, byte a byte.
 *
 * O quadrado branco mantém os 24px do desenho e o alvo de toque cresce
 * para 48x42 através de um pseudo-elemento — assim cumpre-se o mínimo
 * sem engordar o desenho. */
@media (max-width: 430px) {

	/* 1. As caixas de verificação em grelha de duas colunas.
	   A causa: `.checkout-check__caixa` e `p.checkout-check__texto` são
	   irmãos que o desenho de 1920 põe em absoluto (main.css:5643 e
	   5656), cada um com o seu `left`/`top`. Em fluxo caíam em linhas
	   separadas — o quadrado numa, a frase na seguinte. A coluna de 24px
	   é o quadrado, a de 14px é a goteira, o resto é texto. */
	.pagina-checkout .checkout-check,
	.pagina-checkout .checkout-termos {
		display: grid;
		grid-template-columns: 24px minmax(0, 1fr);
		column-gap: 14px;
		align-items: start;
		margin-bottom: 16px;
	}

	/* 2. As filas do resumo e do pagamento têm o mesmo problema, mas não
	   tinham sequer um elemento que as agrupasse: o rádio, o nome e o
	   preço eram três irmãos soltos. O `.checkout-linha` nasce no PHP só
	   para lhes dar esse elemento. */
	.pagina-checkout .checkout-linha {
		display: grid;
		column-gap: 14px;
		/* `align-items: start` não é decoração: com o valor por omissão
		   (`stretch`) o <p> do preço estica à altura da fila. Medido com
		   um nome de método que quebra para três linhas, a caixa do preço
		   passa de 26 para 78px. Hoje não se vê — o <p> não tem fundo nem
		   contorno —, mas passaria a ver-se ao primeiro que lhe puséssemos. */
		align-items: start;
		margin-bottom: 16px;
	}

	/* Declaro só as colunas que existem SEMPRE. A terceira — preço ou
	   ícone — fica implícita, criada pelo `grid-column: 3` mais abaixo. É
	   deliberado: com um terceiro trilho explícito, uma fila sem ícone
	   continuava a pagar os 14px de goteira dele e o nome do método
	   encolhia sem nada lá para justificar o buraco. */
	.pagina-checkout .checkout-linha--valor {
		grid-template-columns: minmax(0, 1fr);
	}

	.pagina-checkout .checkout-linha--envio,
	.pagina-checkout .checkout-linha--pagamento {
		grid-template-columns: 24px minmax(0, 1fr);
	}

	/* Colocação explícita por classe, e não por ordem de aparecimento: o
	   PayPal não emite <p> nenhum (form-checkout.php) e, com colocação
	   automática, o logótipo caía na coluna do nome. */
	.pagina-checkout .checkout-linha .checkout-radio {
		grid-column: 1;
	}

	.pagina-checkout .checkout-linha .checkout-resumo__valor,
	.pagina-checkout .checkout-linha .checkout-envio__nome,
	.pagina-checkout .checkout-linha .checkout-pagamento__nome {
		grid-column: 2;
	}

	.pagina-checkout .checkout-linha .checkout-envio__preco,
	.pagina-checkout .checkout-linha .checkout-pagamento__icone {
		grid-column: 3;
	}

	/* Caso PayPal: sem nome, o logótipo é o único conteúdo da fila e
	   ficava encostado à margem direita, com um vazio enorme a separá-lo
	   do rádio. No desenho ele vem logo a seguir ao rádio (main.css:5834,
	   left 950 contra 915 do rádio) — trago-o para a coluna do nome. */
	.pagina-checkout .checkout-linha--pagamento:not( :has( .checkout-pagamento__nome ) ) .checkout-pagamento__icone {
		grid-column: 2;
		justify-self: start;
	}

	/* O ritmo vertical passa a viver no elemento que agrupa a fila, um
	   sítio só. Sem isto cada <p> traz ainda os seus 16px e a fila mede
	   42 em vez de 26. `!important` porque
	   `body:not(.pagina-home-final) .site-content p, h1, h2, h3
	   { margin: 0 0 16px }` (sda-extra.css:1841) escreve `margin-bottom`
	   com (0,2,1), e os dois membros mais fracos desta lista —
	   `.checkout-check__texto` e `.checkout-termos__texto` — são (0,2,0)
	   e perdiam. */
	.pagina-checkout .checkout-check__texto,
	.pagina-checkout .checkout-termos__texto,
	.pagina-checkout .checkout-linha .checkout-resumo__rotulo,
	.pagina-checkout .checkout-linha .checkout-resumo__valor,
	.pagina-checkout .checkout-linha .checkout-envio__nome,
	.pagina-checkout .checkout-linha .checkout-envio__preco,
	.pagina-checkout .checkout-linha .checkout-pagamento__nome {
		margin-bottom: 0 !important;
	}

	/* 3. Os marcadores são <label> vazios: o único filho é o <input>
	   sr-only, reduzido a 1x1. Sem altura declarada a caixa mede 0 e não
	   há nada para tocar nem para ver.
	   `position: relative !important` vence o `position: static` do
	   refluxo (sda-extra.css:1789, (0,12,1)) e é o que dá bloco contentor
	   ao `::after` do ponto activo e ao `::before` do alvo de toque. Tirei
	   o `!important` e medi: o alvo dos nove colapsa de 48x42 para 24x24 e
	   um toque 8px abaixo do quadrado devolve `.checkout-resumo-bloco` ou
	   o próprio `form`, nunca o controlo.
	   `height: 24px !important` vence o `height: auto` da mesma regra
	   (linha 1796); medido, sem ele os nove ficam a 0px de altura.
	   A LARGURA já não é declarada — é o trilho de 24px da grelha que a
	   dá. Retirei `width: 24px !important` e medi: não muda um pixel. */
	.pagina-checkout .checkout-check__caixa,
	.pagina-checkout .checkout-radio {
		position: relative !important;
		height: 24px !important;
		margin-top: 1px;
	}

	/* Alvo de toque. A causa de os valores verticais serem -9 e não -12:
	   com 24px de caixa e 42 de passo, um alvo de 48 sobrepunha-se 6px ao
	   do vizinho seguinte, e o vizinho ganhava o hit-test por ser o
	   último no DOM. Tocar 8px abaixo do quadrado do Correio Registado
	   seleccionava o Correio Azul e a encomenda ficava 1,72€ mais cara.
	   Com -9 o alvo mede exactamente o passo: 48x42, encostados, nunca
	   sobrepostos. */
	.pagina-checkout .checkout-check__caixa::before,
	.pagina-checkout .checkout-radio::before {
		content: "";
		position: absolute;
		left: -12px;
		right: -12px;
		top: -9px;
		bottom: -9px;
	}

	/* O ponto do rádio activo estava calibrado para os 15px do desenho. */
	.pagina-checkout .checkout-radio--ativo::after {
		left: 9px;
		top: 9px;
	}

	/* 4. O bloco do resumo deixa de ser uma grelha de três colunas: agora
	   cada fila trata de si e ao bloco só lhe compete empilhá-las.
	   Mantenho-o como grelha de uma coluna, e não em fluxo normal, por
	   uma razão concreta: em fluxo as margens colapsavam e os 16px do <p>
	   comiam os 6px do filete, que subia. A grelha não colapsa margens. */
	.pagina-checkout .checkout-resumo-bloco {
		display: grid;
		grid-template-columns: minmax(0, 1fr);
	}

	/* 5. Os dois filetes. A regra de 1836 esconde tudo o que case
	   `[class*="__divisor"]` com (0,3,1) — decoração calibrada ao canvas
	   largo — mas aqui separam blocos de informação e fazem falta; a
	   classe duplicada leva este selector a (0,4,0) e ganha sem
	   `!important`. `height: 1px !important` é que precisa dele: vence o
	   `height: auto` do refluxo (1796, (0,12,1)); medido, sem ele o
	   filete mede 0.
	   Cai o `width: auto !important` que aqui estava: o refluxo já escreve
	   `width: auto` e, sem ele, o filete continua a medir 344,03px a 360,
	   390 e 430. O `grid-column: 1 / -1` também cai — o bloco passou a ter
	   uma coluna só. */
	.pagina-checkout .checkout-resumo-bloco .checkout-resumo__divisor.checkout-resumo__divisor {
		display: block;
		height: 1px !important;
		margin: 6px 0 22px;
		background: var(--cor-cinza-medio, #a4a7a9);
	}

	/* 6. Campos à largura da coluna, com folga e altura de toque.
	   O desenho dá alturas por campo (`height: 9px`, `9.5px`, ...) porque
	   no canvas de 1920 o input é só o filete de baixo; em mobile isso é
	   uma linha de 9px sem área de toque. 48px é o mínimo. Os 16px de
	   corpo evitam o zoom automático do Safari ao focar o campo. */
	.pagina-checkout .checkout-campo.checkout-campo input,
	.pagina-checkout .checkout-notas.checkout-notas textarea {
		width: 100% !important;
		box-sizing: border-box;
		font-size: 16px;
		line-height: 26px;
	}

	.pagina-checkout .checkout-campo.checkout-campo input {
		height: 48px !important;
		padding: 14px 0 7px;
	}

	.pagina-checkout .checkout-notas.checkout-notas textarea {
		height: 96px !important;
		padding: 14px 0 7px;
	}

	.pagina-checkout .checkout-campo input::placeholder,
	.pagina-checkout .checkout-notas textarea::placeholder {
		font-size: 16px;
		line-height: 26px;
	}

	.pagina-checkout .checkout-campo {
		margin-bottom: 14px;
	}

	/* 7. A altura do desenho (955,5px) mais os 210,5px de margem eram do
	   canvas de 1920; em fluxo sobrava uma tira vazia no fim da secção. */
	.pagina-checkout .checkout-conteudo {
		margin-bottom: 40px;
	}

	/* 8. A lista de erros vive fora do `.seccao-inner` e ficava colada às
	   duas margens do ecrã. */
	.pagina-checkout .checkout-erro {
		padding-left: 23px;
		padding-right: 23px;
		box-sizing: border-box;
	}
}

/* ------------------------------------------------------------
 * REVISÃO v5, R119 (PDF p.27) — «o formulário de login está
 * desformatado»
 * ------------------------------------------------------------ */

/* Apanha, pela mesma raiz, quatro ecrãs: o login em `/minha-conta/`, o
 * cartão de Criar Conta, o de recuperar palavra-passe e o MODAL de login
 * que o rodapé rende em todas as páginas.
 *
 * O cartão do mock é 583×560 em absoluto, com todos os filhos absolutos
 * em coordenadas do canvas de 1920. Em mobile partia de duas maneiras
 * diferentes, conforme o sítio:
 *
 * — DENTRO do `.site-content`, a regra de refluxo (0,11,1) ganhava ao
 *   `.login-card__campo { width: 100% }` (0,1,0) que eu já cá tinha, e
 *   devolvia `width/height: auto` aos <input>: os campos caíam para a
 *   largura intrínseca — 218 numa coluna de 344 — colados um ao outro. O
 *   botão escapava porque um bloco posterior lhe impõe 251×61 com
 *   `!important`, e daí o contraste que se via no print: não era o botão
 *   que estava grande, eram os campos que tinham encolhido.
 *
 * — FORA dele (o modal do rodapé) não há refluxo nenhum, e era pior: os
 *   40px de padding somavam-se aos 583 em `content-box`, o cartão ficava
 *   com 623 e, centrado por `translateX(-50%)`, sangrava 116px para cada
 *   lado de um ecrã de 390 — com o X de fechar fora do ecrã. É o login
 *   que a maioria dos visitantes encontra primeiro, pelo ícone de conta.
 *
 * O mock não tem desenho mobile para este cartão. Derivo-o do
 * `.recuperar__card`, que é o irmão do mesmo fluxo e já está afinado:
 * 344 de largura (a goteira de 23 do `.seccao-inner`), interior em fluxo.
 *
 * `!important` em toda a linha porque são dois adversários diferentes:
 * dentro do `.site-content` é o refluxo que é preciso vencer, fora dele
 * são as medidas absolutas do próprio mock. */
@media (max-width: 430px) {

	/* A secção é branca lisa e tapava a textura do corpo — o cartão
	   branco sobre fundo branco deixava de se ler como cartão. No
	   desktop é o `__overlay` cinzento que faz esse trabalho, e esse
	   continua escondido em mobile. */
	.login-cenario {
		background: transparent;
	}

	.login-card {
		position: relative !important;
		left: auto !important;
		top: auto !important;
		right: auto !important;
		transform: none !important;
		box-sizing: border-box !important;
		width: 344px !important;
		max-width: calc(100% - 46px) !important;
		height: auto !important;
		margin-top: 40px !important;
		margin-right: auto !important;
		margin-bottom: 56px !important;
		margin-left: auto !important;
		padding-top: 32px !important;
		padding-right: 24px !important;
		padding-bottom: 28px !important;
		padding-left: 24px !important;
		background: #ffffff;
		border-radius: 20px;
	}

	/* Interior em fluxo — no modal do rodapé o refluxo não chega lá.
	   O `.screen-reader-text` fica de fora: o WooCommerce mantém-no
	   `position: absolute !important` e, sem esta excepção, esta regra
	   punha as labels em fluxo e cada campo ganhava 18px de fantasma
	   por cima. */
	.login-card > *:not(.login-card__fechar):not(.screen-reader-text) {
		position: static !important;
		left: auto !important;
		top: auto !important;
		transform: none !important;
	}

	h1.login-card__titulo,
	h2.login-card__titulo {
		width: 100% !important;
		margin-top: 0 !important;
		margin-right: 0 !important;
		margin-bottom: 28px !important;
		margin-left: 0 !important;
	}

	/* A escala mobile de H1 do projecto (44/52). Na página já vinha do
	   refluxo; aqui é para o modal, que fora do `.site-content` ficava
	   nos 52/62 do canvas de 1920. */
	h1.login-card__titulo {
		font-size: 44px;
		line-height: 52px;
	}

	.login-card__campo {
		display: block !important;
		box-sizing: border-box !important;
		width: 100% !important;
		height: 52px !important;
		margin-top: 0 !important;
		margin-right: 0 !important;
		margin-bottom: 12px !important;
		margin-left: 0 !important;
	}

	.login-card__campo--2 {
		margin-bottom: 24px !important;
	}

	/* As mesmas medidas que o resto do site impõe aos botões, para que o
	   botão do modal não seja outro botão. */
	.login-card__submeter {
		display: flex !important;
		/* Acompanha a regra acima: este botão existe precisamente para ter
		   as mesmas medidas dos outros, e em content-box ficava 2px mais
		   alto do que todos eles. Não é redundante com ela — o modal do
		   rodapé está fora do `.site-content` e aquela não lhe chega. */
		box-sizing: border-box !important;
		padding-top: 0 !important;
		padding-bottom: 0 !important;
		width: 251px !important;
		max-width: 100% !important;
		height: 50px !important;
		padding-left: 0 !important;
		padding-right: 0 !important;
		margin-top: 0 !important;
		margin-right: auto !important;
		margin-bottom: 40px !important;
		margin-left: auto !important;
	}

	p.login-card__link {
		width: 100% !important;
		margin-top: 0 !important;
		margin-right: 0 !important;
		margin-bottom: 0 !important;
		margin-left: 0 !important;
		font-size: 16px;
		line-height: 26px;
	}

	/* O texto do link tem 22px de alto; o padding leva o alvo aos 44
	   sem mexer no ritmo, porque os dois links ficam com margem zero. */
	p.login-card__link a {
		display: inline-block;
		padding-top: 11px;
		padding-right: 8px;
		padding-bottom: 11px;
		padding-left: 8px;
	}

	.login-card--registo .woocommerce-privacy-policy-text {
		width: 100% !important;
		margin-top: 0 !important;
		margin-right: 0 !important;
		margin-bottom: 24px !important;
		margin-left: 0 !important;
	}

	/* Fechar: o refluxo esvaziava o elemento (0×0, um <a> sem conteúdo) e
	   os seus pseudo-elementos — que o `*` do refluxo não apanha — ficavam
	   absolutos sem antepassado posicionado. Resultado: as duas barras do
	   X desenhadas na origem do documento, por baixo do header. Volta a
	   ser um alvo real de 44×44 no canto do cartão. */
	.login-card__fechar {
		display: block !important;
		position: absolute !important;
		left: auto !important;
		top: 6px !important;
		right: 6px !important;
		width: 44px !important;
		height: 44px !important;
		transform: none !important;
	}

	.login-card__fechar::before,
	.login-card__fechar::after {
		left: 8px;
		top: 21px;
		width: 28px;
	}

	/* Mesma causa, outro ecrã: recuperar palavra-passe, que não usa
	   `.login-card`. O campo ficava 240×28 dentro de 296 úteis. */
	.recuperar__campo {
		box-sizing: border-box !important;
		width: 100% !important;
		height: 52px !important;
	}

	/* Os avisos do WooCommerce (credenciais erradas, email já registado)
	   vivem fora do cartão e o refluxo dá-lhes a largura toda: o texto
	   encostava aos dois bordos. O padding não é escrito pelo refluxo. */
	/* A goteira passou a vir do próprio aviso, quando lhes dei caixa e
	   cor no bloco dos avisos do WooCommerce. Mantê-la aqui somava:
	   medido, a mensagem de «já existe uma conta com este email» ficava a
	   x=46 com 298 de largura, contra os 23/344 de todos os outros avisos
	   do site. */
	.login-card__avisos {
		padding-left: 0;
		padding-right: 0;
	}
}

/* ------------------------------------------------------------
 * Arrastar para navegar — sliders e galeria do produto
 * ------------------------------------------------------------ */

/* A classe é posta pelo `ligarArrastoSlides()` no main.js, e é ela que
 * torna o gesto possível: sem `touch-action`, o browser decide sozinho
 * que um dedo a mover-se é scroll da página, entrega-lhe o gesto, e o
 * `preventDefault` do `pointermove` já não o pode recuperar.
 *
 * `pan-y` deixa passar o scroll vertical — quem quiser continuar a
 * descer a página com o dedo em cima do slider consegue. `pinch-zoom`
 * fica explícito porque `pan-y` sozinho DESLIGA o zoom de dois dedos, e
 * a WCAG 1.4.4 conta com ele.
 *
 * Isto vale só para os sliders de fundido e para a imagem do produto.
 * As pistas de scroll (carrosséis da home, produtos relacionados) NÃO
 * levam esta classe: aí o gesto de toque é do browser, com inércia e
 * snap nativos, e eu só lhes acrescento o arrasto com o rato. */
.sda-arrastavel {
	touch-action: pan-y pinch-zoom;
}

/* Enquanto o rato arrasta uma pista, o snap tem de sair do caminho:
 * com `scroll-snap-type: x mandatory` activo, cada píxel de `scrollLeft`
 * que eu escrevo é imediatamente puxado de volta ao cartão mais próximo
 * e a pista não se mexe. Volta a entrar quando se larga, e é aí que ela
 * assenta no cartão. */
.sda-a-arrastar {
	scroll-snap-type: none !important;
	scroll-behavior: auto !important;
	cursor: grabbing;
	user-select: none;
}

/* O cursor diz que a pista se pode agarrar — só onde o arrasto de rato
 * está mesmo ligado, que é onde há mais do que um cartão. */
@media (hover: hover) and (pointer: fine) {

	.sda-carrossel-mobile,
	.home-actividades__pista,
	.seccao-produtos-relacionados__grelha {
		cursor: grab;
	}
}

/* ------------------------------------------------------------
 * Checkout em mobile: rótulo visível assim que o campo tem valor
 * ------------------------------------------------------------ */

/* Defeito reportado pelo Francisco: «não dá para identificar o campo do
 * CP no formulário do checkout». O placeholder estava certo — o que
 * aconteceu foi o preenchimento automático do browser. O desenho usa
 * placeholder EM VEZ de rótulo visível, e assim que alguma coisa escreve
 * um valor no campo o placeholder desaparece e não sobra identificação
 * nenhuma. No print dele o código postal mostrava «-» e o email mostrava
 * o endereço, ambos sem dizer o que eram.
 *
 * É o problema conhecido do placeholder-como-rótulo (WCAG 3.3.2), e
 * agrava-se no telemóvel, onde o preenchimento automático é a norma.
 *
 * O rótulo já existe no markup — está lá para leitores de ecrã. Aqui
 * passa a aparecer quando o campo tem valor ou está focado, que é
 * exactamente quando o placeholder deixa de o dizer. O espaço dos 18px
 * é RESERVADO sempre, com o rótulo em absoluto por cima: se ele entrasse
 * em fluxo, cada campo preenchido empurrava os de baixo 18px e a página
 * saltava enquanto se escreve.
 *
 * Só em mobile: em desktop os campos são absolutos com `top` fixo e um
 * rótulo visível empurrava o <input> 26px para fora do sítio.
 *
 * A dupla classe no selector é para vencer, com folga, a regra global
 * que devolve `.screen-reader-text` a 1x1 com `!important` mais acima
 * neste ficheiro — sem ela ficavam ambas em (0,3,1) e a ordem no
 * ficheiro passava a ser a única coisa a decidir. */
@media (max-width: 430px) {

	.pagina-checkout .checkout-campo.checkout-campo,
	.pagina-checkout .checkout-notas.checkout-notas {
		position: relative !important;
		padding-top: 18px;
	}

	.pagina-checkout .checkout-campo.checkout-campo > label,
	.pagina-checkout .checkout-notas.checkout-notas > label {
		position: absolute !important;
		left: 0 !important;
		top: 0 !important;
		width: auto !important;
		height: 18px !important;
		margin: 0 !important;
		padding: 0 !important;
		overflow: visible !important;
		clip: auto !important;
		clip-path: none !important;
		white-space: nowrap !important;
		display: block;
		font-size: 12px;
		line-height: 18px;
		letter-spacing: 0.04em;
		text-transform: uppercase;
		color: var(--cor-titulos-tom, #483846);
		opacity: 0;
		transition: opacity 0.15s ease;
		pointer-events: none;
	}

	/* `:placeholder-shown` é falso quando o campo tem valor — inclusive
	   quando quem lho pôs foi o browser. É por isso que apanha o caso do
	   preenchimento automático, que um `:not(:empty)` não apanharia. */
	.pagina-checkout .checkout-campo.checkout-campo:has( input:focus ) > label,
	.pagina-checkout .checkout-campo.checkout-campo:has( input:not(:placeholder-shown) ) > label,
	.pagina-checkout .checkout-notas.checkout-notas:has( textarea:focus ) > label,
	.pagina-checkout .checkout-notas.checkout-notas:has( textarea:not(:placeholder-shown) ) > label {
		opacity: 1;
	}
}

/* ------------------------------------------------------------
 * Tabelas do conteúdo editorial
 * ------------------------------------------------------------ */

/* A caixa vem do `sda_tabelas_rolaveis()` em inc/helpers.php. Aqui só lhe
 * dou o scroll e o foco. É `tabindex="0"` com `role="region"` porque uma
 * caixa que rola tem de ser alcançável por teclado — quem não usa rato
 * nem dedo não teria como ver a parte de fora. */
.sda-tabela-rolavel {
	overflow-x: auto;
	max-width: 100%;
	-webkit-overflow-scrolling: touch;
}

.sda-tabela-rolavel:focus-visible {
	outline: 2px solid var(--cor-primaria, #a787a3);
	outline-offset: 2px;
}

/* Sem isto a tabela encolhia para caber e as colunas ficavam espremidas
 * em vez de a caixa rolar — o problema mudava de sítio em vez de se
 * resolver. */
.sda-tabela-rolavel > table {
	min-width: max-content;
}

/* ------------------------------------------------------------
 * Alvos de toque dos dots — tratamento único para as quatro famílias
 * ------------------------------------------------------------ */

/* REGRESSÃO MINHA, apanhada a medir. Eu tinha resolvido isto com um alvo
 * ASSIMÉTRICO — cada dot crescia 16px para a esquerda e 3,5 para a
 * direita, com o último espelhado. Com DOIS dots funciona: o segundo é
 * `:last-child`, cresce para o outro lado, e não tapa o primeiro.
 *
 * Com QUATRO deixa de funcionar, e ninguém tinha reparado. Cada dot
 * cresce 16px para a esquerda sobre um passo de 20 — invade o vizinho
 * anterior por 16px e, por pintar depois, rouba-lhe o toque. Medido no
 * banner da loja a 390px: dos 13px da própria caixa, os dots 1 e 2
 * respondiam em **3**, e o toque no centro deles devolvia o dot
 * seguinte. Ou seja: os dois primeiros slides do banner eram
 * inalcançáveis. O mesmo desenho estava nos testemunhos, com 12 de 13.
 *
 * A causa de fundo é o passo: 13px de dot mais 7 de intervalo dão 20, e
 * um alvo de 24 — o mínimo da WCAG 2.5.8 — não cabe em 20 sem invadir
 * alguém. Não há geometria que salve isto; é preciso mais espaço.
 *
 * Abro o intervalo para 14 (passo 27) e volto a um alvo SIMÉTRICO de 7px
 * de cada lado: cada dot fica com 27 de largura, exactamente até meio do
 * intervalo, sem tocar no vizinho. Quatro dots ocupam 94px de uma coluna
 * de 344 — sobra espaço de sobra. Os dots continuam a medir 13: o que
 * cresce é só a área invisível de toque. */
@media (max-width: 430px) {

	/* O prefixo forte é para vencer as regras que já cá estavam com
	   `gap: 7px` e especificidade (0,3,1) — sem ele o intervalo não
	   mudava e o alvo ficava nos 20px de sempre. */
	body:not(.pagina-home-final) .site-content .loja-banner__dots,
	body:not(.pagina-home-final) .site-content .home-loja__dots,
	body:not(.pagina-home-final) .site-content .home-actividades__dots,
	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados__dots,
	body:not(.pagina-home-final) .site-content .seccao-testemunhos__paginacao,
	.pagina-home-final .home-loja__dots,
	.pagina-home-final .home-actividades__dots,
	.pagina-home-final .seccao-testemunhos__paginacao {
		gap: 14px;
	}

	.loja-banner__dot,
	.home-loja__dot-mobile,
	.seccao-produtos-relacionados__dot,
	.seccao-testemunhos__dot {
		position: relative;
	}

	.loja-banner__dot::after,
	.home-loja__dot-mobile::after,
	.seccao-produtos-relacionados__dot::after,
	.seccao-testemunhos__dot::after {
		content: "";
		position: absolute;
		inset: -16px -7px;
	}
}

/* A seta de «página seguinte» do blog é só a imagem do SVG: 11x22, sem
 * caixa de clique à volta. Fica a menos de metade do mínimo de 24x24, e é
 * o controlo que leva à página 2 — em desktop também, que é onde a
 * paginação do blog se usa. O alvo cresce sem mexer no desenho. */
.seccao-artigos-paginacao-seguinte::after,
.seccao-artigos-paginacao-anterior::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: 44px;
	height: 44px;
	transform: translate(-50%, -50%);
}

/* Em desktop a seta já é `position: absolute` no mock, e portanto já é
   bloco contentor do seu próprio pseudo-elemento — pôr-lhe `relative`
   destruía o `left: 561px` e mandava-a para fora da fila (medi: passou a
   0x0). Só em mobile, onde o refluxo a devolve a `static`, é preciso
   dar-lhe posicionamento de volta. */
@media (max-width: 430px) {

	body:not(.pagina-home-final) .site-content .seccao-artigos-paginacao-seguinte,
	body:not(.pagina-home-final) .site-content .seccao-artigos-paginacao-anterior {
		position: relative !important;
	}
}

/* ------------------------------------------------------------
 * Contraste do botão primário no hover
 * ------------------------------------------------------------ */

/* O mock manda o texto do botão continuar branco quando o fundo passa de
 * roxo a rosa no hover (main.css:139). Medi os dois estados: branco sobre
 * #A787A3 dá 3,16:1 e branco sobre #ECC6C0 dá **1,57:1** — o rótulo fica
 * praticamente invisível com o rato em cima, em todos os botões do site.
 * O mínimo AA para este texto é 4,5:1 (18px a 600 fica 0,66px abaixo do
 * limiar de «texto grande»).
 *
 * O texto escuro sobre o mesmo rosa dá 6,95:1. Mexo só no hover: em
 * repouso o botão fica exactamente como a designer o desenhou.
 *
 * O `.botao-lista` leva o mesmo tratamento — partilha o par de cores e o
 * ícone é `currentColor`, por isso acompanha sozinho. */
.botao-principal:hover,
.botao-principal:focus-visible,
.botao-lista:hover,
.botao-lista:focus-visible {
	color: #483846;
}

/* O ponto de 3,16:1 em repouso fica assinalado e não corrigido: baixar a
 * luminosidade da primária mexe na cor de marca em todo o site e é
 * decisão da designer, não minha. */

/* ------------------------------------------------------------
 * Páginas legais: a secção tem de crescer com o texto
 * ------------------------------------------------------------ */

/* O `.bloco-legal--conteudo` acima já liberta a altura do bloco, mas essa
 * era só metade do problema — e a metade que se vê era a outra.
 *
 * A secção continua com os `height: 1597px` do desenho (main.css:2225) e a
 * coluna continua em `position: absolute` (2230). Um filho absoluto não
 * conta para a altura do pai: o texto cresce, a secção não, e o rodapé
 * arranca onde sempre arrancou. Medido a 1920 em `/termos-e-condicoes/`:
 * secção a acabar em y=2052, rodapé a começar em y=2788, e **136 dos 631
 * blocos de texto pintados por baixo dele**. Na Política são 122, nas
 * Devoluções 85. O documento continua mais 15 000px sem cabeçalho nem
 * rodapé por cima. A ≤430px não acontece, porque lá o refluxo já põe tudo
 * em fluxo — é um defeito só de computador, que é onde se lêem termos.
 *
 * A coluna volta a fluxo e passa a dar a altura à secção. Mantenho-a onde
 * o desenho a põe: os 433px viram margem esquerda, e a largura de 968
 * fica. O menu lateral é absoluto (main.css:2095) e não se mexe.
 *
 * O `min-height` guarda os 1597 do desenho para quando uma página legal
 * for curta — assim o menu lateral nunca fica mais alto do que a secção
 * que o contém.
 *
 * É um desvio deliberado ao canvas de 1920, e assumo-o: a alternativa é
 * publicar os Termos e a Política com o texto escondido debaixo do
 * rodapé, num site de comércio electrónico.
 *
 * Em mobile estas três propriedades são reescritas pela regra de refluxo,
 * que tem (0,11,1) contra os (0,1,0) daqui — verifiquei que lá continua
 * tudo em coluna única. */
.seccao-conteudo-legal {
	height: auto;
	min-height: 1597px;
	padding-bottom: 120px;
}

.seccao-conteudo-legal__coluna {
	position: relative;
	left: auto;
	top: auto;
	margin-left: 433px;
	width: 968px;
}

/* ============================================================
 * CARRINHO E AREA DE CLIENTE  (bloco final)
 * ============================================================ */

/* wrappers novos: nenhuma caixa acima de 430 */
.carrinho-cupao,
.carrinho-resumo {
	display: contents;
}

/* rotulos que so o telemovel mostra */
.carrinho-cupao__rotulo,
.conta-ver-linha__qtd-rotulo {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
	white-space: nowrap;
}

.carrinho-cupao__nota {
	display: none;
}

/* estado do ACTUALIZAR */
.botao-principal:disabled,
.carrinho-cupao__actualizar:disabled {
	background: var(--cor-cinza-claro, #d6d7d9);
	color: var(--cor-footer, #483846);
}

.botao-principal:disabled:hover,
.botao-principal:disabled:focus-visible,
.carrinho-cupao__actualizar:disabled:hover,
.carrinho-cupao__actualizar:disabled:focus-visible {
	background: var(--cor-cinza-claro, #d6d7d9);
	color: var(--cor-footer, #483846);
}

.carrinho-cupao__actualizar:not(:disabled) {
	background: var(--cor-primaria, #a787a3);
	color: #ffffff;
}

.carrinho-cupao__actualizar:not(:disabled):hover,
.carrinho-cupao__actualizar:not(:disabled):focus-visible {
	background: var(--cor-rosa, #ecc6c0);
	color: var(--cor-footer, #483846);
}

/* anel de foco do radio de envio */
.carrinho-envio-opcao__radio:has( input:focus-visible ) {
	outline: 2px solid var(--cor-primaria, #a787a3);
	outline-offset: 3px;
}

/* paginacao da conta */
.conta-paginacao {
	position: absolute;
	left: 385px;
	display: flex;
	align-items: center;
	gap: 12px;
}

.conta-paginacao__pagina {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: 59px;
	height: 59px;
	border-radius: 50%;
	font: 400 22px/1 var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
	text-decoration: none;
}

.conta-paginacao__pagina--activa {
	border: 1px solid var(--cor-primaria, #a787a3);
	color: var(--cor-primaria, #a787a3);
}

/* lista de desejos: a classe de body nova acorda main.css:6967 */
body.pagina-conta-lista-desejos .conta-conteudo {
	height: auto;
	min-height: 620px;
	margin-bottom: 130px;
	padding-bottom: 80px;
}

@media (max-width: 430px) {

/* ---------- CARRINHO: linha ---------- */
body:not(.pagina-home-final) .site-content .carrinho-linha {
	position: relative;
	left: auto !important;
	top: 0 !important;
	width: 100% !important;
	height: auto !important;
	min-height: 0 !important;
	display: grid;
	grid-template-columns: 80px auto minmax(0, 1fr) 48px;
	column-gap: 8px;
	row-gap: 8px;
	align-items: center;
	margin-top: 0 !important;
	margin-bottom: 0 !important;
	padding-top: 0 !important;
	padding-bottom: 12px !important;
}

body:not(.pagina-home-final) .site-content .carrinho-linha__miniatura {
	grid-column: 1;
	grid-row: 1 / span 2;
	align-self: start;
	width: 80px !important;
	height: 77px !important;
	object-fit: cover;
}

body:not(.pagina-home-final) .site-content p.carrinho-linha__nome {
	grid-column: 2 / -1;
	grid-row: 1;
	align-self: start;
	min-width: 0;
	margin-top: 0;
	margin-bottom: 0;
	font-size: 16px;
	line-height: 24px;
}

body:not(.pagina-home-final) .site-content p.carrinho-linha__nome a {
	display: flex;
	align-items: center;
	min-height: 48px;
	overflow-wrap: anywhere;
}

body:not(.pagina-home-final) .site-content .carrinho-linha__quantidade {
	grid-column: 2;
	grid-row: 2;
	display: inline-flex !important;
	align-items: center;
	justify-content: space-between;
	box-sizing: border-box;
	width: 128px !important;
	height: 48px !important;
	padding-left: 4px;
	padding-right: 4px;
}

body:not(.pagina-home-final) .site-content .carrinho-linha__qtd-menos,
body:not(.pagina-home-final) .site-content .carrinho-linha__qtd-mais,
body:not(.pagina-home-final) .site-content .conta-desejos__qtd-menos,
body:not(.pagina-home-final) .site-content .conta-desejos__qtd-mais {
	display: inline-block;
	box-sizing: content-box;
	width: 20px !important;
	height: 20px !important;
	padding-top: 14px;
	padding-right: 14px;
	padding-bottom: 14px;
	padding-left: 14px;
	margin-top: 0 !important;
	margin-right: 0 !important;
	margin-bottom: 0 !important;
	margin-left: 0 !important;
}

body:not(.pagina-home-final) .site-content .carrinho-linha__preco {
	grid-column: 3;
	grid-row: 2;
	margin-left: 0 !important;
	font-size: 16px;
	text-align: right;
}

body:not(.pagina-home-final) .site-content .carrinho-linha__remover {
	grid-column: 4;
	grid-row: 2;
	display: inline-flex !important;
	align-items: center;
	justify-content: center;
	box-sizing: border-box;
	width: 48px !important;
	height: 48px !important;
	padding-top: 0;
	padding-right: 0;
	padding-bottom: 0;
	padding-left: 0;
}

body:not(.pagina-home-final) .site-content .carrinho-tabela__divisor {
	display: block;
	width: 100% !important;
	height: 1px !important;
	margin-top: 0;
	margin-bottom: 16px;
	background: var(--cor-cinza-claro, #d6d7d9);
}

/* ---------- CARRINHO: cupao ---------- */
body:not(.pagina-home-final) .site-content .carrinho-cupao {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	column-gap: 12px;
	align-items: end;
	margin-top: 16px;
	padding-top: 24px;
	border-top: 1px solid var(--cor-cinza-claro, #d6d7d9);
}

body:not(.pagina-home-final) .site-content .carrinho-cupao__rotulo {
	position: static !important;
	width: auto !important;
	height: auto !important;
	overflow: visible;
	clip-path: none;
	white-space: normal !important;
	grid-column: 1 / -1;
	margin-top: 0;
	margin-bottom: 8px;
	font-size: 15px;
	line-height: 22px;
	text-transform: uppercase;
	color: var(--cor-texto, #696969);
}

body:not(.pagina-home-final) .site-content .carrinho-cupao .carrinho-cupao__campo {
	grid-column: 1;
	box-sizing: border-box;
	width: 100% !important;
	max-width: 100% !important;
	height: 50px !important;
	margin-top: 0 !important;
	margin-right: 0 !important;
	margin-bottom: 0 !important;
	margin-left: 0 !important;
	padding-left: 16px;
	font-size: 16px;
	line-height: 48px;
}

body:not(.pagina-home-final) .site-content .carrinho-cupao .carrinho-cupao__aplicar {
	grid-column: 2;
	width: auto !important;
	min-width: 104px;
	height: 50px !important;
	min-height: 50px !important;
	padding-left: 20px !important;
	padding-right: 20px !important;
	margin-top: 0 !important;
	margin-right: 0 !important;
	margin-bottom: 0 !important;
	margin-left: 0 !important;
	font-size: 16px;
}

body:not(.pagina-home-final) .site-content .carrinho-cupao__actualizar {
	margin-top: 24px !important;
	margin-bottom: 8px !important;
}

body:not(.pagina-home-final) .site-content .carrinho-cupao__nota {
	display: block;
	width: 251px !important;
	margin-top: 0;
	margin-bottom: 32px;
	margin-left: auto !important;
	margin-right: auto !important;
	font-size: 14px;
	line-height: 20px;
	text-align: center;
	color: var(--cor-texto, #696969);
}

body:not(.pagina-home-final) .site-content .carrinho-cupao__actualizar:not(:disabled) + .carrinho-cupao__nota {
	display: none;
}

/* ---------- CARRINHO: cartao do resumo ---------- */
body:not(.pagina-home-final) .site-content .carrinho-resumo {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	column-gap: 12px;
	row-gap: 0;
	box-sizing: border-box;
	width: 100% !important;
	margin-top: 32px;
	margin-bottom: 40px;
	padding-top: 24px;
	padding-right: 24px;
	padding-bottom: 24px;
	padding-left: 24px;
	background: rgba(255, 255, 255, 0.4);
	border-radius: 30px;
}

body.pagina-carrinho-3:not(.pagina-home-final) .site-content .carrinho-resumo {
	grid-template-columns: 20px minmax(0, 1fr) auto;
}

body:not(.pagina-home-final) .site-content .carrinho-resumo > * {
	grid-column: 1 / -1;
}

body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__rotulo {
	grid-column: 1 / -2;
	width: auto !important;
	margin-top: 0 !important;
	margin-bottom: 16px !important;
	font-size: 16px;
	line-height: 26px;
}

body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__valor {
	grid-column: -2;
	width: auto !important;
	margin-top: 0 !important;
	margin-bottom: 16px !important;
	font-size: 16px;
	line-height: 26px;
	text-align: right;
}

body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__rotulo--total,
body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__valor--total {
	font-size: 20px;
	line-height: 30px;
	font-weight: 700;
	color: var(--cor-footer, #483846);
}

body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__rotulo--envio {
	grid-column: 1 / -1;
	width: auto !important;
	margin-bottom: 12px !important;
}

body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__divisor {
	display: block;
	width: 100% !important;
	height: 1px !important;
	margin-top: 0;
	margin-bottom: 16px;
	background: var(--cor-cinza-claro, #d6d7d9);
}

body.pagina-carrinho-3:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-envio-opcao__radio {
	grid-column: 1;
	position: relative !important;
	display: inline-block;
	box-sizing: border-box;
	width: 20px !important;
	height: 20px !important;
	margin-top: 14px !important;
	margin-right: 0 !important;
	margin-bottom: 14px !important;
	margin-left: 0 !important;
	align-self: center;
	border: 1px solid var(--cor-cinza-medio, #a4a7a9);
}

body.pagina-carrinho-3:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-envio-opcao__radio::before {
	width: 48px;
	height: 48px;
}

body.pagina-carrinho-3:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-envio-opcao__nome {
	grid-column: 2;
	display: flex;
	align-items: center;
	min-height: 48px;
	margin-top: 0;
	margin-bottom: 0;
	font-size: 16px;
	line-height: 24px;
}

body.pagina-carrinho-3:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-envio-opcao__preco {
	grid-column: -2;
	align-self: center;
	width: auto !important;
	margin-top: 0;
	margin-bottom: 0;
	font-size: 16px;
	line-height: 24px;
	text-align: right;
}

body.pagina-carrinho-3:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-envio-opcao__nota {
	margin-top: 16px;
	margin-bottom: 16px;
	font-size: 14px;
	line-height: 20px;
}

body:not(.pagina-home-final) .site-content .carrinho-resumo > p.carrinho-resumo__iva {
	width: 100% !important;
	margin-top: 0;
	margin-bottom: 24px;
	font-size: 14px;
	line-height: 20px;
	text-align: right;
}

body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__calcular,
body.pagina-carrinho-3:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-envio-opcao__alterar,
body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__finalizar {
	width: 100% !important;
	max-width: 100% !important;
	height: 50px !important;
	min-height: 50px !important;
	margin-top: 0 !important;
	margin-right: 0 !important;
	margin-bottom: 0 !important;
	margin-left: 0 !important;
	padding-top: 0;
	padding-bottom: 0;
	font-size: 16px;
}

body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__calcular,
body.pagina-carrinho-3:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-envio-opcao__alterar {
	margin-bottom: 16px !important;
}

body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-envio__form {
	margin-bottom: 8px;
}

/* Defeito anterior a esta ronda, e so a <=430: com o calculador aberto o
   radio orfao e o «Alterar morada» ficavam visiveis por cima dele. O
   `display: none` do `.pagina-carrinho-2` (0,2,0) perde para o
   `inline-block` de sda-extra:7626 e para o `flex` do bloco de R119, os
   dois (0,3,1). E o mesmo remendo que a linha 7657 ja faz ao «Calcular». */
body:not(.pagina-home-final).pagina-carrinho-2 .site-content .carrinho-envio-opcao__radio,
body:not(.pagina-home-final).pagina-carrinho-2 .site-content .carrinho-envio-opcao__alterar {
	display: none !important;
}

/* ---------- CARRINHO: calculador de portes ---------- */
body:not(.pagina-home-final) .site-content .carrinho-envio__rotulo {
	display: block;
	margin-top: 0;
	margin-bottom: 6px;
	font-size: 15px;
	line-height: 22px;
}

body:not(.pagina-home-final) .site-content .carrinho-envio__form .carrinho-envio__campo {
	box-sizing: border-box;
	width: 100% !important;
	max-width: 100% !important;
	height: 50px !important;
	margin-top: 0 !important;
	margin-right: 0 !important;
	margin-bottom: 16px !important;
	margin-left: 0 !important;
	padding-left: 16px;
	font-size: 16px;
	line-height: 48px;
}

body:not(.pagina-home-final) .site-content .carrinho-envio__campo--pais img {
	top: 20px !important;
}

body:not(.pagina-home-final) .site-content .carrinho-envio__form .carrinho-envio__actualizar {
	width: 100% !important;
	max-width: 100% !important;
	height: 50px !important;
	min-height: 50px !important;
	margin-top: 0 !important;
	margin-right: 0 !important;
	margin-bottom: 0 !important;
	margin-left: 0 !important;
	font-size: 16px;
}

/* ---------- CONTA: menu lateral ---------- */
body:not(.pagina-home-final) .site-content .conta-menu {
	margin-top: 0;
	margin-bottom: 28px;
	border-bottom: 1px solid var(--cor-cinza-claro, #d6d7d9);
}

body:not(.pagina-home-final) .site-content .conta-menu li {
	border-top: 1px solid var(--cor-cinza-claro, #d6d7d9);
}

body:not(.pagina-home-final) .site-content .conta-menu li a {
	display: flex;
	align-items: center;
	min-height: 48px !important;
	font-size: 16px;
	line-height: 24px;
}

/* ---------- CONTA: tracos e divisores ---------- */
body:not(.pagina-home-final) .site-content .conta-campo > span,
body:not(.pagina-home-final) .site-content .conta-encomenda__divisor,
body:not(.pagina-home-final) .site-content .conta-ver__divisor {
	display: block;
	width: 100% !important;
	height: 1px !important;
	margin-top: 8px;
	background: var(--cor-cinza-medio, #a4a7a9);
}

/* ---------- CONTA: painel ---------- */
body.pagina-conta-dados-pessoais .site-content .woocommerce-MyAccount-content {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 48px;
	column-gap: 12px;
	align-items: center;
}

body.pagina-conta-dados-pessoais .site-content .woocommerce-MyAccount-content > * {
	grid-column: 1 / -1;
}

body.pagina-conta-dados-pessoais .site-content .woocommerce-MyAccount-content > h2.conta-titulo {
	grid-column: 1;
	margin-top: 24px;
	margin-bottom: 16px;
}

body.pagina-conta-dados-pessoais .site-content .woocommerce-MyAccount-content > .conta-editar {
	grid-column: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px !important;
	height: 48px !important;
	margin-top: 24px;
	margin-bottom: 16px;
}

body:not(.pagina-home-final) .site-content .conta-campo {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	column-gap: 12px;
	align-items: center;
	margin-bottom: 20px;
}

body:not(.pagina-home-final) .site-content .conta-campo:has(.conta-olho) {
	grid-template-columns: minmax(0, 1fr) 48px;
}

body:not(.pagina-home-final) .site-content .conta-campo > label,
body:not(.pagina-home-final) .site-content .conta-campo > span {
	grid-column: 1 / -1;
}

body:not(.pagina-home-final) .site-content .conta-campo > p {
	grid-column: 1;
	min-width: 0;
	overflow-wrap: anywhere;
	margin-top: 2px;
	margin-bottom: 0;
	font-size: 16px;
	line-height: 26px;
}

body:not(.pagina-home-final) .site-content .conta-campo > .conta-olho {
	grid-column: 2;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px !important;
	height: 48px !important;
}

body:not(.pagina-home-final) .site-content .conta-optin {
	display: grid;
	grid-template-columns: 22px minmax(0, 1fr);
	column-gap: 12px;
	align-items: start;
	margin-bottom: 24px;
}

body:not(.pagina-home-final) .site-content .conta-optin__caixa {
	display: block;
	box-sizing: border-box;
	width: 22px !important;
	height: 22px !important;
	margin-top: 2px;
	border: 1px solid var(--cor-cinza-medio, #a4a7a9);
}

body:not(.pagina-home-final) .site-content .conta-optin__texto {
	margin-top: 0;
	margin-bottom: 0;
	font-size: 16px;
	line-height: 26px;
}

/* ---------- CONTA: cartoes de encomenda ---------- */
body:not(.pagina-home-final) .site-content .conta-encomenda {
	position: relative;
	left: auto !important;
	top: 0 !important;
	width: 100% !important;
	height: auto !important;
	min-height: 0 !important;
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	column-gap: 12px;
	margin-top: 0;
	margin-bottom: 24px;
	padding-top: 0;
	padding-bottom: 0;
}

body:not(.pagina-home-final) .site-content .conta-encomenda > * {
	grid-column: 1 / -1;
}

body:not(.pagina-home-final) .site-content .conta-encomenda > .conta-encomenda__rotulo {
	grid-column: 1;
	margin-top: 0;
	margin-bottom: 12px;
	font-size: 16px;
	line-height: 24px;
}

body:not(.pagina-home-final) .site-content .conta-encomenda > .conta-encomenda__valor {
	grid-column: 2;
	width: auto !important;
	min-width: 0;
	overflow-wrap: anywhere;
	margin-top: 0;
	margin-bottom: 12px;
	font-size: 16px;
	line-height: 24px;
	text-align: right;
}

body:not(.pagina-home-final) .site-content .conta-encomenda > .conta-encomenda__titulo {
	margin-top: 0;
	margin-bottom: 12px;
	font-size: 20px;
	line-height: 28px;
}

body:not(.pagina-home-final) .site-content .conta-encomenda > .conta-badge {
	justify-self: start;
	margin-bottom: 20px;
}

body:not(.pagina-home-final) .site-content .conta-encomenda > .conta-encomenda__reencomendar {
	margin-bottom: 12px !important;
}

body:not(.pagina-home-final) .site-content .conta-encomenda > .conta-encomenda__ver-mais {
	margin-bottom: 20px !important;
}

/* ---------- CONTA: ver encomenda ---------- */
body.pagina-conta-ver-encomenda .site-content .woocommerce-MyAccount-content {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	column-gap: 12px;
}

body.pagina-conta-ver-encomenda .site-content .woocommerce-MyAccount-content > * {
	grid-column: 1 / -1;
}

body.pagina-conta-ver-encomenda .site-content .woocommerce-MyAccount-content > .conta-ver__rotulo {
	grid-column: 1;
	margin-top: 0;
	margin-bottom: 12px;
	font-size: 16px;
	line-height: 24px;
}

body.pagina-conta-ver-encomenda .site-content .woocommerce-MyAccount-content > .conta-ver__valor {
	grid-column: 2;
	width: auto !important;
	min-width: 0;
	overflow-wrap: anywhere;
	margin-top: 0;
	margin-bottom: 12px;
	font-size: 16px;
	line-height: 24px;
	text-align: right;
}

body.pagina-conta-ver-encomenda .site-content .conta-ver__cabecalho--quantidade,
body.pagina-conta-ver-encomenda .site-content .conta-ver__cabecalho--preco {
	display: none;
}

body:not(.pagina-home-final) .site-content .conta-ver-linha {
	display: grid;
	grid-template-columns: 88px minmax(0, 1fr) auto;
	column-gap: 12px;
	row-gap: 8px;
	align-items: center;
	margin-bottom: 20px;
}

body:not(.pagina-home-final) .site-content .conta-ver-linha__miniatura {
	grid-column: 1;
	grid-row: 1 / span 2;
	align-self: start;
	width: 88px !important;
	height: 88px !important;
	object-fit: cover;
}

body:not(.pagina-home-final) .site-content p.conta-ver-linha__nome {
	grid-column: 2 / -1;
	grid-row: 1;
	align-self: start;
	min-width: 0;
	overflow-wrap: anywhere;
	margin-top: 0;
	margin-bottom: 0;
	font-size: 16px;
	line-height: 24px;
}

body:not(.pagina-home-final) .site-content .conta-ver-linha__qtd-rotulo {
	position: static !important;
	width: auto !important;
	height: auto !important;
	overflow: visible;
	clip-path: none;
	white-space: normal !important;
}

body:not(.pagina-home-final) .site-content .conta-ver-linha__quantidade {
	grid-column: 2;
	grid-row: 2;
	font-size: 16px;
}

body:not(.pagina-home-final) .site-content .conta-ver-linha__preco {
	grid-column: 3;
	grid-row: 2;
	font-size: 16px;
	text-align: right;
}

body:not(.pagina-home-final) .site-content .confirmacao-multibanco {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	column-gap: 12px;
}

/* ---------- CONTA: formularios crus do WooCommerce ---------- */
body:not(.pagina-home-final) .site-content .woocommerce-MyAccount-content input[type="text"],
body:not(.pagina-home-final) .site-content .woocommerce-MyAccount-content input[type="email"],
body:not(.pagina-home-final) .site-content .woocommerce-MyAccount-content input[type="tel"],
body:not(.pagina-home-final) .site-content .woocommerce-MyAccount-content input[type="password"],
body:not(.pagina-home-final) .site-content .woocommerce-MyAccount-content textarea {
	box-sizing: border-box;
	width: 100% !important;
	max-width: 100% !important;
	height: 48px !important;
}

body.pagina-conta-morada .site-content .woocommerce-MyAccount-content label,
body.pagina-conta-editar .site-content .woocommerce-MyAccount-content label {
	padding-top: 6px;
	padding-bottom: 6px;
}

/* O olho do WooCommerce e um <button> a seguir ao <input> dentro de um
   <span> inline. Com o refluxo os dois ficam em linhas separadas e o olho
   fica numa linha so dele por baixo do campo. Fila unica. */
body:not(.pagina-home-final) .site-content .woocommerce-MyAccount-content .password-input {
	display: flex;
	align-items: center;
	column-gap: 8px;
	box-sizing: border-box;
	width: 100% !important;
}

body:not(.pagina-home-final) .site-content .woocommerce-MyAccount-content .password-input input {
	flex: 1 1 auto;
	min-width: 0;
}

body:not(.pagina-home-final) .site-content .woocommerce-MyAccount-content button.show-password-input {
	flex: 0 0 48px;
	box-sizing: border-box;
	min-width: 48px !important;
	width: 48px !important;
	min-height: 48px !important;
	height: 48px !important;
	margin-top: 0;
	padding-top: 0;
	padding-right: 0;
	padding-bottom: 0;
	padding-left: 0;
	background: none;
	border: 0;
}

/* ---------- CONTA: lista de desejos ---------- */
/* A linha de accoes tem 344 e nao tem mais: com os botoes do stepper a 48
   o proprio stepper passou de 100 para 167 e empurrou o coracao para
   x=369,5 — 26,5px FORA da coluna. Medido antes e depois. A folga interna
   do stepper e o intervalo da linha pagam a diferenca. */
body:not(.pagina-home-final) .site-content .conta-desejos__accoes {
	column-gap: 16px;
}

body:not(.pagina-home-final) .site-content .conta-desejos__stepper {
	justify-content: space-between;
	box-sizing: border-box;
	width: 112px !important;
	gap: 0;
	padding-left: 0;
	padding-right: 0;
}

body:not(.pagina-home-final) .site-content .conta-desejos__remover {
	flex: 0 0 48px;
	width: 48px !important;
	height: 48px !important;
}

body:not(.pagina-home-final) .site-content .conta-desejos__nome a {
	overflow-wrap: anywhere;
}

/* ---------- CONTA: paginacao ---------- */
body:not(.pagina-home-final) .site-content .conta-paginacao {
	flex-wrap: wrap;
	justify-content: center;
	margin-top: 8px;
	margin-bottom: 40px;
}

body:not(.pagina-home-final) .site-content .conta-paginacao__pagina {
	width: 48px !important;
	height: 48px !important;
	font-size: 18px;
}

}

/* ------------------------------------------------------------
 * Avisos do WooCommerce
 * ------------------------------------------------------------ */

/* Reportado com print: os avisos apareciam sem caixa nenhuma, encostados às
 * duas margens do ecrã, e sem nada que distinguisse um erro («o produto
 * está esgotado») de uma confirmação («produto removido»). O CSS do
 * WooCommerce está desligado no tema — `woocommerce_enqueue_styles` devolve
 * array vazio — e nunca chegou a haver desenho para estes elementos.
 *
 * A goteira é a mesma do site (23 em mobile), a barra à esquerda dá a
 * leitura de estado sem depender só da cor, e as três variantes usam os
 * pastéis que o design system já define. */
.woocommerce-error,
.woocommerce-message,
.woocommerce-info {
	box-sizing: border-box;
	margin: 0 auto 24px;
	padding: 16px 20px 16px 18px;
	max-width: 1400px;
	border-left: 4px solid var(--cor-primaria, #a787a3);
	border-radius: 8px;
	background: #ffffff;
	list-style: none;
	font: 400 16px/26px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

.woocommerce-error {
	border-left-color: #e08b8c;
	background: #fdf2f2;
	/* O mesmo vermelho das mensagens do checkout; antes só lá é que era. */
	color: #A83E44;
}

.woocommerce-message {
	border-left-color: #6aa87d;
	background: #f1f8f3;
}

.woocommerce-info {
	border-left-color: #c9a227;
	background: #fdf9ec;
}

.woocommerce-error li,
.woocommerce-message li,
.woocommerce-info li {
	margin: 0;
	padding: 0;
	list-style: none;
}

.woocommerce-error li + li,
.woocommerce-message li + li,
.woocommerce-info li + li {
	margin-top: 8px;
}

/* O link «Anular?» que o WooCommerce mete dentro do aviso, e os «Ver
   carrinho» — sem isto herdavam o azul do browser. */
.woocommerce-error a,
.woocommerce-message a,
.woocommerce-info a {
	color: var(--cor-primaria, #a787a3);
	text-decoration: underline;
}

@media (max-width: 430px) {

	/* `!important` nas duas margens laterais: a regra de refluxo escreve
	   `margin-left: 0; margin-right: 0` com (0,11,1) e sem ela o aviso ia
	   de bordo a bordo, sem a goteira do site. As outras propriedades não
	   precisam — o refluxo não escreve padding nem margin-bottom. */
	.woocommerce-error,
	.woocommerce-message,
	.woocommerce-info {
		margin-left: 23px !important;
		margin-right: 23px !important;
		margin-bottom: 16px;
	}
}

/* ------------------------------------------------------------
 * Contraste dos rótulos: --cor-titulos-tom
 * ------------------------------------------------------------ */

/* Decisão do Francisco. O `#8E9193` do mock dá **3,17:1** sobre o creme e
 * sobre o branco — abaixo dos 4,5:1 que a WCAG AA pede para texto normal —
 * e é a cor de **85 nós** do site: rótulos de campos, notas de envio,
 * mensagens de erro do login e do checkout, datas dos testemunhos,
 * subtítulos dos heróis, «Presencial e Online» da barra fixa.
 *
 * `#696969` — que é o `--cor-texto`, já usado no corpo de texto do próprio
 * desenho — dá **5,49:1** e resolve os 85 de uma vez, sem inventar uma cor
 * que não exista na paleta.
 *
 * Redefino a variável em vez de perseguir os 49 selectores: é uma
 * substituição de tom, não uma correcção pontual, e assim nada fica para
 * trás quando alguém acrescentar um rótulo novo. É um desvio deliberado ao
 * espelho do Figma, e vale em desktop e em mobile — foi o que ele decidiu
 * quando lhe pus o número à frente.
 *
 * Não mexo na primária: essa continua nos 3,16:1 e fica assinalada para a
 * designer, porque escurecê-la altera a cor de marca em todo o site. */
:root {
	--cor-titulos-tom: #696969;
}

/* O contentor do aviso leva `tabindex="-1"` do WooCommerce e é focado por
 * JS — o anel azul do browser aparecia à volta da caixa, como se vê no
 * print. Some no foco programático e fica para quem navega por teclado. */
.woocommerce-error:focus:not(:focus-visible),
.woocommerce-message:focus:not(:focus-visible),
.woocommerce-info:focus:not(:focus-visible) {
	outline: none;
}

.woocommerce-error:focus-visible,
.woocommerce-message:focus-visible,
.woocommerce-info:focus-visible {
	outline: 2px solid var(--cor-primaria, #a787a3);
	outline-offset: 2px;
}

/* ------------------------------------------------------------
 * REVISÃO v5, R95 — responder a um comentário no telemóvel
 * ------------------------------------------------------------ */

/* Ninguém conseguia responder a um comentário em mobile, e a causa é a
 * armadilha do `z-index` outra vez: o link já tem `z-index: 1` para ficar
 * por cima do cartão, mas o refluxo escreve-lhe `position: static`, e num
 * elemento estático o `z-index` é **inerte**. O `.artigo-comentario__card`
 * é `position: absolute` e, por ser posicionado, pinta por cima.
 *
 * Medido a 360, 390 e 430: `elementFromPoint` no centro dos quatro links
 * devolve `SPAN.artigo-comentario__card`. A 1920 devolve o link — lá ele
 * fica `relative` e o `z-index` conta. E não é só o botão: o mesmo <span>
 * tapa o nome, a data e qualquer ligação dentro do comentário.
 *
 * `!important` porque a regra de refluxo escreve `position` com (0,11,1). */
@media (max-width: 430px) {

	body:not(.pagina-home-final) .site-content .comment-reply-link {
		position: relative !important;
		z-index: 2;
	}
}

/* Em mobile o botão da conta acompanha os 50px que o Francisco fixou para
   todos os botões, e passa a estar centrado como os das outras páginas.
   A especificidade tem de igualar a da regra acima — a genérica dos
   botões, com (0,3,1), perdia para ela. */
@media (max-width: 430px) {}

/* ------------------------------------------------------------
 * Estado de erro nos campos de formulário
 * ------------------------------------------------------------ */

/* O `CLAUDE.md` do projecto já manda isto — «adicionar `aria-invalid="true"`
 * → borda e texto em `state-error`» — mas nunca chegou a existir regra
 * nenhuma. Medido: ao submeter o checkout em branco, oito campos ganham
 * `aria-invalid="true"` e ficam com a MESMA borda cinzenta dos válidos
 * (`rgb(164,167,169)`). A lista de erros diz o que falta, mas quem olha
 * para o formulário não vê qual dos dezoito campos é que é.
 *
 * A cor não é o `state-error` da paleta: o `#FFA2A3` dá 1,76:1 sobre o
 * fundo do checkout, e a WCAG 1.4.11 pede 3:1 para um indicador que não é
 * texto — ficava menos visível do que a borda normal, que já dá 2,22.
 * `#C4545A` dá 4,05:1, é a mesma família de cor, e passa com folga.
 *
 * A borda não é o único sinal: o `::after` do campo acrescenta forma, para
 * quem não distingue a cor (WCAG 1.4.1, «não usar só a cor»). */
/* REVISÃO v6 — um só vermelho de erro no site, o #A83E44 das mensagens do
   checkout (5,63:1 sobre o creme; o #C4545A que aqui estava dava 4,05 e
   ficava a 9 ΔE do outro, os dois à vista no mesmo ecrã). */
.site-content [aria-invalid="true"] {
	border-bottom-color: #A83E44 !important;
}

.site-content input[aria-invalid="true"],
.site-content textarea[aria-invalid="true"],
.site-content select[aria-invalid="true"] {
	background-image: linear-gradient(to top, rgba(168, 62, 68, 0.08), rgba(168, 62, 68, 0.08));
	background-repeat: no-repeat;
}

/* O rótulo flutuante do checkout acompanha o estado do campo. */
.pagina-checkout .checkout-campo:has( input[aria-invalid="true"] ) > label {
	color: #A83E44;
}

/* ------------------------------------------------------------
 * Artigos da home: os três em vez de um só
 * ------------------------------------------------------------ */

/* O mock esconde os cartões 2 e 3 em mobile (main.css:8441) e deixa dois
 * pontos decorativos num contentor `aria-hidden`, sem listener nenhum:
 * dois dos três artigos em destaque eram inalcançáveis no telemóvel.
 * A designer previu carrossel e nunca o especificou — é exactamente o que
 * o cliente reportou nos R23 e R24 para as secções da loja e das
 * actividades, nesta mesma página, e esta ficou de fora.
 *
 * Mesmo tratamento que já dei a essas duas: pista com scroll-snap, os
 * cartões em fluxo dentro dela, e os pontos ligados pelo
 * `ligarCarrosselMobile()`. Acima de 430px a pista é inerte e os cartões
 * continuam absolutos, como o desenho os põe. */
.home-blog__pista {
	display: contents;
}

@media (max-width: 430px) {

	.pagina-home-final .home-blog__pista {
		position: absolute;
		left: 0;
		top: 89px;
		width: 390px;
		height: 552px;
		display: flex;
		gap: 16px;
		padding: 0 25px;
		box-sizing: border-box;
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scroll-snap-type: x mandatory;
		scroll-padding-left: 25px;
		-webkit-overflow-scrolling: touch;
		scrollbar-width: none;
	}

	.pagina-home-final .home-blog__pista::-webkit-scrollbar {
		display: none;
	}

	/* Desfaz o `display: none` dos cartões 2 e 3 e tira os três do
	   absoluto para entrarem na pista. Os filhos de cada cartão continuam
	   a resolver contra ele, que se mantém posicionado. */
	.pagina-home-final .home-blog-card--1,
	.pagina-home-final .home-blog-card--2,
	.pagina-home-final .home-blog-card--3 {
		display: block;
		position: relative;
		left: auto;
		top: auto;
		flex: 0 0 341px;
		width: 341px;
		height: 552px;
		background: #ffffff;
		border-radius: 20px;
		scroll-snap-align: start;
	}
}

/* ============================================================
 * CARTÃO DE PRODUTO — o desenho mobile, todo num sítio
 * ============================================================
 *
 * Pedido do Francisco: «o card de produto não deveria ser um elemento
 * global?». O markup já era — `template-parts/loja/produto-card.php`,
 * usado pelos seis sítios que o rendem. O que não era é isto: o desenho
 * mobile estava espalhado por OITO blocos diferentes deste ficheiro, com
 * DEZASSEIS propriedades escritas mais do que uma vez. Quem lesse o
 * ficheiro não conseguia dizer como é o cartão sem simular a cascata —
 * e havia declarações que nunca chegavam a pintar, como o
 * `padding-bottom: 24px` anulado por um `0` mil linhas abaixo.
 *
 * Aqui está tudo junto, pela mesma ordem relativa em que estava. É uma
 * refactoração e não um redesenho: capturei a posição e vinte e quatro
 * propriedades computadas de 434 elementos, em cinco sítios por quatro
 * larguras, antes e depois, e o critério foi zero diferenças.
 * ============================================================ */
@media (max-width: 430px) {

	/* Interior em fluxo. As excepções são os "cartões", que continuam a
	   ser o contexto de posicionamento do seu próprio interior. */
	body:not(.pagina-home-final) .site-content *:not(.produto-card):not(.seccao-artigos-card):not(.conta-encomenda):not(.carrinho-linha):not(.categoria-card):not(.card-actividade):not(.lista-terapias-card):not(.seccao-formulario__hp):not(.accordion-faq-cabecalho):not(.curso-como-funciona-cabecalho) {
		position: static;
		left: auto;
		top: auto;
		right: auto;
		bottom: auto;
		width: auto;
		max-width: 100%;
		height: auto;
		min-height: 0;
		transform: none;
		translate: none;
		margin-left: 0;
		margin-right: 0;
		white-space: normal;
	}

	body:not(.pagina-home-final) .site-content .produto-card,
	body:not(.pagina-home-final) .site-content .seccao-artigos-card,
	body:not(.pagina-home-final) .site-content .conta-encomenda,
	body:not(.pagina-home-final) .site-content .carrinho-linha,
	body:not(.pagina-home-final) .site-content .categoria-card,
	body:not(.pagina-home-final) .site-content .card-actividade,
	body:not(.pagina-home-final) .site-content .lista-terapias-card {
		position: relative;
		left: auto;
		top: auto;
		width: 100%;
		margin: 0 0 24px;
	}

	body:not(.pagina-home-final) .loja-produtos__grelha .produto-card {
		width: 100%;
	}

	/* REVISÃO v5, R23 (PDF p.5) — «o slider não funciona». Não havia
	   nada para deslizar: o mock esconde os produtos 3 e 4
	   (main.css:8039) e a pista ficava com scrollWidth === clientWidth
	   (344px nos dois). Os quatro voltam à pista, e passa a haver
	   segunda página para os dots levarem. */
	.pagina-home-final .home-loja__grelha .produto-card:nth-child(n+3) {
		display: list-item;
	}

	/* No mobile o reflow anula width/height — o botão ficava 0x0 e era
	   impossível escolher quantidade em toda a loja. */
	body:not(.pagina-home-final) .site-content .produto-card__qtd-menos,
	body:not(.pagina-home-final) .site-content .produto-card__qtd-mais,
	body:not(.pagina-home-final) .site-content .produto-ficha__qtd-menos,
	body:not(.pagina-home-final) .site-content .produto-ficha__qtd-mais,
	body:not(.pagina-home-final) .site-content .carrinho-linha__qtd-menos,
	body:not(.pagina-home-final) .site-content .carrinho-linha__qtd-mais {
		display: inline-block;
		width: 20px !important;
		height: 20px !important;
		padding: 12px;
		margin: 0;
		box-sizing: content-box;
	}

	/* Selo ESGOTADO: saía de cima da imagem e passava a partilhar a linha
	   com o coração. O .produto-card está na lista de excepções do reflow,
	   por isso continua a servir de contexto de posicionamento. */
	.produto-card__esgotado {
		position: absolute !important;
		left: 22px !important;
		top: 22px !important;
	}

	body:not(.pagina-home-final) .site-content .produto-card__qtd-menos,
	body:not(.pagina-home-final) .site-content .produto-card__qtd-mais,
	body:not(.pagina-home-final) .site-content .produto-ficha__qtd-menos,
	body:not(.pagina-home-final) .site-content .produto-ficha__qtd-mais,
	body:not(.pagina-home-final) .site-content .carrinho-linha__qtd-menos,
	body:not(.pagina-home-final) .site-content .carrinho-linha__qtd-mais,
	body:not(.pagina-home-final) .site-content .conta-desejos__qtd-menos,
	body:not(.pagina-home-final) .site-content .conta-desejos__qtd-mais {
		position: relative !important;
	}

	body:not(.pagina-home-final) .site-content .produto-card,
	body:not(.pagina-home-final) .site-content .seccao-artigos-card,
	body:not(.pagina-home-final) .site-content .conta-encomenda,
	body:not(.pagina-home-final) .site-content .carrinho-linha,
	body:not(.pagina-home-final) .site-content .categoria-card,
	body:not(.pagina-home-final) .site-content .card-actividade,
	body:not(.pagina-home-final) .site-content .lista-terapias-card {
		height: auto;
		min-height: 0;
		padding-bottom: 24px;
	}

	body:not(.pagina-home-final) .site-content .produto-card__faixa {
		height: auto;
		min-height: 0;
	}

	/* Numa coluna de 153px um nome comprido chega a 4 linhas e transborda o
	   cartão. Limitado a 3, como o título da ficha já faz a 2 — o nome
	   completo está sempre à distância de um toque, na página do produto. */
	body:not(.pagina-home-final) .site-content .produto-card__nome,
	body:not(.pagina-home-final) .site-content .produto-card__nome a {
		display: -webkit-box;
		-webkit-line-clamp: 3;
		-webkit-box-orient: vertical;
		overflow: hidden;
	}

	/* O stepper só tem uma geometria em todo o CSS — a do canvas de 1920
	   (left 143, top 101, 101x40), medida contra uma faixa de 318x168. No
	   canvas mobile a faixa mede 166x103: 143+101 = 244 e 101+40 = 141,
	   ou seja transbordava 78px à direita e 38px em baixo. Como a pista do
	   carrossel tem `overflow-x: auto` (e portanto `overflow-y` computa
	   `auto`), o stepper era recortado — viam-se 2px por baixo do cartão —
	   e a pista passava a ter 38px de scroll VERTICAL. É o «fica com scroll
	   na secção» do report do Francisco.
	   Aqui vai a caixa em coordenadas do canvas mobile: encostada à
	   esquerda e alinhada em baixo com o ícone do carrinho. */
	.pagina-home-final .produto-card--no-carrinho .produto-card__quantidade {
		display: flex !important;
		left: 12px;
		top: 65px;
		right: auto;
		width: 96px;
		height: 32px;
		padding: 0 10px;
		border-radius: 10px;
		box-sizing: border-box;
	}

	/* Com o selector aberto o preço não cabe: em 166px de faixa o preço em
	   promoção já chega aos 114px e o ícone do carrinho abre aos 122. É o
	   mesmo princípio da regra de desktop que esconde o <del> quando o
	   selector abre. */
	.pagina-home-final .produto-card--no-carrinho .produto-card__preco {
		display: none;
	}

	/* O canvas mobile da home redeclara `left`/`top` em px para o coração
	   do cartão, mas NÃO redeclara `translate` — o -50%/-50% do
	   centramento de desktop sobrevivia e somava-se aos 5/6px do mock,
	   atirando metade do coração para fora do círculo de 21px. Reposto o
	   par completo, que dá o mesmo resultado que o mock queria. */
	.pagina-home-final .produto-card__desejos img {
		left: 50%;
		top: 50%;
		translate: -50% -50%;
	}

	.pagina-home-final .produto-card__carrinho,
	body:not(.pagina-home-final) .site-content .produto-card__carrinho {
		width: 32px !important;
		height: 24px !important;
	}

	.pagina-home-final .produto-card__carrinho img,
	body:not(.pagina-home-final) .site-content .produto-card__carrinho img {
		width: 100% !important;
		height: 100% !important;
		max-width: none !important;
		object-fit: contain;
	}

	body:not(.pagina-home-final) .site-content .produto-card__desejos {
		position: absolute !important;
		top: 12px !important;
		right: 12px !important;
		left: auto !important;
		width: 40px !important;
		height: 40px !important;
		display: flex !important;
		align-items: center;
		justify-content: center;
	}

	body:not(.pagina-home-final) .site-content .produto-card__desejos img {
		width: 18px !important;
		height: 18px !important;
	}

	/* Defeito maior que ninguém tinha reportado: sem `position`, o ícone
	   do carrinho do cartão voltava ao tamanho intrínseco e media
	   166x151 — o cartão inteiro passava de 366 para 490px de altura. */
	body:not(.pagina-home-final) .site-content .produto-card__carrinho {
		display: block !important;
		margin-left: auto !important;
	}

	body:not(.pagina-home-final) .site-content .produto-card__faixa {
		padding-left: 12px !important;
		padding-right: 12px !important;
		/* 6px por baixo, que é a folga que o cartão da home dá ao ícone do
		   carrinho até ao bordo. Aqui era ZERO: o ícone encostava ao fundo
		   e, com o canto arredondado do cartão, lia-se como se estivesse a
		   sair. Report do Francisco. */
		padding-bottom: 6px !important;
		box-sizing: border-box !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados__grelha > .produto-card {
		flex: 0 0 calc((100% - 12px) / 2);
		width: calc((100% - 12px) / 2);
		/* Equivalente flex do `minmax(0, 1fr)` que a grelha usava antes:
		   um item de flex tem `min-width: auto`, e a largura de min-content
		   de um nome comprido empurrava o cartão de 166 para 173, com o
		   passo da pista a ficar irregular (178/178/185). */
		min-width: 0;
		margin-bottom: 0;
		scroll-snap-align: none;
	}

	/* Snap por PÁGINA (dois cartões) e não por cartão — mesma decisão da
	   home: com o snap em todos os filhos um arrasto podia parar a meio,
	   com meio produto de cada página no ecrã. */
	body:not(.pagina-home-final) .site-content .seccao-produtos-relacionados__grelha > .produto-card:nth-child(odd) {
		scroll-snap-align: start;
	}

	/* O preço acompanha, pela mesma razão e pela mesma referência: 22px
	   em mobile contra os 16 do cartão da home. */
	body:not(.pagina-home-final) .site-content .produto-card__preco,
	body:not(.pagina-home-final) .site-content .produto-card__preco del,
	body:not(.pagina-home-final) .site-content .produto-card__preco ins {
		font-size: 16px;
	}

	body:not(.pagina-home-final) .site-content .produto-card > a,
	body:not(.pagina-home-final) .site-content .produto-card__imagem {
		display: block;
	}

	body:not(.pagina-home-final) .site-content .produto-card {
		padding-bottom: 0;
	}

	/* A foto não tinha altura nenhuma e desenhava-se no aspecto do
	   ficheiro — 166x166 em três produtos e 166x161 nos outros seis. Daí
	   as faixas a começarem a alturas diferentes. O rácio é o do cartão
	   mobile da home. Os 30px de canto são do canvas de 1920, onde valem
	   9,4% dos 318 do cartão; em 166 valem 18,1%. */
	body:not(.pagina-home-final) .site-content .produto-card__imagem {
		width: 100% !important;
		height: auto !important;
		aspect-ratio: 166 / 191;
		object-fit: cover;
		border-radius: 16px 16px 0 0;
	}

	/* A faixa passa a grelha de duas colunas: o nome ocupa a linha toda,
	   o preço e o carrinho partilham a segunda — como em desktop e como
	   na home. A linha de 46px é a altura exacta do stepper aberto, para
	   o cartão NÃO crescer quando se toca no carrinho. Estava a crescer
	   46px de cada vez, e a grelha inteira saltava. */
	body:not(.pagina-home-final) .site-content .produto-card__faixa {
		display: grid;
		grid-template-columns: minmax(0, 1fr) 32px;
		grid-template-rows: auto minmax(46px, auto);
		column-gap: 8px;
		align-items: center;
		padding: 12px !important;
		border-radius: 0 0 16px 16px;
	}

	/* Caixa de altura fixa para o nome, como o mock faz em desktop (56) e
	   na home (44). É isto que alinha os preços. */
	body:not(.pagina-home-final) .site-content .produto-card__nome {
		grid-column: 1 / -1;
		grid-row: 1;
		align-self: start;
		min-height: 44px !important;
		margin: 0 !important;
	}

	/* O clamp TEM de ser declarado também no <a> de dentro: a regra que
	   já existe põe `-webkit-line-clamp: 3` nos dois, e é o do <a> que
	   manda — declarar só no <h3> não produz efeito nenhum. */
	body:not(.pagina-home-final) .site-content .produto-card__nome,
	body:not(.pagina-home-final) .site-content .produto-card__nome a {
		-webkit-line-clamp: 2;
	}

	body:not(.pagina-home-final) .site-content .produto-card__preco {
		grid-column: 1;
		grid-row: 2;
		line-height: 24px;
	}

	/* O preço riscado a 14 e não a 16: na célula de 102px o par
	   «24,90€ 19,90€» mede 107,9 a 16px e quebrava em duas linhas. */
	body:not(.pagina-home-final) .site-content .produto-card__preco del {
		font-size: 14px;
	}

	body:not(.pagina-home-final) .site-content .produto-card__carrinho {
		grid-column: 2;
		grid-row: 2;
		justify-self: end;
		margin-left: 0 !important;
	}

	/* Com o stepper aberto o preço sai, como o cartão da home já faz.
	   Assim o stepper ocupa o lugar do preço em vez de acrescentar uma
	   linha. */
	body:not(.pagina-home-final) .site-content .produto-card--no-carrinho .produto-card__preco {
		display: none;
	}

	body:not(.pagina-home-final) .site-content .produto-card__quantidade {
		grid-column: 1;
		grid-row: 2;
		justify-self: start;
		padding: 0 !important;
	}

	/* Sem isto os botões encolhem para 32,6px na célula estreita e a área
	   de toque de 44 desaparecia. */
	body:not(.pagina-home-final) .site-content .produto-card__qtd-menos,
	body:not(.pagina-home-final) .site-content .produto-card__qtd-mais {
		flex: 0 0 auto;
	}

	/* O selo mantinha os 104x32 do canvas de 1920 — 63% da largura de um
	   cartão de 166 — e SOBREPUNHA-SE ao coração em 12px. O texto passa a
	   escuro: branco sobre #FFA2A3 dá 1,92:1 e a WCAG AA pede 4,5;
	   #483846 dá 5,67:1. */
	body:not(.pagina-home-final) .site-content .produto-card__esgotado {
		left: 12px !important;
		top: 12px !important;
		padding: 2px 8px;
		font-size: 11px;
		line-height: 16px;
		border-radius: 6px;
		color: #483846;
	}

	.conta-conteudo .woocommerce-MyAccount-content button:not(.produto-card *):not(.conta-desejos *),
	.conta-conteudo .woocommerce-MyAccount-content input[type="submit"] {
		/* `flex` e não o `inline-flex` da regra base: margens `auto` só
		   centram caixas de nível de BLOCO, e num elemento de nível de
		   linha não fazem nada. Foi por isso que à primeira o botão
		   continuou encostado a x=23 com as margens já postas. */
		display: flex;
		height: 50px;
		margin-left: auto;
		margin-right: auto;
	}
}


/* ============================================================
 * DEFEITO 1 — tranca visual enquanto os portes recalculam
 * ============================================================
 * O método de envio e a morada só chegam à sessão do WooCommerce
 * quando o pedido AJAX responde; até lá o resumo no ecrã está morto.
 * Quem submeter nessa janela confirma um número e é cobrado outro
 * (medi 10,58 € no ecrã e 12,30 € na encomenda, com 300 ms de
 * latência). O `main.js` tranca a submissão; isto é o que a torna
 * legível — um botão que não responde e não explica lê-se como avaria.
 *
 * Sem `!important`: o refluxo dos ≤430px (sda-extra.css:9754,
 * especificidade (0,11,1)) escreve position/left/top/right/bottom/
 * width/max-width/height/min-height/transform/translate/margin-left/
 * margin-right/white-space — nenhuma das propriedades daqui. E o `*`
 * dessa regra não apanha pseudo-elementos.
 * ------------------------------------------------------------ */
.sda-a-calcular::after {
	content: "";
	display: inline-block;
	width: 8px;
	height: 8px;
	margin-left: 8px;
	border-radius: 50%;
	background-color: currentColor;
	animation: sda-a-calcular 900ms ease-in-out infinite;
}

@keyframes sda-a-calcular {
	0%, 100% { opacity: 0.25; }
	50%      { opacity: 1; }
}

@media ( prefers-reduced-motion: reduce ) {
	.sda-a-calcular::after {
		animation: none;
		opacity: 0.6;
	}
}

/* O «Finalizar Compra» do carrinho é uma <a href> e não um <button>:
   o `:disabled` que já pinta o botão do checkout (sda-extra.css:1908 e
   :8659) não lhe pega. Reponho o mesmo cinzento e o mesmo cursor pelo
   `aria-disabled`, que é o que o JS lhe escreve. */
.botao-principal.sda-a-calcular[aria-disabled="true"] {
	background-color: var( --cor-cinza-claro, #d6d7d9 );
	color: var( --cor-footer, #483846 );
	cursor: not-allowed;
}

/* O resumo esbate-se enquanto está desactualizado: sem isto o cliente
   lê um total já morto como se fosse o definitivo. */
[data-sda-checkout-resumo][aria-busy="true"] {
	opacity: 0.55;
	transition: opacity 120ms linear;
}


/* ------------------------------------------------------------
 * ENVIO — o número REAL de métodos da zona
 *
 * O desenho de 1920 só previu duas filas de envio, e o template
 * cortava as restantes (`if ( $sda_r >= 2 ) break`). Depois de o
 * `free_shipping` — os «Portes Gratuitos a partir de 50€» que o
 * cabeçalho da loja promete — passar às cinco zonas, o Norte e
 * Lisboa passaram a ter QUATRO métodos (dois `flat_rate`, um
 * `local_pickup` e o `free_shipping`) e o cliente nunca chegava a
 * ver os portes grátis.
 *
 * Duas coisas mudam aqui.
 *
 * 1) A GEOMETRIA DA FILA DEIXA DE VIR DO MODIFICADOR. `--registado`
 *    e `--azul` eram a POSIÇÃO no ciclo com nome de método
 *    (main.css:5777-5778, 5791-5792, 5804-5805): bastava o
 *    WooCommerce devolver os métodos por outra ordem para o estilo
 *    mentir sobre o que é cada fila. O `top` passa a sair de
 *    `--sda-fila`, o índice que o template escreve inline, e o
 *    modificador passa a ser o `method_id` — serve para dar um
 *    gancho a QUEM é a fila, não a ONDE ela está.
 *
 * 2) TUDO O QUE ESTÁ ABAIXO DESCE. `--sda-envio-extra` é
 *    `filas × passo − 2 × 43px`: com as duas filas do mock dá zero
 *    e o desenho fica intocado; com três ou quatro empurra o
 *    divisor, o Total, o IVA, o pagamento e o botão.
 *
 * O PASSO. O mock dá 43px por fila (rádio 179 → 222, nome 169 →
 * 212), que só chega para uma linha de texto. Medi os rótulos reais
 * a Nunito 22: «Correio Registado» 175,63px, «Levantamento na loja»
 * 211,81px e «Envio grátis (encomendas > 50€)» 323,52px — e a banda
 * do nome tem 311px no checkout e 306px no carrinho. O rótulo dos
 * portes grátis NÃO cabe numa linha em banda nenhuma, e é ele que
 * aparece sempre que há três ou mais filas. Por isso o passo abre
 * para 79px (duas linhas de 36 + os mesmos 7px de folga do mock) a
 * partir da terceira fila. Se o cliente encurtar o título do método
 * em WooCommerce para «Envio grátis» (129px), basta apagar as
 * quatro declarações de `--sda-passo: 79px` e o resumo volta a ser
 * compacto.
 *
 * O NÚMERO DE FILAS VEM DE `:has()` e não de uma propriedade inline
 * como o `--sda-carrinho-extra` (cart.php:67): no checkout o resumo
 * é substituído por AJAX (`bloco.innerHTML`, main.js:1023) e o
 * contentor que teria a propriedade fica FORA da troca — ficaria com
 * o número de filas da morada anterior. O `:has()` reavalia sozinho.
 * Cobre até seis filas; acima disso as filas voltam a empilhar-se, e
 * é preciso acrescentar mais um degrau.
 *
 * Só acima de 430: abaixo disso o resumo é uma grelha em fluxo e
 * estes `top` nem sequer pintam (o refluxo escreve `top: auto` com
 * (0,11,1), sda-extra.css:9754). O media query é para o leitor, não
 * para a cascata.
 * ------------------------------------------------------------ */

@media ( min-width: 431px ) {

	.checkout-conteudo,
	.carrinho-conteudo {
		--sda-filas: 2;
		--sda-passo: 43px;
		--sda-envio-extra: calc( var( --sda-filas ) * var( --sda-passo ) - 86px );
	}

	.checkout-conteudo:has( .checkout-linha--envio ~ .checkout-linha--envio ~ .checkout-linha--envio ) {
		--sda-filas: 3;
		--sda-passo: 79px;
	}

	.checkout-conteudo:has( .checkout-linha--envio ~ .checkout-linha--envio ~ .checkout-linha--envio ~ .checkout-linha--envio ) {
		--sda-filas: 4;
	}

	.checkout-conteudo:has( .checkout-linha--envio ~ .checkout-linha--envio ~ .checkout-linha--envio ~ .checkout-linha--envio ~ .checkout-linha--envio ) {
		--sda-filas: 5;
	}

	.checkout-conteudo:has( .checkout-linha--envio ~ .checkout-linha--envio ~ .checkout-linha--envio ~ .checkout-linha--envio ~ .checkout-linha--envio ~ .checkout-linha--envio ) {
		--sda-filas: 6;
	}

	.carrinho-conteudo:has( .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ) {
		--sda-filas: 3;
		--sda-passo: 79px;
	}

	.carrinho-conteudo:has( .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ) {
		--sda-filas: 4;
	}

	.carrinho-conteudo:has( .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ) {
		--sda-filas: 5;
	}

	.carrinho-conteudo:has( .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ~ .carrinho-envio-opcao__preco ) {
		--sda-filas: 6;
	}

	/* ---- CHECKOUT: a fila ---- */

	/* O `left` era do modificador `--registado`/`--azul` (os dois a
	   1017); passa para a classe da fila, que é onde sempre pertenceu. */
	.checkout-radio--envio {
		left: 1017px;
		top: calc( 179px + var( --sda-fila, 0 ) * var( --sda-passo, 43px ) );
	}

	.checkout-envio__nome,
	.checkout-envio__preco {
		top: calc( 169px + var( --sda-fila, 0 ) * var( --sda-passo, 43px ) );
	}

	/* O nome não tinha largura: crescia até onde quisesse e o rótulo
	   dos portes grátis (323,52px a partir de 1044) passava por cima
	   do preço, que está encostado a 1355. A banda tem 311px; reservo
	   73 para o preço mais largo desta loja («15,37€», 69px) e 16 de
	   goteira. «Levantamento na loja» (211,81px) continua numa linha.
	   O tecto é SÓ dentro da fila. Escrevi-o primeiro em
	   `.checkout-envio__nome` e medi: a mensagem do estado sem código
	   postal — «Indique o código postal para calcular os portes.», que
	   usa a mesma classe e não tem preço nenhum ao lado — passava de
	   duas linhas (356px de largura, 72px de altura) para três (222px,
	   108px) e ia bater na nota, que está fixa a 253. */
	.checkout-linha--envio .checkout-envio__nome {
		max-width: 222px;
	}

	/* ---- CHECKOUT: o que desce ---- */

	/* Selectores iguais aos do original, não mais específicos: o
	   sda-extra.css carrega depois do main.css e ganha pela ordem.
	   Subir a especificidade mudaria a cascata contra regras que nada
	   têm que ver com isto. */
	p.checkout-envio__nota {
		top: calc( 253px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-resumo__divisor--2 {
		top: calc( 386.5px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-resumo__rotulo--total,
	.checkout-resumo__valor--total {
		top: calc( 414px + var( --sda-envio-extra, 0px ) );
	}

	p.checkout-resumo__iva {
		top: calc( 447px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-resumo__rotulo--pagamento {
		top: calc( 496px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-radio--multibanco {
		top: calc( 560px + var( --sda-envio-extra, 0px ) );
	}

	/* Substitui sda-extra.css:1449 (o `left` dela mantém-se lá). */
	.checkout-radio--mbway,
	.checkout-radio--cod {
		top: calc( 620px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-radio--paypal {
		top: calc( 679px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-pagamento__nome--multibanco {
		top: calc( 550px + var( --sda-envio-extra, 0px ) );
	}

	/* Substitui sda-extra.css:1455. */
	.checkout-pagamento__nome--mbway,
	.checkout-pagamento__nome--cod {
		top: calc( 609px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-pagamento__icone--multibanco {
		top: calc( 551px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-pagamento__icone--mbway {
		top: calc( 612px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-pagamento__icone--paypal {
		top: calc( 669px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-finalizar {
		top: calc( 769px + var( --sda-envio-extra, 0px ) );
	}

	/* A newsletter TEM de vir depois dos termos: partilha a classe
	   `.checkout-termos` e as duas regras têm a mesma especificidade —
	   é a ordem que decide, tal como hoje em sda-extra.css:2285. */
	.checkout-termos {
		top: calc( 852px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-newsletter {
		top: calc( 892px + var( --sda-envio-extra, 0px ) );
	}

	.checkout-resumo__fundo {
		height: calc( 715px + var( --sda-envio-extra, 0px ) );
	}

	/* O estado MB WAY deixa de ter baseline própria. O mockup fixou-a
	   (PayPal a 930, botão a 1020, fundo a 966) porque desenhou dois
	   métodos com o MB WAY em primeiro; com sete, e com a caixa a abrir
	   em qualquer um deles, quem trata do empurrão é `--sda-pag-caixa`
	   mais abaixo. Estas continuam a existir só para vencer as de
	   main.css:5975-5978, que são (0,2,0) e ganhariam por especificidade
	   às genéricas. */
	.pagina-checkout-1 .checkout-finalizar {
		top: calc( 769px + var( --sda-envio-extra, 0px ) + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
	}

	.pagina-checkout-1 .checkout-termos {
		top: calc( 852px + var( --sda-envio-extra, 0px ) + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
	}

	.pagina-checkout-1 .checkout-newsletter {
		top: calc( 892px + var( --sda-envio-extra, 0px ) + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
	}

	.pagina-checkout-1 .checkout-resumo__fundo {
		height: calc( 715px + var( --sda-envio-extra, 0px ) + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
	}

	/* ---- CARRINHO: a fila ---- */

	.pagina-carrinho-3 .carrinho-envio-opcao__radio {
		top: calc( 145px + var( --sda-fila, 0 ) * var( --sda-passo, 43px ) );
	}

	.pagina-carrinho-3 .carrinho-envio-opcao__nome,
	.pagina-carrinho-3 .carrinho-envio-opcao__preco {
		top: calc( 135px + var( --sda-fila, 0 ) * var( --sda-passo, 43px ) );
	}

	/* Banda de 306px (1049 → 1355), mesma reserva do checkout. */
	.carrinho-envio-opcao__nome {
		max-width: 217px;
	}

	/* A caixa do preço tem a largura da banda inteira e começa no mesmo `x`
	   do nome: tapava-o por completo. Medi com `elementFromPoint` no centro
	   do rótulo e em três das quatro filas quem respondia era o preço — só
	   o quadrado de 15x15 do rádio era alcançável ao rato e ao toque, e o
	   `<label for>` que o carrinho já tem era inútil. Levanto o nome; o
	   preço está encostado à direita, fora da faixa do nome, por isso não
	   muda um pixel nem deixa de ser seleccionável onde está desenhado.
	   Só no carrinho: no checkout o rótulo é um `<p>` e não tem `for`, por
	   isso levantá-lo não daria nada e tirava área ao preço. */
	.carrinho-envio-opcao__nome {
		z-index: 1;
	}

	/* ---- CARRINHO: o que desce ---- */

	.pagina-carrinho-3 p.carrinho-envio-opcao__nota {
		top: calc( 219px + var( --sda-envio-extra, 0px ) );
	}

	.pagina-carrinho-3 .carrinho-envio-opcao__alterar {
		top: calc( 352px + var( --sda-envio-extra, 0px ) );
	}

	.pagina-carrinho-3 .carrinho-resumo__divisor--2 {
		top: calc( 443px + var( --sda-envio-extra, 0px ) );
	}

	.pagina-carrinho-3 .carrinho-resumo__rotulo--total,
	.pagina-carrinho-3 .carrinho-resumo__valor--total {
		top: calc( 472px + var( --sda-envio-extra, 0px ) );
	}

	.pagina-carrinho-3 p.carrinho-resumo__iva {
		top: calc( 503px + var( --sda-envio-extra, 0px ) );
	}

	.pagina-carrinho-3 .carrinho-resumo__finalizar {
		top: calc( 597px + var( --sda-envio-extra, 0px ) );
	}

	.pagina-carrinho-3 .carrinho-resumo__fundo {
		height: calc( 577px + var( --sda-envio-extra, 0px ) );
	}

}


/* ============================================================
 * CUPÃO — linha de desconto no resumo (carrinho e checkout)
 * ============================================================
 * O resumo é desenhado à mão nos dois sítios (o cart-totals.php e o
 * review-order.php do WooCommerce existem no tema mas nunca chegam a ser
 * chamados), e nenhum deles tinha linha de desconto. Com um cupão
 * aplicado medi SUBTOTAL 69,00€, ENVIO 3,08€ e TOTAL 65,18€: as parcelas
 * somavam 72,08€, nada dizia porquê, o código do cupão não aparecia e não
 * havia como o retirar.
 *
 * O canvas de 1920 é absoluto, por isso a linha nova tem de empurrar o
 * que fica por baixo dela. Todo o empurrão vive dentro de `:has()`: sem
 * cupão nenhuma destas regras chega a casar, e o desenho fica byte a byte
 * como estava. Uso `translate` e não `top` de propósito — assim não
 * reescrevo nem duplico uma única coordenada do main.css, e o empurrão
 * segue os três estados do carrinho e os do checkout sem os conhecer.
 * ------------------------------------------------------------ */

/* Quantos cupões estão aplicados. O WooCommerce deixa empilhar vários e o
   campo do carrinho aceita um de cada vez, por isso conto até quatro; a
   partir daí as linhas sobrepunham-se — se algum dia isso for real, é
   decisão de negócio limitar a um cupão por carrinho. */
.carrinho-conteudo:has( .carrinho-resumo__valor--desconto ),
.checkout-conteudo:has( .checkout-linha--desconto ) {
	--sda-descontos: 1;
}

.carrinho-conteudo:has( .carrinho-resumo__valor--desconto ~ .carrinho-resumo__valor--desconto ),
.checkout-conteudo:has( .checkout-linha--desconto ~ .checkout-linha--desconto ) {
	--sda-descontos: 2;
}

.carrinho-conteudo:has( .carrinho-resumo__valor--desconto ~ .carrinho-resumo__valor--desconto ~ .carrinho-resumo__valor--desconto ),
.checkout-conteudo:has( .checkout-linha--desconto ~ .checkout-linha--desconto ~ .checkout-linha--desconto ) {
	--sda-descontos: 3;
}

.carrinho-conteudo:has( .carrinho-resumo__valor--desconto ~ .carrinho-resumo__valor--desconto ~ .carrinho-resumo__valor--desconto ~ .carrinho-resumo__valor--desconto ),
.checkout-conteudo:has( .checkout-linha--desconto ~ .checkout-linha--desconto ~ .checkout-linha--desconto ~ .checkout-linha--desconto ) {
	--sda-descontos: 4;
}

/* ---------- carrinho: a linha nova ----------
   A base é exactamente onde o TOTAL estava em cada um dos três estados do
   mockup; o TOTAL desce depois o mesmo tanto. Assim a linha entra no sítio
   que já lhe pertencia visualmente, logo abaixo do segundo filete. */
.carrinho-resumo__rotulo--desconto,
.carrinho-resumo__valor--desconto,
p.carrinho-resumo__cupao {
	top: 255px;
}

.pagina-carrinho-2 .carrinho-resumo__rotulo--desconto,
.pagina-carrinho-2 .carrinho-resumo__valor--desconto,
.pagina-carrinho-2 p.carrinho-resumo__cupao {
	top: 644px;
}

.pagina-carrinho-3 .carrinho-resumo__rotulo--desconto,
.pagina-carrinho-3 .carrinho-resumo__valor--desconto,
.pagina-carrinho-3 p.carrinho-resumo__cupao {
	/* A fila do desconto vive DEPOIS das filas de envio: sem somar o
	   `--sda-envio-extra` ficava presa nos 472px do desenho de duas filas e
	   caía em cima da terceira e da quarta. */
	top: calc( 472px + var( --sda-envio-extra, 0px ) );
}

/* Com dois ou mais cupões cada par desce 64px — o mesmo passo que o TOTAL
   usa mais abaixo, para que nunca se cruzem. */
.carrinho-resumo__rotulo--desconto,
.carrinho-resumo__valor--desconto {
	translate: 0 calc( var( --sda-desconto-i, 0 ) * 64px );
}

/* O código e o «Remover» numa segunda linha pequena por baixo do rótulo:
   a 22px o rótulo, o código e a ligação não cabiam nos 220px que separam
   o rótulo do valor — medi 231px só de texto — e batiam no valor. */
p.carrinho-resumo__cupao {
	position: absolute;
	left: 915px;
	width: 440px;
	margin-top: 0;
	margin-right: 0;
	margin-bottom: 0;
	margin-left: 0;
	font-family: var( --fonte-corpo, sans-serif );
	font-size: 14px;
	font-weight: 400;
	line-height: 20px;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	color: var(--cor-titulos-tom, #8E9193);
	translate: 0 calc( 32px + var( --sda-desconto-i, 0 ) * 64px );
}

.carrinho-resumo__cupao-remover,
.checkout-resumo__cupao-remover {
	margin-left: 10px;
	color: var(--cor-primaria, #A787A3);
	text-decoration: underline;
}

.carrinho-resumo__cupao-remover:hover,
.carrinho-resumo__cupao-remover:focus-visible,
.checkout-resumo__cupao-remover:hover,
.checkout-resumo__cupao-remover:focus-visible {
	color: var(--cor-footer, #483846);
}

/* ---------- carrinho: o que desce ----------
   Só o TOTAL, a nota do IVA e o botão. O filete de cima, o Envio e o
   calculador ficam onde estavam. */
.carrinho-conteudo:has( .carrinho-resumo__valor--desconto ) .carrinho-resumo__rotulo--total,
.carrinho-conteudo:has( .carrinho-resumo__valor--desconto ) .carrinho-resumo__valor--total,
.carrinho-conteudo:has( .carrinho-resumo__valor--desconto ) p.carrinho-resumo__iva,
.carrinho-conteudo:has( .carrinho-resumo__valor--desconto ) .carrinho-resumo__finalizar {
	translate: 0 calc( var( --sda-descontos, 0 ) * 64px );
}

/* O cartão branco cresce o mesmo — senão o TOTAL saía-lhe pelo fundo. */
.carrinho-conteudo:has( .carrinho-resumo__valor--desconto ) .carrinho-resumo__fundo {
	height: calc( 360px + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px );
}

.pagina-carrinho-2 .carrinho-conteudo:has( .carrinho-resumo__valor--desconto ) .carrinho-resumo__fundo {
	height: calc( 749px + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px );
}

.pagina-carrinho-3 .carrinho-conteudo:has( .carrinho-resumo__valor--desconto ) .carrinho-resumo__fundo {
	height: calc( 577px + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px );
}

/* ---------- checkout: a linha nova ---------- */
.checkout-resumo__rotulo--desconto,
.checkout-resumo__valor--desconto,
p.checkout-resumo__cupao {
	top: calc( 414px + var( --sda-envio-extra, 0px ) );
}

.checkout-resumo__rotulo--desconto,
.checkout-resumo__valor--desconto {
	translate: 0 calc( var( --sda-desconto-i, 0 ) * 64px );
}

p.checkout-resumo__cupao {
	position: absolute;
	left: 915px;
	width: 440px;
	margin-top: 0;
	margin-right: 0;
	margin-bottom: 0;
	margin-left: 0;
	font-family: var( --fonte-corpo, sans-serif );
	font-size: 14px;
	font-weight: 400;
	line-height: 20px;
	text-transform: uppercase;
	letter-spacing: 0.02em;
	color: var(--cor-titulos-tom, #8E9193);
	translate: 0 calc( 32px + var( --sda-desconto-i, 0 ) * 64px );
}

/* ---------- checkout: o que desce ----------
   Toda a coluna da direita a partir do TOTAL. A coluna da esquerda (os
   campos, as checkboxes e as notas) não é tocada. */
.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-resumo__rotulo--total,
.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-resumo__valor--total,
.checkout-conteudo:has( .checkout-linha--desconto ) p.checkout-resumo__iva,
.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-resumo__rotulo--pagamento,
.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-linha--pagamento .checkout-radio,
.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-pagamento__nome,
.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-pagamento__icone,
.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-pagamento__caixa,
.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-finalizar,
.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-termos {
	translate: 0 calc( var( --sda-descontos, 0 ) * 64px );
}

.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-resumo__fundo {
	height: calc( 715px + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px );
}

.pagina-checkout-1 .checkout-conteudo:has( .checkout-linha--desconto ) .checkout-resumo__fundo {
	height: calc( 715px + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
}

/* ---------- alturas das secções ----------
   Estas quatro substituem as que já lá estão (sda-extra.css:1550-1560 e
   :1480, main.css:5054 e :5866): a secção é uma caixa de altura fixa num
   canvas absoluto e é ela que empurra o que vem a seguir na página. */
.carrinho-conteudo {
	height: calc( 441px + var( --sda-carrinho-extra, 0px ) + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px );
}

.pagina-carrinho-2 .carrinho-conteudo {
	height: calc( 830px + var( --sda-carrinho-extra, 0px ) + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px );
}

.pagina-carrinho-3 .carrinho-conteudo {
	height: calc( 658px + var( --sda-carrinho-extra, 0px ) + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px );
}

.checkout-conteudo {
	height: calc( 955.5px + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
}

.pagina-checkout-1 .checkout-conteudo {
	height: calc( 955.5px + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
}

.pagina-checkout-morada .checkout-conteudo {
	height: calc( 1179.5px + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px );
}

/* ---------- telemóvel (<=430) ----------
   O refluxo (sda-extra.css:9754, (0,11,1)) já escreve `translate: none`,
   `width: auto` e `top: auto` em tudo o que vive no `.site-content`, por
   isso a geometria do canvas de 1920 acima cai sozinha aqui — medi e não
   é preciso repeti-la. O que ele TAMBÉM escreve, e aqui faz falta, é
   `margin-left: 0` e `position: static`: é só isso que reponho. */
@media (max-width: 430px) {

	/* A grelha do resumo já põe o código na fila toda (o `> *` de
	   sda-extra.css:8937 no carrinho; o `grid-column` explícito no
	   checkout, onde o valor já reclamou a coluna 2). Aqui só o corpo. */
	body:not(.pagina-home-final) .site-content .carrinho-resumo > p.carrinho-resumo__cupao,
	.pagina-checkout .checkout-linha--desconto p.checkout-resumo__cupao {
		grid-column: 1 / -1;
		font-size: 13px;
		line-height: 20px;
	}

	/* O par rótulo/valor cola-se à linha do código, que lhe pertence.
	   `!important` porque `... .carrinho-resumo > .carrinho-resumo__rotulo`
	   (sda-extra.css:8941) escreve `margin-bottom: 16px !important`. */
	body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__rotulo--desconto,
	body:not(.pagina-home-final) .site-content .carrinho-resumo > .carrinho-resumo__valor--desconto {
		margin-bottom: 2px !important;
	}

	.pagina-checkout .checkout-linha--desconto .checkout-resumo__cupao {
		margin-top: 2px;
		margin-bottom: 0;
	}

	/* `margin-left: 10px !important` vence o `margin-left: 0` do refluxo
	   (9754, (0,11,1)) — medido: sem ele o código e o «Remover» ficam
	   colados, «TESTE-PCT10REMOVER».
	   `position: relative !important` vence o `position: static` da mesma
	   regra, e é o que dá bloco contentor ao `::before`; sem ele o alvo
	   de toque não existe. É o mesmo remendo que os rádios do checkout já
	   fazem (sda-extra.css:8014). */
	.carrinho-resumo__cupao-remover,
	.checkout-resumo__cupao-remover {
		position: relative !important;
		display: inline-block;
		margin-left: 10px !important;
	}

	/* Alvo de toque: a ligação é a única forma de retirar o cupão e a
	   13px mede 60x20. O pseudo-elemento leva-a aos 44px de altura sem
	   engordar o desenho (o `*` do refluxo não casa pseudo-elementos, por
	   isso o `translate` daqui sobrevive). */
	.carrinho-resumo__cupao-remover::before,
	.checkout-resumo__cupao-remover::before {
		content: "";
		position: absolute;
		left: 50%;
		top: 50%;
		width: 100%;
		min-width: 44px;
		height: 44px;
		translate: -50% -50%;
	}
}

/* ---------------------------------------------------------------------------
   TÍTULO DO MODAL DE LOGIN — h1 para h2
   O cartão está no rodapé de TODAS as páginas, e o seu título era um `<h1>`:
   cada página do site servia dois h1, e a home — cujo primeiro título era um
   `<h2>` — servia como único h1 a palavra «Entrar». Passou a `<h2>`.
   O mock só desenha `h1.login-card__titulo` (top 68, 52/62); a regra `h2` que
   já existia é a da página /minha-conta/, mais pequena de propósito para não
   competir com o h1 dessa página. O modal precisa da geometria do mock, e é
   por isso que se repete aqui presa ao contentor do modal.
   --------------------------------------------------------------------------- */
.sda-login-modal h2.login-card__titulo {
	top: 68px;
	font: 400 52px/62px var(--fonte-titulos, serif);
}

@media (max-width: 430px) {

	/* A escala mobile de H1 do projecto (44/52), como no h1 original. */
	.sda-login-modal h2.login-card__titulo {
		font-size: 44px;
		line-height: 52px;
	}
}

/* ---------------------------------------------------------------------------
   H1 DA HOME
   A home não tinha `<h1>` nenhum: o primeiro título era o `<h2>` das boas-
   vindas, e o único h1 do documento acabava por ser o «Entrar» do modal de
   login que vive no rodapé de todas as páginas. Passou a `<h1>`.
   O reset de margens do mock (main.css) é um agrupamento por elemento —
   `.home-boas-vindas p, .home-boas-vindas h2 { margin: 0 }` — que lista h2 e
   não h1: só com a troca da etiqueta o título ganhou os 0.67em do browser
   (52,26px a 78px de corpo) e desceu outro tanto, com `top: 0` a contar a
   partir da margem. Medido: 0px como h2, 52px como h1.
   --------------------------------------------------------------------------- */
.home-boas-vindas h1 {
	margin: 0;
}

/* ---------------------------------------------------------------------------
   BARRA DE COOKIES
   Fixa no fundo, acima de tudo excepto o modal de login (1500) e a folha do
   curso (1400), que são diálogos e devem tapá-la. Desenhada em flow — é o
   único bloco do site que não vem do mock, e por isso não tem coordenadas
   absolutas nem depende do canvas de 1920: encolhe sozinha em qualquer
   largura. Cor de fundo creme com a barra superior na primária, para ler como
   parte da marca sem competir com o conteúdo.
   --------------------------------------------------------------------------- */
.sda-cookies {
	position: fixed;
	right: 0;
	bottom: 0;
	left: 0;
	/* 1200: acima do cabeçalho colado (1000) e abaixo do menu móvel (1300).
	   Estava em 1300, empatado com o menu — e num empate ganha quem vem
	   depois no documento, que é esta barra: com o menu aberto, a barra
	   pintava-lhe por cima. */
	z-index: 1200;
	background: var(--cor-creme, #fff5de);
	border-top: 2px solid var(--cor-primaria, #a787a3);
	box-shadow: 0 -4px 24px rgba(72, 56, 70, 0.14);
}

.sda-cookies__interior {
	display: flex;
	flex-wrap: wrap;
	gap: 20px 32px;
	align-items: center;
	justify-content: space-between;
	box-sizing: border-box;
	max-width: 1400px;
	margin: 0 auto;
	padding: 22px 24px;
}

.sda-cookies__texto {
	flex: 1 1 420px;
	margin: 0;
	font: 400 17px/26px var(--fonte-corpo, sans-serif);
	color: var(--cor-footer, #483846);
}

.sda-cookies__link {
	/* Sem isto o «Saber mais» parte-se entre as duas linhas a 390px. */
	white-space: nowrap;
	color: var(--cor-primaria, #a787a3);
	text-decoration: underline;
	text-underline-offset: 3px;
}

.sda-cookies__link:hover,
.sda-cookies__link:focus-visible {
	color: var(--cor-footer, #483846);
}

.sda-cookies__accoes {
	display: flex;
	flex: 0 0 auto;
	flex-wrap: wrap;
	gap: 12px;
}

.sda-cookies__botao {
	box-sizing: border-box;
	min-height: 48px;
	padding: 12px 26px;
	border: 1px solid var(--cor-primaria, #a787a3);
	border-radius: 12px;
	font: 600 16px/24px var(--fonte-corpo, sans-serif);
	cursor: pointer;
	transition: background-color 0.2s ease, color 0.2s ease;
}

.sda-cookies__botao--aceitar {
	background: var(--cor-primaria, #a787a3);
	color: #ffffff;
}

.sda-cookies__botao--aceitar:hover,
.sda-cookies__botao--aceitar:focus-visible {
	background: var(--cor-rosa, #ecc6c0);
	/* Branco sobre o rosa não passa AA — o texto escurece em vez de manter. */
	color: var(--cor-footer, #483846);
}

.sda-cookies__botao--recusar {
	background: transparent;
	color: var(--cor-primaria, #a787a3);
}

.sda-cookies__botao--recusar:hover,
.sda-cookies__botao--recusar:focus-visible {
	background: var(--cor-primaria, #a787a3);
	color: #ffffff;
}

.sda-cookies__botao:focus-visible {
	outline: 2px solid var(--cor-footer, #483846);
	outline-offset: 2px;
}

@media (max-width: 767px) {

	.sda-cookies__interior {
		gap: 16px;
		padding: 18px 16px;
	}

	.sda-cookies__texto {
		flex-basis: 100%;
		font-size: 15px;
		line-height: 23px;
	}

	.sda-cookies__accoes {
		width: 100%;
	}

	.sda-cookies__botao {
		flex: 1 1 0;
		padding: 12px 14px;
	}
}

@media (prefers-reduced-motion: reduce) {

	.sda-cookies__botao {
		transition: none;
	}
}

/* ============================================================
 * IMPRESSÃO
 *
 * O site não tinha folha de impressão nenhuma, e o que sai por omissão
 * é inutilizável: o canvas é uma tela fixa de 1920px com o interior em
 * coordenadas absolutas, encolhida no ecrã por um `zoom` que o main.js
 * escreve em linha no elemento raiz. Numa folha A4 isso corta a página
 * a meio e deixa o resto em branco.
 *
 * A abordagem é a mesma do refluxo mobile: o interior passa a fluxo na
 * ordem do DOM. A diferença é que aqui também a home reflui — em papel
 * não há tela larga que valha —, e é preciso `!important` em três
 * sítios: o `zoom` está em linha (nada mais o vence) e as alturas do
 * mock estão em regras de classe que ganhariam a esta.
 *
 * O que interessa mesmo imprimir é a confirmação de encomenda, uma
 * página legal ou um artigo. Tudo o que é navegação, decoração e
 * acção sai da folha.
 * ============================================================ */

@media print {

	@page {
		margin: 1.5cm;
	}

	html {
		/* Inline, escrito pelo main.js — só assim se anula. */
		zoom: 1 !important;
	}

	body {
		min-width: 0 !important;
		background: #ffffff;
		color: #000000;
		font-size: 11pt;
		line-height: 1.5;
	}

	/* Navegação, acções e decoração não vão para o papel. */
	.site-header,
	.site-footer,
	.sda-drawer,
	.sda-loader,
	.sda-login-modal,
	.sda-cookies,
	.curso-barra,
	.curso-folha,
	.seccao-newsletter,
	.seccao-produtos-relacionados,
	.botao-principal,
	.botao-contorno,
	.botao-lista,
	.home-hero__seta,
	[class*="__seta"],
	[class*="__dots"],
	[class*="__dot"],
	.skip-link,
	form {
		display: none !important;
	}

	/* Os próprios contentores do canvas: o `.site-content` e as faixas
	   interiores levam larguras fixas do mock (1920 e 1400) que o
	   selector de baixo não apanha, porque ele só age no INTERIOR. */
	.site-content,
	.seccao-inner {
		width: auto !important;
		max-width: 100%;
		min-width: 0;
		margin: 0;
		padding: 0;
	}

	/* O interior volta a fluxo. Mesma lista de excepções do refluxo
	   mobile: os cartões continuam a ser o contexto do seu interior. */
	.site-content *:not(.produto-card):not(.seccao-artigos-card):not(.conta-encomenda):not(.carrinho-linha):not(.categoria-card):not(.card-actividade):not(.lista-terapias-card):not(.accordion-faq-cabecalho):not(.curso-como-funciona-cabecalho) {
		position: static;
		left: auto;
		top: auto;
		right: auto;
		bottom: auto;
		width: auto;
		max-width: 100%;
		height: auto;
		min-height: 0;
		transform: none;
		translate: none;
		margin-left: 0;
		margin-right: 0;
		white-space: normal;
		background-image: none;
		box-shadow: none;
	}

	.site-content > section,
	.site-content > div {
		height: auto !important;
		min-height: 0 !important;
		margin: 0;
		padding: 0 0 12pt;
	}

	.site-content img {
		max-width: 100%;
		height: auto;
	}

	/* Escala tipográfica de papel — os corpos do canvas de 1920 (78px de
	   H1) dariam títulos de 20cm numa folha de 21. */
	.site-content h1 {
		font-size: 20pt;
		line-height: 1.2;
	}

	.site-content h2 {
		font-size: 16pt;
		line-height: 1.25;
	}

	.site-content h3 {
		font-size: 13pt;
		line-height: 1.3;
	}

	.site-content p,
	.site-content li,
	.site-content td,
	.site-content th {
		font-size: 11pt;
		line-height: 1.5;
		color: #000000;
	}

	/* Um título não deve ficar sozinho no fim da folha, nem uma imagem
	   ou uma linha de tabela partida ao meio. */
	h1,
	h2,
	h3 {
		break-after: avoid;
		break-inside: avoid;
	}

	img,
	tr {
		break-inside: avoid;
	}

	/* Num papel o destino de um link perde-se — a não ser que se escreva.
	   Só nos links de conteúdo: nos de navegação seria ruído, e esses já
	   nem sequer são impressos. */
	.entrada-conteudo a[href^="http"]::after,
	.bloco-legal a[href^="http"]::after,
	.artigo-conteudo a[href^="http"]::after {
		content: " (" attr(href) ")";
		font-size: 9pt;
		word-break: break-all;
	}

	/* Decoração que só faz sentido em ecrã. */
	[class*="__divisor"],
	[class*="__fundo"],
	[class*="__textura"],
	[class*="__selo"] {
		display: none;
	}
}

/* ---------------------------------------------------------------------------
   ÂNCORA DA GRELHA DE PRODUTOS
   O botão do banner da loja passou a levar a `#produtos` em vez de recarregar
   a própria página. Como o cabeçalho é fixo, o salto deixava-o por cima do
   topo da grelha — medi 100px tapados a 1920 e 64 a 390. A folga é a altura do
   cabeçalho mais um respiro, para o título da secção ficar mesmo à vista.
   --------------------------------------------------------------------------- */
#produtos {
	scroll-margin-top: 124px;
}

@media (max-width: 430px) {

	#produtos {
		scroll-margin-top: 88px;
	}
}


/* ============================================================
 * REVISÃO v6 (PDF de 31-08-2026, docs/REVISAO-V6.md)
 *
 * Vinte e seis notas do cliente, dezanove alterações. As de mobile vão
 * todas dentro da mesma media query, mais abaixo; as de desktop (/obrigado/
 * e a cor dos erros do checkout) ficam aqui em cima.
 * ============================================================ */

/* D1 — o vão entre «Mensagem enviada!» e o texto media 205px: 109 vêm do
   herói partilhado com a FAQ (não se toca), e os 96 restantes eram só desta
   página. Passa a alinhar com a FAQ, que é a irmã com o mesmo herói. */
.obrigado-mensagem {
	margin: 0 0 40px;
}

/* D2 — o bloco de texto estava a x=260→1160 (centro 710) num inner cujo
   centro é 960: 250px à esquerda, e o texto alinhado ao início. */
.obrigado-mensagem p {
	margin: 0 auto 24px;
	text-align: center;
}

/* D4a — o «Ler mais» do cartão do artigo não tinha a seta que o mesmo
   cartão tem no /blog/ e na home. O markup passou a levá-la; a regra do
   cartão da lista já a posiciona. */

/* D4b — o símbolo da marca à direita do cartão do artigo, a rodar como nos
   outros selos do site. A âncora é o .seccao-inner (position: relative); o
   cartão ocupa x=0..912 e sobram 488px à direita para os 301 do selo. */
.obrigado-artigo__simbolo {
	position: absolute;
	right: 0;
	top: 170px;
	width: 301px;
	height: 301px;
	animation: sda-selo-rotate 22s linear infinite;
	pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {

	.obrigado-artigo__simbolo {
		animation: none;
	}
}

/* M6 — as mensagens de campos em falta estavam a #696969, o cinzento do
   corpo. O vermelho do design system é #FFA2A3 e dá 1,76:1 sobre o fundo
   real do checkout — pintá-las com ele tornava-as MENOS legíveis (a AA pede
   4,5:1 para texto de 16px). #A83E44 é da mesma família e dá 5,62:1. É o
   mesmo desvio deliberado ao espelho do Figma que já se assumiu para o
   `--cor-titulos-tom`. */
.checkout-erro {
	color: #A83E44;
}

@media (max-width: 430px) {

	/* A — «reduzir a margem antes do título» em SEIS páginas é UMA causa. A
	   regra de refluxo dos heróis (`.site-content > section { padding-top:
	   28px }`) usa combinador de filho directo; nas páginas WooCommerce o
	   filho directo é o `div.woocommerce`, que recebe os 28, e o herói lá
	   dentro conserva os 126px do canvas de 1920. Medido: 28px em Quem
	   Somos/Terapias/Contactos, 154px nas oito páginas da loja e da conta.
	   Zero e não 28, porque os 28 já vêm do wrapper. Fecha M1, M4, M11, M13,
	   M15 e M19 (a recuperação usa o mesmo herói da conta). */
	body:not(.pagina-home-final) .site-content .seccao-hero--carrinho,
	body:not(.pagina-home-final) .site-content .seccao-hero--checkout,
	body:not(.pagina-home-final) .site-content .seccao-hero--conta {
		padding-top: 0;
	}

	/* M19 / Login — o Francisco pediu o mesmo tratamento no cartão de login.
	   O título estava a 100px do cabeçalho (28 do wrapper + 40 de margem do
	   cartão + 32 de padding). Sem a margem, o cartão nasce nos mesmos 28px
	   onde nascem os títulos das outras páginas, e o título fica a 60 — o
	   padding interior é do cartão e mantém-se. */
	.site-content .login-card {
		margin-top: 0 !important;
	}

	/* Com um aviso do WooCommerce por cima (credenciais erradas, email já
	   registado), os 40 que os separavam iam-se com a margem: ficavam os 16
	   do próprio aviso. */
	/* `~` e não `+`: o WooCommerce injecta um `div.woocommerce-notices-wrapper`
	   vazio entre os avisos e o cartão, e o irmão adjacente nunca casava. */
	.login-card__avisos ~ .login-card,
	.woocommerce-info ~ .login-card--inline {
		margin-top: 24px !important;
	}

	/* O modal de login (rodapé, fora do .site-content) partilha a classe e
	   NÃO pode perder a margem: medi o cartão do modal a y=0, colado ao
	   topo do ecrã, com a regra sem o prefixo. Fica com os 40 que tinha. */

	/* D4b em mobile — o símbolo do /obrigado/ é pedido de DESKTOP (p.1 do
	   PDF). Em mobile o refluxo torna-o `static` com `width: auto`, e
	   media 343×343px a rodar a seguir ao cartão do artigo. Escondido. */
	body:not(.pagina-home-final) .site-content .obrigado-artigo__simbolo {
		display: none;
	}

	/* M5 — a lista de erros do checkout tinha 32px por cima e 0 por baixo;
	   colava ao «Dados de Faturação». */
	.pagina-checkout .checkout-erro {
		margin-bottom: 32px;
	}

	/* B — M2 e M3. Os dois elementos estão escondidos no desktop (leitor de
	   ecrã / display: none) e o mock nunca lhes deu tipo de letra; as regras
	   que os revelam em mobile escreviam tamanho e margens mas não
	   `font-family`, e não há nada para herdar. Caíam em Times. Peso 500 no
	   rótulo para igualar o «PRODUTO(S)» ao lado. */
	body:not(.pagina-home-final) .site-content .carrinho-cupao__rotulo {
		font-family: var(--fonte-corpo, sans-serif);
		font-weight: 500;
	}

	body:not(.pagina-home-final) .site-content .carrinho-cupao__nota {
		font-family: var(--fonte-corpo, sans-serif);
	}

	/* C — M12 e M14. Os títulos de secção da conta («DADOS DE FATURAÇÃO»,
	   «PRODUTOS ENCOMENDADOS»…) apanhavam os 38px do `h2` genérico. A
	   referência que o cliente dá é o «AVALIAÇÕES» da página de produto:
	   22px. Vem depois da regra genérica, por isso ganha por ordem. */
	body:not(.pagina-home-final) .site-content h2.conta-titulo,
	body:not(.pagina-home-final) .site-content h2.conta-ver__seccao,
	body:not(.pagina-home-final) .site-content .conta-conteudo .woocommerce-MyAccount-content h2 {
		font-size: 22px;
		line-height: 30px;
	}

	/* D — M16 e M17, que têm de ir juntos. Os separadores da «Estrutura do
	   curso» quebravam para duas linhas (a 360 já para três). Passam a faixa
	   rolável, na receita do R112 que resolveu as tabs do produto: sangria
	   lateral até às bordas, `scroll-padding-left` para o snap não encostar o
	   primeiro ao bordo. A linha cinza (M17) é um <span> de 1105px absoluto
	   que o refluxo zera — esconde-se e passa a `border-bottom` do nav, que
	   assim acompanha a largura real e fica sempre debaixo de UMA linha. */
	body:not(.pagina-home-final) .site-content .curso-estrutura nav {
		flex-wrap: nowrap;
		column-gap: 20px;
		/* `!important` porque o selector de refluxo (0,12,1) reescreve as
		   margens laterais e a sangria não pintava: a faixa ficava a 23→367 e
		   o primeiro separador nascia a 46 quando tudo o resto nasce a 23. Os
		   -4/+4 devolvem ao anel de foco os 4px que o recorte lhe cortava. */
		margin: -4px -23px 24px !important;
		padding: 4px 23px 8px;
		border-bottom: 1px solid var(--cor-cinza-claro, #D6D7D9);
		overflow-x: auto;
		overscroll-behavior-x: contain;
		scroll-snap-type: x proximity;
		scroll-padding-left: 23px;
		scrollbar-width: none;
	}

	body:not(.pagina-home-final) .site-content .curso-estrutura nav::-webkit-scrollbar {
		display: none;
	}

	body:not(.pagina-home-final) .site-content .curso-estrutura-tab {
		flex: 0 0 auto;
		scroll-snap-align: start;
	}

	body:not(.pagina-home-final) .site-content .curso-estrutura__linha-tabs {
		display: none;
	}

	/* F — M7: a imagem e o nome do produto estavam colados (0px — o refluxo
	   dá `margin: 0 0 16px` aos h1). */
	body:not(.pagina-home-final) .site-content h1.produto-ficha__titulo {
		margin-top: 24px;
	}

	/* Com selo «ESGOTADO» entre a imagem e o nome, os 24 caíam entre o selo
	   e o nome que ele rotula (8+24=32, as margens de inline-block não
	   colapsam) e a agrupagem invertia-se. O selo fica a 24 da imagem e a 8
	   do nome, como antes. Com miniaturas, a margem inferior delas somava
	   aos 24 (=40): o h1 dá os 24 sozinho. */
	body:not(.pagina-home-final) .site-content .produto-ficha__esgotado {
		margin-top: 24px;
	}

	body:not(.pagina-home-final) .site-content .produto-ficha__esgotado + h1.produto-ficha__titulo {
		margin-top: 0;
	}

	body:not(.pagina-home-final) .site-content .produto-ficha__miniatura {
		margin-bottom: 0;
	}

	/* F — M8: em desktop preço/título = 32/52 = 0,615; em mobile os 16px
	   genéricos dos <p> davam 16/44 = 0,364. Para manter a proporção do
	   desktop com o título a 44: 27px. */
	body:not(.pagina-home-final) .site-content p.produto-ficha__preco {
		font-size: 27px;
		line-height: 36px;
	}

	/* H — M10: o cartão da lista de desejos tinha o nome a 24px e o preço a
	   28px; o cartão da loja, que o cliente dá como referência, tem 16/22 e
	   16/24, ambos a 600. `!important` porque a regra de desktop já o usa. */
	body:not(.pagina-home-final) .site-content .conta-desejos__nome,
	body:not(.pagina-home-final) .site-content .conta-desejos__nome a {
		font-size: 16px !important;
		line-height: 22px !important;
		font-weight: 600 !important;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__preco {
		font-size: 16px;
		line-height: 24px;
		font-weight: 600;
	}
}

/* G — M18. O clique chegava e a caixa pintava de roxo, mas a regra do mock é
   um preenchimento sólido sem glifo — não há «visto» nenhum. A da
   newsletter, que o cliente dá como certa, tem o SVG do visto sobre branco.
   O mesmo aqui. Vale em todas as larguras: reproduzia também a 1920. */
.seccao-formulario__optin-caixa:checked {
	background: #ffffff url("../img/loja/conta-checkbox-visto.svg") center / 14px 14px no-repeat;
	border-color: var(--cor-primaria, #a787a3);
}

/* M16 — esbatimento das bordas da faixa dos separadores do curso, enquanto
   houver mais fora do ecrã (as classes vêm do main.js). Máscara e não
   degradê: o fundo é a textura creme. */
@media (max-width: 430px) {

	body:not(.pagina-home-final) .site-content .curso-estrutura nav.tem-mais-a-direita {
		-webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 44px), transparent 100%);
		mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 44px), transparent 100%);
	}

	body:not(.pagina-home-final) .site-content .curso-estrutura nav.tem-mais-a-esquerda {
		-webkit-mask-image: linear-gradient(to right, transparent 0, #000 44px, #000 100%);
		mask-image: linear-gradient(to right, transparent 0, #000 44px, #000 100%);
	}

	body:not(.pagina-home-final) .site-content .curso-estrutura nav.tem-mais-a-esquerda.tem-mais-a-direita {
		-webkit-mask-image: linear-gradient(to right, transparent 0, #000 44px, #000 calc(100% - 44px), transparent 100%);
		mask-image: linear-gradient(to right, transparent 0, #000 44px, #000 calc(100% - 44px), transparent 100%);
	}
}

/* ---------------------------------------------------------------------------
   CARRINHO VAZIO
   O mock não desenha este estado e o template emprestava o layout das
   páginas legais — duas colunas, altura fixa de 1597px, bloco de 330px com
   divisor. Uma frase e um botão, centrados, com o ritmo vertical do resto do
   site (o herói acima já traz a sua altura; 130px antes da newsletter, como
   o /obrigado/).
   --------------------------------------------------------------------------- */
.carrinho-vazio,
.estado-vazio {
	padding: 0 0 130px;
	text-align: center;
}

.carrinho-vazio__texto,
.estado-vazio__texto {
	max-width: 760px;
	margin: 0 auto 40px;
	font: 400 22px/36px var(--fonte-corpo, sans-serif);
	color: var(--cor-texto, #696969);
}

@media (max-width: 430px) {

	/* O herói está dentro do `div.woocommerce` e não apanha os 28px de
	   padding do refluxo; sem isto ficavam só os 16 da margem do h1. */
	body:not(.pagina-home-final) .site-content .carrinho-vazio {
		padding-top: 24px;
		padding-bottom: 56px;
	}

	body:not(.pagina-home-final) .site-content .carrinho-vazio__texto,
	body:not(.pagina-home-final) .site-content .estado-vazio__texto {
		margin-bottom: 28px;
		font-size: 16px;
		line-height: 26px;
	}

	/* Ao contrário do carrinho, os heróis do 404, da pesquisa e do arquivo
	   são filhos directos de .site-content e já trazem os 28 do refluxo. */
	body:not(.pagina-home-final) .site-content .estado-vazio {
		padding-top: 0;
		padding-bottom: 56px;
	}
}


/* ============================================================
 * LAYOUTS EMPRESTADOS — o que a auditoria a seguir ao carrinho vazio destapou
 *
 * Seis templates herdavam geometria de outro sítio: 404.php, search.php,
 * page.php e index.php vestiam o layout das páginas legais (secção com
 * `min-height: 1597px`, coluna DIREITA a `left: 433px`, bloco de 330px com
 * `border-bottom`); a loja vazia herdava os 1823px da grelha de 9 cartões; o
 * arquivo do blog vazio herdava os 1930px da lista com sidebar. Medido a
 * 1920: 1504 a 1647px de vazio, texto a 217–358px do centro, linhas órfãs,
 * títulos colados ao cabeçalho, e no page.php 216px de conteúdo CORTADO.
 * ============================================================ */

/* Heróis sem regra própria — `.seccao-hero--404` e `--pesquisa` não existiam
   em lado nenhum e ficavam com 96px sem padding, o título colado ao
   cabeçalho. Levam a geometria do herói legal/FAQ. Em mobile o refluxo
   (0,2,2) ganha a isto (0,1,0) e dá-lhes os 28px, como aos outros. */
.seccao-hero--404,
.seccao-hero--pesquisa,
.seccao-hero--pagina {
	height: 331px;
	padding-top: 126px;
}

.seccao-hero--404 .seccao-hero__titulo,
.seccao-hero--pesquisa .seccao-hero__titulo,
.seccao-hero--pagina .seccao-hero__titulo {
	font-size: 78px;
}

/* O `min-height: 1597px` que a receita das páginas legais (mais acima, 8622)
   dá à secção vale para as legais, que têm menu lateral e quatro blocos —
   não para uma lista de resultados nem para uma página do editor. Selector
   composto (0,2,0) para ganhar à (0,1,0) de cima seja qual for a ordem. */
.seccao-conteudo-legal.sda-lista-simples,
.seccao-conteudo-legal.seccao-conteudo-legal--pagina {
	min-height: 0;
}

/* page.php: coluna de leitura centrada, sem o menu lateral que a justificava. */
.seccao-conteudo-legal--pagina {
	padding-bottom: 130px;
}

.seccao-conteudo-legal--pagina .seccao-conteudo-legal__coluna {
	margin: 0 auto;
	padding-top: 48px;
}

/* Lista de resultados: o último bloco pintava o divisor a fazer de risco
   antes do vazio. */
.sda-lista-simples .bloco-legal:last-of-type {
	border-bottom: 0;
}

/* Loja sem produtos (categoria vazia, pesquisa da loja sem resultados): a
   secção tem 1823px fixos, calibrados para 9 cartões — 1647px de vazio até à
   newsletter com uma frase e um botão. Com o aviso presente, a grelha entra
   em fluxo e dá a altura real à secção; o filtro continua absoluto. */
.loja-produtos:has(.loja-produtos__vazio) {
	height: auto;
	min-height: 0;
	padding-bottom: 130px;
}

.loja-produtos:has(.loja-produtos__vazio) .loja-produtos__grelha {
	position: static;
	margin: 88px 0 0 339px;
}

/* Ordenar zero resultados não faz sentido. */
.loja-produtos:has(.loja-produtos__vazio) [class*="loja-produtos__ordenar"] {
	display: none;
}

@media (max-width: 430px) {

	/* Resultados de pesquisa: os títulos apanhavam o h2 genérico (38px) — o
	   primeiro ocupava 5 linhas. Mesma receita C dos títulos da conta. */
	body:not(.pagina-home-final) .site-content h2.bloco-legal__subtitulo {
		font-size: 22px;
		line-height: 30px;
	}

	/* O refluxo não repunha o `padding-top: 48px` da coluna: 120px do título
	   à contagem, contra 72 em desktop. */
	body:not(.pagina-home-final) .site-content .sda-lista-simples .seccao-conteudo-legal__coluna,
	body:not(.pagina-home-final) .site-content .seccao-conteudo-legal--pagina .seccao-conteudo-legal__coluna {
		padding-top: 0;
	}

	/* A grelha mobile da loja é `grid` de 2 colunas e o aviso caía só na
	   primeira célula (166 dos 344px, 89px à esquerda do centro). O `flex: 1
	   0 100%` de cima é inerte em grid. */
	body:not(.pagina-home-final) .site-content .loja-produtos__vazio {
		grid-column: 1 / -1;
	}

	body:not(.pagina-home-final) .site-content .loja-produtos:has(.loja-produtos__vazio) .loja-produtos__grelha {
		margin: 0;
	}
}

/* Pesquisa sem resultados: o formulário herdava o layout da coluna e ficava
   à esquerda da frase centrada. */
.estado-vazio .sda-lista-simples__pesquisa {
	max-width: 600px;
	margin: 24px auto 0;
}

/* ============================================================
 * REVISÃO DA RAQUEL, 02-09 (WhatsApp) — cinco pontos em mobile
 * ============================================================ */

@media (max-width: 430px) {

	/* «Com Leonardo Mansinhos» no cartão do curso da home: o mock põe-no a
	   top 245 com entrelinha de 36, e os glifos ficavam a 17px do título e a
	   −1px da fila da data. O export do design (design/pages/mobile/home)
	   mede 5px em cima e ~9 em baixo. top 233 dá glifos a 241: 5 do título,
	   11 até aos ícones. */
	.pagina-home-final .home-actividades-card__formador {
		top: 233px;
	}

	/* O botão do carrinho do cartão de produto vivia na grelha sem
	   alinhamento vertical declarado e ficava 6px abaixo do centro do preço
	   (e do stepper, quando aberto). Centra-se na própria fila — sem números
	   mágicos, vale para os dois estados. */
	/* (2.ª medição: o botão é absoluto a top 73 dentro da faixa — o
	   align-self era inerte. 68 centra-o: +1px do preço fechado, −1px do
	   stepper aberto.) */
	.pagina-home-final .produto-card__carrinho,
	body:not(.pagina-home-final) .site-content .produto-card__carrinho {
		top: 68px;
	}

	/* Lista de desejos: nome e preço à direita da imagem (pedido da Raquel —
	   com a redução dos tamanhos sobraram 70px mortos à direita). A imagem
	   fixa uma coluna de 132px; o refluxo não escreve display nem gap, por
	   isso isto sobrevive-lhe. As acções (stepper + carrinho) ficam por
	   baixo do preço, na coluna da informação. */
	/* (2.ª medição: o item JÁ era flex com coluna de imagem de 120px de uma
	   regra anterior — só estava em column. Uma linha muda a direcção; a
	   imagem quadra-se aos 120 que essa regra fixa.) */
	/* Grelha e não flex: numa coluna de 208px o stepper (111) + o botão
	   «Adicionar ao carrinho» (131) + o coração (48) não cabem — mediam
	   x286-418 e x434-482, fora do ecrã. Imagem à esquerda, nome e preço à
	   direita, e as acções numa fila inteira por baixo dos dois. O
	   `display: contents` dissolve o embrulho da info para os filhos
	   entrarem na grelha. !important porque a regra que montou o cartão em
	   coluna também o usa. */
	body:not(.pagina-home-final) .site-content .conta-desejos__item {
		display: grid !important;
		grid-template-columns: 120px minmax(0, 1fr);
		gap: 4px 16px;
		align-items: start;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__imagem-link {
		grid-row: 1 / 3;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__imagem {
		height: 120px !important;
		object-fit: cover;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__info {
		display: contents;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__nome {
		grid-column: 2;
		margin-bottom: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__preco {
		grid-column: 2;
		margin-bottom: 0 !important;
	}

	body:not(.pagina-home-final) .site-content .conta-desejos__accoes {
		grid-column: 1 / -1;
		margin-top: 12px;
	}

	/* E o fundo: 342px até à newsletter contra 182 das encomendas — a soma
	   de cinco camadas (40 do botão + 64 + 80 + 130 + 28) que só aqui
	   estavam todas. Corta-se o que é exclusivo desta página. */
	body.pagina-conta-lista-desejos .site-content .conta-desejos__loja {
		margin-bottom: 0 !important;
	}

	body.pagina-conta-lista-desejos .site-content .woocommerce-MyAccount-content {
		padding-bottom: 0;
	}

	body.pagina-conta-lista-desejos .site-content .conta-conteudo {
		/* 24 + 130 + 28 = 182, o número das encomendas. */
		padding-bottom: 24px;
	}
}


/* ---------------------------------------------------------------------------
   PROMESSA DO HERO EM MOBILE — sem caixa, como em desktop
   O mock mobile desenhava a promessa num cartão branco de 296px fixos; o
   Francisco esclareceu (02-09) que a caixa é para desaparecer e o texto fica
   com o tratamento de desktop: branco com sombra, sobre a fotografia. As
   medidas de tipo (40/46) são as do próprio mock mobile.
   --------------------------------------------------------------------------- */
@media (max-width: 430px) {

	.pagina-home-final .home-hero__promessa {
		left: 24px;
		/* 230 e não os 178 da caixa antiga: centra a tinta na zona útil do
		   hero (cabeçalho→cartões, 175/292 de folga antes; ~233/~233 agora) e
		   alinha-a com as setas, que já estavam nesse centro — ficavam 59px
		   abaixo do meio do texto, ao nível da última linha. */
		top: 236px;
		width: 342px;
		height: auto;
		padding: 0;
		background: none;
		border-radius: 0;
		color: #ffffff;
		text-shadow: 0 0 10px rgba(0, 0, 0, 0.64);
	}
}

/* ============================================================
 * MÉTODOS DE PAGAMENTO POSICIONADOS POR ÍNDICE, NÃO POR SLUG
 *
 * O mock desenhou TRÊS métodos e deu a cada um coordenadas próprias
 * (`--multibanco` 560, `--mbway` 620, `--paypal` 679). Quem não estivesse
 * nessa lista ficava sem posição e caía na origem do contentor: com o Google
 * Pay e o Apple Pay activos, os dois renderizavam-se **sobrepostos um no
 * outro** em y=410, por cima do resumo. E há uma colisão latente: o helper
 * de ícones dá o slug `multibanco` tanto ao `bacs` como ao Multibanco real da
 * ifthenpay — dois métodos, a mesma coordenada.
 *
 * A geometria passa a sair do índice que o template escreve inline
 * (`--sda-pag-i`), como já se faz nas filas do envio e do carrinho. Serve
 * qualquer número de métodos e a ordem passa a ser a do DOM — a mesma que o
 * mobile já usava, o que resolve de caminho a divergência de ordem entre os
 * dois ambientes (indicação do Francisco: manda a de desktop).
 *
 * A ordem dos métodos é a do WooCommerce e muda-se lá (Definições →
 * Pagamentos, arrastando), sem tocar em CSS.
 * ============================================================ */

@media ( min-width: 431px ) {

	/* Quantos métodos existem. `:has()` e não uma contagem em PHP porque o
	   bloco é re-renderizado por AJAX — mesmo motivo do `--sda-filas`. */
	.checkout-conteudo {
		--sda-pags: 1;
		--sda-pag-passo: 60px;
		--sda-pag-extra: calc( ( var( --sda-pags ) - 3 ) * var( --sda-pag-passo ) );
	}

	.checkout-conteudo:has( .checkout-linha--pagamento ~ .checkout-linha--pagamento ) { --sda-pags: 2; }
	.checkout-conteudo:has( .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ) { --sda-pags: 3; }
	.checkout-conteudo:has( .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ) { --sda-pags: 4; }
	.checkout-conteudo:has( .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ) { --sda-pags: 5; }
	.checkout-conteudo:has( .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ) { --sda-pags: 6; }
	.checkout-conteudo:has( .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ) { --sda-pags: 7; }
	.checkout-conteudo:has( .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ~ .checkout-linha--pagamento ) { --sda-pags: 8; }

	/* (0,2,0) — ganha às regras por slug do mock, que são (0,1,0). O `left`
	   dos ícones e as suas dimensões ficam de lá: são de cada marca. */
	.checkout-linha--pagamento .checkout-radio {
		left: 915px;
		top: calc( 560px + var( --sda-pag-i, 0 ) * var( --sda-pag-passo, 60px ) + var( --sda-envio-extra, 0px ) + var( --sda-pag-desloc, 0px ) );
	}

	.checkout-linha--pagamento .checkout-pagamento__nome {
		top: calc( 550px + var( --sda-pag-i, 0 ) * var( --sda-pag-passo, 60px ) + var( --sda-envio-extra, 0px ) + var( --sda-pag-desloc, 0px ) );
	}

	.checkout-linha--pagamento .checkout-pagamento__icone {
		top: calc( 551px + var( --sda-pag-i, 0 ) * var( --sda-pag-passo, 60px ) + var( --sda-envio-extra, 0px ) + var( --sda-pag-desloc, 0px ) );
	}

	/* Tudo o que vive por baixo do bloco desce com ele. */
	.checkout-finalizar {
		top: calc( 769px + var( --sda-envio-extra, 0px ) + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
	}

	.checkout-termos {
		top: calc( 852px + var( --sda-envio-extra, 0px ) + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
	}

	.checkout-newsletter {
		top: calc( 892px + var( --sda-envio-extra, 0px ) + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
	}

	.checkout-resumo__fundo {
		height: calc( 715px + var( --sda-envio-extra, 0px ) + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
	}
}

/* Composto com os descontos: o cupão já empurrava estes elementos; agora
   soma-se-lhe o crescimento do bloco de pagamento. */
.checkout-conteudo:has( .checkout-linha--desconto ) .checkout-resumo__fundo {
	height: calc( 715px + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
}

.pagina-checkout-1 .checkout-conteudo:has( .checkout-linha--desconto ) .checkout-resumo__fundo {
	height: calc( 715px + var( --sda-envio-extra, 0px ) + var( --sda-descontos, 0 ) * 64px + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
}

/* ============================================================
 * CHECKOUT — a caixa do método escolhido
 *
 * O mockup checkout-1 desenhou uma caixa cinzenta (440x216, a 915/660) com
 * o texto do MB WAY, o rótulo e dois campos: indicativo e telemóvel. Essa
 * caixa era marcação do tema, com um `name="sda_mbway_telemovel"` que o
 * ifthenpay nunca leria — o `validate_fields()` dele procura
 * `mbway_ifthen_for_woocommerce_phone`. Passa a ser a MESMA caixa a vestir
 * os campos verdadeiros do gateway, e serve todos os métodos: todos trazem
 * descrição, e quem pede transferência bancária precisa de ver o IBAN tanto
 * como quem escolhe MB WAY precisa de escrever o número.
 *
 * A altura deixa de ser 216px fixos porque o conteúdo é do gateway e o
 * cliente pode editá-lo nas definições do WooCommerce. Mede-a o
 * `sdaAbrirCaixaPagamento()` em main.js e escreve-a em `--sda-pag-caixa`.
 * ============================================================ */

/* O asterisco de campo obrigatório vem sublinhado a tracejado do
   user-agent, em qualquer largura. */
.checkout-pagamento__caixa abbr[title] {
	text-decoration: none;
	border: 0;
}

/* O `checkout.js` do WooCommerce apanha qualquer `.payment_box` e põe-lhe
   `display: block` INLINE — desenhado para a lista `<li>` dele, onde ele
   próprio esconde as outras. Aqui esconde-as ninguém, e as cinco caixas
   pintavam empilhadas. O `!important` vence o inline e é a excepção que o
   CLAUDE.md prevê: repor um valor imposto por plugin. A classe fica, que é
   por ela que o PPCP encontra a caixa do gateway de cartão. */
.checkout-pagamento__caixa[hidden] {
	display: none !important;
}

@media ( min-width: 431px ) {

	.checkout-linha--pagamento .checkout-pagamento__caixa {
		position: absolute;
		left: 915px;
		top: calc( 660px + var( --sda-pag-i, 0 ) * var( --sda-pag-passo, 60px ) + var( --sda-envio-extra, 0px ) + var( --sda-pag-desloc, 0px ) );
		z-index: 1;
		box-sizing: border-box;
		width: 440px;
		padding: 19px 20px 20px;
		background: #f4f4f4;
	}

	/* As filas ABAIXO da escolhida descem o que a caixa ocupa. O irmão
	   geral (`~`) e não `+`: a caixa vive dentro da fila, e entre filas o
	   WooCommerce ainda pode injectar avisos. */
	.checkout-linha--pagamento:has( input:checked ) ~ .checkout-linha--pagamento {
		--sda-pag-desloc: var( --sda-pag-caixa, 0px );
	}

	/* ---- o conteúdo do gateway, vestido com o desenho ---- */

	.checkout-pagamento__caixa p {
		margin: 0 0 10px;
		font: 500 18px/26px var( --fonte-corpo );
		color: var( --cor-texto );
	}

	.checkout-pagamento__caixa p:last-child {
		margin-bottom: 0;
	}

	/* O rótulo do campo — no mockup era `.checkout-mbway__rotulo`. */
	.checkout-pagamento__caixa label {
		display: block;
		margin: 0 0 9px;
		font: 500 18px/26px var( --fonte-corpo );
		color: var( --cor-titulos-tom );
	}


	/* Os dois campos do MB WAY: indicativo (210px) e número (180px), com
	   os 10px de intervalo do desenho. O plugin traz `display: flex` e
	   `gap: 0.75em` próprios num `<style>` inline — daí o `!important`
	   nas medidas, que é a excepção prevista no CLAUDE.md para valores
	   de plugin. */
	/* O plugin traz uma container query aos 400px (linha 1310 do
	   class-wc-mbway-ifthen-webdados.php) que empilha os dois campos. A
	   largura interior da caixa é exactamente 400px, por isso disparava
	   sempre e o desenho perdia a fila de dois campos do mockup. */
	.checkout-pagamento__caixa #mbway_ifthen_for_woocommerce_phone_field_container {
		display: flex !important;
		flex-direction: row !important;
		flex-wrap: nowrap !important;
		align-items: center;
		gap: 10px !important;
		margin-top: 0 !important;
	}

	.checkout-pagamento__caixa #mbway_ifthen_for_woocommerce_phone_field {
		margin-top: 0 !important;
	}

	.checkout-pagamento__caixa #mbway_ifthen_for_woocommerce_phone_field_container_country_code {
		width: 210px !important;
	}

	.checkout-pagamento__caixa #mbway_ifthen_for_woocommerce_phone {
		width: 180px !important;
	}

	.checkout-pagamento__caixa select,
	.checkout-pagamento__caixa input[type="tel"] {
		box-sizing: border-box;
		height: 61px;
		padding: 0 20px;
		font: 600 18px/36px var( --fonte-corpo );
		color: var( --cor-primaria );
		background: #ffffff;
		border: 1px solid var( --cor-cinza-medio );
		border-radius: 12px;
		appearance: none;
	}

	/* A seta do mockup, em vez da nativa do `<select>`. */
	.checkout-pagamento__caixa select {
		width: 100%;
		background-image: url( "../img/loja/checkout-1-seta-dropdown.svg" );
		background-repeat: no-repeat;
		background-position: right 20px center;
		background-size: 18px 9px;
	}

	.checkout-pagamento__caixa input[type="tel"] {
		font-weight: 500;
		color: var( --cor-texto );
	}

	.checkout-pagamento__caixa input[type="tel"]::placeholder {
		color: var( --cor-cinza-medio );
	}

	/* O ifthenpay usa selectWoo quando existe: o desenho tem de chegar
	   também à caixa que ele desenha por cima do `<select>`. */
	/* O select2 mede-se pelo container exterior; sem lhe dar a altura, a
	   caixa do indicativo ficava 4px mais baixa do que a do número. */
	.checkout-pagamento__caixa .select2-container {
		height: 61px;
	}

	.checkout-pagamento__caixa .select2-container .select2-selection--single {
		box-sizing: border-box;
		height: 61px;
		background: #ffffff;
		border: 1px solid var( --cor-cinza-medio );
		border-radius: 12px;
	}

	.checkout-pagamento__caixa .select2-container .select2-selection__rendered {
		padding: 0 20px;
		font: 600 18px/59px var( --fonte-corpo );
		color: var( --cor-primaria );
	}

	.checkout-pagamento__caixa .select2-container .select2-selection__arrow {
		top: 26px;
		right: 16px;
	}

	/* ---- botões do PayPal / Google Pay / Apple Pay ----
	   O PPCP imprime-os no `woocommerce_review_order_after_payment`, logo a
	   seguir às filas, e esconde o `#place_order` quando um deles é o método
	   escolhido. Ficam onde o botão FINALIZAR ficaria.

	   Só o gateway PayPal vem embrulhado em `.ppc-button-wrapper`; o Google
	   Pay e o Apple Pay imprimem um `<div>` nu (ApplepayModule.php:159 e o
	   equivalente no Googlepay), por isso os três ids entram pelo nome. */
	.ppc-button-wrapper,
	#ppc-button-ppcp-googlepay,
	#ppc-button-ppcp-applepay {
		position: absolute;
		left: 915px;
		top: calc( 769px + var( --sda-envio-extra, 0px ) + var( --sda-pag-extra, 0px ) + var( --sda-pag-caixa, 0px ) );
		width: 440px;
	}
}

/* ---------- telemóvel (<=430) ----------
   Em mobile o checkout está em fluxo: a caixa empurra o resto sozinha e o
   `--sda-pag-caixa` nem chega a ser escrito. Só é preciso dar-lhe a
   largura da coluna útil e travar o selector de refluxo, que escreve
   `width` e `position` em tudo o que apanha. */
@media ( max-width: 430px ) {

	/* A fila é uma grelha (24px para o rádio, o resto para o nome). Sem
	   atravessar as colunas todas, a caixa caía na primeira e ficava com
	   32px de largura — medi-a assim antes de o corrigir.
	   Nas filas com ícone a terceira coluna é IMPLÍCITA, e o `-1` só conta
	   as explícitas: `1 / -1` parava aos 298px. Daí a largura fixa, que
	   neste canvas de 390 é sempre a mesma — a coluna útil são 344px, e o
	   `zoom` do `<html>` é que trata das larguras reais do aparelho. */
	.checkout-linha--pagamento .checkout-pagamento__caixa {
		position: static !important;
		grid-column: 1 / -1;
		box-sizing: border-box;
		width: 344px !important;
		max-width: 344px !important;
		margin: 12px 0 4px !important;
		padding: 16px;
		background: #f4f4f4;
	}

	.checkout-pagamento__caixa p,
	.checkout-pagamento__caixa label {
		position: static !important;
		width: auto !important;
		max-width: none !important;
		height: auto !important;
		margin: 0 0 8px;
		font: 500 15px/22px var( --fonte-corpo );
		white-space: normal !important;
	}

	.checkout-pagamento__caixa label {
		color: var( --cor-titulos-tom );
	}

	.checkout-pagamento__caixa #mbway_ifthen_for_woocommerce_phone_field_container {
		display: flex !important;
		flex-direction: row !important;
		flex-wrap: nowrap !important;
		align-items: center;
		gap: 8px !important;
		margin-top: 0 !important;
	}

	/* O `:not(.select2-hidden-accessible)` não é zelo a mais: o select2
	   esconde o `<select>` original com `position: absolute` e um
	   `clip`, e o `position: static !important` daqui trazia-o de volta —
	   o indicativo aparecia DUAS vezes, o nativo por baixo do desenhado. */
	.checkout-pagamento__caixa select:not( .select2-hidden-accessible ),
	.checkout-pagamento__caixa input[type="tel"] {
		position: static !important;
		box-sizing: border-box;
		width: 100% !important;
		max-width: none !important;
		height: 48px !important;
		padding: 0 12px;
		font: 500 15px/22px var( --fonte-corpo );
		color: var( --cor-texto );
		background: #ffffff;
		border: 1px solid var( --cor-cinza-medio );
		border-radius: 12px;
	}

	.checkout-pagamento__caixa #mbway_ifthen_for_woocommerce_phone_field_container_country_code {
		width: 55% !important;
	}

	.checkout-pagamento__caixa #mbway_ifthen_for_woocommerce_phone {
		width: 45% !important;
	}

	/* O select2 desenha a sua própria caixa e a sua própria seta; sem estas
	   ficava com o tipo de letra do plugin e a seta no canto inferior
	   esquerdo. O `!important` na altura é contra o selector de refluxo do
	   mobile (sda-extra.css:9754), que é (0,12,1) e escreve `height` em
	   tudo o que apanha dentro do `.site-content`. */
	.checkout-pagamento__caixa .select2-container {
		width: 100% !important;
		height: 48px !important;
	}

	/* `position: relative` porque o refluxo põe `static` em tudo e a seta,
	   que é `absolute`, ficava sem ancestral posicionado — subia ao canvas
	   e aparecia no topo da página. */
	.checkout-pagamento__caixa .select2-container .select2-selection--single {
		position: relative !important;
		box-sizing: border-box;
		height: 48px !important;
		background: #ffffff;
		border: 1px solid var( --cor-cinza-medio );
		border-radius: 12px;
	}

	.checkout-pagamento__caixa .select2-container .select2-selection__rendered {
		padding: 0 12px;
		font: 500 15px/46px var( --fonte-corpo );
		color: var( --cor-texto );
	}

	.checkout-pagamento__caixa .select2-container .select2-selection__arrow {
		position: absolute !important;
		top: 20px !important;
		right: 10px !important;
		left: auto !important;
		height: 8px !important;
	}

	/* O ficheiro do PayPal é @2x (236x60) e o selector de refluxo tira-lhe
	   a largura, deixando-o render ao tamanho intrínseco — o dobro do que o
	   desenho pede (main.css:5834 diz 118x30) e o dobro da altura de todas
	   as outras filas. Os SVG dos outros métodos não sofrem disto porque
	   já têm o tamanho certo. */
	.checkout-pagamento__icone--paypal {
		width: 118px !important;
		height: 30px !important;
	}

	.ppc-button-wrapper,
	#ppc-button-ppcp-googlepay,
	#ppc-button-ppcp-applepay {
		position: static !important;
		width: 100% !important;
		max-width: 344px !important;
		margin: 12px 0 !important;
	}
}

/* ============================================================
 * HOME — tamanho dos textos introdutórios (revisão da Raquel, 2026-09-10)
 *
 * Divergência DELIBERADA do mock, registada aqui para quem vier depois:
 * reverte-se apagando este bloco. O espelho (main.css:3976 e :4015) traz a
 * home com três corpos de texto — 18 na 1.ª secção, 22 nas Terapias e no
 * Leonardo, 26 na Loja e nas Actividades. A Raquel pediu por escrito que a
 * 1.ª secção fique «no mesmo tamanho dos outros blocos, por exemplo o da
 * secção do Leonardo» (22) e que a intro das Terapias fique como a das
 * secções ao lado (Loja, 26). É, de resto, a relação que o desenho mobile
 * dela já tinha (1.ª secção = Leonardo a 16; Terapias = Loja a 18) — por
 * isso o bloco é só desktop, e o mobile não muda.
 *
 * Só `font-size`: o `line-height` de 36px vem do shorthand do espelho e é
 * o mesmo dos blocos de referência (Leonardo 22/36, Loja 26/36).
 *
 * Medido antes de aplicar: nas Terapias os 26px cabem nas mesmas 3 linhas
 * (delta zero). Na 1.ª secção o texto passa de 10 para 12 linhas (+72px) e
 * a folga até ao SABER MAIS desce de 133 para 61px — da família dos 54px
 * que a Loja tem entre intro e botão. O botão fica onde o desenho o pôs:
 * descê-lo 72px levava-o a 875, fora da secção de 865, e mover a secção
 * arrastava o dente-de-leão, que acaba exactamente no fundo dela.
 * ============================================================ */

@media ( min-width: 431px ) {

	.home-boas-vindas__texto {
		font-size: 22px;
	}

	.home-terapias__intro {
		font-size: 26px;
	}
}

/* ============================================================
 * CURSOS — o selo a rodar no mesmo sítio que nas outras páginas
 *
 * Divergência DELIBERADA do mock, registada para quem vier depois:
 * reverte-se apagando este bloco. Em TODAS as outras páginas o centro do
 * selo assenta na aresta esquerda da foto, a meio da altura — medido:
 * terapia Astrologia e Tarot dx 0 / dy 0, Quem Somos dx 0 / dy +8, home
 * dx 0 / dy -17. Nos cursos o mock punha-o 13px para DENTRO da foto e
 * 280px abaixo do meio (`left: -79px; top: 498px`, main.css:1772), e o
 * 2.º ano do Tarot tinha um terceiro jogo de valores (main.css:1987),
 * pelo que o selo ainda saltava ao trocar de separador.
 *
 * Correcção pedida pelo cliente (2026-09-10): «o logo a girar não está no
 * mesmo sítio que os outros; colocar com a mesma localização da consulta
 * de astrologia».
 *
 * O tamanho fica nos 184px do desenho: a foto do curso é menor (451x620
 * contra 700x762) e a proporção selo/foto mantém-se — 41% aqui, 38% na
 * terapia. Mudar a posição sem mudar o tamanho é o que foi pedido.
 *
 * O deslocamento vai na propriedade `translate` e não em `transform`,
 * pelo mesmo motivo que já levou os outros três selos a fazê-lo
 * (sda-extra.css:268): `rotate` compõe ANTES de `transform`, e com o
 * translate lá dentro a rotação punha o selo em órbita em vez de o rodar
 * sobre o próprio eixo. Medi-o antes de corrigir: com `transform` o centro
 * ficava a dx 18 / dy -15 conforme a fase da animação; com `translate`
 * fica em 0/0, como na terapia.
 * ============================================================ */

@media ( min-width: 431px ) {

	/* (0,2,0) para vencer também a variante do 2.º ano do Tarot. */
	.curso-sobre-leonardo .curso-sobre-leonardo__selo,
	.pagina-curso-tarot-2 .curso-sobre-leonardo__selo {
		left: 0;
		top: 50%;
		transform: none;
		translate: -50% -50%;
		width: 184px;
		height: 183px;
	}
}

/* ============================================================
 * ARTIGO — a secção do conteúdo cresce com o texto
 *
 * `main.css:3453` fixa `.artigo-conteudo { height: 2623px }`, a medida do
 * artigo que o Figma desenhou, e o `.artigo-conteudo__texto` é absoluto a
 * partir dos 565px — não conta para a altura de nada. Medido nos 24 artigos
 * locais: **14 transbordam** e 11 chegam a pintar por cima da secção
 * seguinte (as etiquetas, o coração e os botões de partilha); o pior sai
 * 2563px fora. Não é um artigo mau, é o template: qualquer texto mais longo
 * do que o do mock faz o mesmo.
 *
 * O texto entra em fluxo e o `.seccao-inner` leva no padding o que era o
 * `top` do desenho, para o primeiro parágrafo continuar exactamente nos
 * 565px; a secção cresce com o conteúdo.
 *
 * 2.60.1 (20-10-2026): a secção tinha os 2623 como MÍNIMO, para a barra
 * lateral (absoluta) caber sempre. Com a barra a crescer com o que tem
 * (Fase das etiquetas, 2.56.1), ela mede uns 1130px a 1440, e nos artigos
 * curtos o mínimo deixava até 600px vazios antes das etiquetas (reportado
 * pelo Francisco na produção). O texto e a barra passam a duas colunas de
 * uma grelha com as medidas do desenho (912 + 89 + 399 = 1400): a secção
 * acaba no fim do mais alto dos dois, e o mínimo sai. A barra fica na
 * grelha com `margin-top: -568px` (os 565 do padding e os -3px do
 * main.css:3803) e por isso não muda de sítio; medido no staging, em dez
 * artigos e com um artigo encurtado de propósito: texto, barra e capa no
 * mesmo píxel, e 60px (80 à escala de 0,75) entre o fim do mais alto e o
 * fim da secção, como nos artigos compridos.
 *
 * Só desktop: a ≤430px o refluxo já põe tudo em fluxo e a altura em auto.
 *
 * `screen` para não interferir com o bloco de impressão (2.56.1): a A4 tem
 * cerca de 680px úteis e passava o `min-width`, e o `.artigo-conteudo
 * .seccao-inner` (0,2,0) vencia o `padding: 0` da impressão (0,1,0), com
 * 565px em branco por cima do texto do artigo impresso. O limite passa
 * também de 431 para 430.02, como os blocos mais recentes, para não deixar
 * de fora as larguras fraccionárias entre 430 e 431, que já são canvas.
 * ============================================================ */

@media screen and ( min-width: 430.02px ) {

	.artigo-conteudo {
		height: auto;
	}

	.artigo-conteudo .seccao-inner {
		display: grid;
		grid-template-columns: 912px 399px;
		column-gap: 89px;
		align-items: start;
		padding-top: 565px;
		/* Folga antes da secção das etiquetas, que já traz `margin-top: 53px`
		   (main.css:3521). Juntos dão 133px, a mesma ordem das fronteiras
		   entre secções afinadas na Fase 63.4. */
		padding-bottom: 80px;
	}

	.artigo-conteudo__texto {
		position: static;
		top: auto;
		grid-column: 1;
		grid-row: 1;
	}

	.artigo-conteudo .seccao-sidebar {
		position: relative;
		top: auto;
		left: auto;
		grid-column: 2;
		grid-row: 1;
		margin-top: -568px;
	}

	/* A capa continua absoluta e no sítio (a barra lateral também estava
	   assim até à 2.60.1, e por isso o comentário fala das duas): o bloco de
	   contenção de um elemento absoluto é a caixa de PADDING do ancestral
	   posicionado, e por isso o `top: 0` delas não se mexeu com o padding
	   novo. (Cheguei a compensá-las em -565/-568 e a medição mostrou-as
	   565px acima da secção — a compensação é que estava a mais.)
	   O que precisa de reposição é a margem do primeiro filho do texto:
	   com o bloco absoluto ela colapsava para fora, e em fluxo dentro de um
	   padding já não colapsa — o 1.º parágrafo caía até 48px abaixo dos
	   565px do desenho, conforme começasse por citação, título ou lista. */
	.artigo-conteudo__texto > *:first-child {
		margin-top: 0;
	}
}

/* ============================================================
 * ARTIGO — as etiquetas partem em várias linhas (2.56.1)
 *
 * `main.css:3524` desenha as etiquetas numa fila flex sem quebra, absoluta
 * no topo da secção, e tudo o que vem a seguir (separadores, gosto,
 * partilha, artigo seguinte) em `top` fixos de uma secção de 327px. O
 * desenho tem quatro etiquetas; dos artigos importados, 103 têm 9 ou mais e
 * o mais carregado tem 17. No computador a fila passava a coluna de 912 e
 * corria por baixo da coluna lateral, com scroll horizontal (o foco do
 * teclado na última etiqueta deslocava a página 274px para o lado); no
 * telemóvel a fila espremia as etiquetas e cortava as que não cabiam.
 *
 * A fila passa a partir em linhas dentro da coluna, com 10px entre linhas,
 * o mesmo intervalo que o desenho tem entre etiquetas (o `gap` do main.css
 * já vale nas duas direcções). No telemóvel o refluxo já põe o resto em
 * fluxo e basta a quebra. No computador a fila entra em fluxo e os blocos
 * seguintes, que continuam absolutos, deixam o `top` em `auto`: ficam na
 * posição estática, que é a base da fila, e a margem de cima leva o que
 * falta até ao `top` do desenho, isto é, o `top` do main.css menos os 53px
 * de uma linha de etiquetas. Com uma linha fica tudo onde estava; cada
 * linha a mais desce o resto 63px (53 + 10).
 *
 * Sem etiquetas não há fila e valem os `top` do main.css, por isso as
 * margens só se aplicam a irmãos que vêm depois da fila (`~`). A secção
 * mede a fila mais os 274px que o desenho tem por baixo dela (327 - 53),
 * com os 327 como mínimo para o artigo sem etiquetas.
 *
 * O bloco do computador é só `screen`, como o de cima. Na impressão a A4
 * passava o `min-width` e o `padding-bottom` de 274px (0,2,0) vencia o
 * `padding: 0` do bloco de impressão, e as margens de 75 a 197px ficavam
 * nos blocos que a impressão põe em fluxo: cada artigo impresso ganhava
 * cerca de 620px em branco à volta da partilha. A quebra fica fora da media
 * query, porque também serve no papel, onde a fila saía da folha.
 * ============================================================ */

.artigo-tags-partilha__tags {
	flex-wrap: wrap;
}

@media screen and ( min-width: 430.02px ) {

	.artigo-tags-partilha {
		height: auto;
		min-height: 327px;
	}

	.artigo-tags-partilha .seccao-inner {
		padding-bottom: 274px;
	}

	.artigo-tags-partilha__tags {
		position: static;
		width: 912px;
	}

	.artigo-tags-partilha__tags ~ .artigo-tags-partilha__separador--1,
	.artigo-tags-partilha__tags ~ .artigo-tags-partilha__recomendar,
	.artigo-tags-partilha__tags ~ .artigo-tags-partilha__partilhar,
	.artigo-tags-partilha__tags ~ .artigo-tags-partilha__separador--2,
	.artigo-tags-partilha__tags ~ .artigo-tags-partilha__seguinte {
		top: auto;
	}

	/* 94 - 53 */
	.artigo-tags-partilha__tags ~ .artigo-tags-partilha__separador--1 {
		margin-top: 41px;
	}

	/* 128 - 53 */
	.artigo-tags-partilha__tags ~ .artigo-tags-partilha__recomendar,
	.artigo-tags-partilha__tags ~ .artigo-tags-partilha__partilhar {
		margin-top: 75px;
	}

	/* 216 - 53 */
	.artigo-tags-partilha__tags ~ .artigo-tags-partilha__separador--2 {
		margin-top: 163px;
	}

	/* 250 - 53 */
	.artigo-tags-partilha__tags ~ .artigo-tags-partilha__seguinte {
		margin-top: 197px;
	}
}

/* ============================================================
 * COLUNA DO BLOG — as secções seguem-se em fluxo (2.56.1)
 *
 * `main.css:2656` põe as categorias, as etiquetas, o cartão das terapias e
 * o da palestra em `top` fixos (522, 753, 1111 e 1395), medidos no desenho,
 * que tem três categorias e quatro linhas de etiquetas. O blog importado
 * tem quatro categorias (Blog, Conexões Semanais, Reflexão e Terapias), e a
 * quarta ficava a 3px do título «Tags». As dez etiquetas mais usadas
 * ocupam cinco linhas, e a última entrava 2px por baixo do cartão das
 * terapias, colada a ele (com mais linhas, entrava mais).
 *
 * No computador as quatro secções passam a fluxo dentro da coluna, pela
 * mesma ordem, e a coluna leva no `padding-top` os 522px a que o desenho
 * põe as categorias. A pesquisa e os dois artigos recentes continuam
 * absolutos por cima, nos mesmos sítios. Cada secção leva por baixo o
 * intervalo do desenho até à seguinte: 52px da última categoria ao título
 * das etiquetas, 61px da última linha de etiquetas ao cartão das terapias
 * e 60px desse cartão ao da palestra. Com três categorias e quatro linhas
 * de etiquetas a soma dá os mesmos 522, 753, 1111 e 1395; cada categoria a
 * mais desce o resto 49px (26 + 23) e cada linha de etiquetas 63px
 * (53 + 10). Os intervalos ficam por baixo de cada secção, e por isso, sem
 * uma delas (as categorias e as etiquetas vêm do conteúdo, o cartão das
 * terapias das opções), a seguinte fica no lugar dela.
 *
 * `relative` e não `static`, para as secções continuarem pintadas na mesma
 * camada e pela mesma ordem, e os dois cartões continuarem a ser o
 * contentor dos seus filhos absolutos.
 *
 * Na lista do blog e nos arquivos (categoria, etiqueta e autor) a secção
 * dos artigos tinha 1930px fixos e a coluna, absoluta, não contava para a
 * altura, por isso uma coluna mais comprida passava para cima dos produtos
 * relacionados. Aí a coluna passa a estar em fluxo no `.seccao-inner` (a
 * lista e a paginação continuam absolutas), com os 1001px da esquerda como
 * deslocamento, e a secção cresce com ela. Os 1930 ficam como mínimo e os
 * 51px do desenho entre a base da coluna e a da secção ficam no
 * `padding-bottom`. No artigo a coluna continua absoluta: a secção do
 * conteúdo tem 2623px de mínimo, e a coluna só lá chegaria com mais doze
 * linhas de etiquetas do que o desenho.
 *
 * Só `screen`, como os blocos em fluxo do artigo, para não mexer na
 * impressão. Abaixo dos 430.02px o refluxo já põe a coluna em fluxo.
 * ============================================================ */

@media screen and ( min-width: 430.02px ) {

	.seccao-sidebar {
		height: auto;
		padding-top: 522px;
	}

	.seccao-sidebar__categorias,
	.seccao-sidebar__tags,
	.seccao-sidebar__banner-terapias,
	.seccao-sidebar__card-palestra {
		position: relative;
		top: auto;
	}

	/* 753 - 701 */
	.seccao-sidebar__categorias {
		margin-bottom: 52px;
	}

	/* 1111 - 1050 */
	.seccao-sidebar__tags {
		margin-bottom: 61px;
	}

	/* 1395 - 1335 */
	.seccao-sidebar__banner-terapias {
		margin-bottom: 60px;
	}

	.seccao-artigos {
		height: auto;
		min-height: 1930px;
	}

	/* 1930 - 1879 */
	.seccao-artigos .seccao-inner {
		padding-bottom: 51px;
	}

	.seccao-artigos .seccao-sidebar {
		position: relative;
	}
}

/* ============================================================
 * PAGINAÇÃO — o círculo segue a página actual
 *
 * `main.css:2504` desenha o círculo em `.seccao-artigos-paginacao-numero--1`,
 * isto é, no número 1 e não na página em que estamos: na página 3 do blog o
 * anel continuava no 1. A marcação já dizia a verdade — o número da página
 * actual é um `<span aria-current="page">` e os outros são `<a>` —, faltava
 * o CSS ouvi-la. Mesma correcção na loja, onde `.ativo` trazia colado um
 * `left: 754px` que atirava o número activo para o lugar do primeiro.
 * ============================================================ */

.seccao-artigos-paginacao-numero--1:not( [aria-current="page"] ) {
	color: var( --cor-texto );
	border: 0;
	border-radius: 0;
	height: auto;
	line-height: 59px;
}

.seccao-artigos-paginacao-numero[aria-current="page"] {
	box-sizing: border-box;
	height: 59px;
	line-height: 55px;
	color: var( --cor-primaria );
	border: 2px solid var( --cor-primaria );
	border-radius: 50%;
}

/* Na loja o mock desenhou três páginas, com `left` só no 2.º e no 3.º e o
   activo colado à primeira posição (`.ativo { left: 754px }`,
   main.css:4709) — e o template nem lhe dava o modificador `--N`. Medido
   antes: em /loja/page/2/ os números 1 e 2 pintavam ambos em x=260, um por
   cima do outro. Passa a fluxo, como o blog já fazia (sda-extra.css:1132):
   assim serve qualquer número de páginas e a posição deixa de depender de
   uma regra por índice que só existe até três. */
.loja-paginacao {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
}

.loja-paginacao__pagina,
.loja-paginacao__seta {
	position: static;
	left: auto;
}

/* ============================================================
 * CURSO DE TAROT — a imagem do «Sobre o curso» alinhada com a coluna
 *
 * Divergência DELIBERADA do mock, registada para quem vier depois:
 * reverte-se apagando este bloco. O mock põe a imagem aos 64px no Tarot
 * (main.css:1954) e aos 134px na Astrologia — e a coluna da direita começa
 * aos 107px nas duas. Resultado medido: na Astrologia o «DATA DE INÍCIO»
 * fica 27px acima do topo da imagem e lê-se como um alinhamento; no Tarot a
 * imagem sobe 43px acima do rótulo e a coluna parece descaída.
 *
 * Indicação do cliente (2026-09-10): «o alinhamento que está bem é o do
 * curso de astrologia». A imagem do Tarot passa aos mesmos 134px. Cabe: com
 * 249px de altura acaba aos 383, dentro dos 441px da secção.
 * ============================================================ */

@media ( min-width: 431px ) {

	.pagina-curso-tarot-1 .curso-sobre__imagem,
	.pagina-curso-tarot-2 .curso-sobre__imagem {
		top: 134px;
	}
}

/* ============================================================
 * CONTACTOS — o mapa real com o tratamento da imagem do desenho
 *
 * O desenho tinha uma imagem estática (598x612, raio 25). Pedido do cliente
 * (2026-09-10): mapa real, «com o mesmo estilo da imagem». A caixa é a mesma
 * — o `.seccao-onde-estamos__mapa` do mock (main.css:2294) continua a mandar
 * na posição e no tamanho —, e o que muda é o que vive lá dentro.
 *
 * O filtro é o que aproxima o mapa vivo da imagem do desenho: os mapas do
 * Google saem saturados de azuis e verdes, e a página é creme com roxo. Um
 * `saturate` baixo com um toque de `sepia` aquece-o e tira-lhe o ruído de
 * cor sem o tornar cinzento — os arruamentos continuam legíveis.
 * ============================================================ */

.seccao-onde-estamos__mapa--real {
	overflow: hidden;
	background: #f0ece4;
}

.seccao-onde-estamos__mapa-frame {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
	filter: saturate( 0.42 ) sepia( 0.08 ) contrast( 0.94 ) brightness( 1.04 );
}

/* Antes do consentimento fica a imagem do desenho, com o botão por cima. */
.seccao-onde-estamos__mapa-previa {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Botão de contorno — o «secundário» da Raquel, «aquele que tem o fundo
   branco com as letras roxas» (2026-09-10). No carrinho o contorno é
   transparente e é a página que lhe dá o branco; aqui assenta sobre a
   imagem do mapa, por isso leva o branco no próprio botão, senão as
   letras roxas perdiam-se nos arruamentos. O hover continua o do
   `.botao-contorno` (enche de roxo, letras brancas): `.botao-contorno:hover`
   é (0,2,0) e ganha a esta regra. A largura é a do botão principal que cá
   estava, para o botão não mudar de tamanho ao mudar de estilo. */
.seccao-onde-estamos__mapa-botao {
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate( -50%, -50% );
	width: 251px;
	background: #ffffff;
}

.seccao-onde-estamos__mapa-nota {
	position: absolute;
	left: 50%;
	bottom: 24px;
	transform: translateX( -50% );
	width: 80%;
	margin: 0;
	text-align: center;
	font: 400 15px/22px var( --fonte-corpo );
	color: var( --cor-texto );
}

@media ( max-width: 430px ) {

	/* O refluxo põe a caixa em fluxo e dá-lhe a largura da coluna útil; o
	   iframe herda-a. A altura vem do rácio do desenho (598x612). */
	body:not( .pagina-home-final ) .site-content .seccao-onde-estamos__mapa--real {
		position: relative !important;
		height: auto !important;
		aspect-ratio: 598 / 612;
	}

	body:not( .pagina-home-final ) .site-content .seccao-onde-estamos__mapa-frame,
	body:not( .pagina-home-final ) .site-content .seccao-onde-estamos__mapa-previa {
		position: static !important;
		width: 100% !important;
		height: 100% !important;
		max-width: none !important;
	}

	body:not( .pagina-home-final ) .site-content .seccao-onde-estamos__mapa-botao {
		position: absolute !important;
		left: 50% !important;
		top: 50% !important;
	}

	body:not( .pagina-home-final ) .site-content .seccao-onde-estamos__mapa-nota {
		position: absolute !important;
		left: 50% !important;
		top: auto !important;
		bottom: 16px !important;
		width: 84% !important;
		max-width: none !important;
	}
}

/* ============================================================
 * MOVIMENTO — o que o desenho previa e não estava a acontecer
 *
 * Reparo do cliente: «nas maquetas existem movimentos de imagens e de
 * algumas setas em CTA que não são de botões que não estão a acontecer» e
 * «algumas animações acontecem, mas muitoooooo devagar».
 *
 * O movimento das imagens (parallax) está a correr — medi-o na home: as
 * duas fotografias da secção de boas-vindas deslocam-se ±85px em sentidos
 * opostos ao longo do scroll. O que faltava era mesmo isto: **nenhum** dos
 * CTA com seta tinha regra de hover. Tinham `transition` declarada e nada
 * que a disparasse — a transição estava lá à espera de uma mudança que
 * nunca chegava.
 *
 * A seta avança 6px e o texto acompanha com uma mudança de cor; é o gesto
 * que o cartão de categorias já fazia (`.categoria-card__seta`) e que agora
 * passa a valer para todos os links com seta. Botões ficam de fora, como
 * pedido — têm o seu próprio estado.
 * ============================================================ */

.seccao-artigos-card-ler-mais img,
.home-blog-card__ler-mais img,
.home-actividades-card__saber-mais img,
.card-actividade__saber-mais img,
.artigo-tags-partilha__seguinte-rotulo img,
.seccao-sidebar__recente-ler-mais img,
.seccao-artigos-paginacao-seguinte img,
.loja-paginacao__seta img {
	transition: transform 0.25s ease;
}

.seccao-artigos-card-ler-mais,
.home-blog-card__ler-mais,
.home-actividades-card__saber-mais,
.card-actividade__saber-mais,
.artigo-tags-partilha__seguinte-rotulo,
.seccao-sidebar__recente-ler-mais {
	transition: color 0.25s ease;
}

.seccao-artigos-card-ler-mais:hover img,
.seccao-artigos-card-ler-mais:focus-visible img,
.home-blog-card__ler-mais:hover img,
.home-blog-card__ler-mais:focus-visible img,
.home-actividades-card__saber-mais:hover img,
.home-actividades-card__saber-mais:focus-visible img,
.card-actividade__saber-mais:hover img,
.card-actividade__saber-mais:focus-visible img,
.artigo-tags-partilha__seguinte-rotulo:hover img,
.artigo-tags-partilha__seguinte-rotulo:focus-visible img,
.seccao-sidebar__recente-ler-mais:hover img,
.seccao-sidebar__recente-ler-mais:focus-visible img,
.seccao-artigos-paginacao-seguinte:hover img,
.seccao-artigos-paginacao-seguinte:focus-visible img,
.loja-paginacao__seta:hover img,
.loja-paginacao__seta:focus-visible img {
	transform: translateX( 6px );
}

/* O cartão inteiro é a área de toque: passar o rato no cartão move a seta
   do «Ler mais» que lhe pertence, como no desenho. */
.home-blog-card:hover .home-blog-card__ler-mais img,
.seccao-artigos-card:hover .seccao-artigos-card-ler-mais img,
.card-actividade:hover .card-actividade__saber-mais img,
.home-actividades-card:hover .home-actividades-card__saber-mais img {
	transform: translateX( 6px );
}

.seccao-artigos-card-ler-mais:hover,
.home-blog-card__ler-mais:hover,
.home-actividades-card__saber-mais:hover,
.card-actividade__saber-mais:hover,
.artigo-tags-partilha__seguinte-rotulo:hover,
.seccao-sidebar__recente-ler-mais:hover {
	color: var( --cor-primaria );
}

@media ( prefers-reduced-motion: reduce ) {

	.seccao-artigos-card-ler-mais img,
	.home-blog-card__ler-mais img,
	.home-actividades-card__saber-mais img,
	.card-actividade__saber-mais img,
	.artigo-tags-partilha__seguinte-rotulo img,
	.seccao-sidebar__recente-ler-mais img,
	.seccao-artigos-paginacao-seguinte img,
	.loja-paginacao__seta img {
		transition: none;
		transform: none !important;
	}
}

/* ============================================================
 * COMENTÁRIOS — o aviso que o WordPress injecta tinha onde cair
 *
 * O interior de `.artigo-deixe-comentario` é todo absoluto (o mock desenhou
 * cada campo com o seu `top`), e o WordPress acrescenta em FLUXO um
 * parágrafo que o desenho nunca previu: «Sessão iniciada como … Editar
 * perfil. Sair?» a quem tem sessão, e «Campos obrigatórios marcados com *»
 * a quem não tem. Sem posição própria caía no topo do bloco, exactamente
 * por cima do título — medido: os dois a começar em y5113.
 *
 * Ganha o vão entre o título (que acaba aos 33px) e o primeiro campo (aos
 * 148px), que estava vazio no desenho.
 * ============================================================ */

@media ( min-width: 431px ) {

	.artigo-deixe-comentario .logged-in-as,
	.artigo-deixe-comentario .comment-notes,
	.artigo-comentarios .logged-in-as,
	.artigo-comentarios .comment-notes {
		position: absolute;
		left: 0;
		top: 52px;
		width: 912px;
		margin: 0;
		font: 400 16px/24px var( --fonte-corpo );
		color: var( --cor-titulos-tom );
	}

	.artigo-deixe-comentario .logged-in-as a,
	.artigo-deixe-comentario .comment-notes a,
	.artigo-comentarios .logged-in-as a,
	.artigo-comentarios .comment-notes a {
		color: var( --cor-primaria );
	}

	/* O `#respond` e o `form` ficaram sem altura ao terem os filhos todos
	   absolutos; sem isto o bloco de resposta não reservava espaço nenhum. */
	.artigo-deixe-comentario #respond,
	.artigo-deixe-comentario form.comment-form {
		position: static;
	}
}

@media ( max-width: 430px ) {

	/* Em fluxo basta afastá-lo do título. */
	body:not( .pagina-home-final ) .site-content .logged-in-as,
	body:not( .pagina-home-final ) .site-content .comment-notes {
		position: static !important;
		width: auto !important;
		max-width: none !important;
		margin: 0 0 20px !important;
		font-size: 15px;
	}
}

/* ============================================================
 * Fase 102 — parallax mais notório (revisão da Raquel, 2026-09-10)
 * ============================================================ */

/* A mão de fundo das Actividades sobe 70px em relação à maqueta.
 *
 * Pedido da Raquel: «na secção das Actividades, a imagem de fundo com a
 * mão precisa de ter o efeito de scroll mais notório. Se for necessário,
 * podes subir um pouco a imagem para se notar mais o scroll».
 *
 * Era mesmo necessário: medida, a imagem tinha 462px de folga por cima e
 * apenas 42px por baixo, e é para baixo que anda. Subindo-a 70px, o
 * percurso de 110px que o main.js lhe dá fica centrado na posição da
 * maqueta — a meio do movimento está onde o desenho a põe — e a borda
 * inferior pára a 2px do fim da secção, sem entrar na seguinte.
 * O parallax não corre abaixo de 768px, por isso a subida também não. */
@media ( min-width: 768px ) {
	.home-actividades__lateral {
		top: 392px;
	}
}

/* ============================================================
 * Fase 103 — correcções da Raquel (2026-09-10)
 * ============================================================ */

/* Botões da home com seta (Ver Loja, Descobrir, Ver Todos): a seta anda
 * no hover, como nos outros CTA com seta da Fase 101.
 *
 * Raquel: «todos os botões que têm seta deixaram de ter a animação da
 * seta a mexer. É na Home na secção da Loja, de Actividades e do Blog».
 * O tema pré-migração tinha-a em qualquer `.sda-btn` com `.sda-btn__arrow`
 * (components.css, 2b62d18); a migração trouxe o `.botao-lista` sem regra
 * de hover para a seta, e a Fase 101 deixou os botões de fora de
 * propósito porque o cliente falava das setas «que não são de botões».
 *
 * Os 7px vêm da maqueta (XD, componente «Botão Ver Todos», mostrado pelo
 * Francisco a 2026-09-10): no estado padrão a seta está a 157px da
 * esquerda com 34 de folga à direita; no estado hover a 164 e 27. Só a
 * seta muda — o texto fica no sítio — e a interacção é «passar o mouse →
 * transição». Os outros CTA com seta (Fase 101) ficaram a 6px por não
 * haver medida; se o desenho lhes der também 7, é aqui que se acerta. */
.botao-lista img {
	transition: transform 0.25s ease;
}

.botao-lista:hover img,
.botao-lista:focus-visible img {
	transform: translateX( 7px );
}

@media ( prefers-reduced-motion: reduce ) {

	.botao-lista img {
		transition: none;
		transform: none !important;
	}
}

/* Coluna lateral do curso alinhada com o título «Sobre o curso».
 *
 * Raquel, sobre o Tarot: «o botão também fica colado à imagem da secção
 * seguinte? Sugiro alinhar a barra com o título». Medido: o desenho põe a
 * coluna 107px abaixo do topo do corpo (`.curso-sidebar-coluna { top: 107px }`),
 * e como a margem do «Sobre o curso» colapsa através do `.curso-corpo`, o
 * topo do corpo É o topo do título — a coluna nascia 107px abaixo dele.
 * No Tarot, cujo «Sobre o curso» tem 441px em vez de 765, a coluna de
 * 681px em repouso acabava 13px DENTRO da imagem do «Como funciona»; na
 * Astrologia sobravam 307px. Subir a coluna resolve as duas coisas de uma
 * vez: fica alinhada com o título e ganha esses 107px de folga em baixo.
 * Os 17px são alinhamento óptico, tinta com tinta, e não caixa com caixa:
 * a linha da Raquel está no topo das letras do título. Medido pelas
 * métricas das fontes, com as caixas ao mesmo nível a tinta de «DATA DE
 * INÍCIO» (Nunito 22) ficava 17px acima da de «Sobre o curso» (HV
 * Simplicite 78/96, que leva 9px de meia-entrelinha e um ascendente
 * alto). Só em desktop e tablet: a ≤430 o refluxo põe a coluna em fluxo. */
@media ( min-width: 431px ) {

	.curso-sidebar-coluna {
		top: 17px;
	}
}

/* ============================================================
 * Fase 104 — FAQ com o conteúdo real do cliente (2026-09-15)
 * ============================================================ */

/* O contentor do FAQ cresce com o separador activo.
 *
 * O espelho fixa `.faq-conteudo { height: 1458px }` e põe o acordeão em
 * `position: absolute`, o que servia os 6 acordeões de Lorem ipsum da
 * maqueta. Com as 57 perguntas do cliente, o separador da Loja tem 15 e mede
 * 2014px: entrava 556px pela newsletter adentro. O acordeão volta ao fluxo,
 * na mesma coluna (433,5px de recuo, 967px de largura), e os 1458px ficam
 * como altura mínima, para uma categoria curta manter o desenho. O menu
 * lateral continua absoluto. A ≤430 o refluxo já tratava disto. */
@media ( min-width: 431px ) {

	.faq-conteudo {
		height: auto;
		min-height: 1458px;
	}

	.faq-conteudo .seccao-inner {
		height: auto;
	}

	.faq-conteudo .accordion-faq {
		position: relative;
		top: auto;
		left: auto;
		margin-left: 433.5px;
	}
}

/* As perguntas do FAQ quebram linha em vez de serem cortadas.
 *
 * O espelho põe o rótulo em `white-space: nowrap` com reticências, o que
 * servia o «Lorem ipsum dolor sit amet» da maqueta. Com as perguntas reais,
 * 5 das 57 ficavam cortadas em desktop — «Os produtos estão em stock? O que
 * acontece se um produto…» —, escondendo texto do cliente. A largura máxima
 * de 900px mantém-se e deixa espaço ao ícone, que já está centrado na
 * vertical (ver acima), por isso um rótulo de duas linhas continua alinhado.
 * Em mobile já quebrava. */
@media ( min-width: 431px ) {

	.accordion-faq-rotulo {
		white-space: normal;
		overflow: visible;
		text-overflow: clip;
	}
}

/* ============================================================
 * Fase 105 — newsletter com país e distrito (2026-09-16)
 * ============================================================ */

/* Pedido do cliente: primeiro e último nome na mesma linha, e país e
 * distrito na mesma linha, com selects. A secção mantém a altura: as cinco
 * linhas do desenho (325, 396, 467, 538, 609 em desktop; 214, 272, 330, 388,
 * 456 em mobile) continuam cinco — os dois nomes partilham a primeira, o
 * email passa à segunda e o país e o distrito ocupam a terceira. O intervalo
 * entre os dois campos de uma linha é 14px em desktop e 10px em mobile.
 * O `<form>` é estático: os campos continuam absolutos contra o
 * `.seccao-inner`, como antes de existir formulário. */

.seccao-newsletter__hp {
	position: absolute !important;
	left: -9999px !important;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

/* Os selects vestem a caixa branca dos campos e a seta do checkout. */
select.seccao-newsletter__campo {
	-webkit-appearance: none;
	appearance: none;
	padding-right: 44px;
	background: #ffffff url( "../img/loja/checkout-1-seta-dropdown.svg" ) no-repeat right 20px center / 18px 9px;
	text-overflow: ellipsis;
	white-space: nowrap;
	cursor: pointer;
}

select.seccao-newsletter__campo:disabled {
	cursor: default;
	opacity: 0.75;
}

.seccao-newsletter__campo:focus-visible {
	outline: 2px solid #ffffff;
	outline-offset: 3px;
}

p.seccao-newsletter__estado {
	position: absolute;
	margin: 0;
	text-align: center;
	color: #ffffff;
}

p.seccao-newsletter__estado:empty {
	display: none;
}

@media ( min-width: 431px ) {

	.seccao-newsletter__campo--nome {
		width: 213.5px;
	}

	.seccao-newsletter__campo--apelido {
		left: 707px;
		top: 325px;
		width: 213.5px;
	}

	.seccao-newsletter__campo--email {
		top: 396px;
	}

	.seccao-newsletter__campo--pais {
		top: 467px;
		width: 213.5px;
	}

	.seccao-newsletter__campo--distrito {
		left: 707px;
		top: 467px;
		width: 213.5px;
	}

	p.seccao-newsletter__estado {
		left: 479.5px;
		top: 650px;
		width: 441px;
		font: 400 16px/24px var( --fonte-corpo );
	}
}

@media ( max-width: 430px ) {

	.seccao-newsletter__campo--nome {
		width: 167px;
	}

	.seccao-newsletter__campo--apelido {
		left: 201px;
		top: 214px;
		width: 167px;
	}

	.seccao-newsletter__campo--email {
		top: 272px;
	}

	.seccao-newsletter__campo--pais {
		top: 330px;
		width: 167px;
	}

	.seccao-newsletter__campo--distrito {
		left: 201px;
		top: 330px;
		width: 167px;
	}

	select.seccao-newsletter__campo {
		padding-right: 36px;
		background-position: right 14px center;
		background-size: 14px 7px;
	}

	p.seccao-newsletter__estado {
		left: 24px;
		top: 492px;
		width: 344px;
		font: 400 14px/20px var( --fonte-corpo );
	}
}

/* ------------------------------------------------------------
 * Próximas Actividades sem actividades — a ligação desce até à newsletter
 * (fase 113, item 8)
 * ------------------------------------------------------------
 *
 * Pedido do Francisco: a ligação «Assine a nossa newsletter» da mensagem
 * desce até à secção global da newsletter, no fim da página (main.js,
 * initNewsletterAncora). O formulário que se abria por baixo da mensagem,
 * com a revelação da Fase 110, saiu, e com ele o invólucro e as regras do
 * formulário (o código ficou no commit c7ac6e9, para o caso de voltar).
 *
 * A mensagem volta a ser filha directa da secção, como no desenho
 * (atividades-sem-proximas-atividades.png): no computador o main.css
 * (.proximas-actividades__mensagem) já a põe no sítio, a 255px do topo e
 * com 643px de largura. No telemóvel, o refluxo deixa-lhe só os 16px do
 * `p` por baixo; os 48px dão à secção os mesmos 504px que tinha com o
 * formulário fechado (são os 16px do `p` mais os 32px que o invólucro
 * levava). (0,3,1) para vencer o `p` do refluxo, que tem (0,2,2).
 */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .proximas-actividades__mensagem {
		margin-bottom: 48px;
	}
}

/* A secção da newsletter fica logo abaixo do cabeçalho colado quando se
 * chega a ela pela âncora: no deslize do main.js, no salto sem JavaScript
 * e no regresso depois de subscrever (?sda_newsletter=…#newsletter, em
 * qualquer página). O cabeçalho mede 100px no canvas acima de 430px e 64px
 * abaixo, e o zoom do canvas escala as duas medidas por igual (75px a
 * 1440, 62,5px a 1024, 64px a 390). Sem folga, ao contrário da âncora
 * #produtos da loja (cabeçalho mais 24px): aqui a secção é um fundo rosa
 * de ponta a ponta e o título já fica bem abaixo do topo dela. A secção
 * está fora do .site-content, por isso o refluxo não lhe toca. */
.seccao-newsletter {
	scroll-margin-top: 100px;
}

@media (max-width: 430px) {
	.seccao-newsletter {
		scroll-margin-top: 64px;
	}
}

/* ------------------------------------------------------------
 * TOPO DOS CURSOS, DAS ACTIVIDADES E DAS TERAPIAS EM FLUXO
 * (só acima de 430px)
 *
 * O main.css põe o título, o subtítulo, a meta, o parágrafo e o botão
 * do topo em posições absolutas, calculadas para um título de duas
 * linhas. Desde que o título vem dos campos, deixou de ter sempre duas:
 * «Retiro Terapêutico de Reiki» e «Workshop de Constelação Familiar»
 * partem em três e o título ficava por cima do subtítulo e da meta;
 * «Palestra Anual» cabe numa e deixava um buraco de uma linha.
 *
 * Aqui o conteúdo de texto passa a estar em fluxo, pela ordem do HTML,
 * e cada elemento fica à distância do anterior que o desenho lhe dá
 * com um título de duas linhas. As referências são o Curso de
 * Astrologia e a Consulta de Astrologia, que ficam iguais ao píxel;
 * cada margem abaixo é a diferença entre dois `top` do main.css e vem
 * com a conta ao lado. Um título de uma linha sobe o resto, um de três
 * empurra-o.
 *
 * A imagem e a flor continuam absolutas, onde estavam, e o símbolo
 * pequeno também (continua ancorado ao conteúdo, no mesmo sítio). A
 * secção passa de altura fixa a altura mínima, para crescer quando o
 * texto desce mais do que a imagem.
 *
 * Os valores próprios do Tarot no main.css (`.pagina-curso-tarot-1/-2`
 * ~l.1901 e `.pagina-terapia-tarot` ~l.7227) só mexem em `top`, e com
 * `position: static` deixam de ter efeito. No curso existiam porque o
 * título do Tarot tem uma linha e as posições absolutas não subiam
 * sozinhas; em fluxo isso é automático. Na consulta o título do Tarot
 * tem duas linhas, como o da Astrologia, e o desenho punha o resto 7px
 * mais abaixo (o botão 4px); fica com o ritmo da Consulta de Astrologia,
 * como qualquer outra consulta. Não os apago do main.css porque esse
 * ficheiro acompanha 1:1 o tema de referência.
 *
 * No telemóvel (≤430px) o refluxo genérico já põe tudo em fluxo, com
 * regras próprias, e não lhe toco. `screen` para não interferir com o
 * bloco de impressão.
 * ------------------------------------------------------------ */
@media screen and (min-width: 430.02px) {
	/* Curso e actividade (template-parts/curso/hero.php).
	   Os selectores levam `.curso-hero` à frente para vencer
	   `.curso-hero p, .curso-hero h1 { margin: 0 }` (0,1,1). */

	/* 974px é a altura do desenho, que continua a ser o mínimo. */
	.curso-hero {
		height: auto;
		min-height: 974px;
	}

	/* O afastamento do topo, que era o `top: 118px` do conteúdo, passa a
	   padding do contentor, para contar na altura da secção. A imagem é
	   absoluta e mede o seu `top: 70px` da caixa de padding, por isso não
	   se mexe. Os 126px de baixo são o que o desenho deixa entre o fim do
	   botão e o fim da secção no Curso de Astrologia (974 − 118 − 730):
	   com o texto dele, a secção dá outra vez 974. */
	.curso-hero > .seccao-inner {
		padding-top: 118px;
		padding-bottom: 126px;
	}

	/* Continua posicionado para o símbolo pequeno se medir dele, como
	   antes; o `top` passou para o padding acima. */
	.curso-hero .curso-hero__conteudo {
		position: relative;
		top: 0;
		height: auto;
	}

	.curso-hero .curso-hero__titulo,
	.curso-hero .curso-hero__subtitulo,
	.curso-hero .curso-hero__meta,
	.curso-hero .curso-hero__paragrafo,
	.curso-hero .curso-hero__botao {
		position: static;
	}

	/* 170 − 192 (duas linhas de 96): a caixa de 96px do subtítulo entra
	   pela do título, como no desenho. */
	.curso-hero .curso-hero__subtitulo {
		margin-top: -22px;
	}

	/* 280 − (170 + 96). A faixa mantém os 141px do desenho, mas a data e o
	   formato ficam centrados entre os dois separadores, com o mesmo espaço
	   por cima e por baixo (fase 113, item 10, decisão do Francisco). Os
	   141px vinham de um formato em duas linhas no Figma, e com o formato
	   numa só linha (é uma lista fechada: Presencial, Online, Online e
	   Presencial) o `padding: 18px 0 11px` deixava 19px de tinta por cima e
	   45 por baixo.
	   O que se vê de cima e de baixo são os ícones: cada um ocupa 1px a
	   31px da sua linha de 36 (a relação do Figma, abaixo), com 1px livre
	   por cima e 5 por baixo. Por isso o padding de cima leva mais 4px do
	   que o de baixo: com os itens centrados no que sobra (141 − 2 de
	   bordas − 22 de padding = 117), ficam 36,5px entre o separador e o
	   ícone da data e 36,5 entre o ícone do formato e o separador de
	   baixo, e o mesmo ao meio com um item só. O padding só manda quando o
	   texto passa os 117px (quatro linhas ou mais): aí a faixa cresce,
	   com 14px de cada lado, em vez de o texto atravessar o separador de
	   baixo. O parágrafo e o botão não se mexem, porque a altura não muda. */
	.curso-hero .curso-hero__meta {
		display: flex;
		flex-direction: column;
		justify-content: center;
		height: auto;
		min-height: 141px;
		margin-top: 14px;
		padding: 13px 0 9px;
	}

	/* Cada item passa a uma linha em fluxo e o ícone mede-se do seu item.
	   1px é o `top` da data no main.css (19) menos o início do item (18),
	   a relação que o Figma dá ao ícone com a primeira linha do texto. O
	   formato usa o mesmo: os 10px que tinha (64 − 54) eram do formato em
	   duas linhas, e com uma só deixavam o ícone 7px abaixo do texto. */
	.curso-hero .curso-hero__meta-item {
		position: relative;
		display: block;
	}

	.curso-hero .curso-hero__meta-texto {
		position: static;
		display: block;
		margin-left: 44px;
	}

	.curso-hero .curso-hero__meta-item--data .curso-hero__meta-icone,
	.curso-hero .curso-hero__meta-item--formato .curso-hero__meta-icone {
		top: 1px;
	}

	/* 441 − (280 + 141). */
	.curso-hero .curso-hero__paragrafo {
		margin-top: 20px;
	}

	/* 669 − (441 + 160): o botão vai logo a seguir ao parágrafo. Passa a
	   caixa de bloco (flex, como o inline-flex do botão) para não ficar
	   numa linha de texto cuja altura dependesse da fonte do contentor. */
	.curso-hero .curso-hero__botao {
		display: flex;
		margin-top: 68px;
	}

	/* Consulta (single-sda_terapia.php). Mesma lógica, com os números da
	   Consulta de Astrologia. */
	.terapia-hero {
		height: auto;
		min-height: 974px;
	}

	/* 151px é o `top` do conteúdo no desenho. Em baixo uso o mesmo chão do
	   curso (126px): as duas secções têm a mesma imagem no mesmo sítio, e
	   o texto pode descer até 3px abaixo dela antes de a secção crescer.
	   Com o texto da Consulta de Astrologia sobram 101px e fica nos 974. */
	.terapia-hero > .seccao-inner {
		padding-top: 151px;
		padding-bottom: 126px;
	}

	.terapia-hero .terapia-hero__conteudo {
		position: relative;
		top: 0;
		height: auto;
	}

	.terapia-hero .terapia-hero__titulo,
	.terapia-hero .terapia-hero__subtitulo,
	.terapia-hero .terapia-hero__meta,
	.terapia-hero .terapia-hero__paragrafo,
	.terapia-hero .terapia-hero__botao {
		position: static;
	}

	/* 165 − 192. */
	.terapia-hero .terapia-hero__subtitulo {
		margin-top: -27px;
	}

	/* 273 − (165 + 96). A faixa continua uma linha flex centrada e os 71px
	   passam a mínimo. Os 15px por cima e por baixo só contam quando um
	   texto partir em duas linhas; com uma, a soma (36 + 30 + 2) fica
	   abaixo dos 71 e manda o mínimo. Não os igualo aos 16,5 que dariam
	   71 certos: com o `zoom` das larguras intermédias as bordas
	   arredondam para 1px inteiro e a faixa crescia meio píxel. */
	.terapia-hero .terapia-hero__meta {
		height: auto;
		min-height: 71px;
		margin-top: 12px;
		padding: 15px 0;
	}

	/* 370 − (273 + 71). */
	.terapia-hero .terapia-hero__paragrafo {
		margin-top: 26px;
	}

	/* 535 − (370 + 120). */
	.terapia-hero .terapia-hero__botao {
		display: flex;
		margin-top: 45px;
	}
}

/* ------------------------------------------------------------
 * Próximas Actividades com várias actividades, e o excerto do cartão
 * da home no telemóvel (2026-09-30)
 * ------------------------------------------------------------
 *
 * Com o interruptor «Mostrar na página Actividades», a secção pode ter mais
 * do que a Palestra Anual. Uma actividade mantém o desenho (cartão absoluto
 * a 255px, flor à direita, 1073px de altura). Várias usam a escadinha da
 * lista dos cursos: cada par é uma `.actividades-lista` (890px, os cartões
 * `--astrologia`/`--tarot` nas posições do desenho), em fluxo a partir dos
 * mesmos 255px, e a secção cresce com elas. Em baixo, 86px somados à folga
 * da última linha dão os 168px entre o cartão e o fim da secção do desenho.
 */
@media screen and (min-width: 430.02px) {
	.proximas-actividades--varias {
		height: auto;
	}

	.proximas-actividades--varias > .seccao-inner {
		padding-top: 255px;
		padding-bottom: 86px;
	}
}

/* O cartão de curso da home no telemóvel só tem lugar para 4 linhas de
   texto. O resumo curto que existia para isso saiu com os campos do cartão
   (o texto é agora a introdução do curso): o corte faz-se aqui, com
   reticências. */
@media (max-width: 430px) {
	.pagina-home-final .home-actividades-card .home-actividades-card__excerto--mobile {
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: 4;
		line-clamp: 4;
		overflow: hidden;
	}
}

/* Avaliações do Google (Fase 111): as estrelas seguem a nota.
   As duas imagens trazem cinco estrelas; com menos, corta-se à direita.
   Cartão: estrelas de 17,475 com passo de 19,064 numa imagem de 93,73, e cada
   estrela a menos tira 20,34%. Nota média: estrelas de 22 com passo de 21,188
   numa imagem de 106,751, arredondada à meia estrela no template. */
.seccao-testemunhos__estrelas--4 { clip-path: inset(0 20.34% 0 0); }
.seccao-testemunhos__estrelas--3 { clip-path: inset(0 40.68% 0 0); }
.seccao-testemunhos__estrelas--2 { clip-path: inset(0 61.02% 0 0); }
.seccao-testemunhos__estrelas--1 { clip-path: inset(0 81.36% 0 0); }

.seccao-testemunhos__avaliacoes-estrelas--45 { clip-path: inset(0 10.3% 0 0); }
.seccao-testemunhos__avaliacoes-estrelas--40 { clip-path: inset(0 19.85% 0 0); }
.seccao-testemunhos__avaliacoes-estrelas--35 { clip-path: inset(0 30.15% 0 0); }
.seccao-testemunhos__avaliacoes-estrelas--30 { clip-path: inset(0 39.69% 0 0); }
.seccao-testemunhos__avaliacoes-estrelas--25 { clip-path: inset(0 50% 0 0); }
.seccao-testemunhos__avaliacoes-estrelas--20 { clip-path: inset(0 59.54% 0 0); }
.seccao-testemunhos__avaliacoes-estrelas--15 { clip-path: inset(0 69.85% 0 0); }
.seccao-testemunhos__avaliacoes-estrelas--10 { clip-path: inset(0 79.39% 0 0); }

/* Avaliações do Google (Fase 111): o logótipo segue a data.
   No desenho o logótipo tem posição fixa, pensada para «22 de março, 2024
   em»; com os meses compridos a data passava-lhe por cima (até 20px, medido).
   Passa para dentro do parágrafo da data, a 6px do «em», que é a folga do
   desenho, com o topo 1px abaixo do da linha (0,5px no telemóvel). */
.seccao-testemunhos__data {
	display: flex;
	align-items: flex-start;
	gap: 6px;
}

.seccao-testemunhos__data .seccao-testemunhos__google {
	position: static;
	flex: none;
	margin-top: 1px;
}

/* Um nome comprido acaba em reticências, dentro do cartão. */
.seccao-testemunhos__nome {
	max-width: 279px;
	overflow: hidden;
	text-overflow: ellipsis;
}

@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .seccao-testemunhos__data .seccao-testemunhos__google {
		position: static !important;
		margin-top: 0.5px !important;
	}

	.seccao-testemunhos__data .seccao-testemunhos__google {
		margin-top: 0.5px;
	}

	.seccao-testemunhos__nome {
		max-width: 208px;
	}

	/* Nas páginas interiores o refluxo global (`.site-content :not(…)`, com
	   uma dezena de :not) repõe max-width: 100%; vence só com !important. */
	body:not(.pagina-home-final) .site-content .seccao-testemunhos__nome {
		max-width: 208px !important;
	}
}

/* ------------------------------------------------------------
 * Cartões das terapias (página Terapias e página inicial) — título de
 * três linhas.
 *
 * Fase 113, item 7: o título do cartão passou a ser sempre o título do
 * post com «Consulta de» à frente, e o cliente deixou de poder escrever
 * uma versão mais curta. Com um nome comprido («Consulta de Constelação
 * Familiar») o título vai a três linhas e, com o `top` do desenho, descia
 * por cima do parágrafo (medido a 1440: o título acabava nos 562px e o
 * parágrafo começava nos 549).
 *
 * O título passa a medir-se de baixo: o fundo fica onde fica o de um
 * título de duas linhas (124px = 2 × 62 abaixo do `top` do desenho, 0 na
 * Astrologia e 100 no Tarot) e a altura mínima é de duas linhas. Com uma
 * ou duas linhas a caixa começa no mesmo `top` de antes, e o texto no
 * mesmo sítio (capturas iguais ao byte no Chromium; no WebKit a 1280 o
 * texto difere 0,016px, que não se vê); a partir da terceira, o título
 * cresce para cima, para o espaço livre por cima do cartão, e o
 * parágrafo e o botão não se mexem.
 *
 * Tentei antes `translate` com `2lh`, mas o WebKit resolve o `lh` com o
 * `zoom` das larguras intermédias trocado e mexia meio píxel nos títulos
 * de duas linhas a 1024. Os selectores levam a tag para vencer os do
 * main.css (`h2.terapias-lista__titulo--…`, l.7183) e os de cima
 * (`h3.terapias-lista__titulo--…`). No telemóvel (≤430px) os cartões
 * estão em fluxo e não lhes toco.
 * ------------------------------------------------------------ */
@media screen and (min-width: 430.02px) {
	h2.terapias-lista__titulo,
	h3.terapias-lista__titulo {
		min-height: 124px;
	}

	h2.terapias-lista__titulo--astrologia,
	h3.terapias-lista__titulo--astrologia {
		top: auto;
		bottom: calc(100% - 124px);
	}

	h2.terapias-lista__titulo--tarot,
	h3.terapias-lista__titulo--tarot {
		top: auto;
		bottom: calc(100% - 224px);
	}
}

/* ------------------------------------------------------------
 * Formulário de inscrição — cursos em lista de espera.
 *
 * Fase 113, item 16. Os cursos e as actividades em lista de espera vão
 * para o fim do selector, num grupo «Lista de espera», e por baixo do
 * selector aparece uma frase curta quando a opção escolhida não bate com
 * o título da página (template-parts/formulario-pedido.php e
 * initFormularioEspera, em main.js). A frase só existe quando há opções
 * em lista de espera; vazia, não ocupa lugar.
 *
 * Acima de 430px fica no intervalo de 47px entre o selector e a Mensagem,
 * fora do fluxo da grelha, para a troca não mexer em nada à volta (os
 * campos do desenho têm posições fixas). No telemóvel entra em fluxo e
 * empurra só o que está por baixo do selector, nunca o selector.
 * ------------------------------------------------------------ */
.seccao-formulario__nota {
	display: block;
	margin: 8px 0 0;
	font: 400 18px/26px var(--fonte-corpo);
	letter-spacing: 0;
	text-transform: none;
	color: var(--cor-texto);
}

.seccao-formulario__nota:empty {
	margin: 0;
}

@media screen and (min-width: 430.02px) {
	.seccao-formulario__campo--curso {
		position: relative;
	}

	.seccao-formulario__nota {
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
	}
}

/* O rótulo do grupo na lista aberta do selector, como as opções
   (que o main.css não põe em maiúsculas), em vez das maiúsculas do campo. */
.seccao-formulario__campo select optgroup {
	font-style: normal;
	text-transform: none;
	color: var(--cor-texto);
}

/* Subtítulo do topo do formulário (Inscrição e Marcação) no telemóvel,
   com o recuo dos campos. A secção do topo não tem `.seccao-inner` e o
   refluxo deixa o subtítulo a toda a largura, sem padding: medido a 390,
   o texto ia de 5 a 385px, com os campos a 23. Na Inscrição só aparece
   com um curso em lista de espera (o subtítulo normal está vazio), e foi
   assim que se deu por ele; na Marcação ficava a 10px. O título, centrado
   e com letra grande, já fica a 22px das bordas e não lhe toco. */
@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .inscricao-intro__subtitulo {
		box-sizing: border-box;
		padding-left: 23px;
		padding-right: 23px;
	}
}

/* ------------------------------------------------------------
 * Banners da palestra (Quem Somos e cartão da coluna do blog) —
 * outra actividade e título com ligação.
 *
 * Fase 113, item 5. Sem a Palestra Anual publicada, os dois banners
 * anunciam a próxima actividade, com o título dela (sda_banner_dados(),
 * inc/campos/area-listagens.php). O desenho só prevê «PALESTRA ANUAL»
 * numa linha, em nowrap e com posições absolutas, e um título comprido
 * saía do banner: em Quem Somos, «Palestra: O Mapa Astral como Espelho
 * da Alma» chegava aos 1902px de 1920, e no cartão da coluna até
 * «Workshop de Constelação Familiar» se cortava nas duas margens.
 *
 * Quando o título passa do que cabe numa linha (25 caracteres em Quem
 * Somos, 14 na coluna), o PHP junta o modificador --longo. O título
 * parte, fica mais pequeno e cresce para cima a partir do fundo da linha
 * do desenho, para o orador, a data e o botão ficarem onde estão: o
 * bottom é a altura do banner menos o top e a altura da linha (700 − 160
 * − 90 = 450 em Quem Somos, 484 − 89 − 48 = 347 na coluna). O
 * text-wrap: balance evita uma palavra sozinha na última linha; quem não
 * o conhece parte como sempre. Sem o modificador nada muda, e a Palestra
 * Anual fica igual ao píxel.
 *
 * Na coluna, contar caracteres não chega. O limite começou nos 16, mas
 * com letras largas 15 e 16 caracteres já não cabem a 42px em nowrap
 * («Workshop Mandala» mede 414px e «Workshop de Yoga» 403px, nos 399 do
 * cartão, e o overflow cortava-os à direita) e, mesmo sem corte,
 * «Meditação Mensal» ficava a 6px das bordas, contra os 34 do desenho.
 * Baixei o limite para 14, o comprimento de «Palestra anual», e o título
 * da coluna passou a partir sempre, com ou sem modificador, dentro de
 * 351px (24px de cada lado), medido de baixo como o --longo. Assim um
 * título de 14 com letras largas («Workshop Tarot», 365px) parte em duas
 * linhas a 42px em vez de chegar às bordas. «Palestra anual» mede 330px,
 * cabe numa linha e fica centrada no mesmo sítio (34,3px de cada lado),
 * igual ao píxel. Em Quem Somos o limite de 25 chega: «Workshop de
 * Mandalas Mãe» (24) acaba nos 1368 dos 1920.
 *
 * Com títulos ainda mais compridos (mais de 48 caracteres na coluna, mais
 * de 90 em Quem Somos) entra também o --muito-longo, que desce outra vez a
 * letra. Medi no DOM: na coluna, a 30px, 55 caracteres cabem em três
 * linhas (topo a 28) e 64 já pediam quatro, com o topo 8px acima do
 * cartão, cortado pelo overflow. Preferi descer a letra a cortar o título
 * com reticências (-webkit-line-clamp), que também cortava a sombra do
 * texto nas bordas da caixa.
 *
 * No telemóvel o refluxo já parte o título; aqui só desce a letra, para
 * um título comprido não ocupar quatro linhas. As regras têm uma classe
 * a mais do que as da hierarquia de tamanhos (R38 e a da coluna), para
 * ganharem sem !important.
 *
 * O título passa a levar à página da actividade (fase 113, item 9), sem
 * mudar de aspecto: herda a cor e só se sublinha com o rato por cima,
 * como os títulos dos artigos na página inicial (o hover fica dentro de
 * (hover: hover) para o sublinhado não ficar preso depois de um toque).
 * O foco é o da regra geral, `.site-content a:focus-visible`.
 * ------------------------------------------------------------ */
.qs-palestra__titulo-ligacao,
.seccao-sidebar__palestra-titulo-ligacao {
	color: inherit;
	text-decoration: none;
	text-underline-offset: 0.12em;
}

@media (hover: hover) {
	.qs-palestra__titulo-ligacao:hover,
	.seccao-sidebar__palestra-titulo-ligacao:hover {
		text-decoration-line: underline;
	}
}

@media screen and (min-width: 430.02px) {
	.qs-palestra__titulo--longo {
		top: auto;
		bottom: 450px;
		width: 1100px;
		white-space: normal;
		font-size: 56px;
		line-height: 64px;
		text-wrap: balance;
	}

	.seccao-sidebar__palestra-titulo {
		top: auto;
		bottom: 347px;
		left: 24px;
		width: 351px;
		white-space: normal;
		text-wrap: balance;
	}

	.seccao-sidebar__palestra-titulo--longo {
		font-size: 30px;
		line-height: 36px;
		letter-spacing: -0.6px;
	}

	.qs-palestra__titulo--muito-longo {
		font-size: 44px;
		line-height: 52px;
	}

	.seccao-sidebar__palestra-titulo--muito-longo {
		font-size: 24px;
		line-height: 30px;
		letter-spacing: -0.48px;
	}
}

@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .qs-palestra__titulo.qs-palestra__titulo--longo {
		font-size: 30px;
		line-height: 38px;
		text-wrap: balance;
	}

	body:not(.pagina-home-final) .site-content .seccao-sidebar__palestra-titulo.seccao-sidebar__palestra-titulo--longo {
		font-size: 26px;
		line-height: 34px;
		text-wrap: balance;
	}
}

/* ------------------------------------------------------------
 * Títulos dos cartões com ligação (fase 113, item 9)
 * ------------------------------------------------------------
 *
 * Pedido do Francisco: os cartões dos cursos e das actividades (página
 * Actividades e página inicial) e os das terapias (página Terapias e
 * página inicial) abrem também pelo título e pela fotografia, e não só
 * pelo «Saber mais». O título fica igual ao desenho: a ligação herda a
 * cor, a letra e as maiúsculas do título e só se sublinha com o rato por
 * cima, como os títulos dos artigos na página inicial e o do banner da
 * palestra (mais acima). O hover vive dentro de (hover: hover), para o
 * sublinhado não ficar preso depois de um toque. O foco é o da regra
 * geral, `.site-content a:focus-visible`.
 *
 * As ligações das fotografias são inline e não levam regra: as imagens
 * continuam posicionadas pelo cartão ou pela secção, como antes. Ficam
 * fora do teclado (tabindex -1) e dos leitores de ecrã (aria-hidden).
 * ------------------------------------------------------------ */
.card-actividade__titulo-ligacao,
.home-actividades-card__titulo-ligacao,
.terapias-lista__titulo-ligacao {
	color: inherit;
	text-decoration: none;
	text-underline-offset: 0.12em;
}

@media (hover: hover) {
	.card-actividade__titulo-ligacao:hover,
	.home-actividades-card__titulo-ligacao:hover,
	.terapias-lista__titulo-ligacao:hover {
		text-decoration-line: underline;
	}
}

/* ------------------------------------------------------------
 * Botão dos slides da página inicial e atalhos editáveis
 * (fase 113, itens 1 e 2)
 * ------------------------------------------------------------
 *
 * Cada slide do topo pode levar um botão por baixo da frase. A caixa
 * .home-hero__promessa passou a <div> com a frase e o botão dentro: a frase
 * fica onde estava (herda o tipo e a posição da caixa) e o botão cresce a
 * caixa para baixo, centrado com a frase. É o secundário da Raquel, «aquele
 * que tem o fundo branco com as letras roxas» (como o do mapa dos
 * Contactos, mais acima): o contorno transparente perdia-se na fotografia.
 * O tipo, a cor, o contorno, o raio e os 61px vêm do .botao-contorno; o
 * :hover e o :focus-visible dele (0,2,0) continuam a enchê-lo de roxo. A
 * sombra da frase é herdada, por isso sai no botão. Os 40px entre a frase e
 * o botão são os do banner da loja (título de 96px e botão 41px abaixo);
 * no telemóvel são os 32px da regra do projecto entre texto e botão, e o
 * botão tem a altura e a letra dos botões da página inicial.
 *
 * Nos atalhos, o ícone é escolhido no painel: o object-fit não o deixa
 * deformar se não for quadrado (no telemóvel o main.css já o tinha). O
 * nome fica numa linha: o painel limita-o a 12 letras, mas há nomes de 12
 * letras largas («Workshop Mãe») em que o nome, o espaço e a seta passam
 * 2px da largura do cartão do meio, e a seta saía 1px fora dele no hover.
 * Por isso, na página inicial, os 38px de reserva à esquerda (que centram o
 * nome, ver «REVISÃO v5, R07», mais acima) passam a um espaçador que
 * encolhe: 26px mais os 12 do gap dão os mesmos 38, e é ele que cede, até
 * 26px, quando o nome é comprido. O nome desvia-se do centro só o que for
 * preciso e tudo fica dentro do cartão. No telemóvel não há seta nem
 * reserva, e o espaçador sai.
 *
 * A página inicial está fora do refluxo de ≤430px, por isso não há
 * !important. O branco é um token novo, porque o main.css não tem nenhum.
 * ------------------------------------------------------------ */
:root {
	--cor-branco: #fff;
}

.home-hero__botao {
	display: flex;
	width: fit-content;
	min-width: 251px;
	max-width: 100%;
	margin: 40px auto 0;
	padding: 0 32px;
	background: var( --cor-branco );
	text-shadow: none;
	white-space: nowrap;
}

/* Um slide só com botão, sem frase: o botão fica onde a frase começaria. */
.home-hero__botao:first-child {
	margin-top: 0;
}

.home-categorias .categoria-card__icone {
	object-fit: contain;
}

.home-categorias .categoria-card__rotulo {
	padding-left: 0;
	white-space: nowrap;
}

.home-categorias .categoria-card__rotulo::before {
	content: "";
	flex: 0 1 26px;
}

@media (max-width: 430px) {

	.pagina-home-final .home-hero__botao {
		height: 50px;
		margin-top: 32px;
		font-size: 16px;
	}

	.pagina-home-final .home-hero__botao:first-child {
		margin-top: 0;
	}

	.pagina-home-final .home-categorias .categoria-card__rotulo::before {
		display: none;
	}
}

/* ------------------------------------------------------------
 * Botão «Ver todas» das Terapias e fundo dos testemunhos no painel
 * (fase 113, itens 3 e 4)
 *
 * O botão das Terapias só existe com mais de duas terapias publicadas
 * (front-page.php). Fica por baixo da introdução, na coluna da direita,
 * como o «Ver Loja» e o «Descobrir»: 54px abaixo da introdução, que acaba
 * nos 209 (101 + três linhas de 36), como na Loja, e 70px acima da
 * fotografia do Tarot. O tamanho, as cores, o hover e a seta que anda vêm
 * das regras do .botao-lista. O z-index é preciso: a lista dos cartões é
 * absoluta, vem depois no DOM e começa nos 289, por isso tapava a metade
 * de baixo do botão e o clique lá não chegava. A altura da secção não muda.
 *
 * No telemóvel o botão fica 33px abaixo da introdução (que acaba nos 226),
 * centrado como os da Loja e das Actividades, e a lista desce 90px para lhe
 * dar lugar: 259 + 50 de botão + 50 até à fotografia da Astrologia, a mesma
 * folga que a Loja tem entre o botão e os produtos. A página inicial está
 * fora do refluxo de ≤430px, por isso não há !important.
 *
 * Nos testemunhos, a fotografia escolhida no painel chega numa variável na
 * própria secção (template-parts/seccao-testemunhos.php), só quando é
 * diferente da do desenho. Esta regra (0,2,0), no fim da folha, ganha às
 * dos modificadores no main.css e no sda-extra.css, também à da página
 * inicial no telemóvel. A folha de impressão continua a tirar o fundo.
 * ------------------------------------------------------------ */
.home-terapias__botao {
	position: absolute;
	left: 1023px;
	top: 263px;
	z-index: 1;
}

@media (max-width: 430px) {

	.pagina-home-final .home-terapias__botao {
		left: 90px;
		top: 259px;
		width: 210px;
	}

	.pagina-home-final .home-terapias--com-botao .home-terapias__lista {
		padding-top: 359px;
	}
}

.seccao-testemunhos.seccao-testemunhos--com-fundo {
	background-image: var( --sda-testemunhos-fundo );
}

/* ------------------------------------------------------------
 * Agregado das avaliações e um só testemunho (fase 113, item 11)
 *
 * O logótipo da Google do agregado passa para dentro do texto
 * («1 crítica no», «100 críticas no»), como o da data nos cartões (Fase
 * 111). Na posição fixa do desenho (331 no computador, 203,6 no telemóvel)
 * só batia com «100 críticas no»: com «1 crítica no» ficava a 37px do
 * texto (28 a 1440, medido no staging a 15-10), e com quatro algarismos
 * passava-lhe por cima. As folgas são as do desenho para «100 críticas
 * no», medidas com a letra do site nos dois motores: o texto começa aos
 * 205 e mede 118,84, e o logótipo começa aos 331 (7,16px); no telemóvel
 * aos 91,4, com 105,64, e o logótipo aos 203,6 (6,57px). O topo do
 * logótipo fica 4px abaixo do da linha (5,5px no telemóvel), como no
 * desenho. Com «100 críticas no» tudo fica onde estava.
 *
 * No telemóvel, nas terapias, nos cursos e nas actividades (refluxo de
 * ≤430px), o espaço entre o cartão e o agregado vinha dos pontos da
 * paginação (24px por cima, 13 de ponto e 48 por baixo). Com um só
 * testemunho não há pontos, e o cartão e o agregado ficavam colados (0px,
 * medido na /tarot/ a 390). Sem paginação, o agregado fica 48px abaixo do
 * cartão, a folga que o desenho dá entre os pontos e o agregado. A página
 * inicial tem o agregado em posição absoluta e não muda.
 * ------------------------------------------------------------ */
.seccao-testemunhos__avaliacoes-texto {
	display: flex;
	align-items: flex-start;
	gap: 7.16px;
}

.seccao-testemunhos__avaliacoes-texto .seccao-testemunhos__avaliacoes-google {
	position: static;
	flex: none;
	margin-top: 4px;
}

@media (max-width: 430px) {

	.seccao-testemunhos__avaliacoes-texto {
		gap: 6.57px;
	}

	.seccao-testemunhos__avaliacoes-texto .seccao-testemunhos__avaliacoes-google {
		margin-top: 5.5px;
	}

	/* O refluxo das páginas interiores põe o logótipo em absoluto com
	   !important (REVISÃO v5, R56); dentro do texto volta ao fluxo. */
	body:not(.pagina-home-final) .site-content .seccao-testemunhos__avaliacoes-texto .seccao-testemunhos__avaliacoes-google {
		position: static !important;
		margin-top: 5.5px !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos--sem-paginacao .seccao-testemunhos__avaliacoes {
		margin-top: 48px;
	}
}

/* ------------------------------------------------------------
 * Testemunhos — anel na fotografia e cartão à medida do texto no
 * telemóvel (decisão do Francisco de 15-10-2026, feita a 19-10)
 *
 * Anel: uma fotografia de fundo branco (a da Ana Costa) perdia-se no
 * creme do cartão. Vai em `box-shadow`, que não mexe no tamanho nem na
 * posição da fotografia.
 *
 * Altura: nas terapias e nos cursos, no telemóvel, o cartão tinha os
 * 399,5px do desenho da home, e com um texto de quatro linhas ficava 37%
 * vazio. O texto passa a fluxo, no mesmo sítio (151px do topo e 33px da
 * esquerda), e o cartão cresce com ele, com 33px por baixo. Os slides
 * ficam sobrepostos na mesma célula de uma grelha: a secção fica com a
 * altura do cartão maior e não salta ao trocar de testemunho (com o
 * `display: none` dos carrosséis em mobile, a secção mudava de altura a
 * cada troca). A página inicial tem desenho mobile próprio, com tudo em absoluto,
 * e fica como está.
 * ------------------------------------------------------------ */
.seccao-testemunhos__foto {
	box-shadow: 0 0 0 1px var(--cor-cinza-claro, #d6d7d9);
}

@media (max-width: 430px) {
	body:not(.pagina-home-final) .site-content .seccao-testemunhos .seccao-inner {
		display: grid !important;
		grid-template-columns: minmax(0, 1fr);
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__slide {
		display: flex;
		grid-area: 1 / 1;
	}

	/* Os escondidos voltam à célula (a regra dos carrosséis em mobile, mais
	   acima, tira-os do fluxo porque ali não havia sobreposição): ficam com
	   a `opacity: 0` de sempre, a secção mede o cartão maior e o crossfade
	   volta a funcionar. Não têm nada focável e levam `aria-hidden`. */
	body:not(.pagina-home-final) .site-content .seccao-testemunhos__slide[aria-hidden="true"] {
		display: flex !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__card {
		flex: 1 1 auto;
		height: auto !important;
		padding-bottom: 33px;
		box-sizing: border-box;
	}

	body:not(.pagina-home-final) .site-content .seccao-testemunhos__texto {
		position: relative !important;
		left: auto !important;
		top: auto !important;
		margin: 151px 0 0 33px !important;
	}
}

/* ------------------------------------------------------------
 * Ficha do produto — a galeria inteira, numa faixa (fase 113, item 14)
 *
 * O template cortava a galeria nas duas miniaturas que o desenho mostra
 * (`array_slice( …, 0, 2 )`) e o CSS só tinha lugar para duas
 * (`.produto-ficha__miniatura--1/--2`, main.css:4763). Passam a ir todas
 * numa faixa com scroll horizontal, que começa pela imagem principal, como
 * no produto.png. No desktop fica no sítio e com o tamanho do desenho:
 * 120x116 com 10px de intervalo, a começar aos 640px de altura e a acabar
 * nos 640 de largura da imagem, por isso cabem cinco à vista. A faixa tem
 * 5px de folga à volta (left -5, top 635) para o anel de foco e o contorno
 * da activa (2px a 3px de distância) não serem cortados pelo overflow; as
 * miniaturas não mudam de sítio.
 *
 * Sem snap: a faixa não é um carrossel, e com snap o JS deixava de poder
 * centrar a miniatura escolhida (o snap puxava-a de volta para o lado). O
 * `scroll-margin-inline` serve o foco do teclado, que não fica debaixo do
 * esbatimento.
 * ------------------------------------------------------------ */
@media (min-width: 431px) {

	.produto-ficha__miniaturas {
		position: absolute;
		left: -5px;
		top: 635px;
		display: flex;
		gap: 10px;
		width: 650px;
		height: 126px;
		box-sizing: border-box;
		padding: 5px;
		overflow-x: auto;
		overflow-y: hidden;
		overscroll-behavior-x: contain;
		scrollbar-width: none;
	}

	.produto-ficha__miniaturas .produto-ficha__miniatura {
		position: static;
		flex: 0 0 120px;
	}
}

.produto-ficha__miniaturas::-webkit-scrollbar {
	display: none;
}

.produto-ficha__miniaturas .produto-ficha__miniatura {
	scroll-margin-inline: 48px;
}

/* Indicação de que há mais fotos: máscara e não degradê de cor, porque o
   fundo é a textura creme (o mesmo padrão dos separadores da ficha). As
   classes vêm do main.js e caem sozinhas quando a faixa chega ao fim. Na
   máscara só conta o alfa, daí `black` e `transparent`. */
.produto-ficha__miniaturas.tem-mais-a-direita {
	-webkit-mask-image: linear-gradient(to right, black 0, black calc(100% - 44px), transparent 100%);
	mask-image: linear-gradient(to right, black 0, black calc(100% - 44px), transparent 100%);
}

.produto-ficha__miniaturas.tem-mais-a-esquerda {
	-webkit-mask-image: linear-gradient(to right, transparent 0, black 44px, black 100%);
	mask-image: linear-gradient(to right, transparent 0, black 44px, black 100%);
}

.produto-ficha__miniaturas.tem-mais-a-esquerda.tem-mais-a-direita {
	-webkit-mask-image: linear-gradient(to right, transparent 0, black 44px, black calc(100% - 44px), transparent 100%);
	mask-image: linear-gradient(to right, transparent 0, black 44px, black calc(100% - 44px), transparent 100%);
}

@media (hover: hover) and (pointer: fine) {

	.produto-ficha__miniaturas.tem-mais-a-direita,
	.produto-ficha__miniaturas.tem-mais-a-esquerda {
		cursor: grab;
	}
}

/* Telemóvel: miniaturas de 100x97 (as do bloco «Galeria e selo da ficha
   do produto em mobile»), três à vista e um pedaço da quarta. A faixa vai
   até às bordas do ecrã, como os separadores da ficha (R112), para o
   corte se ler como corte e não como fim; o padding de 23px mantém a
   primeira miniatura alinhada com a coluna. Os 5px de cima e de baixo são
   a folga do anel de foco: a margem de cima mais o padding dão os 10px que
   as miniaturas já tinham da imagem, e a de baixo devolve os 5 para o
   título continuar a 24px. O refluxo escreve a largura, a altura e as
   margens laterais com especificidade (0,12,1), daí os `!important` só
   nessas. */
@media (max-width: 430px) {

	body:not(.pagina-home-final) .site-content .produto-ficha__miniaturas {
		display: flex;
		gap: 4px;
		width: calc(100% + 46px) !important;
		max-width: none !important;
		height: auto !important;
		margin: 5px -23px -5px !important;
		padding: 5px 23px;
		box-sizing: border-box;
		overflow-x: auto;
		overflow-y: hidden;
		overscroll-behavior-x: contain;
		scroll-padding-inline: 23px;
		scrollbar-width: none;
	}

	body:not(.pagina-home-final) .site-content .produto-ficha__miniaturas .produto-ficha__miniatura {
		flex: 0 0 100px;
		margin: 0;
	}
}

/* ------------------------------------------------------------
 * Paginação compacta da loja e do blog (fase 113, item 15 e acrescentos
 * de 16-10)
 *
 * Os números passam a vir do `sda_paginacao_itens()`: a primeira e a
 * última página, a actual e uma de cada lado, com reticências, mais as
 * setas «anterior» e «seguinte». Ficam em fluxo e centrados, sem posições
 * por número.
 *
 * Loja. A fase 99 passou os números a fluxo (bloco «PAGINAÇÃO — o círculo
 * segue a página actual»), mas a `<nav>` nunca teve posição no main.css: só
 * os filhos eram absolutos. Ficou como único elemento em fluxo com altura
 * no `.seccao-inner` (o form da ordenação também está em fluxo, mas mede
 * 0) e subiu para o topo, por cima do filtro, da contagem e do «Ordenar
 * por». Volta à caixa que os números ocupavam no desenho: top 1713, a
 * coluna da grelha com 1060px de largura. O left é 340 e não os 339 da
 * grelha de propósito, para o grupo «1 2 3 >» cair nos 754/820/886 e na
 * seta aos 975 do desenho. A seta fica a 30px do último número (main.css:
 * 4724), daí os 23px a somar aos 7 do intervalo. O top fixo pressupõe os
 * 9 produtos por página, como a altura fixa da secção (main.css:4572). No
 * telemóvel já estava bem (o refluxo põe tudo em fluxo) e não muda.
 * ------------------------------------------------------------ */
@media (min-width: 431px) {

	.loja-paginacao {
		position: absolute;
		left: 340px;
		top: 1713px;
		width: 1060px;
		height: 59px;
	}

	/* `left` e `top` a auto: o main.css dá à seta `left: 975px; top:
	   1731px` para o absoluto do mock, e em `relative` isso empurrava-a. */
	.loja-paginacao__seta {
		position: relative;
		left: auto;
		top: auto;
		margin-left: 23px;
	}

	.loja-paginacao__seta--anterior {
		margin-left: 0;
		margin-right: 23px;
	}

	/* A seta é só o SVG de 11x22, abaixo do mínimo de 24x24 para um alvo.
	   O alvo cresce para 44x44 sem mexer no desenho; com os 30px até ao
	   número, não chega ao vizinho. */
	.loja-paginacao__seta::after {
		content: "";
		position: absolute;
		left: 50%;
		top: 50%;
		width: 44px;
		height: 44px;
		transform: translate(-50%, -50%);
	}

	/* Blog. O alvo de 44x44 das setas (bloco «A seta de "página seguinte"
	   do blog…») contava com a seta absoluta do mock, mas ela está em
	   fluxo desde o bloco «Blog: paginação em flow», e o alvo ficava
	   centrado na `<nav>` inteira. Medido em /category/terapias/page/2/: o
	   centro do «2» (a página actual) levava à página 3. Com a seta como
	   bloco contentor o alvo volta a ela. No desenho (main.css: números em
	   340, 406 e 472, seta em 561) a seta fica a 30px do último número, como
	   na loja, e não aos 7px entre números: os 23px que faltam vão na
	   margem, e com eles o alvo de 44px já não chega ao número vizinho. */
	.seccao-artigos-paginacao-seguinte,
	.seccao-artigos-paginacao-anterior {
		position: relative;
		left: auto;
		top: auto;
	}

	.seccao-artigos-paginacao-seguinte {
		margin-left: 23px;
	}

	.seccao-artigos-paginacao-anterior {
		margin-right: 23px;
	}
}

/* Reticências do tamanho de um número, para a fila manter o passo do
   desenho (66px no canvas de 1920). Só para quem vê: os leitores de ecrã
   ouvem os números e as setas (aria-hidden no template). */
.loja-paginacao__reticencias,
.seccao-artigos-paginacao-reticencias {
	flex: none;
	width: 59px;
	font: 600 22px/59px var(--fonte-corpo);
	text-align: center;
	color: var(--cor-texto);
	user-select: none;
}

/* A seta «anterior» é o SVG da «seguinte» virado. Com a propriedade
   `scale` e não com `transform`: o hover desloca a seta com `transform`
   e o refluxo do telemóvel escreve `transform: none`, e nenhum dos dois
   desfaz o `scale`. Virada, a deslocação de 6px do hover vai para a
   esquerda, que é para onde a seta aponta. */
.loja-paginacao__seta--anterior img,
.seccao-artigos-paginacao-anterior img {
	scale: -1 1;
}

/* A da loja partilha a classe da «seguinte» e já tem estas medidas
   (main.css:4730) e o movimento do hover (bloco «links com seta»); a do
   blog não. */
.seccao-artigos-paginacao-anterior img {
	display: block;
	width: 11px;
	height: 22px;
	transition: transform 0.25s ease;
}

.seccao-artigos-paginacao-anterior:hover img,
.seccao-artigos-paginacao-anterior:focus-visible img {
	transform: translateX( 6px );
}

@media ( prefers-reduced-motion: reduce ) {

	.seccao-artigos-paginacao-anterior img {
		transition: none;
		transform: none !important;
	}
}

/* Telemóvel. O máximo de itens é nove (duas setas, cinco números e duas
   reticências). Na loja, com alvos de 44px, isso dá 7 x 44 + 2 x 16 =
   340px e só cabe nos 344 sem intervalo; no blog, com 36px, cabe com 6.
   O template marca a fila com `--longa` a partir de sete itens, e só aí o
   intervalo encolhe: com três páginas fica tudo como estava. */
@media (max-width: 430px) {

	body:not(.pagina-home-final) .site-content .loja-paginacao--longa {
		column-gap: 0;
	}

	body:not(.pagina-home-final) .site-content .loja-paginacao__reticencias {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 16px !important;
		height: 44px !important;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-paginacao--longa {
		column-gap: 6px;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-paginacao-anterior {
		display: inline-flex !important;
		align-items: center;
		justify-content: center;
		width: 36px !important;
		height: 36px !important;
		box-sizing: border-box;
	}

	body:not(.pagina-home-final) .site-content .seccao-artigos-paginacao-reticencias {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		width: 16px !important;
		height: 36px !important;
	}
}

/* ------------------------------------------------------------
 * BLOCOS E SEPARADORES SEM LIMITE — só acima de 430px
 * (fase 113, item 6)
 *
 * O painel deixou de pôr máximo ao «Como funciona» da consulta (eram
 * três blocos) e aos separadores da «Estrutura do curso» (eram cinco).
 * No computador o main.css só tinha lugar para o que o desenho mostra:
 * três blocos com `top` fixo e uma secção de 1166px (o 4.º bloco ficava
 * por cima do título «Como funciona»), separadores com `left` fixo até
 * ao `--ano-4` (o 6.º caía em cima de «Próxima edição») e uma linha dos
 * anos com quatro marcos de 220px (o 5.º passava a linha e ia para
 * baixo da coluna lateral). Aqui os três passam a fila, com o passo do
 * desenho, e os números reais ficam como estavam (separadores ao píxel;
 * nas consultas, o título e o texto do último bloco a 1px, porque o
 * próprio desenho não é regular: 47 contra 48).
 *
 * Isto ganha às regras do Tarot no main.css (`.pagina-terapia-tarot …`
 * e `.pagina-curso-tarot-1/-2 …`, 0,2,0) por ter a mesma especificidade
 * e vir depois: o sda-extra.css carrega a seguir ao main.css
 * (inc/enqueue.php, dependência sda-main). Se a ordem mudar, ou se uma
 * regra do Tarot passar para este ficheiro, isto parte. O gap de 78px
 * dos marcos do Tarot continua a vir do main.css.
 *
 * No telemóvel (≤430px) não há nada novo: os blocos já estão em fluxo,
 * os separadores são uma faixa que rola e a linha dos anos reparte-se.
 * `screen` para não interferir com o bloco de impressão.
 * ------------------------------------------------------------ */
@media screen and (min-width: 430.02px) {
	/* Separadores da «Estrutura do curso» numa fila. Os 72px entre eles
	   são o passo do desenho (260 = 188 de «Próxima edição» + 72; 408 =
	   260 + 76 de «1º ano» + 72), e os 1033px são o fim da linha cinzenta
	   (−72 + 1105). Com nomes como «1º ano» cabem seis com este passo (o
	   6.º fica em 852), com «Módulo N» só cinco; a linha e a barra rosa
	   continuam absolutas, medidas do <nav> e de cada separador, como
	   antes. */
	.curso-estrutura nav {
		display: flex;
		column-gap: 72px;
		width: 1033px;
	}

	.curso-estrutura nav .curso-estrutura-tab {
		position: relative;
		left: auto;
		flex: 0 0 auto;
	}

	/* Quando os separadores não cabem com este passo, a fila espalha-se pela
	   largura da linha, com pelo menos 16px entre eles: com nomes curtos
	   («1º ano») cabem dez, com «Módulo N» sete. Quem decide é a largura e
	   não o número: a classe sai do template-parts/curso/estrutura.php por
	   uma estimativa e o main.js (initEstruturaApertada()) mede a fila e
	   acerta-a. A barra rosa de 144px do desenho passava por baixo dos
	   vizinhos; aqui cobre o separador e metade do intervalo mínimo de cada
	   lado, e no último acaba onde acaba a linha. */
	.curso-estrutura--apertada nav {
		column-gap: 16px;
		justify-content: space-between;
	}

	.curso-estrutura--apertada .curso-estrutura-tab:not(.curso-estrutura-tab--proxima)::after {
		width: calc(100% + 16px);
	}

	.curso-estrutura--apertada .curso-estrutura-tab:not(.curso-estrutura-tab--proxima):last-of-type::after {
		left: auto;
		right: 0;
		transform: none;
		width: calc(100% + 8px);
	}

	/* Linha dos anos com qualquer número de marcos. Os marcos ficam
	   centrados na linha de 983px, que é o que o desenho faz nos dois
	   casos que tem: quatro marcos de 220px com 21px entre eles começam
	   em 20 (a regra do main.css) e os dois do Tarot, com 78px, em 233
	   (232,5 centrados). A partir de cinco encolhem por igual dentro da
	   linha. O círculo fica ao meio do marco (98 = 110 − 12 com 220px). */
	.curso-tabs-anos .curso-tabs-anos__lista {
		left: 0;
		width: 983px;
		justify-content: center;
	}

	.curso-tabs-anos .curso-tabs-anos__lista > li {
		flex: 0 1 220px;
		min-width: 0;
	}

	.curso-tabs-anos .curso-tabs-anos__tab,
	.curso-tabs-anos .curso-tabs-anos__rotulo {
		width: 100%;
	}

	.curso-tabs-anos .curso-tabs-anos__circulo {
		left: calc(50% - 12px);
	}

	/* «Como funciona» da consulta em fluxo: cada bloco é uma fila com o
	   separador por cima, o título à esquerda e o texto à direita, como
	   as três do desenho, e o botão vai a seguir ao último texto. As
	   margens saem dos `top` do main.css (Consulta de Astrologia):
	   49 = 145 − 96 da caixa do título da secção; 67 e 47 são os `top`
	   do texto no 1.º e nos outros blocos; −31 = 36 − 67 põe a caixa de
	   96px do título ao nível da 1.ª linha do texto; 46 = 403 − (145 + 1
	   + 67 + 144) e 50 o resto entre blocos; 52 = 1105 − (861 + 1 + 47 +
	   144) até ao botão. 588 + 112 + 700 e os 75px de padding repõem os
	   `left` de 75 e 775 dentro dos 1544px do separador. */
	.terapia-como-funciona,
	.pagina-terapia-tarot .terapia-como-funciona {
		height: auto;
	}

	.terapia-como-funciona .terapia-como-funciona__titulo {
		position: static;
	}

	.terapia-como-funciona .terapia-como-funciona__item {
		position: relative;
		top: auto;
		display: grid;
		grid-template-columns: 588px 700px;
		column-gap: 112px;
		align-items: start;
		box-sizing: border-box;
		padding: 47px 0 50px 75px;
	}

	.terapia-como-funciona .terapia-como-funciona__item:first-of-type {
		margin-top: 49px;
		padding-top: 67px;
		padding-bottom: 46px;
	}

	.terapia-como-funciona .terapia-como-funciona__item:last-of-type {
		padding-bottom: 0;
	}

	.terapia-como-funciona .terapia-como-funciona__item-titulo,
	.terapia-como-funciona .terapia-como-funciona__item-texto {
		position: static;
		width: auto;
	}

	.terapia-como-funciona .terapia-como-funciona__item-titulo {
		margin-top: -31px;
	}

	.terapia-como-funciona .terapia-como-funciona__botao,
	.pagina-terapia-tarot .terapia-como-funciona__botao {
		position: static;
		display: flex;
		margin: 52px 0 0 700px;
	}
}

/* ------------------------------------------------------------
 * Artigo — título em duas linhas no computador (decisão do Francisco de
 * 19-10-2026)
 *
 * O desenho tem o título numa linha (`nowrap`, main.css:3415) numa caixa de
 * 1400px e de altura fixa, com o autor e a data em absoluto aos 270px. Com
 * os títulos verdadeiros, 31 dos 337 artigos passavam a caixa e 5 saíam da
 * janela a 1920. O título passa a fluxo e pode partir; o cabeçalho mede-se
 * por ele (150px por cima, como o `top` do desenho, e 64px por baixo, onde
 * cabem os 24 de folga e a linha do autor), e o autor e a data ficam presos
 * ao fundo. Com uma linha fica tudo onde estava (cabeçalho de 310px, autor
 * aos 270); com duas, o cabeçalho cresce 96px e o resto da página desce.
 * Medido nos 337 artigos a 1440 e 1920: nenhum sai da janela nem da caixa,
 * e a folga até ao autor é sempre 24. O telemóvel tem o refluxo próprio.
 * ------------------------------------------------------------ */
@media (min-width: 430.02px) {
	.artigo-cabecalho {
		height: auto;
	}

	.artigo-cabecalho > .seccao-inner {
		padding: 150px 0 64px;
	}

	h1.artigo-cabecalho__titulo {
		position: relative;
		top: auto;
		white-space: normal;
	}

	.artigo-cabecalho__avatar {
		top: auto;
		bottom: 5px;
	}

	.artigo-cabecalho__autor,
	.artigo-cabecalho__meta {
		top: auto;
		bottom: 4px;
	}
}

/* ------------------------------------------------------------
 * Banner da loja com um texto por slide (banners da Raquel, 20-10-2026)
 *
 * Antes mudavam só as imagens e o texto era um para todas. Cada slide leva
 * agora a fotografia (já escurecida à esquerda) e, por cima, sobretítulo,
 * título, subtítulo e o botão com a seta, a branco. As medidas são as dos
 * exemplos dela a 1920, tiradas da tinta das letras: sobretítulo Nunito
 * 600 a 22px com a maiúscula aos 148 (o `top` de 141 do banner antigo),
 * título HV Simplicite a 76px com linhas de 90 a começar aos 206, subtítulo
 * Nunito a 26px aos 387 e o botão aos 465, com 61 de altura e 21px de folga
 * de cada lado do texto. O telemóvel tem o cartão claro (bloco R104).
 * ------------------------------------------------------------ */
.loja-banner__slide {
	position: absolute;
	inset: 0;
	transition: opacity 0.5s ease;
}

.loja-banner__slide[aria-hidden="true"] {
	opacity: 0;
	pointer-events: none;
}

.loja-banner__texto {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	padding-top: 141px;
}

.loja-banner__sobretitulo {
	margin: 0;
	font: 600 22px/32px var(--fonte-corpo);
	text-transform: uppercase;
	color: #ffffff;
}

.loja-banner__titulo {
	margin: 0;
	font: 400 76px/90px var(--fonte-titulos);
	color: #ffffff;
	white-space: nowrap;
}

.loja-banner__sobretitulo + .loja-banner__titulo {
	margin-top: 11px;
}

.loja-banner__subtitulo {
	margin: 15px 0 0;
	font: 400 26px/36px var(--fonte-corpo);
	color: #ffffff;
}

.loja-banner .loja-banner__accao {
	width: auto;
	padding: 0 21px;
	margin-top: 50px;
}

.loja-banner__accao:first-child {
	margin-top: 0;
}
