/*
 * Paleta alinhada ao portal do TRE-RJ e à identidade Eleições 2026.
 * O verde sobrou apenas na mensagem de sucesso, onde é cor de estado e não
 * de identidade.
 */
:root {
  --verde-sucesso: #17532e;
  --amarelo: #f2b705;
  --fundo: #ffffff;
  --grafite: #3c3c3b;
  --verde-hashtag: #456d2a;
  --azul-hashtag: #137c9a;
  --azul-escuro: #0d5f78;
  --tinta: #23302a;
  --tinta-suave: #48564e;
  --borda: #e2d9c9;
  --erro: #a12626;
  /* Azuis do portal do TRE-RJ, medidos nas capturas do site: a barra do topo e
     a primeira faixa do rodapé usam o mesmo tom; a faixa de baixo é o escuro. */
  --azul-institucional: #1b305a;
  --azul-institucional-escuro: #0c2345;
  color-scheme: light;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--fundo);
  color: var(--tinta);
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
  line-height: 1.55;
  /* Coluna de altura mínima igual à da tela: em tela alta, o rodapé
     institucional encosta embaixo em vez de deixar uma faixa branca. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.pagina {
  flex: 1 0 auto;
  width: 100%;
  max-width: 46rem;
  margin: 0 auto;
  padding: 2.5rem 1.25rem 3rem;
}

.cabecalho {
  text-align: center;
  margin-bottom: 2.5rem;
}

.cabecalho h1 {
  margin: 0;
  font-size: clamp(2rem, 6vw, 2.9rem);
  line-height: 1.1;
  color: var(--azul-hashtag);
}

.subtitulo {
  margin: 0.75rem auto 0;
  max-width: 40rem;
  color: var(--tinta-suave);
}

.passos ol {
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  margin: 0 0 2rem;
  padding: 0;
  list-style: none;
}

.passos li {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
}

.passo-numero {
  flex: 0 0 auto;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  background: var(--azul-hashtag);
  color: #fff;
  font-weight: 700;
  display: grid;
  place-items: center;
}

.passos h2 {
  margin: 0.1rem 0 0.2rem;
  font-size: 1rem;
  color: var(--azul-hashtag);
}

.passos p {
  margin: 0;
  font-size: 0.92rem;
  color: var(--tinta-suave);
}

.cartao {
  background: #fff;
  border: 1px solid var(--borda);
  border-radius: 1rem;
  padding: 1.75rem;
  box-shadow: 0 1px 2px rgb(35 48 42 / 6%);
}

.campo {
  display: block;
  margin-bottom: 1.25rem;
}

.campo-titulo {
  display: block;
  font-weight: 600;
}

.campo-ajuda {
  display: block;
  font-size: 0.85rem;
  color: var(--tinta-suave);
  margin-bottom: 0.6rem;
}

input[type='file'] {
  display: block;
  width: 100%;
  padding: 0.75rem;
  border: 1px dashed var(--azul-hashtag);
  border-radius: 0.6rem;
  background: #fbfaf6;
  font: inherit;
  cursor: pointer;
}

input[type='file']:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

/* Ícones dos botões: acompanham o tamanho e a cor do texto. */
.botao-principal svg,
.botao-secundario svg,
.botao-whatsapp svg {
  flex: 0 0 auto;
  width: 1.15em;
  height: 1.15em;
}

/*
 * Ajuste de enquadramento. O palco reproduz a arte em miniatura: a foto fica
 * na área correspondente ao buraco da moldura e a moldura real é desenhada por
 * cima, de modo que o que o usuário vê é o que será gerado.
 *
 * As medidas da área vêm do servidor (atributos data-* no HTML) e são aplicadas
 * pelo JavaScript — não ficam fixas aqui, para acompanharem uma troca da arte.
 */
.editor {
  margin: 0 0 1.25rem;
  text-align: center;
}

.editor-titulo {
  margin: 0 0 0.7rem;
  font-weight: 600;
}

.editor-palco {
  position: relative;
  width: min(19rem, 100%);
  margin: 0 auto;
  aspect-ratio: 2 / 3;
  border-radius: 0.6rem;
  overflow: hidden;
  background: #fff;
}

