/*
  Estilos do App. Todos os valores vêm dos tokens da RCL partilhada (brand.css + produto.css, DEC-009).
  Onde o design system se cala, o valor está agrupado em --auth-* / --shell-* abaixo, com o DEC- que o cobre — para
  desaparecerem num sítio só quando as decisões fecharem, em vez de estarem espalhados pelos ecrãs.
*/

:root {
  /* Sem token — ver DEC-003 (campos) e DEC-029 (moldura). */
  --auth-card-width: 360px;
  --auth-gap-xs: 8px;
  /*
    Respiro do cartão e forma do botão, alinhados com o CRM legado por pedido de 2026-07-30. Nenhum dos quatro
    valores tem token: 40 e 28 caem entre --space-lg e --space-xl e entre --space-md e --space-lg (DEC-006), e o
    botão passa a 16px, um corpo que a escala tipográfica não tem. Ver DEC-033.
  */
  --auth-card-padding: 40px 28px;
  --auth-submit-padding: 9px 24px;
  --auth-submit-font: 600 16px var(--font-heading);
  /* Botão de ver a palavra-passe: proposta de ecras/login.md, sem mockup que a apoie. Ver DEC-003 e DEC-004. */
  --auth-toggle-size: 24px;
  --auth-toggle-icon-size: 20px;
  --auth-toggle-clearance: 42px;
  --shell-topbar-height: 64px;
  --shell-avatar-size: 36px;
}

/* ---------------------------------------------------------------- base */

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font: var(--text-h4);
  color: var(--color-text-primary);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
p,
ul {
  margin: 0;
}

ul {
  padding: 0;
  list-style: none;
}

/* Confirmado em 2026-07-30 (B1): 1px, --color-focus. O offset não veio na resposta e mantém-se o interim de 2px. */
:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus);
  outline-offset: 2px;
}

/*
  Excepção ao anel de B1. O <FocusOnNavigate> do App.razor põe o foco no <h1> a cada navegação — é o que anuncia a
  mudança de página a quem usa leitor de ecrã —, e o Blazor dá-lhe tabindex="-1" para o conseguir focar. Como o foco
  não veio de um clique, o Chrome trata-o como :focus-visible e desenha o anel à volta do título, no primeiro render
  e até se tocar noutra coisa. Nada com tabindex="-1" é alcançável por Tab, portanto o anel ali nunca marca um sítio
  onde alguém possa aterrar a navegar: esconder é gratuito, e o anúncio ao leitor de ecrã mantém-se.
*/
[tabindex="-1"]:focus-visible {
  outline: none;
}

.boot {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  font: var(--text-h4);
  color: var(--color-text-secondary);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  padding: var(--auth-gap-xs) var(--space-sm);
  font: var(--text-h4);
  color: var(--color-text-primary);
  background: var(--color-white);
  border-radius: var(--radius-sm);
}

.skip-link:focus-visible {
  left: var(--space-sm);
  top: var(--space-sm);
}

/* ---------------------------------------------------------------- autenticação */

/*
  Ancorado ao topo, e não centrado como o mockup mostra: ver DEC-031. O mockup foi desenhado a 1440×912 (rácio 1,58)
  e um ecrã real é mais largo e mais baixo — a fotografia é `cover`, o recorte come parede em cima e em baixo, e a
  1920×893 o sofá sobe até ficar atrás do cartão, branco contra branco. Os --space-lg de topo já vêm do padding.
*/
.auth {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  min-height: 100dvh;
  padding: var(--space-lg) var(--space-sm);
  background: url("images/login-fundo-sala-de-estar.jpg") center / cover no-repeat;
}

/*
  A largura vive aqui, e não no cartão, de propósito: a coluna é dimensionada pelo conteúdo, portanto um
  `width: min(360px, 100%)` no cartão resolvia os 100% contra a largura que o próprio cartão acabava de definir
  e colapsava-o para o texto mais largo lá dentro (255px, com o título a mandar). Fixa aqui, o cartão preenche-a.
*/
.auth__block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  width: min(var(--auth-card-width), 100%);
  animation: auth-enter .5s ease;
}

.auth__logo {
  width: 150px;
  height: auto;
}

