/* ===========================================================================
   HISTORY BOARD
   ---------------------------------------------------------------------------
   Nome do arquivo......: widget/estilo.css
   Finalidade...........: Aparência do widget público de atendimento.
   Data de criação......: 2026-10-18
   Última alteração.....: 2026-10-19
   Versão...............: 1.3.0
   Responsabilidade.....: Ser legível em celular velho, em luz do dia e para
                          quem está irritado. Nenhuma fonte remota, nenhuma
                          biblioteca.
   Dependências.........: nenhuma.
   Histórico............: 1.0.0 (2026-10-18) - Etapa D: canal público.
                          1.1.0 (2026-10-19) - Altura da tela travada: quem
                            rolava era a página, e o campo de escrita ia para
                            baixo da dobra.

   DECISÕES, em uma linha cada (o porquê está em plano-de-design.md):
     * Sem fonte remota: quem abre esta tela costuma estar sem internet boa.
       Uma requisição de fonte que trava atrasa o primeiro desenho.
     * Mensagem do cliente tem balão; a do atendimento, não. A assimetria
       distingue os dois lados sem depender de cor, que falha na impressão,
       no daltonismo e no modo de alto contraste.
     * Âmbar aparece só no indicador de enlace e no filete do atendimento.
       Nunca em botão: botão é índigo.
   =========================================================================== */

:root {
  /* --- Cor ------------------------------------------------------------- */
  --nox:          #151A2E;  /* índigo-noite: cabeçalho e balão do cliente   */
  --nox-alto:     #222A47;  /* índigo um passo acima, para borda e relevo   */
  --papel:        #F4F5FA;  /* superfície, com leve viés índigo             */
  --papel-fundo:  #EAECF4;  /* atrás do cartão, quando sobra espaço         */
  --tinta:        #1C2033;
  --tinta-fraca:  #5C6480;
  --realce:       #151A2E;  /* balão do cliente e botão de enviar           */
  --realce-tinta: #F2F4FB;
  --luz:          #F2A33C;  /* âmbar: a luz que atravessa a fibra           */
  --luz-fraca:    #F7D9A8;
  --borda:        #E3E5EF;
  --erro:         #B3322B;
  --erro-fundo:   #FBEDEC;

  /* --- Medida ---------------------------------------------------------- */
  --largura:      460px;
  --raio:         14px;
  --raio-balao:   16px;
  --respiro:      16px;

  /* --- Tipo ------------------------------------------------------------ */
  --familia: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
             "Helvetica Neue", Arial, sans-serif;
  --t-meta:   0.8125rem;  /* 13px */
  --t-corpo:  0.9375rem;  /* 15px */
  --t-medio:  1.0625rem;  /* 17px */
  --t-alto:   1.375rem;   /* 22px */

  --transicao: 160ms cubic-bezier(.2, .7, .3, 1);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    --nox:         #0B0E1A;
    --nox-alto:    #1B2138;
    --realce:      #2E3759;   /* sobe em relação à superfície, não desce */
    --realce-tinta:#EDF0F8;
    --papel:       #12162A;
    --papel-fundo: #090B14;
    --tinta:       #E7E9F3;
    --tinta-fraca: #9AA2BF;
    --luz:         #F0A94E;
    --luz-fraca:   #E3B077;
    --borda:       #262C44;
    --erro:        #F08C84;
    --erro-fundo:  #2A1917;
  }
}

:root[data-tema="escuro"] {
  --nox:         #0B0E1A;
  --nox-alto:    #1B2138;
  --realce:      #2E3759;   /* sobe em relação à superfície, não desce */
  --realce-tinta:#EDF0F8;
  --papel:       #12162A;
  --papel-fundo: #090B14;
  --tinta:       #E7E9F3;
  --tinta-fraca: #9AA2BF;
  --luz:         #F0A94E;
  --luz-fraca:   #E3B077;
  --borda:       #262C44;
  --erro:        #F08C84;
  --erro-fundo:  #2A1917;
}

