/* ============================================================================
   APP SHELL — a casca de aplicativo do Freediaria (barra de baixo, cabeçalho
   compacto, dock, banner de rede, convite de instalação, tela Menu).

   POR QUE ESTE ARQUIVO EXISTE
   ---------------------------
   O CSS deste projeto já mora em três lugares: os arquivos de
   app/assets/stylesheets, um bloco <style> dentro do layout do dashboard e
   dezenas de style="" inline. Isso não é uma opinião: é a razão de regras
   mortas como a .dash-hamburger terem sobrevivido meses sem view nenhuma.
   A casca inteira entra AQUI, num arquivo só, e nada dela vai pro layout.

   COMO LER
   --------
   Tudo abaixo obedece a UMA fronteira:

     ≤768px  → MODO CASCA DE APLICATIVO. Barra de baixo ligada, barra lateral
               e .dash-topbar escondidas, cabeçalho compacto.
     ≥769px  → DESKTOP INTACTO. Barra lateral de 260/220px exatamente como
               sempre foi; .fd-appbar, .fd-tabbar, .fd-dock e o título grande
               todos display:none.

   768 não é breakpoint novo: é o mesmo já documentado no fim do dashboard.css,
   o mesmo em que a barra lateral sempre sumiu. Inventar um segundo seria criar
   uma faixa de largura sem navegação nenhuma.

   Os parciais _tab_bar e _app_header são renderizados SEMPRE, nas duas
   larguras. Quem os esconde é o CSS, não o servidor — o servidor não sabe a
   largura da tela, e decidir isso no ERB é como as duas navegações começam a
   discordar.
   ============================================================================ */

:root {
  /* Altura da barra de baixo. Vira conta em três lugares (padding do conteúdo,
     posição do dock, posição do banner de rede) — por isso é variável. */
  --fd-tabbar-h: 60px;
  --fd-appbar-h: 52px;
  --fd-dock-h: 52px;
  /* SAFE AREA. Sem isto a barra fica embaixo do indicador de home do iPhone e
     da barra de gestos do Android. Depende do viewport-fit=cover que os três
     layouts públicos declaram. */
  --fd-safe-b: env(safe-area-inset-bottom, 0px);
  --fd-safe-t: env(safe-area-inset-top, 0px);

  /* A ALTURA DA FAIXA DE INSTALAR — zero quando ela não está de pé.
     Este token é o que faz TODO o resto do topo conviver com a faixa sem uma
     única condicional espalhada: quem mora colado no alto (`.lp-nav`,
     `.navbar`, `.inv-nav`, `.lp-scroll-progress`, `.fd-appbar`) simplesmente
     usa `top: var(--fd-faixa-h)`. Quando o navegador esconde a faixa (já
     instalou, ou o "×" de 24h), o `:has` abaixo deixa de casar, o token volta
     a 0px e todos eles sobem sozinhos. Sem JavaScript de layout, sem medir
     altura, sem os dois lados discordando. */
  --fd-faixa-h: 0px;

  /* ==========================================================================
     A FÁBRICA DE TOKENS (§ZONA D). Daqui pra baixo é o vocabulário que TODAS
     as telas consomem. Ele nasce num lugar só de propósito: o relatório de
     auditoria achou três verdes diferentes pro mesmo dado e sombra somada em
     cima de sombra antiga justamente porque cada tela inventava o seu valor.
     Quem precisar de um token novo pede aqui — não declara no próprio arquivo.
     ========================================================================== */

  /* DUAS SOMBRAS, E SÓ DUAS. A primeira é de cartão (quase invisível, serve
     pra separar do fundo); a segunda é de superfície que FLUTUA por cima da
     tela (folha de instalação, dock). Botão preenchido não tem sombra: cor
     cheia já é elevação suficiente e sombra em botão é a assinatura de
     "site de 2015". */
  --fd-elev-1: 0 1px 2px rgba(15, 23, 42, .04), 0 1px 3px rgba(15, 23, 42, .06);
  --fd-elev-2: 0 12px 32px rgba(15, 23, 42, .14);

  /* TRÊS RAIOS. Controle (botão, campo, chip), superfície (cartão, folha) e
     pílula. Um quarto raio não acrescenta informação nenhuma — só ruído. */
  --fd-r-controle: 12px;
  --fd-r-superficie: 16px;
  --fd-r-pill: 999px;

  /* RITMO DE 8, com 12 como único meio-passo (o gap de lista). */
  --fd-esp-1: 8px;
  --fd-esp-2: 12px;
  --fd-esp-3: 16px;
  --fd-esp-4: 24px;
  --fd-esp-5: 32px;

  /* O PISO DO DEDO. 44px é o mínimo; a casca usa 48 nos botões de ação. */
  --fd-alvo: 44px;
}

/* NO DESKTOP A BARRA DE BAIXO NÃO EXISTE — e a altura dela também não.
   Sem isto, tudo que compensa a barra (o banner de rede, o dock, a barra de
   salvar) fica boiando 60px acima do rodapé numa janela que não tem barra
   nenhuma embaixo. Foi exatamente o defeito medido em 1440x900. */
@media (min-width: 769px) {
  :root { --fd-tabbar-h: 0px; }
}

/* E NAS TELAS PÚBLICAS ELA TAMBÉM NÃO EXISTE — em QUALQUER largura. A landing,
   o login e o cadastro carregam esta folha, mas o parcial shared/_tab_bar só é
   renderizado no layout do dashboard. Sem isto, em 390x844 a folha de
   instalação e o fundo escuro paravam em y=784 numa janela de 844: sobravam
   60px de página NÃO escurecida embaixo do diálogo, e elementFromPoint no meio
   dessa faixa devolvia o conteúdo da landing — clicável por baixo de um
   aria-modal. A altura da barra passa a depender da PRESENÇA dela, não só da
   largura. Em navegador sem :has() nada muda (volta ao comportamento atual). */
html:not(:has(.fd-tabbar)) { --fd-tabbar-h: 0px; }

/* A faixa de instalar mede 44px de alvo + 1px de borda. `:not([hidden])` é o
   que amarra o token ao estado REAL da faixa: quem a esconde é o
   `install_prompt_controller`, e o layout inteiro reage no mesmo quadro. */
html:has(.fd-instalar-faixa:not([hidden])) { --fd-faixa-h: calc(45px + var(--fd-safe-t)); }

/* ----------------------------------------------------------------------------
   DESKTOP (padrão): a casca inteira não existe.
   ---------------------------------------------------------------------------- */
.fd-appbar,
.fd-tabbar,
.fd-dockbar,
.fd-net,
.fd-titulo-grande,
.fd-menu-tela,
.fd-menu__corte,
.lado-switch--inline { display: none; }

/* O CONVITE DE PUSH FICA CALADO ATÉ A PESSOA ESTAR INSTALADA.
   Instalar primeiro, notificação depois: no Android pedir antes queima a
   permissão, e no iPhone o Web Push nem existe fora do modo instalado. A
   classe `fd-standalone` no <html> é posta pelo `install_prompt_controller`
   quando o aplicativo está mesmo na tela inicial. O !important existe porque
   o `web_push_controller` decide a exibição por style inline — e a ordem
   "instalar antes" tem que ganhar dessa decisão. */
@media (max-width: 768px) {
  html:not(.fd-standalone) .fd-push-convite [data-web-push-target="prompt"] { display: none !important; }
}

/* ----------------------------------------------------------------------------
   BARRA DE BAIXO
   ---------------------------------------------------------------------------- */
.fd-tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 500;
  height: calc(var(--fd-tabbar-h) + var(--fd-safe-b));
  padding-bottom: var(--fd-safe-b);
  background: #FFFFFF;
  border-top: 1px solid var(--color-gray-100, #F1F5F9);
  /* SEM backdrop-filter e SEM sombra: blur em barra fixa engasga o scroll em
     Android modesto, que é o aparelho da maior parte das 989 pessoas. */
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}

.fd-tab {
  flex: 1 1 0;
  min-width: 0;
  min-height: 56px;              /* alvo de dedo, não de mouse */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  text-decoration: none;
  color: #64748B;                /* gray-500 sobre branco = 4.76:1, passa AA.
                                    gray-400 reprova — não trocar. */
  -webkit-tap-highlight-color: transparent;
  transition: color .12s ease, transform .08s ease;
}

