/* PORTEFÓLIO - a lista das empreitadas e a sua barra de filtros
   Cabeçalho da secção, barra de filtros, cabeçalho de colunas, a lista, cada
   cartão-linha, os grupos por tipo de próxima ação e as ações em linha. Painel
   em `public/features/portfolio-panel.js`; as regras puras em
   `public/features/portfolio.js`. Os chips de estado são pintados por
   `public/features/dashboard-panel.js`, mas vivem nesta barra.

   Fica em `public/design.css` o que é partilhado: `.flabel` e `.flabel
   select`, escritos também pelos relatórios mensais e pelo arquivo da ficha, e
   por isso nunca redefinidos aqui sem o prefixo `.toolbar`; e os primitivos
   `.card`, `.dot`, `.top`, `.num`, `.tit`, `.toolbar`, `.fgrupo`, `.fbtn`,
   `.fsep` e `.fcount` do bloco COMPONENTES BASE, que sai por inteiro na
   arrumação final da base. */


/* Cabeçalho da lista reduzido ao contador: o título da vista já diz o resto. */
.contractsHeading.soContador { justify-content: flex-end; margin-bottom: 8px; }

/* Agrupado por tipo de próxima ação, cada ação é um quadro fechado sobre si
   próprio: título por cima, tabela por baixo, e ar a separar do quadro
   seguinte. O cabeçalho de colunas único deixa de fazer sentido (são várias
   tabelas), por isso esconde-se. */
.listHeader[hidden] { display: none; }

.contractsList.agrupado {
  display: grid;
  /* Sem isto, a altura mínima da lista esticava as linhas da grelha: com dois
     ou três grupos colapsados, as ações ficavam afastadas meio ecrã umas das
     outras, como se estivessem a guardar espaço para as EOP que só aparecem
     quando o grupo abre. */
  align-content: start;
  gap: 26px;
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.grupoBloco {
  min-width: 0;
  display: block;
}

/* Cabeçalho de grupo: o título da ação, clicável para abrir e fechar. */
.grupoCab {
  width: 100%;
  margin: 0 0 9px;
  padding: 0 2px 8px;
  display: flex;
  align-items: baseline;
  gap: 9px;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}

.grupoCab:hover b,
.grupoCab:hover .grupoSeta { color: var(--accent); }

.grupoCab b {
  flex: 1;
  min-width: 0;
  color: var(--ink);
  font-size: var(--txt-md);
  font-weight: 750;
  letter-spacing: -.01em;
}

.grupoCab .grupoContagem {
  flex: none;
  color: var(--muted);
  font-size: var(--txt-xs);
  font-weight: 600;
}

.grupoCab .grupoSeta {
  flex: none;
  color: var(--muted);
  font-size: var(--txt-xs);
  line-height: 1;
  transition: transform .15s ease;
}

.grupoBloco.fechado .grupoCab { margin-bottom: 0; }
.grupoBloco.fechado .grupoSeta { transform: rotate(-90deg); }

.grupoLista {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--panel);
  box-shadow: var(--shadow);
}

.grupoLista[hidden] { display: none; }

/* A última linha de cada quadro não precisa de risco: o bordo já fecha. */
.grupoLista .card:last-child { border-bottom: 0; }

/* "Dados incompletos" é uma lista de lacunas, não uma segunda cópia do
   portefólio. Cada quadro responde primeiro a "o que falta?" e só depois
   enumera as EOP onde esse campo deve ser preenchido. */