.auth__card {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  width: 100%;
  padding: var(--auth-card-padding);
  background: var(--color-white);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-overlay);
}

.auth__title {
  font: var(--text-h1);
  color: var(--color-text-primary);
  text-align: center;
}

.auth__hint {
  font: var(--text-h4);
  color: var(--color-text-secondary);
  text-align: center;
}

/* Sem min-height reservado: a designer respondeu que o formulário salta quando o erro aparece (C1). */
.auth__error {
  font: var(--text-h4);
  font-size: 12px;
  color: var(--color-red-text);
}

.auth__row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.auth__recover {
  font: var(--text-h4);
  color: var(--color-blue-text);
  text-underline-offset: 2px;
}

/* componentes.md#entrar — o fundo é --color-red-surface, a correcção de contraste confirmada em A2. */
.auth__submit {
  padding: var(--auth-submit-padding);
  font: var(--auth-submit-font);
  color: var(--color-white);
  text-align: center;
  text-decoration: none;
  background: var(--color-red-surface);
  border: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  /* O legado usa `all 0.3s ease`; aqui só a cor, para não animar também a geometria a cada mudança de layout. */
  transition: background-color .3s ease;
}

.auth__submit:hover:not(:disabled) {
  background: var(--color-red-surface-hover);
}

.auth__submit:disabled {
  color: var(--color-text-secondary);
  background: var(--color-border-divider);
  cursor: not-allowed;
}

.auth__card--rejected {
  animation: auth-shake .45s ease;
}

/* ---------------------------------------------------------------- campos */

/* componentes.md#campo-de-texto — altura, raio e padding confirmados em C1 (2026-07-30). */
.field {
  display: flex;
  flex-direction: column;
  gap: var(--auth-gap-xs);
}

.field__label {
  font: var(--text-h4);
  color: var(--color-text-primary);
}

.field__label span {
  color: var(--color-red);
  font-weight: 700;
}

.field__input {
  width: 100%;
  height: var(--field-height);
  padding: 0 var(--field-padding);
  font: var(--field-font);
  color: var(--color-text-primary);
  background: var(--color-white);
  /* --color-border-control, e não --color-border-input: 3.41:1 ainda passa 1.4.11 e é o tom da pesquisa. Ver DEC-032. */
  border: 1px solid var(--color-border-control);
  border-radius: var(--field-radius);
}

.field__input::placeholder {
  color: var(--color-text-secondary);
}

.field__input[aria-invalid="true"] {
  border-color: var(--color-red-text);
}

/* Botão de ver a palavra-passe — ecras/login.md#campos: 24×24px, a 12px da direita, centrado na vertical. */
.field__box {
  position: relative;
}

.field__input--with-toggle {
  padding-right: var(--auth-toggle-clearance);
}

.field__toggle {
  position: absolute;
  top: 50%;
  right: var(--field-padding);
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--auth-toggle-size);
  height: var(--auth-toggle-size);
  padding: 0;
  font-size: var(--auth-toggle-icon-size);
  color: var(--color-text-secondary);
  background: none;
  border: none;
  transform: translateY(-50%);
  cursor: pointer;
}

.field__toggle:hover {
  color: var(--color-text-primary);
}

/* ---------------------------------------------------------------- moldura */

.shell {
  display: flex;
  min-height: 100dvh;
}

