/* mylo-companion.css
   Estilos do avatar/companheiro MYLO (botão flutuante, painel de conversa) e
   pequenas utilidades comuns às 5 páginas (index, sobre, videos, ferramentas, mylo).
   Carregada em TODAS as páginas.
   Dono do avatar: agente do companheiro MYLO. Escrever por baixo do bloco de
   fundações; não apagar o bloco "Fundações". */

/* === Fundações: skip link + foco do <main> (não remover) === */
.skip-link {
  position: fixed;
  left: 12px;
  top: 0;
  z-index: 100000;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 20px;
  border-radius: 999px;
  background: #10294f;
  color: #fffdf5;
  font:
    800 15px/1 "Nunito",
    "Nunito Fallback",
    system-ui,
    sans-serif;
  text-decoration: none;
  box-shadow: 0 6px 20px rgba(16, 41, 79, 0.28);
  transform: translateY(-160%);
  transition: transform 0.18s ease;
}
.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(12px);
  outline: 3px solid #ffe479;
  outline-offset: 2px;
}
main[tabindex="-1"]:focus {
  outline: none;
}
@media (prefers-reduced-motion: reduce) {
  .skip-link {
    transition: none;
  }
}
/* === fim das fundações === */

/* ============================================================
   MYLO — companheiro flutuante
   ============================================================ */
.mylo-companion {
  --mylo-size: 96px;
  --mylo-ink: #06482f;
  position: fixed;
  right: calc(max(16px, env(safe-area-inset-right)) + var(--mylo-shift, 0px));
  /* --mylo-lift: quanto o MYLO sobe para não ficar poisado em cima de um
     controlo (um "Pausar", uma pílula, um link curto). Quem o escreve é o
     dadiva-companion.js, em degraus, depois de medir. Ver lá a explicação. */
  bottom: calc(max(14px, env(safe-area-inset-bottom)) + var(--mylo-lift, 0px));
  transition:
    opacity 0.3s ease,
    bottom 0.3s cubic-bezier(0.22, 0.9, 0.3, 1);
  z-index: 95;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  pointer-events: none;
}
.mylo-companion[hidden] {
  display: none;
}

