/* Nash — Button de vidro.
   Figma N.A.S.H. DS 327:845, "Primary Button": State=Default, Hover e
   Pressed, num tamanho só (200 × 56, raio 24, respiro lateral 26, 12 entre o
   rótulo e o meta text). A pílula com rótulo, meta text e ícone opcional
   para qualquer ação com texto. Quarta peça da família (Tab Bar, Text Input,
   Icon Button), com o mesmo repertório: placa, anel de 1,5 por máscara, luz
   do cursor, accent registrado por @property, escala de tempo.

   Geometria e cor do Figma: rótulo Archivo 15 branco; meta text 12 a branco
   58%. Fill #0D0F12 32% no repouso, #1F2128 40% sob o ponteiro, #080A0D 32%
   apertado. Stroke 1,5 por dentro: no primário o par âmbar #FFB454 › #FF6B2C
   girando (14% de alfa fora do arco, pra borda nunca sumir); nas ações
   secundárias o branco 15 › 6 › 2 › 0 das irmãs. O stroke não muda entre os
   estados; só o fill.

   Nomes pelo vocabulário do Roshan (docs/vocabulario-mapa.json):
   componente .nash-button; parte .nash-button-<parte> (label, meta, halo,
   spotlight, sweep, ring); variante data-<eixo> (data-size="small|medium|
   large", data-emphasis="primary|secondary|ghost", data-mode); estado por
   ARIA (aria-pressed, aria-busy, :disabled, :focus-visible); token
   --nash-button-<parte>; o que o JS escreve em --nash-runtime-*; movimento
   reduzido por [data-motion="reduced"]. As variantes congeladas da
   documentação são data-state="default|hover|pressed", enum desta peça.

   Adaptações (docs/button.md): o Figma desenha um tamanho, 56 — é o large;
   medium é 44 (--nash-alvo-solto, a "pílula de 44px" do mapa) e small é 32
   (--nash-alvo), os dois alvos do kit, pendentes no Figma. O Pressed do
   Figma é a pressão física (:active, 100ms), não um estado que fica; o que
   fica é aria-pressed (o rótulo acende no accent, com halo e aura) e
   aria-busy (o arco dá a volta em 1,8s e o clique é segurado). O accent é
   --nash-button-accent: branco por padrão, o do modo com data-mode. O arco
   do primário é o par âmbar do Figma (--nash-button-arc-a/-b), não o accent.
   A volta do arco é a do kit, 5,5s (--nash-arco-volta; o Figma anota 4,5s,
   o dono alongou em 2026-09-04).

   Tempo e curva vêm do kit (nash-tokens.css) com fallback próprio; tudo
   passa por --nash-button-time-scale, ou pela --nash-escala da família.

   Documentação: docs/button.md. Contrato: src/renderer/button.test.js.
   Fonte única: o app recebe pelo build:kit (src/renderer/kit/), o PWA pelo
   build:web (web/vendor/).

   Carregar depois de nash-componentes.css. nash-button.js completa a
   anatomia (a aura, a luz, a varredura, o anel de pressão, o rótulo),
   escreve a luz do cursor e o lado da varredura e cuida de aria-pressed e
   aria-busy; sem ele o botão é a placa com o texto que a página escreveu. */

/* Registrados pra interpolar: o accent (troca de cor com transição), os
   dois eixos da luz (seguem o ponteiro com transição), o ângulo do arco
   (animável), o ângulo de ocupado que se soma a ele no primário, a
   respiração (um número de 0 a 1 que o halo da borda e a aura leem) e as
   duas bordas da aura (em px além da casca, com transição). Os três de
   runtime são os mesmos nomes em qualquer peça que os escreva. */
@property --nash-button-accent {
  syntax: '<color>';
  inherits: true;
  initial-value: #ffffff;
}

@property --nash-runtime-spotlight-x {
  syntax: '<length-percentage>';
  inherits: false;
  initial-value: 50%;
}

@property --nash-runtime-spotlight-y {
  syntax: '<length-percentage>';
  inherits: false;
  initial-value: 50%;
}

