/* Simulador do painel do administrador — Compra de pontos
   =========================================================================
   Este arquivo NÃO define token. Ele compõe a casca do painel (barra
   superior, menu lateral, área de conteúdo) e as duas peças que só existem
   nesta jornada: o cartão de pacote e a linha de valor personalizado.

   Toda medida veio do arquivo em assets/telas/Compra Pontos*.svg, lida
   direto dos <rect>: menu lateral 320, barra superior 64, conteúdo a 32 da
   borda do menu, cartão de pacote 160 × 147 com raio 4 e vão de 16, campo
   personalizado 324 × 72 com raio 8.
   ========================================================================= */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background-color: var(--surface-page);
  color: var(--text-body);
  font-family: var(--family-ui);
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  -webkit-font-smoothing: antialiased;
}

/* =========================================================================
   Casca
   =========================================================================
   OS BREAKPOINTS SÃO OS DO SISTEMA, e os mesmos que a Loja de Resgate usa.
   Antes deste ponto o admin tinha uma casca de medida fixa — menu de 320 e
   conteúdo a 32 da borda em qualquer largura — e um único corte responsivo
   em 48rem, que é 768 e portanto já é TABLET: tudo que o arquivo chamava de
   "telefone" valia também para o primeiro pixel do tablet.

   As quatro faixas do sistema, e as duas com navegação lateral:

     breakpoint.mobile          até 767        margem 16   gutter 8
     breakpoint.tablet          768 – 979      margem 32   gutter 8
     breakpoint.hd-painel       980 – 1366     menu 240    margem 32   gutter 16
     breakpoint.fullhd-painel   1367 em diante menu 320    margem 48   gutter 24

   Menu e painel ficam FORA da conta do grid: a margem vale na área entre
   eles. Abaixo de 980 não há navegação persistente — as áreas empilham e o
   corpo volta à margem da faixa comum (32 no tablet, 16 no telefone).

   COMO ESTÁ ESCRITO
   Cada faixa só escolhe QUAIS tokens valem, em apelidos locais
   (--admin-menu-width, --admin-gutter, --admin-vao). As regras de layout
   leem os apelidos e não sabem em que breakpoint estão. Nada aqui define
   valor: os números são todos do sistema.

   > Divergência registrada: o arquivo de origem tem 1366 de largura e
   > desenha o menu com 320. Nos tokens, 1366 é HD, e HD com navegação
   > lateral é 240 — 320 só a partir de 1367. Vale o sistema, para o admin e
   > a loja dizerem a mesma coisa na mesma largura. Voltar atrás é trocar um
   > token nesta declaração.
   ========================================================================= */

.admin {
  /* O padrão é hd-painel; as faixas abaixo só reescrevem estes três. */
  --admin-menu-width: var(--menu-width-hd);            /* 240 */
  --admin-topbar-height: 4rem;                         /* 64 — do rect do arquivo */
  --admin-gutter: var(--grid-hd-painel-margin);        /* 32 */
  --admin-vao: var(--grid-hd-painel-gutter);           /* 16 */

  display: grid;
  grid-template-columns: var(--admin-menu-width) minmax(0, 1fr);
  grid-template-rows: var(--admin-topbar-height) minmax(0, 1fr);
  grid-template-areas:
    "topo  topo"
    "menu  conteudo";
  min-height: 100vh;
}

/* breakpoint.fullhd-painel */
@media (min-width: 85.4375rem) {
  .admin {
    --admin-menu-width: var(--menu-width-fullhd);      /* 320 */
    --admin-gutter: var(--grid-fullhd-painel-margin);  /* 48 */
    --admin-vao: var(--grid-fullhd-painel-gutter);     /* 24 */
  }
}

/* Sem navegação persistente, abaixo de 980. As três áreas empilham e o menu
   deixa de ser coluna — vira o seletor que o bloco do menu descreve. */
@media (max-width: 61.1875rem) {
  .admin {
    --admin-gutter: var(--grid-tablet-margin);         /* 32 */
    --admin-vao: var(--grid-tablet-gutter);            /* 8 */
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "topo"
      "menu"
      "conteudo";
    /* A faixa do menu vale o que ela ocupa; o conteúdo fica com o resto. */
    grid-template-rows: var(--admin-topbar-height) auto minmax(0, 1fr);
  }
  .personalizado { flex-wrap: wrap; }
}

/* breakpoint.mobile */
@media (max-width: 47.9375rem) {
  .admin {
    --admin-gutter: var(--grid-mobile-margin);         /* 16 */
    --admin-vao: var(--grid-mobile-gutter);            /* 8 */
  }
}

/* --- barra superior ---------------------------------------------------- */

/* =========================================================================
   Barra superior e menu FIXOS
   =========================================================================
   Os dois são `position: sticky`, e não `fixed`. A diferença importa:

   - `sticky` mantém as duas peças no fluxo, então o grid continua reservando
     as 320 do menu e as 64 da barra. Com `fixed` elas saem do fluxo e o
     conteúdo passa por baixo, obrigando a repetir as mesmas medidas como
     `margin-left` e `padding-top` — dois lugares para errar quando uma delas
     mudar.
   - A rolagem continua sendo a da JANELA. Um contêiner interno com
     `overflow: auto` tiraria a barra de rolagem do navegador, quebraria a
     restauração de posição ao voltar e, no telefone, impediria a barra de
     endereço de recolher.

   A camada sai de `--level-nav`, que é o degrau que o sistema reserva para
   navegação. O Dropdown está em `--level-flyout` (400), acima — então um
   menu aberto perto do topo passa por cima da barra, como deve.
   ========================================================================= */

.admin__topo {
  grid-area: topo;
  position: sticky;
  inset-block-start: 0;
  z-index: var(--level-nav);

  display: flex;
  align-items: center;
  gap: var(--unit-200);
  padding-inline: var(--unit-400);
  background-color: var(--surface-raised);
  /* Contorno é inset, nunca border: um border muda a caixa e desalinha o
     menu lateral que encosta embaixo. */
  box-shadow: inset 0 -1px 0 0 var(--border-subtle);
}

.admin__marca { display: flex; align-items: center; }
.admin__marca img { display: block; height: 1.125rem; width: auto; }

.admin__topo-fim {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  gap: var(--unit-100);
}

.admin__cliente {
  text-align: end;
  margin-inline-end: var(--unit-150);
  line-height: 1.25;
}
.admin__cliente-rotulo {
  display: block;
  font-size: var(--scale-size-n3);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-subtle);
}
.admin__cliente-nome {
  display: block;
  font-size: var(--scale-size-n1);
  font-weight: var(--weight-bold);
  color: var(--text-body);
}

/* Barra estreita.
   A 320 a barra pedia 436: marca 139, os três botões 140, e o bloco do
   cliente com as folgas no meio. Ela não transbordava de leve — passava 100,
   e o transbordo de um elemento `sticky` arrasta a página inteira para os
   lados, o que estraga toda rolagem vertical no telefone.

   O que sai é o bloco "CLIENTE / Coca-Cola", e não um dos botões: os três
   botões são as únicas saídas da barra — notificação, ajuste e conta — e
   esconder saída é tirar função. O nome do cliente é orientação, não caminho,
   e continua dito pelo botão "Sua conta". A marca fica inteira: encolhê-la
   por 30px trocaria um problema de largura por um logotipo borrado.

   O corte é em 27.5rem, logo abaixo do ponto onde a conta fecha, e não numa
   largura redonda escolhida no olho. */
@media (max-width: 27.5rem) {
  .admin__topo {
    padding-inline: var(--unit-200);
    gap: var(--unit-100);
  }
  .admin__cliente { display: none; }
}

/* --- menu lateral ------------------------------------------------------ */

.admin__menu {
  grid-area: menu;
  position: sticky;
  /* Gruda logo abaixo da barra, e não no topo da janela. */
  inset-block-start: var(--admin-topbar-height);
  z-index: var(--level-nav);
  /* Num grid o item estica para a altura da linha por padrão, e um item
     esticado não tem para onde grudar. `start` mais uma altura definida é o
     que dá folga ao sticky. */
  align-self: start;
  block-size: calc(100vh - var(--admin-topbar-height));
  /* Menu mais alto que a janela rola por dentro de si — sem isto o rodapé
     "Admin Reconhece" ficaria inalcançável em tela baixa. */
  overflow-y: auto;
  overscroll-behavior: contain;

  display: flex;
  flex-direction: column;
  background-color: var(--surface-raised);
  padding-block: var(--unit-200);
}

/* O arquivo desenha a faixa do item com 288 de largura dentro de 320: 16 de
   folga de cada lado. O item do sistema ocupa a largura toda, então a folga
   vem do contêiner.

   Só do contêiner. A folga estava também em `.sysvc-disclosure`, que mora
   DENTRO de `.sysvc-menu` — e aí ela contava duas vezes: item com filhos
   começava 16 à direita do item sem filhos e ficava 32 mais estreito. Numa
   coluna de itens alinhados, quem tem submenu não é um nível abaixo de quem
   não tem: os dois são o primeiro nível. Recuo é dos FILHOS, e esse vem do
   componente. */
.admin__menu .sysvc-menu { padding-inline: var(--unit-200); }
.admin__menu .sysvc-menu-item,
.admin__menu .sysvc-disclosure__trigger {
  min-height: 3rem;
  border-radius: var(--border-50);
}

/* --- o menu flutuante que substitui a coluna ---------------------------
   Abaixo de 980 não há navegação persistente, e a lista não pode virar
   simplesmente um bloco no topo: são cinco entradas de primeiro nível mais
   os filhos de quem tem, e toda tela do painel começaria abaixo da dobra.
   É a mesma conta que a Loja fez com quatro linhas.

   A peça é um POPUP, e o desenho dela está no fim deste arquivo. Os dois
   menus existem no HTML o tempo todo e trocam por `display`, e não por
   JavaScript: uma casca que reescreve o próprio menu no `resize` é a
   origem do estado perdido no meio de um giro de tela. */

@media (max-width: 61.1875rem) {
  /* Empilhado, o menu deixa de ser coluna e vira faixa acima do conteúdo:
     não há coluna para ele acompanhar, e 100vh de altura empurraria o
     conteúdo para fora da primeira tela. A barra superior continua fixa —
     essa vale em qualquer largura.

     O `z-index: auto` é obrigatório, e não arrumação: ITEM DE GRID honra
     z-index mesmo sendo `static` — a regra vale para flex e grid, não só
     para elementos posicionados. Só com `position: static` o menu continuava
     abrindo uma camada em 200 e passando por cima da barra fixa. */
  .admin__menu {
    position: static;
    z-index: auto;
    block-size: auto;
    overflow: visible;
    padding: var(--unit-200) var(--admin-gutter);
    /* Empilhado, o que separa o menu do conteúdo é um fio, e não a coluna. */
    box-shadow: inset 0 -1px 0 0 var(--border-subtle);
  }
  /* Prefixo .admin por especificidade: a regra base de .admin__rodape vem
     DEPOIS no arquivo e, com o mesmo peso, vencia — medido, o rodapé
     continuava visível a 900. */
  /* A COLUNA some e o flutuante entra no lugar. `> .sysvc-menu` é filho
     DIRETO de propósito: o menu de dentro do flutuante também é um
     `.sysvc-menu` dentro de `.admin__menu`, e sem o filho direto esta
     regra o escondia junto — o flutuante abria vazio.

     Prefixo .admin por especificidade no rodapé: a regra base dele vem
     DEPOIS no arquivo e, com o mesmo peso, vencia — medido, o rodapé
     continuava visível a 900. */
  .admin__menu > .sysvc-menu,
  .admin .admin__rodape { display: none; }
}

.admin__rodape {
  margin-block-start: auto;
  display: flex;
  align-items: center;
  gap: var(--unit-100);
  padding: var(--unit-200) var(--unit-400);
  font-size: var(--scale-size-n3);
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--color-grey-500);
}

/* --- conteúdo ---------------------------------------------------------- */

/* O ritmo VERTICAL não é a margem lateral: com a margem do fullhd-painel
   valendo nos quatro lados, o título descia 48 da barra. 32 acima e 64
   antes do fim é o mesmo ritmo que a Loja dá ao corpo do painel. */
.admin__conteudo {
  grid-area: conteudo;
  padding: var(--unit-400) var(--admin-gutter) var(--unit-800);
  min-width: 0;
}

.pagina { max-width: 66rem; }

.pagina__titulo {
  /* O arquivo pinta o título em #44546F — grey.900, que é o valor de
     --text-body. Não é o ink de --text-title, e a diferença é visível. */
  color: var(--text-body);
  margin-block-end: var(--unit-200);
}

.pagina__intro {
  max-width: var(--text-measure);
  color: var(--text-body);
  margin: 0 0 var(--unit-400);
}

.pagina__secao-rotulo {
  display: block;
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
  color: var(--text-subtle);
  margin-block-end: var(--unit-150);
  transition: opacity 160ms ease;
}