.editor-palco:focus-visible {
  outline: 3px solid var(--amarelo);
  outline-offset: 3px;
}

.editor-area {
  position: absolute;
  overflow: hidden;
  cursor: grab;
  background: #e7edf0;
  /* Impede o navegador de rolar a página enquanto se arrasta a foto no toque. */
  touch-action: none;
}

.editor-area:active {
  cursor: grabbing;
}

.editor-area img {
  position: absolute;
  /* left/top explícitos: sem eles o elemento usa a posição estática, que sob o
     text-align: center herdado do .editor cai no meio da área — a foto nasceria
     deslocada para a direita, deixando faixa vazia à esquerda no zoom mínimo. */
  left: 0;
  top: 0;
  transform-origin: 0 0;
  user-select: none;
  -webkit-user-drag: none;
}

.editor-moldura {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.editor-zoom {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  max-width: 19rem;
  margin: 1rem auto 0;
  font-size: 0.9rem;
  color: var(--tinta-suave);
}

.editor-zoom input {
  flex: 1;
  accent-color: var(--azul-hashtag);
}

.editor-ajuda {
  margin: 0.6rem auto 0;
  max-width: 24rem;
  font-size: 0.85rem;
  color: var(--tinta-suave);
}

.editor-ajuda kbd {
  padding: 0.05rem 0.3rem;
  border: 1px solid var(--borda);
  border-radius: 0.25rem;
  background: #f6f6f4;
  font-family: inherit;
  font-size: 0.9em;
}

/*
 * Modelo da arte, exibido enquanto não há resultado. Fica dentro do formulário
 * de propósito: quando a arte é gerada, o formulário some e o modelo vai junto,
 * sem precisar de lógica extra no JavaScript.
 */
.modelo {
  margin: 0 0 1.5rem;
  text-align: center;
}

.modelo img {
  width: 100%;
  max-width: 17rem;
  height: auto;
  border-radius: 0.6rem;
  border: 1px solid var(--borda);
}

.modelo figcaption {
  margin-top: 0.5rem;
  font-size: 0.85rem;
  color: var(--tinta-suave);
}

.botao-principal,
.botao-secundario,
.botao-whatsapp {
  /* Flex, e não inline-block: quando um rótulo quebra em duas linhas o grid
     iguala a altura dos três, e só o flex centraliza o conteúdo no espaço
     que sobra. Com inline-block, o texto fica colado no topo. */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 100%;
  min-height: 3rem;
  padding: 0.85rem 1.25rem;
  border-radius: 0.6rem;
  border: 1px solid transparent;
  font: inherit;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.botao-principal {
  background: var(--azul-hashtag);
  color: #fff;
}

.botao-principal:hover:not(:disabled) {
  background: var(--azul-escuro);
}

.botao-principal:disabled {
  background: #b9c7bf;
  cursor: not-allowed;
}

/*
 * Verde escuro em vez do verde da marca do WhatsApp (#25D366): sobre ele o
 * texto branco fica em 1,8:1, muito abaixo do mínimo de 4,5:1. Aqui o par
 * chega a 9:1, e o botão continua sendo lido como "WhatsApp" pelo rótulo.
 */
.botao-whatsapp {
  background: var(--verde-sucesso);
  color: #fff;
}

.botao-whatsapp:hover {
  background: #0f3d21;
}

.botao-secundario {
  background: #fff;
  color: var(--azul-escuro);
  border-color: var(--azul-hashtag);
}

:focus-visible {
  outline: 3px solid var(--amarelo);
  outline-offset: 2px;
}

.privacidade {
  margin: 1.1rem 0 0;
  font-size: 0.85rem;
  color: var(--tinta-suave);
}

.resultado {
  text-align: center;
}

.resultado img {
  max-width: 100%;
  height: auto;
  border-radius: 0.6rem;
  border: 1px solid var(--borda);
  margin-bottom: 1.25rem;
}

.sucesso {
  margin: 0 0 1rem;
  padding: 0.7rem 1rem;
  border-radius: 0.6rem;
  background: #e8f3ea;
  border: 1px solid #bcdcc5;
  color: var(--verde-sucesso);
  font-weight: 600;
}

.acoes {
  display: grid;
  gap: 0.7rem;
}

/*
 * Caminho de salvamento que não depende do navegador cooperar.
 *
 * O botão de baixar usa <a download> apontando para um blob:, e no WebKit isso
 * não funciona dentro do iframe de outra origem em que a aplicação é embutida —
 * no iPhone o toque simplesmente não faz nada, sem erro. Segurar o dedo sobre a
 * imagem é o gesto nativo do sistema e funciona sempre. A dica aparece só onde
 * faz sentido: ponteiro grosseiro e sem hover, ou seja, tela de toque.
 */
.dica-toque {
  display: none;
  margin: 0.75rem 0 1rem;
  color: var(--tinta-suave);
  font-size: 0.88rem;
}

@media (hover: none) and (pointer: coarse) {
  .dica-toque {
    display: block;
  }
}

/*
 * Saída para fora do quadro.
 *
 * Aparece só quando as duas condições valem: tela de toque e página embutida
 * em outra (classe posta pelo JavaScript). Embutida, a aplicação depende de
 * autorizações que a página de fora precisa conceder — sem elas, o download no
 * celular não dispara e o compartilhamento não anexa a imagem. Aberta em aba
 * própria, nada disso se aplica.
 */
.link-nova-aba {
  display: none;
  margin: 0.9rem 0 0;
  color: var(--tinta-suave);
  font-size: 0.88rem;
  text-align: left;
}

.link-nova-aba a {
  color: var(--azul-escuro);
}

@media (hover: none) and (pointer: coarse) {
  .embutido .link-nova-aba {
    display: block;
  }
}

/*
 * Nota do convite. Deixou de ser aviso de falha depois do clique e passou a
 * explicar, antes dele, o que o botão vai enviar — por isso perdeu a caixa
 * amarela: não há nada de errado acontecendo, é só o que a mensagem leva.
 */
.aviso-compartilhamento {
  margin: 0.9rem 0 0;
  color: var(--tinta-suave);
  font-size: 0.88rem;
  text-align: left;
}

.mensagem-erro:empty {
  display: none;
}

.mensagem-erro {
  margin: 1.1rem 0 0;
  padding: 0.7rem 1rem;
  border-radius: 0.6rem;
  background: #fbeaea;
  border: 1px solid #e8b9b9;
  color: var(--erro);
  font-size: 0.92rem;
}

.rodape {
  margin-top: 2.5rem;
  text-align: center;
  font-size: 1rem;
  color: var(--tinta);
}

/*
 * Hashtag no padrão da identidade Eleições 2026: cerquilha verde, "NA" azul,
 * no mesmo tamanho do restante do rodapé.
 */
.hashtag {
  display: inline-block;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.3;
  vertical-align: middle;
  color: var(--grafite);
  white-space: nowrap;
}

.hashtag-cerquilha {
  color: var(--verde-hashtag);
}

.hashtag-na {
  color: var(--azul-hashtag);
}

@media (min-width: 34rem) {
  .acoes {
    /* Três ações agora: acomoda em uma ou duas linhas conforme a largura. */
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  }
}

/* ------------------------------------------------------------------------
 * Identidade visual do TRE-RJ: cabeçalho e rodapé institucionais.
 *
 * Só aparecem quando a aplicação é a própria página — o servidor nem manda a
 * marcação quando o pedido vem de dentro de um quadro. A regra abaixo, pela
 * classe posta no JavaScript, cobre o navegador que não informa esse contexto.
 *
 * Tudo aqui é enfeite institucional: nenhuma dessas regras influi na geração
 * da arte nem na geometria do editor, que continua vindo do servidor.
 * ------------------------------------------------------------------------ */

.embutido .inst-topo,
.embutido .inst-rodape {
  display: none;
}

/* Texto que existe só para o leitor de tela. Os ícones de rede social e o
   marcador do mapa não têm rótulo visível; sem isto, seriam links sem nome. */
.apenas-leitor {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Largura útil das faixas institucionais. Mais larga que a .pagina de
   propósito: é a moldura do portal em volta de um conteúdo estreito. */
.inst-limite {
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 1.25rem;
}

/* --- Cabeçalho --- */

.inst-barra {
  background: var(--azul-institucional);
  color: #fff;
  font-size: 0.84rem;
}

.inst-barra .inst-limite {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
  padding-top: 0.45rem;
  padding-bottom: 0.45rem;
}

.inst-atalhos ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* Centralizado só faz efeito quando a lista ocupa a barra inteira, isto é,
     quando ela quebrou em duas linhas no celular. Em tela larga a lista tem a
     largura do próprio conteúdo e quem a encosta à direita é a barra. */
  justify-content: center;
  gap: 0.5rem 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.inst-barra a {
  color: #fff;
  text-decoration: none;
}

.inst-barra a:hover {
  text-decoration: underline;
}

.inst-sic {
  display: inline-flex;
  align-items: center;
}

.inst-sic img {
  display: block;
  width: 1.15rem;
  height: 1.15rem;
}

.inst-marca {
  background: #fff;
  border-bottom: 1px solid var(--borda);
}

.inst-marca .inst-limite {
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}

.inst-marca img {
  display: block;
  width: auto;
  height: 2.75rem;
}

/* --- Rodapé --- */

.inst-rodape {
  color: #fff;
  font-size: 0.9rem;
}

.inst-rodape a {
  color: #fff;
  text-decoration: none;
}

.inst-rodape a:hover {
  text-decoration: underline;
}

.inst-rodape-topo {
  background: var(--azul-institucional);
}

.inst-rodape-topo .inst-limite {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding-top: 1.25rem;
  padding-bottom: 1.25rem;
}

/* A logo do portal existe em duas versões; aqui há só o arquivo colorido, e
   sobre o azul ele precisa ser branco. Dois filtros resolvem sem um segundo
   arquivo: zerar o brilho achata tudo em preto, inverter deixa tudo branco. */
.inst-rodape-marca img {
  display: block;
  width: auto;
  height: 3rem;
  filter: brightness(0) invert(1);
}

.inst-rodape-links ul,
.inst-selos,
.inst-redes ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.inst-selos img {
  display: block;
  height: 3.4rem;
  width: auto;
}

.inst-rodape-info {
  background: var(--azul-institucional-escuro);
}

.inst-rodape-info .inst-limite {
  display: grid;
  gap: 2rem;
  padding-top: 1.75rem;
  padding-bottom: 2rem;
}

.inst-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}

.inst-item + .inst-item {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgb(255 255 255 / 20%);
}

.inst-item > svg,
.inst-mapa svg {
  flex: 0 0 auto;
  width: 1.4rem;
  height: 1.4rem;
  margin-top: 0.15rem;
}

.inst-item address {
  margin: 0;
  font-style: normal;
}

.inst-horarios p {
  margin: 0 0 0.5rem;
}

.inst-horarios p:last-child {
  margin-bottom: 0;
}

.inst-canais {
  display: grid;
  gap: 1rem;
  align-content: start;
}

.inst-redes a {
  display: block;
}

.inst-redes svg {
  display: block;
  width: 2.1rem;
  height: 2.1rem;
}

/* O desenho de cada ícone é um círculo cheio com o glifo recortado. Pintar o
   círculo de branco e o glifo do azul da faixa reproduz o rodapé do portal
   sem depender de imagem de fora. */
.inst-rede-fundo {
  fill: #fff;
}

.inst-rede-glifo {
  fill: var(--azul-institucional-escuro);
}

.inst-botoes {
  display: grid;
  gap: 1.25rem;
}

.inst-botoes a {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.7rem 1rem;
  background: var(--azul-institucional);
  font-weight: 600;
  text-align: center;
}

.inst-botoes a:hover {
  background: #24406f;
  text-decoration: none;
}

.inst-botoes svg {
  flex: 0 0 auto;
  width: 1.2em;
  height: 1.2em;
}

@media (min-width: 52rem) {
  /* O separador em barra vertical do portal, só onde os três atalhos cabem em
     uma linha. Estreito, eles quebram, e a barra sobraria pendurada no começo
     da linha de baixo — sem separar nada. */
  .inst-atalhos li + li::before {
    content: '|';
    margin-right: 0.75rem;
    color: rgb(255 255 255 / 45%);
  }

  .inst-rodape-info .inst-limite {
    grid-template-columns: 1.6fr 1fr;
    gap: 3rem;
  }

  .inst-redes ul {
    justify-content: flex-end;
  }
}