.shell__main {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

.shell__content {
  flex: 1;
  padding: var(--space-lg);
}

.sidebar {
  display: flex;
  flex-direction: column;
  flex: 0 0 var(--sidebar-width);
  width: var(--sidebar-width);
  padding: var(--space-sm) 0;
  background: var(--color-white);
  border-right: 1px solid var(--color-border-divider);
}

.sidebar__logo {
  width: 120px;
  height: auto;
  margin: 0 var(--space-sm) var(--space-lg);
}

.sidebar__sections {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.sidebar__item,
.sidebar__group {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px var(--space-sm);
  font: var(--text-h4);
  color: var(--color-text-primary);
  text-align: left;
  text-decoration: none;
  background: none;
  border: none;
  cursor: pointer;
}

.sidebar__item:hover,
.sidebar__group:hover {
  background: var(--color-bg);
}

/*
  tokens.md atribui --color-red à seleção do menu principal. Como texto sobre branco dá 3.41:1 e falha AA — é a mesma
  falha que A2 corrigiu nos botões, sem cobrir este papel por nome. O peso 600 acompanha para a selecção não depender
  só da cor. Ver DEC-029.
*/
.sidebar__item--active {
  color: var(--color-red);
  font-weight: 600;
}

.sidebar__chevron {
  margin-left: auto;
  transition: transform .2s ease;
}

.sidebar__group[aria-expanded="true"] .sidebar__chevron {
  transform: rotate(90deg);
}

.sidebar__items {
  display: flex;
  flex-direction: column;
}

.sidebar__subitem {
  display: block;
  padding: 8px var(--space-sm) 8px 52px;
  font: var(--text-h4);
  color: var(--color-text-primary);
  text-decoration: none;
}

.sidebar__subitem:hover {
  background: var(--color-bg);
}

.sidebar__subitem--active {
  color: var(--color-info-text);
  background: var(--color-info-bg);
}

/* Item sem ecrã: visivelmente indisponível, e nem sequer é uma ligação. Ver DEC-029. */
.sidebar__subitem--absent {
  color: var(--color-text-secondary);
  cursor: default;
}

.sidebar__subitem--absent:hover {
  background: none;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  height: var(--shell-topbar-height);
  padding: 0 var(--space-lg);
  background: var(--color-white);
  border-bottom: 1px solid var(--color-border-divider);
}

/* componentes.md#campo-de-pesquisa — confirmado em C1. */
.search {
  display: flex;
  align-items: center;
  gap: var(--auth-gap-xs);
  width: var(--search-width);
  height: var(--search-height);
  padding: 0 var(--auth-gap-xs);
  color: var(--color-text-tertiary);
  background: var(--color-white);
  border: 1px solid var(--color-border-control);
  border-radius: var(--radius-pill);
}

.search__input {
  flex: 1;
  min-width: 0;
  font: var(--text-h4);
  color: var(--color-text-primary);
  background: none;
  border: none;
}

.search__input::placeholder {
  color: var(--color-text-tertiary);
}

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

.account__identity {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

.account__name {
  font: var(--text-h3);
  color: var(--color-text-primary);
}

.account__roles {
  font: var(--text-h4);
  font-size: 12px;
  color: var(--color-text-secondary);
}

.account__avatar {
  width: var(--shell-avatar-size);
  height: var(--shell-avatar-size);
  object-fit: cover;
  background: var(--color-bg);
  border-radius: 50%;
}

/* componentes.md#cancelar-outline--ghost */
.account__logout {
  padding: 8px 16px;
  font: 400 13px var(--font-body);
  color: var(--color-text-primary);
  background: transparent;
  border: 1px solid var(--color-border-control);
  border-radius: var(--radius-pill);
  cursor: pointer;
}

.account__logout:hover {
  background: var(--color-bg);
}

/* ---------------------------------------------------------------- páginas */

.page__title {
  font: var(--text-h1);
  color: var(--color-text-primary);
}

.page__empty {
  margin-top: var(--space-sm);
  font: var(--text-h4);
  color: var(--color-text-secondary);
}

/* ---------------------------------------------------------------- movimento */

@keyframes auth-enter {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes auth-shake {
  0%, 100% { transform: translateX(0); }
  15%      { transform: translateX(-8px); }
  30%      { transform: translateX(8px); }
  45%      { transform: translateX(-6px); }
  60%      { transform: translateX(6px); }
  75%      { transform: translateX(-3px); }
  90%      { transform: translateX(3px); }
}

@media (prefers-reduced-motion: reduce) {
  .auth__block,
  .auth__card--rejected,
  .auth__submit,
  .sidebar__chevron {
    animation: none;
    transition: none;
  }
}

/* ---------------------------------------------------------------- erro do runtime */

#blazor-error-ui {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 20;
  padding: var(--space-sm) var(--space-md);
  font: var(--text-h4);
  color: var(--color-red-text);
  background: var(--color-error-bg);
  box-shadow: var(--shadow-overlay);
}

#blazor-error-ui .dismiss {
  float: right;
  cursor: pointer;
}
