/* =====================================================================
 *  DASHBOARD FFS · telemóvel
 *
 *  Carrega DEPOIS do ffs.css e só mexe em ecrãs estreitos. O desktop não
 *  passa por aqui: tudo o que está neste ficheiro vive dentro de uma
 *  @media, e nada acrescenta regras novas ao caminho largo.
 *
 *  Ficheiro à parte, e não mais 300 linhas no fim do ffs.css, por duas
 *  razões: dá para ler o que foi feito para o telemóvel sem atravessar
 *  98KB de folha, e dá para desligar o comportamento todo tirando uma
 *  linha do index.html se alguma coisa correr mal em produção.
 *
 *  Cortes (baseados no conteúdo, não em modelos de telemóvel):
 *    ≤ 900px  — deixa de haver espaço para duas colunas lado a lado
 *    ≤ 640px  — telemóvel a sério: uma coluna, tabela em cartões
 *    ≤ 380px  — os pequenos (iPhone SE e afins)
 *
 *  Medir com:  node frontend/testes/banco-mobile.js
 *  Ver com:    node frontend/testes/banco-mobile-fatias.js [vista]
 * ===================================================================== */


/* =====================================================================
 *  BLOCO 1 · a página deixa de fugir para o lado
 *
 *  O sintoma era um documento de 519px num ecrã de 390px: tudo o que se
 *  lia estava torto porque a página inteira andava para trás e para a
 *  frente. As três origens, medidas (ver a sonda do banco-mobile.js):
 *
 *    .ffs-usage-col   371px encostados à direita de uma linha que já não
 *                     tinha espaço — `flex-shrink:0` a segurar.
 *    .ffs-kpi         duas colunas de 481px cada dentro de 318px.
 *    --pad            36px de cada lado comem 18% de um ecrã de 390px.
 *
 *  A gaveta do detalhe não fazia a barra de scroll (é `position:fixed`),
 *  mas era o pior de todos na prática: 94vw encostados à direita numa
 *  página que andava para o lado deixavam o botão de fechar fora do
 *  ecrã. Abria-se um produto e ficava-se lá dentro.
 * ===================================================================== */

@media (max-width: 900px){

  /* ---- A moldura ---------------------------------------------------- */
  /* Nada, em ecrã estreito, tem licença para empurrar a página para fora.
     Isto é a rede de segurança; as regras abaixo tratam de cada caso à
     nascença para que a rede não precise de apanhar nada. */
  html{overflow-x:hidden}
  body{overflow-x:hidden;width:100%}

  :root{ --pad:20px }

  /* ---- Barras de uso (Claude / Codex / DataForSEO) ------------------ */
  /* A linha do "quem" era: avatar · nome · [as três caixas encostadas à
     direita]. Em ecrã largo é uma linha; aqui é uma coluna, e as caixas
     ocupam a largura toda em vez de irem à procura dela para lá da margem. */
  .ffs-intro .who{flex-wrap:wrap}
  .ffs-usage-col{margin-left:0;width:100%;flex-shrink:1;min-width:0}
  .ffs-usage{flex-wrap:wrap;gap:10px 14px;min-width:0}
  .ffs-usage .u{min-width:0}
  /* A barrinha de progresso tinha 66px fixos numa grelha de três colunas
     que já não cabia. Passa a levar o espaço que sobra. */
  .ffs-usage .u{grid-template-columns:auto minmax(40px,1fr) auto;flex:1 1 140px}
  .ffs-usage .u .ur{overflow-wrap:anywhere}

  /* ---- KPIs --------------------------------------------------------- */
  /* O ffs.css já empilhava o .ffs-kpi aos 820px, mas as células lá dentro
     continuavam a ser uma grelha 2x2 desenhada para meia largura de
     desktop — e o número grande (104px) sozinho já não cabia. */
  .ffs-kpi{grid-template-columns:1fr}
  .ffs-kpi .big{border-right:none;border-bottom:1px solid var(--paper-3);padding:22px 20px;min-width:0}
  .ffs-kpi .big .vrow{gap:14px;flex-wrap:wrap;margin:10px 0 16px}
  /* Os três clamp() desta folha são os únicos tamanhos que não saem da escala,
     e é de propósito: o número grande e o h1 têm de encolher com o ecrã, senão
     um iPhone SE parte a palavra ao meio. As pontas são valores da escala; o
     que anda entre elas é o vw. */
  .ffs-kpi .big .v{font-size:clamp(34px, 10vw, 48px);letter-spacing:-3px}
  .ffs-kpi .big .v sup{font-size:clamp(11px, 3vw, 15px);margin-left:2px;letter-spacing:0}
  .ffs-kpi .big .vmeta b{font-size:var(--t-h1)}
  .ffs-kpi .big .legend{gap:14px;flex-wrap:wrap}
  .ffs-kpi .cells{grid-template-columns:1fr 1fr}
  .ffs-kpi .cell{padding:16px 18px;min-width:0}
  .ffs-kpi .cell .vv{font-size:var(--t-d3)}

  /* ---- Gaveta do detalhe do produto --------------------------------- */
  /* Passa a folha inteira. `94vw` deixava uma nesga da página por baixo
     que não servia para nada — ninguém acerta em 6% de ecrã para fechar,
     e o que se ganhava em contexto perdia-se em 24px de gaveta cortada.
     `100dvw`/`100dvh` e não `vw`/`vh`: no Safari do iPhone a barra de
     endereço encolhe e cresce, e com `vh` a gaveta fica com o fundo (e o
     que lá está) escondido por baixo dela. */
  .ffs-drawer{width:100%;max-width:100%;border-left:none;box-shadow:none}
  .ffs-drawer,
  .ffs-drawer-scrim{height:100dvh}

  /* O cabeçalho da gaveta é a única forma de sair dela: fica preso ao
     topo, sempre visível, por mais que se desça no corpo. */
  /* O `padding-right` é o espaço reservado ao × que está absoluto no canto:
     sem ele o título passava-lhe por baixo. */
  .ffs-dh{position:sticky;top:0;z-index:2;padding:16px 64px 12px 18px}
  .ffs-dh h3{font-size:var(--t-b1)}
  .ffs-dh .top{gap:11px}
  .ffs-dh .meta{margin-top:11px;gap:6px}
  .ffs-dh .dh-actions{margin-top:12px;padding-top:12px;flex-wrap:wrap;justify-content:flex-start}
  /* O × deixa de ser o último de três botões que já não cabiam na linha:
     vai para o canto, onde o polegar o procura, e os outros dois ficam com
     a linha toda para eles. */
  .ffs-dh .dh-actions .x{position:absolute;top:12px;right:14px;margin-left:0;
    width:44px;height:44px;font-size:var(--t-h1)}
  .ffs-dh .rf{height:44px;flex:1 1 auto;justify-content:center}
  .ffs-dbody{padding:18px 18px 40px;overscroll-behavior:contain}

  /* ---- Sobreposições ------------------------------------------------ */
  /* Todas nasceram a assumir um rato e uma janela larga. */
  .oauth-card,.oauth-card.wide{width:min(100%, calc(100vw - 24px));max-height:88dvh;overflow-y:auto}
  .ffs-lightbox img{max-width:94vw;max-height:80dvh}
  .ffs-toast{left:12px;right:12px;bottom:16px;transform:translateY(90px);
    max-width:none;justify-content:center;text-align:center}
  .ffs-toast.show{transform:translateY(0)}
}