/* =========================================================================
   Cartão de pacote
   =========================================================================
   Um radio com corpo grande. O <input> de verdade cobre o cartão inteiro: as
   setas do teclado percorrem os quatro pacotes e o leitor de tela anuncia
   "opção 2 de 4". Nada de div com onClick.

   Anatomia, em duas partes:

     .pacote__topo         quantidade + disco do ícone — sempre visível
     .pacote__prateleira   faixa de preço no pé — SÓ no cartão escolhido

   Por que a prateleira é condicional: com quatro preços na tela ao mesmo
   tempo, a pergunta que o olho responde primeiro passa a ser "qual é o mais
   barato", e não "de quantos pontos eu preciso". O preço não some — ele
   espera a escolha, e aí confirma. Como a lista fica compacta em repouso, os
   quatro pacotes cabem numa linha só e a comparação é entre quantidades.

   O crescimento é do cartão escolhido, sozinho: a linha usa
   `align-items: flex-start`, então os irmãos não esticam junto e não sobra um
   vazio embaixo de cada um.
   ========================================================================= */

.pacotes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--unit-200);          /* 16 — o vão entre os rects do arquivo */
  align-items: flex-start;
  margin: 0;
  /* Folga em cima para o selo do recomendado, que sobe além da borda. */
  padding: var(--unit-150) 0 0;
  border: 0;
}

.pacote {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 10rem;                  /* 160 */
  border-radius: var(--border-100);   /* 8 */
  background-color: var(--surface-raised);
  box-shadow: inset 0 0 0 var(--stroke-rest) var(--color-grey-400);
  /* Sem `overflow: hidden` aqui: o selo do recomendado cavalga a borda de
     cima e seria decepado. Quem arredonda o pé é a própria prateleira. */
  cursor: pointer;
  transition:
    background-color 160ms ease,
    box-shadow 160ms ease,
    opacity 160ms ease;
}

.pacote__input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: inherit;
}

/* --- topo -------------------------------------------------------------- */

.pacote__topo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--unit-100);
  padding: var(--unit-250) var(--unit-100) var(--unit-200);
}

/* O arquivo desenha o número em ~40px, que não é degrau da escala. Fica no
   36 (scale.size.5): o degrau existente mais próximo, porque sair da escala
   para ganhar 4px seria trocar o sistema por um pixel. */
.pacote__numero {
  font-size: var(--scale-size-5);      /* 36 */
  line-height: var(--scale-height-5);  /* 43 */
  font-weight: var(--weight-bold);
  color: var(--text-link);             /* #1C40A9, do arquivo */
  letter-spacing: -.01em;
}
.pacote__unidade {
  margin-block-start: calc(var(--unit-100) * -1);
  font-size: var(--scale-size-05);     /* 18 */
  line-height: var(--scale-height-05);
  font-weight: var(--weight-bold);
  color: var(--text-link);
}

/* O disco do ícone — a moeda do pacote. É desenho, não controle: quem recebe
   o clique é o input que cobre o cartão. */
.pacote__disco {
  display: grid;
  place-items: center;
  width: var(--unit-500);        /* 40 */
  height: var(--unit-500);
  border-radius: 50%;
  box-shadow: inset 0 0 0 var(--stroke-rest) var(--border-default);
  color: var(--text-body);
  transition: box-shadow 160ms ease, color 160ms ease;
}
.pacote__disco svg {
  width: var(--icon-grid-small);  /* 20 */
  height: var(--icon-grid-small);
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --- prateleira de preço ------------------------------------------------ */

.pacote__prateleira {
  display: block;
  padding: var(--unit-150);
  background-color: var(--surface-page);
  box-shadow: inset 0 1px 0 0 var(--border-subtle);
  border-end-start-radius: var(--border-100);
  border-end-end-radius: var(--border-100);
  text-align: end;
}
.pacote__prateleira[hidden] { display: none; }

.pacote__prateleira-rotulo {
  display: block;
  font-size: var(--scale-size-n2);   /* 12 */
  line-height: var(--scale-height-n2);
  color: var(--text-subtle);
}
.pacote__preco-valor {
  display: block;
  font-size: var(--scale-size-1);    /* 22 */
  line-height: var(--scale-height-1);
  font-weight: var(--weight-bold);
  color: var(--text-link);
}
.pacote__preco-conta {
  display: block;
  margin-block-start: var(--unit-50);
  font-size: var(--scale-size-n2);
  line-height: var(--scale-height-n2);
  color: var(--text-subtle);
}

/* --- selo do recomendado ------------------------------------------------
   Cavalga a borda de cima, centrado. A cor é brand.primary, e não a magenta
   do print: magenta é brand.tertiary, que no sistema pertence à Loja — selo
   de campanha e vitrine. Aqui é ação de sistema no painel, e a regra diz que
   magenta nunca entra em ação de sistema. */

.pacote--recomendado {
  box-shadow: inset 0 0 0 var(--stroke-selected) var(--accent);
}

.pacote__selo {
  position: absolute;
  inset-block-start: calc(var(--unit-150) * -1);
  inset-inline-start: 50%;
  transform: translateX(-50%);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: var(--unit-50);
  height: var(--unit-300);            /* 24 */
  padding-inline: var(--unit-100);
  border-radius: var(--border-full);
  background-color: var(--accent);
  color: var(--text-negative);
  font-size: var(--scale-size-n3);    /* 11 */
  line-height: 1;
  font-weight: var(--weight-bold);
  text-transform: uppercase;
  letter-spacing: .06em;
  white-space: nowrap;
}
.pacote__selo svg {
  width: var(--unit-150);
  height: var(--unit-150);
  fill: none;
  stroke: currentColor;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* --- estados ------------------------------------------------------------ */

.pacote:hover { background-color: var(--color-grey-50); }

.pacote:has(.pacote__input:checked) {
  background-color: var(--color-teal-100);   /* #DDF7F9, do arquivo */
  box-shadow: inset 0 0 0 var(--stroke-selected) var(--brand-secondary-default);
}
.pacote:has(.pacote__input:checked) .pacote__disco {
  box-shadow: inset 0 0 0 var(--stroke-selected) var(--brand-secondary-default);
  color: var(--brand-secondary-bold);
}
/* Sobre o fundo teal do escolhido a prateleira precisa continuar sendo uma
   faixa: volta ao branco do cartão em vez do cinza da página. */
.pacote:has(.pacote__input:checked) .pacote__prateleira {
  background-color: var(--surface-raised);
  box-shadow: inset 0 1px 0 0 var(--brand-secondary-light);
}

.pacote:has(.pacote__input:focus-visible) {
  box-shadow:
    inset 0 0 0 var(--stroke-selected) var(--border-focus),
    0 0 0 var(--stroke-focus) var(--surface-page),
    0 0 0 calc(var(--stroke-focus) * 2) var(--border-focus);
}

/* =========================================================================
   Apagado
   =========================================================================
   As duas entradas são exclusivas: escolher um pacote apaga o campo, e
   digitar um valor apaga os pacotes. O arquivo mostra isso como opacidade, e
   não como desabilitado — a peça continua clicável, e clicar nela é o
   caminho de volta. Por isso é opacidade, e não [disabled]: um controle
   desabilitado não pode ser o desfazer de si mesmo.
   ========================================================================= */

[data-apagado="true"] { opacity: .45; }
[data-apagado="true"]:hover,
[data-apagado="true"]:focus-within { opacity: 1; }

/* =========================================================================
   Valor personalizado
   ========================================================================= */

.personalizado {
  display: flex;
  align-items: flex-start;
  gap: var(--unit-200);
  margin-block-start: var(--unit-300);
}

.personalizado__campo { width: 20.25rem; }   /* 324 — do rect do arquivo */

.personalizado__saida {
  display: flex;
  align-items: center;
  gap: var(--unit-100);
  min-height: 4.5rem;                        /* alinha com os 72 do campo */
  font-size: var(--text-ui-size);
  color: var(--text-subtle);
}
.personalizado__saida[hidden] { display: none; }

.personalizado__valor {
  font-size: var(--scale-size-05);
  font-weight: var(--weight-bold);
  color: var(--text-link);
}

/* O giro de cálculo do arquivo: 32px, traço de 3, marca em cima do trilho. */
.girinho {
  width: var(--unit-400);
  height: var(--unit-400);
  border: 3px solid var(--color-grey-300);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: girar 700ms linear infinite;
}
@keyframes girar { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .girinho { animation-duration: 2s; } }

/* =========================================================================
   Rodapé de ação
   ========================================================================= */

.pagina__acoes { margin-block-start: var(--unit-400); }

/* =========================================================================
   TELA 4 — Pedidos
   =========================================================================
   A barra de ações acima da tabela, do padrão do admin: a ação à esquerda e
   o filtro empurrado para a direita. `margin-inline-start: auto` no filtro,
   e não `justify-content: space-between` na barra — com um item só, o
   space-between deixaria a ação sozinha na esquerda de qualquer jeito, e no
   dia em que entrar um terceiro botão ele se espalharia no meio.
   ========================================================================= */

.lista-acoes {
  display: flex;
  align-items: center;
  gap: var(--unit-200);
  flex-wrap: wrap;
  margin-block-end: var(--unit-300);
}

/* Um controle que assume não fazer nada, enquanto houver algum. Vale para
   qualquer [aria-disabled] do painel: melhor um botão apagado do que um de
   aparência normal que não responde. */
[aria-disabled="true"].sysvc-button {
  opacity: .55;
  cursor: not-allowed;
}

/* O botão que abre o filtro fica marcado quando o painel está aberto. */
.lista-acoes [data-abre-filtro] { margin-inline-start: auto; }
[data-abre-filtro][aria-expanded="true"] {
  background-color: var(--button-surface-text-hovered);
}

/* A tabela é a peça mais larga da tela e não cabe nas 982 do resto: ela usa
   a coluna inteira do conteúdo. O `--checkout` limita as telas de compra,
   onde a leitura é de um formulário; uma tabela quer largura. */
.pagina--checkout:has(.sysvc-table-wrap) { max-width: none; }
/* A nota do simulador continua com medida de leitura — ela é texto corrido
   e não acompanha a tabela. */
.pagina--checkout:has(.sysvc-table-wrap) .simulador-nota { max-width: var(--text-measure); }

/* =========================================================================
   Filtro de Pesquisa — o painel das duas tabelas
   =========================================================================
   Do arquivo: cartão de 950 × 335 com sombra, título, rótulo de seção,
   divisória recuada 16, campos numa linha e as duas ações no pé.

   O cartão FLUTUA sobre a tabela, como no arquivo: abrir o filtro não
   empurra nada, e a tabela continua exatamente onde estava.

   Três consequências de flutuar, e o que cada uma exigiu:

   1. **Precisa de âncora.** `position: absolute` procura o ascendente
      posicionado mais próximo; sem `.tabela-bloco { position: relative }` o
      painel se penduraria na página inteira e apareceria no lugar errado ao
      rolar.
   2. **Precisa de camada.** `--level-card` (100), e não `--level-overlay`
      (300): o painel passa por cima da tabela, mas continua PASSANDO POR
      BAIXO da barra superior e do menu, que estão em `--level-nav` (200).
      Um filtro que cobre a navegação ao rolar seria pior que o problema que
      ele resolve.
   3. **Precisa fechar clicando fora.** Um painel que empurra pode ficar
      aberto sem incomodar; um que cobre, não — quem clica na tabela embaixo
      está pedindo para sair dele.
   ========================================================================= */

/* A âncora do painel: envolve a barra de ações e a tabela. */
.tabela-bloco { position: relative; }

/* =========================================================================
   Filtros de pesquisa — a anatomia da Loja
   =========================================================================
   As classes são as mesmas da loja (`filtro-flutuante__*`, `filtros__*`),
   porque a peça é a mesma. O que este arquivo compõe é só o que o admin tem
   de diferente: o gatilho mora numa BARRA DE AÇÕES (`.lista-acoes`) junto
   com "Comprar pontos" ou "Adicionar campanha", e não sozinho acima da
   tabela como na loja.

   Por isso a superfície NÃO leva o `inset-block-start: calc(100% + 8px)` da
   loja: lá a âncora é o `.filtros` que embrulha só o gatilho, e 100% cai
   logo abaixo dele. Aqui a âncora é o `.tabela-bloco`, que embrulha a barra,
   os chips e a tabela inteira — 100% cairia abaixo da última linha. A
   superfície fica onde o fluxo a colocou, que é exatamente sob a barra, e os
   8 de folga vêm de uma margem.
   ========================================================================= */

/* Aberto, o gatilho NÃO engorda. O Accordion cresce de 48 para 64 quando o
   cabeçalho expande, porque ali o painel mora dentro do cartão e ele deixa
   de ser uma linha. Aqui o painel flutua, e o cartão continua sendo só o
   gatilho: os 16 a mais empurravam a barra de ações toda vez que o filtro
   abria — justamente o que o painel flutuante veio evitar. */
.filtro-flutuante__gatilho:has(.sysvc-accordion__header[aria-expanded="true"]) > .sysvc-accordion__header {
  min-height: calc(var(--accordion-height) - var(--accordion-border) * 2);
  padding-block: var(--accordion-padding-block);
}
/* Numa barra de ações o gatilho não estica: ele vale o que o rótulo pede. */
.lista-acoes .filtro-flutuante__gatilho,
.campanhas-topo .filtro-flutuante__gatilho { flex: 0 1 auto; min-inline-size: 15rem; }

.filtros__conta { margin-inline-start: var(--unit-100); vertical-align: middle; }

.filtro-flutuante__superficie {
  position: absolute;
  inset-inline: 0;
  z-index: var(--level-card);
  margin-block-start: var(--unit-100);
  padding: var(--unit-300);
  border-radius: var(--border-100);
  background-color: var(--surface-raised);
  /* A sombra é o que diz "isto está acima". Com o painel encostado na
     tabela e sem sombra, os dois leriam como uma peça só. */
  box-shadow: var(--shadow-overlay);
}
.filtro-flutuante__superficie[hidden] { display: none; }

/* A grade dos grupos — DISTRIBUÍDA NA HORIZONTAL.
   =========================================================================
   São poucos recortes: um período e uma lista curta de situações. Em pé,
   eles ocupavam a altura da superfície e deixavam a metade direita vazia —
   uma folha de 960 de largura com duas linhas de 40 empilhadas à esquerda.

   É FLEX, e não grid com `auto-fit`. A tentativa com
   `repeat(auto-fit, minmax(18rem, 1fr))` numa folha de 1047 gerou TRÊS
   trilhas de 312 para DOIS grupos, e a terceira ficou vazia: `auto-fit` só
   recolhe a trilha sem nenhum item, e a linha dos botões, que atravessa de
   ponta a ponta, ocupa todas. O resultado era o mesmo vazio à direita que a
   grade em pé tinha, só que menor.

   Com flex o número de colunas não é calculado: cada grupo pede 18rem e
   CRESCE para dividir o que sobrar. Dois grupos viram duas metades; três
   virariam três terços; e quando a folha encolhe abaixo de dois pisos, a
   linha quebra sozinha e eles empilham — sem um segundo breakpoint.

   O piso é 18rem porque é o que o grupo mais exigente pede: as duas datas
   lado a lado, com o rótulo "dd/mm/aaaa" inteiro em cada uma. Abaixo disso
   elas quebram, e um campo de data quebrado é pior que uma coluna a menos.

   As classes continuam as da loja; o que muda é o display, e nenhuma regra
   de lá dependia dele.                                                    */
.filtros__grade {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--unit-250) var(--unit-400);
}
/* `1 1 18rem`: cresce para dividir a sobra, encolhe até o piso, e o piso é a
   base da distribuição — não uma largura fixa disfarçada. */
.filtros__grupo { flex: 1 1 18rem; margin: 0; padding: 0; border: 0; min-width: 0; }

.filtros__legenda {
  padding: 0;
  margin-block-end: var(--unit-100);
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-line);
  font-weight: var(--weight-bold);
  color: var(--text-subtle);
  text-transform: uppercase;
  letter-spacing: .05em;
}

