/* Weex Design System — Root CSS Entry Point */
@import "./tokens/typography.css";
@import "./tokens/colors.css";
@import "./tokens/spacing.css";
@import "./tokens/motion.css";
@import "./tokens/responsive.css";

/* ── FOCO DE TECLADO — anel único, keyboard-only (:focus-visible) ──        */
/* Rede de segurança: todo elemento interativo ganha o mesmo anel quando     */
/* focado por teclado. Componentes com input nativo escondido ou wrapper     */
/* têm regras próprias abaixo para o anel cair no elemento VISÍVEL.          */
:where(a, button, input, select, textarea, summary, [tabindex], [role="button"], [role="tab"], [role="switch"]):focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}
/* Campo com wrapper (Input): anel no contêiner, não no <input> interno */
.weex-field { transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard); }
.weex-field:hover:not(:has(:focus-visible)) { border-color: rgba(65,23,135,0.42) !important; }
.weex-field--dark:hover:not(:has(:focus-visible)) { border-color: rgba(255,255,255,0.26) !important; }
.weex-field:has(:focus-visible) {
  border-color: var(--brand);
  box-shadow: var(--focus-ring);
}
.weex-field :focus-visible { outline: none; }
/* Placeholder = cor do texto do próprio campo em opacidade reduzida.        */
/* Nunca o cinza-padrão do browser nem cor fixa: como o texto digitado já    */
/* tem contraste garantido em qualquer tema/campanha, o placeholder herda.   */
.weex-field input::placeholder { color: color-mix(in oklab, currentColor 58%, transparent); opacity: 1; }
/* Ponto pulsante — Badge pulse (status "ao vivo") */
@keyframes weex-pulse { 0%, 100% { opacity: .4; transform: scale(1); } 50% { opacity: 1; transform: scale(1.25); } }
/* Campo sobre superfície escura/de marca (Input tone="dark") */
.weex-field--dark:has(:focus-visible) {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--accent) 15%, transparent);
}
/* Hover — realce universal do botão primitivo. transform/filter não são inline,
   então vencem sem brigar com a cor/sombra de cada variante. */
.weex-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  filter: brightness(1.05) saturate(1.02);
}
/* Press — feedback tátil do botão primitivo: escala leve e instantânea. Consome --press-scale / --duration-instant. */
.weex-btn:active:not(:disabled) {
  transform: scale(var(--press-scale));
  transition: transform var(--duration-instant) var(--ease-standard) !important;
}
/* MOVIMENTO REDUZIDO AMORTECE, NUNCA APAGA (mesma régua da celebração). Aqui o valor normal
   JÁ é o amortecido (1px não desloca nada), então a regra existe só para deixar a política
   explícita e impedir que alguém volte a escrever `transform: none`. */
@media (prefers-reduced-motion: reduce) {
  .weex-btn:hover:not(:disabled) { transform: translateY(-1px); }
  .weex-btn:active:not(:disabled) { transform: scale(var(--press-scale)); }
}
/* ── TileAtividade (.weex-tile) — o hover-estrela do produto. Coração da Home, então
   com mais "taste" que o botão: quique de mola na elevação, o quadradinho do ícone
   "acende" na PRÓPRIA cor de status (glow + borda via currentColor — roxo p/ disponível,
   verde p/ concluído, sem chumbar cor), o glifo cresce e o press afunda no padrão do DS.
   transform/filter/box-shadow vencem o estilo inline sem brigar; só a borda pede !important. */
.weex-tile { transition: transform var(--duration-base) var(--ease-spring); }
.weex-tile > div:first-child { transition: box-shadow var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard); }
/* O glifo é `svg` quando vem inline (editor) e `span` com mask-image quando vem do registro
   oficial (GlifoAtividade) — os dois precisam crescer, senão o sinal só existe numa tela. */
