*,
*::before,
*::after {
	box-sizing: border-box;
}

/* Compensa o cabeçalho público fixo (sticky) ao saltar para uma âncora
   (ex.: menu "FAQ" → #paralelo-faq), para o título da secção não ficar
   escondido atrás dele. Inofensivo nas páginas autenticadas (Dashboard/
   Perfil), cuja barra superior não é sticky. */
html {
	scroll-padding-top: 90px;
}

/* NOVO (arquitectura por módulos — ajuste de layout): largura comum às
   duas Sidebars (esquerda e direita) — uma única variável, nunca dois
   números diferentes espalhados pela folha de estilos. */
:root {
	--paralelo-sidebar-width: 260px;
	/* NOVO (ajustes de UI — "criar/reutilizar tokens de espaçamento",
	   Requisito 18): separação vertical entre blocos de uma página de
	   gestão (filtros/pesquisa ↔ tabela, secções do Dashboard, …) —
	   fonte única, em vez de margens soltas repetidas por página. */
	--paralelo-content-gap: 24px;
}

/*
 * Alternância claro/escuro do lado do cliente (Secção 33): as variáveis
 * base já vêm calculadas no <head> pelo ThemeOutput (tema escolhido pelo
 * admin ou paleta clara), consoante `dark_mode.enabled`. Este bloco só
 * força uma variante clara quando o próprio aluno alterna manualmente,
 * mantendo as cores de marca (primária/secundária/links) e trocando
 * apenas fundo/superfície/texto/contorno.
 */
:root.paralelo-force-light {
	--paralelo-bg: #f9fafb;
	--paralelo-surface: #ffffff;
	--paralelo-text: #1f2937;
	--paralelo-border: #e5e7eb;
}

body.paralelo-frontend {
	margin: 0;
	background: var(--paralelo-bg);
	color: var(--paralelo-text);
	font-family: var(--paralelo-font-family);
	/* NOVO (pedido "Classificação, Tipografia e Hero Responsiva" —
	   Secção 2.1): peso base configurável (Administrador → Preferência
	   individual, ver `Preferences::effective()`), aplicado junto com a
	   Família/Tamanho acima. Elementos com peso próprio já definido
	   explicitamente na folha de estilos (títulos, botões, etc.)
	   continuam a usar o seu valor — este só define o texto corrido, tal
	   como já acontecia com o tamanho de fonte base. */
	font-weight: var(--paralelo-font-weight, 400);
	/* AJUSTADO (Revisão Geral e Otimização Responsiva — Secção 3): antes
	   fixo em `--paralelo-font-size-base` (só o valor Desktop, sempre igual
	   em qualquer ecrã) — passa a usar o passo "base" da escala fluida
	   (`clamp()`, calculada em `ThemeOutput::css_variables()`), a mesma
	   reutilizada por todo o resto do texto da plataforma. */
	font-size: var(--paralelo-text-base);
	line-height: 1.5;
	-webkit-font-smoothing: antialiased;
}

/* AJUSTADO (pedido "Ajuste à Implementação de Responsividade" —
   Secção 2): causa real identificada — `.paralelo-auth-shell` tinha
   `min-height:100vh` PRÓPRIO, somado ao espaço já ocupado no fluxo
   normal do documento pelo `.paralelo-public-header` (sticky, mas sticky
   continua a ocupar espaço real, não é `fixed`) logo acima dela. Ou
   seja, o total real da página passava a ser "altura do header +
   100vh", e o formulário ficava centrado nesses 100vh extra — sempre
   deslocado para baixo do centro visual verdadeiro do ecrã, tanto
   mais visível quanto maior o header. Corrigido tornando `<body>`
   (só nas páginas de autenticação, via `body.paralelo-auth-page` — nunca
   as restantes) uma coluna flex de `100vh`, com `.paralelo-auth-shell` a
   preencher exatamente o espaço que sobra abaixo do header
   (`flex:1`), sem duplicar viewport nenhum. */
body.paralelo-auth-page {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}

.paralelo-auth-shell {
	flex: 1;
	display: flex;
	align-items: flex-start;
	justify-content: center;
	padding: 24px;
	/* Desktop: mais próximo do topo do que o centrado vertical
	   anterior, mas com respiro suficiente para não parecer colado ao
	   Header — Tablet/Mobile reduzem este valor progressivamente
	   (media queries abaixo). */
	padding-top: 64px;
}

.paralelo-auth-card {
	width: 100%;
	max-width: 420px;
	background: var(--paralelo-surface);
	border: 1px solid var(--paralelo-border);
	border-radius: 14px;
	padding: 36px 32px;
	box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
}

.paralelo-profile-card {
	max-width: 560px;
}

.paralelo-auth-card h1 {
	margin: 0 0 24px;
	font-size: var(--paralelo-text-lg);
	font-weight: 600;
}

.paralelo-auth-card h3 {
	margin: 28px 0 14px;
	font-size: var(--paralelo-text-sm);
	font-weight: 600;
	border-top: 1px solid var(--paralelo-border);
	padding-top: 20px;
}

/* AJUSTADO (finalização 1.0.0 — Fase 4, "Login e Registo/Cadastro"):
   espaçamento entre campos (14px→20px) e entre label/campo (6px→10px,
   ver `form input`/`form textarea` abaixo) aumentado — os campos
   ficavam visualmente colados uns aos outros. */
.paralelo-auth-card form label {
	display: block;
	font-size: var(--paralelo-text-xs);
	font-weight: 500;
	margin-bottom: 20px;
}

.paralelo-auth-card form input {
	display: block;
	width: 100%;
	margin-top: 10px;
	/* AJUSTADO: campos visualmente baixos — altura aumentada de forma
	   ligeira e proporcional (10px→13px de padding vertical), nunca
	   exagerada. */
	padding: 13px 14px;
	border-radius: 8px;
	border: 1px solid var(--paralelo-border);
	background: rgba(255, 255, 255, 0.04);
	color: var(--paralelo-text);
	font-size: var(--paralelo-text-sm);
	font-family: inherit;
}

.paralelo-auth-card form input:focus {
	outline: 2px solid var(--paralelo-primary);
	outline-offset: 1px;
}

/* NOVO (pedido "Olhinho nos campos de senha"): wrapper só à volta do
   próprio `<input>` (ver `Components::password_field_html()`) — a
   altura do wrapper coincide sempre com a do campo, por isso a
   centragem vertical do botão (`top:50%`) funciona sem precisar de
   saber a altura exata do campo. */
.paralelo-password-field {
	position: relative;
}

.paralelo-password-field input {
	/* AJUSTADO: acompanha o aumento da área clicável do ícone acima —
	   nunca sobrepor o texto escrito no campo. */
	padding-right: 46px;
}

.paralelo-password-toggle {
	position: absolute;
	right: 6px;
	top: 50%;
	transform: translateY(-50%);
	background: none;
	border: none;
	/* AJUSTADO (finalização 1.0.0 — Fase 4.3): área clicável maior
	   (4px→8px de padding à volta do ícone de 18px, ~34px no total) —
	   mais confortável em Mobile/Tablet, sem aumentar visualmente o
	   ícone em si. */
	padding: 8px;
	margin: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: inherit;
	opacity: 0.6;
	cursor: pointer;
}

.paralelo-password-toggle:hover {
	opacity: 1;
}

.paralelo-password-toggle .dashicons {
	font-size: 18px;
	width: 18px;
	height: 18px;
}

/* CORRIGIDO: as perguntas do tipo "textarea" do formulário de avaliação
   (ex.: "Fale sobre o Curso") nunca tinham estilo próprio — caíam para a
   aparência nativa do navegador, pequena e inconsistente com os outros
   campos (`input` acima). Agora tem a mesma largura/borda/padding, com
   altura inicial para ~5 linhas e redimensionamento vertical livre. */
.paralelo-auth-card form textarea {
	display: block;
	width: 100%;
	margin-top: 10px;
	padding: 13px 14px;
	border-radius: 8px;
	border: 1px solid var(--paralelo-border);
	background: rgba(255, 255, 255, 0.04);
	color: var(--paralelo-text);
	font-size: var(--paralelo-text-sm);
	font-family: inherit;
	line-height: 1.5;
	resize: vertical;
}

.paralelo-auth-card form textarea:focus {
	outline: 2px solid var(--paralelo-primary);
	outline-offset: 1px;
}

.paralelo-btn-primary,
.paralelo-btn-secondary {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	/* AJUSTADO (finalização 1.0.0 — Fase 4.2): altura ligeiramente maior
	   (11px→13px), mesmo critério dos inputs acima. */
	padding: 13px 18px;
	border-radius: 8px;
	border: none;
	font-size: var(--paralelo-text-sm);
	font-weight: 600;
	cursor: pointer;
	font-family: inherit;
	text-decoration: none;
}

.paralelo-btn-primary {
	background: var(--paralelo-primary);
	color: #fff;
}

.paralelo-btn-secondary {
	background: transparent;
	color: var(--paralelo-text);
	border: 1px solid var(--paralelo-border);
}

.paralelo-btn-primary:disabled,
.paralelo-btn-secondary:disabled {
	opacity: 0.6;
	cursor: not-allowed;
}

.paralelo-auth-card form .paralelo-btn-primary,
.paralelo-auth-card form .paralelo-btn-secondary {
	width: 100%;
}

/* NOVO (pedido "Nova Aba reCAPTCHA"): espaço próprio para o widget v2
   ("Não sou um robô"), entre a senha e o botão de submissão. */
.paralelo-auth-card form .g-recaptcha {
	margin: 8px 0 20px;
}

.paralelo-auth-alt {
	margin-top: 20px;
	font-size: var(--paralelo-text-xs);
	text-align: center;
	color: var(--paralelo-text);
	opacity: 0.85;
}

.paralelo-auth-alt a,
.paralelo-auth-card a {
	color: var(--paralelo-links);
	text-decoration: none;
}

.paralelo-auth-alt a:hover,
.paralelo-auth-card a:hover {
	text-decoration: underline;
}

.paralelo-form-message {
	padding: 10px 14px;
	border-radius: 8px;
	font-size: var(--paralelo-text-xs);
	margin-bottom: 18px;
}

.paralelo-form-message[data-status='error'] {
	background: rgba(239, 68, 68, 0.15);
	color: #fca5a5;
	border: 1px solid rgba(239, 68, 68, 0.3);
}

.paralelo-form-message[data-status='success'] {
	background: rgba(34, 197, 94, 0.15);
	color: #86efac;
	border: 1px solid rgba(34, 197, 94, 0.3);
}

.paralelo-avatar-row {
	display: flex;
	align-items: center;
	gap: 16px;
	margin-bottom: 24px;
}

.paralelo-avatar-preview {
	width: 64px;
	height: 64px;
	border-radius: 50%;
	object-fit: cover;
	border: 1px solid var(--paralelo-border);
}

