/** 256bip:deps — gerado por deps_annotate.py; não editar manualmente
 * used-by: frontend/layout/header.php
 * uses: (nenhum detectado)
 */

/*
 * ============================================================
 * 256bip — Core CSS
 * Design Premium, Escuro, Sem contraste absoluto (preto/branco puro)
 * ============================================================
 */

/* === RESET === */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/*
 * `hidden` PRECISA ESCONDER (09/08/26).
 *
 * O atributo `hidden` só vira `display: none` pela folha do NAVEGADOR, que é a
 * origem mais fraca da cascata: basta o nosso CSS declarar qualquer `display`
 * para o elemento — um `display: flex` num painel, por exemplo — e o
 * `el.hidden = true` do JavaScript deixa de esconder qualquer coisa.
 *
 * Foi assim que a barra de formatação ficou pendurada na tela por versões a fio:
 * o JS escondia, `.bip-fmt` tinha `display: flex`, e o esconder não existia. Dez
 * tentativas de conserto mexeram em QUANDO esconder; o problema era o COMO.
 *
 * Este arquivo tinha VINTE remendos `.algo[hidden] { display: none !important }`
 * — cada um foi um bug igual, encontrado e tapado sozinho. Esta regra resolve a
 * classe inteira, inclusive para o que ainda vai ser escrito. Quem quiser um
 * elemento visível não põe `hidden` nele.
 */
[hidden] { display: none !important; }

:root {
    /* ══ TEMA ESCURO, REFEITO (13/09/26, ordem do dono: *"nosso tema claro
       está um espetáculo, mas nosso tema escuro está uma tragédia; não vou
       ditar cores, só não faça ffffff com 000000, faça o seu melhor"*).

       O que havia: uma passada anterior tinha trocado o azul de acento por um
       BEGE (#D1CFC0) e cravado esse bege, com #363636 e #1F1F1F, em dezenas
       de regras `:root:not([data-theme="light"])`, deixando os tokens
       originais em comentário. Sidebar, rail, cartões e botões liam cinza
       sobre cinza, com um creme de acento que não é de lugar nenhum. Essas
       regras foram REMOVIDAS: o escuro volta a ser só estes tokens.

       A escala: grafite FRIO (um pingo de azul no cinza), quatro degraus
       (chão → cartão → campo → hover), texto marfim e não branco, acento azul
       claro da mesma família do #4B7BB7 do claro. Chão #141619 e título
       #ECEEF2: nem 000000 nem ffffff. */
    --bg:           #141619;
    --bg-2:         #191C21;
    --surface:      #1E2126;
    --surface-2:    #262A31;
    --surface-3:    rgba(255,255,255,0.04);
    /* Sobreposição (hover) da navegação — no claro vira cinza (ver tema claro). */
    --nav-hover:    #23272E;
    --border:       rgba(255,255,255,0.08);
    --border-hover: rgba(255,255,255,0.16);
    --border-focus: rgba(111,160,232,0.55);

    --white:        #F1F3F6;
    --text:         #D6D9DE;
    /* `--text-1` NUNCA EXISTIU (achado em 24/08/26, dono: *"sem contar este css
       branco, fica péssimo para ler"*). Sessenta e três declarações a usavam —
       `color: var(--text-1)` sem fallback é declaração INVÁLIDA, e a cor caía na
       herança: no tema claro isso pintava de branco o nome de quem tem status,
       sobre fundo claro. Ela é o degrau mais forte da escala (título, nome, o
       que precisa de peso), acima de `--text`. */
    --text-1:       #ECEEF2;
    --text-2:       #9AA2AE;
    --text-3:       #6A7280;

    /* Azul claro da família do #4B7BB7 do claro: sobre grafite, o mesmo azul
       médio afunda; um degrau mais claro lê como o MESMO azul. */
    --accent:       #6FA0E8;
    /* A MOBÍLIA NO ESCURO (21/08/26). Precisa existir nos DOIS temas: a tarja
       do cabeçalho usa `var(--orkut-bar)` e escreve em BRANCO por cima. Sem
       esta linha, no escuro a variável não resolve, o fundo vira transparente
       e o título fica branco sobre cartão escuro… que até se lê, mas some a
       tarja inteira — o móvel que dá a cara do Orkut.
       Tom mais fundo que o #4B7BB7 do claro: sobre superfície escura o azul
       médio brilha demais e a coluna vira um farol. */
    --orkut-bar:    #2F5382;
    /* No ESCURO o "pálido" é um azul fundo — pálido de verdade viraria um bloco
       branco no meio da coluna preta. A tinta é clara pelo mesmo motivo. */
    --orkut-tarja:  #242B36;
    --orkut-tinta:  #B9CEEC;
    --orkut-bar-hover: #284670;
    --orkut-bar-glow:  rgba(47,83,130,0.35);
    --accent-soft:  rgba(111,160,232,0.14);
    --accent-glow:  rgba(111,160,232,0.30);
    --green:        #22C083;
    --green-soft:   rgba(34,192,131,0.14);
    --red:          #F0555A;
    accent-color:   var(--accent);

    /*
     * QUEM DESENHA O EMOJI É O SISTEMA — e deve continuar sendo (09/08/26).
     *
     * Cheguei a pôr 'Noto Color Emoji' aqui para resolver as bandeiras que o
     * Windows não tem. Foi um mau negócio: a Noto passou a valer para TODOS os
     * emojis e substituiu o Fluent Emoji do Windows 11 — que é justamente o
     * desenho bonito e 3D que o dono admirou nas outras redes. Trocar o melhor
     * pelo pior para consertar as bandeiras é pagar caro demais por elas.
     *
     * Emoji igual em todo sistema se resolve com IMAGEM (spritesheet do
     * emoji-mart), não trocando a fonte — e essa decisão fica para quando o
     * seletor novo entrar, com o dono escolhendo o estilo.
     */
    --font:         'Inter', system-ui, -apple-system, sans-serif;
    --radius:       12px;
    /* --radius-md FALTAVA (26/07/26): 4 caixas usavam var(--radius-md) indefinida,
       o navegador ignorava a linha inteira e o canto saía RETO (a barra da tag na
       busca era a mais visível). Definida, todas arredondam de uma vez. */
    --radius-md:    12px;
    --radius-lg:    12px;
    --radius-xl:    12px;
    
    --sidebar-width:  240px;
    --nav-col-width:  240px;
    /* INVERSÃO (24/07/26): em vez de esticar o feed até os menus, o meio ENCOLHE
       e as laterais vêm pra dentro. 620 = card cheio (respiro 14px) com o
       conteúdo/foto nos 548px ORIGINAIS — proporção intacta, distância padrão. */
    --feed-col-width: 620px;
    --rail-col-width: 320px;
    --layout-gap:     28px;
    --feed-gutter-x:  14px; /* respiro padrão card→borda da coluna (24/07/26) */
    --shell-pad-x:    40px;
    --app-shell-width: calc(var(--shell-pad-x) * 2 + var(--nav-col-width) + var(--layout-gap) + var(--feed-col-width) + var(--layout-gap) + var(--rail-col-width));
    --content-col-width: var(--feed-col-width);
    --feed-rail-width: var(--rail-col-width);
    --rail-stack-gap: 16px;
    /* ══ O RESPIRO DO TOPO, UM BOTÃO SÓ (29/08/26) ═══════════════════════
       Ordem do dono: *"veja o respiro entre a nota e o topo — este é o tamanho
       ideal. Em comunidade está muito alto, no chat, no perfil. Não tem mesmo
       como investigar e resolver isso?"*.

       Tinha, e a causa era boba: QUATRO arquivos repetiam o mesmo número à mão
       — `profile.css`, `communities.css`, `inbox.css` (22px cada, todos com o
       comentário "régua única do topo") e `mensagens.css` (16px). "Régua única"
       escrita quatro vezes não é régua nenhuma: mudar no celular exigia achar os
       quatro, e a primeira tentativa de corrigir o perfil ainda apanhou da ordem
       de carga (o CSS da página entra DEPOIS do `mobile.css` e ganhava o empate).

       Agora é uma variável. As páginas dizem `padding-top: var(--topo-respiro)`
       e param de decidir; quem decide é este valor, e o celular o troca num
       lugar só (ver o `mobile.css`). Variável não tem esse problema de ordem:
       ela é lida na hora do uso, não na hora da declaração. */
    --topo-respiro: 22px;
    --app-topbar-height: 72px;
    --feed-rail-offset-y: 12px;
    --container-max: var(--app-shell-width);
    --container-pad-x: 32px;
    --header-h:     64px;

    --ease:         cubic-bezier(0.4, 0, 0.2, 1);
    --duration:     0.25s;

    /* Sombras mais fundas no escuro (13/09/26): é a sombra, e não a linha,
       que separa o cartão do chão quando os dois são grafite. */
    --shadow-sm:    0 1px 3px rgba(0,0,0,0.45);
    --shadow-md:    0 6px 20px rgba(0,0,0,0.50);

    /* Pastilha das abas (feed, perfil, comunidade, busca) no ESCURO.
       Vive aqui e não só no bloco claro: lá `--orkut-tinta` é escura (#33383f)
       e funciona em cima do #BCCDE9; aqui `--orkut-tinta` é clara (tarja) e
       some na pastilha — era o "Fórum" ilegível no tema escuro. */
    /* No escuro a pastilha é um azul fundo com tinta clara (13/09/26): o mesmo
       par da tarja do Orkut, um degrau acima do cartão. */
    --pastilha:        #2B3D5C;
    --pastilha-tinta:  #D6E3F5;
    --pastilha-sombra: none;

    /* A PÍLULA "SEGUIR" (11/09/26, dono: o botão do aipim.social é
       "maravilhoso", e quer igual em toda a rede). Um par FIXO por tema, e não
       `--white`/`--bg`, que trocam de papel entre os temas (ver a nota em
       `.follows-btn`). No ESCURO ela inverte: pílula branca, letra preta; os
       estados (Seguindo/Conectados/Pendente) em cinza escuro com letra clara.
       Quem lê estes tokens: cartão, resposta, rail, /follows, rankings, busca
       (BipTag), perfil e o "+" do avatar no celular. A versão CLARA mora no
       bloco `[data-theme="light"]`, mais abaixo. */
    --seguir-bg:             #ECEEF2;
    --seguir-bg-hover:       #F6F7F9;
    --seguir-fg:             #15181D;
    --seguir-feito-bg:       #2A2F37;
    --seguir-feito-bg-hover: #343A44;
    --seguir-feito-fg:       #E4E7EC;
}

/* === Tema claro — pastel suave, sem branco puro. Só sobrescreve COR (layout/fontes ficam) === */
[data-theme="light"] {
    /* DUAS CORES, SÓ (16/08/26, ordem do dono: "#F4F4F4 e #FFFFFF"). Com as
       caixas sem contorno, quem separa o cartão do fundo é o DEGRAU de cor —
       então ele precisa ser um só e ser claro: #F4F4F4 embaixo, #FFFFFF em
       cima. O antigo #F9FAFB era quase branco e, sem borda, o cartão se
       dissolvia na página.
       A cor de SOBREPOSIÇÃO (hover) da navegação vira cinza mais abaixo
       (--nav-hover) — surface-2 fica branco porque alimenta ~40 painéis. */
    /* PALETA ORKUT (21/08/26, cores levantadas pelo DONO). Para voltar:

           --bg: #D9E8F5;   (azul-Orkut, 1ª medição, 21/08)
           --bg: #F7F3ED;   (creme — tentativa minha, 21/08, ERRADA)
           --bg: #EFF4F7;   (cinza com fundo azul, 17/08/26)
           --bg: #F4F4F4;   (cinza neutro, 16/08/26)

       DUAS TENTATIVAS MINHAS ERRARAM ANTES DESTA, e vale registrar por quê:
       primeiro fui de CREME ("o Orkut era quente porque nada era cinza") e
       depois cogitei MAGENTA. As duas estavam erradas — a memória que as
       pessoas têm do Orkut é o AZUL DE BARRA, e foi o dono quem trouxe os
       números certos. Lição: em cor, referência levantada vale mais do que
       dedução bem argumentada.

       A paleta dele, e o papel de cada uma nesta casa:
           #4B7BB7  barras e cabeçalhos ...... `--orkut-bar` (mobília)
           #D4DDED  fundo (valor CONFIRMADO pelo dono, 21/08) . `--bg`
           #E5E5E5  bordas e divisórias ...... `--border`
           #FFFFFF  conteúdo ................. `--surface` (já era)

       SUPERADO NO MESMO DIA. Aqui eu escrevi que o #4B7BB7 "não vira o azul de
       ação" — que mobília e ação precisavam de tons diferentes para não sumir a
       hierarquia de "onde eu clico". O dono foi levando um por um (botões,
       depois os links) e a página com UM azul só ficou melhor do que o meu
       argumento previa: o que separa botão de link não é o tom, é a FORMA —
       botão é bloco cheio com letra branca, link é palavra sublinhável no meio
       do texto. Fica registrado que a previsão errou. */
    /* ══ MENOS AZUL, MESMO DEGRAU (21/08/26) ═══════════════════════════════

       O dono comparou o modal "Nova comunidade" (cinza neutro) com o resto do
       site e disse: *"o nosso layout do modal e muito mais lindo que este monte
       de azul, fala serio"*. Ele esta certo, e a medicao mostrou por que — e de
       quebra desmentiu a minha primeira ideia.

       EU PROPUS CLAREAR o fundo (#EFF2F7) achando que isso destacaria os
       cartoes. Errado nos dois pontos:
         - clarear PIORA o degrau do cartao branco (1,37 → 1,12): quanto mais
           perto do branco, menos o cartao existe;
         - e #EFF2F7 tem 33% de saturacao contra os 41% do #D4DDED — quase o
           mesmo azul, so mais claro. Nao resolveria o "monte de azul".

       O eixo certo nao era CLARIDADE, era SATURACAO. #E5E8EE tem a mesma
       familia do #F9FAFB do modal (21% x 20%) e mantem o degrau do cartao em
       1,23 — perto do 1,37 de antes. Metade do azul, o cartao continua existindo.

       O AZUL-ORKUT NAO MORREU: ele continua na mobilia (barras, botoes, links,
       icones, a pastilha), que e onde ele sempre esteve no Orkut de verdade. O
       que mudou e que ele parou de ser tambem o CHAO — e cor que esta em tudo
       nao destaca nada.

       Para voltar: `--bg: #D4DDED` e `--bg-2: #CBD4E4`. */
    /* CHÃO #FAFAFA (11/09/26, ordem do dono). Era #E5E8EE. Os espelhos fora
       daqui mudaram juntos: theme-color no header.php, theme_color no
       pwa_helpers/seo_helpers e o fundo do chat retrô. --bg-2 NÃO mudou. */
    --bg:           #FAFAFA;
    /* A cor da MOBÍLIA. Vive aqui, e não solta no CSS, para o dia em que ela
       mudar de tom mudar num lugar só. */
    --orkut-bar:    #4B7BB7;
    /* A TARJA VOLTOU A SER PÁLIDA (21/08/26, e o dono estava certo).
       Eu li "#4B7BB7 = barras e cabeçalhos" e fiz uma FAIXA CHEIA saturada com
       letra branca. Olhando o Orkut de verdade, quase nada ali era bloco sólido:
       os painéis eram azul pálido sobre azul mais pálido, e o #4B7BB7 aparecia
       como TINTA e nas pilulinhas da barra. Palavras dele: *"o contraste
       existia, mas de forma mais suave"*.
       Então a tarja é `--orkut-tarja` e quem escreve nela é `--orkut-tinta` —
       um azul mais fundo, porque o #4B7BB7 sobre o pálido dá só 3,46:1 e o
       título de caixa é texto pequeno em negrito. Com #35597F são 5,77:1: fica
       suave de LONGE e legível de PERTO, que é o que o Orkut fazia. */
    /* A TINTA DO TÍTULO = A LETRA DO MENU (21/08/26, último ajuste do dono:
       *"vamos tentar colocar a mesma cor do menu no nome das caixas"*).

       Ele sublinhou os RÓTULOS do menu, não os ícones — e é a leitura que
       funciona: `--text` sobre a tarja dá **7,34:1**, o melhor número da coluna
       inteira. O azul do ÍCONE (#4B7BB7) daria 2,71:1 e estaria reprovado.
       Ganho de desenho junto: com o título na mesma tinta do menu, a barra
       lateral e a coluna da direita passam a ser a mesma família — sobra UM
       azul na página (o da mobília, nos ícones e botões) em vez de dois. */
    /* VALORES OFICIAIS (21/08/26): o dono achou um print da página real do
       Orkut e tirou as cores de lá — #D4DDED no azul claro (nosso `--bg`),
       **#BCCDE9** no azul escuro (esta tarja) e #B11E89 no rosa.
       Acabaram as estimativas: os três agora são medidos da fonte.
       A tinta fica em #35597F — sobre o #BCCDE9 ela dá 4,52:1 e passa raspando;
       o #4B7BB7 daria 2,71:1, reprovado. Se um dia a tarja escurecer mais, a
       tinta tem de escurecer junto (o #2A4763 já está medido em 5,99:1). */
    /* A TARJA DAS CAIXAS DO RAIL, muito mais pálida (21/08/26). Eram seis
       faixas azuis empilhadas na coluna da direita — metade do "monte de azul"
       que o dono viu. Agora e um degrau discreto dentro do cartao branco (1,18)
       e a tinta escura sobe para 9,7:1. O cabecalho continua existindo; ele so
       parou de gritar.
       Anterior: #BCCDE9 (o azul escuro da pagina oficial do Orkut). */
    --orkut-tarja:  #EBECEF;
    --orkut-tinta:  #33383f;
    /* O PAR DA MOBÍLIA (21/08/26). Existem porque o botão "Novo BiP" tinha
       `#3d7de5` CRAVADO no hover e um `--accent-glow` do azul ANTIGO na sombra:
       parado ele era #4B7BB7, e ao passar o mouse pulava para outro tom, mais
       vivo e de outra família — foi o "estranho" que o dono viu. Hover é o MESMO
       azul um passo mais fundo; brilho é o próprio azul, nunca o de outra
       paleta. */
    /* Ficou SEM USO em 21/08 quando os botões passaram a clarear no hover
       (`filter: brightness`) em vez de trocar de cor — igual ao "Seguir" do
       rail, que o dono aprovou. Fica porque é o par do `--orkut-bar` e o
       próximo elemento que precisar de um azul-mobília mais fundo já tem o
       valor pronto, medido em 5,56:1 com branco. */
    --orkut-bar-hover: #3F6A9F;
    --orkut-bar-glow:  rgba(75,123,183,0.28);
    /* Um degrau ABAIXO do fundo (16/08/26, dono: "essa caixa perdeu o
       contraste, pode ser uma variação um pouquinho mais forte"). Igualada ao
       fundo, a barra de pílulas sumia e a pílula branca ficava boiando. Este
       tom é o "afundado" da casa: serve à barra e aos campos, sem virar uma
       terceira cor na página.

       ACOMPANHA O FUNDO, SEMPRE. O degrau é o MESMO de sempre (-9 por canal),
       agora sobre o azul-Orkut confirmado: 212,221,237 vira 203,212,228. Deixar este tom
       para trás quando o `--bg` muda é o erro que suja as caixas afundadas —
       aconteceu em 17/08 com o cinza neutro debaixo de um fundo azulado.
       Anteriores: #E6EBEE (17/08) · #EBEBEB (16/08). */
    --bg-2:         #DCDFE5;
    --surface:      #FFFFFF;
    --surface-2:    #FFFFFF;
    --surface-3:    rgba(15,23,42,0.04);
    /* O REALCE DO MENU (21/08/26, dono: *"este efeito de sobreposição mudar
       para essa cor #BCCDE9"*).

       Era #EAEDEF, um cinza claro da época em que a barra era quase branca.
       MEDIDO, e sem enfeitar: contra o fundo #D4DDED os dois dão praticamente
       o mesmo — 1,16:1 o antigo, 1,18:1 o novo. Ou seja, a troca NÃO deixa o
       realce mais forte; ela troca a FAMÍLIA. O antigo puxava para o branco
       (cinza de outra paleta), o novo é a mesma pálida da tarja das caixas, e
       aí a barra passa a usar a cor que o resto da página já usa.
       Se um dia o realce precisar ser mais visível, o caminho é aumentar o
       DEGRAU (descer para o #ADC2E3, por exemplo), não trocar de tom.

       Escrito como `var(--orkut-tarja)` e não como o hex: é o MESMO valor, e
       assim os dois não têm como se separar quando a pálida da casa mudar. */
    /* Idem: o realce do menu tambem se separou da tarja. Com o fundo novo
       (#E5E8EE) ele fica em #D7DDE9 — um degrau que se ve sem virar mancha. */
    --nav-hover:    #EBECEF;
    /* BORDA DO ORKUT: #E5E5E5, sólida. Sai o slate translúcido — ele tinge de
       AZUL-ARDÓSIA tudo o que contorna, e era metade do ar de painel
       corporativo que o dono queria tirar. Sólida também é previsível: a
       translúcida mudava de cor conforme o que estivesse por baixo.
       Anterior: rgba(15,23,42,0.10). */
    --border:       #E5E5E5;
    --border-hover: #D2D2D2;
    --border-focus: #B4B4B4;

    --white:        #1E1C1C;
    --text:         #33383f;
    /* Ver a nota no tema escuro: sem esta linha o texto forte herdava branco. */
    --text-1:       #1E1C1C;
    --text-2:       #5f6672;
    --text-3:       #9aa0ab;

    /* A pílula "Seguir" no CLARO (11/09/26): preta com letra branca, como no
       aipim; os estados em cinza claro (#EEEDF4, o chão único do app) com
       letra escura. A versão escura mora no `:root`, acima. */
    --seguir-bg:             #111111;
    --seguir-bg-hover:       #2A2A2A;
    --seguir-fg:             #FFFFFF;
    --seguir-feito-bg:       #EEEDF4;
    --seguir-feito-bg-hover: #E2E1EA;
    --seguir-feito-fg:       #33383f;

    /* ══ UM AZUL SÓ (21/08/26, ordem do dono: *"MUDA A COR DOS LINKS PARA A
       COR DO BOTÃO, TODOS OS LINKS"*) ═══════════════════════════════════════

       Em 21/08 eu separei `--accent` (azul vivo, para texto) de `--btn-azul`
       (azul da mobília, que preenche botão) e argumentei que juntar os dois
       reprovaria na régua de leitura. O dono viu na tela e mandou juntar. Vai
       junto, e o número fica escrito aqui sem maquiagem:

           link #4B7BB7 no cartão branco ...... 4,36:1   (antes 4,70)
           link #4B7BB7 no fundo da página .... 3,19:1   (antes 3,44)

       Ou seja: o mínimo de 4,5 já não era alcançado com o azul anterior no
       fundo da página — a diferença real entre os dois é pequena, e o ganho de
       ter UMA cor azul na rede inteira é grande. Assumido de olhos abertos.

       `--btn-azul` continua existindo e continua valendo a pena: os dois têm o
       mesmo valor hoje, mas nomeiam papéis diferentes. No dia em que a mobília
       escurecer, quem lê "azul de botão" muda e quem lê "azul de link" decide
       separado — que é exatamente a escolha que este comentário registra.

       O par SOFT/GLOW acompanha o tom novo: brilho tingido do azul velho
       debaixo de uma peça do azul novo é a sobra que já apareceu três vezes
       hoje (a sombra verde sob a pílula rosa, o halo #2f6fe0 sob o botão, o
       `rgba(79,142,247)` sob a pílula do feed). */
    --accent:       #4B7BB7;
    --accent-soft:  rgba(75,123,183,0.10);
    --accent-glow:  rgba(75,123,183,0.22);
    --green:        #0f9d6e;
    --green-soft:   rgba(15,157,110,0.12);
    --red:          #dc2626;

    --shadow-sm:    0 1px 3px rgba(15,23,42,0.10);
    --shadow-md:    0 4px 16px rgba(15,23,42,0.12);
}

/* O AZUL DA MARCA NOS ÍCONES DO MENU (17/08/26, ordem do dono: "coloque todos
   estes ícones na cor #145BD7"). É o mesmo #145BD7 do logotipo, e não o
   `--accent` (#2f6fe0 no claro, #4F8EF7 no escuro), que é a cor de AÇÃO — o
   botão "Novo BiP", os links, o "Seguir". Se o menu usasse o accent, ele mudaria
   junto no dia em que a cor de ação mudasse, e o menu não é uma ação.

   PASSOU A SER O AZUL DA MOBÍLIA (21/08/26, pergunta do dono: "a cor azul dos
   ícones não deveria ser a mesma do topo das caixas?"). Deveria — e o raciocínio
   acima já apontava para lá: o menu é MOBÍLIA. Só faltava escolher QUAL azul de
   mobília, e com a paleta Orkut a tela tinha passado a ter TRÊS: #145BD7 nos
   ícones, #4B7BB7 nas tarjas e #2f6fe0 nas ações. Três é um a mais do que a
   página aguenta, e foi isso que ele viu.

   E no fim do dia ficou UM: o dono levou os botões e depois os links para o
   #4B7BB7 também. A rede tem um azul de interface só — mobília, botão e link —
   e o LOGOTIPO segue no #145BD7, o que não é incoerência: marca pode ter cor
   própria, é um elemento único e pequeno.
   Anterior: #145BD7. */
:root {
    --icone-menu: #627084;
}
/* No ESCURO o ícone do menu sobe um degrau (13/09/26): #627084 sobre grafite
   #141619 dava 3:1 e o menu inteiro parecia desligado. */
:root:not([data-theme="light"]) {
    --icone-menu: #96A2B4;
}

/* A SOMBRA VERDE DA MARCA (17/08/26, ordem do dono: "a sombra do botão em verde
   do logo"). O verde é o #00A63C do logotipo, não o `--green` da interface
   (#0f9d6e), que é o verde de ESTADO — "deu certo", "online". Misturar os dois
   faria a pastilha do feed parecer um aviso de sucesso.

   Fica fora dos blocos de tema porque a marca é uma só nos dois: o que muda de
   um para o outro é a opacidade, e 30% aguenta claro e escuro sem virar borrão
   verde num nem sumir no outro. */
:root {
    --verde-marca:  #00A63C;
    /* O ROSA DO ORKUT (21/08/26, escolha do dono para a pílula do feed).
       Ele entra como PILAR PRÓPRIO e não por cima do `--verde-marca`: o verde
       continua sendo METADE DO LOGOTIPO e o estado "Conectados", e sobrescrevê-lo
       arrastaria os dois junto sem ninguém pedir.
       A sombra vem no par: a pílula usa `box-shadow` tingido, e uma pastilha
       rosa com brilho VERDE embaixo é exatamente o tipo de sobra que passa
       despercebida em revisão e salta na tela. */
    /* O ROSA DA CASA. Para voltar em um passo — a linha do tempo inteira:

           --rosa-orkut: #EC4798;  + letra branca   (3,55:1)  ← o dono gostou
           --rosa-orkut: #EFAFD0;  + tinta escura   (5,10:1)  pastel
           --rosa-orkut: #EC1B90;  + letra branca   (4,10:1)  o primeiro

       CHEGOU AQUI POR MEDIÇÃO, não por gosto. O dono aprovou o #EC4798 de olho
       — e estava certo no tom: ele conversa com o azul da mobília sem gritar. O
       problema era só o número: 3,55:1 com letra branca, e a pílula é 14,4px
       semibold, então a régua é 4,5 (a de 3,0 vale a partir de 18,66px em
       negrito). Este é o MESMO rosa um passo mais fundo: **4,73:1**, passa, e a
       diferença de cor é quase imperceptível ao lado do aprovado.

       DESFECHO (mesmo dia): o #D42A80 foi visto na tela e o dono achou escuro
       demais; voltamos ao #EC4798, com 3,55:1 assumido de olhos abertos. E aí ele
       achou um print da página OFICIAL do Orkut e tirou o rosa de lá: **#B11E89**.

       O #B11E89 dá 6,15:1 com letra branca — melhor número de todos. E MESMO
       ASSIM ficou de fora: visto na tela, o dono achou que puxava para o roxo e
       preferiu o #EC4798. Está certo, e tem explicação: no Orkut aquele rosa era
       do LOGOTIPO e de acentos de texto, nunca preenchimento de botão. Cor
       herdada de um papel não serve automaticamente em outro.

       FICA O #EC4798, com 3,55:1 assumido de olhos abertos — rótulo de duas
       palavras em negrito. Eu seguraria a régua se fosse texto corrido; aqui
       não é, e quem olha a tela todo dia é ele. */
    --rosa-orkut:   #EC4798;
    /* A TINTA do rosa: mesma família, escura. Existe por um motivo medido, não
       estético — `#EC1B90` com texto BRANCO dava **4,10:1**, abaixo do mínimo
       de 4,5, e clarear para o pastel (pedido do dono, 21/08) só pioraria. Com
       letra branca, quanto mais harmônico o rosa, menos legível a pílula.
       Pastel + tinta da mesma família dá **5,10:1** e ainda fica mais suave:
       a cor deixa de gritar e passa a se ler. */
    --rosa-orkut-tinta: #8A1157;
    /* Sombra na cor nova e mais fraca: a de 0.30 sob um pastel virava um halo
       sujo em volta de uma peça clara. */
    --shadow-rosa:  0 2px 8px rgba(236,71,152,0.30);
    /* Sombra do VERDE da marca. Ficou sem uso quando a pastilha do feed virou
       rosa (21/08/26) e a `--shadow-rosa` tomou o lugar — mas fica: ela é o par
       do `--verde-marca`, e o próximo elemento que usar o verde da marca vai
       precisar dela. Apagar agora só obrigaria a redescobrir o valor depois. */
    --shadow-marca: 0 2px 8px rgba(0,166,60,0.30);

    /* ══ O AZUL DOS BOTÕES (21/08/26, dono: *"olha a cor deste botão, não tem
       como ver todos os botões e deixar tudo padrão?"*) ═════════════════════

       O "Deixar recado" saiu azul #2f6fe0 ao lado de um "Novo BiP" #4B7BB7. Não
       era um botão esquecido: em 21/08 eu troquei À MÃO os dois botões que o
       dono estava olhando (Novo BiP e Seguir) e deixei os outros ~20 no
       `--accent`. Conserto pontual em cor é isto — nasce certo na tela que se
       está olhando e errado em todas as outras.

       DUAS FUNÇÕES, DOIS NOMES, e é o que faltava:

         --accent    o azul VIVO — links, marcas, indicadores, foco. É TEXTO
                     sobre a página, então precisa passar na régua de leitura:
                     #2f6fe0 sobre o fundo #D4DDED dá 4,52:1. O #4B7BB7 daria
                     3,19:1 e reprovaria — por isso o azul da mobília não pode
                     simplesmente engolir o `--accent`.

         --btn-azul  o azul de MOBÍLIA que PREENCHE botão. Aqui a régua é outra
                     (branco em cima do azul, não azul em cima do fundo):
                     branco sobre #4B7BB7 dá 4,36:1.

       Ele é `var(--orkut-bar)` de propósito, e não uma cópia do valor: assim o
       botão não tem como se separar da mobília no dia em que o tom mudar. Um
       lugar, um lever — que é o que o dono pediu. */
    --btn-azul: var(--orkut-bar);

    /* ══ A PASTILHA DO CONTROLE SELECIONADO ═══════════════════════════════
       O que pinta "esta aba está aberta" nas barras da rede: feed, perfil e
       busca (os chips do filtro do feed saíram em 11/09/26, com o filtro).

       Vive num nome PRÓPRIO (21/08/26, dono: *"vamos tentar trocar este rosa
       pela cor do botão"*) justamente porque já trocou três vezes num dia —
       verde → rosa → azul. Estava cravado em quatro arquivos, e cada troca era
       uma caçada. Agora é UMA linha.

       PARA VOLTAR AO ROSA, troque as duas linhas abaixo por:
           --pastilha:        var(--rosa-orkut);   --pastilha-tinta: #FFFFFF;
           --pastilha-sombra: var(--shadow-rosa);
           --pastilha:        var(--btn-azul);     --pastilha-tinta: #FFFFFF;
           --pastilha-sombra: 0 2px 8px var(--orkut-bar-glow);

       A TINTA VAI JUNTO, SEMPRE. Voltar só a cor de fundo é como o par
       fundo/letra do "Seguir BiPTag" ficou preto: um lado mudou, o outro não.

       MEDIDO: branco sobre o azul dá **4,36:1**, contra 3,55:1 do rosa — a
       troca também melhora a leitura do rótulo aceso.
       O CUSTO, que fica anotado porque é real: azul é a cor de AÇÃO da casa
       (Novo bip, Seguir, Mensagem). Com a pastilha azul, uma aba JÁ ABERTA
       passa a ter a mesma cara de um botão que se aperta — e no feed a pílula
       "Novo" cai logo abaixo do botão "Novo bip", os dois no mesmo tom. */
    /* CRAVADA agora, e nao mais `var(--orkut-tarja)`: a tarja do rail acabou
       de ficar quase branca (21/08), e a pastilha PRECISA se ler contra o
       trilho branco — se ela seguisse a tarja, o controle inteiro sumiria.
       Duas coisas que eram a mesma cor por coincidencia, nao por regra. */
    --pastilha:        #EBECEF;
    /* A TINTA VIAJA COM A PASTILHA (21/08/26) — e agora ela precisa mesmo.
       Enquanto a pastilha foi verde, rosa e azul, o rótulo era branco fixo nos
       três casos e ninguém sentiu falta de um nome. Com o #BCCDE9, branco caía
       para **1,61:1** e o rótulo simplesmente some. Deixar a cor sem o par é
       exatamente o defeito do "Seguir BiPTag" preto: um lado do par mudou, o
       outro ficou. Aqui os dois andam juntos, sempre.
       Com o #33383f (a tinta do menu) no #EBECEF o contraste sobe. */
    --pastilha-tinta:  #33383f;
    /* Sem halo: sombra debaixo de uma peça clara vira borrão sujo. Quem faz a
       pastilha existir é o degrau contra o trilho branco. */
    --pastilha-sombra: none;
}

/* === GLOBAL === */
html {
    scroll-behavior: smooth;
}

body {
    font-family: var(--font);
    background: var(--bg);
    color: var(--text);
    line-height: 1.65;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body:has(.app-topbar) {
    --feed-rail-offset-y: calc(var(--app-topbar-height) + 6px);
}

h1, h2, h3, h4 {
    font-family: var(--font);
    color: var(--white);
    line-height: 1.2;
    font-weight: 700;
    letter-spacing: -0.02em;
}

a { text-decoration: none; color: inherit; }

/* === Shell 3 colunas (nav | feed | rail) — centralizado === */
.app-shell {
    display: grid;
    grid-template-columns: var(--nav-col-width) minmax(0, 1fr);
    gap: var(--layout-gap);
    width: min(var(--app-shell-width), 100%);
    max-width: var(--app-shell-width);
    margin: 0 auto;
    padding: 0 var(--shell-pad-x);
    align-items: start;
    min-height: 100vh;
}

/* === Navegação esquerda (estilo X / Bluesky) === */
.sidebar {
    position: sticky;
    top: 0;
    width: var(--nav-col-width);
    height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: 8px 0 24px;
    background: transparent;
    border-right: none;
    z-index: 100;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.sidebar::-webkit-scrollbar {
    display: none;
}

/* ══ A CABECEIRA DA BARRA ═══════════════════════════════════════════════
   Logotipo + a chave que encolhe o menu, na mesma linha (29/08/26). O botão
   não pode morar DENTRO do <a>: link dentro de link não existe em HTML e o
   clique viraria navegação para a home. */
.sidebar-head {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 8px;
}

.sidebar-logo {
    color: var(--white);
    text-decoration: none;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    background: transparent;
    border: none;
    border-radius: var(--radius);
    transition: background var(--duration) var(--ease);
    min-width: 0;
}

/* AS DUAS PEÇAS DA MARCA — uma por vez, nunca as duas.
   `logo-oficial` é DEITADA (2172×724): é ela que traz o "256bip" escrito, e é
   ela que fica cortada quando a coluna encolhe. O `/logo.png` da raiz é
   QUADRADO (512×512) e é o que sobrevive nos 88px da barra estreita. */
.sidebar-logo__marca {
    height: 44px;
    width: auto;
    max-width: 100%;
    display: block;
    object-fit: contain;
}

.sidebar-logo__icone {
    display: none;
    width: 44px;
    height: 44px;
    object-fit: contain;
}

/* A CHAVE. Discreta parada, acende no hover — ela é mobília, não convite. */
.sidebar-collapse {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    margin-left: auto;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--text-3);
    font-size: 1.15rem;
    cursor: pointer;
    opacity: 0.55;
    transition: background var(--duration) var(--ease),
                color var(--duration) var(--ease),
                opacity var(--duration) var(--ease);
}

.sidebar-collapse:hover,
.sidebar-collapse:focus-visible {
    /* Mesmo par do `.sidebar-link:hover` logo abaixo — a chave é vizinha dos
       itens do menu e tem que acender igual a eles. `--hover` e `--text` NÃO
       existem nesta folha; var fantasma vira herança e some. */
    background: var(--nav-hover);
    color: var(--white);
    opacity: 1;
}
.sidebar-logo:hover {
    /* Efeito over removido a pedido do design */
    transform: none;
}
.sidebar-logo__pager {
    display: block;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    color: var(--white);
    filter: drop-shadow(0 0 8px rgba(79, 142, 247, 0.4));
    transition: filter var(--duration);
}
.sidebar-logo:hover .sidebar-logo__pager {
    filter: drop-shadow(0 0 14px rgba(79, 142, 247, 0.65));
}

/* Tema claro: sem o glow azul (vira um borrão esfumaçado no fundo claro). */
[data-theme="light"] .sidebar-logo__pager,
[data-theme="light"] .sidebar-logo:hover .sidebar-logo__pager {
    filter: none;
}

.sidebar-logo__wordmark {
    font-size: 1.35rem;
    font-weight: 800;
    letter-spacing: -0.03em;
    color: var(--white);
}

/* SELO BETA (12/08/26, pedido do dono): retângulo em PRATA refinada ao lado do
   logotipo — metal escovado: gradiente claro-escuro-claro, borda que segura o
   brilho, luz interna no topo e a leve sombra que descola do fundo. */
.bip-beta-badge {
    display: inline-block;
    padding: 2px 8px 3px;
    border-radius: 6px;
    background: linear-gradient(180deg, #f8fafc 0%, #d7dce3 38%, #aeb6c2 62%, #e6eaef 100%);
    border: 1px solid #98a1ad;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.9),
        inset 0 -1px 1px rgba(70, 80, 95, 0.35),
        0 1px 3px rgba(0, 0, 0, 0.25);
    color: #3d4653;
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.75);
    line-height: 1.3;
    vertical-align: middle;
    -webkit-user-select: none;
    user-select: none;
}

.sidebar-nav {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex-grow: 0;
    width: 100%;
}

.sidebar-footer {
    margin-top: auto;
    padding-top: 8px;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.sidebar-e81-stamp {
    margin: 10px 8px 14px;
    padding: 0;
    text-align: center;
}

.sidebar-e81-stamp .e81-stamp {
    padding: 0;
    gap: 3px;
    font-size: 0.62rem;
    line-height: 1.35;
    text-align: center;
    color: var(--text-3);
}

.sidebar-e81-stamp .e81-stamp a {
    color: var(--text-2);
    font-weight: 600;
}

.sidebar-e81-stamp .e81-stamp a:hover {
    color: var(--text-1);
    text-decoration: underline;
}

/* ── O MENU ENCOLHEU (12/09/26, ordem do dono, depois de comparar lado a lado
   com o do aipim: *"então bora melhorar este menu"*) ────────────────────────

   A fonte NÃO era o problema — os dois usam Inter (conferido no navegador
   deles). Era o TAMANHO: o nosso rótulo estava em 1,2rem (19px) com ícone de
   1,72rem e linha de 52px; o deles, 14px com ícone de 18px e linha de 38px.
   Um terço maior em tudo, e por isso o nosso parecia um menu de tablet e o
   deles um menu de aplicativo.

   O que ficou: 15px de rótulo, ícone de 22px, linha de 44px e gap de 12. Não
   copiei os 14px deles porque a nossa lista é mais curta e a leitura em
   português tem palavras mais longas ("Selo de Verificação") — 15px é o piso
   confortável aqui.

   E a COR: item parado vira `--text-2`. Com tudo em preto cheio, doze linhas
   competiam entre si e nenhuma vencia; apagando as paradas, a página aberta
   (negrito, cor cheia, fundo e risquinho azul) aparece de longe. */
.sidebar-link {
    position: relative;
    color: var(--text-2);
    font-size: 0.95rem;
    font-weight: 500;
    text-decoration: none;
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    min-height: 44px;
    padding: 0 12px;
    border-radius: var(--radius);
    transition: background var(--duration) ease, color var(--duration) ease;
    border: none;
    background: transparent;
    cursor: pointer;
    font-family: inherit;
    text-align: left;
}

/* AZUL EM TODOS OS ESTADOS (17/08/26): parado, sob o cursor e na página aberta.
   O ícone deixou de carregar estado e passou a ser identidade — quem diz onde
   você está continua sendo o rótulo em negrito, o fundo da linha e o risquinho
   azul na borda esquerda, que são três sinais e sobram. */
.sidebar-link i {
    font-size: 1.32rem;
    width: 24px;
    flex-shrink: 0;
    text-align: center;
    color: var(--icone-menu);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.sidebar-link__label {
    font-size: 0.95rem;
    letter-spacing: -0.01em;
    white-space: nowrap;
}

button.sidebar-link {
    -webkit-appearance: none;
    appearance: none;
}

/* ── ITEM DESLIGADO (24/08/26) ─────────────────────────────────────────────
   Recurso em manutenção continua na barra, apagado e inerte: sumir da lista
   faria quem já usava concluir que ele acabou. A etiqueta diz o que houve — sem
   ela, o item cinza pareceria defeito. */
.sidebar-link--off {
    cursor: default;
    opacity: 0.45;
}

.sidebar-link--off:hover {
    background: transparent;
    color: var(--text);
}

.sidebar-link__tag {
    margin-left: auto;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--surface-2, rgba(120, 120, 128, 0.14));
    color: var(--text-3);
    font-size: 0.66rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    white-space: nowrap;
}

.sidebar-link:hover {
    background: var(--nav-hover);
    color: var(--white);
}

/* O ÍCONE ESCURECE JUNTO. Parado ele é o azul do menu; sobre a pálida esse
   azul mede 2,71:1 — abaixo dos 3,0 que um componente pede, e na tela vira
   azul dentro de azul. Acompanhar o rótulo é o que o menu da conta já fazia
   (`.sidebar-user-menu__item:hover i`), e é o mesmo aprendizado do "Ver todas"
   que sumia dentro da tarja: quem entra numa superfície tira a cor DELA. */
.sidebar-link:hover i {
    color: var(--white);
}

.sidebar-link.active {
    font-weight: 700;
    /* A página aberta é a ÚNICA em cor cheia — é o contraste com as apagadas
       que faz o "você está aqui" funcionar sem gritar. */
    color: var(--white);
}

.sidebar-link.active::before {
    content: '';
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 4px;
    height: 26px;
    background: var(--white);
    border-radius: 0 4px 4px 0;
}

.sidebar-link.active i {
    color: var(--icone-menu);
}


.sidebar-link--danger {
    color: var(--text-2);
}

.sidebar-link--danger:hover,
.sidebar-link--danger:hover i {
    color: var(--red);
}

/* ══ OS GRUPOS DA BARRA (12/09/26, refeitos em 27/09/26) ═════════════════════
   Desde 27/09 são Conversas (o mesmo grupo que o app abre ao segurar o chat) e
   Extras (as telas de passatempo), ordem do dono: *"nosso menu está ficando muito
   grande e muito bagunçado"*. O Suporte virou o "Fale conosco" de Conversas.

   Aqui eles DOBRAM (`<details>`): fechado, cada grupo é UMA linha, e ele já
   nasce aberto quando a página aberta mora dentro dele.

   O rótulo segue a escrita da casa, sem `text-transform`: caixa alta gritaria. */
.sidebar-grupo {
    width: 100%;
}

.sidebar-grupo > summary {
    list-style: none;
}

.sidebar-grupo > summary::-webkit-details-marker {
    display: none;
}

/* A seta é enfeite do rótulo: sem o tamanho e o azul dos ícones de destino. */
.sidebar-link i.sidebar-grupo__seta {
    width: auto;
    margin-left: auto;
    font-size: 1.1rem;
    color: var(--text-3);
    transition: transform var(--duration) ease;
}

.sidebar-grupo[open] > summary .sidebar-grupo__seta {
    transform: rotate(180deg);
}

.sidebar-grupo__itens {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 2px 0 6px 14px;
}

.sidebar-grupo__itens .sidebar-link {
    min-height: 40px;
}

/* O "FALE CONOSCO" DA GAVETA DO CELULAR (12/09/26, ordem do dono: *"um botão fale
   conosco e ao clicar abre o chat comigo @geniouk"*). Veste o desenho do "Novo
   Bip". Na barra do computador ele é um item de Conversas desde 27/09/26. */
.suporte-fale {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    min-height: 40px;
    padding: 8px 16px;
    border-radius: var(--radius);
    background: #2A2A2A;
    color: #fff;
    font-family: var(--font);
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
    transition: filter var(--duration) var(--ease);
}

.suporte-fale:hover,
.suporte-fale:focus-visible {
    color: #fff;
    filter: brightness(1.08);
}

.suporte-fale i {
    font-size: 1.2rem;
}

.rail-social__btn--email:hover,
.rail-social__btn--email:focus-visible {
    color: var(--accent);
}

.sidebar-post-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    flex-shrink: 0;
    margin: 12px 0 0;
    padding: 10px 20px;
    border: none;
    border-radius: var(--radius);
    /* O AZUL DA MOBÍLIA TAMBÉM NOS BOTÕES (21/08/26, dono: "botão novo e botão
       de seguir ainda estão na cor azul diferente").

       Só o FUNDO DOS BOTÕES muda, não o `--accent` inteiro: ele também pinta os
       LINKS (#hashtag, endereço de comunidade, o "Hoje" do aniversário), e o
       #4B7BB7 sobre o fundo #D4DDED mede 3,19:1 — reprovado para texto. Botão é
       fundo com letra branca; link é letra sobre a página. Mesmo tom, exigências
       diferentes.
       MEDIDO: branco sobre #4B7BB7 dá 4,36:1, um triz abaixo do 4,5 da régua. Se
       a letra do botão parecer fraca, o conserto é escurecer o tom em um passo
       (#43709F), não devolver o botão ao azul antigo. */
    background: #2A2A2A;
    color: #fff;
    font-family: var(--font);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    /* SEM BRILHO E SEM PULO (21/08/26, dono: *"parece mover quando sobreposto"*
       e *"se quiser o mesmo de Quem seguir está perfeito"*).
       O botão tinha um `box-shadow` largo e um `translateY(-1px)` no hover — era
       o pulo. E o hover ESCURECIA o azul, enquanto o "Seguir" do rail CLAREIA:
       mesma cor, efeito oposto, e era isso que fazia os dois parecerem azuis
       diferentes. Agora os três botões se comportam igual. */
    transition: filter var(--duration) var(--ease);
}

.sidebar-post-btn i {
    display: none;
    font-size: 1.5rem;
}

.sidebar-post-btn:hover {
    filter: brightness(1.08);
}

/* A marca no botão: "bip" minúsculo e mais forte que o resto da frase. */
.sidebar-post-btn b {
    font-weight: 800;
}


/* Chip do usuário (rodapé da nav — estilo X) */
.sidebar-user-wrap {
    position: relative;
    width: 100%;
}

.sidebar-user {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 10px 12px;
    border: none;
    border-radius: var(--radius);
    background: transparent;
    color: var(--text);
    font-family: var(--font);
    text-align: left;
    cursor: pointer;
    transition: background var(--duration) ease;
}

.sidebar-user:hover,
.sidebar-user[aria-expanded="true"] {
    background: var(--nav-hover);
}

.sidebar-user__avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--surface);
    border: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
    color: var(--text-3);
    font-size: 1.25rem;
}

.sidebar-user__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.sidebar-user__meta {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.sidebar-user__name {
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--white);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* O NOME INTEIRO NO MENU (16/10/26, ordem do dono: "fazer o nome ficar em 2 ou 3 linhas, mas sem corte"):
   quebra em linhas em vez de virar "Bip.fan - A Red…". Só no menu lateral; na barra de cima segue numa linha. */
#bip-sidebar .sidebar-user__name {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    overflow-wrap: anywhere;
    line-height: 1.25;
}

.sidebar-user__nick {
    font-size: 0.8rem;
    color: var(--text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar-user__more {
    font-size: 1.35rem;
    color: var(--text-2);
    flex-shrink: 0;
}

.sidebar-user-menu {
    position: absolute;
    left: 0;
    right: 0;
    bottom: calc(100% + 8px);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: 6px;
    z-index: 300;
    overflow: hidden;
}

.sidebar-user-menu[hidden] {
    display: none;
}

.sidebar-user-menu__item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 12px 14px;
    border: none;
    border-radius: var(--radius);
    background: transparent;
    color: var(--text);
    text-decoration: none;
    font-family: var(--font);
    font-size: 0.88rem;
    font-weight: 500;
    text-decoration: none;
    text-align: left;
    cursor: pointer;
    transition: background var(--duration) ease, color var(--duration) ease;
}

.sidebar-user-menu__item i {
    font-size: 1.15rem;
    color: var(--text-2);
}

.sidebar-user-menu__item:hover {
    background: var(--nav-hover);
    color: var(--white);
}

.sidebar-user-menu__item:hover i {
    color: var(--white);
}

.sidebar-user-menu__item--danger {
    color: var(--text-2);
}

.sidebar-user-menu__item--danger:hover {
    color: var(--red);
}

.sidebar-user-menu__item--danger:hover i {
    color: var(--red);
}

/* === MAIN CONTENT === */
.main-wrapper {
    flex: 1;
    margin-left: 0;
    width: 100%;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding-top: 0;
    padding-bottom: 0;
}

.app-topbar {
    width: 100%;
    max-width: calc(var(--feed-col-width) + var(--layout-gap) + var(--rail-col-width));
    /* Linha em TODA página (21/07/26): a comunidade usava o topbar base (só o
       sino) e ficava sem o separador que o resto do site tem. */
    padding: 14px 0 12px;
    /* A LINHA DO TOPO É MOBÍLIA (21/08/26, dono: *"a linha de cima que era
       branca eu também acho que deveria mudar para a cor do botão"*).

       Era `--border` (#E5E5E5) — cinza claríssimo, escolhido quando o fundo da
       página era quase branco. Sobre o azul-Orkut ela virou um risco esbranquiçado
       que não separava nada. Vai para `--orkut-bar` e NÃO para `--btn-azul`: é a
       mesma cor, mas aqui o papel é mobília, não botão. Nome errado hoje é a
       linha que muda junto com os botões amanhã, sem ninguém pedir. */
    border-bottom: 1px solid var(--orkut-bar);
    display: flex;
    justify-content: flex-end;
    align-items: center;
    position: sticky;
    top: 0;
    z-index: 200;
    background: var(--bg);
    min-height: 56px;
}

.app-topbar--home,
.app-topbar--feed,
.app-topbar--search {
    display: grid;
    grid-template-columns: minmax(0, var(--feed-col-width)) var(--rail-col-width);
    gap: var(--layout-gap);
    align-items: center;
    padding-bottom: 12px;
    /* O MESMO RISCO EM TODA PÁGINA (21/08/26, dono: *"a cor do risco está ok,
       mas deve ser assim para tudo e não só aqui"*).

       A linha do `.app-topbar` já era azul, mas TRÊS variantes redeclaravam
       `--border` logo abaixo — e, tendo mais especificidade, ganhavam. Home,
       feed, busca e a barra do visitante continuavam com o cinza.

       ARMADILHA CONHECIDA e vale escrever: trocar a cor na regra-base não
       adianta quando existe variante que repete a propriedade. Antes de dar a
       mudança por feita, `grep` na propriedade, não na classe. */
    border-bottom: 1px solid var(--orkut-bar);
    max-width: 100%;
    justify-content: center;
    flex-shrink: 0;
}

.app-topbar--search {
    /* Usa o border-bottom do seletor superior */
}

.app-topbar--search .search-bar-wrap--topbar {
    grid-column: 1;
    padding-inline: 0; /* Alinha perfeitamente com o feed */
    margin-bottom: 0;
    width: 100%;
}

.app-topbar--search .search-bar {
    padding: 12px 22px;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: none;
    transition: border-color var(--duration);
}

.app-topbar--search .search-bar:focus-within {
    border-color: var(--accent);
}

.app-topbar--home .app-topbar__slogan {
    grid-column: 1;
    padding-inline: 4px;
}

.app-topbar--home .notif-wrap,
.app-topbar--feed .notif-wrap,
.app-topbar--search .notif-wrap,
.app-topbar--home .app-topbar__rail-spacer {
    grid-column: 2;
    justify-self: end;
}

.app-topbar__rail-spacer {
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    pointer-events: none;
    visibility: hidden;
}

/* :not(--home):not(--feed) porque, desde o feed aberto (05/08/26), a barra do
   visitante existe em TODA página — e nas de grade (home/feed/BiP) ela precisa
   continuar em grade. Antes --guest só aparecia na busca, e o flex bastava. */
.app-topbar--guest:not(.app-topbar--home):not(.app-topbar--feed) {
    display: flex;
    justify-content: center;
    border-bottom: 1px solid var(--orkut-bar);
    padding-bottom: 14px;
}

/* Onde mora o sino de quem tem conta mora o sino de quem não tem (30/08/26): o
   MESMO desenho, sem contador. A pílula azul "Entrar" que ficava aqui saiu por
   ordem do dono — botão de texto no lugar de um ícone redondo era o que
   quebrava a barra. */
.app-topbar__guest-sino {
    grid-column: 2;
    justify-self: end;
    align-self: center;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--surface-3);
    color: var(--text-1);
    font-size: 1.3rem;
    text-decoration: none;
    transition: background var(--duration);
}

.app-topbar__guest-sino:hover { background: var(--surface-2); }
.app-topbar__guest-sino:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Onde o sino do visitante aparece, o vão do rail já foi ocupado por ele. */
.app-topbar--guest .app-topbar__guest-sino + .app-topbar__rail-spacer { display: none; }

.app-topbar--search.app-topbar--guest {
    width: 100%;
    max-width: var(--feed-col-width);
    margin: 0 auto;
    padding-inline: 0;
    border-bottom: 1px solid var(--orkut-bar);
    padding-bottom: 12px;
}

.app-topbar--search.app-topbar--guest .search-bar-wrap--topbar {
    width: 100%;
    padding-bottom: 0;
    border-bottom: none;
}

.app-topbar__slogan {
    grid-column: 1;
    margin: 0;
    font-size: clamp(1rem, 2.2vw, 1.25rem);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.3;
    color: var(--white);
    /* CENTRALIZADO na coluna do feed (a mesma dos cartões) — pedido 21/07/26. */
    text-align: center;
    justify-content: center;
    white-space: nowrap;
    display: flex;
    align-items: center;
    gap: 8px;
}

.app-topbar__page-title {
    grid-column: 1;
    margin: 0;
    font-size: 1.2rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: var(--white);
    display: flex;
    align-items: center;
    gap: 8px;
    padding-inline: 4px;
}

/* A CONTAGEM AO LADO DO TÍTULO (18/09/26) — metadado, não o nome da página:
   mesma cor do título (o topo é sempre escuro, claro ou não), só mais leve
   e menor, para "Comunidades" continuar sendo a palavra forte da linha. */
.app-topbar__page-title-meta {
    font-weight: 500;
    font-size: 0.85em;
    opacity: 0.7;
    white-space: nowrap;
}

.app-topbar__lead {
    grid-column: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    margin-right: auto;
}

.app-topbar__lead .app-topbar__page-title {
    grid-column: auto;
    min-width: 0;
    padding-inline: 0;
}

.app-topbar__back {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    color: var(--white);
    font-size: 1.5rem;
    line-height: 1;
    transition: background var(--duration), color var(--duration);
}

.app-topbar__back:hover {
    background: color-mix(in srgb, var(--white) 10%, transparent);
}

.app-topbar__back:active {
    background: color-mix(in srgb, var(--white) 16%, transparent);
}

.app-topbar__back i {
    display: block;
}

.app-topbar--guest .app-topbar__slogan {
    grid-column: unset;
}

.app-topbar__slogan-accent {
    color: var(--accent);
}

.app-topbar__spacer { flex: 1; }

.notif-wrap { position: relative; z-index: 1200; }

.notif-bell {
    position: relative;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.25rem;
    transition: border-color var(--duration), background var(--duration);
}

.notif-bell:hover {
    border-color: var(--border-hover);
    background: var(--surface-2);
}

.notif-bell__badge {
    position: absolute;
    top: -1px;
    right: 3px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--radius);
    background: var(--red);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

.notif-dropdown {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    /* 460 desde 22/08/26 (era 400, ordem do dono: *"vamos aumentar um pouco
       mais o tamanho da caixa de notificações"*). As notificações ganharam
       texto — "Fulano quer responder seu caderno de enquetes" com a prévia
       embaixo — e a 400 quase toda linha quebrava em três. O `calc` continua
       mandando na tela estreita: a caixa nunca encosta na borda. */
    width: min(460px, calc(100vw - 120px));
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    overflow: hidden;
    z-index: 1201;
    isolation: isolate;
}

.notif-dropdown__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
    font-size: 0.95rem;
}

.notif-dropdown__header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.notif-filter-btn {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-2);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    transition: border-color var(--duration), color var(--duration), background var(--duration);
}

.notif-filter-btn:hover,
.notif-filter-btn[aria-expanded="true"] {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-soft);
}

.notif-filter-btn--active {
    border-color: var(--accent);
    color: var(--accent);
}

.notif-filter-panel {
    padding: 12px 14px 10px;
    border-bottom: 1px solid var(--border);
    background: var(--surface-2);
}

.notif-filter-panel__title {
    margin: 0 0 8px;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-2);
}

.notif-filter-panel__hint {
    margin: 8px 0 0;
    font-size: 0.72rem;
    color: var(--text-3);
    line-height: 1.4;
}

.notif-filter-panel__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.notif-filter-chip {
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-2);
    border-radius: var(--radius);
    padding: 5px 10px;
    font-size: 0.72rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color var(--duration), background var(--duration), color var(--duration), opacity var(--duration);
}

.notif-filter-chip:hover {
    border-color: var(--border-hover);
}

.notif-filter-chip.is-on {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent);
}

.notif-filter-chip:not(.is-on) {
    opacity: 0.55;
}

.notif-mark-read-btn {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-2);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.05rem;
    transition: border-color var(--duration), color var(--duration), background var(--duration);
}

.notif-mark-read-btn:hover:not(:disabled) {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-soft);
}

.notif-mark-read-btn:disabled {
    opacity: 0.45;
    cursor: default;
}

.notif-dropdown__body {
    /* ALTURA EM VH, e não os 360px fixos (22/08/26): 360 mostrava quatro avisos
       numa tela de notebook e quatro numa de 27 polegadas — a caixa ignorava o
       espaço que existia. O teto de 620 existe para a lista não virar uma
       coluna do topo ao rodapé em telas muito altas. */
    max-height: min(620px, 60vh);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
    background: var(--surface);
}

.notif-dropdown__body::-webkit-scrollbar {
    width: 6px;
}

.notif-dropdown__body::-webkit-scrollbar-track {
    background: transparent;
}

.notif-dropdown__body::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: var(--radius);
}

.notif-dropdown__body::-webkit-scrollbar-thumb:hover {
    background: var(--text-3);
}

.notif-dropdown__footer {
    padding: 12px 16px;
    border-top: 1px solid var(--border);
    text-align: center;
}

.notif-footer-link {
    display: block;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    text-decoration: none;
    font-size: 0.85rem;
    font-weight: 600;
    transition: background var(--duration);
}

.notif-footer-link:hover {
    background: var(--surface-2);
}

.notif-empty {
    padding: 32px 16px;
    text-align: center;
    color: var(--text-3);
    font-size: 0.9rem;
}

.notif-item {
    display: flex;
    gap: 12px;
    padding: 12px 16px;
    text-decoration: none;
    color: inherit;
    border-bottom: 1px solid var(--border);
    /* box-shadow junto: a barrinha azul do "não lida" some suave ao clicar. */
    transition: background var(--duration), box-shadow var(--duration);
    background: var(--surface);
}

/* ESTOURO da notificação (08/08/26): clicou = bolha que incha e some; depois
   a linha recolhe (height é fixado pelo JS antes) e a lista fecha o vão. */
.notif-item--pop {
    animation: notifPop .2s ease forwards;
    pointer-events: none;
    overflow: hidden;
}

.notif-item--gone {
    transition: height .17s ease, padding .17s ease, border-color .17s ease;
    padding-top: 0;
    padding-bottom: 0;
    border-color: transparent;
}

@keyframes notifPop {
    0% { transform: scale(1); opacity: 1; }
    45% { transform: scale(1.06); opacity: .9; }
    100% { transform: scale(.82); opacity: 0; }
}

.notif-item:hover { background: var(--surface-2); }

.notif-item--unread {
    background: var(--surface-2);
    box-shadow: inset 3px 0 0 var(--accent);
}

.notif-item__icon {
    position: relative;
    width: 40px;
    height: 40px;
    margin-left: 3px;
    border-radius: 50%;
    background: var(--bg-2);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    font-size: 1.1rem;
    overflow: hidden;
    isolation: isolate;
}

.notif-item__avatar {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    border-radius: 50%;
}

.notif-item__vote-badge,
.notif-item__type-badge {
    position: absolute;
    right: -1px;
    bottom: -1px;
    min-width: 17px;
    height: 17px;
    padding: 0 3px;
    border-radius: 6px;
    background: var(--accent);
    color: #1a2030;
    font-size: 0.58rem;
    font-weight: 800;
    line-height: 13px;
    text-align: center;
    border: 2px solid var(--surface);
    box-sizing: border-box;
    pointer-events: none;
}

.notif-item__type-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.65rem;
}

.notif-item__stars-fallback {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    color: #e8c547;
    font-size: 0.62rem;
    font-weight: 800;
    line-height: 1;
}

.notif-item__stars-fallback i {
    font-size: 1.05rem;
}

.notif-item__emoji-single {
    font-size: 1.05rem;
    line-height: 1;
}

.notif-item__body { flex: 1; min-width: 0; }

.notif-item__msg {
    font-size: 0.85rem;
    color: var(--white);
    margin: 0 0 4px;
    line-height: 1.35;
}

.notif-item__preview {
    font-size: 0.78rem;
    /* --text-3 no tema escuro (#555558) some no fundo do dropdown — --text-2 lê bem nos dois temas. */
    color: var(--text-2);
    margin: 0 0 4px;
    line-height: 1.3;
}

.notif-item__time {
    font-size: 0.72rem;
    color: var(--text-3);
}

.notif-item__actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.notif-item__actions .btn { padding: 4px 10px; font-size: 0.72rem; }

/* === Toasts de notificação (canto superior direito) === */
.bip-notify-toast-stack {
    position: fixed;
    bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
    right: calc(env(safe-area-inset-right, 0px) + 16px);
    z-index: 10050;
    display: flex;
    flex-direction: column-reverse;
    gap: 12px;
    width: min(360px, calc(100vw - 32px));
    pointer-events: none;
}

/* No mobile, fica acima da barra de navegação inferior (.mobile-tabbar). */
@media (max-width: 768px) {
    .bip-notify-toast-stack {
        bottom: calc(env(safe-area-inset-bottom, 0px) + 72px);
        left: 16px;
        right: 16px;
        width: auto;
    }
}

.bip-notify-toast {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 14px 16px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 255, 255, 0.04) inset;
    color: var(--text);
    text-decoration: none;
    cursor: pointer;
    opacity: 0;
    /* Sobe ao aparecer, desce ao guardar (estilo "bandeja" do MSN). Começa 28px abaixo. */
    transform: translateY(28px) scale(0.98);
    transition: opacity 0.38s var(--ease), transform 0.5s cubic-bezier(0.22, 1.15, 0.36, 1);
}

.bip-notify-toast.is-visible {
    opacity: 1;
    transform: translateY(0) scale(1);
}

.bip-notify-toast.is-leaving {
    opacity: 0;
    /* Desce de volta, "guardando". */
    transform: translateY(28px) scale(0.98);
    transition: opacity 0.32s var(--ease), transform 0.4s cubic-bezier(0.4, 0, 1, 1);
}

.bip-notify-toast__avatar {
    width: 42px;
    height: 42px;
    border-radius: var(--radius);
    object-fit: cover;
    flex-shrink: 0;
    background: var(--surface-2);
    border: 1px solid var(--border);
}

.bip-notify-toast__avatar--fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    color: var(--accent);
}

.bip-notify-toast__body {
    flex: 1;
    min-width: 0;
}

.bip-notify-toast__title {
    font-size: 0.82rem;
    font-weight: 700;
    color: var(--white);
    margin: 0 0 2px;
    line-height: 1.3;
}

.bip-notify-toast__msg {
    font-size: 0.84rem;
    color: var(--text-2);
    margin: 0;
    line-height: 1.35;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}

.bip-notify-toast__close {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--text-3);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: -4px -6px 0 0;
    transition: background var(--duration) var(--ease), color var(--duration) var(--ease);
}

.bip-notify-toast__close:hover {
    background: var(--surface-2);
    color: var(--white);
}

.bip-notify-toast--message { border-left: 3px solid #60a5fa; }
.bip-notify-toast--follow { border-left: 3px solid #34d399; }
.bip-notify-toast--follow_request { border-left: 3px solid #fbbf24; }
.bip-notify-toast--profile_visit { border-left: 3px solid #a78bfa; }
.bip-notify-toast--profile_hi { border-left: 3px solid #fbbf24; }
.bip-notify-toast--community_invite { border-left: 3px solid #f472b6; }
.bip-notify-toast--unfollow { border-left: 3px solid #f87171; }
.bip-notify-toast--block { border-left: 3px solid #ef4444; }

/* ===== Popup nostálgico estilo MSN / Windows Live Messenger (todos os toasts) ===== */
.bip-notify-toast--msn {
    display: block;
    width: 300px;
    max-width: 92vw;
    padding: 0;
    color: #14324f;
    background: linear-gradient(180deg, #fbfdff 0%, #eaf3fb 44%, #cfe2f4 100%);
    border: 1px solid #9db8d4;
    border-radius: 9px;
    box-shadow: 0 12px 34px rgba(10, 30, 60, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.9);
    overflow: hidden;
    font-family: Tahoma, "Segoe UI", system-ui, sans-serif;
}

.bip-msn-toast__head {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 6px 8px 6px 10px;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
    border-bottom: 1px solid rgba(120, 150, 185, 0.35);
}

.bip-msn-toast__brand {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1;
    min-width: 0;
    font-size: 0.85rem;
    font-weight: 700;
    color: #2b5a86;
    text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
}

.bip-msn-toast__logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    font-size: 1.05rem;
    color: #2f6fb0;
}

.bip-msn-toast__close {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.95rem;
    color: #2b5a86;
    cursor: pointer;
    border: 1px solid #9db8d4;
    border-radius: 4px;
    background: linear-gradient(180deg, #ffffff, #dbe8f5);
}

.bip-msn-toast__close:hover {
    background: linear-gradient(180deg, #ffffff, #c4d9ee);
}

.bip-msn-toast__main {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 11px 12px 6px;
    cursor: pointer;
}

.bip-msn-toast__frame {
    flex-shrink: 0;
    width: 52px;
    height: 52px;
    padding: 3px;
    border-radius: 4px;
    background: #ffffff;
    border: 1px solid #b7cbe0;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.85), 0 1px 2px rgba(0, 0, 0, 0.14);
    display: flex;
    align-items: center;
    justify-content: center;
}

.bip-msn-toast__avatar {
    width: 100%;
    height: 100%;
    border-radius: 2px;
    object-fit: cover;
}

.bip-msn-toast__avatar--fallback {
    color: #7fa3c6;
    font-size: 1.7rem;
}

.bip-msn-toast__text {
    flex: 1;
    min-width: 0;
}

.bip-msn-toast__name {
    margin: 0 0 2px;
    font-size: 0.92rem;
    font-weight: 700;
    color: #12324f;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bip-msn-toast__status {
    margin: 0;
    font-size: 0.86rem;
    color: #2f4a63;
}

.bip-msn-toast__foot {
    display: flex;
    justify-content: flex-end;
    padding: 2px 12px 9px;
}

.bip-msn-toast__options {
    font-size: 0.8rem;
    color: #1f6fc4;
    text-decoration: none;
    cursor: pointer;
}

.bip-msn-toast__options:hover {
    text-decoration: underline;
}

/* === Quem visitou (perfil) === */
.profile-visitors {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 20px 22px;
    margin-bottom: 24px;
}

.profile-visitors__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 6px;
}

.profile-visitors__head h2 {
    font-size: 1rem;
    font-weight: 700;
    color: var(--white);
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
}

.profile-visitors__head h2 i { color: var(--accent); }

.profile-visitors__hint {
    font-size: 0.82rem;
    color: var(--text-3);
    margin: 0 0 16px;
}

.profile-visitors__empty {
    font-size: 0.88rem;
    color: var(--text-3);
    text-align: center;
    padding: 16px 0;
}

.profile-visitors__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.profile-visitors__list--inline {
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    gap: 8px;
    overflow-x: auto;
    padding-bottom: 4px;
    scrollbar-width: thin;
}

.profile-visitors__list--inline > li {
    flex: 0 0 auto;
    margin: 0;
}

.profile-visitors__mini {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    display: block;
    background: var(--bg-2);
    border: 1px solid var(--border);
}

.profile-visitors__mini--ph {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text-3);
    font-size: 1.15rem;
}

.profile-visitors__item {
    display: grid;
    grid-template-columns: 40px 1fr auto;
    align-items: center;
    gap: 12px;
    padding: 10px 8px;
    border-radius: var(--radius);
    transition: background var(--duration);
}

.profile-visitors__item:hover { background: var(--surface-2); }

.profile-visitors__avatar {
    width: 40px;
    height: 40px;
    border-radius: var(--radius);
    background: var(--bg-2);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    color: var(--text-2);
    text-decoration: none;
    flex-shrink: 0;
}

.profile-visitors__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.profile-visitors__info {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.profile-visitors__name {
    color: var(--white);
    font-weight: 600;
    font-size: 0.9rem;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.profile-visitors__name:hover { color: var(--accent); }

.profile-visitors__id {
    font-size: 0.75rem;
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
}

.profile-visitors__when {
    font-size: 0.72rem;
    color: var(--text-3);
    white-space: nowrap;
}

.main-content {
    width: 100%;
    max-width: calc(var(--feed-col-width) + var(--layout-gap) + var(--rail-col-width));
    padding: 0;
}

#feed-container {
    padding-top: 8px;
}

/* Cartões: respiro do topo é do container — o primeiro cartão não pode nascer
   colado na linha/abas de cima (pedido do dono, 21/07/26). Regra ÚNICA para
   todas as abas/listas: BiPs, Respostas e Repost idênticos. */
#BiPs-list,
#saved-BiPs-list,
#community-bips-list,
#profile-tab-content,
#activity-content {
    padding-top: 14px;
}

.container {
    width: 100%;
    max-width: none;
    padding: 0;
}

.container-narrow {
    max-width: var(--content-col-width);
    margin-left: auto;
    margin-right: auto;
}

/** Coluna principal — mesma largura do feed em todas as telas */
.content-col {
    width: 100%;
    max-width: var(--content-col-width);
    margin-inline: auto;
}

/* ══ MENU ENCOLHIDO ════════════════════════════════════════════════════
   Um só desenho, DUAS portas (29/08/26):

     1. `html[data-nav="mini"]` — a pessoa apertou a chave e a escolha ficou
        gravada no navegador;
     2. a régua de 1280px logo abaixo — a janela encolheu e não há escolha.

   As regras são as mesmas nos dois casos, por isso os seletores andam em par
   em cada bloco. Mexer num sem mexer no outro é o defeito clássico da casa:
   um lado do par muda, o outro fica. */
:root[data-nav="mini"] {
    --nav-col-width: 88px;
}

:root[data-nav="mini"] .sidebar-logo__wordmark,
:root[data-nav="mini"] .sidebar-link__label,
:root[data-nav="mini"] .sidebar-link__tag {
    display: none;
}

/* A TROCA DA MARCA: a peça deitada sai, a quadrada entra. */
:root[data-nav="mini"] .sidebar-logo__marca {
    display: none;
}

:root[data-nav="mini"] .sidebar-logo__icone {
    display: block;
}

:root[data-nav="mini"] .sidebar {
    padding: 8px 4px 24px;
    align-items: center;
}

:root[data-nav="mini"] .sidebar-head {
    flex-direction: column;
    gap: 2px;
    width: 100%;
}

:root[data-nav="mini"] .sidebar-logo {
    justify-content: center;
    padding: 12px 0;
}

:root[data-nav="mini"] .sidebar-collapse {
    margin-left: 0;
}

/* O ÍCONE DA BARRA RECOLHIDA NÃO ENCOLHEU (12/09/26). O menu aberto diminuiu
   porque lá o ícone acompanha um rótulo; aqui ele é a ÚNICA coisa na coluna, e
   um alvo de 21px numa faixa de 52 seria mais difícil de acertar do que o de
   antes — o "melhorar o menu" não pode piorar o modo em que ele é só ícone. */
:root[data-nav="mini"] .sidebar-link i {
    font-size: 1.72rem;
    width: 32px;
}

:root[data-nav="mini"] .sidebar-link {
    justify-content: center;
    width: 52px;
    padding: 0;
    margin: 0 auto;
}

:root[data-nav="mini"] .sidebar-post-btn {
    display: flex;
    width: 52px;
    height: 52px;
    margin: 12px auto;
    padding: 0;
    border-radius: 50%;
}

:root[data-nav="mini"] .sidebar-post-btn span {
    display: none;
}

:root[data-nav="mini"] .sidebar-post-btn i {
    display: block;
}

/* OS GRUPOS NA BARRA ESTREITA (12/09/26): a seta some com o rótulo, e os itens
   perdem o recuo e se alinham ao centro, só o ícone, como o resto da barra. */
:root[data-nav="mini"] .sidebar-grupo__seta {
    display: none;
}

:root[data-nav="mini"] .sidebar-grupo__itens {
    align-items: center;
    padding-left: 0;
}

:root[data-nav="mini"] .sidebar-user__meta,
:root[data-nav="mini"] .sidebar-user__more {
    display: none;
}

:root[data-nav="mini"] .sidebar-user {
    justify-content: center;
    width: 52px;
    margin: 0 auto;
    padding: 8px;
}

:root[data-nav="mini"] .sidebar-user-menu {
    left: calc(100% + 8px);
    right: auto;
    bottom: 0;
    min-width: 200px;
}

:root[data-nav="mini"] .sidebar-e81-stamp {
    display: none;
}

@media (max-width: 1280px) {
    :root {
        --nav-col-width: 88px;
        --feed-col-width: min(620px, 100%);
        --rail-col-width: 300px;
        --layout-gap: 28px;
        --feed-gutter-x: 14px;
        --shell-pad-x: 24px;
    }

    .sidebar-logo__wordmark,
    .sidebar-link__label,
    .sidebar-link__tag {
        display: none;
    }

    /* MESMA TROCA do bloco `[data-nav="mini"]` acima — aqui ela é FORÇADA:
       nesta largura a peça deitada não cabe, ela era CORTADA no meio do
       "256bip". Era este o "quebrado" que o dono via ao redimensionar. */
    .sidebar-logo__marca {
        display: none;
    }

    .sidebar-logo__icone {
        display: block;
    }

    /* A chave some: aqui não existe escolha para oferecer. A preferência da
       pessoa continua guardada e volta a valer quando a janela crescer. */
    .sidebar-collapse {
        display: none;
    }

    .sidebar {
        padding: 8px 4px 24px;
        align-items: center;
    }

    .sidebar-head {
        width: 100%;
    }

    .sidebar-logo {
        justify-content: center;
        padding: 12px 0;
    }

    .sidebar-link {
        justify-content: center;
        width: 52px;
        padding: 0;
        margin: 0 auto;
    }

    .sidebar-post-btn {
        display: flex;
        width: 52px;
        height: 52px;
        margin: 12px auto;
        padding: 0;
        border-radius: 50%;
    }

    .sidebar-post-btn span {
        display: none;
    }

    .sidebar-post-btn i {
        display: block;
    }

    /* Par do bloco `[data-nav="mini"]` dos grupos (12/09/26). */
    .sidebar-grupo__seta {
        display: none;
    }

    .sidebar-grupo__itens {
        align-items: center;
        padding-left: 0;
    }

    .sidebar-user__meta,
    .sidebar-user__more {
        display: none;
    }

    .sidebar-user {
        justify-content: center;
        width: 52px;
        margin: 0 auto;
        padding: 8px;
    }

    .sidebar-user-menu {
        left: calc(100% + 8px);
        right: auto;
        bottom: 0;
        min-width: 200px;
    }

    .sidebar-e81-stamp {
        display: none;
    }
}

@media (max-width: 1100px) {
    .app-topbar--home,
    .app-topbar--feed,
    .app-topbar--search {
        grid-template-columns: 1fr auto;
    }

    .app-topbar--home .app-topbar__slogan,
    .app-topbar--search .search-bar-wrap--topbar {
        grid-column: 1;
    }

    .app-topbar--home .notif-wrap,
    .app-topbar--feed .notif-wrap,
    .app-topbar--search .notif-wrap,
    .app-topbar--home .app-topbar__rail-spacer {
        grid-column: 2;
    }

    .feed-layout {
        grid-template-columns: minmax(0, 1fr);
        max-width: var(--feed-col-width);
        margin: 0 auto;
    }

    .feed-main {
        border-right: none;
        max-width: 100%;
    }

    .feed-rail-anchor {
        display: none;
    }

    .feed-rail {
        display: none;
    }

    .feed-rail-anchor:has(.rail-actions) {
        display: block;
        width: 0;
        min-width: 0;
        height: 0;
        overflow: visible;
    }

    .feed-rail:has(.rail-actions) {
        display: flex;
        position: fixed;
        right: 16px;
        bottom: 16px;
        top: auto;
        width: min(220px, calc(100vw - 32px));
        max-height: none;
        overflow: visible;
        padding: 0;
        gap: 8px;
        z-index: 150;
        background: transparent;
    }

    .feed-rail:has(.rail-actions) > *:not(.rail-actions) {
        display: none !important;
    }

    .feed-rail:has(.rail-actions) .rail-actions {
        position: static;
        margin-top: 0;
        padding-top: 0;
        background: transparent;
    }

    .main-content,
    .app-topbar {
        max-width: 100%;
        width: 100%;
        margin: 0;
    }
}

@media (max-width: 768px) {
    :root {
        --container-pad-x: 16px;
        --nav-col-width: 72px;
        --layout-gap: 16px;
        --feed-gutter-x: 14px;
        --shell-pad-x: 12px;
    }

    .app-shell {
        padding: 0 var(--shell-pad-x);
        gap: 12px;
    }

    .main-content {
        max-width: 100%;
    }

    .feed-main {
        border-left: none;
        border-right: none;
        padding-inline: var(--feed-gutter-x);
        min-height: auto;
    }
}

/* === Feed + sidebar direita — 2ª e 3ª colunas do shell === */
.feed-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--layout-gap);
    align-items: stretch;
    width: 100%;
    flex: 1;
}

@media (min-width: 1101px) {
    .feed-layout--with-rail,
    .feed-layout:has(> .feed-rail-anchor) {
        /* Mesma grelha do topbar: feed | rail */
        grid-template-columns: minmax(0, var(--feed-col-width)) var(--rail-col-width);
        justify-content: center;
    }

    .feed-layout--with-rail > .feed-main,
    .feed-layout:has(> .feed-rail-anchor) > .feed-main {
        grid-column: 1;
    }

    .feed-layout--with-rail > .feed-rail-anchor,
    .feed-layout:has(> .feed-rail-anchor) > .feed-rail-anchor {
        grid-column: 2;
    }
}

.feed-layout--solo {
    grid-template-columns: minmax(0, var(--feed-col-width));
    max-width: var(--feed-col-width);
}

@media (max-width: 1100px) {
    body:has(.app-topbar) .feed-main {
        min-height: calc(100dvh - var(--app-topbar-height, 72px) - 24px);
    }

    .feed-main {
        min-height: calc(100vh - 24px);
    }
}

.feed-main {
    min-width: 0;
    width: 100%;
    max-width: var(--feed-col-width);
    margin-inline: 0;
    min-height: 0;
    padding-inline: var(--feed-gutter-x);
    border-left: none;
    border-right: none;
    box-sizing: border-box;
    position: relative;
}

/* Teste radical (2026-07-24): sem linhas divisórias verticais. No feed inicial,
   o card de convite nasce na MESMA altura da busca do rail (régua única). */
.feed-main:has(> .feed-composer) {
    padding-top: var(--rail-stack-gap);
}

/* ══ QUANDO OS STATUS VÊM PRIMEIRO, A COLUNA NÃO PAGA RESPIRO (29/08/26) ═════
   A régua acima nasceu quando o convite de post era o PRIMEIRO item da coluna:
   os 16px o punham na mesma linha da busca do rail da direita. Depois a fileira
   dos status passou na frente (23/08/26) e ninguém refez a conta — os 16px
   deixaram de alinhar coisa nenhuma e viraram só empurrão para baixo, somados
   à reserva de 46px que a própria fileira já carrega para o balão da nota.

   Com o trilho na frente, o respiro de cima é o dele. O convite continua
   ganhando os 16px em toda página onde ele é o primeiro (perfil, comunidade,
   salvos). */
.feed-main:has(> .feed-topo-trilho) {
    /* 8px e não 0: a reserva do balão é medida ao milímetro para o caso de 3
       linhas, e com zero aqui esse balão nasceria a 4px do topo da tela (ou da
       barra de cima, no celular) — encostado. 8px é o fio de ar que impede o
       encosto e ainda devolve 16 dos 24px que sobravam. */
    padding-top: 8px;
}

/* Com o convite no topo, zera o respiro de topo da lista — senão o vão até o
   1º post fica MAIOR que o vão entre cards. Espaçamento uniforme (12px). */
.feed-main:has(> .feed-composer) > #feed-container { padding-top: 0; }
.feed-main:has(> .feed-composer) #BiPs-list { padding-top: 0; }

/* Coluna feed — páginas internas (agendados, etc.). O respiro do topo é o
   `--topo-respiro` de toda a casa (29/08/26): 22px no computador, 8 no celular.
   Esta era a QUINTA cópia do 22 escrita à mão. */
.feed-page-body {
    padding-top: var(--topo-respiro);
    padding-bottom: 32px;
}

.feed-surface-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 24px;
    box-sizing: border-box;
}

.feed-new-pill-host {
    position: sticky;
    top: 12px;
    z-index: 40;
    display: flex;
    justify-content: center;
    pointer-events: none;
    padding-top: 4px;
}

.feed-new-pill-host:not([hidden]) {
    margin-bottom: -44px;
}

.feed-new-pill {
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 16px 8px 12px;
    border: none;
    border-radius: var(--radius);
    background: var(--btn-azul);
    color: #fff;
    font-size: 0.82rem;
    font-weight: 700;
    cursor: pointer;
    /* Mesmo azul cravado do tema ESCURO que estava no hover — o halo parado
       tambem era dele. Agora e o brilho do proprio botao. */
    box-shadow: 0 4px 20px var(--orkut-bar-glow);
    transition: filter 0.15s var(--ease);
}

/* A sombra era `rgba(79,142,247,.55)` — o azul do tema ESCURO, cravado, aceso
   embaixo de um botao que no claro e outro tom. Sai junto com o pulo. */
.feed-new-pill:hover {
    filter: brightness(1.08);
}

.feed-new-pill__arrow {
    font-size: 1.15rem;
    line-height: 1;
}

.feed-new-pill__avatars {
    display: inline-flex;
    align-items: center;
    flex-direction: row-reverse;
}

.feed-new-pill__avatar {
    width: 24px;
    height: 24px;
    border-radius: var(--radius);
    overflow: hidden;
    border: 2px solid var(--accent);
    margin-left: -8px;
    background: rgba(0, 0, 0, 0.25);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.feed-new-pill__avatars .feed-new-pill__avatar:last-child {
    margin-left: 0;
}

.feed-new-pill__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.feed-new-pill__avatar--ph {
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.9rem;
}

.feed-new-pill__text {
    letter-spacing: 0.01em;
    text-transform: lowercase;
}

.feed-rail-anchor {
    width: var(--rail-col-width);
    min-width: var(--rail-col-width);
    align-self: start;
    /* Acima do feed: a janela do sino vaza para a esquerda, por cima da coluna. */
    position: relative;
    z-index: 80;
}

.feed-rail {
    position: sticky;
    top: var(--feed-rail-offset-y);
    align-self: start;
    display: flex;
    flex-direction: column;
    gap: var(--rail-stack-gap);
    padding-top: var(--rail-stack-gap);
    overflow: visible;
    padding-left: 8px;
    padding-right: 4px;
    box-sizing: border-box;
}

.feed-rail__scroll {
    display: flex;
    flex-direction: column;
    gap: var(--rail-stack-gap);
    min-width: 0;
}

@media (min-width: 1101px) {
    /* Shell travado no viewport — laterais fixas, só o feed rola (estilo X / inbox) */
    html:has(body.bip-layout-with-rail),
    html:has(body.bip-layout-with-rail) {
        height: 100%;
        overflow: hidden;
    }

    body.bip-layout-with-rail,
    body.bip-layout-with-rail {
        height: 100dvh;
        max-height: 100dvh;
        overflow: hidden;
    }

    body.bip-layout-with-rail .app-shell,
    body.bip-layout-with-rail .app-shell {
        height: 100dvh;
        max-height: 100dvh;
        min-height: 0;
        overflow: hidden;
        align-items: stretch;
    }

    body.bip-layout-with-rail .sidebar,
    body.bip-layout-with-rail .sidebar {
        height: 100%;
        max-height: 100dvh;
        align-self: stretch;
        position: sticky;
        top: 0;
    }

    body.bip-layout-with-rail .main-wrapper,
    body.bip-layout-with-rail .main-wrapper {
        height: 100%;
        max-height: 100dvh;
        min-height: 0;
        overflow: hidden;
    }

    body.bip-layout-with-rail .app-topbar,
    body.bip-layout-with-rail .app-topbar {
        flex-shrink: 0;
    }

    body.bip-layout-with-rail .main-content,
    body.bip-layout-with-rail .main-content {
        flex: 1 1 0;
        min-height: 0;
        overflow: visible;
        display: flex;
        flex-direction: column;
    }

    body.bip-layout-with-rail .feed-layout--with-rail,
    body.bip-layout-with-rail .feed-layout:has(> .feed-rail-anchor) {
        flex: 1 1 0;
        min-height: 0;
        height: 100%;
        overflow: hidden;
        align-items: stretch;
        grid-template-rows: minmax(0, 1fr);
        --feed-rail-offset-y: var(--rail-stack-gap);
    }

    body.bip-layout-with-rail .feed-main {
        min-height: 0;
        height: 100%;
        max-height: 100%;
        overflow-y: auto;
        overflow-x: hidden;
        /* RESPIRO NO FIM DA COLUNA (01/10/26, dono: *"vai até o final, trava e
           não tem respiro"*). Quem rola é esta coluna, não a página: sem este
           pé, o último cartão da lista encosta na borda de baixo da janela e
           os ícones sociais dele ficam rentes ao vidro. Dois respiros da casa. */
        padding-bottom: calc(var(--rail-stack-gap, 16px) * 2);
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        -ms-overflow-style: none;
        z-index: 0;
    }
    
    body.bip-layout-with-rail .feed-main::-webkit-scrollbar {
        display: none;
    }

    body.bip-layout-with-rail .feed-rail-anchor,
    body.bip-layout-with-rail .feed-rail-anchor {
        height: 0;
        min-height: 0;
        align-self: start;
        overflow: visible;
        z-index: 80;
    }

    body.bip-layout-with-rail .feed-rail,
    body.bip-layout-with-rail .feed-rail {
        position: sticky;
        top: var(--rail-stack-gap);
        width: var(--rail-col-width);
        max-height: calc(100dvh - var(--app-topbar-height, 72px) - var(--rail-stack-gap));
        overflow: visible;
        overscroll-behavior: contain;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    body.bip-layout-with-rail .feed-rail__scroll {
        flex: 1 1 auto;
        min-height: 0;
        overflow-x: clip;
        overflow-y: auto;
        overscroll-behavior: contain;
        scrollbar-width: none;
        -ms-overflow-style: none;
        display: flex;
        flex-direction: column;
        gap: var(--rail-stack-gap);
    }

    body.bip-layout-with-rail .feed-rail__scroll::-webkit-scrollbar,
    body.bip-layout-with-rail .feed-rail::-webkit-scrollbar {
        display: none;
    }

    body.bip-layout-with-rail:not(:has(.app-topbar)) .feed-rail,
    body.bip-layout-with-rail:not(:has(.app-topbar)) .feed-rail {
        max-height: calc(100dvh - var(--rail-stack-gap));
    }

    body:has(.app-topbar--feed) .feed-main.inbox-page {
        min-height: 0;
        height: 100%;
        max-height: 100%;
        display: flex;
        flex-direction: column;
        /* A régua única do topo vale aqui também (21/07/26) — e agora ela é
           `--topo-respiro` (29/08/26), não um 22 cravado. O box-sizing
           border-box mantém a conta de altura do chat intacta. */
        padding-top: var(--topo-respiro);
        overflow: hidden;
    }
}

.feed-rail__foot {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding: 4px 0 8px;
    margin-top: 0;
}

.feed-rail__foot-line {
    display: block;
    width: 100%;
    height: 1px;
    background: linear-gradient(
        90deg,
        transparent,
        var(--border) 20%,
        var(--border) 80%,
        transparent
    );
}

.e81-stamp {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    margin: 0;
    padding: 2px 4px 4px;
    font-size: 0.68rem;
    line-height: 1.4;
    color: var(--text-3);
    text-align: center;
}

.e81-stamp__line {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-wrap: nowrap;
    gap: 5px;
    max-width: 100%;
}

.e81-stamp__line--sub {
    gap: 4px;
}

.e81-stamp a {
    color: var(--text-2);
    font-weight: 600;
    text-decoration: none;
    transition: color var(--duration);
    white-space: nowrap;
}

.e81-stamp a:hover {
    color: var(--text-1);
    text-decoration: underline;
}

.e81-stamp .country-flag {
    display: inline-flex;
    flex-shrink: 0;
    margin: 0;
}

.e81-stamp .country-flag__img {
    width: 16px;
    height: auto;
    display: block;
}

.feed-rail__foot .rail-actions {
    margin-top: 0;
    position: static;
    padding: 0;
    background: none;
}

.rail-legal {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 4px 6px;
    padding: 4px 2px 2px;
    font-size: 0.72rem;
    line-height: 1.35;
    text-align: center;
}

.rail-legal a {
    color: var(--text-2);
    text-decoration: none;
    font-weight: 600;
}

.rail-legal a:hover,
.rail-legal a:focus-visible {
    color: var(--accent);
    text-decoration: underline;
}

.rail-legal span {
    color: var(--text-3);
    user-select: none;
}

/* Redes sociais — rodapé da coluna direita */
.rail-social {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 10px 4px 6px;
    margin-top: 2px;
}

.rail-social__label {
    margin: 0;
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-3);
    line-height: 1.2;
}

.rail-social__list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 10px;
}

.rail-social__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-2);
    text-decoration: none;
    transition:
        color var(--duration) ease,
        background var(--duration) ease,
        border-color var(--duration) ease,
        transform var(--duration) ease,
        box-shadow var(--duration) ease;
}

.rail-social__btn:hover,
.rail-social__btn:focus-visible {
    color: var(--white);
    background: var(--surface-2);
    border-color: var(--border-hover);
    transform: translateY(-1px);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
}

.rail-social__btn:focus-visible {
    outline: 2px solid var(--accent-glow);
    outline-offset: 2px;
}

.rail-social__btn--pending {
    opacity: 0.62;
    cursor: default;
    pointer-events: none;
}

.rail-social__icon {
    width: 18px;
    height: 18px;
    display: block;
    flex-shrink: 0;
}

.rail-social__logo {
    width: 22px;
    height: 22px;
    display: block;
    flex-shrink: 0;
    object-fit: contain;
}

.rail-social__btn--facebook:hover,
.rail-social__btn--facebook:focus-visible {
    color: #6ea3ff;
}

.rail-social__btn--instagram:hover,
.rail-social__btn--instagram:focus-visible {
    color: #f08bb0;
}

.rail-social__btn--whatsapp:hover,
.rail-social__btn--whatsapp:focus-visible {
    color: #5fd68a;
}

.rail-social__btn--youtube:hover,
.rail-social__btn--youtube:focus-visible {
    color: #ff8a8a;
}

.rail-social__accent {
    display: block;
    width: 72px;
    height: 4px;
    border-radius: 999px;
    background: linear-gradient(90deg, var(--accent), rgba(79, 142, 247, 0.28));
    opacity: 0.9;
}

/* Botões fixos — relatar (coluna direita) */
.rail-actions {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 4px 0 8px;
    margin-top: 0;
    padding-top: 8px;
}

.rail-action-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    padding: 11px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    font-family: var(--font);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--duration), border-color var(--duration), color var(--duration);
    text-align: center;
    text-decoration: none;
    box-sizing: border-box;
}

.rail-action-btn i {
    font-size: 1.1rem;
    color: var(--text-2);
    flex-shrink: 0;
}

.rail-action-btn:hover {
    background: var(--surface-2);
    border-color: var(--border-hover);
    color: var(--white);
}

.rail-action-btn:hover i {
    color: var(--white);
}

.rail-action-btn--warn:hover {
    border-color: rgba(239, 68, 68, 0.35);
    color: var(--red);
}

.rail-action-btn--warn:hover i {
    color: var(--red);
}

body:has(.feed-rail .rail-actions) .rail-actions-fallback {
    display: none !important;
}

.rail-actions-fallback {
    display: none;
    flex-direction: column;
    gap: 8px;
    position: fixed;
    right: 16px;
    bottom: 16px;
    width: min(220px, calc(100vw - 32px));
    z-index: 150;
}

body:not(:has(.feed-rail)) .rail-actions-fallback {
    display: flex;
}

.rail-card {
    /* Teste "sem caixa" (24/07/26) revertido no mesmo dia: sem o card o rail
       ficava solto/estranho. Cards de volta — brancos, como os BiPs. */
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 18px 20px;
    /* A TARJA AZUL SANGRA até a borda (margens negativas em .rail-card__title):
       sem `overflow: hidden` ela passa por cima do canto arredondado e o cartão
       ganha dois cantos quadrados no topo. */
    overflow: hidden;
    /* NÃO ENCOLHER (21/08/26) — e isto é um defeito ANTIGO que só apareceu com
       a linha de cima.

       Os cartões são filhos flex de `.feed-rail__scroll`, que é uma coluna. Com
       o `flex-shrink: 1` que o flex dá de graça, sempre que a pilha passava da
       altura da tela cada cartão ESPREMIA um pouco em vez de a coluna rolar. Com
       `overflow: visible` isso não se via: o conteúdo vazava para fora e continuava
       desenhado. Assim que o `overflow: hidden` entrou, o mesmo aperto virou
       CORTE — meia foto, meia linha, o conteúdo comido que o dono viu no print.

       Quem tem de rolar é a coluna (`.feed-rail__scroll` já é `overflow-y: auto`),
       nunca o cartão que encolhe. */
    flex-shrink: 0;
}

/* A TARJA AZUL NO TOPO DA CAIXA (21/08/26) — é ELA que carrega a memória do
   Orkut. Lá, toda caixinha ("meus amigos", "próximos aniversários", "recados")
   tinha sua barra azul no topo; era o móvel da página inteira.

   Ela SANGRA até as bordas do cartão (as margens negativas): tarja com respiro
   dos lados vira etiqueta, e etiqueta não é a lembrança de ninguém. O
   `--radius-lg` de cima acompanha o cartão, e o `overflow` dele apara o resto. */
.rail-card__title {
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--orkut-tinta);
    background: var(--orkut-tarja);
    /* O fio embaixo faz o trabalho que a cor forte fazia: separa a tarja do
       conteúdo. Um traço fino resolve o que um bloco saturado resolvia gritando. */
    border-bottom: 1px solid var(--border);
    margin: -18px -20px 12px;
    padding: 9px 20px;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
}

.rail-card__title i {
    color: var(--orkut-tinta);
    font-size: 1rem;
}

.rail-card__fire {
    flex: 0 0 auto;
    width: 17px;
    height: 17px;
}

.rail-card__hint {
    font-size: 0.7rem;
    font-weight: 400;
    color: var(--text-3);
}

.rail-card__link {
    margin-left: auto;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
}

.rail-card__link:hover {
    text-decoration: underline;
}

.rail-card__toggle {
    margin-left: auto;
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--accent);
    cursor: pointer;
}

/* REGRA DA TARJA: quem vive dentro dela tira a cor DELA, nunca da paleta de
   fora.

   O "Ver todas" é a ÚNICA exceção ao azul único de 21/08, e por medição: sobre
   a tarja #BCCDE9 o `--accent` novo dá **2,71:1** e o link some dentro do
   próprio cabeçalho — foi exatamente o que aconteceu quando a tarja era o azul
   cheio, e o dono viu na hora ("css quebrado no ver mais"). Aqui ele usa o azul
   da mesma família um passo mais fundo: **4,52:1**, e continua lendo-se como
   link porque é azul, não tinta de texto.

   Se a tarja mudar de tom, este valor muda junto. */
.rail-card__title .rail-card__link,
.rail-card__title .rail-card__toggle {
    color: #35597F;
    opacity: 1;
}

.rail-card__title .rail-card__link:hover,
.rail-card__title .rail-card__toggle:hover {
    text-decoration: underline;
}

.rail-card__toggle:hover {
    text-decoration: underline;
}

/* Colapsável: mostra 3; "Ver todas" adiciona .is-expanded e revela até 10. */
.rail-card--collapsible:not(.is-expanded) .rail-user-list > li:nth-child(n+4) {
    display: none;
}

.rail-muted {
    color: var(--text-3);
    font-size: 0.8rem;
}

.rail-tag-cloud {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 10px;
    line-height: 1.4;
}

.rail-tag-cloud--trending {
    max-height: calc(1.4em * 3 + 16px);
    overflow: hidden;
}

.rail-tag {
    color: var(--accent);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.9rem;
    transition: color var(--duration);
}

.rail-tag:hover {
    color: #6ba3ff;
    text-decoration: underline;
}

/* Tamanho ÚNICO (20/07/26): a nuvem com sm/md/lg por popularidade desalinhava as
   linhas e parecia bug de alinhamento, não hierarquia. As classes seguem vindo
   do JS (rail-tag--sm/md/lg) — aqui viram neutras de propósito. */
.rail-tag--sm, .rail-tag--md, .rail-tag--lg { font-size: 0.9rem; opacity: 1; }

.rail-user-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.rail-user {
    display: grid;
    grid-template-columns: 22px 1fr auto;
    align-items: center;
    gap: 8px;
    font-size: 0.82rem;
}

.rail-user__rank {
    color: var(--text-3);
    font-weight: 700;
    font-size: 0.75rem;
    text-align: center;
}

/* O ROSTO nos rankings do rail (28/08/26, ordem do dono): a MESMA bolinha de
   34px dos aniversários, entre o número e o nome. Classe própria porque os
   "BiPs em alta" dividem o .rail-user e não têm rosto. */
.rail-user--pic {
    grid-template-columns: 22px 34px 1fr auto;
}

.rail-user__pic {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-3, rgba(148, 163, 184, 0.2));
    color: var(--text-3);
}

.rail-user__pic img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.rail-user__name {
    color: var(--text);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-width: 0;
}

.rail-user__label {
    overflow: hidden;
    text-overflow: ellipsis;
    /* Nome completo no rail estreito: o corte é no NOME, nunca no selo nem na
       bandeira — quem some primeiro tem de ser a última letra do sobrenome. */
    min-width: 0;
    flex: 0 1 auto;
}

.rail-user__name .trust-tier,
.rail-user__name .country-flag {
    flex-shrink: 0;
}

.rail-user__name .trust-tier__icon {
    width: 14px;
    height: 14px;
}

.rail-user__flag {
    width: 14px;
    height: 10px;
    object-fit: cover;
    border-radius: 1px;
    flex-shrink: 0;
}

.rail-user__name:hover {
    color: var(--accent);
}

.rail-user__stat {
    flex-shrink: 0;
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--text-3);
    white-space: nowrap;
}

/* ══ SEGUIR DENTRO DA COLUNA (29/08/26) ════════════════════════════════════
   Ordem do dono: *"nos próximos aniversários, em bipers ativos e bipers do mês,
   vamos incluir o botão seguir se não for seguidor nosso"*.

   MENOR que o "Seguir" do cartão "Quem seguir", e de propósito: lá o botão é o
   assunto da linha (a linha existe para isso); aqui ele é uma oferta ao lado do
   nome — quem manda na linha continua sendo a pessoa, o aniversário, a posição
   no ranking. Um botão do mesmo tamanho nos dois lugares faria os três cartões
   virarem quatro listas de "Seguir".

   Só aparece para quem eu não sigo (o servidor decide, campo `relacao`), então
   ele nunca é um "deixar de seguir" disfarçado. */
/* PÍLULA PRETA, como no aipim (11/09/26, ordem do dono). Continua MENOR que a
   do cartão (a razão acima segue valendo), mas é a mesma peça: cheia, sem
   contorno, letra branca em negrito. Cores pelos tokens `--seguir-*` — no
   escuro ela vira branca sozinha. */
.rail-seguir-mini {
    flex-shrink: 0;
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 26px;
    padding: 0 12px;
    border: 0;
    border-radius: 999px;
    background: var(--seguir-bg);
    color: var(--seguir-fg);
    font-family: var(--font);
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--duration), color var(--duration), transform 0.12s ease;
}

.rail-seguir-mini:hover {
    background: var(--seguir-bg-hover);
    color: var(--seguir-fg);
}

.rail-seguir-mini:active {
    transform: scale(0.97);
}

.rail-seguir-mini:disabled {
    opacity: 0.6;
    cursor: default;
    transform: none;
}

/* Depois do toque ("Seguindo"/"Solicitado") ele deixa de ser botão e vira
   recado: pílula CINZA com letra escura (11/09/26), o mesmo "feito" do cartão
   e das listas — não há mais nada para apertar ali. */
.rail-seguir-mini--feito,
.rail-seguir-mini--feito:hover {
    background: var(--seguir-feito-bg);
    color: var(--seguir-feito-fg);
    font-weight: 600;
    cursor: default;
}

/* A linha do aniversário é um <li> com o link ocupando tudo; para o botão caber
   ao lado, o item vira a fileira e o link fica com o que sobra. */
.rail-aniversarios__lista > li {
    display: flex;
    align-items: center;
    gap: 6px;
}

.rail-aniversarios__lista > li > .rail-aniv__link {
    flex: 1 1 auto;
    min-width: 0;
}

.rail-hot-bip__link {
    flex: 1;
    min-width: 0;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--text);
    text-decoration: none;
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.rail-hot-bip__link:hover {
    color: var(--accent);
}

.rail-community__name {
    flex: 1;
    min-width: 0;
}

/* === Página de busca === */
.search-page {
    padding-top: 0;
}

/* RESPIRO ENTRE O RISCO E O PAINEL DAS ABAS (21/08/26, ordem do dono). O painel
   nascia colado na linha do topbar — e a coluna da direita, não: o rail já
   descia `--rail-stack-gap`. As duas colunas começavam em alturas diferentes,
   com a da esquerda espremida contra o risco.

   O valor é o MESMO do rail de propósito: assim o painel das abas e o primeiro
   cartão da direita nascem na mesma linha, que é a régua que o resto do site
   já segue. */
.feed-layout--search .search-panel {
    margin-top: var(--rail-stack-gap);
}

.search-shell {
    background: transparent;
    border: none;
    border-radius: 0;
    overflow: visible;
    box-shadow: none;
}

.search-bar-wrap {
    margin-bottom: 20px;
}

/* A CAIXA DE BUSCA DO RAIL MORREU (12/09/26, ordem do dono: *"vamos parar de
   enganar nossos usuários, vamos tirar essa caixa de busca e mostrar só um
   círculo como o de notificação mas com o ícone de busca"*). Com ela foram as
   regras `.search-bar-wrap--rail`, `.rail-explorar` e `.search-bar__input--porta`
   (grep: nenhum PHP as escreve; o mobile-search.js só as alternaria num
   formulário que o rail não tem mais). Os atalhos redondos do rail moram em
   `feed_sidebar.php`. */

/* ══ O CAMPO DO EXPLORAR: UMA CAIXA QUE PARECE CAIXA (29/08/26) ════════════
   Ordem do dono: *"faça o campo busca do explorar ser branco, uma caixa de
   texto visível, pois assim a pessoa não sabe onde escrever"*.

   O `.search-bar` nasceu no rail da direita, pousado sobre o fundo da página:
   lá `background: transparent` com 1px de borda bastava. Este campo é novo (ele
   era emprestado do rail até hoje) e mora DENTRO do painel — mesmo tom dos dois
   lados. O que sobra na tela é um texto cinza solto, sem nada dizendo que
   aquilo se escreve.

   Fundo próprio (`--surface` é branco no tema claro), borda mais firme e o foco
   acendendo no azul: os três sinais que o olho procura sem pensar. */
.search-bar-wrap--explorar {
    display: block;
    margin: 10px 0 6px;
}

.search-bar-wrap--explorar .search-bar {
    background: var(--surface);
    border-color: var(--border-hover);
    box-shadow: var(--shadow-sm);
    transition: border-color var(--duration), box-shadow var(--duration);
}

.search-bar-wrap--explorar .search-bar:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* O convite no tom apagado, o que se digita no tom forte — sem dizer, os dois
   saem iguais e a caixa parece já preenchida. */
.search-bar-wrap--explorar .search-bar__input::placeholder {
    color: var(--text-3);
    opacity: 1;
}

/* ══ A VITRINE DO EXPLORAR ════════════════════════════════════════════════
   Quatro blocos servidos por `api/explore.php` — o mesmo endpoint do app, o
   mesmo desenho: fotos grandes primeiro (é o que faz parar), gente depois,
   e as duas listas curtas (tags e lugares) fechando. */
.explorar {
    display: flex;
    flex-direction: column;
    gap: 26px;
    padding: 4px 0 8px;
}

.explorar__titulo {
    margin: 0 0 12px;
    font-size: 1.02rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: var(--white);
}

/* FOTOS: grade que se adapta sozinha à largura da coluna — três no computador,
   duas no celular estreito, sem media query. */
.explorar__fotos {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 6px;
}

.explorar__foto {
    display: block;
    aspect-ratio: 1;
    overflow: hidden;
    border-radius: 12px;
    background: var(--surface-2);
}

.explorar__foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.25s var(--ease);
}

.explorar__foto:hover img {
    transform: scale(1.05);
}

/* GENTE: fileira que quebra, com espaço em cima para o balão da nota — a mesma
   peça do rail de status, e por isso a mesma reserva de altura. */
.explorar__gente {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(86px, 1fr));
    /* 40px ENTRE AS FILEIRAS, e não os 10 de sempre: o balão da nota é
       `position: absolute` e sobe para fora da célula. Com o vão pequeno ele
       caía por cima do rosto da fileira de baixo — o mesmo cuidado que a
       fileira de status já tem no topo do feed, só que aqui repetido a cada
       linha da grade. */
    gap: 40px 10px;
    padding-top: 30px;
}

.explorar__pessoa {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    min-width: 0;
    color: var(--text);
    text-decoration: none;
}

/* 71px, 15% MAIOR (13/09/26, ordem do dono: "aumente em 15% o tamanho dos
   avatares"). A célula da grade continua com 86px de mínimo: o rosto cabe
   nela com folga e o celular estreito segue com três por fileira. */
.explorar__rosto {
    width: 71px;
    height: 71px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--surface-2);
    border: 1px solid var(--border);
}

.explorar__rosto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.explorar__nome {
    max-width: 100%;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A SEÇÃO VAZIA DIZ QUE ESTÁ VAZIA (13/09/26): com o filtro de lugar ou de
   selo, sumir calada parecia defeito do filtro. */
.explorar__vazio {
    margin: 0;
    color: var(--text-2);
    font-size: 0.9rem;
}

/* O balão da nota, igual ao do rail de status: 2 linhas no teto, e o corte com
   reticência em vez de uma terceira linha. */
.explorar__nota {
    position: absolute;
    bottom: calc(100% - 8px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    width: max-content;
    min-width: 0;
    max-width: 92px;
    padding: 3px 8px 0;
    border-radius: 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: 0 2px 8px rgb(0 0 0 / 14%);
    color: var(--text-1);
    font-size: 0.66rem;
    line-height: 1.55;
    text-align: center;
    overflow-wrap: anywhere;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* TAGS e LUGARES: listas curtas, em pílula — o mesmo vocabulário das BiPTags
   do rail, para não inventar um terceiro jeito de mostrar uma tag. */
.explorar__tags,
.explorar__lugares {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.explorar__tag,
.explorar__lugar {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    max-width: 100%;
    padding: 7px 14px;
    border-radius: 999px;
    background: var(--surface-3);
    border: 1px solid var(--border);
    color: var(--accent);
    font-size: 0.88rem;
    font-weight: 600;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: background var(--duration), border-color var(--duration);
}

.explorar__lugar {
    color: var(--text);
}

.explorar__lugar i {
    color: var(--text-2);
    font-size: 1.05rem;
}

.explorar__tag:hover,
.explorar__lugar:hover {
    background: var(--nav-hover);
    border-color: var(--border-hover);
}

.search-bar__clear {
    font-size: 1.2rem;
}

@media (max-width: 1100px) {
    .search-bar-wrap--mobile {
        display: block;
        width: 100%;
        margin: 0 0 14px;
        padding: 0;
    }

    .search-bar-wrap--mobile .search-bar {
        padding: 12px 16px;
        border-radius: var(--radius-lg);
        background: transparent;
        border: 1px solid var(--border);
        transition: border-color var(--duration);
    }

    .search-bar-wrap--mobile .search-bar:focus-within {
        border-color: var(--accent);
    }

    .search-bar-wrap--mobile .search-bar__input {
        font-size: 1rem;
    }

    .search-page .search-bar-wrap--mobile {
        margin: 14px 0 16px;
    }

    .feed-main > .search-bar-wrap--mobile:first-child {
        margin-top: 4px;
    }

    .feed-main > .rail-topo-row:first-child {
        margin: 4px 0 14px;
        width: 100%;
    }

    .rail-topo-row .search-bar-wrap--mobile {
        display: block;
        width: auto;
        flex: 1 1 auto;
        min-width: 0;
        margin: 0;
    }
}

.search-bar {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 14px 22px;
    background: transparent;
    border: 1px solid var(--border);
    border-radius: 24px;
}

.search-bar__icon {
    color: var(--text-2);
    font-size: 1.4rem;
    flex-shrink: 0;
}

.search-bar__input {
    flex: 1;
    min-width: 0;
    background: transparent;
    border: none;
    color: var(--white);
    font-size: 1.1rem;
    outline: none;
}

.search-bar__clear {
    flex-shrink: 0;
    padding: 0;
    border: none;
    background: none;
    color: var(--text-3);
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
}

.search-bar__clear:hover {
    color: var(--white);
}

.search-panel {
    width: 100%;
}

.search-panel--feed-style {
    background: transparent;
    border: none;
    box-shadow: none;
    overflow: visible;
}

.saved-page-head {
    margin-bottom: 0;
    padding: 24px 0 16px;
    border-bottom: 1px solid var(--border);
}

.saved-page-head p {
    margin: 0 0 16px;
    color: var(--text-2);
    font-size: 0.95rem;
}

.saved-search-wrap {
    position: relative;
    display: flex;
    align-items: center;
}

.saved-search__icon {
    position: absolute;
    left: 14px;
    color: var(--text-3);
    font-size: 1.15rem;
    pointer-events: none;
}

.saved-search__input {
    width: 100%;
    padding: 11px 16px 11px 42px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    /* Mesma regra da `.filter-pill`: campo na página tem superfície própria. */
    background: var(--surface);
    color: var(--white);
    font-size: 0.95rem;
    font-family: var(--font);
    outline: none;
    transition: border-color var(--duration), box-shadow var(--duration);
}

.saved-search__input::placeholder {
    color: var(--text-3);
}

.saved-search__input:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
}

.saved-search__input::-webkit-search-cancel-button {
    -webkit-appearance: none;
}

/* A barra de abas do Explorar (.search-tabs, .search-tabs__indicator,
   .search-tab) morava aqui desde 21/08/26 e morreu em 12/09/26, ordem do dono:
   "vamos tirar a barra de filtros e responder direto na tela tudo". O que ela
   escolhia, a caixinha "Ver" escolhe (ver o bloco no fim deste arquivo). */

.search-results-list {
    padding: 0;
    min-height: 0;
    position: relative;
}

.search-results-list--loading .search-results__body {
    pointer-events: none;
}

.search-results__body {
    transition: opacity 0.22s var(--ease);
}

.search-results__body--enter {
    opacity: 0;
}

.search-results__loader {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 16px 0;
    color: var(--text-3);
    font-size: 0.85rem;
    background: transparent;
}

.search-results__loader[hidden] {
    display: none !important;
}

.search-filters-bar[hidden] {
    display: none !important;
}

.search-row-link {
    display: flex;
    align-items: center;
    gap: 15px;
    padding: 12px 20px;
    text-decoration: none;
    color: inherit;
    transition: background var(--duration) var(--ease);
}

.search-row-link:hover {
    background: var(--surface-2);
}

.search-bip-hit {
    display: block;
    padding: 8px 20px 14px;
    text-decoration: none;
    color: inherit;
    transition: background var(--duration) var(--ease);
}

.search-bip-hit:hover {
    background: var(--surface-2);
}

.search-BiPs-feed {
    margin-top: 0;
}

.search-filters-bar {
    padding: 14px 0 16px;
    background: transparent;
    border-bottom: 1px solid var(--border);
}

/* FILTRAR (13/09/26, ordem do dono: "falta um botão filtrar"). O botão-mãe da
   casa (.btn-primary) na altura e no raio das pílulas ao lado, com a borda
   invisível que elas têm, para a fileira não serrilhar. */
.search-filtrar {
    padding: 8px 18px;
    border: 1px solid transparent;
    border-radius: var(--radius-lg);
    font-size: 0.9rem;
    /* `normal`, como a pílula (que é <button> e fica com o do navegador): o
       1.65 herdado do body deixava o botão 8px mais alto que a fileira. */
    line-height: normal;
}

/* Apagadas em 12/09/26 (grep: só viviam neste arquivo): as regras do modelo
   antigo da barra de filtros (.search-filters-bar__lead/__grid/__field/__label,
   .input-control dentro da barra, --tags, __row, __select-inline) e o
   .search-section-label. A barra de hoje é só .filter-pills-row + pills. */

.search-users-feed {
    list-style: none;
    margin: 0;
    padding: 0;
}

.search-users-feed.follows-list .follows-row {
    padding-left: 0;
    padding-right: 0;
}

.search-users-feed.follows-list .follows-row__name .country-flag__img,
.search-users-feed.follows-list .follows-row__name .trust-tier__icon {
    vertical-align: middle;
}

.search-user-row {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 18px 0;
    border-bottom: 1px solid var(--border);
}

.search-user-row:last-child {
    border-bottom: none;
}

.search-user-row__avatar {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--surface-2);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-3);
    font-size: 1.4rem;
    text-decoration: none;
}

.search-user-row__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.search-user-row__body {
    flex: 1;
    min-width: 0;
}

.search-user-row__name {
    font-weight: 700;
    color: var(--white);
    font-size: 0.95rem;
    margin: 0 0 2px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
}

.search-user-row__name a {
    color: inherit;
    text-decoration: none;
}

.search-user-row__name a:hover {
    text-decoration: underline;
}

.search-user-row__nick {
    color: var(--text-2);
    font-size: 0.85rem;
    margin: 0 0 4px;
}

.search-user-row__details {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 12px;
    margin: 0 0 4px;
    font-size: 0.82rem;
    color: var(--text-3);
}

.search-user-row__meta {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.search-user-row__meta .bx {
    font-size: 0.95rem;
    color: var(--accent);
}

.search-user-row__bio {
    color: var(--text-3);
    font-size: 0.82rem;
    line-height: 1.45;
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.search-results-divider {
    height: 1px;
    background: var(--border);
    margin: 4px 0 8px;
}

.search-BiPtags-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    padding: 16px 0 20px;
    margin-top: 0;
}

.search-BiPtag-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    text-decoration: none;
    color: inherit;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: transparent;
    transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
    min-width: 0;
}

.search-BiPtag-card:nth-child(odd) {
    padding-right: 16px;
    border-right: 1px solid var(--border);
}

.search-BiPtag-card:nth-child(even) {
    padding-left: 16px;
}

.search-BiPtag-card:hover,
.search-BiPtag-card:focus-visible {
    border-color: var(--border);
    background: var(--surface-2);
}

.search-BiPtag-card__icon {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: transparent;
    border: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--accent);
    font-size: 1.25rem;
}

.search-BiPtag-card__body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.search-BiPtag-card__name {
    font-weight: 700;
    color: var(--white);
    font-size: 0.92rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.search-BiPtag-card__count {
    font-size: 0.8rem;
    color: var(--text-3);
}

.search-BiPtag-card--with-action {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: transparent;
}

.search-BiPtag-card--with-action .search-BiPtag-card__link {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 1;
    min-width: 0;
    text-decoration: none;
    color: inherit;
}

.search-BiPtag-card--with-action .tag-follow-btn {
    flex-shrink: 0;
    /* Pílula compacta (11/09/26): a mesma régua do `.follows-btn--sm`. */
    height: 26px;
    padding: 0 12px;
    font-size: 0.78rem;
}

.search-tag-follow-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 12px 0 8px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
}

.search-tag-follow-bar__info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.search-tag-follow-bar__name {
    font-weight: 700;
    color: var(--accent);
    font-size: 1rem;
}

.search-tag-follow-bar__count {
    font-size: 0.8rem;
    color: var(--text-3);
}

.search-empty {
    text-align: center;
    padding: 56px 28px 64px;
    color: var(--text-3);
}

.search-empty__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin: 0 auto;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border);
    color: var(--text-3);
    font-size: 1.75rem;
}

.search-empty__title {
    margin: 18px 0 0;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text);
}

.search-empty__hint {
    margin: 10px auto 0;
    max-width: 480px;
    font-size: 0.88rem;
    line-height: 1.55;
    color: var(--text-3);
}

.search-hint {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 6px;
    background: rgba(79, 142, 247, 0.12);
    color: var(--accent);
    font-weight: 500;
    font-size: 0.86rem;
}

@media (max-width: 720px) {
    .search-BiPtags-grid {
        grid-template-columns: 1fr;
        padding: 12px 0 16px;
    }

    .search-BiPtag-card:nth-child(odd),
    .search-BiPtag-card:nth-child(even) {
        padding: 14px 16px;
        border-right: 1px solid var(--border);
    }

    .search-empty {
        padding: 40px 20px 48px;
    }
}

/* === BiP cards + privacidade === */
.feed-sentinel {
    height: 1px;
    width: 100%;
    pointer-events: none;
}

/* Linha das pílulas. Até 11/09/26 abrigava também o botão do filtro, fora da
   faixa que rola; o filtro morreu (ordem do dono: "Remover o campo filtro, não
   precisamos mais dele") e a linha segue só com o trilho das três abas. */
.feed-pills-row {
    display: flex;
    align-items: center;
    gap: 8px;
}
/* Escondida por enquanto (02/10/26): o `hidden` do HTML precisa vencer o display:flex de cima. */
.feed-pills-row[hidden] { display: none; }

/* `flex: 0 1 auto` de 08/08/26 (o trilho tinha a largura das abas, com o
   botão do filtro ao lado). A regra da barra simétrica, mais abaixo, sobrepõe
   com `flex: 1 1 auto`: as três abas repartem a linha inteira. */
.feed-pills-row > .feed-pills {
    flex: 0 1 auto;
    min-width: 0;
}

/* O FILTRO MORREU (11/09/26, ordem do dono: "Remover o campo filtro, não
   precisamos mais dele"). Aqui moravam o botão redondo antigo
   (.feed-filter-btn, já morto desde que o botão virou .feed-pill--filtro), o
   pontinho .feed-filter-btn__dot e a janela inteira: .feed-filter__panel,
   __label, __chips (com o corpo próprio dos chips de 17/08/26),
   __chips--tipos, __select e __foot. O HTML saiu do home.php no mesmo dia. */

/* PÍLULAS DO FEED (07/08/26): Novo · Em alta · Só likes. Rolam na horizontal
   no celular sem barra visível; são três e cabem. */
/* ABAS COM PASTILHA DESLIZANTE (08/08/26, pedido do dono): as pílulas soltas
   viraram UM controle — trilho afundado e uma pastilha que corre até a aba
   escolhida. O indicador é um único elemento posicionado por JS (as abas têm
   larguras diferentes), então o movimento é de verdade, não um fade. */
.feed-pills {
    position: relative;
    display: flex;
    gap: 2px;
    padding: 4px;
    margin: 4px 0 12px;
    /* Cantos LEVEMENTE arredondados, como as abas do perfil (08/08/26, ordem
       do dono) — a cápsula de 999px sumia com a cara de "controle" e brigava
       com o resto da página, que é toda de cantos suaves. */
    border-radius: 14px;
    background: var(--bg-2);
    border: 1px solid var(--border);
    overflow-x: auto;
    scrollbar-width: none;
}

/* TRILHO BRANCO NO CLARO (17/08/26, ordem do dono: "vamos deixar o fundo dessa
   parte em branco").

   Só no claro, e de propósito: no escuro o `--surface` é #262626, praticamente
   o mesmo cinza do trilho (#222) e da própria pastilha — igualar os três
   apagaria o controle inteiro. Lá o afundado continua sendo o que separa.

   Com o trilho branco, o que faz a pastilha existir passa a ser a BORDA e a
   SOMBRA VERDE — as duas juntas, porque branco sobre branco não tem degrau
   nenhum para se apoiar. */
[data-theme="light"] .feed-pills {
    background: var(--surface);
}

.feed-pills::-webkit-scrollbar {
    display: none;
}

/* A PASTILHA. Fica atrás dos rótulos e desliza no eixo X; a largura acompanha
   a aba (rótulos têm tamanhos diferentes). Sem transição na primeira pintura
   — só depois que ela ganha a classe `is-ready`, senão ela "voa" da esquerda
   ao carregar a página. */
.feed-pills__thumb {
    position: absolute;
    top: 4px;
    left: 0;
    /* Largura ZERO até o JS medir a aba ativa — é o que a mantém invisível na
       primeira pintura. Antes isto era `opacity: 0` revelado por uma classe, e
       bastava essa classe não entrar (aba carregada em segundo plano, onde o
       requestAnimationFrame não dispara) para a pastilha sumir de vez. Sem
       medida ela não aparece; com medida, aparece — sem depender de nada. */
    width: 0;
    height: calc(100% - 8px);
    border-radius: 10px;
    /* VERDE SÓLIDO DA MARCA (17/08/26, ordem do dono, com a referência do
       Momspace na mão: "quero que ele fique no mesmo verde do logo, #00A63C,
       verde sólido, e vá trocando a cada botão clicado como hoje no efeito").

       Ela era BRANCA e se apoiava no degrau de cor contra o trilho. Com o
       trilho branco (mudança de hoje, logo acima) esse degrau tinha acabado, e
       quem segurava a pastilha era só a borda e a sombra. Agora a cor é a
       própria pastilha, e o controle volta a se ler de longe.

       O DESLIZE NÃO MUDOU: quem move é o JS, e ele só mexe em `transform` e
       `width` — nada aqui toca nisso. */
    background: var(--pastilha);
    /* A borda existia para a pastilha não sumir no ESCURO, onde o fundo dela
       (#262626) e o do trilho (#222) eram quase o mesmo cinza. Com verde
       sólido ela não some em fundo nenhum, e um contorno escuro em volta do
       verde só sujaria a peça. Fica TRANSPARENTE, e não removida: o
       box-sizing é border-box e o JS mede a largura contando com ela. */
    border: 1px solid transparent;
    box-shadow: var(--pastilha-sombra);
    pointer-events: none;
}

/* A transição entra DEPOIS do primeiro posicionamento (senão ela "voa" da
   esquerda ao abrir a página). Se por algum motivo esta classe não entrar, a
   pastilha continua visível — só troca de aba sem deslizar. */
.feed-pills__thumb.is-ready {
    transition: transform .28s var(--ease), width .28s var(--ease);
}

.feed-pill {
    position: relative;
    z-index: 1;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 9px 14px;
    border-radius: 10px;
    border: none;
    background: transparent;
    color: var(--text-2);
    font-family: var(--font);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: color .18s ease;
}

/* O ícone acompanha a cor do rótulo (currentColor) — acende junto quando a
   aba fica ativa, sem regra extra. */
.feed-pill__icon {
    width: 17px;
    height: 17px;
    flex-shrink: 0;
}

.feed-pill:hover {
    color: var(--text);
}

/* Rótulo e ícone em BRANCO sobre o verde (17/08/26) — o ícone acompanha por
   currentColor. Era `--white`, que é #1E1C1C no tema claro: texto quase preto
   dentro de uma pastilha verde sólida. E fixo, não por tema: a pastilha é
   verde nos dois, então o que vai em cima dela não tem por que mudar. */
/* A PÍLULA ATIVA ESCREVE NA TINTA DO ROSA, não em branco (21/08/26).
   Não é preferência: com o rosa pastel que o dono pediu, letra branca cai para
   ~1,8:1 — some. A tinta escura da mesma família dá 5,10:1 e ainda é ELA que
   diz "esta está escolhida": num pastel, quem carrega o estado é o texto, não
   mais o fundo gritando. */
.feed-pill.is-active {
    color: var(--pastilha-tinta);
}

.feed-pill:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
    border-radius: 999px;
}

/* Quem pediu menos movimento vê a troca sem o deslize. */
@media (prefers-reduced-motion: reduce) {
    .feed-pills__thumb.is-ready {
        transition: none;
    }
}

/* DIVISOR DE DIA do feed cronológico (07/08/26) — o padrão de agenda: número
   grande, mês discreto ao lado. Fica FORA do cartão, à esquerda, para o olho
   entender que ele separa blocos em vez de pertencer ao post seguinte. */
.feed-day {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 22px 4px 10px;
}

.feed-day__num {
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1;
    color: var(--white);
    font-variant-numeric: tabular-nums;
}

.feed-day__label {
    font-size: 0.95rem;
    color: var(--text-3);
}

/* Primeiro divisor da lista não empurra o feed para baixo. */
.feed-day:first-child {
    padding-top: 6px;
}

.feed-status {
    text-align: center;
    padding: 28px 16px;
    color: var(--text-3);
    font-size: 0.9rem;
}

.feed-status--end {
    padding: 36px 16px 48px;
    font-size: 0.85rem;
}

.feed-status--error {
    color: var(--red);
}

.feed-status--empty {
    padding: 48px 24px 56px;
    max-width: 420px;
    margin: 0 auto;
}

.feed-empty__title {
    margin: 0 0 10px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-2);
}

.feed-empty__hint {
    margin: 0 0 20px;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--text-3);
}

.feed-empty__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
}

.feed-status .bx-spin {
    font-size: 1.4rem;
    vertical-align: middle;
    margin-right: 6px;
}

/* CARTÃO estilo app (21/07/26): cada post é um cartão arredondado com fundo —
   fim das linhas divisórias. Avatar no header (nome ao lado), texto em largura
   total, rodapé estrelas à esquerda + comentar à direita. */
/* ── Convite de post no topo do feed (estilo Facebook/Quora) — linha única:
      avatar · caixa de texto · foto · enquete. MESMA largura e respiro do
      card de post (margens espelhadas de 60px no desktop — ver media query). ── */
.feed-composer {
    display: flex;
    align-items: center;
    gap: 10px;
    /* width explícito: <button> encolhe para o conteúdo (fit-content) — sem
       isto o convite termina onde o texto acaba e fica mais curto que o card. */
    width: 100%;
    margin: 0 0 12px;
    padding: 12px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    transition: border-color var(--duration);
}

.feed-composer:hover { border-color: var(--border-hover); }
.feed-composer:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.feed-composer__avatar {
    flex: none;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-2);
    color: var(--text-2);
    font-size: 1.35rem;
}

.feed-composer__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Caixa de texto: cor CONSTANTE (não muda no hover) — parece um campo real. */
.feed-composer__pill {
    flex: 1;
    min-width: 0;
    padding: 11px 18px;
    border-radius: 999px;
    background: var(--bg-2);
    color: var(--text-2);
    font-size: 1rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

[data-theme="light"] .feed-composer__pill {
    background: #EBECEF;
}

/* Convite de post do VISITANTE (05/08/26): mesma caixa, mesmo lugar, mesma
   altura do compositor de quem tem conta. Some seria esconder o que a pessoa
   ganha entrando — o que ela vê é exatamente a caixa que vai passar a usar.

   O BOTÃO AZUL "ENTRAR" SAIU EM 30/08/26 (ordem do dono, com o iPhone na mão:
   *"está aparecendo o botão entrar em tudo, não acho isso inteligente, além de
   quebrar o layout"*). Ele era `flex: none` com 18px de cada lado e comia a
   largura da pílula — daí o "O que você está pens..." cortado no meio. O que
   ficou é o desenho de quem tem conta, com os dois ícones; o muro entra no
   toque. A classe `.feed-composer__guest-cta` morreu junto. */
.feed-composer--guest .feed-composer__pill { pointer-events: none; }

/* Ícones vivos, sem fundo (estilo Facebook). */
.feed-composer__quick {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 6px;
    font-size: 1.55rem;
    line-height: 1;
}

.feed-composer__quick--photo { color: #22c55e; }
.feed-composer__quick--poll { color: var(--accent); }

@media (max-width: 420px) {
    .feed-composer { gap: 8px; padding: 10px 12px; }
    .feed-composer__pill { padding: 10px 14px; font-size: 0.95rem; }
    .feed-composer__quick { font-size: 1.4rem; padding: 4px; }
}

.bip-card {
    --bip-card-side-padding: 22px;
    display: flex;
    flex-direction: column;
    /* Padding horizontal 16 → 22 (24/07/26): com o card mais largo (margem menor),
       o respiro interno maior segura o texto/imagem — a foto cresce só um pouco. */
    padding: 14px var(--bip-card-side-padding) 12px;
    margin-bottom: 12px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    content-visibility: auto;
    contain-intrinsic-size: auto 240px;
}

/* Margens laterais espelhadas (o "espaço do avatar" dos dois lados): o cartão
   centraliza na coluna com 60px de respiro em cada borda — só no desktop, no
   celular a largura é curta. Vale para todas as listas de post do site. */
/* 768.01 e não 769: o mobile.css corta em max-width:768 — com 769 sobrava uma
   janela fracionária (zoom/DPR) sem margem nenhuma. */
/* Margens espelhadas REMOVIDAS (24/07/26, inversão): o card preenche a coluna
   — o respiro lateral agora é o gutter padrão da coluna (--feed-gutter-x: 14px),
   a MESMA régua do Painel/Comunidades. A coluna é que encolheu (620px), então a
   foto segue nos 548px originais e as laterais vieram pra dentro. */

/* content-visibility:auto implica contain:paint — o card CORTA na própria borda
   qualquer flutuante interno. O painel de emoji do composer de resposta abre
   ABAIXO do rodapé do card e aparecia só uma tira de emojis pela metade
   (bug 20/07, thread). Com painel OU menu aberto, desliga a contenção e SOBE o
   card no empilhamento (z-60) — regra única para os dois casos: antes o painel
   de emoji ficava sem o z-index e um ⋯ aberto em outro card pintava por cima. */
.bip-card:has(.bip-emoji-panel:not([hidden])),
.bip-card:has(.bip-popover:not([hidden])) {
    content-visibility: visible;
    contain: none;
    position: relative;
    z-index: 60;
}

/* O MENU DO CABEÇALHO DA COMUNIDADE POR CIMA (23/08/26, dono: *"modal
   aparecendo por trás — arrumar para frente"*). A mesma doença do @menção
   atrás do card: o popover mora num cartão que os irmãos de BAIXO (abas,
   compositor) pintam por cima; z-index no popover sozinho não resolve quando
   o ancestral não sobe junto. Menu aberto → o cabeçalho inteiro sobe. */
.comm-header-share-wrap,
.comm-header-menu-wrap {
    position: relative;
}

.comm-community-header:has(.bip-popover:not([hidden])) {
    position: relative;
    z-index: 80;
}

/* Cartões do feed: brancos e limpos nos dois temas (o wash arco-íris do tema
   claro foi removido em 2026-07-24 — cada .bip-card usa var(--surface)). */

/* UM POUCO MAIOR (10/09/26, ordem do dono: *"avatar ligeiramente maior, não
   muito, só um pouco"*) — 45 → 52, que é o tamanho em que o rosto ganha peso
   sem empurrar a linha do nome para baixo. */
.bip-card__avatar {
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: var(--bg-2);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
    flex-shrink: 0;
    overflow: hidden;
    color: var(--text-3);
}

/* ── O ANEL DO PERFIL — AS MOLDURAS (05/09/26, 2ª rodada do dono: *"ativei o
   anel e não apareceu no feed nem nos stories"*). As classes MORAVAM no
   profile.css, que só carrega no perfil — aqui elas vestem TAMBÉM o avatar
   do card e a bolha do rail. Gêmeas do BipMolduras.kt do app.

   O seletor DUPLO não é enfeite: o status.css (que carrega DEPOIS deste
   arquivo, no corpo da home) pinta `.status-bolha__anel` com `var(--border)`
   e ganharia o empate de especificidade — a segunda forma (0,2,0) devolve a
   vitória à moldura sem !important. */
/* `flex`, E NÃO `inline-flex` (13/09/26, print do dono: "a bandeira no Suemar
   ficou muito para baixo, a bandeira para a Juliana ficou perfeita"). Desde que
   a bandeira pediu o `.bip-card__avatar-box` (um bloco comum), a moldura
   inline passou a sentar numa LINHA DE TEXTO: o respiro de 26,4px da linha
   deixava 5px vazios embaixo do anel (caixa de 56x61, medido no ar) e a
   bandeira, presa ao pé da caixa, descia junto. Sem anel a foto já é flex e a
   caixa tem a altura exata; só quem tem moldura sofria. */
.bip-card__moldura {
    display: flex;
    flex: 0 0 auto;
    border-radius: 50%;
    padding: 2px;
}

/* Nos rostos pequenos (menu da conta, barra de baixo, dock, compositor) o
   anel nasce do MESMO truque do perfil: o conic pinta o span e a foto recua
   2px. */
.sidebar-user__avatar[class*="perfil-moldura--"] img,
.mobile-tabbar__avatar[class*="perfil-moldura--"] img,
.dock__avatar[class*="perfil-moldura--"] img,
.compose-identity__avatar[class*="perfil-moldura--"] img {
    padding: 2px;
    box-sizing: border-box;
    border-radius: 50%;
}

/* ── A REGRA QUE CRIA O ANEL (23/09/26, print de uma usuária: escolheu
   "Carnaval" e não viu anel nenhum).

   O anel não é um elemento: é o fundo cônico do PRÓPRIO div aparecendo pela
   borda, porque a `img` de dentro recua 3px. Sem este recuo, a imagem cobre o
   fundo inteiro e o anel simplesmente não existe.

   ELA MOROU NO profile.css ATÉ HOJE, e o `profile.css` é carregado SÓ pelo
   perfil. Em 05/09 as cores (`.perfil-moldura--*`) foram movidas para cá
   justamente porque o anel passou a vestir o avatar do feed, do rail, da gaveta
   e da barra do celular — mas a regra do padding ficou para trás. Resultado: em
   toda tela que não fosse o perfil, o div recebia a cor e a imagem tapava tudo.
   Mudança pela metade é defeito com data marcada. */
.perfil-moldura img {
    padding: 3px;
    box-sizing: border-box;
}

.perfil-moldura--ouro, .status-bolha__anel.perfil-moldura--ouro { background: conic-gradient(#ffd54f, #ff8f00, #ffd54f); }
.perfil-moldura--eletrica, .status-bolha__anel.perfil-moldura--eletrica { background: conic-gradient(#8b5cf6, #c084fc, #8b5cf6); }
.perfil-moldura--brasa, .status-bolha__anel.perfil-moldura--brasa { background: conic-gradient(#ff5722, #ffc107, #ff5722); }
.perfil-moldura--mare, .status-bolha__anel.perfil-moldura--mare { background: conic-gradient(#00bcd4, #4dd0e1, #0288d1, #00bcd4); }
.perfil-moldura--jade, .status-bolha__anel.perfil-moldura--jade { background: conic-gradient(#10b981, #6ee7b7, #10b981); }
.perfil-moldura--entardecer, .status-bolha__anel.perfil-moldura--entardecer { background: conic-gradient(#ff9800, #ff4081, #7c4dff, #ff9800); }
.perfil-moldura--nebulosa, .status-bolha__anel.perfil-moldura--nebulosa { background: conic-gradient(#3f51b5, #e040fb, #7c4dff, #3f51b5); }
.perfil-moldura--cristal, .status-bolha__anel.perfil-moldura--cristal { background: conic-gradient(#e3f2fd, #90caf9, #e3f2fd); }
.perfil-moldura--zebra, .status-bolha__anel.perfil-moldura--zebra { background: repeating-conic-gradient(#111 0 15deg, #fff 15deg 30deg); }
.perfil-moldura--limao, .status-bolha__anel.perfil-moldura--limao { background: repeating-conic-gradient(#2e7d32 0 15deg, #b9f6ca 15deg 30deg); }
/* 12 setores ciclando as 3 cores (05/09/26, dono: *"aparece quebrado"* — em
   3 fatias de ⅓ a branca sumia no fundo branco e o anel lia como um arco
   incompleto; ciclado, toda fatia branca tem vizinho escuro dos dois lados). */
.perfil-moldura--tricolor, .status-bolha__anel.perfil-moldura--tricolor { background: repeating-conic-gradient(#d32f2f 0 30deg, #111 30deg 60deg, #fff 60deg 90deg); }
.perfil-moldura--orgulho, .status-bolha__anel.perfil-moldura--orgulho { background: conic-gradient(#e40303 0 16.6%, #ff8c00 16.6% 33.3%, #ffed00 33.3% 50%, #008026 50% 66.6%, #004dff 66.6% 83.3%, #750787 83.3% 100%); }
/* As três da 2ª leva (05/09/26, dono: *"um bem rosa, outro bem colorido e um
   entre preto, cinza e branco mesclado"*). */
.perfil-moldura--chiclete, .status-bolha__anel.perfil-moldura--chiclete { background: conic-gradient(#ff80ab, #f50057, #ffc1e3, #ff80ab); }
.perfil-moldura--carnaval, .status-bolha__anel.perfil-moldura--carnaval { background: conic-gradient(#ff1744, #ffc400, #00e676, #00b0ff, #d500f9, #ff1744); }
.perfil-moldura--grafite, .status-bolha__anel.perfil-moldura--grafite { background: conic-gradient(#111, #9e9e9e, #f5f5f5, #616161, #111); }

/* ── O ESTILO DO NOME — DEGRADÊ QUE NÃO PARA (22/09/26, segunda ordem do
   dono: *"veja que o efeito do nome que eu pedi a IA errou também, ela fez um
   degradê estático e a intenção é fazer este efeito animado, para essas cores
   ficarem em degradê animado, sem parar"*). Irmã da moldura acima: UMA classe
   base (o truque de recortar o degradê no formato do texto + a animação) e DEZ
   classes de cor, cada uma só trocando a imagem de fundo. Gêmeas do
   BipEstilosDeNome.kt do app.

   COMO O CICLO FECHA SEM SALTO: cada degradê traz a sequência de cores DUAS
   vezes e repete a primeira no fim (A,B,C,A,B,C,A). Com "background-size:200%"
   a imagem tem o dobro da largura do nome, então andar de ponta a ponta
   ("background-position" de 0% a 100%) percorre exatamente UM ciclo de cores —
   e o quadro final é idêntico ao primeiro. Sem isso, a animação daria um
   tranco de cor a cada volta.

   "display:inline-block" é o que faz "background-clip:text" medir a ÁREA DO
   NOME, e não a linha inteira — sem ele o degradê se estica pela largura do
   card e o nome sai quase sólido de uma cor só. "-webkit-text-fill-color"
   é o prefixo que os navegadores ainda pedem para o recorte valer. */
.nome-estilo {
    display: inline-block;
    font-weight: 800;
    /* UM POUCO MAIOR QUE O NOME DE SEMPRE (22/09/26, ordem do dono: *"o nome no
       estilo colorido pode ser levemente maior, temos espaço para isso e sem
       quebrar, e será outro diferencial para as pessoas"*). Em `em` e não em
       `rem`: o nome aparece em lugares de tamanhos diferentes (cartão do feed,
       perfil, preview das Configurações) e o degrau tem de ser PROPORCIONAL em
       todos, nunca um tamanho fixo que atropela o menor deles.

       O `line-height: 1.05` é o que impede a linha de crescer junto: a caixa
       desta peça fica em 1,05 da própria letra, bem abaixo da entrelinha do
       texto em volta, então o nome fica maior sem empurrar nada. */
    font-size: 1.12em;
    line-height: 1.05;
    background-size: 200% 100%;
    background-position: 0% 50%;
    background-clip: text;
    -webkit-background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
    animation: nome-estilo-anda 6s linear infinite;
}

@keyframes nome-estilo-anda {
    from { background-position: 0% 50%; }
    to { background-position: 100% 50%; }
}

/* Quem pediu menos movimento no sistema fica com o degradê parado — continua
   bonito, só não anda. */
@media (prefers-reduced-motion: reduce) {
    .nome-estilo { animation: none; }
}

.nome-estilo--brasa { background-image: linear-gradient(90deg, #e8302a, #ff7a18, #ffc400, #e8302a, #ff7a18, #ffc400, #e8302a); }
.nome-estilo--ambar { background-image: linear-gradient(90deg, #ffc93d, #ff8a00, #c1440e, #ffc93d, #ff8a00, #c1440e, #ffc93d); }
.nome-estilo--aurora { background-image: linear-gradient(90deg, #ff2e9f, #a855f7, #2979f6, #ff2e9f, #a855f7, #2979f6, #ff2e9f); }
.nome-estilo--oceano { background-image: linear-gradient(90deg, #00c2d1, #0057d8, #00c2d1, #0057d8, #00c2d1); }
.nome-estilo--esmeralda { background-image: linear-gradient(90deg, #11998e, #38ef7d, #11998e, #38ef7d, #11998e); }
.nome-estilo--framboesa { background-image: linear-gradient(90deg, #e0116f, #ff6fa8, #e0116f, #ff6fa8, #e0116f); }
.nome-estilo--ametista { background-image: linear-gradient(90deg, #7b2ff7, #4527a0, #7b2ff7, #4527a0, #7b2ff7); }
.nome-estilo--safira { background-image: linear-gradient(90deg, #0b5fff, #00d4ff, #0b5fff, #00d4ff, #0b5fff); }
.nome-estilo--meianoite { background-image: linear-gradient(90deg, #1e3c72, #00c9ff, #1e3c72, #00c9ff, #1e3c72); }
.nome-estilo--confete { background-image: linear-gradient(90deg, #ff1744, #ffc400, #2979f6, #ff1744, #ffc400, #2979f6, #ff1744); }
.nome-estilo--vulcao { background-image: linear-gradient(90deg, #4a00e0, #e91e63, #ff6d00, #4a00e0, #e91e63, #ff6d00, #4a00e0); }

.bip-card__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* No cartão em coluna o body é largura total; position:relative fica pelos
   popovers/slots que ancoram dentro dele. */
.bip-card__body { min-width: 0; position: relative; }

/* Header do cartão: avatar | nome+meta | ⋯ — o avatar mora AQUI agora. */
.bip-card__header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 10px;
}

.bip-card__header-end {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    margin-left: auto;
    padding-top: 1px;
}

/* ══ O CABEÇALHO É UM TEXTO SÓ, E ELE ENVOLVE (29/08/26) ═══════════════════
   Ordem do dono: *"o desenho será escrever o nome da pessoa + selo + sentimento
   + tempo, tudo em sequência; não coube na primeira linha continua na segunda e
   nada mais será quebrado"*.

   ANTES ERAM DUAS CAIXAS BRIGANDO. A linha 1 (nome + selo + sentimento) era
   `flex-wrap: nowrap` com `overflow: hidden`: quem não coubesse era CORTADO —
   e o primeiro a apanhar era sempre o nome, que virava "Da…". A linha 2 levava
   a hora sozinha, num andar só dela. Duas réguas de largura, duas decisões
   independentes, e o resultado na tela era nome picado com espaço sobrando
   embaixo.

   AGORA É UMA COISA SÓ. As duas linhas viram `display: contents` — elas somem
   como caixas e seus filhos passam a ser peças DESTE flex, que envolve. Nome,
   selo, "está 😊 se sentindo animado", cidade e hora ficam em sequência e
   quebram onde a largura mandar. Não há mais o que cortar, porque não há mais
   uma primeira linha com tamanho fixo para estourar.

   Continua sendo o contêiner do post: quem tem itens soltos usa
   `.bip-inline-reply__header` ou `.bip-card__header-line1` (foi a coluna deste
   aqui que quebrou o comentário do feed em 2026-07-16). */
.bip-card__header {
    /* BLOCO DE TEXTO, E NÃO UM FLEX (29/08/26 — segunda tentativa, e a lição
       fica escrita). Com `flex-wrap: wrap` nada era cortado, mas cada peça
       continuava sendo uma CAIXA: o "está 😊 se sentindo animado" não cabia
       inteiro ao lado do nome e descia INTEIRO para a linha de baixo, deixando
       um vão à direita do nome. Não é isso que o dono pediu — ele pediu texto
       corrido, que continua na linha seguinte NA PALAVRA em que acabou a
       largura.

       Quem faz isso é o fluxo de texto de sempre, não o flex. Como bloco, os
       filhos viram trechos inline e quebram entre PALAVRAS. O respiro entre as
       peças passa a ser o espaço que já existe no HTML entre uma tag e outra —
       por isso não há `gap` aqui. */
    display: block;
    line-height: 1.4;
    flex: 1;
    min-width: 0;
}

/* AS DUAS LINHAS VOLTARAM A SER CAIXAS (06/09/26, ordem do dono: *"nome + selo
   + bandeira de gênero + horário; na linha debaixo o sentimento"*).

   Entre 29/08 e 06/09 elas eram `display: contents` e tudo corria como uma
   frase só, para o "está 😊 se sentindo animado" nunca ser cortado. Isso
   resolveu o corte, mas juntou coisas de naturezas diferentes na mesma
   corrente: quem é a pessoa (nome, selo, bandeira, quando postou) e como ela
   está (o sentimento).

   Agora são dois andares. O sentimento tem a linha inteira para si, então ele
   continua sem ser cortado — que era o motivo do `contents` — e o de cima fica
   com a identidade. A cidade e a hashtag saíram das duas e foram para o
   rodapé. */
.bip-card__header > .bip-card__header-line1,
.bip-card__header > .bip-card__header-line2 {
    display: block;
}

/* O SENTIMENTO SUBIU e o segundo andar virou do metadado (10/09/26). A regra
   fica porque ela também vale no primeiro andar: onde quer que a frase esteja,
   ela é TEXTO — quebra por palavra e nunca é cortada, que foi a lição de 29/08. */
.bip-card__header > .bip-card__header-line1 > .bip-card__status,
.bip-card__header > .bip-card__header-line2 > .bip-card__status {
    display: inline;
    white-space: normal;
}

/* A hora, sozinha embaixo, é um sussurro: sem linha de altura cheia. */
.bip-card__header > .bip-card__header-line2 {
    line-height: 1.25;
}

/* O AVATAR ENCOSTA EM CIMA. Com o cabeçalho podendo ter duas linhas, centrar
   deixaria o rosto flutuando no meio do texto. Só no cartão de post: o
   comentário em linha usa outro cabeçalho e continua centrado. */
.bip-card__header-row:has(> .bip-card__header) {
    align-items: flex-start;
}

/* O PONTO DA HORA MORREU COM A MUDANÇA DE ANDAR (10/09/26). Ele existia porque
   a hora dividia a linha com o nome: solta ali, "28s" virava uma palavra a
   mais, e o "·" a devolvia à condição de dado. Sozinha no segundo andar ela não
   divide nada com ninguém, e um ponto pendurado na frente seria enfeite órfão.

   O ponto do COMENTÁRIO continua no HTML dele — outro cabeçalho, outra regra. */

/* O RODAPÉ DO CARTÃO (06/09/26): hashtag à esquerda, cidade à direita.
   *"a localização vira embaixo no lado direito e a hashtag no lado esquerdo"*.

   Não é um andar novo: a hashtag já morava numa faixa própria acima das ações,
   e a cidade só mudou de ponta. Sem nenhuma das duas a faixa NÃO NASCE — um
   `:has()` decide, porque a hashtag chega depois, injetada pelo JS, e uma faixa
   vazia esperando por ela deixaria um vão no cartão de quem não tem tag. */
.bip-card__rodape {
    display: none;
    align-items: center;
    gap: 10px;
    margin-top: 8px;
}

.bip-card__rodape:has(.bip-card__hashtag),
.bip-card__rodape:has(.bip-card__city-link) {
    display: flex;
}

.bip-card__rodape-dir {
    margin-left: auto;
}

/* COMENTÁRIO no feed: uma linha só (nome + selos + flag + data) — não tem
   tópico nem cidade, então não precisa da segunda linha do post. */
.bip-inline-reply__header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 5px;
    flex: 1;
    min-width: 0;
    line-height: 1.3;
}

/* Linha 1: Nome + Selos + Bandeira + #tag */
.bip-card__header-line1 {
    display: flex;
    align-items: center;
    gap: 5px;
    flex-wrap: nowrap;
    overflow: hidden;
    min-width: 0;
}

/* NOME › #BiPTag colados (01/08/26): o chevron duplo e a tag formam UM bloco,
   com respiro só antes dele. Antes o gap de 5px da linha entrava duas vezes —
   antes do símbolo e depois — e a tag parecia solta no meio do cabeçalho. */
.bip-card__hashtag {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    min-width: 0;
}

.bip-card__ctx-chevron {
    width: 13px;
    height: 13px;
    flex-shrink: 0;
    color: var(--text-3);
}

.bip-card__hashtag-link {
    color: var(--accent);
    font-size: 0.9rem;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* A ETIQUETA NO FIM DO POST (28/08/26) — ver o comentário em bips-ui.js.
   Ela desceu da linha do nome para abrir espaço ao "está se sentindo X".

   Mais discreta do que era em cima, e de propósito: no cabeçalho ela competia
   com o nome pela primeira leitura; aqui ela é o fecho. Sem a seta dupla (»),
   que só fazia sentido enquanto ela vinha DEPOIS do nome. */
.bip-card__tag-fim {
    margin-top: 8px;
    /* Respiro para BAIXO também (28/08/26, dono: "sobe a tag um pouquinho
       para não pegar nas estrelas") — a pílula terminava colada na régua de
       engajamento. */
    margin-bottom: 7px;
}

/* FUNDO TRANSPARENTE (04/09/26, ordem do dono: *"o fundo dessas duas caixas
   [a #tag e o voto] transparente — se o card for azul, será azul; se for
   branco, será branco"*).

   O `--surface-3` é cor do TEMA: sobre um card colorido ele virava uma mancha
   cinza flutuando, e no modo "Minha cor" disputava o tom escolhido. Sem
   preenchimento, a cápsula mostra a cor do próprio card; o contorno entra no
   lugar do fundo para a forma não sumir junto. */
.bip-card__tag-fim-link {
    display: inline-block;
    max-width: 100%;
    padding: 3px 10px;
    border-radius: 999px;
    background: transparent;
    border: 1px solid var(--border);
    color: var(--accent);
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: bottom;
}

.bip-card__tag-fim-link:hover {
    /* No hover a cor entra de leve — e vem do ACCENT, não do tema, para
       continuar valendo sobre qualquer cor de card. */
    background: color-mix(in srgb, var(--accent) 12%, transparent);
}

/* O NOME NÃO É MAIS CORTADO (29/08/26). Estas quatro linhas eram a reticência:
   `nowrap` + `overflow: hidden` + `text-overflow: ellipsis` transformavam
   "Damiana" em "Da…" toda vez que o sentimento ao lado era comprido.

   `overflow-wrap: anywhere` é o seguro para o caso raro: um "nome" de trinta
   letras sem espaço nenhum não tem onde quebrar e furaria o cartão. */
.bip-card__header-line1 .bip-card__author {
    white-space: normal;
    overflow-wrap: anywhere;
    min-width: 0;
}

/* Selos e badges nunca encolhem — ficam sempre visíveis */
.bip-card__header-line1 .trust-tier,
.bip-card__header-line1 .country-flag,
.bip-card__header-line1 .bip-card__ctx-sep,
.bip-card__header-line1 .bip-card__community,
.bip-card__header-line1 .bip-vis-badge,
.bip-card__header-line1 .bip-locked-badge {
    flex-shrink: 0;
}

/* Linha 2: Localização + Data */
.bip-card__header-line2 {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    min-width: 0;
    line-height: 1.2;
}

/* Compatibilidade: header-meta ainda pode existir em outros contextos */
.bip-card__header-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    min-width: 0;
}

.bip-card__menu-wrap {
    position: relative;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
}

/* ══ A SETA NO LUGAR DOS TRÊS PONTOS (22/08/26, ordem do dono) ═════════════
   *"veja o indicador para baixo no lugar dos 3 pontos, que discreto"*.

   Os três pontos são o botão universal de "tem mais coisa aqui" — e é
   exatamente esse o problema: eles não dizem O QUE tem, nem para onde vai. A
   seta diz uma coisa só, e é a verdade: ALGO ABRE PARA BAIXO. Quem vê já sabe o
   que vai acontecer antes de tocar, e isso é o oposto de mistério.

   Ela também é MENOS TINTA no cabeçalho: três pontos empilhados desenham uma
   coluna que o olho conta; a seta é um traço. Num feed com vinte cartões, essa
   diferença é vinte colunas a menos disputando a atenção com os nomes. */
.bip-card__menu-btn {
    background: none;
    border: none;
    color: var(--text-3);
    cursor: pointer;
    padding: 4px 6px;
    border-radius: 8px;
    font-size: 1.35rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color var(--duration) ease, background var(--duration) ease,
        transform 180ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.bip-card__menu-btn:hover {
    color: var(--white);
    background: var(--surface-2);
}

/* A SETA GIRA quando o menu está aberto: o botão passa a dizer "fecho isto",
   e não mais "abro alguma coisa". É o mesmo gesto de um acordeão — e sem ele a
   seta apontaria para baixo com o menu já aberto, mentindo. */
.bip-card__menu-wrap:has(.bip-popover:not([hidden])) .bip-card__menu-btn {
    transform: rotate(180deg);
    color: var(--white);
}

/* X do cabeçalho (reforma Quora, 23/07/26): dispensar o cartão. Espelha o menu-btn. */
/* SEGUIR NO CABEÇALHO DO CARTÃO (17/08/26, ordem do dono, com a referência do
   Momspace na mão: "no estilo desse rosa, mas na cor azul").

   A referência é uma pílula de CONTORNO, não um botão cheio: fundo quase da cor
   da página, borda e letra na cor da marca. É o que a deixa presente sem
   disputar com o "Novo BiP" azul sólido da barra lateral, que é a ação
   principal da tela. Aqui o rosa vira o par da casa: `#EFF4F7` por dentro (a
   mesma cor de fundo que entrou hoje) e o `#145BD7` do logotipo na borda e no
   texto.

   O FUNDO NÃO É `var(--bg)` DE PROPÓSITO: se o dono trocar a cor da página de
   novo, o botão continua com este tom claro. Ele existe para ter contraste
   contra o BRANCO do cartão, e não para acompanhar o fundo — amarrar os dois
   faria o botão sumir no dia em que a página ficasse branca. */
.bip-card__follow-btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 28px;
    padding: 0 14px;
    margin-right: 2px;
    /* CÁPSULA DE NOVO (11/09/26, ordem do dono: o "Seguir" do aipim.social é
       "maravilhoso", e quer igual). O 10px de 17/08 existia para não parecer
       chip do filtro — o preto cheio resolve isso melhor que o canto: chip é
       contorno claro, este é bloco escuro com letra branca. */
    border-radius: 999px;
    /* UM "SEGUIR" SÓ EM TODA A REDE (21/08/26, dono: *"não entendo como dois
       botões seguir têm cores diferentes"*).

       Este era CONTORNADO (fundo da página + letra azul) e o do rail era
       SÓLIDO. A mesma ação com duas aparências ensina que são coisas
       diferentes — e obriga a pessoa a reaprender o botão a cada tela.
       Vence o sólido: "Seguir" é CONVITE, e convite é a ação principal do
       cartão. O contorno era a roupa de estado ("Seguindo", "Conectados"),
       que é justamente o que ele NÃO é. */
    /* ══ DISCRETO, E ISSO É UM UPGRADE (22/08/26, ordem do dono) ═══════════
       *"olha este botão de seguir: é muito discreto e muito premium, acho que
       seria um plus para nossa rede"*.

       O botão era AZUL SÓLIDO desde 21/08, e a razão escrita era boa: "Seguir é
       convite, e convite é a ação principal do cartão". O que a referência
       mostrou é que a premissa estava errada — a ação principal do cartão é
       LER O QUE A PESSOA ESCREVEU. Um retângulo azul saturado ao lado do nome
       compete com o texto em todos os cartões da rolagem, e o que aparece em
       todo cartão para de ser destaque e vira ruído.

       Discreto NÃO é apagado: a moldura, o "+" e o hover azul mantêm o botão
       legível e clicável. O que ele perdeu foi o direito de gritar.

       A REGRA DE 21/08 CONTINUA VALENDO — um "Seguir" só em toda a rede. Por
       isso o do rail mudou junto (ver `.rail-seguir__btn`): a mudança é da
       APARÊNCIA do botão, não do número de botões. */
    /* PRETO CHEIO (11/09/26): sem borda, letra branca em negrito — os tokens
       `--seguir-*` (paleta do index.css) invertem sozinhos no escuro. A nota
       de 22/08 acima fica como história: o "discreto" perdeu para a referência
       que o dono trouxe. */
    border: 0;
    background: var(--seguir-bg);
    color: var(--seguir-fg);
    font-family: var(--font);
    /* 11px, medida do aipim (11/09/26). */
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--duration) ease, color var(--duration) ease,
        transform 0.12s ease;
}

/* O "+" É O QUE DISTINGUE (22/08/26). Sem o azul, "Seguir" e "Conectados"
   seriam dois contornos neutros com palavras diferentes — e palavra se lê,
   sinal se reconhece. O "+" diz "isto ACRESCENTA alguém" antes de qualquer
   leitura, e é exatamente o que a referência fazia com o "+ Segue".

   Só no estado inicial: nos outros não há nada a acrescentar. */
.bip-card__follow-btn:not(.is-following):not(.is-mutual):not(.is-pending):not(.is-declined)::before {
    /* O "+" SAIU (11/09/26): na pílula preta quem distingue "Seguir" dos
       estados é a COR (preto × cinza), e a referência do aipim não leva ícone.
       Para voltar: content: "+"; margin-right: 5px; font-weight: 700; opacity: 0.75. */
    content: none;
}

/* HOVER um degrau mais claro (11/09/26): a pílula continua preta, só respira. */
.bip-card__follow-btn:hover {
    background: var(--seguir-bg-hover);
    color: var(--seguir-fg);
}

/* Pressionado encolhe um fio: é o toque do aipim. */
.bip-card__follow-btn:active {
    transform: scale(0.97);
}

.bip-card__follow-btn:disabled {
    opacity: 0.55;
    cursor: default;
    transform: none;
}

/* ══ SEGUINDO × CONECTADOS: INVERTIDOS (21/08/26, ordem do dono) ════════════
   *"temos muitos conectados e está ficando muito rosa, então invertendo ficará
   menos"*.

   O rosa era do CONECTADOS, por ser o estado mais forte. Só que forte no papel
   e frequente na tela são coisas diferentes: nesta rede quase todo mundo se
   segue de volta, então a cor de destaque caía em quase todos os cartões — e
   uma cor que aparece sempre para de destacar e vira fundo.

   Regra que fica: destaque se dá ao estado RARO, não ao estado importante.
   O rosa mudou de porta e vai para "Seguindo" (a minoria: eu sigo e ele ainda
   não seguiu de volta), e "Conectados" herda o contorno neutro — que é o certo
   para o que se repete vinte vezes numa rolagem. */
/* ESTADOS EM CINZA (11/09/26): Seguindo, Conectados e Pendente vestem a mesma
   pílula cinza clara com letra escura, peso 600 — o preto fica só para a
   AÇÃO. O rosa da inversão de 21/08 saiu junto: a referência não tem cor de
   estado, e "destaque para o raro" continua valendo — o raro agora é o preto
   do "Seguir". */
.bip-card__follow-btn.is-following {
    background: var(--seguir-feito-bg);
    color: var(--seguir-feito-fg);
    font-weight: 600;
}

/* O hover anuncia o "deixar de seguir" que o clique faz: letra vermelha. */
.bip-card__follow-btn.is-following:hover {
    background: var(--seguir-feito-bg-hover);
    color: var(--red);
}

/* CONECTADOS: os dois se seguem. Contorno NEUTRO desde a inversão de 21/08
   (nota acima) — é o estado que mais se repete na página, e o que se repete
   pede calma, não cor.

   Continua SÓ O RISCO, nunca preenchido: *"não ficaria forte pois é em cima do
   branco e seria só o risco"*. Perde a cor, não a presença. */
.bip-card__follow-btn.is-mutual {
    background: var(--seguir-feito-bg);
    color: var(--seguir-feito-fg);
    font-weight: 600;
}

.bip-card__follow-btn.is-mutual:hover {
    background: var(--seguir-feito-bg-hover);
    color: var(--red);
}

/* Perfil fechado: o pedido já foi. Mesma pílula cinza, sem convite ao clique
   — e o hover NÃO acende (vale para o <span> do servidor e para o <button>
   que o followAuthor deixa vivo com aria-disabled). */
.bip-card__follow-btn.is-pending,
.bip-card__follow-btn.is-pending:hover,
.bip-card__follow-btn.is-declined,
.bip-card__follow-btn.is-declined:hover {
    background: var(--seguir-feito-bg);
    color: var(--seguir-feito-fg);
    font-weight: 600;
    cursor: default;
}

/* NO ESCURO A PÍLULA INVERTE (11/09/26): branca com letra preta, estados em
   cinza escuro — tudo pelos tokens `--seguir-*`, que já trazem as duas
   versões. A regra escura de 22/08 que morava aqui SAIU de propósito: com
   (0,3,0) ela vencia `.is-following/.is-mutual/.is-pending` (0,2,0) e no
   escuro todos os estados saíam iguais ao "Seguir". */

/* O X "Marcar como lido" SAIU do cabeçalho (12/09/26, ordem do dono): virou o
   primeiro item do menu ⋮ (bips-ui.js). As regras `.bip-card__close-btn`
   morreram com ele. */

/* Post raiz: o canto superior direito do cartão (estilo Quora) leva o Seguir e
   o ⋮ — segue no fluxo, então nunca cobre nome/#tag. */
.bip-card__header-end--top {
    align-self: flex-start;
    margin-top: -8px;
    margin-right: -8px;
}

/* Toast do "Lido" (23/07/26): neutro (sem cor de alerta, sem som), com Desfazer. */
.bip-dismiss-toast {
    display: flex;
    align-items: center;
    gap: 14px;
    background: var(--surface-2);
    color: var(--text);
    border: 1px solid var(--border);
    padding: 10px 14px;
    border-radius: var(--radius);
    font-size: 0.9rem;
    font-weight: 500;
    box-shadow: var(--shadow-md);
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.bip-dismiss-toast--in {
    opacity: 1;
    transform: translateY(0);
}

.bip-dismiss-toast__undo {
    background: none;
    border: none;
    color: var(--accent);
    font-weight: 700;
    font-size: 0.9rem;
    cursor: pointer;
    padding: 2px 4px;
    flex-shrink: 0;
}

.bip-dismiss-toast__undo:hover {
    text-decoration: underline;
}

/* ══ A JANELA QUE SE REVELA (22/08/26, ordem do dono) ══════════════════════
   *"ao tocar nesse ícone a janela abre numa transição muito linda, tipo
   revelando, algo que amaria experimentar na nossa rede"*.

   REVELAR não é aparecer nem deslizar: é o menu CRESCER a partir do ponto que
   foi tocado. Por isso o `transform-origin` é a quina de cima à direita — onde
   a seta está. O menu parece sair de dentro do botão, e não cair de fora da
   tela; o olho não precisa procurar de onde aquilo veio porque acompanhou o
   crescimento.

   São três coisas ao mesmo tempo, e nenhuma sozinha faria o efeito: a altura
   abre (`clip-path`), o corpo cresce de 96% para 100%, e a opacidade sobe. A
   curva desacelera no fim — o menu chega no lugar e ASSENTA, em vez de parar
   seco.

   160ms é o teto do que ainda se sente como resposta imediata. Acima disso o
   efeito deixa de enfeitar e começa a atrasar. */
/* O TOCADOR DE ÁUDIO DA CASA (22/08/26, dono: "estilizar o nosso player para
   não ficar tão feio"). Play redondo azul, trilho com progresso e os dois
   tempos — o <audio> real é invisível e único por página (ver bips-ui.js). */
.bip-audio {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 10px;
    padding: 12px 14px;
    border-radius: 14px;
    /* O degradê discreto do azul da casa: o cartão de som se apresenta como
       objeto, não como um controle solto do navegador. */
    background: linear-gradient(135deg, rgba(64, 112, 176, 0.14), rgba(64, 112, 176, 0.05));
    border: 1px solid var(--border);
}

.bip-audio__botao {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 50%;
    background: var(--btn-azul, #4070B0);
    color: #fff;
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: transform 0.12s ease, filter 0.12s ease;
}

.bip-audio__botao:hover {
    filter: brightness(1.08);
    transform: scale(1.04);
}

.bip-audio__botao svg {
    width: 20px;
    height: 20px;
}

/* Play e pausa são o MESMO botão: a classe do cartão decide qual aparece. */
.bip-audio__ico-pausa {
    display: none;
}

.bip-audio.is-tocando .bip-audio__ico-pausa {
    display: block;
}

.bip-audio.is-tocando .bip-audio__ico-play {
    display: none;
}

.bip-audio__meio {
    flex: 1 1 auto;
    min-width: 0;
}

.bip-audio__trilho {
    position: relative;
    height: 6px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--btn-azul, #4070B0) 18%, transparent);
    cursor: pointer;
}

.bip-audio__feito {
    position: absolute;
    inset: 0 auto 0 0;
    width: 0%;
    border-radius: 999px;
    background: var(--btn-azul, #4070B0);
    transition: width 0.15s linear;
}

.bip-audio__tempos {
    display: flex;
    justify-content: space-between;
    margin-top: 6px;
    font-size: 0.72rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

/* VÍDEO NATIVO (22/08/26): o player ocupa a largura do cartão e o canto segue
   a régua das fotos. `max-height` segura o vertical 720x1280 — sem ele, um
   vídeo em pé ocuparia duas telas dentro do feed. */
/* A FRASE DA TELA PRETA (02/09/26) — ver `vigiarVideoArquivo` em bips-ui.js.
   Ela só aparece quando o navegador não desenhou UM quadro sequer; no caminho
   normal ninguém a vê. Discreta de propósito: é uma explicação, não um alarme. */
.bip-videofile__falha {
    margin: 8px 0 0;
    font-size: 0.86rem;
    line-height: 1.45;
    color: var(--text-2);
    text-align: center;
}

.bip-videofile__falha[hidden] { display: none; }

.bip-videofile.bip-videofile--expired {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    width: 100%;
    min-height: 92px;
    padding: 20px;
    border-radius: 12px;
    background: var(--bg-3);
    color: var(--text-2);
    font-size: 0.92rem;
}

.compose-native-video {
    margin: 10px 0;
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-3);
    color: var(--text);
}
.compose-native-video[hidden], .compose-native-video [hidden] { display: none; }
.compose-native-video__head { display: flex; gap: 8px; align-items: center; }
.compose-native-video__head strong { flex: 1; min-width: 0; overflow-wrap: anywhere; font-size: 0.9rem; }
.compose-native-video__head > i, .compose-add-btn--native-video i { color: var(--accent); }
.compose-native-video__remove {
    flex: 0 0 32px;
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--text-2);
    font-size: 1.35rem;
    cursor: pointer;
}
.compose-native-video__remove:hover { background: var(--bg-2); }
.compose-native-video__status { margin: 6px 0; color: var(--text-2); font-size: 0.83rem; line-height: 1.45; }
.compose-native-video__progress { width: 100%; height: 8px; accent-color: var(--accent); }
.compose-native-video__player { display: block; width: 100%; max-height: 220px; margin-top: 8px; border-radius: 8px; }

.bip-videofile__falha a {
    color: var(--accent);
    font-weight: 600;
}

/* Sem imagem, o player vira uma faixa preta alta e sem sentido — encolhe para a
   altura dos controles, que é a única parte dele que ainda funciona. */
.bip-videofile.is-sem-imagem .bip-videofile__player {
    max-height: 56px;
    background: var(--surface-2);
}

/* A CAIXA É O VÍDEO (27/09/26, ordem do dono): a proporção dele (--r, medida pelo bips-ui.js
   no `loadedmetadata`; 9:16 até lá), na largura do cartão, sem faixa preta. A altura para na
   janela: a caixa estreita e fica no meio. Era `max-height: min(70vh, 560px)` com o vídeo em
   pé espremido entre duas faixas. */
.bip-videofile {
    --r: 0.5625;
    width: min(100%, calc(var(--bip-video-alto-max) * var(--r)));
    margin: 10px auto 0;
}

/* NUNCA RETÂNGULO PRETO MUDO (22/09/26, ordem do dono): atrás do pôster mora a capa
   padrão do 256bip. Se o .jpg do vídeo faltar, é ela que aparece, e não o preto. */
.bip-videofile__player {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: var(--r);
    object-fit: contain;
    border-radius: 12px;
    background: #e8edf5 url("/assets/img/video-capa-padrao.jpg") center / cover no-repeat;
}

/* O botão de anexar áudio na barra da resposta. Só a EQUIPE o vê — quem desenha
   é o `botaoAudioHtml`, e a recusa de verdade é do servidor. */
/* A FAIXA DO ÁUDIO ANEXADO (22/08/26, ordem do dono: *"esconde este texto numa
   div abaixo e deixa a caixa de texto limpa, coloca um x para descartar"*).
   Mesma anatomia da faixa do vídeo: ícone, nome e o × — nunca a tag crua. */
.bip-reply-audio {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    padding: 6px 8px 6px 10px;
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text-1);
    font-size: 0.82rem;
}

.bip-reply-audio i {
    color: var(--accent);
    font-size: 1.05rem;
}

.bip-reply-audio__nome {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 220px;
}

.bip-reply-audio__x {
    border: 0;
    background: var(--border);
    color: var(--text-2);
    width: 20px;
    height: 20px;
    border-radius: 50%;
    line-height: 1;
    cursor: pointer;
}

.bip-reply-pill__audio.is-on {
    color: var(--accent);
}

.bip-reply-pill__audio.is-enviando {
    opacity: 0.5;
    pointer-events: none;
}

.bip-popover {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    min-width: 200px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
    padding: 6px;
    z-index: 50;
    transform-origin: top right;
    animation: bipPopoverRevelar 170ms cubic-bezier(0.16, 1, 0.3, 1);
    /* Menu cresceu (Repostar + bloco Moderação): em tela baixa, o teto + rolagem
       interna evitam itens fora da viewport — no flip-up inclusive (21/07/26). */
    max-height: min(60vh, 480px);
    overflow-y: auto;
}

.bip-popover[hidden] {
    display: none;
}

@keyframes bipPopoverRevelar {
    from {
        opacity: 0;
        transform: scale(0.96);
        clip-path: inset(0 0 100% 0);
    }
    to {
        opacity: 1;
        transform: scale(1);
        clip-path: inset(0 0 0 0);
    }
}

/* Perto do rodapé o menu abre para CIMA (senão os últimos itens ficam cortados). */
.bip-popover--up {
    top: auto;
    bottom: calc(100% + 4px);
    /* Abrindo de baixo, ele nasce da quina de BAIXO e se revela de baixo para
       cima: a origem tem de seguir o botão, senão o menu cresceria a partir de
       um canto onde não há nada. */
    transform-origin: bottom right;
    animation-name: bipPopoverRevelarCima;
}

@keyframes bipPopoverRevelarCima {
    from {
        opacity: 0;
        transform: scale(0.96);
        clip-path: inset(100% 0 0 0);
    }
    to {
        opacity: 1;
        transform: scale(1);
        clip-path: inset(0 0 0 0);
    }
}

/* Quem pediu menos movimento recebe o menu pronto — a revelação é enfeite, e
   enfeite é a primeira coisa que sai quando o sistema pede calma. */
@media (prefers-reduced-motion: reduce) {
    .bip-popover,
    .bip-popover--up {
        animation: none;
    }
}

/* Cabeçalho de bloco no menu ⋯ ("Moderação"): a linha acima é o que separa de
   fato; o texto só diz por quê. Discreto de propósito — é placa, não botão. */
.bip-popover__group {
    margin-top: 6px;
    padding: 8px 14px 4px;
    border-top: 1px solid var(--border, rgba(148, 163, 184, 0.18));
    color: var(--text-3);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    user-select: none;
}

/* Primeiro filho não leva linha: não há o que separar acima dele. */
.bip-popover__group:first-child {
    margin-top: 0;
    border-top: none;
}

/* ── O DESENHO NOVO DO MENU (28/08/26, ordem do dono, olhando o Facebook:
   "com explicação nos tópicos, com svg lindos") ──────────────────────────────
   Ícone num DISCO à esquerda, título forte e a explicação em letra miúda
   embaixo. Os itens antigos (span + i à direita) continuam renderizando —
   as regras novas só valem para quem tem as peças novas. */
.bip-popover__ico {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-2);
    color: var(--text-2);
    font-size: 17px;
}

.bip-popover__item--danger .bip-popover__ico {
    background: rgb(239 68 68 / 10%);
    color: #ef4444;
}

.bip-popover__txt {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}

.bip-popover__txt small {
    color: var(--text-3);
    font-size: 0.72rem;
    font-weight: 400;
    line-height: 1.3;
}

.bip-popover__item:has(.bip-popover__ico) {
    justify-content: flex-start;
    padding: 8px 12px;
}

/* Menu com itens ricos pede mais ombro: a explicação não pode quebrar a cada
   duas palavras. */
.bip-popover:has(.bip-popover__ico) {
    min-width: 290px;
}

/* JANELA SOLTA DO BOTÃO (28/08/26, dono: "tipo modal, não presa ao botão").
   O JS mede e crava left/top; fixo escapa do recorte do cartão e a rolagem
   interna morre — o teto é a própria tela. */
.bip-popover--flutuante {
    position: fixed;
    transform-origin: top right;
    max-height: calc(100vh - 24px);
}

.bip-popover__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    padding: 11px 14px;
    border: none;
    border-radius: var(--radius);
    background: transparent;
    color: var(--white);
    font-family: var(--font);
    font-size: 0.9rem;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
    /* O item inteiro se move um fio para a direita no hover (22/08/26). É o
       detalhe da referência que o dono chamou de "efeito conforme vai passando
       o mouse": o realce não só pinta, ele RESPONDE. Dois pixels bastam — mais
       do que isso vira sacudida, e a lista inteira parece instável. */
    transition: background var(--duration) ease, color var(--duration) ease,
        transform 140ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* O REALCE DO MENU LATERAL, AQUI TAMBÉM (22/08/26, ordem do dono: *"tem como
   mostrar essa sombra que temos no menu dos links nas opções do botão de ações
   do feed? Na mesma cor do usado lá nos links"*).

   `--nav-hover` é a cor que o item do menu lateral usa ao passar o mouse — a
   mesma que ele apontou. O `--surface-2` que estava aqui é quase o branco do
   próprio menu: o realce existia no CSS e não existia na tela, e a pessoa não
   via qual linha ia clicar.

   E a faixa vai de PONTA A PONTA. A PRIMEIRA RECEITA REFLUÍA (corrigido em
   25/08/26, dono: *"o primeiro item está mudando conforme o mouse está sobre
   ele e não deveria fazer isso, mudar só a cor, não ter outra linha"*):

   ela era `margin: -6px` de cada lado + `padding: 20px` de cada lado. A conta
   parecia fechar — 12 a mais na caixa, 12 a mais no respiro — mas o item tem
   `width: 100%` com `box-sizing: border-box`, e `100%` NÃO cresce com margem
   negativa: a largura da caixa continuava a mesma e os 12px extras de padding
   saíam do TEXTO. "Marcar como lido" cabia numa linha parado e quebrava em duas
   sob o cursor, empurrando o menu inteiro para baixo.

   Agora a faixa é uma SOMBRA, não uma caixa maior: dois `box-shadow` sólidos
   com deslocamento horizontal pintam os 6px de cada lado sem tocar em nenhuma
   medida do item. Sombra não ocupa espaço — é exatamente o que se queria de um
   realce. */
.bip-popover__item:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    pointer-events: none;
}

.bip-popover__item:hover {
    background: var(--nav-hover);
    color: var(--white);
    transform: translateX(2px);
    border-radius: 0;
    box-shadow: -6px 0 0 0 var(--nav-hover), 6px 0 0 0 var(--nav-hover);
}

/* O ÍCONE ACENDE junto (22/08/26): parado ele é cinza — informação de apoio;
   sob o cursor ele assume a cor do item, e a linha inteira passa a ser UMA
   coisa em vez de texto mais um desenho ao lado. */
.bip-popover__item i {
    font-size: 1.15rem;
    color: var(--text-3);
    transition: color var(--duration) ease;
}

/* O ÍCONE ACOMPANHA (a mesma lição do `.sidebar-link:hover i`): quem entra
   numa superfície tira a cor DELA. O azul do accent sobre a faixa vira azul
   dentro de azul. */
.bip-popover__item:hover i {
    color: var(--white);
}

/* Os itens vermelhos mantêm a IDENTIDADE deles na faixa: o texto continua
   vermelho, porque é ele que avisa que a ação é séria. O que muda é só o
   fundo — perder o vermelho no hover apagaria o aviso justo no momento em que
   o dedo está em cima. */
.bip-popover__item--danger:hover,
.bip-popover__item--danger:hover i {
    color: var(--red);
}

@media (prefers-reduced-motion: reduce) {
    .bip-popover__item:hover {
        transform: none;
    }
}

.bip-popover__item--danger {
    color: var(--red);
}

.bip-popover__item--danger i {
    color: var(--red);
}

/* Flashes por box-shadow INSET (21/07/26): animar `background` apagaria o fundo
   permanente do cartão durante o efeito. O inset pinta sobre o fundo e sob o
   conteúdo, e respeita o border-radius. */
.bip-card--highlight {
    animation: bip-highlight 2.5s ease;
}

@keyframes bip-highlight {
    0%, 100% { box-shadow: inset 0 0 0 999px transparent; }
    15%, 85% { box-shadow: inset 0 0 0 999px rgba(99, 102, 241, 0.08); }
}

.bip-card--just-posted {
    animation: bip-just-posted 2.2s ease;
}

@keyframes bip-just-posted {
    0%, 100% { box-shadow: inset 0 0 0 999px transparent; }
    12%, 70% { box-shadow: inset 0 0 0 999px rgba(79, 142, 247, 0.07); }
}

.bip-card__author {
    color: var(--white);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
}

.bip-card__ctx-sep {
    color: var(--text-3);
    font-size: 0.82rem;
    font-weight: 500;
    margin: 0 4px;
}

.bip-card__community {
    color: var(--accent);
    font-size: 0.88rem;
    font-weight: 600;
    text-decoration: none;
}

.bip-card__community:hover {
    text-decoration: underline;
}

.bip-card__time { color: var(--text-3); font-size: 0.8rem; }

/* Título estilo fórum (BiP de comunidade): cabeçalho em negrito acima da descrição. */
.bip-card__title {
    font-size: 1.15rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--text-1, var(--text));
    margin: 0 0 4px;
    letter-spacing: -0.01em;
    word-break: break-word;
    cursor: pointer;
}

.bip-card__title:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--accent) 45%, transparent);
    outline-offset: 2px;
    border-radius: 4px;
}

.bip-card__text {
    font-size: 1rem;
    color: var(--text);
    line-height: 1.5;
    margin-bottom: 12px;
    word-break: break-word;
    white-space: pre-wrap;
    cursor: pointer;
}

/* O "VER MAIS" DA DOBRA DO FEED (27/09/26): a cara do app, na cor da casa e em negrito leve, no fim do
   trecho à mostra. É um botão de verdade (teclado e leitor de tela), vestido de texto. */
.bip-ver-mais {
    display: inline;
    margin: 0 0 0 4px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--accent);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.bip-ver-mais:hover {
    text-decoration: underline;
}

.bip-card__text:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--accent) 45%, transparent);
    outline-offset: 2px;
    border-radius: 4px;
}

.bip-content-link {
    color: var(--accent);
    text-decoration: none;
}

.bip-content-link:hover {
    text-decoration: underline;
}

/* Link cru substituído pelo cartão de prévia (só quando fecha o texto). */
.bip-content-link--replaced {
    display: none;
}

/* ==========================================================================
   EMOJI ANIMADO INLINE (05/09/26) — o renderizador (BipText.emojisAnimadosHtml)
   troca o caractere pelo WebP do Noto Animated DENTRO do fluxo do texto.
   Tamanho em `em`: acompanha a letra onde estiver (card, resposta, fórum).
   O vertical-align negativo senta o emoji na linha de base como um glifo —
   `middle` deixaria ele flutuando acima das letras baixas.
   ========================================================================== */
.bip-emoji-anim {
    display: inline-block;
    width: 1.3em;
    height: 1.3em;
    vertical-align: -0.3em;
    user-select: none;
}

/* ==========================================================================
   ÊNFASE DO AUTOR (05/08/26) — negrito, itálico e sublinhado no texto do BiP.
   Sem COR, por decisão de produto: cor competiria com os OUTROS cards do feed,
   e "a atenção é conquistada, não comprada" está escrito na porta de entrada.
   ========================================================================== */
.bip-card__text strong,
.bip-reply__text strong {
    font-weight: 700;
}

.bip-card__text em,
.bip-reply__text em {
    font-style: italic;
}

/* O sublinhado do AUTOR não pode ser confundido com LINK. O link daqui é
   colorido no accent e SEM traço (ganha traço só no hover); este é da cor do
   texto, com traço mais fino e afastado da letra — lê-se como ênfase, não
   como "clique aqui". */
.bip-underline {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
}

/* SEGUNDA GERAÇÃO da ênfase (07/08/26) — riscado, monoespaçado, spoiler e
   citação, nascidos com o editor WYSIWYG. Mesma regra: sem cor de autor. */
.bip-card__text s,
.bip-reply__text s {
    text-decoration: line-through;
    text-decoration-thickness: 1px;
}

.bip-mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .92em;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 5px;
    padding: 1px 5px;
}

/* SPOILER VIVO (08/08/26, pedido do dono): poeira animada estilo Telegram/
   Threads — pontinhos que derivam em três camadas com velocidades diferentes,
   como fumaça de brilho sobre o segredo. Puro CSS (nada de GIF): três
   radial-gradients em movimento. A cor dos pontos usa --white, que é claro no
   tema escuro e escuro no claro — adapta sozinha. Nada dentro responde a
   clique (um link escondido não pode navegar antes de revelar); o toque
   revela (bips-ui.js) e vira texto comum. */
.bip-spoiler {
    border-radius: 5px;
    cursor: pointer;
    padding: 0 2px;
    /* Spoiler quebrando de linha: cada pedaço fecha o próprio cantinho. */
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
}

.bip-spoiler:not(.is-revealed) {
    background-color: color-mix(in srgb, var(--text) 16%, transparent);
    background-image:
        radial-gradient(circle, color-mix(in srgb, var(--white) 90%, transparent) 1px, transparent 1.3px),
        radial-gradient(circle, color-mix(in srgb, var(--white) 60%, transparent) 0.8px, transparent 1.1px),
        radial-gradient(circle, color-mix(in srgb, var(--white) 38%, transparent) 0.6px, transparent 0.9px);
    background-size: 13px 13px, 23px 19px, 17px 29px;
    animation: bipSpoilerPoeira 3s linear infinite;
}

/* Deslocamentos múltiplos do tamanho de cada camada: o laço fecha sem "pulo". */
@keyframes bipSpoilerPoeira {
    0% { background-position: 0 0, 0 0, 0 0; }
    100% { background-position: 26px -13px, -23px 38px, 34px -29px; }
}

@media (prefers-reduced-motion: reduce) {
    .bip-spoiler:not(.is-revealed) { animation: none; }
}

.bip-spoiler:not(.is-revealed),
.bip-spoiler:not(.is-revealed) * {
    color: transparent !important;
    text-decoration-color: transparent !important;
    user-select: none;
}

/* Emoji animado NÃO fura a tarja (05/09/26): imagem ignora `color`, então o
   WebP apareceria dançando sobre o segredo. `visibility` some e PRESERVA o
   espaço — a tarja não muda de tamanho ao revelar. */
.bip-spoiler:not(.is-revealed) img.bip-emoji-anim {
    visibility: hidden;
}

.bip-spoiler:not(.is-revealed) * { pointer-events: none; }

.bip-spoiler.is-revealed {
    cursor: inherit;
    background: var(--surface-2);
}

/* CITAÇÃO: bloco com a barra do accent — o mesmo desenho do Telegram. */
.bip-quote {
    display: block;
    margin: 6px 0;
    padding: 4px 12px;
    border-left: 3px solid var(--accent);
    border-radius: 4px;
    background: var(--accent-soft);
}

/* Cidade do card é PORTA (08/08/26): abre o feed da região. Continua com a
   cara muted de metadado — não pode competir com o link/menção azul. */
.bip-card__city-link {
    color: var(--text-3);
    font-size: 0.82rem;
    white-space: nowrap;
    text-decoration: none;
}

.bip-card__city-link:hover {
    color: var(--accent);
}

/* Prévia de link estilo Threads (21/07/26): miniatura + site + título — cartão
   compacto horizontal (o vertical gigante briga com as fotos de BiP). */
/* Mesma armadilha do cartão de comunidade: este bloco também é injetado
   dentro do `.bip-card__text`, que é `pre-wrap`. Hoje o template dele é
   compacto e por isso não quebrou — mas basta alguém indentar uma linha. */
.bip-link-preview {
    white-space: normal;
    display: flex;
    align-items: stretch;
    gap: 0;
    /* Mesma LARGURA da foto do post (ambos preenchem o .bip-card__text) e
       colada nela — o respiro é este margin-top, nada mais (26/07/26). */
    /* O max-width:520px fixo que morava aqui era o que encolhia a caixa à
       direita — fora ele: a prévia casa com a foto de ponta a ponta. */
    width: 100%;
    margin-top: 8px;
    border: 1px solid var(--border);
    border-radius: 12px;
    overflow: hidden;
    background: var(--surface-2);
    text-decoration: none;
    color: inherit;
    transition: border-color var(--duration), background var(--duration);
}

.bip-link-preview:hover {
    border-color: var(--accent);
}

.bip-link-preview__thumb {
    flex-shrink: 0;
    width: 108px;
    min-height: 84px;
    background: var(--bg-2);
}

.bip-link-preview__thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.bip-link-preview__body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 3px;
    padding: 10px 14px;
    min-width: 0;
}

.bip-link-preview__site {
    font-size: 0.76rem;
    color: var(--text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bip-link-preview__title {
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--text);
    line-height: 1.35;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    word-break: break-word;
}

/* @menção — mesma cor de link do resto do conteúdo, com um peso a mais: é uma
   pessoa, não um endereço. */
.bip-mention {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

.bip-mention:hover {
    text-decoration: underline;
}

/* A PÍLULA DA MENÇÃO (26/09/26, ordem do dono: *"vem o avatar e o nome da pessoa
   em negrito e até em uma fonte menor, achei lindo"*). Quem veste o link é o
   assets/js/bip-mencao-pilula.js; sem ele, fica o @ azul de cima. A pílula não
   quebra no meio: nome longo vira reticências, e ela desce inteira de linha. */
.bip-mention.bip-mention--pilula {
    display: inline-flex;
    box-sizing: border-box;
    align-items: center;
    gap: .375rem;
    min-height: 2rem;
    max-width: 100%;
    padding: .125rem .625rem .125rem .1875rem;
    margin: 2px 1px;
    border: 1px solid var(--border-hover);
    border-color: color-mix(in srgb, var(--accent) 28%, transparent);
    border-radius: 999px;
    background: var(--surface-2);
    color: var(--text-1);
    font-family: var(--font);
    font-size: .8125rem;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: normal;
    vertical-align: middle;
    white-space: nowrap;
    text-decoration: none;
    box-shadow: 0 1px 2px rgba(15, 23, 42, .08);
    transition: border-color .15s ease, background-color .15s ease;
}

.bip-mention.bip-mention--pilula:hover,
.bip-mention.bip-mention--pilula:focus-visible {
    text-decoration: none;
    border-color: var(--accent);
    background: var(--surface-2);
    background: color-mix(in srgb, var(--surface-2) 92%, var(--accent));
}

.bip-mention.bip-mention--pilula:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

.bip-mention__foto {
    flex: none;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    object-fit: cover;
    background: var(--surface-3);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent);
}

.bip-mention__nome {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 9.5rem;
}

.bip-media-caption {
    display: inline-block;
    max-width: min(320px, 88%);
    margin-top: 8px;
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--border);
    background: var(--surface-2);
    vertical-align: top;
}

/* No CARTÃO, a foto+legenda também ocupa a largura útil (21/07/26) — o teto de
   320px era da era das linhas divisórias e deixava a foto miúda no card novo. */
.bip-card__body .bip-media-caption {
    display: block;
    max-width: 100%;
}

.bip-card__body .bip-media-caption .bip-content-image {
    width: 100%;
    max-height: 880px;
    object-fit: cover;
}

.bip-media-caption .bip-content-image-wrap {
    margin: 0;
    max-width: 100%;
}

.bip-media-caption .bip-content-image-lightbox-open {
    border-radius: 0;
}

.bip-media-caption .bip-content-image {
    display: block;
    width: 100%;
    max-width: 100%;
    height: auto;
    /* Mesmo teto do feed: acima disso corta (cover) em vez de esticar a página. */
    max-height: 430px;
    border: none;
    border-radius: 0;
    object-fit: cover;
    background: rgba(0, 0, 0, 0.15);
}

.bip-media-caption__text {
    padding: 8px 12px 10px;
    font-size: inherit;
    line-height: 1.45;
    word-break: break-word;
}

.bip-content-image-wrap {
    margin-top: 10px;
    max-width: 80%;
}

/* Simetria do app (21/07/26): a FOTO do post ocupa a LARGURA ÚTIL do cartão —
   começa e termina alinhada com o texto, sem margem lateral. A proporção fica
   intacta (o upload já garante 3:4..4:3); o teto alto + cover só apara imagem
   EXTERNA fora desse intervalo (link de comunidade). Vale para o feed e para a
   raiz da Discussão; RESPOSTA segue com a imagem pequena de sempre. */
.bip-card__body .bip-content-image-wrap {
    max-width: 100%;
    margin-left: auto;
    margin-right: auto;
    /* O <figure> vinha com o margin-bottom PADRÃO do navegador (1em) — era o
       vão morto entre a foto e a prévia de link logo abaixo (26/07/26). */
    margin-bottom: 0;
}

.bip-card__body .bip-content-image {
    width: 100%;
    /* Teto anti-abandono (24/07/26): 880 → 600. Só morde foto RETRATO (3:4 =
       731px natural); paisagem/quadrada passam inteiras. Corte central é só a
       MOLDURA do feed — o arquivo fica intacto e o clique abre no lightbox.
       Garante que o começo do próximo BiP sempre apareça na tela. */
    max-height: 600px;
    object-fit: cover;
    margin-left: auto;
    margin-right: auto;
}

/* FIGURINHA POSTADA (07/09/26) — ver o porquê em bips-ui.js/ehFigurinha.
   A arte de origem tem 256px de lado, e é ela que manda no tamanho: quanto
   mais a gente estica, mais borra. 148px fica ABAIXO do arquivo, então a
   figurinha só encolhe. `inline-block` deixa duas figurinhas seguidas ficarem
   lado a lado, como numa conversa. */
.bip-content-sticker {
    display: inline-block;
    vertical-align: bottom;
    width: 148px;
    max-width: 42%;
    margin: 10px 8px 0 0;
}

.bip-content-sticker img {
    display: block;
    width: 100%;
    height: auto;
    /* Sem moldura, sem fundo: o alfa da figurinha é o desenho. */
    border: none;
    background: none;
    border-radius: 0;
}

/* O TOQUE NA FIGURINHA SALVA (17/09/26) — ver renderBipContentImage.
   O selo de baixar fica discreto e só acende no hover (no toque ele já está
   visível de leve): a figurinha é o desenho, o selo é a dica. */
.bip-content-sticker__save {
    display: block;
    position: relative;
    cursor: pointer;
}

.bip-content-sticker__badge {
    position: absolute;
    right: 2px;
    bottom: 2px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(0, 0, 0, .45);
    color: #fff;
    font-size: 15px;
    opacity: .25;
    transition: opacity .15s ease;
}

.bip-content-sticker__save:hover .bip-content-sticker__badge,
.bip-content-sticker__save:focus-visible .bip-content-sticker__badge {
    opacity: 1;
}

.bip-content-image-lightbox-open {
    display: block;
    width: 100%;
    max-width: 100%;
    padding: 0;
    margin: 0;
    border: none;
    background: none;
    cursor: zoom-in;
    border-radius: var(--radius);
    text-align: left;
    line-height: 0;
}

.bip-content-image-lightbox-open:focus-visible {
    outline: 2px solid color-mix(in srgb, var(--accent) 45%, transparent);
    outline-offset: 2px;
}

.bip-content-image {
    display: block;
    max-width: 100%;
    width: auto;
    height: auto;
    /* Teto de altura: retrato não detona o feed — mesma régua do preview (430px).
       Com width/height auto a proporção fica intacta (encolhe, não corta). */
    max-height: 430px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    object-fit: contain;
    background: var(--surface-2);
}

.bip-reply__text .bip-content-image-wrap {
    margin-top: 8px;
}

.bip-image-lightbox {
    position: fixed;
    inset: 0;
    z-index: 10060;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px 20px;
    background: rgba(28, 28, 28, 0.55);
    backdrop-filter: blur(6px);
}

.bip-image-lightbox[hidden] {
    display: none;
}

body.bip-image-lightbox-open {
    overflow: hidden;
}

/* A JANELA PARAVA DE CABER (22/08/26, dono: *"precisa aumentar um pouco a
   janela, está cortando embaixo"*).

   A conta não fechava: a caixa tinha teto de 78vh e a FOTO sozinha já podia
   ocupar 62vh — sobravam 16vh para o cabeçalho, a fileira de emojis e as
   estrelas, que juntos passam disso. Com `overflow: hidden`, o que não coubesse
   simplesmente sumia, e o que sumia era sempre a última linha: o voto.

   O CONSERTO NÃO É "AUMENTAR O TETO", é parar de fixar a altura da foto: as
   barras ficam com o tamanho delas (`flex: none`) e a foto FICA COM O QUE
   SOBRAR (`flex: 1`, `min-height: 0`). Assim nada é cortado em tela nenhuma —
   em vez de escolher um número que funcione no monitor de hoje. */
.bip-image-lightbox__stage {
    position: relative;
    display: flex;
    flex-direction: column;
    max-width: min(68vw, 640px);
    max-height: min(92vh, 900px);
    background: var(--bg-2, var(--surface));
    border: 1px solid var(--border);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.38);
}

/* Desktop: limite de 900px (+40,6%); a janela continua cabendo na tela. */
@media (min-width: 769px) {
    .bip-image-lightbox__stage {
        max-width: min(92vw, 900px);
    }
}

.bip-image-lightbox__stage > .bip-image-lightbox__top,
.bip-image-lightbox__stage > .bip-image-lightbox__bar {
    flex: none;
}

.bip-image-lightbox__close {
    position: absolute;
    top: 16px;
    right: 16px;
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-2);
    color: var(--text);
    font-size: 1.5rem;
    cursor: pointer;
    transition: background var(--duration), border-color var(--duration), color var(--duration);
}

.bip-image-lightbox__close:hover {
    background: var(--nav-hover, var(--bg-2));
    border-color: var(--border-hover);
}

.bip-image-lightbox__img {
    display: block;
    /* `min-height: 0` é o que permite ao flex ENCOLHER esta linha: sem ele o
       item guarda o tamanho natural da imagem e empurra as barras para fora. */
    flex: 1 1 auto;
    min-height: 0;
    max-width: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    margin: 0 auto;
}

.bip-card__actions {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: nowrap;
    width: 100%;
    min-width: 0;
}

/* OS LADOS TROCARAM (01/09/26, ordem do dono). À ESQUERDA o que se faz COM o
   BiP — comentar · repostar · encaminhar —, com um respiro maior entre os três:
   agora eles abrem a linha e o olho precisa separá-los. A fileira do POST ganhou
   o vão do app em 18/09/26 (ver `.bip-card__actions--reform`, logo abaixo); a
   NOTA DA DIREITA (`.bip-card__actions-right`, com o "N pts" e os polegares na
   moldura) saiu inteira, e o 👎 virou o 2º ícone da fileira. */
.bip-card__actions-left {
    display: flex;
    gap: 10px;
    align-items: center;
    color: #d4d4d8;
    flex: 1;
    min-width: 0;
}

/* Reforma Quora (23/07/26): barra única no rodapé do POST — pílula + comentar/
   repostar/enviar/copiar à esquerda; ⋯ ancorado à direita. */
.bip-card__actions--reform {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: nowrap;
    width: 100%;
    min-width: 0;
}

/* A FILEIRA DO APP NO POST (18/09/26, ordem do dono: *"web não está com o mesmo
   sistema de ícones sociais e ainda está com o antigo sistema de voto"*). Os
   cinco (coração · dislike · comentários · repostar · compartilhar) encostados à
   esquerda, no vão do app: 14dp entre um e outro, mais 1dp do fim do chip, ou
   seja, 15 do fim do número ao ícone seguinte. Aqui o vão é o `gap` somado ao
   respiro que cada botão tem de cada lado (4px no computador; no celular, 8px de
   padding menos 4px de margem, ver mobile.css) e à folga do piso de largura do
   número (`min-width` do `.bip-action-count`, ~1,6px num algarismo só):
   1,6 + 4 + 5 + 4 ≈ 15px nos dois tamanhos. Medido na bancada contra a fileira
   do app: o mesmo passo de ícone a ícone (46px com um algarismo).

   Só a fileira do POST (`--reform`): a resposta desenhada como cartão e a
   prévia de resposta seguem como estavam. */
.bip-card__actions--reform > .bip-card__actions-left {
    gap: 5px;
}

/* O DISLIKE ISOLADO À DIREITA (22/09/26, ordem do dono): usuários votavam errado
   com o 👎 colado no coração; um `margin-left: auto` empurra ele sozinho pra ponta. */
.bip-card__actions--reform > .bip-card__actions-right {
    display: flex;
    align-items: center;
    margin-left: auto;
}

/* A ANATOMIA DO CHIP DO APP: 3dp entre o ícone e o número, a caixa de 20 também
   no celular (o mobile.css dá 21 aos outros ícones de ação) e o número na letra
   da casa. Botão não herda a fonte da página (o navegador dá a dele, Arial no
   Windows e Roboto no Android), então os contadores da fileira saíam numa letra
   diferente do resto do cartão e do app. */
.bip-card__actions--reform .bip-action-btn {
    gap: 3px;
    font-family: inherit;
}

.bip-card__actions--reform .bip-action-icon {
    width: 20px;
    height: 20px;
}

/* O CORAÇÃO NA PRUMADA DO TEXTO, como no app: lá a fileira começa 2dp antes do
   texto, para descontar a folga que o desenho tem dentro da própria caixa. Aqui
   o botão ainda soma o respiro dele (4px), então a margem é -6px e a caixa do
   primeiro ícone nasce 2px antes do texto. No celular a conta muda (ver
   mobile.css). */
.bip-card__actions--reform > .bip-card__actions-left > .bip-action-btn:first-child {
    margin-left: -6px;
}

.bip-card__actions-main {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex: 1 1 auto;
    min-width: 0;
    flex-wrap: nowrap;
}

.bip-card__actions-end {
    display: inline-flex;
    align-items: center;
    margin-left: auto;
    flex-shrink: 0;
}

.bip-action-btn {
    background: none;
    border: none;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    font-size: 0.95rem;
    padding: 8px 4px;
    margin: -8px 0;
    border-radius: var(--radius);
    flex-shrink: 0;
    transition: color 0.18s ease, transform 0.18s ease;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

.bip-action-btn:hover {
    color: var(--white);
}

.bip-action-btn:active {
    transform: scale(0.94);
}

.bip-action-btn i {
    font-size: 1.375rem;
    line-height: 1;
}

/* ══ CINCO ÍCONES, UMA CAIXA SÓ (18/09/26) ═════════════════════════════════
   A fileira do cartão passou a usar os desenhos do app (ver FILEIRA_SVG_ATTR no
   bips-ui.js), que saíram dos svg que o dono baixou em 256bip.com/teste: *"se
   estiverem grossos afinar para a mesma espessura"*. Os cinco têm o MESMO traço
   (1,5 no viewBox de 24) e foram desenhados na MESMA área, centrados na mesma
   altura. Por isso a caixa é uma só, a de 20px, igual à de 20dp do app.

   A conta de 01/09/26 (*"o repostar ficou um pouco maior que os outros e o
   compartilhar ficou menor"*) dava uma caixa a cada ícone (repostar 17px, avião
   21px) porque os desenhos antigos ocupavam frações diferentes do viewBox. Ela
   morreu com eles. Se um ícone da fileira mudar, a régua é a mesma do app:
   mesmo traço e mesma área, nunca uma caixa diferente para compensar. */
.bip-action-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    display: block;
    shape-rendering: geometricPrecision;
}

/* ══ O CORAÇÃO (01/09/26, ordem do dono) ═══════════════════════════════════
   Ele é o PRIMEIRO da barra social e a única peça colorida dela: o resto do
   rodapé é cinza, e é justamente por isso que o vermelho aceso conta a história
   sem precisar de rótulo. Apagado, é contorno — cheio só depois do toque.

   Desde 18/09/26 o desenho é o do app, na caixa única da fileira (ver
   `.bip-action-icon`), e o cheio tem o mesmo contorno: não pula ao curtir. */
.bip-action-icon--heart {
    width: 20px;
    height: 20px;
}

.bip-action-btn--heart:hover {
    color: #e0245e;
}

/* ACESO = VERMELHO, NOS DOIS TEMAS E NAS DUAS PONTAS (01/09/26, ordem do dono:
   *"coração vermelho quando clicado e tudo certo — nem branco e nem preto"*).

   Eu tinha lido a mensagem anterior como "iguale na tinta forte" e pintei o
   ícone com a cor do texto: no claro ficou preto, no escuro ficou branco. Errado
   duas vezes — ele queria VERMELHO, e o vermelho já era o que ele tinha
   elogiado. Coração aceso é vermelho; não há nada a interpretar.

   Os dois seletores repetidos com `[data-theme="light"]` NÃO são redundância: a
   regra de tema (`[data-theme="light"] .bip-action-btn`, 0-2-1) ganha da
   simples (0-2-0) e forçava `--text-2` no claro. Foi ela que produziu o coração
   preto acidental. Empatar a especificidade é o que garante o vermelho nos dois
   temas. */
.bip-action-btn--heart.is-hearted,
.bip-action-btn--heart.is-hearted .bip-action-icon--heart,
.bip-action-btn--heart.is-hearted .bip-action-count,
[data-theme="light"] .bip-action-btn--heart.is-hearted,
[data-theme="light"] .bip-action-btn--heart.is-hearted .bip-action-icon--heart,
[data-theme="light"] .bip-action-btn--heart.is-hearted .bip-action-count {
    color: #e0245e;
}

/* ══ O BEIJO DO BiP (01/09/26, ordem do dono: *"tocar no coração e ter um lindo
   efeito especial, tipo beijo de um bip — isso motivaria as pessoas a darem
   novos corações"*) ═══════════════════════════════════════════════════════════

   Coraçõezinhos que sobem do próprio botão e somem. `position: fixed` e
   `pointer-events: none` no `body`: preso ao cartão, ele seria cortado pelo
   `overflow` do feed no primeiro pixel que subisse.

   Meio segundo, e só. Efeito de recompensa que dura mais que isso deixa de ser
   recompensa e vira espera — e este acontece a cada toque. */
.bip-beijo {
    position: fixed;
    z-index: 9999;
    pointer-events: none;
    font-size: 15px;
    line-height: 1;
    will-change: transform, opacity;
    animation: bip-beijo-sobe 620ms cubic-bezier(0.22, 0.9, 0.3, 1) forwards;
}

@keyframes bip-beijo-sobe {
    0%   { transform: translate(-50%, -50%) scale(0.4) rotate(0deg); opacity: 0; }
    18%  { transform: translate(calc(-50% + var(--bx, 0px) * 0.25), calc(-50% - 8px)) scale(1.15) rotate(var(--br, 0deg)); opacity: 1; }
    100% { transform: translate(calc(-50% + var(--bx, 0px)), calc(-50% - var(--by, 46px))) scale(0.7) rotate(var(--br, 0deg)); opacity: 0; }
}

/* O PULO DO PRÓPRIO BOTÃO: confirma o toque no lugar onde o dedo está. */
.bip-action-btn--heart.is-pulsando .bip-action-icon--heart {
    animation: bip-beijo-pulo 380ms cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes bip-beijo-pulo {
    0%   { transform: scale(1); }
    35%  { transform: scale(1.35); }
    100% { transform: scale(1); }
}

/* QUEM PEDIU MENOS MOVIMENTO NÃO RECEBE NENHUM (a régua da casa). */
@media (prefers-reduced-motion: reduce) {
    .bip-beijo { display: none; }
    .bip-action-btn--heart.is-pulsando .bip-action-icon--heart { animation: none; }
}

.bip-action-count {
    font-size: 0.85rem;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    line-height: 1;
    color: #a1a1aa;
    flex-shrink: 0;
    display: inline-block;
    text-align: start;
    min-width: 0.65rem;
    transition: color 0.18s ease;
}

/* Repost e enviar mostram "0" por padrão (24/07/26): espaço já reservado, sem
   pulo quando o contador vai de 0 → 1. (Antes escondia o span quando era 0.) */

.bip-action-btn:hover .bip-action-count {
    color: #d4d4d8;
}

/* Tema claro: ícones e contadores de engajamento em cinza médio legível (no escuro herdam a cor). */
[data-theme="light"] .bip-action-btn {
    color: var(--text-2);
}
[data-theme="light"] .bip-action-count {
    color: var(--text-2);
}
[data-theme="light"] .bip-action-btn:hover,
[data-theme="light"] .bip-action-btn:hover .bip-action-count {
    color: var(--white);
}

/* ══ O DISLIKE, 2º ÍCONE DA FILEIRA (18/09/26) ═══════════════════════════════
   A cápsula da ponta (👍, 👎 e o "N pts" na moldura, de 01/09/26) saiu
   inteira, ordem do dono: *"web não está com o mesmo sistema de ícones sociais
   e ainda está com o antigo sistema de voto"*. O 👎 virou a SETA do app, logo
   depois do coração, com a mesma caixa e o mesmo contador dos vizinhos. As
   regras `.bip-vote-thumb*`, `.bip-vote-cluster` e `.bip-rating*` saíram com
   ela: nenhum JS emite mais essas classes.

   ACESO = VERMELHO #DC2626 E CHEIO, o do app, nos dois temas: é a cor do voto,
   não papel de tema. Os seletores repetidos com `[data-theme="light"]` são o
   mesmo empate de especificidade do coração (ver `.is-hearted`, acima). */
.bip-action-btn--dislike:not(.is-own):hover {
    color: #dc2626;
}

.bip-action-btn--dislike.is-disliked,
.bip-action-btn--dislike.is-disliked .bip-action-count,
[data-theme="light"] .bip-action-btn--dislike.is-disliked,
[data-theme="light"] .bip-action-btn--dislike.is-disliked .bip-action-count {
    color: #dc2626;
}

/* NO PRÓPRIO BIP a seta fica apagada como no app (35%), e o número continua
   legível: é o que o autor quer ler. O botão segue clicável porque o toque
   explica por que não dá para votar (ver toggleDislike no bips-ui.js). */
.bip-action-btn--dislike.is-own:not(.is-disliked) .bip-action-icon {
    opacity: 0.35;
}

/* Faxina 21/07/26: widget de voto antigo (trio de caras + barra vermelho-verde
   + thumb) removido — nenhum JS/PHP emite bip-vote-trio/face/bar/btn/indicator/
   sep/icon desde que as ESTRELAS (renderVoteBar -> .bip-vote-stars) assumiram. */

.bip-score {
    font-size: 0.8rem;
    font-weight: 600;
    flex-shrink: 0;
    white-space: nowrap;
}

.bip-score--header {
    margin-left: 0;
    padding: 0 4px;
    font-variant-numeric: tabular-nums;
}

.bip-vis-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.7rem;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: var(--radius);
    background: var(--surface-2);
    color: var(--text-2);
}

/* Autor limitou os comentários: selo no card + ícone de comentar apagado. */
.bip-vis-badge--locked {
    color: #fbbf24;
}

.bip-action-btn--locked {
    opacity: 0.35;
    /* O TOQUE TEM DE CHEGAR (18/09/26): com `pointer-events: none` o botão apagado
       ficava mudo, e o ouvinte de `data-bip-gate-motivo` (bips-ui.js) nunca dizia
       o porquê. Regra da casa: botão bloqueado diz o motivo. */
    cursor: pointer;
}

.bip-vis-badge--private { color: #f59e0b; }
.bip-vis-badge--followers { color: var(--accent); }
.bip-vis-badge--connected { color: var(--accent); }

/* FIXAR NO TOPO DO FEED (16/09/26): marquinha discreta, mesma família visual
   do selo de comentários trancados — só muda a cor para diferenciar. */
.bip-vis-badge--pinned { color: var(--accent); }

.bip-vis-cycle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin-left: 4px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--text-3);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0.72;
    transition: color var(--duration), opacity var(--duration), transform var(--duration);
}

.bip-vis-cycle:hover {
    opacity: 1;
    transform: scale(1.08);
    background: transparent;
}

.bip-vis-cycle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.bip-vis-cycle--private {
    color: #f59e0b;
    opacity: 0.85;
}

.bip-vis-cycle--followers {
    color: var(--accent);
    opacity: 0.85;
}

.bip-vis-cycle--connected {
    color: var(--accent);
    opacity: 0.85;
}

.bip-vis-cycle--public {
    color: #34d399;
    opacity: 0.85;
}

.bip-compose-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    position: relative;
}

.bip-emoji-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin-left: 2px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--text-3);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0.72;
    transition: color var(--duration), opacity var(--duration), transform var(--duration);
}

.bip-emoji-toggle:hover {
    opacity: 1;
    transform: scale(1.08);
}

.bip-emoji-toggle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.bip-emoji-toggle[aria-expanded="true"] {
    opacity: 1;
    color: var(--accent);
}

.bip-emoji-panel {
    position: absolute;
    /* Abre PARA BAIXO — ancorado à direita porque o emoji é o último botão da
       fileira. Se não couber, o JS aplica .bip-emoji-panel--up. */
    top: calc(100% + 8px);
    bottom: auto;
    right: 0;
    z-index: 30;
    display: flex;
    flex-direction: column;
    /* 340px cortava a última aba de categoria — folga para a fileira inteira. */
    width: min(396px, 92vw);
    border-radius: 14px;
    background: var(--bg-2, #1e293b);
    border: 1px solid var(--border, rgba(148, 163, 184, 0.2));
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.42);
    overflow: hidden;
}

.bip-emoji-panel[hidden] {
    display: none;
}

/* PAINEL SOLTO NO CORPO (10/09/26, ordem do dono: *"quero que ao selecionar
   emoji, GIF e figurinhas a janela seja montada abaixo da caixa de texto,
   sempre centralizados"*). Enquanto aberto, ele deixa a cápsula e flutua no
   `body` — é a única forma de não ser cortado pela janela de comentários, que
   se centra com `transform` e corta com `overflow: clip`. Quem escreve a
   posição é o JS (BipPainelSobACaixa); aqui fica só o que ele não mede: ficar
   ACIMA da janela (que é 9900) e não herdar largura de ninguém. */
/* O 9950 VAI DE `!important` (28/09/26, relato do dono: *"o GIF está aparecendo
   atrás e não na frente"*, na web do computador).

   O número aqui já estava certo desde 10/09 — quem o apagava era a ORDEM do
   arquivo. `.bip-painel-solto` e `.bip-gif-panel` têm a MESMA especificidade
   (uma classe cada), e a regra do GIF mora umas quarenta linhas ABAIXO desta:
   empate é decidido pela ordem, então o painel solto voltava ao `z-index: 30`
   do ninho e afundava atrás da janela de comentários, que é 9900. O emoji
   escapava por sorte de escrita: a regra dele nasceu ACIMA desta.

   `!important` porque este é o estado que precisa vencer o ninho — qualquer
   painel, esteja a regra dele escrita onde estiver. É o mesmo motivo pelo qual
   o JS grava `position`, `left` e `top` com `!important` em BipPainelSobACaixa:
   solto, o painel não obedece mais ao lugar de onde saiu. Sem isso, cada painel
   novo (e a faixa do celular, que dobra a classe para vencer em (0,2,0))
   reabre o mesmo defeito. Continua ABAIXO dos overlays que o modal dispara —
   compartilhar 10000, toast 10050, lightbox 10060, excluir 10120. */
.bip-painel-solto {
    z-index: 9950 !important;
    margin: 0;
    /* ENCOLHE PARA CABER EMBAIXO (10/09/26): `--bip-painel-alt` é a altura livre
       que o JS mediu debaixo da caixa de texto. Sem ela (painel no lugar de
       sempre) nada aqui muda — o valor só existe enquanto ele está solto. */
    max-height: var(--bip-painel-alt, none);
    overflow: hidden;
}

.bip-painel-solto .bip-emoji-shell {
    max-height: var(--bip-painel-alt, none);
    min-height: 0;
}

/* O Emoji Mart rola por dentro: dar a ele a altura certa é melhor do que cortar
   o pé dele com overflow. 48px é a fileira de abas acima. */
.bip-painel-solto em-emoji-picker {
    height: min(435px, calc(var(--bip-painel-alt, 999px) - 48px));
}

.bip-painel-solto .bip-gif-grid {
    max-height: calc(var(--bip-painel-alt, 999px) - 76px);
}

/* ==========================================================================
   SELETOR DE GIF (09/08/26) — vizinho do emoji, mesma geometria de popover.
   ========================================================================== */
.bip-gif-wrap {
    position: relative;
    display: inline-flex;
}

/* O botão é a palavra "GIF": ícone de GIF genérico não é reconhecido, e as
   redes que acertaram isso escrevem as três letras. */
.compose-add-btn__gif {
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    line-height: 1;
}

.bip-gif-panel {
    position: absolute;
    /* Para cima, pelo mesmo motivo do painel de emoji: a barra está no pé. */
    bottom: calc(100% + 8px);
    right: 0;
    z-index: 30;
    display: flex;
    flex-direction: column;
    width: min(392px, 92vw);
    border-radius: 14px;
    background: var(--bg-2, #1e293b);
    border: 1px solid var(--border, rgba(148, 163, 184, 0.2));
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.42);
    overflow: hidden;
}

.bip-gif-panel[hidden] {
    display: none;
}

.bip-gif-search {
    margin: 8px;
    padding: 9px 12px;
    border: 1px solid var(--border, rgba(148, 163, 184, 0.22));
    border-radius: 10px;
    background: var(--bg-3, rgba(148, 163, 184, 0.1));
    color: var(--text);
    font-size: 0.9rem;
    font-family: inherit;
    outline: none;
}

/* TRÊS COLUNAS (18/08/26, ordem do dono), como no painel do chat do app. Duas
   colunas era a regra antiga — "GIF é imagem larga" — mas a conta não fechava:
   com 392px de painel, dois GIFs por linha davam tijolos de 190px e cabiam três
   e meio na altura toda. Procurar GIF é varrer com o olho, e varrer pede
   QUANTIDADE à vista. Três também alinha web e app na mesma grade. */
/* CASCATA, NÃO GRADE (01/09/26, dono: *"problemas na exibição dos gifs"*).
   Com `display:grid`, os três itens de uma linha ganhavam a altura do MAIS ALTO
   (stretch) — e como cada GIF tem a sua proporção, os outros dois eram cortados
   no `object-fit: cover`: rostos pela metade, cenas sem pé nem cabeça.

   As colunas são TRÊS CAIXAS DE VERDADE (o JS distribui), e não `column-count`:
   coluna CSS com altura limitada não rola para baixo — ela cria colunas novas
   para o LADO, e os GIFs saíam do painel (medido em 01/09/26). */
.bip-gif-grid {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    padding: 0 8px 8px;
    max-height: 320px;
    overflow-y: auto;
    /* A barra grossa do sistema roubava a atenção da grade (foto do dono,
       09/08/26). Fina e discreta: quem olha ali está olhando os GIFs. */
    scrollbar-width: thin;
    scrollbar-color: var(--border, rgba(148, 163, 184, 0.35)) transparent;
}

.bip-gif-grid::-webkit-scrollbar { width: 8px; }
.bip-gif-grid::-webkit-scrollbar-track { background: transparent; }

.bip-gif-grid::-webkit-scrollbar-thumb {
    background: var(--border, rgba(148, 163, 184, 0.35));
    border-radius: 8px;
}

/* Uma coluna da cascata: empilha os GIFs que couberem nela. */
.bip-gif-col {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.bip-gif-item {
    display: block;
    width: 100%;
    padding: 0;
    border: none;
    border-radius: 10px;
    overflow: hidden;
    background: var(--bg-3, rgba(148, 163, 184, 0.12));
    cursor: pointer;
    /* A proporção vem do servidor (style inline): a caixa nasce com a altura
       final e a cascata não pula enquanto os GIFs terminam de baixar. */
    aspect-ratio: 1;
}

.bip-gif-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.bip-gif-item:hover {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
}

.bip-gif-msg {
    /* Atravessa as três colunas da cascata (era grid-column, de quando isto
       aqui era grade). */
    column-span: all;
    padding: 22px 10px;
    text-align: center;
    color: var(--text-3);
    font-size: 0.85rem;
}

/* ATRIBUIÇÃO KLIPY (02/10/26, no lugar da marca do GIPHY). Os termos da KLIPY
   exigem o placeholder "Buscar KLIPY" no campo de busca; o crédito "Powered by
   KLIPY" é recomendado, e fica onde o conteúdo deles aparece. */
.bip-gif-credit {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 6px 10px;
    border-top: 1px solid var(--border);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--text-3);
}

/* O crédito também fecha a aba Figurinhas (a KLIPY mora lá desde 02/10/26). */
.bip-emoji-sticker-scroll .bip-gif-credit { margin: 8px 0 0; }

/* AS CATEGORIAS DA ABA FIGURINHAS (02/10/26): um chip por catálogo, cada um com a
   sua grade inteira, nenhum no fundo do outro. */
.bip-emoji-sticker-cats {
    display: flex;
    gap: 6px;
    padding: 6px 10px 2px;
}
.bip-emoji-sticker-cat {
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-2);
    border-radius: 999px;
    padding: 4px 12px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.bip-emoji-sticker-cat.is-active {
    background: var(--btn-azul);
    border-color: var(--btn-azul);
    color: #fff;
}

/* EMOJI MART + SHELL (09/08/26): abas Emojis/Figurinhas no estilo Paçoca —
   uma única janela com sombra; o Emoji Mart perde a moldura duplicada. */
.bip-emoji-panel:has(.bip-emoji-shell) {
    padding: 0;
    background: transparent;
    border: none;
    box-shadow: none;
    width: max-content;
    max-width: 96vw;
    min-width: min(510px, 96vw);
    overflow: visible;
}

/* Largura final vem do JS (larguraPickerEmoji: colunas×50 + 56); aqui só o
   mínimo seguro — os números abaixo SEGUEM a fórmula, não a lideram. */
.bip-emoji-shell {
    width: 510px;
    max-width: 96vw;
    box-sizing: border-box;
    border-radius: 12px;
    background: var(--bg-2, #1e293b);
    border: 1px solid var(--border, rgba(148, 163, 184, 0.2));
    box-shadow:
        0 12px 40px rgba(0, 0, 0, 0.28),
        0 4px 14px rgba(0, 0, 0, 0.12);
    overflow: hidden;
}

[data-theme="light"] .bip-emoji-shell {
    background: #fff;
    box-shadow:
        0 12px 40px rgba(15, 23, 42, 0.14),
        0 4px 14px rgba(15, 23, 42, 0.08);
}

/* Abas principais — Emojis | GIF | Animados | Figurinhas. */
.bip-emoji-shell__tabs {
    display: flex;
    flex-wrap: nowrap;
    border-bottom: 1px solid var(--border, rgba(148, 163, 184, 0.18));
    background: inherit;
}

.bip-emoji-shell__tab {
    flex: 1 1 0;
    min-width: 0;
    margin: 0;
    padding: 10px 6px;
    border: none;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--text-3);
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.bip-emoji-shell__tab:hover {
    color: var(--text);
}

.bip-emoji-shell__tab.is-active {
    color: var(--text);
    border-bottom-color: var(--accent);
}

.bip-emoji-shell__pane--emojis {
    display: block;
    overflow: visible;
}

.bip-emoji-shell__pane--figurinhas {
    display: flex;
    flex-direction: column;
    height: min(435px, 62vh);
}

.bip-emoji-shell__pane--gifs {
    display: flex;
    flex-direction: column;
    height: min(435px, 62vh);
    overflow: hidden;
}

.bip-emoji-shell__pane--gifs .bip-gif-grid {
    flex: 1 1 auto;
    max-height: none;
    min-height: 0;
}

.bip-emoji-shell em-emoji-picker {
    /* 506 = 9×50 + 12 + 12 + 16 (barra) + 16 de folga — espelho de
       larguraPickerEmoji. O `--sidebar-width: 18px` que morava aqui era LETRA
       MORTA (achado da verificação, 10/08/26): o vendor declara 16px DIRETO no
       #root do shadow DOM, e declaração própria vence herança do host — a
       barra sempre foi 16, e o 18 só desinformava a fórmula. */
    width: 506px;
    min-width: 506px;
    max-width: 96vw;
    flex-shrink: 0;
    height: min(435px, 62vh);
    --border-radius: 0;
    --shadow: none;
}

.bip-emoji-sticker-search-wrap {
    padding: 10px 12px 0;
}

.bip-emoji-sticker-search {
    width: 100%;
    padding: 10px 12px 10px 2.2em;
    border: 0;
    border-radius: 10px;
    background: var(--bg-3, rgba(148, 163, 184, 0.12));
    color: var(--text);
    font-family: inherit;
    font-size: 0.9rem;
    outline: none;
}

.bip-emoji-sticker-search:focus {
    box-shadow: inset 0 0 0 1px var(--accent);
}

.bip-emoji-sticker-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
    padding: 8px 0 0;
}

.bip-emoji-sticker-heading {
    margin: 0;
    padding: 4px 14px 8px;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    color: var(--text-3);
}

.bip-emoji-sticker-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 0 10px 12px;
    scrollbar-width: thin;
    scrollbar-color: var(--border, rgba(148, 163, 184, 0.35)) transparent;
}

.bip-emoji-sticker-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
}

.bip-emoji-sticker-item {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    padding: 6px;
    border: none;
    border-radius: 10px;
    background: transparent;
    cursor: pointer;
    transition: background 0.12s ease, transform 0.12s ease;
}

.bip-emoji-sticker-item:hover {
    background: var(--bg-3, rgba(148, 163, 184, 0.14));
    transform: scale(1.04);
}

.bip-emoji-sticker-item img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    pointer-events: none;
}

.bip-emoji-sticker-empty {
    margin: 0;
    padding: 28px 16px;
    text-align: center;
    color: var(--text-3);
    font-size: 0.88rem;
    line-height: 1.45;
}

/* Legado: picker montado direto no painel (respostas inline antigas).
   478px MORREU em 10/08/26: com `#root{width:100%!important}` no picker.css, o
   componente passou a seguir o host — e num host de 478 a grade fixa de 450
   ficaria com 438 de área útil (478 − 24 de padding − 16 de barra) e cortaria.
   Mesma conta da fórmula: 450 + 24 + 16 + folga. */
.bip-emoji-panel em-emoji-picker {
    width: 506px;
    max-width: 96vw;
    flex-shrink: 0;
    align-self: flex-end;
    height: min(435px, 62vh);
}

/* ARMADILHA DE NOME (09/08/26): NÃO declare `--rgb-background` aqui.
   Custom property ATRAVESSA o shadow DOM, e `--rgb-background` é exatamente o
   nome que o Emoji Mart lê para se pintar (`rgb(var(--rgb-background,255,255,255))`).
   Havia um `--rgb-background: transparent` neste bloco para não repetir o fundo
   do painel — e o resultado foi o seletor inteiro TRANSPARENTE, com o texto do
   compositor aparecendo entre os emojis. Quem pinta o fundo é ele; o painel se
   apaga (abaixo), não o contrário. */

/* O painel some quando o Mart está dentro: o componente traz o próprio fundo, a
   própria borda arredondada e a própria sombra. Duas molduras, uma sobre a
   outra, era o defeito que este bloco veio corrigir — e continua corrigindo,
   agora sem levar o fundo do componente junto. */
/* Legado: painel sem shell (respostas com grid manual). */
.bip-emoji-panel:has(em-emoji-picker):not(:has(.bip-emoji-shell)) {
    padding: 0;
    background: transparent;
    border: none;
    box-shadow: none;
    width: max-content;
    max-width: 96vw;
    /* 506, não 478 — mesma conta da fórmula (o 478 morreu em 10/08/26). */
    min-width: min(506px, 96vw);
    /* `overflow: hidden` FICA. Ele é a rede de segurança: qualquer coisa que
       quebre o layout interno do componente vaza para a página inteira sem ele —
       foi exatamente o que aconteceu quando saiu daqui. */
    overflow: hidden;
}

/* Sem espaço abaixo: o JS aplica .bip-emoji-panel--up e abre para cima. */
.bip-emoji-panel.bip-emoji-panel--up {
    top: auto;
    bottom: calc(100% + 8px);
}

/* Emoji do COMENTÁRIO: o painel abre para a DIREITA (10/08/26, relato do dono).
   O `right: 0` lá de cima nasceu no compositor, onde o emoji é o ÚLTIMO botão da
   fileira — ali crescer para a esquerda é o certo. Na pílula de resposta o emoji
   é o PRIMEIRO, colado na borda esquerda da caixa: ancorado à direita, o painel
   de 396px crescia por cima da borda e saía cortado pela lateral do feed.
   O JS ainda mede e corrige o que sobrar (ver posicionarPainelEmoji).

   SÓ NO COMPUTADOR, e a media query aqui não é enfeite: no celular o painel vira
   uma faixa `position: fixed; left: 8px; right: 8px` (mobile.css). Media query
   não soma especificidade — três classes venceriam a regra de lá em qualquer
   largura e o celular perderia a faixa sem ninguém pedir. */
@media (min-width: 768px) {
    .bip-reply-pill .bip-emoji-wrap > .bip-emoji-panel,
    /* O GIF do comentário (10/08/26) abre no mesmo lugar e para o mesmo lado que
       o emoji: os dois botões ficam à esquerda da pílula. */
    .bip-reply-pill .bip-gif-wrap > .bip-gif-panel,
    .bip-reply-compose--modal .bip-gif-wrap > .bip-gif-panel {
        top: calc(100% + 8px);
        bottom: auto;
        left: 0;
        right: auto;
    }

    /* Sem espaço embaixo, sobe — o JS decide medindo (posicionarPainelGif). */
    .bip-reply-pill .bip-gif-wrap > .bip-gif-panel.bip-gif-panel--up,
    .bip-reply-compose--modal .bip-gif-wrap > .bip-gif-panel.bip-gif-panel--up {
        top: auto;
        bottom: calc(100% + 8px);
    }

    /* O EMOJI TAMBÉM SOBE (10/09/26, relato do dono: *"o site está bem bugado
       quando ativo os emojis neste novo formato"*).

       O GIF ganhou esta gêmea em 10/08 e o emoji ficou sem — e sem ela a regra
       de subir NUNCA vencia aqui dentro: `.bip-emoji-panel.bip-emoji-panel--up`
       tem duas classes, e a regra de cima, três. O JS media certo, punha a
       classe, e o CSS ignorava. Na coluna de comentários, onde o compositor é o
       RODAPÉ, o painel abria para baixo e caía fora da coluna inteira. */
    .bip-reply-pill .bip-emoji-wrap > .bip-emoji-panel.bip-emoji-panel--up {
        top: auto;
        bottom: calc(100% + 8px);
    }
}

/* AS FERRAMENTAS DE RESPOSTA MUDARAM DE CASA (11/09/26): a pílula flutuante
   `.bip-reply-tools` substituiu `.bip-reply-pill` como casa do emoji/GIF/
   figurinha, mas as regras de ancoragem do painel tinham ficado no local antigo
   — por isso o painel abria fora da janela de comentários (recortada) e a
   pessoa via "não abre". Espelhadas aqui para o local novo. No desktop o JS
   ainda solta o painel no body; isto cobre o caminho em-lugar. */
.bip-reply-tools .bip-emoji-wrap,
.bip-reply-tools .bip-gif-wrap {
    position: relative;
}

@media (min-width: 768px) {
    .bip-reply-tools .bip-emoji-wrap > .bip-emoji-panel,
    .bip-reply-tools .bip-gif-wrap > .bip-gif-panel {
        top: calc(100% + 8px);
        bottom: auto;
        left: 0;
        right: auto;
    }

    .bip-reply-tools .bip-emoji-wrap > .bip-emoji-panel.bip-emoji-panel--up,
    .bip-reply-tools .bip-gif-wrap > .bip-gif-panel.bip-gif-panel--up {
        top: auto;
        bottom: calc(100% + 8px);
    }
}

/* O botão "GIF" da pílula de resposta: as três letras no lugar do ícone, na
   mesma caixa dos outros utensílios (a palavra é reconhecível; ícone de GIF
   genérico não é — mesma razão do botão do compositor). */
.bip-reply-pill__gif,
.bip-reply-modal__gif {
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.02em;
    line-height: 1;
}

/* Com um painel aberto, o cartão não pode recortar nem ficar embaixo — a regra
   irmã de .bip-card:has(.bip-emoji-panel…) lá em cima, agora para o GIF. */
.bip-card:has(.bip-gif-panel:not([hidden])) {
    content-visibility: visible;
    contain: none;
    position: relative;
    z-index: 60;
}

.bip-emoji-search {
    margin: 8px 8px 6px;
    padding: 9px 12px;
    border: 1px solid var(--border, rgba(148, 163, 184, 0.22));
    border-radius: 10px;
    background: var(--bg-3, rgba(148, 163, 184, 0.1));
    color: var(--text);
    font-size: 0.9rem;
    outline: none;
}

.bip-emoji-search:focus {
    border-color: var(--accent);
}

.bip-emoji-tabs {
    display: flex;
    gap: 2px;
    padding: 0 6px 6px;
    overflow-x: auto;
    /* Distribui as abas na largura toda — nada de categoria cortada na ponta. */
    justify-content: space-between;
    border-bottom: 1px solid var(--border, rgba(148, 163, 184, 0.14));
    scrollbar-width: none;
}

.bip-emoji-tabs::-webkit-scrollbar {
    display: none;
}

.bip-emoji-tab {
    flex: 0 0 auto;
    border: none;
    background: none;
    cursor: pointer;
    font-size: 1.15rem;
    line-height: 1;
    padding: 5px 7px;
    border-radius: 8px;
    opacity: 0.55;
    transition: opacity var(--duration), background var(--duration);
}

.bip-emoji-tab:hover,
.bip-emoji-tab.is-active {
    opacity: 1;
    background: var(--bg-3, rgba(148, 163, 184, 0.16));
}

.bip-emoji-scroll {
    max-height: 208px;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 2px 8px 8px;
    /* Barra OCULTA (24/07/26): rola normal (roda/touch/teclado) — a barra nativa
       ficava feia no tema claro. Mesmo padrão dos dropdowns. */
    scrollbar-width: none;
}

.bip-emoji-scroll::-webkit-scrollbar {
    display: none;
}

.bip-emoji-cat-title {
    position: sticky;
    top: 0;
    margin: 6px 2px 4px;
    padding: 2px 0;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-3);
    background: var(--bg-2, #1e293b);
}

.bip-emoji-grid {
    display: grid;
    grid-template-columns: repeat(8, 1fr);
    gap: 2px;
}

.bip-emoji-empty {
    padding: 22px 10px;
    text-align: center;
    color: var(--text-3);
    font-size: 0.85rem;
}

/* MAIORES (09/08/26, pedido do dono): 34px/1.35rem era um emoji do tamanho de
   uma letra — no seletor das outras redes eles são o assunto da tela, não um
   detalhe. Alvo de toque de 40px e desenho de 1.7rem: cabe a mesma quantidade
   por fileira e o dedo acerta de primeira no celular. */
.bip-emoji-panel__item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    border-radius: 10px;
    background: transparent;
    font-size: 1.7rem;
    line-height: 1;
    cursor: pointer;
    transition: background var(--duration), transform var(--duration);
}

.bip-emoji-panel__item:hover {
    background: var(--bg-3, rgba(148, 163, 184, 0.16));
    transform: scale(1.12);
}

/* Campo inline para inserir imagem por URL (sem prompt nativo). */
.compose-image {
    margin-top: 12px;
    padding: 12px;
    border: 1px solid var(--border, rgba(148, 163, 184, 0.2));
    border-radius: 12px;
    background: var(--bg-2, rgba(148, 163, 184, 0.06));
}

.compose-image[hidden] {
    display: none;
}

.compose-image__url {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--border, rgba(148, 163, 184, 0.22));
    border-radius: 10px;
    background: var(--bg-3, rgba(148, 163, 184, 0.1));
    color: var(--text);
    font-size: 0.92rem;
    outline: none;
    box-sizing: border-box;
}

.compose-image__url:focus {
    border-color: var(--accent);
}

.compose-image__foot {
    display: flex;
    gap: 8px;
    margin-top: 10px;
}

.compose-image__add {
    padding: 7px 16px;
    border: none;
    border-radius: 8px;
    background: var(--btn-azul);
    color: #fff;
    font-weight: 600;
    font-size: 0.88rem;
    cursor: pointer;
}

.compose-image__add:hover {
    filter: brightness(1.08);
}

.compose-image__cancel {
    padding: 7px 12px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--text-3);
    font-size: 0.88rem;
    cursor: pointer;
}

.compose-image__cancel:hover {
    color: var(--text);
}

.compose-image__err {
    margin-top: 8px;
    color: var(--red, #ef4444);
    font-size: 0.82rem;
}

/* Wrap posicionado para o painel de emoji na resposta inline (footer não é relative). */
.bip-emoji-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
}

.compose-modal__panel {
    padding: 24px 22px 20px;
}

.compose-modal__intro {
    /* Risco sutil separando o cabeçalho (24/07/26, pedido do dono). */
    margin-bottom: 14px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--border);
}

.compose-modal__headline {
    text-align: center;
    font-size: 1.65rem;
    font-weight: 800;
    color: var(--white);
    margin: 0 0 6px;
    line-height: 1.2;
}

.compose-modal__accent {
    color: var(--accent);
}

.compose-modal__tagline {
    text-align: center;
    color: var(--text-3);
    font-size: 0.88rem;
    line-height: 1.4;
    margin: 0;
    max-width: 540px;
    margin-left: auto;
    margin-right: auto;
}

.compose-modal__editor {
    width: 100%;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.compose-modal__textarea {
    resize: none;
    background: var(--bg-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: 14px 16px 26px;
    font-size: 1.05rem;
    line-height: 1.5;
    /* SEM foto a caixa nasce com o dobro de altura (paridade com o app);
       com foto ela encolhe (regra abaixo). O JS segue no auto-grow. */
    min-height: 104px;
    width: 100%;
    color: var(--white);
    font-family: var(--font);
    transition: border-color var(--duration), box-shadow var(--duration);
}

.compose-modal__panel.compose-modal--has-image .compose-modal__textarea {
    min-height: 52px;
}

/* Assunto + localização na MESMA linha, mesmo layout (o da localização). */
.compose-head-row {
    display: flex;
    gap: 8px;
    margin-bottom: 10px;
}

.compose-head-row .compose-topic,
.compose-head-row .compose-location {
    flex: 1;
    min-width: 0;
    margin: 0;
}

.compose-topic {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border-radius: 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
}

.compose-topic__hash {
    color: var(--accent);
    font-weight: 600;
    font-size: 15px;
}

.compose-topic__input {
    flex: 1;
    min-width: 0;
    background: none;
    border: none;
    outline: none;
    color: var(--text);
    font-size: 14px;
    font-family: var(--font);
}

/* A BARRA DE ROLAGEM DO COMPOSITOR (10/09/26, dono: *"barra de rolagem feia e
   contador quebrado por estar abaixo"*). O auto-grow para em 280px e liga
   `overflow-y: auto` — daí para cima aparecia a barra CRUA do sistema, cinza,
   larga e com setas, dentro de um modal que não tem mais nada quadrado. Fina,
   redonda e da cor da borda: some no repouso e aparece quando é útil. */
.compose-modal__textarea {
    scrollbar-width: thin;
    scrollbar-color: var(--border-hover, var(--border)) transparent;
}

.compose-modal__textarea::-webkit-scrollbar {
    width: 10px;
}

.compose-modal__textarea::-webkit-scrollbar-track {
    background: transparent;
}

.compose-modal__textarea::-webkit-scrollbar-thumb {
    /* A borda transparente com `background-clip` afina o polegar sem afinar a
       ÁREA DE PEGAR: o alvo do mouse continua com 10px. */
    background: var(--border-hover, var(--border));
    background-clip: padding-box;
    border: 3px solid transparent;
    border-radius: 999px;
}

.compose-modal__textarea::-webkit-scrollbar-thumb:hover {
    background: var(--text-3);
    background-clip: padding-box;
}

/* Dentro da caixa: contador numa linha ABAIXO do texto (29/09/26). */
.compose-editor-box {
    display: flex;
    flex-direction: column;
    align-items: stretch;
}

.compose-editor-box__counter {
    flex-shrink: 0;
    align-self: flex-end;
    padding: 6px 4px 2px;
    font-size: 0.78rem;
    color: var(--text-3);
    opacity: 0.85;
    pointer-events: none;
}

/* ══ REFORMA FB DO COMPOSITOR (24/07/26) ══════════════════════════════════
   Identidade (avatar+nome+chips) · texto ABERTO sem caixa · barra de opções
   só-ícone com tooltip escuro · BiPar grande · cidade por GPS. */

/* Texto aberto, estilo FB — só no compositor principal (#bip-compose); o
   modal de resposta continua com a caixa dele. */
#bip-compose .compose-editor-box .compose-modal__textarea {
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
    /* Contador numa linha abaixo — sem reserva à direita na última linha. */
    padding: 8px 2px 4px;
    min-height: 112px;
}

/* Com foto, a área de texto encolhe (a regra base perdia para o ID acima). */
.compose-modal--has-image #bip-compose .compose-editor-box .compose-modal__textarea {
    min-height: 52px;
}

/* O emoji fica no CANTO DIREITO da barra — o painel abre ancorado à direita
   para não estourar a borda do modal. */
.compose-addbar .bip-emoji-panel {
    left: auto;
    right: 0;
}

/* O GIF ABRE ONDE O EMOJI ABRE (10/08/26, ordem do dono: "amei a posição da
   janela de emoji, quero a de GIF exatamente no mesmo lugar").

   Os dois botões são vizinhos, mas cada painel se ancorava no PRÓPRIO wrap — e o
   do GIF fica um botão à esquerda, então o mesmo `right: 0` dava dois lugares
   diferentes (e o GIF ainda abria para CIMA, por cima do modal). A âncora agora é
   a FILEIRA de ícones: como o emoji é o último botão dela, a borda direita é a
   mesma, e `top: 100%` mede a partir da mesma linha de base.

   Só no computador: no celular `mobile.css` faz dos dois uma faixa
   `position: fixed` no rodapé, e media query não soma especificidade — sem este
   recorte, duas classes venceriam a regra de lá em qualquer largura. */
@media (min-width: 768px) {
    .compose-addbar__icons {
        position: relative;
    }

    /* Sem isto o painel continuaria preso ao wrap do próprio botão. */
    .compose-addbar .bip-gif-wrap {
        position: static;
    }

    .compose-addbar .bip-gif-panel {
        top: calc(100% + 8px);
        bottom: auto;
        left: auto;
        right: 0;
        /* Mesma caixa do painel de emoji (.bip-emoji-shell = 510): mesmo lugar
           com larguras diferentes ainda pareceria outra janela — este número
           SEGUE o shell, e os dois mudam juntos (achado da verificação:
           ficou 502 quando o shell foi a 510). */
        width: min(510px, 96vw);
    }

    /* Sem espaço embaixo, volta a abrir para cima — o mesmo que o emoji faz
       (o JS decide medindo, em posicionarPainelGif). */
    .compose-addbar .bip-gif-panel.bip-gif-panel--up {
        top: auto;
        bottom: calc(100% + 8px);
    }
}

.compose-head-row[hidden] {
    display: none !important; /* o display:flex da base vencia o hidden */
}

.compose-identity {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin: 2px 0 6px;
}

.compose-identity__avatar {
    flex: none;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-2);
    color: var(--text-2);
    font-size: 1.3rem;
}

.compose-identity__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.compose-identity__name {
    display: block;
    color: var(--white);
    font-size: 0.98rem;
    font-weight: 700;
    line-height: 1.2;
    margin-bottom: 2px;
}

/* A SEGUNDA LINHA DO CABEÇALHO (10/09/26, ordem do dono): @ e depois o lugar,
   a mesma ordem do app — quem usa os dois lê a mesma coisa no mesmo lugar. */
.compose-identity__handle {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 2px;
    margin-bottom: 6px;
    line-height: 1.2;
}

.compose-identity__arroba {
    color: var(--text-2);
    font-size: 0.82rem;
    font-weight: 600;
}

/* ── UMA LINHA SÓ NO COMPUTADOR (12/09/26, ordem do dono: *"como na web não tem
   como estourar, coloque o @ e o local na linha de cima, ficará só em uma
   linha, só para desktop web"*) ────────────────────────────────────────────

   O cabeçalho de duas linhas veio do APP, onde a tela é estreita e nome + @ +
   cidade não cabem lado a lado. No computador cabem com folga, e a segunda
   linha só gastava altura da janela do compositor — que é onde a pessoa quer
   ver a própria caixa de escrever.

   `display: contents` é o truque exato aqui: o `.compose-identity__handle`
   deixa de existir como caixa e seus filhos passam a ser itens do MESMO flex
   do nome, sem trocar uma vírgula na marcação — e o app, que não passa por
   este arquivo, continua com as duas linhas dele.

   Só de 900px para cima: abaixo disso o navegador está num celular, e ali a
   régua é a mesma do app. */
@media (min-width: 900px) {
    .compose-identity__linha {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 8px;
    }

    /* O RESPIRO DAS CAIXINHAS (13/09/26, ordem do dono: "a linha que tem as
       caixinhas precisa de um respiro em relação ao nome"). Com o @ em
       `display: contents`, a margem de baixo dele sumia junto com a caixa e os
       chips encostavam no nome; a margem passa a ser da linha inteira. */
    .compose-identity__linha {
        margin-bottom: 7px;
    }

    .compose-identity__linha .compose-identity__name {
        margin-bottom: 0;
    }

    .compose-identity__linha .compose-identity__handle {
        display: contents;
    }
}

/* Pino + cidade ao lado do nome (24/07/26): aparece quando a cidade é definida. */
/* O selo entre o nome e a cidade (18/08/26). `inline-flex` para o desenho
   assentar na linha do nome em vez de empurrá-la para baixo. */
.compose-identity__trust {
    display: inline-flex;
    align-items: center;
    margin-left: 6px;
    vertical-align: middle;
}

.compose-identity__city {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    margin-left: 6px;
    padding: 2px 6px;
    border-radius: 8px;
    color: var(--text-2);
    font-size: 0.82rem;
    font-weight: 600;
    /* Porta, não etiqueta (05/09/26): tocar aqui abre a caixa de trocar o
       lugar — a mesma do ícone da barra. */
    cursor: pointer;
}

.compose-identity__city:hover {
    background: color-mix(in srgb, var(--border) 45%, transparent);
}

.compose-identity__city[hidden] { display: none !important; }

/* SEM LUGAR ESCOLHIDO o chip continua na tela, só que apagado: ele é a única
   porta para pôr um (o pino saiu da barra em 10/09/26). */
.compose-identity__city.is-vazio {
    font-weight: 500;
    opacity: 0.75;
}

.compose-identity__city i {
    color: #f0284a;
    font-size: 0.95rem;
}

.compose-identity__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.compose-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border: none;
    border-radius: 8px;
    background: var(--bg-2);
    color: var(--text-2);
    font-family: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: background var(--duration), color var(--duration);
}

.compose-chip:hover {
    background: var(--surface-2);
    color: var(--white);
}

.compose-chip i { font-size: 1rem; }
.compose-chip .bx-chevron-down { font-size: 0.9rem; margin-left: -2px; }
.compose-chip__hash { font-weight: 800; color: var(--accent); }

/* Chip de comentários: aceso = vermelho (comentários desativados). */
.compose-chip--lock[aria-pressed="true"] {
    background: rgba(239, 68, 68, 0.14);
    color: #f87171;
}

.compose-chip--topic.is-on {
    background: var(--accent-soft);
    color: var(--accent);
}

/* Vocabulário FECHADO (26/07/26): tópico digitado que NÃO existe no índice
   oficial — chip vermelho "escolha da lista"; o BiPar fica escondido junto. */
.compose-chip--topic.is-invalid {
    background: rgba(239, 68, 68, 0.14);
    color: #f87171;
}

/* Tópico INLINE (25/07/26): o chip É o campo — clicar troca o rótulo pelo
   input ali mesmo (cursor piscando), e o dropdown de sugestões ancora no
   próprio chip. A caixa "assunto do BiP" embaixo morreu. */
.compose-topic-chip-wrap {
    display: inline-flex;
}

/* O display acima venceria o atributo hidden — regra explícita (mesmo padrão
   do .compose-suggest[hidden]): só UM dos dois chips (rótulo OU input) vive. */
.compose-chip[hidden] {
    display: none;
}

.compose-chip--topic-edit {
    position: relative;
    background: var(--surface-2);
    color: var(--white);
    cursor: text;
}

.compose-chip__input {
    width: 14ch;
    background: none;
    border: none;
    outline: none;
    padding: 0;
    margin: 0;
    color: var(--text);
    font: inherit;
    line-height: 1;
}

/* Navegador novo: o campo cresce com o texto (até 30ch). */
@supports (field-sizing: content) {
    .compose-chip__input {
        field-sizing: content;
        width: auto;
        min-width: 7ch;
        max-width: 30ch;
    }
}

.compose-chip__input::placeholder {
    color: var(--text-3);
    font-weight: 500;
}

.compose-chip--topic-edit .compose-suggest {
    right: auto;
    min-width: 250px;
}

/* O chip de privacidade herda .bip-vis-cycle (cores por estado) — aqui só se
   garante o formato de chip por cima de qualquer estilo redondo herdado. */
.compose-identity .bip-vis-cycle {
    width: auto;
    height: auto;
    border-radius: 8px;
    padding: 5px 10px;
}

.compose-vis-wrap { position: relative; display: inline-flex; }

.compose-vis-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    z-index: 60;
    min-width: 190px;
    padding: 6px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow-md);
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.compose-vis-menu[hidden] { display: none !important; }

.compose-vis-menu button {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 9px 10px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--text);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.compose-vis-menu button:hover { background: var(--surface-2); }
.compose-vis-menu button.is-active { background: var(--accent-soft); color: var(--accent); }
.compose-vis-menu button i { font-size: 1.05rem; }

/* Barra de anexos — SÓ ÍCONES desde 29/08/26 (o rótulo "Adicionar ao BiP" saiu;
   ver o comentário no `compose_modal.php`). O padding voltou a ser igual dos dois
   lados: os 14px da esquerda existiam para afastar a frase da borda. */
.compose-addbar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 8px;
    border: 1px solid var(--border);
    border-radius: 12px;
    margin-bottom: 12px;
}

/* Os ícones tomam a barra inteira e se espalham. Encolhidos num canto — que é o
   que sobra quando o texto sai e nada ocupa o lugar — a barra viraria um bloco
   vazio com sete botões amontoados à direita. */
.compose-addbar__icons {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex: 1;
    gap: 2px;
}

.compose-add-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 40/1.3 → 44/1.55 (24/07/26): ícones maiores, presença de FB. */
    width: 44px;
    height: 44px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    cursor: pointer;
    font-size: 1.55rem;
    line-height: 1;
    transition: background var(--duration), transform 0.15s ease;
}

.compose-add-btn:hover { background: var(--surface-3); }
.compose-add-btn:active { transform: scale(0.92); }
.compose-add-btn[aria-pressed="true"] { background: var(--accent-soft); }

/* Cores VIVAS por opção (saturação de FB, 24/07/26). */
.compose-add-btn--schedule { color: #8b5cf6; }
.compose-add-btn--poll { color: #1877f2; }
.compose-add-btn--photo { color: #23b558; }
.compose-add-btn--emoji { color: #f7b928; }
/* O GIF ficou SEM cor até 09/08/26: herdava a do container e sumia no branco do
   modal claro — o dono via um buraco entre o relógio e o emoji. */
.compose-add-btn--gif { color: #00a67d; }
/* A MÚSICA repetiu a história do GIF (31/08/26, dono: "o ícone de música no
   tema claro ficou apagado"): nasceu sem cor e herdava a do container —
   invisível no branco do modal. Rosa de player de música. */
.compose-add-btn--music { color: #ec4899; }
/* REGRA (10/09/26), depois do GIF e da música, que nasceram sem cor e sumiam no
   branco: ícone que entra nesta fileira SAI COM COR PRÓPRIA no mesmo commit. */
/* CHECK IN (12/09/26): coral de pino de mapa, a cor que o FB dá ao "estou em".
   Com cor própria no mesmo commit, pela regra logo acima. */

/* O "Aa" (08/09/26, ordem do dono: *"coloca o botão de cor dentro do quadro de
   ícones"*). É o único da fileira que não é ícone de linha — é uma PASTILHA em
   degradê, porque nele a cor não decora: ela é o próprio assunto do botão. A
   pastilha tem 30px dentro da roda de 44px, então o hover redondo dos vizinhos
   continua desenhando igual. */
.compose-add-btn__aa {
    display: inline-grid;
    place-items: center;
    width: 30px;
    height: 30px;
    border-radius: 9px;
    background: linear-gradient(135deg, #7B2FF7, #F7642F 60%, #F7C12F);
    color: #fff;
    font-size: 0.9rem;
    font-weight: 800;
    font-family: Georgia, serif;
    line-height: 1;
}

/* Com cor escolhida o botão fica marcado — é o que o aria-pressed faz nos
   vizinhos; aqui o anel vai na pastilha, que é o que a pessoa enxerga. */
#btn-bip-estilo.is-on .compose-add-btn__aa {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* GPS em andamento: o pino pulsa. */
.compose-add-btn.is-busy i {
    animation: bipCityPulse 0.9s ease-in-out infinite;
}

@keyframes bipCityPulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50% { opacity: 0.45; transform: scale(0.85); }
}

/* Tooltip escuro estilo FB — some no toque (hover/focus só). */
.compose-add-btn[data-tip]::after {
    content: attr(data-tip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%) translateY(2px);
    padding: 6px 10px;
    border-radius: 8px;
    background: #111827;
    color: #f9fafb;
    font-size: 0.74rem;
    font-weight: 600;
    font-family: var(--font);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 70;
}

.compose-add-btn[data-tip]::before {
    content: '';
    position: absolute;
    bottom: calc(100% + 3px);
    left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: #111827;
    opacity: 0;
    transition: opacity 0.15s ease;
    z-index: 70;
    pointer-events: none;
}

.compose-add-btn[data-tip]:hover::after,
.compose-add-btn[data-tip]:focus-visible::after {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.compose-add-btn[data-tip]:hover::before,
.compose-add-btn[data-tip]:focus-visible::before {
    opacity: 1;
}

/* BiPar GRANDE, linha inteira (estilo FB "Postar"). */
#modal-bip-compose .compose-modal__actions { flex: 1 1 auto; }

.compose-submit-split {
    display: flex;
    width: 100%;
    align-items: stretch;
    position: relative;
    flex-wrap: nowrap;
}

.compose-submit-split__main {
    flex: 1 1 auto;
    min-width: 0;
    border-top-right-radius: 0 !important;
    border-bottom-right-radius: 0 !important;
}

.compose-submit-split__more {
    position: relative;
    flex: 0 0 auto;
}

.compose-submit-split__caret {
    height: 100%;
    min-width: 44px;
    padding: 11px 12px;
    font-size: 1.15rem;
    line-height: 1;
    border-top-left-radius: 0 !important;
    border-bottom-left-radius: 0 !important;
    border-top-right-radius: 10px !important;
    border-bottom-right-radius: 10px !important;
    border-left: 1px solid rgba(255, 255, 255, 0.28);
}

.compose-submit-split__caret.is-active,
.compose-submit-split__caret[aria-expanded="true"] {
    filter: brightness(0.96);
}

.compose-submit-split__menu {
    position: absolute;
    right: 0;
    bottom: calc(100% + 8px);
    min-width: min(240px, 92vw);
    padding: 6px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow-md);
    z-index: 1400;
}

.compose-submit-split__menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 10px 12px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--text-1);
    font-size: 0.92rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
}

.compose-submit-split__menu-item:hover,
.compose-submit-split__menu-item:focus-visible {
    background: var(--surface-2, rgba(79, 142, 247, 0.08));
}

.compose-submit-split__menu-item .bx {
    font-size: 1.25rem;
    color: var(--primary, #4f8ef7);
}

.compose-submit-split.is-sched-on .compose-submit-split__caret {
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.35);
}

.compose-modal__submit--big {
    width: 100%;
    padding: 11px 16px;
    font-size: 0.98rem;
    font-weight: 700;
    border-radius: 10px;
}

.compose-submit-split .compose-modal__submit--big {
    width: auto;
}

.compose-submit-split--solo .compose-modal__submit--big {
    width: 100%;
    border-radius: 10px !important;
}

.compose-modal__submit--big:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    filter: none;
}

.compose-modal__submit--big:disabled:hover {
    filter: none;
}

/* ── Agendamento em MODAL próprio (24/07/26): o painel ficava CORTADO dentro
   do compositor. Mesmo DOM/ids de sempre — só a apresentação virou overlay
   centrado (classe .is-open, controlada pelo JS). ── */
#bip-schedule-wrap { display: none; }

#bip-schedule-wrap.is-open:not([hidden]) {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 1300;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(8, 10, 14, 0.6);
}

/* A folha cresceu ~86px com as duas rodas (10/09/26): teto e rolagem própria
   para nunca estourar em tela baixa nem com o teclado do celular aberto. */
#bip-schedule-wrap.is-open:not([hidden]) .compose-schedule__panel {
    max-height: calc(100dvh - 40px);
    overflow-y: auto;
    /* 500px (31/08/26, dono: "com tanto espaço na tela, porque limitar e
       causar linha debaixo em Às?") — os 7 atalhos de cada fileira cabem
       numa linha só. */
    width: min(500px, 94vw);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 20px;
    box-shadow: var(--shadow-md);
}

.compose-schedule__head {
    display: flex;
    align-items: center;
    gap: 10px;
    position: relative;
    padding-bottom: 12px;
    margin-bottom: 14px;
}

/* O RISCO PREMIUM sob o título (31/08/26, dono: "um risco lindo e premium…
   vai parecer janela de sistema operacional"). Roxo do despertador de um
   lado, azul da casa do outro, morrendo nas pontas. */
.compose-schedule__head::after,
.bip-reply-sched__head::after {
    content: '';
    position: absolute;
    left: -20px;
    right: -20px;
    bottom: 0;
    height: 2px;
    background: linear-gradient(90deg, transparent, rgba(139, 92, 246, 0.5) 25%, rgba(79, 142, 247, 0.5) 75%, transparent);
}

/* O X de fechar, canto do título — no lugar do botão Cancelar. */
.sched-x {
    appearance: none;
    border: 0;
    background: transparent;
    margin-left: auto;
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    font-size: 1.45rem;
    line-height: 1;
    color: var(--text-2);
    cursor: pointer;
}

.sched-x:hover {
    background: var(--surface-2);
    color: var(--text);
}

/* O risco SUTIL entre as caixinhas da folha — irmão discreto do risco do
   título: só borda, sem cor de marca. */
.sched-div {
    height: 1px;
    margin: 8px 0 4px;
    background: linear-gradient(90deg, transparent, var(--border) 18%, var(--border) 82%, transparent);
}

.compose-schedule__head-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(139, 92, 246, 0.14);
    color: #8b5cf6;
    font-size: 1.3rem;
}

.compose-schedule__title {
    font-size: 1.05rem;
    margin: 0;
}

.compose-schedule__actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    margin-top: 16px;
}

/* O RESUMO no rodapé (01/09/26, dono: "na mesma linha do botão agendar") —
   à esquerda, o Agendar à direita; vale no post e na resposta. */
.compose-schedule__actions .sched-summary,
.bip-reply-sched__actions .sched-summary {
    flex: 1;
    margin: 0;
    text-align: left;
}

/* ═══ BiP em PARTES (26/07/26) ═══ */

/* Compositor: pílulas Parte 1/2/3 sob a caixa — trocam o buffer em edição. */
.compose-parts {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 2px 0 6px;
}

.compose-parts[hidden] { display: none !important; }

.compose-parts__btn {
    padding: 4px 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-2);
    color: var(--text-3);
    font-family: inherit;
    font-size: 0.74rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color var(--duration), color var(--duration), background var(--duration);
}

.compose-parts__btn:hover { border-color: var(--border-hover); color: var(--text); }

.compose-parts__btn.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 700;
}

.compose-parts__btn--add { border-style: dashed; }

.compose-parts__btn[hidden] { display: none !important; }

/* Card: divisor entre as partes de UM BiP — filete + selo "2/3" discreto.
   É UMA postagem: nada de engajamento por parte; o rodapé continua único. */
.bip-part-break {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 10px 0;
}

.bip-part-break::before {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border);
}

/* A PRIMEIRA parte também tem selo ("1/3") desde 07/08/26 — sem ele a leitura
   começava no "2/3" e parecia faltar um pedaço. Só o respiro de cima diminui:
   o selo abre o texto, não separa nada. */
.bip-part-break--first {
    margin-top: 2px;
    margin-bottom: 6px;
}

/* Selo da parte: fundo azul SUAVE (o token dos chips) + tinta muted — a mesma
   receita do app (27/07/26), medida em 4,0:1 no escuro e 3,9:1 no claro. */
.bip-part-break__n {
    flex: none;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--text-3);
    border-radius: 999px;
    padding: 2px 9px;
    background: var(--accent-soft);
}

/* Pílulas do "Quando": as opções ficam à mostra, clique escolhe. */
#bip-schedule-mode[hidden] { display: none !important; }

/* No MODAL o painel tem ~390px úteis; em duas colunas cada uma fica com ~190px
   e a pílula "Após meu último agendamento" (nowrap, ~225px) transbordava POR
   CIMA do Intervalo — o agendamento parecia quebrado ao escolher essa opção
   (26/07/26). Aqui "Quando" e "Intervalo/Data" viram LINHAS, uma sob a outra.
   As três regras antigas mandavam flex-wrap/flex num container GRID
   (.compose-schedule__row é display:grid): não valiam nada. */
#bip-schedule-wrap.is-open:not([hidden]) .compose-schedule__row {
    grid-template-columns: minmax(0, 1fr);
}

.compose-schedule__modes {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.compose-schedule__mode-btn {
    flex: 1 1 auto;
    /* Sem isto a pílula não podia encolher abaixo do próprio texto (nowrap) e
       vazava do painel em tela estreita, em vez de quebrar linha. */
    min-width: 0;
    max-width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-2);
    color: var(--text-2);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
    /* Cinto de segurança: se um dia não couber (tela minúscula, fonte grande),
       a pílula corta com "…" em vez de invadir o campo vizinho. */
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
    transition: border-color var(--duration), background var(--duration), color var(--duration);
}

.compose-schedule__mode-btn:hover { border-color: var(--border-hover); color: var(--white); }

.compose-schedule__mode-btn.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 700;
}

/* Colapsada, a ativa ganha um ▾ discreto: dá pra clicar e trocar. */
.compose-schedule__mode-btn.is-active::after {
    content: ' ▾';
    font-size: 0.75em;
    opacity: 0.7;
}

.compose-schedule__mode-btn[hidden] { display: none !important; }

/* Caixa da cidade (fallback do GPS). */
/* MAIS LARGA, PARA OS TRÊS BOTÕES CABEREM NA LINHA (17/09/26, defeito do dono:
   *"deixar essa caixa web (desktop) mais larga, está quebrando o botão
   localização atual"*). Em 380px, "Localização atual" + "Remover cidade" +
   "Salvar" estouravam a fila e o primeiro vazava para fora da caixa. 460px é o
   que os três medem com o respiro de 8px entre eles; no celular a caixa segue
   pela largura da tela (o `max-width` só limita). */
.compose-city-modal__panel { max-width: 460px; }

/* E se um idioma alongar os rótulos, a fila QUEBRA em vez de vazar: o pior
   desfecho aqui é o botão sair da caixa, não ele descer uma linha. */
.compose-city-modal__actions { flex-wrap: wrap; }

.compose-city-modal__head { text-align: center; margin-bottom: 14px; }

.compose-city-modal__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: rgba(239, 68, 68, 0.12);
    color: #ef4444;
    font-size: 1.6rem;
    margin-bottom: 10px;
}

.compose-city-modal__title {
    font-size: 1.1rem;
    margin-bottom: 4px;
}

.compose-city-modal__desc {
    font-size: 0.85rem;
    color: var(--text-2);
    margin: 0;
}

.compose-city-modal__actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 14px;
}

.compose-editor-box__emoji {
    position: absolute;
    right: 10px;
    /* Respiro da borda de baixo — sem colar na linha. */
    bottom: 12px;
    margin-left: 0;
}

/* Caixas de ação estilo app: Agendar/Enquete/Foto em grade de 2 colunas. */
.compose-action-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-top: 10px;
}

.compose-action-box {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-radius: 14px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--white);
    font-family: var(--font);
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    transition: border-color var(--duration), color var(--duration);
}

.compose-action-box > i:first-child,
.compose-action-box > svg:first-child {
    color: var(--accent);
    font-size: 18px;
    flex-shrink: 0;
}

.compose-action-box span {
    flex: 1;
    text-align: left;
}

.compose-action-box__plus {
    color: var(--text-3);
    font-size: 16px;
}

.compose-action-box:hover {
    border-color: var(--border-hover);
}

.compose-action-box[aria-pressed="true"] {
    border-color: var(--accent);
    color: var(--accent);
}

/* Cores do "Público" na caixa: verde público, azul seguidores, âmbar só eu. */
.compose-action-box.bip-vis-cycle--public > i:first-child { color: var(--green); }
.compose-action-box.bip-vis-cycle--followers > i:first-child { color: var(--accent); }
.compose-action-box.bip-vis-cycle--connected > i:first-child { color: var(--accent); }
.compose-action-box.bip-vis-cycle--private > i:first-child { color: #fbbf24; }

/* Modo ENQUETE = foco (08/08/26, pedido do dono): somem os chips do
   cabeçalho (globo/comentários/tópico), as pílulas de partes e os ícones
   que não são da enquete. O alarme de agendar fica — o mesmo de texto e foto. */
.compose-modal--poll .compose-identity__chips,
.compose-modal--poll .compose-parts,
.compose-modal--poll #btn-bip-visibility {
    display: none;
}

/* `.compose-addbar__label` saiu desta lista em 29/08/26: o rótulo deixou de
   existir no HTML, então não há mais o que esconder aqui. */
.compose-modal--poll #btn-bip-poll,
.compose-modal--poll #btn-bip-image,
.compose-modal--poll .bip-gif-wrap,
.compose-modal--poll .bip-emoji-wrap,
/* O VÍDEO TAMBÉM SAI (10/09/26, ordem do dono: *"estando no modo enquete não faz
   sentido ter o vídeo, favor ocultar"*): um vídeo do YouTube dentro de uma enquete
   disputa a atenção com as opções, que é o que a pessoa tem de ler para votar. */
/* O CHECK IN SAI DA ENQUETE (13/09/26, ordem do dono: "remove o check in das
   enquetes"). */
.compose-modal--poll .compose-modal--poll #btn-bip-youtube {
    display: none;
}

/* NA ENQUETE A BARRA DE ÍCONES SAI INTEIRA (12/10/26, ordem do dono: "tirar todos estes ícones,
   não tem sentido"). A lista de cima falhava em silêncio: o seletor do YouTube veio duplicado, o
   GIF mudou de lugar (#btn-bip-gif) e a música nunca entrou. Agendar mora na seta do Postar Bip. */
.compose-modal--poll .compose-addbar {
    display: none !important;
}

/* ══ EM ENQUETE, O ALARME OCUPA O LUGAR DO "Aa" (29/08/26) ═════════════════
   Ordem do dono: *"tire o seletor de cor em caso de enquetes e coloque o ícone
   de agendamento lá no lugar do seletor de cor — com isso vamos salvar o espaço
   da barra abaixo"*.

   Enquete não tem cartão colorido (o fundo é a caixa de opções), então o "Aa"
   ali era um botão que não fazia nada. E a barra de baixo, com os outros ícones
   já escondidos, virava uma caixa vazia com um alarme no canto — uma linha
   inteira de altura para um botão.

   Some o "Aa", e a barra sobe para a vaga dele: `order: 1` a põe logo depois da
   área do cartão e ANTES da caixa de opções (que é `order: 2`), que é
   exatamente onde o "Aa" estava. Sem borda e sem padding, ela deixa de parecer
   caixa e vira o que é agora: um ícone solto. */
/* O aviso de enquete travada (29/08/26) — discreto, do tamanho de nota de
   rodapé: ele explica, não repreende. */
.compose-poll__aviso {
    margin: 8px 0 0;
    font-size: 0.82rem;
    line-height: 1.4;
    color: var(--text-2);
}

/* Enquete não tem cartão colorido — some a âncora do painel E o gatilho, que
   desde 08/09/26 mora na fileira de ícones e não cai mais junto com o wrap. */
.compose-modal--poll .compose-estilo,
.compose-modal--poll .compose-add-btn--estilo {
    display: none;
}

.compose-modal--poll .compose-addbar {
    order: 1;
    justify-content: flex-start;
    border: none;
    padding: 0;
    margin-bottom: 0;
}

.compose-modal--poll .compose-addbar__icons {
    flex: 0 0 auto;
    justify-content: flex-start;
}

/* Pergunta → opções → alarme (o mesmo lugar da barra em texto/foto) → BiPar. */
.compose-modal--poll .compose-editor-box { order: 1; }
.compose-modal--poll .compose-poll { order: 2; }
.compose-modal--poll .compose-modal__footer { order: 4; }

/* Com imagem anexada as caixas viram SÓ ícones (modal estável). */
.compose-modal--has-image .compose-action-grid {
    display: flex;
    gap: 8px;
}

/* Com foto o globo entra na FILEIRA de ícones (o JS o move para cá): vira uma
   caixa como as outras — uma linha só. No modo texto ele volta ao rodapé, solto.
   Sem isto o 22x22 fixo do .bip-vis-cycle esmagaria a caixa. */
.compose-action-grid .bip-vis-cycle {
    width: auto;
    height: auto;
    margin-left: 0;
}

/* Com foto o Cancelar/BiPar sobe para a MESMA fileira (o JS os move para cá) e
   encosta à direita, com os ícones à esquerda. O rodapé fica vazio e colapsa
   sozinho — ele não tem padding nem borda próprios. */
.compose-action-grid .compose-modal__actions {
    margin-left: auto;
}

/* Cortando a foto: Cancelar/BiPar somem — a decisão do momento é UMA só (Ok).
   Menos botões, zero confusão; o × da foto desfaz o corte.
   Os DOIS seletores são necessários: com foto o JS move o .compose-modal__actions
   para dentro da fileira de ícones, então esconder só o rodapé deixaria de
   alcançá-los justamente no caso em que há corte (que só existe com foto). */
.compose-modal--cropping .compose-modal__footer,
.compose-modal--cropping .compose-modal__actions {
    display: none;
}

/* Campo Título (estilo fórum): oculto por padrão, aparece só no modo comunidade. */
.compose-community-title { display: none; }
.compose-modal--community .compose-community-title { display: block; margin-bottom: 10px; }
/* TÓPICO = só a pergunta: o campo de título some (a seção continua com título). */
.compose-modal--community.compose-modal--topic .compose-community-title { display: none; }
.compose-community-title__input {
    width: 100%;
    font-size: 1.05rem;
    font-weight: 600;
}

/* ── MODO FÓRUM (21/08/26, ordem do dono: *"isso aí era para o bip, aqui é o
   fórum e vamos fazer cara de fórum: aceitar emoji, GIF, nada de localização,
   sim para foto e sim para enquete, nada de BiPTag"*) ────────────────────────

   O comentário antigo dizia que a cidade e o assunto já estavam de fora — não
   estavam. `.compose-head-row` some, mas o chip do **BiPTag** e o botão de
   **Cidade** vivem noutros contêineres e continuavam na tela; foi o que apareceu
   no print. Comentário que descreve a intenção em vez do que o seletor alcança
   é pior do que comentário nenhum: ele faz a próxima leitura pular a conferência.

   POR QUE CADA UM SAI, que é o critério e não o gosto:
     - **BiPTag** é a taxonomia do FEED, para achar o assunto na rede inteira.
       Dentro de uma comunidade o assunto já É a comunidade — a etiqueta não
       classifica nada e ainda joga o tópico numa busca global onde ele não tem
       contexto.
     - **Cidade** é o mesmo caso: comunidade não tem lugar.
     - **Agendar** e **visibilidade** não fazem sentido num fórum: quem manda em
       quem vê é a comunidade.

   O QUE FICA, e por quê: **texto, foto, enquete, GIF e emoji**. Todos servem
   para dizer melhor a mesma coisa — que é do que um tópico precisa. */
.compose-modal--community .compose-head-row,
.compose-modal--community #btn-bip-lock,
.compose-modal--community #btn-bip-schedule,
.compose-modal--community .compose-submit-split__more,
.compose-modal--community #bip-schedule-wrap,
.compose-modal--community .bip-compose-meta,
.compose-modal--community .compose-topic-chip-wrap,
/* O pino saiu da barra em 10/09/26; na comunidade quem se esconde agora é o
   chip do cabeçalho — post de comunidade não leva lugar. */
.compose-modal--community #bip-city-inline,
/* com foto o JS move o globo para dentro da grade — some nos dois lugares */
.compose-modal--community #btn-bip-visibility {
    display: none !important;
}

/* Grade só com Enquete + Foto: duas caixas, mesma largura das outras telas. */
.compose-modal--community .compose-action-grid {
    grid-template-columns: repeat(2, 1fr);
}

.compose-modal--community .compose-submit-split .compose-modal__submit--big {
    width: 100%;
    border-top-right-radius: 10px !important;
    border-bottom-right-radius: 10px !important;
}

/* COM FOTO, SEM ENQUETE (13/09/26, ordem do dono: "não faz sentido deixar algo
   que vai trazer um problema"). A enquete só aparecia apagada e a pessoa ainda
   tentava, até levar "Enquete não pode ter foto". Agendar segue ativo, bip com
   foto também agenda (2026-07-20). */
.compose-modal--has-image #btn-bip-poll {
    display: none !important;
}

.compose-modal__actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto; /* BiPar sempre à direita, mesmo sem o globo de visibilidade */
}

.compose-modal--has-image .compose-action-box span,
.compose-modal--has-image .compose-action-box__plus {
    display: none;
}

.compose-modal--has-image .compose-action-box {
    padding: 10px 12px;
}

/* Aviso do descomissionamento do chat (5s, some sozinho). */
.chat-sunset-notice {
    position: fixed;
    left: 50%;
    bottom: 24px;
    z-index: 10200;
    display: flex;
    align-items: flex-start;
    gap: 10px;
    max-width: min(560px, 92vw);
    padding: 14px 18px;
    border-radius: 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-md);
    color: var(--text);
    font-size: 0.92rem;
    line-height: 1.45;
    transform: translate(-50%, 16px);
    opacity: 0;
    transition: opacity var(--duration) var(--ease), transform var(--duration) var(--ease);
}

.chat-sunset-notice.is-visible {
    opacity: 1;
    transform: translate(-50%, 0);
}

.chat-sunset-notice i {
    color: var(--accent);
    font-size: 20px;
    flex-shrink: 0;
}

.chat-sunset-notice p {
    margin: 0;
}

.chat-sunset-notice a {
    color: var(--accent);
    font-weight: 600;
}

/* Autocomplete canônico (assunto/cidade): sugere valores JÁ usados na rede. */
.compose-topic,
.compose-location {
    position: relative;
}

.compose-suggest {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 40;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: var(--shadow-md);
    overflow: hidden;
}

.compose-suggest[hidden] {
    display: none;
}

.compose-suggest__item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 9px 14px;
    background: none;
    border: none;
    color: var(--text);
    font-size: 0.92rem;
    font-family: var(--font);
    text-align: left;
    cursor: pointer;
}

.compose-suggest__item:hover {
    background: var(--surface-2);
}

.compose-suggest__item span {
    color: var(--text-3);
    font-size: 0.8rem;
}

.compose-modal__textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 1px rgba(79, 142, 247, 0.25);
}

.compose-modal__textarea--readonly {
    opacity: 0.72;
    cursor: default;
}

.compose-modal__footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    overflow: visible;
}

.compose-modal__submit {
    min-width: 96px;
}

.compose-modal__counter {
    font-size: 0.8rem;
    color: var(--text-3);
}

/* Abre ABAIXO da caixa "Agendar" (o dropdown nativo cai sobre o rodapé,
   nunca por cima das caixas de ação) — com respiro embaixo. */
.compose-schedule {
    margin-top: 10px;
    padding: 12px 0 6px;
    border-top: 1px solid var(--border);
}

.compose-schedule__checkbox {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.compose-schedule__field--hidden,
.compose-schedule__field[hidden],
.compose-schedule__col-secondary[hidden] {
    display: none !important;
}

.compose-schedule__panel {
    display: grid;
    gap: 10px;
}

.compose-schedule__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 10px;
    align-items: start;
}

.compose-schedule__row:has(#bip-schedule-secondary-wrap[hidden]) {
    grid-template-columns: 1fr;
}

.compose-schedule__col-secondary {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.compose-schedule__col-secondary .compose-schedule__field {
    width: 100%;
}

.compose-schedule__field--mode {
    min-width: 0;
}

.compose-schedule__tz-note {
    margin: 4px 0 0;
    font-size: 0.75rem;
    color: var(--text-3);
    text-align: center;
}

.compose-schedule__tz-note[hidden] {
    display: none !important;
}

.compose-schedule__anchor-wrap {
    display: flex;
    justify-content: center;
    margin: 0 0 4px;
}

.compose-schedule__anchor-wrap[hidden] {
    display: none !important;
}

.compose-schedule__anchor {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    padding: 5px 12px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    line-height: 1.2;
    white-space: nowrap;
}

.compose-schedule__anchor-label {
    font-size: 0.68rem;
    font-weight: 600;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.compose-schedule__anchor-dot {
    color: var(--text-3);
    opacity: 0.45;
    font-size: 0.7rem;
    line-height: 1;
}

.compose-schedule__anchor-time {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text);
    font-variant-numeric: tabular-nums;
}

.bip-schedule-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin-left: 2px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--text-3);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0.72;
    transition: color var(--duration), opacity var(--duration), transform var(--duration);
}

.bip-schedule-toggle:hover {
    opacity: 1;
    transform: scale(1.08);
}

.bip-schedule-toggle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.bip-schedule-toggle.is-active {
    color: #f59e0b;
    opacity: 1;
}

.bip-schedule-toggle.is-active:hover {
    color: #fbbf24;
}

.compose-schedule__field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.compose-schedule__label {
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.compose-schedule__select,
.compose-schedule__datetime {
    width: 100%;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    font-family: inherit;
    font-size: 0.85rem;
    padding: 8px 10px;
}

.compose-schedule__select:focus,
.compose-schedule__datetime:focus {
    outline: none;
    border-color: var(--accent);
}

/* Agendamento em passos (11/08/26, 2ª volta): Hoje/Outro dia → grade de dias →
   AM/PM, hora e minutos. NADA rola de lado: cada passo cabe inteiro na folha. */
.compose-schedule__picker {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}

.sched-pills {
    display: flex;
    gap: 6px;
    min-width: 0;
    flex-wrap: wrap;
}

/* Linhas que dividem o espaço por igual (Hoje/Outro dia, AM/PM, minutos). */
.sched-pills--fill .sched-pill {
    flex: 1 1 0;
}

.sched-days {
    display: flex;
    flex-direction: column;
    gap: 6px;
    /* 30 dias em 7 colunas = 5 linhas + os 2 nomes de mês. O teto é medido para
       caber tudo isso SEM rolar; em tela muito baixa a lista rola dentro da
       própria caixa, nunca a folha inteira. */
    max-height: 280px;
    overflow-y: auto;
    scrollbar-width: thin;
}

.sched-month {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-top: 2px;
}

/* Dias e horas em grade: linha cheia, sem sobra e sem corte nas bordas. */
.sched-daygrid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 5px;
}

.sched-hourgrid {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 5px;
}

/* O `.sched-time` de coluna (picker de pílulas) saiu em 30/08/26: ninguém o
   usava mais e o nome colidia com as caixas de hora/minuto lá embaixo — que
   nasciam empilhadas por causa dele. */

.sched-pill {
    min-width: 0;
    padding: 8px 6px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-2);
    color: var(--text-2);
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color var(--duration), background var(--duration), color var(--duration);
}

/* "Hoje" e "Outro dia" pedem mais ar do que um número de dia. */
.sched-pill--wide {
    padding: 10px 12px;
}

.sched-pill:hover {
    border-color: var(--border-hover);
    color: var(--white);
}

.sched-pill.is-active {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 700;
}

/* "terça-feira, 11 de agosto, às 10:30" — o retrato da escolha. */
.sched-summary {
    /* Menor e mais APAGADO (31/08/26, dono: "tem muito elemento numa caixa
       pequena") — é conferência, não protagonista. O JS quebra em 2 linhas. */
    font-size: 0.76rem;
    font-weight: 500;
    line-height: 1.4;
    color: var(--text-2);
    text-align: center;
    margin-top: 6px;
}

/* ── HORÁRIO DE ONDE? (31/08/26) — a dupla local/BR acima da roda. Só aparece
   para quem está fora do fuso de São Paulo (schedTzInit decide). */
.sched-tz {
    /* Bandeira e relógio vivo (01/09/26, dono) — o "HORÁRIO DE" morreu:
       bandeira + hora atual dizem tudo sozinhas.
       AO CENTRO desde 10/09/26 (dono: *"centralizar caixa uk / br"*): a linha
       do "último agendamento", logo acima, já é centrada, e a dupla encostada
       na esquerda quebrava o eixo do cabeçalho da folha. */
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin: 2px 0 10px;
}

.sched-tz__flag {
    font-size: 1rem;
    margin-right: 6px;
}

img.sched-tz__flag {
    width: 20px;
    height: auto;
    border-radius: 3px;
    display: inline-block;
}

.sched-tz__seg {
    display: inline-flex;
    border: 1px solid var(--border);
    border-radius: 999px;
    overflow: hidden;
    background: var(--surface-2);
}

.sched-tz__opt {
    appearance: none;
    border: 0;
    background: transparent;
    padding: 6px 14px;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text-2);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    font-variant-numeric: tabular-nums;
}

.sched-tz__opt.is-on {
    background: var(--accent);
    color: #fff;
}

/* A RODA do agendamento (15/08/26 · reformada 30/08/26, ordem do dono: *"este
   slider não funcionou, está horrível — transforme este campo em um input e a
   pessoa insere os valores… a data deixei como está"*).

   Sobrou UMA coluna rolável, o DIA. Hora e minuto viraram duas caixas de dois
   dígitos ao lado. A máscara que esmaece as pontas desceu para o `__pane` do
   dia: aplicada no container inteiro, ela comia o topo e a base dos inputs. */
/* GRADE 2×4 (31/08/26, dono: "o Hoje tem que estar alinhado com a hora; DIA
   sobre o dia, à esquerda da caixa, como HORA"): linha 1 = rótulos; linha 2 =
   roda + caixas. O align-items:center da linha de 162px põe as caixas de hora
   NA MESMA ALTURA da linha escolhida da roda — é o alinhamento que faltava. */
.sched-wheel {
    display: grid;
    grid-template-columns: minmax(0, 1fr) max-content max-content max-content;
    column-gap: 10px;
    row-gap: 4px;
    /* start, não center: a linha ESCOLHIDA agora mora no TOPO do painel
       (31/08/26) — as caixas de hora alinham com ela pelo topo. */
    align-items: start;
    margin: 4px 0 10px;
}

.sched-wheel__pane {
    /* ESPELHO ZERO (10/09/26): a altura da linha passou a ser VARIÁVEL, e o JS
       a lê daqui com getComputedStyle. O número morava em três lugares do CSS
       e mais dois do JS (SCHED_ROW_H, RS_ROW_H); divergir não dá erro nenhum no
       console — a roda simplesmente escolhe uma linha e mostra outra. Os
       valores abaixo são os de sempre: a roda do DIA não anda um pixel. */
    --sched-row: 54px;
    /* UMA LINHA SÓ (10/09/26, ordem do dono: *"tem como manter o mesmo modo,
       mas sem exibir as linhas abaixo, só a atual mesmo?"*).

       De 31/08 até aqui eram DUAS: a escolhida no topo e o próximo dia
       espiando embaixo, para deixar claro que aquilo rola. A prévia cumpriu o
       papel e virou ruído — três rodas na mesma folha, cada uma exibindo o que
       NÃO foi escolhido, é mais texto pálido do que informação. Fica o valor,
       e só ele.

       A MÁSCARA SAIU JUNTO: ela esmaecia a metade de baixo do painel, que era
       a linha de prévia. Com uma linha só, ela apagaria justamente o valor
       escolhido. */
    --sched-linhas: 1;
    position: relative;
    min-width: 0;
    height: calc(var(--sched-row) * var(--sched-linhas));
}

.sched-wheel__col {
    flex: 1;
    height: 100%;
    overflow-y: auto;
    scroll-snap-type: y mandatory;
    /* Respiro só EMBAIXO (31/08/26): o item escolhido assenta no TOPO do
       painel (scrollTop = i×linha continua valendo), e o último dia ainda
       consegue subir até lá. O respiro é o painel MENOS uma linha — com o
       número cravado em 54 ele só valia para painel de 2 linhas. */
    padding: 0 0 calc(var(--sched-row, 54px) * (var(--sched-linhas, 2) - 1));
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

/* AS CAIXAS (30/08/26). Fundo `--surface-3` sobre o painel `--surface`: caixa
   nunca tem a cor do fundo (padrão de contraste da casa). 1rem+ no input para
   o iOS não dar zoom ao focar. */
/* .sched-time/.sched-time__box/.sched-time__cap MORRERAM em 31/08/26: a grade
   do .sched-wheel assumiu o alinhamento — rótulos são .sched-cap. */

.sched-time__input {
    width: 74px;
    max-width: 100%;
    height: 54px;
    padding: 0;
    text-align: center;
    font-size: 1.45rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.06em;
    color: var(--text);
    background: var(--surface-3);
    border: 1px solid var(--border);
    border-radius: 12px;
    outline: none;
    transition: border-color .15s ease, box-shadow .15s ease;
}

.sched-time__input::placeholder {
    color: var(--text-3);
}

.sched-time__input:hover {
    border-color: var(--border-hover);
}

.sched-time__input:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px rgba(64, 112, 176, 0.22);
}

.sched-time__sep {
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--text-3);
    /* A grade alinha pelo topo agora — o line-height centra o ":" na linha
       de 54px, a mesma das caixas. */
    line-height: 54px;
    align-self: start;
}

/* Celular estreito: as caixas encolhem para o dia não virar reticências. */
@media (max-width: 430px) {
    .sched-wheel { gap: 8px; }

    .sched-time__input {
        width: 58px;
        height: 50px;
        font-size: 1.2rem;
    }

    /* O separador é centrado pela grade — sem line-height por tamanho. */

    /* "seg., 31 de ago." pedia 151px numa coluna de 150 — um fio de
       reticências. Meio ponto de fonte a menos resolve sem apertar o resto. */
    .sched-wheel__item { font-size: 0.88rem; }
}

.sched-wheel__col::-webkit-scrollbar {
    display: none;
}

.sched-wheel__col--dia {
    flex: 1;
}

.sched-wheel__item {
    /* 54px: a MESMA espessura das caixas de HORA/MINUTO (31/08/26, dono). O
       número mora só aqui desde 10/09/26 — o JS lê a variável. */
    height: var(--sched-row, 54px);
    line-height: var(--sched-row, 54px);
    text-align: center;
    /* start: o imã agora puxa para o TOPO do painel, onde vive a escolhida. */
    scroll-snap-align: start;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sched-wheel__focus {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: var(--sched-row, 54px);
    border-radius: 12px;
    background: rgba(79, 142, 247, 0.10);
    border: 1px solid var(--border);
    pointer-events: none;
}

/* ── AS DUAS FILEIRAS DE ATALHO VIRARAM DUAS RODAS (10/09/26, ordem do dono
   a partir da ideia de um usuário: *"faça uma roda como essa do dia para o EM
   e para o AS, isso faz sentido, pois será só uma caixa cada e dá para ficar
   até em 1 só linha"*).

   O pedido veio junto com o outro: *"agora teremos todas as horas de 05h até
   00, favor incluir as que faltam"* e *"incluir no EM 4h, 5h, 12h, 36h, 72h"*.
   Com isso o "Em:" foi de 7 para 12 opções e o "Às:" de 7 para 20 — em pílula
   isso seria uma parede de quatro fileiras, que é justamente o "visual poluído"
   que ele mandou matar. Uma CAIXA cada, as duas na MESMA linha.

   A conta fecha até em 320px: o painel do post é min(500px, 94vw) com 20 de
   respiro, sobram ~176px por caixa em 430px de tela e ~79px de coluna útil em
   320px — "30m" pede uns 34px. As duas NUNCA empilham. O que não cabe é juntar
   os atalhos com a roda do dia na mesma linha: ela sozinha pede ~210px para
   "seg., 31 de ago.".

   Linha de 44px contra os 54 da roda do dia: o atalho é secundário e 44 é o
   piso de um alvo de toque. Painel de 3 linhas porque a régua tem 20 horas —
   em 2 linhas, chegar nas 19h seria rolar dez telas. */
/* O RÓTULO DOS BLOCOS e as duas RODAS DE ATALHO (.sched-atalho*) foram
   apagados em 10/09/26, horas depois de nascerem: *"o calendário ficou tão
   lindo que podemos tirar a UI e lógica do Em e Às"*. Quem agenda hora agora é
   o calendário; a folha ficou com uma roda só, e um rótulo sobre uma roda só é
   texto a mais. */

/* A HORA JÁ TOMADA (10/09/26): o resumo troca de assunto e diz o motivo — é a
   linha que acompanha o botão Agendar trancado. Vermelho de aviso, não de erro
   fatal: a pessoa muda a hora e segue. */
.sched-summary--tomada {
    color: var(--danger, #d64545);
    font-weight: 600;
}

/* E O BOTAO TRANCADO TEM DE PARECER TRANCADO (10/09/26): o motivo ja esta ao
   lado, mas o dedo tenta antes de ler — sem isto o Agendar fica identico ao
   vivo e o clique some no vazio. Nao havia estilo de :disabled para .btn nesta
   casa; aqui ele nasce onde faz falta, nas duas folhas (post e resposta). */
.compose-schedule__actions .btn:disabled,
.bip-reply-sched__actions .btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.sched-summary::first-letter {
    text-transform: uppercase;
}

.compose-modal__editor.bip-compose--focus .compose-modal__textarea {
    border-color: var(--accent);
    box-shadow: 0 0 0 1px rgba(79, 142, 247, 0.35);
}

.bip-replies-wrap {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid rgba(255, 255, 255, 0.14);
}

.bip-replies-panel { display: flex; flex-direction: column; gap: 0; }

.bip-replies-toolbar {
    display: flex;
    align-items: center;
    padding: 0 0 8px;
}

.bip-replies-tree {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.bip-replies-tree > .bip-reply-branch {
    padding: 12px 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.bip-replies-tree > .bip-reply-branch:last-child {
    border-bottom: none;
}

/* Prévia inline no feed — 1 resposta, sub-bloco do CARTÃO (21/07/26): o grid
   antigo com linha vertical morreu junto com o avatar-à-esquerda; a resposta
   vira um bloco recuado abaixo do rodapé, separado por um divisor fino. */
.bip-card--inline-reply > .bip-inline-reply {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    margin-top: 10px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}

.bip-card--inline-reply > .bip-inline-reply > .bip-card__avatar {
    width: 34px;
    height: 34px;
    font-size: 0.95rem;
    flex-shrink: 0;
}

.bip-inline-reply__body {
    flex: 1;
    min-width: 0;
}

.bip-inline-reply__body .bip-card__text {
    cursor: pointer;
}

.bip-inline-reply__body .bip-card__text:hover {
    color: var(--white);
}

.bip-reply-modal__context {
    margin-bottom: 0;
}

.tool-modal--reply .tool-modal__backdrop {
    background: rgba(8, 8, 8, 0.52);
    backdrop-filter: blur(3px);
}

.bip-reply-modal__loading {
    text-align: center;
    color: var(--text-3);
    padding: 24px 0;
    font-size: 1.4rem;
}

.bip-reply-modal__post {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    /* Respiro à direita: o texto encostava no botão X do modal (21/07/26). */
    padding-right: 34px;
}

/* Foto no modal de resposta (21/07/26): mais larga e CENTRALIZADA na coluna —
   a regra do cartão não alcança aqui (classes próprias do modal). */
.bip-reply-modal__post-text .bip-content-image-wrap {
    max-width: 100%;
    width: fit-content;
    margin-left: auto;
    margin-right: auto;
}

.bip-reply-modal__post-text .bip-content-image {
    max-height: 480px;
}

.bip-reply-modal__avatar-link {
    flex-shrink: 0;
    text-decoration: none;
    color: inherit;
    border-radius: var(--radius);
    transition: opacity var(--duration);
}

.bip-reply-modal__avatar-link:hover {
    opacity: 0.88;
}

.bip-reply-modal__avatar {
    width: 42px;
    height: 42px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius);
    background: var(--surface-2);
    color: var(--text-3);
    font-size: 1.2rem;
    overflow: hidden;
}

.bip-reply-modal__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.bip-reply-modal__post-body {
    flex: 1;
    min-width: 0;
}

.bip-reply-modal__post-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    line-height: 1.3;
}

.bip-reply-modal__author {
    color: var(--white);
    font-weight: 600;
    font-size: 0.92rem;
    text-decoration: none;
}

.bip-reply-modal__author:hover {
    color: var(--accent);
    text-decoration: underline;
}

.bip-reply-modal__time {
    color: var(--text-3);
    font-size: 0.78rem;
    font-weight: 400;
}

.bip-reply-modal__post-text {
    margin-top: 6px;
    font-size: 0.95rem;
    line-height: 1.5;
    color: var(--text);
    word-break: break-word;
    white-space: pre-wrap;
}

.bip-reply-modal__post-text .bip-content-image-wrap {
    margin-top: 8px;
    max-width: 100%;
}

.bip-reply-compose--modal {
    margin-top: 14px;
}

/* Caixa de resposta ENXUTA na abertura (~2 linhas) — o JS faz auto-grow enquanto digita. */
.bip-reply-compose--modal .compose-modal__textarea {
    min-height: 58px;
}

.bip-reply-modal__input-box {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--bg-2);
    overflow: hidden;
}

.bip-reply-modal__input {
    width: 100%;
    height: 112px;
    min-height: 112px;
    max-height: 112px;
    resize: none;
    overflow-y: auto;
    border: none;
    background: transparent;
    color: var(--text);
    font-family: inherit;
    font-size: 0.95rem;
    line-height: 1.5;
    padding: 14px 16px;
    outline: none;
    display: block;
    box-sizing: border-box;
    transition: box-shadow var(--duration);
}

.bip-reply-modal__input:focus {
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 45%, var(--border));
}

.bip-reply-modal__input::placeholder {
    color: var(--text-3);
}

.bip-reply-modal__input-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 12px 10px;
    border-top: 1px solid var(--border);
    background: color-mix(in srgb, var(--surface-2) 55%, transparent);
}

.bip-reply-modal__vis-btn {
    margin: 0;
    flex-shrink: 0;
}

.bip-reply-modal__input-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
    flex-shrink: 0;
}

.bip-reply-modal__counter {
    font-size: 0.78rem;
    color: var(--text-3);
    font-variant-numeric: tabular-nums;
    transition: color var(--duration);
    user-select: none;
}

.bip-reply-modal__counter--warn {
    color: #fbbf24;
}

.bip-reply-modal__counter--limit {
    color: var(--red);
}

.bip-reply-compose__counter {
    margin-left: auto;
    margin-right: 4px;
}

.bip-reply-modal__send {
    width: 38px;
    height: 38px;
    border: none;
    border-radius: var(--radius);
    background: var(--btn-azul);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.1rem;
    cursor: pointer;
    flex-shrink: 0;
    transition: filter var(--duration), transform var(--duration);
}

.bip-reply-modal__send:hover {
    filter: brightness(1.08);
}

.bip-reply-modal__send:active {
    transform: scale(0.96);
}

body.bip-reply-modal-open {
    overflow: hidden;
}

.bip-thread-branch {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.bip-thread-branch__nested {
    display: flex;
    flex-direction: column;
    gap: 0;
    margin-left: 40px;
    padding-left: 0;
    border-left: none;
}

/* —— Ramo de discussão (árvore de respostas) —— */
.bip-reply-branch {
    position: relative;
}

/* Chegou pela notificação (#reply-N): SEM destaque azul (removido a pedido do
   dono, 21/07/26 — o fundo colava no avatar e comia as margens). A rolagem até
   o comentário + composer focado já dizem "é esta aqui"; o JS ainda aplica a
   classe .bip-reply--focused, de propósito sem estilo. */

.bip-reply-row {
    display: flex;
    gap: 10px;
    align-items: flex-start;
}

.bip-reply__avatar-wrap {
    flex-shrink: 0;
    width: 34px;
}

.bip-reply-item {
    display: flex;
    gap: 10px;
    align-items: flex-start;
}

.bip-reply__avatar--nested,
.bip-reply-item--nested .bip-reply__avatar,
.bip-reply-branch--nested .bip-reply__avatar {
    width: 28px;
    height: 28px;
    font-size: 1rem;
}

.bip-reply-branch--nested .bip-reply__avatar-wrap {
    width: 28px;
}

.bip-reply__avatar {
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text-3);
    font-size: 1.15rem;
    overflow: hidden;
}

.bip-reply__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.bip-reply__col {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Geometria ÚNICA da árvore (21/07/26): mesmo recuo da Discussão; a linha reta
   antiga deu lugar aos conectores curvos estilo YouTube (abaixo). */
.bip-reply__follow {
    margin-left: 40px;
    padding-left: 0;
    border-left: none;
    margin-top: 2px;
}

.bip-reply__follow > .bip-reply-branch {
    padding-top: 12px;
}

/* Nível 2+ achatado (como na Discussão): recuar sem fim comia a largura. */
.bip-reply__follow .bip-reply__follow {
    margin-left: 0;
}

/* ── Conectores estilo YouTube (21/07/26, pedido do dono) ─────────────────
   Tronco desce do avatar do PAI e uma curva suave entra em cada resposta.
   Sutil (cor da borda, 2px), e só com o ramo ABERTO — fechado, nada aparece.
   Só no 1º nível de recuo: do 2º em diante a árvore é achatada. */
.bip-reply-branch:has(> .bip-reply__follow:not([hidden])) > .bip-reply-row {
    position: relative;
}

/* Tronco: do pé do avatar do pai (34px, centro x=17) até o vão do primeiro filho. */
.bip-reply-branch:has(> .bip-reply__follow:not([hidden])) > .bip-reply-row::before {
    content: '';
    position: absolute;
    left: 16px;
    top: 40px;
    bottom: -4px;
    width: 2px;
    border-radius: 2px;
    background: var(--bip-thread-line, color-mix(in srgb, var(--text-3) 42%, transparent));
}

.bip-reply__follow > .bip-reply-branch {
    position: relative;
}

/* A CURVA: continua o tronco e dobra até o centro do avatar do filho. */
.bip-reply__follow > .bip-reply-branch::before {
    content: '';
    position: absolute;
    left: -24px;
    top: 0;
    width: 24px;
    height: 28px;
    border-left: 2px solid var(--bip-thread-line, color-mix(in srgb, var(--text-3) 42%, transparent));
    border-bottom: 2px solid var(--bip-thread-line, color-mix(in srgb, var(--text-3) 42%, transparent));
    border-bottom-left-radius: 16px;
    pointer-events: none;
}

/* Irmão que não é o último: o tronco segue descendo para o próximo. */
.bip-reply__follow > .bip-reply-branch:not(:last-child)::after {
    content: '';
    position: absolute;
    left: -24px;
    top: 0;
    bottom: 0;
    width: 2px;
    border-radius: 2px;
    background: var(--bip-thread-line, color-mix(in srgb, var(--text-3) 42%, transparent));
    pointer-events: none;
}

/* Nível 2+ (achatado, sem recuo): sem curva e sem tronco pendurado. */
.bip-reply__follow .bip-reply__follow > .bip-reply-branch::before,
.bip-reply__follow .bip-reply__follow > .bip-reply-branch::after,
.bip-reply__follow .bip-reply-branch > .bip-reply-row::before {
    display: none;
}

.bip-reply__follow .bip-reply-branch {
    padding-top: 0;
    border-bottom: none;
}

.bip-reply-branch--composing .bip-reply__avatar-wrap::after {
    display: none;
}

.bip-reply__bubble {
    padding: 0;
    background: none;
    border: none;
    border-radius: 0;
}

.bip-reply__top {
    display: flex;
    align-items: flex-start;
    gap: 4px;
}

/* A PÍLULA DA RELAÇÃO no comentário (01/09/26, dono: *"não tem como saber se a
   pessoa é ou não amigo"*). Menor que a do cartão — aqui ela divide a linha com
   nome, selo e hora —, mesma escada de cores.

   O `.bip-reply__top` solto que vivia antes deste comentário SAIU (11/09/26):
   ele fazia do seletor `.bip-reply__top .bip-reply__follow-btn`, e a base
   nunca chegava ao fórum da comunidade (`.cf-resp__linha`), onde a pílula saía
   como botão nativo. Pílula preta do aipim, como no cartão. */
.bip-reply__follow-btn {
    margin-left: auto;
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 24px;
    padding: 0 10px;
    border: 0;
    border-radius: 999px;
    background: var(--seguir-bg);
    color: var(--seguir-fg);
    font-family: var(--font);
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--duration), color var(--duration), transform 0.12s ease;
}

/* No fórum da comunidade o ⋮ já é quem vai para a direita (margin-left auto);
   um segundo auto racharia a folga ao meio e a pílula ficaria boiando. */
.cf-resp__linha .bip-reply__follow-btn {
    margin-left: 0;
}

.bip-reply__follow-btn:hover {
    background: var(--seguir-bg-hover);
    color: var(--seguir-fg);
}

.bip-reply__follow-btn:active {
    transform: scale(0.97);
}

.bip-reply__follow-btn:disabled {
    opacity: 0.55;
    cursor: default;
    transform: none;
}

/* Já sigo / já somos conectados / pedido feito: pílula CINZA com letra escura
   (11/09/26) — o preto é só para o RARO (quem eu ainda NÃO sigo). */
.bip-reply__follow-btn.is-following,
.bip-reply__follow-btn.is-mutual,
.bip-reply__follow-btn.is-pending {
    background: var(--seguir-feito-bg);
    color: var(--seguir-feito-fg);
    font-weight: 600;
}

.bip-reply__follow-btn.is-following:hover,
.bip-reply__follow-btn.is-mutual:hover {
    background: var(--seguir-feito-bg-hover);
    color: var(--red, #e0245e);
}

/* Pendente não é ação: o hover da base não acende aqui. */
.bip-reply__follow-btn.is-pending,
.bip-reply__follow-btn.is-pending:hover,
.bip-reply__follow-btn.is-declined,
.bip-reply__follow-btn.is-declined:hover {
    background: var(--seguir-feito-bg);
    color: var(--seguir-feito-fg);
    cursor: default;
}

.bip-reply__header {
    flex: 1;
    min-width: 0;
}

.bip-reply__menu-wrap {
    position: relative;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    margin: -2px -4px 0 0;
}

/* RESPOSTA: cabeçalho em UMA linha só (nome + selo + flag + >> alvo + data).
   As duas linhas com cidade/data embaixo são do POST — lá a primeira linha tem
   tópico e comunidade e precisa do espaço. Aqui não tem, e dividir só deixava a
   resposta alta à toa. */
.bip-reply__header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    line-height: 1.3;
}

.bip-reply__header .bip-reply__time {
    color: var(--text-3);
    font-size: 0.75rem;
    font-weight: 400;
}

.bip-reply__header--chain {
    gap: 8px;
}

.bip-reply__author,
.bip-reply__parent {
    color: var(--white);
    font-weight: 600;
    font-size: 0.86rem;
    text-decoration: none;
}

.bip-reply__parent {
    color: var(--text-2);
    font-weight: 500;
}

.bip-reply__author:hover,
.bip-reply__parent:hover {
    color: var(--accent);
    text-decoration: underline;
}

.bip-reply__arrow {
    color: var(--text-3);
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    user-select: none;
}

.bip-reply__meta-inline {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    margin-top: 2px;
}

.bip-reply__actions {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 6px 0 0;
    width: 100%;
}

/* Primeira ação alinha com o TEXTO do comentário (o padding do botão indentava
   8px; o antigo margin-left:-6px compensava — saiu junto com ele). */
.bip-reply__actions > .bip-action-btn:first-child {
    padding-left: 0;
}

/* "Ver N respostas" — o abre/fecha do ramo (árvore fechada estilo app, 21/07).
   O desenho completo (linha própria, seta, recuo, pedaço do risco) mora no
   thread.css; aqui ficam só a cor e o peso, que valem em toda parte.

   SEM SUBLINHADO (09/09/26, ordem do dono: *"tirar este risco de link debaixo,
   vamos manter como link mas tirar este visual feio"*). Ele vinha daqui, do dia
   em que o botão nasceu. A cor de destaque e o peso 600 já dizem que aquilo é
   clicável — o traço embaixo só somava sujeira a uma linha que a reforma de
   08/09 tinha acabado de limpar, e ainda brigava com a seta ao lado. */
.bip-reply__expand {
    color: var(--accent);
    font-weight: 600;
    text-decoration: none;
}

/* Coração encosta à DIREITA da linha (estilo app). */
.bip-reply__actions-end {
    display: inline-flex;
    align-items: center;
    margin-left: auto;
}

.bip-action-btn--compact {
    padding: 6px 8px;
    margin: 0;
    font-size: 0.85rem;
    gap: 4px;
}

/* Compacto: a MESMA conta, um ponto acima (ver .bip-action-icon). */
.bip-action-btn--compact .bip-action-icon {
    width: 21px;
    height: 21px;
}

.bip-action-btn--compact .bip-action-icon--repost {
    width: 18px;
    height: 18px;
}

.bip-action-btn--compact .bip-action-icon--send {
    width: 22px;
    height: 22px;
}

.bip-action-btn--compact .bip-action-count {
    font-size: 0.82rem;
}

/* Ação em PALAVRA e não em ícone — usada só pelo "Responder" do comentário, que
   não tem contador para acompanhar um ícone (2026-07-16). Peso maior que o texto
   corrido porque, sem ícone, é ele sozinho que precisa parecer clicável. */
.bip-action-btn--text {
    font-weight: 600;
    letter-spacing: 0.01em;
}

.bip-reply__dot {
    color: var(--text-3);
    font-size: 0.75rem;
}

.bip-reply-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0;
    border: none;
    background: none;
    color: var(--text-3);
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    transition: color 0.15s;
}

.bip-reply-btn:hover { color: var(--accent); }

.bip-reply-btn--root {
    font-size: 0.85rem;
    color: var(--text-2);
}

.bip-reply-compose-slot {
    margin-top: 8px;
}

.bip-reply-compose-slot .bip-reply-compose {
    padding-left: 0;
}

.bip-reply-compose-slot--root {
    margin-bottom: 4px;
}

.bip-reply__time {
    color: var(--text-3);
    font-size: 0.75rem;
}

.bip-reply__text {
    margin: 2px 0 0;
    font-size: 0.95rem;
    line-height: 1.45;
    color: var(--text);
    word-break: break-word;
    white-space: pre-wrap;
}

/* legado — mantido para compatibilidade */
.bip-replies-list { display: flex; flex-direction: column; gap: 0; }

.bip-reply {
    padding: 12px 0;
    background: none;
    border-radius: 0;
    border: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.14);
}

.bip-reply__author {
    color: var(--white);
    font-weight: 600;
    font-size: 0.85rem;
    text-decoration: none;
}

.bip-reply-badge {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 0.68rem;
    color: #f59e0b;
    margin-left: 6px;
}

.bip-replies-hint, .bip-replies-loading {
    color: var(--text-3);
    font-size: 0.85rem;
}

.bip-reply-compose { display: flex; flex-direction: column; gap: 8px; }

/* A CAIXA NÃO PISA NA LINHA — resolvido na origem (19/08/26).
   Aqui morava a regra ".bip-reply__follow .bip-reply-compose { margin-left: 44px }"
   (16/08/26, dono: "a caixa sobrepõe o risco"). Era um contrapeso: o JS puxava
   o slot para a borda com margem NEGATIVA e este 44px empurrava de volta, só no
   nível aninhado. O primeiro nível ficou de fora e o dono reclamou de novo —
   mesma queixa, outro nível.
   Agora `openReplyComposer` simplesmente NÃO estica o slot dentro de um ramo, e
   a posição natural já deixa o tronco livre nos dois níveis. Manter os dois
   mecanismos indentaria a pílula aninhada duas vezes. */

/* ── PÍLULA de resposta estilo Threads/app (24/07/26): texto + contador +
      globo + emoji + seta de enviar, tudo DENTRO de uma cápsula única.
      Sem Cancelar/Responder — Esc fecha, seta envia. ── */
.bip-reply-pill {
    display: flex;
    align-items: center;
    gap: 4px;
    /* SEM BORDA (16/08/26, dono: "tira as bordas da caixa de texto, a cor já
       faz a diferença"): o fundo próprio (--bg-2) já separa a pílula do
       cartão; o filete só somava ruído. */
    border: none !important;
    /* Simétrico (24/07/26): emoji abre a pílula à esquerda, seta fecha à direita. */
    padding: 6px;
    border: 1px solid var(--border);
    /* Arredondada, mas SEM virar cápsula (24/07/26) — mesmo nível dos cards/seletor. */
    border-radius: 16px;
    background: var(--bg-2);
    transition: border-color var(--duration);
}

[data-theme="light"] .bip-reply-pill {
    background: #EBECEF;
}

/* Digitação em curso: globo sai de cena (privacidade se escolhe antes). */
.bip-reply-pill.is-typing .bip-reply-vis-btn {
    display: none;
}

/* Sem borda, o foco se anuncia pelo fundo — nada de anel voltando por aqui. */
.bip-reply-pill:focus-within {
    background: var(--bg-3, var(--bg-2));
}

.bip-reply-input {
    font-size: 0.9rem !important;
    resize: none;
    max-height: 88px;
    overflow-y: auto;
    width: 100%;
}

.bip-reply-pill__input {
    flex: 1;
    min-width: 0;
    /* UM RESPIRO À ESQUERDA (10/09/26, ordem do dono: *"quero um pequeno
       respiro na caixa de texto, para quando eu começar a escrever não ficar tão
       à esquerda"*).

       O horizontal era ZERO, e a cápsula só tem 6px de padding próprio: o texto
       começava a 6px do fio, encostado. Isso passou despercebido enquanto as
       ferramentas nasciam à mostra e empurravam o campo para dentro — no mesmo
       dia em que a cápsula passou a nascer colapsada (ver o gatilho de escrever
       em bips-ui.js), o campo virou o PRIMEIRO item da linha e a falta de
       respiro apareceu.

       Com as ferramentas abertas o mesmo recuo vira o espaço entre o último
       ícone e a primeira letra, que também faltava. */
    padding: 8px 4px 8px 10px !important;
    border: none !important;
    background: transparent !important;
    color: var(--white);
    font-family: var(--font);
    outline: none !important;
    box-shadow: none !important;
    line-height: 1.4;
}

.bip-reply-pill__counter {
    flex: none;
    color: var(--text-3);
    font-size: 0.72rem;
    padding: 0 2px;
}

/* ─────────────────────────────────────────────────────────────────────────
   CONTADOR AO LADO DE CAMPO DE TEXTO TEM LARGURA FIXA (11/08/26).

   O bug que isto mata, visto em produção: digitando uma resposta na 3ª/4ª
   linha, a PRIMEIRA linha oscilava — a palavra da fronteira pulava para
   baixo e voltava a cada tecla. A causa não era o texto: era o CONTADOR.
   A fonte da casa tem dígitos de larguras diferentes ("1" magro, "8"
   gordo); o contador vive na mesma linha flex do textarea, então 168→167
   mudava a largura dele em uns pixels, o textarea ganhava/perdia esses
   pixels e TODAS as linhas re-quebravam. Provado nos prints do dono: o
   último dígito largo (8, 5) encolhia a linha 1; estreito (7, 1) esticava.

   `min-width: 3ch` reserva o espaço do pior caso ("256") de uma vez;
   `tabular-nums` deixa os dígitos de largura igual onde a fonte suportar.
   Vale para TODOS os contadores que dividem linha com um campo — um só
   fora da regra reintroduz o bug naquela tela.
   ───────────────────────────────────────────────────────────────────────── */
.bip-reply-pill__counter,
.compose-editor-box__counter,
.compose-modal__counter,
.bip-reply-modal__counter {
    min-width: 3ch;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.bip-reply-pill__tool {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--text-2);
    font-size: 1.15rem;
    cursor: pointer;
    transition: background var(--duration), color var(--duration);
}

.bip-reply-pill__tool:hover {
    background: var(--surface-3);
    color: var(--white);
}

/* A FIGURINHA COM O DESENHO DO DONO (13/09/26): o mesmo `sticker.svg` do app,
   no lugar do `bx-sticker`. Em `em`, para acompanhar o tamanho da fonte dos
   ícones vizinhos (e o da variante do mural, que é menor). */
.bip-reply-pill__tool .bip-ico-figurinha {
    flex: none;
    width: 1.1em;
    height: 1.1em;
}

/* AS FERRAMENTAS MORAM DENTRO DO "+" (11/08/26 → INVERTIDO EM 08/09/26)
   ─────────────────────────────────────────────────────────────────────────
   A regra de 11/08 era: as ferramentas ficam à mostra e só se recolhem no "+"
   quando a pessoa COMEÇA A ESCREVER. O dono virou do avesso em 08/09/26:
   *"deixa por padrão já com o + ativado e todos os ícones dentro, só vai
   mostrar se a pessoa clicar no +, inverso de hoje"*.

   O motivo é o mesmo de sempre, levado até o fim: emoji, foto, GIF, áudio e
   agendar são CINCO botões numa cápsula que também precisa caber o texto, e na
   coluna de comentários (08/09/26) sobrava um campo do tamanho de uma palavra.
   Recolher só depois do primeiro caractere resolvia tarde: quem ainda não
   escreveu é justamente quem olha para a caixa e precisa vê-la como caixa.

   E EM 10/09/26 O GATILHO VIROU ESCREVER (ordem do dono, com a janela de
   comentários já larga de novo): a cápsula nasce colapsada, e as ferramentas
   aparecem no primeiro caractere. É o mais natural dos três desenhos — caixa
   vazia é caixa, e quem tem o que enviar tem o que anexar. Quem liga e desliga
   a classe é o contador (`updateReplyCharCounter`, em bips-ui.js).

   Quem manda aqui é só `is-tools-open`, que nasce ausente. O "+" fica sempre
   visível e é um interruptor: aberto, ele gira 45° e vira o × que fecha. Sem
   isso, quem abrisse as ferramentas ficaria sem caminho de volta, que era o
   preço escondido da inversão de 08/09.

   ENTRA E SAI COM `display`, igual ao globo de privacidade logo acima — e não
   com `max-width`, que numa PRIMEIRA versão desta regra não colapsava: item de
   flex nasce com `min-width: auto`, e o mínimo automático vence o max-width.
   O movimento fica na ENTRADA de quem aparece (bipToolIn), que é onde o olho
   acompanha; sumir é instantâneo, como o globo já fazia. */
/* ══ A PÍLULA FLUTUANTE (10/09/26, ordem do dono) ═══════════════════════════

   *"Não vamos mais exibir o botão mais (+), isso acabou na interface web. Vamos
   fazer uma pílula flutuante que nasce colapsada no meio, entre os ícones
   sociais e a pílula de voto (…) vamos deixar a caixa de texto livre para
   ESCREVER. Nessa pílula terá os botões de privacidade, emoji, foto, GIF,
   figurinhas e agendamento."*

   O erro que isto corrige: as ferramentas moravam DENTRO da cápsula de texto —
   ora à mostra, ora escondidas num "+", ora recolhendo ao digitar. Todas as
   três versões dividiam a mesma linha com o texto, e a caixa de escrever nunca
   era só uma caixa de escrever.

   Agora elas saem da cápsula e viram uma tira PRÓPRIA, ancorada ao topo dela.
   Como a cápsula nasce logo abaixo da fileira de ações do cartão, `bottom:100%`
   a pousa exatamente no vão entre os ícones sociais (esquerda) e a pílula de
   voto (direita) — o lugar que o dono desenhou.

   Colapsada ela é só três pontinhos; abre ao ESCREVER (o gatilho que ele pediu,
   ver updateReplyCharCounter) ou ao toque nos pontinhos, para quem quer anexar
   antes de escrever. */
.bip-reply-compose {
    position: relative;
}

.bip-reply-tools {
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-bottom: 6px;
    z-index: 6;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px 6px;
    border-radius: 999px;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
    /* A tira é uma ilha sobre a fileira de ações: sem isto o clique atravessa
       para o cartão de baixo e a pessoa curte o post sem querer. */
    pointer-events: auto;
}

/* Colapsada: três pontinhos, do tamanho de um alvo de toque e nada mais. */
.bip-reply-tools__dots {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    border: none;
    background: none;
    padding: 5px 6px;
    cursor: pointer;
    line-height: 0;
}

.bip-reply-tools__dots span {
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--text-3);
    transition: background 0.18s var(--ease);
}

.bip-reply-tools__dots:hover span {
    background: var(--accent);
}

.bip-reply-pill__tools {
    display: inline-flex;
    align-items: center;
    flex: none;
}

/* Um estado por vez: pontinhos OU ferramentas, nunca os dois. */
.bip-reply-tools:not(.is-open) .bip-reply-pill__tools {
    display: none;
}

.bip-reply-tools.is-open .bip-reply-tools__dots {
    display: none;
}

.bip-reply-tools.is-open .bip-reply-pill__tools {
    animation: bipToolIn 0.2s var(--ease);
}

@keyframes bipToolIn {
    from { opacity: 0; transform: scale(0.8); }
    to { opacity: 1; transform: scale(1); }
}

/* Enviar — círculo azul; o contador mora NO MEIO do botão e não some. */
.bip-reply-pill__send {
    position: relative;
    flex: none;
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--btn-azul);
    color: #fff;
    font-size: 1.3rem;
    cursor: pointer;
    transition: filter var(--duration);
}

.bip-reply-pill__send .bip-reply-pill__counter {
    position: static;
    color: #fff;
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1;
    min-width: 0;
    padding: 0;
    text-align: center;
}

.bip-reply-pill__send .bip-action-icon {
    width: 15px;
    height: 15px;
    color: #fff;
}

.bip-reply-pill__send:hover { filter: brightness(1.08); }
.bip-reply-pill__send:disabled { opacity: 0.6; cursor: default; }

/* Âncora do painel de emoji dentro da pílula. */
.bip-reply-pill .bip-emoji-wrap { position: relative; }

/* ── FOTO NA RESPOSTA (25/07/26): miniatura ACIMA da pílula, com X para tirar.
      Pequena de propósito — a resposta continua sendo texto; a foto acompanha. ── */
.bip-reply-attach {
    position: relative;
    display: inline-block;
    margin-bottom: 8px;
    max-width: 200px;
}

.bip-reply-attach[hidden] {
    display: none;
}

.bip-reply-attach__thumb {
    display: block;
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid var(--border);
    background: var(--surface-2);
    cursor: zoom-in;
}

.bip-reply-attach__thumb img {
    display: block;
    width: 100%;
    max-height: 150px;
    object-fit: cover;
}

.bip-reply-attach__remove {
    position: absolute;
    top: -7px;
    right: -7px;
    width: 24px;
    height: 24px;
    display: grid;
    place-items: center;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.72);
    color: #fff;
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
}

.bip-reply-attach__remove:hover {
    background: rgba(0, 0, 0, 0.88);
}

/* Foto PUBLICADA na resposta: menor que a do post — comentário é comentário.
   (O CSS base já deixa a resposta com a imagem pequena; aqui só se aperta o
   teto para a foto não dominar a conversa.) */
.bip-reply__text .bip-content-image-wrap,
.bip-reply__text .bip-media-caption {
    max-width: min(300px, 100%);
}

.bip-reply__text .bip-content-image {
    max-height: 320px;
}

/* Câmera acesa = já tem foto anexada (mesma pista do compositor de post). */
.bip-reply-pill__photo.is-on,
.bip-reply-modal__photo.is-on {
    color: var(--accent);
}

.bip-reply-pill__photo.is-busy,
.bip-reply-modal__photo.is-busy {
    opacity: 0.5;
    cursor: default;
}

.bip-vis-cycle--direct {
    color: #f59e0b;
    opacity: 0.9;
}

/* === BUTTONS === */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 20px;
    border-radius: var(--radius);
    font-family: var(--font);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    border: none;
    transition: all var(--duration) var(--ease);
    white-space: nowrap;
}

/* O BOTAO-MAE. "Deixar recado", "Mensagem", os OK dos modais — quase todo
   botao cheio da rede cai aqui. Era ele que estava azul #2f6fe0 ao lado do
   "Novo BiP" #4B7BB7.

   SEM SOMBRA E SEM PULO (21/08/26, mesma regra do "Novo BiP" e dos dois
   "Seguir"): o halo era `--accent-glow`, brilho do azul ANTIGO, e ficou
   sobrando quando o fundo mudou de familia. E o `translateY(-1px)` era o
   *"parece mover quando sobreposto"*. Hover CLAREIA a propria cor — nunca troca
   de tom, que era o que fazia o mesmo botao parecer dois azuis. */
.btn-primary {
    background: var(--btn-azul);
    color: #fff;
}

.btn-primary:hover {
    filter: brightness(1.08);
}

.btn-secondary {
    background: transparent;
    color: var(--text);
    border: 1px solid var(--border);
}

.btn-secondary:hover {
    border-color: var(--border-hover);
    background: var(--surface-3);
}

.btn-sm {
    padding: 6px 14px;
    font-size: 0.8rem;
}

/* === FORMS & INPUTS === */
.input-group {
    margin-bottom: 16px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.input-label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-2);
}
.input-control {
    width: 100%;
    padding: 12px 16px;
    background: var(--bg-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--white);
    font-size: 0.95rem;
    font-family: var(--font);
    transition: border-color var(--duration);
}
.input-control:focus {
    outline: none;
    border-color: var(--accent);
}

/* Modals */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(10,10,10,0.6);
    backdrop-filter: blur(5px);
    z-index: 99999;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration) var(--ease);
}
.modal-overlay.active {
    opacity: 1;
    pointer-events: auto;
}
.modal-content {
    background: var(--surface);
    width: 100%;
    max-width: 400px;
    border-radius: var(--radius-lg);
    border: 1px solid var(--border);
    padding: 30px;
    box-shadow: var(--shadow-lg);
    transform: translateY(20px) scale(0.95);
    transition: all var(--duration) var(--ease);
}
.modal-overlay.active .modal-content {
    transform: translateY(0) scale(1);
}

/* Card premium — mesmo visual de BiPTools.confirm / alert (opt-in: class="bip-dialog-card") */
.bip-dialog-card,
.modal-content.bip-dialog-card {
    background: #F7F8FA;
    border: none;
    border-radius: 28px;
    color: #1A1D26;
    box-shadow:
        0 24px 64px rgba(15, 23, 42, 0.14),
        0 8px 24px rgba(15, 23, 42, 0.06);
}

.modal-overlay.bip-dialog-overlay,
.modal-overlay:has(.bip-dialog-card) {
    background: rgba(18, 22, 30, 0.32);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
}
.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
}
.modal-close {
    background: transparent;
    border: none;
    color: var(--text-2);
    cursor: pointer;
    font-size: 1.2rem;
}
.modal-close:hover {
    color: var(--white);
}

/* Utils */
.d-none { display: none !important; }

/* Pontos de reputação (+5, +2, +1) */
#bip-points-layer {
    position: fixed;
    top: 72px;
    right: 24px;
    z-index: 10050;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
    pointer-events: none;
}

.bip-points-pop {
    padding: 8px 14px;
    border-radius: var(--radius);
    background: rgba(59, 130, 246, 0.92);
    color: #fff;
    font-size: 0.95rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
    opacity: 0;
    transform: translateY(12px) scale(0.9);
    transition: opacity 0.35s ease, transform 0.35s ease;
}

.bip-points-pop--neg {
    background: rgba(239, 68, 68, 0.9);
}

.bip-points-pop--show {
    opacity: 1;
    transform: translateY(0) scale(1);
}

.bip-points-pop--out {
    opacity: 0;
    transform: translateY(-20px) scale(0.95);
}

.notif-item__pts {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 8px;
    border-radius: var(--radius);
    background: var(--accent);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
}

/* Corrige ordem em cascata: garante 1 coluna em telas ≤1100px */
@media (max-width: 1100px) {
    .feed-layout,
    .feed-layout--with-rail,
    .feed-layout--solo {
        grid-template-columns: minmax(0, 1fr) !important;
        max-width: 100%;
        width: 100%;
    }

    .feed-rail-anchor,
    .feed-rail-anchor:has(.rail-actions) {
        display: none !important;
    }

    .main-content {
        max-width: 100%;
        width: 100%;
    }
}

/* —— Página 404 —— */
/* 404 desce do divisor (31/07/26): colado no topo, o card parecia continuação da
   barra. A folga aqui é a mesma respiração dos cards do feed. */
.page-404 {
    padding: 56px 24px 48px;
    text-align: center;
    max-width: none;
    margin: 16px 0 0;
}

@media (max-width: 768px) {
    .page-404 {
        padding: 36px 18px 32px;
        margin-top: 12px;
    }
}

.page-404__code {
    color: var(--accent);
    font-weight: 700;
    letter-spacing: 0.08em;
    margin-bottom: 8px;
    font-size: 0.85rem;
}

.page-404__title {
    font-size: clamp(1.5rem, 3.5vw, 2rem);
    margin-bottom: 10px;
    color: var(--white);
}

.page-404__lead {
    color: var(--text-3);
    margin-bottom: 24px;
    line-height: 1.6;
    max-width: 520px;
    margin-left: auto;
    margin-right: auto;
}

.page-404__actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    margin-bottom: 32px;
}

.page-404__search {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
    width: 100%;
    max-width: 480px;
}

.page-404__search input {
    flex: 1 1 220px;
    min-width: 0;
}

.page-404__hot {
    text-align: left;
    margin: 0 auto 28px;
    max-width: 640px;
    border-top: 1px solid var(--border);
    padding-top: 24px;
}

.page-404__hot-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--white);
    margin-bottom: 14px;
}

.page-404__hot-title i {
    color: var(--accent);
}

.page-404__hot-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.page-404__hot-link {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    background: var(--surface-2);
    color: var(--text-2);
    text-decoration: none;
    transition: border-color 0.15s, background 0.15s;
}

.page-404__hot-link:hover {
    border-color: var(--accent);
    background: var(--surface-3);
}

.page-404__hot-rank {
    font-weight: 700;
    color: var(--accent);
    min-width: 1.25rem;
}

.page-404__hot-text {
    color: var(--text-1);
    line-height: 1.45;
    text-align: left;
}

.page-404__hot-pts {
    font-size: 0.85rem;
    color: var(--text-3);
    white-space: nowrap;
}

.page-404__search {
    display: flex;
    gap: 8px;
    margin-bottom: 24px;
    max-width: 420px;
    margin-left: auto;
    margin-right: auto;
}

.page-404__search input {
    flex: 1;
    min-width: 0;
}

.page-404__links {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
    margin-top: 20px;
}

.page-404__links a {
    color: var(--text-2);
    font-size: 0.9rem;
    text-decoration: none;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    transition: color 0.18s ease, border-color 0.18s ease;
}

.page-404__links a:hover {
    color: var(--white);
    border-color: var(--accent);
}

/* Breadcrumbs (SEO + navegação em páginas internas) */
.breadcrumbs {
    max-width: 680px;
    margin: 0 auto 12px;
    padding: 0 16px;
}

.breadcrumbs__list {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 0.82rem;
    color: var(--text-3);
}

.breadcrumbs__item:not(:last-child)::after {
    content: "›";
    margin-left: 6px;
    color: var(--text-3);
    opacity: 0.7;
}

.breadcrumbs__item a {
    color: var(--text-2);
    text-decoration: none;
}

.breadcrumbs__item a:hover {
    color: var(--accent);
}

.breadcrumbs__item[aria-current="page"] {
    color: var(--text-2);
}

/* Estilos para a barra de pesquisa premium (movidos do search.php) */
.search-shell,
.search-panel,
.search-panel--feed-style {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
}
.search-filters-bar[hidden] {
    display: none !important;
}

.filter-pills-row {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 4px;
    margin-bottom: 16px;
    flex-wrap: wrap;
}

.filter-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    /* BRANCO, não transparente (21/08/26, dono: *"botões perderam o contraste
       com a nova cor, precisam ser brancos"*).

       `transparent` funcionava quando o fundo da página era quase branco: o
       controle "aparecia" emprestando o branco de trás. Com o azul-Orkut
       (#D4DDED) esse empréstimo virou camuflagem — o botão e o campo passaram a
       ter exatamente a cor da página e sumiram.

       REGRA: controle tocável tem superfície PRÓPRIA (`--surface`). Fundo
       transparente só serve a quem vive DENTRO de um cartão, onde o branco já
       está garantido. */
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    color: var(--text-2);
    font-size: 0.9rem;
    cursor: pointer;
    transition: all 0.2s ease;
    user-select: none;
}

.filter-pill:hover, .filter-pill[aria-expanded="true"] {
    background: var(--surface-2);
    color: var(--white);
    border-color: var(--accent);
}

.custom-dropdown {
    position: relative;
}

.custom-dropdown__menu {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    min-width: 240px;
    max-height: 320px;
    overflow-y: auto;
    /* Barra de rolagem OCULTA (24/07/26): rola normal (roda/touch/teclado),
       só a barra feia some — Firefox + WebKit logo abaixo. */
    scrollbar-width: none;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: 0 8px 24px rgba(0,0,0,0.5);
    z-index: 100;
    padding: 8px 0;
    display: flex;
    flex-direction: column;
}

.custom-dropdown__menu::-webkit-scrollbar {
    display: none; /* Chrome/Safari/Edge — par do scrollbar-width acima */
}

.custom-dropdown__menu[hidden] {
    display: none !important;
}

.custom-dropdown__item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    width: 100%;
    background: transparent;
    border: none;
    color: var(--text-2);
    font-size: 0.92rem;
    text-align: left;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.custom-dropdown__item:hover {
    background: var(--surface-2);
    color: var(--white);
}

.custom-dropdown__item.selected {
    color: var(--white);
    font-weight: 500;
}

.custom-dropdown__icon {
    font-size: 1.2rem;
    width: 20px;
    display: flex;
    justify-content: center;
}

.check-icon {
    margin-left: auto;
    opacity: 0;
    color: var(--accent);
    font-size: 1.1rem;
}

.custom-dropdown__item.selected .check-icon {
    opacity: 1;
}

.custom-dropdown__menu--pad {
    padding: 12px;
}

.hidden-select {
    display: none !important;
}

/* Preview SSR para crawlers — home (oculto quando JS está ativo) */
html.bip-js .seo-feed-ssr {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.seo-feed-preview {
    margin: 0 0 20px;
    padding: 16px 20px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
}

.seo-feed-preview--intro .seo-feed-preview__title {
    margin: 0 0 10px;
    font-size: 1.15rem;
    color: var(--text);
}

.seo-feed-preview__desc {
    margin: 0 0 12px;
    color: var(--text-2);
    line-height: 1.55;
}

.seo-feed-preview__links {
    margin: 0;
    font-size: 0.9rem;
}

.seo-feed-preview__links a {
    color: var(--accent);
    text-decoration: none;
}

.seo-feed-preview__links a:hover {
    text-decoration: underline;
}

.seo-feed-preview__title {
    margin: 0 0 12px;
    font-size: 0.95rem;
    color: var(--text-2);
}

.seo-feed-preview__list {
    margin: 0;
    padding-left: 1.1rem;
    color: var(--text);
    line-height: 1.55;
}

.seo-feed-preview__list a {
    color: var(--text);
    text-decoration: none;
}

.seo-feed-preview__list a:hover {
    color: var(--accent);
}

.seo-feed-preview__tag {
    color: var(--accent);
}

/* === Tema claro — overrides (nao altera o escuro) === */
/* Overlays brancos "clarear-no-escuro" viram escurecimento-no-claro (senao somem) */
[data-theme="light"] .search-empty__icon { background: var(--surface-3); }
[data-theme="light"] .bip-replies-wrap { border-top-color: var(--border); }
[data-theme="light"] .bip-replies-tree > .bip-reply-branch { border-bottom-color: var(--border); }
[data-theme="light"] .bip-reply__follow { border-left-color: var(--border); }
[data-theme="light"] .bip-reply { border-bottom-color: var(--border); }

/* Sombras muito pesadas p/ fundo claro */
[data-theme="light"] .bip-notify-toast {
    box-shadow: 0 12px 40px rgba(15,23,42,0.14), 0 0 0 1px rgba(15,23,42,0.05) inset;
}
[data-theme="light"] .custom-dropdown__menu { box-shadow: var(--shadow-md); }

/* ===== Enquete no BiP (compositor + card) ===== */
.compose-poll { margin: 8px 0 4px; padding: 10px; border: 1px solid var(--border, rgba(148,163,184,.2)); border-radius: 12px; background: var(--bg-3, rgba(148,163,184,.06)); }
.compose-poll[hidden] { display: none; }
.compose-poll__list { display: flex; flex-direction: column; gap: 6px; }
.compose-poll__opt { padding: 9px 12px; border: 1px solid var(--border, rgba(148,163,184,.22)); border-radius: 10px; background: var(--bg-2, #1e293b); color: var(--text); font-size: .9rem; outline: none; }
.compose-poll__opt:focus { border-color: var(--accent); }
.compose-poll__foot { display: flex; justify-content: space-between; align-items: center; margin-top: 8px; }
.compose-poll__add, .compose-poll__remove { border: none; background: none; cursor: pointer; font-size: .82rem; font-weight: 600; padding: 4px 6px; border-radius: 8px; }
.compose-poll__add { color: var(--accent); }
.compose-poll__remove { color: var(--text-3); }
.compose-poll__add:hover, .compose-poll__remove:hover { background: var(--bg-3, rgba(148,163,184,.14)); }

/* ── O BOTÃO E A JANELA DO ESTILO (09/09/26) ─────────────────────────────────
   O "Estilo" mora entre "+ Opção" e "Remover enquete" de propósito: as três
   decisões da enquete numa fila só, na mesma tipografia. Ele NÃO abre modal —
   o painel cresce dentro do editor, porque escolher marcador é uma decisão de
   segundos e uma janela por cima esconderia justamente as opções que o
   marcador vai enfeitar. */
.compose-poll__estilo-btn {
    border: none;
    background: none;
    cursor: pointer;
    font-size: .82rem;
    font-weight: 600;
    padding: 4px 6px;
    border-radius: 8px;
    color: var(--accent);
}

.compose-poll__estilo-btn:hover,
.compose-poll__estilo-btn[aria-expanded="true"] {
    background: var(--bg-3, rgba(148, 163, 184, .14));
}

.compose-poll__estilo {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 10px;
    padding: 12px;
    border-radius: 12px;
    background: var(--bg-2);
}

.compose-poll__estilo-grupo {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.compose-poll__estilo-titulo {
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-3);
}

.compose-poll__estilo-fila {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

/* Cada quadradinho mostra DUAS amostras (A B, 1 2, • •): uma não diz se o
   estilo enumera, e quatro viram uma parede de marcadores. */
.compose-poll__estilo-opt {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-width: 62px;
    padding: 7px 9px;
    border: 1.5px solid transparent;
    border-radius: 10px;
    background: var(--bg-3, rgba(148, 163, 184, .14));
    cursor: pointer;
}

.compose-poll__estilo-opt:hover { border-color: var(--border); }
.compose-poll__estilo-opt.is-on { border-color: var(--btn-azul); }

.compose-poll__estilo-nada {
    font-size: .76rem;
    font-weight: 600;
    color: var(--text-3);
}
.bip-poll-toggle[aria-pressed="true"] { color: var(--accent); opacity: 1; }
.bip-poll { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 4px; }
.bip-poll__opt { position: relative; display: flex; align-items: center; gap: 8px; width: 100%; padding: 10px 12px; border: 1px solid var(--border, rgba(148,163,184,.22)); border-radius: 10px; background: var(--bg-2, #1e293b); color: var(--text); font-size: .9rem; cursor: pointer; overflow: hidden; text-align: left; transition: border-color var(--duration); }
.bip-poll__opt:hover { border-color: var(--accent); }

/* ── O MARCADOR DA OPÇÃO (09/09/26) ──────────────────────────────────────────
   Letra, número ou símbolo antes do rótulo, na forma que o autor escolheu. As
   quatro formas moram aqui e no app (BipEnqueteEstilos.kt) com as MESMAS
   medidas: 22px de lado, canto 7 na caixa, círculo redondo nos outros dois.

   `flex: none` e largura fixa porque a coluna do marcador precisa ser uma
   coluna: com quatro opções, um "1" estreito e um "4" largo desalinhariam o
   começo dos quatro rótulos, que é justamente o que o marcador vem arrumar. */
.bip-poll__mark {
    position: relative;
    z-index: 1;
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    font-size: 0.78rem;
    font-weight: 700;
    line-height: 1;
    color: var(--text-3);
}

.bip-poll__mark--caixa {
    border-radius: 7px;
    background: var(--bg-3, rgba(148, 163, 184, 0.16));
    color: var(--white);
}

.bip-poll__mark--circulo {
    border-radius: 50%;
    box-shadow: inset 0 0 0 1.5px var(--border);
    color: var(--white);
}

.bip-poll__mark--cheia {
    border-radius: 50%;
    background: var(--btn-azul);
    color: #fff;
}

/* Sem forma, o símbolo é só um sinal: menor peso e a cor de apoio, para ele
   apontar a linha sem competir com o texto dela. */
.bip-poll__mark--nenhuma {
    font-size: 0.85rem;
    color: var(--text-3);
}
.bip-poll__opt.is-voted { cursor: default; }
.bip-poll__fill { position: absolute; inset: 0 auto 0 0; width: 0; background: rgba(96,165,250,.18); background: color-mix(in srgb, var(--accent) 22%, transparent); transition: width .4s ease; z-index: 0; }
.bip-poll__opt.is-mine .bip-poll__fill { background: rgba(96,165,250,.32); background: color-mix(in srgb, var(--accent) 38%, transparent); }
.bip-poll__label { position: relative; z-index: 1; flex: 1; }
.bip-poll__opt.is-mine .bip-poll__label { font-weight: 700; }
.bip-poll__pct { position: relative; z-index: 1; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text-2); }
.bip-poll__total { font-size: .78rem; color: var(--text-3); padding: 2px 2px 0; }

/* Repost estilo X: carimbo "Fulano repostou" no topo do card do BiP original. */
.bip-card__repost-note {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 4px;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-3);
}

.bip-card__repost-note i {
    font-size: 0.95rem;
    color: var(--accent);
}

/* ─────────────────────────────────────────────────────────────────────────
   REPOST COM CITAÇÃO (11/08/26) — o BiP do outro dentro do seu.

   MOLDURA E NADA MAIS: borda fina, fundo levemente afastado e o texto um
   ponto menor. O cartão de dentro NÃO pode competir com o de fora — quem
   está sendo avaliado (estrela, comentário) é a citação, e um cartão interno
   com o mesmo peso visual faria a pessoa mirar no alvo errado.
   ───────────────────────────────────────────────────────────────────────── */
.bip-quote {
    margin-top: 10px;
    padding: 10px 12px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--bg-2, transparent);
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}

.bip-quote:hover {
    border-color: var(--accent);
}

/* No compositor a moldura é só para VER o que se está citando: clicar sairia
   do texto que a pessoa está escrevendo. */
.bip-quote--previa {
    cursor: default;
}

.bip-quote--previa:hover {
    border-color: var(--border);
}

.bip-quote__head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
    min-width: 0;
}

.bip-quote__avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    overflow: hidden;
    flex: 0 0 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-3, var(--border));
}

.bip-quote__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.bip-quote__name {
    font-weight: 700;
    font-size: 0.85rem;
    color: var(--text-1);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bip-quote__handle {
    font-size: 0.8rem;
    color: var(--text-3);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

.bip-quote__text {
    font-size: 0.9rem;
    line-height: 1.45;
    color: var(--text-2);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    /* Três linhas e um "…": a prévia convida a abrir o original, não o
       substitui. Sem o teto, citar um BiP de 3 partes faria o cartão de
       dentro ficar MAIOR que o comentário de quem citou. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.bip-quote__thumb {
    margin-top: 8px;
    border-radius: 10px;
    overflow: hidden;
    max-height: 180px;
}

.bip-quote__thumb img {
    width: 100%;
    height: auto;
    display: block;
    object-fit: cover;
}

/* O original morreu (expurgo ou moderação). O quadro FICA: sem ele o
   comentário de quem citou vira uma frase solta sem assunto. */
.bip-quote--indisponivel {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
    color: var(--text-3);
    font-style: italic;
    cursor: default;
    background: transparent;
    border-style: dashed;
}

.bip-quote--indisponivel:hover {
    border-color: var(--border);
}

/* Prévia dentro do compositor: mesma moldura, respirando do texto acima. */
.compose-quote-preview {
    margin: 10px 0 0;
}

.compose-community-share-preview {
    margin: 10px 0 0;
}

/* Cartão de comunidade compartilhada no feed (21/08/26). */
/* ── O CARTÃO DE COMUNIDADE DENTRO DO BiP ───────────────────────────────────
   Refeito em 21/08/26 com a anatomia do CABEÇALHO da comunidade (ordem do
   dono, com o print daquela tela na mão): capa larga, foto GRANDE pousada na
   quina esquerda, título forte, uma linha de fatos, ação à direita.

   O desenho anterior encaixava duas medidas mágicas — o corpo subia 22px por
   cima da capa e o texto descia 26px para compensar. Só fechava quando o
   conteúdo tinha exatamente a altura prevista; com título de duas linhas ou sem
   descrição, o texto descolava do avatar e o cartão esticava sozinho. Aqui a
   foto é ABSOLUTA, presa na capa: sobrepõe sem empurrar nada. */
.bip-community-share {
    /* ── A CORREÇÃO QUE FALTAVA (21/08/26) ──────────────────────────────────
       O cartão ficava perfeito na prévia do compositor e QUEBRADO no feed, com
       o mesmo HTML e o mesmo CSS. A diferença era o vizinho: no feed ele é
       injetado dentro do `.bip-card__text`, que tem `white-space: pre-wrap`
       para preservar as quebras de linha que a pessoa escreveu no BiP.

       Com `pre-wrap`, cada quebra de linha e cada espaço da INDENTAÇÃO do
       template viram espaço em branco de verdade na tela — eram eles os vãos
       entre o título e a categoria, e as faixas cinza em cima e embaixo da
       capa. O HTML estava certo; ele só estava sendo lido como texto formatado.

       Curado aqui, e não apagando as quebras do template: assim a marcação
       continua legível, e o conserto não depende de ninguém lembrar de escrever
       o HTML numa linha só. */
    white-space: normal;
    margin-top: 10px;
    border: 1px solid var(--border);
    border-radius: 14px;
    overflow: hidden;
    background: var(--surface);
    color: inherit;
    transition: border-color .15s ease;
}

.bip-community-share:hover {
    border-color: color-mix(in srgb, var(--accent) 35%, var(--border));
}

.bip-community-share--previa {
    pointer-events: none;
}

/* 3:1, a mesma proporção da capa na página da comunidade. `aspect-ratio` em vez
   de altura fixa: o cartão vive no feed, que muda de largura entre o desktop, o
   rail estreito e o celular — capa de altura cravada estica ou achata a foto em
   uma dessas. */
.bip-community-share__capa {
    position: relative;
    display: block;
    aspect-ratio: 3 / 1;
    background: linear-gradient(135deg,
        color-mix(in srgb, var(--accent) 22%, var(--bg-2)),
        var(--bg-2));
    overflow: visible;
}

.bip-community-share__banner-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    /* A imagem é cortada pelo raio do cartão em cima; embaixo ela encosta no
       corpo, então não precisa de raio nenhum. */
    border-radius: 13px 13px 0 0;
}

/* A FOTO, grande, na quina esquerda — metade dentro da capa, metade fora. É o
   que faz o cartão ser reconhecível como "aquela comunidade". */
.bip-community-share__avatar {
    position: absolute;
    left: 14px;
    bottom: -26px;
    width: 68px;
    height: 68px;
    border-radius: 50%;
    border: 3px solid var(--surface);
    background: var(--bg-2);
    box-shadow: 0 2px 10px rgba(15, 23, 42, .18);
    overflow: hidden;
}

.bip-community-share__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.bip-community-share__avatar--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-3);
    font-size: 1.7rem;
}

/* O `padding-top` abre espaço para a metade da foto que ficou de fora (26px do
   `bottom` + folga). É a ÚNICA medida daqui que conversa com outra, e a outra
   está vinte linhas acima. */
.bip-community-share__body {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 34px 14px 14px;
}

.bip-community-share__texto {
    flex: 1;
    min-width: 0;
}

.bip-community-share__title {
    display: block;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.25;
    color: var(--text-1, var(--text));
    text-decoration: none;
}

.bip-community-share__title:hover {
    text-decoration: underline;
}

.bip-community-share__meta {
    display: block;
    margin-top: 3px;
    font-size: 0.82rem;
    color: var(--text-3);
    line-height: 1.35;
}

.bip-community-share__dot {
    margin: 0 5px;
    opacity: .7;
}

.bip-community-share__desc {
    margin: 7px 0 0;
    font-size: 0.85rem;
    line-height: 1.45;
    color: var(--text-2);
    /* Duas linhas e corta. O JS já corta em 120 caracteres; isto segura o caso
       do texto sem espaços, que nenhum corte por caractere resolve. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ── O BOTÃO ENTRAR ─────────────────────────────────────────────────────────
   À direita, na fileira do texto — o lugar do "Novo tópico" na página da
   comunidade. E FORA do link: `<button>` dentro de `<a>` é HTML inválido, e
   cada navegador reage de um jeito. */
.bip-community-share__entrar {
    flex: 0 0 auto;
    padding: 9px 20px;
    border: none;
    border-radius: 999px;
    background: var(--btn-azul, var(--accent));
    color: #FFFFFF;
    font: inherit;
    font-size: 0.87rem;
    font-weight: 600;
    cursor: pointer;
    transition: filter .15s ease;
}

.bip-community-share__entrar:hover:not(:disabled) {
    filter: brightness(1.07);
}

/* Já é membro (ou já pediu): o botão para de convidar e passa a informar. */
.bip-community-share__entrar:disabled {
    cursor: default;
    background: var(--surface-3, var(--border));
    color: var(--text-3);
}

/* "ABRIR" — quem JÁ é membro (01/09/26, defeito que o dono viu: *"se mostra sair
   é porque já estou dentro; então por que Entrar aqui no feed?"*).

   Discreto de propósito: é um <a> com a mesma caixa do botão, mas em tinta de
   contorno. O azul cheio é o convite — para quem já entrou, ele seria um
   chamado para uma ação que não existe mais. */
a.bip-community-share__entrar--dentro {
    background: transparent;
    color: var(--text-2);
    border: 1px solid var(--border);
    text-decoration: none;
    line-height: normal;
    /* `padding` do botão menos a borda: sem isto o "Abrir" nasce 2px mais alto
       que o "Entrar" e as duas variantes não encaixam na mesma fileira. */
    padding: 8px 19px;
}

a.bip-community-share__entrar--dentro:hover {
    filter: none;
    border-color: var(--border-hover);
    color: var(--text-1);
}

/* No estreito o botão desce e ocupa a largura: espremido ao lado do título ele
   corta o nome da comunidade, que é a informação principal do cartão. */
@media (max-width: 460px) {
    .bip-community-share__body {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }
    .bip-community-share__entrar {
        width: 100%;
    }
}

@media (prefers-reduced-motion: reduce) {
    .bip-community-share,
    .bip-community-share__entrar { transition: none; }
}

/* ══ O CARTÃO DO TÓPICO DE COMUNIDADE OFICIAL (27/09/26) ═══════════════════
   Mesma caixa do cartão de comunidade (as classes base são as dele) com duas
   linhas a mais: quem postou e o título do tópico. O que ele acrescenta em
   CSS é só isso — herdar a anatomia é o que faz os dois cartões parecerem a
   mesma família no meio do feed. */
/* RESPIRO ANTES DA FILEIRA SOCIAL (27/09/26, ordem do dono: *"precisa de um
   respiro maior entre os ícones sociais e o card"*). O cartão de comunidade
   compartilhada cai no fim do texto e a fileira vem depois de um bloco; este
   encosta nela, porque é o último elemento do corpo do post. */
.bip-topico-card {
    margin-bottom: 14px;
}

.bip-topico-card__linha {
    margin: 0 0 2px;
    font-size: 0.86rem;
    line-height: 1.35;
    color: var(--text-2);
}

.bip-topico-card__linha strong {
    color: var(--text-1, var(--text));
    font-weight: 700;
}

/* O TÍTULO DO TÓPICO, quando existe, é o que dá vontade de entrar — fica logo
   abaixo do nome da comunidade, em tinta forte e limitado a duas linhas para
   não empurrar o botão para fora da fileira. */
.bip-topico-card__topico {
    display: -webkit-box;
    margin-top: 5px;
    font-size: 0.92rem;
    font-weight: 600;
    line-height: 1.4;
    color: var(--text-1, var(--text));
    text-decoration: none;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.bip-topico-card__topico:hover {
    text-decoration: underline;
}

/* O botão é um <a> (leva ao tópico), então precisa das medidas que o <button>
   ganha de fábrica — a mesma correção do "Abrir" do cartão de comunidade. */
a.bip-topico-card__responder {
    display: inline-block;
    text-decoration: none;
    line-height: normal;
    padding: 10px 20px;
    text-align: center;
}

/* Repostar e citar: menu junto ao botão, sem interromper o feed. */
.bip-repost-choice {
    position: fixed;
    inset: auto;
    z-index: 10200;
    width: 188px;
    max-width: calc(100vw - 24px);
    max-height: calc(100dvh - 24px);
    margin: 0;
    padding: 5px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
    color: var(--text-1, var(--text));
    box-shadow: 0 8px 28px rgb(0 0 0 / 12%), 0 2px 6px rgb(0 0 0 / 4%);
    display: flex;
    flex-direction: column;
    gap: 1px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.bip-repost-choice[hidden] {
    display: none;
}

.bip-repost-choice::backdrop {
    background: transparent;
    pointer-events: none;
}

.bip-repost-choice__item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 42px;
    padding: 10px 12px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: inherit;
    text-align: left;
    cursor: pointer;
    font: 500 13px/1.4 var(--font);
    -webkit-tap-highlight-color: transparent;
}

.bip-repost-choice__item:hover {
    background: var(--nav-hover);
}

.bip-repost-choice__item svg {
    width: 18px;
    height: 18px;
    color: var(--text-2, var(--muted));
    flex: 0 0 auto;
}

.bip-repost-choice__item:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
    background: var(--nav-hover);
}

@media (pointer: coarse) {
    .bip-repost-choice__item { min-height: 44px; }
}

/* RESPOSTA AGENDADA (27/08/26): folha do relógio do "+" da resposta — mesma
   gramática da folha de repost, com a roda do agendamento dentro. */
.bip-reply-sched {
    position: fixed;
    inset: 0;
    z-index: 10250; /* acima do modal de comentários */
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.bip-reply-sched[hidden] {
    display: none;
}

.bip-reply-sched__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .45);
}

.bip-reply-sched__panel {
    position: relative;
    width: min(480px, 100%);
    /* var(--surface), e não var(--bg-1): --bg-1 NUNCA existiu no tema — o
       fallback #fff valia sempre e a folha abria BRANCA no modo escuro
       (31/08/26, dono: "o css do modo escuro está horrível"). */
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 18px 18px 0 0;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    box-shadow: 0 -8px 30px rgba(0, 0, 0, .18);
    /* A folha cresceu com as duas rodas de atalho (10/09/26): teto e rolagem
       própria, para não estourar com o teclado do celular aberto. */
    max-height: 88dvh;
    overflow-y: auto;
}

@media (min-width: 640px) {
    .bip-reply-sched {
        align-items: center;
    }

    .bip-reply-sched__panel {
        border-radius: 18px;
    }
}

.bip-reply-sched__head {
    display: flex;
    align-items: center;
    gap: 10px;
    position: relative;
    padding-bottom: 10px;
    margin-bottom: 4px;
}

.bip-reply-sched__head::after {
    left: -16px;
    right: -16px;
}

.bip-reply-sched__head-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: rgba(79, 142, 247, 0.12);
    color: var(--accent);
    font-size: 1.2rem;
    flex: 0 0 auto;
}

.bip-reply-sched__title {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    /* var(--text): o --text-1 era outra variável fantasma (nunca existiu). */
    color: var(--text);
}

/* As PÍLULAS de atalho (.sched-rapido*, 31/08/26) foram apagadas em 10/09/26:
   viraram as duas RODAS de .sched-atalhos, mais acima neste arquivo. Nada mais
   escreve esse markup — nem o compose_modal.php, nem o template da folha da
   resposta. */

/* ── O CARTÃO DA NOTA no chat (31/08/26, dono: "não é para contar, é para
   fazer um card bonito da nota e enviar para a pessoa em DM"). A mensagem
   viaja como TEXTO comum (`👍 · Nota: "frase"`) de propósito: cliente antigo
   lê uma frase digna; cliente novo desenha este cartão. ── */
.inbox-msg__notacard {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 12px 8px;
    margin: 2px 0 6px;
    border-left: 3px solid var(--accent);
    border-radius: 10px;
    background: rgba(79, 142, 247, 0.10);
}

.inbox-msg__notacard-cap {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--accent);
}

.inbox-msg__notacard-texto {
    font-size: 0.95rem;
    font-style: italic;
    line-height: 1.35;
    color: var(--text);
    overflow-wrap: anywhere;
}

.inbox-msg__notacard-emoji {
    font-size: 1.6rem;
    line-height: 1.2;
}

.bip-reply-sched__actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 8px;
    margin-top: 4px;
}

/* O chip que a escolha vira no compositor: o estado mora no DOM e morre com o
   compositor — enviar com ele presente agenda em vez de publicar na hora. */
.bip-reply-sched-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0 6px;
    padding: 8px 10px;
    border-radius: 12px;
    background: rgba(79, 142, 247, 0.10);
    color: var(--text-1);
    font-size: 0.85rem;
    line-height: 1.3;
}

.bip-reply-sched-chip > i {
    color: var(--accent);
    font-size: 1.1rem;
    flex: 0 0 auto;
}

.bip-reply-sched-chip > span {
    min-width: 0;
}

.bip-reply-sched-chip__x {
    margin-left: auto;
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    color: var(--text-2);
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
    padding: 2px 6px;
    border-radius: 8px;
}

.bip-reply-sched-chip__x:hover {
    background: rgba(0, 0, 0, .08);
    color: var(--text-1);
}

/* Preview da foto anexada no compositor (estilo Threads): a imagem aparece
   INTEIRA, na proporção real, contida numa moldura máxima — nunca cortada,
   nunca gigante. Retrato limita pela ALTURA; paisagem limita pela LARGURA;
   imagem pequena fica pequena. A moldura abraça a foto (fit-content), então
   o X cai sempre sobre ela. */
/* PALCO de mídia (24/07/26): faixa de altura limitada na largura TODA — foto
   inteira no centro (contain) e as laterais preenchidas pela própria foto
   desfocada, igual ao post publicado. Preview baixo = modal cabe em qualquer
   monitor e sobra espaço pro resto. */
.compose-attach {
    position: relative;
    width: 100%;
    height: 240px;
    margin: 4px 0 2px;
    border-radius: 12px;
    overflow: hidden;
    background: var(--bg-2);
    display: flex;
    align-items: center;
    justify-content: center;
}

/* ── O CLIPE DO TECLADO (04/09/26) ──────────────────────────────────────
   Com o teclado de pé (classe posta pelo index.js), o palco de 240px vira uma
   tira de 38px que só DIZ que há foto anexada. O × continua ali: encolher não
   pode custar o caminho de desfazer. Sair do campo de texto devolve tudo.

   Com VÁRIAS fotos a tira já é pequena; ali basta encolher as miniaturas de 64
   para 40px e recolher os chips de formato — assim continua-se vendo QUANTAS
   são e em que ordem, que é o que o número na miniatura ensina. */
body.bip-compose-teclado .compose-attach:not(.compose-attach--multi) {
    height: 38px;
    justify-content: flex-start;
    background: var(--surface-2, var(--bg-2));
    border: 1px solid var(--border);
}

body.bip-compose-teclado .compose-attach:not(.compose-attach--multi) .compose-attach__canvas,
body.bip-compose-teclado .compose-attach:not(.compose-attach--multi) .compose-attach__zoom,
body.bip-compose-teclado .compose-attach:not(.compose-attach--multi) .compose-attach__crop,
body.bip-compose-teclado .compose-attach:not(.compose-attach--multi) .compose-attach__add {
    display: none;
}

body.bip-compose-teclado .compose-attach:not(.compose-attach--multi)::after {
    content: "Foto anexada — sai do texto para ver";
    padding-left: 12px;
    color: var(--text-2);
    font-size: 0.82rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

body.bip-compose-teclado .compose-attach--multi .compose-attach__thumb {
    width: 40px;
    height: 40px;
}

body.bip-compose-teclado .compose-attach__layouts {
    display: none;
}

.compose-attach__canvas {
    position: absolute;
    inset: -24px; /* sangra além da borda: o blur não deixa halo transparente */
    background-size: cover;
    background-position: center;
    filter: blur(22px) saturate(1.1);
    opacity: 0.55;
    pointer-events: none;
}

/* Moldura clicável: amplia no lightbox (lupa no cursor avisa). */
.compose-attach__zoom {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    max-width: 100%;
    cursor: zoom-in;
}

.compose-attach img {
    display: block;
    position: relative; /* acima do canvas desfocado */
    width: auto;
    height: auto;
    max-width: 100%;
    /* Dentro do PALCO (24/07/26): a foto inteira cabe na faixa de 240px. */
    max-height: 100%;
    border-radius: 0;
    border: none;
    background: transparent;
    object-fit: contain;
}

.compose-attach__remove {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 26px;
    height: 26px;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.62);
    color: #fff;
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background var(--duration);
}

.compose-attach__remove:hover {
    background: rgba(0, 0, 0, 0.85);
}

/* Localização manual do BiP (web): cidade digitada — a do assunto, não GPS. */
.compose-location {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
    padding: 8px 12px;
    border-radius: 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
}

.compose-location i {
    color: var(--accent);
    font-size: 18px;
}

.compose-location__input {
    flex: 1;
    min-width: 0;
    background: none;
    border: none;
    outline: none;
    color: var(--text);
    font-size: 14px;
    font-family: var(--font);
}

.compose-location__clear {
    border: none;
    background: none;
    color: var(--text-3);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}

.compose-location__clear:hover {
    color: var(--red);
}

/* ===== Editor de corte do compositor (padrão 3:4 retrato · 4:3 paisagem) =====
   Foto fora do padrão abre aqui: a área que SAI fica em sombra escura e a
   janela clara (proporção-alvo) desliza com o arraste — vertical no retrato,
   horizontal na paisagem. 1:1 e afins nem passam por aqui: sobem direto. */
.compose-crop {
    width: fit-content;
    max-width: 100%;
    margin: 10px auto 2px;
}

.compose-crop__stage {
    position: relative;
    width: fit-content;
    max-width: 100%;
    margin: 0 auto;
    border-radius: 14px;
    overflow: hidden;
    border: 1px solid var(--border);
    background: var(--surface-2);
    cursor: grab;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
    line-height: 0;
}

.compose-crop__stage:active {
    cursor: grabbing;
}

.compose-crop__canvas {
    display: block;
    height: min(56vh, 420px);
    width: auto;
    max-width: 100%;
}

.compose-crop__stage--h {
    width: 100%;
}

.compose-crop__stage--h .compose-crop__canvas {
    width: 100%;
    height: auto;
}

.compose-crop__shade {
    position: absolute;
    background: rgba(0, 0, 0, 0.68);
    pointer-events: none;
}

.compose-crop__window {
    position: absolute;
    pointer-events: none;
    box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.85);
    border-radius: 2px;
}

.compose-crop__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 8px;
}

.compose-crop__btns {
    display: flex;
    gap: 8px;
    margin-left: auto;
}

/* ===== Filtros da foto no compositor (13/09/26) =====
   Os mesmos filtros dos stories (bip-filtros.js). A tira, as abas e a régua usam
   as classes do editor de stories (status-editor.css, que vem para quem entrou);
   aqui só o palco da prévia, a escolha da foto e o tamanho das miniaturas. O
   botão tem a cor dele, como os vizinhos, e o mesmo desenho do botão do app. */
.compose-add-btn--filtros { color: #0d9488; }

.compose-add-btn[hidden] {
    display: none;
}

.compose-add-btn__svg {
    display: block;
    width: 0.92em;
    height: 0.92em;
}

.compose-filtros {
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-width: 0;
    margin: 10px 0 2px;
}

.compose-filtros__palco {
    display: flex;
    justify-content: center;
    border-radius: 14px;
    overflow: hidden;
    border: 1px solid var(--border);
    background: var(--surface-2);
    line-height: 0;
}

.compose-filtros__previa {
    display: block;
    max-width: 100%;
    max-height: min(46vh, 380px);
}

.compose-filtros__fotos {
    display: flex;
    gap: 6px;
}

.compose-filtros__foto {
    width: 40px;
    height: 40px;
    padding: 0;
    border: 2px solid transparent;
    border-radius: 8px;
    background: var(--surface-2) center / cover no-repeat;
    cursor: pointer;
}

.compose-filtros__foto[aria-pressed="true"] {
    border-color: var(--accent);
}

.compose-filtros .status-filtro {
    width: 60px;
}

.compose-filtros .status-filtro canvas {
    width: 56px;
    height: 56px;
}

.compose-filtros__forca[hidden] {
    display: none;
}

/* ===== Compositor: X à direita (padrão dos modais) =====
   O menu ⋯ e a chave do "Bloquear comentários" morreram em 2026-07-15:
   tudo virou caixa visível na grade de ações. */

/* Arrastar foto sobre o modal */
.compose-modal__panel.is-dragover {
    outline: 2px dashed var(--accent);
    outline-offset: -8px;
}

/* Botão "Bloquear comentários" na barra do compositor (SVG inline) */
.bip-lock-toggle svg {
    display: block;
}

.bip-lock-toggle.is-on {
    color: var(--accent);
    opacity: 1;
}

/* ── @menção: sugestão dentro do textarea ─────────────────────────────── */
/* FIXA E NO <body> (21/08/26). Era `absolute` dentro do cartão e ficava ATRÁS
   dele — print do dono. A causa é o `content-visibility: auto` de `.bip-card`:
   ele implica `contain: paint`, que RECORTA os filhos na caixa do cartão e cria
   um contexto de empilhamento próprio. Dentro dele nenhum `z-index` escapa — era
   por isso que subir o número (estava em 40) nunca resolvia.
   Quem posiciona é o JS (`posicionar()` em bip-mentions.js), que prefere abrir
   para CIMA: a caixa de texto costuma estar no rodapé de um modal. */
.bip-mention-suggest {
    position: fixed;
    /* Acima de tudo o que a casa empilha (o teto atual é 12000, nos tools). */
    z-index: 12050;
    max-height: 216px;
    overflow-y: auto;
    padding: 4px;
    border-radius: 12px;
    background: var(--bg-2, #1e293b);
    border: 1px solid var(--border, rgba(148, 163, 184, 0.2));
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}

.bip-mention-suggest[hidden] {
    display: none;
}

.bip-mention-suggest__item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 7px 8px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--text-1, #e2e8f0);
    font-size: 0.9rem;
    text-align: left;
    cursor: pointer;
}

.bip-mention-suggest__item:hover,
.bip-mention-suggest__item.is-active {
    background: var(--bg-3, rgba(148, 163, 184, 0.16));
}

.bip-mention-suggest__pic {
    flex: none;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--bg-3, rgba(148, 163, 184, 0.2));
}

.bip-mention-suggest__nick {
    color: var(--accent);
    font-weight: 600;
}

/* ── CAPA ABSTRATA (01/08/26) — porta do app (ProfileCoverFallback.kt).
   Gradiente + dois círculos claros: dá movimento sem virar poluição atrás da
   foto. A cor vem do ID da pessoa (bip_cover_palette_index), então o perfil de
   cada um tem sempre a MESMA capa — e uma lista de perfis não fica repetitiva.
   Nada de imagem: zero requisição e nítido em qualquer densidade de tela. */
.profile-cover__art {
    position: absolute;
    inset: 0;
    display: block;
    overflow: hidden;
    border-radius: var(--radius-xl);
}

.profile-cover__art::before,
.profile-cover__art::after {
    content: '';
    position: absolute;
    aspect-ratio: 1;
    border-radius: 50%;
    transform: translate(-50%, -50%);
}

/* Raio 0,62 da altura → diâmetro 124%. Mesmos números do app. */
.profile-cover__art::before {
    height: 124%;
    left: 12%;
    top: 18%;
    background: rgba(255, 255, 255, 0.10);
}

.profile-cover__art::after {
    height: 170%;
    left: 88%;
    top: 92%;
    background: rgba(255, 255, 255, 0.06);
}

.profile-cover__art--p0 { background: linear-gradient(135deg, #1d3b73, #3d6fd1); } /* azul profundo */
.profile-cover__art--p1 { background: linear-gradient(135deg, #6b1f32, #ae4257); } /* vinho */
.profile-cover__art--p2 { background: linear-gradient(135deg, #9a5b21, #d79a4c); } /* ocre */
.profile-cover__art--p3 { background: linear-gradient(135deg, #1f5145, #3e937d); } /* verde musgo */
.profile-cover__art--p4 { background: linear-gradient(135deg, #4a2a70, #8b5fbf); } /* ameixa */
.profile-cover__art--p5 { background: linear-gradient(135deg, #2c3a47, #5a7184); } /* grafite */

/* ==========================================================================
   GALERIA DE 2+ IMAGENS (04/08/26) — carrossel e colagem
   O layout já chega decidido do cliente (bips-ui.js › resolveMediaLayout);
   aqui é só a moldura. Regra: 2–3 imagens = carrossel; 4 = colagem 2x2 ou
   carrossel, escolha do autor.
   ========================================================================== */
.bip-gallery {
    position: relative;
    margin-top: 10px;
    border-radius: 14px;
    overflow: hidden;
}

/* LARGURA CHEIA no cartão, igual à foto única (05/08/26). A galeria vive na
   mesma coluna do texto e vai de ponta a ponta — o JS ajusta só a PROPORÇÃO da
   moldura, nunca a largura. Antes um retrato no carrossel era estreitado para
   ~322px e ficava com um vão branco do lado, enquanto a foto única do BiP
   vizinho ia de ponta a ponta: duas fotos do mesmo formato, dois tamanhos. */
.bip-card__body .bip-gallery {
    width: 100%;
    margin-left: auto;
    margin-right: auto;
}

/* O TETO DE 600px DO CARROSSEL NO CARTÃO SAIU (13/09/26, moldura inteligente).
   A foto única já vai até 3:4 na largura cheia, e o carrossel acompanha: a
   proporção vem da 1ª foto presa entre 3:4 e 16:9 (clampCarouselStage), que
   nunca passa de 4/3 da largura. O pré-carga 4:3 é mais baixo que isso, então
   a rede de segurança não protegia de nada e aparava a página do modo
   escritor (4:5) em cima e embaixo. */

/* --- carrossel: o arrasto é do NAVEGADOR (scroll-snap), sem JS de gesto --- */
.bip-gallery--carousel .bip-gallery__track {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    /* Moldura FIXA para o conjunto (altura mudando a cada arrasto empurraria o
       feed). 4:3 é só o pré-carga: o JS (clampBipImageRatios) troca pela
       proporção REAL da 1ª foto, no mesmo portão da foto única (3:4..16:9). */
    aspect-ratio: 4 / 3;
}

.bip-gallery--carousel .bip-gallery__track::-webkit-scrollbar {
    display: none;
}

.bip-gallery__slide {
    flex: 0 0 100%;
    scroll-snap-align: center;
    height: 100%;
    cursor: zoom-in;
}

.bip-gallery__slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.bip-gallery__counter {
    position: absolute;
    top: 10px;
    right: 10px;
    padding: 3px 8px;
    border-radius: 999px;
    background: rgba(0, 0, 0, .45);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    pointer-events: none;
}

.bip-gallery__dots {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 8px;
    display: flex;
    justify-content: center;
    gap: 6px;
}

.bip-gallery__dot {
    width: 6px;
    height: 6px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, .5);
    box-shadow: 0 0 3px rgba(0, 0, 0, .4);
    transition: background .15s ease, transform .15s ease;
    cursor: pointer;
}

.bip-gallery__dot.is-active {
    background: var(--accent, #4F8EF7);
    transform: scale(1.15);
}

/* --- colagem: grade 2x2 de quadrados; a foto inteira abre no lightbox --- */
.bip-gallery--collage {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 3px;
}

.bip-gallery__cell {
    aspect-ratio: 1 / 1;
    overflow: hidden;
    cursor: zoom-in;
}

.bip-gallery__cell img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ===== Compositor com ATÉ 4 FOTOS (04/08/26) ===== */
/* Uma foto = o palco de sempre; duas ou mais = faixa de miniaturas. */
.compose-attach__add,
.compose-attach__add-tile {
    background: none;
    border: 1px dashed var(--border, rgba(148,163,184,.4));
    color: var(--text-muted, #94a3b8);
    border-radius: 10px;
    cursor: pointer;
}

.compose-attach__add {
    position: absolute;
    left: 10px;
    bottom: 10px;
    padding: 5px 12px;
    font-size: 13px;
    background: rgba(0, 0, 0, .45);
    color: #fff;
    border-color: rgba(255, 255, 255, .35);
}

/* CORTAR É DEPOIS (30/08/26, ordem do dono): a foto entra INTEIRA sozinha e o
   corte virou este botão opcional — pílula ao lado do "+ foto" na foto única,
   selo no pé da miniatura quando são várias. */
.compose-attach__crop {
    position: absolute;
    right: 10px;
    bottom: 10px;
    padding: 5px 12px;
    font-size: 13px;
    background: rgba(0, 0, 0, .45);
    color: #fff;
    border: 1px dashed rgba(255, 255, 255, .35);
    border-radius: 10px;
    cursor: pointer;
}

.compose-attach__thumb-crop {
    position: absolute;
    left: 2px;
    right: 2px;
    bottom: 2px;
    padding: 2px 0;
    border: none;
    border-radius: 7px;
    background: rgba(0, 0, 0, .6);
    color: #fff;
    font-size: 10.5px;
    line-height: 1.2;
    cursor: pointer;
}

.compose-attach--multi {
    display: block;
    background: none;
    height: auto;
}

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

.compose-attach__thumb {
    position: relative;
    width: 64px;
    height: 64px;
    border-radius: 10px;
    background-size: cover;
    background-position: center;
    border: 1px solid var(--border, rgba(148,163,184,.35));
}

.compose-attach__thumb-x {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 20px;
    height: 20px;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, .6);
    color: #fff;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}

.compose-attach__add-tile {
    width: 64px;
    height: 64px;
    font-size: 22px;
}

/* .compose-attach__hint MORREU em 09/08/26 (ordem do dono): a linha "N fotos —
   o máximo por BiP" saiu do compositor. Estilo removido junto para o seletor
   não ficar de herança órfã. */

.compose-attach__layouts {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.compose-attach__chip {
    padding: 7px 14px;
    border-radius: 999px;
    border: 1px solid var(--border, rgba(148,163,184,.4));
    background: none;
    color: var(--text, #e8eaed);
    font-size: 13px;
    cursor: pointer;
}

.compose-attach__chip.is-active {
    background: var(--accent, #4F8EF7);
    border-color: var(--accent, #4F8EF7);
    color: #fff;
    font-weight: 600;
}

/* Fila de cortes (04/08/26): "Foto 2 de 3" na barra do editor de enquadre. */
.compose-crop__step {
    font-size: 12px;
    color: var(--text-muted, #94a3b8);
    margin-right: auto;
    align-self: center;
}

/* ===== Setas do carrossel do feed (04/08/26) =====
   Aparecem no hover em quem tem ponteiro; no toque o arrasto já resolve, e
   seta sempre visível só roubaria foto. Somem na ponta: apontar para o nada é
   pior do que não ter seta. */
.bip-gallery__arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, .5);
    color: #fff;
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    transition: opacity .15s ease, background .15s ease;
}

.bip-gallery__arrow--prev { left: 8px; }
.bip-gallery__arrow--next { right: 8px; }
.bip-gallery__arrow:hover { background: rgba(0, 0, 0, .72); }
.bip-gallery--carousel:hover .bip-gallery__arrow { opacity: 1; }
.bip-gallery__arrow:focus-visible { opacity: 1; outline: 2px solid var(--accent, #4F8EF7); }

/* Sem ponteiro (celular): o arrasto é o gesto; setas não ocupam a foto. */
@media (hover: none) {
    .bip-gallery__arrow { display: none; }
}

/* ===== Lightbox com galeria ===== */
.bip-image-lightbox__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 46px;
    height: 46px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: var(--radius);
    background: rgba(28, 28, 28, .55);
    color: #ececec;
    font-size: 30px;
    line-height: 1;
    cursor: pointer;
    transition: background .15s ease;
    z-index: 2;
}

.bip-image-lightbox__nav:hover { background: rgba(28, 28, 28, .78); }
.bip-image-lightbox__nav--prev { left: 16px; }
.bip-image-lightbox__nav--next { right: 16px; }

.bip-image-lightbox__bar {
    position: relative;
    left: auto;
    right: auto;
    bottom: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 8px 12px 12px;
    background: var(--surface);
    border-top: 1px solid var(--border);
    pointer-events: none;
}

.bip-image-lightbox__counter {
    padding: 0;
    border-radius: 0;
    background: none;
    color: var(--text-2);
    font-size: 12px;
    font-weight: 600;
}

.bip-image-lightbox__dots {
    display: flex;
    gap: 8px;
    pointer-events: auto;
}

.bip-image-lightbox__dot {
    width: 8px;
    height: 8px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--text-3);
    cursor: pointer;
    transition: background .15s ease, transform .15s ease;
}

.bip-image-lightbox__dot.is-active {
    background: var(--text);
    transform: scale(1.2);
}

@media (max-width: 600px) {
    .bip-image-lightbox__nav { width: 38px; height: 38px; font-size: 24px; }
    .bip-image-lightbox__nav--prev { left: 6px; }
    .bip-image-lightbox__nav--next { right: 6px; }
}

/* ===== Foto aberta com DONO e INTERAÇÃO (04/08/26) =====
   A tela cheia era foto crua + X. Agora tem autor com selo no topo e, embaixo,
   a moeda da casa: as estrelas e o comentar. Nada de emoji decorativo — voto
   de 1 a 5 é o que alimenta a entrega do feed.

   CONTRASTE NO CLARO (23/08/26): esta faixa usava `var(--text-1, #fff)`, e
   `--text-1` NÃO EXISTE na paleta (o token da casa é `--text`). No tema claro
   o cartão é `--surface` branco e o fallback branco pintava o nome e o X por
   cima — ilegível, o que o dono marcou. Tokens reais: `--text` / `--text-2` /
   `--bg-2`. A faixa deixa de ser vidro translúcido e vira barra do cartão. */
.bip-image-lightbox__top {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px 12px 16px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    z-index: 3;
}

.bip-image-lightbox__author {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
    text-decoration: none;
    color: var(--text);
    padding: 4px 10px 4px 4px;
    border-radius: 10px;
    transition: background .15s ease;
}

.bip-image-lightbox__author:hover { background: var(--surface-3); }

.bip-image-lightbox__avatar {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    object-fit: cover;
    flex: none;
}

.bip-image-lightbox__ident {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.bip-image-lightbox__name {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 15px;
    font-weight: 600;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bip-image-lightbox__handle {
    font-size: 12px;
    color: var(--text-2);
}

/* O X fica SEMPRE à direita da faixa, mesmo sem autor. */
.bip-image-lightbox__top .bip-image-lightbox__close {
    position: static;
    flex: none;
    margin-left: auto;
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-2);
    color: var(--text);
    font-size: 22px;
    cursor: pointer;
    transition: background .15s ease, border-color .15s ease;
}

.bip-image-lightbox__top .bip-image-lightbox__close:hover {
    background: var(--nav-hover, var(--bg-2));
    border-color: var(--border-hover);
}

.bip-image-lightbox__actions {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 8px 14px;
    border-radius: 12px;
    background: var(--bg-2);
    border: 1px solid var(--border);
    pointer-events: auto;
}

/* A FILEIRA DO APP NA FOTO ABERTA (18/09/26): no lugar dos polegares, o
   coração e a seta do dislike (os mesmos botões do cartão, copiados pelo
   bips-ui.js), um traço, e o comentar. Como no app: caixa de 22, número só a
   partir de 1 (igual ao do comentar ao lado) e a cor do texto da faixa, com o
   vermelho do coração e da seta quando acesos. */
.bip-image-lightbox__actions .bip-action-btn {
    margin: 0;
    padding: 2px 4px;
    gap: 5px;
}

/* Os números da faixa na letra da casa: botão não herda a fonte da página. */
.bip-image-lightbox__actions button {
    font-family: inherit;
}

.bip-image-lightbox__actions .bip-action-btn:not(.is-hearted):not(.is-disliked),
[data-theme="light"] .bip-image-lightbox__actions .bip-action-btn:not(.is-hearted):not(.is-disliked) {
    color: var(--text);
}

.bip-image-lightbox__actions .bip-action-count,
[data-theme="light"] .bip-image-lightbox__actions .bip-action-count {
    color: inherit;
    font-size: 14px;
    min-width: 0;
}

.bip-image-lightbox__actions .bip-action-count[data-count="0"] { display: none; }

.bip-image-lightbox__actions .bip-action-icon { width: 22px; height: 22px; }

.bip-image-lightbox__sep {
    flex: none;
    width: 1px;
    height: 22px;
    background: var(--border);
}

/* O beijo do coração nasce no `body` com z-index 9999, e a foto aberta mora em
   10060: tocado aqui, o sopro sairia por baixo dela. */
body.bip-image-lightbox-open .bip-beijo { z-index: 10070; }

.bip-image-lightbox__comment {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: none;
    background: none;
    color: var(--text);
    font-size: 14px;
    cursor: pointer;
    padding: 2px 4px;
}

.bip-image-lightbox__comment svg { width: 22px; height: 22px; }

@media (max-width: 600px) {
    .bip-image-lightbox__actions { gap: 10px; padding: 7px 12px; }
    .bip-image-lightbox__name { font-size: 14px; }
}

/* Emoji da foto aberta = COMENTÁRIO publicado (um toque). Fica ACIMA da barra
   de estrelas para não competir com o voto — são coisas diferentes. */
.bip-image-lightbox__emojis {
    display: flex;
    gap: 2px;
    padding: 4px 8px;
    border-radius: 12px;
    background: var(--bg-2);
    border: 1px solid var(--border);
    pointer-events: auto;
}

.bip-image-lightbox__emoji {
    border: none;
    background: none;
    font-size: 24px;
    line-height: 1;
    padding: 5px 7px;
    border-radius: 8px;
    cursor: pointer;
    transition: transform .12s ease, background .15s ease, opacity .15s ease;
}

.bip-image-lightbox__emoji:hover {
    background: var(--surface-3);
    transform: scale(1.18);
}

/* Enviado: some devagar em vez de sumir seco — a pessoa vê que foi. */
.bip-image-lightbox__emoji.is-sent {
    transform: scale(1.35);
    opacity: .45;
    cursor: default;
}

@media (max-width: 600px) {
    .bip-image-lightbox__emoji { font-size: 21px; padding: 4px 5px; }
}

/* Um emoji por BiP: depois do toque a fileira inteira fica opaca e surda —
   o escolhido continua um pouco mais visível que os outros. */
.bip-image-lightbox__emojis.is-done .bip-image-lightbox__emoji {
    opacity: .3;
    cursor: default;
    pointer-events: none;
}

.bip-image-lightbox__emojis.is-done .bip-image-lightbox__emoji.is-sent {
    opacity: .75;
    transform: scale(1.2);
}

/* ==========================================================================
   BARRA FLUTUANTE DE FORMATAÇÃO (07/08/26) — aparece sobre a seleção no
   editor WYSIWYG. Sete formatos, como no Telegram: negrito, itálico,
   sublinhado, riscado, monoespaçado, spoiler e citação. Sem cor.

   A BARRA QUE NÃO SUMIA (09/08/26): o `display: flex` abaixo anulava o
   `barra.hidden = true` do JavaScript, e o esconder nunca aconteceu. Quem
   conserta é a regra `[hidden]` do RESET, no topo deste arquivo — não mexa
   nela sem ler o comentário de lá.
   ========================================================================== */
.bip-fmt {
    position: absolute;
    z-index: 10120;
    display: flex;
    gap: 2px;
    padding: 4px;
    border-radius: 10px;
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: 0 6px 20px rgba(0, 0, 0, .18);
}


.bip-fmt__btn {
    width: 34px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 7px;
    background: transparent;
    color: var(--text);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    font-family: inherit;
}

.bip-fmt__btn:hover { background: var(--bg-2); }
.bip-fmt__btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Seleção que JÁ tem o formato: o botão acende (contrato do Telegram). */
.bip-fmt__btn.is-active {
    background: var(--accent-soft);
    color: var(--accent);
}

/* Cada botão se parece com o que faz — o rótulo É a amostra. */
.bip-fmt__btn--b { font-weight: 800; }
.bip-fmt__btn--i { font-style: italic; font-weight: 600; }
.bip-fmt__btn--u { text-decoration: underline; text-underline-offset: 3px; font-weight: 600; }
.bip-fmt__btn--s { text-decoration: line-through; font-weight: 600; }
.bip-fmt__btn--m { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-weight: 600; font-size: .92rem; }
.bip-fmt__btn--sp svg, .bip-fmt__btn--q svg { display: block; }

/* ==========================================================================
   EDITOR WYSIWYG (07/08/26) — o contenteditable que substitui o textarea.
   Ele herda a cara do campo pelas MESMAS classes (.compose-modal__textarea /
   .bip-reply-input); aqui só o que um div precisa e um textarea não.
   ========================================================================== */
.bip-editor {
    position: relative; /* âncora do placeholder absoluto (ver ::before) */
    white-space: pre-wrap;
    overflow-wrap: break-word;
    word-break: break-word;
    overflow-y: auto;
    max-height: 280px;
    cursor: text;
}

.bip-editor.bip-reply-input { max-height: 220px; }

.bip-editor:focus { outline: none; }

.bip-editor[contenteditable="false"] {
    opacity: .72;
    cursor: default;
}

/* Placeholder de contenteditable: pseudo-elemento enquanto vazio.
   FORA DO FLUXO (08/08/26, reportado pelo dono): com `float: left` o
   pseudo-elemento OCUPAVA espaço na linha e o cursor piscava DEPOIS dele —
   parecia texto de verdade já digitado. Absoluto, ele vira pintura de fundo:
   o cursor nasce no começo, como em qualquer caixa de texto, e o placeholder
   some no primeiro caractere (data-empty). O `padding: inherit` alinha a
   dica exatamente onde o texto vai nascer. */
.bip-editor[data-empty="true"]::before {
    content: attr(data-placeholder);
    position: absolute;
    inset: 0;
    padding: inherit;
    color: var(--text-2);
    opacity: .75;
    pointer-events: none;
    overflow: hidden;
    white-space: pre-wrap;
}

/* A formatação DENTRO do editor — o que se vê é o que se publica. */
.bip-editor b { font-weight: 700; }
.bip-editor i { font-style: italic; }
.bip-editor u { text-decoration: underline; text-underline-offset: 3px; }
.bip-editor s { text-decoration: line-through; }

.bip-editor .bip-ed-mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .92em;
    background: var(--surface-2);
    border-radius: 5px;
    padding: 1px 4px;
}

/* O EMOJI ANIMADO na caixa (05/09/26): um halo pulsando diz "este vai ganhar
   vida" — a animação de verdade a pessoa já viu na aba de escolha, e um <img>
   dentro do contenteditable quebraria o modelo (offsets são texto). */
.bip-editor .bip-ed-anim {
    border-radius: 6px;
    padding: 0 2px;
    background: color-mix(in srgb, var(--accent) 16%, transparent);
    animation: bipEdAnimPulso 1.6s ease-in-out infinite;
}

@keyframes bipEdAnimPulso {
    50% { background: color-mix(in srgb, var(--accent) 32%, transparent); }
}

@media (prefers-reduced-motion: reduce) {
    .bip-editor .bip-ed-anim { animation: none; }
}

/* Spoiler no EDITOR fica legível (o autor precisa ver o que escreveu): a
   mesma poeira do card, parada e suave, só marcando o trecho coberto. */
.bip-editor .bip-ed-spoiler {
    border-radius: 5px;
    padding: 0 2px;
    -webkit-box-decoration-break: clone;
    box-decoration-break: clone;
    background-color: color-mix(in srgb, var(--text) 10%, transparent);
    background-image:
        radial-gradient(circle, color-mix(in srgb, var(--white) 45%, transparent) 0.8px, transparent 1.1px),
        radial-gradient(circle, color-mix(in srgb, var(--white) 28%, transparent) 0.6px, transparent 0.9px);
    background-size: 15px 15px, 21px 25px;
}

.bip-editor .bip-ed-quote {
    display: block;
    margin: 4px 0;
    padding: 3px 10px;
    border-left: 3px solid var(--accent);
    border-radius: 4px;
    background: var(--accent-soft);
}

/* =========================================================================
   COMPOSITOR EM FOLHAS FOCADAS (08/08/26)
   O "+" abre DIRETO o compositor de texto (18/08/26) — foto e enquete são
   botões dentro dele, e a folha de escolha morreu. Sobraram dois modos, Texto
   e Enquete, sobre UM markup só: o #bip-content é resolvido uma única vez, no
   carregamento, e alimenta partes, contador, auto-crescimento e envio. Dois
   editores seriam dois contadores, um deles mudo — por isso o que muda entre
   os modos é o que APARECE, nunca o que existe.
   ========================================================================= */

/* --- Geometria da meia-tela: cola no rodapé, deixa o feed aparecer --- */
#modal-bip-compose.tool-modal {
    place-items: end center;
    padding: 0;
}

/* O fundo escurece menos que o dos outros modais: a graça é continuar vendo
   o BiP atrás. O desfoque some — desfocar o feed é perdê-lo de vista. */
#modal-bip-compose .tool-modal__backdrop {
    background: rgba(8, 8, 8, 0.55);
    backdrop-filter: blur(2px);
}

/* Os ids entram por ESPECIFICIDADE: tools.css crava a largura do compositor em
   `.tool-modal__panel.compose-modal__panel`, que empata com qualquer seletor de
   duas classes — e empate se decide por ordem de arquivo, que muda com bundle. */
#modal-bip-compose .tool-modal__panel.compose-sheet {
    width: min(600px, 100%);
    max-width: 100%;
    border-radius: 22px 22px 0 0;
    border-bottom: none;
    box-shadow: 0 -18px 48px rgba(0, 0, 0, 0.45);
    padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
    animation: composeSheetUp 0.26s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* A folha do compositor pode crescer com foto/agenda; a da escolha é baixa. */
#modal-bip-compose .compose-sheet {
    max-height: min(88dvh, 720px);
    overflow-y: auto;
}

/* Com emoji/GIF abertos para baixo, o recorte da folha cortava o picker. */
#modal-bip-compose .compose-sheet:has(.bip-emoji-panel:not([hidden])),
#modal-bip-compose .compose-sheet:has(.bip-gif-panel:not([hidden])),
#modal-bip-compose .compose-sheet:has(.compose-submit-split__menu:not([hidden])) {
    overflow: visible;
}

/* =========================================================================
   NO COMPUTADOR NÃO É FOLHA, É JANELA (09/08/26, pedido do dono).

   A meia-tela colada no rodapé foi desenhada para o CELULAR, onde o polegar
   alcança o de baixo e o feed continua à vista. No monitor ela caía no pé da
   tela, longe dos olhos, e o `overflow-y: auto` acima cortava o seletor de
   emoji — que é `position: absolute` e abre para fora do painel. Daí a barra
   de rolagem no meio do compositor e os emojis "quebrados" pela metade: o
   painel existia inteiro, só estava sendo recortado pelo modal.

   No computador: janela ancorada no ALTO, cantos arredondados nos quatro
   lados, sem animação de folha e SEM recorte — o seletor abre por cima de
   tudo, como manda um popover. No celular, nada muda.
   ========================================================================= */
@media (min-width: 768px) {
    #modal-bip-compose.tool-modal {
        place-items: start center;
        padding: 4vh 24px 24px;
    }

    #modal-bip-compose .tool-modal__panel.compose-sheet {
        border-radius: 22px;
        border-bottom: 1px solid var(--border);
        box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
        padding-bottom: 18px;
        animation: none;
    }

    /* Sem recorte: é isto que devolve o seletor de emoji inteiro. O conteúdo
       do compositor cabe de sobra em 4vh do topo — quem cresce é a foto, e ela
       já tem moldura própria. */
    #modal-bip-compose .compose-sheet {
        max-height: none;
        overflow: visible;
    }

    /* A alça é o "isto se puxa" do celular; numa janela ela não significa nada. */
    #modal-bip-compose .compose-sheet__grabber {
        display: none;
    }
}

@keyframes composeSheetUp {
    from { transform: translateY(100%); }
    to   { transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .tool-modal__panel.compose-sheet { animation: none; }
}

/* Alça: o sinal de "isto se puxa", igual ao menu do celular. */
.compose-sheet__grabber {
    display: block;
    width: 36px;
    height: 4px;
    margin: -4px auto 12px;
    border-radius: 999px;
    background: var(--border-hover);
}

/* --- O que cada modo mostra --- */

/* TEXTO É A JANELA INTEIRA (18/08/26). Antes ela escondia foto e enquete para
   "não competir por atenção" — mas a competição só existia porque a escolha
   vinha antes, numa folha à parte. Sem essa folha, esconder os dois botões
   deixaria a pessoa sem nenhum caminho para foto ou enquete. O editor da
   enquete continua fora daqui: quem o abre troca o modo para `enquete`. */
.compose-modal--kind-texto #bip-poll-editor {
    display: none !important;
}

/* Entrou foto: ela sobe para cima do texto pelo `order` — nenhum elemento muda
   de lugar no DOM e nenhum listener se perde. (O preview é injetado pelo JS
   depois da caixa de texto.) */
.compose-modal--kind-texto.compose-modal--has-image #bip-image-preview { order: -1; }

/* Com foto o texto vira LEGENDA: a caixa nasce baixa (o auto-crescimento faz o
   resto). Sem isto ela entra com os 104px de sempre e, somada à foto, empurra a
   janela para 88% da altura.
   O #bip-compose entra no seletor porque a régua de sempre também usa id
   (`#bip-compose .compose-editor-box .compose-modal__textarea`) e id ganha de
   classe, não importa a ordem no arquivo. */
.compose-modal--kind-texto.compose-modal--has-image #bip-compose .compose-editor-box .compose-modal__textarea {
    min-height: 56px;
}

/* Cabeçalho enxuto nas folhas (08/08/26). O título centrado e grande era do
   tempo em que o compositor era UMA tela com tudo; numa folha focada ele só
   empurra o conteúdo para fora da metade da tela. */
.compose-modal--kind-texto .compose-modal__intro,
.compose-modal--kind-enquete .compose-modal__intro {
    margin-bottom: 10px;
    padding-bottom: 10px;
    /* Só o X à direita mora aqui desde 18/08/26 — a seta de voltar morreu com a
       folha de escolha, e com ela o recuo da esquerda: o título começa na
       margem, como todo texto da janela. */
    padding-right: 44px;
    min-height: 40px;
}

/* TÍTULO CENTRADO (18/08/26, ordem do dono) — o mesmo desenho da folha do app.
   Ele foi para a esquerda em 08/08, quando o compositor virou "folha focada" e
   o título dividia a linha com outras peças. Hoje ele está sozinho na faixa, e
   um título encostado na margem sob um cabeçalho simétrico ficava torto. */
.compose-modal--kind-texto .compose-modal__headline,
.compose-modal--kind-enquete .compose-modal__headline {
    font-size: 1.2rem;
    text-align: center;
    margin-bottom: 2px;
    /* O X é absoluto no canto: sem o mesmo recuo dos dois lados, "centro" seria
       o meio do espaço que sobra, e o título nasceria deslocado para a
       esquerda. O `padding-right: 44px` do .compose-modal__intro ganha aqui o
       par simétrico. */
    padding-left: 44px;
}

.compose-modal--kind-texto .compose-modal__tagline,
.compose-modal--kind-enquete .compose-modal__tagline {
    font-size: 0.8rem;
    text-align: center;
    margin-left: 0;
    margin-right: 0;
    padding-left: 44px;
}

/* Enquete: as regras de foco já existiam em .compose-modal--poll (o JS liga as
   duas juntas); aqui só garantimos que a foto não volte pela barra — enquete e
   foto continuam sendo excludentes. */
.compose-modal--kind-enquete #btn-bip-image {
    display: none !important;
}

/* Os ícones da barra do feed viraram atalho (08/08/26): ganham o realce de
   quem se clica — antes eram só enfeite e nada respondia ao passar do mouse. */
.feed-composer__quick {
    border-radius: 10px;
    cursor: pointer;
    transition: background var(--duration);
}

.feed-composer__quick:hover {
    background: var(--surface-2);
}

/* =========================================================================
   A BARRA DO FEED, SIMÉTRICA (08/08/26 — a mesma do app)
   Três abas dividindo o espaço em partes iguais e riscos leves entre as
   caixas. O Filtro que fechava pela direita (e que desde 08/08/26 guardava
   "Seguindo" e "Seguidores" dentro dele) morreu em 11/09/26, ordem do dono:
   "Remover o campo filtro, não precisamos mais dele".
   ========================================================================= */

/* O trilho ocupa a linha inteira: não há mais nada disputando a largura. */
.feed-pills-row > .feed-pills {
    flex: 1 1 auto;
}

/* As três abas repartem a linha em partes iguais. Era
   `.feed-pill:not(.feed-pill--filtro)` enquanto o Filtro existia (11/09/26);
   o :not() saiu com ele, e as três declarações são as mesmas. */
.feed-pills .feed-pill {
    flex: 1 1 0;
    min-width: 0;
    justify-content: center;
}

/* O risco: fininho, discreto, e some quando encosta na pastilha branca —
   encostado nela viraria um traço desenhado por cima. */
.feed-pills__risco {
    flex: 0 0 auto;
    align-self: center;
    width: 1px;
    height: 18px;
    background: var(--border-hover);
    opacity: 0.55;
    transition: opacity var(--duration);
}

.feed-pill.is-active + .feed-pills__risco,
.feed-pills__risco:has(+ .feed-pill.is-active) {
    opacity: 0;
}

/* O "Filtro ACESO" (.feed-pill--filtro.is-on) e o pontinho
   .feed-filter-btn__dot saíram em 11/09/26 com o filtro. */

/* ==========================================================================
   PÁGINA DO SELO (09/08/26) — a ponte entre o site e a prova facial do app.
   ========================================================================== */
.selo-page {
    padding-top: var(--rail-stack-gap, 16px);
    padding-bottom: 48px;
}

/* ── VERIFICAÇÃO FACIAL PELO NAVEGADOR (25/08/26) ─────────────────────────
   O bloco que resolve o selo sem sair do site. Fica DENTRO do cartão do selo,
   com moldura própria e cor de destaque: ele é a ação da página, e o QR do app
   virou a alternativa logo abaixo. */

.selo-facial {
    margin: 18px 0 8px;
    padding: 16px;
    border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
    border-radius: 16px;
    background: color-mix(in srgb, var(--accent) 6%, var(--surface));
    text-align: left;
}

.selo-facial__cabeca {
    display: flex;
    gap: 12px;
    align-items: flex-start;
}

.selo-facial__cabeca > i {
    font-size: 1.6rem;
    color: var(--accent);
    flex-shrink: 0;
}

.selo-facial__cabeca strong {
    display: block;
    font-size: 1rem;
    color: var(--text-1);
    margin-bottom: 4px;
}

.selo-facial__cabeca p {
    margin: 0;
    font-size: 0.88rem;
    line-height: 1.5;
    color: var(--text-2);
}

.selo-facial__btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 14px;
}

.selo-facial__palco[hidden] {
    display: none;
}

.selo-facial__palco {
    margin-top: 16px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}

/* A MOLDURA REDONDA não é enfeite: ela diz onde o rosto tem de ficar, e é o que
   faz a pessoa se centralizar sozinha sem uma linha de instrução. */
.selo-facial__moldura {
    width: min(280px, 70vw);
    aspect-ratio: 1;
    border-radius: 50%;
    overflow: hidden;
    background: #000;
    border: 3px solid var(--accent);
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

/* ENQUADROU: a moldura responde antes de qualquer frase — é o vivo dizendo
   "assim está bom, agora pisque" (classe posta pelo selo-facial.js). */
.selo-facial__moldura.is-pronto {
    border-color: #12a150;
    box-shadow: 0 0 0 4px color-mix(in srgb, #12a150 25%, transparent);
}

.selo-facial__moldura video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* ESPELHADO NA TELA porque é assim que a pessoa se reconhece. A PROVA
       gravada é desespelhada no canvas — ver `capturar()` em selo-facial.js. */
    transform: scaleX(-1);
}

.selo-facial__trilho {
    width: min(280px, 70vw);
    height: 6px;
    border-radius: 999px;
    background: var(--surface-2);
    overflow: hidden;
}

.selo-facial__trilho > span {
    display: block;
    width: 0;
    height: 100%;
    border-radius: 999px;
    background: var(--accent);
    transition: width 0.25s ease;
}

/* O AVISO SAIU DE DENTRO DO PALCO (02/09/26) — ver selo.php. O palco é um
   flex-column centralizado, e era ele quem centrava esta frase; fora dele, ela
   se centra sozinha (`margin-inline: auto`), senão a mensagem de erro nasceria
   colada na esquerda do cartão no dia em que mais importa ser lida.

   `min-height` reserva a linha: sem ela, o texto aparecendo empurra o resto do
   cartão para baixo no instante em que a câmera fecha — e a pessoa perde de
   vista justamente a frase que acabou de surgir. */
.selo-facial__aviso {
    margin: 12px auto 0;
    max-width: 340px;
    min-height: 1.3em;
    text-align: center;
    font-size: 0.9rem;
    line-height: 1.45;
    color: var(--text-1);
}

.selo-facial__aviso[hidden] { display: none; }

.selo-facial__aviso.is-erro { color: #dc2626; }
.selo-facial__aviso.is-ok { color: #12a150; font-weight: 700; }

.selo-card {
    padding: 28px 24px;
    border: 1px solid var(--border);
    border-radius: 16px;
    background: var(--surface);
}

.selo-vitalicia {
    margin-top: 20px;
    padding: 24px;
    border: 1px solid color-mix(in srgb, #7546D8 38%, var(--border));
    border-radius: 16px;
    background: color-mix(in srgb, #7546D8 5%, var(--surface));
}

.selo-vitalicia__heading {
    display: flex;
    align-items: center;
    gap: 10px;
    color: #7546D8;
}

.selo-vitalicia__heading h2 {
    margin: 0;
    font-size: 1.23rem;
    color: var(--white);
}

.selo-vitalicia__heading > i {
    font-size: 1.4rem;
}

.selo-vitalicia__number,
.selo-vitalicia__step {
    display: grid;
    place-items: center;
    flex: none;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: #7546D8;
    color: #fff;
    font-weight: 700;
    font-size: 0.84rem;
}

.selo-vitalicia > p {
    margin: 12px 0 0;
    line-height: 1.55;
    color: var(--text-2);
}

.selo-vitalicia__benefit {
    font-weight: 600;
}

.selo-vitalicia .selo-vitalicia__status {
    margin: 18px 0 0;
    padding: 11px 13px;
    border-radius: 10px;
    background: color-mix(in srgb, #7546D8 12%, var(--surface));
    color: var(--white);
}

.selo-vitalicia__status[data-status="approved"] {
    color: #7546D8;
    font-weight: 700;
}

.selo-vitalicia__grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    margin-top: 18px;
}

.selo-vitalicia__grid[hidden],
.selo-vitalicia__slot [hidden] {
    display: none !important;
}

.selo-vitalicia__slot {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    min-width: 0;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
}

.selo-vitalicia__slot.is-done {
    border-color: color-mix(in srgb, #7546D8 40%, var(--border));
}

.selo-vitalicia__slot.is-locked:not(.is-done) {
    opacity: 0.7;
}

.selo-vitalicia__slot label {
    color: var(--white);
    font-weight: 700;
}

.selo-vitalicia__slot input[type="file"] {
    max-width: 100%;
    color: var(--text-2);
    font: inherit;
    font-size: 0.87rem;
}

.selo-vitalicia__slot button {
    width: 100%;
}

.selo-vitalicia__done {
    color: #7546D8;
    font-weight: 700;
}

@media (max-width: 600px) {
    .selo-vitalicia { padding: 18px; }
    .selo-vitalicia__grid { grid-template-columns: 1fr; }
}

/* Quem já tem o selo vê o selo primeiro, grande e centralizado: a página é o
   comprovante dela, não um formulário. */
.selo-card--tem {
    text-align: center;
}

.selo-card__marca {
    display: flex;
    justify-content: center;
    margin-bottom: 14px;
}

.selo-card__marca svg {
    width: 72px;
    height: 72px;
}

.selo-card__titulo {
    margin: 0 0 8px;
    font-size: 1.28rem;
    font-weight: 700;
    color: var(--white);
}

.selo-card__texto {
    margin: 0 0 22px;
    line-height: 1.6;
    color: var(--text-2);
}

.selo-card__rodape {
    margin: 22px 0 0;
    padding-top: 18px;
    border-top: 1px solid var(--border);
    font-size: 0.92rem;
    line-height: 1.6;
    color: var(--text-2);
}

.selo-passos {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin: 0;
    padding: 0;
    list-style: none;
    text-align: left;
}

.selo-passos--feitos {
    display: inline-flex;
    margin: 0 auto;
}

.selo-passo {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface-3);
}

.selo-passo > i {
    flex: none;
    font-size: 1.35rem;
    line-height: 1.35;
    color: var(--text-3);
}

/* O passo cumprido fica verde e CALMO — nada de comemoração, é só um estado. */
.selo-passo--ok {
    border-color: var(--green-soft);
    background: var(--green-soft);
}

.selo-passo--ok > i {
    color: var(--green);
}

.selo-passo__corpo {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.selo-passo__corpo strong {
    color: var(--white);
    font-weight: 600;
}

.selo-passo__nota {
    font-size: 0.9rem;
    line-height: 1.5;
    color: var(--text-2);
}

.selo-qr {
    margin-top: 24px;
    padding-top: 22px;
    border-top: 1px solid var(--border);
}

.selo-qr__desktop {
    display: flex;
    gap: 22px;
    align-items: center;
}

/* Fundo BRANCO fixo, no claro e no escuro: leitor de QR quer contraste, e um
   código desenhado em cinza sobre cinza é um código que não lê. */
.selo-qr__codigo {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 172px;
    height: 172px;
    padding: 10px;
    border-radius: 12px;
    background: #ffffff;
    /* O TEXTO DE RESERVA PRECISA SER LEGÍVEL. A caixa tem fundo branco fixo (é o
       contraste que o leitor de QR exige), e a cor herdada é a do tema — no
       escuro, que é o padrão, o endereço ficava branco no branco. Quem estivesse
       sem JS via o mesmo quadrado vazio que o texto veio evitar. */
    color: #111827;
    font-size: 0.9rem;
    font-weight: 600;
    text-align: center;
    word-break: break-all;
}

.selo-qr__codigo svg {
    display: block;
    width: 100%;
    height: 100%;
}

.selo-qr__texto strong {
    display: block;
    margin-bottom: 6px;
    color: var(--white);
    font-weight: 600;
}

.selo-qr__texto p {
    margin: 0 0 8px;
    line-height: 1.55;
    color: var(--text-2);
}

.selo-qr__aviso {
    font-size: 0.88rem;
    color: var(--text-3);
}

.selo-qr__botao {
    display: inline-flex;
    gap: 8px;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 14px 18px;
    border-radius: 12px;
    background: var(--btn-azul);
    color: #ffffff;
    font-weight: 600;
    text-decoration: none;
}

.selo-qr__botao i {
    font-size: 1.2rem;
}

.selo-qr__esperando {
    margin: 18px 0 0;
    font-size: 0.88rem;
    color: var(--text-3);
}

@media (max-width: 640px) {
    .selo-qr__desktop {
        flex-direction: column;
        text-align: center;
    }
}

/* CHIP do agendamento no compositor (12/08/26): o "Pronto" deixa rastro.
   AO CENTRO desde 10/09/26 (dono: *"centralizar a pilula do agendamento"*):
   ele mora no bloco do título, que é centrado, e encostado à esquerda parecia
   sobra de outra caixa. `flex` + `width: fit-content` porque margem automática
   não centra elemento em linha — e o `[hidden]` continua vencendo, que a regra
   dele vem depois. */
.compose-sched-chip {
    display: flex;
    width: fit-content;
    align-items: center;
    gap: 6px;
    margin: 8px auto 0;
    padding: 5px 12px;
    border-radius: 999px;
    background: rgba(124, 92, 240, 0.14);
    border: 1px solid rgba(124, 92, 240, 0.45);
    color: #7C5CF0;
    font-size: 0.8rem;
    font-weight: 700;
}

.compose-sched-chip[hidden] {
    display: none;
}


/* ═══════════════════════════════════════════════════════════════════════════
   CAIXAS SEM BORDA (16/08/26, ordem do dono, com a referência de um feed
   moderno: "tire as bordas das nossas caixas do site").

   O contorno de 1px cumpria o papel de separar o cartão do fundo — mas o fundo
   já é cinza e o cartão já é branco: o traço só endurecia a página. Aqui ele
   cai nos CONTÊINERES (cartão do feed, cartões do rail, compositor e a caixa
   das pílulas). Botões, campos e chips MANTÊM as bordas: neles a linha não é
   enfeite, é a fronteira do que se pode tocar.

   Um bloco só, no fim do arquivo, para desfazer numa linha se o dono mudar de
   ideia — e não 69 edições espalhadas. */
.bip-card,
.rail-card,
.feed-composer,
.feed-pills,
/* 2ª leva (16/08/26, mesma régua): os cartões das PÁGINAS — comunidades, selo
   e os três de Configurações. As caixinhas DENTRO deles (as opções de tema,
   por exemplo) MANTÊM a borda: ali a linha é a fronteira do que se escolhe,
   não moldura ("remova as bordas somente dos 3 externos, dentro do tema
   deixa"). */
.selo-card,
/* 3ª leva: o PERFIL — os dois botões que ladeiam a foto (Visitantes /
   Depoimentos) e a caixa das abas (BiPs · Respostas · Reposts). O fundo
   próprio de cada um já os separa da página. */
.profile-cta-btn {
    border-color: transparent;
}

/* 4ª leva: os cartões do PAINEL do administrador (Técnico, Administrativo,
   BiP Comunidade, Moderação, Caderno de enquete). A borda sai em painel.css —
   aqui só garante que nenhum hover devolve o traço. */
.painel-hub__card,
.painel-hub__card:hover,
.comm-card,
.comm-card:hover,
.settings-card,
.profile-tabs {
    border: none;
}

/* No tema ESCURO o cartão e o fundo são quase o mesmo tom: sem o contorno, a
   separação vem de um degrau sutil de cor — nunca de uma linha. */
[data-theme="dark"] .bip-card,
[data-theme="dark"] .rail-card,
[data-theme="dark"] .feed-composer,
[data-theme="dark"] .comm-card,
[data-theme="dark"] .selo-card,
[data-theme="dark"] .settings-card {
    background: var(--surface);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.04);
}

/* ── A MARCA NOVA NA WEB (16/08/26, dono: "alinhar a nova logo") ─────────────
   A logo-oficial é UMA imagem (balão + 256bip): no sidebar e no título do
   feed, alinhada pela linha de base do texto ao lado.

   A COPIA DE `.sidebar-logo__marca` QUE MORAVA AQUI FOI EMBORA (29/08/26).
   Ela repetia, 11 mil linhas depois, o mesmo `display: block` da regra que
   vive junto do resto da barra — e, por ser a ÚLTIMA, ganhava de todo mundo:
   o menu encolhia, a peça deitada continuava lá e voltava a ser cortada. Uma
   regra, um lugar: a definição é a de `.sidebar-logo__marca` lá em cima. */

.app-topbar__slogan {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.app-topbar__slogan-logo {
    height: 30px;
    width: auto;
    display: inline-block;
    vertical-align: middle;
}

/* ── A LINHA DA BUSCA COM O SINO (16/08/26, dono: home sem a faixa de cima;
   "Explorar" um pouco menor e as notificações do lado direito). ─────────── */
.rail-topo-row {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 10px;
    width: 100%;
    flex-shrink: 0;
    position: relative;
    z-index: 1200;
}

.rail-topo-row .search-bar-wrap {
    flex: 1 1 auto;
    min-width: 0;
    width: auto;
    margin-bottom: 0;
}

/* A BUSCA E O SINO NA MESMA ALTURA (17/08/26, dono: "a pílula da busca está
   muito mais alta que o botão de notificações").

   A conta explica os 15px de diferença: a caixa da busca já tinha 10px de
   respiro em cima e embaixo (`.search-bar-wrap--rail .search-bar`), e em
   16/08 o "um tico menor" acrescentou MAIS 9px de padding NO INPUT, que é
   filho dela. Os dois se somavam — 19px de cada lado, mais o texto, davam ~55px
   contra os 40px do sino. O padding do input parecia estar encolhendo a caixa e
   estava era engordando.

   Agora quem manda é UMA altura fixa, igual à do sino, e o input não tem
   respiro vertical nenhum: com `align-items: center` no flex da caixa, o texto
   se centra sozinho. Mexer nesta altura passa a mexer nos dois de uma vez. */
.rail-topo-row--com-sino .search-bar {
    height: 40px;
    padding-top: 0;
    padding-bottom: 0;
}

.rail-topo-row--com-sino .search-bar__input {
    padding-top: 0;
    padding-bottom: 0;
    font-size: 13.5px;
}

.rail-topo-row .notif-wrap {
    position: relative;
    flex-shrink: 0;
}

.rail-topo-row .notif-bell {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--surface, #fff);
    border: 1px solid var(--border, #e3e6ea);
}

.rail-topo-row .notif-dropdown {
    right: 0;
    left: auto;
    top: calc(100% + 8px);
    z-index: 1300;
}

/* ── EDITAR PERFIL + MEU STATUS no menu de ações (16/08/26, ordem do dono) ── */
.sidebar-user-menu__sep {
    height: 1px;
    background: var(--border, #e3e6ea);
    margin: 6px 0;
}

.sidebar-user-menu__label {
    margin: 2px 0 4px;
    padding: 0 12px;
    color: var(--text-3, #8a8a8e);
    font-size: 11.5px;
    font-weight: 700;
    letter-spacing: 0.4px;
    text-transform: uppercase;
}

.sidebar-user-status {
    display: flex;
    flex-direction: column;
    max-height: 232px;
    overflow-y: auto;
    scrollbar-width: none;
}

.sidebar-user-status::-webkit-scrollbar {
    width: 0;
    display: none;
}

.sidebar-user-status__opt {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 12px;
    border: none;
    background: transparent;
    color: var(--text, #1b2430);
    font-size: 13.5px;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
    border-radius: 8px;
}

.sidebar-user-status__opt:hover {
    background: var(--surface-2, #f1f3f6);
}

.sidebar-user-status__dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex: none;
}

.sidebar-user-status__nome {
    flex: 1;
    min-width: 0;
}

.sidebar-user-status__check {
    color: var(--accent, #145BD7);
    font-size: 16px;
    opacity: 0;
}

.sidebar-user-status__opt.is-atual .sidebar-user-status__check {
    opacity: 1;
}

/* ── QUEM SEGUIR (16/08/26, ordem do dono): 3 pessoas sorteadas, com Seguir
   à direita — o desenho do cartão de sugestão que ele mandou de referência. */
.rail-seguir-lista {
    display: flex;
    flex-direction: column;
}

.rail-seguir {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 2px;
}

.rail-seguir + .rail-seguir {
    border-top: 1px dashed var(--border, #e3e6ea);
}

/* O pontilhado do "Quem seguir" nos outros cards do rail (11/09/26, ordem do
   dono: "ficou lindo, faça para os outros"): Bips em alta, aniversários, ativos
   hoje e Top Bipers do mês (comunidades vão junto, é a mesma lista). O mesmo
   traço; o padding-top devolve em cima o respiro que o gap do container já dá
   embaixo, e a linha fica no meio. */
.rail-user-list > li + li,
.rail-aniversarios__lista > li + li {
    border-top: 1px dashed var(--border, #e3e6ea);
    padding-top: 8px;
}

.rail-seguir__foto {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    overflow: hidden;
    flex: none;
    background: var(--surface-2, #eef1f5);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-3, #8a8a8e);
    font-size: 20px;
}

.rail-seguir__foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.rail-seguir__texto {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    text-decoration: none;
}

.rail-seguir__nome {
    color: var(--text, #1b2430);
    font-size: 13.5px;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rail-seguir__nick {
    color: var(--text-3, #8a8a8e);
    font-size: 12px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rail-seguir__btn {
    flex: none;
    /* Mesmo desenho do "Seguir" do cartão (17/08/26): são o MESMO botão em dois
       lugares, e dois desenhos para a mesma ação na mesma tela é o tipo de
       detalhe que ninguém sabe nomear mas todo mundo sente.
       PÍLULA PRETA DO AIPIM (11/09/26, ordem do dono), junto com o do cartão e
       pela mesma regra de 21/08: um "Seguir" só em toda a rede. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* MEDIDAS DO AIPIM (11/09/26, dono: "o nosso está muito maior"): 28px de altura, 11px. */
    height: 28px;
    padding: 0 14px;
    border: 0;
    border-radius: 999px;
    background: var(--seguir-bg);
    color: var(--seguir-fg);
    font-family: var(--font);
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    transition: background var(--duration) ease, color var(--duration) ease, transform 0.12s ease;
}

.rail-seguir__btn::before {
    /* O "+" saiu com a pílula preta (11/09/26) — ver a nota no cartão. */
    content: none;
}

.rail-seguir__btn:hover:not(:disabled) {
    background: var(--seguir-bg-hover);
    color: var(--seguir-fg);
}

.rail-seguir__btn:active:not(:disabled) {
    transform: scale(0.97);
}

.rail-seguir__btn:disabled {
    opacity: 0.6;
    cursor: default;
}

/* Perfil privado com pedido pendente (18/08/26): mesmo peso do botão, sem
   convite ao clique — "Solicitado" é estado, não ação. Pílula CINZA (11/09/26),
   o mesmo "feito" do cartão. */
.rail-seguir__estado {
    flex: none;
    display: inline-flex;
    align-items: center;
    /* Medidas do aipim (11/09/26): 28px e 11px, para casar com o botão ao lado. */
    height: 28px;
    padding: 0 12px;
    border-radius: 999px;
    background: var(--seguir-feito-bg);
    color: var(--seguir-feito-fg);
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
}

/* ── MÚSICA DO BiP (20/08/26) ─────────────────────────────────────────────
   UMA LINHA, não um cartão. O dono viu o cartão grande e disse "ficou muito
   feio"; o formato aceito foi o do Instagram — nota + artista · título, com um
   play discreto. Ela vive colada no fim do texto, dentro do mesmo cartão do
   BiP, e por isso não tem fundo próprio nem borda: um bloco a mais competiria
   com a foto logo acima. */
.bip-musica {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
    min-width: 0;
    font-size: 13.5px;
    color: var(--text-muted, #667085);
}

.bip-musica__play {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    cursor: pointer;
    background: var(--brand, #145BD7);
    padding: 0;
}

.bip-musica__tri {
    width: 0;
    height: 0;
    /* 1px de folga à esquerda: o triângulo tem o peso todo de um lado e,
       centrado pela caixa, parece encostado na borda esquerda do círculo. */
    margin-left: 2px;
    border-top: 5px solid transparent;
    border-bottom: 5px solid transparent;
    border-left: 8px solid #fff;
}

.bip-musica.is-playing .bip-musica__tri {
    /* Tocando, o triângulo vira as duas barras do pause — sem trocar de ícone
       (e sem um segundo SVG para carregar). */
    width: 9px;
    height: 10px;
    margin-left: 0;
    border: 0;
    background: linear-gradient(90deg, #fff 0 3px, transparent 3px 6px, #fff 6px 9px);
}

.bip-musica__nota {
    flex: 0 0 auto;
    font-size: 14px;
    line-height: 1;
    color: var(--brand, #145BD7);
}

.bip-musica__texto {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bip-musica.is-carregando .bip-musica__texto { opacity: 0.6; }

.bip-musica.is-off .bip-musica__play {
    background: var(--border, #d0d5dd);
    cursor: default;
    pointer-events: none;
}

/* A música no PERFIL usa a mesma linha do bip, com um respiro a mais: ali ela
   fecha o cartão, aqui ela fica solta entre o nome e as abas.

   CENTRALIZADA (21/08/26, ordem do dono). Dentro do bip ela é uma linha do
   cartão e alinha à esquerda com o texto; aqui, depois que a bio desceu para a
   ficha, ela ficou sozinha embaixo de um bloco inteiro centralizado — nome, @ e
   cidade — e era a única coisa encostada na margem esquerda. `width:fit-content`
   com margem automática porque ela é uma FILEIRA (botão + nota + texto):
   `text-align:center` centraria as palavras dentro dela, não ela na página. */
.profile-musica {
    width: fit-content;
    max-width: 100%;
    margin: 16px auto 18px;
}

/* ── PRÓXIMOS ANIVERSÁRIOS (21/08/26) ─────────────────────────────────────
   O quadro do Orkut, na barra e em tela cheia. Ordem do dono: *"no orkut
   tínhamos os próximos aniversários, vamos fazer isso na nossa barra... focar
   sempre no mês e um ver mais para abrir geral separado por meses"*.

   O ROSTO É O CONTEÚDO. No Orkut a linha era foto + nome + dia, e era a FOTO
   que fazia a pessoa reconhecer o amigo antes de ler. Por isso o avatar aqui é
   maior que o dos outros cartões da coluna. */
.rail-aniversarios__lista {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.rail-aniv__link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 4px;
    border-radius: 10px;
    text-decoration: none;
    color: inherit;
}

.rail-aniv__link:hover {
    background: var(--bg-2);
}

[data-theme="light"] .rail-aniv__link:hover {
    background: #EBECEF;
}

.rail-aniv__pic {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-3, rgba(148, 163, 184, 0.2));
    color: var(--text-3);
}

.rail-aniv__pic img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.rail-aniv__txt {
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}

/* Nome + bolo na MESMA linha: o bolo é irmão do nome (não filho) para o
   ellipsis do nome nunca cortar o bolo. */
.rail-aniv__linha {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.rail-aniv__bolo {
    flex: 0 0 auto;
}

.rail-aniv__nome {
    font-size: 0.86rem;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rail-aniv__dia {
    font-size: 0.75rem;
    color: var(--text-3);
}

/* HOJE tem cor, o resto não. Se todo dia tivesse destaque, nenhum dia teria. */
.rail-aniv--hoje .rail-aniv__dia {
    color: var(--accent);
    font-weight: 700;
}

/* ── A tela cheia ───────────────────────────────────────────────────────── */
.aniv-page {
    padding-top: var(--rail-stack-gap, 16px);
    padding-bottom: 48px;
}

.aniv-page__head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 14px;
}

.aniv-page__back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    color: var(--text);
    text-decoration: none;
    font-size: 1.3rem;
}

.aniv-page__back:hover {
    background: var(--bg-2);
}

.aniv-page__title {
    margin: 0;
    font-size: 1.15rem;
    font-weight: 700;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 8px;
}

.aniv-page__vazio,
.aniv-mes__vazio {
    margin: 0;
    font-size: 0.9rem;
    color: var(--text-3);
}

.aniv-mes {
    margin-bottom: 22px;
    padding: 14px 16px 16px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
}

/* O mês CORRENTE ganha o fio da marca à esquerda — é onde a pessoa está. */
.aniv-mes--atual {
    border-left: 3px solid var(--accent);
}

.aniv-mes__titulo {
    margin: 0 0 12px;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 8px;
}

.aniv-mes__conta {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--text-3);
    background: var(--bg-2);
    border-radius: 999px;
    padding: 1px 8px;
}

/* GRADE de rostos, como o quadro do Orkut — não uma lista em pé. Auto-fill
   para caber mais gente em tela larga sem esticar o avatar. */
.aniv-grade {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
    gap: 14px 10px;
}

.aniv-card__link {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    text-decoration: none;
    color: inherit;
    text-align: center;
}

.aniv-card__foto {
    width: 62px;
    height: 62px;
    border-radius: 50%;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-3, rgba(148, 163, 184, 0.2));
    color: var(--text-3);
    font-size: 1.6rem;
    border: 2px solid transparent;
}

.aniv-card__foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.aniv-card--hoje .aniv-card__foto {
    border-color: var(--accent);
}

.aniv-card__nome {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text);
    line-height: 1.2;
    overflow-wrap: anywhere;
}

.aniv-card__bolo {
    vertical-align: -3px;
    margin-left: 4px;
}

.aniv-card__dia {
    font-size: 0.72rem;
    color: var(--text-3);
}

.aniv-card--hoje .aniv-card__dia {
    color: var(--accent);
    font-weight: 700;
}

/* ── FÃS: a estrelinha do Orkut no placar (21/08/26) ──────────────────────
   É a ÚNICA coluna do placar que se toca para mudar — as outras levam a
   listas, esta muda o número na hora. Daí ela ser <button> e ter estado
   visível: sem o preenchido/vazio, a pessoa toca e não sabe se pegou. */
.profile-stat--fa {
    border: none;
    background: transparent;
    font: inherit;
    cursor: default;
    color: inherit;
}

button.profile-stat--fa {
    cursor: pointer;
}

.profile-stat__value--fa {
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

/* ── A ESTRELA SAIU DO PLACAR (12/09/26, ordem do dono: *"tirar a estrela de
   fã, não precisa, ali é só um contador, senão teria que ter para todos"*) ──
   As três regras que a pintavam (amarela sempre, halo no `is-fan`, crescer no
   hover) foram junto com o <i> do profile.php. O número, o rótulo e o toque
   de virar fã ficam; o estado segue no `aria-pressed` e no título ("Virar fã"
   / "Deixar de ser fã"), que o JS continua trocando com o `is-fan`. */

button.profile-stat--fa:disabled {
    opacity: 0.6;
}

/* ── ANIVERSÁRIOS: HOJE/AMANHÃ + FILTRO DE MÊS (22/08/26, ordem do dono) ─────
   *"um bloco exibindo os aniversariantes de hoje e os de amanhã, pronto, e além
   disso o filtro, mês a mês"*.

   A hierarquia é o ponto: em cima o que é AÇÃO (dá para dar parabéns AGORA),
   embaixo o que é CONSULTA. Antes os doze meses tinham o mesmo peso e o
   aniversário de hoje ficava do tamanho do de 14 de dezembro. */
.aniv-destaque {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-bottom: 14px;
}

.aniv-destaque__bloco {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 12px 14px;
}

/* Só o bloco de HOJE tem cor. Dois blocos destacados não destacam nada. */
.aniv-destaque__bloco--hoje {
    border-color: color-mix(in srgb, #ec4899 45%, transparent);
    background: color-mix(in srgb, #ec4899 6%, var(--surface));
}

.aniv-destaque__titulo {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 10px;
    font-size: 0.95rem;
    color: var(--text-1);
}

.aniv-destaque__bloco--hoje .aniv-destaque__titulo i {
    color: #ec4899;
}

/* ── O FILTRO: SEIS E SEIS, EM DUAS FILEIRAS ─────────────────────────────────
   23/08/26, ordem do dono: *"se são 12 meses, favor colocar 6 e 6 em duas
   linhas; não tem necessidade de colocar 12 em linha e criar uma barra de
   rolagem"*.

   Ele está certo, e o argumento antigo ("rolar é melhor que gastar altura")
   caiu por terra na prática: a fileira única escondia METADE do ano atrás de
   uma barra de rolagem — quem quer dezembro precisava descobrir que a lista
   andava, e arrastar até lá. Duas fileiras de seis mostram o ano INTEIRO de
   uma vez e custam ~40px, menos do que a própria barra de rolagem ocupava.

   `grid` com 6 colunas iguais, e não `flex-wrap`: com flex, a segunda fileira
   herdaria larguras diferentes da primeira e os meses ficariam desalinhados
   entre as linhas — que é justamente o que faria parecer desleixo. */
.aniv-filtro {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 6px;
    padding: 2px 2px 8px;
    margin-bottom: 10px;
}

/* Telas estreitas: três colunas, quatro fileiras. Seis pílulas num celular de
   360px dariam 52px cada, e "Dez 46" não cabe em 52px sem cortar. */
@media (max-width: 480px) {
    .aniv-filtro {
        grid-template-columns: repeat(3, 1fr);
    }
}

.aniv-filtro__mes {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1px;
    min-width: 0;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: 11px;
    background: var(--surface);
    color: var(--text-2);
    text-decoration: none;
    transition: border-color var(--duration, .16s) ease, background var(--duration, .16s) ease;
}

.aniv-filtro__mes:hover {
    border-color: var(--accent);
}

.aniv-filtro__nome {
    font-size: 0.78rem;
    font-weight: 600;
}

.aniv-filtro__n {
    font-size: 0.68rem;
    color: var(--text-3);
}

/* MÊS ABERTO (cheio) × MÊS CORRENTE (só o ponto). São coisas diferentes: um é
   onde você está, o outro é onde o calendário está — e em outubro olhando
   dezembro os dois precisam aparecer ao mesmo tempo. */
.aniv-filtro__mes.is-ativo {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.aniv-filtro__mes.is-ativo .aniv-filtro__n {
    color: rgba(255, 255, 255, 0.85);
}

.aniv-filtro__mes.is-atual:not(.is-ativo) {
    border-color: color-mix(in srgb, var(--accent) 55%, transparent);
}

.aniv-filtro__mes.is-atual::after {
    content: '';
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--accent);
}

.aniv-filtro__mes.is-ativo::after {
    background: #fff;
}

.aniv-paginacao {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 14px 4px 4px;
    flex-wrap: wrap;
}

.aniv-paginacao__btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface);
    color: var(--text-1);
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
}

.aniv-paginacao__btn:hover {
    border-color: var(--accent);
}

.aniv-paginacao__pos {
    font-size: 0.78rem;
    color: var(--text-3);
}

@media (max-width: 640px) {
    /* Um embaixo do outro: dois blocos de avatares lado a lado em 360px viram
       duas colunas de um rosto cada. */
    .aniv-destaque {
        grid-template-columns: 1fr;
    }
}

@media (prefers-reduced-motion: reduce) {
    .aniv-filtro__mes { transition: none; }
}

/* ── ARRASTAR AS FOTOS PARA ORDENAR (22/08/26, ordem do dono) ────────────────
   *"uma forma que eu possa arrastar as fotos para decidir qual será primeira e
   assim por diante, arrastar entre elas"*. A mecânica está em assets/js/index.js
   (ligarArrasteDasFotos).

   `touch-action: none` é OBRIGATÓRIO, não estilo: sem ele o navegador entende o
   arrasto do dedo como rolagem da página e a foto nunca sai do lugar no celular. */
.compose-attach__thumb {
    cursor: grab;
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
}

/* O NÚMERO é o que dá sentido ao arrasto: sem ele a pessoa não sabe qual é a
   primeira nem se o que arrastou surtiu efeito. O 1 fica em destaque porque é a
   única posição que muda o cartão inteiro — é a foto que abre o BiP. */
.compose-attach__ordem {
    position: absolute;
    left: 3px;
    bottom: 3px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: rgba(15, 23, 42, 0.72);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
    pointer-events: none;
}

.compose-attach__thumb:first-child .compose-attach__ordem {
    background: var(--accent);
}

.compose-attach__thumb.is-arrastando {
    cursor: grabbing;
    opacity: 0.85;
    transform: scale(1.06);
    box-shadow: 0 8px 20px rgba(15, 23, 42, 0.28);
    z-index: 2;
}

/* Enquanto se ordena, as outras dão um passo atrás — o alvo do arrasto fica
   óbvio sem precisar de linha pontilhada nem placeholder. */
.compose-attach__strip.is-ordenando .compose-attach__thumb:not(.is-arrastando) {
    opacity: 0.55;
}

.compose-attach__thumb,
.compose-attach__ordem {
    transition: transform var(--duration, .16s) ease, opacity var(--duration, .16s) ease;
}

@media (prefers-reduced-motion: reduce) {
    .compose-attach__thumb,
    .compose-attach__ordem { transition: none; }
}

/* ── VÍDEO DO YOUTUBE NO CARTÃO (22/08/26, ordem do dono) ────────────────────
   A MINIATURA é o estado normal; o iframe só nasce no toque (ver renderBipVideo
   em bips-ui.js). Dez vídeos no feed são dez imagens — não dez players. */
.bip-video {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    margin-top: 10px;
    border-radius: 12px;
    overflow: hidden;
    background: #000;
    cursor: pointer;
}

.bip-video__thumb {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.bip-video__frame {
    width: 100%;
    height: 100%;
    border: 0;
    display: block;
}

/* O botão de play É o do YouTube, e de propósito: a pessoa reconhece de longe
   o que aquilo faz, sem precisar de legenda. */
.bip-video__play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    background: none;
    cursor: pointer;
}

.bip-video__play svg {
    width: 68px;
    height: 48px;
    transition: opacity var(--duration, .16s) ease;
}

.bip-video__play-bg {
    fill: #212121;
    fill-opacity: 0.8;
}

.bip-video:hover .bip-video__play-bg {
    fill: #f00;
    fill-opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .bip-video__play svg { transition: none; }
}

/* ── A CAIXINHA DO YOUTUBE NO COMPOSITOR (22/08/26, ordem do dono) ───────────
   Refeita no mesmo dia, depois do teste: *"a lista de opções deve vir abaixo
   como em GIF e emoji, e o CSS está morto, não dá para ler o que está acima."*

   ERAM DOIS DEFEITOS NUM. Ela abria PARA CIMA e cobria o compositor inteiro —
   nome, visibilidade e o campo de texto sumiam atrás dela. E usava tokens que
   este painel não tem (`--surface`, `--text-1`): o fundo saía quase
   transparente e o título, claro sobre claro, ficava ilegível. Agora ela usa
   os MESMOS tokens do painel de GIF ao lado (`--bg-2`, `--bg-3`, `--text`),
   que é o que garante que os dois continuem iguais quando o tema mudar.

   ABAIXO do botão, como o dono pediu: a lista cresce para onde não há nada,
   em vez de por cima do que a pessoa está escrevendo. */
.bip-yt-wrap {
    position: relative;
    display: inline-flex;
}

.compose-add-btn--yt i {
    color: #f00;
}

.bip-yt-panel {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 30;
    display: flex;
    flex-direction: column;
    width: min(392px, 92vw);
    /* Teto + rolagem: sem isto uma busca de oito vídeos empurraria o painel
       para fora da janela e os últimos ficariam inalcançáveis. */
    max-height: 46vh;
    overflow-y: auto;
    padding: 8px;
    border-radius: 14px;
    background: var(--bg-2, #1e293b);
    border: 1px solid var(--border, rgba(148, 163, 184, 0.2));
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.42);
}

.bip-yt-panel[hidden] {
    display: none;
}

.bip-yt-campo {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--border, rgba(148, 163, 184, 0.22));
    border-radius: 10px;
    background: var(--bg-3, rgba(148, 163, 184, 0.1));
    color: var(--text, #e2e8f0);
    font: inherit;
    font-size: 0.9rem;
}

.bip-yt-campo::placeholder {
    color: var(--text-3, rgba(148, 163, 184, 0.8));
}

.bip-yt-dica {
    margin: 8px 2px 4px;
    font-size: 0.72rem;
    color: var(--text-3, rgba(148, 163, 184, 0.8));
    line-height: 1.4;
}

.bip-yt-status {
    margin: 10px 2px;
    font-size: 0.8rem;
    color: var(--text-3, rgba(148, 163, 184, 0.8));
}

.bip-yt-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 7px;
    border: 0;
    border-radius: 10px;
    background: none;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.bip-yt-item:hover {
    background: var(--bg-3, rgba(148, 163, 184, 0.12));
}

/* 16:9 na miniatura, como no YouTube: quadrada, ela corta o rosto de quem está
   no vídeo — que é justamente o que a pessoa usa para reconhecer o que procura. */
.bip-yt-item__thumb {
    width: 88px;
    height: 50px;
    object-fit: cover;
    border-radius: 7px;
    flex: 0 0 auto;
    background: #000;
}

.bip-yt-item__texto {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.bip-yt-item__titulo {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text, #e2e8f0);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.bip-yt-item__canal {
    font-size: 0.72rem;
    color: var(--text-3, rgba(148, 163, 184, 0.8));
}

/* ── A FAIXA DO VÍDEO ANEXADO (22/08/26, ordem do dono) ──────────────────────
   *"seria tão simples incluir uma faixa acima do adicionar bip, um svg lindo de
   vídeo e o título com o botão X para remover; pra que mostrar isso feio na
   caixa de texto?"*

   Ele estava certo: `[VIDEO]…[/VIDEO]` dentro do textarea era mostrar o
   encanamento. A faixa fica ENTRE o texto e a barra de ações — o mesmo lugar da
   prévia da foto, que é onde o olho procura o que foi anexado. */
.compose-video-chip {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 10px 0 0;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface-3, rgba(148, 163, 184, 0.1));
}

.compose-video-chip__thumb {
    width: 62px;
    height: 35px;
    object-fit: cover;
    border-radius: 6px;
    flex: 0 0 auto;
    background: #000;
}

.compose-video-chip__texto {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
    flex: 1 1 auto;
}

/* A marca vermelha do YouTube diz de onde o vídeo veio sem gastar uma palavra —
   e é o que evita a pessoa achar que subiu um vídeo para os nossos servidores. */
.compose-video-chip__marca {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--text-3);
}

.compose-video-chip__marca svg {
    width: 16px;
    height: 16px;
}

.compose-video-chip__titulo {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-1);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.compose-video-chip__x {
    flex: 0 0 auto;
    width: 26px;
    height: 26px;
    border: 0;
    border-radius: 50%;
    background: rgba(15, 23, 42, 0.08);
    color: var(--text-2);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}

.compose-video-chip__x:hover {
    background: rgba(220, 38, 38, 0.15);
    color: #dc2626;
}


/* ── O SELETOR DUPLO (23/08/26, dono, com a referência Monthly/Yearly:
   *"isso vai elevar o nível de beleza"*). Duas palavras sempre à vista e a
   pastilha azul deslizando para a escolhida — o gesto das pílulas do feed,
   agora em par. O thumb é um elemento só, movido por transform: animar
   background em dois botões piscaria em vez de deslizar. ── */
.bip-seg {
    position: relative;
    display: flex;
    width: 100%;
    padding: 4px;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
}

.bip-seg__thumb {
    position: absolute;
    top: 4px;
    bottom: 4px;
    left: 4px;
    width: calc(50% - 4px);
    border-radius: 999px;
    background: var(--btn-azul, #4070B0);
    transition: transform 0.18s ease;
}

.bip-seg--dir .bip-seg__thumb {
    transform: translateX(100%);
}

.bip-seg__opt {
    position: relative;
    z-index: 1;
    flex: 1;
    border: 0;
    background: none;
    padding: 9px 0;
    border-radius: 999px;
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--muted);
    cursor: pointer;
    transition: color 0.18s ease;
}

.bip-seg__opt.is-on {
    color: #fff;
}

/* ── A FOTO INTEIRA SOBRE O SEU PRÓPRIO BORRÃO (24/08/26) ─────────────────
   Ordem do dono: *"o nosso espaço não é 3x4, mas a imagem é, então fica muito
   feio a exibição assim; temos que exibir a imagem aqui com canva neste
   formato e ao tocar abrir o 3x4 normal"*.

   A moldura do cartão é mais larga do que alta. Com `object-fit: cover`, foto
   em pé perdia as bordas — e num print (que é metade do que se posta) a borda
   é onde está o texto. Aqui ela entra INTEIRA, centrada, e o vão das laterais
   recebe a mesma foto ampliada e desfocada. O toque continua abrindo o
   lightbox com o arquivo original, no 3:4 dele.

   Estas regras vêm DEPOIS das antigas de propósito: mesma especificidade,
   última ganha — e assim a moldura antiga continua valendo para tudo o que
   não é `.bip-foto-canvas` (galeria, miniatura de resposta, painel). */
.bip-foto-canvas {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: var(--surface-2);
    border-radius: var(--radius);
}

/* A FAIXA CINZA ERA O VÉU (25/08/26, dono: *"teria como essas bordas serem a
   propria imagem ou algum efeito de cor proxima da imagem para nao ficar essa
   faixa?"*).

   O borrão já existia, mas entrava a 55% sobre `--surface-2`: metade do que
   se via era o cinza da moldura, e num tema claro isso vira exatamente a
   faixa que o dono apontou. Agora o fundo é a PRÓPRIA foto, opaca — a lateral
   herda a cor real da imagem. Para o assunto não sumir dentro do próprio
   borrão, dois cuidados: `scale(1.25)` afasta as formas reconhecíveis e a
   sombra da foto de cima desenha a separação (antes feita pelo contraste do
   cinza). */
.bip-foto-canvas__fundo {
    position: absolute;
    /* Sangra além da borda: o blur não deixa halo transparente na moldura. */
    inset: -24px;
    width: calc(100% + 48px);
    height: calc(100% + 48px);
    max-width: none;
    max-height: none;
    object-fit: cover;
    filter: blur(28px) saturate(1.35);
    transform: scale(1.25);
    opacity: 1;
    pointer-events: none;
    border: none;
    border-radius: 0;
}

.bip-card__body .bip-foto-canvas .bip-content-image,
.bip-media-caption .bip-foto-canvas .bip-content-image,
.bip-foto-canvas .bip-content-image {
    position: relative;
    width: auto;
    max-width: 100%;
    object-fit: contain;
    border: none;
    background: none;
    /* Onde termina a foto e começa o borrão: a sombra faz esse trabalho agora
       que os dois têm a mesma cor. */
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06), 0 6px 22px rgba(0, 0, 0, 0.22);
}

.bip-media-caption .bip-foto-canvas {
    border-radius: 0;
}

.bip-media-caption .bip-foto-canvas .bip-content-image {
    max-height: 430px;
}

/* ── MOLDURA INTELIGENTE (13/09/26, ordem do dono) ─────────────────────────
   *"Se a imagem é 1:1, não deveria ter canva e deveria mostrar só a imagem; se
   for 3x4, perfeito e sem canva novamente; se a imagem é 16x9 não precisaria
   de canva, pois não cortaria nada."* Substitui a moldura SEMPRE 3:4 de
   10/09/26, que pintava borrão em cima e embaixo de toda foto quadrada.

   A regra, igual no app (BipFotoMoldurada, em BipImageGallery.kt):
   - Entre 9:16 e 16:9 a moldura é a PRÓPRIA foto na largura cheia: sem canva,
     sem corte. É a faixa do portão do servidor (feed_image_ratio.php), com a
     mesma folga de 0,01, então todo upload novo cai aqui. O chão era 3:4 até
     27/09/26 (ordem do dono: *"para imagem incluir o 9x16 sem canva"*).
   - Mais em pé que isso (só a captura comprida, desde 27/09/26 à noite: o print de
     celular já cabe, até 0,38): a moldura para em 0,38 e o borrão entra nas laterais.
   - Mais deitada que 16:9 (panorama): a moldura para em 16:9 e o borrão entra
     em cima e embaixo.
   Nos dois últimos casos a foto entra inteira (`contain`) sobre o borrão.

   SEM JAVASCRIPT: quem decide é o próprio <img>. `aspect-ratio: auto 3 / 4`
   usa a proporção real assim que a foto chega e reserva 3:4 enquanto ela não
   chega. A largura é sempre 100%; o teto e o piso de ALTURA saem da largura da
   moldura (`cqw`, por isso ela é container): 100cqw / 0,5525 em pé e
   100cqw / 1,7878 deitada. Passou do teto ou do piso, a caixa trava ali e o
   `contain` encaixa a foto com o borrão atrás.

   A sombra de 24/08 sai: com `contain` a caixa da foto é a moldura inteira e
   a sombra cairia do lado de fora, cortada. Só foto antiga ou link externo
   passa do portão, então o borrão sem sombra é o caso raro.

   Estas regras vêm DEPOIS das da legenda de propósito: o teto de 430px de
   `.bip-media-caption` é da prévia; dentro do cartão manda a moldura. */
.bip-card__body .bip-foto-canvas {
    display: block;
    width: 100%;
    aspect-ratio: auto;
    container-type: inline-size;
}

.bip-card__body .bip-foto-canvas .bip-content-image {
    width: 100%;
    max-width: 100%;
    height: auto;
    aspect-ratio: auto 3 / 4;
    min-height: calc(100cqw / 1.7878);
    /* 0,38 menos a folga de 0,01 (27/09/26, à noite: o print na largura toda, escolha do dono); de
       manhã era 9:16 (100cqw / 0.5525), antes 3:4 (100cqw / 0.74). */
    max-height: calc(100cqw / 0.37);
    object-fit: contain;
    box-shadow: none;
}

/* Fotos dos posts de borda a borda, como o versículo do dia. */
.bip-card__body .bip-card__text :is(.bip-content-image-wrap, .bip-gallery, .bip-media-caption) {
    width: calc(100% + 2 * var(--bip-card-side-padding));
    max-width: none;
    margin-inline: calc(-1 * var(--bip-card-side-padding));
    border: none;
    border-radius: 0;
}

.bip-card__body .bip-card__text .bip-media-caption .bip-content-image-wrap {
    width: 100%;
    max-width: 100%;
    margin-inline: 0;
}

.bip-card__body .bip-card__text :is(.bip-foto-canvas, .bip-content-image) {
    border: none;
    border-radius: 0;
}

.bip-card__body .bip-card__text .bip-content-image-lightbox-open {
    cursor: default;
    border-radius: 0;
    touch-action: manipulation;
    user-select: none;
    -webkit-user-select: none;
}

/* Várias fotos preenchem a colagem ou o carrossel; o toque abre a foto inteira. */
.bip-card__body .bip-card__text .bip-gallery .bip-content-image-lightbox-open {
    cursor: zoom-in;
}

/* ── SENTIMENTO, "FAZENDO AGORA" E O FILME (27/08/26, ordem do dono) ────────
   Os dois chips que nasceram do espaço devolvido pelo bipTag colapsado, a
   folha de escolha e o cartão do filme no BiP publicado. */

/* Vazio, o chip é só o emoji; escolhido, ele se abre e mostra a escolha — a
   mesma gramática dos vizinhos da linha. */
.compose-chip--status .compose-chip__emoji {
    font-size: 0.95rem;
    line-height: 1;
}

/* ENQUANTO O TÓPICO ESTÁ SENDO ESCRITO (06/09/26, ordem do dono): o rótulo sai
   e sobra o emoji, devolvendo a linha ao campo que está em uso. Gêmeo do
   `colapsado` do ComposeStatusChip no app. */
.compose-identity__chips.is-topico-escrevendo .compose-chip--status > span:not(.compose-chip__emoji) {
    display: none;
}

.compose-chip--status.is-on {
    background: color-mix(in srgb, var(--accent) 16%, transparent);
    color: var(--accent);
}

/* A folha: uma só para os três conteúdos (sentimento, atividade, filme) —
   três folhas quase iguais divergem no primeiro ajuste. */
.bip-status-sheet {
    position: fixed;
    inset: 0;
    z-index: 10300;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.bip-status-sheet[hidden] { display: none; }

.bip-status-sheet__backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .45);
}

.bip-status-sheet__panel {
    position: relative;
    width: min(420px, 100%);
    /* A FOLHA ENCOLHE COM O TECLADO (09/09/26). No app o dono reclamou duas
       vezes que a caixa de musica ficava alta — e a queixa era sempre com o
       teclado de pe, disputando a metade da tela com a folha. Aqui a peca
       equivalente e esta altura: `vh` ignora o teclado (a unidade e da janela
       inteira, nao do que sobrou dela), entao a folha continuava com 76% da
       tela enquanto so metade estava visivel.

       `dvh` e a altura VIVA: quando o teclado sobe, ela cai junto. O `vh` fica
       como primeira linha para o navegador que nao conhece a unidade nova. */
    max-height: 76vh;
    max-height: 76dvh;
    display: flex;
    flex-direction: column;
    background: var(--bg-1, #fff);
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -8px 30px rgba(0, 0, 0, .18);
}

@media (min-width: 640px) {
    .bip-status-sheet { align-items: center; }
    .bip-status-sheet__panel { border-radius: 18px; }
}

.bip-status-sheet__head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--border);
}

.bip-status-sheet__title {
    flex: 1;
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    color: var(--text-1);
}

.bip-status-sheet__voltar,
.bip-status-sheet__x {
    border: 0;
    background: transparent;
    color: var(--text-2);
    font-size: 1.3rem;
    line-height: 1;
    cursor: pointer;
    padding: 2px 8px;
    border-radius: 8px;
}

.bip-status-sheet__voltar:hover,
.bip-status-sheet__x:hover { background: var(--bg-2); }

.bip-status-sheet__body {
    padding: 14px 16px 18px;
    overflow-y: auto;
}

.bip-status-sheet__aviso {
    margin: 10px 0;
    color: var(--text-3);
    font-size: 0.88rem;
}

/* Sentimento em DUAS colunas (a grade do print); atividade e filme em lista,
   porque ali cada linha carrega mais texto. */
.bip-status-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.bip-status-lista {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.bip-status-opt {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 11px 12px;
    border: 0;
    border-radius: 12px;
    background: var(--bg-2);
    color: var(--text-1);
    font: inherit;
    font-size: 0.9rem;
    text-align: left;
    cursor: pointer;
}

/* `--surface-2` é #FFFFFF no tema claro: o item cinza ficava BRANCO no hover e
   parecia sumir da lista, deixando só a caixinha do ícone boiando (visto no
   check-in, 13/09/26). O hover escurece um tom em vez de clarear. */
.bip-status-opt:hover { background: color-mix(in srgb, var(--text-1) 7%, var(--bg-2)); }

.bip-status-opt.is-on {
    background: color-mix(in srgb, var(--accent) 16%, transparent);
    color: var(--accent);
    font-weight: 600;
}

.bip-status-opt__emoji { font-size: 1.15rem; line-height: 1; }

.bip-status-opt--filme { align-items: flex-start; }

.bip-status-opt__poster {
    width: 44px;
    height: 66px;
    flex: 0 0 auto;
    border-radius: 8px;
    object-fit: cover;
    background: var(--bg-2);
}

.bip-status-opt__poster--vazio {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
}

.bip-status-opt__ficha {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.bip-status-opt__ficha small { color: var(--text-3); font-size: 0.78rem; }

/* ═══ O CARTÃO COLORIDO (28/08/26, ordem do dono) ═══════════════════════════
   Fundo, fonte e alinhamento do post de texto — 3 cores fixas (preto,
   vermelho, azul), 7 degradês, 6 fontes e o alinhamento.

   UMA classe por slug, usada em TRÊS lugares: o cartão publicado, o preview do
   compositor e a amostra do painel. É o que garante que a bolinha da paleta, a
   caixa onde se escreve e o post no feed sejam a MESMA cor para sempre.

   O texto é sempre branco — todos os dez fundos foram escolhidos escuros o
   bastante para isso; um fundo claro exigiria trocar a cor do texto por slug,
   e é exatamente o tipo de tabela paralela que envelhece torto. */
/* LINK NO CARTÃO COLORIDO (24/09/26, dono: *"o css do link com as cores está
   horrível"*): o azul da marca some num fundo azul/roxo. Dentro do cartão o
   link (e o @, o #) é BRANCO, sublinhado e um pouco mais forte — legível em
   qualquer um dos 24 fundos, todos escuros. */
.bip-cartao a,
.bip-cartao a:visited,
.bip-cartao a:hover {
    color: #fff;
    font-weight: 700;
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
    text-decoration-color: rgba(255, 255, 255, 0.75);
}

/* A pílula de menção já tem seu próprio fundo e cor legível. Protege contra o a:visited acima. */
.bip-cartao a.bip-mention.bip-mention--pilula,
.bip-cartao a.bip-mention.bip-mention--pilula:visited {
    color: var(--text-1);
    font-weight: 600;
    text-decoration: none;
}
.bip-cartao a.bip-mention.bip-mention--pilula:hover {
    color: var(--text-1);
}

.bip-cartao--c1 { background: #191919; }
.bip-cartao--c2 { background: #C22B2B; }
.bip-cartao--c3 { background: #2456A6; }
.bip-cartao--c4 { background: linear-gradient(135deg, #7B2FF7, #F72F8E); }
.bip-cartao--c5 { background: linear-gradient(135deg, #F7642F, #F72F5B); }
.bip-cartao--c6 { background: linear-gradient(135deg, #1F6FE0, #16C4C4); }
.bip-cartao--c7 { background: linear-gradient(135deg, #14803C, #0FA88A); }
.bip-cartao--c8 { background: linear-gradient(135deg, #B02FF7, #2D2F8F); }
.bip-cartao--c9 { background: linear-gradient(135deg, #E08A16, #C2371F); }
.bip-cartao--c10 { background: linear-gradient(160deg, #3A3F4B, #14161C); }

/* A SEGUNDA LINHA (31/08/26, ordem do dono: *"cabem mais 13 combinações —
   quero os mais lindos degradês; só preto, vermelho e azul ficam fixas"*).
   Todos mix de 2–3 cores, todos com texto branco legível. Como os dez
   primeiros, os slugs são estáveis para sempre. */
.bip-cartao--c11 { background: linear-gradient(135deg, #F59E0B, #EF4444, #7C3AED); }
.bip-cartao--c12 { background: linear-gradient(135deg, #0EA5E9, #2563EB, #1E3A8A); }
.bip-cartao--c13 { background: linear-gradient(135deg, #22C55E, #06B6D4, #3B82F6); }
.bip-cartao--c14 { background: linear-gradient(135deg, #EAB308, #F97316, #DC2626); }
.bip-cartao--c15 { background: linear-gradient(135deg, #F472B6, #A78BFA); }
.bip-cartao--c16 { background: linear-gradient(135deg, #65A30D, #14B8A6); }
.bip-cartao--c17 { background: linear-gradient(135deg, #7C3AED, #312E81); }
.bip-cartao--c18 { background: linear-gradient(135deg, #FB923C, #F43F5E); }
.bip-cartao--c19 { background: linear-gradient(160deg, #0F172A, #6D28D9); }
.bip-cartao--c20 { background: linear-gradient(135deg, #E11D48, #FB7185); }
.bip-cartao--c21 { background: linear-gradient(135deg, #059669, #D97706); }
.bip-cartao--c22 { background: linear-gradient(135deg, #6B21A8, #DB2777); }
.bip-cartao--c23 { background: linear-gradient(135deg, #0284C7, #6366F1, #C026D3); }
.bip-cartao--c24 { background: linear-gradient(135deg, #14B8A6, #6366F1); }

.bip-cartao--f-sans { font-family: var(--font); }
.bip-cartao--f-serif { font-family: Georgia, 'Times New Roman', serif; }
.bip-cartao--f-mono { font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace; }
.bip-cartao--f-cursiva { font-family: 'Segoe Script', 'Comic Sans MS', cursive; }
.bip-cartao--f-display { font-family: 'Arial Black', Impact, sans-serif; }
/* A Inter não é carregada como webfont — o fallback é a fonte da casa, e o
   slug existe para o dia em que ela entrar sem migrar post nenhum. */
.bip-cartao--f-inter { font-family: 'Inter', var(--font); }

.bip-cartao--a-left { text-align: left; }
.bip-cartao--a-center { text-align: center; }
.bip-cartao--a-right { text-align: right; }

/* O CARTÃO PUBLICADO: o texto do BiP dentro da cor. `justify-content` centra
   verticalmente — texto curto no meio do cartão, como no Facebook. */
/* O CARTÃO COLORIDO PEDE FUNDO NEUTRO (28/08/26, dono: *"a cor do cartão
   para branco quando a pessoa escolhe a cor — contraste melhor; os tons
   pastéis não, só no card que marcou cor"*). O tom que ele viu é o DESTAQUE de
   post recente (highlight/just-posted): bonito num post normal, mas ao lado de
   um degradê vivo ele briga. Com cor escolhida, o cartão fica na superfície
   pura — branco no claro, o cinza da casa no escuro. */
.bip-card--estilo,
.bip-card--estilo.bip-card--highlight,
.bip-card--estilo.bip-card--just-posted {
    background: var(--surface);
}

.bip-card__text.bip-cartao {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 220px;
    /* RESPIRO IGUAL EM CIMA E EMBAIXO (31/08/26, dono: "o de cima está muito
       grande em relação ao avatar; mesma espessura"). O flex do card NÃO
       colapsa margens: em cima somavam os 10px do header + 8px daqui = 18px,
       contra 12px embaixo (margin-bottom do __text). 10 + 2 = 12 dos dois
       lados. */
    margin-top: 2px;
    /* SANGRIA TOTAL (28/08/26, dono: *"não é uma faixa de cor, é a cor total
       no card, como no Facebook"*). As margens negativas anulam o respiro do
       .bip-card (22px nas laterais) e a cor toca as bordas — por isso também
       o raio zero: o retângulo atravessa o cartão de lado a lado. */
    margin-inline: -22px;
    padding: 26px 22px;
    border-radius: 0;
    color: #fff;
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.4;
}

/* O MIOLO é o ÚNICO item do flex (07/09/26): sem ele, cada <strong>/<u>/menção
   virava uma linha própria no computador. Bloco de largura cheia para o
   text-align do cartão (esquerda/centro/direita) continuar mandando. */
.bip-card__text.bip-cartao > .bip-cartao__miolo {
    display: block;
    width: 100%;
    min-width: 0;
}

/* O PREVIEW no compositor: a mesma pintura sobre a caixa de texto. */
/* O preview sangra até as bordas do modal e DESCE até a fileira do Aa (dono,
   28/08/26: "o colorido inclui o botão"): quem é pintado é o invólucro
   #bip-cartao-area, que contém o editor e a paleta — como no Facebook. */
#bip-cartao-area.bip-cartao {
    border-radius: 0;
    /* 24px = o respiro lateral do .tool-modal__panel (tools.css). */
    margin-inline: -24px;
    padding: 18px 24px 12px;
}

/* Sobre a cor, o painel perde o cartão branco: as bolinhas pousam direto no
   fundo, como no Facebook — só um véu para o toque continuar visível. */
#bip-cartao-area.bip-cartao .compose-estilo__panel {
    background: rgb(0 0 0 / 18%);
    border-color: rgb(255 255 255 / 30%);
}

#bip-cartao-area.bip-cartao .compose-estilo__fonte,
#bip-cartao-area.bip-cartao .compose-estilo__alinha,
#bip-cartao-area.bip-cartao .compose-estilo__trocar {
    background: rgb(255 255 255 / 14%);
    border-color: rgb(255 255 255 / 35%);
    color: #fff;
}

#bip-cartao-area.bip-cartao .compose-estilo__fonte.is-on,
#bip-cartao-area.bip-cartao .compose-estilo__alinha.is-on {
    background: #fff;
    color: var(--accent);
    border-color: #fff;
}

#bip-cartao-area.bip-cartao .compose-estilo__swatch--off,
#bip-cartao-area.bip-cartao .compose-estilo__recolher {
    background: rgb(255 255 255 / 20%);
    border-color: rgb(255 255 255 / 35%);
    color: #fff;
}

.bip-cartao .compose-modal__textarea {
    background: transparent;
    color: #fff;
    font-size: 1.15rem;
    font-weight: 700;
    font-family: inherit;
    text-align: inherit;
    min-height: 130px;
}

.bip-cartao .compose-modal__textarea::placeholder {
    color: rgb(255 255 255 / 75%);
}

/* O campo VISÍVEL é o contenteditable (.bip-editor) e o placeholder dele é um
   ::before com cor própria (var(--text-2)) — era ele que aparecia escuro por
   cima do vermelho (28/08/26, dono: "arruma a cor da fonte no site"). */
.bip-cartao .bip-editor[data-empty="true"]::before {
    color: #fff;
    opacity: .8;
}

/* ── O PAINEL atrás do "Aa" ──
   O GATILHO MUDOU DE CASA (08/09/26, ordem do dono): o "Aa" virou o primeiro
   botão da fileira de ícones (.compose-add-btn--estilo) e aqui sobrou só a
   ÂNCORA do painel, que segue nascendo colado embaixo do editor — o botão
   andou, o painel não. Sem botão dentro, o invólucro não pode mais empurrar
   8px: quem afasta o painel do editor é a margem do próprio painel, senão o
   compositor ganharia um vão vazio com o painel fechado. */
.compose-estilo {
    position: relative;
    margin-top: 0;
}

.compose-estilo__panel {
    margin-top: 8px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface);
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.compose-estilo__linha {
    display: flex;
    align-items: center;
    /* TUDO CENTRALIZADO (31/08/26, ordem do dono) — as duas linhas de cores,
       as fontes e o alinhamento se acomodam no meio da caixa. */
    justify-content: center;
    gap: 7px;
    flex-wrap: wrap;
}

.compose-estilo__grupo {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}

/* A caixa que troca de assunto — "Escolha a fonte" ⇄ "Escolher cor". Borda
   levemente arredondada, nunca pílula (31/08/26). */
.compose-estilo__trocar {
    padding: 8px 18px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-2);
    color: var(--text);
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
}

.compose-estilo__trocar:hover {
    border-color: var(--accent);
    color: var(--accent);
}

/* QUADRADINHOS (30/08/26, ordem do dono: "cores assim, quadradinhos lindos" —
   o desenho do Facebook). A bolinha virou tile arredondado; o anel de escolha
   acompanha o canto. */
.compose-estilo__swatch {
    width: 34px;
    height: 34px;
    border: 2px solid transparent;
    border-radius: 10px;
    cursor: pointer;
    padding: 0;
}

/* DUAS LINHAS SEMPRE (31/08/26): grade fixa de 13 colunas — 26 casas (seta +
   sem-cor + 24 cores) fecham em 13 + 13, em qualquer largura de tela. */
.compose-estilo__linha--cores {
    display: grid;
    grid-template-columns: repeat(13, minmax(0, 1fr));
    gap: 6px;
    width: 100%;
}

.compose-estilo__linha--cores .compose-estilo__swatch,
.compose-estilo__linha--cores .compose-estilo__recolher {
    width: 100%;
    height: auto;
    aspect-ratio: 1;
}

/* Cartão de citação DENTRO da bolha de comentário (31/08/26): link da casa
   colado no comentário vira o mesmo cartão do repost com citação. */
.bip-reply__bubble .bip-quote {
    margin-top: 8px;
}

/* ── CHIPS COLAPSADOS do compositor (31/08/26, dono: "público e desativar
   comentários ficam colapsados; ao clicar abre, mostra a alteração em texto e
   fecha de novo"). O chip vira só o ícone; o texto aparece no toque. */
.compose-chip.is-colapsado > span,
.compose-chip.is-colapsado > .bx-chevron-down {
    display: none;
}

.compose-chip.is-colapsado {
    padding-left: 8px;
    padding-right: 8px;
}

/* ── MÚSICA NO POST (31/08/26): painel de busca no padrão do GIF, chip da
   faixa escolhida abaixo da barra. */
.bip-music-wrap {
    position: relative;
    display: inline-flex;
}

.bip-music-panel {
    position: absolute;
    bottom: calc(100% + 8px);
    right: 0;
    width: min(320px, 80vw);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 10px;
    box-shadow: var(--shadow-md);
    z-index: 60;
}

.bip-music-q {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-2);
    color: var(--text);
    font-size: 0.9rem;
}

.bip-music-q:focus {
    border-color: var(--accent);
    outline: none;
}

.bip-music-results {
    margin-top: 8px;
    max-height: 260px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.bip-music-aviso {
    margin: 6px 2px;
    font-size: 0.82rem;
    color: var(--text-2);
}

.bip-music-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    cursor: pointer;
    text-align: left;
    width: 100%;
}

.bip-music-item:hover {
    background: var(--bg-2);
}

.bip-music-item img {
    width: 40px;
    height: 40px;
    border-radius: 6px;
    object-fit: cover;
    background: var(--bg-2);
    flex-shrink: 0;
}

.bip-music-item__txt {
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.bip-music-item__txt strong {
    font-size: 0.88rem;
    color: var(--text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bip-music-item__txt small {
    font-size: 0.78rem;
    color: var(--text-2);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.bip-music-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-2);
    color: var(--text);
    font-size: 0.85rem;
}

.bip-music-chip > i {
    color: var(--accent);
}

.bip-music-chip > span {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bip-music-chip button {
    margin-left: auto;
    border: 0;
    background: transparent;
    color: var(--text-2);
    font-size: 1.1rem;
    cursor: pointer;
    line-height: 1;
}

/* O "💬 N respostas" na fileira do fórum (31/08/26): destacado em azul para
   dizer que ali dentro tem conversa — é a porta de acesso às respostas. */
.comm-forum-engage .bip-reply__expand {
    color: var(--accent);
    font-weight: 600;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.compose-estilo__swatch.is-on {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent);
}

.compose-estilo__swatch--off {
    display: inline-grid;
    place-items: center;
    background: var(--bg-2);
    color: var(--text-2);
}

/* A setinha de recolher — primeira casa da fileira, como no Facebook. */
.compose-estilo__recolher {
    width: 34px;
    height: 34px;
    display: inline-grid;
    place-items: center;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--bg-2);
    color: var(--text-2);
    cursor: pointer;
    padding: 0;
}

.compose-estilo__recolher:hover {
    color: var(--text);
}

.compose-estilo__fonte {
    padding: 6px 14px;
    border: 1px solid var(--border);
    /* Caixa de canto levemente arredondado — a pílula saiu (31/08/26). */
    border-radius: 8px;
    background: var(--bg-2);
    color: var(--text);
    font-size: 0.85rem;
    cursor: pointer;
}

.compose-estilo__fonte.is-on {
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 700;
}

.compose-estilo__sep {
    width: 1px;
    height: 22px;
    background: var(--border);
    margin: 0 3px;
}

.compose-estilo__alinha {
    width: 32px;
    height: 30px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-2);
    color: var(--text-2);
    font-size: 0.95rem;
    cursor: pointer;
}

.compose-estilo__alinha.is-on {
    border-color: var(--accent);
    color: var(--accent);
}

/* AS ABAS DE PROVEDOR da busca de música (28/08/26) — Deezer | Spotify.
   Pílulas gêmeas das do feed: uma acesa de cada vez, trocar refaz a busca. */
/* O TRILHO ÚNICO DA ESCOLHA DA FICHA (09/09/2026, ordem do dono: *"estes
   botões estão horríveis; você poderia usar o espaço inteiro e fazer algo tipo
   o que já temos, muito mais bonito e mais simples"*).

   Eram três retângulos com borda própria disputando a linha — três caixas para
   uma escolha só. Aqui é um trilho e uma pastilha: a mesma leitura das abas do
   feed, e a largura inteira aproveitada. Gêmeo da `BipPillTabs` do app. */
.bip-status-modos {
    display: flex;
    gap: 2px;
    margin: 0 0 12px;
    padding: 3px;
    border-radius: 999px;
    background: var(--bg-2);
}

.bip-status-modo {
    flex: 1;
    min-width: 0;
    padding: 9px 6px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--text-2);
    font: inherit;
    font-size: 0.86rem;
    font-weight: 600;
    cursor: pointer;
    transition: background .18s ease, color .18s ease;
}

.bip-status-modo.is-on {
    background: var(--accent);
    color: #fff;
}

.bip-status-abas {
    display: flex;
    gap: 8px;
    margin-bottom: 10px;
}

.bip-status-aba {
    flex: 1;
    padding: 8px 12px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-2);
    color: var(--text-2);
    font: inherit;
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}

.bip-status-aba.is-on {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.bip-status-campo {
    width: 100%;
    padding: 11px 12px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-2);
    color: var(--text-1);
    font: inherit;
    font-size: 0.92rem;
}

.bip-status-sheet__ok { width: 100%; margin-top: 10px; }

.bip-status-sheet__limpar {
    display: block;
    width: 100%;
    margin-top: 12px;
    padding: 8px;
    border: 0;
    border-radius: 10px;
    background: transparent;
    color: var(--text-2);
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
}

.bip-status-sheet__limpar:hover { background: var(--bg-2); }

/* A frase ao lado do nome: "😊 está se sentindo feliz". Discreta de propósito
   — o nome é o que se lê primeiro, e a frase é o complemento. */
.bip-card__status {
    /* INLINE, e não `inline-flex` (29/08/26). Ela era `nowrap` + `ellipsis` e
       virava "está 🤩 se sentindo anima…". Como caixa flex ela parava de cortar,
       mas quebrava como BLOCO — ou cabia inteira ao lado do nome, ou descia
       inteira. Inline, ela é o que sempre foi: texto, que continua na linha de
       baixo na palavra em que a largura acabou. */
    display: inline;
    color: var(--text-3);
    font-size: 0.82rem;
    font-weight: 400;
    white-space: normal;
}

/* O respiro à DIREITA do emoji vinha do `gap: 3px` da caixa flex; sem a caixa,
   ele precisa ser dito. À esquerda o espaço já existe: a frase é "está " + emoji. */
.bip-card__status-emoji {
    font-size: 0.92rem;
    margin-right: 3px;
}

/* O cartão do filme, no corpo — junto da enquete e da citação. */
.bip-movie {
    display: flex;
    gap: 12px;
    align-items: center;
    margin-top: 10px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 14px;
    background: var(--bg-2);
}

.bip-movie__poster {
    width: 56px;
    height: 84px;
    flex: 0 0 auto;
    border-radius: 10px;
    object-fit: cover;
    background: var(--surface-2);
}

.bip-movie__poster--vazio {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.4rem;
}

.bip-movie__ficha {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.bip-movie__etiqueta {
    color: var(--accent);
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: .02em;
}

.bip-movie__titulo {
    color: var(--text-1);
    font-size: 0.94rem;
    line-height: 1.3;
}

.bip-movie__meta { color: var(--text-3); font-size: 0.78rem; }

/* ═══ O CARTÃO DE MÍDIA — filme, série, livro e jogo (28/08/26) ═══════════
   Dono: *"é isso que eu espero, um card lindo e bem montado, para livro, game
   e filmes"*.

   As três medidas que fazem o cartão parecer cuidado, e por que são estas:

   · A CAPA MANDA NA ALTURA. 64×96 é a proporção 2:3 de capa de livro e pôster
     de filme — a mesma que as duas indústrias usam há um século. A capa de
     jogo é larga (16:9) e é recortada para o mesmo retângulo pelo
     `object-fit`: um cartão que muda de altura conforme a espécie faria a
     rolagem tremer.
   · O TÍTULO EM DUAS LINHAS, no máximo. "O Senhor dos Anéis: A Sociedade do
     Anel" não cabe em uma, e cortar no meio da primeira esconde justamente o
     que identifica a obra. Na terceira linha o cartão já compete com o texto
     de quem escreveu.
   · A LINHA DE BAIXO é sempre "Espécie · quem fez · ano". Ela é o que diz, sem
     ícone e sem legenda, que aquilo é um livro e não um filme. */
.bip-media {
    display: flex;
    gap: 12px;
    align-items: center;
    margin-top: 10px;
    /* Respiro para as ESTRELAS logo abaixo (28/08/26, ordem do dono: "temos
       que deixar um espaço entre eles") — o cartão colava na barra de ações. */
    margin-bottom: 12px;
    padding: 10px;
    border: 1px solid var(--border);
    border-radius: 14px;
    /* FUNDO TRANSPARENTE (05/09/26, ordem do dono: *"deixar este fundo dos
       cards de filme, jogos e música transparente e só a moldura na cor do
       cartão, um pouquinho mais forte"* — o banho da cápsula da hashtag,
       04/09). O `--bg-2` era um retângulo cinza flutuando sobre o cartão
       tingido; sem preenchimento, o anexo veste a cor do próprio card. */
    background: transparent;
}

/* A MOLDURA NA COR DO CARTÃO: o card se tinge com o véu de 7-8% do `--tom`
   (ver mobile.css) — a moldura é o MESMO tom com mais força. Cartão sem tom
   (branco, tema escuro) fica na borda do tema, que já aparece.

   FRACA de propósito (05/09/26, 2ª rodada do dono: *"ela só precisa existir,
   não ser marcante"* — a régua da borda do voto): 0.35 era contorno; 0.18
   se vê sem se notar. */
.bip-card[class*="bip-card--tom"] .bip-media {
    border-color: rgba(var(--tom), 0.18);
}

/* Clicável leva à FONTE (28/08/26). `<a>` herdaria azul e sublinhado — o
   cartão continua parecendo cartão; o convite é o hover, como na cidade. */
.bip-media--link {
    text-decoration: none;
    color: inherit;
    transition: border-color .15s ease, background .15s ease;
}

/* O hover convida pela MOLDURA, não por um preenchimento (05/09/26): o fundo
   cinza no hover reintroduziria a caixa que acabou de morrer. */
.bip-media--link:hover {
    border-color: var(--border-hover);
}

.bip-card[class*="bip-card--tom"] .bip-media--link:hover {
    border-color: rgba(var(--tom), 0.32);
}

.bip-media__capa {
    width: 64px;
    height: 96px;
    flex: 0 0 auto;
    border-radius: 10px;
    object-fit: cover;
    background: var(--surface-2);
}

.bip-media__capa--vazia {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.7rem;
}

.bip-media__ficha {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.bip-media__titulo {
    color: var(--text-1);
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.3;
    /* Duas linhas e reticências — ver o comentário acima. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.bip-media__meta {
    color: var(--text-2);
    font-size: 0.82rem;
    line-height: 1.35;
}

/* O "#" DO CHIP ABERTO É O BOTÃO DE FECHAR (27/08/26): clicou abre, clicou de
   novo fecha. Sem o cursor de mão ninguém descobre que ele é clicável — e
   descobrir por acidente é o que faz a pessoa tocar fora e publicar sem querer. */
.compose-chip--topic-edit .compose-chip__hash {
    cursor: pointer;
    user-select: none;
}

.compose-chip--topic-edit .compose-chip__hash:hover {
    color: var(--accent);
}

/* O RODAPÉ DAS BUSCAS (27/08/26): a saída manual à esquerda e o crédito do
   provedor à direita. O crédito é exigência dos termos (RAWG e TMDB pedem
   atribuição visível); a saída manual está sempre à vista porque catálogo
   nenhum tem tudo, e quem não acha precisa de um caminho, não de uma lista
   vazia. */
.bip-status-sheet__rodape {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
}

.bip-status-sheet__manual {
    border: 0;
    background: transparent;
    color: var(--accent);
    font: inherit;
    font-size: 0.84rem;
    font-weight: 600;
    cursor: pointer;
    padding: 4px 0;
    text-align: left;
}

.bip-status-sheet__manual:hover { text-decoration: underline; }

.bip-status-sheet__credito {
    color: var(--text-3);
    font-size: 0.78rem;
    white-space: nowrap;
    text-decoration: none;
}

.bip-status-sheet__credito:hover { color: var(--text-2); }

/* O RESPIRO DA BUSCA (13/09/26, ordem do dono: "a primeira caixa está ficando
   muito acima, precisa de um respiro"). A lista nascia colada no campo, e o
   primeiro resultado parecia parte da caixa de digitar. Vale para toda busca
   da folha (lugar, filme, jogo, livro, música). */
.bip-status-campo + .bip-status-lista {
    margin-top: 14px;
}

/* O LUGAR NÃO TEM CAPA. A caixa de 44x66 é a de pôster de filme; para o pino
   ela só deixava cada linha alta e com um retângulo cinza sobrando. Aqui o pino
   vira um círculo pequeno e a linha centraliza. A folha do lugar é reconhecida
   pelo crédito do Geoapify, que os termos obrigam a estar sempre na tela, sem
   depender de o JS marcar a lista. */
.bip-status-sheet__body:has(.bip-status-sheet__credito[href*="geoapify"]) .bip-status-opt--filme {
    align-items: center;
    padding: 10px 12px;
}

.bip-status-sheet__body:has(.bip-status-sheet__credito[href*="geoapify"]) .bip-status-opt__poster--vazio {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: color-mix(in srgb, #E0336F 13%, var(--surface, #fff));
    font-size: 1.05rem;
}

/* ══ A JANELA DAS NOTAS — UMA SÓ (30/08/26, ordem do dono: *"hoje temos 3
   janelas diferentes para fazer o mesmo, não faz sentido"*) ════════════════

   Ela serve o rail do feed E o perfil, e por isso mora aqui (global) e não no
   `status.css`: o perfil não carrega aquele arquivo — foi exatamente por isso
   que ele teve um diálogo só dele durante dois dias.

   O PADRÃO DE CONTRASTE DA CASA: a caixa em `--surface`, e tudo o que é campo
   ou pílula dentro dela em `--surface-3` — nunca caixa da cor do fundo. */
.bip-notaj {
    position: fixed;
    inset: 0;
    z-index: 1300;
    display: grid;
    place-items: center;
}

.bip-notaj__fundo {
    position: absolute;
    inset: 0;
    background: rgb(8 8 8 / 55%);
}

.bip-notaj__caixa {
    position: relative;
    width: min(360px, calc(100vw - 32px));
    max-height: calc(100vh - 48px);
    overflow-y: auto;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 20px;
    text-align: center;
}

.bip-notaj__x {
    position: absolute;
    top: 10px;
    right: 12px;
    border: 0;
    background: none;
    color: var(--text-3);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    padding: 4px;
}

.bip-notaj__x:hover { color: var(--text-1); }

.bip-notaj__titulo {
    margin: 0 0 14px;
    color: var(--text-1);
    font-size: 1.05rem;
    font-weight: 700;
}

.bip-notaj__avatar {
    display: block;
    width: 72px;
    height: 72px;
    margin: 0 auto;
    border-radius: 50%;
    object-fit: cover;
}

.bip-notaj__avatar--letra {
    display: grid;
    place-items: center;
    background: var(--surface-3);
    color: var(--text-2);
    font-size: 1.6rem;
    font-weight: 700;
}

.bip-notaj__texto {
    margin: 14px 0 0;
    color: var(--text-1);
    font-size: 1.02rem;
    line-height: 1.4;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.bip-notaj__quando {
    display: block;
    margin-top: 8px;
    color: var(--text-3);
    font-size: 0.8rem;
}

.bip-notaj__editor {
    margin-top: 16px;
    text-align: left;
}

.bip-notaj__campo {
    width: 100%;
    padding: 11px 13px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--surface-3);
    color: var(--text-1);
    font-family: inherit;
    font-size: 0.95rem;
}

.bip-notaj__campo:focus {
    outline: none;
    border-color: var(--accent);
}

.bip-notaj__conta {
    display: block;
    margin-top: 4px;
    color: var(--text-3);
    font-size: 0.74rem;
    text-align: right;
}

.bip-notaj__botao {
    width: 100%;
    margin-top: 12px;
    padding: 12px;
    border: 0;
    border-radius: 12px;
    background: var(--accent);
    color: #fff;
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: 700;
    cursor: pointer;
}

.bip-notaj__link {
    width: 100%;
    margin-top: 8px;
    padding: 8px;
    border: 0;
    background: none;
    color: var(--accent);
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: 700;
    cursor: pointer;
}

.bip-notaj__link--perigo { color: #EF4444; }

/* Os TRÊS emojis (curtir, amei, triste) — o meu fica marcado, e o número só
   aparece quando existe: "0" ao lado de um coração convida ao nada. */
.bip-notaj__reacoes {
    display: flex;
    justify-content: center;
    gap: 10px;
    margin-top: 18px;
}

.bip-notaj__emoji {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border: 1px solid var(--border);
    border-radius: 20px;
    background: var(--surface-3);
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
}

.bip-notaj__emoji.is-minha {
    border-color: var(--accent);
    background: var(--accent-soft, rgb(79 142 247 / 16%));
}

.bip-notaj__emoji b {
    color: var(--text-2);
    font-size: 0.82rem;
}

.bip-notaj__emoji.is-minha b { color: var(--accent); }

.bip-notaj__resposta {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 16px;
}

.bip-notaj__resposta .bip-notaj__campo { border-radius: 22px; }

.bip-notaj__enviar {
    flex: 0 0 auto;
    width: 42px;
    height: 42px;
    border: 0;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-size: 1rem;
    cursor: pointer;
}

/* ── A BANDEIRA NO NOME (05/09/26, ordem do dono: 10 opções, ordem
   alfabética) ─────────────────────────────────────────────────────────────
   A bandeirinha ao lado do nome: listras em hard-stop de gradient, sem
   imagem. O slug vem do servidor (author_bandeira); os nomes de classe são o
   catálogo — gêmeos do BipBandeiras.kt do app. */
/* ── A GRADE DOS EMOJIS ANIMADOS (07/09/26, ordem do dono) ─────────────────
   Eles tocam todos ao mesmo tempo de propósito: é exatamente isso que a pessoa
   veio ver. São 512, servidos da variante `mini/` (64px) — o arquivo do feed é
   dez vezes maior e deixava a grade em branco enquanto baixava. */
/* O painel tem a MESMA altura do de figurinhas: são 512, a grade rola por
   dentro e a fileira de prateleiras fica presa em cima. Sem altura, o painel
   crescia com os 512 e saía da tela. */
.bip-emoji-shell__pane--animados {
    display: flex;
    flex-direction: column;
    height: min(435px, 62vh);
}

/* As PRATELEIRAS — a mesma fileira de ícones do seletor comum ao lado
   (gêmea do DmAnimadosGrid do app). */
.bip-emoji-anim-abas {
    display: flex;
    flex: 0 0 auto;
    gap: 4px;
    padding: 8px 10px 4px;
    overflow-x: auto;
    scrollbar-width: none;
}

.bip-emoji-anim-abas::-webkit-scrollbar {
    display: none;
}

.bip-emoji-anim-aba {
    flex: 0 0 auto;
    padding: 6px 10px;
    border: 0;
    border-radius: 10px;
    background: none;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}

.bip-emoji-anim-aba:hover {
    background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.bip-emoji-anim-aba.is-active {
    background: color-mix(in srgb, var(--accent) 18%, transparent);
}

.bip-emoji-anim-grade {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(44px, 1fr));
    grid-auto-rows: max-content;
    align-content: start;
    gap: 6px;
    padding: 6px 10px 10px;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.bip-emoji-anim-item {
    display: grid;
    place-items: center;
    aspect-ratio: 1;
    padding: 4px;
    border: 0;
    border-radius: 10px;
    background: none;
    cursor: pointer;
}

.bip-emoji-anim-item:hover {
    background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.bip-emoji-anim-item img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.bip-bandeira {
    display: inline-block;
    width: 18px;
    height: 12px;
    border-radius: 2.5px;
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
    vertical-align: -1px;
    margin-left: 4px;
    flex: 0 0 auto;
}

.bip-bandeira--assexual { background: linear-gradient(180deg, #000 0 25%, #a3a3a3 25% 50%, #fff 50% 75%, #800080 75% 100%); }
.bip-bandeira--bissexual { background: linear-gradient(180deg, #d60270 0 40%, #9b4f96 40% 60%, #0038a8 60% 100%); }
.bip-bandeira--demissexual {
    position: relative;
    overflow: hidden;
    background: linear-gradient(180deg, #fff 0 42%, #6c0ba9 42% 58%, #d3d3d3 58% 100%);
}
/* O triângulo preto que sai da haste — é ele que separa a demi da assexual. */
.bip-bandeira--demissexual::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-left: 7px solid #000;
}
/* A HETERO É PRETA E BRANCA (06/09/26, ordem do dono). A versão rosa/branco/azul
   que estava aqui era a referência que ele mesmo mandou em 05/09, mas em 18x12px
   ela virava a TRANS (azul-claro/rosa/branco): duas das três listras iguais, e
   pessoa nenhuma olha uma bandeirinha de 18px com lupa. Bandeira errada com o
   nome certo é pior que bandeira faltando — esta trocava a identidade de quem
   escolheu. Preto e branco não colide com nada do catálogo. */
.bip-bandeira--heterossexual { background: linear-gradient(180deg, #111 0 25%, #fff 25% 50%, #111 50% 75%, #fff 75% 100%); }
.bip-bandeira--lgbt { background: linear-gradient(180deg, #e40303 0 16.6%, #ff8c00 16.6% 33.3%, #ffed00 33.3% 50%, #008026 50% 66.6%, #004dff 66.6% 83.3%, #750787 83.3% 100%); }
.bip-bandeira--naobinario { background: linear-gradient(180deg, #fcf434 0 25%, #fff 25% 50%, #9c59d1 50% 75%, #2c2c2c 75% 100%); }
.bip-bandeira--pansexual { background: linear-gradient(180deg, #ff218c 0 33%, #ffd800 33% 66%, #21b1ff 66% 100%); }
.bip-bandeira--sapiossexual { background: linear-gradient(180deg, #3c7e14 0 33%, #955438 33% 66%, #1727f8 66% 100%); }
.bip-bandeira--trans { background: linear-gradient(180deg, #5bcefa 0 20%, #f5a9b8 20% 40%, #fff 40% 60%, #f5a9b8 60% 80%, #5bcefa 80% 100%); }

/* ── AS DEZESSEIS QUE FALTAVAM (06/09/26, ordem do dono) ──────────────────
   *"um usuário reclamou que é gay e não tem a bandeira gay; vamos logo incluir
   todas"*. A lista de 05/09 tinha nove e deixava de fora justamente Gay e
   Lésbica. Estas são gêmeas das entradas do `BipBandeiras.kt` — mexeu numa,
   mexa na outra, senão o slug chega sem cor e a bandeira nasce invisível. */
.bip-bandeira--abrossexual { background: linear-gradient(180deg, #46d294 0 20%, #9be6b6 20% 40%, #fff 40% 60%, #ee9bbd 60% 80%, #dc2d7a 80% 100%); }
.bip-bandeira--agenero { background: linear-gradient(180deg, #000 0 14.28%, #bcc4c7 14.28% 28.56%, #fff 28.56% 42.84%, #b7f684 42.84% 57.12%, #fff 57.12% 71.4%, #bcc4c7 71.4% 85.68%, #000 85.68% 100%); }
.bip-bandeira--arromantico { background: linear-gradient(180deg, #3ba740 0 20%, #a8d47a 20% 40%, #fff 40% 60%, #ababab 60% 80%, #000 80% 100%); }
.bip-bandeira--bigenero { background: linear-gradient(180deg, #c479a2 0 14.28%, #eda5cd 14.28% 28.56%, #d6c7e8 28.56% 42.84%, #fff 42.84% 57.12%, #d6c7e8 57.12% 71.4%, #9ac7e8 71.4% 85.68%, #6d82d1 85.68% 100%); }
.bip-bandeira--demiboy { background: linear-gradient(180deg, #7f7f7f 0 14.28%, #c4c4c4 14.28% 28.56%, #9ad9ea 28.56% 42.84%, #fff 42.84% 57.12%, #9ad9ea 57.12% 71.4%, #c4c4c4 71.4% 85.68%, #7f7f7f 85.68% 100%); }
.bip-bandeira--demigirl { background: linear-gradient(180deg, #7f7f7f 0 14.28%, #c4c4c4 14.28% 28.56%, #ffaec9 28.56% 42.84%, #fff 42.84% 57.12%, #ffaec9 57.12% 71.4%, #c4c4c4 71.4% 85.68%, #7f7f7f 85.68% 100%); }
.bip-bandeira--gay { background: linear-gradient(180deg, #078d70 0 14.28%, #26ceaa 14.28% 28.56%, #98e8c1 28.56% 42.84%, #fff 42.84% 57.12%, #7bade2 57.12% 71.4%, #5049cc 71.4% 85.68%, #3d1a78 85.68% 100%); }
.bip-bandeira--genderfluid { background: linear-gradient(180deg, #ff75a2 0 20%, #fff 20% 40%, #be18d6 40% 60%, #000 60% 80%, #333ebd 80% 100%); }
.bip-bandeira--genderqueer { background: linear-gradient(180deg, #b57edc 0 33.3%, #fff 33.3% 66.6%, #4a8123 66.6% 100%); }
.bip-bandeira--grayssexual { background: linear-gradient(180deg, #740194 0 20%, #a9a9a9 20% 40%, #fff 40% 60%, #a9a9a9 60% 80%, #740194 80% 100%); }
.bip-bandeira--lesbica { background: linear-gradient(180deg, #d52d00 0 20%, #ff9a56 20% 40%, #fff 40% 60%, #d362a4 60% 80%, #a30262 80% 100%); }
.bip-bandeira--neutrois { background: linear-gradient(180deg, #fff 0 33.3%, #1f9f00 33.3% 66.6%, #000 66.6% 100%); }
.bip-bandeira--omnissexual { background: linear-gradient(180deg, #fe9ace 0 20%, #ff53bf 20% 40%, #200e3f 40% 60%, #6b34fe 60% 80%, #8ea6ff 80% 100%); }
.bip-bandeira--poligenero { background: linear-gradient(180deg, #000 0 20%, #939393 20% 40%, #ed94c6 40% 60%, #f5ed81 60% 80%, #64bdf7 80% 100%); }
.bip-bandeira--polissexual { background: linear-gradient(180deg, #f61cb9 0 33.3%, #07d569 33.3% 66.6%, #1c92f6 66.6% 100%); }

/* ── SEGUNDA LEVA (06/09/26) ──────────────────────────────────────────────
   O dono pesquisou e trouxe a tabela grande: a lista de identidades nao cabe
   em resumo. Estas seis fecham os buracos que sobraram na primeira leva. */
.bip-bandeira--androgino { background: linear-gradient(180deg, #fe7f9d 0 33.3%, #9d75cc 33.3% 66.6%, #6a6aff 66.6% 100%); }
.bip-bandeira--aquileu { background: linear-gradient(180deg, #77bfea 0 33.3%, #f2f7e6 33.3% 66.6%, #77bfea 66.6% 100%); }
.bip-bandeira--aroace { background: linear-gradient(180deg, #e28c00 0 20%, #eccd00 20% 40%, #fff 40% 60%, #62aedc 60% 80%, #203856 80% 100%); }
.bip-bandeira--maverique { background: linear-gradient(180deg, #ffda00 0 33.3%, #fff 33.3% 66.6%, #ff9a00 66.6% 100%); }
.bip-bandeira--safico { background: linear-gradient(180deg, #fd8ba8 0 33.3%, #fff 33.3% 66.6%, #fd8ba8 66.6% 100%); }

/* A demirromantica e a demissexual com a listra do meio VERDE, mesmo triangulo. */
.bip-bandeira--demirromantico {
    position: relative;
    overflow: hidden;
    background: linear-gradient(180deg, #fff 0 42%, #3ba740 42% 58%, #d3d3d3 58% 100%);
}
.bip-bandeira--demirromantico::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-left: 7px solid #000;
}

/* A INTERSEXO NÃO TEM LISTRA: é um campo amarelo com um círculo roxo VAZADO no
   meio. Por isso ela é a segunda (com a demissexual) a precisar de desenho
   extra — aqui um `::before` redondo, no app um círculo no Canvas. */
.bip-bandeira--intersexo {
    position: relative;
    overflow: hidden;
    background: #ffd800;
}

.bip-bandeira--intersexo::before {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: 7px;
    height: 7px;
    transform: translate(-50%, -50%);
    border: 1.6px solid #7902aa;
    border-radius: 50%;
}

/* ── O HUMOR DO DIA (05/09/26) ────────────────────────────────────────────
   O BADGE é um só na rede inteira: o emoji num disco branco, pendurado no
   canto do rosto (rail, cards do feed, perfil). Quem desenha e resolve o
   clique é o humor.js; aqui só a roupa. */
.bip-humor-badge {
    display: inline-grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--surface);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.22);
    /* O EMOJI ENCHE O DISCO (05/09/26, ordem do dono: *"a bolinha branca é
       muito grande e o emoji muito pequeno, aumenta e centraliza que vai
       parecer só uma bordinha"*): fonte a ~72% do disco, o branco vira anel. */
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    user-select: none;
}

/* No card do feed: canto de CIMA do avatar (o de baixo é do "+" de seguir). */
.bip-card__avatar-box { position: relative; }

.bip-card__humor {
    position: absolute;
    /* 9px para FORA (05/09/26, 4ª medida do dono: "ainda temos margem, puxa
       um pouquinho mais"). */
    top: -9px;
    right: -9px;
    z-index: 2;
}

/* O HUMOR SAIU DA FOTO E ENTROU NA CORRENTE DO NOME (10/09/26, ordem do dono,
   padronizando com o app): aqui ele é uma peça da frase, não um adesivo na
   quina — então nada de `position: absolute`, e o disco branco sai junto, pelo
   mesmo motivo do perfil (o fundo aqui é o do cartão, não uma foto). */
.bip-card__humor--linha {
    position: static;
    top: auto;
    right: auto;
    background: none;
    box-shadow: none;
    width: auto;
    height: auto;
    font-size: 17px;
    vertical-align: -0.12em;
}

/* O SELO SAIU DA QUINA DO AVATAR (11/09/26, ordem do dono: "em algumas
   pessoas, como a Ellen, ficou perfeito, na Luciana ficou muito ruim; vamos
   voltar aos tradicionais, o selo no nome"): as regras da quina (selo-avatar)
   morreram com o markup (bips-ui.js). O selo colado ao nome mora em
   trust-badges.css (.bip-card__nome-fim). */

/* Cidade e hora na MESMA linha (10/09/26), com o ponto do app entre elas. */
.bip-card__meta-sep {
    margin: 0 5px;
    color: var(--text-3);
}

/* No rail: canto de baixo do rosto (o balão da nota mora em cima), puxado
   para fora na mesma medida dos cards. */
.status-bolha__humor {
    position: absolute;
    right: -5px;
    bottom: -5px;
    z-index: 2;
}

/* A janela de VER: o emoji grande sobre o rosto e a dica do sistema. */
.bip-humorj__espera {
    margin: 14px 0 6px;
    color: var(--text-2);
    font-size: 0.92rem;
    text-align: center;
}

.bip-humorj__emojao {
    display: block;
    margin-top: -18px;
    font-size: 1.7rem;
    line-height: 1;
    text-align: center;
}

.bip-humorj__dica {
    display: block;
    margin-top: 6px;
    color: var(--text-2);
    font-size: 0.88rem;
    text-align: center;
}

.bip-humorj__chat {
    display: block;
    text-align: center;
    text-decoration: none;
}

/* A régua de MARCAR: 7 emojis sobre o arco-íris (vermelho → verde, como a
   referência que o dono mandou) e o slider embaixo. */
.bip-humorj__regua {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
    margin-top: 14px;
    padding: 10px 6px;
    border-radius: 14px;
    background: linear-gradient(90deg, #e05c5c 0%, #e08a4a 18%, #e070a8 34%, #d9b83f 50%, #9dc45c 66%, #3aa8a0 82%, #46b878 100%);
}

.bip-humorj__opcao {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    margin: 0 auto;
    border-radius: 50%;
    background: #fff;
    font-size: 19px;
    line-height: 1;
    cursor: pointer;
    transition: transform 0.12s ease;
}

.bip-humorj__opcao.is-atual {
    transform: scale(1.22);
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.65);
}

.bip-humorj__slider {
    width: 100%;
    margin-top: 12px;
    accent-color: var(--accent);
}

.bip-humorj__frase {
    min-height: 22px;
    margin: 12px 0 4px;
    color: var(--text-1);
    font-size: 0.95rem;
    font-weight: 600;
    text-align: center;
}

/* A RESENHA E O TRAILER DO CARTÃO DE MÍDIA (09/09/26). A sinopse é cortada em
   quatro linhas: o cartão mora dentro de um BiP, e um BiP não pode virar uma
   página de enciclopédia. Quem quiser o texto inteiro toca no cartão. */
.bip-media__resenha {
    margin: 6px 0 0;
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--text-3);
    display: -webkit-box;
    -webkit-line-clamp: 4;
    line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.bip-media__trailer {
    display: inline-block;
    margin-top: 6px;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--accent);
    text-decoration: none;
}

.bip-media__trailer:hover { text-decoration: underline; }

/* ══ 🍀 A JANELA DA SORTE DO DIA (05/09/26; global desde 10/09/26) ══════════

   Ela morava no profile.css porque só existia no perfil. Em 10/09/26 o dono
   trouxe o relato: *"as pessoas da web estão contestando o porquê elas não têm
   a sorte do dia"* — no app a janela aparece SOZINHA na primeira abertura do
   dia, e na web era preciso ir ao próprio perfil e reparar numa linha verde de
   12px. Agora ela abre no feed também, e por isso o desenho é global.

   Ver assets/js/sorte-do-dia.js e frontend/partials/sorte_modal.php. */
.sorte-modal {
    max-width: 420px;
    text-align: center;
}

.sorte-modal__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.sorte-modal__head h2 {
    margin: 0;
    font-size: 1.15rem;
    color: var(--text);
}

.sorte-modal__fechar {
    border: 0;
    background: transparent;
    color: var(--text-3);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    padding: 2px 6px;
}

.sorte-modal__frase {
    margin: 16px 0 0;
    padding: 22px 16px;
    border-radius: 14px;
    background: color-mix(in srgb, var(--border) 30%, transparent);
    color: var(--text);
    font-size: 1rem;
    line-height: 1.5;
}

/* PUBLICAR é o botão PRINCIPAL (10/09/26): é ele que faz o cartão verde
   aparecer no feed, que é como a rede inteira descobriu que a sorte existe.
   Verde-trevo, a cor da funcionalidade, e não o azul da marca — a mesma
   distinção que a linha do perfil já fazia. */
.sorte-modal__publicar {
    display: block;
    width: 100%;
    margin-top: 16px;
    padding: 12px;
    border: 0;
    border-radius: 12px;
    background: #2e7d32;
    color: #fff;
    font-size: 0.95rem;
    font-weight: 700;
    cursor: pointer;
}

/* Compartilhar FORA da rede é o caminho secundário: vira botão de contorno,
   para os dois não disputarem o olho. */
.sorte-modal__compartilhar {
    display: block;
    width: 100%;
    margin-top: 8px;
    padding: 12px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: transparent;
    color: var(--text);
    font-size: 0.95rem;
    font-weight: 700;
    cursor: pointer;
}

.sorte-modal__compartilhar:hover {
    background: var(--surface-2);
}

/* O FECHAR DA SORTE (11/09/26, ordem do dono: "colocar este botão fechar um
   pouco mais para baixo"): 20px de respiro acima dele, tanto colado na frase
   (perfil alheio, só ver) quanto abaixo do "Compartilhar fora". A pílula em si
   morava só no profile.css (`.seq-modal__fechar-btn`), e no FEED, que também
   abre esta janela, o botão nascia pelado; o desenho passa a valer aqui,
   global, para a peça única servir as duas telas de verdade. */
.sorte-modal .seq-modal__fechar-btn {
    display: inline-block;
    margin-top: 20px;
    border: none;
    background: var(--accent);
    color: #fff;
    border-radius: 999px;
    padding: 9px 24px;
    font-weight: 700;
    cursor: pointer;
}

/* ══ FLERTE (10/09/26, ordem do dono) ══════════════════════════════════════
   O cupido/escudo da fileira sob o avatar e o palco da animação.

   MORA NO index.css, e não no profile.css (correção de 10/09/26, relato do
   dono: *"flerte web quebrado"*): o `flerte.js` vive no bundle-core e anima em
   QUALQUER página — inclusive no cadastro, ao escolher o cupido. Estilo preso à
   folha do perfil deixava a animação sem desenho fora dele, e foi assim que o
   bloco do cadastro nasceu sem estilo nenhum. */
/* ══ FLERTE (10/09/26, ordem do dono) ══════════════════════════════════════
   O cupido/escudo na fileira sob o avatar, a grade de escolha no cadastro e o
   palco da animação. A COR É O RECADO: vermelho para quem está aberto, cinza
   para quem passou o escudo — ler de relance é o ponto. */
.bip-flerte-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: var(--surface);
    border: 1px solid var(--border);
    cursor: pointer;
    transition: transform .15s ease, box-shadow .15s ease;
}

.bip-flerte-badge--cupido { color: #E11D48; }
.bip-flerte-badge--escudo { color: var(--text-3); cursor: default; }

.bip-flerte-badge--cupido:hover,
.bip-flerte-badge--cupido:focus-visible {
    transform: scale(1.12);
    box-shadow: 0 0 0 3px rgba(225, 29, 72, 0.18);
}

/* Enquanto a flechada sobe, o ícone pulsa: o gesto tem de ter resposta antes
   da rede responder. */
.bip-flerte-badge.is-enviando { animation: bip-flerte-pulso .5s ease infinite alternate; }
@keyframes bip-flerte-pulso { to { transform: scale(1.2); } }

/* ── O PALCO DA ANIMAÇÃO ──────────────────────────────────────────────────
   Por cima de tudo e SEM captura de toque (`pointer-events: none`): a chuva de
   corações não pode trancar a página por dois segundos e meio. */
.bip-flerte-palco {
    position: fixed;
    inset: 0;
    z-index: 9990;
    pointer-events: none;
    opacity: 0;
    transition: opacity .3s ease;
}

.bip-flerte-palco.is-on { opacity: 1; }

/* O CUPIDO ENTRA VOANDO (10/09/26, 2ª rodada do dono): vem da esquerda,
   balança de leve como quem plana e sai de cena. Sombra colorida por baixo para
   ele não parecer um adesivo colado na tela. */
.bip-flerte-cupido {
    position: absolute;
    top: 14%;
    left: 50%;
    transform: translate(-50%, 0);
    animation: bip-flerte-voo 2.4s cubic-bezier(.22, .8, .3, 1) forwards;
    filter: drop-shadow(0 14px 30px rgba(225, 29, 72, .3));
}

.bip-flerte-cupido img {
    display: block;
    width: min(260px, 54vw);
    height: auto;
}

@keyframes bip-flerte-voo {
    0%   { transform: translate(-165%, 18%) scale(.72) rotate(-8deg); opacity: 0; }
    18%  { opacity: 1; }
    38%  { transform: translate(-50%, 0) scale(1) rotate(0deg); }
    62%  { transform: translate(-46%, -2%) scale(1.02) rotate(2deg); }
    86%  { transform: translate(-40%, -4%) scale(1) rotate(0deg); opacity: 1; }
    100% { transform: translate(60%, -14%) scale(.9) rotate(6deg); opacity: 0; }
}

/* AS FLECHAS cruzam a tela por trás da chuva — três, em alturas diferentes. */
.bip-flerte-flecha {
    position: absolute;
    left: -12%;
    font-size: 30px;
    opacity: 0;
    animation: bip-flerte-flechada 1s cubic-bezier(.3, .1, .2, 1) forwards;
}

@keyframes bip-flerte-flechada {
    0%   { transform: translateX(0) scale(.8); opacity: 0; }
    12%  { opacity: 1; }
    100% { transform: translateX(125vw) scale(1.1); opacity: 0; }
}

.bip-flerte-legenda {
    position: absolute;
    top: calc(14% + min(260px, 54vw) * 0.94 + 8px);
    left: 50%;
    transform: translateX(-50%);
    margin: 0;
    width: max-content;
    max-width: 90vw;
    text-align: center;
    font-size: 1.05rem;
    font-weight: 700;
    color: #E11D48;
    /* PÍLULA BRANCA por baixo (11/09/26, ordem do dono: "não tem contraste"): a
       legenda cai sobre o card claro do feed e o rosa sumia. A pílula garante a
       leitura em qualquer fundo que a chuva de corações atravesse. */
    background: rgba(255, 255, 255, .95);
    padding: 8px 18px;
    border-radius: 999px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .16);
}

.bip-flerte-coracao {
    position: absolute;
    bottom: -40px;
    animation-name: bip-flerte-sobe;
    animation-timing-function: ease-in;
    animation-fill-mode: forwards;
}

@keyframes bip-flerte-sobe {
    from { transform: translateY(0) rotate(0deg); opacity: 0; }
    12%  { opacity: 1; }
    to   { transform: translateY(-105vh) rotate(28deg); opacity: 0; }
}

/* Quem pediu menos movimento recebe o recado sem o voo (a régua da casa). */
@media (prefers-reduced-motion: reduce) {
    .bip-flerte-coracao,
    .bip-flerte-flecha { display: none; }
    .bip-flerte-cupido { animation: none; transform: translate(-50%, 0); }
}


/* O RECADO DO FLERTE quando não há `showToast` na página (10/09/26): plano B
   do aviso, para que uma recusa do servidor nunca vire silêncio. */
.bip-flerte-recado {
    position: fixed;
    left: 50%;
    bottom: 26px;
    z-index: 9995;
    transform: translate(-50%, 12px);
    max-width: min(420px, 92vw);
    padding: 12px 16px;
    border-radius: 12px;
    background: rgba(17, 24, 39, .92);
    color: #fff;
    font-size: .9rem;
    text-align: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease, transform .2s ease;
}

.bip-flerte-recado.is-on { opacity: 1; transform: translate(-50%, 0); }
.bip-flerte-recado.is-erro { background: rgba(190, 18, 60, .95); }

/* ══ O POST DO FLERTE (10/09/26, ideia de um usuário, ordem do dono) ════════
   *"Fazer uma postagem do sistema do tipo 'Suemar recebeu um flerte, quem
   será?' e deixa os ícones sociais para as pessoas poderem comentar. Só não
   colocaria o botão de votos."*

   O cartão inteiro muda de roupa: fundo em degradê rosa, o cupido de água
   marca no canto e a frase em destaque. O CONTEÚDO é o mesmo texto que o app
   antigo mostra — aqui ele só ganha palco. */
.bip-card--flerte {
    position: relative;
    overflow: hidden;
    background:
        radial-gradient(120% 120% at 100% 0%, rgba(225, 29, 72, .14) 0%, rgba(225, 29, 72, 0) 55%),
        linear-gradient(135deg, rgba(255, 228, 236, .85) 0%, rgba(255, 245, 248, .95) 60%);
    border-color: rgba(225, 29, 72, .22);
}

[data-theme="dark"] .bip-card--flerte {
    background:
        radial-gradient(120% 120% at 100% 0%, rgba(225, 29, 72, .22) 0%, rgba(225, 29, 72, 0) 55%),
        linear-gradient(135deg, rgba(80, 12, 32, .55) 0%, rgba(24, 26, 33, .9) 60%);
}

/* O CUPIDO de marca d'água: o MESMO arquivo da animação — uma arte, todos os
   lugares. `pointer-events: none` porque ele é papel de parede, não botão. */
.bip-card--flerte::after {
    content: "";
    position: absolute;
    right: -18px;
    bottom: -12px;
    width: 168px;
    height: 158px;
    background: url("/assets/img/flerte-cupido.webp") no-repeat right bottom / contain;
    opacity: .22;
    pointer-events: none;
}

.bip-card--flerte .bip-card__content,
.bip-card--flerte .bip-card__text {
    position: relative;
    z-index: 1;
    font-size: 1.05rem;
    font-weight: 600;
    line-height: 1.45;
    color: #9F1239;
}

[data-theme="dark"] .bip-card--flerte .bip-card__content,
[data-theme="dark"] .bip-card--flerte .bip-card__text { color: #FDA4AF; }

/* SEM VOTOS (ordem do dono): o cartão é convite a comentar, não a julgar.
   Curtir, comentar, repostar e enviar continuam — são eles que fazem a
   brincadeira circular. Desde 18/09/26 quem cuida disso é o bips-ui.js: a seta
   do dislike (o único voto que sobrou) nem é desenhada no flerte, e a regra que
   escondia a nota da ponta saiu com ela. */

/* O ícone do cupido é IMAGEM (10/09/26): `object-fit: contain` para o disco do
   badge nunca esticar o desenho, e o filtro de cor sai de cena — a arte já vem
   pintada. */
.bip-flerte-icone {
    display: block;
    width: 68%;
    height: 68%;
    object-fit: contain;
}

.bip-flerte-badge--escudo .bip-flerte-icone { width: 62%; height: 62%; }

/* ══ MEUS FLERTES, EM NÚMEROS (10/09/26, ordem do dono) ════════════════════
   Janela pequena, sem nome nenhum: só as contas. */
.bip-flerte-numeros { position: fixed; inset: 0; z-index: 9970; }
.bip-flerte-numeros[hidden] { display: none; }
.bip-flerte-numeros__fundo { position: absolute; inset: 0; background: rgba(15, 23, 42, .55); }

.bip-flerte-numeros__caixa {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: min(340px, 92vw);
    padding: 20px 20px 16px;
    border-radius: 18px;
    background: var(--bg);
    border: 1px solid var(--border);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .28);
    text-align: center;
}

.bip-flerte-numeros__x {
    position: absolute;
    top: 8px;
    right: 12px;
    border: none;
    background: none;
    color: var(--text-3);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
}

.bip-flerte-numeros__cupido { display: block; margin: 0 auto 6px; width: 120px; height: auto; }
.bip-flerte-numeros__n { display: block; font-size: 2.4rem; font-weight: 800; color: #E11D48; line-height: 1.1; }
.bip-flerte-numeros__rot { display: block; font-size: .9rem; color: var(--text-2); }
.bip-flerte-numeros__linha { margin: 10px 0 0; font-size: .85rem; color: var(--text-3); }
.bip-flerte-numeros__pe { margin: 8px 0 0; font-size: .78rem; color: var(--text-3); line-height: 1.4; }
.bip-flerte-numeros__link { display: inline-block; margin-top: 14px; font-size: .85rem; font-weight: 600; color: var(--accent); }

/* A BORDINHA FINA DO RAIL (11/09/26, ordem do dono: "para essas caixas ficarem
   ainda melhor precisa daquela bordinha mega fina que fizemos no perfil"). A
   leva de 16/08 apagou as bordas dos contêineres (bloco acima); o rail volta a
   ter a linha, na MESMA cor do card do Editar perfil (#EBECEF), e no escuro o
   branco a 8% no lugar do anel de 4%. Vem no fim do arquivo de propósito: a
   última regra de mesma especificidade vence a que apagou. */
.rail-card {
    border: 1px solid #EBECEF;
}

:root:not([data-theme="light"]) .rail-card {
    border-color: rgba(255, 255, 255, 0.08);
    box-shadow: none;
}

/* ══ O FIO FINO NAS CAIXAS DO FEED E DO EXPLORAR (11/09/26, ordem do dono:
   "colocar a borda, o risco que você colocou nas outras caixas, também na
   caixa de postagem, na caixa de filtro e nos cards das postagens, e no botão
   de busca explorar"; depois: "na barra de filtro e em cada uma das caixas
   Destaque, pessoas para conhecer, biptags, lugares").

   POR QUE NÃO BASTAVA O --border: a leva "CAIXAS SEM BORDA" de 16/08 zera a
   cor da borda do cartão, do compositor e da barra das pílulas
   (border-color: transparent), do tempo em que o chão era cinza. Com o chão
   em #FAFAFA a caixa branca some sem o fio, e o dono aprovou o fio do rail
   (#EBECEF). Este bloco vem DEPOIS daquela leva e a vence pela ordem. No
   escuro, o fio do rail (branco a 8%). As caixas do Explorar nunca tiveram
   caixa: ganham a mesma roupa do .rail-card, com o mesmo raio. */
.bip-card,
.feed-composer,
.feed-pills,
.app-topbar--search .search-bar {
    border: 1px solid #EBECEF;
}

.explorar__secao {
    padding: 16px 18px 18px;
    background: var(--surface);
    border: 1px solid #EBECEF;
    border-radius: var(--radius-lg);
}

/* Dentro da caixa o título respira menos; o vão entre caixas é o do rail. */
.explorar {
    gap: 14px;
}

.explorar__secao .explorar__titulo {
    margin-bottom: 12px;
}

:root:not([data-theme="light"]) .bip-card,
:root:not([data-theme="light"]) .feed-composer,
:root:not([data-theme="light"]) .feed-pills,
:root:not([data-theme="light"]) .app-topbar--search .search-bar,
:root:not([data-theme="light"]) .explorar__secao {
    border-color: rgba(255, 255, 255, 0.08);
}

/* ══ A FRASE DO HUMOR NO CABEÇALHO DO CARTÃO (11/09/26, ordem do dono: "no selo
   do humor vamos escrever o texto: Nome + selo + 'está radiante hoje' + emoji").
   O emoji solto ao lado do nome virou a frase do catálogo (BipHumor.frase), em
   peso normal e no tom do metadado, com o emoji no fim. Continua botão: o toque
   abre a janela do humor. Desfaz o disco do .bip-humor-badge pelo mesmo motivo
   do --linha: aqui é texto, não adesivo. */
.bip-humor-badge--frase {
    display: inline;
    position: static;
    width: auto;
    height: auto;
    padding: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
    font-size: 0.92em;
    font-weight: 400;
    line-height: inherit;
    color: var(--text-2);
    cursor: pointer;
    white-space: normal;
}

.bip-humor-badge--frase:hover {
    color: var(--text);
}

/* ══ "CONECTADOS" VOLTOU A SER PALAVRA (15/09/26, ordem do dono: "volta o botão lindo
   e pequeno, melhor que este ícone"). A corrente de 11/09 saiu da pílula, e com ela o
   recuo de quadrado: o estado mútuo usa o mesmo recuo do "Seguindo". A classe
   `.bip-corrente` fica para quem ainda usa BipsUI.correnteSvg fora do cartão. */

.bip-corrente {
    display: block;
    width: 16px;
    height: 16px;
}

.bip-reply__follow-btn .bip-corrente {
    width: 14px;
    height: 14px;
}

/* ══ A BANDEIRA DE GÊNERO NA QUINA DO ROSTO (12/09/26, ordem do dono: "para
   fechar com chave de ouro, colocar a bandeira do lado esquerdo do avatar, 1:1,
   quadrada, assim fica bem posicionada e não atrapalha"). Saiu da corrente do
   nome (que ficou nome + selo + a frase do humor) e virou um quadradinho de
   16px no canto de baixo à esquerda da foto, com um anel na cor da superfície
   para descolar do rosto, o mesmo truque do selo de antes. Continua botão:
   abre a janela da bandeira. O app faz igual. */
.bip-card__bandeira-avatar {
    position: absolute;
    left: -4px;
    bottom: -3px;
    z-index: 2;
    line-height: 0;
}

/* Com anel, a caixa é a foto MAIS os 2px da moldura de cada lado: sem este
   desconto a bandeira ficaria 2px mais longe da quina do rosto do que em quem
   não tem anel. A régua é a FOTO, não o anel. */
.bip-card__moldura ~ .bip-card__bandeira-avatar {
    left: -2px;
    bottom: -1px;
}

.bip-card__bandeira-avatar .bip-bandeira {
    display: block;
    width: 16px;
    height: 16px;
    margin: 0;
    border-radius: 4px;
    vertical-align: baseline;
    box-shadow: 0 0 0 2px var(--surface), inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}

/* O "e" ENTRE O HUMOR E O SENTIMENTO (12/09/26, ideia do dono: "quando tiver
   uma combinação a gente coloca um 'e': Suemar está num dia mais ou menos e
   está compartilhando sua sorte do dia, fica mais fluido"). Só nasce quando as
   duas frases existem; no tom do metadado, como a frase do humor. */
.bip-card__conector {
    color: var(--text-2);
    font-size: 0.92em;
}

/* ══ A BUSCA DE SENTIMENTO E O ESCRITO À MÃO (12/09/26, ordem do dono: "vamos
   colocar uma caixa de busca no topo e, se não encontrar, deixar a opção da
   pessoa definir personalizado, que entrará como texto da pessoa"). O catálogo
   foi de 30 para 195 no mesmo dia, e uma grade de 195 sem busca é uma lista
   que ninguém rola até o fim.

   A caixa mora DENTRO do corpo que rola (a folha é uma só para sentimento,
   atividade e filme, e o cabeçalho é delas todas) e fica PEGAJOSA no topo: o
   dedo desce pela grade e a busca continua à mão. As margens negativas a
   encostam nas bordas do corpo para o fundo cobrir a grade que passa por
   baixo. O corpo ganha `min-height: 0` dito em voz alta: é o que deixa a
   coluna flex encolher até o teto de 76dvh do painel e rolar por dentro.

   A opção "Usar “…” como sentimento" atravessa as duas colunas e vem
   tracejada: não é o 196º item do catálogo, é a saída para o que não está
   nele. Acesa (is-on) ela usa a mesma roupa dos outros. */
.bip-status-sheet__body {
    flex: 1 1 auto;
    min-height: 0;
}

/* A CAIXA NÃO É MAIS PEGAJOSA: QUEM ROLA É A GRADE (12/09/26, ordem do dono:
   "aumente o respiro pois está cortando os primeiros"). A primeira versão
   deixava a caixa `sticky` dentro do corpo que rola, com 10px de folga: 30px
   de rolagem já enfiavam a primeira fileira debaixo dela (medido na bancada),
   e o dono viu "feliz" e "abençoado" cortados ao meio. Pegajoso é isso por
   definição, o conteúdo passa POR BAIXO; folga maior só adia o corte.

   Agora o corpo vira coluna sem rolagem e a GRADE é o que rola: a caixa fica
   parada em cima com 14px de ar, nada nunca passa atrás dela, e o botão
   "Tirar o sentimento" fica sempre à vista no pé. Só se aplica quando a caixa
   existe (`:has`), para atividade e filme continuarem como eram. */
.bip-status-sheet__body:has(.bip-status-busca) {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.bip-status-busca {
    flex: 0 0 auto;
    margin: 0 0 14px;
}

.bip-status-sheet__body:has(.bip-status-busca) > .bip-status-grid {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    align-content: start;
    /* Ar de 2px nas laterais para o anel de foco dos botões não ser cortado
       pela rolagem; a margem negativa devolve a largura. */
    padding: 2px;
    margin: -2px;
}

.bip-status-sheet__body:has(.bip-status-busca) > .bip-status-sheet__limpar {
    flex: 0 0 auto;
    margin-top: 12px;
}

/* `--bg-1` NUNCA EXISTIU (visto na bancada, 12/09/26, a mesma armadilha do
   `--text-1` de 24/08): o painel da folha pedia `var(--bg-1, #fff)` e caía
   SEMPRE no branco, também no tema preto, onde o texto é #ececec: título
   branco sobre painel branco. `--surface` existe nos dois temas (#FFFFFF no
   claro, então nada muda para quem usa o padrão; #262626 no preto, a cor das
   caixas). A caixa de busca pegajosa usa a mesma cor para cobrir a grade que
   passa por baixo. */
.bip-status-sheet__panel {
    background: var(--surface, #fff);
}

/* AS COLUNAS NÃO PODEM CRESCER COM O RÓTULO. `1fr` é `minmax(auto, 1fr)`: a
   coluna nunca fica mais estreita que o rótulo mais comprido dela, e com 195
   itens ("de coração partido", "sobrecarregada", "sem importância") as duas
   colunas somadas passavam dos 420px do painel, com barra horizontal e a
   segunda coluna cortada (visto na bancada, 12/09/26). Com 30 itens o mais
   longo era "esperançoso(a)" e cabia por sorte. `minmax(0, 1fr)` divide o
   painel em duas metades de verdade, e o rótulo que não cabe QUEBRA a linha
   em vez de empurrar a grade. */
.bip-status-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.bip-status-grid > .bip-status-opt {
    min-width: 0;
}

.bip-status-grid > .bip-status-opt > span:last-child {
    min-width: 0;
    overflow-wrap: anywhere;
}

.bip-status-grid > .bip-status-opt--livre,
.bip-status-grid > .bip-status-sheet__aviso {
    grid-column: 1 / -1;
}

.bip-status-opt--livre {
    border: 1px dashed var(--border);
    background: transparent;
}

.bip-status-opt--livre:hover { background: var(--bg-2); }

.bip-status-opt--livre.is-on { border-color: transparent; }

/* ══ O EXPLORAR SEM ABAS (12/09/26, ordem do dono: "vamos tirar a barra de
   filtros e responder direto na tela tudo, com um título para cada resposta
   [...] tirar o filtro Todos os países; melhorar a Localização carregando as
   localizações que já temos no sistema sem a pessoa digitar; e uma outra
   caixinha que será o filtro da barra removida, para filtrar só BiPs, BiPers,
   BipTags ou BipLugar") ═══════════════════════════════════════════════════════

   As seções de resultado (BiPs, BiPers, BipTags, BipLugar) entram uma embaixo
   da outra, cada uma com o título no peso do Explorar (.explorar__titulo). A
   caixa branca com o fio fica no CORPO e não na seção: as linhas de BiPer e
   de cidade (.follows-list) já são caixa e só ganham o fio do rail; os cards
   de BiP são caixas por si (quadro dentro de quadro seria o erro); a grade
   de tags são cartões soltos. Só a fatia cortada do Tudo mostra "Ver todos". */
.search-secoes {
    display: flex;
    flex-direction: column;
    gap: 22px;
    padding: 4px 0 8px;
}

/* O slot vazio (tipo sem resultado, ou ainda em voo) não ocupa nem o gap. */
.search-secao-slot:empty {
    display: none;
}

.search-secao-slot {
    transition: opacity 0.22s var(--ease);
}

.search-secao-slot--enter {
    opacity: 0;
}

.search-secao__topo {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin: 0 0 10px;
}

.search-secao__titulo {
    margin: 0;
    font-size: 1.02rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    color: var(--white);
}

.search-secao__mais {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 4px 0;
    background: none;
    border: none;
    color: var(--accent);
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}

.search-secao__mais:hover {
    text-decoration: underline;
}

/* Os corpos: as listas de gente e de cidade ganham o fio do rail (#EBECEF,
   branco a 8% no escuro), a mesma roupa das caixas do Explorar. */
.search-secao .follows-list {
    border: 1px solid #EBECEF;
}

:root:not([data-theme="light"]) .search-secao .follows-list {
    border-color: rgba(255, 255, 255, 0.08);
}

/* A grade de tags respirava 16px em cima porque nascia colada na barra de
   filtros; agora nasce embaixo do título. A barra da tag (#tag + Seguir
   BipTag) abre a seção BiPs colada no título pelo mesmo motivo. */
.search-secao .search-BiPtags-grid {
    padding-top: 0;
}

.search-secao .search-tag-follow-bar {
    margin-top: 0;
}

/* A barra de filtros é uma e fica sempre à vista, logo abaixo da caixa: perde
   o fio de baixo (os títulos das seções já separam) e encurta o respiro. */
.search-filters-bar {
    border-bottom: none;
    padding: 10px 0 0;
}

/* A pill de Ordem das BipTags some fora do Ver = BipTags. .custom-dropdown não
   tem display próprio, então o `hidden` já valeria; garantido aqui para não
   depender disso se alguém der display ao .custom-dropdown um dia. */
.custom-dropdown[hidden] {
    display: none !important;
}

/* O menu de lugares: sub-itens (estados), contagem e o rótulo "Fora do Brasil"
   são as mesmas regras de rankings.css, que esta página não carrega; a
   bandeira é nova (o diretório não a desenha). */
.custom-dropdown__menu--scroll {
    max-height: 320px;
    overflow-y: auto;
}

.custom-dropdown__item--sub {
    padding-left: 28px;
}

.custom-dropdown__count {
    margin-left: 6px;
    font-size: 0.72rem;
    font-weight: 600;
    color: var(--text-3);
}

.custom-dropdown__label {
    display: block;
    padding: 10px 12px 4px;
    font-size: 0.68rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-3);
}

.custom-dropdown__flag {
    width: 20px;
    height: 15px;
    border-radius: 2px;
    object-fit: cover;
    flex-shrink: 0;
}

/* ══ A GRADE DE SENTIMENTOS EM 4 / 3 / 1 COLUNAS (12/09/26, ordem do dono:
   "vamos fazer essa lista ficar em 4 colunas para PC, 3 colunas para tablet e
   1 coluna para celular"). Com 195 itens, duas colunas viravam um rolo de
   quase cem linhas no computador. O PAINEL alarga junto (só o da grade de
   sentimento, via :has; atividade e buscas seguem em 420px), e o rótulo
   continua com minmax(0, 1fr): coluna nunca cresce com a palavra. */
@media (max-width: 639px) {
    .bip-status-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (min-width: 640px) and (max-width: 1023px) {
    .bip-status-sheet__panel:has(.bip-status-grid) {
        width: min(700px, 96vw);
    }

    .bip-status-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (min-width: 1024px) {
    .bip-status-sheet__panel:has(.bip-status-grid) {
        width: min(880px, 96vw);
    }

    .bip-status-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* ── OS CARTÕES DO SISTEMA NO FEED DA WEB (15/09/26, dono: "na web não monta os cards especiais a cada 5?")
   Mesmo lugar e mesma régua do app: um cartão depois de cada 5 bips (ver assets/js/feed-cartoes.js).
   Marcador que não recebeu cartão não ocupa espaço. */
.feed-sis:empty { display: none; }
.feed-sis {
    margin-bottom: 12px;
    padding: 14px 18px 14px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 16px;
    color: var(--text);
}
.feed-sis__topo { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.feed-sis__icone { font-size: 1.1rem; line-height: 1; }
.feed-sis__titulo { font-weight: 700; font-size: 0.95rem; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed-sis__mais { font-size: 0.82rem; font-weight: 600; color: var(--accent); text-decoration: none; }
.feed-sis__chip { font-size: 0.74rem; font-weight: 600; color: var(--text-2); background: var(--bg-2); padding: 3px 9px; border-radius: 999px; }
.feed-sis__lista { display: flex; flex-direction: column; gap: 10px; }
.feed-sis__pessoa, .feed-sis__alta { display: flex; align-items: center; gap: 10px; min-width: 0; }
.feed-sis__pessoa-link { display: flex; align-items: center; gap: 10px; flex: 1; min-width: 0; color: inherit; text-decoration: none; }
.feed-sis__alta { color: inherit; text-decoration: none; }
.feed-sis__avatar { width: 42px; height: 42px; border-radius: 50%; object-fit: cover; flex-shrink: 0; background: var(--bg-2); }
.feed-sis__avatar--vazia { display: inline-flex; align-items: center; justify-content: center; color: var(--text-3); }
.feed-sis__textos { display: flex; flex-direction: column; min-width: 0; }
.feed-sis__nome, .feed-sis__comm-nome, .feed-sis__poster-nome { font-weight: 600; font-size: 0.9rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed-sis__trecho { font-size: 0.9rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.feed-sis__sub { font-size: 0.8rem; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed-sis__btn {
    flex-shrink: 0; border: 0; border-radius: 999px; padding: 6px 14px;
    font: 600 0.82rem var(--font, inherit); cursor: pointer; text-decoration: none;
    background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent);
}
.feed-sis__btn:disabled { opacity: .6; cursor: default; }
.feed-sis__btn--cheio { background: var(--accent); color: #fff; }
.feed-sis__estado { flex-shrink: 0; font-size: 0.8rem; font-weight: 600; color: var(--text-2); }
.feed-sis__pessoa--hoje .feed-sis__nome::after { content: ' 🎂'; }

.feed-sis__comms { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.feed-sis__comm {
    position: relative; display: flex; flex-direction: column; align-items: center; text-align: center;
    padding: 0 8px 10px; border: 1px solid var(--border); border-radius: 12px; overflow: hidden;
    color: inherit; text-decoration: none; min-width: 0;
}
.feed-sis__capa { align-self: stretch; height: 56px; margin: 0 -8px; background: var(--bg-2) center / cover no-repeat; }
.feed-sis__comm-foto { width: 44px; height: 44px; border-radius: 12px; object-fit: cover; margin-top: -22px; border: 2px solid var(--surface); background: var(--bg-2); display: inline-flex; align-items: center; justify-content: center; }
.feed-sis__comm-nome { margin-top: 6px; max-width: 100%; }
.feed-sis__comm .feed-sis__sub { max-width: 100%; }
@media (max-width: 480px) { .feed-sis__comms { grid-template-columns: 1fr; } .feed-sis__comm { flex-direction: row; text-align: left; gap: 10px; padding: 8px; } .feed-sis__capa { display: none; } .feed-sis__comm-foto { margin-top: 0; } .feed-sis__comm-nome { margin-top: 0; } }

.feed-sis__pergunta { margin: 2px 0 10px; font-size: 1.05rem; font-weight: 600; line-height: 1.4; }
.feed-sis__resposta {
    display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%;
    min-height: 44px; padding: 10px 12px; border-radius: 12px; font-size: 0.88rem;
    background: repeating-linear-gradient(135deg, var(--bg-2) 0 8px, color-mix(in srgb, var(--bg-2) 70%, var(--surface)) 8px 16px);
    color: var(--text-2); border: 0;
}
.feed-sis__resposta--spoiler { position: relative; cursor: pointer; font: inherit; }
.feed-sis__resposta--spoiler span { filter: blur(7px); font-weight: 700; color: var(--text); transition: filter .25s; }
.feed-sis__resposta--spoiler em { position: absolute; font-style: normal; font-weight: 600; font-size: 0.82rem; color: var(--text); }
.feed-sis__resposta--spoiler.aberto span { filter: none; }
.feed-sis__resposta--spoiler.aberto em { display: none; }
.feed-sis__regua { display: grid; grid-template-columns: repeat(10, 1fr); gap: 4px; margin: 10px 0 8px; }
.feed-sis__regua span { height: 5px; border-radius: 3px; background: var(--bg-2); }
.feed-sis__regua span.on { background: var(--accent); }
.feed-sis__rodape { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

.feed-sis__posteres { display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 2px; scrollbar-width: none; }
.feed-sis__posteres::-webkit-scrollbar { display: none; }
.feed-sis__poster {
    position: relative; flex: 0 0 112px; scroll-snap-align: start; display: flex; flex-direction: column;
    gap: 2px; padding: 0; border: 0; background: none; color: inherit; text-align: left; cursor: pointer; font: inherit;
}
.feed-sis__poster img, .feed-sis__poster-vazio { width: 112px; height: 168px; border-radius: 10px; object-fit: cover; background: var(--bg-2); display: flex; align-items: center; justify-content: center; font-size: 2rem; }
.feed-sis__poster-play {
    position: absolute; top: 62px; left: 36px; width: 40px; height: 40px; border-radius: 50%;
    background: rgba(0,0,0,.55); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 1.5rem;
    opacity: .9; transition: transform .15s;
}
.feed-sis__poster:hover .feed-sis__poster-play { transform: scale(1.1); }
.feed-sis__poster-nome { margin-top: 4px; font-size: 0.82rem; }

.feed-sis-tv { position: fixed; inset: 0; z-index: 2000; background: rgba(0,0,0,.78); display: flex; align-items: center; justify-content: center; padding: 16px; }
.feed-sis-tv__caixa { width: min(860px, 100%); background: #000; border-radius: 14px; overflow: hidden; }
.feed-sis-tv__topo { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 14px; color: #fff; font-weight: 600; }
.feed-sis-tv__topo button { border: 0; background: none; color: #fff; font-size: 1.6rem; cursor: pointer; line-height: 1; }
.feed-sis-tv__video { position: relative; aspect-ratio: 16 / 9; max-width: 100%; }
.feed-sis-tv__video iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* 😂 A ADIVINHA EM DESTAQUE (15/09/26, dono: "ficou muito morto… faça algum destaque, vai acabar passando batido;
   como os posts em destaque de outra rede, mas ao invés de um falante um emoji de riso"). Mesmo desenho no app. */
.feed-sis--adivinha {
    position: relative;
    margin-top: 22px;
    border: 2px solid #FF8A00;
    background: linear-gradient(180deg, color-mix(in srgb, #FFB020 10%, var(--surface)) 0%, var(--surface) 60%);
    box-shadow: 0 8px 24px rgba(255, 122, 0, .16);
}
.feed-sis__selo {
    position: absolute; top: -18px; left: -10px; width: 40px; height: 40px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center; font-size: 22px; line-height: 1;
    background: linear-gradient(135deg, #FFC23D, #FF7A00);
    box-shadow: 0 0 0 3px var(--surface), 0 4px 12px rgba(255, 122, 0, .4);
    animation: feed-sis-riso 2.6s ease-in-out infinite;
    transform-origin: 50% 60%;
}
@keyframes feed-sis-riso {
    0%, 55%, 100% { transform: rotate(0) scale(1); }
    62% { transform: rotate(-14deg) scale(1.08); }
    70% { transform: rotate(12deg) scale(1.08); }
    78% { transform: rotate(-8deg) scale(1.04); }
    86% { transform: rotate(5deg) scale(1); }
}
@media (prefers-reduced-motion: reduce) { .feed-sis__selo { animation: none; } }
.feed-sis--adivinha .feed-sis__topo { padding-left: 26px; }
.feed-sis--adivinha .feed-sis__icone:empty { display: none; }
.feed-sis--adivinha .feed-sis__titulo { color: #FF7A00; font-size: 1rem; }
.feed-sis--adivinha .feed-sis__chip { color: #C25700; background: color-mix(in srgb, #FFB020 22%, var(--surface)); }
.feed-sis--adivinha .feed-sis__regua span.on { background: #FF8A00; }
.feed-sis--adivinha .feed-sis__btn--cheio { background: linear-gradient(90deg, #FFB020, #FF7A00); color: #fff; box-shadow: 0 4px 12px rgba(255, 122, 0, .3); }
/* Os ícones de um post na adivinha (15/09/26): a fileira é a do .bip-card, só ganha o respiro e o fio acima. */
.feed-sis__social:empty { display: none; }
.feed-sis__social { margin-top: 12px; padding-top: 8px; border-top: 1px solid color-mix(in srgb, #FF8A00 22%, var(--border)); }

/* ══ A ROLAGEM NO TEMA CLARO (20/09/26, ordem do dono) ══════════════════════
   *"Tema claro dá para fazer essa rolagem em um tom bem mais claro e apagado,
   para não ficar tão forte e agressivo."* — com o print da janela "Como você
   está se sentindo?", onde a barra cinza-escuro do navegador cortava a lista
   de emoções ao meio.

   No claro o Chrome desenha a barra padrão quase preta sobre o branco, e ela
   vira a coisa mais forte da janela. Aqui ela fica fina e clara: só aparece de
   verdade quando o ponteiro chega perto. No escuro nada muda — lá a barra do
   sistema já nasce discreta contra o fundo. */
[data-theme="light"] {
    scrollbar-width: thin;
    scrollbar-color: rgba(15, 23, 42, 0.16) transparent;
}

[data-theme="light"] *::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

[data-theme="light"] *::-webkit-scrollbar-track {
    background: transparent;
}

[data-theme="light"] *::-webkit-scrollbar-thumb {
    background: rgba(15, 23, 42, 0.14);
    border: 3px solid transparent;
    background-clip: padding-box;
    border-radius: 999px;
}

[data-theme="light"] *::-webkit-scrollbar-thumb:hover {
    background: rgba(15, 23, 42, 0.26);
    background-clip: padding-box;
}

[data-theme="light"] *::-webkit-scrollbar-corner {
    background: transparent;
}

/* ⏳ O BOTÃO ESPERANDO A POSTAGEM LENTA (20/09/26, ordem do dono: *"apresentar o
   timer no botão e deixar o botão de postagem desabilitado, habilitando
   automaticamente após o tempo"*). Ele continua LEGÍVEL: quem lê "BiPar em 1:36"
   entende o que está acontecendo, e é por isso que ele não some nem apaga
   demais. O cursor diz que não adianta insistir. */
.compose-modal__submit.is-esperando,
#btnSubmitBiP.is-esperando {
    opacity: 0.72;
    cursor: not-allowed;
    font-variant-numeric: tabular-nums;
}

/* O TETO DA ALTURA DO VÍDEO (27/09/26): a janela menos a barra de cima (e, no celular, a de
   baixo) e um respiro. É ele que faz a gravação de tela caber inteira sem canva. */
:root {
    --bip-video-alto-max: calc(100dvh - var(--mobile-header-height, var(--app-topbar-height, 72px)) - var(--mobile-tabbar-height, 0px) - 24px);
}

/* ══ 💬 MODO TÍMIDO (01/10/26, ordem do dono) ═══════════════════════════════

   *"Quem ativar, o perfil mostra um selo tipo este resumo, mas 'Bora prosear?'.
   Veja como a pílula é fina e pequena, algo discreto mas funcional e bonito."*

   FINA DE VERDADE: 11px de letra, 3px de respiro em cima e embaixo, fundo
   lavado do azul da casa e um fio da mesma família. Ela mora logo abaixo do @
   no perfil, e a mesma peça serve de prévia nas Configurações — uma pílula só,
   num lugar só, para as duas telas nunca divergirem. */
.bip-timido-selo {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    border: 1px solid var(--accent-glow);
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent);
    font-family: var(--font);
    font-size: 11px;
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: 0.01em;
    white-space: nowrap;
    text-decoration: none;
    transition: background var(--duration) ease, border-color var(--duration) ease;
}

.bip-timido-selo i {
    font-size: 13px;
    line-height: 1;
}

/* Só o do DONO é link (leva à chave): o dos outros é informação, e informação
   não acende ao passar o rato. */
a.bip-timido-selo:hover,
a.bip-timido-selo:focus-visible {
    background: var(--accent-glow);
    border-color: var(--accent);
    outline: none;
}

.profile-header__timido {
    margin: 4px 0 0;
    /* Acompanha o alinhamento do @ e da cidade, que mudam de lado conforme o
       perfil é o meu ou o de outra pessoa. */
    text-align: inherit;
}

/* A prévia das Configurações fica à esquerda do cartão, colada na frase. */
.bip-timido-selo--previa {
    margin-top: 2px;
}

/* O cartão do rail: a linha de apoio sob o título, antes dos três rostos. */
.rail-timidos__sub {
    margin: -2px 0 10px;
    color: var(--text-2);
    font-size: 0.78rem;
    line-height: 1.4;
}

/* "Conversar" não é "+ Amigo": mesma pílula, tinta da casa — um abre a conversa
   que já existe, o outro pede a porta. Cores iguais fariam o cartão parecer ter
   um botão só com dois nomes. */
.rail-seguir__btn--prosa {
    background: var(--accent);
    color: #fff;
    text-decoration: none;
}

.rail-seguir__btn--prosa:hover {
    background: var(--accent);
    color: #fff;
    filter: brightness(1.08);
}

/* A MESMA PÍLULA NO CARTÃO DO BiP (02/10/26, ordem do dono: *"no perfil ok, mas
   fica escondido; não tem nos posts da pessoa, que seria o lugar visível"*).

   Um degrau MENOR que a do perfil: ali ela é a apresentação da pessoa, aqui
   divide a linha com a cidade e a hora, que são um sussurro. Maior que elas, a
   pílula viraria o assunto do cabeçalho em todo post dessa pessoa. */
.bip-timido-selo--card {
    margin-left: 8px;
    padding: 1px 7px;
    font-size: 10.5px;
    vertical-align: middle;
}