.weex-tile > div:first-child > svg, .weex-tile > div:first-child > span { transition: transform var(--duration-base) var(--ease-spring); }
.weex-tile:hover { transform: translateY(var(--hover-lift-strong)) scale(var(--hover-scale)); }
.weex-tile:hover > div:first-child {
  box-shadow: 0 10px 24px -10px color-mix(in oklab, currentColor 55%, transparent);
  border-color: currentColor !important;
}
.weex-tile:hover > div:first-child > svg, .weex-tile:hover > div:first-child > span { transform: scale(1.06); }
.weex-tile:active { transform: scale(var(--press-scale)); transition: transform var(--duration-instant) var(--ease-standard); }
/* Quando o lift precisa morar num ANCESTRAL do tile — pastilhas posicionadas fora dele que
   têm de subir junto, caso do editor da Sua Campanha — ponha .weex-tile-lift no wrap. Mesma
   curva, mesmo amortecimento: ninguém reescreve -5px/1.05 numa folha local (foi assim que a
   Sua Campanha ficou com um hover e a Home com outro). */
.weex-tile-lift { transition: transform var(--duration-base) var(--ease-spring); }
.weex-tile-lift:hover { transform: translateY(var(--hover-lift-strong)) scale(var(--hover-scale)); }
.weex-tile-lift:hover .weex-tile { transform: none !important; }
.weex-tile-lift:active { transform: scale(var(--press-scale)); transition: transform var(--duration-instant) var(--ease-standard); }
/* AMORTECIMENTO — o que cai é a MOLA (o quique), não a amplitude. Mesma lição dos confetis:
   em movimento suave cai a VELOCIDADE e o repique, não a dose — a versão amortecida é a que
   todo revisor vê (o preview reporta `reduce` sempre), então ela tem de ser bonita. Eleva
   quase o mesmo, com escala mínima, em curva neutra; o acender do quadradinho segue intacto.
   E o PRESS vem DEPOIS do hover: uma regra de :hover declarada depois do :active de mesma
   especificidade mata o afundar do clique — foi exatamente o que aconteceu aqui. */
@media (prefers-reduced-motion: reduce) {
  .weex-tile, .weex-tile-lift { transition: transform var(--duration-fast) var(--ease-standard); }
  .weex-tile:hover, .weex-tile-lift:hover { transform: translateY(-4px) scale(1.03); }
  .weex-tile:hover > div:first-child > svg, .weex-tile:hover > div:first-child > span { transform: scale(1.03); }
  .weex-tile:active, .weex-tile-lift:active { transform: scale(var(--press-scale)); }
}
/* ── ESTADOS DE INTERAÇÃO GENÉRICOS ────────────────────────────────────────────────────
   Nasceram no <style> da Home do participante. Enquanto moraram lá, toda tela nova nascia sem
   eles e ninguém percebia — falta de hover não quebra nada, só deixa a tela morta (a Sua
   Campanha usava 1 dos 7). Agora são do DS e as duas telas consomem os mesmos.
     .weex-lift   cartão/faixa clicável que eleva      .weex-press  só brilho + press
     .weex-ctrl   botão de ícone (tint de fundo)        .weex-row    linha de lista (tint)
     .weex-link   link com seta que desliza
   transform/filter/opacity vencem o estilo inline sem !important; só o tint de fundo sobre
   superfície transparente pede !important. */
.weex-lift { transition: transform var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard); }
.weex-lift:hover { transform: translateY(var(--hover-lift)); box-shadow: 0 8px 22px rgba(65,23,135,.14); }
.weex-lift:active { transform: scale(var(--press-scale)); transition: transform var(--duration-instant) var(--ease-standard); }
.weex-press { transition: transform var(--duration-fast) var(--ease-standard), filter var(--duration-fast) var(--ease-standard); }
.weex-press:hover { filter: brightness(1.05) saturate(1.02); }
.weex-press:active { transform: scale(var(--press-scale)); transition: transform var(--duration-instant) var(--ease-standard); }
.weex-ctrl { transition: transform var(--duration-fast) var(--ease-standard), background var(--duration-fast) var(--ease-standard); }
.weex-ctrl:hover { background: var(--color-bg-hover) !important; }
.weex-ctrl:active { transform: scale(var(--press-scale)); transition: transform var(--duration-instant) var(--ease-standard); }
.weex-row { transition: background var(--duration-fast) var(--ease-standard); }
.weex-row:hover { background: var(--color-bg-hover) !important; }
.weex-link { transition: opacity var(--duration-fast) var(--ease-standard); }
.weex-link:hover { opacity: .72; }
.weex-link svg { transition: transform var(--duration-base) var(--ease-spring); }
.weex-link:hover svg { transform: translateX(3px); }
/* Amortecimento: o lift destes já é curto (--hover-lift), então só a seta encurta — e o
   :active vem DEPOIS do :hover, senão o press morre no cascade. */