.paralelo-field-help {
	font-size: var(--paralelo-text-xs);
	opacity: 0.7;
	margin: 4px 0 0;
}

/* AJUSTADO (pedido "Ajuste à Implementação de Responsividade" —
   Secção 2): progressão de respiro no topo — 64px no Desktop (regra
   base, acima), 40px em Tablet, 20px em Mobile — nunca colado ao
   Header, mas cada vez mais compacto conforme o ecrã encolhe. */
@media (max-width: 900px) {
	.paralelo-auth-shell {
		padding-top: 40px;
	}
}

@media (max-width: 600px) {
	.paralelo-auth-shell {
		padding: 16px;
		padding-top: 20px;
	}

	.paralelo-auth-card {
		padding: 28px 20px;
	}
}

/* ---------- Cabeçalho público (fixo/sticky, partilhado por todas as
   páginas acessíveis antes do login) ---------- */

.paralelo-public-header {
	position: sticky;
	top: 0;
	z-index: 100;
	padding: 16px 32px;
	border-bottom: 1px solid var(--paralelo-border);
	background: var(--paralelo-surface);
	transition: padding 0.2s ease, box-shadow 0.2s ease;
}

/* NOVO (auditoria "Header Principal — Boxed vs Full-Width"): o
   `<header>` continua o fundo/faixa a toda a largura (sticky, borda,
   padding) - só o conteúdo (logo + navegação + ações) passa a viver
   neste wrapper próprio, que é quem realmente ganha o `max-width`
   quando "Boxed" estiver escolhido, abaixo. Layout flex idêntico ao
   que já estava no `<header>`, só deslocado para aqui - nenhuma
   mudança visual para quem ficar em "Full Width" (o valor por
   omissão). */
.paralelo-public-header__inner {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 20px;
	width: 100%;
}

/* AJUSTADO (pedido "Unificar a Largura dos Containers da Home"): o
   valor 1100px passou a viver numa única variável
   (`--paralelo-home-content-width`, definida em `.paralelo-public`, abaixo,
   com este mesmo valor como reserva para quando o cabeçalho aparece
   fora da Home — Página do Curso, Login, Registo, etc. — que não têm
   esse wrapper) - `.paralelo-public section.paralelo-section`/
   `#paralelo-youtube` (mais abaixo) leem a MESMA variável, em vez de cada
   um repetir "1100px" solto, que era a causa real de as secções da
   Home ficarem com larguras de conteúdo ligeiramente diferentes do
   Header (o Header não tinha padding lateral próprio nesta caixa; as
   secções tinham `padding: 0 24px` DENTRO do mesmo `max-width`, com
   `box-sizing: border-box` — encolhendo o conteúdo real ~24px de cada
   lado em relação ao Header). Sem efeito nenhum em ecrãs mais estreitos
   do que 1100px (único breakpoint deste cabeçalho é 900px, abaixo), por
   isso não interfere com o menu hambúrguer mobile. */
.paralelo-public-header--boxed .paralelo-public-header__inner {
	max-width: var(--paralelo-home-content-width, 1100px);
	margin: 0 auto;
}

/* Aplicada via JS ao rolar (ver assets/frontend/js/student.js) — reduz
   ligeiramente a altura e acrescenta sombra, sem exagerar na animação. */
.paralelo-public-header.is-scrolled {
	padding-top: 10px;
	padding-bottom: 10px;
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}

.paralelo-app-logo {
	font-weight: 700;
	font-size: var(--paralelo-text-md);
	color: var(--paralelo-text);
	text-decoration: none;
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
}

/* NOVO (correção do logotipo): imagem da logo carregada no admin (em vez do
   texto do nome da plataforma). O tamanho vem de um `style="height:...px"`
   inline, aplicado dinamicamente a partir da configuração "Altura da Logo". */
.paralelo-app-logo__img {
	display: block;
	max-width: 220px;
}

/* Alternância clara/escura: por omissão mostra-se a imagem correspondente
   ao tema do servidor (--default-dark ou --default-light, calculada a
   partir de `dark_mode.enabled`); a classe `paralelo-force-light` em `<html>`
   é a mesma já usada por todo o sistema de tema para a troca ao vivo, sem
   recarregar a página, quando o aluno alterna o tema manualmente. */
.paralelo-app-logo--default-dark .paralelo-app-logo__img--light,
.paralelo-app-logo--default-light .paralelo-app-logo__img--dark {
	display: none;
}

:root.paralelo-force-light .paralelo-app-logo--default-dark .paralelo-app-logo__img--dark {
	display: none;
}

:root.paralelo-force-light .paralelo-app-logo--default-dark .paralelo-app-logo__img--light {
	display: block;
}

.paralelo-icon-btn {
	background: none;
	border: 1px solid var(--paralelo-border);
	border-radius: 8px;
	width: 36px;
	height: 36px;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	color: var(--paralelo-text);
	flex-shrink: 0;
}

.paralelo-public-header__toggle {
	display: none;
	background: none;
	border: 1px solid var(--paralelo-border);
	border-radius: 8px;
	width: 40px;
	height: 40px;
	align-items: center;
	justify-content: center;
	color: var(--paralelo-text);
	cursor: pointer;
	flex-shrink: 0;
}

.paralelo-public-header__panel {
	display: flex;
	align-items: center;
	justify-content: flex-end;
	gap: 24px;
	flex: 1;
	min-width: 0;
}

/* AJUSTADO (auditoria "Header Principal — Espaçamento do Menu"):
   20px → 28px, pedido explícito ("os itens estão muito próximos") -
   `flex-wrap: wrap`, já existente, continua a ser a rede de segurança
   contra overflow horizontal em qualquer largura (Tablet incluído) -
   sem breakpoint novo, os itens simplesmente passam para uma segunda
   linha se não couberem, em vez de espremer o cabeçalho. Em Mobile
   (<900px, abaixo) o menu já muda para coluna vertical, com o seu
   próprio `gap` mais compacto - inalterado. */
.paralelo-public-header__nav {
	display: flex;
	align-items: center;
	gap: 28px;
	flex-wrap: wrap;
}

.paralelo-public-header__nav a {
	color: var(--paralelo-text);
	text-decoration: none;
	font-size: var(--paralelo-text-sm);
	font-weight: 500;
	opacity: 0.8;
	white-space: nowrap;
}

.paralelo-public-header__nav a:hover {
	opacity: 1;
	color: var(--paralelo-primary);
}

.paralelo-public-header__actions {
	display: flex;
	align-items: center;
	gap: 12px;
	flex-shrink: 0;
}

.paralelo-public-header .paralelo-btn-primary,
.paralelo-public-header .paralelo-btn-secondary {
	padding: 8px 16px;
	white-space: nowrap;
}

@media (max-width: 900px) {
	.paralelo-public-header__toggle {
		display: inline-flex;
	}

	.paralelo-public-header__panel {
		display: none;
		position: absolute;
		top: 100%;
		left: 0;
		right: 0;
		flex-direction: column;
		align-items: stretch;
		gap: 18px;
		background: var(--paralelo-surface);
		border-bottom: 1px solid var(--paralelo-border);
		padding: 20px 24px 24px;
		box-shadow: 0 16px 30px rgba(0, 0, 0, 0.18);
		max-height: calc(100vh - 68px);
		overflow-y: auto;
	}

	.paralelo-public-header__panel.is-open {
		display: flex;
	}

	.paralelo-public-header__nav {
		flex-direction: column;
		align-items: flex-start;
		gap: 14px;
	}

	.paralelo-public-header__actions {
		flex-direction: column;
		align-items: stretch;
	}

	.paralelo-public-header__actions .paralelo-btn-primary,
	.paralelo-public-header__actions .paralelo-btn-secondary {
		text-align: center;
	}
}

.paralelo-eyebrow {
	display: inline-block;
	font-size: var(--paralelo-text-xs);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--paralelo-primary);
	margin-bottom: 10px;
}

.paralelo-section-subtitle {
	opacity: 0.75;
	margin: -8px 0 20px;
	font-size: var(--paralelo-text-sm);
}

/* ---------- App shell (Dashboard / Perfil) ---------- */

/* CORRIGIDO (correcção do App Shell — "Header fixo a toda a largura,
   Sidebars fixas, só o conteúdo central rola"): generaliza a toda a
   aplicação um padrão já validado e em produção só na página de Aula
   (ver `body.paralelo-lesson-page`, mais abaixo) — Header
   (`.paralelo-app-topbar`) passa a filho direto do shell (a toda a
   largura, acima das duas colunas), e uma nova linha
   (`.paralelo-app-row`) contém Sidebar esquerda + conteúdo + Sidebar
   direita (quando existir). Tal como no padrão da Aula, só a partir de
   901px: abaixo disso mantém-se a rolagem normal da página inteira —
   mais adequado a ecrãs pequenos do que forçar painéis com scroll
   interno próprio (mesma razão já documentada para a Aula). */
/* CORRIGIDO (pedido "Autor dos Registos + Novo App Shell + Modo de
   Aparência" — Parte 2, Requisitos 2.1-2.7): a Sidebar esquerda deixa de
   viver DENTRO de `.paralelo-app-row` (que ficava abaixo do Header,
   filho de um shell `flex-direction:column`) — passa a filho DIRECTO do
   próprio shell, agora `flex-direction:row`. Isto sozinho já resolve
   "Sidebar começa em top:0" (o shell inteiro já tem `height:100vh` em
   Desktop, e `align-items:stretch` — o valor por omissão do Flexbox —
   estica a Sidebar à altura toda, sem precisar de nenhuma regra extra) e
   "Header começa depois da Sidebar" (o Header deixa de ser filho directo
   do shell, passa a viver dentro de `.paralelo-app-main-column`, o
   SEGUNDO filho do shell, ao lado da Sidebar — nunca por cima dela). */
.paralelo-app-shell {
	display: flex;
	flex-direction: row;
	min-height: 100vh;
}

@media (min-width: 901px) {
	.paralelo-app-shell {
		height: 100vh;
		overflow: hidden;
	}
}

/* NOVO — a coluna que agora contém Header + `.paralelo-app-row`
   (conteúdo + Sidebar direita), ao lado da Sidebar esquerda — nunca por
   baixo dela (Requisito 2.7). `flex:1`/`min-width:0` garantem que ocupa
   sempre o espaço restante, incluindo quando a Sidebar esquerda é
   escondida (Requisito 2.8 — sem nenhum JS a recalcular larguras, o
   mesmo princípio já usado para a Sidebar direita). */
.paralelo-app-main-column {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-width: 0;
	min-height: 0;
}

.paralelo-app-row {
	display: flex;
	flex: 1;
	min-height: 0;
}