@property --nash-runtime-spin {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

@property --nash-button-busy-spin {
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

@property --nash-button-breath {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}

@property --nash-button-halo-inner {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

@property --nash-button-halo-outer {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

/* ---------- tempo e curva ----------
   Os tempos das três peças anteriores, com os mesmos valores, mais os do
   botão: a varredura (640), o anel de pressão (sobe em 50, solta em 300), o
   concluído (700) e a volta do arco (5,5s). */
.nash-button {
  --nash-button-ease: var(--nash-curva-saida, cubic-bezier(0.16, 1, 0.3, 1));
  --nash-button-duration-press: calc(var(--nash-dur-pressao, 100ms) * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-release: calc(var(--nash-dur-solta, 160ms) * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-text: calc(var(--nash-dur-micro, 140ms) * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-state: calc(var(--nash-dur-estado, 180ms) * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-ring: calc(var(--nash-dur-brilho, 260ms) * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-spotlight: calc(var(--nash-dur-brilho, 260ms) * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-spotlight-follow: calc(70ms * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-glow: calc(320ms * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-delay-glow: calc(120ms * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-enter: calc(420ms * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-aura: calc(420ms * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-fade: calc(600ms * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-sweep: calc(var(--nash-dur-lampejo, 640ms) * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-ring-press: calc(50ms * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-ring-release: calc(var(--nash-dur-clarao, 300ms) * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-duration-complete: calc(var(--nash-dur-concluido, 700ms) * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-loop-spin: calc(1800ms * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-loop-arc: calc(var(--nash-arco-volta, 5500ms) * var(--nash-button-time-scale, var(--nash-escala, 1)));
  --nash-button-loop-breathe: calc(1800ms * var(--nash-button-time-scale, var(--nash-escala, 1)));
}

/* ---------- cor ----------
   Sem data-mode, o accent do kit (--accent: branco, ou o vermelho imperial
   com data-accent="imperio"), herdado. Com data-mode, um dos cinco modos do
   Figma, a mesma tabela do Tab Bar, do Text Input e do Icon Button. O halo
   é o accent a 48%, o Accent Glow. O arco do primário é o par âmbar do
   Figma, e o anel de pressão também: a página que quer outro par escreve os
   dois tokens. */
:root {
  --nash-button-accent: var(--accent, #ffffff);
}

.nash-button {
  --nash-button-halo: color-mix(in srgb, var(--nash-button-accent) 48%, transparent);
  --nash-button-spotlight-alpha: 12%;
  --nash-button-arc-a: #ffb454;
  --nash-button-arc-b: #ff6b2c;
}

.nash-button[data-mode='chat'],
.nash-button[data-mode='voz'] {
  --nash-button-accent: var(--accent-chat, #4dc9ff);
}

.nash-button[data-mode='design'] {
  --nash-button-accent: var(--accent-design, #b36bff);
}

.nash-button[data-mode='imagem'] {
  --nash-button-accent: var(--accent-image, #ffb454);
}

.nash-button[data-mode='social'] {
  --nash-button-accent: var(--accent-social, #5fe0a5);
}

/* ---------- o stroke por dentro ----------
   O anel de 1,5px das três peças e da .nash-surface: dois gradientes, o
   content-box tira o miolo e sobra a borda. O anel de pressão
   (.nash-button-ring, o Button.Ring do mapa) é o mesmo recorte. */
.nash-button::before,
.nash-button::after,
.nash-button-spotlight::before {
  content: '';
}

.nash-button::before,
.nash-button::after,
.nash-button-spotlight::before,
.nash-button-ring {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: var(--nash-stroke, 1.5px);
  pointer-events: none;
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
}

/* ---------- a casca ----------
   Medium: 44 de alto (--nash-alvo-solto), respiro lateral 24, rótulo 15 a
   500. Raio 24 do Figma em todos os tamanhos: a 32 e a 44 ele vira pílula
   sozinho; a 56 é o raio desenhado. A página que precisa de outra
   densidade escreve --nash-button-height; o enum de data-size é o dos
   alvos do kit mais o do Figma. */
.nash-button {
  --nash-button-size: var(--nash-button-height, var(--nash-alvo-solto, 44px));
  --nash-button-halo-reach: calc(var(--nash-button-size) / 2);
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--nash-e2, 12px);
  flex: none;
  box-sizing: border-box;
  height: var(--nash-button-size);
  margin: 0;
  padding: 0 var(--nash-button-padding, var(--nash-e4, 24px));
  border: 0;
  border-radius: var(--nash-button-radius, 24px);
  appearance: none;
  -webkit-appearance: none;
  background-color: var(--nash-placa, rgba(13, 15, 18, 0.32));
  -webkit-backdrop-filter: blur(var(--nash-vidro-blur, 24px)) saturate(var(--nash-vidro-sat, 1.85));
  backdrop-filter: blur(var(--nash-vidro-blur, 24px)) saturate(var(--nash-vidro-sat, 1.85));
  box-shadow: 0 0 24px -8px transparent;
  color: #fff;
  font: inherit;
  font-size: var(--nash-t4, 15px);
  font-weight: 500;
  letter-spacing: 0.005em;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  text-shadow: 0 0 8px transparent;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-app-region: no-drag;
  transition:
    background-color var(--nash-button-duration-state) var(--nash-button-ease),
    box-shadow var(--nash-button-duration-glow) var(--nash-button-ease),
    transform var(--nash-button-duration-release) var(--nash-button-ease),
    color var(--nash-button-duration-text) var(--nash-button-ease),
    text-shadow var(--nash-button-duration-glow) var(--nash-button-ease),
    --nash-button-accent var(--nash-button-duration-ring) var(--nash-button-ease);
  /* `backwards`, nunca `both`: lição do trilho do nav. A respiração já
     existe aqui, parada: ao desligar ela pausa onde está em vez de ser
     removida, e nada salta de volta a zero. */
  animation:
    nash-button-enter var(--nash-button-duration-enter) var(--nash-button-ease) backwards,
    nash-button-breathe var(--nash-button-loop-breathe) ease-in-out calc(var(--nash-button-delay-glow) + var(--nash-button-duration-glow)) infinite;
  animation-play-state: running, paused;
}

.nash-button[data-size='small'] {
  --nash-button-size: var(--nash-button-height, var(--nash-alvo, 32px));
  gap: var(--nash-e1, 8px);
  padding: 0 var(--nash-button-padding, var(--nash-e3, 16px));
  font-size: var(--nash-t3, 13px);
}

.nash-button[data-size='large'] {
  --nash-button-size: var(--nash-button-height, 56px);
  padding: 0 var(--nash-button-padding, 26px);
}

/* Dois anéis: branco (as ações secundárias) e accent (aria-pressed,
   aria-busy, foco pelo teclado). No primário o branco dá lugar ao arco. */
.nash-button::before {
  z-index: 0;
  opacity: 1;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.15),
    rgba(255, 255, 255, 0.06) 40%,
    rgba(255, 255, 255, 0.02) 70%,
    rgba(255, 255, 255, 0)
  );
  transition: opacity var(--nash-button-duration-state) var(--nash-button-ease);
}

.nash-button::after {
  z-index: 0;
  opacity: 0;
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--nash-button-accent) 45%, transparent),
    color-mix(in srgb, var(--nash-button-accent) 18%, transparent) 40%,
    color-mix(in srgb, var(--nash-button-accent) 6%, transparent) 70%,
    transparent
  );
  transition:
    opacity var(--nash-button-duration-ring) var(--nash-button-ease),
    background var(--nash-button-duration-ring) var(--nash-button-ease);
}

/* ---------- o rótulo, o meta text e o ícone ----------
   O rótulo herda o tipo da casca. O meta text é 12 a 58% (11 no small); no
   large, os 12 do Figma. O ícone é o .nash-icon do kit, a 16. Os três
   ficam por cima das luzes. */
.nash-button-label,
.nash-button-meta,
.nash-button .nash-icon {
  position: relative;
  z-index: 1;
}

.nash-button-meta {
  font-size: var(--nash-t2, 12px);
  font-weight: 400;
  opacity: 0.58;
}

.nash-button[data-size='small'] .nash-button-meta {
  font-size: var(--nash-t1, 11px);
}

.nash-button .nash-icon {
  width: var(--nash-button-icon-size, 16px);
  height: var(--nash-button-icon-size, 16px);
  flex: none;
}

/* A parte do ícone que enche ao ligar: fill no accent, de 0 a 1 em 260ms.
   Nasce com fill-opacity 0 por cima do fill: none do kit, pra interpolar. */
.nash-button .nash-icon-fill {
  fill: currentColor;
  fill-opacity: 0;
  transition: fill-opacity var(--nash-button-duration-ring) var(--nash-button-ease);
}

.nash-button[aria-pressed='true'] .nash-icon-fill {
  fill-opacity: 1;
}

/* ---------- a ênfase ----------
   primary: o stroke é o arco âmbar do Figma, sempre girando, uma volta a
   cada 5,5s (--nash-arco-volta), 14% de alfa fora do arco. O ângulo é a
   soma de dois registrados: --nash-runtime-spin (a volta lenta) e
   --nash-button-busy-spin (a volta de ocupado, 1,8s, que existe parada e
   roda enquanto aria-busy). Trocar de um pro outro pausa um e solta o
   outro, então o ângulo nunca salta. Uma por tela.
   ghost: sem placa e sem anel em repouso; os dois aparecem sob o ponteiro. */
.nash-button[data-emphasis='primary']::before {
  opacity: 1;
  background: conic-gradient(
    from calc(var(--nash-runtime-spin) + var(--nash-button-busy-spin)),
    color-mix(in srgb, var(--nash-button-arc-a) 14%, transparent) 0deg,
    var(--nash-button-arc-a) 58deg,
    var(--nash-button-arc-b) 118deg,
    color-mix(in srgb, var(--nash-button-arc-b) 14%, transparent) 196deg,
    color-mix(in srgb, var(--nash-button-arc-a) 14%, transparent) 360deg
  );
  animation:
    nash-button-spin var(--nash-button-loop-arc) linear infinite,
    nash-button-busy-spin var(--nash-button-loop-spin) linear infinite;
  animation-play-state: running, paused;
}

.nash-button[data-emphasis='ghost'] {
  background-color: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.nash-button[data-emphasis='ghost']::before {
  opacity: 0;
}

.nash-button[data-emphasis='ghost']:is(:hover, [data-state='hover'], :active, [data-state='pressed'], [aria-pressed='true'], [aria-busy='true']):not(:disabled) {
  -webkit-backdrop-filter: blur(var(--nash-vidro-blur, 24px)) saturate(var(--nash-vidro-sat, 1.85));
  backdrop-filter: blur(var(--nash-vidro-blur, 24px)) saturate(var(--nash-vidro-sat, 1.85));
}

.nash-button[data-emphasis='ghost']:is(:hover, [data-state='hover'], :active, [data-state='pressed']):not(:disabled)::before {
  opacity: 1;
}

/* ---------- hover ----------
   Placa #1F2128 a 40%. Não se aplica ao botão ligado (aria-pressed) nem
   ocupado (aria-busy): o Figma não define Hover sobre Pressed. */
.nash-button:is(:hover, [data-state='hover']):not(:disabled):not([data-state='pressed']):not([aria-pressed='true']):not([aria-busy='true']) {
  background-color: var(--nash-placa-hover, rgba(31, 33, 40, 0.4));
}

/* ---------- a aura ----------
   A luz larga em volta da casca, num elemento próprio (i.nash-button-halo)
   que segue o contorno da pílula. É uma sombra do accent a 48% num
   elemento sem fundo: a borda de dentro é o tamanho do elemento
   (--nash-button-halo-inner, além da casca) e a borda de fora é o desfoque
   (--nash-button-halo-outer). Ligar abre a borda de fora (0 → meia casca
   em 420, depois dos 120 do halo); desligar move a borda de dentro (0 →
   meia casca em 600) enquanto a opacidade cai: a luz é comida de dentro
   pra fora e não some de uma vez. A borda de fora volta a zero só quando
   o apagar termina (transição de 0s com atraso). Respira com o mesmo
   número do halo da borda, 3% de scale. */
.nash-button-halo {
  --nash-button-halo-inner: var(--nash-button-halo-reach);
  --nash-button-halo-outer: 0px;
  position: absolute;
  inset: calc(-1 * var(--nash-button-halo-inner));
  z-index: 0;
  border-radius: calc(var(--nash-button-radius, 24px) + var(--nash-button-halo-inner));
  pointer-events: none;
  opacity: 0;
  box-shadow: 0 0 max(0px, calc(var(--nash-button-halo-outer) - var(--nash-button-halo-inner))) 0 color-mix(in srgb, var(--nash-button-accent) 48%, transparent);
  transition:
    opacity var(--nash-button-duration-fade) ease-in-out,
    transform var(--nash-button-duration-fade) var(--nash-button-ease),
    --nash-button-halo-inner var(--nash-button-duration-fade) ease-in-out,
    --nash-button-halo-outer 0s linear var(--nash-button-duration-fade);
}

.nash-button[aria-pressed='true'] .nash-button-halo {
  --nash-button-halo-inner: 0px;
  --nash-button-halo-outer: var(--nash-button-halo-reach);
  opacity: 1;
  transform: scale(calc(1 + 0.03 * var(--nash-button-breath)));
  /* transform sem transição enquanto ligado: o scale segue a respiração
     no mesmo quadro, sem o atraso que uma transição imporia a um valor
     herdado animado. O assentar de volta usa a transição do repouso. */
  transition:
    opacity var(--nash-button-duration-aura) var(--nash-button-ease) var(--nash-button-delay-glow),
    transform 0s,
    --nash-button-halo-inner 0s,
    --nash-button-halo-outer var(--nash-button-duration-aura) var(--nash-button-ease) var(--nash-button-delay-glow);
}

/* ---------- a luz do cursor ----------
   A das três peças, em proporção da altura: névoa de 2,4 alturas no accent
   a 12% e o anel aceso no ponto mais próximo do ponteiro (1,4 altura,
   accent 70%). Segue em 70ms, apaga em 260. */
.nash-button-spotlight {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(
    calc(var(--nash-button-size) * 2.4) circle at var(--nash-runtime-spotlight-x) var(--nash-runtime-spotlight-y),
    color-mix(in srgb, var(--nash-button-accent) var(--nash-button-spotlight-alpha), transparent),
    transparent 70%
  );
  transition:
    opacity var(--nash-button-duration-spotlight) var(--nash-button-ease),
    --nash-runtime-spotlight-x var(--nash-button-duration-spotlight-follow) linear,
    --nash-runtime-spotlight-y var(--nash-button-duration-spotlight-follow) linear;
}

.nash-button-spotlight::before {
  background: radial-gradient(
    calc(var(--nash-button-size) * 1.4) circle at var(--nash-runtime-spotlight-x) var(--nash-runtime-spotlight-y),
    color-mix(in srgb, var(--nash-button-accent) 70%, transparent),
    transparent 70%
  );
}

.nash-button:hover:not([data-state]):not(:disabled) .nash-button-spotlight {
  opacity: 1;
}

.nash-button[aria-pressed='true'] {
  --nash-button-spotlight-alpha: 18%;
}

.nash-button:active {
  --nash-button-spotlight-alpha: 24%;
}

/* ---------- a varredura ----------
   O lampejo do kit, dentro da peça: um traço de luz a 6% atravessa a placa
   quando o ponteiro entra, uma vez, pelo lado por onde ele entrou
   (nash-button.js grava --nash-runtime-sweep-direction: 1 ou -1). Não
   repete enquanto o ponteiro fica. 640ms. */
.nash-button-sweep {
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  overflow: hidden;
  pointer-events: none;
}

.nash-button-sweep::before {
  content: '';
  position: absolute;
  top: -50%;
  bottom: -50%;
  left: 0;
  width: 42%;
  opacity: 0;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.06) 50%, transparent);
  transform: translateX(calc(-130% * var(--nash-runtime-sweep-direction, 1))) skewX(-8deg);
}

.nash-button:hover:not([data-state]):not(:disabled) .nash-button-sweep::before {
  animation: nash-button-sweep var(--nash-button-duration-sweep) var(--nash-button-ease) forwards;
}

/* ---------- pressão (o Pressed do Figma) ----------
   Placa #080A0D a 32% e scale 0,98 em 100ms; solta em 160. Junto, o anel
   de pressão (o clarão do kit): o anel âmbar fecha na borda e sobe a 40%
   em 50ms; ao soltar, abre 4% e apaga em 300. */
.nash-button:is(:active, [data-state='pressed']):not(:disabled) {
  background-color: var(--nash-placa-pressed, rgba(8, 10, 13, 0.32));
}

.nash-button:active:not([data-state]):not(:disabled) {
  transform: scale(0.98);
  transition-duration:
    var(--nash-button-duration-state),
    var(--nash-button-duration-glow),
    var(--nash-button-duration-press),
    var(--nash-button-duration-text),
    var(--nash-button-duration-glow),
    var(--nash-button-duration-ring);
}

.nash-button-ring {
  z-index: 0;
  opacity: 0;
  transform: scale(1.04);
  background: conic-gradient(var(--nash-button-arc-a), var(--nash-button-arc-b), var(--nash-button-arc-a));
  transition:
    opacity var(--nash-button-duration-ring-release) var(--nash-button-ease),
    transform var(--nash-button-duration-ring-release) var(--nash-button-ease);
}

.nash-button:active:not([data-state]):not(:disabled) .nash-button-ring {
  opacity: 0.4;
  transform: none;
  transition-duration: var(--nash-button-duration-ring-press), var(--nash-button-duration-ring-press);
}

/* ---------- foco pelo teclado ---------- */
.nash-button:focus-visible {
  outline: 2px solid var(--nash-button-accent);
  outline-offset: 2px;
}

.nash-button:focus-visible:not([data-emphasis='primary'])::after {
  opacity: 1;
}

/* ---------- ligado (aria-pressed) ----------
   Placa #080A0D, anel branco 0, anel de accent 1 em 260 (no primário o
   arco fica); o rótulo toma o accent em 140 com text-shadow de 8px; o halo
   da borda espera 120 e vai 0 → 32px a 70% → 24px a 48% em 320 (a curva do
   ponto da aba), e junto com ele uma onda: um anel de accent que se abre da
   borda a 18px e apaga; a aura se abre da borda até meia casca além em
   420. Total: 540ms. A parte .nash-icon-fill do ícone enche em 260. Depois,
   enquanto ligado, respira: --nash-button-breath vai de 0 a 1 e volta em
   1,8s, e dele derivam o halo da borda (24 → 32px, 48 → 60%) e a aura
   (scale 1 → 1,03), sem transição nela enquanto ligado, pra seguir o número
   no mesmo quadro. Desligar: placa, anéis, cor e fill voltam nos tempos de
   sempre; o halo da borda apaga em 320; a aura é comida de dentro pra fora
   em 600; a respiração pausa onde está (a animação fica, parada), então
   nada salta. */
.nash-button[aria-pressed='true'] {
  background-color: var(--nash-placa-pressed, rgba(8, 10, 13, 0.32));
  box-shadow: 0 0 calc(24px + 8px * var(--nash-button-breath)) calc(-8px + 4px * var(--nash-button-breath))
    color-mix(in srgb, var(--nash-button-accent) calc(48% + 12% * var(--nash-button-breath)), transparent);
  color: var(--nash-button-accent);
  text-shadow: 0 0 8px var(--nash-button-halo);
  transition-delay: 0s, var(--nash-button-delay-glow), 0s, 0s, 0s, 0s;
  animation:
    nash-button-glow var(--nash-button-duration-glow) var(--nash-button-ease) var(--nash-button-delay-glow) backwards,
    nash-button-breathe var(--nash-button-loop-breathe) ease-in-out calc(var(--nash-button-delay-glow) + var(--nash-button-duration-glow)) infinite;
  animation-play-state: running;
}

.nash-button[aria-pressed='true']:not([data-emphasis='primary'])::before {
  opacity: 0;
}

.nash-button[aria-pressed='true']:not([data-emphasis='primary'])::after {
  opacity: 1;
}

/* ---------- ocupado (aria-busy) ----------
   Nas ações secundárias e fantasma o anel de accent vira um arco cônico que
   dá a volta em 1,8s, sem halo. No primário a volta lenta do arco âmbar
   pausa e a de ocupado roda, também em 1,8s — o mesmo ângulo, sem salto.
   O rótulo baixa a 60%. O JS segura o clique. Termina com o estado. */
.nash-button[aria-busy='true'] {
  background-color: var(--nash-placa-pressed, rgba(8, 10, 13, 0.32));
  color: rgba(255, 255, 255, 0.6);
  cursor: progress;
}

.nash-button[aria-busy='true'][aria-pressed='true'] {
  color: color-mix(in srgb, var(--nash-button-accent) 60%, transparent);
}

.nash-button[aria-busy='true']:not([data-emphasis='primary'])::before {
  opacity: 0;
}

.nash-button[aria-busy='true']:not([data-emphasis='primary'])::after {
  opacity: 1;
  background: conic-gradient(
    from var(--nash-runtime-spin),
    transparent 0deg,
    color-mix(in srgb, var(--nash-button-accent) 6%, transparent) 200deg,
    color-mix(in srgb, var(--nash-button-accent) 45%, transparent) 300deg,
    color-mix(in srgb, var(--nash-button-accent) 70%, transparent) 340deg,
    transparent 360deg
  );
  animation: nash-button-spin var(--nash-button-loop-spin) linear infinite;
}

.nash-button[data-emphasis='primary'][aria-busy='true']::before {
  animation-play-state: paused, running;
}

/* ---------- desabilitado ----------
   50%, sem ponteiro; no primário o arco para no quadro em que estava. */
.nash-button:is(:disabled, [aria-disabled='true']) {
  opacity: 0.5;
  pointer-events: none;
}

.nash-button[data-emphasis='primary']:is(:disabled, [aria-disabled='true'])::before {
  animation-play-state: paused, paused;
}

/* ---------- as variantes congeladas ----------
   data-state="default|hover|pressed" são as do Figma, pra documentação;
   pointer-events: none pra não mudarem com o cursor; o arco parado no
   quadro do Figma. */
.nash-button[data-state] {
  pointer-events: none;
  animation: none;
}

.nash-button[data-state][data-emphasis='primary']::before {
  animation-play-state: paused, paused;
}

/* ---------- quadros ---------- */
@keyframes nash-button-glow {
  0% {
    box-shadow:
      0 0 0 0 transparent,
      0 0 0 0 color-mix(in srgb, var(--nash-button-accent) 45%, transparent);
  }

  45% {
    box-shadow:
      0 0 32px -4px color-mix(in srgb, var(--nash-button-accent) 70%, transparent),
      0 0 0 8px color-mix(in srgb, var(--nash-button-accent) 22%, transparent);
  }

  100% {
    box-shadow:
      0 0 24px -8px var(--nash-button-halo),
      0 0 0 18px transparent;
  }
}

@keyframes nash-button-breathe {
  0%,
  100% {
    --nash-button-breath: 0;
  }

  50% {
    --nash-button-breath: 1;
  }
}

@keyframes nash-button-spin {
  from {
    --nash-runtime-spin: 0deg;
  }

  to {
    --nash-runtime-spin: 360deg;
  }
}

@keyframes nash-button-busy-spin {
  from {
    --nash-button-busy-spin: 0deg;
  }

  to {
    --nash-button-busy-spin: 360deg;
  }
}

@keyframes nash-button-sweep {
  0% {
    opacity: 0;
    transform: translateX(calc(-130% * var(--nash-runtime-sweep-direction, 1))) skewX(-8deg);
  }

  20% {
    opacity: 1;
  }

  100% {
    opacity: 0;
    transform: translateX(calc(190% * var(--nash-runtime-sweep-direction, 1))) skewX(-8deg);
  }
}

/* O concluído do kit, dentro da peça: nash-button.js põe esta animação no
   anel de pressão (complete()), em 700ms, uma vez por evento — só
   opacidade, sem escala. */
@keyframes nash-button-ring-complete {
  0% {
    opacity: 0;
  }

  15% {
    opacity: 1;
  }

  70% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

@keyframes nash-button-enter {
  from {
    opacity: 0;
    transform: scale(0.96);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* ---------- movimento reduzido ----------
   Cor e opacidade em 100ms; sem scale, varredura, onda ou respiração. O
   arco do primário para no quadro em que estava (o que o Figma desenha);
   ocupado vira o anel de accent parado. Vale por prefers-reduced-motion e
   por [data-motion="reduced"] num ancestral. */
@media (prefers-reduced-motion: reduce) {
  .nash-button,
  .nash-button[aria-pressed='true'],
  .nash-button:not([data-emphasis='primary'])[aria-busy='true']::after,
  .nash-button:hover:not([data-state]):not(:disabled) .nash-button-sweep::before {
    animation: none;
  }

  .nash-button[data-emphasis='primary']::before,
  .nash-button[data-emphasis='primary'][aria-busy='true']::before {
    animation-play-state: paused, paused;
  }

  .nash-button,
  .nash-button[aria-pressed='true'],
  .nash-button::before,
  .nash-button::after,
  .nash-button-spotlight,
  .nash-button-halo,
  .nash-button[aria-pressed='true'] .nash-button-halo,
  .nash-button-ring,
  .nash-button .nash-icon-fill {
    transition-duration: 100ms;
    transition-delay: 0s;
  }

  .nash-button-halo {
    --nash-button-halo-inner: 0px;
    --nash-button-halo-outer: var(--nash-button-halo-reach);
  }

  .nash-button:not([data-emphasis='primary'])[aria-busy='true']::after {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--nash-button-accent) 45%, transparent),
      color-mix(in srgb, var(--nash-button-accent) 18%, transparent) 40%,
      color-mix(in srgb, var(--nash-button-accent) 6%, transparent) 70%,
      transparent
    );
  }

  .nash-button:active:not([data-state]),
  .nash-button-ring,
  .nash-button[aria-pressed='true'] .nash-button-halo {
    transform: none;
  }
}

[data-motion='reduced'] .nash-button,
[data-motion='reduced'] .nash-button[aria-pressed='true'],
[data-motion='reduced'] .nash-button:not([data-emphasis='primary'])[aria-busy='true']::after,
[data-motion='reduced'] .nash-button:hover:not([data-state]):not(:disabled) .nash-button-sweep::before {
  animation: none;
}

[data-motion='reduced'] .nash-button[data-emphasis='primary']::before,
[data-motion='reduced'] .nash-button[data-emphasis='primary'][aria-busy='true']::before {
  animation-play-state: paused, paused;
}

[data-motion='reduced'] .nash-button,
[data-motion='reduced'] .nash-button[aria-pressed='true'],
[data-motion='reduced'] .nash-button::before,
[data-motion='reduced'] .nash-button::after,
[data-motion='reduced'] .nash-button-spotlight,
[data-motion='reduced'] .nash-button-halo,
[data-motion='reduced'] .nash-button[aria-pressed='true'] .nash-button-halo,
[data-motion='reduced'] .nash-button-ring,
[data-motion='reduced'] .nash-button .nash-icon-fill {
  transition-duration: 100ms;
  transition-delay: 0s;
}

[data-motion='reduced'] .nash-button-halo {
  --nash-button-halo-inner: 0px;
  --nash-button-halo-outer: var(--nash-button-halo-reach);
}

[data-motion='reduced'] .nash-button:not([data-emphasis='primary'])[aria-busy='true']::after {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--nash-button-accent) 45%, transparent),
    color-mix(in srgb, var(--nash-button-accent) 18%, transparent) 40%,
    color-mix(in srgb, var(--nash-button-accent) 6%, transparent) 70%,
    transparent
  );
}

[data-motion='reduced'] .nash-button:active:not([data-state]),
[data-motion='reduced'] .nash-button-ring,
[data-motion='reduced'] .nash-button[aria-pressed='true'] .nash-button-halo {
  transform: none;
}

/* ---------- o modo claro ----------
   Sobre data-tema="claro", os degraus de branco viram os mesmos degraus de
   tinta (#14140F): o rótulo, o anel e a varredura. */
:root[data-tema='claro'] .nash-button {
  color: #14140f;
}

:root[data-tema='claro'] .nash-button[aria-busy='true'] {
  color: rgba(20, 20, 15, 0.6);
}

:root[data-tema='claro'] .nash-button:not([data-emphasis='primary'])::before {
  background: linear-gradient(
    180deg,
    rgba(20, 20, 15, 0.15),
    rgba(20, 20, 15, 0.06) 40%,
    rgba(20, 20, 15, 0.02) 70%,
    rgba(20, 20, 15, 0)
  );
}

:root[data-tema='claro'] .nash-button-sweep::before {
  background: linear-gradient(100deg, transparent, rgba(20, 20, 15, 0.06) 50%, transparent);
}