.contractsList.qualityMode {
  display: grid;
  gap: 16px;
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

/* Ações em linha: a lista dizia o que fazer e não deixava fazer nada.
   Três lugares de largura fixa, e não um fluxo livre: "Registar auto" e
   "Registar consignação" têm larguras diferentes e os botões desalinhavam-se
   de linha para linha. Cada lugar é sempre ocupado, nem que seja por um vazio. */
.rowActions {
  display: grid;
  grid-template-columns: 152px 52px 30px;
  align-items: center;
  justify-content: end;
  gap: 6px;
}

.rowActionVazia { display: block; }

.rowAction {
  min-width: 0;
  padding: 5px 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: var(--panel);
  color: var(--ink);
  font-size: var(--txt-xs);
  font-weight: 650;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}

.rowAction:hover { border-color: var(--accent, #3448b5); }

.rowAction.primary {
  border-color: transparent;
  background: var(--accent-solid, #175cd3);
  color: #fff;
}

.rowAction.ghost {
  padding: 5px 8px;
  border-color: transparent;
  background: none;
  color: var(--muted);
  font-size: var(--txt-sm);
}

.contractsHeading {
  margin-bottom: 11px;
}

/* A barra acompanha a lista: numa lista de 35 empreitadas, filtrar obrigava a
   subir ao topo para chegar aos filtros. Fica presa debaixo da barra de topo,
   que tem 68px. */
.toolbar {
  min-height: 54px;
  margin-bottom: 10px;
  padding: 8px 10px;
  position: sticky;
  top: 68px;
  z-index: 6;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  gap: 9px;
}

.toolbar[hidden] {
  display: none;
}

.toolbar #btnAgrupar,
.toolbar #btnColapsarGrupos,
.toolbar .clearFilters {
  min-height: 32px;
  padding: 0 11px;
  border: 1px solid var(--line) !important;
  border-radius: var(--r-sm);
  background: var(--panel);
  color: var(--ink);
  box-shadow: 0 1px 2px rgba(21, 32, 47, .08);
  font-size: var(--txt-xs);
  font-weight: 650;
  white-space: nowrap;
}

.toolbar #btnAgrupar:hover,
.toolbar #btnColapsarGrupos:hover,
.toolbar .clearFilters:hover {
  border-color: var(--accent) !important;
  color: var(--accent);
}

.toolbar #btnAgrupar.on {
  border-color: var(--accent) !important;
  background: color-mix(in srgb, var(--accent) 10%, var(--panel));
  color: var(--accent);
}

.toolbar .clearFilters {
  color: var(--muted);
}

.groupLabelMobile {
  display: none;
}

.mobileFiltersToggle {
  display: none;
}

.fgrupo {
  padding: 3px;
  border: 0;
  border-radius: var(--r-sm);
  background: var(--subtle);
}

.fbtn {
  min-height: 29px;
  padding: 0 10px;
  border: 0 !important;
  border-radius: var(--r-xs);
  background: transparent;
  color: var(--muted);
  font-size: var(--txt-xs);
}

/* Na vista de dados incompletos só os chips de estado fazem sentido: ordenar
   ou agrupar não se aplica a um ecrã que não é a lista. */
.toolbar.soEstado > *:not(.fEstado) {
  display: none;
}

/* Chips de estado: o rótulo e a contagem no mesmo botão, para o número que se
   clica ser o número de linhas que aparece. */
.fEstado {
  flex-wrap: wrap;
}

.fEstado .fbtn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.fEstado .fbtn em {
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--ink) 8%, transparent);
  color: var(--muted);
  font-size: var(--txt-xs);
  font-style: normal;
  font-weight: 700;
}

.fEstado .fbtn.on em {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
}

.fbtn.on {
  background: var(--panel);
  color: var(--ink);
  box-shadow: 0 1px 4px rgba(21, 32, 47, .12);
}

.selectField {
  min-width: 0;
  position: relative;
  display: inline-block;
}

.selectField::after {
  width: 7px;
  height: 7px;
  position: absolute;
  top: 50%;
  right: 12px;
  border-right: 1.7px solid var(--muted);
  border-bottom: 1.7px solid var(--muted);
  content: "";
  pointer-events: none;
  transform: translateY(-68%) rotate(45deg);
}

.toolbar .selectField select {
  -webkit-appearance: none;
  appearance: none;
}

.listHeader {
  min-height: 38px;
  padding: 0 14px;
  display: grid;
  grid-template-columns: minmax(230px, 2fr) minmax(76px, .6fr) minmax(112px, .85fr) minmax(104px, .95fr) minmax(190px, 1.4fr) 246px;
  align-items: center;
  gap: 14px;
  border: 1px solid var(--line);
  border-bottom: 0;
  border-radius: 13px 13px 0 0;
  background: var(--subtle);
  color: var(--muted);
  font-size: var(--txt-xs);
  font-weight: 720;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.contractsList {
  /* Um filtro que devolve uma linha encurtava a página ao ponto de o browser
     ser obrigado a puxar o scroll para o topo - e a barra de filtros saltava
     debaixo do cursor. Com uma altura mínima, a página não encolhe abaixo do
     que o scroll precisa. */
  min-height: calc(100vh - 240px);
  overflow: hidden;
  display: block;
  border: 1px solid var(--line);
  border-radius: 0 0 13px 13px;
}

.contractsList .card {
  width: 100%;
  min-height: 82px;
  padding: 11px 14px;
  display: grid;
  grid-template-columns: minmax(230px, 2fr) minmax(76px, .6fr) minmax(112px, .85fr) minmax(104px, .95fr) minmax(190px, 1.4fr) 246px;
  align-items: center;
  gap: 14px;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  background: var(--panel);
  color: var(--ink);
  box-shadow: none;
  text-align: left;
  cursor: pointer;
  transform: none;
}

.contractsList .card:last-child {
  border-bottom: 0;
}

.contractsList .card:hover {
  background: var(--subtle);
  border-color: var(--line);
  filter: none;
  transform: none;
}

.contractIdentity {
  min-width: 0;
}

.contractIdentity .top {
  margin: 0 0 2px;
}

.contractIdentity .num {
  font-size: var(--txt-md);
}

.contractIdentity .tit {
  min-height: 0;
  margin: 0;
  overflow: hidden;
  color: var(--ink);
  font-size: var(--txt-sm);
  /* Duas linhas em vez de reticências: o título é como se reconhece a obra,
     e era a primeira coisa a desaparecer nos ecrãs mais estreitos. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  white-space: normal;
  line-height: 1.35;
}

.contractIdentity .submeta {
  margin-top: 4px;
  color: var(--muted);
  font-size: var(--txt-xs);
  /* PM e empreiteiro numa linha: são a informação de contexto, e a três
     linhas empurravam a lista para 155px por empreitada. O título, esse,
     pode ocupar duas. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.contractStatus small,
.contractAction small {
  display: block;
  margin-top: 4px;
  color: var(--muted);
  font-size: var(--txt-xs);
}

/* Os dias de atraso ficam sempre à mesma altura e na mesma linha. Antes, a
   coluna era estreita ao ponto de "487 dias em atraso" partir em duas, e como
   as células estão centradas verticalmente cada linha punha a data a uma
   altura diferente - o que se lia como desalinhamento. */
.contractStatus {
  align-self: center;
}

.contractStatus small.warn {
  white-space: nowrap;
}

.contractStatus small.warn {
  color: var(--vermelho);
}

.contractProgress .progressLabel {
  margin-bottom: 5px;
  display: flex;
  justify-content: space-between;
  color: var(--muted);
  font-size: var(--txt-xs);
}

.contractProgress .bar {
  height: 5px;
  margin: 0;
}

.contractAction { min-width:0; }
.contractAction small {
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
  overflow:hidden;
  line-height:1.35;
}

/* A largura útil da tabela não coincide com a largura da janela: no desktop,
   a barra lateral e o padding do conteúdo retiram mais de 300px. A grelha
   passa por isso a adaptar-se ao próprio quadro, mantendo sempre visíveis as
   ações da direita mesmo em ecrãs 1280x800 a 100%. */
@container contracts (max-width: 1080px) {
  .listHeader,
  .contractsList .card {
    grid-template-columns: minmax(200px, 1.8fr) minmax(76px, .6fr) minmax(112px, .85fr) minmax(170px, 1.2fr) 246px;
  }

  .listHeader > span:nth-child(4),
  .contractsList .contractProgress {
    display: none;
  }
}

/* Entre 900 e 1400px a linha da lista pedia 1056px mínimos e o espaço
   disponível num portátil de 1366 são 1026: a coluna das ações ficava
   cortada pelo overflow, sem barra de scroll para a recuperar. As seis
   colunas mantêm-se - perder a fase ou o progresso num portátil seria pior,
   apertadas ao que cada uma precisa mesmo. */
@media (max-width: 1400px) {
  .contractsList .card,
  .listHeader {
    grid-template-columns:
      minmax(180px, 2fr) minmax(64px, .5fr) minmax(114px, .8fr)
      minmax(84px, .8fr) minmax(150px, 1.3fr) 254px;
    gap: 10px;
  }

  .rowActions {
    grid-template-columns: 158px 56px 28px;
    gap: 6px;
  }
}

@media (max-width: 900px) {
  /* Os filtros continuam acessíveis durante listas longas, tal como no
     desktop. A composição mobile mais compacta impede que a barra presa tome
     conta do ecrã. */
  .toolbar {
    position: sticky;
    top: 62px;
    z-index: 12;
    box-shadow: 0 5px 16px rgba(21, 32, 47, .1);
  }

  .toolbar {
    flex-wrap: wrap;
  }

  .listHeader,
  .contractsList .card {
    grid-template-columns: minmax(200px, 1.6fr) minmax(112px, .8fr) minmax(170px, 1.2fr) 246px;
  }

  .listHeader > span:nth-child(2),
  .contractsList .contractPhase {
    display: none;
  }
}

@media (max-width: 620px) {
  /* No telemóvel os três lugares fixos das ações deixam de fazer sentido: não
     há colunas para alinhar, e a largura fixa cortava "Registar consignação"
     a meio. Cada botão passa a ocupar o que precisa. */
  .rowActions {
    grid-template-columns: auto auto auto;
    justify-content: start;
    gap: 8px;
  }

  .rowActionVazia {
    display: none;
  }

  .toolbar {
    display: grid;
    grid-template-columns: minmax(76px, .7fr) minmax(132px, 1.3fr) auto;
    align-items: end;
    gap: 7px;
    padding: 6px 8px;
  }

  /* Todos/Efetivos/Suplentes é uma escolha curta, não uma ação principal. A
     caixa mantém largura confortável, mas perde o excesso vertical que fazia
     esta única linha parecer um segundo cabeçalho. */
  .toolbar #fPapel {
    align-self: end;
    padding: 2px;
  }

  .toolbar #fPapel .fbtn {
    height: 34px;
    min-height: 34px;
    padding: 0 8px;
  }

  /* Um nome de gestor não cabe na mesma fila de Ano e Ordenar. Quando este
     filtro existe (auditoria e administração), ocupa uma linha completa; os
     três controlos curtos continuam juntos por baixo. */
  .toolbar #fGestorCampo { grid-column: 1 / -1; }
  .toolbar #fAnoCampo { grid-column: 1; }
  .toolbar #fOrdenarCampo { grid-column: 2; }

  /* Ano e Ordenar passam a ter o rótulo dentro do próprio controlo. Assim os
     três controlos curtos deixam de gastar uma linha só em legendas. */
  .toolbar #fAnoCampo,
  .toolbar #fOrdenarCampo {
    position: relative;
    align-self: end;
  }

  .toolbar #fAnoCampo .filterLabelText,
  .toolbar #fOrdenarCampo .filterLabelText {
    width: 1px;
    height: 1px;
    position: absolute;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .toolbar #fAnoCampo .selectField::before,
  .toolbar #fOrdenarCampo .selectField::before {
    position: absolute;
    top: 50%;
    left: 9px;
    z-index: 1;
    color: var(--muted);
    font-size: var(--txt-xs);
    font-weight: 650;
    pointer-events: none;
    transform: translateY(-50%);
  }

  .toolbar #fAnoCampo .selectField::before { content: "Ano:"; }
  .toolbar #fOrdenarCampo .selectField::before { content: "Ordenar:"; }
  .toolbar #fAnoCampo select { padding-left: 40px; }
  .toolbar #fOrdenarCampo select { padding-left: 62px; }

  /* Sem escolha feita, o valor do controlo é "Todos" e "Prioridade": duas
     palavras que não acrescentam nada ao rótulo e que, somadas a ele, não
     cabiam na caixa e saíam cortadas. Enquanto o filtro está por omissão
     mostra-se apenas o rótulo; a palavra volta assim que houver escolha,
     que é quando ela diz alguma coisa. A lista aberta continua a mostrar
     todas as opções por extenso. */
  .toolbar #fAnoCampo.semValor .selectField::before { content: "Ano"; }
  .toolbar #fOrdenarCampo.semValor .selectField::before { content: "Ordenar"; }

  .toolbar .flabel.semValor select {
    color: transparent;
  }

  .toolbar .flabel.semValor select option {
    color: var(--ink);
  }

  .toolbar #fAnoCampo select,
  .toolbar #fOrdenarCampo select,
  .toolbar #btnAgrupar {
    height: 36px;
    min-height: 36px;
  }

  .fgrupo {
    width: 100%;
    min-width: 0;
    grid-column: 1 / -1;
  }

  .fgrupo button {
    flex: 1;
  }

  /* Oito chips esticados à mesma largura numa caixa de 350px partiam o rótulo
     em duas e três linhas ("Sem ação / imediata", "Documentos / em atraso") e
     empilhavam-se em quatro filas de altura desigual. Passam a ter a largura
     do próprio texto, numa tira única que se desliza com o polegar: a ordem
     põe à vista o que mais se usa e o chip cortado à direita diz que há mais.
     Só os chips de estado - o grupo do papel são três e cabem na largura. */
  .fEstado {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

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

  .fEstado .fbtn {
    flex: none;
    white-space: nowrap;
  }

  /* Rótulo por cima do seletor, e o seletor a ocupar a célula toda: é assim
     que os filtros da lista cabem num ecrã estreito. A regra vale só dentro da
     barra - sem o `.toolbar`, apanhava todos os `.flabel` da plataforma, e a
     caixa "Só arquivar (não analisar com IA)" da ficha da EOP ficava com o
     quadradinho esticado a 180px numa linha e o texto noutra. */
  .toolbar .flabel {
    min-width: 0;
    align-items: stretch;
    flex-direction: column;
  }

  .toolbar .flabel select {
    width: 100%;
  }

  .toolbar .selectField {
    width: 100%;
  }

  .fsep {
    display: none;
  }

  .toolbar #btnAgrupar,
  .toolbar #btnColapsarGrupos,
  .toolbar .clearFilters {
    min-width: 0;
  }

  .toolbar #btnAgrupar {
    grid-column: 3;
    width: auto;
    padding-inline: 10px;
    white-space: nowrap;
  }

  .toolbar #btnColapsarGrupos,
  .toolbar .clearFilters {
    width: 100%;
    grid-column: 1 / -1;
  }

  .groupLabelFull {
    display: none;
  }

  .groupLabelMobile {
    display: inline;
  }

  .listHeader {
    display: none;
  }

  .contractsList {
    /* O quadro da lista herdava 19px de padding lateral de quando era mesmo
       um quadro, com bordo e fundo. Em mobile deixou de o ser - cada linha é
       um cartão com bordo próprio - e o padding continuava lá, a encolher os
       cartões 38px e a desalinhá-los da barra de filtros logo por cima. */
    padding: 0;
    display: grid;
    align-content: start;
    gap: 10px;
    overflow: visible;
    border: 0;
    background: transparent;
  }

  .contractsList .card {
    min-height: 0;
    padding: 12px;
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    /* Sem espaço entre linhas: cada bloco traz a sua própria margem, que é o
       que permite colar o subtítulo ao título e afastar o bloco da ação. Uma
       goteira única dava a tudo a mesma distância e inchava o cartão. */
    gap: 0 10px;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow);
  }

  /* Em mobile cada linha já é um cartão com bordo próprio: o quadro do grupo
     deixa de ser uma caixa e passa a ser só o espaçamento entre cartões. */
  .grupoLista {
    display: grid;
    gap: 10px;
    overflow: visible;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }

  .contractsList .card:last-child,
  .grupoLista .card:last-child {
    border-bottom: 1px solid var(--line);
  }

  .contractsList.agrupado {
    gap: 22px;
  }

  /* O estado estava encostado ao canto em posição absoluta, com um espaço de
     150px reservado à mão na primeira linha. Num ecrã de 375px "Crítico" mais
     "499 dias em atraso" ocupam bem mais do que isso e passavam por cima do
     papel - lia-se "Efetiv". A identidade dissolve-se na grelha do cartão
     para o número e o estado partilharem a primeira linha a sério, cada um
     com a largura que precisa, e o título e o subtítulo ficarem com a
     largura toda por baixo. */
  .contractsList .contractIdentity {
    display: contents;
  }

  .contractsList .contractIdentity .top {
    grid-column: 1;
    grid-row: 1;
    align-self: center;
    margin-bottom: 0;
  }

  .contractsList .contractStatus {
    grid-column: 2;
    grid-row: 1;
    display: flex;
    align-items: flex-end;
    /* Empilhado: o estado e os dias lado a lado exigiam 200px de linha e
       roubavam-nos ao número da empreitada. */
    flex-direction: column;
    gap: 2px;
    text-align: right;
  }

  .contractsList .contractStatus small {
    margin-top: 0;
  }

  .contractsList .contractIdentity .tit {
    grid-column: 1 / -1;
    margin-top: 5px;
  }

  .contractsList .contractIdentity .submeta,
  .contractsList .contractAction,
  .contractsList .rowActions {
    grid-column: 1 / -1;
  }

  .contractsList .contractAction {
    margin-top: 9px;
    padding: 7px 24px 7px 9px;
    position: relative;
    border-left: 0;
    border-radius: var(--r-sm);
    background: var(--subtle);
  }

  .contractsList .rowActions {
    margin-top: 8px;
  }

  /* O sinal de "isto abre" passa para dentro do bloco da próxima ação, que é
     o que se lê por último. A seta que estava a fazer esse trabalho ocupava
     uma linha inteira no fundo do cartão, para dizer o mesmo que o cartão
     inteiro já diz ao ser tocável. */
  .contractsList .contractAction::after {
    position: absolute;
    top: 50%;
    right: 8px;
    color: var(--cinza);
    content: "›";
    font-size: var(--txt-lg);
    line-height: 1;
    transform: translateY(-52%);
  }

  .contractsList .rowActionAbrir {
    display: none;
  }

  /* Sem a seta, uma linha de ações que só a tinha fica vazia: sai do cartão em
     vez de deixar lá o espaço dela. */
  .contractsList .rowActions.soAbrir {
    display: none;
  }
}

