/* styles/lifematch-user-ui.css
   ────────────────────────────────────────────────────────────────
   Fundação visual do LifeMatch — CAMADA DE UI COMPARTILHADA.
   Ciclo 2A (Investor Ready). Depende de styles/lifematch-tokens.css.

   Camada ADITIVA e enxuta: não substitui styles/lifematch-theme.css
   (a biblioteca de componentes mobile já existente). Centraliza o
   boilerplate que hoje está duplicado em cada página (fonte, ícones,
   spinner, foco visível) e adiciona só os componentes gerais realmente
   usados pelas páginas piloto: canvas de desktop, elevação do shell e
   alerta/feedback.
   ──────────────────────────────────────────────────────────────── */

/* ── Baseline compartilhado (antes duplicado em cada <style> inline) ── */
body {
  font-family: var(--lm-font-family);
  color: var(--lm-color-text);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.material-symbols-outlined {
  font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}

/* Spinner inline (usado nos botões de login) — antes definido em cada página */
.spinner {
  display: inline-block; width: 18px; height: 18px;
  border: 2px solid rgba(255, 255, 255, .4); border-top-color: #fff;
  border-radius: var(--lm-radius-pill);
  animation: lm-spin .7s linear infinite;
  vertical-align: middle; margin-right: 6px;
}
@keyframes lm-spin { to { transform: rotate(360deg); } }
/* Compat: páginas que referenciam a animação legada `spin` continuam válidas */
@keyframes spin { to { transform: rotate(360deg); } }

/* ── Foco visível consistente (acessibilidade) ─────────────────────
   Baseline geral para teclado; não afeta clique de mouse (:focus-visible). */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: var(--lm-focus-ring);
  outline-offset: var(--lm-focus-offset);
}

/* ── Canvas de desktop ─────────────────────────────────────────────
   O app do LifeMatch é um shell mobile centralizado (max-width 28rem).
   Em telas largas, sem tratamento, ele fica como uma coluna estreita
   sobre fundo cru ("aparência mobile"). Aqui o shell passa a flutuar
   sobre uma superfície de marca discreta, com profundidade — premium,
   sem alterar em nada o layout mobile (< 768px). */
@media (min-width: 768px) {
  body.lm-app-canvas {
    min-height: 100dvh;
    background:
      radial-gradient(130% 70% at 50% -10%, var(--lm-canvas-tint), transparent 60%),
      var(--lm-color-canvas);
  }

  /* Eleva o shell centralizado (index, login, conteúdos, eventos). */
  .lm-app-canvas .lm-shell {
    box-shadow: var(--lm-shadow-float);
    border-radius: var(--lm-radius-2xl);
    overflow: hidden;
  }

  /* Respiro vertical para o shell não colar no topo/rodapé da janela. */
  .lm-app-canvas .lm-shell--framed {
    margin-top: var(--lm-space-5);
    margin-bottom: var(--lm-space-5);
    min-height: calc(100dvh - (2 * var(--lm-space-5)));
  }
}

/* ── Alerta / feedback (erro, atenção, sucesso) ────────────────────
   Componente de mensagem associada a um contexto (ex.: erro de login).
   Preferir preenchimento via textContent (nunca innerHTML com dado do
   usuário). Usa role="alert" + aria-live no HTML. */
.lm-alert {
  display: flex; align-items: flex-start; gap: var(--lm-space-2);
  padding: 11px 13px;
  border-radius: var(--lm-radius-md);
  font-size: var(--lm-text-sm);
  line-height: var(--lm-leading-snug);
  border: 1px solid transparent;
}
.lm-alert .material-symbols-outlined { font-size: 19px; flex: 0 0 auto; margin-top: 1px; }
.lm-alert--error {
  color: var(--lm-color-error);
  background: var(--lm-color-error-soft);
  border-color: var(--lm-color-error-border);
}
.lm-alert--warning {
  color: var(--lm-color-warning);
  background: var(--lm-color-warning-soft);
  border-color: var(--lm-color-warning-border);
}
.lm-alert--success {
  color: var(--lm-color-success);
  background: var(--lm-color-success-soft);
  border-color: var(--lm-color-success-border);
}

/* Estado utilitário para esconder o alerta sem remover do DOM (a11y-safe).
   Mantém compatibilidade com o utilitário .hidden do Tailwind. */
.lm-alert[hidden] { display: none; }

/* ── Respeito a prefers-reduced-motion ─────────────────────────────
   Desliga animações e transições para quem pediu menos movimento. */