/* O FIO ENTRE OS GRUPOS SAIU com a grade horizontal, e não por descuido.
   Lado a lado, um fio embaixo de cada grupo desenha duas réguas soltas na
   altura de quem tem mais conteúdo, e elas não separam nada: o que separa
   duas colunas é o vão entre elas, que aqui é 32.

   O fio que ficou é o de CIMA da linha dos botões, e esse tem trabalho:
   separa os controles da ação, que é uma fronteira de assunto e não de
   arrumação. Ele pode vir em cima porque a linha dos botões não tem
   `<legend>` — e é por causa da legend que o fio dos grupos tinha de ficar
   no fim do anterior: o navegador desenha a legenda sobre a borda superior
   do fieldset, e uma linha ali corta o rótulo ao meio. */
.filtros__acoes {
  /* Linha inteira, sempre: `100%` de base com `flex-grow: 0` força a quebra
     antes dela, e os botões nunca sobem para o lado de um grupo. */
  flex: 0 0 100%;
  display: flex;
  justify-content: flex-start;
  gap: var(--unit-100);
  padding-block-start: var(--unit-250);
  box-shadow: inset 0 1px 0 0 var(--border-subtle);
}

/* As duas datas dividem a coluna por igual. O teto de leitura saiu: quem
   limita a largura agora é a própria coluna da grade, e um segundo teto por
   dentro deixaria um vazio à direita do grupo.

   O PISO DE 11rem é o que o campo de data precisa, e ele vem do navegador,
   não do sistema: `type="date"` desenha a máscara dd/mm/aaaa mais o botão do
   calendário por conta própria, e abaixo de uns 176 o Chrome corta o texto —
   "dd/mm/a". E ele corta em SILÊNCIO: `scrollWidth` continua igual a
   `clientWidth`, então nenhuma medida do DOM acusa o transbordo. Só a tela.

   Com o piso e a quebra, o par desce para duas linhas antes de encolher
   demais — uma data em duas linhas é legível; uma data cortada, não. */
.filtros__faixa { display: flex; flex-wrap: wrap; gap: var(--unit-150); }
.filtros__faixa .sysvc-field { flex: 1 1 11rem; min-width: 0; }

/* As caixas correm na HORIZONTAL, quebrando linha quando faltar espaço: são
   poucas opções curtas, e em pé ocupavam a altura do painel. */
.filtro__caixas {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--unit-150) var(--unit-300);
}

/* O rótulo do campo de data não encolhe sozinho: `type="date"` mostra a
   máscara dd/mm/aaaa mesmo vazio, então nunca há `:placeholder-shown` e o
   estado "filled" do campo não chega pelo caminho normal. */
.filtro__data .sysvc-field__label {
  font-size: var(--field-label-size-active);
  line-height: var(--field-label-height-active);
}

/* Estreito, o painel volta ao FLUXO. Não é preferência: flutuando, um cartão
   mais alto que a janela fica com o rodapé — e portanto os botões Filtrar e
   Limpar — fora de alcance, porque `absolute` não rola com a página.

   `relative`, e não `static`: no fluxo os dois desenham a mesma caixa, mas
   z-index só vale em elemento posicionado, e sem ele o véu do menu (350)
   cobriria o painel que veio destacar. Aqui a peça precisa das duas coisas —
   rolar com a página e ficar acima da tinta —, e `relative` é a única que dá
   as duas. */
@media (max-width: 47.9375rem) {
  .filtro-flutuante__superficie {
    position: relative;
    margin-block-end: var(--unit-200);
  }
  .lista-acoes .filtro-flutuante__gatilho,
  .campanhas-topo .filtro-flutuante__gatilho { inline-size: 100%; }
}

/* =========================================================================
   TELA 5 — Extrato de pontos
   ========================================================================= */

/* A faixa de resumo do arquivo: pares rótulo em caixa alta e valor grande,
   lado a lado. Mesma gramática do Recibo — rótulo 12/16 cinza, valor bold —
   porque é a mesma pergunta: "que dado é este, e qual o valor dele". */
.extrato-resumo {
  display: flex;
  flex-wrap: wrap;
  gap: var(--unit-400) var(--unit-800);
  margin: 0 0 var(--unit-300);
  padding: var(--unit-300);
  border-radius: var(--border-50);
  background-color: var(--surface-raised);
  box-shadow: var(--shadow-raised);
}
.extrato-resumo__par > dt {
  font-size: var(--receipt-label-size);
  line-height: var(--receipt-label-line);
  letter-spacing: var(--receipt-label-tracking);
  text-transform: uppercase;
  color: var(--receipt-label-color);
}
.extrato-resumo__par > dd {
  margin: var(--unit-50) 0 0;
  font-size: var(--scale-size-2);       /* 24 */
  line-height: var(--scale-height-2);
  font-weight: var(--weight-bold);
  color: var(--text-body);
  font-variant-numeric: tabular-nums;
}
/* O saldo é o número que a pessoa veio ver. Único em cor de marca — dois
   números destacados seriam dois saldos. */
.extrato-resumo__saldo { color: var(--text-link); }

/* A barra branca de 982 × 64 do arquivo. */
.extrato-barra {
  display: flex;
  align-items: center;
  gap: var(--unit-200);
  flex-wrap: wrap;
  min-height: var(--unit-800);          /* 64 */
  margin-block-end: var(--unit-200);
  padding: var(--unit-100) var(--unit-200);
  border-radius: var(--border-50);
  background-color: var(--surface-raised);
  box-shadow: var(--shadow-raised);
}
.extrato-barra [data-abre-filtro] { margin-inline-start: auto; }

.extrato-exibir {
  display: flex;
  align-items: center;
  gap: var(--unit-150);
  font-size: var(--text-ui-size);
  color: var(--text-body);
}
/* O campo encolhe para caber dois dígitos e a seta, e nada mais: o Dropdown
   nasce ocupando a largura do contêiner, que aqui seria a barra inteira. */
.extrato-exibir__campo { inline-size: 6.5rem; }
.extrato-exibir__campo .sysvc-field__box { min-height: var(--unit-600); }

/* A direção do movimento. A cor REFORÇA o que a coluna "Tipo de registro" já
   diz por escrito — ela nunca é a única pista, então quem não distingue
   verde de vermelho continua lendo o extrato. */
.movimento--entra { color: var(--alert-success-bold); font-weight: var(--weight-bold); }
.movimento--sai   { color: var(--text-danger);        font-weight: var(--weight-bold); }

/* =========================================================================
   TELA 6 — Dashboard
   =========================================================================
   Composição, como o resto deste arquivo: nenhum token novo é definido aqui.
   As cores dos minigráficos saem de tokens semânticos que já existem — o
   sistema não tem tokens de visualização de dados, e isso está registrado no
   README como lacuna.
   ========================================================================= */

/* O dashboard é uma tela de faixas largas, e não de formulário: as 66rem de
   `.pagina` cortariam o carrossel bem no ponto em que ele precisa mostrar
   que continua. */
.pagina--dashboard { max-width: none; }

.painel-inicial__saudacao {
  color: var(--text-subtle);
  font-size: var(--heading-sm-size);
  line-height: var(--heading-sm-line);
  margin: calc(var(--unit-100) * -1) 0 var(--unit-500);
}

/* --- seção ---------------------------------------------------------------
   O rótulo em caixa alta com a régua embaixo, do arquivo. É um <h2> de
   verdade — a caixa alta é da CLASSE, não do texto digitado, senão o leitor
   de tela soletra "C-A-M-P-A-N-H-A-S". */
.secao { margin-block-start: var(--unit-600); }

.secao__titulo {
  font-family: var(--family-ui);
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
  font-weight: var(--weight-bold);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-subtle);
  margin: 0 0 var(--unit-150);
  padding-block-end: var(--unit-150);
  border-block-end: var(--stroke-100) solid var(--border-subtle);
}

.secao__controle { margin-block-end: var(--unit-300); }

/* --- carrossel -----------------------------------------------------------
   As duas faixas rolam no eixo horizontal, como no arquivo: o último cartão
   fica cortado na borda, e é esse corte que diz que a lista continua.

   `scroll-snap` para o arrasto parar em cartão inteiro, e não no meio de um.
   O contêiner é focável (tabindex no HTML) porque uma região que rola e não
   recebe foco é inalcançável por teclado — o navegador não dá rolagem de
   graça a quem não pode focar. */
/* O vão entre cartões é o GUTTER da faixa, e não um 16 fixo: 8 no telefone
   e no tablet, 16 no HD, 24 no FullHD. Era o último lugar do admin onde uma
   medida de grade estava escrita à mão. */
.carrossel {
  display: flex;
  align-items: stretch;
  gap: var(--admin-vao);
  overflow-x: auto;
  scroll-snap-type: x proximate;
  overscroll-behavior-inline: contain;
  padding-block-end: var(--unit-200);
}

.carrossel:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--stroke-focus) var(--border-focus);
  border-radius: var(--border-50);
}

.carrossel__lista {
  display: contents;
}

.carrossel > *,
.carrossel__lista > * {
  flex: 0 0 auto;
  scroll-snap-align: start;
}

/* A barra de rolagem é desenhada no arquivo, então ela fica visível — não é
   um carrossel que esconde o próprio controle. */
.carrossel::-webkit-scrollbar { height: var(--unit-100); }
.carrossel::-webkit-scrollbar-track {
  background-color: var(--color-grey-50);
  border-radius: var(--border-full);
}
.carrossel::-webkit-scrollbar-thumb {
  background-color: var(--color-grey-300);
  border-radius: var(--border-full);
}
.carrossel { scrollbar-width: thin; }