/* ========================================================================= */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--papel-fundo);
  color: var(--tinta);
  font-family: var(--familia);
  font-size: var(--t-corpo);
  line-height: 1.55;
  /* dvh em vez de vh: no celular, a barra do navegador que aparece e some
     muda o vh e corta o campo de escrita bem na hora de digitar. */
  min-height: 100dvh;
  display: flex;
  justify-content: center;
  /* A página não rola; a transcrição rola. Sem isto, o salto do teclado
     virtual no celular empurra a tela inteira. */
  overflow: hidden;
}

.tela {
  width: 100%;
  max-width: var(--largura);

  /* ALTURA FIXA, não mínima.
     Com `min-height`, a tela crescia junto com a conversa: quem rolava era a
     PÁGINA, não a transcrição, e o campo de escrita ia parar abaixo da dobra.
     O cliente precisava diminuir o zoom ou rolar à mão para ler a resposta e
     responder — defeito observado em 19/10/2026.
     Travando a altura, a `.conversa` volta a ser quem rola, e o cabeçalho e o
     campo de escrita ficam presos no lugar. */
  height: 100dvh;
  max-height: 100dvh;

  display: flex;
  flex-direction: column;
  background: var(--papel);
  border-inline: 1px solid var(--borda);
  overflow: hidden;
}

@media (min-width: 520px) {
  body { align-items: center; padding: 24px 16px; }
  .tela {
    height: min(720px, calc(100dvh - 48px));
    max-height: calc(100dvh - 48px);
    border: 1px solid var(--borda);
    border-radius: var(--raio);
  }
}

/* === Cabeçalho =========================================================== */

.cabecalho {
  flex: 0 0 auto;
  background: var(--nox);
  color: #F4F5FA;
  padding: 14px var(--respiro);
  padding-top: max(14px, env(safe-area-inset-top));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.marca { display: flex; align-items: baseline; gap: 8px; min-width: 0; }

.marca-nome {
  font-size: var(--t-medio);
  font-weight: 600;
  letter-spacing: -0.012em;
}

.marca-funcao {
  font-size: var(--t-meta);
  font-weight: 400;
  color: #A8B0CC;
}

/* --- O indicador de enlace ---------------------------------------------
   É o elemento principal desta tela. Quem abre o atendimento costuma estar
   sem internet; ver que ESTE caminho está vivo muda a conversa. A luz
   percorre o trilho uma vez a cada ciclo — é o único movimento não disparado
   por ação da pessoa em toda a interface. */

.enlace {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}

.enlace-trilho {
  position: relative;
  display: block;
  width: 34px;
  height: 2px;
  border-radius: 2px;
  background: var(--nox-alto);
  overflow: hidden;
}

.enlace-luz {
  position: absolute;
  inset-block: 0;
  left: -40%;
  width: 40%;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--luz), transparent);
}

.enlace-texto {
  font-size: var(--t-meta);
  color: #A8B0CC;
  white-space: nowrap;
}

.enlace[data-estado="ligando"] .enlace-luz { animation: percorrer 1.1s linear infinite; }

.enlace[data-estado="ligado"] .enlace-luz {
  left: 0;
  width: 100%;
  background: var(--luz);
  animation: respirar 3.4s ease-in-out infinite;
}
.enlace[data-estado="ligado"] .enlace-texto { color: var(--luz-fraca); }

.enlace[data-estado="caido"] .enlace-trilho { background: var(--nox-alto); }
.enlace[data-estado="caido"] .enlace-luz {
  left: 0; width: 100%;
  background: repeating-linear-gradient(90deg,
    var(--nox-alto) 0 4px, transparent 4px 8px);
  animation: none;
}
.enlace[data-estado="caido"] .enlace-texto { color: #8A93B5; }

@keyframes percorrer {
  from { left: -40%; }
  to   { left: 100%; }
}

@keyframes respirar {
  0%, 100% { opacity: 1; }
  50%      { opacity: .45; }
}

/* === Conversa ============================================================ */

.conversa {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--respiro);
  display: flex;
  flex-direction: column;
  gap: 14px;
  scroll-behavior: smooth;
}