/* --- botão --- */
.myloc-launch {
  pointer-events: auto;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: calc(var(--mylo-size) + 12px);
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--mylo-ink);
  cursor: pointer;
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
}
.myloc-launch::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 20%;
  width: calc(var(--mylo-size) * 0.84);
  height: calc(var(--mylo-size) * 0.84);
  transform: translateX(-50%);
  border-radius: 50%;
  /* Disco de marfim sólido: o MYLO lê-se como autocolante a flutuar e não
     como um artefacto por cima do texto que está a passar por baixo. */
  background: #fffdf5;
  box-shadow:
    0 6px 18px rgba(16, 41, 79, 0.15),
    0 0 0 1px rgba(16, 41, 79, 0.06);
  z-index: -1;
  transition:
    box-shadow 0.25s ease,
    opacity 0.25s ease,
    transform 0.25s ease;
}
.myloc-launch:hover::before,
.myloc-launch:focus-visible::before {
  box-shadow:
    0 8px 26px rgba(6, 72, 47, 0.24),
    0 0 0 1px rgba(6, 72, 47, 0.12);
}
.myloc-launch:focus-visible {
  outline: 3px solid var(--blue, #0864ec);
  outline-offset: 4px;
  border-radius: 20px;
}
/* Enquanto o voo da landing dura (html.flight, posta pelo dadiva-flight.js)
   este avatar é o DESTINO: não pode mexer-se, por isso o --mylo-lift fica
   preso a zero e ele não se desvia do que estiver por baixo. Em ecrãs
   estreitos os pinos do mapa entram nessa faixa antes de o voo acabar e o
   toque no pino "Vídeos" abria a conversa em vez de ir para /videos
   (medido a 320 e a 360). Enquanto está a chegar, não apanha o dedo: o
   toque passa para o que está por baixo. Não mexe em medida nenhuma — o
   pointer-events não altera a caixa que o voo mede — e assim que a classe
   sai (dock = 1, avatar opaco) volta a ser clicável. */
html.flight .myloc-launch {
  pointer-events: none;
}

/* --- figura (sombra + corpo + brilhos) --- */
.myloc-figure {
  position: relative;
  display: block;
  width: var(--mylo-size);
  height: var(--mylo-size);
  transition:
    width 0.3s ease,
    height 0.3s ease;
}
.myloc-shadow {
  position: absolute;
  left: 50%;
  bottom: 3%;
  width: 54%;
  height: 8%;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(
    ellipse at 50% 50%,
    rgba(16, 41, 79, 0.22),
    rgba(16, 41, 79, 0) 72%
  );
  animation: myloc-shadow-breathe 4.4s ease-in-out infinite;
}
.myloc-body {
  display: block;
  width: 100%;
  height: 100%;
  transform-origin: 50% 94%;
  animation: mylo-breathe 4.4s ease-in-out infinite;
}
.myloc-art {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transform-origin: 50% 92%;
  filter: drop-shadow(0 3px 4px rgba(16, 59, 36, 0.14));
}

/* --- etiqueta --- */
.myloc-label {
  font:
    800 11px/1.3 "Nunito",
    "Nunito Fallback",
    system-ui,
    "Segoe UI",
    sans-serif;
  background: var(--ivory, #fffdf5);
  border: 1px solid #bcd3c8;
  /* Mesmos cantos e sombra dos cartões do mapa e das miniaturas: em todo o
     site há só dois raios — --radius-card e 999px para as pílulas. */
  border-radius: var(--radius-card, 12px);
  padding: 5px 11px;
  margin-top: -4px;
  white-space: nowrap;
  box-shadow: var(--shadow-card, 0 6px 20px rgba(16, 41, 79, 0.08));
  transition:
    opacity 0.25s ease,
    transform 0.25s ease;
}

/* --- brilhos do salto --- */
.myloc-sparks {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
.myloc-sparks i {
  position: absolute;
  left: 50%;
  top: 46%;
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  background: var(--yellow, #ffe479);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.75);
  opacity: 0;
}
.myloc-sparks i:nth-child(1) {
  --sx: -46px;
  --sy: -26px;
}
.myloc-sparks i:nth-child(2) {
  --sx: -18px;
  --sy: -46px;
}
.myloc-sparks i:nth-child(3) {
  --sx: 20px;
  --sy: -48px;
  width: 9px;
  height: 9px;
}
.myloc-sparks i:nth-child(4) {
  --sx: 46px;
  --sy: -22px;
}
.myloc-sparks i:nth-child(5) {
  --sx: -38px;
  --sy: 12px;
  width: 5px;
  height: 5px;
}
.myloc-sparks i:nth-child(6) {
  --sx: 40px;
  --sy: 14px;
  width: 5px;
  height: 5px;
}

/* --- estados --- */
.myloc-launch:hover .myloc-art,
.myloc-launch:focus-visible .myloc-art,
.mylo-companion.is-waving .myloc-art {
  animation: mylo-wave 0.95s ease-in-out 1;
}
.mylo-companion.is-jumping .myloc-body {
  animation: mylo-jump 0.66s cubic-bezier(0.3, 0.9, 0.35, 1) 1;
}
.mylo-companion.is-jumping .myloc-shadow {
  animation: myloc-shadow-jump 0.66s cubic-bezier(0.3, 0.9, 0.35, 1) 1;
}
.mylo-companion.is-jumping .myloc-sparks i {
  animation: mylo-spark 0.72s ease-out 1;
}
.myloc-launch:active .myloc-figure {
  transform: scale(0.95);
}

/* --- recolhido: fica só a cabeça.
   is-tucked  = scroll rápido no telemóvel
   is-quiet   = está no ecrã uma zona onde o MYLO tapava conteúdo (hero,
                mapa, rodapé). Lá também não aparece o balão. Ver a lista
                de zonas em dadiva-companion.js. --- */
.mylo-companion.is-tucked {
  --mylo-size: 56px;
}
.mylo-companion.is-quiet {
  --mylo-size: 64px;
}
/* is-shy = não há UMA faixa livre em toda a coluna direita (o
   dadiva-companion.js já tentou subir o MYLO 64, 128 e 192px). Só aí ele
   encolhe. O que nunca acontece é ficar translúcido: um MYLO a 0.62 de
   opacidade deixava a seta azul das ferramentas aparecer desenhada dentro do
   chapéu, como um erro de render. Opaco, é um autocolante — tapa. O alvo
   tátil continua nos 44px garantidos pelo min-width/min-height. */
.mylo-companion.is-shy {
  --mylo-size: 52px;
}
.mylo-companion.is-quiet .myloc-label,
.mylo-companion.is-tucked .myloc-label,
.mylo-companion.is-shy .myloc-label {
  opacity: 0;
  transform: translateY(8px) scale(0.9);
  pointer-events: none;
  position: absolute;
  bottom: 0;
}

/* --- balão de "chamada de atenção" --- */
.myloc-live {
  pointer-events: none;
  display: flex;
  justify-content: flex-end;
}
.myloc-live:empty {
  display: none;
}
.myloc-bubble {
  pointer-events: auto;
  position: relative;
  max-width: min(244px, calc(var(--dv-w, 100vw) - 44px));
  padding: 13px 48px 13px 15px;
  border: 1px solid #cfe0d6;
  border-radius: 18px 18px 5px 18px;
  background: var(--ivory, #fffdf5);
  color: var(--navy, #10294f);
  font:
    700 14px/1.45 "Nunito",
    "Nunito Fallback",
    system-ui,
    "Segoe UI",
    sans-serif;
  box-shadow: 0 12px 30px rgba(16, 41, 79, 0.16);
  transform-origin: 100% 100%;
  animation: myloc-bubble-in 0.42s cubic-bezier(0.2, 1.1, 0.35, 1) 1;
}
.myloc-bubble::after {
  content: "";
  position: absolute;
  right: 18px;
  bottom: -7px;
  width: 13px;
  height: 13px;
  background: var(--ivory, #fffdf5);
  border-right: 1px solid #cfe0d6;
  border-bottom: 1px solid #cfe0d6;
  transform: rotate(45deg) skew(6deg, 6deg);
  border-bottom-right-radius: 3px;
}
.myloc-bubble-close {
  position: absolute;
  top: 0;
  right: 0;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  color: inherit;
  font-size: 19px;
  line-height: 1;
  opacity: 0.72;
  cursor: pointer;
  border-radius: 18px;
}
.myloc-bubble-close:hover {
  opacity: 1;
}
.mylo-companion.is-tucked .myloc-bubble {
  display: none;
}

/* --- animações --- */
@keyframes mylo-breathe {
  0%,
  100% {
    transform: translateY(0) scale(1, 1);
  }
  50% {
    transform: translateY(-2.5px) scale(0.985, 1.02);
  }
}
@keyframes myloc-shadow-breathe {
  0%,
  100% {
    transform: translateX(-50%) scale(1);
    opacity: 1;
  }
  50% {
    transform: translateX(-50%) scale(0.88);
    opacity: 0.8;
  }
}
@keyframes mylo-wave {
  0% {
    transform: rotate(0) translateY(0);
  }
  18% {
    transform: rotate(-9deg) translateY(-5px);
  }
  42% {
    transform: rotate(7deg) translateY(-3px);
  }
  64% {
    transform: rotate(-5deg) translateY(-4px);
  }
  84% {
    transform: rotate(3deg) translateY(-1px);
  }
  100% {
    transform: rotate(0) translateY(0);
  }
}
@keyframes mylo-jump {
  0% {
    transform: translateY(0) scale(1, 1);
  }
  16% {
    transform: translateY(2px) scale(1.13, 0.85);
  }
  34% {
    transform: translateY(-26%) scale(0.9, 1.14);
  }
  56% {
    transform: translateY(-30%) scale(0.97, 1.04);
  }
  78% {
    transform: translateY(0) scale(1.12, 0.87);
  }
  100% {
    transform: translateY(0) scale(1, 1);
  }
}
@keyframes myloc-shadow-jump {
  0% {
    transform: translateX(-50%) scale(1);
    opacity: 1;
  }
  16% {
    transform: translateX(-50%) scale(1.2, 0.9);
    opacity: 1;
  }
  45% {
    transform: translateX(-50%) scale(0.55);
    opacity: 0.4;
  }
  78% {
    transform: translateX(-50%) scale(1.2, 0.9);
    opacity: 1;
  }
  100% {
    transform: translateX(-50%) scale(1);
    opacity: 1;
  }
}
@keyframes mylo-spark {
  0% {
    opacity: 0;
    transform: translate(0, 0) scale(0.3);
  }
  22% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translate(var(--sx, 0), var(--sy, 0)) scale(1.1);
  }
}
@keyframes myloc-bubble-in {
  0% {
    opacity: 0;
    transform: translateY(10px) scale(0.86);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@media (max-width: 700px) {
  .mylo-companion {
    --mylo-size: 76px;
    /* 14px de folga mínima; em ecrãs com barra de gestos o env() sobe para
       ~34px e o botão nunca cai dentro da zona do indicador. */
    right: calc(max(14px, env(safe-area-inset-right)) + var(--mylo-shift, 0px));
    bottom: calc(
      max(14px, env(safe-area-inset-bottom)) + var(--mylo-lift, 0px)
    );
    gap: 8px;
  }
  /* No mapa o rótulo tem de se ver: sem ele o avatar era um autocolante. */
  .mylo-companion.is-quiet .myloc-label {
    opacity: 1;
    transform: none;
    position: static;
    pointer-events: none;
  }
  .myloc-label {
    font-size: 10px;
    padding: 4px 9px;
  }
  .myloc-bubble {
    font-size: 13px;
    padding: 12px 46px 12px 13px;
  }
  /* Com texto por baixo, no telemóvel, encosta-se mesmo ao canto: é a única
     forma de a última linha de uma frase centrada passar ao lado dele. */
  .mylo-companion.is-shy {
    --mylo-size: 48px;
    right: calc(max(6px, env(safe-area-inset-right)) + var(--mylo-shift, 0px));
  }
}

/* Encostado ao canto, o lançador fica mais estreito (60px) do que a etiqueta
   "Fala comigo" (77px). Centrada, ela saía para lá da margem direita do ecrã.
   Alinhada pela direita cresce para DENTRO e o seu limite passa a ser o mesmo
   do avatar — que está sempre a 6–16px da aresta. No PC continua centrada
   (sobra ecrã de lado e é assim que o Jaime a viu). */
.mylo-companion.is-shy .myloc-label {
  align-self: flex-end;
}
/* Telemóvel e tablet: a etiqueta NUNCA sai do ecrã, venha o estado que vier
   (is-quiet, is-shy, is-tucked, PT ou EN). Duas garantias independentes:
   alinhada pela direita (cresce para dentro) e com um tecto de largura que
   é a largura VISÍVEL do documento menos a goteira dos dois lados. A
   --dv-w é escrita pelo dadiva-companion.js (clientWidth real, já sem a
   barra de scroll) e cai para 100vw se o script ainda não correu. */
@media (max-width: 1024px) {
  .myloc-label {
    align-self: flex-end;
    max-width: calc(var(--dv-w, 100vw) - 28px);
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* ── Tablet (701–1024px) ────────────────────────────────────────────────
   Aqui o conteúdo das páginas interiores vai quase até à margem do ecrã,
   como no telemóvel, mas o avatar tinha ainda o tamanho de PC (96px, a
   16px do canto): ficava poisado em cima dos botões "Pausar" dos cartões
   da Sobre e a cortar os contadores das categorias da Vídeos. O tratamento
   de canto do telemóvel passa a valer também no tablet. */
@media (min-width: 701px) and (max-width: 1024px) {
  .mylo-companion {
    --mylo-size: 80px;
    right: calc(max(12px, env(safe-area-inset-right)) + var(--mylo-shift, 0px));
  }
  .mylo-companion.is-quiet {
    --mylo-size: 64px;
  }
  .mylo-companion.is-shy {
    --mylo-size: 52px;
    right: calc(max(6px, env(safe-area-inset-right)) + var(--mylo-shift, 0px));
  }
}

/* Ecrãs de 360px ou menos: o canto do MYLO é proporcionalmente muito maior
   (um disco de 64px come 20% da largura), por isso ele anda sempre um ponto
   mais pequeno e mais encostado ao canto. */
@media (max-width: 360px) {
  .mylo-companion {
    --mylo-size: 64px;
  }
  .mylo-companion.is-quiet {
    --mylo-size: 56px;
  }
  .mylo-companion.is-shy {
    --mylo-size: 44px;
  }
}

/* Folga para o avatar no fim da página. Sobre o rodapé ele está sempre em
   is-quiet (64px, sem etiqueta) e assenta a 14px do fundo: 96px chegam e
   sobram. Com os 130px de antes ficava uma faixa de marfim vazia que fazia
   a página parecer ter perdido a última secção. */
.site-footer,
.inner-page footer {
  padding-bottom: 96px;
}
@media (max-width: 700px) {
  .site-footer,
  .inner-page footer {
    padding-bottom: 88px;
  }
}

/* --- diálogos: a página não escorrega por trás deles ---
   Sem isto a roda do rato sobre o fundo levava o scroll de 0 a 600 com o
   diálogo aberto, e no telemóvel o mesmo acontecia por encadeamento quando o
   conteúdo do diálogo chegava ao fim. O scrollbar-gutter entra no mesmo
   instante em que a barra desaparece, por isso não há salto de largura.
   A conversa do MYLO está de fora: no PC ela é um cartão ancorado ao canto,
   não um modal centrado, e travar a página por trás de um cartão de 400px
   dava a sensação de o site ter encravado. Aí o encadeamento é travado só
   pelo overscroll-behavior, que chega. No telemóvel — onde a conversa ocupa
   o ecrã todo — a página continua travada (regra a seguir). */
html:has(dialog[open]:not(#chat)) {
  overflow: hidden;
  scrollbar-gutter: stable;
}
@media (max-width: 700px) {
  html:has(#chat[open]) {
    overflow: hidden;
  }
}
dialog,
.chat-scroll {
  overscroll-behavior: contain;
}

@media (prefers-reduced-motion: reduce) {
  .myloc-body,
  .myloc-shadow,
  .myloc-art,
  .myloc-bubble,
  .myloc-sparks i,
  .mylo-companion.is-jumping .myloc-body,
  .mylo-companion.is-jumping .myloc-shadow,
  .mylo-companion.is-jumping .myloc-sparks i,
  .myloc-launch:hover .myloc-art,
  .myloc-launch:focus-visible .myloc-art,
  .mylo-companion.is-waving .myloc-art {
    animation: none !important;
  }
  .mylo-companion,
  .myloc-figure,
  .myloc-label,
  .myloc-launch::before {
    transition: none !important;
  }
  .myloc-launch:active .myloc-figure {
    transform: none;
  }
  .myloc-sparks {
    display: none;
  }
}

/* ============================================================
   Conversa com o MYLO — <dialog id="chat">, injetado pelo companion
   ------------------------------------------------------------
   Um só diálogo, duas formas:

   • TELEMÓVEL (<=700px) — FOLHA QUE SOBE do fundo, com pega, cantos
     arredondados em cima e arrastar para baixo para fechar. A folha ABRAÇA o
     conteúdo (height:auto) até um tecto de 92dvh: ao abrir vê-se uma folha
     curta com a saudação, as três sugestões e a barra de escrita, e ela
     cresce à medida que a conversa cresce. Era aqui que estava o defeito
     apontado no QA: com altura fixa de ecrã inteiro ficavam ~415px de creme
     vazio entre o cabeçalho e a primeira bolha.
     A folha é ancorada em BAIXO pelo --vv-bottom (o que sobra do viewport
     visual por baixo dela, ou seja a altura do teclado) e nunca por 100dvh:
     com o teclado aberto o iOS não encolhe o viewport de layout e a barra de
     escrita ficava escondida por baixo das teclas. O tecto usa o --vv-h pela
     mesma razão. Cabeçalho e barra de escrita são fixos; só as mensagens
     rolam. As margens de segurança (env(safe-area-*)) entram no cabeçalho,
     na barra de escrita e na nota, não no diálogo, para o fundo chegar mesmo
     às arestas.

   • PC (>700px) — cartão de 400x620 ancorado ao canto inferior direito, ao
     pé do avatar, a abrir a partir dele. Não é um modal centrado: a página
     continua à vista e a rolar por trás (ver a regra do scroll lock).

   Esc, foco preso dentro do diálogo e foco devolvido a quem o abriu vêm do
   <dialog> nativo (showModal). O texto todo é escrito pelo
   dadiva-companion.js na língua do <html lang> — nada aqui tem palavras.
   ============================================================ */
.chat-dialog {
  /* Tokens locais: a conversa usa a paleta do site, escrita uma vez. */
  --chat-cream: #fffdf5;
  --chat-warm: #fffaea;
  --chat-line: rgba(16, 41, 79, 0.1);
  --chat-bot: #ffffff;
  --chat-bot-line: #e8dcc0;
  --chat-user: #ffe479;
  --chat-user-line: #edcb58;
  --chat-muted: #4a5f77;

  position: fixed;
  margin: 0;
  padding: 0;
  border: 0;
  max-width: none;
  max-height: none;
  background: var(--chat-cream);
  color: var(--navy, #10294f);
  font:
    400 16px/1.5 "Nunito",
    "Nunito Fallback",
    system-ui,
    "Segoe UI",
    sans-serif;
  overflow: hidden;

  /* Telemóvel primeiro: folha que sobe do fundo e abraça o conteúdo. */
  left: 0;
  right: 0;
  top: auto;
  bottom: var(--vv-bottom, 0px);
  width: 100%;
  height: auto;
  max-height: min(92dvh, calc(var(--vv-h, 100dvh) - 10px));
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -8px 40px rgba(16, 41, 79, 0.22);
  /* O arrastar escreve aqui. É a propriedade `translate` e não o `transform`
     de propósito: o transform está entregue à animação de entrada (com
     fill both, que o fixa em `none` no fim) e as duas coexistem sem se
     pisarem. */
  translate: 0 var(--chat-dy, 0px);
}
/* No telemóvel o foco vai para o próprio <dialog> ao abrir, para o leitor de
   ecrã anunciar a conversa sem fazer subir o teclado. Ele não é um controlo:
   um anel azul de 3px à volta da folha inteira lia-se como uma moldura
   errada (antes não se via porque a folha ocupava o ecrã todo e o contorno
   ficava fora dele). Os elementos lá dentro mantêm todos o seu anel. */
.chat-dialog:focus,
.chat-dialog:focus-visible {
  outline: none;
}
/* Enquanto o dedo manda, nada de transições — a folha segue o dedo. */
.chat-dialog.is-dragging {
  transition: none;
}
.chat-dialog.is-easing {
  transition: translate 0.24s cubic-bezier(0.22, 0.9, 0.3, 1);
}
.chat-dialog[open] {
  display: flex;
  flex-direction: column;
  animation: chat-sheet-in 0.34s cubic-bezier(0.22, 0.9, 0.3, 1) both;
}
.chat-dialog::backdrop {
  background: rgba(16, 41, 79, 0.44);
  backdrop-filter: blur(4px);
}
.chat-dialog[open]::backdrop {
  animation: chat-veil-in 0.3s ease both;
}

/* Só para leitores de ecrã: o estado da conversa é anunciado sem aparecer
   duas vezes (já se vê no cabeçalho e nas bolhas). */
.chat-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- cabeçalho: pega, avatar, nome, estado, fechar ---
   No telemóvel o cabeçalho é também a pega da folha: é por aqui que se
   arrasta para baixo para fechar (o dadiva-companion.js trata do gesto). O
   touch-action:none é o que impede o browser de interpretar o mesmo
   movimento como scroll da página. A zona das mensagens e o campo de
   escrita ficam de fora do gesto de propósito — lá o dedo é para ler e
   para escrever. */
.chat-head {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 18px 10px 10px 16px;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(10px, env(safe-area-inset-right));
  background: linear-gradient(180deg, #fff4cf 0%, var(--chat-warm) 100%);
  border-bottom: 1px solid var(--chat-line);
  touch-action: none;
}
/* A pega. Decorativa: quem não vê o ecrã fecha pelo botão, pelo Esc ou pelo
   toque fora, que continuam todos lá. */
.chat-head::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 7px;
  width: 42px;
  height: 4px;
  transform: translateX(-50%);
  border-radius: 2px;
  background: rgba(16, 41, 79, 0.22);
}
.chat-avatar {
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  object-fit: contain;
  filter: drop-shadow(0 3px 4px rgba(16, 59, 36, 0.14));
}
.chat-id {
  flex: 1 1 auto;
  min-width: 0;
}
.chat-name {
  display: block;
  margin: 0;
  color: var(--green, #06482f);
  font:
    800 18px/1.15 "Nunito",
    "Nunito Fallback",
    system-ui,
    "Segoe UI",
    sans-serif;
  letter-spacing: 0.4px;
}
.chat-state {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 3px 0 0;
  font-size: 13px;
  line-height: 1.3;
  color: #2f5c47;
}
.chat-pulse {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #2b7f52;
  animation: chat-pulse 2.8s ease-out infinite;
}
.chat-dialog.is-busy .chat-pulse {
  animation-duration: 1.1s;
}
.chat-close {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 253, 245, 0.85);
  box-shadow: 0 0 0 1px rgba(16, 41, 79, 0.08);
  color: var(--navy, #10294f);
  cursor: pointer;
  transition:
    background 0.16s ease,
    transform 0.16s ease;
}
.chat-close svg {
  width: 17px;
  height: 17px;
}
.chat-close:hover {
  background: #fff;
}
.chat-close:active {
  transform: scale(0.94);
}
.chat-close:focus-visible {
  outline: 3px solid var(--blue, #0864ec);
  outline-offset: 2px;
}

/* --- corpo: as mensagens rolam, o botão de ir para o fim flutua --- */
.chat-body {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.chat-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 14px 16px 12px;
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
  scroll-behavior: smooth;
  /* A conversa assenta em baixo, como em qualquer conversa: com duas linhas
     escritas o vazio fica em cima, ao pé do cabeçalho, e não entre a última
     bolha e a barra de escrita. O margin-top:auto resolve-se a zero assim
     que o conteúdo passa a altura da caixa, por isso nada é cortado em cima
     quando a conversa cresce (o que aconteceria com justify-content:end). */
  display: flex;
  flex-direction: column;
}
.chat-log {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* --- bolhas --- */
.chat-log > p {
  position: relative;
  margin: 0;
  max-width: 85%;
  padding: 11px 15px;
  border: 1px solid var(--chat-bot-line);
  border-radius: 18px 18px 18px 6px;
  background: var(--chat-bot);
  box-shadow: 0 2px 6px rgba(16, 41, 79, 0.05);
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  align-self: flex-start;
  animation: chat-msg-in 0.26s cubic-bezier(0.22, 0.9, 0.3, 1) both;
}
/* Cauda: um quadradinho rodado 45 graus, metade por baixo da bolha (mesma
   cor, por isso não se vê a emenda) e metade de fora, a mostrar só os dois
   lados com risco. É o mesmo truque do balão do avatar, espelhado. */
.chat-log > p::after {
  content: "";
  position: absolute;
  left: -3px;
  bottom: 1px;
  width: 10px;
  height: 10px;
  background: inherit;
  border-left: 1px solid var(--chat-bot-line);
  border-bottom: 1px solid var(--chat-bot-line);
  border-bottom-left-radius: 3px;
  transform: rotate(45deg) skew(5deg, 5deg);
}
.chat-log > p.user {
  align-self: flex-end;
  background: var(--chat-user);
  border-color: var(--chat-user-line);
  border-radius: 18px 18px 6px 18px;
}
.chat-log > p.user::after {
  left: auto;
  right: -3px;
  border-left: 0;
  border-bottom: 1px solid var(--chat-user-line);
  border-right: 1px solid var(--chat-user-line);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 3px;
  transform: rotate(-45deg) skew(-5deg, -5deg);
}
/* A primeira bolha traz a apresentação: uma linha forte e o convite. */
.chat-log > p.intro {
  max-width: 92%;
}
.chat-greet {
  display: block;
  margin-bottom: 3px;
  color: var(--green, #06482f);
  font-weight: 800;
  font-size: 17px;
}

/* --- a escrever --- */
.chat-log > p.thinking {
  padding: 14px 18px;
}
.chat-dots {
  display: inline-flex;
  gap: 5px;
  align-items: center;
  height: 8px;
}
.chat-dots i {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--green, #06482f);
  opacity: 0.35;
  animation: chat-dot 1.1s ease-in-out infinite;
}
.chat-dots i:nth-child(2) {
  animation-delay: 0.15s;
}
.chat-dots i:nth-child(3) {
  animation-delay: 0.3s;
}

/* --- erro: amigável, com saída --- */
/* O aviso ocupa a largura toda e o botão fica por baixo: numa coluna de
   390px, texto e botão lado a lado partiam a frase em cinco linhas de duas
   palavras. */
.chat-log > .chat-error {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin: 0;
  padding: 13px 15px;
  border: 1px solid #efd5a0;
  border-radius: 16px;
  background: #fff6e2;
  animation: chat-msg-in 0.26s cubic-bezier(0.22, 0.9, 0.3, 1) both;
}
.chat-error p {
  margin: 0;
  font-size: 15px;
  line-height: 1.45;
}
.chat-retry {
  flex: 0 0 auto;
  min-height: 44px;
  padding: 8px 18px;
  border: 1.5px solid var(--green, #06482f);
  border-radius: 999px;
  background: #fff;
  color: var(--green, #06482f);
  font:
    700 14px/1.2 "Nunito",
    "Nunito Fallback",
    system-ui,
    "Segoe UI",
    sans-serif;
  cursor: pointer;
  transition:
    background 0.16s ease,
    transform 0.16s ease;
}
.chat-retry:hover {
  background: #f1f8f3;
}
.chat-retry:active {
  transform: scale(0.97);
}
.chat-retry:focus-visible {
  outline: 3px solid var(--blue, #0864ec);
  outline-offset: 2px;
}

/* --- sugestões iniciais --- */
.chat-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 12px 0 0;
}
.chat-chips[hidden] {
  display: none;
}
.chat-chip {
  min-height: 44px;
  padding: 10px 17px;
  border: 1px solid #bcd3c8;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 2px 6px rgba(16, 41, 79, 0.05);
  color: var(--green, #06482f);
  font:
    700 14px/1.2 "Nunito",
    "Nunito Fallback",
    system-ui,
    "Segoe UI",
    sans-serif;
  cursor: pointer;
  animation: chat-msg-in 0.34s cubic-bezier(0.22, 0.9, 0.3, 1) both;
  transition:
    background 0.18s ease,
    border-color 0.18s ease,
    transform 0.18s ease;
}
.chat-chip:nth-child(1) {
  animation-delay: 0.06s;
}
.chat-chip:nth-child(2) {
  animation-delay: 0.12s;
}
.chat-chip:nth-child(3) {
  animation-delay: 0.18s;
}
.chat-chip:hover {
  background: #fff;
  border-color: #9cc3af;
}
.chat-chip:active {
  transform: scale(0.97);
}
.chat-chip:focus-visible {
  outline: 3px solid var(--blue, #0864ec);
  outline-offset: 2px;
}

/* --- ir para o fim --- */
.chat-jump {
  position: absolute;
  left: 50%;
  bottom: 10px;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 1px solid #cfe0d6;
  border-radius: 50%;
  background: var(--ivory, #fffdf5);
  box-shadow: 0 8px 22px rgba(16, 41, 79, 0.18);
  color: var(--green, #06482f);
  cursor: pointer;
  transform: translateX(-50%);
  animation: chat-jump-in 0.24s ease both;
}
.chat-jump[hidden] {
  display: none;
}
.chat-jump svg {
  width: 18px;
  height: 18px;
}
.chat-jump:hover {
  background: #fff;
}
.chat-jump:focus-visible {
  outline: 3px solid var(--blue, #0864ec);
  outline-offset: 2px;
}

/* --- barra de escrita --- */
.chat-compose {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-end;
  gap: 10px;
  padding: 10px 14px;
  padding-left: max(14px, env(safe-area-inset-left));
  padding-right: max(14px, env(safe-area-inset-right));
  background: var(--chat-cream);
  border-top: 1px solid var(--chat-line);
}
/* A moldura não tem enchimento vertical: quem o tem é o <textarea>, para o
   alvo de toque ter os 44px em toda a altura da barra (carregar na margem
   da moldura focava o nada). */
.chat-field {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  padding: 0 15px;
  border: 1.5px solid #c6d8cd;
  border-radius: 23px;
  background: #fff;
  cursor: text;
  transition:
    border-color 0.16s ease,
    box-shadow 0.16s ease;
}
/* UM anel, arredondado, o da pílula. O <textarea> lá dentro não desenha
   contorno nenhum: o :focus-visible geral (dadiva.css) e o das páginas
   interiores (.inner-page :focus-visible, dadiva-inner.css) punham por cima
   um retângulo de 3px a 4px de distância, com border-radius 0 — dois anéis
   com formas diferentes à volta do mesmo campo. Como esses seletores têm
   duas classes de especificidade, `.chat-field textarea { outline: none }`
   não chegava; o #chatInput é que ganha sempre. Ver o bloco do textarea
   logo a seguir. */
.chat-field:focus-within {
  border-color: var(--blue, #0864ec);
  /* 1,5px de borda a #0864ec sobre branco = 5,2:1 (AA folgado para um
     elemento de interface, que pede 3:1) e um halo de 3px que se vê de
     relance sem pesar. */
  box-shadow: 0 0 0 3px rgba(8, 100, 236, 0.34);
}
/* 16px é o mínimo para o Safari do iOS não dar zoom ao focar o campo. */
.chat-field textarea {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px; /* 1 linha de 22px + 2x11 de enchimento */
  max-height: 110px; /* 4 linhas + enchimento */
  margin: 0;
  padding: 11px 0;
  border: 0;
  background: transparent;
  color: var(--navy, #10294f);
  font:
    400 16px/22px "Nunito",
    "Nunito Fallback",
    system-ui,
    "Segoe UI",
    sans-serif;
  resize: none;
  outline: none;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* O id é preciso: qualquer regra de folha partilhada com duas classes
   (.inner-page :focus-visible) ganhava a um seletor de elemento. Cobre
   rato/toque (:focus) e teclado (:focus-visible) — o anel visível é sempre
   o da .chat-field, aqui em cima. */
#chatInput:focus,
#chatInput:focus-visible,
.chat-field textarea:focus,
.chat-field textarea:focus-visible {
  outline: none;
  outline-offset: 0;
  box-shadow: none;
}
.chat-field textarea::placeholder {
  color: #5a7089;
  opacity: 1;
}
.chat-send {
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: var(--blue, #0864ec);
  box-shadow: 0 4px 14px rgba(8, 100, 236, 0.3);
  color: #fff;
  cursor: pointer;
  transition:
    background 0.16s ease,
    transform 0.16s ease,
    box-shadow 0.16s ease;
}
.chat-send svg {
  width: 20px;
  height: 20px;
}
.chat-send:hover:not(:disabled) {
  background: #0a55c4;
}
.chat-send:active:not(:disabled) {
  transform: scale(0.93);
}
.chat-send:disabled {
  background: #e2e8ef;
  box-shadow: none;
  color: #6b7c91;
  cursor: default;
}
.chat-send:focus-visible {
  outline: 3px solid var(--blue, #0864ec);
  outline-offset: 3px;
}

/* --- nota de privacidade: uma linha, abre se quiserem ler --- */
.chat-note {
  flex: 0 0 auto;
  padding: 0 16px max(4px, env(safe-area-inset-bottom));
  padding-left: max(16px, env(safe-area-inset-left));
  padding-right: max(16px, env(safe-area-inset-right));
  background: var(--chat-cream);
  color: var(--chat-muted);
  font-size: 12.5px;
}
.chat-note > summary {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  list-style: none;
  cursor: pointer;
  font-weight: 700;
  color: var(--chat-muted);
}
.chat-note > summary::-webkit-details-marker {
  display: none;
}
.chat-note > summary::after {
  content: "";
  width: 7px;
  height: 7px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  opacity: 0.7;
  transition: transform 0.18s ease;
}
.chat-note[open] > summary::after {
  transform: translateY(1px) rotate(-135deg);
}
.chat-note > summary:focus-visible {
  outline: 3px solid var(--blue, #0864ec);
  outline-offset: 2px;
  border-radius: 8px;
}
.chat-note p {
  margin: 0 0 10px;
  line-height: 1.5;
}
/* Com o teclado aberto cada linha conta: a nota sai e volta assim que ele
   fecha. Já esteve à vista antes de se começar a escrever. */
/* Com o teclado aberto sobra pouca folha: o cabeçalho encolhe e as margens
   das mensagens apertam-se, para a saudação e as três sugestões caberem sem
   se ter de rolar. Não chega para tudo a 320px (ver o relatório), mas cada
   píxel aqui é uma linha de texto que se lê sem mexer no dedo. */
.chat-dialog.kb-open .chat-head {
  padding-top: 12px;
  padding-bottom: 7px;
}
.chat-dialog.kb-open .chat-head::before {
  top: 5px;
}
.chat-dialog.kb-open .chat-avatar {
  width: 38px;
  height: 38px;
}
.chat-dialog.kb-open .chat-scroll {
  padding-top: 9px;
  padding-bottom: 8px;
}
.chat-dialog.kb-open .chat-note {
  display: none;
}

/* ── PC e tablet: cartão ancorado ao canto, ao pé do avatar ────────────── */
@media (min-width: 701px) {
  .chat-dialog {
    left: auto;
    top: auto;
    right: calc(max(16px, env(safe-area-inset-right)) + var(--mylo-shift, 0px));
    bottom: max(16px, env(safe-area-inset-bottom));
    width: min(400px, calc(var(--dv-w, 100vw) - 32px));
    height: min(620px, calc(100dvh - 32px));
    /* Aqui é cartão, não folha: sem tecto, sem pega e sem arrastar. */
    max-height: none;
    translate: none;
    border-radius: 24px;
    box-shadow:
      0 26px 70px rgba(16, 41, 79, 0.26),
      0 2px 10px rgba(16, 41, 79, 0.08);
    transform-origin: 100% 100%;
  }
  .chat-dialog[open] {
    animation: chat-pop 0.32s cubic-bezier(0.2, 1.05, 0.35, 1) both;
  }
  /* Véu leve: o cartão não é um modal centrado, a página fica à vista. */
  .chat-dialog::backdrop {
    background: rgba(16, 41, 79, 0.14);
    backdrop-filter: none;
  }
  .chat-head {
    padding: 14px 12px 13px 18px;
    touch-action: auto;
  }
  .chat-head::before {
    display: none;
  }
  .chat-scroll {
    padding: 16px 18px 12px;
  }
  .chat-compose {
    padding: 12px 16px;
  }
  .chat-note {
    padding: 0 18px 6px;
  }
}

/* --- animações --- */
@keyframes chat-sheet-in {
  from {
    opacity: 0;
    transform: translateY(26px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes chat-pop {
  from {
    opacity: 0;
    transform: translateY(16px) scale(0.9);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes chat-veil-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes chat-msg-in {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes chat-jump-in {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateX(-50%);
  }
}
@keyframes chat-dot {
  0%,
  100% {
    opacity: 0.3;
    transform: translateY(0);
  }
  40% {
    opacity: 1;
    transform: translateY(-3px);
  }
}
@keyframes chat-pulse {
  0%,
  72%,
  100% {
    opacity: 1;
    transform: scale(1);
  }
  36% {
    opacity: 0.55;
    transform: scale(0.72);
  }
}

@media (prefers-reduced-motion: reduce) {
  .chat-dialog[open],
  .chat-dialog[open]::backdrop,
  .chat-log > p,
  .chat-log > .chat-error,
  .chat-chip,
  .chat-jump,
  .chat-dots i,
  .chat-pulse {
    animation: none !important;
  }
  .chat-dots i {
    opacity: 0.6;
  }
  .chat-dialog::backdrop {
    backdrop-filter: none;
  }
  .chat-scroll {
    scroll-behavior: auto;
  }
  .chat-close,
  .chat-chip,
  .chat-retry,
  .chat-send,
  .chat-field,
  .chat-note > summary::after {
    transition: none !important;
  }
}