/* AJUSTADO: antes só invertia `.paralelo-app-row` (continha as duas
   Sidebars); agora a Sidebar esquerda já não vive lá dentro — precisa de
   inverter também ao nível do próprio shell, para as duas Sidebars
   continuarem a trocar de lado em conjunto quando a preferência pessoal
   for "Sidebar à direita" (mesmo comportamento combinado de sempre,
   nunca alterado nesta correcção estrutural). */
.paralelo-app-shell[data-paralelo-sidebar-position='right'] {
	flex-direction: row-reverse;
}

.paralelo-app-shell[data-paralelo-sidebar-position='right'] .paralelo-app-row {
	flex-direction: row-reverse;
}

.paralelo-sidebar {
	width: var(--paralelo-sidebar-width);
	flex-shrink: 0;
	background: var(--paralelo-surface);
	border-right: 1px solid var(--paralelo-border);
	padding: 20px 16px;
	display: flex;
	flex-direction: column;
}

@media (min-width: 901px) {
	.paralelo-sidebar {
		overflow-y: auto;
		scrollbar-width: thin;
		scrollbar-color: var(--paralelo-border) transparent;
	}

	.paralelo-sidebar::-webkit-scrollbar {
		width: 6px;
	}

	.paralelo-sidebar::-webkit-scrollbar-track {
		background: transparent;
	}

	.paralelo-sidebar::-webkit-scrollbar-thumb {
		background-color: var(--paralelo-border);
		border-radius: 3px;
	}
}

/* AJUSTADO (pedido "Ajuste à Implementação de Responsividade" —
   Secção 1): faltava esta regra de base — sem ela, o botão (um
   `<button>`, `display:inline-block` por omissão do navegador) ficava
   visível em desktop, onde a Sidebar nunca funciona como painel
   sobreposto e não há nada para "fechar". Só ganha `display:flex`
   dentro da media query mobile/tablet, mais abaixo — exatamente o
   intervalo (≤900px) em que a Sidebar passa a comportar-se como
   painel lateral/overlay em toda a folha de estilos. */
.paralelo-sidebar-close {
	display: none;
}

/* CORRIGIDO: o botão de alternar (`data-paralelo-sidebar-toggle`) já
   alternava a classe `is-open` corretamente via JS, mas essa classe só
   tinha algum efeito visual dentro da media query do mobile (abaixo) —
   em ecrã largo (>900px, onde a Sidebar já está sempre visível por
   omissão), clicar no botão não tinha nenhum efeito percetível. Agora o
   mesmo clique também recolhe/expande a Sidebar em desktop/tablet
   largo; `.paralelo-app-content` já tem `flex: 1`, por isso ocupa sozinho o
   espaço libertado sem precisar de mais nenhum ajuste. */
@media (min-width: 901px) {
	.paralelo-sidebar.is-open {
		display: none;
	}
}

.paralelo-sidebar-logo {
	padding: 8px 12px 20px;
}

.paralelo-sidebar-label {
	font-size: var(--paralelo-text-xs);
	font-weight: 700;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	opacity: 0.5;
	padding: 0 12px 10px;
}

/* CORRIGIDO (pedido "Ajustes Finais de Navegação..." — Parte 2,
   Requisito 2.7: "não hardcodear... criar uma variável/token global"):
   três tokens únicos controlam TODO o espaçamento das DUAS Sidebars —
   nunca mais um valor de padding repetido por regra/densidade. "Normal"
   (aqui, na raiz do shell) já reflecte uma redução ligeira face ao
   espaçamento anterior (Requisito 2.5: "reduzir ligeiramente a
   densidade relativamente ao estado excessivamente espaçado actual") —
   eram 18px/4px/10px, passam a 14px/3px/8px. */
/* AJUSTADO (pedido "Ajustes de Sidebars, Padding e Scrollbar dos
   Formulários" — Parte 2): a escolha em 3 níveis (Compacto/Normal/
   Confortável) foi substituída por um valor numérico real,
   `--paralelo-sidebar-item-padding`, escrito directamente pelo PHP como
   variável inline no próprio `.paralelo-app-shell`
   (`Components::app_shell_open()`, Requisito 14 — "criar uma
   variável/token global") — os itens de menu das duas Sidebars usam-na
   directamente (ver `.paralelo-sidebar nav a`, mais abaixo); o `12px` em
   `var(--paralelo-sidebar-item-padding, 12px)` é só o valor de recurso
   caso o atributo `style` não chegue a ser aplicado, nunca o valor
   realmente usado num carregamento normal. `--paralelo-menu-group-gap`/
   `--paralelo-menu-item-inner-gap` deixam de ser configuráveis nesta
   fase — mantêm-se no valor "Normal" já ajustado anteriormente. */
.paralelo-app-shell {
	--paralelo-menu-group-gap: 14px;
	--paralelo-menu-item-inner-gap: 3px;
}

.paralelo-sidebar nav {
	display: flex;
	flex-direction: column;
	gap: var(--paralelo-menu-group-gap);
}

/* NOVO (pedido "Front-end como Plataforma Profissional de Gestão de
   Dados Humanitários"): navegação agrupada em secções (Principal, Base
   de Dados, Formação, Conta) em vez de uma lista plana — reaproveita a
   mesma aparência de link já existente (`.paralelo-sidebar nav a`
   abaixo), só acrescenta o rótulo da secção. */
.paralelo-sidebar-group {
	display: flex;
	flex-direction: column;
	gap: var(--paralelo-menu-item-inner-gap);
}

/* CORRIGIDO (pedido "Refinamento de UX..." — Parte 5, secções 21-23:
   "remover títulos/separadores visuais das Sidebars, o agrupamento pode
   continuar semanticamente no código"): visualmente escondido, nunca
   removido do DOM — continua a dar contexto a leitores de ecrã, só deixa
   de ocupar espaço/aparecer como cabeçalho decorativo. `position:absolute`
   também tira o elemento do fluxo do `flex` do grupo (`.paralelo-sidebar-group`),
   por isso os itens ficam com o mesmo espaçamento uniforme entre si, sem
   o "buraco" que um `display:none` simples deixaria na contagem do `gap`. */
.paralelo-sidebar-group-label {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
}

.paralelo-sidebar nav a,
.paralelo-module-sidebar__nav a {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: var(--paralelo-sidebar-item-padding, 12px) 12px;
	border-radius: 8px;
	color: var(--paralelo-text);
	text-decoration: none;
	font-size: var(--paralelo-text-sm);
}

/* NOVO (Requisitos 16-19 — "separadores configuráveis, independente do
   espaçamento"): linha discreta acima de cada grupo (excepto o
   primeiro) — só quando `sidebar_separators` = 'show' (o padrão
   continua 'hide', mesma decisão já tomada de remover separadores
   visuais). Nunca junto com o rótulo do grupo (continua escondido) — só
   a linha em si, sempre fina/discreta. */
[data-paralelo-sidebar-separators="show"] .paralelo-sidebar-group:not(:first-child),
[data-paralelo-sidebar-separators="show"] .paralelo-module-sidebar__nav .paralelo-sidebar-group:not(:first-child) {
	border-top: 1px solid var(--paralelo-border);
	padding-top: 12px;
}

.paralelo-sidebar nav a.is-active,
.paralelo-sidebar nav a:hover,
.paralelo-module-sidebar__nav a.is-active,
.paralelo-module-sidebar__nav a:hover {
	background: var(--paralelo-primary);
	color: #fff;
}

/* ---------- Sidebar direita contextual (arquitectura por módulos) ---------- */

.paralelo-module-sidebar {
	width: var(--paralelo-sidebar-width);
	flex-shrink: 0;
	background: var(--paralelo-surface);
	border-left: 1px solid var(--paralelo-border);
	padding: 24px 16px;
}

@media (min-width: 901px) {
	.paralelo-module-sidebar {
		overflow-y: auto;
		scrollbar-width: thin;
		scrollbar-color: var(--paralelo-border) transparent;
		/* NOVO (Requisitos 1.3/1.4 — ocultar/revelar com transição
		   curta): só `width`/`padding` animam — o conteúdo central, um
		   irmão `flex:1`, preenche automaticamente o espaço libertado
		   sem nenhum JS a recalcular larguras (Requisito 1.5). */
		transition: width 0.2s ease, padding 0.2s ease;
	}

	.paralelo-module-sidebar::-webkit-scrollbar {
		width: 6px;
	}

	.paralelo-module-sidebar::-webkit-scrollbar-track {
		background: transparent;
	}

	.paralelo-module-sidebar::-webkit-scrollbar-thumb {
		background-color: var(--paralelo-border);
		border-radius: 3px;
	}

	/* CORRIGIDO (pedido "Ajustes Finais de Navegação..." — Parte 1): o
	   botão vive DENTRO do `<aside>` (Requisito 1.1) — "recolhida" já não
	   pode ser `width:0`/`display:none` no `<aside>` inteiro, ou o botão
	   desapareceria com ele, sem forma de reabrir. Encolhe para uma
	   faixa estreita, larga o suficiente só para o botão — o `<nav>` lá
	   dentro (Visão Geral + itens) é que fica escondido. */
	.paralelo-app-shell.is-module-sidebar-collapsed .paralelo-module-sidebar {
		/* 60px = padding (12px × 2) + o botão .paralelo-icon-btn (36px),
		   o mesmo tamanho exacto do botão da Sidebar esquerda. */
		width: 60px;
		padding: 20px 12px;
	}

	.paralelo-app-shell.is-module-sidebar-collapsed .paralelo-module-sidebar__nav {
		display: none;
	}
}

/* CORRIGIDO (pedido "Ajustes de Sidebars, Padding e Scrollbar dos
   Formulários" — Parte 1, Requisito 1: "não criar um novo estilo de
   botão"): a aparência (tamanho, borda, cor, hover) já vem inteiramente
   de `.paralelo-icon-btn` (a mesma classe do botão da Sidebar esquerda
   no Header, sem alterações — Requisito 5), aplicada directamente na
   marcação (`Components::app_shell_close()`). Esta classe fica
   deliberadamente vazia de aparência — só o posicionamento específico
   desta instância (espaço antes de "Visão Geral", Requisito 2), que
   nunca poderia vir de `.paralelo-icon-btn` (usado em vários sítios
   diferentes, cada um com o seu próprio contexto de layout). */
.paralelo-module-sidebar-collapse-toggle {
	margin: 0 0 16px;
}

/* O botão novo só faz sentido em Desktop (onde a Sidebar direita é
   sempre visível por omissão) — em Mobile/Tablet ela já se comporta
   como drawer, com o seu próprio botão "Navegação do módulo"
   (`data-paralelo-module-sidebar-toggle`, inalterado — Requisito 30:
   "o botão deve continuar disponível"). Evita dois botões diferentes a
   controlar a mesma Sidebar com semânticas diferentes no mesmo ecrã. */