@media (max-width: 640px){
  :root{ --pad:16px }

  /* Numa coluna as duas células por linha ficam com 150px cada e o número
     de 30px encosta-se às letras da etiqueta. Uma por linha respira. */
  .ffs-kpi .cells{grid-template-columns:1fr}
  .ffs-kpi .cell{border-right:none}
  .ffs-kpi .cell:nth-child(n+3){border-bottom:1px solid var(--paper-3)}
  .ffs-kpi .cell:last-child{border-bottom:none}
  .ffs-kpi .big .estados{grid-template-columns:1fr}
  .ffs-kpi .big .estados .est+.est{padding:14px 0 0;border-left:none;
    border-top:1px solid var(--paper-3);margin-top:14px}
}

@media (max-width: 380px){
  :root{ --pad:13px }
  .ffs-kpi .big .v{font-size:clamp(30px, 9.5vw, 40px)}
}


/* =====================================================================
 *  BLOCO 2 · o cabeçalho deixa de ser o ecrã todo
 *
 *  Antes: 620px de preto — logo, um título de 46px em quatro linhas, um
 *  parágrafo de descrição e três caixas de telemetria — antes de se ver
 *  um único número. Num ecrã de 844px isso é três quartos da primeira
 *  vista gastos a dizer o que a aplicação é a quem já a abriu.
 *
 *  O que sai e porquê:
 *    · a descrição — explica o produto a quem entra pela primeira vez,
 *      e quem abre isto no telemóvel é quem já cá anda todos os dias.
 *      Fica no desktop, onde não custa nada.
 *    · a altura das caixas de uso — o conteúdo fica todo, encolhe a
 *      moldura. São números de consumo, não são o trabalho.
 *
 *  Os separadores passam de dois andares (número por cima, nome por
 *  baixo) para uma linha só, e a barra ganha scroll lateral próprio: as
 *  Definições têm quatro e não há ecrã de telemóvel que os ponha lado a
 *  lado sem os espremer a ponto de não se acertar em nenhum.
 * ===================================================================== */

@media (max-width: 900px){

  /* ---- Intro -------------------------------------------------------- */
  .ffs-intro{padding:18px 0 22px}
  .ffs-intro .rp-home{margin-bottom:14px}
  .ffs-intro .rp-logo{height:17px}
  .ffs-intro .eyebrow{margin-bottom:10px;gap:8px}
  .ffs-intro .eyebrow .txt{font-size:var(--t-m2);letter-spacing:1.8px}
  .ffs-intro h1{font-size:clamp(17px, 5vw, 21px);letter-spacing:-.8px;max-width:none}
  .ffs-intro .sub{font-size:var(--t-b2);margin-top:12px;line-height:1.5}
  .ffs-intro .who{margin-top:16px;padding-top:14px;gap:10px}
  .ffs-intro .who .av{width:34px;height:34px;border-radius:8px}
  .ffs-intro .who .av img{width:20px;height:20px}
  .ffs-intro .who .nm{font-size:var(--t-b2)}

  /* Caixas de uso: mesma informação, metade da altura. */
  .ffs-usage-col{gap:6px;margin-top:2px}
  .ffs-usage{padding:7px 11px;border-radius:8px;gap:7px 13px}
  .ffs-usage .u .ut{font-size:var(--t-m2);letter-spacing:1px}
  .ffs-usage .u .up{font-size:var(--t-m1)}
  .ffs-usage .u .ur{font-size:var(--t-m2);margin-top:2px}
  .ffs-usage .cl{width:16px;height:16px}

  /* ---- Separadores -------------------------------------------------- */
  /* Uma linha em vez de dois andares, e a barra rola de lado quando os
     separadores não cabem — com `flex-shrink:0` neles, senão o flex
     espremia-os todos em vez de deixar rolar. */
  .ffs-tabs-inner{overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch}
  .ffs-tabs-inner::-webkit-scrollbar{display:none}
  .ffs-tabs-btns{flex-shrink:0}
  .ffs-tab{min-width:0;flex-shrink:0;padding:11px 15px;display:flex;align-items:center;gap:8px;
    white-space:nowrap}
  .ffs-tab .n{font-size:var(--t-m2);letter-spacing:1.1px}
  .ffs-tab .t{margin-top:0;font-size:var(--t-b2)}
  /* O rótulo da esquerda ("DASHBOARD", "DEFINIÇÕES") repete o que o menu
     do hamburger já diz, e é o que empurra os separadores para fora. */
  .ffs-tabs .lbl{display:none}
  .ffs-tabs .count{padding-left:12px}

  /* ---- Corpo -------------------------------------------------------- */
  .ffs-main{padding:22px var(--pad) 60px}
  .section{padding:24px 0}
  .section-h h2{font-size:var(--t-h1)}
  .section-sub{font-size:var(--t-b2);margin-bottom:18px}
  .ffs-vhead h2{font-size:var(--t-h1)}
}

@media (max-width: 640px){
  /* Quem abre isto no telemóvel já sabe o que a aplicação faz. */
  .ffs-intro .sub{display:none}
  .ffs-intro .who{margin-top:14px}
}


/* =====================================================================
 *  BLOCO 3 · a tabela de produtos passa a cartões
 *
 *  Nove colunas em 390px davam três visíveis — id, imagem, título — e
 *  seis fora do ecrã. As seis que ficavam de fora incluíam o Status, que
 *  é a razão de existir desta tabela: quem abre isto quer saber o que
 *  falhou, não quer confirmar nomes de produtos. E cada linha ficava com
 *  ~280px de altura porque o título encolhia para 6 caracteres por linha:
 *  50 produtos davam 11.900px de página.
 *
 *  Aqui a mesma marcação — sem tocar no ffs-app.js, que continua a
 *  desenhar `<tr>` e `<td>` — passa a uma grelha por linha. O que ganha
 *  linhas próprias é o que se lê primeiro: título, depois status e data,
 *  depois a proveniência.
 *
 *  Só o `#ffs-table`. As outras tabelas com `.ffs-log` (utilizadores,
 *  sites, tags, syslog) têm colunas diferentes e vão no Bloco 5.
 * ===================================================================== */