@media (prefers-reduced-motion: reduce) {
  .weex-link:hover svg { transform: translateX(2px); }
  .weex-lift:active, .weex-press:active, .weex-ctrl:active { transform: scale(var(--press-scale)); }
}
/* ── RankingList — affordance de hover nas linhas (nomes de pessoas E equipes) e no pódio.
   A linha é gatilho do peek de perfil (~700ms); o tint dá o retorno imediato que faz a ponte.
   bg pede !important (o fundo da linha é inline: transparente / selecionado). ── */
.weex-rank-row { transition: background var(--duration-fast) var(--ease-standard); border-radius: 10px; }
.weex-rank-row:hover { background: var(--color-bg-hover) !important; }
.weex-rank-podium { transition: transform var(--duration-base) var(--ease-spring); }
.weex-rank-podium:hover { transform: translateY(-3px); }
/* FAB do chat da equipe — realce no hover (o transform inline exige !important; press mais fundo). */
.weex-fab { transition: transform var(--duration-fast) var(--ease-standard), filter var(--duration-fast) var(--ease-standard) !important; }
.weex-fab:hover { transform: scale(1.06) !important; filter: brightness(1.05); }
.weex-fab:active { transform: scale(var(--press-scale)) !important; }
@media (prefers-reduced-motion: reduce) {
  .weex-rank-podium:hover { transform: translateY(var(--hover-lift)); }
  .weex-fab:hover { transform: scale(1.02) !important; }
  .weex-fab:active { transform: scale(var(--press-scale)) !important; }
}
/* Conquista (medalha) \u2014 micro-eleva\u00e7\u00e3o com quique no hover; o tooltip do componente segue pr\u00f3prio. */
.weex-conq { transition: transform var(--duration-base) var(--ease-spring); }
.weex-conq:hover { transform: translateY(-3px); }
@media (prefers-reduced-motion: reduce) { .weex-conq:hover { transform: translateY(var(--hover-lift)); } }
/* \u2500\u2500 Skeleton (.weex-skel) \u2014 placeholder de carregamento: um brilho correndo da
   esquerda p/ direita sobre um bloco neutro, no lugar de texto/n\u00famero que ainda n\u00e3o
   chegou do servidor. Usar em vez de spinner/legenda "Carregando\u2026" quando o layout
   final j\u00e1 \u00e9 conhecido (linha de tabela, contador, avatar) \u2014 o olho l\u00ea a FORMA do
   conte\u00fado chegando, n\u00e3o uma tela que troca de figura inteira duas vezes.
   Reduced motion: o brilho para (fica um tom s\u00f3lido), a forma continua \u2014 mesma
   r\u00e9gua de amortecimento do resto do DS ("cai a mola, n\u00e3o a amplitude"). */
@keyframes weex-skel-shimmer { 0% { background-position: -220px 0; } 100% { background-position: 220px 0; } }
.weex-skel {
  display: inline-block;
  background: linear-gradient(90deg, var(--color-bg-hover) 25%, var(--color-border-faint) 37%, var(--color-bg-hover) 63%);
  background-size: 400px 100%;
  animation: weex-skel-shimmer 1.4s ease-in-out infinite;
  border-radius: var(--radius-input);
  color: transparent !important;
}
@media (prefers-reduced-motion: reduce) {
  .weex-skel { animation: none; background: var(--color-bg-hover); }
}