@media (max-width: 900px) {
	[data-paralelo-module-sidebar-collapse-toggle] {
		display: none;
	}
}

.paralelo-module-sidebar__nav {
	display: flex;
	flex-direction: column;
	gap: var(--paralelo-menu-group-gap);
}

.paralelo-module-sidebar-backdrop {
	display: none;
}

.paralelo-module-sidebar-toggle {
	display: none;
}

/* ---------- Breadcrumbs (Requisito 34) ---------- */

.paralelo-breadcrumbs {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
	font-size: var(--paralelo-text-xs);
	opacity: 0.65;
	margin-bottom: 16px;
}

.paralelo-breadcrumbs a {
	color: inherit;
	text-decoration: none;
}

.paralelo-breadcrumbs a:hover {
	text-decoration: underline;
}

.paralelo-breadcrumbs__sep {
	opacity: 0.5;
}

/* ---------- "Utilizadores por Role" (módulo Perfis, secção 18) ---------- */

.paralelo-role-bars {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 12px;
	background: var(--paralelo-surface);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	padding: 20px;
}

.paralelo-role-bar {
	display: grid;
	grid-template-columns: 140px 1fr 40px;
	align-items: center;
	gap: 12px;
	font-size: var(--paralelo-text-sm);
}

.paralelo-role-bar__track {
	background: var(--paralelo-bg);
	border-radius: 999px;
	height: 8px;
	overflow: hidden;
}

.paralelo-role-bar__fill {
	display: block;
	height: 100%;
	background: var(--paralelo-primary);
	border-radius: 999px;
}

.paralelo-role-bar__count {
	text-align: right;
	font-weight: 600;
}

@media (max-width: 900px) {
	.paralelo-module-sidebar {
		position: fixed;
		inset: 0 0 0 auto;
		z-index: 210;
		width: min(280px, 84vw);
		transform: translateX(100%);
		transition: transform 0.2s ease;
		box-shadow: 0 0 40px rgba(0, 0, 0, 0.3);
		overflow-y: auto;
	}

	.paralelo-module-sidebar.is-open {
		transform: translateX(0);
	}

	.paralelo-module-sidebar-backdrop.is-open {
		display: block;
		position: fixed;
		inset: 0;
		background: rgba(0, 0, 0, 0.5);
		z-index: 205;
	}

	.paralelo-module-sidebar-toggle {
		display: flex;
		align-items: center;
		gap: 8px;
		margin-bottom: 20px;
		padding: 10px 16px;
		border-radius: 8px;
		border: 1px solid var(--paralelo-border);
		background: var(--paralelo-surface);
		color: var(--paralelo-text);
		font-size: var(--paralelo-text-sm);
		cursor: pointer;
	}

	.paralelo-role-bar {
		grid-template-columns: 100px 1fr 32px;
	}
}

.paralelo-sidebar-bottom {
	margin-top: auto;
	padding-top: 16px;
	border-top: 1px solid var(--paralelo-border);
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.paralelo-sidebar-bottom a {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 10px 12px;
	border-radius: 8px;
	color: var(--paralelo-text);
	text-decoration: none;
	font-size: var(--paralelo-text-xs);
	opacity: 0.8;
}

.paralelo-sidebar-bottom a:hover {
	opacity: 1;
}

.paralelo-sidebar-logout {
	color: #ef4444 !important;
	opacity: 1 !important;
}

.paralelo-app-content {
	flex: 1;
	min-width: 0;
	min-height: 0;
	display: flex;
	flex-direction: column;
}

.paralelo-app-topbar {
	display: flex;
	align-items: center;
	gap: 16px;
	padding: 14px 24px;
	border-bottom: 1px solid var(--paralelo-border);
	background: var(--paralelo-surface);
	flex-shrink: 0;
}

.paralelo-app-header__actions {
	display: flex;
	align-items: center;
	gap: 16px;
	margin-left: auto;
}

/* Selo de versão visível (auditoria "Provar qual código está realmente
   em execução"): mostra, no próprio ecrã (nunca só em comentário HTML),
   a versão do plugin que gerou a página atual. */
.paralelo-build-badge {
	font-size: var(--paralelo-text-xs);
	opacity: 0.5;
	white-space: nowrap;
	letter-spacing: 0.02em;
}

@media (max-width: 600px) {
	.paralelo-build-badge {
		display: none;
	}
}

/* AJUSTADO: "Ver Perfil" passou de link de navegação a gatilho de um
   popover (`.paralelo-user-popover`, ver marcação em Components::topbar()).
   `.paralelo-user-menu` continua a dar o mesmo aspeto (agora num <button>,
   por isso o reset de estilo nativo do botão logo a seguir). */
.paralelo-user-popover {
	position: relative;
}

button.paralelo-user-menu {
	background: none;
	border: none;
	padding: 0;
	font: inherit;
	cursor: pointer;
}

.paralelo-user-menu {
	display: flex;
	align-items: center;
	gap: 10px;
	text-decoration: none;
	color: var(--paralelo-text);
}

.paralelo-user-avatar {
	width: 36px;
	height: 36px;
	border-radius: 50%;
	object-fit: cover;
	flex-shrink: 0;
}

.paralelo-user-avatar--initials {
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--paralelo-primary);
	color: #fff;
	font-size: var(--paralelo-text-xs);
	font-weight: 700;
}

.paralelo-user-menu__text {
	display: flex;
	flex-direction: column;
	font-size: var(--paralelo-text-xs);
	line-height: 1.3;
}

.paralelo-user-menu__text small {
	opacity: 0.6;
	font-size: var(--paralelo-text-xs);
}

/* CORRIGIDO (pedido "Correcção do App Shell + Perfis" — Parte 1, secção 4):
   `max-width: 1200px` limitava o conteúdo central a uma largura fixa,
   deixando espaço vazio entre ele e a Sidebar direita em ecrãs largos —
   exactamente o que o pedido proíbe explicitamente ("max-width que
   impeça o conteúdo de ocupar o espaço disponível"). `.paralelo-app-content`
   (flex:1; min-width:0) já garante que esta coluna nunca empurra as
   Sidebars; removido o limite para o conteúdo ocupar sempre 100% do
   espaço que sobra entre as duas. */
.paralelo-app-main {
	padding: 32px;
	flex: 1;
	min-height: 0;
	min-width: 0;
}

@media (min-width: 901px) {
	.paralelo-app-main {
		overflow-y: auto;
		overflow-x: hidden;
		/* NOVO (Parte 1, secção 6 — "reduzir a barra de scroll vertical"):
		   scrollbar fina, mesmo padrão já usado em `.paralelo-sidebar-modules`
		   (Sidebar da Aula) — aplicada só a este container, nunca à
		   scrollbar do sistema/navegador inteiro. */
		scrollbar-width: thin;
		scrollbar-color: var(--paralelo-border) transparent;
	}

	.paralelo-app-main::-webkit-scrollbar {
		width: 6px;
	}

	.paralelo-app-main::-webkit-scrollbar-track {
		background: transparent;
	}

	.paralelo-app-main::-webkit-scrollbar-thumb {
		background-color: var(--paralelo-border);
		border-radius: 3px;
	}
}

/* NOVO (pedido "Ajustes de Sidebars, Padding e Scrollbar dos
   Formulários" — Parte 3, Requisito 20: "criar/reutilizar uma regra
   global para scrollbars internas"): a MESMA aparência já usada em
   `.paralelo-app-main` acima (6px, `var(--paralelo-border)`), agora
   como classe reutilizável de verdade — qualquer painel interno com
   scroll próprio (formulários em drawer/modal, listas longas, etc.)
   pode simplesmente ganhar esta classe, em vez de repetir estas 4
   regras. Sem `@media`: ao contrário de `.paralelo-app-main` (só faz
   sentido como scroll interno a partir de 901px, porque a página inteira
   ainda rola normalmente em ecrãs pequenos), um formulário dentro de um
   drawer/modal já tem scroll interno próprio em qualquer largura de
   ecrã. */
.paralelo-scrollbar-thin {
	scrollbar-width: thin;
	scrollbar-color: var(--paralelo-border) transparent;
}

.paralelo-scrollbar-thin::-webkit-scrollbar {
	width: 6px;
}

.paralelo-scrollbar-thin::-webkit-scrollbar-track {
	background: transparent;
}

.paralelo-scrollbar-thin::-webkit-scrollbar-thumb {
	background-color: var(--paralelo-border);
	border-radius: 3px;
}

/* AJUSTADO (pedido "alinhamento não está perfeito em Mobile/Tablet —
   containers com a mesma largura do Header"): `.paralelo-app-topbar` já
   reduz o seu padding horizontal para 14px em ≤900px (ver
   `.paralelo-app-topbar` dentro do `@media (max-width: 900px)`, mais
   abaixo), mas `.paralelo-app-main` — o contentor do conteúdo de cada
   página (Dashboard, Tutoriais, Perfil, Links) — nunca tinha um ajuste
   equivalente, ficando preso ao padding de 32px do desktop também em
   ecrãs pequenos. Os limites esquerdo/direito do conteúdo ficavam, por
   isso, 18px mais para dentro do que os do cabeçalho, dando a
   impressão de que a página é "mais estreita". */
@media (max-width: 900px) {
	.paralelo-app-main {
		padding-left: 14px;
		padding-right: 14px;
	}
}

.paralelo-app-main h1 {
	margin-top: 0;
}

.paralelo-app-main--narrow .paralelo-profile-card {
	max-width: 560px;
	margin: 0;
	box-shadow: none;
}

.paralelo-section {
	margin-bottom: 40px;
}

.paralelo-dashboard-hero {
	background: linear-gradient(135deg, var(--paralelo-bg), var(--paralelo-surface));
	border: 1px solid var(--paralelo-border);
	border-radius: 14px;
	padding: 32px;
	margin-bottom: 24px;
}

.paralelo-dashboard-hero h1 {
	margin: 6px 0 8px;
	font-size: var(--paralelo-text-xl);
}

.paralelo-dashboard-hero__actions {
	display: flex;
	gap: 10px;
	margin-top: 16px;
}

.paralelo-dashboard-hero__actions .paralelo-btn-primary,
.paralelo-dashboard-hero__actions .paralelo-btn-secondary {
	padding: 10px 20px;
}

/* Dashboard V1 ("PARALELO V1.0.0") — substitui a variante "Painel do
   Estudante" (título + saudação + botões de curso) por uma identidade
   própria da Paralelo: emblema de versão, título e subtítulo centrados.
   Reaproveita a caixa base `.paralelo-dashboard-hero` acima (gradiente/
   borda/padding), só ajusta o alinhamento e o conteúdo interno. */
.paralelo-dashboard-hero--v1 {
	text-align: center;
	padding: 48px 32px;
}