@media (max-width: 640px){

  /* A moldura da tabela deixa de ser uma caixa com scroll e passa a ser
     apenas o espaço onde os cartões vivem. */
  #ffs-table{min-width:0;table-layout:auto}
  .ffs-tablewrap:has(#ffs-table){border:none;background:none;overflow-x:visible}

  #ffs-table,
  #ffs-table tbody{display:block;width:100%}

  /* O cabeçalho perde as etiquetas das colunas — num cartão cada valor
     diz-se sozinho — mas NÃO desaparece: leva lá dentro o "escolher
     todos" e o botão de ordenar por data, que não existem em mais lado
     nenhum do ecrã. */
  #ffs-table thead{display:block}
  #ffs-table thead tr{display:flex;align-items:center;gap:10px;
    padding:9px 12px;border:1.5px solid var(--ink);border-radius:8px;
    background:var(--paper-2);margin-bottom:10px}
  #ffs-table thead th{display:none}
  #ffs-table thead th.th-check,
  #ffs-table thead th.th-time{display:flex;align-items:center;gap:6px;
    width:auto;padding:0;background:none;border:none;position:static;text-align:left}
  #ffs-table thead th.th-time{margin-left:auto;min-height:26px}

  /* ---- O cartão ----------------------------------------------------- */
  #ffs-table tbody tr{
    display:grid;
    grid-template-columns:54px minmax(0,1fr) auto;
    /* A coleção e o fornecedor partilham a última linha. Chegaram a ter uma
       linha cada; com 50 produtos por página isso eram 1500px de scroll a
       mais só para separar duas etiquetas que se lêem bem lado a lado. */
    grid-template-areas:
      "thumb    titulo   escolher"
      "thumb    ident    ident"
      "estado   estado   data"
      "coleccao coleccao marca";
    column-gap:12px;
    align-items:center;
    padding:11px 13px;
    margin-bottom:9px;
    border:1.5px solid var(--paper-3);
    border-radius:10px;
    background:#fff;
  }
  #ffs-table tbody tr:last-child{border-bottom:1.5px solid var(--paper-3)}
  /* O toque não tem `:hover`; o que marca a linha é estar seleccionada. */
  #ffs-table tbody tr:hover{background:#fff}
  #ffs-table tbody tr.sel{background:var(--accent-soft);border-color:var(--accent-ink)}

  /* `width:auto` é obrigatório, não é arrumação: as colunas da tabela têm
     larguras em percentagem (`.c-status{width:12%}`, `.c-coll{width:15%}`…)
     que continuam a valer depois de o `td` passar a caixa de grelha — e um
     `width:12%` numa célula de grelha ignora a área que lhe foi dada e
     encolhe para 43px. É por isso que "PUBLICADO" saía escrito ao alto. */
  #ffs-table tbody td{display:block;border:none;padding:0;
    width:auto;min-width:0;overflow-wrap:anywhere}

  #ffs-table tbody td.c-thumb   {grid-area:thumb;  align-self:start}
  #ffs-table tbody td.c-title   {grid-area:titulo; font-size:var(--t-b2);line-height:1.3}
  #ffs-table tbody td.c-check   {grid-area:escolher;align-self:start;width:auto;
    display:flex;align-items:center;justify-content:flex-end;min-height:26px}
  /* O id não parte: 14 dígitos partidos ao meio não servem para nada, e o
     `overflow-wrap:anywhere` da regra acima parte-os todos. */
  #ffs-table tbody td.c-id      {grid-area:ident;  align-self:start;margin-top:2px;
    font-size:var(--t-m2);white-space:nowrap;overflow-wrap:normal;overflow:visible;text-overflow:clip}
  /* A data desceu para a linha do estado. Estava ao lado do id, e um id de
     catorze dígitos com o M à frente não cabia na coluna que lhe tocava —
     como o id não pode partir nem ser cortado (um id cortado não serve para
     nada), o que ele fazia era passar POR CIMA da data. Duas coisas no mesmo
     sítio: cabia tudo na página, nenhuma sonda de transbordo acusava, e o que
     se via era o número e a data encavalitados.
     Na linha do estado há espaço a sobrar — era onde estava a setinha. */
  #ffs-table tbody td.c-time    {grid-area:data;   align-self:center;
    text-align:right;white-space:nowrap;padding-left:8px}
  /* A setinha era decoração: o cartão inteiro já abre o produto. Sai, e o
     lugar dela fica para a data. */
  #ffs-table tbody td.c-go{display:none}
  #ffs-table tbody td.c-status  {grid-area:estado; margin-top:9px}
  #ffs-table tbody td.c-coll    {grid-area:coleccao;margin-top:7px;font-size:var(--t-m1);
    align-self:center;padding-right:10px}
  #ffs-table tbody td.c-vendor  {grid-area:marca;  margin-top:7px;
    align-self:center;text-align:right}


  /* O handle por baixo do título: fica, porque é por ele que se procura,
     mas numa linha só — três linhas de handle empurravam o status para
     fora do primeiro olhar. */
  #ffs-table tbody td.c-title .h{white-space:nowrap;overflow:hidden;
    text-overflow:ellipsis;overflow-wrap:normal;font-size:var(--t-m2)}

  #ffs-table .c-thumb-box{width:54px;height:54px}
  /* O `overflow-wrap:anywhere` que a célula leva (para os handles compridos
     não esticarem o cartão) é herdado por este crachá — e a 8,5px nunca
     chegava a disparar, porque "SEM FOTO" cabia em duas linhas. Com o corpo
     no chão da escala passa a bater no `max-width` da miniatura, e o
     `anywhere` estilhaça a palavra: SE / M / FO / TO.
     Aqui só se quebra no espaço, que é o que o desenho quer — "SEM" por cima
     de "FOTO". */
  #ffs-table .c-thumb-box .sem-img{overflow-wrap:normal;word-break:keep-all}
  /* O estado e a reserva ("sem imagem", "cofre por confirmar") são dois
     crachás pequenos. Na tabela vinham empilhados, porque a coluna tinha
     12% de largura; aqui têm a linha toda e cabem lado a lado — 28px por
     cartão, mil e quatrocentos numa página de cinquenta. */
  #ffs-table tbody td.c-status{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
  #ffs-table tbody td.c-status .ffs-st{display:inline-flex}
  #ffs-table tbody td.c-status .rbadge{display:inline-block;margin-top:0}
  /* Em bloco, não em linha. Como inline-block ficava na última linha das
     coleções — e sendo mais alto do que a entrelinha, era desenhado POR CIMA
     da linha de cima: "Parafarmácia+2 categorias" sobrepostos. */
  #ffs-table tbody td.c-coll .pbadge{display:block;width:fit-content;margin-top:5px}

  /* Alvo de toque: a caixinha de 15px do desktop não se acerta com o
     polegar. A caixa cresce à volta dela sem a fazer crescer a ela. */
  #ffs-table .row-check,
  #ffs-table #ffs-check-all{width:20px;height:20px}

  /* Sem resultados: o `<td colspan="9">` deixa de ter colunas para
     atravessar, e sem isto encolhia para a primeira coluna da grelha. */
  #ffs-table tbody tr:has(td[colspan]){display:block;padding:0;border:none;background:none}
  #ffs-table tbody td[colspan]{grid-column:1 / -1}
  #ffs-table .ffs-empty{padding:36px 18px;border:1.5px dashed var(--paper-3);border-radius:10px;background:#fff}

  /* Rodapé e paginação */
  .ffs-tfoot{font-size:var(--t-m2);justify-content:center;text-align:center}
  .ffs-pager{gap:10px;flex-wrap:wrap}
  .pg-nav{padding:11px 14px}
}