.carrossel__vazio {
  margin: 0 0 var(--unit-200);
  color: var(--text-subtle);
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
}

/* --- cartão de contagem --------------------------------------------------
   O único cartão colorido da faixa (teal.100 no arquivo). Ele não é uma
   campanha: é o resumo dela, e por isso não repete a anatomia dos vizinhos. */
.contagem {
  display: flex;
  flex-direction: column;
  justify-content: center;
  inline-size: 9.625rem;          /* 154 do arquivo */
  min-block-size: 7.625rem;       /* 122 do arquivo */
  padding: var(--unit-250);
  border-radius: var(--border-50);
  background-color: var(--brand-secondary-low-contrast);
  box-shadow: inset 0 0 0 var(--stroke-100) var(--brand-secondary-mid-contrast);
}

.contagem__rotulo {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-line);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-body);
}

.contagem__numero {
  font-size: var(--scale-size-5);
  line-height: var(--scale-height-5);
  font-weight: var(--weight-bold);
  color: var(--text-title);
}

.contagem__unidade {
  font-size: var(--scale-size-1);
  line-height: var(--scale-height-1);
  color: var(--text-title);
}

/* --- cartão de campanha -------------------------------------------------- */
.campanha {
  display: flex;
  flex-direction: column;
  gap: var(--unit-100);
  inline-size: 17.4375rem;        /* 279 do arquivo, o mais largo dos dois */
  min-block-size: 7.625rem;
  padding: var(--unit-250);
  border-radius: var(--border-50);
  background-color: var(--surface-raised);
  box-shadow: inset 0 0 0 var(--stroke-100) var(--border-subtle);
}

.campanha__topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--unit-200);
}

.campanha__nome {
  margin: 0;
  font-family: var(--family-ui);
  font-size: var(--scale-size-1);
  line-height: var(--scale-height-1);
  font-weight: var(--weight-bold);
  color: var(--text-title);
}

.campanha__inicio {
  margin: 0;
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  color: var(--text-body);
}

/* Empurrado para o pé: nos dois cartões o número de participantes precisa
   cair na mesma linha, mesmo que um nome de campanha ocupe duas. */
.campanha__participantes {
  margin: auto 0 0;
  font-size: var(--scale-size-1);
  line-height: var(--scale-height-1);
  font-weight: var(--weight-bold);
  color: var(--text-title);
}

/* --- adicionar campanha --------------------------------------------------
   Cartão de ação, cinza (grey.50 no arquivo) e sem sombra: ele é o convite
   no fim da fila, não mais um item dela. */
.adicionar {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--unit-100);
  /* O 239 do arquivo é piso, e não teto: o rótulo fica numa linha só em
     qualquer resolução, e se a fonte crescer o cartão cresce junto em vez de
     quebrar a frase em duas. */
  min-inline-size: 14.9375rem;    /* 239 do arquivo */
  min-block-size: 7.625rem;
  padding: var(--unit-250);
  border-radius: var(--border-50);
  background-color: var(--color-grey-50);
  box-shadow: inset 0 0 0 var(--stroke-100) var(--border-subtle);
  color: var(--text-title);
  text-decoration: none;
  transition: background-color 140ms ease;
}

.adicionar:hover { background-color: var(--button-surface-text-hovered); }
.adicionar:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 var(--stroke-focus) var(--border-focus);
}

.adicionar__icone {
  inline-size: var(--icon-grid);
  block-size: var(--icon-grid);
  stroke-width: var(--icon-stroke);
}

.adicionar__rotulo {
  font-size: var(--scale-size-1);
  line-height: var(--scale-height-1);
  font-weight: var(--weight-bold);
  /* Numa linha só: é rótulo de ação curto, e quebrado em duas ele desalinha
     do "+" e da altura dos vizinhos da faixa. */
  white-space: nowrap;
}

/* --- painel de extrato --------------------------------------------------- */
.painel {
  display: flex;
  flex-direction: column;
  inline-size: 23.375rem;         /* 374 do arquivo */
  min-block-size: 13.625rem;      /* 218 do arquivo */
  padding: var(--unit-250);
  border-radius: var(--border-50);
  background-color: var(--surface-raised);
  box-shadow: inset 0 0 0 var(--stroke-100) var(--border-subtle);
}

.painel__topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--unit-200);
}

.painel__rotulo {
  margin: 0;
  font-family: var(--family-ui);
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
  font-weight: var(--weight-bold);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-subtle);
}

.painel__corpo {
  display: flex;
  align-items: center;
  gap: var(--unit-200);
  margin-block: var(--unit-150) auto;
}

.painel__numeros { flex: 0 0 auto; }

.painel__apoio {
  display: block;
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  color: var(--text-subtle);
}

.painel__valor {
  display: block;
  font-size: var(--scale-size-5);
  line-height: var(--scale-height-5);
  font-weight: var(--weight-bold);
  color: var(--text-title);
  /* O número troca por bolinhas ao esconder, e trocar texto muda a largura.
     A tabular impede que o cartão inteiro pule ao alternar. */
  font-variant-numeric: tabular-nums;
}

.painel__unidade {
  display: block;
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-body);
}

/* O gráfico ocupa o que sobra e encolhe junto com o cartão. `min-inline-size:
   0` porque item de flex não encolhe abaixo do conteúdo sem isso — e o SVG
   acha que seu conteúdo é a largura inteira. */
.painel__area-grafico {
  display: flex;
  gap: var(--unit-100);
  flex: 1 1 auto;
  min-inline-size: 0;
}

.painel__eixo,
.painel__meses {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-line);
  color: var(--text-subtle);
}

.painel__eixo {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  text-align: end;
  /* Alinha com a área desenhada, não com a caixa toda: o eixo do arquivo
     começa no topo da curva e termina na base dela. */
  padding-block: 0 var(--text-caption-line);
}

.painel__plotagem {
  flex: 1 1 auto;
  min-inline-size: 0;
}

.painel__meses {
  display: flex;
  justify-content: space-between;
}

.painel__grafico {
  display: block;
  inline-size: 100%;
  /* A mesma variável que a área sensível dos meses usa para saber até onde
     subir. Dois números escritos à mão descolariam no dia em que um mudasse. */
  block-size: var(--painel-grafico-altura);
}

.painel__grafico-linha { stroke-width: 2; }

/* Os três tons. `data-tom` no cartão e não classe solta: o tom é do painel
   inteiro, e amanhã ele pode pintar mais que a curva. */
.painel[data-tom="primaria"]   .painel__grafico-linha { stroke: var(--brand-primary-default); }
.painel[data-tom="primaria"]   .painel__grafico-area  { fill: var(--brand-primary-low-contrast); }
.painel[data-tom="sucesso"]    .painel__grafico-linha { stroke: var(--alert-success-default); }
.painel[data-tom="sucesso"]    .painel__grafico-area  { fill: var(--alert-success-low-contrast); }
.painel[data-tom="secundaria"] .painel__grafico-linha { stroke: var(--brand-secondary-bold); }
.painel[data-tom="secundaria"] .painel__grafico-area  { fill: var(--brand-secondary-low-contrast); }

/* Com o valor escondido o gráfico some junto. Esconder o número e deixar a
   curva seria esconder metade: a curva mostra a ordem de grandeza e a
   tendência, que é boa parte do que a pessoa está protegendo. */
.painel[data-oculto="true"] .painel__area-grafico { visibility: hidden; }

.painel__pe {
  margin-block-start: var(--unit-150);
  padding-block-start: var(--unit-150);
  border-block-start: var(--stroke-100) solid var(--border-subtle);
  text-align: center;
}

/* --- estreito ------------------------------------------------------------
   Abaixo de 48rem os painéis passam a caber inteiros: um cartão de 374 numa
   tela de 375 rola para sempre. Eles encolhem e o carrossel vira lista. */
@media (max-width: 47.9375rem) {
  .carrossel { flex-wrap: wrap; overflow-x: visible; }
  .painel,
  .campanha,
  .adicionar,
  .contagem { inline-size: 100%; }
  /* O piso de 239 sairia da tela num aparelho de 375 menos as margens. */
  .adicionar { min-inline-size: 0; }
}

/* =========================================================================
   Nota do simulador — não faz parte do produto
   ========================================================================= */

.simulador-nota {
  margin-block-start: var(--unit-600);
  padding: var(--unit-200);
  border-radius: var(--border-100);
  background-color: var(--surface-raised);
  box-shadow: inset var(--stroke-band) 0 0 0 var(--brand-secondary-default);
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-line);
  color: var(--text-subtle);
  max-width: var(--text-measure);
}
.simulador-nota strong { color: var(--text-body); }
.simulador-nota p { margin: 0 0 var(--unit-100); }
.simulador-nota p:last-child { margin-block-end: 0; }

/* =========================================================================
   TELA 2 — Método de pagamento
   =========================================================================
   Geometria do arquivo (Compra Pontos-1.svg):
     régua sob os breadcrumbs em y=135.5, de x=352 a x=1334 — 982 de largura
     segunda régua em y=261.5, entre o subtítulo e as linhas
     linhas de método: x=352, 600 × 48, raio 8, vão de 16
     carrinho: x=984, 350 × 186, raio 4 — vão de 32 entre as colunas
   600 + 32 + 350 = 982. As duas colunas fechavam a régua.

   > Divergência registrada: essas três medidas eram do arquivo a 1366, com
   > um menu de 320. Desde que a casca passou a usar os breakpoints do
   > sistema — menu de 240 no HD — nenhuma delas descreve mais a tela: a
   > área útil mudou, e a coluna de apoio virou o PAINEL do grid (288 no HD,
   > 320 no FullHD). O teto de 982 saiu junto; o checkout usa o mesmo teto
   > de leitura das outras telas do painel, e quem dá a largura das colunas
   > são os tokens.
   ========================================================================= */

.pagina__regua {
  height: 0;
  margin: var(--unit-200) 0;
  border: 0;
  border-block-start: var(--stroke-100) solid var(--color-grey-400);
}

.pagina__migalhas { margin-block-end: var(--unit-150); }

/* =========================================================================
   O fluxo de compra — duas colunas, como na Loja de Resgate
   =========================================================================
   A COLUNA DA DIREITA É O PAINEL DO GRID DO SISTEMA, e passou a ser em
   30/09/2026. Antes era `21.875rem` — 350 — escrito à mão, que não é medida
   de lugar nenhum do sistema. Agora sai dos mesmos tokens que a casca usa:

     breakpoint.hd-painel      980 – 1366   painel 288   vão 16
     breakpoint.fullhd-painel  1367 +       painel 320   vão 24

   `--panel-width-hd` e `--panel-width-fullhd` são os tokens que o Painel do
   Cliente da loja estreou; aqui eles valem para a mesma coisa — uma coluna
   de apoio ao lado do conteúdo. O vão entre as duas colunas é o gutter da
   faixa, o mesmo `--admin-vao` do carrossel.

   Abaixo de 980 não há painel: a tela vira uma coluna, e o resumo desce para
   baixo do conteúdo — que é onde a decisão acontece depois de ler.
   ========================================================================= */

.checkout {
  --checkout-painel: var(--panel-width-hd);          /* 288 */
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--checkout-painel);
  gap: var(--admin-vao);
  align-items: start;
}

@media (min-width: 85.4375rem) {
  .admin .checkout { --checkout-painel: var(--panel-width-fullhd); }  /* 320 */
}

@media (max-width: 61.1875rem) {
  .checkout { grid-template-columns: minmax(0, 1fr); }
  /* Empilhado não há para onde grudar, e um resumo `sticky` numa coluna
     única fica pregado no meio da rolagem. */
  .checkout .resumo { position: static; }
}

/* A coluna da esquerda é uma grade com ritmo próprio: 24 entre o título, o
   texto, o comprovante e o aviso. Antes esse vão vinha de margens de cada
   peça, e elas discordavam entre si. */
.checkout__principal { display: grid; gap: var(--unit-300); min-width: 0; }
.checkout__bloco { display: grid; gap: var(--unit-100); }
.checkout__bloco > .sysvc-status { justify-self: start; }

/* Item de grade nasce com largura mínima de conteúdo. Sem zerar, o recibo e
   o aviso mediam mais que a coluna e passavam da margem — e é este zero que
   acende a consulta de container do Recibo, que abaixo de 480 empilha rótulo
   e valor sozinho, que é o desenho dele para largura curta. */
.checkout__principal > *,
.checkout__lateral > * { min-inline-size: 0; }
.conclusao .sysvc-receipt__rotulo,
.conclusao .sysvc-receipt__valor,
.conclusao .sysvc-utility__title,
.conclusao .sysvc-utility__description { min-inline-size: 0; overflow-wrap: anywhere; }

/* O Total que fecha o comprovante sobe DOIS degraus da escala em rótulo e
   valor: rótulo n2 → 0 (12 → 16), valor 0 → 1 (16 → 22; o meio passo 05 conta
   como degrau). Composição, como na loja — o Recibo do sistema mantém a
   quantia só na cor. */