.paralelo-dashboard-version {
	display: inline-block;
	padding: 4px 14px;
	border-radius: 999px;
	background: var(--paralelo-primary);
	color: #fff;
	font-size: var(--paralelo-text-xs);
	font-weight: 600;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	margin-bottom: 14px;
}

.paralelo-dashboard-hero--v1 h1 {
	margin: 0 0 8px;
	font-size: 2.1rem;
	letter-spacing: 0.03em;
}

.paralelo-dashboard-hero--v1 p {
	margin: 0;
	opacity: 0.75;
	font-size: var(--paralelo-text-md);
}

/* Saudação com nome+role (V1.1.0 — "Roles & Capabilities dinâmicas"). */
.paralelo-dashboard-greeting {
	margin-top: 10px !important;
	font-size: var(--paralelo-text-sm) !important;
	opacity: 0.6 !important;
}

/* "Acesso rápido" (V1.1.0). */
.paralelo-quick-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.paralelo-quick-actions .paralelo-btn-secondary {
	padding: 10px 18px;
}

/* "Atividade recente" (V1.1.0) — dados reais, ver DashboardPage::recent_activity(). */
.paralelo-recent-activity {
	list-style: none;
	margin: 0;
	padding: 0;
	background: var(--paralelo-surface);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	overflow: hidden;
}

.paralelo-recent-activity__item {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 14px 18px;
	border-bottom: 1px solid var(--paralelo-border);
	font-size: var(--paralelo-text-sm);
}

.paralelo-recent-activity__item:last-child {
	border-bottom: none;
}

/* Cards de resumo do banco de dados (Dashboard V1) — visualmente distintos
   de `.paralelo-stat-card` (ícone+número simples, herdado do LMS): maior
   destaque ao número, e um estado "linkado" (`--linked`) para as
   entidades que já têm página de listagem ligada à navegação. */
/* CORRIGIDO (pedido "Ajustes Finais..." — Parte 4, Requisitos 4.1/4.3/4.5:
   "exactamente 3 cards por linha... não corrigir apenas uma página"):
   `repeat(auto-fit, minmax(200px, 1fr))` empacotava tantas colunas de
   200px+ quantas coubessem — 4, 5 ou mais num ecrã largo, nunca um
   número fixo. Esta É a única classe partilhada por TODAS as páginas de
   estatísticas (Dashboard, Unidades, Perfis, `StatisticsPage`) — corrigir
   aqui corrige-as todas de uma vez, nunca por página. */
.paralelo-dashboard-summary {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 16px;
}

@media (max-width: 900px) {
	.paralelo-dashboard-summary {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 600px) {
	.paralelo-dashboard-summary {
		grid-template-columns: repeat(1, minmax(0, 1fr));
	}
}

/* Dashboard principal (secção 35) — grupos "Banco de Dados"/
   "Infraestrutura"/"Pessoas", cada um com o seu próprio
   `.paralelo-dashboard-summary`. */
.paralelo-dashboard-summary-groups {
	display: flex;
	flex-direction: column;
	gap: var(--paralelo-content-gap);
}

.paralelo-dashboard-summary-groups h3 {
	margin: 0 0 12px;
	font-size: var(--paralelo-text-sm);
	font-weight: 700;
	text-transform: uppercase;
	letter-spacing: 0.06em;
	opacity: 0.6;
}

.paralelo-dashboard-summary-card {
	display: flex;
	flex-direction: column;
	gap: 6px;
	background: var(--paralelo-surface);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	padding: 20px;
	text-decoration: none;
	color: var(--paralelo-text);
	transition: border-color 0.15s ease, transform 0.15s ease;
}

.paralelo-dashboard-summary-card .dashicons {
	font-size: 22px;
	width: 22px;
	height: 22px;
	opacity: 0.7;
}

.paralelo-dashboard-summary-card strong {
	font-size: 1.8rem;
	line-height: 1.1;
}

.paralelo-dashboard-summary-card__label {
	font-size: var(--paralelo-text-sm);
	opacity: 0.7;
}

.paralelo-dashboard-summary-card--linked:hover {
	border-color: var(--paralelo-primary);
	transform: translateY(-2px);
}

.paralelo-dashboard-summary-card__link {
	margin-top: 8px;
	font-size: var(--paralelo-text-xs);
	font-weight: 600;
	color: var(--paralelo-primary);
}

/* "Ver estatísticas completas →" (Fase de Consolidação, secção 17). */
.paralelo-dashboard-summary-more {
	margin: 16px 0 0;
}

.paralelo-dashboard-summary-more a {
	font-size: var(--paralelo-text-sm);
	font-weight: 600;
	color: var(--paralelo-primary);
	text-decoration: none;
}

.paralelo-dashboard-summary-more a:hover {
	text-decoration: underline;
}

.paralelo-stat-cards {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
	gap: 16px;
	margin-bottom: 32px;
}

.paralelo-stat-card {
	display: flex;
	align-items: center;
	gap: 14px;
	background: var(--paralelo-surface);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	padding: 18px 20px;
}

.paralelo-stat-card .dashicons {
	font-size: 22px;
	width: 22px;
	height: 22px;
	color: var(--paralelo-primary);
}

.paralelo-stat-card strong {
	display: block;
	font-size: var(--paralelo-text-lg);
}

.paralelo-stat-card span {
	font-size: var(--paralelo-text-xs);
	opacity: 0.7;
}

.paralelo-quick-actions {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: 16px;
}

.paralelo-quick-tile {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8px;
	padding: 24px 12px;
	background: var(--paralelo-surface);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	color: var(--paralelo-text);
	text-decoration: none;
	font-size: var(--paralelo-text-xs);
	font-weight: 600;
	cursor: pointer;
	font-family: inherit;
}

.paralelo-quick-tile .dashicons {
	font-size: 22px;
	width: 22px;
	height: 22px;
	color: var(--paralelo-primary);
}

.paralelo-quick-tile:hover {
	border-color: var(--paralelo-primary);
}

.paralelo-quick-tile--danger .dashicons,
.paralelo-quick-tile--danger {
	color: #ef4444;
}

/* ---------- Home pública ---------- */

.paralelo-hero {
	position: relative;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 80px 24px;
	background-size: cover;
	background-position: center;
	overflow: hidden;
}

/* Altura configurável pelo admin (Configurações → Geral → Hero da Home).
   `min-height` (não `height` fixo) para nunca cortar o conteúdo em
   ecrãs pequenos ou com título/subtítulo longos. */
.paralelo-hero--small {
	min-height: 280px;
}

.paralelo-hero--medium {
	min-height: 420px;
}

.paralelo-hero--large {
	min-height: 560px;
}

.paralelo-hero--screen {
	min-height: calc(100vh - 70px);
}

.paralelo-hero__overlay {
	position: absolute;
	inset: 0;
	background: linear-gradient(
		180deg,
		rgba(var(--paralelo-hero-overlay-color, 0, 0, 0), var(--paralelo-hero-overlay-opacity, 0.55)) 0%,
		var(--paralelo-bg) 95%
	);
}

.paralelo-hero__content {
	position: relative;
	max-width: 640px;
	margin: 0 auto;
	text-align: center;
}

.paralelo-hero h1 {
	font-size: var(--paralelo-text-3xl);
	line-height: 1.15;
	margin: 0 0 16px;
}

.paralelo-hero p {
	max-width: 560px;
	margin: 0 auto 28px;
	opacity: 0.85;
}

.paralelo-hero__actions {
	display: flex;
	justify-content: center;
	gap: 12px;
}

.paralelo-hero__actions .paralelo-btn-primary,
.paralelo-hero__actions .paralelo-btn-secondary {
	padding: 12px 28px;
}

.paralelo-stats-bar {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	gap: 48px;
	padding: 28px 24px;
	border-bottom: 1px solid var(--paralelo-border);
}

.paralelo-stat {
	text-align: center;
}

.paralelo-stat strong {
	display: block;
	font-size: var(--paralelo-text-lg);
}

.paralelo-stat span {
	font-size: var(--paralelo-text-xs);
	opacity: 0.7;
}

/* NOVO (pedido "Unificar a Largura dos Containers da Home"): fonte
   única da largura de conteúdo da Home — mesmo valor (1100px) já usado
   pelo Header quando "Boxed" (`.paralelo-public-header--boxed
   .paralelo-public-header__inner`, acima), lido de volta por essa regra e
   pelas de largura das secções, abaixo, em vez de "1100px" repetido em
   cada sítio. `--paralelo-home-section-padding` é o padding lateral já
   existente das secções (24px) — usado para calcular o `max-width`
   necessário para o CONTEÚDO (depois de subtrair o padding, com
   `box-sizing: border-box`) ficar exatamente igual ao do Header. */
.paralelo-public {
	--paralelo-home-content-width: 1100px;
	--paralelo-home-section-padding: 24px;
}

.paralelo-public section.paralelo-section {
	margin: 0 auto 60px;
	padding: 0 var(--paralelo-home-section-padding);
}

/* AJUSTADO: `max-width` deixou de ser um valor único e incondicional —
   passa a respeitar a mesma configuração "Boxed"/"Full-Width" do
   Header (`general.header_layout`, ver `HomePage::render()` —
   `.paralelo-public--boxed`/`.paralelo-public--full_width`, aplicada ao
   wrapper da página). "Boxed": `max-width` calculado para o CONTEÚDO
   (já descontado o padding lateral) ficar exatamente com
   `--paralelo-home-content-width` (1100px), igual ao Header. "Full-Width":
   sem limite de largura — mesmo comportamento já existente do próprio
   Header nesse modo (só o padding lateral de sempre, sem "caixa"
   central). */
.paralelo-public--boxed section.paralelo-section {
	max-width: calc(var(--paralelo-home-content-width) + (var(--paralelo-home-section-padding) * 2));
}

.paralelo-public--full_width section.paralelo-section {
	max-width: none;
}

/* Corrige o espaçamento vertical apertado entre o rótulo "CATÁLOGO", o
   título, a descrição e os cards — sem alterar `.paralelo-eyebrow`/
   `.paralelo-section-subtitle` de base (partilhadas com o Dashboard/
   Perfil autenticados, que não têm este problema). */
.paralelo-public section.paralelo-section > .paralelo-eyebrow {
	display: block;
	margin-bottom: 14px;
}

.paralelo-public section.paralelo-section > h2 {
	margin: 0 0 14px;
}

.paralelo-public section.paralelo-section > .paralelo-section-subtitle {
	margin: 0 0 36px;
}

/* NOVO (pedido "Revisão Geral e Otimização Responsiva" — Secção 2:
   "evitar espaçamentos exagerados"): o Hero da Home tinha sempre
   80px de respiro vertical, o mesmo em qualquer ecrã — reduzido em
   tablet/mobile, mesmos breakpoints já usados no resto da folha de
   estilos (900px/600px). */
@media (max-width: 900px) {
	.paralelo-hero {
		padding: 56px 20px;
	}
}

@media (max-width: 600px) {
	.paralelo-hero {
		padding: 40px 16px;
	}

	.paralelo-hero__actions {
		flex-direction: column;
	}

	.paralelo-hero__actions .paralelo-btn-primary,
	.paralelo-hero__actions .paralelo-btn-secondary {
		width: 100%;
	}
}


.paralelo-public-footer {
	text-align: center;
	padding: 32px;
	border-top: 1px solid var(--paralelo-border);
	font-size: var(--paralelo-text-xs);
	opacity: 0.7;
}

.paralelo-public-footer p {
	margin: 0 0 6px;
}

.paralelo-public-footer p:last-child {
	margin-bottom: 0;
}

/* NOVO (pedido "Configurações da Empresa"): linha de copyright sempre
   gerada pelo servidor (nunca texto livre) - ligeiramente mais
   discreta que uma eventual tagline acima dela. */
.paralelo-public-footer__copyright {
	opacity: 0.85;
}

/* NOVO (pedido "Rodapé com links legais"): linha de links centrada,
   com separadores "·" - sem cores/gradiente próprios, usa sempre as
   variáveis de tema já existentes (Claro/Escuro continuam a decidir a
   cor, nunca um valor fixo aqui). */
.paralelo-public-footer__links {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	align-items: center;
	gap: 8px;
	margin: 14px 0;
}

.paralelo-public-footer__links a {
	color: inherit;
	text-decoration: none;
	opacity: 0.85;
}

.paralelo-public-footer__links a:hover,
.paralelo-public-footer__links a:focus-visible {
	opacity: 1;
	text-decoration: underline;
}

.paralelo-public-footer__links span[aria-hidden="true"] {
	opacity: 0.5;
}

.paralelo-public-footer__credit {
	opacity: 0.85;
}

.paralelo-public-footer__credit a {
	color: var(--paralelo-primary, inherit);
	text-decoration: none;
}

.paralelo-public-footer__credit a:hover,
.paralelo-public-footer__credit a:focus-visible {
	text-decoration: underline;
}

.paralelo-public-footer__version {
	opacity: 0.6;
	font-size: 0.9em;
}

/* ---------- Perfil ---------- */

.paralelo-page-header {
	display: flex;
	align-items: flex-start;
	justify-content: space-between;
	gap: 16px;
	margin-bottom: 24px;
	flex-wrap: wrap;
}

.paralelo-page-header h1 {
	margin: 0 0 6px;
}

.paralelo-page-header p {
	margin: 0;
	opacity: 0.7;
	font-size: var(--paralelo-text-sm);
}

.paralelo-page-header .paralelo-btn-primary {
	width: auto;
	padding: 10px 20px;
}

/* NOVO: mensagem amigável para páginas sem conteúdo ainda (Meus Cursos,
   Mais Cursos, Certificados) — nunca uma área vazia sem explicação. */
.paralelo-empty-state {
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 12px;
	padding: 60px 24px;
	border: 1px dashed var(--paralelo-border);
	border-radius: 12px;
	background: var(--paralelo-surface);
}

.paralelo-empty-state .dashicons {
	font-size: 40px;
	width: 40px;
	height: 40px;
	opacity: 0.5;
}

.paralelo-empty-state p {
	margin: 0;
	max-width: 420px;
	opacity: 0.8;
}

.paralelo-empty-state .paralelo-btn-primary {
	width: auto;
	padding: 10px 24px;
}

.paralelo-profile-summary-card {
	display: flex;
	align-items: center;
	gap: 20px;
	background: var(--paralelo-surface);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	padding: 24px;
	margin-bottom: 20px;
}

.paralelo-profile-summary-card__avatar {
	width: 72px;
	height: 72px;
	border-radius: 50%;
	object-fit: cover;
	background: var(--paralelo-border);
}

.paralelo-profile-summary-card h2 {
	margin: 0 0 8px;
	font-size: var(--paralelo-text-md);
}

.paralelo-profile-summary-card__meta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 16px;
	font-size: var(--paralelo-text-xs);
	opacity: 0.85;
}