/* =====================================================================
 *  BLOCO 4 · dá para acertar com o polegar
 *
 *  Duas coisas, e as duas são do mesmo sítio: isto foi desenhado para um
 *  rato, que acerta num alvo de 15px, e para um ecrã que não faz zoom
 *  sozinho.
 *
 *  1. Alvos de toque. A régra são 44x44 (Apple e WCAG 2.5.5). O banco
 *     contava 20 tipos de alvo abaixo disso em cada ecrã — as caixas de
 *     selecção da tabela a 20px, os botões do editor a 26px, "Guardar" e
 *     "Otimizar" a 28px de altura, os separadores de datas a 25px.
 *     Onde o desenho não aguenta o botão a crescer (o × de uma etiqueta,
 *     o link do product id), cresce a área à volta e não o desenho.
 *
 *  2. Zoom automático do iOS. O Safari do iPhone dá zoom à página quando
 *     se toca num campo com letra abaixo de 16px — e depois a página fica
 *     torta, encostada a um lado, e é preciso fechar o teclado e voltar a
 *     enquadrar. Vinte e um campos desta aplicação estavam nesse caso,
 *     do "Procurar produto" aos textos compridos da execução manual.
 *     Não há truque: ou têm 16px, ou o iOS dá zoom.
 * ===================================================================== */

@media (max-width: 900px){

  /* ---- Campos: 16px, senão o iOS dá zoom ---------------------------- */
  input[type="text"],input[type="url"],input[type="email"],input[type="password"],
  input[type="search"],input[type="number"],input:not([type]),
  textarea,select,
  .ffs-search input,.ffs-select,.cal-sel,.fld-select,.tb-sel,
  .ffs-runform input,.ffs-runform textarea,.ffs-runform select,
  .ffs-combo .combo-input,.cred-input,
  /* Este tem regra própria no ffs.css (`.ffs-pact .fonte-url`), que ganha às
     genéricas de cima por especificidade — vive dentro da gaveta e escapou
     à primeira passagem. */
  .ffs-pact .fonte-url{font-size:var(--t-campo)}

  /* Com 16px de letra, a altura vem quase toda de graça — falta a folga. */
  .ffs-select,.cal-sel,.fld-select,.tb-sel,.ffs-runform select{padding-top:11px;padding-bottom:11px;min-height:44px}
  .ffs-search{min-height:48px}
  .ffs-combo.filtro{flex:1 1 100%;max-width:none}
  .ffs-combo.filtro .combo-input{padding-top:12px;padding-bottom:12px}

  /* ---- Botões ------------------------------------------------------- */
  .ffs-btn{padding:12px 18px;min-height:44px;font-size:var(--t-m1)}
  .ffs-btn.sm{padding:10px 14px;min-height:42px;font-size:var(--t-m2)}
  .segbtn{padding:0 18px;min-height:44px}
  .datechip{padding:0 14px;min-height:44px}
  .datechip.sm{min-height:44px}
  .pg-nav{padding:13px 18px;min-height:44px}
  .ffs-hitem{padding:13px 14px;min-height:44px}
  .ffs-hamb{width:44px;height:44px}
  .ffs-tab{min-height:44px}
  .ffs-panel .ph .pm-sort{padding:12px 0;min-height:44px}

  /* Botões do editor de texto rico. 26px é metade do polegar; a esta
     largura de ecrã são nove numa linha e falha-se sempre o do lado. */
  .fld-tb{gap:6px;flex-wrap:wrap}
  .fld-tb button{width:40px;height:40px;border-radius:7px}
  .tb-sep{height:28px}

  /* O × de uma etiqueta não pode ter 44px — ficava maior do que a
     etiqueta. Cresce a área sensível com padding e mantém-se o desenho. */
  .chips-lista .chip{padding:7px 4px 7px 11px}
  .chips-lista .chip-x{padding:6px 8px;font-size:var(--t-b1);line-height:1}

  /* ---- Alvos dentro dos cartões ------------------------------------- */
  /* A caixa de selecção. Dar 44x44 à CÉLULA e deixar a caixa a 24px seria
     pior do que não fazer nada: só a caixa é que trava a propagação do
     clique (ver paintRows no ffs-app.js), portanto os 20px de folga à
     volta dela abririam o produto em vez de o marcarem — um alvo maior a
     fazer a coisa errada. Então é a caixa que passa a ter 44x44, com o
     desenho a 22px: área de toque inteira, aspecto igual.
     A caixa nativa não se redimensiona sem `appearance:none`, e com ela
     perde-se o visto — daí o SVG. */
  #ffs-table tbody td.c-check{min-height:44px}
  #ffs-table .row-check,
  #ffs-table #ffs-check-all{appearance:none;-webkit-appearance:none;
    width:44px;height:44px;margin:0;padding:0;border:none;background:none;
    display:grid;place-content:center;cursor:pointer}
  #ffs-table .row-check::before,
  #ffs-table #ffs-check-all::before{content:"";width:22px;height:22px;
    border:1.5px solid var(--muted-2);border-radius:5px;background:#fff;
    transition:background .12s,border-color .12s}
  #ffs-table .row-check:checked::before,
  #ffs-table #ffs-check-all:checked::before{background:var(--ink) no-repeat center;
    border-color:var(--ink);
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'><path d='M20 6 9 17l-5-5'/></svg>")}
  #ffs-table .row-check:focus-visible::before,
  #ffs-table #ffs-check-all:focus-visible::before{outline:2px solid var(--accent-ink);outline-offset:2px}
  #ffs-table thead th.th-time{padding:9px 0}
  /* O link do product id abre a loja e é o único ponto do cartão que NÃO
     abre o detalhe — falhá-lo dá o resultado errado, não dá resultado
     nenhum. Ganha altura sem empurrar nada: o cartão já tinha esta folga. */
  #ffs-table .c-id .pidlink{padding:8px 6px 8px 0;font-size:var(--t-m1)}
  #ffs-table tbody td.c-id{margin-top:0}

  /* ---- Texto pequeno demais ----------------------------------------- */
  /* Só o que carrega dados. Os crachás decorativos (o "sem foto" sobre a
     miniatura, os tipos de campo) ficam como estão — são etiquetas, não
     são para ler ao pormenor. */
  #ffs-table .c-time{font-size:var(--t-m1)}
  #ffs-table .c-tag{font-size:var(--t-m1)}
  #ffs-table .c-status .ffs-st{font-size:var(--t-m2)}
  .ffs-dh .pid .storelink{padding:6px 4px;display:inline-block}
  .ffs-src .nm{min-width:0}

  /* ---- Os que ficaram de fora da primeira passagem ------------------ */
  /* Cada um destes tem a sua regra própria no ffs.css, com uma classe que
     ganha ao `select`/`input` genéricos das regras acima. */
  .sort-select{font-size:var(--t-campo);padding:11px 26px 11px 6px;min-height:44px}
  .ffs-panel .pf .dchip{min-height:44px;padding:0 14px}
  /* Procurar dentro dos painéis de categoria/marca, e procurar no plano:
     inputs sem classe própria, herdados por descendência — as regras
     genéricas de `input` lá de cima não lhes chegam. */
  .ffs-panel .pf .dsearch input,
  .plano-scope .plano-search input{font-size:var(--t-campo);padding:11px 0}
  .ffs-panel .pf{flex-wrap:wrap;gap:10px}
  .plano-scope .cmt-input{font-size:var(--t-campo);height:46px}
  /* Botões só de texto, sem moldura, no cabeçalho do log de execução. */
  .rl-clear,.rl-abort{padding:14px 8px;font-size:var(--t-m2)}
  .rl-hd{gap:4px}
  /* O logo é o caminho de volta ao início. Tinha 17px de altura. */
  .ffs-intro .rp-home{padding:11px 0}
  /* Campos de texto do formulário de execução: com 16px de letra faltavam
     4px de altura para os 44. */
  .ffs-runform input,.ffs-runform .combo-input{padding-top:12px;padding-bottom:12px}
  .fld-tb button{width:44px;height:44px}
  .ffs-btn{min-height:46px}
  .ffs-btn.sm{min-height:44px}
  #ffs-table .c-id .pidlink{padding:12px 8px 12px 0}
  /* "Ver na loja" no cabeçalho da gaveta, e a via do URL na galeria de
     imagens: dois caminhos secundários com letra de 10-11px e nenhuma
     folga à volta. */
  .ffs-dh .pid .storelink{padding:10px 6px}
  .img-url-abrir{padding:12px 2px}
  .img-url-linha{gap:8px;flex-wrap:wrap}
  .img-url-linha input{font-size:var(--t-campo);padding:11px 10px;flex:1 1 100%}
  .img-url-ok{padding:12px 18px;min-height:44px;flex:1 1 100%}
  /* Filtros de lado no plano (Todos · RankPanda · Farmácia). */
  .plano-scope .fchip{padding:11px 15px;min-height:44px}
  .plano-scope .plano-search input{min-height:44px}
  #idea-input{min-height:44px;font-size:var(--t-campo)}
}