.fd-tab__icone {
  position: relative;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.fd-tab__icone svg { width: 24px; height: 24px; display: block; }

.fd-tab__rotulo {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .01em;
  line-height: 1;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ESTADO ATIVO COM TRÊS SINAIS AO MESMO TEMPO — cor, peso do rótulo e ícone
   preenchido. Cor sozinha reprova em daltonismo e em tela sob sol, que é
   exatamente a condição de quem usa isto na rua. */
.fd-tab--ativa { color: var(--color-primary, #2563EB); }
.fd-tab--ativa .fd-tab__rotulo { font-weight: 700; }
.fd-tab--ativa .fd-tab__icone svg [data-fd-fill] { fill: currentColor; fill-opacity: .16; }

/* PINTURA NO TOQUE, antes do Turbo responder. É o que separa "aplicativo" de
   "site travado" em 3G: a pessoa vê a aba acender no dedo, não meio segundo
   depois que a página chegou. */
.fd-tab--tocada { color: var(--color-primary, #2563EB); }
.fd-tab:active { transform: scale(.97); }

.fd-tab:focus-visible {
  outline: 2px solid var(--color-primary, #2563EB);
  outline-offset: -3px;
  border-radius: 10px;
}

/* O MICROFONE do lado empresa: círculo azul cheio, na MESMA linha de base das
   outras abas. Sem elevação, sem sombra, sem sair da barra — botão central
   flutuante foi rejeitado de propósito. */
.fd-tab__circulo {
  width: 30px; height: 30px;
  border-radius: 999px;
  background: var(--color-primary, #2563EB);
  color: #FFFFFF;
  display: flex; align-items: center; justify-content: center;
}
.fd-tab__circulo svg { width: 17px; height: 17px; }
.fd-tab--publicar .fd-tab__icone { width: 30px; height: 30px; }
/* No ativo o rótulo e o círculo já são azuis; escurece só o círculo pra
   diferença ser visível sem mudar o desenho. */
.fd-tab--ativa .fd-tab__circulo { background: var(--color-primary-dark, #1D4ED8); }

/* A 5ª aba é a PESSOA, não um pictograma. */
.fd-tab__avatar {
  width: 24px; height: 24px;
  border-radius: 999px;
  object-fit: cover;
  display: block;
}
.fd-tab__avatar--letra {
  background: var(--color-primary, #2563EB);
  color: #FFFFFF;
  font-size: 11px;
  font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  line-height: 1;
}
.fd-tab--ativa .fd-tab__avatar { box-shadow: 0 0 0 2px var(--color-primary, #2563EB); }

/* BADGE numérico. Vem de turbo_frame preguiçoso; quando é zero o frame volta
   vazio e não sobra bolinha nenhuma.

   ATENÇÃO AO `display` DESTE FRAME: `display: contents` parece a escolha óbvia
   (o frame some do layout e só o badge conta), mas MATA o carregamento
   preguiçoso — o Turbo decide quando buscar um frame `loading="lazy"` por
   IntersectionObserver, e elemento sem caixa nunca "entra na tela". O badge
   simplesmente nunca chegaria, sem erro nenhum no console.
   Por isso o frame é uma caixa absoluta cobrindo o ícone: tem geometria pro
   observador, não empurra nada, e continua sendo o pai posicionador do badge. */
.fd-tab__icone turbo-frame,
.fd-appbar__acao turbo-frame {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.fd-badge {
  position: absolute;
  top: -5px; right: -8px;
  min-width: 17px; height: 17px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--color-danger, #EF4444);
  color: #FFFFFF;
  font-size: 10px;
  font-weight: 800;
  line-height: 17px;
  text-align: center;
  border: 1.5px solid #FFFFFF;
}

/* ----------------------------------------------------------------------------
   CABEÇALHO COMPACTO
   ---------------------------------------------------------------------------- */
.fd-appbar {
  position: sticky;
  /* Gruda ABAIXO da faixa de instalar, não por baixo dela. */
  top: var(--fd-faixa-h);
  z-index: 400;
  height: calc(var(--fd-appbar-h) + var(--fd-safe-t));
  padding: var(--fd-safe-t) 8px 0 8px;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: #FAFBFC;           /* opaco, casando com o fundo do dashboard */
  border-bottom: 1px solid transparent;
  transition: border-color .14s ease;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}

/* A borda só nasce quando há conteúdo rolado por baixo — no topo da página ela
   seria uma linha sem função. */
.fd-appbar--scrolled { border-bottom-color: var(--color-gray-100, #F1F5F9); }

.fd-appbar__esq { display: flex; align-items: center; min-width: 0; flex: 1 1 auto; }
.fd-appbar__dir { display: flex; align-items: center; gap: 2px; flex: none; }

.fd-appbar__titulo {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--color-gray-900, #0F172A);
  padding-left: 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* EM TELA RAIZ o título do cabeçalho começa apagado: o título GRANDE já está
   no corpo da página. Ele só entra quando a pessoa rola e o grande sai de
   vista — a mesma gramática do cabeçalho dos aplicativos nativos. */
.fd-appbar--raiz .fd-appbar__titulo {
  opacity: 0;
  transform: translateY(4px);
  transition: opacity .14s ease, transform .14s ease;
}
.fd-appbar--raiz.fd-appbar--scrolled .fd-appbar__titulo { opacity: 1; transform: none; }

/* Em tela de profundidade o título e o chevron aparecem desde o scroll 0. */
.fd-appbar__voltar {
  display: flex;
  align-items: center;
  gap: 2px;
  min-height: 44px;
  min-width: 0;
  text-decoration: none;
  color: var(--color-gray-900, #0F172A);
}
.fd-appbar__voltar svg { width: 22px; height: 22px; flex: none; }
.fd-appbar__titulo--sempre { opacity: 1; transform: none; padding-left: 2px; }

.fd-appbar__acao {
  position: relative;
  width: 44px; height: 44px;     /* alvo de dedo. 31px não serve — o
                                    .lado-switch--topbar já dizia isso. */
  display: flex; align-items: center; justify-content: center;
  border-radius: 12px;
  color: var(--color-gray-600, #475569);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
.fd-appbar__acao svg { width: 22px; height: 22px; }
.fd-appbar__acao:active { background: var(--color-gray-100, #F1F5F9); }

/* O pontinho verde do Fred: ele está sempre acordado, e isso é a promessa. */
.fd-appbar__ponto {
  position: absolute;
  top: 9px; right: 9px;
  width: 6px; height: 6px;
  border-radius: 999px;
  background: var(--color-secondary, #10B981);
  border: 1px solid #FAFBFC;
}

/* TÍTULO GRANDE — primeiro elemento do conteúdo nas telas raiz. Rola junto,
   sem borda: é o corpo da página apresentando a si mesmo. */
.fd-titulo-grande {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--color-gray-900, #0F172A);
  margin: 2px 0 16px;
  line-height: 1.15;
}

/* ----------------------------------------------------------------------------
   DOCK — a faixa contextual, acima da barra, nunca dentro dela.
   ---------------------------------------------------------------------------- */
.fd-dockbar {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(var(--fd-tabbar-h) + var(--fd-safe-b));
  z-index: 490;
  pointer-events: none;          /* quando vazio não intercepta nada */
}
.fd-dockbar > turbo-frame { display: block; }
.fd-dockbar .fd-dock__acao { pointer-events: auto; }

.fd-dock__acao {
  display: flex;
  align-items: center;
  gap: 10px;
  height: var(--fd-dock-h);
  padding: 0 16px;
  text-decoration: none;
  color: #FFFFFF;
  font-size: 15px;
  font-weight: 700;
}
.fd-dock__acao--ponto { background: #10B981; }
.fd-dock__acao svg { width: 20px; height: 20px; flex: none; }
.fd-dock__texto { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fd-dock__chev { opacity: .8; }
.fd-dock__acao:active { filter: brightness(.95); }

/* ----------------------------------------------------------------------------
   BANNER DE REDE — some a conexão, a pessoa fica sabendo, e todo botão de
   dinheiro é desligado na hora. Nada de fila offline: sem rede, a ação falha
   de forma honesta.
   ---------------------------------------------------------------------------- */
.fd-net {
  position: fixed;
  left: 0; right: 0;
  bottom: calc(var(--fd-tabbar-h) + var(--fd-safe-b));
  z-index: 480;
  height: 28px;
  align-items: center;
  justify-content: center;
  background: #FFFBEB;
  color: #92400E;
  font-size: 13px;
  font-weight: 600;
  border-top: 1px solid #FDE68A;
}
/* A CLASSE QUE ACENDE O BANNER MORA DENTRO DA FRONTEIRA. Ela estava solta,
   fora de qualquer @media, e reacendia no desktop uma faixa que é desenhada
   pra encostar na barra de baixo — resultado medido em 1440x900: o aviso
   flutuando 60px acima do rodapé, ancorado numa barra que não existe ali. */
@media (max-width: 768px) {
  .fd-net--visivel { display: flex; }
}

/* NO DESKTOP O AVISO CONTINUA EXISTINDO — só muda de forma.
   Apagar o banner acima de 769px resolveria a geometria e criaria coisa pior:
   `.fd-sem-rede` desliga os botões de dinheiro nas DUAS larguras (é o que o
   comentário dele diz), e desligar botão sem dizer por quê é a definição de
   interface que mente. Aqui ele vira uma pílula no canto, sem depender de
   barra nenhuma embaixo. */
@media (min-width: 769px) {
  .fd-net--visivel {
    display: flex;
    left: auto;
    right: var(--fd-esp-4);
    bottom: var(--fd-esp-4);
    width: auto;
    height: auto;
    padding: var(--fd-esp-1) var(--fd-esp-3);
    border: 1px solid #FDE68A;
    border-radius: var(--fd-r-pill);
    box-shadow: var(--fd-elev-2);
  }
}

/* EMPILHAR, NÃO SOBREPOR. O dock ('Bater ponto') e este banner nasciam com o
   MESMO `bottom`, e o dock é opaco e está por cima (490 > 480): a pessoa perdia
   o sinal exatamente na hora em que o dock está na tela e não via aviso nenhum
   — tocava em Bater ponto e caía na /offline sem entender. Com o banner
   visível, o dock sobe os 28px dele e os dois ficam legíveis. */
.dash-layout:has(.fd-net--visivel) .fd-dockbar {
  bottom: calc(var(--fd-tabbar-h) + var(--fd-safe-b) + 28px);
}

/* Enquanto não há rede, o gesto de dinheiro fica visivelmente morto. Vale nas
   duas larguras: perder conexão no desktop não é menos grave. */
.fd-sem-rede {
  pointer-events: none;
  opacity: .55;
  filter: grayscale(1);
}

/* ----------------------------------------------------------------------------
   CONVITE DE INSTALAÇÃO — folha de baixo, nunca banner de topo nem modal
   centralizado. Ela SOBE por cima da barra e do dock, cobrindo por inteiro com
   o fundo escuro; nunca fica meio em cima deles.
   ---------------------------------------------------------------------------- */
.fd-install-backdrop {
  position: fixed;
  /* O FUNDO ESCURO PARA NO TOPO DA BARRA DE BAIXO. Com `inset: 0` ele cobria a
     barra inteira (899 contra os 500 dela) e engolia o toque de aba: medido com
     elementFromPoint, as 5 abas devolviam o botão "Entendi" da folha. Convite
     que sequestra a navegação não é convite. */
  inset: 0 0 calc(var(--fd-tabbar-h) + var(--fd-safe-b)) 0;
  /* ACIMA DAS BARRAS DAS TELAS PÚBLICAS. As navs fixas da landing/investidores
     (.lp-nav, .navbar, .inv-nav) moram em 1000: com 899/900 a folha era um
     diálogo aria-modal com a faixa do topo acesa e clicável por cima dela.
     1899/1900 passa por elas e continua abaixo da barra de progresso da
     landing (9999, 3px e pointer-events:none). */
  z-index: 1899;
  background: rgba(15, 23, 42, .45);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .24s ease, visibility .24s;
}
.fd-install-backdrop--aberto { opacity: 1; visibility: visible; pointer-events: auto; }

.fd-install-sheet {
  position: fixed;
  left: 0; right: 0;
  /* A FOLHA TAMBÉM PARA ACIMA DA BARRA. O botão "Colocar na tela" nascia
     exatamente na linha do polegar onde as abas moram (y=772..824 contra a
     barra em 784..844): quem ia tocar em "Vagas" aceitava a instalação. */
  bottom: calc(var(--fd-tabbar-h) + var(--fd-safe-b));
  z-index: 1900;
  background: #FFFFFF;
  border-radius: 20px 20px 0 0;
  box-shadow: var(--fd-elev-2);
  padding: 10px 20px 20px;
  transform: translateY(100%);
  visibility: hidden;
  transition: transform .24s cubic-bezier(.32, .72, 0, 1), visibility .24s;
  max-height: 88vh;
  overflow-y: auto;
}
.fd-install-sheet--aberto { transform: translateY(0); visibility: visible; }

.fd-install__alca {
  width: 36px; height: 4px;
  border-radius: 999px;
  background: var(--color-gray-200, #E2E8F0);
  margin: 0 auto 16px;
}
.fd-install__icone { width: 56px; height: 56px; border-radius: 14px; display: block; margin-bottom: 12px; }
.fd-install__titulo { font-size: 18px; font-weight: 800; letter-spacing: -0.02em; color: var(--color-gray-900, #0F172A); margin: 0 0 8px; }
.fd-install__texto { font-size: 14px; line-height: 1.55; color: var(--color-gray-600, #475569); margin: 0 0 18px; }
.fd-install__passos { list-style: none; padding: 0; margin: 0 0 18px; display: grid; gap: 12px; }
.fd-install__passo { display: flex; gap: 10px; align-items: flex-start; font-size: 14px; line-height: 1.45; color: var(--color-gray-700, #334155); }
.fd-install__passo svg { width: 22px; height: 22px; flex: none; color: var(--color-primary, #2563EB); }
.fd-install__botoes { display: grid; gap: 8px; }
.fd-install__btn {
  height: 52px;
  border: none;
  border-radius: 14px;
  font-family: inherit;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
}
.fd-install__btn--sim { background: var(--color-primary, #2563EB); color: #FFFFFF; }
.fd-install__btn--nao { background: transparent; color: #64748B; font-weight: 600; }
.fd-install__btn:focus-visible { outline: 2px solid var(--color-gray-900, #0F172A); outline-offset: 2px; }

/* O FUNDO NÃO ROLA ENQUANTO A FOLHA ESTÁ ABERTA. Sem isto o conteúdo escorrega
   atrás do escuro enquanto um diálogo (`aria-modal`) está na frente — o
   navegador não sabe que aquilo é modal, quem sabe é a gente. Em CSS, e não no
   controller, porque quem cria a folha é a ZONA B: assim a trava não depende
   de o JS lembrar de destravar num caminho de erro. */
body:has(.fd-install-backdrop--aberto) { overflow: hidden; }

/* NO DESKTOP A FOLHA É UMA FOLHA, NÃO UMA TARJA. Sem largura máxima ela virava
   uma faixa branca de 1440px colada no rodapé — parece bug de layout, não
   convite. Acima de 769px ela é um cartão centrado, com os quatro cantos
   arredondados e descolado do rodapé. */
@media (min-width: 769px) {
  .fd-install-sheet {
    left: auto; right: auto;
    max-width: 420px;
    margin-inline: auto;
    inset-inline: 0;
    bottom: var(--fd-esp-4);
    border-radius: var(--fd-r-superficie);
  }
}

/* ----------------------------------------------------------------------------
   A TELA MENU — o que era a gaveta, agora com endereço fixo (/dashboard/perfil).
   Lista agrupada, item de 56px com chevron. Existe SÓ no celular: no desktop a
   barra lateral continua fazendo esse papel, e duas listas iguais na mesma tela
   seria a mesma porta em dois lugares.
   ---------------------------------------------------------------------------- */
.fd-menu-tela { margin-bottom: 4px; }

.fd-menu__cartao {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 72px;
  padding: 14px 16px;
  margin-bottom: 12px;
  border-radius: 16px;
  border: 1px solid var(--color-gray-100, #F1F5F9);
  background: #FFFFFF;
  text-decoration: none;
  color: var(--color-gray-900, #0F172A);
}
.fd-menu__cartao--fred { background: #F0FDF4; border-color: #A7F3D0; }
.fd-menu__cartao-icone {
  width: 44px; height: 44px; flex: none;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  background: var(--color-primary-50, #EFF6FF);
  color: var(--color-primary, #2563EB);
}
.fd-menu__cartao--fred .fd-menu__cartao-icone { background: #D1FAE5; color: #059669; }
.fd-menu__cartao-icone svg { width: 22px; height: 22px; }
.fd-menu__cartao-corpo { min-width: 0; flex: 1 1 auto; }
/* `display: block` NÃO É DETALHE AQUI. Os dois são <span> dentro de um <span>
   blocado pelo flex: enquanto forem inline, as duas caixas se sobrepõem (título
   em y=133.9, subtítulo em y=135.9, medido em produção) e o cartão do Fred lê
   como uma frase só, com a segunda linha começando embaixo do título. */
.fd-menu__cartao-titulo { display: block; font-size: 15px; font-weight: 700; letter-spacing: -0.01em; }
.fd-menu__cartao-sub { display: block; font-size: 13px; line-height: 1.35; color: var(--color-gray-500, #64748B); margin-top: 2px; }
.fd-menu__cartao-chev { width: 18px; height: 18px; flex: none; color: var(--color-gray-400, #94A3B8); }

.fd-menu {
  border: 1px solid var(--color-gray-100, #F1F5F9);
  border-radius: 16px;
  background: #FFFFFF;
  overflow: hidden;
  margin-bottom: 12px;
}
.fd-menu__item {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 0 16px;
  text-decoration: none;
  color: var(--color-gray-900, #0F172A);
  font-size: 15px;
  font-weight: 500;
  border: none;
  background: transparent;
  width: 100%;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.fd-menu__item + .fd-menu__item { border-top: 1px solid var(--color-gray-100, #F1F5F9); }
.fd-menu__item:active { background: var(--color-gray-50, #F8FAFC); }
.fd-menu__item svg { width: 20px; height: 20px; flex: none; color: var(--color-gray-400, #94A3B8); }
.fd-menu__rotulo { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fd-menu__chev { width: 18px !important; height: 18px !important; }
.fd-menu__item--sair { color: var(--color-danger-dark, #DC2626); font-weight: 600; }
.fd-menu__item--sair svg { color: var(--color-danger, #EF4444); }
.fd-menu__contexto { padding: 12px 16px; border-top: 1px solid var(--color-gray-100, #F1F5F9); }
.fd-menu__corte { border: 0; border-top: 1px solid var(--color-gray-100, #F1F5F9); margin: 20px 0 24px; }

/* ----------------------------------------------------------------------------
   ESQUELETO DE CARREGAMENTO (opcional, para listas longas: Vagas e Trabalhos).
   Fica aqui pra que a lista que precisar dele não invente um shimmer próprio.
   ---------------------------------------------------------------------------- */
@keyframes fdShimmer { from { background-position: -180px 0; } to { background-position: 180px 0; } }
.fd-esqueleto {
  border-radius: var(--fd-r-controle);
  background: linear-gradient(90deg, #F1F5F9 25%, #E9EEF5 37%, #F1F5F9 63%);
  background-size: 360px 100%;
  animation: fdShimmer 2s linear infinite;
}

/* O ESQUELETO DAS TELAS RAIZ. Quem o põe e o tira é o `casca_controller`,
   300ms depois do toque na aba — antes disso não há espera pra sinalizar, e
   pôr esqueleto numa tela que chega em 200ms é piscar à toa.
   O conteúdo velho é ESCONDIDO, nunca removido: se a navegação falhar, ele
   volta inteiro. */
.fd-conteudo-velho { display: none !important; }
.fd-carregando { display: grid; gap: var(--fd-esp-3); padding-top: var(--fd-esp-1); }
.fd-carregando__titulo { height: 30px; width: 55%; }
.fd-carregando__bloco { height: 116px; }
.fd-carregando__linha { height: 56px; }

/* ============================================================================
   OS UTILITÁRIOS COMPARTILHADOS — a escala, o alvo e os moldes
   ============================================================================
   Estas classes são o contrato desta rodada: as telas CONSOMEM, ninguém
   redeclara. Elas existem porque a auditoria mediu 9 dos 11 elementos de um
   card entre 11 e 13px — quando tudo tem o mesmo tamanho, nada tem hierarquia,
   e o olho não acha "quanto paga" num relance.

   A ESCALA TEM SEIS DEGRAUS, E SÓ SEIS. Título grande (o `.fd-titulo-grande`
   lá em cima, 28/800 no corpo da tela raiz), título de card, título de linha,
   corpo, meta e selo — mais o dinheiro, que é o único peso 800 de um card.
   Sétimo degrau não acrescenta hierarquia: acrescenta indecisão.

   Valem nas DUAS larguras. Uma classe de tipografia que só existe no celular
   é como o desktop volta a divergir sozinho.
   ============================================================================ */
.fd-t-titulo  { font-size: 20px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.25; color: var(--color-gray-900, #0F172A); }
.fd-t-linha   { font-size: 17px; font-weight: 600; line-height: 1.3;  color: var(--color-gray-900, #0F172A); }
.fd-t-corpo   { font-size: 15px; font-weight: 400; line-height: 1.45; color: var(--color-gray-700, #334155); }
/* 13px em gray-500 sobre branco dá 4.76:1 — passa AA. gray-400 reprova, e é
   justamente o cinza que o projeto usava em legenda. Não trocar. */
.fd-t-meta    { font-size: 13px; font-weight: 500; line-height: 1.35; color: var(--color-gray-500, #64748B); }
.fd-t-selo    { font-size: 11px; font-weight: 700; line-height: 1; text-transform: uppercase; letter-spacing: .04em; }

/* O DINHEIRO — o único elemento peso 800 de um card, e a única coisa verde do
   aplicativo inteiro.

   POR QUE O VERDE AQUI É O `--color-secondary-dark` E NÃO O `--color-secondary`:
   #10B981 sobre branco dá 2.58:1. Mesmo a 22px/800 (que conta como "texto
   grande", piso 3:1) ele REPROVA — e o dinheiro é literalmente o número que a
   pessoa lê na rua, no sol, no celular barato. #059669 é o mesmo verde da
   família, dá 3.82:1 e passa. Quem quiser o #10B981 tem onde usá-lo: em
   preenchimento e superfície (o herói de /dashboard/ganhos, o dock do ponto),
   onde ele não é texto. Regra curta: verde de TEXTO é o dark; verde de FUNDO é
   o claro. */
.fd-t-dinheiro { font-size: 22px; font-weight: 800; line-height: 1.1; letter-spacing: -0.02em; color: var(--color-secondary-dark, #059669); }

/* AÇÃO PRIMÁRIA É FULL-WIDTH DE 48px. Não é gosto: um botão de 110x37 no canto
   esquerdo de um card é o que a auditoria mediu como "o candidatar não é o
   gesto principal". Largura cheia responde onde o polegar já está. */
.fd-btn-bloco,
/* Os dois seletores de elemento não são enfeite: o dashboard.css tem
   `input[type="submit"] { min-height: 44px }` no bloco de celular, e
   `input[type=submit]` (0,1,1) VENCE `.fd-btn-bloco` (0,1,0) por
   especificidade, por mais tarde que esta folha carregue. Medido: o "Salvar
   perfil" saía com 44px em vez de 48. Empatar a especificidade devolve a
   decisão pra ordem de carga, que é a nossa. */
input.fd-btn-bloco,
button.fd-btn-bloco {
  width: 100%;
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--fd-esp-1);
  text-align: center;
}

/* O PISO DE 44px, GANHO POR PADDING. Subir font-size pra chegar em 44 destrói
   a hierarquia que a escala acima está criando — por isso a classe cresce a
   caixa, não a letra. */
.fd-alvo-44 {
  min-height: var(--fd-alvo);
  display: inline-flex;
  align-items: center;
}

/* O MOLDE ÚNICO DO VAZIO. Ícone, uma linha que promete, uma linha que explica,
   um CTA. Nada de parágrafo de sete linhas centralizado: borda esquerda
   irregular a cada linha é o pior caso de leitura no celular, e foi o que a
   auditoria achou em Vagas, Convites de turno e Mensagens. */
.fd-vazio {
  min-height: 240px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: var(--fd-esp-2);
  padding: var(--fd-esp-4) var(--fd-esp-3);
}
.fd-vazio__icone { width: 40px; height: 40px; color: var(--color-gray-300, #CBD5E1); }
.fd-vazio__icone svg { width: 40px; height: 40px; display: block; }
.fd-vazio__titulo { font-size: 17px; font-weight: 600; color: var(--color-gray-900, #0F172A); margin: 0; }
/* 14px é o piso de texto corrido. 12px só em selo/eyebrow, que ninguém lê. */
.fd-vazio__texto { font-size: 14px; font-weight: 400; line-height: 1.5; color: var(--color-gray-500, #64748B); margin: 0; max-width: 30ch; }
.fd-vazio .fd-btn-bloco, .fd-vazio__acao { max-width: 320px; margin-top: var(--fd-esp-1); }

/* A BARRA DE SALVAR. Formulário de 1.800px com "Salvar" de 122x37 no fim é
   pedir que a pessoa role até o rodapé pra descobrir se tem botão. Sticky
   acima da barra de baixo: no desktop a conta dá zero (--fd-tabbar-h: 0px) e
   ela encosta no rodapé da janela, sem inventar breakpoint novo. */
.fd-barra-salvar {
  position: sticky;
  bottom: calc(var(--fd-tabbar-h) + var(--fd-safe-b));
  z-index: 300;
  background: #FFFFFF;
  border-top: 1px solid var(--color-gray-100, #F1F5F9);
  padding: var(--fd-esp-2);
  margin: var(--fd-esp-4) calc(-1 * var(--fd-esp-2)) 0;
}

/* FILA DE CHIPS — uma linha que rola de lado, nunca quatro linhas empilhadas.
   Sem barrinha (em Android ela aparece cinza por cima do último chip) e com o
   overscroll contido, senão chegar no fim da fila arrasta a página junto. */
.fd-chips-fila {
  display: flex;
  gap: var(--fd-esp-1);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.fd-chips-fila::-webkit-scrollbar { display: none; }
.fd-chips-fila > * { flex: none; min-height: var(--fd-alvo); display: inline-flex; align-items: center; }

/* ESCONDER O CONTROLE NATIVO SEM ESCONDER DO LEITOR DE TELA. É o que troca o
   "Choose File / No file chosen" em inglês por um botão nosso, sem tirar o
   input do caminho do teclado. */
.fd-so-leitor {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
/* O foco do teclado tem que ser visível NO BOTÃO, já que o input sumiu. */
.fd-so-leitor:focus-visible + .fd-btn-bloco,
.fd-so-leitor:focus-visible + .dash-btn,
.fd-so-leitor:focus-visible + label {
  outline: 2px solid var(--color-primary, #2563EB);
  outline-offset: 2px;
}

/* ============================================================================
   ≤768px — MODO CASCA DE APLICATIVO
   ============================================================================ */
@media (max-width: 768px) {
  .fd-appbar { display: flex; }
  .fd-tabbar { display: flex; }
  .fd-dockbar { display: block; }
  .fd-titulo-grande { display: block; }
  .fd-menu-tela { display: block; }
  .fd-menu__corte { display: block; }

  /* A GAVETA MORRE. Ela não é escondida "por enquanto": no celular a navegação
     é a barra de baixo, e a 5ª aba absorveu o "Mais" inteiro. O <aside>
     continua sendo renderizado (o servidor não sabe a largura da tela) e
     continua idêntico acima de 769px. */
  .dash-sidebar { display: none !important; }
  .dash-topbar { display: none; }

  /* A SEGUNDA SETA DE VOLTAR MORRE. 14 views ainda trazem `<a class="dash-back">←
     Voltar</a>` no corpo; no celular o cabeçalho já tem o chevron (fd_voltar_path).
     Duas setas na mesma tela é assinatura de site, não de app. Quem precisa de
     outro destino declara `content_for :fd_voltar`. Acima de 769px nada muda. */
  .dash-back { display: none; }

  /* `min-width: 0` NO MIOLO — o defeito estrutural que a barra de baixo tornou
     visível. `.dash-main` é `flex: 1` dentro do `.dash-layout`, e item de flex
     nasce com `min-width: auto`: ele NÃO encolhe abaixo do conteúdo mais largo
     que tiver dentro. Bastava um grid com coluna de 220px pra tela inteira
     ficar 500px de largura numa janela de 393 — o conteúdo saía cortado pela
     direita (medido em /dashboard/suporte). Com barra fixa no rodapé isso vira
     "aplicativo quebrado", então a linha é pré-requisito, não polimento. */
  .dash-main { min-width: 0; }
  .dash-content { min-width: 0; max-width: 100%; }

  /* O ESPAÇO DA BARRA. Sem isto some o último botão de TODA tela — inclusive
     Sacar e Publicar. Não é polimento: é pré-requisito. */
  .dash-content {
    padding-bottom: calc(var(--fd-tabbar-h) + var(--fd-safe-b) + 24px);
    /* Mata o bounce e o pull-to-refresh acidental dentro do aplicativo. */
    overscroll-behavior-y: contain;
  }

  /* Quando o dock está na tela ele come mais 52px do rodapé. `:has` resolve sem
     precisar de JavaScript avisando o CSS. */
  .dash-layout:has(.fd-dock__acao) .dash-content {
    padding-bottom: calc(var(--fd-tabbar-h) + var(--fd-dock-h) + var(--fd-safe-b) + 24px);
  }

  /* O TOAST TEM QUE NASCER ONDE O OLHO ESTÁ.
     O `#flash` é o alvo dos avisos que chegam por Turbo Stream (candidatura
     aceita, ponto batido) e ele entrava em FLUXO, no topo do conteúdo: com a
     página rolada 472px, o aviso nascia em y=-367 — fora da tela. A pessoa
     age, o servidor confirma, e ela não vê confirmação nenhuma; então ela toca
     de novo. Fixo logo abaixo do cabeçalho, acima dele (400) e abaixo da folha
     de instalação (899). O flash de página inteira (o notice/alert de redirect)
     continua em fluxo, que é onde ele faz sentido. */
  #flash {
    position: fixed;
    top: calc(var(--fd-appbar-h) + var(--fd-safe-t) + 8px);
    left: 12px; right: 12px;
    z-index: 600;
    pointer-events: none;   /* vazio, não pode tapar o que está embaixo */
  }
  #flash > * { pointer-events: auto; margin-bottom: 0; box-shadow: var(--fd-elev-2); }
  #flash:empty { display: none; }

  /* A CONVERSA CABE NA TELA — inclusive nas curtas.
     `.dash-chat` declara `height: calc(100dvh - 200px)` com `min-height: 400px`
     (dashboard.css): em tela baixa o piso vence o cálculo e empurra o campo de
     escrever pra baixo da barra. Aqui a altura desconta a casca inteira e o
     piso some — quem manda no tamanho é a janela, não um número fixo.

     RESSALVA MEDIDA: hoje NENHUMA view usa `.dash-chat` (nem o Fred, nem a
     conversa — a de /dashboard/mensagens/:id é um `.dash-card` em fluxo, com
     `min-height:500px` inline). A regra fica como rede de proteção pro dia em
     que a classe voltar a ser usada; o risco real do chat é o TECLADO, e esse
     está atacado no meta viewport (`interactive-widget=resizes-content`), que
     só aparelho de verdade fecha. */
  .dash-chat {
    height: calc(100dvh - var(--fd-appbar-h) - var(--fd-tabbar-h) - var(--fd-safe-t) - var(--fd-safe-b) - 32px);
    min-height: 0;
  }

  /* O INTERRUPTOR TEM 24px DE DESENHO E PRECISA DE 44 DE DEDO.
     `.dash-toggle` (dashboard.css) é 44x24 — no celular isso é metade do alvo
     mínimo, e ele liga coisas que importam (emitir nota, receber aviso). Aqui
     a CAIXA cresce pra 44 e o desenho continua com os 24 de sempre, centrado:
     o `slider` deixa de ser esticado por `inset` e passa a ter altura própria.
     A regra é da ZONA D porque é acabamento de toque, não estilo de tela — e
     por isso vive aqui, não no dashboard.css. */
  .dash-toggle { height: 44px; display: flex; align-items: center; }
  .dash-toggle__slider { top: 10px; bottom: 10px; }

  /* MENU É MENU, FORMULÁRIO É FORMULÁRIO.
     A aba Menu abria /dashboard/perfil com a lista de navegação E o formulário
     de perfil inteiro embaixo — 5.118px de página, com "Sair" no meio e o
     salvar no fim. No celular o formulário só aparece quando a pessoa pede
     ("Meus dados", que é /dashboard/perfil?secao=dados). No desktop esta classe
     não existe e a tela continua sendo o formulário de sempre. */
  .fd-dados-perfil--recolhido { display: none; }

  /* O alternador de lado sai do cabeçalho e vai pro topo da tela Menu: trocar
     de lado é decisão de "onde eu estou", e ela cabe numa tela, não colada no
     dedo em toda navegação. */
  .lado-switch--inline { display: flex; margin: 0 0 16px; }
  /* Mesmo alvo de dedo que o alternador já usava no cabeçalho: 44px, não 31px. */
  .lado-switch--inline .lado-switch__opt { padding: 10px 8px; min-height: 44px; font-size: 13px; }

  /* Barra de progresso do Turbo, logo abaixo do cabeçalho. Em 3G a pessoa
     precisa VER que carregou, senão toca duas vezes no mesmo botão. */
  .turbo-progress-bar {
    height: 3px;
    background: var(--color-primary, #2563EB);
    top: calc(var(--fd-appbar-h) + var(--fd-safe-t));
  }

  /* TÍTULO UMA VEZ SÓ. Nas telas raiz quem apresenta a tela é o
     `.fd-titulo-grande` do topo do conteúdo, com o nome de rua que a barra de
     baixo usa ("Dinheiro", não "Meus Ganhos"). O título do cabeçalho de página
     ali embaixo vira eco — e dois títulos empilhados é a coisa que mais denuncia
     "site espremido no celular". O SUBTÍTULO fica: ele explica, não repete.
     Nas telas de PROFUNDIDADE não se mexe: lá o título da página costuma trazer
     o nome da coisa (a vaga, o posto), que o cabeçalho compacto não tem. */
  .dash-content--raiz .dash-page-header__title { display: none; }

  /* E NAS TELAS DE PROFUNDIDADE TAMBÉM. Lá quem apresenta a tela é o título do
     cabeçalho compacto, ao lado do chevron ("‹ Candidaturas"), e o `<h2>` do
     corpo repetia quase a mesma frase logo abaixo ("Minhas Candidaturas") —
     dois títulos empilhados, a assinatura de site espremido no celular.
     O SUBTÍTULO fica: ele explica, não repete.
     EXCEÇÃO: título que carrega DADO (o nome da vaga, o nome de quem fala) não
     é eco de coisa nenhuma — o cabeçalho compacto só sabe o nome da seção. Essa
     tela marca o próprio título com `--dado` e ele continua aparecendo. */
  .dash-page-header__title:not(.dash-page-header__title--dado) { display: none; }

  /* FAIXA DE TRÊS COLUNAS (ícone · texto · botão) — empilha no celular.
     Em 360px sobravam ~115px pro texto e a frase saía uma palavra por linha.
     O `!important` é a única forma de vencer o `display:flex` que está em
     `style=` inline na própria view. */
  .fd-banner-3col {
    display: grid !important;
    grid-template-columns: 44px 1fr;
    gap: 12px !important;
    align-items: center;
    padding: 16px !important;
  }
  .fd-banner-3col > :first-child { width: 44px !important; height: 44px !important; }
  .fd-banner-3col > :first-child svg { width: 22px !important; height: 22px !important; }
  .fd-banner-3col > :last-child { grid-column: 1 / -1; text-align: center; }

  /* Nenhuma animação de entrada escalonada no celular: em Android modesto o
     dashFadeIn por nth-child faz a tela inteira "montar" na frente da pessoa. */
  .dash-card, .dash-stat { animation: none !important; }

  /* Nenhuma tela pode rolar de lado. Tabela e lista largas rolam DENTRO delas. */
  body { overflow-x: hidden; }

  /* O crossfade entre telas encurta pra 120ms no celular. É a MESMA gramática
     do Turbo 8 que o dashboard.css já define (0.22s) — só mais curta, porque
     em aparelho modesto 220ms de fade entre abas é lentidão percebida.
     NADA de slide horizontal: caro em 60Hz com CPU fraca, e o chevron ‹ do
     cabeçalho já ensina a hierarquia. */
  ::view-transition-old(root),
  ::view-transition-new(root) { animation-duration: 0.12s; }
}

/* Telas bem estreitas: o rótulo da aba encolhe antes de sumir. Rótulo some
   NUNCA — o público não decodifica pictograma. */
@media (max-width: 360px) {
  .fd-tab__rotulo { font-size: 10px; }
  .fd-appbar__titulo { font-size: 16px; }
}

/* ============================================================================
   MOVIMENTO — sob a mesma guarda que o resto do dashboard já respeita.
   Com prefers-reduced-motion: só troca de cor. Zero translate, zero scale.
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  .fd-tab,
  .fd-appbar,
  .fd-appbar__titulo,
  .fd-install-sheet,
  .fd-install-backdrop {
    transition-duration: .001ms !important;
  }
  /* Só o MOVIMENTO some. A folha continua entrando e saindo (é ela que carrega
     o convite inteiro) — o que deixa de existir é o deslize. */
  .fd-tab:active { transform: none !important; }
  .fd-appbar--raiz .fd-appbar__titulo { transform: none !important; }
  .fd-esqueleto { animation: none !important; }
}

/* ============================================================================
   POLIMENTO — o que separa "site responsivo" de "aplicativo"
   ============================================================================
   Tudo daqui pra baixo é acabamento: nada aqui muda navegação, rota ou regra
   de negócio. São as sete coisas que o dedo percebe e que ninguém sabe nomear
   — a barra que não pisca ao trocar de tela, o toque que responde na hora, o
   scroll que não "puxa a página inteira", o texto que não fica azul de seleção
   quando se segura o dedo, e o carregamento que não é uma tela branca.

   Três regras que valem para o bloco inteiro:
   1. Nada some do foco de teclado. Toda regra de :active abaixo convive com o
      :focus-visible que já existe — e onde o projeto não tinha um, este bloco
      acrescenta. Aplicativo que engole o foco é aplicativo que exclui gente.
   2. Nada aqui roda sob prefers-reduced-motion: o bloco final desliga
      movimento e deixa só cor. Ver o fim do arquivo.
   3. Zero biblioteca nova. Tudo é CSS de navegador e o Turbo que já está aqui.
   ============================================================================ */

/* ----------------------------------------------------------------------------
   1. A CASCA NÃO ENTRA NA TRANSIÇÃO DE PÁGINA

   O Turbo 8 já faz crossfade entre telas (meta view-transition no layout). Só
   que, sem nome próprio, a barra de baixo e o cabeçalho entram no snapshot da
   RAIZ e desaparecem/reaparecem junto com o conteúdo — a barra "pisca" a cada
   navegação. É o tique visual que mais denuncia site: em aplicativo nativo a
   barra de abas simplesmente NÃO se move quando a tela troca.

   Dar `view-transition-name` a cada peça de casca a tira do grupo da raiz e
   dá a ela um grupo só seu. Para a barra de baixo, que é `data-turbo-permanent`
   e nunca muda, o grupo é congelado (`animation: none`): ela fica parada
   enquanto o miolo faz o crossfade. O cabeçalho e o dock mantêm o crossfade
   próprio, porque o conteúdo deles muda de verdade (título, botão do ponto).

   Só dentro de ≤768px: acima disso as três peças são `display:none`, não
   entram em snapshot nenhum, e nome de transição em elemento não renderizado
   não existe pro navegador.
   ---------------------------------------------------------------------------- */
@media (max-width: 768px) {
  .fd-tabbar  { view-transition-name: fd-tabbar; }
  .fd-appbar  { view-transition-name: fd-appbar; }
  .fd-dockbar { view-transition-name: fd-dockbar; }
  .fd-net     { view-transition-name: fd-net; }
}

/* A barra de baixo NÃO anima NADA: nem o retrato antigo desbotando, nem o
   grupo (que é a caixa se movendo de um lugar pro outro). Ela é a única coisa
   da tela que a pessoa pode usar como ponto fixo enquanto o resto troca. */
::view-transition-old(fd-tabbar),
::view-transition-new(fd-tabbar),
::view-transition-group(fd-tabbar),
::view-transition-old(fd-net),
::view-transition-new(fd-net),
::view-transition-group(fd-net) { animation: none; mix-blend-mode: normal; }

/* Cabeçalho e dock: crossfade próprio, na mesma duração do miolo (0.12s). O
   `group` entra na conta porque o padrão do navegador pra ele é 250ms — deixar
   só o fade em 120ms faria a caixa continuar se ajeitando depois que o
   conteúdo já trocou. */
::view-transition-old(fd-appbar),
::view-transition-new(fd-appbar),
::view-transition-group(fd-appbar),
::view-transition-old(fd-dockbar),
::view-transition-new(fd-dockbar),
::view-transition-group(fd-dockbar) { animation-duration: 0.12s; }

/* ----------------------------------------------------------------------------
   2. CARREGAMENTO — nunca a tela branca de site

   A barra de progresso do Turbo é a resposta certa aqui, e não esqueleto:
   entre um toque e a tela nova o Turbo mantém a página ANTIGA visível (não há
   tela branca nenhuma), então a única coisa que falta é o sinal de "estou
   indo". Esqueleto seria uma mentira: ele desenharia caixas que talvez não
   existam na resposta.

   Duas mudanças: cor da marca (o padrão do Turbo é um azul que não é o nosso)
   e o atraso, que sai dos 500ms de fábrica pra 300ms (ver application.js). Em
   3G, meio segundo sem sinal nenhum é o tempo exato em que a pessoa toca de
   novo no mesmo botão.

   Fora do ≤768px também: no desktop a mesma barra vale, só que colada no topo
   da janela (lá não existe .fd-appbar pra ficar embaixo).
   ---------------------------------------------------------------------------- */
.turbo-progress-bar {
  height: 3px;
  background: linear-gradient(90deg, var(--color-primary, #2563EB), var(--color-primary-light, #3B82F6));
}

/* ESQUELETO ONDE ELE É VERDADE: quando um turbo-frame recarrega no lugar (o
   filtro de Vagas, o painel do dia do posto), a página não navega e a barra de
   progresso NÃO aparece — o que existia era só o `opacity:.55` do
   dashboard.css, que em rede ruim parece tela travada. Aqui a lista apagada
   ganha uma varredura de luz por cima: diz "estou buscando" sem inventar
   nenhuma linha que talvez não venha. */
.dash-content turbo-frame[busy] { position: relative; }
.dash-content turbo-frame[busy]::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: 12px;
  background: linear-gradient(100deg, transparent 20%, rgba(37, 99, 235, .07) 46%, rgba(37, 99, 235, .12) 50%, rgba(37, 99, 235, .07) 54%, transparent 80%);
  background-size: 220% 100%;
  animation: fdVarredura 1.15s linear infinite;
}
@keyframes fdVarredura { from { background-position: 130% 0; } to { background-position: -130% 0; } }

/* ----------------------------------------------------------------------------
   3. FEEDBACK DE TOQUE

   Duas metades que só funcionam JUNTAS, e é por isso que estão no mesmo bloco:

   (a) `-webkit-tap-highlight-color: transparent` mata o retângulo cinza que o
       Android pinta em cima de qualquer link tocado. É o realce que mais
       denuncia "site".
   (b) Um `:active` próprio no lugar dele. Tirar (a) sem fazer (b) é PIOR do
       que não mexer: o toque fica sem resposta nenhuma e o aplicativo parece
       morto — exatamente o oposto do que se queria.

   Escala de 0.98, nunca menos: abaixo disso o cartão "afunda" e vira brinquedo.
   ---------------------------------------------------------------------------- */
@media (max-width: 768px) {
  a, button, summary, label, [role="button"], .dash-card, .dash-stat {
    -webkit-tap-highlight-color: transparent;
  }

  /* O que responde ao dedo com escala: o que é clicável de verdade. */
  .dash-btn:active:not(:disabled),
  .btn:active:not(:disabled),
  a.dash-stat:active,
  .dash-card[data-controller~="card-link"]:active,
  .fd-vaga-card:active,
  .fd-menu__cartao:active,
  .dash-nav-link:active {
    transform: scale(.98);
  }
  .dash-btn, .btn, a.dash-stat, .dash-card[data-controller~="card-link"], .fd-vaga-card, .fd-menu__cartao, .dash-nav-link {
    transition: transform .08s ease, box-shadow .12s ease, background-color .12s ease;
  }

  /* Cartão clicável some a sombra e escurece um tico: o dedo tapa a metade de
     baixo do cartão, então a resposta tem que ser visível na metade de cima. */
  .dash-card[data-controller~="card-link"]:active,
  .fd-menu__cartao:active { background-color: var(--color-gray-50, #F8FAFC); }

  /* FOCO CONTINUA EXISTINDO. Se um elemento ganhou :active aqui e não tinha
     :focus-visible próprio, ele ganha agora — a regra é a do resto do projeto
     (2px na cor primária, deslocado 2px). */
  .dash-btn:focus-visible,
  .btn:focus-visible,
  .dash-card[data-controller~="card-link"]:focus-visible,
  .fd-vaga-card:focus-visible,
  .fd-menu__cartao:focus-visible,
  .fd-menu__item:focus-visible,
  .dash-nav-link:focus-visible {
    outline: 2px solid var(--color-primary, #2563EB);
    outline-offset: 2px;
  }
}

/* O HOVER QUE FICA GRUDADO. Num aparelho de toque não existe "sair com o
   mouse": o Android aplica :hover no toque e ele SÓ sai quando a pessoa toca em
   outro lugar. O resultado é um cartão que continua levantado depois que a
   tela já mudou — a coisa mais "site" que existe. Aqui os efeitos de hover que
   MOVEM são desligados em quem não tem ponteiro fino; cor e borda continuam
   (elas não deixam rastro estranho). Não é `!important` em ninguém: é só a
   mesma especificidade, declarada depois. */
@media (hover: none) {
  a.dash-stat:hover,
  .dash-stat:hover,
  .dash-card:hover,
  .dash-gig-card:hover,
  .fd-vaga-card:hover,
  .dash-btn:hover,
  .btn:hover { transform: none; }
  a.dash-stat:hover .dash-stat__chevron { transform: none; }

  /* O CARD DE VAGA ERA O ÚNICO ELEMENTO TOCÁVEL FORA DESTE BLOCO — e é
     literalmente o cartão que o Sergio chamou de "estranho". `.dash-gig-card`
     tem `translateY(-2px)` + sombra no :hover (dashboard.css): num aparelho de
     toque o :hover só sai quando se toca em OUTRO lugar, então o cartão fica
     levantado e com sombra grudados depois que a tela já mudou. Some a sombra
     junto com o transform: metade da correção deixaria a sombra pendurada. */
  .dash-gig-card:hover, .fd-vaga-card:hover { box-shadow: var(--fd-elev-1); }
}

/* ----------------------------------------------------------------------------
   4. O SCROLL NÃO PUXA A PÁGINA INTEIRA

   `.dash-content` já contém o overscroll (lá em cima). Falta o resto do que
   rola por dentro: a conversa, a folha de instalação e qualquer tabela larga.
   Sem isto, chegar no fim da conversa continua arrastando a página atrás dela
   e a barra de baixo balança junto.

   E quando o aplicativo está MESMO na tela inicial (`fd-standalone`), o
   documento inteiro deixa de ter bounce e pull-to-refresh: ali dentro não há
   navegador nem botão de recarregar, e a página "esticando" no topo é o
   defeito visual mais óbvio de PWA mal acabado. No navegador comum o
   pull-to-refresh CONTINUA funcionando — é gesto que a pessoa já conhece e
   tirar seria pior. */
.dash-chat,
.fd-install-sheet { overscroll-behavior: contain; }

/* A FILA DE ABAS DE DENTRO DA TELA (`.dash-tabs`) rola de lado. Faltavam duas
   coisas nela: conter o overscroll (chegar no fim da fila arrastava a página
   junto, e a barra de baixo balançava) e esconder a barrinha de rolagem, que
   em Android aparece cinza por cima da última aba. */
.dash-tabs {
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.dash-tabs::-webkit-scrollbar { display: none; }

html.fd-standalone,
html.fd-standalone body { overscroll-behavior-y: none; }

/* ----------------------------------------------------------------------------
   5. SEGURAR O DEDO NÃO SELECIONA A CASCA

   Segurar um item da barra ou do cabeçalho selecionava o rótulo e abria a
   alça azul de seleção de texto — em aplicativo isso não acontece. A barra e o
   cabeçalho já tinham `user-select: none`; falta a barra lateral (que é a
   mesma navegação no desktop), o dock e o banner de rede. E o
   `-webkit-touch-callout` mata o menu de "abrir em nova aba / copiar link" que
   o iOS abre em cima de qualquer link segurado.

   O CONTEÚDO NÃO ENTRA NISTO. Endereço da vaga, valor, nome da empresa: tudo
   isso a pessoa PRECISA poder selecionar e copiar. Só a casca fica travada. */
.fd-tabbar,
.fd-appbar,
.fd-dockbar,
.fd-net,
.dash-sidebar,
.dash-topbar,
.fd-install__alca {
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* ----------------------------------------------------------------------------
   6. VOLTAR CAI NO LUGAR ONDE A PESSOA ESTAVA

   `html { scroll-behavior: smooth }` está no application.css e serve pros
   links de âncora da landing. Só que ele também pega a restauração de scroll
   do Turbo: ao voltar, em vez de a tela JÁ estar na posição antiga, ela ANIMA
   até lá — e em lista longa a animação é longa, visível e, quando a pessoa
   rola durante ela, é interrompida no meio e a posição se perde.

   A classe é posta pelo `casca_controller` só durante a troca de tela e tirada
   logo depois, então a rolagem suave dos links de âncora continua existindo. */
html.fd-restaurando { scroll-behavior: auto !important; }


/* ============================================================================
   O ALTERNADOR DE LADO, O CONVITE PRO OUTRO LADO E O RESTO DO CROMO DO LAYOUT

   Este bloco veio inteiro do `<style>` que morava dentro de
   app/views/layouts/dashboard.html.erb. Ele não mudou de conteúdo — mudou de
   endereço, e é a razão de ser deste arquivo: CSS em três lugares (folha,
   <style> do layout, style="" inline) é a causa raiz das regras mortas que o
   comentário de abertura cita. Com o alternador aqui, "onde está o CSS da
   casca" tem UMA resposta.
   ============================================================================ */
/* Alternador: segmentado de dois estados. O lado ativo é sólido; o outro,
   apagado — a pessoa lê "onde estou" antes de ler "pra onde vou". */
.lado-switch { display: flex; gap: 4px; padding: 4px; background: var(--color-gray-100, #F1F5F9); border-radius: 12px; }
.lado-switch__opt { flex: 1 1 0; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 6px;
                    padding: 8px 6px; min-height: 36px; border: none; border-radius: 9px; background: transparent; cursor: pointer;
                    font-size: 12.5px; font-weight: 600; color: #475569; /* gray-600: 12px em cinza-500 não passa 4.5:1 */
                    font-family: inherit; transition: background .15s ease, color .15s ease; }
/* Foco visível: é um controle de navegação, e quem anda de teclado
   precisa ver onde está antes de trocar a tela inteira. */
.lado-switch__opt:focus-visible { outline: 2px solid var(--color-primary, #2563EB); outline-offset: 2px; }
.lado-switch__opt svg { width: 16px; height: 16px; flex: none; }
.lado-switch__opt span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lado-switch__opt:hover:not(:disabled) { color: var(--color-gray-900, #0F172A); background: rgba(255,255,255,.6); }
.lado-switch__opt--on { background: #fff; color: var(--color-primary, #2563EB); font-weight: 700;
                        box-shadow: 0 1px 2px rgba(15,23,42,.08); cursor: default; }
.lado-switch__opt:disabled { opacity: 1; }
.lado-switch--sidebar { margin: 4px 12px 8px; }
/* NO CELULAR O ALTERNADOR MUDOU DE CASA. Ele morava no cabeçalho, colado
   no hambúrguer. Com a gaveta morta e a barra de baixo no lugar, o
   cabeçalho de celular ficou com dois alvos só (Fred e mensagens) e o
   alternador foi pro TOPO DA TELA MENU, na variante `--inline` (as regras dela
   estão lá em cima, no bloco da tela Menu). Continua valendo o que sempre
   valeu: ele NUNCA vai pra
   dentro de um menu escondido — a tela Menu é um destino com endereço
   (/dashboard/perfil), não uma gaveta. */
@media (max-width: 768px) {
  .lado-switch--sidebar { display: none; }
}

/* Convite pro outro lado — RECOLHIDO (<details> nativo).
   Ele tinha ~450px de altura no celular e roubava a home de quem só queria ver
   o trabalho de hoje. Agora é uma linha só: badge + título + uma frase. O que
   estava escrito continua tudo lá dentro, a um toque. */
.lado-convite { background: #fff; border: 1.5px solid var(--color-gray-100, #E2E8F0);
                border-radius: 16px; }
.lado-convite--card { margin-top: 28px; }
.lado-convite--tela { box-shadow: 0 4px 20px rgba(15,23,42,.05); }
/* O marcador nativo (triângulo do Safari/Chrome) some: o chevron é nosso, e o
   triângulo do sistema quebra o alinhamento do badge. */
.lado-convite > summary { list-style: none; }
.lado-convite > summary::-webkit-details-marker { display: none; }
.lado-convite__resumo { display: flex; align-items: center; gap: 12px; cursor: pointer;
                        min-height: 44px; padding: 14px 16px; -webkit-tap-highlight-color: transparent; }
.lado-convite--tela .lado-convite__resumo { padding: 18px 20px; }
.lado-convite__resumo:focus-visible { outline: 2px solid var(--color-gray-900, #0F172A); outline-offset: -2px;
                                      border-radius: 16px; }
.lado-convite__resumo-txt { min-width: 0; display: grid; gap: 2px; }
.lado-convite__uma-linha { font-size: 12.5px; line-height: 1.4; color: var(--color-gray-500, #64748B); }
.lado-convite__chev { width: 18px; height: 18px; flex: none; margin-left: auto;
                      color: var(--color-gray-400, #94A3B8); transition: transform .15s ease; }
.lado-convite[open] .lado-convite__chev { transform: rotate(180deg); }
/* Quem pediu menos movimento não ganha chevron girando. */
@media (prefers-reduced-motion: reduce) {
  .lado-convite__chev { transition: none; }
}
.lado-convite__badge { width: 32px; height: 32px; flex: none; border-radius: 10px; background: var(--lado-cor-fraca);
                       color: var(--lado-cor); display: flex; align-items: center; justify-content: center; }
.lado-convite__badge svg { width: 17px; height: 17px; }
.lado-convite__corpo { min-width: 0; padding: 0 16px 16px 60px; }
.lado-convite--tela .lado-convite__corpo { padding: 0 20px 22px 64px; }
.lado-convite__title { display: block; font-size: 15px; font-weight: 800; color: var(--color-gray-900, #0F172A); margin: 0; }
.lado-convite__text { font-size: 13.5px; line-height: 1.55; color: var(--color-gray-500, #64748B); margin: 0 0 14px; }
.lado-convite__list { list-style: none; padding: 0; margin: 0 0 18px; display: grid; gap: 8px; }
.lado-convite__list li { display: flex; gap: 8px; align-items: flex-start; font-size: 13.5px; line-height: 1.45;
                         color: var(--color-gray-700, #334155); }
.lado-convite__list svg { width: 15px; height: 15px; flex: none; margin-top: 2px; color: var(--lado-cor); }
.lado-convite__btn { width: 100%; max-width: 320px; padding: 12px 18px; border: none; border-radius: 12px;
                     background: var(--lado-cor); color: #fff; font-family: inherit; font-size: 14px;
                     font-weight: 700; cursor: pointer; }
.lado-convite__btn:hover { filter: brightness(.94); }
.lado-convite__btn:focus-visible { outline: 2px solid var(--color-gray-900, #0F172A); outline-offset: 2px; }
/* 12px em gray-400 sobre branco dá ~2.6:1 — a promessa honesta ficava
   ilegível justamente pra quem mais precisa lê-la. */
.lado-convite__nota { font-size: 12.5px; line-height: 1.5; color: var(--color-gray-500, #64748B); margin: 10px 0 0; }
.lado-convite-page { max-width: 620px; }
.lado-convite-page__back { display: inline-flex; align-items: center; gap: 6px; margin-bottom: 16px;
                           font-size: 13px; font-weight: 600; color: var(--color-gray-500, #64748B); text-decoration: none; }
.lado-convite-page__back svg { width: 14px; height: 14px; }
@media (max-width: 480px) {
  /* No celular o corpo perde o recuo do badge: 60px de margem esquerda deixava
     a lista de benefícios com meia dúzia de caracteres por linha. */
  .lado-convite__corpo,
  .lado-convite--tela .lado-convite__corpo { padding: 0 16px 16px; }
  .lado-convite__btn { max-width: none; }
}

/* O "MAIS" HONESTO (§7.1.6): a gaveta de profundidade da barra lateral.
   Fica fechada por padrão e abre sozinha quando a pessoa já está numa
   das telas de dentro — assim ela vê ONDE está, em vez de olhar para um
   menu que não acende em lugar nenhum. */
.dash-nav-more > summary { list-style: none; cursor: pointer; }
.dash-nav-more > summary::-webkit-details-marker { display: none; }
.dash-nav-more__chev { width: 16px; height: 16px; margin-left: auto; transition: transform .15s ease; }
.dash-nav-more[open] .dash-nav-more__chev { transform: rotate(180deg); }
.dash-nav-more__group { font-size: 11px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase;
                        color: var(--color-gray-400, #94A3B8); padding: 12px 12px 4px; display: block; }
.dash-nav-more .dash-nav-link { padding-left: 22px; font-size: 13.5px; }

/* Balão de mensagens no cabeçalho: a conversa nasce dentro do trabalho,
   mas o "me responderam?" é pergunta de topo de tela, não de menu. */
.dash-topbar__msg { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px;
                    border-radius: 12px; color: var(--color-gray-500, #64748B); text-decoration: none; }
.dash-topbar__msg:hover { background: var(--color-gray-100, #F1F5F9); color: var(--color-gray-900, #0F172A); }
.dash-topbar__msg svg { width: 20px; height: 20px; }
.dash-sidebar__user-link { display: flex; text-decoration: none; color: inherit; }

/* ============================================================================
   MOVIMENTO — a guarda vale pro bloco de polimento inteiro.
   ============================================================================ */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(fd-appbar),
  ::view-transition-new(fd-appbar),
  ::view-transition-group(fd-appbar),
  ::view-transition-old(fd-dockbar),
  ::view-transition-new(fd-dockbar),
  ::view-transition-group(fd-dockbar) { animation: none !important; }

  /* Sem escala no toque: a resposta vira só a mudança de cor de fundo, que
     continua acontecendo. Feedback não some — movimento é que some. */
  .dash-btn:active, .btn:active, a.dash-stat:active,
  .dash-card[data-controller~="card-link"]:active,
  .fd-vaga-card:active,
  .fd-menu__cartao:active, .dash-nav-link:active { transform: none !important; }

  .dash-content turbo-frame[busy]::after { animation: none !important; background: rgba(37, 99, 235, .06); }
  .turbo-progress-bar { transition: none !important; }
}

/* ============================================================================
   A FAIXA DE INSTALAR — a porta pequena que fica de pé em toda tela.
   ============================================================================
   Ver `shared/_instalar_faixa.html.erb` pro porquê de ela existir (01/09/2026:
   quem criava conta no celular não era convidado a instalar em tela nenhuma).

   NO FLUXO, NÃO FIXA, e isso é decisão de camada, não de gosto: a faixa de
   baixo já tem três donos (tabbar 500, dock 490, banner de rede 480) e o alto
   do dashboard é do `.fd-appbar` (400). Flutuar seria escolher qual peça
   cobrir. Como primeiro filho do <body> ela apenas empurra a página, e convive
   com a `.fd-appbar` porque aquela é `sticky` e não `fixed`: as duas dividem o
   fluxo, a faixa rola pra fora e a appbar gruda no topo, sem sobreposição.

   O `padding-top: var(--fd-safe-t)` NÃO soma com o da appbar na prática, e o
   motivo é bom de saber antes de "otimizar" isto: `safe-area-inset-top` só é
   maior que zero em modo instalado (é lá que a página passa por baixo da barra
   de status) — e em modo instalado esta faixa está escondida, porque não há
   mais o que instalar. Quando ela aparece, o inset é zero e não há vão nenhum
   entre as duas.
   ---------------------------------------------------------------------------- */
.fd-instalar-faixa {
  /* STICKY, e não `fixed`: sticky ocupa lugar no fluxo (então nada precisa de
     padding compensatório e nenhum `100dvh` ganha rolagem extra) E gruda no
     topo quando a página rola — que é o "estimular sempre" do pedido. */
  position: sticky;
  top: 0;
  z-index: 700;
  box-sizing: border-box;
  height: var(--fd-faixa-h);
  display: flex;
  align-items: stretch;
  gap: 0;
  background: #EFF6FF;
  border-bottom: 1px solid #DBEAFE;
  padding-top: var(--fd-safe-t);
}
.fd-instalar-faixa[hidden] { display: none; }

.fd-instalar-faixa__alvo {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  /* 44px é o piso de alvo de toque da casca inteira (§ZONA D). A faixa é
     pequena, não é minúscula: um convite que a pessoa erra o dedo não é
     convite. */
  min-height: 44px;
  padding: 6px 4px 6px 12px;
  background: none;
  border: 0;
  color: #1E3A8A;
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
.fd-instalar-faixa__icone { width: 18px; height: 18px; flex: none; }
.fd-instalar-faixa__texto {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* O "Instalar" é o que a pessoa procura quando decide — cor de ação, e não
   mais um pedaço do texto. Mas ele é um SPAN dentro do botão inteiro: a faixa
   toda é o alvo, pra ninguém precisar acertar duas palavras. */
.fd-instalar-faixa__cta {
  flex: none;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--color-primary, #2563EB);
  color: #FFFFFF;
  font-size: 13px;
  font-weight: 700;
}
.fd-instalar-faixa__alvo:active { background: #DBEAFE; }

/* O "×" é DELIBERADAMENTE discreto e fica na ponta: ele é a saída, não a ação.
   Mesmo assim tem 44px de alvo — esconder também é um direito. */
.fd-instalar-faixa__fechar {
  flex: none;
  width: 44px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  color: #60A5FA;
  cursor: pointer;
}
.fd-instalar-faixa__fechar svg { width: 16px; height: 16px; }

/* No computador a faixa não vira uma tarja de 1920px: o texto respira no mesmo
   limite de leitura do resto e o convite fica centrado. */
@media (min-width: 769px) {
  .fd-instalar-faixa { justify-content: center; }
  .fd-instalar-faixa__alvo { flex: 0 1 auto; padding-left: 16px; }
  .fd-instalar-faixa__texto { white-space: normal; }
}