.conclusao .conclusao__total .sysvc-receipt__rotulo {
  font-size: var(--scale-size-0); line-height: var(--scale-height-0);
}
.conclusao .conclusao__total .sysvc-receipt__valor {
  font-size: var(--scale-size-1); line-height: var(--scale-height-1);
}

/* O Botão de utilidade não tem recuo vertical — numa lista, quem dá a altura
   é o item de 56. Como RECADO, com título mais descrição, o texto passa dos
   54 e encosta nas bordas. E o ícone acompanha a PRIMEIRA LINHA, e não o meio
   do bloco: o componente centraliza tudo, o que é certo para um item de menu
   de uma linha; com duas, o ícone descia e não apontava para nenhuma. */
.sysvc-utility--static { padding-block: var(--unit-100); }
.sysvc-utility--static:has(.sysvc-utility__description) { align-items: flex-start; }

/* --- o resumo ------------------------------------------------------------
   =========================================================================
   É o `.resumo` da loja. O `.carrinho` que ele substitui falava a língua do
   RECIBO — `--receipt-*` em toda medida, rótulo em caixa alta de 12 contra
   valor de 16, superfície com sombra externa. A gramática estava certa para
   um comprovante; esta coluna não é um. Ela é uma barra de apoio ao lado do
   conteúdo, e o contorno por sombra INTERNA diz isso melhor do que a sombra
   externa, que faz a peça flutuar sobre a página.

   O rótulo em caixa alta saiu junto: numa coluna de 288, com duas palavras
   por linha, a caixa alta de 12 pesava mais que o número que ela nomeia.
   Rótulo e valor ficam no mesmo corpo (UI 14/20) e alinhados pela LINHA DE
   BASE — o que separa os dois é a cor e o peso, não o tamanho.             */
.resumo {
  position: sticky;
  /* Gruda 32 abaixo da barra superior, que tem 64. */
  inset-block-start: calc(var(--admin-topbar-height) + var(--unit-400));
  /* `minmax(0, 1fr)` e não a coluna implícita: item de grade tem
     `min-width: auto` e não encolhe abaixo do próprio conteúdo. */
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--unit-150);
  padding: var(--unit-300);
  background-color: var(--surface-raised);
  border-radius: var(--border-100);
  box-shadow: inset 0 0 0 1px var(--border-subtle);
}
.resumo > * { min-inline-size: 0; }

.resumo__linha {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--unit-200);
  font-size: var(--text-ui-size); line-height: var(--text-ui-line);
}
.resumo__rotulo { color: var(--text-subtle); }
.resumo__valor { font-variant-numeric: tabular-nums; font-weight: var(--weight-bold); }

/* O par empilhado: rótulo em cima, quantidade embaixo, sem vão entre os dois
   — é o vão maior de fora contra o zero de dentro que faz "Pacote" e "10.000
   pontos" lerem como uma coisa só. */
.resumo__detalhe {
  display: block;
  font-weight: var(--weight-bold);
  color: var(--text-body);
}

.resumo__regua {
  height: 1px;
  background-color: var(--border-subtle);
  margin-block: var(--unit-50);
}

/* A linha do total: um degrau acima no corpo e na cor da marca, dos dois
   lados. O rótulo perde o cinza — num total, rótulo e valor são a mesma
   afirmação. */
.resumo__total {
  font-size: var(--text-body-size);
  font-weight: var(--weight-bold);
  color: var(--brand-primary-bold);
}

/* Os botões da etapa moram DENTRO do resumo: a caixa que mostra o total é a
   mesma que oferece a saída. Empilhados e em largura cheia, porque a coluna
   tem 288 e dois botões lado a lado ali ficariam com o rótulo espremido.

   O Button group do sistema é grade com `grid-auto-flow: column` — só a
   coluna única não basta, o fluxo também precisa virar. */
.checkout .checkout__acoes {
  display: grid;
  grid-auto-flow: row;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--unit-100);
}
.checkout .checkout__acoes > .sysvc-button { justify-content: center; }

/* --- o rastreio ----------------------------------------------------------
   =========================================================================
   CRIADO, sem arquivo de origem — e o conteúdo dele não foi inventado: as
   três paradas são a frase que esta tela já dizia, "creditados dentro do
   prazo de 24 horas após a análise, processamento e confirmação do
   pagamento". O desenho é o da loja, que usa a mesma peça para a entrega.

   Em pé, e não deitado: três paradas lado a lado numa coluna de 288 quebram
   cada rótulo em três linhas. O fio passa a ser vertical, entre os discos.
   ========================================================================= */
.rastreio { display: flex; flex-direction: column; gap: var(--unit-200); margin-block: var(--unit-100) 0; }
.rastreio__parada { display: flex; align-items: center; gap: var(--unit-150); position: relative; }
.rastreio__parada + .rastreio__parada::before {
  content: '';
  position: absolute;
  inset-inline-start: calc(1.375rem - 1px);
  inset-block-end: 100%;
  width: 2px;
  height: var(--unit-200);
  background-color: var(--border-default);
}
.rastreio__parada--feita + .rastreio__parada::before { background-color: var(--alert-success-bold); }
.rastreio__disco {
  flex: none;
  position: relative; z-index: 1;
  width: 2.75rem; height: 2.75rem; border-radius: var(--border-full);
  display: grid; place-items: center;
  background-color: var(--surface-raised);
  box-shadow: inset 0 0 0 2px var(--border-default);
  color: var(--text-subtle);
}
/* A parada feita tem anel VERDE e rótulo em negrito — cor e forma juntas,
   para quem não distingue as duas cores continuar vendo a diferença. */
.rastreio__parada--feita .rastreio__disco {
  box-shadow: inset 0 0 0 3px var(--alert-success-bold);
  color: var(--alert-success-bold);
}
.rastreio__disco svg { width: 1.375rem; height: 1.375rem; }
.rastreio__rotulo {
  font-size: var(--text-caption-size); line-height: var(--text-caption-line);
  color: var(--text-subtle);
}
.rastreio__parada--feita .rastreio__rotulo {
  color: var(--alert-success-bold);
  font-weight: var(--weight-bold);
}

/* O título de bloco do checkout: Heading sm, bold, na cor da marca — o
   mesmo desenho do `.secao__titulo` da loja.

   O NOME É OUTRO de propósito. `.secao__titulo` já existe neste arquivo, e
   quer dizer outra coisa: é o rótulo em CAIXA ALTA com a régua embaixo que
   o dashboard usa em "CAMPANHAS" e "EXTRATOS DE PONTOS", lido do arquivo de
   origem. Reusar o nome da loja aqui repintou os dois títulos do dashboard
   de azul e tirou a régua deles — dois significados disputando um seletor.
   Mesma aparência, nomes diferentes, porque são peças diferentes. */
.checkout__titulo {
  margin: 0;
  font-size: var(--heading-sm-size);
  line-height: var(--heading-sm-line);
  font-weight: var(--weight-bold);
  color: var(--brand-primary-bold);
}


/* A FOLHA QUE É PROVA — a mesma classe que a loja usa no comprovante.
   Ela reaponta o rótulo do Recibo para text.subtle no escopo da peça: não
   define token, reaponta um token do componente para outro do sistema, que é
   o mecanismo que a própria documentação prescreve.

   Só a folha da conclusão a leva. O resumo de um modal de confirmação usa o
   mesmo componente, mas não é prova de nada — é a pergunta antes do ato, e
   ali o rótulo continua com o peso que o componente lhe dá. */
.recibo--prova { --receipt-label-color: var(--text-subtle); }

/* O código de autenticação é a única coisa aqui que pode quebrar: são 35
   caracteres numa coluna que não os comporta. Quebra entre os grupos de 8,
   nunca no meio de um — os espaços já dizem onde. */
.recibo-codigo {
  font-family: var(--family-mono);
  font-size: var(--scale-size-n1);
  letter-spacing: .02em;
  overflow-wrap: normal;
}


/* --- painéis dos métodos ------------------------------------------------ */

.metodo__grade {
  display: grid;
  grid-template-columns: 7.625rem minmax(0, 1fr);   /* 122 — o QR do arquivo */
  gap: var(--unit-400);
  align-items: start;
}
/* 208 e não 176: "Visualizar boleto" tem que caber numa linha. Um rótulo de
   botão que quebra em duas linhas deixa de ser um rótulo e vira uma frase. */
.metodo__grade--boleto { grid-template-columns: 13rem minmax(0, 1fr); }
.metodo__grade--ted { grid-template-columns: 15.6875rem minmax(0, 1fr); } /* 251 */

.metodo__texto {
  display: flex;
  flex-direction: column;
  gap: var(--unit-200);
  color: var(--text-body);
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
}
.metodo__texto p { margin: 0; }

/* --- Pix ---------------------------------------------------------------- */

/* O QR do arquivo é um raster embutido. Aqui ele é desenhado: os três olhos
   nos cantos e uma trama gerada por semente fixa, com a marca do Pix no
   meio. É uma FIGURA de QR, não um QR — nenhum aplicativo lê. Está dito no
   aria-label e na legenda, porque um protótipo que finge ler leva alguém a
   apontar a câmera para ele numa demonstração. */
.pix-qr {
  width: 7.625rem;                   /* 122 */
  height: 7.625rem;
  border-radius: var(--border-50);
  box-shadow: inset 0 0 0 var(--stroke-rest) var(--color-grey-400);
  background-color: var(--surface-raised);
}

/* A figura do documento do boleto: 64 de grade, traço de 2 como todo ícone
   do sistema — o que muda é o tamanho, não a espessura relativa. */
.boleto-figura {
  align-self: center;
  width: var(--unit-800);        /* 64 */
  height: var(--unit-800);
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.pix-passos {
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--unit-200);
  counter-reset: passo;
  list-style: none;
}
.pix-passos li {
  display: grid;
  grid-template-columns: var(--unit-250) minmax(0, 1fr);
  gap: var(--unit-150);
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
  color: var(--text-body);
}
.pix-passos li::before {
  counter-increment: passo;
  content: counter(passo);
  font-weight: var(--weight-bold);
  color: var(--text-body);
  text-align: end;
}

.pix-expira {
  margin: 0;
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
  color: var(--text-body);
}
/* Tabular para o relógio não tremer a cada segundo — o número muda, a
   largura não. */
.pix-relogio {
  font-weight: var(--weight-bold);
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.pix-expira--vencido .pix-relogio { color: var(--text-danger); }

/* --- Transferência bancária --------------------------------------------- */

.ted-dados {
  display: grid;
  grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--unit-150) var(--unit-400);
  margin: 0;
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
}
.ted-dados dt { color: var(--text-subtle); }
.ted-dados dd {
  margin: 0;
  font-weight: var(--weight-bold);
  color: var(--text-body);
}

/* A zona de arquivo é tracejada de propósito: contorno cheio diz "caixa
   com conteúdo", tracejado diz "lugar que espera receber". */
.zona-arquivo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--unit-150);
  padding: var(--unit-200);
  border: var(--stroke-200) dashed var(--color-blue-400);
  border-radius: var(--border-100);
  text-align: center;
  color: var(--text-body);
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
}
.zona-arquivo svg {
  width: var(--unit-400);
  height: var(--unit-400);
  fill: none;
  stroke: var(--accent);
  stroke-width: var(--icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
}
.zona-arquivo__chamada { font-weight: var(--weight-bold); }
.zona-arquivo__ou { color: var(--text-subtle); }
.zona-arquivo input[type="file"] { display: none; }
.zona-arquivo--cheia { border-style: solid; border-color: var(--alert-success-default); }

/* --- Cartão de crédito --------------------------------------------------
   A grade do print: número, nome e CPF ocupam a linha inteira; validade e
   CVV dividem uma. Não é economia de espaço — é o desenho do cartão. Mês e
   código de segurança ficam lado a lado no plástico, e o formulário que
   repete essa vizinhança é preenchido sem a pessoa procurar. */

.metodo__titulo {
  margin: 0;
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  color: var(--text-subtle);
}
/* Um título de seção logo depois de outro bloco precisa de ar; o primeiro,
   colado no cabeçalho do accordion, não. */
.metodo__titulo:not(:first-child) { margin-block-start: var(--unit-100); }

.cartao-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--unit-200);
}
.cartao-form__largo { grid-column: 1 / -1; }

.cartao-parcelas { max-width: 21.25rem; }   /* 340 — a proporção do print */

/* A bandeira: o NOME, não o logotipo. Um logotipo de terceiro redesenhado à
   mão é pior do que nenhum; a arte oficial é ativo licenciado e entra neste
   mesmo espaço quando chegar. */