/* =====================================================================
 *  BLOCO 5 · Definições, Tasks e o interior da gaveta
 *
 *  Sobre as quatro tabelas secundárias (sites negativos, utilizadores,
 *  tags, log do sistema): NÃO passam a cartões, e é uma decisão, não um
 *  esquecimento. O `#ffs-table` pôde passar porque cada valor se explica
 *  sozinho — um nome de produto é um nome de produto, uma data é uma
 *  data. Aqui não: "aprendido", "2", "activo" só querem dizer alguma
 *  coisa por baixo do cabeçalho da coluna, e o ffs-app.js não escreve
 *  esse nome em lado nenhum na célula. Um cartão sem etiquetas seria uma
 *  lista de valores soltos — pior do que a tabela.
 *
 *  Ficam tabelas com scroll lateral próprio, que já tinham, mas agora
 *  com o scroll a VER-SE: uma sombra no bordo direito que desaparece
 *  quando se chega ao fim. São ecrãs que se consultam de vez em quando
 *  no telemóvel; o trabalho a sério é o registo de produtos, e esse tem
 *  cartões.
 * ===================================================================== */

@media (max-width: 900px){

  /* ---- Tabelas secundárias: o scroll lateral passa a ver-se ---------- */
  .ffs-tablewrap{position:relative;
    /* Duas camadas: o fundo branco preso a cada bordo e, por cima, uma
       sombra que só aparece quando há mais tabela para aquele lado. É o
       truque das duas `background-attachment` — o `local` anda com o
       conteúdo, o `scroll` fica parado, e um tapa o outro exactamente
       quando se chega ao fim. */
    background:
      linear-gradient(to right, #fff 30%, rgba(255,255,255,0)) left center / 24px 100% no-repeat local,
      linear-gradient(to left,  #fff 30%, rgba(255,255,255,0)) right center / 24px 100% no-repeat local,
      radial-gradient(farthest-side at 0 50%, rgba(12,12,12,.16), rgba(12,12,12,0)) left center / 12px 100% no-repeat scroll,
      radial-gradient(farthest-side at 100% 50%, rgba(12,12,12,.16), rgba(12,12,12,0)) right center / 12px 100% no-repeat scroll,
      #fff;
    -webkit-overflow-scrolling:touch;overscroll-behavior-x:contain}
  table.ffs-log tbody td{padding:12px 9px}
  table.ffs-log thead th{padding:12px 9px}

  /* ---- Credenciais -------------------------------------------------- */
  /* A linha era: ícone · nome de 180px fixos · campo elástico · estado.
     Em 390px o campo elástico ficava com 40px. Passa a duas linhas. */
  .ffs-cred-row{flex-wrap:wrap;gap:10px 12px;padding:14px 15px}
  .cred-name{width:auto;flex:1 1 auto;min-width:0}
  .cred-status{order:3}
  .cred-input-wrap{flex:1 1 100%;order:4}
  .cred-oauth{flex:1 1 100%;order:4;font-size:var(--t-m1);line-height:1.5}

  /* ---- Gaveta: o corpo ---------------------------------------------- */
  /* Os botões de cada campo (Otimizar · Guardar · Repor original) já
     quebravam de linha; o que faltava era largura suficiente para não
     ficarem três órfãos empilhados. */
  .ffs-pact{gap:8px}
  .ffs-pact .ffs-btn{flex:1 1 auto;justify-content:center;text-align:center}
  .ffs-pact .chars{flex:1 1 100%;margin-left:0;text-align:right}
  .ffs-fld{padding:16px 0}
  .img-gallery{grid-template-columns:repeat(auto-fill,minmax(90px,1fr))}
  /* Blocos de HTML e JSON gerados: não partem palavras e esticavam a
     gaveta para dentro do seu próprio scroll horizontal. */
  .ffs-fld .code,.ffs-fld pre{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .ffs-fld .render table{display:block;overflow-x:auto}

  /* ---- Tasks -------------------------------------------------------- */
  /* Os itens do plano são grelhas de colunas fixas somadas a mais do que
     390px (22+104+1fr+46+66 mais gaps). O que sai é a coluna do meio, que
     é a que já se percebe pelo contexto da linha de cima. */
  .plano-scope .tl-item{grid-template-columns:22px minmax(0,1fr) 46px;
    gap:0 10px;padding:12px 12px}
  .plano-scope .tl-client-item{grid-template-columns:14px minmax(0,1fr) 44px;
    gap:0 10px;padding:12px 14px}
  /* O histórico é uma linha do tempo: uma calha vertical à esquerda com o
     mês, e as tarefas à direita. Numa coluna só a calha deixa de ter lado
     — o mês ficava encostado à direita, com o traço da calha a separá-lo
     do nada. Passa a um cabeçalho horizontal, com o ponto à frente do mês
     em vez de suspenso sobre um traço que já não existe. */
  .plano-scope .tl-grp{grid-template-columns:1fr}
  .plano-scope .tl-when{text-align:left;border-right:none;padding:18px 0 8px;
    display:flex;align-items:center;gap:11px}
  .plano-scope .tl-node-big{position:static;top:auto;right:auto;
    box-shadow:0 0 0 3px var(--paper);flex-shrink:0}
  .plano-scope .tl-when-y{margin-top:0}
  .plano-scope .tl-grp-body{padding:0 0 22px}
  .plano-scope .tl-grp-sum{margin-left:0;justify-content:flex-start;flex:1 1 100%}
  .plano-scope .modal-body.two-col,
  .plano-scope .fld-row{grid-template-columns:1fr}

  /* A ficha de uma tarefa. O fundo tinha 48px de margem em cima e o cartão
     uma sombra sólida de 10px para a direita — num telemóvel isso é ecrã
     gasto a emoldurar. O rodapé (apagar · sincronizar · guardar) era uma
     linha só; aqui quebra, e o "Guardar" fica com a largura toda. */
  .plano-scope .modal-back{padding:14px 12px 24px}
  .plano-scope .modal{box-shadow:4px 4px 0 rgba(10,10,10,.18)}
  .plano-scope .modal-h{padding:16px 16px;align-items:flex-start}
  .plano-scope .modal-h h3{font-size:var(--t-b1)}
  .plano-scope .modal-h .x{width:44px;height:44px;font-size:var(--t-h1)}
  .plano-scope .modal-body,
  .plano-scope .modal-body.two-col{padding:18px 16px;gap:16px}
  .plano-scope .modal-foot{padding:14px 16px;flex-wrap:wrap;gap:10px}
  .plano-scope .modal-foot .grow{flex:1 1 100%;height:0}
  .plano-scope .modal-foot .plano-btn{min-height:44px}
  .plano-scope .cmt-list{max-height:none}

  /* Os botões de estado: cinco lado a lado, com `flex:1` mas cada um a
     precisar de ~97px para caber a palavra. Somados passam dos 358px que
     há, e o `overflow:hidden` da barra cortava o quinto ("Planeado") — o
     estado que se deixava de conseguir escolher era invisível, não estava
     desactivado. Dois por linha, com altura de dedo. */
  .plano-scope .segmented{flex-wrap:wrap}
  .plano-scope .segmented button{flex:1 1 45%;min-height:44px;
    border-bottom:1px solid var(--paper-3)}
  .plano-scope .cat-chip,
  .plano-scope .plano-btn{min-height:44px}
}

@media (max-width: 640px){
  /* Nas Definições, cada secção tem uma barra com a procura e um botão de
     acção ("+ Acrescentar site", "+ Convidar utilizador") empurrado para a
     direita por um `margin-left:auto` escrito à mão no elemento. A esta
     largura a barra já quebra de linha, e o que o `auto` faz é encostar o
     botão a um canto com o resto da linha vazia. Daí o `!important`: o
     estilo está no atributo do elemento, e nada sem ele lhe ganha. */
  .ffs-bar{gap:10px}
  .ffs-bar .ffs-search{flex:1 1 100%;min-width:0}
  .ffs-bar > .ffs-btn,
  .ffs-bar > .ffs-btn.sm{margin-left:0 !important;flex:1 1 100%;width:100%}
  .ffs-adminonly{margin-left:0 !important;flex:1 1 100%}
  .ffs-vhead{flex-direction:column;align-items:stretch;gap:12px}
}


/* =====================================================================
 *  BLOCO 6 · entrar e trocar a password
 *
 *  O login e a troca de password são páginas à parte, fora da aplicação
 *  (ver a nota no ffs-auth.js), e ficaram de fora da primeira passagem.
 *  A forma delas aguenta bem um ecrã estreito — é um cartão centrado —
 *  mas os dois campos têm letra a 14,5px, e isso no Safari do iPhone
 *  significa que a página dá zoom e se desloca assim que se toca no
 *  email. É o pior sítio possível para acontecer: é o primeiro ecrã, e
 *  fica-se a escrever a password sem ver o campo.
 * ===================================================================== */

@media (max-width: 900px){
  .ffs-auth-field input{font-size:var(--t-campo);padding:13px 14px}
  .ffs-auth-submit{font-size:var(--t-m1);padding:16px 16px}
  /* O link de recuperar tinha 13px de altura. */
  .ffs-auth-forgot{display:inline-block;padding:12px 8px;font-size:var(--t-m1)}
}


/* =====================================================================
 *  BLOCO 7 · o que só se viu com os dados verdadeiros
 *
 *  Os blocos acima foram afinados contra o conjunto de exemplo do
 *  ffs-data.js, e esse conjunto é bem-comportado: títulos de duas
 *  linhas, uma coleção por produto, ids de sete dígitos. O catálogo a
 *  sério não é nada disso, e só se viu ao auditar a produção com o
 *  auditar-producao-mobile.js:
 *
 *    · os produtos vêm com três, quatro e cinco coleções ao mesmo tempo
 *      ("Advancis, Parafarmácia, SUPLEMENTOS ALIMENTARES E PRODUTOS
 *      NATURAIS"), e isso são quatro linhas onde os exemplos tinham uma:
 *      cartões de 284px onde a medida local dava 180px.
 *
 *    · os ids têm catorze dígitos e muitos trazem o M à frente, e com o
 *      "Ver na loja" ao lado a primeira linha do cabeçalho da gaveta
 *      passa a duas — com a miniatura a boiar a meio de um bloco de
 *      quatro linhas, alinhada com coisa nenhuma.
 * ===================================================================== */

@media (max-width: 900px){
  /* A miniatura encosta ao topo, ao pé do id, em vez de se centrar contra
     um bloco que pode ter duas linhas ou cinco. */
  .ffs-dh .top{align-items:flex-start}
  .ffs-dh .pid{line-height:1.5}
}

/* Sobre a altura dos cartões, que com o catálogo a sério dá 237px de média
   e não os 180px que os dados de exemplo davam: fica assim. Cheguei a
   apertar a lista de coleções (11,5px em vez de 12px, entrelinha 1,25 em
   vez de 1,4) e rendeu SETE pixels por cartão — 3% da página em troca de
   meio ponto de corpo de letra num texto que já está no limite do que se
   lê num telemóvel. Não compensa, e fica escrito para não se voltar a
   tentar.
   Se a altura vier mesmo a incomodar, o corte que vale a pena é outro:
   baixar o "Mostrar 50" por omissão em ecrãs estreitos. São 50 cartões
   que se poupam, não sete pixels — mas é no ffs-app.js, não aqui. */


/* =====================================================================
 *  BLOCO 8 · os painéis de categoria e marca
 *
 *  Visto no telemóvel do Rui, não numa medida: a lista de categorias
 *  mostrava "Parafarm…", "Dermoco…", "SUPLEME…", "Bebé e M…",
 *  "ORTOPED…". Percentagem e contagem à vista, e o nome — a única coisa
 *  que diz DO QUE se está a falar — cortado em todas as linhas.
 *
 *  A causa é a linha manter a grelha do desktop: `1fr 100px 42px 58px`
 *  mais 36px de espaços são 236px fixos num ecrã de 390. Sobravam ~120px
 *  para um nome que precisa de 300.
 *
 *  Nenhuma sonda apanhou isto — não há transbordo nenhum, o texto é
 *  cortado com reticências, que é exactamente o que o CSS lhe mandou
 *  fazer. Só se vê a olhar.
 * ===================================================================== */

@media (max-width: 640px){
  /* O nome leva a linha toda e pode quebrar; a barra, a percentagem e a
     contagem descem para a linha de baixo, que é onde se comparam umas
     com as outras. */
  .ffs-drow{
    grid-template-columns:1fr auto auto;
    grid-template-areas:
      "nome  nome  nome"
      "barra pc    ct";
    gap:7px 10px;
    padding:12px 0;
  }
  .ffs-drow .nm{grid-area:nome;white-space:normal;overflow:visible;
    text-overflow:clip;line-height:1.3}
  .ffs-drow .bar{grid-area:barra;align-self:center}
  .ffs-drow .pc{grid-area:pc}
  .ffs-drow .ct{grid-area:ct}

  /* A procura ficava com meia linha porque o "Esconder 100%" lhe roubava
     a outra metade — e uma caixa de procura com dez caracteres à vista
     não serve para procurar. Cada um leva a sua linha. */
  .ffs-panel .pf{flex-wrap:wrap;gap:9px}
  .ffs-panel .pf .dsearch{flex:1 1 100%}
  .ffs-panel .pf .dchip{flex:1 1 100%;justify-content:center}
}


/* =====================================================================
 *  BLOCO 9 · o toque, e o entalhe do telemóvel
 *
 *  Da revisão contra as Web Interface Guidelines da Vercel e a
 *  better-typography. Nada disto se vê numa fotografia — sente-se a usar.
 * ===================================================================== */

@media (max-width: 900px){
  /* O atraso dos 300ms. Sem isto o browser espera para ver se o toque vai
     ser um duplo-toque para dar zoom, e cada botão responde tarde. É a
     diferença entre a aplicação parecer lenta e parecer nativa. */
  button, a, [role="button"], input, select, textarea, label,
  .segbtn, .datechip, .ffs-tab, .ffs-hitem, #ffs-table tbody tr{
    touch-action:manipulation;
  }
  /* O rectângulo cinzento que o Android desenha por cima do que se toca.
     Fica, porque é o único retorno que há num ecrã sem rato — mas na cor
     da casa e discreto, em vez do cinzento do sistema. */
  a, button, [role="button"], #ffs-table tbody tr{
    -webkit-tap-highlight-color:rgba(134,194,50,.18);
  }

  /* Títulos e descrições quebram com intenção: `balance` reparte as linhas
     de um título por igual, `pretty` não deixa uma palavra sozinha na
     última linha de um parágrafo. */
  .ffs-intro h1, .section-h h2, .ffs-vhead h2, .ffs-dh h3{text-wrap:balance}
  .section-sub, .ffs-vsub, .ffs-intro .sub{text-wrap:pretty}

  /* O entalhe e a barra de gestos. A gaveta ocupa o ecrã todo, e num
     iPhone com entalhe o cabeçalho ficava por baixo dele e os últimos
     campos por baixo da barra de baixo. */
  .ffs-dh{padding-top:max(16px, env(safe-area-inset-top))}
  .ffs-dh .dh-actions .x{top:max(12px, env(safe-area-inset-top))}
  .ffs-dbody{padding-bottom:max(40px, calc(env(safe-area-inset-bottom) + 28px))}
  .ffs-toast{bottom:max(16px, calc(env(safe-area-inset-bottom) + 8px))}
  .plano-scope .modal-back{padding-bottom:max(24px, calc(env(safe-area-inset-bottom) + 16px))}
}

@media (max-width: 640px){
  /* Com a escala um degrau abaixo, a moldura tem de acompanhar — senão o
     texto encolhe e os espaços à volta continuam a gritar. */
  .ffs-main{padding:18px var(--pad) 52px}
  .section{padding:20px 0}
  .section-sub{margin-bottom:14px}
  .ffs-bar2{gap:8px;margin-bottom:16px}
  .ffs-bar{margin-bottom:10px}
  .ffs-intro{padding:16px 0 18px}
  .ffs-kpi .big{padding:18px 16px}
  .ffs-kpi .cell{padding:14px 16px}
  .ffs-panel .pb{padding:6px 14px 12px}
  .ffs-panel .ph{padding:12px 14px}
}


/* =====================================================================
 *  BLOCO 10 · os filtros deixam de ser um ecrã inteiro
 *
 *  Medido: do título "Registo de produtos" ao primeiro produto iam 632px
 *  — um ecrã e meio de procura e filtros antes de se ver um produto. Não
 *  é a letra, é a contagem: dez controlos, cada um com os seus 44px de
 *  altura (que ficam, é o dedo), a quebrarem para cinco linhas.
 *
 *  A PRIMEIRA TENTATIVA FOI PÔ-LOS A ROLAR DE LADO, e estava errada. O
 *  Rui cortou-a e tem razão: numa fila que rola, os filtros que estão
 *  fora do ecrã não existem para quem olha — e um filtro que não se vê é
 *  um filtro que não se usa. Numa barra de ferramentas de uma aplicação
 *  que se consulta, esconder controlos para poupar altura é trocar o
 *  problema por um pior.
 *
 *  Fica a quebrar de linha, como sempre. A altura vem de apertar cada
 *  controlo — menos folga lateral, mesma altura de dedo — e não de os
 *  esconder.
 * ===================================================================== */

@media (max-width: 640px){
  .ffs-bar,
  .ffs-bar2{flex-wrap:wrap;gap:7px;overflow:visible}

  /* Menos folga lateral em cada chip: com 44px de altura intactos, cabem
     mais por linha e a barra encolhe sem esconder nada. */
  .datechip.sm{padding:0 11px}
  .segbtn{padding:0 13px}
  .ffs-btn.sm{padding:10px 12px}

  /* A procura leva a linha toda — é onde se escreve. As duas combos
     dividem a linha seguinte, e o estado fica com a sua: "Todos os
     fornecedores" precisa de espaço para se ler, e três a dividir 358px
     davam 55px cada um, com o texto cortado a meio. */
  .ffs-bar .ffs-search{flex:1 1 100%}
  .ffs-combo.filtro{flex:1 1 100%;min-width:0;max-width:none}
  .ffs-bar .ffs-select{flex:1 1 100%}
  .sort-select{margin-left:auto}
}



/* =====================================================================
 *  BLOCO 11 · os placeholders passam a ser um só
 *
 *  Medidos os onze que a aplicação mostra: três estavam CORTADOS a meio
 *  ("Todos os fornecedores" precisava de 189px e tinha 55), e entre eles
 *  havia três espessuras (400, 600 e 700) e dois tamanhos (16 e 12px).
 *  Onze pistas escritas de cinco maneiras diferentes.
 *
 *  Um placeholder não é conteúdo, é uma sugestão do que ali se escreve —
 *  por isso normal (400), um degrau abaixo do texto que se escreve, e
 *  sempre igual em toda a aplicação.
 *
 *  E o tamanho do PLACEHOLDER não é o tamanho do CAMPO: o zoom do Safari
 *  dispara com o corpo do input, não com o da pista. O campo fica nos 16px
 *  obrigatórios; a pista desce, e passa a caber.
 * ===================================================================== */

@media (max-width: 900px){
  input::placeholder,
  textarea::placeholder{
    font-family:var(--sans);
    font-size:var(--t-b2);
    font-weight:400;
    letter-spacing:0;
    text-transform:none;
    opacity:1;              /* Firefox e Android descem-na sozinhos */
  }
  /* Estes três têm regra própria no ffs.css, mais específica do que a de
     cima, e ficavam de fora: o combo do filtro com peso 700 e maiúsculas,
     e as duas textareas com a pista presa aos 12px. */
  .ffs-combo.filtro .combo-input::placeholder{font-weight:400;text-transform:none}
  .ffs-runform textarea::placeholder,
  .cat-campo textarea::placeholder{font-size:var(--t-b2);line-height:1.5}
}


/* =====================================================================
 *  BLOCO 12 · altura sem esconder nada
 *
 *  Tirado o scroll lateral, a barra de filtros voltou aos 620px até ao
 *  primeiro produto. A altura tem de vir de outro lado que não seja pôr
 *  controlos fora do ecrã.
 * ===================================================================== */

@media (max-width: 640px){
  /* "Atualizar todos os campos" só funciona com produtos escolhidos, e até
     lá está cinzento e inerte — 52px de altura a dizer que não se pode
     carregar. Aparece quando há selecção (o syncBulkUI liga-o), que é
     quando quer dizer alguma coisa. Não é esconder um controlo: é não
     mostrar um botão que não faz nada. */
  .ffs-bar2 .bulk-btn:disabled{display:none}

  /* Os controlos ficam com a altura do dedo e perdem a gordura à volta. */
  .ffs-bar{gap:7px;margin-bottom:8px}
  .ffs-bar2{gap:7px;margin-bottom:12px}
  .ffs-combo.filtro .combo-input{padding-top:11px;padding-bottom:11px}
  .ffs-select,.cal-sel,.fld-select{padding-top:10px;padding-bottom:10px}
  .ffs-search{min-height:46px}

  /* O cabeçalho da tabela é uma barra só com o "escolher todos" e a
     ordenação por data: não precisa da moldura de 1,5px nem de 9px de
     folga em cima e em baixo. */
  #ffs-table thead tr{padding:4px 10px;margin-bottom:8px;border-width:1px}
}

@media (max-width: 900px){
  /* Três controlos do mesmo filtro, os três por preencher, e um deles
     aparecia a negrito e a 16px enquanto os outros dois estavam leves e a
     13px. Não é escolha de desenho: um `<select>` não tem placeholder, e a
     primeira opção — "Todos os estados" — é um VALOR como qualquer outro,
     por isso desenhava-se como um valor escolhido.
     Enquanto estiver na opção de origem, veste-se como as pistas ao lado.
     Assim que se escolhe um estado a sério, volta ao peso de valor. */
  #ffs-status:has(option[value="all"]:checked){
    font-weight:400;
    font-size:var(--t-b2);
    color:var(--muted-2);
  }
}