.paralelo-profile-summary-card__meta span {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}

.paralelo-profile-summary-card__meta .dashicons {
	font-size: 15px;
	width: 15px;
	height: 15px;
}

.paralelo-info-card-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 16px;
	margin-bottom: 24px;
}

.paralelo-info-card {
	background: var(--paralelo-surface);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	padding: 20px 22px;
}

.paralelo-info-card h3 {
	display: flex;
	align-items: center;
	gap: 8px;
	margin: 0 0 16px;
	font-size: var(--paralelo-text-sm);
}

.paralelo-info-card dl {
	margin: 0;
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.paralelo-info-card dt {
	font-size: var(--paralelo-text-xs);
	opacity: 0.6;
	margin: 0 0 2px;
}

.paralelo-info-card dd {
	margin: 0;
	font-size: var(--paralelo-text-sm);
}

/* NOVO (pedido "Página de Preferências do Usuário"): a página reutiliza
   `.paralelo-info-card` (já usado no Painel/Perfil) como cartão de cada
   categoria, mas com `<label>`/`<select>` em vez de `dl/dt/dd` — estas
   regras dão-lhes a mesma aparência (borda, espaçamento, foco) já
   estabelecida para campos de formulário nos cartões de autenticação
   (`.paralelo-auth-card form select`), sem duplicar nenhuma cor/variável
   nova.  */
.paralelo-preferences-form .paralelo-info-card {
	margin-bottom: 16px;
}

.paralelo-preferences-form label {
	display: block;
	font-size: var(--paralelo-text-xs);
	font-weight: 500;
	margin-bottom: 0;
}

.paralelo-preferences-form select {
	display: block;
	width: 100%;
	margin-top: 6px;
	padding: 10px 12px;
	border-radius: 8px;
	border: 1px solid var(--paralelo-border);
	background: var(--paralelo-surface);
	color: var(--paralelo-text);
	font-size: var(--paralelo-text-sm);
	font-family: inherit;
}

.paralelo-preferences-form select:focus {
	outline: 2px solid var(--paralelo-primary);
	outline-offset: 1px;
}

/* AJUSTADO (auditoria "Refinar Preferências"): o campo "Padding dos
   itens de menu" (`sidebar_item_padding`) era o único campo desta
   página sem esta aparência — só o `.paralelo-input-with-suffix`
   (layout flex + unidade "px") o envolvia, sem nenhuma borda/fundo/
   estado de foco próprios. Mesma aparência exacta do `select` acima,
   nunca uma segunda definição de "campo de formulário". O wrapper
   `.paralelo-input-with-suffix` (data-app.css) continua a tratar só do
   layout (input + unidade lado a lado), sem sobrepor nada aqui. */
.paralelo-preferences-form input[type="number"] {
	display: block;
	width: 100%;
	margin-top: 6px;
	padding: 10px 12px;
	border-radius: 8px;
	border: 1px solid var(--paralelo-border);
	background: var(--paralelo-surface);
	color: var(--paralelo-text);
	font-size: var(--paralelo-text-sm);
	font-family: inherit;
}

.paralelo-preferences-form input[type="number"]:focus {
	outline: 2px solid var(--paralelo-primary);
	outline-offset: 1px;
}

.paralelo-preferences-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: 8px;
}

.paralelo-preferences-actions .paralelo-btn-primary,
.paralelo-preferences-actions .paralelo-btn-secondary {
	width: auto;
}

@media (max-width: 600px) {
	.paralelo-preferences-actions {
		flex-direction: column;
	}

	.paralelo-preferences-actions .paralelo-btn-primary,
	.paralelo-preferences-actions .paralelo-btn-secondary {
		width: 100%;
	}
}

.paralelo-edit-section {
	margin-bottom: 24px;
}

.paralelo-edit-section .paralelo-profile-card {
	margin: 0;
}

.paralelo-account-settings h2 {
	margin-bottom: 4px;
}

.paralelo-settings-tiles {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
	gap: 16px;
	margin-top: 16px;
}

@media (max-width: 900px) {
	.paralelo-app-topbar {
		padding: 10px 14px;
		gap: 10px;
	}

	.paralelo-sidebar {
		position: fixed;
		inset: 0 auto 0 0;
		z-index: 210;
		width: min(280px, 84vw);
		transform: translateX(-100%);
		transition: transform 0.2s ease;
		box-shadow: 0 0 40px rgba(0, 0, 0, 0.3);
	}

	.paralelo-sidebar.is-open {
		transform: translateX(0);
	}

	/* NOVO (Secções 9/10 do pedido): botão de fechar dedicado (só faz
	   sentido em mobile/tablet — em desktop a Sidebar já está sempre
	   visível, não há nada para "fechar") e fundo escurecido atrás dela
	   enquanto aberta, com fecho ao tocar fora. */
	.paralelo-sidebar-close {
		display: flex;
		align-items: center;
		justify-content: center;
		width: 32px;
		height: 32px;
		margin-bottom: 12px;
		margin-left: auto;
		border: none;
		border-radius: 8px;
		background: transparent;
		color: inherit;
		cursor: pointer;
	}

	.paralelo-sidebar-close:hover {
		background: rgba(255, 255, 255, 0.08);
	}

	.paralelo-sidebar-backdrop {
		position: fixed;
		inset: 0;
		z-index: 200;
		background: rgba(0, 0, 0, 0.45);
		opacity: 0;
		pointer-events: none;
		transition: opacity 0.2s ease;
	}

	.paralelo-sidebar-backdrop.is-open {
		display: block;
		opacity: 1;
		pointer-events: auto;
	}

	body.paralelo-no-scroll {
		overflow: hidden;
	}

}

/* ---------- Notificações (Fase 8) ---------- */

.paralelo-notifications {
	position: relative;
}

.paralelo-notifications-badge {
	position: absolute;
	top: -4px;
	right: -4px;
	background: #dc2626;
	color: #fff;
	font-size: var(--paralelo-text-xs);
	font-weight: 700;
	line-height: 1;
	padding: 3px 5px;
	border-radius: 999px;
	min-width: 16px;
	text-align: center;
}

.paralelo-notifications-panel {
	position: absolute;
	top: calc(100% + 10px);
	right: 0;
	width: 320px;
	max-height: 420px;
	overflow-y: auto;
	background: var(--paralelo-surface);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	box-shadow: 0 20px 40px rgba(0, 0, 0, 0.25);
	z-index: 50;
}

/* NOVO: aviso inline quando "Marcar todas como lidas" falha (ver
   `showError()` em notifications.js) — nunca substitui a lista, só avisa
   por cima dela, para não dar a entender que a operação funcionou. */