.conversa:focus-visible { outline: 2px solid var(--nox); outline-offset: -2px; }

/* --- Abertura ----------------------------------------------------------- */

.partida[hidden] { display: none; }

/* `margin-top: auto` no primeiro item empurra a conversa para baixo enquanto
   ela é curta: as mensagens nascem junto ao campo de escrita e sobem, como
   em qualquer conversa. Quando o conteúdo passa da altura, a margem deixa de
   ter efeito sozinha e a rolagem volta ao normal. */
.conversa > :first-child { margin-top: auto; }

.partida { margin-block: 4px 2px; }

.partida-titulo {
  margin: 0 0 6px;
  font-size: var(--t-alto);
  font-weight: 600;
  letter-spacing: -0.018em;
  line-height: 1.25;
}

.partida-texto {
  margin: 0 0 16px;
  color: var(--tinta-fraca);
  max-width: 38ch;
}

.atalhos { display: flex; flex-wrap: wrap; gap: 8px; }

.atalho {
  font: inherit;
  font-size: var(--t-meta);
  color: var(--tinta);
  background: transparent;
  border: 1px solid var(--borda);
  border-radius: 999px;
  padding: 7px 13px;
  cursor: pointer;
  transition: border-color var(--transicao), background var(--transicao);
}

.atalho:hover { border-color: var(--tinta-fraca); }
.atalho:focus-visible { outline: 2px solid var(--nox); outline-offset: 2px; }
.atalho:active { background: var(--papel-fundo); }

/* --- Mensagens ----------------------------------------------------------
   Cliente e atendimento recebem tratamento diferente de propósito. O balão
   cheio marca o que a pessoa disse; a resposta do atendimento vem como texto
   corrido com um filete âmbar, que é como se lê uma resposta e não uma
   réplica. A distinção não depende de cor sozinha. */

.msg { display: flex; flex-direction: column; max-width: 86%; }

.msg-cliente { align-self: flex-end; align-items: flex-end; }

.msg-cliente .msg-texto {
  background: var(--realce);
  color: var(--realce-tinta);
  padding: 10px 14px;
  border-radius: var(--raio-balao) var(--raio-balao) 4px var(--raio-balao);
}

.msg-atendimento { align-self: flex-start; max-width: 94%; }

.msg-atendimento .msg-texto {
  border-left: 2px solid var(--luz);
  padding: 2px 0 2px 13px;
}

.msg-sistema { align-self: center; max-width: 100%; }

.msg-sistema .msg-texto {
  color: var(--tinta-fraca);
  font-size: var(--t-meta);
  text-align: center;
}

.msg-texto { white-space: pre-wrap; overflow-wrap: anywhere; margin: 0; }

.msg-hora {
  font-size: 0.75rem;
  color: var(--tinta-fraca);
  margin-top: 5px;
  padding-inline: 2px;
}

.msg-atendimento .msg-hora { padding-left: 15px; }
.msg-sistema .msg-hora { display: none; }

/* Mensagem ainda não confirmada pelo servidor. */
.msg-pendente .msg-texto { opacity: .55; }

.msg-falhou .msg-texto {
  background: var(--erro-fundo);
  color: var(--erro);
  border: 1px solid var(--erro);
}
.msg-falhou .msg-hora { color: var(--erro); }

/* Entrada de mensagem nova. É resposta a uma ação, não enfeite. */
.msg { animation: surgir 180ms cubic-bezier(.2, .7, .3, 1); }

@keyframes surgir {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

/* --- Digitando ----------------------------------------------------------- */

.digitando { display: flex; gap: 4px; padding-left: 15px; align-self: flex-start; }

.digitando span {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--tinta-fraca);
  animation: pulsar 1.2s ease-in-out infinite;
}
.digitando span:nth-child(2) { animation-delay: .15s; }
.digitando span:nth-child(3) { animation-delay: .30s; }

@keyframes pulsar {
  0%, 60%, 100% { opacity: .3; transform: translateY(0); }
  30%           { opacity: 1;  transform: translateY(-3px); }
}

