/* ==========================================================================
   FabricioIA — a redação como aplicativo.

   A área restrita tem duas encarnações da mesma página. No monitor ela se
   espalha em colunas. No celular ela vira app: título fixo em cima, abas no
   alcance do polegar embaixo, e o conteúdo respirando entre os dois — com as
   bordas curvas e a barra de gestos do aparelho respeitadas por env(safe-area).

   O portão de entrada é `max-width: 760px` **ou** estar instalado na tela
   inicial: quem abriu pelo ícone recebe a casca de app em qualquer tamanho.
   ========================================================================== */

/* Fora do celular a casca não existe — o painel de monitor segue intacto. */
.app-bar, .tabbar { display: none; }

@media (max-width: 760px), all and (display-mode: standalone) {

  :root {
    --app-bar-h: 52px;
    --tab-h: 58px;
    --safe-t: env(safe-area-inset-top, 0px);
    --safe-b: env(safe-area-inset-bottom, 0px);
    --safe-l: env(safe-area-inset-left, 0px);
    --safe-r: env(safe-area-inset-right, 0px);
  }

  /* O app é dono da tela: o cabeçalho e o rodapé do blog saem de cena, e com
     eles a rolagem elástica que faz um site parecer site. */
  body.app .site-head,
  body.app .site-foot,
  body.app .admin-nav,
  body.app .skip { display: none; }

  body.app {
    font-size: 16px;
    overscroll-behavior-y: none;
    -webkit-tap-highlight-color: transparent;
  }

  /* O respiro só existe onde a casca existe: a tela de login não tem abas. */
  body.app:has(.tabbar) {
    padding-top: calc(var(--app-bar-h) + var(--safe-t));
    padding-bottom: calc(var(--tab-h) + var(--safe-b) + 8px);
  }

  body.app .wrap,
  body.app .wrap-viz,
  body.app .wrap-narrow { width: calc(100% - 32px); }

  /* ── Barra de título ──────────────────────────────────────────────────
     Translúcida sobre o fundo, porque no iPhone ela vive debaixo do relógio:
     o `black-translucent` deixa o conteúdo subir até o topo e é este bloco
     que devolve a margem segura. */
  .app-bar {
    position: fixed; inset: 0 0 auto 0; z-index: 60;
    display: flex; align-items: center; gap: 10px;
    height: calc(var(--app-bar-h) + var(--safe-t));
    padding: var(--safe-t) calc(12px + var(--safe-r)) 0 calc(14px + var(--safe-l));
    background: color-mix(in oklab, var(--bg) 86%, transparent);
    backdrop-filter: saturate(160%) blur(16px);
    -webkit-backdrop-filter: saturate(160%) blur(16px);
    border-bottom: 1px solid var(--line);
  }
  .app-bar-mark { width: 24px; height: 24px; color: var(--text); flex: none; }
  .app-bar-mark svg { width: 100%; height: 100%; }
  .app-bar-title {
    flex: 1; min-width: 0; margin: 0;
    font-family: var(--font-display); font-size: 18px; font-weight: 600; letter-spacing: -.015em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .app-bar-btn {
    width: 38px; height: 38px; flex: none;
    display: grid; place-items: center; border-radius: 999px;
    background: none; border: 0; color: var(--muted); cursor: pointer;
    text-decoration: none; padding: 0;
  }
  .app-bar-btn svg { width: 20px; height: 20px; }
  .app-bar-btn:active { background: var(--surface-2); color: var(--accent); }

  /* ── Barra de abas ────────────────────────────────────────────────────
     Quatro destinos, sempre os mesmos, sempre no mesmo lugar: a mão aprende
     o caminho e para de procurar. Alvo de 48px de altura, o mínimo do dedo. */
  .tabbar {
    position: fixed; inset: auto 0 0 0; z-index: 60;
    display: grid; grid-template-columns: repeat(4, 1fr);
    padding: 0 var(--safe-r) var(--safe-b) var(--safe-l);
    background: color-mix(in oklab, var(--bg) 88%, transparent);
    backdrop-filter: saturate(160%) blur(16px);
    -webkit-backdrop-filter: saturate(160%) blur(16px);
    border-top: 1px solid var(--line);
  }
  .tabbar a {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    height: var(--tab-h); text-decoration: none; color: var(--muted);
    font-size: 10.5px; font-weight: 500; letter-spacing: .01em;
    position: relative;
    transition: color var(--dur) var(--ease);
  }
  .tabbar a svg { width: 22px; height: 22px; }
  .tabbar a.is-on { color: var(--accent); }
  /* A aba corrente é marcada por cor **e** por um traço: cor sozinha não conta. */
  .tabbar a.is-on::before {
    content: ''; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
    width: 26px; height: 2.5px; border-radius: 0 0 3px 3px; background: var(--accent);
  }
  .tabbar a:active { color: var(--text); }

  /* ── Cabeçalho da tela ────────────────────────────────────────────────
     O nome da tela já está na barra de título e repetido na aba acesa. Dizê-lo
     uma terceira vez custaria noventa pixels da primeira dobra — que é onde o
     número da audiência precisa estar. Fica só a linha que situa o dado. */
  body.app .admin { padding-bottom: 24px; }
  body.app .admin-head {
    margin: 12px 0 14px; gap: 10px;
    align-items: flex-start; flex-direction: column;
  }
  body.app .admin-head .eyebrow { display: none; }
  /* O h1 continua na página para quem lê por leitor de tela — só sai da vista. */
  body.app .admin-head h1 {
    position: absolute; width: 1px; height: 1px; margin: -1px;
    padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  body.app .admin-head p.muted { font-size: 13px; line-height: 1.5; margin: 0; }
  body.app .admin-head .btn,
  body.app .head-actions { width: 100%; }
  body.app .admin-head .btn { justify-content: center; width: 100%; }

  /* O azul da marca é claro no tema escuro: texto branco em cima dele fica em
     2:1. Dentro do app o botão principal inverte a tinta e volta a se ler. */
  [data-theme='dark'] body.app .btn { color: #0b0d10; }
  [data-theme='dark'] body.app .btn.ghost { color: var(--text); }

  /* ══ Audiência no bolso ═════════════════════════════════════════════════
     O painel foi desenhado para um monitor de 29". No celular ele não encolhe:
     ele se reordena. A ordem aqui responde à pergunta de quem confere o blog
     na fila do café — quanta gente veio, subiu ou desceu, e lendo o quê. */

  body.app .viz { display: flex; flex-direction: column; gap: 0; }
  /* Os arranjos de coluna desaparecem e devolvem os cartões à pilha, para que
     a ordem seja decidida bloco a bloco, e não pelo grupo em que ele caiu. */
  body.app .viz-top,
  body.app .viz-duo,
  body.app .viz-grid-3,
  body.app .viz-grid-4 { display: contents; }
  body.app .viz > section,
  body.app .viz > div > section,
  body.app .viz > nav,
  body.app .viz > p { order: var(--m, 50); }

  body.app .viz-card { padding: 16px; margin: 0 0 14px; border-radius: var(--r-md); }
  body.app .viz-card-head { margin-bottom: 14px; }
  body.app .viz-card-head h2 { font-size: 18px; }
  body.app .viz-card-head p { font-size: 12.5px; line-height: 1.45; }

  /* Filtros: uma fita rolável que gruda embaixo da barra de título. Nenhum
     período fica escondido atrás de um menu — todos ficam a um polegar. */
  body.app .viz-filters {
    position: sticky; top: calc(var(--app-bar-h) + var(--safe-t)); z-index: 40;
    display: flex; flex-wrap: nowrap; overflow-x: auto; overscroll-behavior-x: contain;
    scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
    margin: 0 -16px 14px; padding: 8px 16px;
    background: color-mix(in oklab, var(--bg) 90%, transparent);
    backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
    border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
    scrollbar-width: none;
  }
  body.app .viz-filters::-webkit-scrollbar { display: none; }
  body.app .viz-filters a {
    flex: none; scroll-snap-align: center;
    padding: 9px 16px; font-size: 14px; border: 1px solid var(--line);
    background: var(--surface);
  }
  body.app .viz-filters a.is-on { color: #fff; background: var(--accent); border-color: var(--accent); }
  [data-theme='dark'] body.app .viz-filters a.is-on { color: #0b0d10; }

  /* Ao vivo sobe para o topo do painel: é o dado mais perecível da tela. */
  body.app .live {
    order: 2; width: 100%; margin: 0 0 12px;
    padding: 11px 14px; border-radius: 999px;
    background: var(--surface); border: 1px solid var(--line); font-size: 14px;
  }

  /* O número que lidera ocupa a largura toda; o fio de tendência corre embaixo. */
  body.app .viz-hero { flex-direction: column; align-items: stretch; gap: 12px; }
  body.app .hero-figure { font-size: 52px; margin: 2px 0 8px; }
  body.app .viz-spark { width: 100%; height: 46px; }

  /* Quadros-resumo em dois por linha: cinco números legíveis sem rolar muito. */
  body.app .tile-row { grid-template-columns: 1fr 1fr; gap: 10px; margin: 0 0 14px; }
  body.app .tile { padding: 13px 14px; }
  body.app .tile-label { font-size: 12px; line-height: 1.35; }
  body.app .tile-value { font-size: 25px; margin: 4px 0 6px; }
  body.app .delta { font-size: 11.5px; line-height: 1.35; }
  body.app .tile-note { font-size: 11px; line-height: 1.35; }
  /* A rolagem média fecha a fileira sozinha, e ganha a linha inteira. */
  body.app .tile-row .tile:nth-child(5) { grid-column: 1 / -1; }

  /* ── Figuras ──────────────────────────────────────────────────────────
     O desenho já nasceu do tamanho do aparelho (o servidor conhece a largura
     da tela), então rótulo de 11px é 11px de verdade — nada de texto virando
     risco por causa de um viewBox de monitor espremido em 390 pixels. */
  body.app .viz-figure svg { touch-action: pan-y; }

  body.app .viz-bars { gap: 14px; }
  /* Numa faixa de 326px, um título de matéria cortado na primeira linha não diz
     qual matéria é. Aqui ele ganha duas linhas e só então reticências — e o
     número sobe para a primeira linha, alinhado com o começo do título. */
  body.app .viz-bar-head { align-items: flex-start; gap: 10px; }
  body.app .viz-bar-name {
    font-size: 14px; line-height: 1.35;
    white-space: normal; overflow-wrap: anywhere;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  }
  body.app .viz-bar-val { font-size: 14px; line-height: 1.35; }
  body.app .viz-bar-sub { font-size: 11.5px; line-height: 1.4; }
  body.app .viz-bar-track { height: 8px; }

  body.app .viz-stack { height: 26px; }
  body.app .viz-legend { gap: 6px 16px; font-size: 12.5px; margin-top: 12px; }

  /* Mapa de calor: sete linhas por vinte e quatro colunas cabem num iPhone se
     a régua da esquerda encolher e o vão entre células virar um fio. */
  body.app .viz-heat-grid { grid-template-columns: 22px repeat(24, minmax(0, 1fr)); gap: 1.5px; }
  body.app .viz-heat-day { font-size: 9.5px; padding-right: 4px; }
  body.app .viz-heat-hour { font-size: 8.5px; }
  body.app .viz-cell { border-radius: 2px; }
  body.app .viz-heat-scale { font-size: 10.5px; gap: 3px; margin-top: 10px; }
  body.app .viz-heat-scale i { width: 11px; height: 11px; }

  body.app .viz-cols { height: 120px; gap: 1.5px; }
  body.app .viz-col small { font-size: 8.5px; }

  /* A tabela gêmea continua a um toque de distância, rolando na horizontal. */
  body.app .viz-table summary { font-size: 12.5px; padding: 8px 0; }
  body.app .admin-table { min-width: 560px; }
  body.app .admin-table th { padding: 10px 12px; font-size: 10px; }
  body.app .admin-table td { padding: 10px 12px; font-size: 13px; }

  /* O balão de leitura vira uma tarja larga no rodapé útil: no toque, o dedo
     cobre o ponto tocado, então o valor aparece longe dele. */
  body.app .viz-tip {
    left: 16px !important; right: 16px;
    max-width: none; width: auto;
    top: auto !important; bottom: calc(var(--tab-h) + var(--safe-b) + 14px);
    font-size: 13.5px; padding: 11px 14px; text-align: center;
    box-shadow: var(--shadow);
  }

  /* ── Matérias ─────────────────────────────────────────────────────────
     A tabela de quatro colunas vira uma pilha de cartões: no celular o dedo
     lê de cima para baixo, nunca de esquerda para direita. */
  body.app .posts-scroll { border: 0; background: none; border-radius: 0; overflow: visible; }
  body.app .posts-table { display: block; min-width: 0; }
  body.app .posts-table thead { display: none; }
  body.app .posts-table tbody { display: block; }
  body.app .posts-table tr {
    display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r-md); padding: 12px; margin-bottom: 12px;
  }
  body.app .posts-table tr:hover td { background: none; }
  body.app .posts-table td { display: block; border: 0; padding: 0; }
  /* Título ocupa a linha inteira; estado e data dividem a segunda; as ações
     fecham o cartão com alvos de dedo. */
  body.app .posts-table td:nth-child(1),
  body.app .posts-table td:nth-child(4) { flex: 1 0 100%; }
  body.app .posts-table td:nth-child(2),
  body.app .posts-table td:nth-child(3) { flex: none; }
  body.app .posts-table .thumb { width: 74px; height: 46px; }
  body.app .posts-table .tcell { gap: 11px; align-items: flex-start; }
  body.app .posts-table .tcell strong { font-size: 15.5px; line-height: 1.3; }
  /* O endereço da matéria não é acionável no celular e custava duas linhas. */
  body.app .posts-table .tcell span.mono { display: none; }
  body.app .posts-table .row-actions { gap: 8px; }
  body.app .posts-table .row-actions .mini { padding: 9px 15px; font-size: 13px; }

  /* ── Puxar para atualizar ─────────────────────────────────────────────
     Um arco que se completa conforme o dedo desce; cheio, ele solta e o
     painel volta do servidor. */
  .pull-cue {
    position: fixed; z-index: 55; left: 50%; pointer-events: none;
    top: calc(var(--app-bar-h) + var(--safe-t) + 4px);
    transform: translate(-50%, calc(-14px + var(--pull, 0) * 26px));
    opacity: var(--pull, 0);
    transition: opacity 160ms var(--ease), transform 160ms var(--ease);
  }
  .pull-cue span {
    display: block; width: 22px; height: 22px; border-radius: 50%;
    border: 2px solid var(--line); border-top-color: var(--accent);
    transform: rotate(calc(var(--pull, 0) * 300deg));
  }
  .pull-cue.is-armed span { border-color: var(--accent); }
  .pull-cue.is-loading span { animation: pull-spin .7s linear infinite; }
  @keyframes pull-spin { to { transform: rotate(360deg); } }

  body.app .admin-pager { margin-top: 18px; justify-content: flex-start; }

  /* ── Escrever e ajustar ───────────────────────────────────────────────
     Campo de 16px porque abaixo disso o iPhone dá zoom sozinho ao focar. */
  body.app .admin input, body.app .admin textarea, body.app .admin select,
  body.app .login-card input { font-size: 16px; padding: 12px 14px; }
  body.app .admin fieldset { padding: 16px 16px 2px; margin-bottom: 16px; border-radius: var(--r-md); }
  body.app .editor { gap: 18px; }
  /* O corpo da matéria pede espaço, e a tela do celular é rolagem: meia tela de
     campo mantém o botão de publicar a um polegar de distância. */
  body.app .admin textarea.mono { height: 46svh; min-height: 260px; }
  body.app .admin .btn { width: 100%; justify-content: center; }
  body.app .settings, body.app .preview-sig { max-width: none; }

  /* ── Entrar ───────────────────────────────────────────────────────────── */
  body.app .login-wrap { min-height: 100svh; padding: calc(var(--safe-t) + 28px) 20px calc(var(--safe-b) + 28px); }
  body.app .login-card { padding: 30px 24px 24px; }
}

/* Instalado na tela inicial: sem barra de endereço, o texto selecionável e o
   arrastar de link roubam a sensação de app. A leitura continua livre no
   conteúdo das matérias e nos campos de escrita. */
@media all and (display-mode: standalone) {
  body.app { -webkit-user-select: none; user-select: none; }
  body.app input, body.app textarea, body.app .prose, body.app .viz-table { -webkit-user-select: text; user-select: text; }
  body.app a { -webkit-touch-callout: none; }
}
