/* Nash — Icon Button de vidro.
   Figma N.A.S.H. DS 327:754: Size=Small (56, raio 28) com State=Default,
   Hover, Pressed; Size=Large (112, raio 56) só com Default. A casca circular
   para qualquer ação com ícone. Terceira peça da família (Tab Bar, Text
   Input), 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: Small 56 com ícone de 24; Large 112 com um poço
   de 64 (branco 8%, raio 32) e ícone de 32. Fill #0D0F12 32% no repouso,
   #1F2128 40% sob o ponteiro, #080A0D 32% apertado. Stroke 1,5 por dentro,
   branco 15 › 6 › 2 › 0, nos três estados. Ícone branco.

   Nomes pelo vocabulário do Roshan (docs/vocabulario-mapa.json):
   componente .nash-icon-button; parte .nash-icon-button-<parte>; variante
   data-<eixo> (data-size, data-icon-motion, data-mode); estado por ARIA
   (aria-pressed, aria-busy, aria-expanded, :disabled); token
   --nash-icon-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/icon-button.md): o Pressed do Figma é a pressão física
   (:active, 100ms), não um estado que fica; o que fica é aria-pressed (o
   ícone acende no accent, com halo) e aria-busy (o anel vira um arco). O
   Large recebe o Hover e o Pressed do Small, pendentes no Figma. O accent é
   --nash-icon-button-accent: branco por padrão, o do modo com data-mode.

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

   Documentação: docs/icon-button.md. Contrato: src/renderer/icon-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-icon-button.js completa a
   anatomia (a aura, a luz, o poço, o ícone), escreve a luz do cursor e cuida de
   aria-pressed e aria-busy; sem ele o botão é a placa com o ícone 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 de
   aria-busy (animável), a respiração (um número de 0 a 1 que o halo da
   borda, a aura, o poço e o ícone 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-icon-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-icon-button-breath {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}

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

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

/* ---------- tempo e curva ----------
   Os tempos do Tab Bar e do Text Input, com os mesmos valores. */