/* === Aviso =============================================================== */

/* O atributo `hidden` do HTML vale `display: block` na folha do navegador.
   Qualquer `display` declarado aqui vence por especificidade, e a faixa
   aparecia vazia mesmo escondida. Esta regra precisa vir antes. */
.aviso[hidden] { display: none; }

.aviso {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px var(--respiro);
  background: var(--erro-fundo);
  color: var(--erro);
  font-size: var(--t-meta);
  border-top: 1px solid var(--borda);
}

.aviso-texto { flex: 1 1 auto; }

.aviso-acao {
  font: inherit;
  font-weight: 500;
  color: inherit;
  background: transparent;
  border: 1px solid currentColor;
  border-radius: 999px;
  padding: 4px 12px;
  cursor: pointer;
  flex: 0 0 auto;
}
.aviso-acao:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }

/* === Campo de escrita ==================================================== */

.escrita {
  flex: 0 0 auto;
  border-top: 1px solid var(--borda);
  padding: 10px var(--respiro);
  padding-bottom: max(10px, env(safe-area-inset-bottom));
  background: var(--papel);
}

.formulario { display: flex; align-items: flex-end; gap: 8px; }

.rotulo-oculto {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

.campo {
  flex: 1 1 auto;
  font: inherit;
  color: var(--tinta);
  background: var(--papel-fundo);
  border: 1px solid var(--borda);
  border-radius: 20px;
  padding: 10px 14px;
  resize: none;
  max-height: 140px;
  overflow-y: auto;
  transition: border-color var(--transicao);
}

.campo::placeholder { color: var(--tinta-fraca); }
.campo:focus { outline: none; border-color: var(--nox-alto); }
.campo:focus-visible { outline: 2px solid var(--nox); outline-offset: 1px; }
.campo:disabled { opacity: .55; cursor: not-allowed; }

.enviar {
  flex: 0 0 auto;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  color: var(--realce-tinta);
  background: var(--realce);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  transition: opacity var(--transicao), transform var(--transicao);
}

.enviar:hover:not(:disabled) { opacity: .88; }
.enviar:active:not(:disabled) { transform: scale(.94); }
.enviar:focus-visible { outline: 2px solid var(--nox); outline-offset: 2px; }
.enviar:disabled { opacity: .35; cursor: not-allowed; }

.rodape {
  margin: 8px 2px 0;
  font-size: 0.75rem;
  color: var(--tinta-fraca);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.rodape-aviso { margin: 0; flex: 1 1 auto; }

/* Em 19/10/2026 o botão estava aqui, sublinhado e cinza, e o cliente pediu um
   "botão de reiniciar conversa" sem tê-lo visto. Texto sublinhado no rodapé lê
   como aviso legal, não como controle. Com contorno, lê como botão — sem
   competir com o campo de escrita, que continua sendo a ação principal. */
.rodape-acao {
  flex: 0 0 auto;
  font: inherit;
  color: var(--tinta-fraca);
  background: transparent;
  border: 1px solid var(--borda);
  border-radius: 999px;
  padding: 4px 11px;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color var(--transicao), color var(--transicao);
}

.rodape-acao:hover { color: var(--tinta); border-color: var(--tinta-fraca); }
.rodape-acao:focus-visible { outline: 2px solid var(--nox); outline-offset: 2px; }

@media (max-width: 400px) {
  .rodape { flex-direction: column; gap: 8px; text-align: center; }
  .rodape-aviso { order: 2; }
}

/* === Movimento reduzido ==================================================
   Quem pediu menos movimento no sistema recebe menos movimento. O indicador
   de enlace continua existindo, parado: ele carrega informação, não enfeite. */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .conversa { scroll-behavior: auto; }
  .enlace[data-estado="ligando"] .enlace-luz { left: 0; width: 100%; opacity: .5; }
}

/* === Contraste alto ====================================================== */

@media (prefers-contrast: more) {
  :root { --tinta-fraca: #3A4057; --borda: #9AA2BF; }
  .msg-atendimento .msg-texto { border-left-width: 3px; }
}