@media (max-width: 620px) {
  /* No telemóvel, os estados mantêm-se todos acessíveis mesmo com o painel
     fechado. A faixa horizontal preserva rótulos inteiros e o último chip
     parcialmente visível indica que se pode deslizar. */
  .toolbar {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: stretch;
    padding: 8px;
  }

  .toolbar.mobileFiltersOpen {
    max-height: calc(100dvh - 72px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .toolbar .mobileFiltersToggle,
  .toolbar.soEstado > .mobileFiltersToggle {
    width: 100%;
    min-height: 44px;
    display: flex;
    grid-column: 1 / -1;
    align-items: center;
    justify-content: space-between;
    padding: 0 12px;
    border: 1px solid var(--line) !important;
    background: var(--panel);
    color: var(--ink);
    font-size: var(--txt-sm);
    font-weight: 680;
  }

  .toolbar .mobileFiltersToggle::after {
    content: "⌄";
    color: var(--muted);
    transition: transform .15s ease;
  }

  .toolbar.mobileFiltersOpen .mobileFiltersToggle::after {
    transform: rotate(180deg);
  }

  .toolbar > *:not(.mobileFiltersToggle):not(.fEstado) { display: none; }
  .toolbar:not(.mobileFiltersOpen) > .clearFilters { display: none !important; }
  .toolbar .fEstado {
    width: 100%;
    grid-column: 1 / -1;
    display: flex;
    gap: 4px;
  }
  .toolbar .fEstado .fbtn { min-height: 40px; }

  .toolbar:not(.mobileFiltersOpen) .fEstado {
    padding-right: 22px;
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .toolbar:not(.mobileFiltersOpen) .fEstado::-webkit-scrollbar { display: none; }

  .toolbar:not(.mobileFiltersOpen) .fEstado .fbtn {
    flex: none;
    scroll-snap-align: start;
    white-space: nowrap;
  }

  .toolbar.mobileFiltersOpen .fEstado {
    flex-wrap: wrap;
    overflow: hidden;
  }

  .toolbar.mobileFiltersOpen > *:not(.fsep) { display: flex !important; }
  .toolbar.mobileFiltersOpen #fGestorCampo[hidden],
  .toolbar.mobileFiltersOpen #btnColapsarGrupos[hidden] { display: none !important; }
  .toolbar.mobileFiltersOpen #fPapel,
  .toolbar.mobileFiltersOpen #fGestorCampo,
  .toolbar.mobileFiltersOpen #btnAgrupar,
  .toolbar.mobileFiltersOpen #btnColapsarGrupos,
  .toolbar.mobileFiltersOpen .clearFilters {
    width: 100%;
    min-height: 44px;
    grid-column: 1 / -1;
  }
  .toolbar.mobileFiltersOpen #fAnoCampo,
  .toolbar.mobileFiltersOpen #fOrdenarCampo {
    width: 100%;
    min-width: 0;
    min-height: 44px;
  }
  .toolbar.mobileFiltersOpen #fAnoCampo {
    grid-column: 1;
  }
  .toolbar.mobileFiltersOpen #fOrdenarCampo {
    grid-column: 2;
  }
  .toolbar.mobileFiltersOpen #fPapel .fbtn,
  .toolbar.mobileFiltersOpen select,
  .toolbar.mobileFiltersOpen #btnAgrupar,
  .toolbar.mobileFiltersOpen #btnColapsarGrupos,
  .toolbar.mobileFiltersOpen .clearFilters {
    min-height: 44px;
    display: flex !important;
    align-items: center;
    justify-content: center;
  }
  .toolbar .selectField select { height: 44px !important; }

  .grupoCab {
    min-height: 44px;
    padding: 8px 2px;
    align-items: center;
  }
}