.bandeira {
  flex: none;
  align-self: center;
  padding: var(--unit-25) var(--unit-100);
  border-radius: var(--border-50);
  background-color: var(--surface-page);
  box-shadow: inset 0 0 0 var(--stroke-rest) var(--border-subtle);
  font-size: var(--scale-size-n2);
  line-height: var(--scale-height-n2);
  font-weight: var(--weight-bold);
  color: var(--text-subtle);
  white-space: nowrap;
}
.bandeira[hidden] { display: none; }

.cartao-ajuda {
  display: flex;
  align-items: center;
  cursor: help;
}

/* --- aviso de atenção ---------------------------------------------------
   alert.caution: a faixa lateral marca o bloco de um lado só, e o ícone
   repete o recado para quem não distingue a cor. */
.aviso {
  display: flex;
  align-items: center;
  gap: var(--unit-150);
  padding: var(--unit-150) var(--unit-200);
  border-radius: var(--border-50);
  background-color: var(--surface-page);
  box-shadow: inset var(--stroke-band) 0 0 0 var(--alert-caution-default);
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
  color: var(--text-body);
}
.aviso svg {
  flex: none;
  width: var(--icon-grid);
  height: var(--icon-grid);
  fill: none;
  stroke: var(--alert-caution-bold);
  stroke-width: var(--icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* O aviso do protótipo não é `caution`: não há nada de errado com a tela, e
   pintar de laranja o que é só um recado gasta o alarme para quando ele
   precisar. Vai na cor de marca — é informação sobre a natureza da peça. */
.aviso--prototipo {
  align-items: start;
  box-shadow: inset var(--stroke-band) 0 0 0 var(--accent);
}
.aviso--prototipo svg { stroke: var(--accent); }
.aviso--prototipo code {
  font-family: var(--family-mono);
  font-size: var(--scale-size-n2);
  padding: 0 var(--unit-50);
  border-radius: var(--border-25);
  background-color: var(--surface-raised);
}

/* --- ícone do método na linha fechada ------------------------------------
   O arquivo pinta boleto e banco em teal.1000 (#005E5F) e a marca do Pix na
   cor dela. É a cor do MEIO DE PAGAMENTO, não do sistema — por isso não sai
   de --accent. */
.metodo-icone { color: var(--color-teal-1000); }
.metodo-icone svg {
  width: var(--icon-grid);
  height: var(--icon-grid);
  fill: none;
  stroke: currentColor;
  stroke-width: var(--icon-stroke);
  stroke-linecap: round;
  stroke-linejoin: round;
}
/* A marca do Pix é de terceiro: tem preenchimento próprio e não segue o
   traço do Lucide. */
.metodo-icone--pix svg { fill: currentColor; stroke: none; }

.copiado {
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-line);
  color: var(--alert-success-bold);
  font-weight: var(--weight-bold);
}
.copiado[hidden] { display: none; }

/* 68rem era o ponto em que a coluna de apoio de 350 deixava de caber. Ela
   não tem mais 350: é o PAINEL do grid (288/320), e quem decide quando ele
   some é o breakpoint do sistema, em 980 — a regra está junto do `.checkout`.
   Esta aqui ficou mandando na tela inteira até 1088, e a segunda coluna
   sumia a 1000 sem motivo nenhum. O que sobrou no bloco são os painéis de
   método de pagamento, que continuam com a conta deles. */
@media (max-width: 68rem) {
  .metodo__grade,
  .metodo__grade--boleto,
  .metodo__grade--ted { grid-template-columns: minmax(0, 1fr); }
}

/* Validade e CVV só empilham quando não cabem mesmo: separá-los cedo demais
   desfaz a vizinhança que existe no plástico. */
@media (max-width: 34rem) {
  .cartao-form { grid-template-columns: minmax(0, 1fr); }
}


/* O selo BETA do rodapé do menu: rect 39 × 16, raio 2, teal.100 no arquivo. */
.admin__beta {
  padding: 0 var(--unit-50);
  border-radius: var(--border-25);
  background-color: var(--color-teal-100);
  color: var(--brand-secondary-bold);
  font-weight: var(--weight-bold);
  letter-spacing: .08em;
}

/* =========================================================================
   TELA 7 — Drawer "Adicionar campanha"
   =========================================================================
   Composição sobre sys-drawer.css. Nenhum token novo: as cores do arquivo
   foram lidas e trocadas pelo token que já as define — o tracejado azul
   #60B2FE é blue.400 (--brand-primary-light), o cinza das colunas é grey.100.
   ========================================================================= */

/* --- cabeçalho -----------------------------------------------------------
   O sistema desenha o cabeçalho como "botão + título". Aqui o lugar do
   título é ocupado pela barra de etapas, e o título desceu para o corpo —
   é assim nos sete arquivos, e faz sentido: a barra é o que muda a cada
   passo, e o que muda merece o topo. */
.drawer-campanha__cabecalho { align-items: flex-end; }
.drawer-campanha__progresso { flex: 1 1 auto; }

.drawer-campanha__titulo {
  margin-block: 0 var(--unit-400);
  font-size: var(--scale-size-4);
  line-height: var(--scale-height-4);
}

/* --- corpo ---------------------------------------------------------------
   O vão entre campos é do passo, e não de cada campo: margem em componente
   do sistema é o começo do fim — o mesmo Field passa a espaçar diferente
   conforme a tela que o usa. */
.drawer-passo {
  display: flex;
  flex-direction: column;
  gap: var(--unit-300);
}
.drawer-passo[hidden] { display: none; }

.drawer-campanha__texto { margin: 0; }
.drawer-campanha__chave { align-self: start; }

/* --- campo com botão de arquivo ------------------------------------------
   O campo estica e o botão fica no tamanho do rótulo, alinhados pelo topo da
   caixa de 72: `align-items: center` deixaria o botão flutuando no meio,
   longe da borda que ele comanda. */
.arquivo-linha {
  display: flex;
  align-items: start;
  gap: var(--unit-200);
}

.arquivo-linha__campo { flex: 1 1 auto; min-inline-size: 0; }
.arquivo-linha__botao { block-size: var(--field-height); flex: 0 0 auto; }

/* O input nativo não é escondido com `display: none` por acidente: ele
   continua no DOM e continua sendo quem abre o seletor. Quem o aciona é o
   botão ao lado, que é focável e tem rótulo. */
.entrada-arquivo { display: none; }

/* --- as colunas do modelo ------------------------------------------------ */
.colunas {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--unit-150);
  margin: 0;
  padding: var(--unit-150);
  list-style: none;
  background-color: var(--surface-raised-sunken, var(--color-grey-50));
  border-radius: var(--border-50);
}

.colunas__item {
  padding: var(--unit-150) var(--unit-100);
  text-align: center;
  background-color: var(--color-grey-100);
  border-radius: var(--border-25);
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-line);
  color: var(--text-body);
}

/* --- cartão do modelo ---------------------------------------------------- */
.modelo {
  padding: var(--unit-250);
  border-radius: var(--border-50);
  background-color: var(--color-grey-50);
  box-shadow: inset 0 0 0 var(--stroke-100) var(--border-subtle);
}

.modelo__aviso {
  display: flex;
  align-items: center;
  gap: var(--unit-150);
  margin: 0 0 var(--unit-200);
  padding-block-end: var(--unit-200);
  border-block-end: var(--stroke-100) solid var(--border-subtle);
  color: var(--text-subtle);
}

.modelo__icone {
  inline-size: var(--icon-grid);
  block-size: var(--icon-grid);
  stroke-width: var(--icon-stroke);
  flex: 0 0 auto;
}

/* --- área de soltar ------------------------------------------------------
   Tracejado, e não borda cheia: o tracejado é a convenção de "solte aqui" e
   distingue a área de um cartão comum sem precisar de texto extra. */
.solta {
  padding: var(--unit-500) var(--unit-300);
  border: var(--stroke-100) dashed var(--brand-primary-light);
  border-radius: var(--border-50);
  text-align: center;
  transition: background-color 140ms ease;
}

/* Enquanto o arquivo paira: a área precisa reagir, senão a pessoa não sabe
   se soltar ali vale. */
.solta[data-sobre="true"] { background-color: var(--brand-primary-low-contrast); }

.solta__convite[hidden] { display: none; }

.solta__icone {
  inline-size: var(--unit-400);
  block-size: var(--unit-400);
  stroke-width: var(--icon-stroke);
  color: var(--brand-primary-default);
}

.solta__chamada {
  margin: var(--unit-200) 0 0;
  font-family: var(--family-ui);
  font-size: var(--scale-size-1);
  line-height: var(--scale-height-1);
  font-weight: var(--weight-bold);
  color: var(--text-title);
}

.solta__ou {
  margin: var(--unit-100) 0 var(--unit-200);
  color: var(--text-subtle);
}

/* --- envio em curso ------------------------------------------------------ */
.envio[hidden] { display: none; }
.envio { text-align: start; }

/* Cancelar o envio é o danger do sistema (sysvc-button--danger): cor e
   hover vermelhos vêm dele. */

.envio__linha {
  display: flex;
  align-items: center;
  gap: var(--unit-200);
  margin-block-start: var(--unit-200);
}

.envio__arquivo {
  flex: 1 1 auto;
  min-inline-size: 0;
  padding: var(--unit-150) var(--unit-200);
  border-radius: var(--border-50);
  box-shadow: inset 0 0 0 var(--stroke-100) var(--border-subtle);
  background-color: var(--surface-raised);
}