.paralelo-notifications-error {
	margin: 0;
	padding: 10px 16px;
	font-size: var(--paralelo-text-xs);
	color: #ef4444;
	background: rgba(239, 68, 68, 0.1);
	border-bottom: 1px solid var(--paralelo-border);
}

.paralelo-notifications-panel__header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	padding: 14px 16px;
	border-bottom: 1px solid var(--paralelo-border);
}

.paralelo-notifications-panel__header button {
	background: none;
	border: none;
	color: var(--paralelo-links);
	font-size: var(--paralelo-text-xs);
	cursor: pointer;
	padding: 0;
}

.paralelo-notifications-list {
	display: flex;
	flex-direction: column;
}

.paralelo-notifications-empty {
	padding: 20px 16px;
	margin: 0;
	text-align: center;
}

.paralelo-notification {
	display: block;
	padding: 12px 16px;
	border-bottom: 1px solid var(--paralelo-border);
	text-decoration: none;
	color: var(--paralelo-text);
}

.paralelo-notification:last-child {
	border-bottom: none;
}

.paralelo-notification p {
	margin: 0 0 4px;
	font-size: var(--paralelo-text-xs);
}

/* NOVO (pedido "Performance + Ordenação..." — Etapa 6: Modo Offline):
   mesmo padrão visual do sino de Notificações acima — `.paralelo-offline-status`
   é o equivalente posicional de `.paralelo-notifications`, o painel
   reutiliza directamente `.paralelo-notifications-panel`/`.paralelo-notifications-badge`
   (ver Components::offline_badge()), só a lista de itens é que precisa
   de regras próprias (estados pending/syncing/synced/duplicate/error,
   sem equivalente nas notificações). */
.paralelo-offline-status {
	position: relative;
}

.paralelo-offline-list {
	display: flex;
	flex-direction: column;
	margin: 0;
	padding: 0;
	list-style: none;
}

.paralelo-offline-item {
	padding: 12px 16px;
	border-bottom: 1px solid var(--paralelo-border);
	display: flex;
	flex-direction: column;
	gap: 6px;
	font-size: var(--paralelo-text-xs);
}

.paralelo-offline-item:last-child {
	border-bottom: none;
}

.paralelo-offline-item--empty {
	text-align: center;
	opacity: 0.7;
}

.paralelo-offline-item__status {
	font-size: var(--paralelo-text-xs);
	font-weight: 600;
	width: fit-content;
	padding: 2px 8px;
	border-radius: 999px;
}

.paralelo-offline-item--pending .paralelo-offline-item__status {
	background: rgba(234, 179, 8, 0.15);
	color: #eab308;
}

.paralelo-offline-item--syncing .paralelo-offline-item__status {
	background: rgba(99, 102, 241, 0.15);
	color: var(--paralelo-primary);
}

.paralelo-offline-item--synced .paralelo-offline-item__status {
	background: rgba(34, 197, 94, 0.15);
	color: #22c55e;
}

.paralelo-offline-item--duplicate .paralelo-offline-item__status,
.paralelo-offline-item--error .paralelo-offline-item__status {
	background: rgba(239, 68, 68, 0.15);
	color: #ef4444;
}

.paralelo-offline-item button {
	align-self: flex-start;
	font-size: var(--paralelo-text-xs);
	padding: 4px 10px;
}

.paralelo-offline-sync-btn {
	display: block;
	width: calc(100% - 32px);
	margin: 12px 16px;
}

.paralelo-notification time {
	font-size: var(--paralelo-text-xs);
	opacity: 0.6;
}

.paralelo-notification.is-unread {
	background: rgba(99, 102, 241, 0.08);
}

.paralelo-notification.is-unread p {
	font-weight: 600;
}

/* NOVO: popover de perfil — reutiliza `.paralelo-notifications-panel` (mesmo
   padrão visual) e `.paralelo-notification` para as duas linhas de ação
   ("Ver Perfil Completo" / "Sair da conta"), só com o necessário próprio
   (cabeçalho com avatar+nome lado a lado, em vez do espaçamento entre
   título e botão usado nas notificações; ícone e cor do link de logout). */
.paralelo-user-popover__header {
	justify-content: flex-start;
	gap: 10px;
}

.paralelo-user-popover__link .dashicons {
	font-size: 16px;
	width: 16px;
	margin-right: 6px;
	vertical-align: text-bottom;
}

.paralelo-user-popover__link:hover {
	background: var(--paralelo-bg);
}

/* ---------- Dados Geográficos (transformação Paralelo) ---------- */

.paralelo-btn-danger {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	padding: 13px 18px;
	border-radius: 8px;
	border: 1px solid #dc2626;
	background: transparent;
	color: #dc2626;
	font-size: var(--paralelo-text-sm);
	font-weight: 600;
	cursor: pointer;
	font-family: inherit;
	text-decoration: none;
}

.paralelo-btn-danger:hover {
	background: #dc2626;
	color: #fff;
}

.paralelo-btn-danger:disabled {
	opacity: 0.6;
	cursor: not-allowed;
}

/* Popup de "possível duplicação" (Requisito 8) — o Front-End não carrega
   `wp.components` (só o admin), por isso o modal é HTML/CSS próprio,
   mostrado/escondido por `data-app.js`. */
.paralelo-modal-backdrop {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0.55);
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 20px;
	z-index: 10000;
}

/* AJUSTADO (Parte 3, Requisito 24 — "modais e drawers... o mesmo
   padrão"): junta-se a `.paralelo-scrollbar-thin` na prática (mesmas 4
   regras) sem precisar de acrescentar a classe à marcação — o selector
   composto abaixo aplica-lhe directamente os mesmos valores. */
.paralelo-modal {
	width: 100%;
	max-width: 480px;
	max-height: 80vh;
	overflow-y: auto;
	background: var(--paralelo-surface);
	border-radius: 14px;
	padding: 28px;
	box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
	scrollbar-width: thin;
	scrollbar-color: var(--paralelo-border) transparent;
}

.paralelo-modal::-webkit-scrollbar {
	width: 6px;
}

.paralelo-modal::-webkit-scrollbar-track {
	background: transparent;
}

.paralelo-modal::-webkit-scrollbar-thumb {
	background-color: var(--paralelo-border);
	border-radius: 3px;
}

.paralelo-modal h2 {
	margin: 0 0 12px;
	font-size: var(--paralelo-text-md);
}

.paralelo-modal ul {
	margin: 12px 0 0;
	padding-left: 20px;
	list-style: disc;
}

.paralelo-modal li {
	margin-bottom: 6px;
	font-size: var(--paralelo-text-sm);
}

.paralelo-modal-actions {
	display: flex;
	gap: 10px;
	margin-top: 20px;
}

.paralelo-user-popover__logout {
	color: #ef4444;
}

/* CORRIGIDO (auditoria "Popup de Notificações — Mobile"): causa real —
   `.paralelo-notifications-panel` usava `position: absolute; right: 0;
   width: 320px`, sempre relativo ao próprio ícone do sino (um botão de
   36px), nunca ao ecrã. Como o sino não fica junto à margem direita
   real (há mais ícones depois dele — tema, preferências, avatar), um
   painel de 320px a abrir para a esquerda a partir dessa posição podia
   ultrapassar a margem esquerda do ecrã em qualquer largura estreita —
   a correção anterior (só ≤380px, só a largura) reduzia o sintoma sem
   corrigir a causa, e não cobria tablets/telemóveis maiores (390px,
   430px, 768px, todos > 380px).
   Corrigido com `position: fixed` (relativo ao VIEWPORT, nunca ao
   ícone) e margens fixas dos dois lados — o painel fica sempre dentro
   do ecrã, com a mesma largura disponível independentemente de onde o
   sino estiver posicionado. `env(safe-area-inset-*)` respeita entalhes/
   Ilha Dinâmica em iPhones recentes. Desktop (>900px) preservado, sem
   nenhuma alteração — continua `position: absolute` relativo ao ícone,
   comportamento de sempre. Aplica-se também a `.paralelo-user-popover__panel`
   (popover do perfil), que reutiliza esta mesma classe — mesma causa,
   mesma correção, sem duplicar regras. */
@media (max-width: 900px) {
	.paralelo-notifications-panel {
		position: fixed;
		top: 60px;
		left: calc(12px + env(safe-area-inset-left, 0px));
		right: calc(12px + env(safe-area-inset-right, 0px));
		width: auto;
		max-width: none;
		max-height: calc(100vh - 80px);
	}
}

/* ---------- Chat de suporte (Fase 9) ---------- */

/* CORRIGIDO (correções finais 1.0 — Ponto 1, "ícone de Chat não
   aparece"): z-index era 200, mais baixo do que `.paralelo-cookie-bar`
   (400) e `.paralelo-install-banner` (399) — ambas faixas fixas no fundo
   do ecrã, com largura suficiente para cobrir o canto inferior
   direito em ecrãs mais estreitos. Não era a única causa possível
   (ver relatório), mas era um problema real e confirmado: sempre que
   uma dessas faixas estivesse visível, ficava por cima do botão do
   Chat, tornando-o inacessível/invisível nesse momento. */
.paralelo-chat-widget {
	position: fixed;
	right: 20px;
	bottom: 20px;
	z-index: 500;
}

.paralelo-chat-widget__toggle {
	position: relative;
	width: 56px;
	height: 56px;
	border-radius: 50%;
	border: none;
	background: var(--paralelo-primary);
	color: #fff;
	cursor: pointer;
	box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
	display: flex;
	align-items: center;
	justify-content: center;
}

.paralelo-chat-widget__toggle .dashicons {
	font-size: 24px;
	width: 24px;
	height: 24px;
}

.paralelo-chat-widget__toggle .paralelo-notifications-badge {
	top: -2px;
	right: -2px;
}

.paralelo-chat-widget__panel {
	position: absolute;
	right: 0;
	bottom: calc(100% + 12px);
	width: 320px;
	height: 420px;
	display: flex;
	flex-direction: column;
	background: var(--paralelo-surface);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
	overflow: hidden;
}

/* CORRIGIDO: o atributo `hidden` do HTML tem a mesma especificidade que a
   classe acima (0,0,1,0) — sem este seletor combinado, `display: flex`
   ganhava sempre ao `display: none` do `[hidden]` nativo (a folha de
   estilo do autor carrega depois da folha do navegador), e o painel do
   chat ficava sempre visível, independentemente do JS abrir/fechar. */
.paralelo-chat-widget__panel[hidden] {
	display: none;
}

.paralelo-chat-widget__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 14px 16px;
	border-bottom: 1px solid var(--paralelo-border);
}

.paralelo-chat-widget__header button {
	background: none;
	border: none;
	font-size: 20px;
	line-height: 1;
	cursor: pointer;
	color: var(--paralelo-text);
}