.nash-icon-button {
  --nash-icon-button-ease: var(--nash-curva-saida, cubic-bezier(0.16, 1, 0.3, 1));
  --nash-icon-button-duration-press: calc(var(--nash-dur-pressao, 100ms) * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-release: calc(var(--nash-dur-solta, 160ms) * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-icon: calc(var(--nash-dur-micro, 140ms) * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-state: calc(var(--nash-dur-estado, 180ms) * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-ring: calc(var(--nash-dur-brilho, 260ms) * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-spotlight: calc(var(--nash-dur-brilho, 260ms) * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-spotlight-follow: calc(70ms * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-glow: calc(320ms * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-delay-glow: calc(120ms * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-enter: calc(420ms * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-loop-spin: calc(1800ms * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-open: calc(420ms * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-loop-breathe: calc(1800ms * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-aura: calc(420ms * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  --nash-icon-button-duration-fade: calc(600ms * var(--nash-icon-button-time-scale, var(--nash-escala, 1)));
  /* A única curva que passa do alvo: o giro de abrir vai além e volta. */
  --nash-icon-button-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 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 e do Text Input. O halo é o accent a
   48%, o Accent Glow. */
:root {
  --nash-icon-button-accent: var(--accent, #ffffff);
}

.nash-icon-button {
  --nash-icon-button-halo: color-mix(in srgb, var(--nash-icon-button-accent) 48%, transparent);
  --nash-icon-button-spotlight-alpha: 12%;
}

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

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

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

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

/* ---------- o stroke por dentro ----------
   O anel de 1,5px das duas peças anteriores e da .nash-surface: dois
   gradientes, o content-box tira o miolo e sobra a borda. */
.nash-icon-button::before,
.nash-icon-button::after,
.nash-icon-button-spotlight::before {
  content: '';
  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 ----------
   56 × 56 no Figma (--nash-icon-button-size); raio 50%. A página que precisa
   de outra densidade escreve o token (36 no Project Builder); o enum de
   data-size é o do Figma. */
.nash-icon-button {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  box-sizing: border-box;
  --nash-icon-button-halo-reach: calc(var(--nash-icon-button-size, 56px) / 2);
  width: var(--nash-icon-button-size, 56px);
  height: var(--nash-icon-button-size, 56px);
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  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;
  line-height: 1;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-app-region: no-drag;
  transition:
    background-color var(--nash-icon-button-duration-state) var(--nash-icon-button-ease),
    box-shadow var(--nash-icon-button-duration-glow) var(--nash-icon-button-ease),
    transform var(--nash-icon-button-duration-release) var(--nash-icon-button-ease),
    color var(--nash-icon-button-duration-icon) var(--nash-icon-button-ease),
    --nash-icon-button-accent var(--nash-icon-button-duration-ring) var(--nash-icon-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-icon-button-enter var(--nash-icon-button-duration-enter) var(--nash-icon-button-ease) backwards,
    nash-icon-button-breathe var(--nash-icon-button-loop-breathe) ease-in-out calc(var(--nash-icon-button-delay-glow) + var(--nash-icon-button-duration-glow)) infinite;
  animation-play-state: running, paused;
}

.nash-icon-button[data-size='large'] {
  --nash-icon-button-halo-reach: calc(var(--nash-icon-button-size, 112px) / 2);
  width: var(--nash-icon-button-size, 112px);
  height: var(--nash-icon-button-size, 112px);
}

/* Dois anéis: branco (os três estados do Figma) e accent (aria-pressed,
   aria-busy, foco pelo teclado). */
.nash-icon-button::before {
  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-icon-button-duration-state) var(--nash-icon-button-ease);
}

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

/* ---------- o poço ----------
   O icon-inner-container do Large: 64, branco 8%, raio 32. No Small existe
   com o tamanho do ícone e sem fill, pra anatomia ser uma só. */
.nash-icon-button-well {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  box-sizing: border-box;
  width: var(--nash-icon-button-well-size, 24px);
  height: var(--nash-icon-button-well-size, 24px);
  border-radius: 50%;
  background-color: var(--nash-icon-button-well-fill, transparent);
  pointer-events: none;
  transition:
    background-color var(--nash-icon-button-duration-state) var(--nash-icon-button-ease),
    transform var(--nash-icon-button-duration-release) var(--nash-icon-button-ease);
}

.nash-icon-button[data-size='large'] .nash-icon-button-well {
  width: var(--nash-icon-button-well-size, 64px);
  height: var(--nash-icon-button-well-size, 64px);
  background-color: var(--nash-icon-button-well-fill, rgba(255, 255, 255, 0.08));
}

/* ---------- o ícone ----------
   24 no Small, 32 no Large (as instâncias de 24 e 32 da Icon Library),
   branco. O .nash-icon do kit dá o traço (1,5, sem fill). */
.nash-icon-button .nash-icon {
  width: var(--nash-icon-button-icon-size, 24px);
  height: var(--nash-icon-button-icon-size, 24px);
  flex: none;
  transition:
    transform var(--nash-icon-button-duration-icon) var(--nash-icon-button-ease),
    filter var(--nash-icon-button-duration-glow) var(--nash-icon-button-ease),
    opacity var(--nash-icon-button-duration-icon) var(--nash-icon-button-ease);
}

.nash-icon-button[data-size='large'] .nash-icon {
  width: var(--nash-icon-button-icon-size, 32px);
  height: var(--nash-icon-button-icon-size, 32px);
}

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

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

/* data-icon-motion (vocabulário: .nash-giro e .nash-realce viraram este
   eixo): tilt inclina 15° no hover, scale cresce 5%. */
.nash-icon-button[data-icon-motion='tilt']:hover:not([data-state]) .nash-icon {
  transform: rotate(15deg);
}

.nash-icon-button[data-icon-motion='scale']:hover:not([data-state]) .nash-icon {
  transform: scale(1.05);
}

/* aria-expanded: o ícone gira 135° com mola em 420ms (o + vira ×, passando
   do alvo e voltando), por cima do data-icon-motion; a placa desce à
   apertada; do poço sai uma onda no accent (o anel de 0 a 16px de spread,
   apagando). Fechar desfaz o giro pela mesma mola, sem onda. */
.nash-icon-button[aria-expanded] .nash-icon {
  transition-duration:
    var(--nash-icon-button-duration-open),
    var(--nash-icon-button-duration-glow),
    var(--nash-icon-button-duration-icon);
  transition-timing-function:
    var(--nash-icon-button-ease-spring),
    var(--nash-icon-button-ease),
    var(--nash-icon-button-ease);
}

.nash-icon-button[aria-expanded='true'] .nash-icon,
.nash-icon-button[aria-expanded='true']:hover .nash-icon {
  transform: rotate(135deg);
}

.nash-icon-button[aria-expanded='true'] {
  background-color: var(--nash-placa-pressed, rgba(8, 10, 13, 0.32));
}

.nash-icon-button[aria-expanded='true'] .nash-icon-button-well {
  animation: nash-icon-button-ripple var(--nash-icon-button-duration-open) var(--nash-icon-button-ease) forwards;
}

/* ---------- 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-icon-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-icon-button-halo)
   porque box-shadow não tem borda de dentro. Um degradê radial do accent da
   borda da casca até meia casca além (--nash-icon-button-halo-reach), com
   uma máscara em anel cujas duas bordas são tokens registrados: ligar abre a
   borda de fora (0 → reach em 420, depois dos 120 do halo); desligar move a
   borda de dentro (0 → reach em 600, com a rampa alargando) 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, 5% de scale. */
.nash-icon-button-halo {
  --nash-icon-button-halo-inner: var(--nash-icon-button-halo-reach);
  --nash-icon-button-halo-outer: 0px;
  position: absolute;
  inset: calc(-1 * var(--nash-icon-button-halo-reach));
  z-index: 0;
  border-radius: 50%;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(
    circle closest-side,
    color-mix(in srgb, var(--nash-icon-button-accent) 48%, transparent) 50%,
    color-mix(in srgb, var(--nash-icon-button-accent) 20%, transparent) 70%,
    transparent 100%
  );
  -webkit-mask: radial-gradient(
    circle closest-side,
    transparent calc(50% + var(--nash-icon-button-halo-inner)),
    #000 calc(50% + var(--nash-icon-button-halo-inner) * 1.5 + var(--nash-icon-button-halo-reach) / 4),
    #000 calc(50% + var(--nash-icon-button-halo-outer) - var(--nash-icon-button-halo-reach) / 4),
    transparent calc(50% + var(--nash-icon-button-halo-outer))
  );
  mask: radial-gradient(
    circle closest-side,
    transparent calc(50% + var(--nash-icon-button-halo-inner)),
    #000 calc(50% + var(--nash-icon-button-halo-inner) * 1.5 + var(--nash-icon-button-halo-reach) / 4),
    #000 calc(50% + var(--nash-icon-button-halo-outer) - var(--nash-icon-button-halo-reach) / 4),
    transparent calc(50% + var(--nash-icon-button-halo-outer))
  );
  transition:
    opacity var(--nash-icon-button-duration-fade) ease-in-out,
    transform var(--nash-icon-button-duration-fade) var(--nash-icon-button-ease),
    --nash-icon-button-halo-inner var(--nash-icon-button-duration-fade) ease-in-out,
    --nash-icon-button-halo-outer 0s linear var(--nash-icon-button-duration-fade);
}

.nash-icon-button[aria-pressed='true'] .nash-icon-button-halo {
  --nash-icon-button-halo-inner: 0px;
  --nash-icon-button-halo-outer: var(--nash-icon-button-halo-reach);
  opacity: 1;
  transform: scale(calc(1 + 0.05 * var(--nash-icon-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-icon-button-duration-aura) var(--nash-icon-button-ease) var(--nash-icon-button-delay-glow),
    transform 0s,
    --nash-icon-button-halo-inner 0s,
    --nash-icon-button-halo-outer var(--nash-icon-button-duration-aura) var(--nash-icon-button-ease) var(--nash-icon-button-delay-glow);
}

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

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

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

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

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

/* ---------- pressão (o Pressed do Figma) ----------
   Placa #080A0D a 32% e scale 0,96 em 100ms; solta em 160. */
.nash-icon-button:is(:active, [data-state='pressed']):not(:disabled) {
  background-color: var(--nash-placa-pressed, rgba(8, 10, 13, 0.32));
}

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

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

.nash-icon-button:focus-visible::after {
  opacity: 1;
}

/* ---------- ligado (aria-pressed) ----------
   Placa #080A0D, anel branco 0, anel de accent 1 em 260; o ícone toma o
   accent em 140 com drop-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. O poço
   pula 18% e volta em 320; a parte .nash-icon-fill do ícone enche em 260.
   Depois, enquanto ligado, respira: --nash-icon-button-breath vai de 0 a
   1 e volta em 1,8s, e dele derivam o halo da borda (24 → 32px, 48 → 60%),
   a aura (scale 1 → 1,05) e o poço (1 → 1,06), sem transição nesses dois
   enquanto ligado, pra seguirem 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-icon-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-icon-button-breath)) calc(-8px + 4px * var(--nash-icon-button-breath))
    color-mix(in srgb, var(--nash-icon-button-accent) calc(48% + 12% * var(--nash-icon-button-breath)), transparent);
  color: var(--nash-icon-button-accent);
  transition-delay: 0s, var(--nash-icon-button-delay-glow), 0s, 0s, 0s;
  animation:
    nash-icon-button-glow var(--nash-icon-button-duration-glow) var(--nash-icon-button-ease) var(--nash-icon-button-delay-glow) backwards,
    nash-icon-button-breathe var(--nash-icon-button-loop-breathe) ease-in-out calc(var(--nash-icon-button-delay-glow) + var(--nash-icon-button-duration-glow)) infinite;
  animation-play-state: running;
}

.nash-icon-button[aria-pressed='true'] .nash-icon-button-well {
  transform: scale(calc(1 + 0.06 * var(--nash-icon-button-breath)));
  transition-duration: var(--nash-icon-button-duration-state), 0s;
  animation: nash-icon-button-pop var(--nash-icon-button-duration-glow) var(--nash-icon-button-ease);
}

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

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

.nash-icon-button[aria-pressed='true'] .nash-icon {
  filter: drop-shadow(0 0 8px var(--nash-icon-button-halo));
}

/* ---------- ocupado (aria-busy) ----------
   O anel de accent vira um arco cônico que dá a volta em 1,8s, sem halo; o
   ícone baixa a 60%. O JS segura o clique. Único laço; termina com o
   estado. */
.nash-icon-button[aria-busy='true'] {
  background-color: var(--nash-placa-pressed, rgba(8, 10, 13, 0.32));
  cursor: progress;
}

.nash-icon-button[aria-busy='true']::before {
  opacity: 0;
}

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

.nash-icon-button[aria-busy='true'] .nash-icon {
  opacity: 0.6;
}

/* ---------- desabilitado ---------- */
.nash-icon-button:is(:disabled, [aria-disabled='true']) {
  opacity: 0.5;
  pointer-events: none;
}

/* ---------- 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. */
.nash-icon-button[data-state] {
  pointer-events: none;
  animation: none;
}

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

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

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

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

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

@keyframes nash-icon-button-pop {
  0% {
    transform: scale(1);
  }

  40% {
    transform: scale(1.18);
  }

  100% {
    transform: scale(1);
  }
}

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

  100% {
    box-shadow: 0 0 0 16px transparent;
  }
}

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

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

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

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

/* ---------- movimento reduzido ----------
   Cor e opacidade em 100ms; sem scale, giro ou inclinação. 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-icon-button,
  .nash-icon-button[aria-pressed='true'],
  .nash-icon-button[aria-pressed='true'] .nash-icon-button-well,
  .nash-icon-button[aria-expanded='true'] .nash-icon-button-well,
  .nash-icon-button[aria-busy='true']::after {
    animation: none;
  }

  .nash-icon-button,
  .nash-icon-button::before,
  .nash-icon-button::after,
  .nash-icon-button-spotlight,
  .nash-icon-button-halo,
  .nash-icon-button-well,
  .nash-icon-button .nash-icon,
  .nash-icon-button .nash-icon-fill {
    transition-duration: 100ms;
    transition-delay: 0s;
  }

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

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

  .nash-icon-button:active:not([data-state]),
  .nash-icon-button[data-icon-motion]:hover .nash-icon {
    transform: none;
  }
}

[data-motion='reduced'] .nash-icon-button,
[data-motion='reduced'] .nash-icon-button[aria-pressed='true'],
[data-motion='reduced'] .nash-icon-button[aria-pressed='true'] .nash-icon-button-well,
[data-motion='reduced'] .nash-icon-button[aria-expanded='true'] .nash-icon-button-well,
[data-motion='reduced'] .nash-icon-button[aria-busy='true']::after {
  animation: none;
}

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

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

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

[data-motion='reduced'] .nash-icon-button:active:not([data-state]),
[data-motion='reduced'] .nash-icon-button[data-icon-motion]:hover .nash-icon {
  transform: none;
}

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

:root[data-tema='claro'] .nash-icon-button::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-icon-button[data-size='large'] .nash-icon-button-well {
  background-color: var(--nash-icon-button-well-fill, rgba(20, 20, 15, 0.08));
}