.envio__nome {
  margin: 0 0 var(--unit-100);
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  color: var(--text-title);
  /* Nome de arquivo é longo e não pode empurrar a barra para fora. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.envio__medida {
  display: flex;
  align-items: center;
  gap: var(--unit-150);
}

.envio__peso {
  flex: 0 0 auto;
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-line);
  color: var(--text-subtle);
}

.envio__barra { flex: 1 1 auto; }

/* O estado é uma caixa de tamanho fixo: girinho e certo têm larguras
   diferentes, e sem isso a linha inteira pula ao terminar o envio. */
.envio__estado {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  inline-size: var(--unit-400);
  block-size: var(--unit-400);
}

.envio__certo {
  inline-size: var(--unit-400);
  block-size: var(--unit-400);
  stroke-width: var(--icon-stroke);
  color: var(--alert-success-default);
}

/* --- gravando ------------------------------------------------------------
   O estado do arquivo Loading1: o painel inteiro a meio tom, nada clicável.
   `pointer-events: none` no conteúdo e não `disabled` em cada botão — são
   dez controles, e um esquecido é um clique que passa. */
.drawer-campanha[data-gravando] .sysvc-drawer__body,
.drawer-campanha[data-gravando] .sysvc-drawer__footer {
  opacity: .5;
  pointer-events: none;
}

/* --- sucesso -------------------------------------------------------------- */
.drawer-passo--sucesso { gap: var(--unit-300); }

/* Sem "Avançar" o rodapé tem um botão só, e ele ocupa a largura inteira em
   vez de ficar metade órfã. */
.sysvc-button[hidden] { display: none; }
.drawer-campanha[data-passo="sucesso"] .sysvc-button-group--block {
  grid-template-columns: minmax(0, 1fr);
}

/* --- estreito ------------------------------------------------------------
   O drawer já vira tela cheia abaixo de 48rem, por conta do sistema. O que
   não cabe são as duas linhas de arquivo lado a lado e as três colunas. */
@media (max-width: 47.9375rem) {
  .arquivo-linha { flex-direction: column; align-items: stretch; }
  .arquivo-linha__botao { inline-size: 100%; }
  .colunas { grid-template-columns: minmax(0, 1fr); }
}

/* =========================================================================
   TELA 8 — Campanhas
   =========================================================================
   Quase tudo aqui já existia: a tabela, o filtro, a paginação e o rodapé de
   exportação são os mesmos de Pedidos e do Extrato. O que este bloco compõe
   é a barra de abas com a ação ao lado, o menu de ações da linha, e o bloco
   de envio quando ele mora dentro do modal em vez do drawer.
   ========================================================================= */

.campanhas-topo {
  display: flex;
  align-items: flex-end;
  gap: var(--unit-300);
  margin-block-end: var(--unit-400);
}

/* As abas ficam com o que sobra e rolam; a ação nunca encolhe. Sem o
   `min-inline-size: 0` a barra de abas se recusa a encolher abaixo do
   conteúdo e empurra o botão para fora da tela. */
.campanhas-abas {
  flex: 1 1 auto;
  min-inline-size: 0;
}

.campanhas-topo__acao { flex: 0 0 auto; }

/* --- a aba que é link ----------------------------------------------------
   O componente pinta o estado selecionado a partir de `aria-selected`, que
   é atributo de tablist. Num conjunto de links o atributo certo é
   `aria-current`, e estas duas regras são a tradução — mesma aparência,
   mesmos tokens, semântica de link. */
a.sysvc-tab { text-decoration: none; }

.sysvc-tab[aria-current="page"] { color: var(--tab-label-selected); }
.sysvc-tab[aria-current="page"] .sysvc-tab__label::after { transform: scaleX(1); }
.sysvc-tab[aria-current="page"]:hover { color: var(--tab-label-selected); }

/* "+ Adicionar campanha" não é uma campanha: é o convite no fim da fila, e o
   peso menor diz isso sem precisar de separador. */
.campanhas-abas__nova { color: var(--text-subtle); }

/* --- menu de ações da linha ---------------------------------------------- */
.acoes-da-linha { display: inline-flex; }

/* --- o menu não pode ser cortado pela tabela ------------------------------
   `.sysvc-table-wrap` rola na horizontal, e caixa que rola CORTA: na última
   linha da tabela o menu abria para baixo e ficava 76px fora da vista.
   Medido — o `elementFromPoint` no rodapé do menu devolvia a página, e não o
   item.

   O componente não tem como resolver sozinho: `Popup.js` mede a JANELA para
   decidir se vira para cima, e a janela ali sobra. Quem corta é um ancestral,
   e o ancestral é desta tela. Está registrado no README para o sistema.

   `overflow: clip visible` é a única combinação que não força os dois eixos:
   `auto` ou `hidden` num eixo obrigam o outro a virar caixa de rolagem
   também, e aí o corte volta. Vale só enquanto há menu aberto — que é
   justamente quando ninguém está rolando a tabela —, e a posição de rolagem
   é preservada. Verificado. */
.sysvc-table-wrap:has(.sysvc-popup__trigger[aria-expanded="true"]) {
  overflow: clip visible;
}

/* O alinhamento à direita e a largura da superfície NÃO são compostos aqui:
   o componente já resolve os dois. `Popup.js` mede a janela e põe
   `data-align="end"` quando a superfície passaria da borda — é o caso da
   última coluna da tabela —, e o CSS do sistema já publica
   `inline-size: max-content` com piso e teto em token.

   Havia uma sobrescrita aqui com um piso de 13rem escrito à mão. Ela não
   acrescentava nada e trocava um token do sistema por um número solto.
   Foi removida. */


.acoes-da-linha__perigo { color: var(--alert-danger-default); }
.acoes-da-linha__perigo:hover { color: var(--alert-danger-bold); background-color: var(--button-surface-danger-wash-hovered); }
.acoes-da-linha__perigo:active { background-color: var(--button-surface-danger-wash-pressed); }

/* --- o bloco de envio dentro do modal ------------------------------------
   No drawer o espaçamento vem do passo, que é uma coluna com vão. O corpo do
   modal não é, então a coluna é declarada aqui — e não no bloco, que precisa
   servir aos dois hospedeiros sem trazer margem própria. */
.envio-bloco {
  display: flex;
  flex-direction: column;
  gap: var(--unit-300);
}

.envio-intro { margin: 0; }

/* --- estreito ------------------------------------------------------------ */
@media (max-width: 47.9375rem) {
  /* A ação principal desce para baixo das abas: lado a lado, ou ela come a
     barra de abas ou a barra come o rótulo dela. */
  .campanhas-topo {
    flex-direction: column;
    align-items: stretch;
    gap: var(--unit-200);
  }
  .campanhas-topo__acao { inline-size: 100%; }
}

/* =========================================================================
   TELA 9 — Usuários
   =========================================================================
   Composição sobre o que já existe. A tabela, o filtro e a paginação são os
   mesmos das outras três; o que este bloco veste é a célula de duas linhas
   (nome sobre e-mail) e o formulário de convite dentro do modal.
   ========================================================================= */

/* Nome e e-mail numa célula só, e não em duas colunas: são a MESMA pessoa, e
   separá-los faria a tabela ter cinco colunas de largura desigual num espaço
   que já é apertado. O e-mail vem menor e mais claro — é o dado de apoio. */
.usuario__nome {
  display: flex;
  align-items: center;
  gap: var(--unit-100);
  font-weight: var(--weight-bold);
  color: var(--text-title);
}

.usuario__email {
  display: block;
  margin-block-start: var(--unit-25);
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-line);
  color: var(--text-subtle);
}

/* "você" é uma etiqueta de orientação, não um Status nem uma Tag: não
   classifica a pessoa nem descreve situação dela — diz de quem é a linha.
   Por isso é discreta de propósito, e não uma pílula colorida a mais numa
   linha que já tem duas. */
.usuario__voce {
  padding: 0 var(--unit-100);
  border-radius: var(--border-full);
  background-color: var(--color-grey-100);
  color: var(--text-subtle);
  font-size: var(--text-caption-size);
  line-height: calc(var(--text-caption-line) + var(--unit-50));
  font-weight: var(--weight-regular);
  text-transform: lowercase;
}

/* --- o convite ----------------------------------------------------------- */
.convite {
  display: flex;
  flex-direction: column;
  gap: var(--unit-300);
}

.convite__texto {
  margin: 0;
  color: var(--text-subtle);
}

.convite__rotulo {
  display: block;
  margin-block-end: var(--unit-100);
  font-family: var(--family-ui);
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
  font-weight: var(--weight-bold);
  color: var(--text-body);
}

/* A descrição do perfil escolhido fica FORA do dropdown, e muda com ele: o
   texto de dentro do menu some quando o menu fecha, e é justamente na hora
   de confirmar que a pessoa precisa saber o que está dando de acesso. */
.convite__ajuda {
  margin: var(--unit-100) 0 0;
  font-size: var(--text-caption-size);
  line-height: var(--text-caption-line);
  color: var(--text-subtle);
}

/* =========================================================================
   MENU — os estados que o arquivo desenha
   =========================================================================
   `assets/componentes/content-dashboard.svg` mostra os dez estados do menu
   lado a lado. Três deles o componente do sistema resolve de outro jeito, e
   aqui ele é composto para bater com o arquivo. Nenhum token novo; só as
   variáveis que o próprio componente já publica.

   As três, e o que o sistema faz em cada uma:

   1. A SETA. No arquivo, grupo fechado aponta para a DIREITA e aberto para
      baixo. O componente usa baixo/cima. Os dois pares são convenções
      válidas; a do arquivo é a que o produto já mostra ao cliente, e a
      diferença é de 90 graus de rotação.

   2. O FILHO ATIVO. No arquivo ele é AZUL E NEGRITO, sem fundo e sem trilho.
      O componente pinta o item selecionado com superfície e trilho à
      esquerda. O do arquivo é mais silencioso e funciona porque o filho já
      está recuado dentro de um grupo destacado — o contexto faz metade do
      trabalho que o fundo faria.

   3. O PAI DE UM GRUPO ABERTO. No arquivo é fundo cinza, rótulo em negrito e
      ícone escuro — a mesma pintura do item selecionado. O componente reserva
      uma superfície mais fria para "aberto sem estar selecionado". Aqui abrir
      e estar dentro coincidem na prática, e o arquivo não desenha o caso
      separado.
   ========================================================================= */

/* 1. a seta ---------------------------------------------------------------
   O ícone já entra como chevron-right; a rotação de 90 graus ao abrir é o
   que o componente faz com 180. */
.admin__menu .sysvc-disclosure__trigger[aria-expanded="true"] .sysvc-disclosure__chevron {
  transform: rotate(90deg);
}

/* 2. o filho ativo -------------------------------------------------------- */
.admin__menu .sysvc-menu-item--sub[aria-current="page"] {
  background-color: transparent;
  color: var(--brand-primary-default);
  font-weight: var(--weight-bold);
}
/* O trilho vem do ::before do componente; sem fundo ele ficaria sozinho na
   borda, apontando para um item que já se identifica pela cor. */
.admin__menu .sysvc-menu-item--sub[aria-current="page"]::before {
  background-color: transparent;
}
.admin__menu .sysvc-menu-item--sub[aria-current="page"]:hover {
  background-color: var(--menu-surface-hovered);
}

/* 3. o peso do rótulo -----------------------------------------------------
   No arquivo, item de repouso é peso normal e só o item onde a pessoa está
   fica em negrito. O componente publica `--menu-label-weight` em bold para
   TODOS os itens de primeiro nível — e aí o negrito deixa de dizer alguma
   coisa, porque todos o têm. Aqui ele volta a ser sinal. */
.admin__menu .sysvc-menu-item,
.admin__menu .sysvc-disclosure__trigger {
  font-weight: var(--weight-regular);
}
.admin__menu .sysvc-menu-item--selected,
.admin__menu .sysvc-menu-item[aria-current="page"],
.admin__menu .sysvc-disclosure__trigger[aria-expanded="true"] {
  font-weight: var(--weight-bold);
}

/* 4. o pai de um grupo aberto --------------------------------------------- */
.admin__menu .sysvc-disclosure__trigger[aria-expanded="true"] {
  background-color: var(--menu-surface-selected);
  color: var(--menu-text-selected);
  font-weight: var(--weight-bold);
}
.admin__menu .sysvc-disclosure__trigger[aria-expanded="true"] .sysvc-disclosure__icon {
  color: var(--menu-icon-selected);
}

/* =========================================================================
   TELA 10 — Histórico de Pontos
   =========================================================================
   Duas peças novas: a volta para a lista e a faixa de filtros aplicados.
   Todo o resto é a mesma composição do Extrato e da tela de Campanhas.
   ========================================================================= */

/* Um título que só o leitor de tela ouve. No arquivo, o título da tela de
   detalhe É o link de voltar — e link não é cabeçalho: quem navega por
   cabeçalhos ficaria sem âncora nenhuma. O h1 fica, invisível.

   `clip-path` mais 1px de caixa, e não `display: none` nem `visibility:
   hidden`: os dois tiram o elemento da árvore de acessibilidade junto. */
.sr-somente {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --- a volta -------------------------------------------------------------
   Link, e não botão: leva a uma tela que tem endereço próprio, e precisa do
   clique do meio e do "abrir em nova aba" que só o <a> dá. */
.voltar-historico {
  display: inline-flex;
  align-items: center;
  gap: var(--unit-150);
  margin-block-end: var(--unit-400);
  font-family: var(--family-ui);
  font-size: var(--text-ui-size);
  line-height: var(--text-ui-line);
  font-weight: var(--weight-bold);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--brand-primary-default);
  text-decoration: none;
  border-radius: var(--border-25);
}

.voltar-historico:hover { color: var(--brand-primary-bold); }
.voltar-historico:focus-visible {
  outline: var(--stroke-focus) solid var(--border-focus);
  outline-offset: var(--unit-50);
}

.voltar-historico__icone {
  inline-size: var(--icon-grid);
  block-size: var(--icon-grid);
  stroke-width: var(--icon-stroke);
}

/* --- filtros aplicados ---------------------------------------------------
   Do arquivo -3. Eles ficam ENTRE a barra e a tabela porque é ali que dizem
   o que está sendo escondido — sobre a tabela, e não dentro do painel de
   filtro, que está fechado quando eles importam. */
.filtros-aplicados {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--unit-150);
  margin-block: var(--unit-200);
}

.filtros-aplicados__rotulo {
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  font-style: italic;
  color: var(--text-subtle);
}

.filtros-aplicados__limpar { margin-inline-start: var(--unit-100); }

/* O × do chip é um link aqui, e não o botão que o componente publica:
   remover um filtro muda a URL, e mudar a URL é navegar. Precisa então
   parecer com o botão que ele substitui. */
.filtros-aplicados a.sysvc-chip__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

/* =========================================================================
   TELA 11 — Estorno de Pontos
   =========================================================================
   Quase nada de novo: a tabela, o filtro, o resumo e a paginação já existiam.
   Só o corpo do modal de confirmação precisa de uma coluna com vão.
   ========================================================================= */

.estorno-confirma {
  display: flex;
  flex-direction: column;
  gap: var(--unit-300);
}

.estorno-confirma__texto {
  margin: 0;
  color: var(--text-subtle);
}

/* O Recibo do sistema nasceu sobre o branco do comprovante, onde o cinza
   dele lê como folha. Dentro do modal, que também é branco, vale a mesma
   coisa — e por isso ele não precisa de ajuste nenhum aqui. */

/* =========================================================================
   TELA 12 — Recargas
   =========================================================================
   Um cartão só de composição: o painel do dashboard, esticado na largura da
   página em vez de encolhido num carrossel. As medidas fixas do carrossel
   saem; o resto do painel serve como está.
   ========================================================================= */

.relatorio-grafico {
  inline-size: auto;
  min-block-size: 0;
  margin-block-end: var(--unit-300);
}

/* No dashboard o gráfico divide o cartão com o número; aqui ele é o cartão. */
.relatorio-grafico .painel__corpo { margin-block: var(--unit-200) 0; }


/* =========================================================================
   TELA 13 — Pagamentos
   ========================================================================= */

/* Número de documento é para CONFERIR contra outro papel, e não para ler:
   tabular alinha os dígitos em coluna, e é assim que o olho compara dois
   números de seis casas sem contar posição por posição. */