.paralelo-chat-widget__messages {
	flex: 1;
	overflow-y: auto;
	padding: 14px 16px;
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.paralelo-chat-message {
	max-width: 85%;
	padding: 8px 12px;
	border-radius: 12px;
	font-size: var(--paralelo-text-xs);
}

.paralelo-chat-message p {
	margin: 0 0 2px;
}

.paralelo-chat-message time {
	font-size: var(--paralelo-text-xs);
	opacity: 0.6;
}

.paralelo-chat-message.is-self {
	align-self: flex-end;
	background: var(--paralelo-primary);
	color: #fff;
}

.paralelo-chat-message.is-staff {
	align-self: flex-start;
	background: var(--paralelo-bg);
	border: 1px solid var(--paralelo-border);
}

/* AJUSTADO: campo e botão passam de lado-a-lado para bloco vertical —
   textarea em cima, botão "Enviar" alinhado à direita por baixo dela. */
.paralelo-chat-widget__form {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 12px;
	border-top: 1px solid var(--paralelo-border);
}

/* CORRIGIDO: campo de digitação demasiado pequeno (1 linha fixa). Agora
   nasce com altura para ~3-4 linhas (`min-height`) e cresce sozinho
   conforme se escreve (ver `autoGrowChatTextarea()` em chat.js), até um
   limite (`max-height`) que passa a fazer scroll interno em vez de
   continuar a crescer indefinidamente. `width: 100%` é seguro contra
   overflow horizontal graças ao `box-sizing: border-box` global no topo
   deste ficheiro. */
.paralelo-chat-widget__form textarea {
	width: 100%;
	resize: none;
	border-radius: 8px;
	border: 1px solid var(--paralelo-border);
	background: transparent;
	color: var(--paralelo-text);
	font-family: inherit;
	font-size: var(--paralelo-text-sm);
	line-height: 1.5;
	padding: 10px 12px;
	min-height: 88px;
	max-height: 160px;
	overflow-y: auto;
}

/* AJUSTADO: o botão reutiliza a classe partilhada `.paralelo-btn-primary` do
   Design System (mesma cor/tipografia/raio dos outros CTAs da plataforma)
   — esta classe só acrescenta o que é específico deste botão (posição,
   ícone, hover, foco, loading), sem tocar em `.paralelo-btn-primary`
   globalmente (evita alterar todos os outros botões do site). */
.paralelo-chat-widget__send {
	align-self: flex-end;
	gap: 6px;
}

.paralelo-chat-widget__send .dashicons {
	font-size: 16px;
	width: 16px;
	height: 16px;
}

.paralelo-chat-widget__send:hover:not(:disabled) {
	background: var(--paralelo-secondary);
}

.paralelo-chat-widget__send:focus-visible {
	outline: 2px solid var(--paralelo-primary);
	outline-offset: 2px;
}

.paralelo-chat-widget__send.is-loading {
	cursor: wait;
}

@media (max-width: 480px) {
	.paralelo-chat-widget__panel {
		width: calc(100vw - 40px);
	}
}

/* ---------- Barra de Notificação (top_bar) ---------- */

.paralelo-top-bar {
	padding: 10px 24px;
	text-align: center;
}

.paralelo-top-bar__inner {
	max-width: 1200px;
	margin: 0 auto;
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 16px;
	flex-wrap: wrap;
}

.paralelo-top-bar__text {
	font-size: var(--paralelo-text-sm);
	font-weight: 500;
}

.paralelo-top-bar__button {
	display: inline-block;
	padding: 6px 16px;
	border-radius: 999px;
	color: #fff;
	text-decoration: none;
	font-size: var(--paralelo-text-xs);
	font-weight: 600;
	white-space: nowrap;
}

/* ---------- Política de Privacidade / Termos e Condições ---------- */

.paralelo-legal-page {
	max-width: 760px;
	margin: 0 auto;
	padding: 48px 24px 80px;
	line-height: 1.7;
}

.paralelo-legal-page h1 {
	margin: 0 0 28px;
}

.paralelo-legal-content h2 {
	font-size: var(--paralelo-text-lg);
	margin: 32px 0 12px;
}

.paralelo-legal-content h2:first-child {
	margin-top: 0;
}

.paralelo-legal-content p {
	margin: 0 0 14px;
	opacity: 0.9;
}

.paralelo-legal-content ul {
	margin: 0 0 14px;
	padding-left: 22px;
}

.paralelo-legal-content li {
	margin-bottom: 6px;
	opacity: 0.9;
}

.paralelo-legal-content em {
	display: block;
	padding: 12px 16px;
	background: var(--paralelo-surface);
	border: 1px dashed var(--paralelo-border);
	border-radius: 8px;
	font-style: normal;
	font-size: var(--paralelo-text-xs);
	opacity: 0.8;
	margin-bottom: 20px;
}

@media (max-width: 600px) {
	.paralelo-legal-page {
		padding: 32px 16px 60px;
	}
}

/* ---------- Barra de Cookies ---------- */

.paralelo-cookie-bar {
	position: fixed;
	left: 16px;
	right: 16px;
	bottom: 16px;
	z-index: 400;
	max-width: 720px;
	margin: 0 auto;
	background: var(--paralelo-surface);
	color: var(--paralelo-text);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25);
	padding: 20px 22px;
}

.paralelo-cookie-bar h2 {
	margin: 0 0 8px;
	font-size: var(--paralelo-text-md);
}

.paralelo-cookie-bar p {
	margin: 0 0 16px;
	font-size: var(--paralelo-text-sm);
	opacity: 0.85;
	line-height: 1.6;
}

.paralelo-cookie-bar p a {
	color: var(--paralelo-links);
}

.paralelo-cookie-bar__actions {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
}

.paralelo-cookie-bar__actions .paralelo-btn-primary,
.paralelo-cookie-bar__actions .paralelo-btn-secondary {
	width: auto;
	padding: 9px 22px;
}

/* NOVO (finalização 1.0.0 — Fase 6.3, "PWA — Instalação"): faixa
   discreta no fundo do ecrã, nunca um popup/modal invasivo — criada
   dinamicamente por `pwa-install.js` só quando o navegador confirma
   suporte real de instalação (`beforeinstallprompt`). Mesmo padrão
   visual já usado por `.paralelo-cookie-bar` acima. */
.paralelo-install-banner {
	position: fixed;
	left: 16px;
	right: 16px;
	bottom: 16px;
	z-index: 399;
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	max-width: 480px;
	margin: 0 auto;
	padding: 14px 16px;
	background: var(--paralelo-surface);
	color: var(--paralelo-text);
	border: 1px solid var(--paralelo-border);
	border-radius: 12px;
	box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25);
}

.paralelo-install-banner__text {
	font-size: var(--paralelo-text-sm);
	flex: 1 1 200px;
}

.paralelo-install-banner__actions {
	display: flex;
	align-items: center;
	gap: 8px;
}

.paralelo-install-banner__actions .paralelo-btn-primary {
	width: auto;
	padding: 9px 18px;
}

.paralelo-install-banner__dismiss {
	background: none;
	border: none;
	font-size: 20px;
	line-height: 1;
	opacity: 0.6;
	cursor: pointer;
	padding: 4px 8px;
	color: inherit;
}

.paralelo-install-banner__dismiss:hover {
	opacity: 1;
}

@media (max-width: 480px) {
	.paralelo-install-banner {
		flex-direction: column;
		align-items: stretch;
	}
}

/* ---------- Esqueci Minha Senha / Login ---------- */

/* CORRIGIDO (finalização 1.0.0 — Fase 4.1): margem superior NEGATIVA
   colava este link ao campo de senha logo acima, e só 4px o separavam
   do botão "Entrar" abaixo — espaçamento respirável dos dois lados. */
.paralelo-auth-forgot {
	margin: 10px 0 20px;
	text-align: right;
	font-size: var(--paralelo-text-xs);
}

.paralelo-auth-forgot a {
	color: var(--paralelo-links);
	text-decoration: none;
}

.paralelo-auth-forgot a:hover {
	text-decoration: underline;
}

/* Medidor de força de senha (página "Escolher Nova Senha") — heurística
   só do lado do cliente, para dar feedback imediato; a regra que
   realmente decide se a senha é aceite continua a ser validada no
   Backend (ver `AuthController::reset_password()`). */
/* CORRIGIDO (finalização 1.0.0 — Fase 4.1): mesma classe de bug do
   `.paralelo-auth-forgot` acima — margem superior negativa, que agora
   colidiria ainda mais com o espaçamento maior entre campos (Fase
   4.1). O campo "Nova Senha" logo acima já tem `margin-bottom: 20px`
   (regra partilhada de `form label`), suficiente por si só — só
   precisa de uma margem inferior consistente antes de "Confirmar Nova
   Senha". */
.paralelo-password-strength {
	margin: 0 0 20px;
	display: flex;
	align-items: center;
	gap: 8px;
}

.paralelo-password-strength__bar {
	flex: 1;
	height: 6px;
	border-radius: 999px;
	background: var(--paralelo-border);
	overflow: hidden;
}

.paralelo-password-strength__bar span {
	display: block;
	height: 100%;
	width: 0;
	border-radius: 999px;
	transition: width 0.2s ease, background 0.2s ease;
	background: #ef4444;
}

.paralelo-password-strength[data-level='medium'] .paralelo-password-strength__bar span {
	background: #f59e0b;
}

.paralelo-password-strength[data-level='strong'] .paralelo-password-strength__bar span {
	background: #22c55e;
}

.paralelo-password-strength__label {
	font-size: var(--paralelo-text-xs);
	opacity: 0.75;
	white-space: nowrap;
}

/* ---------- Timeout por Inatividade ---------- */

.paralelo-inactivity-modal {
	position: fixed;
	inset: 0;
	z-index: 500;
	display: flex;
	align-items: center;
	justify-content: center;
	background: rgba(0, 0, 0, 0.55);
	padding: 20px;
}

.paralelo-inactivity-modal__card {
	background: var(--paralelo-surface);
	color: var(--paralelo-text);
	border-radius: 12px;
	padding: 28px 26px;
	max-width: 380px;
	width: 100%;
	text-align: center;
	box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
}

.paralelo-inactivity-modal__card h2 {
	margin: 0 0 12px;
	font-size: var(--paralelo-text-lg);
}

.paralelo-inactivity-modal__card p {
	margin: 0 0 20px;
	opacity: 0.85;
	line-height: 1.5;
}

.paralelo-inactivity-modal__actions {
	display: flex;
	justify-content: center;
}

.paralelo-inactivity-modal__actions .paralelo-btn-primary {
	width: auto;
	padding: 11px 28px;
}

@media (max-width: 600px) {
	.paralelo-inactivity-modal__card {
		padding: 22px 20px;
	}
}