@media (prefers-reduced-motion: reduce) {
  .spinner,
  .lm-spinner { animation-duration: .001ms; animation-iteration-count: 1; }
  *, *::before, *::after {
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ════════════════════════════════════════════════════════════════════
   Ciclo 2B — Descoberta, conexão e perfis
   Aditivo sobre o 2A. Reutiliza .lm-app-canvas / .lm-shell. Não redefine
   componentes do tema (.lm-list-card, .lm-sheet, .lm-profile-*). Só o que
   as páginas desta rodada realmente usam.
   ════════════════════════════════════════════════════════════════════ */

/* ── Grid de resultados ────────────────────────────────────────────
   Mobile: coluna única (substitui o space-y sem quebrar a semântica).
   Desktop largo: 2 colunas, aproveitando o espaço. */
.lm-results-grid { display: flex; flex-direction: column; gap: var(--lm-space-3); }
/* Seções de perfil: pilha no mobile, 2 colunas no desktop (hero full-width) */
.lm-profile-grid { display: flex; flex-direction: column; gap: var(--lm-space-4); }

/* ── Skeleton de carregamento ──────────────────────────────────────
   Reflete aproximadamente a estrutura real; some quando o dado chega
   (o container de loading é ocultado pela página). Distinto de vazio/erro. */
.lm-skeleton {
  position: relative; overflow: hidden;
  background: var(--lm-color-border-faint);
  border-radius: var(--lm-radius-sm);
}
.lm-skeleton::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .65), transparent);
  animation: lm-shimmer 1.3s infinite;
}
@keyframes lm-shimmer { 100% { transform: translateX(100%); } }
.lm-skeleton--text { height: .8em; border-radius: var(--lm-radius-pill); }
.lm-skeleton--avatar { width: 88px; height: 88px; border-radius: var(--lm-radius-lg); flex: 0 0 auto; }
.lm-skeleton--card { height: 120px; border-radius: var(--lm-radius-lg); }
.lm-skeleton-card { display: flex; gap: 14px; padding: 14px; background: var(--lm-color-surface); border: 1px solid var(--lm-color-border); border-radius: var(--lm-radius-lg); }
.lm-skeleton-card__body { flex: 1 1 auto; display: flex; flex-direction: column; gap: 9px; padding-top: 4px; }

/* ── Estado de erro (distinto de vazio) ────────────────────────────
   Vazio = neutro (tema). Erro = atenção (cor de erro no ícone). */
.lm-error-state { text-align: center; padding: 48px 16px; }
.lm-error-state .lm-error-icon {
  width: 56px; height: 56px; border-radius: var(--lm-radius-pill);
  background: var(--lm-color-error-soft); color: var(--lm-color-error);
  display: flex; align-items: center; justify-content: center; margin: 0 auto 12px;
}
.lm-error-state .lm-error-icon .material-symbols-outlined { font-size: 28px; }
.lm-error-state h3 { font-weight: 700; color: var(--lm-color-text-body); margin-bottom: 4px; }
.lm-error-state p { font-size: 14px; color: var(--lm-color-text-muted); line-height: 1.45; }
.lm-error-state[hidden] { display: none; }

/* ── Modal acessível compartilhado ─────────────────────────────────
   Visual base; o comportamento (Escape, foco, aria) vem de
   services/lifematch-modal.js. Mantém compat com o utilitário .hidden. */
.lm-modal { position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; padding: 16px; }
.lm-modal[hidden], .lm-modal.hidden { display: none; }
.lm-modal__backdrop { position: absolute; inset: 0; background: rgba(15, 23, 42, .55); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
.lm-modal__panel {
  position: relative; z-index: 1; width: 100%; max-width: var(--lm-modal-width);
  background: var(--lm-color-surface); border-radius: var(--lm-radius-2xl);
  box-shadow: var(--lm-shadow-float); padding: 24px;
  max-height: calc(100dvh - 32px); overflow-y: auto;
}

/* ── Tablet e desktop (>=768px): shell e grids aproveitam a largura ──
   O shell alarga já no tablet, mas SEMPRE limitado à viewport
   (min(largura-alvo, 100vw - respiro)) para nunca gerar rolagem horizontal.
   O grid usa auto-fill: 1 coluna no mobile (flex, fora deste media query),
   2 colunas quando há espaço. Escopado por .lm-app-canvas (no body) para
   vencer o max-w-md do Tailwind sem depender da ordem das folhas. */
@media (min-width: 768px) {
  .lm-app-canvas .lm-shell--wide { max-width: min(var(--lm-content-wide), calc(100vw - 2 * var(--lm-space-4))); }
  .lm-app-canvas .lm-shell--profile { max-width: min(var(--lm-content-profile), calc(100vw - 2 * var(--lm-space-4))); }

  .lm-results-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr)); gap: var(--lm-space-4); align-content: start; }

  /* Barra inferior acompanha o shell largo — só onde a página opta (lm-page-wide),
     preservando as páginas do 2A (Conteúdos/Eventos) com barra estreita. */
  .lm-page-wide .lm-bottom-nav { max-width: min(var(--lm-content-wide), calc(100vw - 2 * var(--lm-space-4))); }

  /* Perfil: hero ocupa a linha inteira, seções em colunas quando cabem */
  .lm-profile-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr)); gap: var(--lm-space-4); align-items: start; }
  .lm-profile-grid > .lm-profile-hero,
  .lm-profile-grid > .lm-profile-hero-wrap { grid-column: 1 / -1; }
}

/* Skeleton respeita movimento reduzido (sem shimmer) */
@media (prefers-reduced-motion: reduce) {
  .lm-skeleton::after { animation: none; }
}