.documento { font-variant-numeric: tabular-nums; }

/* =========================================================================
   A zona de perigo
   =========================================================================
   O lugar da ação que apaga. Ela ficava na barra do topo, a um pixel da ação
   principal; agora fica DEPOIS da tabela e da paginação, onde só chega quem
   rolou até lá de propósito.

   O contorno é vermelho e a superfície não: um bloco inteiro pintado de
   vermelho vira aviso permanente, e aviso que está sempre lá deixa de ser
   lido. A borda basta para dizer "aqui é diferente".
   ========================================================================= */

.perigo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--unit-400);
  margin-block-start: var(--unit-600);
  padding: var(--unit-300);
  border-radius: var(--border-50);
  background-color: var(--surface-raised);
  box-shadow: inset 0 0 0 var(--stroke-100) var(--alert-danger-mid-contrast);
}

.perigo__texto { min-inline-size: 0; }

.perigo__titulo {
  margin: 0 0 var(--unit-100);
  font-family: var(--family-ui);
  font-size: var(--scale-size-1);
  line-height: var(--scale-height-1);
  font-weight: var(--weight-bold);
  color: var(--text-title);
}

.perigo__aviso {
  margin: 0;
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  color: var(--text-subtle);
}

.perigo__botao { flex: 0 0 auto; }

/* --- a coluna de escolha da tabela ---------------------------------------
   Estreita e sem rótulo visível: o cabeçalho seria "Escolher" sobre três
   pixels de rádio. O nome de cada opção mora no próprio rádio. */
.sysvc-table__head--escolha,
.sysvc-table__cell--escolha {
  inline-size: var(--unit-600);
  text-align: center;
}

/* O rádio aqui não tem rótulo à vista, então o alvo de clique seria só o
   anel. `padding` no label devolve a área de toque sem desenhar nada. */
.escolha {
  display: inline-flex;
  padding: var(--unit-100);
}

@media (max-width: 47.9375rem) {
  .perigo { flex-direction: column; align-items: stretch; }
  .perigo__botao { inline-size: 100%; }
}

/* =========================================================================
   A régua de meses sensível ao ponteiro
   =========================================================================
   Cada mês vira um alvo do Tooltip do sistema. O que muda em relação à régua
   antiga é só isto: o rótulo deixou de ser texto solto e virou botão, e a
   área sensível dele sobe sobre o gráfico.
   ========================================================================= */

.painel__meses--sensivel { align-items: stretch; }

.painel__mes {
  /* .sysvc-tooltip-wrap já é inline-flex e position: relative — o que falta é
     dizer que cada mês divide a largura por igual, para a coluna sensível
     bater com o passo da curva. */
  flex: 1 1 0;
  min-inline-size: 0;
  justify-content: center;
}

.painel__mes-alvo {
  position: relative;
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: default;
}

/* A área sensível sobe sobre o gráfico sem elemento a mais e sem cobrir o
   traço: o ::before é transparente e fica atrás do desenho na ordem de
   pintura, mas na frente para o ponteiro — que é o que importa aqui. */
.painel__mes-alvo::before {
  content: "";
  position: absolute;
  inset-inline: calc(var(--unit-100) * -1);
  inset-block-end: 100%;
  block-size: var(--painel-grafico-altura, 3.25rem);
}

.painel__mes-alvo:hover,
.painel__mes-alvo:focus-visible { color: var(--text-title); }

.painel__mes-alvo:focus-visible {
  outline: var(--stroke-focus) solid var(--border-focus);
  outline-offset: var(--unit-50);
  border-radius: var(--border-25);
}

/* A altura do gráfico é declarada uma vez e lida pelo ::before: com dois
   números escritos à mão, a área sensível descolaria do desenho no dia em
   que um deles mudasse. */
.painel { --painel-grafico-altura: 3.25rem; }
.relatorio-grafico { --painel-grafico-altura: 6rem; }

/* =========================================================================
   O véu do menu sob o painel de filtro
   =========================================================================
   O Blanket do sistema tem dois níveis, e o painel de filtro acende o de
   MENU: metade da tinta do modal, um degrau abaixo na pilha, sem travar a
   rolagem. É o caso que o componente descreve — flutuante grande, que cobre
   boa parte da página e quer o fundo calado para ser lido.

   ELE VEM COM UMA OBRIGAÇÃO para quem o acende, e aqui ela cai em dois
   lugares, não um. O véu está em 350; quem tem de ficar acima é só o que a
   pessoa ainda vai usar:

     .filtro-flutuante__superficie
                    A superfície. Em repouso ela vale --level-card (100) e
                    passa POR BAIXO da barra superior, que é o certo para um
                    flutuante ancorado no conteúdo. Com o véu aceso, 100
                    ficaria embaixo da tinta — o véu cobriria justamente o
                    painel que veio destacar. Foi o primeiro defeito que o
                    sistema registrou neste componente.
     .lista-acoes   A barra que hospeda o gatilho "Filtros de pesquisa". Sobe
                    junto porque é onde a pessoa clica em seguida para
                    fechar, e um gatilho embaixo da tinta é um controle que
                    parece apagado e ainda responde.

   A barra superior e o menu lateral NÃO sobem. Eles estão em --level-nav
   (200) e ficam sob o véu de propósito: o flutuante não mora neles, e
   escurecer a página é o trabalho que o véu veio fazer.

   `.lista-acoes` ganha `position: relative` porque z-index em elemento
   estático não vale nada — e um z-index que não faz efeito é pior do que
   ausente, porque parece resolvido.
   ========================================================================= */

body:has(.sysvc-blanket--menu) .filtro-flutuante__superficie,
body:has(.sysvc-blanket--menu) .lista-acoes {
  position: relative;
  z-index: var(--level-flyout);
}

/* O painel é `position: absolute`, e a regra acima não pode reescrever isso:
   trocado por `relative`, ele voltaria ao fluxo e empurraria a tabela para
   baixo no instante em que o véu acendesse.

   MAS SÓ ACIMA DO TELEFONE. No estreito a superfície é `static` de propósito
   — flutuando, um painel mais alto que a janela deixa os botões Filtrar e
   Limpar fora de alcance, porque `absolute` não rola com a página. Sem este
   media query a regra do véu, que vem depois no arquivo, devolvia o
   `absolute` a 320 justamente quando o painel estava aberto: medido,
   `position` lia "absolute" com o véu aceso. */
@media (min-width: 48rem) {
  body:has(.sysvc-blanket--menu) .filtro-flutuante__superficie { position: absolute; }
}

/* =========================================================================
   O esqueleto dentro da tabela
   =========================================================================
   O componente já traz a forma, o brilho e as medidas. O que sobra para o
   produto é uma coisa só: onde a peça encosta dentro da célula. Uma peça de
   largura fixa — `pill`, `circle` — é `display: block`, então começa na
   borda de início; na coluna de número o valor de verdade está alinhado à
   direita, e na de ações o botão está no centro. Sem estas três linhas o
   esqueleto desenha a tabela deslocada, e o conteúdo salta de lado quando
   chega.
   ========================================================================= */

.esqueleto-corpo .sysvc-table__cell--numero .sysvc-skeleton { margin-inline-start: auto; }
.esqueleto-corpo .sysvc-table__cell--acoes .sysvc-skeleton { margin-inline: auto; }
.esqueleto-corpo .sysvc-table__head--escolha .sysvc-skeleton,
.esqueleto-corpo .escolha .sysvc-skeleton { margin-inline: auto; }

/* =========================================================================
   O esqueleto dos cartões do dashboard
   =========================================================================
   O clone herda TODO o CSS do cartão — é para isso que ele é clone. O que
   sobra é apagar a pintura das peças que têm chrome próprio: o Status tem
   fundo e cor, o botão de ícone tem contorno, o link tem sublinhado. Com a
   pintura no lugar, o retângulo cinza apareceria dentro de uma pastilha
   verde, e o esqueleto passaria a prometer o estado da campanha antes de
   saber qual é.

   A CAIXA fica: o padding continua ali, e com ele a altura e a largura que
   aquela peça ocupa. Apaga-se o que pinta, não o que mede.
   ========================================================================= */

.esqueleto-cartao .sysvc-status,
.esqueleto-cartao .sysvc-icon-button,
.esqueleto-cartao .sysvc-link,
.esqueleto-cartao .sysvc-link__label {
  background: none;
  box-shadow: none;
  color: transparent;
  text-decoration: none;
  pointer-events: none;
}

/* O ponto do Status é desenho dele, e um ponto colorido sobrando ao lado do
   retângulo cinza é a única coisa que ainda diria "ativa". */
.esqueleto-cartao .sysvc-status__dot { display: none; }

/* Os números do eixo e os meses saem com o gráfico: o bloco cinza já ocupa a
   área inteira, e uma escala legível ao lado dele anunciaria valores que o
   esqueleto não tem. */
.esqueleto-cartao .painel__eixo,
.esqueleto-cartao .painel__meses { display: none; }

/* A área do gráfico vira um retângulo só, e o `block-size` vem medido no
   cartão de verdade — por isso aqui só o que a peça precisa para ocupar a
   largura toda. */
.esqueleto-cartao .painel__area-grafico { display: block; }
.esqueleto-cartao .painel__area-grafico .sysvc-skeleton { inline-size: 100%; }

/* O cartão clonado não responde a nada: ele não é o cartão, é o desenho do
   cartão enquanto ele não chega. */
.esqueleto-cartao { cursor: default; }

/* `hidden` é um atributo, e o navegador o aplica com `display: none` na folha
   do agente — que perde para QUALQUER seletor de classe do autor. `.campanha`
   e `.painel` declaram `display: flex`, então `cartao.hidden = true` não
   escondia nada: o esqueleto e o cartão de verdade apareciam lado a lado.

   Vale para qualquer elemento a que se dê `display` e depois se esconda por
   atributo. As tabelas escaparam por acaso — ninguém declara `display` num
   `<tbody>`. */
.campanha[hidden],
.contagem[hidden],
.painel[hidden] { display: none; }

/* =========================================================================
   O menu flutuante abaixo de 980 — Popup, e não Dropdown
   =========================================================================
   O gatilho continua com a cara do Campo, que é o que já estava ali: mesma
   caixa de 72, mesmo rótulo pequeno em cima do valor. Trocar o componente
   por dentro não é motivo para mudar o que a pessoa reconhece.

   O que muda é a superfície: ela guarda o MESMO `.sysvc-menu` da coluna da
   esquerda, com os mesmos Disclosures. Fechado são cinco linhas; abrir um
   grupo mostra os filhos dele, como no desktop.
   ========================================================================= */

/* O Popup é `inline-flex` por padrão — ele nasceu para embrulhar um botão de
   ícone. Aqui ele é a barra inteira. */
.admin__seletor { display: none; inline-size: 100%; }
.admin__seletor-gatilho { inline-size: 100%; text-align: start; }

/* A SUPERFÍCIE OCUPA A LARGURA DO GATILHO, e não a do conteúdo.
   -----------------------------------------------------------------------
   O componente faz o contrário, e com razão: "a largura é do CONTEÚDO, e
   não do gatilho… o teto de 320 impede que um recado vire coluna de
   leitura". Isso vale para o popup que ele descreve — um recado, um resumo,
   duas ações, abertos a partir de um botão de ícone.

   Aqui o popup não é recado: ele É a navegação da página, e o gatilho é uma
   barra de ponta a ponta. Medido, com o teto do componente a superfície
   saía com 320 debaixo de um gatilho de 821 — e uma coluna de menu mais
   estreita que a barra que a abriu lê como menu de contexto, não como a
   navegação que ela substitui. O teto é reescrito, não ignorado: ele
   continua existindo, agora com a medida desta composição.

   Isto NÃO redefine token: reaponta a largura da peça no escopo dela.      */
.admin__seletor-superficie {
  inline-size: 100%;
  max-inline-size: 100%;
  /* O vão de 16 por dentro, o mesmo da coluna da esquerda — lá ele vem do
     `.admin__menu .sysvc-menu`, aqui da superfície. */
  padding: var(--unit-200);
  /* Cinco linhas de 48 mais os filhos de um grupo aberto cabem sem rolagem
     no tablet. O teto existe para o telefone deitado, onde a janela é baixa:
     ali o menu rola por dentro de si em vez de sair da tela. */
  max-block-size: min(70vh, 32rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Os itens dentro do flutuante têm a mesma altura e o mesmo raio da coluna.
   A regra da coluna é `.admin__menu .sysvc-menu-item`, e o flutuante está
   DENTRO de `.admin__menu` — então ela já alcança os dois. O que falta é o
   recuo lateral, que na coluna vem do `.sysvc-menu` e aqui vem da
   superfície: sem zerar, ele contaria duas vezes. */
.admin__seletor-superficie .sysvc-menu { padding-inline: 0; }

@media (max-width: 61.1875rem) {
  .admin__seletor { display: inline-flex; }
}