/* =====================================================================
 *  BLOCO 13 · os filtros passam a caber numa gaveta
 *
 *  Depois de tirar o scroll lateral (Bloco 10), a barra do registo voltou
 *  a ser um ecrã inteiro: quatro campos, cinco botões de data e três de
 *  estado, todos ao tamanho do dedo, todos à vista, 547px antes do
 *  primeiro produto.
 *
 *  As duas saídas anteriores estavam ambas erradas: rolar de lado esconde
 *  sem dizer que esconde, e deixar tudo à vista gasta o ecrã todo a
 *  perguntar em vez de responder. A terceira é a que qualquer aplicação
 *  de telemóvel usa e que nenhuma das outras duas tem: um botão com
 *  ETIQUETA e com a CONTA de quantos filtros estão a esconder linhas.
 *
 *  A procura fica sempre fora da gaveta — é o filtro que se usa mais e
 *  quem o procura não devia ter de abrir nada.
 *
 *  A conta no botão é o que impede o pior modo de falhar disto: alguém
 *  deixa um filtro ligado, fecha a gaveta, e passa a tarde a perguntar
 *  porque é que faltam produtos. Com um "3" ao lado da palavra Filtros,
 *  a resposta está no ecrã.
 * ===================================================================== */

@media (max-width: 640px){
  .ffs-filtros-btn{
    display:inline-flex;align-items:center;gap:7px;
    appearance:none;cursor:pointer;
    border:1.5px solid var(--ink);border-radius:8px;background:#fff;
    color:var(--ink);font-family:var(--sans);font-size:var(--t-b2);font-weight:700;
    padding:0 14px;min-height:44px;flex:0 0 auto;
    transition:background .12s,color .12s;
  }
  .ffs-filtros-btn .fn{
    display:inline-flex;align-items:center;justify-content:center;
    min-width:19px;height:19px;padding:0 5px;border-radius:999px;
    background:var(--accent);color:#0a0a0a;
    font-family:var(--mono);font-size:var(--t-m2);font-weight:800;
  }
  .ffs-filtros-btn .fn[hidden]{display:none}
  /* Aberta: o botão fica escuro, para se perceber que o que está por baixo
     dele é dele. */
  .ffs-filtros-btn.on{background:var(--ink);color:var(--paper)}
  .ffs-filtros-btn.on .fn{background:var(--accent);color:#0a0a0a}

  /* Fechada: da primeira barra ficam a procura e o botão; a segunda
     desaparece inteira. */
  .ffs-bar:not(.filtros-abertos) > *:not(.ffs-search):not(.ffs-filtros-btn){display:none}
  .ffs-bar2:not(.filtros-abertos){display:none}

  /* A procura deixa de levar a linha toda: divide-a com o botão. */
  .ffs-bar .ffs-search{flex:1 1 auto;min-width:0}
}
