/* app.css — base visual do site KeroDesconto.
   Depende de css/tokens.css, que e gerado do Figma e nao se edita a mao.

   Lei 3: cor, tipografia, forma e espacamento so por custom property, e o nome
   da custom property e o code syntax WEB da variavel no Figma.
   Lei 6: sem borda em nenhum componente. A separacao vem do empilhamento das
   superficies (surface, surface-container-low, surface-container, ...).

   ---------------------------------------------------------------------------
   MEDIDAS PROPRIAS (--kd-*)
   ---------------------------------------------------------------------------
   Sao as poucas dimensoes que o Figma tem e a colecao Spacing nao cobre. Cada
   uma esta anotada com o componente e o valor medido. Quando virarem variavel
   no Figma, passam a vir de la. Tudo o mais usa token.
   --------------------------------------------------------------------------- */

:root {
  /* A CAIXA DO CONTEUDO, com a margem por dentro (lote 23).
     O Matheus comparou o site com a Shopee e o Mercado Livre e pediu conteudo
     menos largo. O desenho foi refeito em 25/09/2026: o conteudo util para em
     1200, e com a margem de 32 dos dois lados a caixa fecha em 1264 — que e
     exatamente a largura de janela a partir da qual a sobra vira margem. No
     1440 sobram 88 de cada lado, que somados aos 32 de padding dao os 120 do
     desenho, da borda da tela ate o texto.
     Era 1440 (conteudo de 1376) ate o lote 22. */
  --kd-largura-conteudo: 1264px;

  /* Placeholder "logo" do Header/Footer: 120x40 no desktop, 96x32 no mobile. */
  /* O LOGO E MEDIDO PELA ALTURA, NAO PELA LARGURA (lote 17.1).
     A caixa do Figma era 120x40 porque guardava um espaco reservado de
     proporcao livre. A marca de verdade e 344x59 — 5,83:1. Dentro de 120 ela
     sairia com 20 de altura, metade da busca de 40 que fica ao lado: o Matheus
     viu e disse, e estava certo. Agora a altura e que e fixada (40 no desktop,
     32 no mobile, as mesmas alturas dos controles ao lado) e a largura sai da
     proporcao da arte, por `aspect-ratio`. Nenhum numero de largura e
     escolhido a mao.
     A palavra ocupa 50 dos 59 px da arte, entao a 40 de altura ela fica com 34
     — que e o que casa opticamente com a Busca de 40.

     NO LOTE 23 O DESKTOP CAIU DE 40 PARA 32, com o Header inteiro passando de
     64 para 72: o Figma passou a desenhar a marca com 187x32 no lugar de
     233x40. A proporcao e a mesma (187/32 = 5,84; a arte e 3440x590 = 5,83),
     entao continua bastando trocar a altura — a largura sai do `aspect-ratio`,
     e nenhum numero de largura e escolhido a mao. */
  /* 40 CONTINUA SENDO O PADRAO, e ele e o do FOOTER e o do Login. O lote 23
     encolheu o logo do HEADER, e so dele: medido no Figma em 25/09/2026, as 88
     instancias do Footer continuam com 233,22x40, e as 88 do Header passaram
     para 186,58x32. Baixar a raiz para 32 encolhia o Footer junto. */
  --kd-logo-altura: 40px;
  --kd-logo-altura-mobile: 32px;

  /* ALTURA DO HEADER, por ponto de quebra (lote 23).
     Ela existe porque o `scroll-padding-top` precisa dela: o Header e fixo, e
     tudo o que rola a pagina — ancora, `scrollIntoView` e a rolagem que o
     navegador faz ao mover o foco — tem de parar ABAIXO dele.
     Mobile 100 (8 + 32 do logo + 12 + 40 da busca + 8). Desktop 72 (16 + 40 da
     busca + 16), com o logo de 32 centrado nos 40. */
  --kd-header-altura: 100px;

  /* A FAIXA DA MARCA DA HOME (lote 32): a altura e o ponto onde o solido acaba.
     Medidas no Figma em 25/09/2026, camada "fundo da marca (degrade)" das telas
     da Home: 300 de altura no 390 e 260 no 768 e no 1440; o solido do
     `--kd-fundo-da-marca` vai ate 50% no 390 e ate 42% nas outras duas.

     SAO DOIS NUMEROS SEM TOKEN, e a lei 3 manda dizer por que. Nenhuma das seis
     colecoes do Figma tem variavel para isto: Shape so descreve canto, Spacing
     so descreve espacamento, e na propria camada da Home os dois valores sao
     geometria do retangulo e posicao dos stops do degrade, e nao variaveis
     ligadas. Entao entram aqui nomeados, do mesmo jeito que `--kd-header-altura`
     (lote 23) entrou: um nome so, num lugar so, em vez do numero espalhado por
     regra e media query. AS DUAS CORES CONTINUAM SENDO TOKEN
     (`--kd-fundo-da-marca` e `--md-sys-color-surface`).

     Este bloco e o do 390; o de 600 em diante esta na media query abaixo. */
  --kd-faixa-marca-altura: 300px;
  --kd-faixa-marca-solido: 50%;

  /* MOVIMENTO — as duas primeiras do projeto (lote 23), e as duas sao excecao
     declarada. O `tokens.css` e gerado do Figma e nao tem token de movimento:
     nenhuma das 6 colecoes tem variavel de duracao ou de curva, e ate este lote
     o `app.css` nao tinha uma `transition` sequer. Os valores vem do documento
     (300 ms) e do M3 (a curva `emphasized`), e a curva esta MEDIDA dentro do
     proprio arquivo do Figma, nos prototipos do kit — CUSTOM_CUBIC_BEZIER
     x1=0.2 y1=0 x2=0 y2=1. No dia em que o Figma ganhar a colecao de motion,
     estes dois nomes trocam pelos do code syntax de la. */
  --kd-movimento-duracao: 300ms;
  --kd-movimento-curva: cubic-bezier(0.2, 0, 0, 1);
  /* As proporcoes sao o viewBox dos SVG, nao numeros escolhidos: a marca e
     3440x590 e o simbolo 870x590. Ate o lote 18.1 a arte era PNG e o simbolo
     saia de um recorte automatico de 860x590, que perdia a ponta do cabo da
     lupa — a diferenca (86/59 contra 870/590) some no SVG, que traz a lupa
     inteira. */
  --kd-logo-proporcao: 3440 / 590;        /* a marca com a palavra */
  --kd-logo-simbolo-proporcao: 870 / 590; /* so a lupa */

  /* Navigation Drawer do Header Mobile · Menu aberto: 360 de largura. */
  --kd-drawer-largura: 360px;

  /* Card Grade compacta: largura maxima do nome da loja, para o tempo
     ("· ha 55 min") nunca ser cortado. Medido no Figma: 60. */
  --kd-loja-nome-max: 60px;

  /* Card de oferta Lista (Figma 560x176): imagem de largura fixa 144,
     altura acompanhando o conteudo. */
  --kd-card-lista-imagem: 144px;

  /* Card de oferta Lista compacta (Figma 358x168): imagem 112x112 fixa,
     centrada na altura. */
  --kd-card-lista-compacta-imagem: 112px;

  /* Footer Desktop: coluna da marca, 360 de largura (Figma). */
  --kd-footer-marca-largura: 360px;

  /* Menor card de Grade em qualquer largura (Figma: o card do 1200, do 720,
     do 944 e do 1168). E o piso do minmax() que decide quantas colunas cabem
     entre 600 e 1199. Nele ainda cabem a linha da loja mais longa medida
     ("Mercado Livre · ha 35 min", 171 de 176) e a linha do preco com o
     icone (146 de 176). */
  /* 160 DESDE O LOTE 23 (era 208). O Matheus pediu o card menor, como o da
     Shopee e o do Mercado Livre, e o desenho foi refeito: com piso de 160 e gap
     16 o `auto-fill` devolve exatamente `piso((C + 16) / 176)` colunas, que e a
     conta escrita no documento. Medidos e conferidos: 4 colunas de 164 no 768 e
     6 de 186,67 com o conteudo nos 1200. O teto de 6 do documento nao precisa
     de regra propria — com o conteudo travado em 1200, a conta nunca passa de
     6 (1216 / 176 = 6,9). */
  --kd-card-grade-min: 160px;

  /* Largura maxima da Lista a partir de 600 (Figma: "a Lista nao pode passar de
     560 — mais larga, o titulo cabe em 1 linha, o card fica mais baixo e a
     imagem deixa de ser quadrada"). Esta e regra de layout, nao de amostra. */
  --kd-card-lista-largura: 560px;
  /* O piso da coluna no modo Lista (lote 24). Com gap 16 o `auto-fill`
     devolve piso((C + 16) / 356), que e a conta do documento: 1 coluna no
     600, 2 de 344 no 768 e 3 de 389,33 no 1440. */
  --kd-card-lista-min: 340px;
  /* As alturas DESENHADAS da Lista e da Lista compacta. O card e HUG e nao
     usa nenhuma das duas; quem usa e o In-feed, que no Figma tem "a altura
     do card" escrita dentro dele e, sozinho numa linha de uma coluna, nao
     teria altura nenhuma. */
  --kd-card-lista-altura: 168px;
  --kd-card-lista-compacta-altura: 148px;

  /* Larguras do desenho usadas so nas AMOSTRAS do catalogo, para a peca
     aparecer no tamanho real independente da largura da janela. Nao valem para
     a grade de verdade, que e fluida. */
  --kd-card-compacta-largura: 173px;
  --kd-card-lista-compacta-largura: 358px;

  /* Banner da Home (Figma 60839:25473, Tipo=Home): 360 de altura no desktop,
     200 no mobile, e 184 do item seguinte aparecendo na borda (o "peek" do
     Carousel Hero do kit). */
  /* Banner da Home. NO LOTE 23 O DESENHO MUDOU: a altura do desktop caiu de
     360 para 264 (o carrossel passou a dividir a linha com os dois fixos) e o
     "peek" de 184 acabou — o banner ocupa a largura inteira do bloco e quem
     diz que ha mais e o indicador. Os 264 so aparecem no caso SEM fixo
     cadastrado; com fixo, a altura vem da proporcao 3:1. */
  --kd-banner-altura: 264px;
  --kd-banner-altura-mobile: 200px;

  /* Cupom (Figma 60826:330): 400 de largura no carrossel, 320 em 390.
     O circulo das iniciais tem 40. */
  --kd-cupom-largura: 320px;
  --kd-cupom-logo: 40px;

  /* CTA do canal (Figma 60838:445): logo da marca com 40. */
  --kd-cta-logo: 40px;

  /* Card dos CARROSSEIS, travado (lote 23). E o mesmo card da grade de 1200:
     (1200 - 5 x 16) / 6 = 186,666..., que o Figma desenha como 186,67. Era 240
     (o Card de oferta Layout=Grade, que o site nao usa mais). O valor fica com
     a fracao de proposito: arredondar para 187 daria 0,33 de diferenca por
     card, e seis cards numa linha de 1200 ficariam 2 px fora. */
  --kd-card-grade-largura: 186.67px;

  /* Campo do codigo no Cupom: 40 de altura, texto centrado (Figma, densidade
     de 24/09/2026 — era 44 com padding vertical). */
  --kd-cupom-codigo-altura: 40px;

  /* Busca do Header e botao do menu: 40 de altura (Figma 61031:83707). A
     colecao Spacing nao tem 40 como medida de componente — o space500 e 40,
     mas e espaco, nao altura de controle. Fica nomeada aqui. */
  --kd-busca-altura: 40px;
  /* Icon button (kit, Round/Small/Default — medido em 24/09/2026 em
     58663:30358): a caixa e 48x48 e o `Content` pintado, 40x40. Os dois numeros
     existem porque sao coisas diferentes: 48 e onde o dedo acerta, 40 e o que
     se ve. Ate o lote 19.1 o botao inteiro tinha 40 e os 4 de folga eram
     MARGEM — e margem nao recebe clique. */
  --kd-botao-icone-area: 48px;
  --kd-botao-icone-pilula: 40px;

  /* Botao do kit, Size=Small: a PILULA pintada tem 40 e a area de toque 48. O
     40 e altura de controle, pelo mesmo motivo do `--kd-busca-altura` acima —
     a colecao Spacing mede espaco, nao componente. Os 4 de folga de cada lado,
     que completam os 48, sao espaco de verdade e saem do Space 50. */
  --kd-botao-altura: 40px;
  /* Button Size=XSmall (Figma 57994:2326): pilula de 32 dentro dos mesmos 48 de
     area de toque. Sao os mesmos 32 do chip de filtro e do seletor de
     ordenacao, de proposito — a regra que o Matheus pediu em 24/09/2026 e que
     controles vizinhos numa linha tenham a MESMA altura visivel. */
  --kd-botao-altura-xs: 32px;
  /* O QUE O ANEL DE FOCO OCUPA PARA FORA DO CONTROLE: 2 de afastamento mais 2
     de espessura. Nao e medida do Figma — e a consequencia do anel que o
     projeto inteiro usa, escrita uma vez para as superficies rolaveis poderem
     reservar exatamente isso. Ver "O anel dentro de uma superficie rolavel". */
  --kd-anel-folga: 4px;

  /* Skeleton (Figma 60840:502). As barras cinzas sao formas decorativas: o
     Figma desenha cada uma com largura e altura proprias, e nenhuma delas sai
     de colecao — Spacing e medida de ESPACO, nao de forma. Ficam nomeadas
     aqui, com o valor medido no componente. A altura do bloco de textos (124)
     e o que faz o card fechar em 376 / 392 / 360 / 309 sem nenhuma altura
     escrita a mao. */
  --kd-skeleton-textos: 124px;
  --kd-skeleton-loja-largura: 96px;
  --kd-skeleton-loja-altura: 12px;
  --kd-skeleton-titulo-altura: 14px;
  --kd-skeleton-titulo-curto: 140px;
  --kd-skeleton-preco-largura: 120px;
  --kd-skeleton-preco-altura: 24px;

  /* Card lista do Skeleton: as mesmas barras, nas larguras do desenho de 560. */
  --kd-skeleton-lista-titulo: 340px;
  --kd-skeleton-lista-titulo-curto: 220px;
  --kd-skeleton-lista-preco: 140px;

  /* Pagina de produto (Figma, telas 60842:71 / 27409 / 28231, medidas em
     24/09/2026). Sao medidas de COMPONENTE, que a colecao Spacing nao cobre —
     ela mede espaco, nao peca. Mesmo criterio do `--kd-busca-altura`. */
  --kd-topo-imagem-desktop: 520px;   /* caixa da foto no Topo do produto, 1440 */
  /* No desktop a ALTURA da foto nao e um valor: e `max(520, coluna de
     informacoes)`. O 520 acima serve de largura e de minimo. Ver a regra no
     bloco de 1200 em diante. */
  --kd-topo-imagem-alt-movel: 326px; /* altura da foto abaixo de 1200, medida no 768 e no 390 */
  --kd-topo-cupom-largura: 392px;    /* a linha do cupom tem a largura dos botoes */
  --kd-historico-largura: 560px;     /* coluna do Historico no 1440 (HUG no Figma) */
  --kd-loja-altura: 80px;            /* Linha de loja Desktop; ela NAO estica */
  --kd-grafico-altura: 200px;        /* piso do grafico; estica ate 206 com 5 lojas */
  --kd-grafico-eixo-x: 24px;         /* faixa das datas, reservada no eixo y */
  --kd-grafico-eixo-y: 52px;         /* coluna dos precos do grafico, no Figma */
  --kd-periodo-item: 93px;           /* segmento do seletor de periodo, os tres iguais */
  --kd-veredito-altura: 60px;        /* altura minima: o grafico nao pode saltar */

  /* BARRA DE ORDENACAO E MENU DE EXIBICAO (lote 24), medidos no Figma em
     25/09/2026: Barra 61139:2192, Aba 61139:2191, Menu 61139:2225.
     Nenhum destes cinco tem variavel no Figma — sao tamanhos de peca, como
     o `--kd-busca-altura` e o `--kd-periodo-item` logo acima. */
  --kd-barra-ordem-altura: 56px;     /* 8 + 40 + 8 */
  --kd-aba-ordem-altura: 40px;       /* 10 + 20 + 10 */
  --kd-exibicao-botao: 40px;         /* o botao tune, quadrado */
  --kd-menu-exibicao-largura: 320px; /* o menu e FIXED no Figma */
  --kd-modo-botao: 32px;             /* grade e lista, quadrados */

  /* SLIDER DA FAIXA DE PRECO (lote 30). Standard slider do kit, Size XSmall,
     uma alca — Figma 58008:10356, com o exemplo "faixa de preco arrastando"
     61205:2291. Como os cinco de cima, nenhum destes tem variavel no Figma:
     sao tamanhos de PECA, e a colecao Spacing mede espaco, nao peca.
     Medidos no exemplo 61205:2295 em 25/09/2026, no de dentro (Active track,
     Handle, Inactive track, Value indicator) e conferidos no pixel da
     exportacao: trilhos 16 de altura, alca 4x44 (2 arrastando), vao de 6 de
     cada lado dela, indicador 44 com 4 de folga ate a peca. */
  --kd-slider-altura: 44px;          /* a peca inteira, e a altura da alca */
  --kd-slider-toque: 48px;           /* a area de toque do <input>; ver o CSS */
  --kd-slider-indicador-altura: 44px;/* o Value indicator: 12 + 20 + 12 */
  /* O CANTO DE 2 NAO TEM VARIAVEL NO FIGMA, E ESTA NO RELATORIO. A colecao
     Shape comeca em Corner/Extra small = 4. Medidos na exportacao do exemplo:
     as pontas dos trilhos que ficam DE FRENTE PARA A ALCA tem 2, as de fora
     tem 8 (Corner/Small, que entra pelo token), e a alca tem 2. Um numero sem
     variavel vira custom property com nome e motivo, em vez de ficar solto no
     meio de uma regra (lei 3). */
  --kd-slider-canto-justo: 2px;
  /* A faixa de anuncio da Home (Figma `anuncio`). O documento diz "100 de
     altura (era um de 90)", e as instancias das telas confirmam: FIXED 100
     nas tres larguras. O componente mestre `Responsivo desktop` ficou para
     tras, com 1376x90 — quem vale e a instancia. */
  --kd-anuncio-home-altura: 100px;

  /* ITEM DE CATEGORIA (Figma 61175:2214, lote 25). Nenhum destes quatro tem
     variavel no Figma: sao tamanhos de peca, como o `--kd-busca-altura`. As
     medidas do Mobile ficam na raiz e as do Desktop entram no bloco de 600,
     que e a ordem que o resto do arquivo usa. */
  --kd-categoria-item: 96px;         /* largura do item, Mobile */
  --kd-categoria-quadrado: 72px;     /* o quadrado da imagem, Mobile */
  --kd-categoria-icone: 32px;        /* o icone de reserva, Desktop */
  --kd-categoria-respiro: var(--md-sys-measurement-space100);  /* 8 */

  /* SETA DE CARROSSEL (Figma 61175:2221, lote 25). O 40 nao tem variavel no
     Figma; e tamanho de peca, como o botao Exibicao do lote 24. */
  --kd-seta: 40px;

  /* CORES DE MARCA — exceção nomeada à lei 3, com motivo.
     ----------------------------------------------------
     Estas quatro NÃO são tokens de interface e não podem virar um: o verde do
     WhatsApp é o verde do WhatsApp no tema claro e no escuro, porque é a marca
     de outra empresa, não uma decisão de design nossa. Medido no Figma em
     24/09/2026: os vetores `marca` do Telegram, do WhatsApp e do Instagram têm
     cor LITERAL, sem variável ligada, e o valor é o mesmo nos dois modos — só o
     TikTok está ligado a Schemes/On Surface e acompanha o tema (por isso ele
     não está aqui: continua em currentColor).

     Onde valem: CTA do canal e os botões de Compartilhar do Topo do produto.
     No Footer os quatro são neutros (on-surface-variant), e lá nenhuma destas
     variáveis é definida — o logo cai no currentColor de sempre.

     O branco do avião do Telegram é parte do desenho do logo, não superfície:
     no Figma é a elipse `fundo-aviao`, sempre #FFFFFF nos dois temas. */
  --kd-marca-telegram: #26a5e4;
  --kd-marca-telegram-aviao: #ffffff;
  --kd-marca-whatsapp: #25d366;
  --kd-marca-instagram: #ff0069;

  /* Painel (Figma, página "Descontos · Painel", medidas de 24/09/2026).
     Como as da página de produto, são medidas de PEÇA, que a coleção Spacing
     não cobre — ela mede espaço, não componente. */
  /* A AREA UTIL DO PAINEL PARA DE CRESCER AQUI (lote 20).
     O documento fecha a pendencia de "acima de 1440" assim: "no painel, a area
     util para em 1280, alinhada a esquerda, junto do trilho" — os mesmos 1280
     que ela tem no 1440 (conteudo 1344 com padding 32 de cada lado). Acima
     disso a sobra fica a direita, e nao centrada: o trilho e a ancora.
     No site nao ha nada a fazer: `--kd-largura-conteudo` ja trava em 1440 e o
     `.kd-conteudo` ja centra. */
  --kd-painel-largura: 1280px;
  --kd-trilho-largura: 96px;         /* Navegacao do painel Trilho */
  --kd-trilho-logo: 64px;            /* a CAIXA do logo no trilho: 64x40 */
  /* A ARTE DENTRO DA CAIXA, medida no Figma em 24/09/2026 (lote 18.1): o
     simbolo fica com 32 de altura, nao com os 40 da caixa. A 40 ele pesava mais
     que os icones de 24 dos itens logo abaixo — o Matheus viu no ar e disse.
     A largura nao entra aqui: sai da proporcao do SVG (870/590 x 32 = 47,2). */
  --kd-trilho-simbolo-altura: 32px;
  --kd-barra-nav-altura: 80px;       /* Navegacao do painel Barra */
  --kd-nav-indicador-largura: 56px;  /* pastilha do item atual */
  --kd-nav-indicador-altura: 32px;
  --kd-painel-secao: 48px;           /* espaco entre secoes no 1440 */
  --kd-painel-secao-movel: 40px;     /* e no 390 */
  --kd-tema-item: 32px;              /* segmento do Alternador de tema */
  --kd-folha-canto: 28px;            /* superficie modal do M3, so em cima */
  --kd-folha-alca-largura: 32px;
  --kd-folha-alca-altura: 4px;
  --kd-login-largura: 400px;         /* bloco do Login no 1440 */
  --kd-campo-altura: 48px;           /* Campo de texto */
  --kd-chip-altura: 32px;            /* Chip de filtro e pilula do contador */
  /* Os icones do Chip de filtro sao 18 no Figma — 18 nao esta na colecao
     Spacing (ela pula de 16 para 20), entao a medida vive aqui. */
  --kd-chip-icone: 18px;
  /* Menu de filtro (Figma 61077:2049). A largura e fixa no desenho; a altura
     do item por dentro e 44, que com os 2 de recuo em cima e embaixo fecha os
     48 do item do kit. Nenhum dos dois tem variavel no Figma. */
  --kd-menu-filtro-largura: 208px;
  --kd-menu-item-altura: 44px;
  /* Estado vazio (Figma 60840:566). A variante Desktop e 680 FIXO — medida no
     desenho, igual no 1440 e no 768; a Mobile e largura total. 680 nao sai de
     nenhuma colecao, entao mora aqui. */
  --kd-vazio-largura: 680px;
  /* Logo da loja, variante Extra grande (Figma 60907:921). As outras tres
     batem com a colecao Spacing (24, 40, 56); 72 nao esta nela, entao a medida
     mora aqui. */
  --kd-logo-loja-extra: 72px;
  --kd-indicador-altura: 128px;      /* Card de indicador no 1440 */
  --kd-indicador-altura-movel: 148px;/* e no 390, onde a variacao quebra em 2 linhas */
  --kd-indicador-canto: 20px;        /* Corner/Large-increased, 16% de 128 */
  --kd-grafico-eixo-y-painel: 22px;  /* coluna dos numeros do Grafico de cliques */
  --kd-tabela-cabecalho: 52px;
  --kd-tabela-linha: 56px;
  --kd-tabela-acoes: 72px;           /* coluna do menu de acoes da linha */
  --kd-col-140: 140px;               /* colunas de dados 2, 3 e 4 */
  --kd-col-160: 160px;               /* coluna de dados 5 */

  /* --- Formularios do painel (lote 19) ------------------------------------
     Medidas de PECA, todas lidas no Figma em 24/09/2026. */
  --kd-form-largura: 720px;          /* o `formulario` no 1440, FIXED */
  --kd-fab-altura: 56px;             /* Extended FAB Size=Small, no 390 */
  /* Opcao com switch: o trilho, a alca em cada estado e o traco do desligado.
     O canto do trilho (100) e o da alca (24) sao LITERAIS no kit — nao estao
     ligados a colecao Shape — entao os dois saem de Corner/Full, que e o unico
     canto redondo do projeto. */
  --kd-switch-largura: 52px;
  --kd-switch-altura: 32px;
  --kd-switch-alca-ligada: 24px;
  --kd-switch-alca-desligada: 16px;
  --kd-switch-traco: 2px;            /* stroke INSIDE, Schemes/Outline */
  /* Campo de upload: as duas alturas do desenho e a miniatura. */
  --kd-upload-vazio: 192px;
  --kd-upload-com-imagem: 128px;
  --kd-upload-miniatura: 96px;
  /* ONDE O "Com imagem" QUEBRA EM DUAS LINHAS. O Figma desenha o campo a 688 e
     a 560 numa linha so, e a 326 com os botoes na segunda — mas nao diz onde
     fica a virada entre 560 e 326. O numero aqui e a largura MEDIDA do bloco
     `arquivo` na versao que quebrou (182 a 326w): abaixo disso ele nao cabe, e
     a quebra acontece exatamente onde o desenho mostra. Esta no relatorio. */
  --kd-upload-nome-minima: 182px;

  /* Opacidade do conteudo desabilitado (M3). Excecao nomeada: a colecao State
     do Figma so exporta as opacidades de state layer (hover, focus, pressed,
     dragged, scrim) — nao ha token para o conteudo em Disabled. O 0,38 e o do
     proprio kit, lido na variante `State=Disabled` do Icon button. */
  --kd-desabilitado: 0.38;
  --kd-tabela-minima: 872px;         /* largura da tabela dentro da rolagem, no 390 */

  /* Botao apagado do Cupom Expirado. No Figma o fill e a variavel
     `State Layers/On Surface/Opacity-10`, da colecao State Layers — que o
     tokens.css ainda NAO tem (esta nas "Pendencias no codigo": o arquivo
     precisa ser regerado do Figma junto com essa colecao). Ate la o valor fica
     nomeado aqui, como as outras medidas que o Figma tem e a colecao atual nao
     cobre. Quando a colecao entrar, esta linha sai. */
  --kd-estado-apagado-opacidade: 10%;

  /* Margem lateral e espaco entre secoes, por ponto de quebra.
     Os valores vem da colecao Spacing; o que muda e qual token vale em cada
     largura, e isso e regra de layout, nao valor solto. */
  --kd-margem: var(--md-sys-measurement-space200);        /* 16 — ate 599  */
  /* Espaco entre secoes da pagina, e da ultima secao ate o Footer. Passou de
     48/48/40 para 40/40/32 na densidade de 24/09/2026. Vale para toda pagina
     do site; hoje so a Home existe. */
  --kd-secao: var(--md-sys-measurement-space400);         /* 32 — ate 599  */

  /* Grade de cards, medida no Figma em 15 larguras (Estados 61001:82305).
     Ate 599: 2 colunas fluidas (158 no 360, 173 no 390, 277,5 no 599). */
  --kd-grade-template: repeat(2, minmax(0, 1fr));
  --kd-grade-gap: var(--md-sys-measurement-space150);     /* 12 */
}

/* 600 a 1199: desenho de 768 */
@media (min-width: 600px) {
  :root {
    --kd-margem: var(--md-sys-measurement-space400);      /* 32 */
    --kd-secao: var(--md-sys-measurement-space500);       /* 40 */

    /* Quantas couberem com o card de no minimo 160 (lote 23). Nao ha ponto de
       quebra proprio: o `auto-fill` com gap 16 devolve `piso((C + 16) / 176)`,
       que e literalmente a conta do documento. Com o conteudo de cada largura:
       3 colunas no 600, 4 no 768, 5 no 944 e 6 a partir de 1200. */
    --kd-grade-template: repeat(auto-fill, minmax(var(--kd-card-grade-min), 1fr));
    --kd-grade-gap: var(--md-sys-measurement-space200);   /* 16 */

    --kd-cupom-largura: 400px;

    /* Item de categoria: a variante Desktop, medida no Figma no 768 E no
       1440 — as duas usam a mesma. O corte em 600 e do documento: entre 390
       e 768 nao ha tela desenhada.

       124, E NAO 112 (lote 26): o Figma alargou o item para
       "Eletrodomesticos" caber numa linha so. O quadrado continua 96 e fica
       centralizado — medido, ele nasce em x=14, que e (124 - 96) / 2. */
    --kd-categoria-item: 124px;
    --kd-categoria-quadrado: 96px;

    /* 72: 16 + 40 (a Busca, o item mais alto) + 16. */
    --kd-header-altura: 72px;

    /* A faixa da marca da Home encolhe de 300 para 260 e o solido acaba mais
       cedo, em 42% no lugar de 50% (Figma, telas de 768 e de 1440). O motivo de
       os dois nao serem token esta no `:root`, la em cima. */
    --kd-faixa-marca-altura: 260px;
    --kd-faixa-marca-solido: 42%;
  }
}

/* 1264 ou mais: o conteudo trava em 1200 e a sobra vira margem.

   A GRADE NAO GANHA REGRA PROPRIA AQUI, e essa e a mudanca do lote 23. Ate o
   lote 22 havia `repeat(5, ...)` com gap 24 a partir de 1200, porque o desenho
   antigo tinha 5 cards de 256 num conteudo de 1376. Agora a conta e uma so de
   600 para cima — `auto-fill` com piso de 160 e gap 16 —, e quem muda o numero
   de colunas e a largura do conteudo, que para em 1200.

   Sobrou so o cupom do carrossel: com o conteudo travado cabem tres inteiros na
   linha, e o Figma os desenha com (1200 - 32) / 3 = 389,33. */
@media (min-width: 1264px) {
  :root {
    --kd-cupom-largura: 389.33px;
  }
}

/* ===========================================================================
   Fonte — servida pelo proprio site, sem requisicao a terceiros.
   Manrope e fonte variavel: um arquivo por subconjunto cobre 200 a 800.
   Licenca em /fonts/OFL.txt (SIL Open Font License 1.1).
   =========================================================================== */

@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("/fonts/manrope-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Manrope";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("/fonts/manrope-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ===========================================================================
   Base
   =========================================================================== */

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

html { background: var(--md-sys-color-background); }

body {
  margin: 0;
  background: var(--md-sys-color-background);
  color: var(--md-sys-color-on-background);
  font-family: var(--md-sys-typescale-body-medium-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: var(--md-sys-typescale-body-medium-line-height);
  letter-spacing: var(--md-sys-typescale-body-medium-tracking);
  font-weight: var(--md-sys-typescale-body-medium-weight);
  -webkit-font-smoothing: antialiased;
}

body.kd-travado { overflow: hidden; }

img { display: block; max-width: 100%; }

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

button { font: inherit; color: inherit; background: none; border: none; padding: 0; }

/* `hidden` tem de esconder, sempre.
   A regra `[hidden] { display: none }` que o navegador traz tem especificidade
   ZERO, entao qualquer classe do projeto que declare `display` a vence — e o
   elemento marcado como escondido continua na tela. Aconteceu com dois:
   o botao "Copiar" do Cupom (`.kd-botao`, display inline-flex), que aparecia
   sem JavaScript e nao copiava nada, e a linha do "Carregar mais"
   (`.kd-carregar-mais`, display flex), que ficava na tela junto com o
   esqueleto. Os dois foram medidos no navegador em 24/09/2026.
   `!important` aqui e o uso certo dele: `hidden` e uma afirmacao do HTML sobre
   o que existe na pagina, nao uma preferencia de estilo que o CSS possa
   discordar. */
[hidden] { display: none !important; }

/* Foco visivel, igual em tudo que recebe foco. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* ===========================================================================
   NADA DESENHADO PELO NAVEGADOR (lote 18.1)

   O Matheus abriu o painel no ar e viu duas coisas com cara de "padrao do
   navegador": a barra de rolagem no trilho e a lista nativa do `<select>` nos
   chips de filtro. Pediu para conferir TODOS os lugares onde o navegador
   desenha controle proprio. Este bloco e o resultado; o `<select>` saiu por
   outro caminho (virou o Menu de filtro, mais abaixo).

   A REGRA: o que o Figma desenha e o que aparece. O navegador continua sendo
   dono do que e dele — a barra de rolagem DA PAGINA INTEIRA fica, porque ela e
   do documento, nao de um componente nosso.

   Cada regra abaixo foi MEDIDA antes e depois, em 24/09/2026, no Chrome 154 e
   no Edge, em 1440, 768 e 390, nos dois temas. O que nao existe no projeto
   (checkbox, radio, `<details>`, campo de arquivo, campo de data, `number`)
   NAO ganhou regra: CSS para elemento que nao existe e peso morto que ninguem
   vai lembrar de conferir quando ele nascer.
   =========================================================================== */

/* 1. O FLASH AZUL DO TOQUE.
   Medido: o padrao do Chrome e `rgba(0, 0, 0, 0.18)` — um retangulo cinza que
   pisca sobre TODO link e botao tocado no celular, com o canto do retangulo, e
   nao o do componente. Quem responde ao toque no M3 e a state layer, que o
   projeto ja desenha. A propriedade e herdada, entao uma linha no `html` cobre
   a arvore inteira. */
html { -webkit-tap-highlight-color: transparent; }

/* 2. BARRA DE ROLAGEM DE COMPONENTE.
   Medido em 24/09/2026 com o conteudo transbordando de verdade:

     .kd-trilho          772 de conteudo numa janela de 700   -> barra vertical
     .kd-tabela-rolagem  872 de tabela numa janela de 358     -> barra horizontal
     .kd-drawer          menu do Header, quando a lista passa da tela
     .kd-rolagem-borda   carrosseis (ja estava escondida desde o lote 11)

   As quatro ficam numa lista so para que a proxima superficie rolavel que
   nascer entre aqui, e nao ganhe uma copia das tres linhas em outro lugar do
   arquivo. A ROLAGEM CONTINUA INTEIRA: roda do mouse, toque, trackpad, teclado
   e o arrasto de mouse do `kd.js`. O que some e o desenho da barra. */
.kd-trilho,
.kd-tabela-rolagem,
.kd-drawer,
.kd-rolagem-borda {
  scrollbar-width: none;            /* Firefox, e o padrao novo */
  -ms-overflow-style: none;         /* Edge antigo */
}

.kd-trilho::-webkit-scrollbar,
.kd-tabela-rolagem::-webkit-scrollbar,
.kd-drawer::-webkit-scrollbar,
.kd-rolagem-borda::-webkit-scrollbar { display: none; }   /* Chrome, Edge, Safari */

/* 3. O "X" DE LIMPAR DO CAMPO DE BUSCA.
   O WebKit poe um X dentro de todo `type="search"` com texto. O Figma desenha
   a Busca com a lupa a esquerda e mais nada.

   MEDIDO EM 24/09/2026, E A MEDIDA TEM UMA RESSALVA HONESTA: no Chrome 154
   headless o X NAO chega a ser pintado com o CSS deste projeto — nem com esta
   regra, nem sem ela. A prova em pixel esta no relatorio: o unico caso em que
   aparecia tinta na ponta direita do campo era a BORDA nativa, que o reset do
   `.kd-busca-campo` ja tira. E `getComputedStyle(campo, '::-webkit-...')` nao
   serve de prova: nesta versao ele devolve a caixa do proprio input.

   A regra FICA mesmo assim, e a razao e explicita: ela e a forma documentada de
   barrar o controle no WebKit, o Safari do iPhone o desenha, e o dia em que
   alguem devolver um `background` ao campo o Chrome volta a desenha-lo. Custa
   um seletor. Esta no relatorio como "conferir numa janela de verdade". */
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}

/* 4. O OLHO DE SENHA DO EDGE.
   O Edge poe um olho proprio (`::-ms-reveal`) dentro de todo campo de senha,
   alem do icone `visibility` que o Figma desenha no Campo de texto do painel.
   Sao dois olhos lado a lado, um deles fora do desenho. O `::-ms-clear` e o X
   que ele poe nos campos de texto, pela mesma razao. */
input::-ms-reveal,
input::-ms-clear { display: none; }

/* 5. O CAMPO PREENCHIDO PELO NAVEGADOR.
   O Chrome pinta de amarelo (claro) ou azul-escuro (escuro) todo campo que ele
   preenche sozinho — o login do painel, sempre. A cor entra pelo tema interno
   do navegador e `background-color` NAO a vence: ela nao e um fundo comum, e um
   realce do UA. O que a cobre e uma sombra interna solida do tamanho do campo,
   e e por isso que existe uma sombra num projeto que nao usa sombra em lugar
   nenhum — ela nao desenha nada, so repinta.

   A cor vem de `--kd-autofill-fundo`, para cada contexto dizer a sua: o Campo
   de texto do painel mora dentro de um bloco e usa surface-container-high; a
   Busca do Header usa surface-container-lowest, que desde o lote 32 e a cor
   dela em TODO estado — parada, rolada e sobre o fundo da marca. Ate o lote 31
   eram duas (surface-container parada, surface-container-lowest so no Header
   rolado) e esta linha guardava a primeira; com o Header vermelho a Busca
   ficou branca sempre, e o autopreenchimento acompanhou.
   O padrao cobre o caso do painel, que e onde ha login.

   `-webkit-text-fill-color` e nao `color`: no campo preenchido o Chrome
   tambem troca a cor do texto, e so essa propriedade a vence. */
:root { --kd-autofill-fundo: var(--md-sys-color-surface-container-high); }
.kd-busca { --kd-autofill-fundo: var(--md-sys-color-surface-container-lowest); }

input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
  /* `100px` de espalhamento e nao a altura do campo: a sombra interna cresce
     do contorno para dentro, e qualquer numero maior que a metade da maior
     dimensao do campo ja o preenche inteiro. 100 cobre com folga os 48 do
     Campo de texto e os 40 da Busca, e continua valendo se o campo crescer. */
  box-shadow: 0 0 0 100px var(--kd-autofill-fundo) inset;
  -webkit-text-fill-color: var(--md-sys-color-on-surface);
  caret-color: var(--md-sys-color-on-surface);
}

/* Texto so para leitor de tela. */
.kd-oculto-visual {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ===========================================================================
   Tipografia — cada papel do Figma vira uma classe
   =========================================================================== */

.kd-title-large {
  font-family: var(--md-sys-typescale-title-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-title-large-size);
  line-height: var(--md-sys-typescale-title-large-line-height);
  letter-spacing: var(--md-sys-typescale-title-large-tracking);
  font-weight: var(--md-sys-typescale-title-large-weight);
}
/* Iniciais do Logo da loja Extra grande (Figma 60907:921), e so isso por
   enquanto: Manrope ExtraBold 24/32. */
.kd-headline-small-emphasized {
  font-family: var(--md-sys-typescale-headline-small-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-headline-small-size);
  line-height: var(--md-sys-typescale-headline-small-line-height);
  letter-spacing: var(--md-sys-typescale-headline-small-tracking);
  font-weight: var(--md-sys-typescale-headline-small-weight-emphasized);
}
.kd-title-large-emphasized {
  font-family: var(--md-sys-typescale-title-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-title-large-size);
  line-height: var(--md-sys-typescale-title-large-line-height);
  letter-spacing: var(--md-sys-typescale-title-large-tracking);
  font-weight: var(--md-sys-typescale-title-large-weight-emphasized);
}
.kd-title-medium {
  font-family: var(--md-sys-typescale-title-medium-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-title-medium-size);
  line-height: var(--md-sys-typescale-title-medium-line-height);
  letter-spacing: var(--md-sys-typescale-title-medium-tracking);
  font-weight: var(--md-sys-typescale-title-medium-weight);
}
.kd-title-small {
  font-family: var(--md-sys-typescale-title-small-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-title-small-size);
  line-height: var(--md-sys-typescale-title-small-line-height);
  letter-spacing: var(--md-sys-typescale-title-small-tracking);
  font-weight: var(--md-sys-typescale-title-small-weight);
}
/* O titulo do Menu de exibicao (lote 24). Mesmo tamanho da title/small, so o
   peso muda — e o token do peso ja existia no tokens.css, sem uso ate aqui. */
.kd-title-small-emphasized {
  font-family: var(--md-sys-typescale-title-small-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-title-small-size);
  line-height: var(--md-sys-typescale-title-small-line-height);
  letter-spacing: var(--md-sys-typescale-title-small-tracking);
  font-weight: var(--md-sys-typescale-title-small-weight-emphasized);
}
/* As três que o painel acrescenta (lote 17): `headline/small` no título do
   Login, `headline/medium` no título de cada tela e `headline/large` no número
   dos Card de indicador; `label/small` nos rótulos do eixo y do gráfico.
   Todas saem do typescale do Figma, sem valor solto. */
.kd-headline-small {
  font-family: var(--md-sys-typescale-headline-small-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-headline-small-size);
  line-height: var(--md-sys-typescale-headline-small-line-height);
  letter-spacing: var(--md-sys-typescale-headline-small-tracking);
  font-weight: var(--md-sys-typescale-headline-small-weight);
}
.kd-headline-medium {
  font-family: var(--md-sys-typescale-headline-medium-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-headline-medium-size);
  line-height: var(--md-sys-typescale-headline-medium-line-height);
  letter-spacing: var(--md-sys-typescale-headline-medium-tracking);
  font-weight: var(--md-sys-typescale-headline-medium-weight);
}
.kd-headline-large {
  font-family: var(--md-sys-typescale-headline-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-headline-large-size);
  line-height: var(--md-sys-typescale-headline-large-line-height);
  letter-spacing: var(--md-sys-typescale-headline-large-tracking);
  font-weight: var(--md-sys-typescale-headline-large-weight);
}
.kd-label-small {
  font-family: var(--md-sys-typescale-label-small-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-label-small-size);
  line-height: var(--md-sys-typescale-label-small-line-height);
  letter-spacing: var(--md-sys-typescale-label-small-tracking);
  font-weight: var(--md-sys-typescale-label-small-weight);
}
/* Usada no título da célula principal da Tabela do painel — medido
   `M3/body/medium-emphasized`. */
.kd-body-medium-emphasized {
  font-family: var(--md-sys-typescale-body-medium-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: var(--md-sys-typescale-body-medium-line-height);
  letter-spacing: var(--md-sys-typescale-body-medium-tracking);
  font-weight: var(--md-sys-typescale-body-medium-weight-emphasized);
}
.kd-headline-medium-emphasized {
  font-family: var(--md-sys-typescale-headline-medium-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-headline-medium-size);
  line-height: var(--md-sys-typescale-headline-medium-line-height);
  letter-spacing: var(--md-sys-typescale-headline-medium-tracking);
  font-weight: var(--md-sys-typescale-headline-medium-weight-emphasized);
}
.kd-body-large {
  font-family: var(--md-sys-typescale-body-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: var(--md-sys-typescale-body-large-line-height);
  letter-spacing: var(--md-sys-typescale-body-large-tracking);
  font-weight: var(--md-sys-typescale-body-large-weight);
}
.kd-body-medium {
  font-family: var(--md-sys-typescale-body-medium-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-body-medium-size);
  line-height: var(--md-sys-typescale-body-medium-line-height);
  letter-spacing: var(--md-sys-typescale-body-medium-tracking);
  font-weight: var(--md-sys-typescale-body-medium-weight);
}
.kd-body-small {
  font-family: var(--md-sys-typescale-body-small-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: var(--md-sys-typescale-body-small-line-height);
  letter-spacing: var(--md-sys-typescale-body-small-tracking);
  font-weight: var(--md-sys-typescale-body-small-weight);
}
.kd-label-large {
  font-family: var(--md-sys-typescale-label-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line-height);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  font-weight: var(--md-sys-typescale-label-large-weight);
}
.kd-label-large-emphasized {
  font-family: var(--md-sys-typescale-label-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line-height);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  font-weight: var(--md-sys-typescale-label-large-weight-emphasized);
}
.kd-label-medium {
  font-family: var(--md-sys-typescale-label-medium-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-label-medium-size);
  line-height: var(--md-sys-typescale-label-medium-line-height);
  letter-spacing: var(--md-sys-typescale-label-medium-tracking);
  font-weight: var(--md-sys-typescale-label-medium-weight);
}
.kd-label-small-emphasized {
  font-family: var(--md-sys-typescale-label-small-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-label-small-size);
  line-height: var(--md-sys-typescale-label-small-line-height);
  letter-spacing: var(--md-sys-typescale-label-small-tracking);
  font-weight: var(--md-sys-typescale-label-small-weight-emphasized);
}

/* ===========================================================================
   Estrutura da pagina
   =========================================================================== */

.kd-pagina {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.kd-conteudo {
  width: 100%;
  max-width: var(--kd-largura-conteudo);
  margin: 0 auto;
  padding-left: var(--kd-margem);
  padding-right: var(--kd-margem);
}

.kd-principal {
  flex: 1 1 auto;
  padding-top: var(--md-sys-measurement-space200);
  padding-bottom: var(--kd-secao);
  display: flex;
  flex-direction: column;
  gap: var(--kd-secao);
}

.kd-secao {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);
}

.kd-secao-titulo {
  margin: 0;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-title-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-title-large-size);
  line-height: var(--md-sys-typescale-title-large-line-height);
  letter-spacing: var(--md-sys-typescale-title-large-tracking);
  font-weight: var(--md-sys-typescale-title-large-weight);
}

.kd-grade {
  display: grid;
  grid-template-columns: var(--kd-grade-template);
  gap: var(--kd-grade-gap);
  align-items: stretch;
}

/* ---------------------------------------------------------------------------
   A FAIXA DA MARCA NA HOME (lote 32, etapa 3)

   Figma, camada "fundo da marca (degrade)" das telas da Home: retangulo na
   largura da JANELA, a partir do TOPO DA PAGINA — portanto por tras do Header
   tambem —, 260 de altura de 600 em diante e 300 abaixo, com degrade linear de
   cima para baixo, `--kd-fundo-da-marca` solido ate 42% (50% abaixo de 600) e
   dali ate `surface` no fim. As duas cores sao token; nenhuma cor escrita.

   E A UNICA EXCECAO A LEI 6 ("sem gradiente decorativo"), ja registrada no
   CLAUDE.md: pedido do Matheus em 25/09/2026, com o Magalu e o Mercado Livre
   como referencia. Em qualquer outro lugar do site continua nao havendo
   gradiente.

   POR QUE ISTO E O FUNDO DO `<body>` E NAO UM ELEMENTO NOVO NO HTML. O pedido
   tem tres exigencias que, juntas, ficam caras para quem usa um `<div>`:

     1. comecar no topo da PAGINA, acima do `<main>` e atras do Header;
     2. ter a largura da JANELA, e nao os 1200 do `.kd-conteudo`;
     3. ficar ABAIXO de tudo na pilha do lote 30 (setas 1, barra presa 2, aviso
        3, header 4, menus 5).

   Um `<div>` posicionado resolveria as duas primeiras e deixaria a terceira por
   conta de um `z-index` negativo — um degrau abaixo do zero acrescentado aquela
   pilha so por causa de uma decoracao, e que qualquer contexto de empilhamento
   novo no caminho anularia. O fundo de um elemento nao disputa pilha nenhuma:
   ele e pintado antes do conteudo e antes de todo descendente posicionado, por
   definicao. Nada pode ficar atras dele e nada precisa de `z-index`. De quebra,
   dispensa um elemento vazio no HTML — o Figma desenha uma CAMADA DE FUNDO, e
   nao um bloco de conteudo (lei 1).

   E ELE ROLA JUNTO COM A PAGINA, que e o item 4 do lote: `background-attachment`
   fica no padrao `scroll`, isto e, o fundo e posicionado na caixa do `<body>`,
   que rola. `fixed` grudaria a faixa na janela e ela reapareceria embaixo do
   Header no meio da pagina.

   O FUNDO DO `<body>` NAO VAZA PARA A TELA INTEIRA porque o `html` ja declara
   `background` proprio, la na secao "Base". Quando a raiz tem fundo, o do
   `<body>` deixa de ser propagado para o canvas e pinta so a caixa dele — que e
   exatamente o retangulo que o Figma desenha. Se um dia alguem tirar o fundo do
   `html`, esta faixa se espalha pela janela inteira; e a unica amarra deste
   trecho com outro, e por isso ela esta escrita aqui.

   A EMENDA COM O HEADER NAO EXISTE COMO LINHA. Nos primeiros 72 px (100 no
   celular) o Header pinta `--kd-fundo-da-marca` solido e a faixa, atras dele,
   esta na mesma cor solida — 72 e 100 cabem folgados dentro dos 109,2 e dos 150
   de trecho solido. E o MESMO valor do MESMO token nos dois temas: nao ha meio
   pixel de diferenca para virar linha.

   `:has()` NO LUGAR DE UMA CLASSE NOVA NO `<body>`: a Home ja se identifica
   pelo `.kd-home` do `<main>`, e o arquivo ja usa o seletor no
   `html:has(.kd-barra-ordem)` do `scroll-padding-top`. Assim nenhum PHP muda, e
   as outras quatro paginas continuam comecando em `surface` logo abaixo do
   Header, sem faixa — item 5 do lote.

   `background-image` E OS TRES LONGHANDS, E NAO O ATALHO `background`: o atalho
   apagaria o `background-color` que a regra do `<body>` define. Esse fundo e o
   `--md-sys-color-background`, que vale #FFFFFF no claro e #121212 no escuro —
   os mesmos valores do `surface` onde o degrade termina. Por isso o fim da
   faixa emenda com o resto da pagina sem linha nenhuma.
   --------------------------------------------------------------------------- */
body:has(.kd-home) {
  background-image: linear-gradient(
    to bottom,
    var(--kd-fundo-da-marca) 0%,
    var(--kd-fundo-da-marca) var(--kd-faixa-marca-solido),
    var(--md-sys-color-surface) 100%);
  background-repeat: no-repeat;
  background-position: left top;
  background-size: 100% var(--kd-faixa-marca-altura);
}

/* ===========================================================================
   Icones — sprite inline, desenhados com a cor do texto
   =========================================================================== */

.kd-icone {
  display: block;
  width: var(--md-sys-measurement-space300);   /* 24 */
  height: var(--md-sys-measurement-space300);
  fill: currentColor;
  flex: none;
}
/* 32: so o `search_off` do Estado vazio, medido no Figma (60840:566). */
.kd-icone-32 {
  width: var(--md-sys-measurement-space400);   /* 32 */
  height: var(--md-sys-measurement-space400);
}
.kd-icone-20 {
  width: var(--md-sys-measurement-space250);   /* 20 */
  height: var(--md-sys-measurement-space250);
}
.kd-icone-18 {
  /* 18 nao existe na colecao Spacing; e medida do Chip de filtro. */
  width: var(--kd-chip-icone);
  height: var(--kd-chip-icone);
}
.kd-icone-16 {
  width: var(--md-sys-measurement-space200);   /* 16 */
  height: var(--md-sys-measurement-space200);
}

/* ===========================================================================
   Logo da marca (lote 17.1, medidas refeitas no 18.1)

   O projeto desenhou um espaço reservado — uma pastilha cinza com a palavra
   "logo" — enquanto a marca não existia. Ela entrou no lote 17.1, em PNG, e no
   18.1 virou SVG; o Figma foi atualizado junto e hoje desenha a marca de
   verdade nos cinco lugares.

   DUAS ARTES, UMA POR TEMA. O arquivo claro tem a palavra em preto e o escuro
   em branco; a lupa é vermelha nos dois. A troca é feita por uma custom
   property com o endereço da imagem, redefinida nos MESMOS seletores que o
   `tokens.css` usa — `[data-theme="dark"]` para a escolha gravada e
   `@media (prefers-color-scheme: dark)` com a guarda `:not([data-theme="light"])`
   para a preferência do sistema. Assim o logo acompanha o alternador na hora,
   sem recarregar, como todo o resto.

   POR QUE `background-image` E NÃO `<img>`. Um `<img>` só troca de arquivo por
   `srcset`/`<picture>`, e o `media` do `<picture>` enxerga só o
   `prefers-color-scheme` — ele ignoraria o `data-theme` que o alternador põe no
   `<html>`, e clicar no tema deixaria o logo errado até o próximo F5. Com
   `background-image` quem manda é o CSS, que já sabe dos dois. O nome
   acessível não se perde: onde o logo é link, ele vem do `aria-label`; onde não
   é, de um texto escondido.

   O SÍMBOLO SOZINHO, NO TRILHO DO PAINEL. A marca inteira é 3440×590 (5,8305:1)
   e a caixa do trilho é 64×40 — a marca ali daria 64×11, ilegível. O símbolo é
   um arquivo à parte, 870×590 (1,4746:1), e é um só, sem versão por tema,
   porque a lupa é vermelha nos dois. Até o lote 17.1 ele era um recorte
   automático do PNG, 860×590, que perdia a ponta do cabo da lupa; o SVG traz a
   lupa inteira.

   O TAMANHO DE CADA CAIXA É O DO FIGMA, MEDIDO EM 24/09/2026:
     Header desktop, Footer e Login   233,2203 × 40   (a marca)
     Header mobile                    186,576  × 32   (a marca)
     Trilho do painel                 64 × 40 de caixa, com a arte a 47,186 × 32
   As três primeiras são caixa e arte na mesma medida: fixa-se a ALTURA e a
   largura sai da proporção, por `aspect-ratio`. A do trilho é a exceção, e o
   porquê está no bloco dela, mais abaixo.

   Entre 600 e 767 o Header troca a marca pelo símbolo. Essa largura o Figma não
   desenha — é regra do projeto, decidida no lote 17.1 e escrita no documento do
   Figma. O porquê está na regra, logo abaixo.
   =========================================================================== */

/* OS TRES ENDERECOS DA ARTE NAO MORAM MAIS AQUI (lote 18.1).
   Eles passaram para `templates/parciais/marca.php`, que e PHP e pode carimbar
   a versao no endereco com `Ativo::url()`. Dentro de um `.css` nao ha PHP, e
   sem versao a arte ficaria dez anos no cache do visitante — o defeito que o
   `tokens.css` teve no lote 13. O que continua aqui e o tamanho e a posicao:
   `--kd-logo-imagem` e `--kd-logo-simbolo` chegam do <head>. */

/* A caixa do Figma, com a arte contida e centrada. Sem fundo e sem canto: a
   pastilha cinza era do espaço reservado, não da marca. */
.kd-logo {
  display: block;
  height: var(--kd-logo-altura);
  aspect-ratio: var(--kd-logo-proporcao);
  /* `fit-content` e nao `auto`: um bloco com largura automatica ENCHE o pai, e
     a proporcao seria ignorada — no Footer e no Login o logo saia com 360 e 336
     de largura em vez dos 233 da arte. */
  width: fit-content;
  flex: none;
  background-image: var(--kd-logo-imagem);
  background-repeat: no-repeat;
  background-position: left center;
  background-size: contain;
}

/* A LOGO DO HEADER E BRANCA, E ELA SAI POR MASCARA (lote 32).
   -------------------------------------------------------------------------
   O Figma pede a variante nova "Marca sobre a marca" / "Simbolo sobre a marca"
   do componente Logo: o desenho inteiro em on-primary, sobre o fundo da marca.

   AQUI A LOGO NAO E UM <svg> NO HTML, E UMA IMAGEM DE FUNDO. Os arquivos
   chegam por `--kd-logo-imagem` e `--kd-logo-simbolo`, escritas no
   `parciais/marca.php` para o endereco poder levar a versao. Imagem de fundo
   nao se repinta por CSS, e dentro de cada arquivo a cor esta ESCRITA: `fill`
   no `<g>`, #F0001A na lupa e #000000 (claro) ou #FFFFFF (escuro) na palavra.
   Nenhum deles usa `currentColor`.

   ENTAO NAO ENTROU UM QUARTO ARQUIVO BRANCO: entrou a mascara. `mask-image`
   usa o ALFA do SVG como forma e joga fora a cor dele; quem pinta e o
   `background-color`, que aqui e o token `--md-sys-color-on-primary`. Um
   arquivo serve os dois temas, nenhuma cor literal entra no CSS (lei 3), e no
   dia em que a arte mudar de desenho a mascara acompanha sozinha.

   FUNCIONA PORQUE OS ARQUIVOS NAO TEM FUNDO: conferidos em 25/09/2026, sao so
   dois `<g>` de `<path>` sobre transparente, sem `<rect>` por tras. E o claro e
   o escuro tem a MESMA geometria — o `diff` acusa UMA linha de diferenca, o
   `fill` do segundo grupo. Por isso tanto faz qual dos dois a `--kd-logo-imagem`
   entrega aqui: a forma da mascara e a mesma nos dois temas.

   `-webkit-mask-*` junto do padrao, que o Safari ainda pede.

   SO NO HEADER. No Footer e no Login a mesma classe `.kd-logo` continua sendo a
   arte colorida, porque la ela nao esta sobre a marca. */
.kd-header .kd-logo {
  background-image: none;
  background-color: var(--md-sys-color-on-primary);
  -webkit-mask-image: var(--kd-logo-imagem);
          mask-image: var(--kd-logo-imagem);
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: left center;
          mask-position: left center;
  -webkit-mask-size: contain;
          mask-size: contain;
}

/* ENTRE 600 E 767 O HEADER MOSTRA SÓ O SÍMBOLO.
   O Header desktop começa em 600, e ali a linha é logo + busca + alternador.
   Com a marca inteira (233) a busca sobrava com 179 e o texto de dentro saía
   cortado — "Buscar ofe…". Com o símbolo (58) ela volta a 354 e o texto cabe.
   De 768 em diante, que é a largura que o Figma desenha, a marca inteira entra
   e a busca fica com 347. É a mesma decisão da caixa que cresceu: a arte real
   tem proporção que o espaço reservado do desenho não tinha. Está no relatório.

   QUEM TROCA AGORA É A MÁSCARA, e não o `background-image` (lote 32): dentro do
   Header o fundo é uma cor lisa e a arte virou recorte. Trocar o
   `background-image` aqui pintaria o símbolo VERMELHO por baixo do recorte, em
   vez do branco. A regra vem depois da de cima de propósito — as duas têm a
   mesma especificidade, e no empate vence a última. */
@media (min-width: 600px) and (max-width: 767.98px) {
  .kd-header-desktop .kd-logo {
    aspect-ratio: var(--kd-logo-simbolo-proporcao);
    -webkit-mask-image: var(--kd-logo-simbolo);
            mask-image: var(--kd-logo-simbolo);
  }
}

/* Trilho do painel: so o simbolo, e ele nao muda com o tema (a lupa e vermelha
   nos dois).

   AQUI A CAIXA E A ARTE TEM TAMANHOS DIFERENTES, e por isso este bloco nao se
   parece com os outros tres. Nos outros, a caixa E a arte: fixa-se a altura e a
   largura sai da proporcao. No trilho o Figma desenha uma caixa de 64x40 com o
   simbolo de 47x32 CENTRADO dentro dela — a caixa guarda o lugar na pilha (e e
   ela que faz a conta dos 772 de altura fechar), e a arte fica menor que ela.

   Ate o lote 18.1 a arte enchia a caixa: 58x40. Ao lado de icones de 24 ela
   pesava demais, e o Matheus viu isso no ar. A 32 de altura o simbolo fica do
   tamanho do indicador do item atual (56x32), que e o vizinho de baixo.

   `background-size: auto 32px` e nao `contain`: `contain` encheria a altura da
   caixa de novo. A LARGURA continua sem numero escrito — ela sai da proporcao
   do SVG (870/590 x 32 = 47,2, que e o 47 do Figma). */
.kd-trilho-logo {
  display: block;
  width: var(--kd-trilho-logo);                         /* 64 */
  height: var(--kd-botao-altura);                       /* 40 */
  flex: none;
  background-image: var(--kd-logo-simbolo);
  background-repeat: no-repeat;
  background-position: center;
  background-size: auto var(--kd-trilho-simbolo-altura);  /* 32 de altura */
}

/* Login do painel: a marca inteira, alinhada à esquerda do bloco. */
.kd-login-logo {
  display: block;
  height: var(--kd-botao-altura);                       /* 40 */
  aspect-ratio: var(--kd-logo-proporcao);
  width: fit-content;
  flex: none;
  background-image: var(--kd-logo-imagem);
  background-repeat: no-repeat;
  background-position: left center;
  background-size: contain;
}

/* ===========================================================================
   Alternador de tema (Figma 60981:1878) — pilula 76x40
   =========================================================================== */

/* Alternador de tema — pilula 76x40, medido no Figma. VALE PARA O SITE E PARA O
   PAINEL: os dois desenham a mesma pilula, e o que muda e o nome do segmento
   (`.kd-tema-opcao` no site, `.kd-tema-item` no painel). Ate o lote 19.1 esta
   declaracao aparecia duas vezes no arquivo, com as sete propriedades
   identicas; ficou uma. */
.kd-tema {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space50);
  padding: var(--md-sys-measurement-space50);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest);
  flex: none;
}

.kd-tema-opcao {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--md-sys-measurement-space400);   /* 32 */
  height: var(--md-sys-measurement-space400);
  border-radius: var(--md-sys-shape-corner-full);
  color: var(--md-sys-color-on-surface-variant);
  cursor: pointer;
}

.kd-tema-opcao[aria-pressed="true"] {
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

.kd-tema-opcao .kd-icone {
  width: var(--md-sys-measurement-space250);   /* 20 */
  height: var(--md-sys-measurement-space250);
}

/* O TRILHO DO ALTERNADOR FICA BRANCO DENTRO DO HEADER (lote 32).
   Medido na camada `tema` das quatro variantes do Header 60838:2515: o fill do
   trilho deixou de ser `Schemes/Surface Container Highest` e passou a ser
   `Schemes/On Primary` — o branco que separa a pilula do vermelho.

   SO DENTRO DO HEADER, e por isso a regra e `.kd-header .kd-tema` e nao
   `.kd-tema`: a mesma pilula existe na barra de conta do painel, sobre
   superficie normal, e la o trilho continua surface-container-highest.

   A PILULA ESCOLHIDA E OS ICONES NAO PRECISAM DE REGRA NOVA. Eles ja sao
   `secondary` / `on-secondary` / `on-surface-variant`, e o `data-theme="light"`
   que o header.php poe na linha faz esses tres chegarem com o valor do tema
   CLARO tambem no escuro: fundo #1A1A1A, icone branco, #636363 no nao
   escolhido — exatamente o que o Figma desenha nas quatro variantes. Sem o
   atributo, no escuro `secondary` seria #FFFFFF e a pilula sumiria no trilho. */
.kd-header .kd-tema {
  background: var(--md-sys-color-on-primary);
}

/* ===========================================================================
   Busca (Figma 61031:83707) — h40, Corner/Full

   Ate 24/09/2026 era o Search bar do kit, que so existe com 56 e nao aceita
   outra altura na instancia. Virou componente proprio: 40 de altura, canto
   full, fundo surface-container; o icone `search` de 24 fica centrado numa
   area de 40, e o texto e body/large em on-surface-variant, com reticencias.
   Padding Space 50 a esquerda (a area do icone ja afasta) e Space 200 a
   direita; Space 50 entre o icone e o texto.
   =========================================================================== */

/* A BORDA DA BUSCA SAIU (lote 32), E COM ELA A ULTIMA EXCECAO A LEI 6.
   -------------------------------------------------------------------------
   Ela nasceu no lote 26: a Busca `surface-container` sumia dentro do Header
   `surface` e o Matheus pediu um contorno. Com o Header na cor da marca o
   problema deixou de existir — a Busca e branca sobre vermelho e se separa
   sozinha, com 4,58:1 de contraste no claro e 6,44:1 no escuro.

   MEDIDO NO FIGMA em 25/09/2026, nas quatro variantes do Header 60838:2515
   (Desktop, Mobile, Desktop · Rolado e Mobile · Rolado): `strokes: []` e
   `strokeWeight: 0` na camada `busca` das quatro. A linha da excecao saiu do
   `CLAUDE.md` junto, e o site voltou a nao ter borda nenhuma.

   O FUNDO PASSOU A SER surface-container-lowest, E EM TODO ESTADO. Ate o lote
   31 eram duas cores — surface-container parada e surface-container-lowest so
   quando o Header rolava. Agora e uma so, e o `.kd-header-rolado` nao troca
   mais nada alem da sombra.

   O TEXTO CONTINUA on-surface / on-surface-variant, E NAO VIRA BRANCO: quem
   garante que ele fica legivel e o `data-theme="light"` que o header.php poe na
   linha da Busca, e que faz esses tokens valerem o do tema claro tambem no
   escuro. Sem o atributo, a Busca branca do tema escuro receberia on-surface
   #FFFFFF — texto branco sobre branco.                                     */
.kd-busca {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space50);        /* 4 */
  height: var(--kd-busca-altura);                /* 40 */
  padding: 0 var(--md-sys-measurement-space200) 0 var(--md-sys-measurement-space50);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface-variant);
  flex: 1 1 auto;
  min-width: 0;
}

/* O icone mora numa area de 40, como no Figma — e o que o alinha com a altura
   da barra sem depender de padding. */
.kd-busca > .kd-icone {
  width: var(--kd-busca-altura);
  height: var(--kd-busca-altura);
  padding: var(--md-sys-measurement-space100);   /* 8: 24 de icone em 40 */
  box-sizing: border-box;
  color: var(--md-sys-color-on-surface);
}

.kd-busca-campo {
  flex: 1 1 auto;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  text-overflow: ellipsis;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-body-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: var(--md-sys-typescale-body-large-line-height);
  letter-spacing: var(--md-sys-typescale-body-large-tracking);
  /* O PESO FALTAVA (achado no lote 23). O texto do Figma tem o `fontStyle`
     ligado a `Static/Body Large/Weight` e o token existe desde sempre; aqui os
     outros quatro eixos estavam aplicados e este nao. Hoje nao muda nada na
     tela — o padrao do navegador e 400, que e o Manrope Regular —, mas bastava
     a fonte mudar de peso padrao para o campo sair diferente do desenho. */
  font-weight: var(--md-sys-typescale-body-large-weight);
}

.kd-busca-campo::placeholder {
  color: var(--md-sys-color-on-surface-variant);
  opacity: 1;
}

/* --- O exemplo que troca sozinho na Busca (lote 23) -----------------------
   MEDIDO NO FIGMA EM 25/09/2026: o texto e `Buscar “air fryer”`, com aspas
   curvas (U+201C e U+201D), em `M3/body/large` e `Schemes/On Surface Variant` —
   exatamente o que o `::placeholder` ja tinha. Ele deixou de ser o atributo
   `placeholder` e virou um elemento por cima do campo porque ATRIBUTO NAO
   ANIMA: o documento pede que o texto saia para cima e o proximo entre de
   baixo.

   A SOBREPOSICAO NAO E CLICAVEL (`pointer-events: none`): o clique atravessa e
   cai no `<input>`, como cairia num placeholder de verdade.

   ELA SOME NO INSTANTE EM QUE SE DIGITA. Quem faz isso e o
   `:placeholder-shown` do campo — e e por isso que o `<input>` ficou com um
   `placeholder` de um espaco: sem placeholder nenhum o pseudo nunca casaria, e
   o exemplo ficaria por cima do texto da pessoa.

   NO FOCO ELA FICA. Igual a um placeholder de verdade, que so some quando se
   escreve. O que para no foco e a TROCA, e disso cuida o kd.js.              */
.kd-busca-sugestao {
  position: absolute;
  /* O texto comeca exatamente onde o `<input>` comeca: o `left` de um elemento
     `absolute` conta da caixa de PADDING do pai, e o padding da pilula fica
     dentro dela — entao os 4 da esquerda entram na conta junto com os 40 do
     icone e os 4 de gap. Medido em 25/09/2026: sem os primeiros 4, o exemplo
     saia 4 px a esquerda do que a pessoa digita. */
  left: calc(var(--md-sys-measurement-space50)      /* 4  — padding da pilula */
             + var(--kd-busca-altura)               /* 40 — area do icone     */
             + var(--md-sys-measurement-space50));  /* 4  — gap ate o campo   */
  right: var(--md-sys-measurement-space200);                                /* 16 */
  height: var(--md-sys-typescale-body-large-line-height);
  overflow: hidden;
  pointer-events: none;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-body-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-body-large-size);
  line-height: var(--md-sys-typescale-body-large-line-height);
  letter-spacing: var(--md-sys-typescale-body-large-tracking);
}

/* A pilula vira a referencia do `absolute` acima. Ela ja era `flex`; o
   `relative` e a unica linha nova. */
.kd-busca { position: relative; }

.kd-busca-campo:not(:placeholder-shown) ~ .kd-busca-sugestao { display: none; }

/* O TEXTO E QUE SE MOVE, dentro da janela de uma linha que o `overflow: hidden`
   do pai recorta. Sai para cima (-100%) e o proximo entra de baixo (100%).

   DUAS EXCECOES DE VALOR SOLTO, e as duas estao no relatorio. O `tokens.css` e
   gerado do Figma e NAO TEM nenhum token de movimento — nenhuma das 6 colecoes
   tem variavel de duracao ou de curva, e este e o primeiro movimento do
   projeto (o `app.css` nao tinha uma `transition` sequer ate aqui). Os dois
   valores vem do documento e do M3:

     300ms                      o documento do lote 23
     cubic-bezier(0.2, 0, 0, 1) a curva `emphasized` do M3. Ela esta MEDIDA
                                dentro do proprio arquivo do Figma, nos 1.192
                                prototipos do kit M3 (CUSTOM_CUBIC_BEZIER
                                x1=0.2 y1=0 x2=0 y2=1) — so que la com 200 ms,
                                no hover dos componentes. O 300 e do documento.

   Quem pediu menos movimento no sistema nao ganha movimento nenhum: a regra de
   `prefers-reduced-motion` desliga a transicao, e o kd.js nem chega a trocar o
   texto. Sao as duas metades da mesma decisao, e as duas precisam existir — a
   de CSS para o caso de a classe ser posta por engano, a de JavaScript para o
   texto ficar parado na primeira sugestao.                                   */
.kd-busca-sugestao-texto {
  display: block;
  transition: transform var(--kd-movimento-duracao) var(--kd-movimento-curva);
}

.kd-busca-sugestao-saindo  { transform: translateY(-100%); }
.kd-busca-sugestao-entrando { transform: translateY(100%); }

/* Sem transicao: o texto pula direto para o lugar, sem intervalo visivel. */
.kd-busca-sugestao-sem-transicao { transition: none; }

@media (prefers-reduced-motion: reduce) {
  .kd-busca-sugestao-texto { transition: none; }
}


/* QUEM MOSTRA O FOCO E A PILULA INTEIRA, NAO O CAMPO DE DENTRO.
   O `outline: none` no `.kd-busca-campo` tem especificidade 0,1,0 e perdia para
   a regra geral `input:focus-visible` (0,1,1) la de cima — o resultado era
   DOIS aneis ao clicar na busca: um em volta do campo e outro em volta da
   pilula. Visto pelo Matheus em 24/09/2026. O `:focus-visible` aqui empata a
   especificidade e desliga o anel de dentro; o de fora, que envolve tambem a
   lupa, e o que fica. */
.kd-busca-campo:focus-visible { outline: none; }

/* `:has(:focus-visible)` E NAO `:focus-within` (lote 18.1), E O QUE ISSO MUDA
   E MENOS DO QUE PARECE — vale dizer o que foi medido.

   `:focus-within` acende com QUALQUER foco de QUALQUER filho. `:has(:focus-visible)`
   repassa a decisao ao navegador. A regra fica certa, mas O QUE SE VE HOJE NAO
   MUDA: o unico filho focavel da pilula e um `<input type="search">`, e o
   navegador considera que campo de texto clicado com o mouse PRECISA de foco
   visivel — quem clica ali vai digitar. Medido em 24/09/2026: clique na busca,
   `matches(':focus-visible')` = true, anel aceso.

   E esta certo assim, e por isso nada mais foi feito: esconder o foco de um
   campo de texto seria pior do que o anel. O que a troca resolve e o futuro —
   um botao dentro da pilula (limpar, filtro) nao vai mais acender o anel dela
   ao ser clicado com o mouse. O anel no clique so aparece em campo de texto, e
   o levantamento inteiro esta no relatorio do lote 18.1. */
/* O ANEL DO FOCO FICA BRANCO DENTRO DO HEADER, E ISSO O FIGMA NAO DEFINE.
   O anel do projeto e `primary` em toda parte. Sobre o fundo da marca ele e a
   MESMA COR: #E3262F sobre #E3262F no claro da 1,00:1 pela formula da WCAG 2.1
   — um anel invisivel, que e pior do que anel nenhum, porque quem navega por
   teclado perde o rastro. No escuro seria #E3262F sobre #B81F27: 1,58:1, longe
   dos 3:1 que a 1.4.11 pede para componente de interface.

   O Figma nao desenha o estado de foco do Header, entao o valor vem da regra do
   M3 para conteudo sobre primary: `on-primary`. Medido: 4,58:1 sobre #E3262F e
   6,44:1 sobre #B81F27. Esta no relatorio como decisao que o Figma nao define.

   Ele continua POR FORA (`outline`), como o lote 26 deixou — e agora sem borda
   nenhuma por baixo.                                                        */
.kd-busca:has(:focus-visible) {
  outline: 2px solid var(--md-sys-color-on-primary);
  outline-offset: 2px;
}

/* ===========================================================================
   Header (Figma 60838:2515)
   Desktop 1440x64 · Mobile 390x100 · Mobile · Menu aberto
   =========================================================================== */

/* O HEADER E FIXO NO TOPO EM TODAS AS LARGURAS (lote 23).
   `sticky` e nao `fixed`: com `fixed` ele sai do fluxo e o conteudo de baixo
   subiria 72 px por baixo dele, exigindo um `padding-top` no `<body>` que teria
   de ser mantido em sincronia com a altura em cada ponto de quebra. Com
   `sticky` o espaco continua reservado e a altura e uma so — a do proprio
   elemento.

   Z-INDEX 4, E O NUMERO TEM UM PORQUE. A pilha do site, de baixo para cima:

     0   o conteudo da pagina (cards, grades, carrosseis)
     1   o Aviso de ofertas novas, que e `sticky` dentro do feed
     4   o Header
     5   o Menu de filtro (`fixed`, do lote 21)
     6   o FAB do painel
    10   o scrim do site
    11   o drawer do Header
    40/50 o scrim e a folha

   O Header fica ACIMA do conteudo e do Aviso, e ABAIXO dos menus, do scrim, do
   drawer e da folha — que e o que o lote pede: "folhas, drawer e menus
   continuam por cima de tudo". Um numero maior que 5 poria o Header na frente
   do Menu de filtro, e um menu aberto perto do topo da pagina sumiria por baixo
   dele.

   O FUNDO E O DA MARCA, EM TODAS AS PAGINAS (lote 32), e nao mais `surface`.
   Medido no Figma em 25/09/2026 nas quatro variantes do Header 60838:2515
   (Desktop 1440x72, Mobile 390x100 e as duas Roladas): o fill das quatro e a
   variavel `KD/Fundo da marca` — #E3262F no claro, #B81F27 no escuro.
   Referencia do Matheus: Magalu e Mercado Livre.

   ROLADO O FUNDO NAO MUDA MAIS. Ate o lote 31 ele trocava de `surface` para
   `surface-container`; agora as quatro variantes tem a MESMA cor e a unica
   diferenca entre parado e rolado e a KD/Sombra leve. Quem poe a classe
   continua sendo o `ligarHeaderRolado` do `kd.js`, que nao mudou uma linha: ele
   so liga e desliga `.kd-header-rolado`, e o que essa classe faz e que encolheu.

   O `color` passa a ser on-primary, que e o que fica por cima do fundo da
   marca. Ele nao pinta nada sozinho — a logo e mascara, a Busca e o botao de
   menu dizem a propria cor —, mas e o valor certo para herdar, e evita que um
   texto novo no Header nasca preto sobre o vermelho.                        */
.kd-header {
  position: sticky;
  top: 0;
  z-index: 4;
  background: var(--kd-fundo-da-marca);
  color: var(--md-sys-color-on-primary);
}

/* O ESTADO ROLADO AGORA E SO A SOMBRA (lote 32).
   Medido em 25/09/2026 nas quatro variantes: `Tamanho=Desktop` 60838:2340,
   `Tamanho=Mobile` 60838:2368, `Tamanho=Desktop · Rolado` 61172:2139 e
   `Tamanho=Mobile · Rolado` 61172:2164. As quatro tem o MESMO fill
   (`KD/Fundo da marca`) e a mesma Busca (surface-container-lowest, sem stroke).
   A unica diferenca entre parado e rolado, nos dois tamanhos, e o `effects`:
   vazio nas duas de cima, `KD/Sombra leve` nas duas de baixo.

   POR ISSO DUAS REGRAS SUMIRAM DAQUI, e vale dizer quais eram e por que
   deixaram de fazer sentido:

     `background: surface-container` no Header rolado — o Header agora e da cor
     da marca nos quatro estados. Trocar a cor ao rolar seria inventar um quinto
     estado que o Figma nao desenha (lei 1).

     `background: surface-container-lowest` na Busca do Header rolado — ela
     existia porque, ao rolar, o Header assumia a MESMA cor da Busca e o campo
     sumia (defeito do lote 23, corrigido no 26). Sem a troca de fundo do
     Header, nao ha mais colisao: a Busca e branca sobre vermelho o tempo todo,
     e a cor dela, junto com a do autopreenchimento, mora num lugar so, no
     bloco da propria Busca.

   O `ligarHeaderRolado` do `kd.js` NAO MUDOU: ele continua ligando e desligando
   `.kd-header-rolado` em `scrollY > 0`. Sem JavaScript o Header fica fixo e sem
   sombra, que e a variante padrao do Figma.                                 */
.kd-header-rolado {
  box-shadow: var(--kd-sombra-leve);
}

/* NADA FICA ESCONDIDO ATRAS DO HEADER FIXO.
   `scroll-padding-top` vale para TUDO o que rola a pagina por conta propria: a
   ancora de `href="#..."`, o `scrollIntoView` do JavaScript e — o que mais
   importa — a rolagem que o navegador faz sozinho quando o foco por teclado cai
   num elemento fora da vista. Sem isto, o Tab levaria o foco para debaixo do
   Header e o visitante veria o anel pela metade, ou nem veria.

   Os 8 a mais sao o respiro: colar o alvo na borda de baixo do Header deixa a
   secao parecendo cortada. E o mesmo Space 100 que o resto do projeto usa. */
html {
  scroll-padding-top: calc(var(--kd-header-altura) + var(--md-sys-measurement-space100));
}

/* ONDE HA BARRA PRESA, A CONTA GANHA A ALTURA DELA (lote 30, etapa 3.1).
   Sem isto, pular para `#ofertas` ou dar Tab num card poria o alvo
   exatamente atras da barra: o navegador desconta o Header, a barra desce e
   cobre o que ele acabou de revelar.

   O `:has()` limita a regra as paginas que TEM a barra. A alternativa era
   somar os 64 em toda pagina, e ai a Home e o Produto ganhariam um vao de 64
   abaixo do Header em cada ancora, para desviar de uma barra que nao existe
   la.                                                                    */
html:has(.kd-barra-ordem) {
  scroll-padding-top: calc(var(--kd-header-altura) + var(--md-sys-measurement-space100)
                           + var(--kd-barra-ordem-altura) + var(--md-sys-measurement-space100));
}

/* --- Mobile: ate 599 (o desenho de 390) ---
   100 de altura: padding 8 em cima e embaixo, linha do logo 32, Space 150 (12)
   e a barra de 40 com o botao do menu e a Busca. */
.kd-header-mobile {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space150);        /* 12 */
  padding-top: var(--md-sys-measurement-space100);
  padding-bottom: var(--md-sys-measurement-space100);
  position: relative;
}

.kd-header-mobile .kd-logo {
  --kd-logo-altura: var(--kd-logo-altura-mobile);        /* 32 */
  margin-left: var(--md-sys-measurement-space50);        /* 4 */
}

.kd-header-linha-busca {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);        /* 8 */
  height: var(--kd-busca-altura);                 /* 40 */
}

/* Icon button: caixa de 48 (o alvo), pilula pintada de 40 no `::before`, icone
   de 24 em on-surface. */
.kd-botao-icone {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--kd-botao-icone-area);              /* 48 — onde o dedo acerta */
  height: var(--kd-botao-icone-area);
  flex: none;
  border-radius: var(--md-sys-shape-corner-full);
  color: var(--md-sys-color-on-surface);
  cursor: pointer;
}

/* AS DUAS CAMADAS DE 40 DENTRO DOS 48 (lote 19.2).
   -------------------------------------------------------------------------
   O que se ve do Icon button e um circulo de 40; os 48 sao so alvo. Ate o lote
   19.1 o elemento tinha 40 e os 4 de folga vinham de `margin-block` — mas
   MARGEM NAO RECEBE CLIQUE, entao o alvo continuava em 40, abaixo do minimo de
   toque. Agora o elemento tem os 48 e as duas camadas pintadas ficam em 40,
   centradas.

     ::before  o fundo do botao (transparente na maioria) e o ANEL de foco
     ::after   a camada de estado

   Sao duas porque o anel nao pode herdar a opacidade da camada: se os dois
   morassem no mesmo pseudo-elemento, um anel sobre uma camada a 10% sairia com
   10% de tinta. O icone fica entre as duas — `position: relative` o poe acima
   do `::before` e a ordem do DOM o deixa abaixo do `::after`, que e como o
   `.kd-botao` ja empilha desde o lote 11. */
.kd-botao-icone::before,
.kd-botao-icone::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: var(--kd-botao-icone-pilula);            /* 40 — o que se ve */
  height: var(--kd-botao-icone-pilula);
  transform: translate(-50%, -50%);
  border-radius: var(--md-sys-shape-corner-full);
  pointer-events: none;
}

.kd-botao-icone::after {
  background: currentColor;
  opacity: 0;
}

.kd-botao-icone > * { position: relative; }

/* A CAMADA DE ESTADO, medida no kit em 24/09/2026 (58663:30358, Round/Small):
     Hovered  State-layer com `State Layers/On Surface Variant/Opacity-08`
     Focused  o mesmo em `Opacity-10`, mais um `Focus indicator` de 44x44
     Pressed  o mesmo em `Opacity-08`
   A COR E `currentColor`, E NAO UM TOKEN ESCRITO: no kit a camada e a cor do
   CONTEUDO do botao, e o conteudo do Icon button standard e on-surface-variant
   — de onde sai o nome da variavel medida. Neste projeto o `more_vert` e os
   chevrons ficaram em on-surface e o "Sair" em on-surface-variant; com
   `currentColor` cada um acende na propria cor, que e a regra do kit, em vez de
   um dos dois tokens escolhido a dedo. As opacidades vem da colecao.
   O `Focus indicator` de 44 e o anel de 2 a 2 de afastamento em volta dos 40 —
   a mesma conta, o mesmo anel do resto do projeto.
   O Pressed do kit ainda encolhe o canto do `Content` de 100 para 8; o projeto
   nao faz essa troca de forma em lugar nenhum, e ela nao entrou so aqui. Esta
   no relatorio. */
.kd-botao-icone:hover::after  { opacity: var(--md-sys-state-hover-state-layer-opacity); }
/* O KIT DESENHA O Pressed COM `Opacity-08`, E AQUI ELE E 0,10.
   Nao e descuido: o kit repete a camada do hover no frame do Pressed e poe um
   `Ripple` por cima para dar a diferenca — e o projeto nao desenha ondulacao em
   lugar nenhum. Sem o Ripple, copiar os 8% deixaria pressionar igual a passar o
   mouse. Os 0,10 sao o valor que a propria colecao do projeto guarda para
   `pressed`, e o mesmo que o M3 especifica. Esta no relatorio. */
.kd-botao-icone:active::after { opacity: var(--md-sys-state-pressed-state-layer-opacity); }

.kd-botao-icone:focus-visible { outline: none; }

.kd-botao-icone:focus-visible::after { opacity: var(--md-sys-state-focus-state-layer-opacity); }

.kd-botao-icone:focus-visible::before {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* 4, E NAO 8 (lote 19.1). O comentario de `.kd-header-linha-logo`, mais abaixo,
   ja dizia o numero certo desde o lote 09: "o alternador de tema fica absoluto
   sobre ela (Figma: x 298, y 4 no 390)". Com `top: 8` a pilula de 40 ocupava
   y 8..48, com centro em 28, enquanto a linha do logo tem centro em 24 — o
   alternador ficava 4 px abaixo do logo na mesma linha. Medido em 24/09/2026.
   A altura do Header nao muda: o elemento e absoluto e nao entra na conta. */
/* O MENU DO HEADER MOBILE OCUPA 40 DE LAYOUT E 48 DE ALVO (lote 19.2).
   Medido no Figma (Header Tamanho=Mobile, 60838:2368): a linha `barra` tem
   358x40 com gap 8, e o `menu` dentro dela e um frame de 40x40 — nao uma
   instancia do Icon button de 48, como sao os do painel e os de compartilhar.
   Dar 48 de layout a ele empurrava a Busca de x=64 para x=72 e a encolhia de
   295 para 287, contra o desenho. A margem negativa devolve os 8: o alvo
   continua com 48 e o que se ve volta para onde estava. */
.kd-header-mobile .kd-botao-icone {
  margin-inline: calc(var(--md-sys-measurement-space50) * -1);   /* -4 */
}

/* O ICONE DE MENU FICA EM on-primary (lote 32).
   Medido na camada `menu` das variantes Mobile e Mobile · Rolado do Header
   60838:2515: `Schemes/On Primary`. Antes era `on-surface` — preto sobre o
   vermelho no claro e, com o `data-theme="light"` da linha, preto tambem no
   escuro. Contraste pela formula da WCAG 2.1: 4,58:1 sobre #E3262F e 6,44:1
   sobre #B81F27, os dois acima dos 3:1 da 1.4.11.

   A CAMADA DE ESTADO ACOMPANHA SOZINHA: ela e `currentColor` desde o lote 19.2,
   entao hover, foco e pressionado passam a acender em branco sobre o vermelho,
   em vez de um preto que praticamente nao apareceria ali.

   O ANEL DO FOCO TROCA PELO MESMO MOTIVO DA BUSCA: `primary` sobre o fundo da
   marca da 1,00:1 no claro e 1,58:1 no escuro — invisivel. Aqui so o
   `outline-color` e sobrescrito, porque a espessura, o afastamento e a caixa de
   40 continuam sendo os do projeto.                                        */
.kd-header .kd-botao-icone {
  color: var(--md-sys-color-on-primary);
}

.kd-header .kd-botao-icone:focus-visible::before {
  outline-color: var(--md-sys-color-on-primary);
}

.kd-header-mobile .kd-tema {
  position: absolute;
  top: var(--md-sys-measurement-space50);         /* 4 — o y do Figma */
  right: var(--kd-margem);
}

/* --- Desktop: 600 ou mais (o desenho de 768 e 1440) ---
   A media query vem DEPOIS das regras base de proposito: e ela que decide
   qual das duas formas aparece, e em CSS quem vem depois vence no empate. */
.kd-header-desktop { display: none; }

@media (min-width: 600px) {
  .kd-header-mobile { display: none; }

  /* 72 DE ALTURA (lote 23; era 64): padding Space 200 (16) em cima e embaixo
     sobre o item mais alto, que agora e a Busca (40) — o logo caiu para 32 e
     fica centrado nela. 16 + 40 + 16 = 72. */
  .kd-header-desktop {
    display: flex;
    align-items: center;
    gap: var(--md-sys-measurement-space300);      /* 24 */
    padding-top: var(--md-sys-measurement-space200);    /* 16 */
    padding-bottom: var(--md-sys-measurement-space200);
  }

  /* O logo do HEADER caiu para 32 no lote 23 (186,58 de largura, pela mesma
     proporcao da arte). O do Footer continua em 40 — sao dois lugares e dois
     tamanhos, medidos nas 176 instancias das telas do Site. Por isso a altura
     e sobrescrita AQUI, e nao na raiz. */
  .kd-header-desktop .kd-logo { --kd-logo-altura: var(--kd-logo-altura-mobile); }
}

/* Scrim do drawer.
   Medido no Figma em 24/09/2026 (Header, variante Mobile · Menu aberto
   60838:2392, e a secao "Superficie modal e scrim"): instancia do Scrim do kit,
   390x844 — a tela inteira, constraints STRETCH nos dois eixos —, fill
   `Schemes/Scrim` e opacidade da camada ligada a variavel `Scrim opacity` (32).

   ATE AQUI ELE NAO TINHA UMA LINHA DE CSS, desde o lote 09. Era um <div> vazio
   com zero de altura: nao escurecia nada, e o `click` que o kd.js registra
   nele desde sempre nao tinha onde acontecer — ou seja, clicar fora nunca
   fechou o menu. Achado na revisao do lote 14.

   Os dois tokens ja existiam no tokens.css (`--md-sys-color-scrim` e
   `--md-sys-state-scrim-opacity`), entao nenhum `--kd-*` novo foi preciso.
   A cor e a mesma nos dois temas — o preto do scrim nao inverte no M3. */
.kd-scrim {
  position: fixed;
  inset: 0;
  /* Abaixo do drawer, que esta em 11, e acima de todo o resto da pagina —
     inclusive do Header, que o Figma tambem mostra coberto. */
  z-index: 10;
  background: var(--md-sys-color-scrim);
  opacity: var(--md-sys-state-scrim-opacity);   /* 0,32 */
}

.kd-drawer {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: var(--kd-drawer-largura);
  max-width: calc(100% - var(--md-sys-measurement-space400));
  z-index: 11;
  overflow-y: auto;
  padding: var(--md-sys-measurement-space150);    /* 12 */
  border-radius: var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
}

.kd-drawer-titulo {
  display: flex;
  align-items: center;
  height: var(--md-sys-measurement-space700);     /* 56 */
  padding: 0 var(--md-sys-measurement-space200);
  margin: 0;
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-title-small-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-title-small-size);
  line-height: var(--md-sys-typescale-title-small-line-height);
  letter-spacing: var(--md-sys-typescale-title-small-tracking);
  font-weight: var(--md-sys-typescale-title-small-weight);
}

.kd-drawer-item {
  display: flex;
  align-items: center;
  height: var(--md-sys-measurement-space700);     /* 56 */
  padding: 0 var(--md-sys-measurement-space300);  /* 24 */
  border-radius: var(--md-sys-shape-corner-full);
  color: var(--md-sys-color-on-surface-variant);
  font-family: var(--md-sys-typescale-label-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-label-large-size);
  line-height: var(--md-sys-typescale-label-large-line-height);
  letter-spacing: var(--md-sys-typescale-label-large-tracking);
  font-weight: var(--md-sys-typescale-label-large-weight);
}

.kd-drawer-item[aria-current="page"] {
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
  font-weight: var(--md-sys-typescale-label-large-weight-emphasized);
}

/* ===========================================================================
   Footer (Figma 60841:661) — faixa de largura total, sem canto
   =========================================================================== */

.kd-footer {
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
  padding-top: var(--md-sys-measurement-space400);     /* 32 no mobile */
  padding-bottom: var(--md-sys-measurement-space400);
}

/* O Figma usa o Footer Desktop so no 1440; no 768 a tela leva o Footer Mobile
   com a margem lateral de 32. Por isso o ponto de quebra aqui e 1200. */
@media (min-width: 1200px) {
  .kd-footer {
    padding-top: var(--md-sys-measurement-space600);   /* 48 */
    padding-bottom: var(--md-sys-measurement-space400);
  }
}

.kd-footer-bloco {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space600);             /* 48 */
}

.kd-footer-colunas {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space400);             /* 32 */
}

@media (min-width: 1200px) {
  .kd-footer-colunas {
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--md-sys-measurement-space600);
  }
}

.kd-footer-marca {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);
}

@media (min-width: 1200px) {
  .kd-footer-marca { width: var(--kd-footer-marca-largura); flex: none; }
}

.kd-footer-aviso {
  margin: 0;
  color: var(--md-sys-color-on-surface-variant);
}

/* No mobile as colunas de links viram grade de 2 */
.kd-footer-links {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--md-sys-measurement-space400);
}

@media (min-width: 1200px) {
  .kd-footer-links {
    display: contents;
  }
}

.kd-footer-coluna {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space150);             /* 12 */
}

.kd-footer-coluna-titulo {
  margin: 0;
  color: var(--md-sys-color-on-surface);
}

.kd-footer-coluna a {
  color: var(--md-sys-color-on-surface-variant);
}

.kd-footer-coluna a:hover { color: var(--md-sys-color-on-surface); }

.kd-footer-canal {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);
  color: var(--md-sys-color-on-surface-variant);
}

.kd-footer-canal span { color: var(--md-sys-color-on-surface); }

/* No mobile os quatro canais ficam numa linha so, sem o nome */
.kd-footer-canais-icones {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space300);             /* 24 */
}

@media (min-width: 1200px) {
  .kd-footer-canais-icones {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--md-sys-measurement-space150);
  }
}

.kd-footer-rodape {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);
  color: var(--md-sys-color-on-surface-variant);
}

@media (min-width: 1200px) {
  .kd-footer-rodape {
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--md-sys-measurement-space100);
  }
}

/* Header mobile: a linha do logo. O alternador de tema fica absoluto sobre ela
   (Figma: x 298, y 4 no 390 — ou seja, encostado na margem direita). */
.kd-header-linha-logo {
  display: flex;
  align-items: center;
  height: var(--md-sys-measurement-space400);     /* 32 */
}

/* Footer: no mobile os quatro canais ficam numa linha so e o nome some da tela
   (continua no aria-label do link). No desktop o nome aparece. */
.kd-canal-nome { display: none; }

@media (min-width: 1200px) {
  .kd-canal-nome { display: inline; }
}

.kd-footer-rodape p { margin: 0; }

.kd-footer-identificacao {
  display: flex;
  flex-wrap: wrap;
  gap: var(--md-sys-measurement-space50);
}

/* ===========================================================================
   Desconto (Figma 60824:7122) e Selo (60864:29488) — pilulas
   =========================================================================== */

.kd-pilula {
  display: inline-flex;
  align-items: center;
  flex: none;
  padding: var(--md-sys-measurement-space25) var(--md-sys-measurement-space75);
  border-radius: var(--md-sys-shape-corner-full);
  white-space: nowrap;
}

.kd-pilula-grande {
  padding: var(--md-sys-measurement-space50) var(--md-sys-measurement-space100);
}

/* ---------------------------------------------------------------------------
   Forma curta do selo (propriedade `Forma` do Figma, 24/09/2026).

   Os dois textos vem no HTML e o CSS mostra um. Por padrao o completo; nos
   cards estreitos, o curto. O escondido sai com `display: none`, entao o leitor
   de tela tambem le so um.

   Onde e estreito: Grade compacta e Lista compacta travadas sempre, e os cards
   responsivos (`auto` e `lista`) abaixo de 600 — o mesmo ponto de quebra que
   troca o layout.
   --------------------------------------------------------------------------- */
.kd-selo-com-curto .kd-selo-curto { display: none; }

.kd-card-compacta .kd-selo-com-curto .kd-selo-completo,
.kd-card-lista-compacta .kd-selo-com-curto .kd-selo-completo,
.kd-card-auto .kd-selo-com-curto .kd-selo-completo,
.kd-card-lista .kd-selo-com-curto .kd-selo-completo { display: none; }

.kd-card-compacta .kd-selo-com-curto .kd-selo-curto,
.kd-card-lista-compacta .kd-selo-com-curto .kd-selo-curto,
.kd-card-auto .kd-selo-com-curto .kd-selo-curto,
.kd-card-lista .kd-selo-com-curto .kd-selo-curto { display: inline; }

/* A partir de 600 a LISTA vira larga e volta a forma completa. O CARD DA GRADE
   NAO VOLTA MAIS (lote 23): ele e Grade compacta em toda largura, entao a forma
   curta vale sempre. Ate o lote 22 o `.kd-card-auto` entrava aqui junto com a
   Lista. */
@media (min-width: 600px) {
  .kd-card-lista:not(.kd-card-lista-compacta) .kd-selo-com-curto .kd-selo-completo,
  [data-kd-modo="lista"] .kd-card-auto .kd-selo-com-curto .kd-selo-completo { display: inline; }

  .kd-card-lista:not(.kd-card-lista-compacta) .kd-selo-com-curto .kd-selo-curto,
  [data-kd-modo="lista"] .kd-card-auto .kd-selo-com-curto .kd-selo-curto { display: none; }
}

.kd-desconto {
  background: var(--md-sys-color-tertiary-fixed-dim);
  color: var(--md-sys-color-on-tertiary-fixed);
}

.kd-selo-destaque {
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}

.kd-selo-informativo {
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
}

/* ===========================================================================
   Bloco de preco (Figma 60824:7150)
   =========================================================================== */

.kd-preco {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);              /* 4 */
  min-width: 0;
}

/* A linha do preco antigo nunca quebra e nunca e cortada. Quem cede espaco e so
   o icone de tendencia, e ele nao encolhe: ou aparece inteiro, ou nao aparece
   (ver `.kd-preco-desconto-tendencia:has(...)` abaixo). Regra em
   "Acrescimos · Tendencia de preco" do documento de componentes. */
.kd-preco-linha {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: var(--md-sys-measurement-space100);             /* 8 */
  min-width: 0;
  overflow: hidden;
}

.kd-preco-antigo {
  color: var(--md-sys-color-on-surface-variant);
  flex: none;
  white-space: nowrap;
}

.kd-preco-desconto-tendencia {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space50);
  min-width: 0;
  overflow: hidden;
}

/* O desconto nunca some. */
.kd-preco-desconto-tendencia .kd-desconto { flex: none; }

/* O icone de tendencia e tudo ou nada: ou aparece inteiro, ou nao aparece.
   Deixar ele encolher daria um icone espremido (medido: 8,45 de 20 numa
   janela de 360), e o Figma manda sumir.

   Como funciona: o icone nao encolhe (`flex: none`), entao quando nao cabe ele
   quebra para a linha de baixo — e a linha de baixo fica fora do `max-height`,
   que corta. O resultado e o icone inteiro ou nada, sem mexer na altura da
   linha nem na do card.

   20 e a altura da `linha-superior` do bloco Compacto no Figma, que e a unica
   variante onde a tendencia existe (Compacto Ativa: `desconto-tendencia` com
   `desconto` 43x20 + `tendencia` 20x20). O `:has()` garante que a regra so
   valha quando o icone esta la, entao o desconto Grande (28) nunca e cortado. */
.kd-preco-desconto-tendencia:has(.kd-preco-tendencia) {
  flex-wrap: wrap;
  align-content: flex-start;
  max-height: var(--md-sys-measurement-space250);     /* 20 */
}

.kd-preco-tendencia {
  color: var(--md-sys-color-on-surface-variant);
  flex: none;
}

/* O TEXTO OBRIGATORIO DA LOJA (lei 15, lote 20).
   Medido no Figma (Bloco de preco 60824:7150, propriedade `Mostrar texto da
   loja`): `M3/body/small`, `Schemes/On Surface Variant`, largura do bloco,
   `textAutoResize: HEIGHT` com `textTruncation: DISABLED` e `maxLines: null`.

   QUEBRA LINHA E NUNCA CORTA, e isso e a propria lei: o programa de afiliados
   exige o texto INTEIRO junto do preco. Reticencias seriam quebra de contrato.
   Por isso aqui nao ha `text-overflow`, nem `-webkit-line-clamp`, nem
   `white-space: nowrap` — e por isso o `overflow-wrap` cobre tambem a palavra
   unica maior que a coluna, que no card de 173 (Grade compacta) e um caso real. */
.kd-preco-texto-loja {
  color: var(--md-sys-color-on-surface-variant);
  overflow-wrap: anywhere;
}

.kd-preco-atual { color: var(--md-sys-color-on-surface); }

.kd-preco-detalhe { color: var(--md-sys-color-on-surface-variant); }

/* Encerrada: o preco atual perde o destaque */
.kd-preco-encerrada .kd-preco-atual { color: var(--md-sys-color-on-surface-variant); }

/* ===========================================================================
   Card de oferta (Figma 60825:291)
   =========================================================================== */

.kd-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space150);            /* 12 */
  padding: var(--md-sys-measurement-space150);        /* 12 */
  /* 12, E NAO MAIS 24 (lote 32, etapa 4). Medido no Card de oferta 60825:291
     em 25/09/2026: o canto das variantes passou de Corner/Large-plus (24) para
     Corner/Medium (12), em TODOS os layouts (Grade, Grade compacta, Lista e
     Lista compacta) e em todos os estados. Pedido do Matheus na mesma passada
     do Header na cor da marca: card menos arredondado.

     UMA LINHA SO RESOLVE OS QUATRO LAYOUTS porque nenhuma variante redeclara o
     canto — `.kd-card-lista`, `.kd-card-lista-compacta`, `.kd-card-compacta` e
     `.kd-card-auto` mudam direcao, imagem e larguras, e herdam o canto daqui. A
     camada de estado do `::after` usa `border-radius: inherit` e acompanha
     sozinha, inclusive no hover.

     O TOKEN `--md-sys-shape-corner-large-plus` CONTINUA VALENDO 24 E NAO FOI
     TOCADO, e essa e a parte que importa: ele e compartilhado. Quem ainda usa
     os 24 e os banners da Home, o CTA de canal, o Item de categoria, o Topo do
     produto, o Historico de preco, o bloco do Login, o grafico e a tabela do
     painel, o bloco do formulario, o estado vazio e o cabecalho da Loja —
     nenhum deles entra neste lote. Mexer no token teria arredondado menos onze
     componentes que ninguem mandou mexer. A troca e de REFERENCIA, um
     componente de cada vez. */
  border-radius: var(--md-sys-shape-corner-medium);      /* 12 */
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
  height: 100%;
  min-width: 0;
}

/* Hover: state layer on-surface sobre o container inteiro, mesmo canto. */
.kd-card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--md-sys-color-on-surface);
  opacity: 0;
  pointer-events: none;
}

.kd-card:hover::after,
.kd-card.kd-card-hover::after {
  opacity: var(--md-sys-state-hover-state-layer-opacity);
}

/* A SOMBRA DO HOVER (lote 26), nas 12 variantes Estado=Hover do Figma — os
   quatro layouts, as tres tendencias. As outras 24 variantes nao tem efeito
   nenhum.

   SO COM MOUSE. `hover: hover` e a mesma pergunta que as setas fazem: num
   aparelho de toque o `:hover` gruda depois do toque e o card ficaria
   levantado ate alguem tocar em outro lugar. A camada de estado acima ja
   convive com isso ha lotes, mas ela e sutil; uma sombra presa seria visivel.

   `.kd-card-hover` e a amostra do catalogo, que mostra o estado parado — ela
   entra junto, e por isso esta fora da media query.

   A TRANSICAO E A QUE O CARD JA TEM. Ele nao tinha nenhuma ate aqui: a
   camada de estado acende sem transicao, e a sombra acompanha do mesmo
   jeito. Nao inventei uma — o Figma nao tem motion, e o lote 23 ja registrou
   que as duas unicas excecoes de movimento do projeto sao a da Busca. Com
   `prefers-reduced-motion` nada muda, porque nao ha o que desligar. */
.kd-card.kd-card-hover { box-shadow: var(--kd-sombra-leve); }

@media (hover: hover) {
  .kd-card:hover { box-shadow: var(--kd-sombra-leve); }
}

.kd-card:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

.kd-card-imagem {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 1 / 1;
  flex: none;
  overflow: hidden;
  /* 8, E NAO MAIS 12 (lote 32, etapa 4). A imagem dentro do card acompanhou o
     card no Figma 60825:291: Corner/Medium (12) virou Corner/Small (8). A
     relacao entre os dois continua a de antes — a imagem sempre teve metade do
     canto do bloco que a segura. */
  border-radius: var(--md-sys-shape-corner-small);    /* 8 */
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface-variant);
}

/* A foto fica fora do fluxo de propósito. Se ela ficasse no fluxo, na Lista
   (onde a caixa da imagem estica na altura, sem altura própria) a proporção do
   arquivo passaria a mandar na altura do card: medido, uma foto 400x800 numa
   janela de 768 fazia a caixa virar 144x288 e o card 560x320, contra os 176 do
   Figma. Fora do fluxo, quem manda na altura é o conteúdo ao lado — que é o que
   o Figma desenha (imagem FILL na vertical) — e o `object-fit: contain` cabe a
   foto dentro sem cortar. */
.kd-card-imagem img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.kd-card-selo {
  position: absolute;
  top: var(--md-sys-measurement-space100);            /* 8 */
  left: var(--md-sys-measurement-space100);
  max-width: calc(100% - var(--md-sys-measurement-space200));
  overflow: hidden;
}

.kd-card-conteudo {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);            /* 8 */
  min-width: 0;
  flex: 1 1 auto;
}

.kd-card-linha-loja {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--md-sys-measurement-space100);
  row-gap: var(--md-sys-measurement-space50);
  min-width: 0;
}

.kd-card-loja {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space50);             /* 4 */
  color: var(--md-sys-color-on-surface-variant);
  min-width: 0;
}

.kd-card-loja-nome {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kd-card-tempo { white-space: nowrap; flex: none; }

/* As duas etiquetas quebram linha quando nao cabem lado a lado (em 360 elas
   somam 136 numa area de texto de 134). Gap 4 nas duas direcoes, como o
   `linha-loja` do Figma. O component set nao quebra porque o Figma nao tem
   wrap aqui; a ilustracao em Estados e uma instancia desanexada. */
.kd-card-etiquetas {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--md-sys-measurement-space50);
  min-width: 0;
}

.kd-card-titulo {
  margin: 0;
  color: var(--md-sys-color-on-surface);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.kd-card .kd-preco { margin-top: auto; }

/* ---------------------------------------------------------------------------
   Layouts do card.

   Desde a passada de densidade (24/09/2026) os QUATRO layouts tem o mesmo
   padding (12), o mesmo canto (24) e a mesma imagem (canto 12). Medido no
   component set: Grade 240x376 imagem 216, Grade compacta 173x309 imagem 149,
   Lista 560x168 imagem 144, Lista compacta 358x148 imagem 112.

   Com isso a Grade e a Grade compacta ficaram IDENTICAS no Figma, com uma
   unica diferenca medida: o nome da loja tem `maxWidth 60` com reticencias na
   compacta e nenhum limite na Grade. E so isso que sobrou aqui embaixo — o
   resto que existia (padding e canto por ponto de quebra) saiu, porque nao ha
   mais o que diferenciar.
   --------------------------------------------------------------------------- */

/* GRADE COMPACTA EM TODA LARGURA (lote 23). Ate o lote 22 o card responsivo
   virava Grade a partir de 600; agora o site usa so a Grade compacta, e o
   Layout=Grade nao e mais usado em tela nenhuma.

   MEDIDO NO FIGMA, no e no: as duas variantes so diferem em DUAS coisas — a
   largura do componente (240 contra 173, que nas telas nao vale porque as duas
   esticam) e o `loja-nome`, que na compacta tem `maxWidth 60`, `maxLines 1` e
   truncagem no fim. Todo o resto e identico: gap 12, padding 12, canto 24,
   imagem quadrada com canto 12, selo em 8/8, titulo em duas linhas.

   Ou seja: o que restava de "Grade" no codigo era exatamente a linha de baixo
   com `max-width: none` a partir de 600. Tirando-a, o card e compacto sempre —
   e o limite do nome da loja, que existe para o tempo ("· ha 55 min") nunca ser
   cortado, passa a valer em todas as larguras. */
.kd-card-auto .kd-card-loja-nome { max-width: var(--kd-loja-nome-max); }

/* ---------------------------------------------------------------------------
   Lista: abaixo de 600 e a Lista compacta (imagem 112, itens centrados na
   altura); a partir de 600 e a Lista (imagem 144, itens no topo), travada em
   560 de largura. Padding e canto sao os mesmos dos outros layouts.
   --------------------------------------------------------------------------- */
/* O MODO LISTA DO LOTE 24 ENTRA AQUI, e nao numa copia destas regras: quando
   o visitante escolhe Lista no Menu de exibicao, o <html> ganha
   data-kd-modo="lista" e o card responsivo (`.kd-card-auto`) passa a valer
   como card de Lista. Assim a Lista tem uma definicao so, e o card travado
   do catalogo continua funcionando como antes. */
.kd-card-lista,
[data-kd-modo="lista"] .kd-card-auto {
  flex-direction: row;
  align-items: center;
}

.kd-card-lista .kd-card-imagem,
[data-kd-modo="lista"] .kd-card-auto .kd-card-imagem {
  width: var(--kd-card-lista-compacta-imagem);
  height: var(--kd-card-lista-compacta-imagem);
  aspect-ratio: auto;
  align-self: center;
}

/* NA LISTA O NOME DA LOJA NAO CORTA. Medido nas duas variantes: o
   `loja-nome` da Lista e HUG, sem maxWidth e sem truncation — ao contrario
   da Grade compacta, que corta em 60. */
[data-kd-modo="lista"] .kd-card-auto .kd-card-loja-nome { max-width: none; }

@media (min-width: 600px) {
  .kd-card-lista,
  [data-kd-modo="lista"] .kd-card-auto {
    align-items: flex-start;
    max-width: var(--kd-card-lista-largura);                         /* 560 */
  }

  .kd-card-lista .kd-card-imagem,
  [data-kd-modo="lista"] .kd-card-auto .kd-card-imagem {
    width: var(--kd-card-lista-imagem);                              /* 144 */
    height: var(--kd-card-lista-imagem);
    align-self: flex-start;
  }

  /* Na Lista o bloco de preco e HUG (no Figma), entao ele fica do tamanho do
     conteudo em vez de esticar. */
  .kd-card-lista .kd-preco,
  [data-kd-modo="lista"] .kd-card-auto .kd-preco { align-self: flex-start; }
}

/* Lista compacta travada, para a amostra do catalogo aparecer no tamanho do
   desenho mesmo numa janela larga.

   Os seletores levam as duas classes de proposito: `.kd-card-lista` sozinha
   tambem aparece dentro do `@media (min-width: 600px)` acima, e duas classes
   ganham de uma na cascata. Assim a travada continua travada mesmo que alguem
   mova estes blocos de lugar no arquivo. */
.kd-card-lista.kd-card-lista-compacta {
  align-items: center;
  max-width: none;
}

.kd-card-lista.kd-card-lista-compacta .kd-card-imagem {
  width: var(--kd-card-lista-compacta-imagem);
  height: var(--kd-card-lista-compacta-imagem);
  align-self: center;
}

.kd-card-lista.kd-card-lista-compacta .kd-preco { align-self: auto; }

/* --- Grade compacta travada (amostra do catalogo) ---
   O carrossel nao usa esta: ele usa a Grade travada, que e o `.kd-card` puro,
   com a largura de 240 vindo do proprio carrossel. Depois da densidade a unica
   coisa que a compacta tem de proprio e o limite do nome da loja. */
.kd-card-compacta .kd-card-loja-nome { max-width: var(--kd-loja-nome-max); }

/* ===========================================================================
   Catalogo de componentes (/_componentes) — so fora de producao
   =========================================================================== */

.kd-secundario { color: var(--md-sys-color-on-surface-variant); }

.kd-amostras {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--md-sys-measurement-space300);
}

.kd-amostras-blocos { gap: var(--md-sys-measurement-space600); }

.kd-amostra {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--md-sys-measurement-space100);
}

.kd-amostra-nome { color: var(--md-sys-color-on-surface-variant); }

.kd-amostra-card {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);
  min-width: 0;
}

.kd-amostra-card .kd-card { flex: 1 1 auto; }

.kd-lista-amostras {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space300);
}

/* ---------------------------------------------------------------------------
   Amostras de card no catalogo.

   A grade de verdade e fluida (ver `--kd-grade-template`). Estas secoes sao
   outra coisa: mostram a peca no tamanho do desenho, para dar para conferir
   contra o Figma sem depender da largura da janela. Por isso continuam usando
   as larguras `--kd-card-*-largura`, que sao de amostra, nao de layout.
   --------------------------------------------------------------------------- */
.kd-amostras-cards {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: var(--kd-grade-gap);
}

.kd-amostras-cards .kd-amostra-card { flex: none; }

.kd-amostras-compacta .kd-amostra-card { width: var(--kd-card-compacta-largura); }
.kd-amostras-grade .kd-amostra-card    { width: var(--kd-card-grade-min); }
.kd-amostras-lista-compacta .kd-amostra-card {
  width: min(100%, var(--kd-card-lista-compacta-largura));
}

/* ===========================================================================
   Home — secoes, carrosseis e componentes proprios da pagina
   =========================================================================== */

/* Cabecalho de secao: titulo title/large, on-surface, 16 ate o conteudo. */
.kd-secao-cabecalho {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);        /* 16 */
}

/* NADA MAIS FICA AO LADO DO TITULO (lote 24). Ate aqui, a partir de 1200 o
   seletor de ordenacao subia para a linha do titulo. A Barra de ordenacao que
   o substituiu tem largura total nas TRES larguras — medido nas seis telas de
   Home: `cabecalho` 1200x28 com um filho so, e a barra 16 abaixo. */

/* ---------------------------------------------------------------------------
   Carrossel que vai ate a borda da tela.

   O primeiro item fica alinhado a margem da pagina e o corte acontece na borda,
   nunca dentro da margem. Como o bloco ja vive dentro de `.kd-conteudo` (que
   tem a margem como padding), basta desfazer o padding da direita com margem
   negativa e devolve-lo como padding do proprio rolavel — assim o ultimo item
   tambem respira antes de acabar.

   Sem JavaScript: rolagem por toque, por barra e por teclado (o Tab leva o foco
   ao item seguinte e o navegador rola sozinho). `scroll-snap` deixa a parada
   alinhada ao item, e nenhum autoplay mexe na tela de quem esta lendo.

   Acima de 1440 o conteudo trava em 1376 e fica centralizado (regra do lote
   10), entao o carrossel termina no limite do conteudo e nao na borda fisica da
   tela. O Figma nao desenha a Home acima de 1440; esta no relatorio.
   --------------------------------------------------------------------------- */
.kd-rolagem-borda {
  display: flex;
  gap: var(--md-sys-measurement-space200);          /* 16 */
  margin-right: calc(var(--kd-margem) * -1);
  padding-right: var(--kd-margem);
  overflow-x: auto;
  overscroll-behavior-x: contain;

  /* O ANEL DO PRIMEIRO ITEM NAO PODE SER CORTADO (lote 19.1).
     Medido em 24/09/2026: o primeiro chip, o primeiro segmento de ordenacao e o
     primeiro banner encostam na borda esquerda do rolavel (folga 0), e
     `overflow-x: auto` corta os 4 px que o anel ocupa para fora — o anel do
     primeiro item aparecia aberto de um lado.
     O padding abre a folga e a margem negativa a devolve, entao NADA MUDA DE
     LUGAR: e a mesma conta que a linha `margin-right`/`padding-right` acima ja
     faz para o carrossel chegar na borda da tela. O `scroll-padding-left`
     acompanha o padding, senao o encaixe pararia 4 px adiantado. */
  margin-left: calc(var(--kd-anel-folga) * -1);
  padding-left: var(--kd-anel-folga);
  padding-block: var(--kd-anel-folga);
  margin-block: calc(var(--kd-anel-folga) * -1);

  /* Encaixe: ao soltar, o carrossel para com um item alinhado ao inicio do
     rolavel — que ja e a margem da pagina, porque o `.kd-conteudo` em volta tem
     a margem como padding. Por isso o `scroll-padding` fica em 0 e nao na
     margem: soma-la deslocaria o encaixe em mais 16 ou 32. */
  scroll-snap-type: x proximity;
  scroll-padding-left: var(--kd-anel-folga);

  /* A barra de rolagem some com o resto das superficies rolaveis, la em cima,
     em "Nada desenhado pelo navegador". Aqui ela nao apareceria de qualquer
     jeito, mas a lista de quem esconde a barra e uma so. */
}

/* Arrasto de mouse: o cursor avisa que da para arrastar, e enquanto arrasta o
   texto nao e selecionado nem o encaixe briga com o movimento. As duas classes
   sao postas e tiradas pelo kd.js — sem JavaScript, nada disso aparece e a
   rolagem continua sendo a do navegador. */
.kd-arrastavel { cursor: grab; }

.kd-arrastando {
  cursor: grabbing;
  scroll-snap-type: none;
  user-select: none;
  -webkit-user-select: none;
}

.kd-arrastando a,
.kd-arrastando img { -webkit-user-drag: none; }

/* A PARTIR DE 1264 O CARROSSEL PARA NA BORDA DO CONTEUDO (lote 23).
   A sangria existe para o carrossel chegar na borda da TELA e dizer, cortando
   um item ao meio, que ha mais para o lado. Isso vale enquanto o conteudo
   ocupa a tela. De 1264 em diante ele trava em 1200 e a sobra vira margem
   (120 de cada lado no 1440) — e a margem negativa de 32 nao chega perto da
   borda: ela so faria o carrossel vazar 32 px para dentro da margem, num lugar
   onde nao ha borda nenhuma para alcancar. Medido no Figma: no 1440 o
   carrossel de `melhores-ofertas` tem 1200 de largura em x=120, ou seja para
   exatamente na borda do conteudo.

   A FOLGA DE 4 DO ANEL DE FOCO FICA. Ela e o par `margin-left: -4` /
   `padding-left: 4` que o lote 19.2 acrescentou para o anel do primeiro item
   nao ser cortado pelo `overflow`, e nao tem nada a ver com a sangria. */
@media (min-width: 1264px) {
  .kd-rolagem-borda {
    margin-right: 0;
    padding-right: 0;
  }
}

.kd-rolagem-borda > * {
  flex: none;
  scroll-snap-align: start;
}

/* --- Banners da Home (lote 23) --------------------------------------------
   Figma: component set novo `Banners · 600 ou mais` 61133:93099, e o `Banner`
   60839:25473 para o celular. Medido em 25/09/2026.

   TRES ARRANJOS, UMA MARCACAO:

     abaixo de 600   so o carrossel, em largura total, 200 de altura. Os fixos
                     nao aparecem — regra do documento.
     600 a 1199      Tablet: carrossel em largura total (~3:1) e os dois fixos
                     LADO A LADO abaixo, cada um 3:1 exato.
     1200 ou mais    Desktop: carrossel a esquerda e os dois fixos empilhados a
                     direita.

   A CONTA DO DESKTOP NAO E "2/3 E 1/3", e isso esta medido: o bloco dos fixos e
   C/3 EXATO (400 num conteudo de 1200) e o principal e o que sobra menos o gap
   (C - C/3 - 8 = 792). Dois tercos do espaco util dariam 794,67 e 397,33, que
   nao e o desenho. A altura sai do principal em 3:1 (792/264 = 3,000 exato) e
   cada fixo fica com (264 - 8) / 2 = 128 — razao 3,125:1, e nao 3:1.

   NO TABLET A REGRA E OUTRA: la o principal e ~3:1 (704/235 = 2,996; o Figma
   arredondou os 234,67) e os fixos sao 3:1 EXATO (348/116). Duas regras para a
   mesma peca, e as duas estao no relatorio.

   O PEEK MORREU. Ate o lote 22 o segundo banner aparecia com 184 na borda
   (Carousel Hero do kit). O desenho novo nao tem peek em largura nenhuma: o
   banner ocupa a largura inteira do bloco e o indicador diz que ha mais.      */
.kd-banners {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);          /* 8 */
}

/* O `relative` existe para o indicador, que agora fica DENTRO do banner. */
.kd-banner-principal {
  position: relative;
  min-width: 0;
}

.kd-banner-carrossel {
  gap: var(--md-sys-measurement-space100);          /* 8 */
  align-self: stretch;
}

.kd-banner-item {
  display: block;
  width: 100%;
  height: var(--kd-banner-altura-mobile);           /* 200 */
  overflow: hidden;
  border-radius: var(--md-sys-shape-corner-large-plus);    /* 24 */
  background: var(--md-sys-color-surface-container-low);
  flex: none;
}

.kd-banner-item img,
.kd-banner-fixo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.kd-banner-item:focus-visible,
.kd-banner-fixo:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* O INDICADOR FICA DENTRO DO BANNER, a 12 da base, centralizado — e nao abaixo
   dele, como estava. Medido nas quatro variantes novas, e tambem no banner de
   Categoria, que o documento nem menciona.

   AS CORES ESTAVAM ERRADAS DESDE ANTES DESTE LOTE, e sao duas: o ponto atual
   era `primary` e os outros `outline-variant`. O Figma usa `on-surface` no
   atual e `surface-container-highest` nos demais — nas duas versoes, a antiga e
   a nova. Corrigido aqui.

   `pointer-events: none` porque ele nao clica: quem rola e o dedo, a roda e o
   Tab nos proprios links. */
.kd-banner-indicador {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: var(--md-sys-measurement-space150);       /* 12 */
  display: flex;
  gap: var(--md-sys-measurement-space100);          /* 8 */
  align-items: center;
  pointer-events: none;
}

.kd-banner-ponto {
  width: var(--md-sys-measurement-space100);        /* 8 */
  height: var(--md-sys-measurement-space100);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest);
}

.kd-banner-ponto-atual { background: var(--md-sys-color-on-surface); }

/* ABAIXO DE 600 OS FIXOS NAO APARECEM. Regra do documento, e o desenho
   confirma: o celular usa o Banner Tipo=Home, Mobile de antes, que so tem o
   carrossel. Eles entram a partir de 600, na variante Tablet. */
.kd-banners-fixos { display: none; }

@media (min-width: 600px) {
  .kd-banners-fixos {
    display: flex;
    gap: var(--md-sys-measurement-space100);        /* 8 */
    min-width: 0;
  }
}

.kd-banner-fixo {
  display: block;
  flex: 1 1 0;
  min-width: 0;
  /* 3:1 exato, que e o que o Tablet desenha. No Desktop a altura vem de cima
     (os dois dividem a altura do carrossel) e esta proporcao e ignorada — ver
     a media query de 1200. */
  aspect-ratio: 3;
  overflow: hidden;
  border-radius: var(--md-sys-shape-corner-large-plus);    /* 24 */
  background: var(--md-sys-color-surface-container-low);
}

/* --- 600 a 1199: Tamanho=Tablet ------------------------------------------- */
@media (min-width: 600px) {
  /* ~3:1, com a largura do conteudo. Em 704 da 234,67 contra os 235 que o
     Figma arredondou — 0,33 de diferenca, e a proporcao e que e a regra. */
  .kd-banner-item {
    aspect-ratio: 3;
    height: auto;
  }
}

/* --- 1200 ou mais: Tamanho=Desktop ---------------------------------------- */
@media (min-width: 1200px) {
  .kd-banners {
    flex-direction: row;
    align-items: stretch;
  }

  /* O bloco dos fixos e C/3 EXATO e o principal fica com o resto. Escrito
     assim — e nao com `flex: 2` e `flex: 1` — porque `flex` dividiria o espaco
     JA SEM o gap, dando 794,67/397,33. A conta do desenho tira o terco da
     largura inteira e so depois desconta o gap do lado do principal. */
  .kd-banners-fixos {
    flex: none;
    width: calc((100% - var(--md-sys-measurement-space100)) / 3
                + var(--md-sys-measurement-space100) / 3);
    flex-direction: column;
  }

  .kd-banner-principal { flex: 1 1 auto; }

  /* Os dois dividem a altura do carrossel, que vem do 3:1 do principal: cada um
     fica com (264 - 8) / 2 = 128, que e 3,125:1 e nao 3:1. Por isso a proporcao
     sai aqui. */
  .kd-banner-fixo {
    aspect-ratio: auto;
    flex: 1 1 0;
    min-height: 0;
  }
}

/* SEM FIXO CADASTRADO o carrossel ocupa a largura toda, com 264 de altura
   (regra do documento). A proporcao de 3:1 daria 400 num conteudo de 1200 —
   alto demais para uma faixa sozinha —, entao aqui a altura e a do desenho. */
@media (min-width: 1200px) {
  .kd-banners-sem-fixos .kd-banner-item {
    aspect-ratio: auto;
    height: var(--kd-banner-altura);                /* 264 */
  }
}

/* --- Chip de categoria ---------------------------------------------------- */
.kd-chip {
  display: inline-flex;
  align-items: center;
  flex: none;
  min-height: var(--md-sys-measurement-space400);   /* 32 */
  padding: var(--md-sys-measurement-space75) var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  white-space: nowrap;
  position: relative;
}

.kd-chip::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--md-sys-color-on-surface);
  opacity: 0;
  pointer-events: none;
}

.kd-chip:hover::after { opacity: var(--md-sys-state-hover-state-layer-opacity); }

.kd-chip:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* --- Barra de ordenacao (Figma 61139:2192, lote 24) -----------------------
   SUBSTITUI o Seletor de ordenacao (Connected button group XSmall) em todo o
   site: Home, Categoria, Busca e Loja. O componente antigo nao existe mais em
   no nenhum do arquivo do Figma — nem em Site, nem em Componentes, nem em
   Estados. Medido em 25/09/2026 no componente e nas 34 instancias das telas.

   A BARRA   1200x56 no 1440, FILL na largura, padding Space 100 (8) nos quatro
             lados, gap Space 100, Corner/Large (16), surface-container-low,
             sem sombra e sem borda. A largura e a do CONTEUDO nas tres telas
             (1200 / 704 / 358): ela NAO sangra ate a borda em largura
             nenhuma. (A Barra de filtros, que sangrava e que ficava logo
             abaixo, saiu no lote 30.)
   AS ABAS   frame proprio, FILL na largura. Desde o lote 30 o gap dele e
             Space 200 (16) e separa os DOIS grupos de dentro; o Space 50
             (4) desceu para dentro de cada grupo. Cada aba e HUG — elas
             nunca dividem a largura da barra entre si.
   O BOTAO   40x40 fixo, Corner/Medium (12), surface-container-lowest, com o
             icone tune de 20. Quem o empurra para a direita e o FILL das abas:
             no desenho nao ha spacer nem justify, e por isso nao ha nenhum
             aqui.

   ROLAGEM NO CELULAR. As quatro abas somam 584 (159 + 101 + 136 + 176 e tres
   gaps de 4), e a barra precisa de 8 + 584 + 8 + 40 + 8 = 648 para mostrar
   tudo: cabe no 1440 (1200) e no 768 (704), nao cabe no 390 (358). O FIGMA NAO
   RESOLVE — ele corta "Menor preco" ao meio, com clipsContent e
   overflowDirection NONE, sem fade, sem seta e sem sombra. Quem resolve e o
   lote, que manda as abas rolarem de lado sem barra visivel.

   A ROLAGEM E DAS ABAS, E NAO DA BARRA INTEIRA. Rolando a barra, o botao
   Exibicao sairia de vista junto — e ele e a ancora de um menu. Rolando so o
   frame das abas, o botao fica onde esta.

   O ANEL DE FOCO PRECISA DE 4, e o rolavel cortaria. E o mesmo par de margem
   negativa e padding dos carrosseis (`.kd-rolagem-borda`): a caixa cresce 4
   para dentro do padding de 8 da barra, entao nada muda de lugar. ELE TEM DE
   SER DESCONTADO DOS DOIS LADOS na hora de medir o espaco em volta da barra —
   o retangulo do trilho e 8 maior que o conteudo dele, 4 em cima e 4 embaixo,
   sem que nada tenha mudado de lugar na tela.

   SEM HOVER E SEM PRESSIONADO, de proposito: o component set tem duas
   variantes (Estado = Padrao | Selecionada) e a pagina "Descontos · Estados"
   nao tem secao de ordenacao. O seletor antigo tambem nao tinha. Fica o anel
   de foco, que e regra do projeto e nao desenho de componente.            */
/* --- A BARRA PRENDE EMBAIXO DO HEADER AO ROLAR (lote 30, etapa 3.1) ------
   Pedido do Matheus, modelo Pechinchou. Medido nos dois exemplos do Figma
   ("Exemplo - Barra de ordenacao fixa ao rolar - 1440" e "- 390"): o Header
   fica em y=0 com 72 (1440) e 100 (390), e a barra presa em y=80 e y=108 —
   8 abaixo dele nas duas, que e o Space 100.

   O `top` SAI DOS MESMOS DOIS TOKENS que o `scroll-padding-top` da pagina ja
   usava, e nao de dois numeros novos: `--kd-header-altura` ja vale 100 no
   celular e 72 a partir de 600, que e exatamente o que o Figma desenha.

   ELA PARA SOZINHA QUANDO A LISTA ACABA, e isso nao custa uma linha de
   JavaScript: `position: sticky` so prende dentro do bloco que contem o
   elemento, e a barra vive dentro do bloco que leva a grade. Quando a grade
   passa, a barra vai junto — que e o que o lote pede ("fica presa so enquanto
   a lista de ofertas dela esta na tela"). Na Home isso a limita a secao
   "Melhores descontos", sem ninguem precisar escrever isso em codigo.

   Z-INDEX 2, ESCOLHIDO CONTRA UMA PILHA INTEIRA:
     1  as setas dos carrosseis, que passam POR BAIXO da barra presa;
     2  a barra presa;
     3  o Aviso de ofertas novas, que nunca pode ser coberto por ela;
     4  o Header, acima de tudo isso;
     5  os menus (Menu de filtro e Menu de exibicao).
   Sem z-index nenhum a barra PERDERIA para os cards: os dois seriam
   posicionados com z-index automatico, e ai quem ganha e a ordem do DOM — os
   cards vem depois. Com 2 ela ganha dos cards e continua perdendo do Header.

   O QUE NAO MUDA: o fundo solto continua surface-container-low, sem sombra,
   como o Figma desenha a barra parada. A troca e a regra logo abaixo.    */
.kd-barra-ordem {
  position: sticky;
  top: calc(var(--kd-header-altura) + var(--md-sys-measurement-space100));
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);           /* 8 */
  min-height: var(--kd-barra-ordem-altura);          /* 56 */
  padding: var(--md-sys-measurement-space100);       /* 8 */
  border-radius: var(--md-sys-shape-corner-large);   /* 16 */
  background: var(--md-sys-color-surface-container-low);
  transition: background-color var(--kd-movimento-duracao) var(--kd-movimento-curva),
              box-shadow var(--kd-movimento-duracao) var(--kd-movimento-curva);
}

/* PRESA: o mesmo par do Header rolado — surface-container mais a sombra leve.
   Nao e coincidencia: o Figma pinta os dois iguais porque os dois dizem a
   mesma coisa, que ha conteudo passando por baixo.

   QUEM POE ESTA CLASSE E O JAVASCRIPT, por um sentinela observado. O
   `position: sticky` prende sem avisar que prendeu: nao existe seletor de
   "esta grudado". SEM JAVASCRIPT A BARRA PRENDE DO MESMO JEITO — o sticky e
   do CSS — e so nao troca de fundo nem ganha sombra. E o mesmo acordo que o
   Header tem desde o lote 23: o que se perde e enfeite, nao funcao.      */
.kd-barra-ordem-presa {
  background: var(--md-sys-color-surface-container);
  box-shadow: var(--kd-sombra-leve);
}

/* QUEM PEDE MENOS MOVIMENTO nao ve a troca acontecer: ela ja esta feita
   quando a barra prende. A classe continua entrando igual — o que sai e o
   caminho entre um estado e outro.

   ESTA REGRA TEM DE FICAR DEPOIS DA DE CIMA, e isso custou uma medicao: na
   primeira tentativa ela foi parar no bloco `prefers-reduced-motion` que ja
   existia la em cima, na altura da Busca. Mesma especificidade, e a regra de
   baixo ganha — entao o `transition` da barra sobrescrevia o `none` e o
   movimento continuava. Medido: 0.3s nos dois modos.                     */
@media (prefers-reduced-motion: reduce) {
  .kd-barra-ordem { transition: none; }
}

/* O SENTINELA. Uma caixa de altura zero logo antes da barra: enquanto ela
   esta a vista, a barra ainda nao prendeu; quando ela sai por cima, prendeu.

   A MARGEM NEGATIVA NAO E ENFEITE, E O QUE IMPEDE UMA REGRESSAO. O pai da
   barra e flex column com `gap: 16` nos dois casos (`.kd-secao` na Home,
   `.kd-bloco-ofertas` nas outras tres). Um filho a mais, mesmo com altura 0,
   ganha um `gap` proprio e empurraria a barra 16 para baixo em silencio. A
   margem cancela exatamente esse gap, e sai do MESMO token do gap — se um
   mudar, o outro muda junto. Medido antes e depois: nada se moveu.       */
.kd-barra-ordem-sentinela {
  height: 0;
  margin-bottom: calc(-1 * var(--md-sys-measurement-space200));
  pointer-events: none;
}

.kd-abas-ordem {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space200);           /* 16 */
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  -ms-overflow-style: none;

  padding: var(--kd-anel-folga);
  margin: calc(var(--kd-anel-folga) * -1);
}

.kd-abas-ordem::-webkit-scrollbar { display: none; }

/* OS DOIS GRUPOS DE DENTRO DO TRILHO (lote 30) -----------------------------
   Ate aqui as quatro abas eram filhas diretas de `.kd-abas-ordem`, com 4
   entre elas. O Figma 61139:2192 agora poe dois frames dentro de `abas`:
   `ordem` (584x40, as quatro abas de ordenacao) e `filtros` (265x40, Frete
   gratis com 129 e Com cupom com 132), com Space 200 (16) ENTRE OS GRUPOS e
   Space 50 (4) dentro de cada um.

   O 16 E DO TRILHO E O 4 E DOS GRUPOS, e nao o contrario. Com o 4 no trilho
   os dois grupos encostariam um no outro e a separacao entre ordenar e
   filtrar sumiria; com o 16 dentro dos grupos, quem se afastaria seriam as
   abas irmas.

   `flex: none` PORQUE O TRILHO ROLA. Um grupo que encolhe apertaria as abas
   ate o rotulo quebrar em duas linhas, em vez de deixar a barra rolar de
   lado — e e essa rolagem que as setas e o arrasto do lote 25 atendem.

   NENHUMA MEDIDA NOVA ENTRA AQUI: a aba de filtro e a MESMA Aba de
   ordenacao 61139:2191 do Figma, entao ela usa `.kd-aba-ordem` inteira, e
   ligada usa `.kd-aba-ordem-atual`, que e o estado Selecionada. Na Home so
   existe o grupo `ordem`, e um gap sem segundo filho nao muda nada: a barra
   fica exatamente como estava.                                           */
.kd-abas-grupo {
  display: flex;
  align-items: center;
  flex: none;
  gap: var(--md-sys-measurement-space50);            /* 4 */
}

/* Padrao: SEM FUNDO (o Figma devolve a lista de fills vazia) e tudo em
   on-surface-variant — icone e rotulo na mesma cor. */
.kd-aba-ordem {
  display: inline-flex;
  align-items: center;
  flex: none;
  gap: var(--md-sys-measurement-space100);           /* 8 */
  min-height: var(--kd-aba-ordem-altura);            /* 40 */
  padding: var(--md-sys-measurement-space125) var(--md-sys-measurement-space150);  /* 10 / 12 */
  border-radius: var(--md-sys-shape-corner-medium);  /* 12 */
  color: var(--md-sys-color-on-surface-variant);
  white-space: nowrap;
}

/* Selecionada: surface-container-lowest, on-surface, e o rotulo passa de
   label/large para label/large-emphasized. So o PESO muda — tamanho, entrelinha
   e tracking sao os mesmos nas duas variantes, medidos. Por isso aqui vai uma
   propriedade so, e nao uma troca de classe: a classe teria de ser trocada pelo
   JavaScript a cada clique, e o peso acompanha sozinho. */
.kd-aba-ordem-atual {
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
  font-weight: var(--md-sys-typescale-label-large-weight-emphasized);
  /* Medido em 61139:2185: a Selecionada tem KD/Sombra leve e a Padrao nao
     tem efeito nenhum. E ela que levanta a aba escolhida do fundo da
     capsula. */
  box-shadow: var(--kd-sombra-leve);
}

.kd-aba-ordem:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* A CONTAGEM E FILHA DO AUTO-LAYOUT, e nao um badge sobreposto: ela vem DEPOIS
   do rotulo, com o mesmo gap de 8, e empurra a largura da aba. Medido na
   instancia 61139:2215 (o rotulo acaba em 134 e a contagem comeca em 142).
   Altura 16 FIXA, largura HUG com padding lateral Space 50. */
.kd-aba-ordem-contagem {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  height: var(--md-sys-measurement-space200);        /* 16 */
  padding-inline: var(--md-sys-measurement-space50); /* 4 */
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}

/* O botao que abre o Menu de exibicao. ABERTO ELE VAI PARA secondary-container:
   isso vem do figma-componentes.md, e nao do desenho — o botao e um frame
   simples dentro do componente, sem variante de aberto e sem instancia em
   estado nenhum em tela nenhuma. Esta registrado no relatorio. */
.kd-exibicao-abrir {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--kd-exibicao-botao);                   /* 40 */
  height: var(--kd-exibicao-botao);
  border-radius: var(--md-sys-shape-corner-medium);  /* 12 */
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
  /* As abas ao lado sao `<a href>` e ganham a mao do navegador de graca; um
     `<button>` nao ganha. No projeto cada componente clicavel declara o seu —
     `.kd-botao`, `.kd-chip-filtro`, `.kd-periodo-item` e mais dez. */
  cursor: pointer;
}

.kd-exibicao-abrir[aria-expanded="true"] {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}

/* ATIVO: menu FECHADO e Loja ou Faixa de preco com valor escolhido (Botao da
   barra 61200:2264, terceira variante, lote 30). E o aviso de que ha filtro
   ligado dentro do menu — sem ele, com o menu fechado, um filtro de loja
   ficaria invisivel, porque a Barra de filtros, que mostrava os chips acesos,
   saiu neste lote.

   O "FECHADO" MORA NO `:not`, E NAO NO PHP. Quem tem o valor escolhido e o
   servidor quem sabe, e ele escreve o `data-kd-exibicao-ativo`; quem esta
   aberto e o JavaScript quem sabe, e ele escreve o `aria-expanded`. Cruzar os
   dois no seletor mantem UM estado por dono, sem ninguem ter de avisar o
   outro: abrir o menu ja apaga o Ativo, fechar ja o devolve. */
.kd-exibicao-abrir[data-kd-exibicao-ativo]:not([aria-expanded="true"]) {
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

.kd-exibicao-abrir:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* --- Botoes --------------------------------------------------------------- */
/* A PILULA TEM 40, A AREA DE TOQUE TEM 48.
   Medido no Figma nos tres botoes do site (Carregar mais, Copiar do Cupom,
   Entrar no canal do CTA): a instancia do Button - tonal Size=Small ocupa 48
   de altura, mas o `Content` — a parte PINTADA — tem 40, com 4 transparentes
   em cima e 4 embaixo. O CSS pintava os 48 inteiros. A margem de 4 devolve os
   48 de area sem pintar os 48, entao nada muda de lugar e a pilula fica do
   tamanho do desenho. Achado medindo o lote 14; as medicoes anteriores
   comparavam a caixa da instancia, nao a forma pintada. */
.kd-botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  min-height: var(--kd-botao-altura);              /* 40 — a pilula pintada */
  margin-block: var(--md-sys-measurement-space50);  /* 4 + 4 = 48 de area */
  padding: var(--md-sys-measurement-space125) var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-full);
  white-space: nowrap;
  cursor: pointer;
  position: relative;
}

/* --- Button Size=XSmall (Figma 57994:2326) --------------------------------
   O MESMO botao, com a pilula de 32 em vez de 40. E o tamanho que o Figma usa
   quando o botao divide a linha com um chip: o "Novo ..." e o "Filtrar" sem
   JavaScript das 7 telas de lista do painel. O segundo caso era o tonal
   "Filtros" da Barra de filtros Compacta, que saiu no lote 30 — o "Filtrar" do
   site agora divide a linha com campos de 48, e por isso usa o Small.

   MEDIDO EM 24/09/2026, comparado com o Small:
                      Small     XSmall
     instancia         48         48     (a area de toque nao muda)
     Content           40         32     (a pilula pintada)
     padding         10/16       6/12
     gap interno        8          4
     icone             20         20
     rotulo      label/large  label/large

   A area de toque continua com 48 nos dois: o que muda e so a tinta. Por isso
   trocar Small por XSmall NAO mexe na altura de linha nenhuma — a linha ja
   tinha 48. */
.kd-botao-xs {
  min-height: var(--kd-botao-altura-xs);            /* 32 — a pilula pintada */
  margin-block: var(--md-sys-measurement-space100); /* 8 + 8 = os mesmos 48 */
  padding: var(--md-sys-measurement-space75) var(--md-sys-measurement-space150);
  gap: var(--md-sys-measurement-space50);           /* 4 — icone ate o rotulo */
}

/* Tonal sobre bloco: surface-container-highest (regra de superficie). */
/* Tonal sobre bloco: o FUNDO e surface-container-highest (override do fill
   `Content` do kit, pela regra de superficie), mas o rotulo e o icone ficam com
   a cor do kit — on-secondary-container. Medido no Cupom do Figma. */
.kd-botao-tonal {
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-secondary-container);
  gap: var(--md-sys-measurement-space100);          /* 8 — icone ate o rotulo */
}

.kd-botao::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--md-sys-color-on-surface);
  opacity: 0;
  pointer-events: none;
}

.kd-botao:hover::after { opacity: var(--md-sys-state-hover-state-layer-opacity); }

.kd-botao:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* --- Cupom ---------------------------------------------------------------- */
.kd-cupom {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space150);          /* 12 */
  width: var(--kd-cupom-largura);                   /* 400; 320 abaixo de 600 */
  padding: var(--md-sys-measurement-space200);      /* 16 */
  /* 12, E NAO MAIS 24 (lote 32, etapa 4). Medido no Cupom 60826:330 em
     25/09/2026, nos QUATRO estados: Corner/Medium. Mesma passada do Card de
     oferta e pelo mesmo motivo.

     O CAMPO DO CODIGO (`.kd-cupom-codigo`) FICA NOS 8 DE SEMPRE: o lote mandou
     mudar o canto do bloco, nao o do que esta dentro dele. */
  border-radius: var(--md-sys-shape-corner-medium);       /* 12 */
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
}

.kd-cupom-topo {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space150);          /* 12 */
  min-width: 0;
}

.kd-cupom-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--kd-cupom-logo);                      /* 40 */
  height: var(--kd-cupom-logo);
  border-radius: var(--md-sys-shape-corner-full);
  /* Surface Container Lowest com o modo claro preso (a classe `kd-modo-claro`
     vem no HTML): circulo branco com as iniciais escuras nos dois temas, a
     mesma regra da caixa da foto de produto. Figma, 24/09/2026. */
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
}

.kd-cupom-textos {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space25);           /* 2 */
  min-width: 0;
}

.kd-cupom-loja { color: var(--md-sys-color-on-surface-variant); }

.kd-cupom-descricao {
  color: var(--md-sys-color-on-surface);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.kd-cupom-validade {
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space50);           /* 4 */
  color: var(--md-sys-color-on-surface-variant);
}

/* O texto obrigatorio da loja no cupom (lei 15) — ultima linha do cartao.
   A MESMA regra do `.kd-preco-texto-loja`, e pelo mesmo motivo: quebra linha e
   NUNCA corta. O programa de afiliados exige o texto inteiro junto do cupom;
   reticencias seriam quebra de contrato. Por isso nao ha `text-overflow` nem
   `-webkit-line-clamp` aqui, e o `overflow-wrap` cobre a palavra unica maior
   que o cartao de 320 (o cupom abaixo de 600). */
.kd-cupom-texto-loja {
  margin: 0;
  color: var(--md-sys-color-on-surface-variant);
  overflow-wrap: anywhere;
}

/* A SOBRA FICA ABAIXO DO BOTAO, e nao acima dele (medido no lote 22).
   Havia aqui um `margin-top: auto`, que empurrava a linha do codigo para o fim
   do cartao sempre que o cartao esticava — e ele estica em toda linha onde um
   vizinho e mais alto, que e a regra "todas as celulas da linha com a altura da
   mais alta". Medido no Figma em 25/09/2026, na grade de Cupons do 768: um
   cupom de UMA linha esticado para 178 mantem os filhos nas MESMAS coordenadas
   de um cartao de 160 (topo y16, validade y68, acao y96..144), e os 18 que
   sobram ficam DEPOIS do botao. Ou seja, conteudo colado no topo.
   Sem esta correcao, dois cupons lado a lado com alturas diferentes ficavam com
   o codigo em alturas diferentes dentro do proprio cartao. */
.kd-cupom-acao {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);          /* 8 */
}

/* O codigo do cupom CONTA COMO CAMPO: o visitante seleciona e copia. Pela regra
   de superficie, campo dentro de bloco (surface-container-low) vai em
   surface-container-high — dois tons acima. Estava em lowest, que no tema
   escuro e #0a0a0a, mais escuro que o proprio cartao (#1c1c1c): parecia um
   buraco preto, e nao um campo. Corrigido no Figma em 24/09/2026. */
.kd-cupom-codigo {
  flex: 1 1 auto;
  min-width: 0;
  /* 40 de altura com o texto centrado: no Figma o `codigo` tem altura fixa e
     alinhamento CENTER, e nao padding vertical. */
  height: var(--kd-cupom-codigo-altura);            /* 40 */
  padding: 0 var(--md-sys-measurement-space200);    /* 0 / 16 */
  border-radius: var(--md-sys-shape-corner-small);  /* 8 */
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  border: none;
  text-overflow: ellipsis;
}

.kd-cupom-codigo:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

.kd-cupom-expirado .kd-cupom-descricao,
.kd-cupom-expirado .kd-cupom-codigo { color: var(--md-sys-color-on-surface-variant); }

/* --- CTA do canal --------------------------------------------------------- */
.kd-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--md-sys-measurement-space200);          /* 16 */
  padding: var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-large-plus);  /* 24, vertical */
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
}

.kd-cta-identidade {
  display: flex;
  align-items: flex-start;
  gap: var(--md-sys-measurement-space200);
  min-width: 0;
}

/* LOGO NA COR DA MARCA.
   Estas classes vão no próprio `<svg>` do ícone, e não num ancestral, porque
   cada logo tem a sua cor: no Footer, Telegram e WhatsApp são irmãos, e uma
   variável posta no pai pintaria os dois de uma cor só.
   Elas não trocam no tema escuro — o Figma mede o mesmo valor nos dois modos. */
.kd-logo-telegram {
  --kd-logo-marca: var(--kd-marca-telegram);
  --kd-logo-fundo: var(--kd-marca-telegram-aviao);
}

.kd-logo-whatsapp  { --kd-logo-marca: var(--kd-marca-whatsapp); }
.kd-logo-instagram { --kd-logo-marca: var(--kd-marca-instagram); }

/* No Figma o logo do CTA aparece na COR DA MARCA, chapado sobre o card — sem
   círculo em volta. O código pintava em on-surface desde o lote 11; corrigido
   no lote 17. */
.kd-cta-logo {
  display: inline-flex;
  flex: none;
  width: var(--kd-cta-logo);                        /* 40 */
  height: var(--kd-cta-logo);
}

.kd-cta-logo .kd-icone {
  width: 100%;
  height: 100%;
}

.kd-cta-textos {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);           /* 4 */
  min-width: 0;
}

.kd-cta-titulo { color: var(--md-sys-color-on-surface); }
.kd-cta-descricao { color: var(--md-sys-color-on-surface-variant); }

.kd-cta-acao { width: 100%; }

/* A partir de 600 o CTA vira horizontal: canto 16 (faixa de uma linha de
   conteudo), itens centrados e o botao com a largura do proprio texto. */
@media (min-width: 600px) {
  .kd-cta {
    flex-direction: row;
    align-items: center;
    border-radius: var(--md-sys-shape-corner-large);  /* 16 */
  }

  .kd-cta-identidade {
    align-items: center;
    flex: 1 1 auto;
  }

  .kd-cta-acao { width: auto; }
}

/* --- Canais: empilhados; lado a lado so a partir de 1200 ------------------ */
.kd-canais {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);
}

@media (min-width: 1200px) {
  .kd-canais { flex-direction: row; }
  .kd-canais > * { flex: 1 1 0; min-width: 0; }
}

/* ---------------------------------------------------------------------------
   "Melhores descontos agora": 15 cards renderizados, so linhas completas na
   tela.

   O Figma mostra 2 linhas em 1440 (2x5), 3 em 768 (3x3) e 3 em 390 (3x2). Como
   entre 600 e 1199 o numero de colunas sai da conta do `auto-fill`, o corte
   precisa conhecer a mesma fronteira: 2 colunas ate 719, 3 de 720 a 943, 4 de
   944 a 1167 e 5 de 1168 em diante — exatamente os limites medidos no Figma na
   secao "Grade e Lista por largura" (as telas 719/720, 943/944 e 1167/1168).

   Esconder o excedente com `display: none` em vez de cortar com altura: linha
   incompleta nao aparece, e nenhum card fica pela metade.
   --------------------------------------------------------------------------- */
/* AS CONTAS FORAM REFEITAS NO LOTE 24, porque o lote 23 trocou a conta das
   colunas e nao mexeu aqui: os pontos de quebra tinham sido medidos para 2
   / 3 / 4 / 5 colunas e a grade passou a dar 2 / 3 / 4 / 5 / 6 por
   piso((C + 16) / 176). Medido no navegador em 25/09/2026, antes da
   correcao: 1440 mostrava 10 cards em 6 colunas (linha torta de 4), 1168
   mostrava 15 em 6 (torta de 3), 944 mostrava 12 em 5 (torta de 2) e 768
   mostrava 9 em 4 (torta de 1). So o 390 estava certo.

   A REGRA DO DESENHO, medida nas seis telas de Home do Figma: 3 linhas no
   390 e no 768, 2 linhas no 1440. Com 15 cards no banco, a unica leitura que
   fecha nas tres e "3 linhas cheias, nunca mais de 15, nunca linha torta":

     2 colunas -> 6     3 colunas -> 9     4 colunas -> 12
     5 colunas -> 15    6 colunas -> 12  (3 linhas dariam 18, e so ha 15)

   OS PONTOS DE QUEBRA SAO OS DA PROPRIA CONTA DAS COLUNAS: a coluna troca
   quando C >= 176k - 16, e com a margem de 32 e a barra de rolagem do Chrome
   (15) isso da 767, 943 e 1119 de JANELA. Sao os mesmos numeros do lote 23,
   so que agora escritos onde a contagem precisa deles. Em maquina sem barra
   de rolagem a troca cai 15 px antes; nessa faixa de 15 px a ultima linha
   fica com um card a menos, e nao ha como o CSS contar coluna. */
.kd-grade-limitada > :nth-child(n + 7)  { display: none; }   /* 2 col x 3 linhas */

@media (min-width: 600px) {
  .kd-grade-limitada > :nth-child(n + 7)  { display: flex; }
  .kd-grade-limitada > :nth-child(n + 10) { display: none; } /* 3 col x 3 linhas */
}

@media (min-width: 767px) {
  .kd-grade-limitada > :nth-child(n + 10) { display: flex; }
  .kd-grade-limitada > :nth-child(n + 13) { display: none; } /* 4 col x 3 linhas */
}

@media (min-width: 943px) {
  .kd-grade-limitada > :nth-child(n + 13) { display: flex; } /* 5 col x 3 linhas */
}

@media (min-width: 1119px) {
  .kd-grade-limitada > :nth-child(n + 13) { display: none; } /* 6 col x 2 linhas */
}

/* --- Carrosseis da Home, com o gap de cada um (medido no Figma) ----------- */

/* Chips de categoria: gap Space 100. */
/* --- Setas de carrossel (Figma "Seta de carrossel" 61175:2221, lote 25) ---
   Toda lista que rola de lado ganha duas, e quem as cria e o `kd.js`: ele
   embrulha o rolavel num `.kd-rolavel` e poe os dois botoes dentro. Sem
   JavaScript nao existe nem o involucro nem as setas, e a lista continua
   rolando como sempre — por toque, por barra, por roda e por Tab.

   MEDIDO no componente: 40x40, Corner/Full, surface-container-highest,
   chevron de 24 em on-surface com folga de 8 de cada lado. Sem sombra, sem
   borda, sem estado desabilitado — a seta que nao serve nao fica cinza, ela
   SOME (regra do documento: a Anterior some no comeco e a Proxima no fim).

   8 PARA DENTRO. Medido na unica seta desenhada (61175:2274): ela fica em
   x=1152 num quadro de 1200, ou seja 8 da borda direita. A posicao da
   Anterior nao esta desenhada — e simetria, e esta no relatorio.

   O `top` VEM DO JAVASCRIPT, e nao daqui, porque a altura de referencia
   muda por lista: no Item de categoria a seta se centraliza no quadrado da
   imagem (medido: centro 48 num item de 124), no carrossel de cards na
   imagem do card, e onde nao ha imagem no proprio item. O `translateY` de
   -50% completa a conta.

   SO COM MOUSE. `hover: hover` e a pergunta "este aparelho tem ponteiro que
   passa por cima?" — no toque, nao. E a mesma pergunta que o documento faz.
   Fora dela as setas ficam `display: none` e somem tambem da arvore de
   acessibilidade.                                                        */
.kd-rolavel { position: relative; }

/* O INVOLUCRO ENTROU NO LUGAR DAS ABAS, entao ele herda o papel delas dentro
   da Barra de ordenacao: e ele que estica e que pode encolher abaixo do
   tamanho do conteudo. Sem o `min-width: 0` um flex item nao encolhe alem do
   proprio conteudo, e as quatro abas (584) empurrariam o botao Exibicao para
   fora da barra no celular.

   Quem embrulha e o `kd.js`, entao esta regra so entra em cena quando ha
   JavaScript — e sem ele a barra continua como sempre foi. */
.kd-barra-ordem > .kd-rolavel {
  flex: 1 1 auto;
  min-width: 0;
}

.kd-seta {
  display: none;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 1;
  align-items: center;
  justify-content: center;
  width: var(--kd-seta);                             /* 40 */
  height: var(--kd-seta);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
  cursor: pointer;
  /* Ela fica POR CIMA do conteudo — dai a flutuante, e nao a leve. Medido
     nas duas variantes de 61175:2221. */
  box-shadow: var(--kd-sombra-flutuante);
}

.kd-seta-anterior { left: var(--md-sys-measurement-space100); }   /* 8 */
.kd-seta-proxima  { right: var(--md-sys-measurement-space100); }

/* DUAS CONDICOES, E NAO UMA (decisao do Matheus, 25/09/2026).

   `hover: hover` pergunta se o aparelho tem ponteiro que passa por cima —
   num celular, nao. So que essa pergunta sozinha ainda mostrava as setas num
   navegador de DESKTOP com a janela estreita, que e o desenho Mobile do
   projeto. O pedido foi: seta so no desktop.

   `min-width: 600px` e o mesmo ponto onde o Header, o Item de categoria e a
   grade trocam de Mobile para Desktop. Abaixo dele nao ha seta nem com
   mouse, e nao faz falta: o arrasto por mouse entrou no mesmo lote e alcanca
   o que estiver escondido.

   NUM CELULAR DE VERDADE NADA MUDA — la `hover: hover` ja era falso e as
   setas nunca apareceram. Medido com a emulacao de toque do Chrome.

   APARECEM NO HOVER DA LISTA E COM O FOCO DENTRO DELA. O `:focus-within`
   cobre a segunda metade da regra: quem percorre a lista pelo Tab ve as
   setas enquanto o foco esta la dentro, mesmo sem encostar o mouse.      */
@media (hover: hover) and (min-width: 600px) {
  .kd-rolavel:hover > .kd-seta:not([hidden]),
  .kd-rolavel:focus-within > .kd-seta:not([hidden]) {
    display: flex;
  }
}

/* A camada de estado do projeto, a mesma dos botoes. O Figma nao desenha
   hover nem pressionado da seta — a propriedade do componente e so Direcao —,
   entao aqui vale a regra geral, e nao uma medida. */
.kd-seta::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--md-sys-color-on-surface);
  opacity: 0;
  pointer-events: none;
}

.kd-seta:hover::after { opacity: var(--md-sys-state-hover-state-layer-opacity); }

.kd-seta:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

.kd-chips { gap: var(--md-sys-measurement-space100); }

/* --- Item de categoria (Figma 61175:2214, lote 25) ------------------------
   O carrossel de Categorias da Home deixou de ser uma fila de chips
   "Nome · N ofertas" e passou a ser uma fila destes: quadrado com a imagem
   da categoria e o nome embaixo.

   MEDIDO nas quatro variantes e nas 12 instancias das telas de Home:
     Desktop (600+)  item 112, quadrado 96, rotulo body/medium, icone 32
     Mobile          item 96,  quadrado 72, rotulo body/small,  icone 24
   Altura: 124 = 96 + 8 + 20 no Desktop, 96 = 72 + 8 + 16 no Mobile. Ela nao
   e escrita em lugar nenhum — sai da soma, como no Figma, onde o item e HUG
   na vertical.

   O ROTULO E DE UMA LINHA SO, e aqui o Figma DESMENTE o documento, que diz
   "ate 2 linhas": medido `maxLines: 1` com truncation ENDING nas quatro
   variantes e nas 12 instancias, e as alturas de 124 e 96 so fecham com uma
   linha. Pela lei 1 vale o desenho. Esta no relatorio.                   */
.kd-item-categoria {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--md-sys-measurement-space100);           /* 8 */
  flex: none;
  width: var(--kd-categoria-item);
  color: var(--md-sys-color-on-surface);
}

/* O QUADRADO FICA SEMPRE CLARO. O frame `imagem` tem o modo da colecao de
   cores preso em Light nas quatro variantes e nas 12 instancias — a mesma
   coisa que a caixa da foto do produto ja faz. A classe `.kd-modo-claro` no
   HTML e quem redeclara as cores; aqui fica so a forma.

   `overflow: hidden` e o que arredonda a imagem pelo canto de 24: no Figma e
   o `clipsContent` do mesmo frame. */
.kd-item-categoria-quadrado {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  position: relative;
  width: var(--kd-categoria-quadrado);
  height: var(--kd-categoria-quadrado);
  border-radius: var(--md-sys-shape-corner-large-plus);   /* 24 */
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant);
  overflow: hidden;
}

/* A IMAGEM INTEIRA, COM RESPIRO DE 8 — e este e o unico ponto do componente
   que NAO sai de medida. O Figma nao tem nenhum no com imagem de verdade
   aqui: as 4 variantes, as 10 do exemplo e as 12 das telas mostram todas o
   icone de reserva, e o padding do quadrado e 0. O `contain` e o respiro de
   8 vem do documento e do lote. Registrado no relatorio.

   `contain`, e nao `cover`: a imagem da categoria e um desenho de produto em
   PNG transparente, e cortar a borda dele para preencher o quadrado tiraria
   justamente o que identifica a categoria. */
.kd-item-categoria-quadrado img {
  width: 100%;
  height: 100%;
  padding: var(--kd-categoria-respiro);              /* 8 */
  object-fit: contain;
  display: block;
}

/* ATE DUAS LINHAS, COM RETICENCIAS — e aqui o Figma se contradiz, entao vale
   o que ele ESCREVE. O `description` do component set 61175:2214 diz, com
   estas palavras: "Rotulo centralizado, ate 2 linhas com reticencias". O no
   de texto das quatro variantes, porem, esta com `maxLines: 1`.

   Fica valendo o texto do componente, por tres motivos: ele e a
   especificacao escrita pelo proprio desenho (e o `figma-componentes.md`
   repete a mesma frase); os nomes desenhados sao todos curtos, entao o
   `maxLines: 1` nunca foi posto a prova la; e com uma linha so as
   categorias de verdade ficariam ilegiveis — "Utilidades Domesticas",
   "Livros e Papelaria" e "Saude e Bem-estar" viram "Utilidades Do...".
   Registrado no relatorio.

   A ALTURA DO ITEM PASSA A VARIAR (124 com uma linha, 144 com duas), e o
   `align-items: stretch` que o carrossel ja tem iguala todos pela mais
   alta: os quadrados continuam alinhados no topo, que e o que importa. */
.kd-item-categoria-nome {
  width: 100%;
  text-align: center;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  /* PALAVRA QUE NAO CABE QUEBRA COM HIFEN, PELA SILABA, e nunca no meio sem
     hifen (lote 26). Quem hifeniza e o navegador, e ele so sabe fazer isso
     com o idioma declarado: o `<html lang="pt-BR">` esta nos dois documentos
     do projeto, o do site e o do painel. Sem o `lang`, `hyphens: auto` nao
     faz nada. */
  hyphens: auto;
  font-family: var(--md-sys-typescale-body-small-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-body-small-size);
  line-height: var(--md-sys-typescale-body-small-line-height);
  letter-spacing: var(--md-sys-typescale-body-small-tracking);
  font-weight: var(--md-sys-typescale-body-small-weight);
}

/* HOVER: state layer on-surface a 10% SOBRE O QUADRADO, e so sobre ele — o
   rotulo nao e coberto. Medido: a unica diferenca entre Estado=Padrao e
   Estado=Hover e o aparecimento desse no. */
.kd-item-categoria-quadrado::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--md-sys-color-on-surface);
  opacity: 0;
  pointer-events: none;
}

.kd-item-categoria:hover .kd-item-categoria-quadrado::after {
  opacity: var(--md-sys-state-hover-state-layer-opacity);
}

/* O ANEL DE FOCO NAO ESTA NO FIGMA — a propriedade Estado do componente so
   tem Padrao e Hover. Ele vem da regra do projeto, igual a de todo link. */
.kd-item-categoria:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
  border-radius: var(--md-sys-shape-corner-small);
}

@media (min-width: 600px) {
  .kd-item-categoria-nome {
    font-family: var(--md-sys-typescale-body-medium-font), system-ui, sans-serif;
    font-size: var(--md-sys-typescale-body-medium-size);
    line-height: var(--md-sys-typescale-body-medium-line-height);
    letter-spacing: var(--md-sys-typescale-body-medium-tracking);
    font-weight: var(--md-sys-typescale-body-medium-weight);
  }

  /* O icone de reserva: 24 no Mobile (o padrao do `.kd-icone`) e 32 aqui. */
  .kd-item-categoria-quadrado > .kd-icone {
    width: var(--kd-categoria-icone);
    height: var(--kd-categoria-icone);
  }
}

/* O carrossel da Home: gap 16 de 600 em diante, 12 abaixo — medido nas seis
   telas. Os dois sao valores literais no Figma, sem variavel ligada, mas
   coincidem com Space 200 e Space 150. */
.kd-carrossel-categorias { gap: var(--md-sys-measurement-space150); }

@media (min-width: 600px) {
  .kd-carrossel-categorias { gap: var(--md-sys-measurement-space200); }
}

/* Cards de oferta no carrossel: 240 fixos, gap Space 200 — o carrossel nao
   segue a grade fluida, e o card fica no tamanho do desenho. */
.kd-carrossel-cards > .kd-card { width: var(--kd-card-grade-largura); }

/* Cupons: 400 (320 abaixo de 600), gap Space 200. A largura vem do proprio
   `.kd-cupom`. */

/* Todos os itens de um carrossel com a mesma altura (regra de padding e
   espacamento: "blocos lado a lado sempre com a mesma altura"). */
.kd-rolagem-borda { align-items: stretch; }

/* --- Botao "Copiar" do cupom: icone + rotulo -----------------------------
   No Figma o botao tem o icone `content_copy` de 20 e gap Space 100 (8) ate o
   rotulo. No estado Copiado o icone troca para `check` e o rotulo para
   "Copiado" — por isso os dois icones vem no HTML e o CSS mostra um.       */
.kd-cupom-icone-copiar,
.kd-cupom-icone-copiado { display: inline-flex; flex: none; }

.kd-cupom-icone-copiado { display: none; }

.kd-cupom-copiado .kd-cupom-icone-copiar  { display: none; }
.kd-cupom-copiado .kd-cupom-icone-copiado { display: inline-flex; }

/* Expirado: o Figma desenha o botao apagado — fundo com o state layer de
   on-surface a 10%, e o rotulo e o icone em on-surface (nao mais em
   on-secondary-container). Fica `disabled` no HTML: um cupom vencido nao tem
   codigo para copiar. */
.kd-cupom-expirado .kd-botao-tonal {
  background: color-mix(in srgb,
              var(--md-sys-color-on-surface) var(--kd-estado-apagado-opacidade),
              var(--md-sys-color-surface-container-low));
  color: var(--md-sys-color-on-surface);
  cursor: default;
}

.kd-cupom-expirado .kd-botao-tonal::after { content: none; }

/* ===========================================================================
   Skeleton de card (Figma 60840:502)

   Medido no Figma em 24/09/2026, depois da densidade do lote 13: as variantes
   Card grade (240x376) e Card grade compacta (173x309) sao IDENTICAS fora o
   tamanho — mesmo padding, mesmo canto, mesmas barras, mesma altura de bloco de
   textos. O tamanho vem da celula da grade. Entao ha uma regra so para as duas,
   como ja acontece com o Card de oferta de verdade.

   A altura sai da conta, nao de um numero escrito aqui:
     12 + (largura - 24) + 12 + 124 + 12
   Em 240 da 376, em 256 da 392, em 224 da 360 e em 173 da 309 — os quatro
   valores que o Figma desenha nas telas de carregamento.
   =========================================================================== */

.kd-skeleton {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space150);               /* 12 */
  padding: var(--md-sys-measurement-space150);           /* 12 */
  /* 12, PELO MESMO MOTIVO DO CARD (lote 32, etapa 4). Figma: as variantes Card
     grade, Card lista e Card grade compacta do Skeleton 60840:502 passaram a
     Corner/Medium junto com o card de verdade.

     ELE TEM DE ANDAR JUNTO, e nao por simetria: o esqueleto e o card antes de o
     conteudo chegar, e no mesmo lugar da tela. Se ficasse nos 24 antigos, o
     canto mudaria na frente do visitante no instante em que a oferta entrasse
     — um salto visivel no "Carregar mais" e na troca parcial da lei 23. */
  border-radius: var(--md-sys-shape-corner-medium);       /* 12 */
  background: var(--md-sys-color-surface-container-low);
  min-width: 0;
}

/* Imagem quadrada travada, igual a do card (regra de padding do Figma). */
.kd-skeleton-imagem {
  width: 100%;
  aspect-ratio: 1;
  /* 8, acompanhando `.kd-card-imagem` (lote 32, etapa 4). */
  border-radius: var(--md-sys-shape-corner-small);       /* 8 */
  background: var(--md-sys-color-surface-container-high);
}

.kd-skeleton-textos {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);               /* 8 */
  height: var(--kd-skeleton-textos);                     /* 124 */
}

.kd-skeleton-barra {
  flex: none;
  max-width: 100%;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-high);
}

.kd-skeleton-loja {
  width: var(--kd-skeleton-loja-largura);                /* 96 */
  height: var(--kd-skeleton-loja-altura);                /* 12 */
}

.kd-skeleton-titulo {
  width: 100%;
  height: var(--kd-skeleton-titulo-altura);              /* 14 */
}

.kd-skeleton-titulo-curto {
  width: var(--kd-skeleton-titulo-curto);                /* 140 */
  height: var(--kd-skeleton-titulo-altura);
}

.kd-skeleton-preco {
  width: var(--kd-skeleton-preco-largura);               /* 120 */
  height: var(--kd-skeleton-preco-altura);               /* 24 */
}

/* Card lista (560x168): imagem 144 fixa ao lado, bloco de textos com a altura
   do proprio conteudo (HUG no Figma, 88). Ainda nao ha tela que use — entra
   agora para o dia em que a listagem em lista existir. */
.kd-skeleton-lista {
  flex-direction: row;
  align-items: flex-start;
  max-width: var(--kd-card-lista-largura);               /* 560 */
}

.kd-skeleton-lista .kd-skeleton-imagem {
  flex: none;
  width: var(--kd-card-lista-imagem);                    /* 144 */
}

.kd-skeleton-lista .kd-skeleton-textos {
  flex: 1 1 auto;
  min-width: 0;
  height: auto;
}

.kd-skeleton-lista .kd-skeleton-titulo       { width: var(--kd-skeleton-lista-titulo); }
.kd-skeleton-lista .kd-skeleton-titulo-curto { width: var(--kd-skeleton-lista-titulo-curto); }
.kd-skeleton-lista .kd-skeleton-preco        { width: var(--kd-skeleton-lista-preco); }

/* ===========================================================================
   Feed "Todas as ofertas": Carregar mais e Aviso de ofertas novas
   =========================================================================== */

/* O involucro existe para o aviso ter a que se prender: ele comeca onde a grade
   comeca e termina onde ela termina, entao e ele que define de onde ate onde o
   `sticky` do aviso vale. Sem ele, o aviso grudaria ate o fim da secao — ou da
   pagina — em vez de sumir com o feed. */
.kd-feed { display: flow-root; }

/* O aviso acompanha a rolagem (regra do Matheus, 24/09/2026).
   Enquanto o feed estiver na tela ele fica preso 16 abaixo do topo da TELA,
   centralizado; quando o feed sai da tela, ele some junto.

   COMO: `position: sticky` com `top: 0` no involucro, e os 16 no `margin-top`
   da pilula. Assim o mesmo 16 serve aos dois estados, sem regra dupla:
     solto   -> o involucro fica no topo da grade, a pilula 16 abaixo dele
                (a posicao que as 6 telas do Figma desenham);
     grudado -> o involucro fica no topo da tela, a pilula 16 abaixo dele.

   `height: 0` e o que faz o aviso nao empurrar a grade: o involucro nao ocupa
   altura nenhuma e a pilula transborda por cima do conteudo.

   E `sticky` e limitado pelo pai: quando o fim do `.kd-feed` passa por cima, o
   involucro sobe junto e sai da tela — que e exatamente "quando o feed sai da
   tela, ele some junto", sem uma linha de JavaScript para isso.

   z-index 1 passa na frente dos cards; o drawer e o scrim, que cobrem tudo,
   estao em 11 e 10. */
/* O AVISO GRUDA ABAIXO DO HEADER, E NAO NO TOPO DA JANELA (lote 23).
   Ate o lote 22 o Header rolava junto com a pagina e `top: 0` era o topo
   visivel. Agora ele e fixo: com `top: 0` a pilula ficaria presa POR BAIXO do
   Header, invisivel justamente enquanto o feed rola — que e a unica hora em
   que ela serve. Os 8 a mais sao o mesmo respiro do `scroll-padding-top`. */
/* O `top` NAO MUDOU no lote 30, e isso foi MEDIDO antes de decidir: o Aviso
   vive na secao "Todas as ofertas" da Home e a Barra de ordenacao vive na
   secao "Melhores descontos agora". Como `position: sticky` so prende dentro
   do proprio bloco, e os dois blocos sao secoes seguidas e disjuntas, nunca
   ha instante em que os dois estejam presos ao mesmo tempo — apesar de o
   `top` dos dois ser a MESMA expressao. Empurrar este aqui para baixo da
   barra o afastaria do lugar que o Figma desenha, para desviar de uma barra
   que nunca esta ali.

   O Z-INDEX SUBIU DE 1 PARA 3, E E PRECAUCAO, nao conserto: a barra presa
   entrou em 2, e no dia em que "Todas as ofertas" ganhar barra propria — ela
   e a candidata obvia, ja tem grade e "Carregar mais" — a ordem certa ja vai
   estar escrita. Continua abaixo do Header (4), entao o Aviso nunca passa
   por cima dele.                                                         */
.kd-aviso-novas {
  position: sticky;
  top: calc(var(--kd-header-altura) + var(--md-sys-measurement-space100));
  z-index: 3;
  height: 0;
  display: flex;
  justify-content: center;
  /* `flex-start` e nao o `stretch` padrao: num flex de altura 0, `stretch`
     esticaria a pilula para a altura do involucro — ou seja, a comprimiria de
     40 para os 20 do padding. Com `flex-start` ela fica na altura natural e
     transborda, que e o que se quer de um aviso flutuante. Medido: 229,58x40,
     contra os 230x40 do Figma. */
  align-items: flex-start;
}

/* A pilula inteira e o botao (Figma 60964:82204, 230x40).
   `inverse-surface` troca de lado sozinho no tema escuro: a pilula escura do
   claro vira clara no escuro, exatamente como nas seis telas. */
/* A pilula flutua sobre o feed: sombra flutuante (medido em 60964:82204,
   cuja descricao no Figma e literalmente "KD/Sombra flutuante"). */
.kd-aviso-novas-pilula {
  margin-top: var(--md-sys-measurement-space200);        /* 16 */
  display: inline-flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);               /* 8 */
  padding: var(--md-sys-measurement-space125)            /* 10 */
           var(--md-sys-measurement-space200);           /* 16 */
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
  white-space: nowrap;
  cursor: pointer;
  position: relative;
  box-shadow: var(--kd-sombra-flutuante);
}

/* Hover: o mesmo state layer de todo o resto, na cor do proprio texto — sobre
   uma superficie invertida, on-surface seria invisivel. */
.kd-aviso-novas-pilula::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--md-sys-color-inverse-on-surface);
  opacity: 0;
  pointer-events: none;
}

.kd-aviso-novas-pilula:hover::after {
  opacity: var(--md-sys-state-hover-state-layer-opacity);
}

/* Linha do "Carregar mais": largura total, botao centrado (Figma
   `carregar-mais`, FILL x 48, alinhamento CENTER). O espaco de 16 ate a grade
   vem do gap da propria secao. */
.kd-carregar-mais {
  display: flex;
  justify-content: center;
}


/* Botao tonal SOBRE A PAGINA.
   A regra de superficie do Figma troca o fill do `Content` do kit por
   surface-container-highest quando o botao esta DENTRO DE UM BLOCO — e o caso
   do "Copiar" no Cupom e do "Entrar no canal" no CTA. O "Carregar mais" fica
   direto sobre a pagina (surface), entao mantem o fill do kit. Medido nos tres
   botoes: secondary-container aqui, surface-container-highest nos outros dois;
   o rotulo e on-secondary-container nos tres. */
.kd-botao-tonal-pagina {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
}

/* ===========================================================================
   PÁGINA DE PRODUTO (Figma, telas 60842:71 / 60842:27409 / 60842:28231)

   Tudo aqui foi medido no Figma em 24/09/2026, com a densidade daquele dia.
   O Figma desenha três larguras — 1440, 768 e 390 — e as duas trocas de layout
   ficam em pontos de quebra que o desenho NÃO define:

     600   o que a página já usa em todo o resto (card, margem, grade)
     1200  a partir daí o Topo do produto fica lado a lado e a comparação e o
           histórico viram duas colunas

   O 1200 é escolha de código, como o `auto-fill` da grade foi no lote 10: o
   Topo Desktop precisa de 520 de imagem mais 800 de informações, e abaixo de
   1200 as duas colunas ficariam estreitas demais. Está no relatório.
   =========================================================================== */

/* --- Breadcrumb (Figma 60838:335) ---------------------------------------- */
/* Padding 16 em cima e embaixo nas três larguras, gap Space 50 (4).
   O mobile não é o desktop encolhido: ele mostra só o nível anterior, com a
   seta para trás. Os dois vêm no HTML e o CSS escolhe. */
/* O INVOLUCRO E FLEX, e nao um bloco. Medido em 25/09/2026, no `topo` da
   Categoria a 390: o desenho pede 52 de altura (20 de texto + 16 de padding em
   cima e embaixo) e o codigo dava 55. A causa e o `.kd-breadcrumb-voltar`, que
   e `inline-flex`: num bloco ele vira conteudo de LINHA e se apoia na linha de
   base, e o espaco do descendente da fonte entra na altura da linha. Os 3 px
   nao apareciam antes porque a unica tela com breadcrumb a 390 ate aqui era a
   de Produto, onde nada depende da altura dele. Com o involucro em `flex` o
   filho vira item de flex, sai da linha de base, e a altura volta aos 52 nas
   tres larguras. */
.kd-breadcrumb {
  display: flex;
  align-items: center;
  padding-top: var(--md-sys-measurement-space200);      /* 16 */
  padding-bottom: var(--md-sys-measurement-space200);
}

/* QUEM TEM BREADCRUMB NAO PAGA O PADDING DUAS VEZES (lote 24, etapa 0).
   Medido no Figma nas tres larguras: a folga entre o Header e o primeiro
   texto e 16 em toda pagina; o que muda e quem a paga. Sem breadcrumb (Home,
   Busca, Cupons, 404) o frame `conteudo` tem paddingTop 16; COM breadcrumb
   ele tem 0, e os 16 vem do padding de cima do proprio breadcrumb.

   A Categoria e a Loja ja zeravam o seu desde os lotes 21 e 22; faltava a
   pagina de Produto, que somava 16 + 16 = 32. Medido antes: 32 no 1440 e no
   768. */
.kd-produto { padding-top: 0; }

.kd-breadcrumb-trilha {
  display: none;
  margin: 0;
  padding: 0;
  list-style: none;
  align-items: center;
  gap: var(--md-sys-measurement-space50);               /* 4 */
  flex-wrap: wrap;
}

.kd-breadcrumb-item {
  display: inline-flex;
  align-items: center;
  gap: var(--md-sys-measurement-space50);
}

.kd-breadcrumb-link,
.kd-breadcrumb-voltar { color: var(--md-sys-color-on-surface-variant); }
.kd-breadcrumb-atual  { color: var(--md-sys-color-on-surface); }

.kd-breadcrumb-voltar {
  display: inline-flex;
  align-items: center;
  gap: var(--md-sys-measurement-space50);
}

@media (min-width: 600px) {
  .kd-breadcrumb-trilha  { display: flex; }
  .kd-breadcrumb-voltar  { display: none; }
}

/* --- Topo do produto (Figma 60841:25668) --------------------------------- */
.kd-topo {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);              /* 16 — mobile */
  padding: var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-large-plus); /* 24 */
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
}

/* Caixa da foto: quadrada, canto 8 (Corner/Small), surface-container-lowest,
   e a foto INTEIRA (contain) — a regra de superfície do Figma. O modo claro
   fixo vem da classe `kd-modo-claro` no HTML. */
/* A CAIXA DA FOTO NÃO É QUADRADA — medido no Figma em 24/09/2026:
     1440  520 × 544
      768  672 × 326   (largura toda da coluna, altura fixa)
      390  326 × 326   (a largura coincide com a altura; não é proporção)
   Era `aspect-ratio: 1`, e por isso a altura seguia a largura: em 1199 a foto
   ficava 1103 × 1103, uma faixa de mil pixels de altura. A altura é fixa. */
.kd-topo-imagem {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: var(--kd-topo-imagem-alt-movel);              /* 326 */
  border-radius: var(--md-sys-shape-corner-small);      /* 8 */
  background: var(--md-sys-color-surface-container-lowest);
  overflow: hidden;
}

.kd-topo-imagem img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.kd-topo-imagem-reserva {
  width: var(--md-sys-measurement-space400);            /* 32 */
  height: var(--md-sys-measurement-space400);
  color: var(--md-sys-color-on-surface-variant);
}

.kd-topo-informacoes {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space300);              /* 24 */
  min-width: 0;
}

.kd-topo-identificacao {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);              /* 8 */
}

.kd-topo-loja {
  display: inline-flex;
  align-items: center;
  gap: var(--md-sys-measurement-space50);               /* 4 */
  color: var(--md-sys-color-on-surface-variant);
}

/* title/large no mobile, headline/small no desktop — medido. */
.kd-topo-titulo {
  margin: 0;
  color: var(--md-sys-color-on-surface);
  font-family: var(--md-sys-typescale-title-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-title-large-size);
  line-height: var(--md-sys-typescale-title-large-line-height);
  letter-spacing: var(--md-sys-typescale-title-large-tracking);
  font-weight: var(--md-sys-typescale-title-large-weight);
}

/* Linha do cupom: código + botão, gap 8. O código é um CAMPO (o visitante
   seleciona e copia), então segue a regra de superfície: dentro de bloco
   (surface-container-low) o campo é surface-container-high. */
.kd-topo-cupom {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);              /* 8 */
}

.kd-topo-cupom-codigo {
  flex: 1 1 auto;
  min-width: 0;
  height: var(--kd-cupom-codigo-altura);                /* 40 */
  padding: 0 var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-small);      /* 8 */
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  border: none;
  text-overflow: ellipsis;
}

.kd-topo-cupom-codigo:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* O texto obrigatorio do cupom no Topo do produto (lei 15). No Figma ele e
   irmao do frame do cupom dentro de `informacoes`, e nao filho dele: por isso
   pega a largura toda da coluna e fica a 24 do codigo, nao a 8. Nunca corta,
   como as outras duas linhas de texto obrigatorio. */
.kd-topo-texto-loja {
  margin: 0;
  color: var(--md-sys-color-on-surface-variant);
  overflow-wrap: anywhere;
}

/* Botões empilhados em largura total no mobile; em linha no desktop. */
.kd-topo-acoes {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);
}

.kd-topo-acoes > .kd-botao { width: 100%; }

.kd-topo-detalhes {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);              /* 8 */
}

.kd-topo-detalhe {
  display: inline-flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);
  color: var(--md-sys-color-on-surface-variant);
}

/* "Comparar com mais N lojas" é um link para a comparação, que fica logo
   abaixo. No Figma o sublinhado está SÓ nessa parte — o ", a partir de R$ X"
   que vem depois é continuação da frase, não do link. E a cor é a mesma dos
   outros detalhes: a linha é igual às de cima, sem cor de link. */
.kd-topo-comparar {
  color: inherit;
  text-decoration: underline;
  cursor: pointer;
}

/* --- Compartilhar --------------------------------------------------------
   MEDIDO NO FIGMA em 24/09/2026 (frame `compartilhar` do Topo do produto, igual
   no 1440 e no 390): 264×48, gap Space 200 (16) entre o rótulo e os botões.
     rótulo   "Compartilhar", body/medium
     botões   três de 48×48 com gap 8; a superfície pintada é 40×40, canto
              full, secondary-container, ícone 24 em on-secondary-container.
   Os 48 são área de toque, como no seletor de período: 40 de altura mais 4 de
   margem em cima e embaixo. */
.kd-topo-compartilhar {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space200);              /* 16 */
  flex-wrap: wrap;
}

.kd-topo-compartilhar-rotulo { color: var(--md-sys-color-on-surface-variant); }

.kd-topo-compartilhar-botoes {
  display: flex;
  gap: var(--md-sys-measurement-space100);              /* 8 */
}

/* O fundo mora no `::before`, que tem os 40 pintados — no elemento ele viraria
   um circulo de 48. A margem saiu: os 48 agora sao do proprio elemento. */
.kd-topo-compartilhar-botoes > .kd-botao-icone {
  color: var(--md-sys-color-on-secondary-container);
}

.kd-topo-compartilhar-botoes > .kd-botao-icone::before {
  background: var(--md-sys-color-secondary-container);
}

@media (min-width: 1200px) {
  /* Desktop: imagem 520 à esquerda, informações à direita, gap 24.
     A imagem não encolhe; as informações tomam o resto. */
  .kd-topo {
    flex-direction: row;
    gap: var(--md-sys-measurement-space300);            /* 24 */
  }

  /* A FOTO ESTICA NA ALTURA DA LINHA, COM MÍNIMO DE 520.
     Medido no Figma em 24/09/2026, nas três variantes Desktop: o frame `imagem`
     é largura FIXED 520 e altura FILL com `minHeight: 520` e `layoutAlign:
     STRETCH`. A altura do bloco é sempre `max(520, altura das informações) + 32`:

       sem cupom   informações 472 → perde para o mínimo → foto 520, bloco 552
       com cupom   informações 544 → ganha              → foto 544, bloco 576

     O código fixava 520×544 sempre, e a foto ficava 24 px alta demais no estado
     sem cupom. `align-self: stretch` + `min-height` é a mesma regra em CSS: o
     mínimo empurra a linha quando a coluna é mais curta, e o stretch acompanha
     quando ela é mais alta. */
  .kd-topo-imagem {
    flex: none;
    width: var(--kd-topo-imagem-desktop);               /* 520 */
    height: auto;
    align-self: stretch;
    min-height: var(--kd-topo-imagem-desktop);          /* 520 */
  }

  .kd-topo-informacoes {
    flex: 1 1 auto;
    padding: var(--md-sys-measurement-space300) var(--md-sys-measurement-space300)
             var(--md-sys-measurement-space300) 0;
  }

  .kd-topo-titulo {
    font-family: var(--md-sys-typescale-headline-small-font), system-ui, sans-serif;
    font-size: var(--md-sys-typescale-headline-small-size);
    line-height: var(--md-sys-typescale-headline-small-line-height);
    letter-spacing: var(--md-sys-typescale-headline-small-tracking);
    font-weight: var(--md-sys-typescale-headline-small-weight);
  }

  .kd-topo-acoes { flex-direction: row; }
  .kd-topo-acoes > .kd-botao { width: auto; }

  /* A linha do cupom tem a largura dos botões (392 no Figma), não a da coluna
     inteira: ela pertence ao bloco de ação, não ao texto. */
  .kd-topo-cupom { max-width: var(--kd-topo-cupom-largura); }
}

/* --- Comparação e Histórico lado a lado ---------------------------------- */
/* Até 1199 os dois ficam empilhados, na ordem do Figma de 768 e 390.
   De 1200 em diante viram duas colunas com a MESMA ALTURA: a comparação toma o
   espaço que sobra e o histórico fica com 560, que é o que o Figma desenha
   (`historico` é HUG na horizontal, `comparacao` é FILL). */
.kd-comparacao-historico {
  display: grid;
  gap: var(--kd-secao);
}

.kd-coluna-comparacao,
.kd-coluna-historico {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);              /* 16 */
  min-width: 0;
}

@media (min-width: 1200px) {
  .kd-comparacao-historico {
    grid-template-columns: minmax(0, 1fr) var(--kd-historico-largura);  /* 560 */
    gap: var(--md-sys-measurement-space300);            /* 24 */
    align-items: stretch;
  }

  /* O invólucro da troca parcial precisa esticar junto, senão o histórico não
     alcança a altura da lista de lojas. */
  .kd-coluna-historico > .kd-troca { flex: 1 1 auto; display: flex; }
  .kd-coluna-historico > .kd-troca > .kd-historico { flex: 1 1 auto; }
}

/* --- Lista de lojas ------------------------------------------------------ */
/* Linhas com altura FIXA que não estica: quando a coluna do histórico é mais
   alta, o espaço sobra embaixo da lista em vez de inchar as linhas. É a regra
   escrita na seção "Histórico × lista de lojas" do documento. */
.kd-lista-lojas {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--md-sys-measurement-space100);              /* 8 */
}

/* --- Linha de loja (Figma 60826:242) ------------------------------------- */
.kd-loja {
  display: flex;
  flex-direction: column;
  flex: none;
  gap: var(--md-sys-measurement-space150);              /* 12 — mobile */
  padding: var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-large);      /* 16 */
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
  position: relative;
  min-width: 0;
}

/* Hover: state layer on-surface sobre a linha inteira, mesmo canto. */
.kd-loja::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--md-sys-color-on-surface);
  opacity: 0;
  pointer-events: none;
}

.kd-loja:hover::after { opacity: var(--md-sys-state-hover-state-layer-opacity); }

.kd-loja:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* Círculo do logo: 40, Corner/Full, surface-container-lowest, iniciais
   centradas. O modo claro fixo vem da classe no HTML. */
.kd-loja-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--kd-cupom-logo);                          /* 40 */
  height: var(--kd-cupom-logo);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
}

.kd-loja-info {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space25);               /* 2 */
  flex: 1 1 auto;
  min-width: 0;
}

.kd-loja-linha-1 {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);              /* 8 */
  min-width: 0;
}

.kd-loja-nome {
  color: var(--md-sys-color-on-surface);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kd-loja-linha-2 {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space50);               /* 4 */
  color: var(--md-sys-color-on-surface-variant);
  min-width: 0;
}

.kd-loja-detalhe {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kd-loja-preco {
  color: var(--md-sys-color-on-surface);
  white-space: nowrap;
}

.kd-loja-acao { flex: none; }

/* Mobile: logo e info na primeira linha; preço e botão na segunda, com o preço
   à esquerda e o botão à direita (space-between), como o Figma mostra. */
.kd-loja > .kd-loja-logo,
.kd-loja > .kd-loja-info { }

/* O CORTE É EM 600, NÃO EM 1200. Medido no Figma em 24/09/2026, na altura da
   `lista-lojas` das três telas:
     1440  792 × 432  = 5 linhas de 80 + 4 gaps de 8
      768  704 × 432  = 5 linhas de 80   <-- também em uma linha só
      390  358 × 692  = 5 linhas de 132 + 4 gaps de 8
   Ou seja, a linha só empilha no 390. Estava empilhando já a partir de 1199, o
   que engordava a comparação do 768 em 260 px. O corte de 600 é o mesmo que a
   margem e o espaço entre seções já usam. */
@media (max-width: 599.98px) {
  .kd-loja {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      "logo  info"
      "preco acao";
    align-items: center;
    column-gap: var(--md-sys-measurement-space200);     /* 16 */
    row-gap: var(--md-sys-measurement-space150);        /* 12 */
  }

  .kd-loja-logo  { grid-area: logo; }
  .kd-loja-info  { grid-area: info; }
  .kd-loja-preco { grid-area: preco; }
  .kd-loja-acao  { grid-area: acao; justify-self: end; }
}

@media (min-width: 600px) {
  .kd-loja {
    flex-direction: row;
    align-items: center;
    gap: var(--md-sys-measurement-space200);            /* 16 */
    height: var(--kd-loja-altura);                      /* 80 */
  }
}

/* --- Histórico de preço (Figma 60827:608) -------------------------------- */
.kd-historico {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);              /* 16 */
  padding: var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-large-plus); /* 24 */
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
  min-width: 0;
}

/* O gap na linha é 16, mas o da QUEBRA é 12 — `itemSpacing` 16 e
   `counterAxisSpacing` 12 no Figma. No 390 o seletor desce para a segunda
   linha e o cabeçalho fica com 102 (42 + 12 + 48); com 16 nos dois sentidos
   dava 106, e o card inteiro saía 4 px mais alto que o desenho. */
.kd-historico-cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--md-sys-measurement-space150) var(--md-sys-measurement-space200);  /* 12 / 16 */
  flex-wrap: wrap;
}

.kd-historico-titulos {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space25);               /* 2 */
}

.kd-historico-titulo    { color: var(--md-sys-color-on-surface); }
.kd-historico-subtitulo { color: var(--md-sys-color-on-surface-variant); }

/* No 1440 a seção já tem o título "Histórico de preço" ao lado de "Compare em
   N lojas", e o card mostra só o subtítulo — medido nas seis telas. */
@media (min-width: 1200px) {
  .kd-historico-titulo { display: none; }
}
@media (max-width: 1199.98px) {
  .kd-coluna-historico > .kd-secao-titulo { display: none; }
}

/* Seletor de período: pílula em TODOS os segmentos, Corner/Full, gap 8,
   altura 40 — ajustado pelo Matheus no Figma, não mexer.
   Selecionado = secondary / on-secondary; não selecionado =
   surface-container-highest, a mesma regra de estado selecionado do projeto. */
.kd-periodo {
  display: flex;
  gap: var(--md-sys-measurement-space100);              /* 8 */
}

/* Os TRÊS SEGMENTOS TÊM A MESMA LARGURA. Medido no Figma: o seletor é 295 × 48
   com segmentos de 93 × 40 e gap 8 (93 × 3 + 8 × 2 = 295), nas três telas.
   Deixar cada um com a largura do próprio texto dava 79 no "30 dias" e 261 no
   conjunto — os segmentos ficavam desiguais, que é o contrário do que um
   seletor segmentado do M3 desenha. É `min-width` e não `width` porque o rótulo
   é conteúdo: "180 dias" já ocupa quase os 93, e um rótulo maior no futuro
   deve empurrar, não vazar. */
.kd-periodo-item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  min-width: var(--kd-periodo-item);                    /* 93 */
  min-height: var(--kd-botao-altura);                   /* 40 */
  margin-block: var(--md-sys-measurement-space50);      /* 4 + 4 = 48 de área */
  padding: var(--md-sys-measurement-space125) var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
  white-space: nowrap;
  cursor: pointer;
  position: relative;
}

.kd-periodo-item-atual {
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

.kd-periodo-item::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--md-sys-color-on-surface);
  opacity: 0;
  pointer-events: none;
}

.kd-periodo-item:hover::after { opacity: var(--md-sys-state-hover-state-layer-opacity); }

.kd-periodo-item:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* Gráfico: eixo y à esquerda com largura própria, coluna do desenho tomando o
   resto. `flex: 1 1 auto` com `min-height: 200` é o que faz o gráfico crescer
   quando a lista de lojas é mais alta, sem nunca ficar abaixo de 200. */
/* ALTURA EXATA ABAIXO DE 1200, e não só um piso. O SVG tem `viewBox` de
   1000×200 com `preserveAspectRatio="none"`; sem altura definida na cadeia ele
   assume a proporção 5:1, e aí a largura manda na altura. Medido em
   24/09/2026: num viewport de 1199 o gráfico ia a 232 (1039 ÷ 5 + 24 do eixo
   x), fora da regra 200/206. O Figma desenha 200 no 768 e no 390.
   De 1200 em diante a altura volta a ser automática: ali a coluna do histórico
   estica até a altura da lista de lojas e o gráfico cresce junto, dos 200 aos
   206 que o Figma mostra com cinco lojas. */
.kd-grafico {
  display: flex;
  gap: var(--md-sys-measurement-space150);              /* 12 */
  flex: 1 1 auto;
  height: var(--kd-grafico-altura);                     /* 200 */
  min-height: var(--kd-grafico-altura);
}

@media (min-width: 1200px) {
  .kd-grafico { height: auto; }
}

/* O Figma desenha esta coluna com 52 fixo e rótulos sem centavos ("R$ 2.400").
   Aqui é `min-width`: 52 comporta os quatro dígitos do desenho, mas um produto
   de cinco dígitos ("R$ 12.999") precisa de mais, e cortar o preço seria pior
   do que empurrar o gráfico alguns pixels. */
.kd-grafico-eixo-y {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex: none;
  min-width: var(--kd-grafico-eixo-y);                  /* 52 */
  /* O padding inferior reserva a faixa do eixo x, para o último rótulo do eixo
     y ficar na altura da última linha de grade. */
  padding-bottom: var(--kd-grafico-eixo-x);             /* 24 */
  color: var(--md-sys-color-on-surface-variant);
  text-align: right;
}

.kd-grafico-coluna {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);              /* 8 */
  flex: 1 1 auto;
  min-width: 0;
}

.kd-grafico-area { flex: 1 1 auto; min-height: 0; }

.kd-grafico-svg {
  display: block;
  width: 100%;
  height: 100%;
}

.kd-grafico-grade {
  stroke: var(--md-sys-color-outline-variant);
  stroke-width: 1;
}

.kd-grafico-linha {
  fill: none;
  stroke: var(--md-sys-color-on-surface);
  stroke-width: 2;
  /* O traço não deve engordar quando o SVG estica na horizontal. */
  vector-effect: non-scaling-stroke;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.kd-grafico-atual { fill: var(--md-sys-color-primary); }

.kd-grafico-eixo-x {
  display: flex;
  justify-content: space-between;
  flex: none;
  color: var(--md-sys-color-on-surface-variant);
}

/* Veredito (Figma 60876:709): caixa de conteúdo dentro de bloco, então
   surface-container-lowest. Canto 8 e altura mínima 60 — a altura é o que
   impede o gráfico de mudar de tamanho quando o veredito troca. */
.kd-veredito {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space150);              /* 12 */
  min-height: var(--kd-veredito-altura);                /* 60 */
  padding: var(--md-sys-measurement-space150);
  border-radius: var(--md-sys-shape-corner-small);      /* 8 */
  background: var(--md-sys-color-surface-container-lowest);
  flex: none;
}

.kd-veredito .kd-icone { flex: none; color: var(--md-sys-color-on-surface); }

/* O único ícone em primary das três variantes: "menor preço da história" é a
   única que é uma notícia. Medido no Figma. */
.kd-veredito-destaque .kd-icone { color: var(--md-sys-color-primary); }

.kd-veredito-textos {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.kd-veredito-frase { color: var(--md-sys-color-on-surface); }
.kd-veredito-apoio { color: var(--md-sys-color-on-surface-variant); }

.kd-historico-resumo {
  display: flex;
  gap: var(--md-sys-measurement-space200);              /* 16 */
  flex: none;
}

.kd-historico-stat {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space25);               /* 2 */
  flex: 1 1 0;
  min-width: 0;
}

.kd-historico-stat-rotulo { color: var(--md-sys-color-on-surface-variant); }
.kd-historico-stat-valor  { color: var(--md-sys-color-on-surface); }

/* --- Cupons da página de produto ----------------------------------------- */
/* Empilhados em largura total até 1199; três colunas iguais no desktop, com a
   mesma altura (regra de padding: blocos lado a lado sempre com a mesma
   altura). O Cupom tem largura fixa no carrossel da Home; aqui ele preenche a
   coluna, então a largura é sobrescrita. */
.kd-lista-cupons {
  display: grid;
  gap: var(--md-sys-measurement-space200);              /* 16 */
}

.kd-lista-cupons > .kd-cupom { width: 100%; }

@media (min-width: 1200px) {
  .kd-lista-cupons { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* --- Ofertas parecidas ---------------------------------------------------- */
/* Carrossel até a borda da tela abaixo de 1200, com o primeiro card na margem
   da página — a mesma técnica dos carrosséis da Home. De 1200 em diante vira
   uma grade de cinco cards dentro da margem, como o Figma desenha no 1440. */
.kd-parecidas-lista {
  display: flex;
  gap: var(--md-sys-measurement-space200);              /* 16 */
  padding-left: var(--kd-margem);
  padding-right: var(--kd-margem);

  /* O `.kd-rolagem-borda` puxa a margem direita para fora com
     `margin-right: calc(var(--kd-margem) * -1)`, porque na Home ele mora DENTRO
     de um `.kd-conteudo` e esse negativo cancela o padding do pai. Aqui a lista
     está fora do invólucro de margem — de propósito, para o carrossel ir até a
     borda —, então não há padding para cancelar e o negativo vira 32 px de
     estouro: a página inteira ganhava rolagem horizontal (medido em 24/09/2026,
     `scrollWidth` 1472 num viewport de 1440, em todas as larguras).

     A MARGEM DA ESQUERDA SAI PELO MESMO MOTIVO, e essa e correcao do lote 19.2:
     o `.kd-rolagem-borda` ganhou um par `margin-left: -4` / `padding-left: 4`
     para o anel de foco do primeiro item nao ser cortado, e os dois so se
     anulam juntos. Esta regra reescreve o `padding-left` logo acima — e a
     margem negativa ficava sozinha. Medido em 24/09/2026: a lista comecava em
     x = -4 e o primeiro card em 28, com a margem da pagina em 32. */
  margin-inline: 0;
}

.kd-parecidas-lista > .kd-card {
  width: var(--kd-card-grade-largura);                  /* 240 */
  flex: none;
}

/* "OFERTAS RELACIONADAS" CONTINUA CARROSSEL EM TODA LARGURA (lote 23).
   Ate o lote 22 ela virava uma GRADE de 5 colunas a partir de 1200, e os cards
   do sexto em diante sumiam — o desenho antigo mostrava cinco. Medido em
   25/09/2026 na tela de Produto 1440: sao **6 cards de 186,67, FIXED**, com gap
   16, ou seja o mesmo carrossel das outras larguras, com o mesmo card dos
   outros carrosseis. Nao ha grade, e nao ha card escondido. */
@media (min-width: 1200px) {
  .kd-parecidas {
    width: 100%;
    max-width: var(--kd-largura-conteudo);
    margin: 0 auto;
  }
}

/* --- O bloco final: "Mais opções" e os canais ----------------------------
   MEDIDO NO FIGMA em 24/09/2026. Abaixo de 1200 as duas últimas seções não
   ficam no mesmo invólucro do corpo: são um bloco próprio (`conteudo-final`)
   com espaçamento maior que o das outras seções.

     espaço                    1440   768    390
     parecidas → mais opções     40    96     80
     mais opções → canais        40    48     40

   No 768 o `conteudo-final` tem padding 48 e gap 48; os 96 são o padding de
   baixo das parecidas (48) mais o de cima do bloco (48). No 390 os mesmos
   números com Space 500 (40). No 1440 tudo está num invólucro só e o espaço é
   o de sempre.

   Aqui as seções são irmãs de um flex com `gap: var(--kd-secao)`, então o
   extra entra como margem de cima: o valor do Figma menos o gap que já existe.
   O corte fica em 1200 e em 600, os mesmos do resto da página. */
@media (max-width: 1199px) {
  .kd-produto > .kd-secao-mais-opcoes {
    margin-top: var(--md-sys-measurement-space700);     /* 96 − 40 = 56 */
  }

  .kd-produto > .kd-secao-canais {
    margin-top: var(--md-sys-measurement-space100);     /* 48 − 40 =  8 */
  }
}

@media (max-width: 599px) {
  .kd-produto > .kd-secao-mais-opcoes {
    margin-top: var(--md-sys-measurement-space600);     /* 80 − 32 = 48 */
  }

  .kd-produto > .kd-secao-canais {
    margin-top: var(--md-sys-measurement-space100);     /* 40 − 32 =  8 */
  }
}

/* --- Mais opções --------------------------------------------------------- */
/* Chips em pílula, quebrando em várias linhas, gap Space 100 nos dois sentidos
   — o mesmo estilo das Categorias da Home. */
.kd-mais-opcoes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--md-sys-measurement-space100);              /* 8 */
}

/* --- Botão filled (Figma: Button, Content em primary) -------------------- */
/* O tonal já existe desde o lote 11; o filled entra agora, com a página de
   produto. Mesma pílula de 40 dentro de 48 de área de toque. */
.kd-botao-primario {
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}

/* =========================================================================
   PAINEL (lote 17)

   Tudo medido no Figma em 24/09/2026, página "Descontos · Painel" e os
   componentes da seção Painel. O painel divide com o site os tokens, a
   tipografia, os botões, o sprite e o kd.js — o que muda é o arranjo.

   O PONTO DE QUEBRA É 1024, e não o 1200 do site.
   O Figma desenha só 1440 e 390; entre os dois é escolha de código, como o
   1200 da página de produto. Aqui a conta é outra: o trilho come 96 fixos e a
   tabela precisa de 1280 para as colunas 628/140/140/140/160/72 caberem sem
   apertar. Abaixo de 1024 sobrariam menos de 930 para a tabela, e ela viraria
   rolagem de qualquer jeito — então é ali que a casca troca para a Barra de
   baixo, que é o desenho de 390. Entre 1024 e 1440 o trilho fica e a tabela
   rola quando precisa. Está no relatório.
   ========================================================================= */

/* --- Invólucro: trilho e conteúdo lado a lado ---------------------------- */
.kd-painel {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--md-sys-color-surface);
  color: var(--md-sys-color-on-surface);
}

/* Todo espaco do painel vem de `gap`, medido no Figma. A margem que o
   navegador da de brinde a titulo e paragrafo some aqui, senao ela se soma ao
   gap e nenhuma distancia bate com o desenho.

   ATE O LOTE 18.1 A LISTA ERA SO `h1, p`, e estava certa: nao havia `h2` no
   painel. O lote 19 trouxe o titulo de secao do formulario, que e `h2`, e a
   margem de 18,26 px do navegador voltou por ali — medido em 24/09/2026: o
   frame do titulo da secao saiu com 89 de altura onde o Figma tem 52, e com 65
   onde ele tem 28. Os niveis que ainda nao existem entram junto: quando um
   `h3` nascer, ele ja nasce sem margem, e nao com um desalinhamento para
   alguem descobrir. */
.kd-painel h1,
.kd-painel h2,
.kd-painel h3,
.kd-painel h4,
.kd-painel p { margin: 0; }

/* --- Trilho (1440) -------------------------------------------------------
   96 de largura, altura da tela, SEM fundo — medido: o frame do trilho não tem
   preenchimento nenhum, ele fica sobre a `surface` da página.
   `sticky` porque a lista rola e o trilho não pode subir junto. */
.kd-trilho {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: none;
  gap: var(--md-sys-measurement-space300);              /* 24 */
  width: var(--kd-trilho-largura);                      /* 96 */
  padding-block: var(--md-sys-measurement-space200);    /* 16 */
  position: sticky;
  top: 0;
  align-self: flex-start;
  max-height: 100vh;
  max-height: 100dvh;
  overflow-y: auto;
}

.kd-trilho-itens {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);               /* 4 */
  width: 100%;
}

/* --- Item do painel (Figma 60938:1076) -----------------------------------
   O indicador é uma PASTILHA de 56x32 no meio do item, não o fundo da linha
   inteira: por isso ele é um elemento próprio dentro do link. */
.kd-nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--md-sys-measurement-space50);               /* 4 */
  padding-block: var(--md-sys-measurement-space75);     /* 6 */
  color: var(--md-sys-color-on-surface-variant);
  text-decoration: none;
  cursor: pointer;
}

.kd-nav-item-trilho { width: 100%; }
.kd-nav-item-barra  { flex: 1 1 0; min-width: 0; }

.kd-nav-indicador {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--kd-nav-indicador-largura);               /* 56 */
  height: var(--kd-nav-indicador-altura);               /* 32 */
  border-radius: var(--md-sys-shape-corner-large);      /* 16 */
}

/* O rotulo nao pode vazar o item: no Figma ele e FILL na largura do item, com
   truncagem desligada — ou seja, quebra em duas linhas em vez de transbordar.
   "Configuracoes" com 12px passa dos 96 do trilho. */
.kd-nav-rotulo {
  width: 100%;
  text-align: center;
  overflow-wrap: anywhere;
}

/* O ANEL DE FOCO FICA NA PASTILHA, E NAO NO ITEM INTEIRO (lote 19.1).
   -------------------------------------------------------------------------
   O `.kd-nav-item` tem 96x64 e NAO PINTA NADA: quem se ve e a pastilha de
   56x32, canto 16 — e no item atual e ela que recebe o `secondary`. O anel
   estava no item, e isso dava dois problemas medidos em 24/09/2026:

     1. um retangulo RETO de 96x64 num projeto onde todo anel segue a forma do
        controle ("pilula na pilula, 8 no campo, 24 no card");
     2. ele nao cabia. O item tem exatamente a largura do trilho, e o trilho e
        `overflow-y: auto` — o que obriga o `overflow-x` a virar `auto` tambem —
        entao os 4 px do anel eram cortados dos dois lados: aparecia so a linha
        de cima e a de baixo. E, mesmo sem o corte, o lado esquerdo cairia em
        x = -4, FORA DA JANELA, porque o item encosta na borda da tela.

   Na pastilha os dois somem de uma vez: ela tem 20 px de folga de cada lado
   dentro do trilho (11 na Barra de baixo) e canto 16, que e a forma que se ve.
   E o que o M3 faz no Navigation rail.

   O `outline: none` no item tem `:focus-visible` (0,2,0) para vencer a regra
   geral `a:focus-visible` (0,1,1) la de cima — a mesma conta da Busca e do
   Campo de texto. */
.kd-nav-item:focus-visible { outline: none; }

.kd-nav-item:focus-visible > .kd-nav-indicador {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

.kd-nav-item-atual > .kd-nav-indicador {
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

.kd-nav-item-atual > .kd-nav-rotulo { color: var(--md-sys-color-secondary); }

/* --- Barra de baixo (390) ------------------------------------------------
   390x80, surface-container, padding 8 em cima e embaixo, presa embaixo. */
.kd-barra-nav {
  display: none;
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 30;
  height: var(--kd-barra-nav-altura);                   /* 80 */
  padding-block: var(--md-sys-measurement-space100);    /* 8 */
  background: var(--md-sys-color-surface-container);
}

/* --- Conteúdo ------------------------------------------------------------ */
.kd-painel-conteudo {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--kd-painel-secao);                          /* 48 */
  padding: var(--md-sys-measurement-space400) var(--md-sys-measurement-space400)
           var(--kd-painel-secao) var(--md-sys-measurement-space400);
  /* 1280 de area util mais os 32 de padding de cada lado. Sem `margin: auto`,
     de proposito: o documento manda alinhar A ESQUERDA, colado no trilho — o
     contrario do site, que centra. Abaixo de 1024 o padding cai para 16 e a
     conta mudaria, mas ali a janela e menor que o limite e ele nunca pega. */
  max-width: calc(var(--kd-painel-largura) + var(--md-sys-measurement-space400) * 2);
}

.kd-painel-topo {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space300);              /* 24 */
}

.kd-painel-titulo {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);               /* 4 */
}

.kd-painel-data { color: var(--md-sys-color-on-surface-variant); }

/* --- Alternador de tema e Conta do painel -------------------------------- */
.kd-conta-tema {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--md-sys-measurement-space200);              /* 16 */
}

.kd-tema-item {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--kd-tema-item);                           /* 32 */
  height: var(--kd-tema-item);
  border-radius: var(--md-sys-shape-corner-full);
  color: var(--md-sys-color-on-surface-variant);
  cursor: pointer;
}

.kd-tema-item[aria-pressed="true"] {
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

.kd-conta {
  display: flex;
  align-items: center;
  flex: none;
  gap: var(--md-sys-measurement-space50);               /* 4 */
  /* 0 à direita: o botão de 40 já dá o respiro (medido). */
  padding-left: var(--md-sys-measurement-space200);     /* 16 */
  height: var(--kd-botao-altura);                       /* 40 */
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest);
}

.kd-conta-nome { color: var(--md-sys-color-on-surface); white-space: nowrap; }
.kd-conta-sair { display: flex; }

/* --- Folha "Mais" (390) --------------------------------------------------
   Cantos 28 só em cima (superfície modal do M3), alça 32x4 em `outline`, sem
   sombra. O scrim é o mesmo do drawer do site: Schemes/Scrim a 32%. */
/* O scrim do site fica em z-index 10, abaixo do drawer (11). No painel ele
   precisa cobrir TAMBEM a barra de baixo, que esta em 30 — no Figma a folha e o
   scrim cobrem a barra inteira. Por isso este fica entre a barra (30) e a folha
   (50). */
.kd-scrim-painel { z-index: 40; }

.kd-folha {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  padding: 0 var(--md-sys-measurement-space200) var(--md-sys-measurement-space300);
  border-start-start-radius: var(--kd-folha-canto);     /* 28 */
  border-start-end-radius: var(--kd-folha-canto);
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
}

.kd-folha-alca {
  flex: none;
  width: var(--kd-folha-alca-largura);                  /* 32 */
  height: var(--kd-folha-alca-altura);                  /* 4 */
  margin: var(--md-sys-measurement-space200) auto;      /* 16 em cima e embaixo */
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-outline);
}

.kd-folha-conteudo {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space300);              /* 24 */
}

/* Duas linhas de três, gap 4 entre as linhas e 0 dentro delas (medido).

   O ITEM NÃO FICA CENTRADO NA COLUNA. Medido: a coluna é FILL (119,33) mas o
   item dentro dela é 96 FIXO e ancorado no começo — sobram 23,33 à direita de
   cada um. Centrar ficaria 12 px mais à direita em cada item; a lei 1 diz que
   quem manda é o desenho. */
.kd-folha-destinos {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  row-gap: var(--md-sys-measurement-space50);           /* 4 */
  column-gap: 0;
  justify-items: start;
}

.kd-folha-destinos > .kd-nav-item {
  width: var(--kd-trilho-largura);                      /* 96 */
}

/* Na folha a linha da conta é SPACE_BETWEEN, com a Conta à esquerda e o
   Alternador à direita — o contrário do 1440, onde as duas ficam encostadas à
   direita. O HTML é o mesmo; quem inverte é o CSS. */
.kd-folha .kd-conta-tema {
  flex-direction: row-reverse;
  justify-content: space-between;
}

/* --- Login --------------------------------------------------------------- */
.kd-login {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  padding: var(--md-sys-measurement-space200);
}

.kd-login-bloco {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space300);              /* 24 */
  width: 100%;
  max-width: var(--kd-login-largura);                   /* 400 */
  padding: var(--md-sys-measurement-space400);          /* 32 */
  border-radius: var(--md-sys-shape-corner-large-plus); /* 24 */
  background: var(--md-sys-color-surface-container-low);
}

.kd-login-cabecalho {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);               /* 4 */
}

.kd-login-titulo { color: var(--md-sys-color-on-surface); }
.kd-login-apoio  { color: var(--md-sys-color-on-surface-variant); }

/* O Figma não desenha lugar para erro nem para o aviso de saída. O texto fica
   no ponto mais próximo do desenho e SEM cor de erro inventada: on-surface, o
   mesmo token do título. Quem garante que é anunciado é o `role`. */
.kd-login-aviso { color: var(--md-sys-color-on-surface); }

.kd-login-form {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space300);              /* 24 */
}

.kd-login-campos {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);              /* 16 */
}

.kd-login-entrar { width: 100%; }

/* --- Campo de texto (Figma 60940:1368) -----------------------------------
   48 de altura, canto 8, surface-container-high, sem linha e sem borda.
   O rótulo mora em cima (16 de altura, a 4 do topo) e o valor embaixo (24 de
   altura, a 20 do topo) — as duas posições do desenho. */
.kd-campo {
  position: relative;
  display: flex;
  align-items: center;
  height: var(--kd-campo-altura);                       /* 48 */
  padding-inline: var(--md-sys-measurement-space200);   /* 16 */
  border-radius: var(--md-sys-shape-corner-small);      /* 8 */
  background: var(--md-sys-color-surface-container-high);
}

/* O PADDING DA DIREITA SO SAI QUANDO HA MESMO UM BOTAO ALI (correcao do 19.2).
   A classe `kd-campo-com-icone` marca tres casos diferentes: o campo de
   escolha, que tem a seta; o campo calculado ("Preco final"), que NAO tem icone
   nenhum; e o campo de senha do Login, cujo olho desaparece sem JavaScript.
   Zerar o padding nos tres deixava o texto encostado na borda da caixa nos dois
   ultimos — medido em 24/09/2026, com e sem JavaScript.
   O `:not([hidden])` e o que cobre o caminho sem JavaScript: o olho nasce
   `hidden` e so o `kd.js` o mostra. */
.kd-campo:has(> .kd-botao-icone:not([hidden])) { padding-right: 0; }

.kd-campo-rotulo {
  position: absolute;
  top: var(--md-sys-measurement-space50);               /* 4 */
  left: var(--md-sys-measurement-space200);
  color: var(--md-sys-color-on-surface-variant);
  pointer-events: none;
}

/* `padding: 0` E NAO `font: inherit`, E A TROCA E UMA CORRECAO (lote 19).
   O `<input>` ja vem com a classe `kd-body-large`, que e o que o Figma manda
   (valor 16/24, `M3/body/large`). O `font: inherit` escrito aqui no lote 17
   vinha DEPOIS dela no arquivo e vencia por propriedade: o campo herdava o
   `body`, que e body/medium 14/20. Medido no navegador em 24/09/2026 — o campo
   do login e os dos formularios saiam os dois com 14px. Sem o `font`, a classe
   volta a valer.
   O `padding` entra no lugar porque era o `font: inherit` que, junto do resto,
   escondia o `1px 2px` que o navegador poe em todo `<input>`: com 24 de
   line-height e 2 de padding o valor media 26 e descia 1px do desenho. */
.kd-campo-valor {
  width: 100%;
  min-width: 0;
  margin-top: var(--md-sys-measurement-space200);       /* leva o valor aos 20 do desenho */
  padding: 0;
  background: none;
  border: none;
  color: var(--md-sys-color-on-surface);
}

.kd-campo-olho {
  flex: none;
  color: var(--md-sys-color-on-surface-variant);
}

/* OS DOIS ESTADOS DO OLHO (lote 20.2).
   Senha escondida: `visibility`, "Mostrar senha". Senha à mostra:
   `visibility_off`, "Ocultar senha". Quem manda é o `aria-pressed`, que já
   existia no botão e é o que o leitor de tela anuncia — assim o estado não é
   dito duas vezes, uma para a máquina e outra para o CSS.

   A mesma mecânica do "Copiar" do cupom (linhas 2336-2342), com os dois ícones
   no HTML e o CSS escondendo um. */
.kd-olho-mostrar,
.kd-olho-ocultar { display: inline-flex; flex: none; }

.kd-olho-ocultar { display: none; }

.kd-campo-olho[aria-pressed="true"] .kd-olho-mostrar { display: none; }
.kd-campo-olho[aria-pressed="true"] .kd-olho-ocultar { display: inline-flex; }

/* UM ANEL SO, EM VOLTA DO CAMPO INTEIRO (lote 19.1, visto pelo Matheus).
   -------------------------------------------------------------------------
   Ao clicar no campo "Nome" aparecia um retangulo RETO em volta do `<input>`,
   dentro da caixa arredondada do campo. Medido em 24/09/2026: o anel saia em
   `input.kd-campo-valor` com 656x24 e canto 0, enquanto a caixa tem 688x48 e
   canto 8.

   A CAUSA E A MESMA DA BUSCA DO LOTE 17.1, e a cura tambem: a regra geral
   `input:focus-visible` (0,1,1) la de cima acende o anel em TODO input. Uma
   classe sozinha (0,1,0) nao a vence; `.kd-campo-valor:focus-visible` (0,2,0)
   vence. Com o anel de dentro desligado, quem o mostra e a caixa.

   `:has(:focus-visible)` E NAO `:focus-within`, pelo mesmo motivo do lote 18.1:
   `:focus-within` acende com QUALQUER foco de QUALQUER filho, e o campo de
   escolha tem um botao de seta dentro. `:has(:focus-visible)` repassa a decisao
   ao navegador — e o navegador acende o foco visivel de campo de texto clicado
   com o mouse, que e o que o desenho pede ("clicar no campo tambem mostra o
   anel"). MEDIDO nos dois casos em 24/09/2026: clique no campo comum e clique
   no campo de escolha (`readonly`), `matches(':focus-visible')` = true nos dois.
   O canto do anel e o da caixa (Corner/Small, 8), porque o `outline` segue o
   `border-radius` do elemento em que esta. */
.kd-campo-valor:focus-visible { outline: none; }

/* O `:has` APONTA PARA O VALOR, E NAO PARA QUALQUER FILHO (correcao do 19.2).
   Escrito como `:has(:focus-visible)`, ele acendia tambem quando o foco estava
   no olho da senha — que e um `.kd-botao-icone` dentro do campo e tem anel
   proprio desde o lote 19.2. Medido: Tab ate o olho acendia DOIS aneis, o do
   campo (336x48) e o da pastilha (40x40). E o mesmo defeito que este lote saiu
   cacando, reintroduzido pelo lado de dentro.
   Agora e um de cada vez: o campo acende quando o foco esta no VALOR (ou no
   `<select>` que o substitui sem JavaScript), e o botao de dentro acende
   sozinho quando o foco e dele — assim da para saber onde se esta. */
.kd-campo:has(> .kd-campo-valor:focus-visible),
.kd-campo:has(> .kd-campo-sem-js:focus-visible) {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* --- Início: indicadores ------------------------------------------------- */
.kd-indicadores {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--md-sys-measurement-space300);              /* 24 */
}

.kd-indicador {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);              /* 8 */
  min-height: var(--kd-indicador-altura);               /* 128 */
  padding: var(--md-sys-measurement-space200);          /* 16 */
  border-radius: var(--kd-indicador-canto);             /* 20 */
  background: var(--md-sys-color-surface-container-low);
}

.kd-indicador-rotulo { color: var(--md-sys-color-on-surface-variant); }
.kd-indicador-numero { color: var(--md-sys-color-on-surface); }

/* Sem cor de alta nem de queda: medido, as duas variantes do Figma ficam em
   on-surface-variant. O sentido está no sinal e no ícone. */
.kd-indicador-variacao {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);              /* 8 */
  margin-top: auto;
  color: var(--md-sys-color-on-surface-variant);
}

/* --- Início: gráfico de cliques ------------------------------------------ */
.kd-grafico-cliques {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);              /* 16 */
  padding: var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-large-plus); /* 24 */
  background: var(--md-sys-color-surface-container-low);
}

.kd-grafico-cliques-cabecalho {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);               /* 4 */
}

.kd-grafico-cliques-titulo { color: var(--md-sys-color-on-surface); }
.kd-grafico-cliques-total  { color: var(--md-sys-color-on-surface-variant); }

.kd-grafico-cliques-area {
  display: flex;
  gap: var(--md-sys-measurement-space150);              /* 12 */
  height: var(--kd-grafico-altura);                     /* 200 */
}

.kd-grafico-cliques-eixo-y {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-end;
  flex: none;
  min-width: var(--kd-grafico-eixo-y-painel);           /* 22 */
  color: var(--md-sys-color-on-surface-variant);
}

.kd-grafico-cliques-barras {
  display: flex;
  align-items: flex-end;
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
  gap: var(--md-sys-measurement-space100);              /* 8 */
}

.kd-grafico-barra {
  flex: 1 1 0;
  min-width: 0;
  border-start-start-radius: var(--md-sys-shape-corner-extra-small);  /* 4 */
  border-start-end-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--md-sys-color-on-surface-variant);
}

.kd-grafico-barra-hoje { background: var(--md-sys-color-primary); }

/* As datas ficam sob a ÁREA DAS BARRAS, não sob o eixo y: o recuo é a largura
   do eixo mais o gap, para a primeira data cair no começo da primeira barra. */
.kd-grafico-cliques-eixo-x {
  display: flex;
  justify-content: space-between;
  margin-left: calc(var(--kd-grafico-eixo-y-painel) + var(--md-sys-measurement-space150));
  color: var(--md-sys-color-on-surface-variant);
}

/* --- Listas: topo, contador e filtros ------------------------------------ */
.kd-lista-topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--md-sys-measurement-space200);
  flex-wrap: wrap;
}

.kd-lista-titulo {
  flex-direction: row;
  align-items: center;
  gap: var(--md-sys-measurement-space150);              /* 12, medido */
}

/* Pílula do contador: 32 de altura, canto full, highest. */
.kd-contador {
  display: inline-flex;
  align-items: center;
  flex: none;
  height: var(--kd-chip-altura);                        /* 32 */
  padding-inline: var(--md-sys-measurement-space150);   /* 12 */
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
}

.kd-filtros {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);              /* 8 */
  flex-wrap: wrap;
}

/* --- Chip de filtro (Figma 60888:916) ------------------------------------
   Pílula de 32, canto full, em surface-container-highest; ligada vira
   secondary com o texto em on-secondary. Até o lote 17 havia aqui um
   `<select>` transparente esticado por cima do chip, e o menu que abria era o
   nativo do navegador. Agora o chip é um `<button>` e o menu é o do Figma —
   o `<select>` ficou só no `<noscript>`, no fim deste bloco.

   O invólucro existe para o menu ter de quem se pendurar: ele é
   `position: relative`, e o menu sai dele em `absolute`. Sem ele o menu se
   penduraria no chip, e o chip já usa `relative` para o `<select>` do
   `<noscript>`. */
.kd-filtro { position: relative; }

.kd-chip-filtro {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);              /* 8 */
  height: var(--kd-chip-altura);                        /* 32 */
  /* MEDIDO NO FIGMA (60888:916), e a regra nao e "16 a esquerda e 8 a
     direita": e 16 DO LADO QUE ENCOSTA EM TEXTO e 8 DO LADO QUE ENCOSTA EM
     ICONE. Desligado tem texto a esquerda e a seta a direita, entao 16/8.
     Ligado ganha o check a esquerda, e vira 8/8 — a regra logo abaixo.
     Confere nas somas do desenho: 16+28+8+18+8 = 78 (Desligado, Menu=Sim) e
     8+18+8+28+8+18+8 = 96 (Ligado, Menu=Sim). */
  padding-left: var(--md-sys-measurement-space200);     /* 16 */
  padding-right: var(--md-sys-measurement-space100);    /* 8 */
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
  cursor: pointer;
}

/* Medido no component set `Chip de filtro` (60888:916): Estado=Ligado usa
   `Schemes/Secondary` com o texto em `Schemes/On Secondary` — nao
   secondary-container. E a mesma regra de Estado selecionado do projeto. */
.kd-chip-filtro-ligado {
  padding-left: var(--md-sys-measurement-space100);     /* 8: agora encosta em icone */
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

/* O CHECK ESTA SEMPRE NO HTML e quem o mostra e esta regra.
   Criar e destruir o elemento daria o mesmo desenho, mas abriria espaco para o
   estado visual e o `aria-checked` andarem separados. Aqui e um atributo so. */
.kd-chip-filtro-check { display: none; }
.kd-chip-filtro-ligado > .kd-chip-filtro-check { display: block; }

/* A TRUNCAGEM E UMA REDE, NAO O COMPORTAMENTO NORMAL, e vale dizer.
   O chip tem largura de conteudo (`inline-flex`, sem largura declarada), e o
   Figma tambem o desenha assim — HUG nas seis variantes, sem largura maxima.
   Entao com "Mercado Livre" ele simplesmente cresce, e estas tres linhas nao
   fazem nada. Elas existem para o caso em que a fila de filtros do painel
   ficar apertada e o flex encolher o chip: sem elas o texto vazaria a pilula
   em vez de cortar. Que o Figma nao defina largura maxima esta no relatorio.
   (O chip do SITE saiu no lote 30, com a Barra de filtros; o do painel fica.) */
.kd-chip-filtro-texto {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Menu de filtro (Figma 61077:2049) -----------------------------------

   O MENU QUE O `<select>` NAO DESENHAVA. Ate o lote 17 o chip abria a lista
   nativa do navegador; agora abre isto.

   Medido em 24/09/2026: 208 de largura, `surface-container-high`, canto 16
   (Corner/Large), padding 4 (Space 50) em cima e embaixo e 0 nos lados, SEM
   sombra e SEM borda — os dois conferidos como arrays vazios no arquivo.

   UMA DIVERGENCIA CONSCIENTE, e ela esta no relatorio: no arquivo cada item
   carrega um fill proprio `surface-container-low`, herdado do componente do
   kit, e com isso o `surface-container-high` do menu so apareceria em duas
   faixas de 4 px em cima e embaixo. No escuro isso vira um corpo escuro com
   duas listras claras. A descricao gravada no proprio componente diz "Fundo
   surface-container-high", a regra de superficie do projeto diz que superficie
   sobreposta e high, e o Navigation Drawer — o outro menu do projeto — ja e
   high com os itens sem fundo. Tres sinais contra um resto de kit: o item fica
   transparente. Uma linha inverte isso, se o Matheus preferir o literal.

   SEM SOMBRA E SEM BORDA, e o menu ainda assim se separa do fundo: ele e
   `surface-container-high` sobre `surface` (a pagina) ou sobre
   `surface-container-low` (um bloco). E a mesma separacao por empilhamento que
   a lei 6 usa no projeto inteiro. */
.kd-menu-filtro {
  /* A DISTANCIA ATE O CONTROLE MORA NUMA VARIAVEL, e nao no valor de cada
     regra: ela vale para o lado de baixo e para o de cima, e cada menu a
     reescreve com a sua. Escrita direto, quem decidia qual valia era a
     especificidade — e o `:not(.kd-menu-acoes)` da regra de cima, acrescentado
     logo depois, virou 0,3,0 e passou a ganhar do 0,2,0 do campo de escolha:
     o menu dele abria a 8 do campo em vez de 4. Medido em 24/09/2026. */
  --kd-menu-afastamento: var(--md-sys-measurement-space100);   /* 8 */

  position: absolute;
  top: calc(100% + var(--kd-menu-afastamento));
  left: 0;
  /* 5: na frente da tabela e da paginacao, atras do scrim do site (10), do
     drawer (11) e do scrim e da folha do painel (40 e 50). O menu nao e
     superficie modal — ele nao cobre a tela, so passa por cima do conteudo. */
  z-index: 5;
  width: var(--kd-menu-filtro-largura);                  /* 208 */
  overflow-y: auto;
  padding-block: var(--md-sys-measurement-space50);      /* 4 */
  border-radius: var(--md-sys-shape-corner-large);       /* 16 */
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
  /* A barra de rolagem some como a de todo componente do projeto — ver "Nada
     desenhado pelo navegador".

     A ALTURA MAXIMA NAO ESTA AQUI DE PROPOSITO. O Figma desenha o menu com
     tres itens e nao diz o que acontece com trinta lojas. Em vez de escolher
     um numero (`60vh`, `400px`, "oito itens" — todos igualmente inventados),
     quem define o limite e o `kd.js`, com o espaco que SOBRA abaixo do chip na
     janela de verdade. E medida, nao escolha. */
  scrollbar-width: none;
  -ms-overflow-style: none;

  /* A SOMBRA FLUTUANTE DOS TRES MENUS (lote 26). Ate aqui o comentario acima
     dizia "sem sombra e sem borda", e era o que o Figma mostrava; em
     25/09/2026 os tres ganharam o estilo `KD/Sombra flutuante` — Menu de
     filtro 61077:2049, Menu de exibicao 61139:2225 e Menu de acoes
     61082:86515. A borda continua nao existindo.

     Uma regra so para os tres: `.kd-menu-filtro` e a classe base, e os
     outros dois a levam junto no HTML. */
  box-shadow: var(--kd-sombra-flutuante);
}

.kd-menu-filtro::-webkit-scrollbar { display: none; }

/* ABRE PARA CIMA QUANDO NAO CABE EMBAIXO (lote 19.2).
   Quem decide o lado e o `kd.js`, que mede o espaco de cada um; aqui fica so o
   desenho de cada lado. `bottom: calc(100% + 8)` poe a base do menu 8 acima do
   TOPO do involucro — que e o topo do chip no Menu de filtro e o topo do campo
   no campo de escolha, porque em ambos o involucro comeca no controle. Por isso
   uma regra serve para os dois, mudando so a distancia.
   O MENU DE ACOES FICA DE FORA PELO SELETOR, e nao por acordo. Ele tambem tem a
   classe `kd-menu-filtro`, entao esta regra o alcancava; o que o segurava era um
   `if` do outro lado, no `kd.js`. Alcancando, o `bottom` daqui entraria junto
   com o `top` que o JavaScript escreve, e um elemento posicionado com os dois
   perde a altura propria — foi assim que o menu saiu com 8 px de altura ao abrir
   para cima, medido em 24/09/2026. O `:not` fecha a porta aqui tambem.
   `:not(.kd-menu-ofertas)` SAIU NO LOTE 30, com os chips da Barra de filtros.
   Os menus `fixo` que sobraram — o de exibicao e o de lojas — nunca recebem
   `kd-menu-acima`: o `criarMenu` so a poe em menu que NAO e `fixo`, justamente
   por causa do `top` mais `bottom`. */
.kd-menu-filtro.kd-menu-acima:not(.kd-menu-acoes) {
  top: auto;
  bottom: calc(100% + var(--kd-menu-afastamento));
}

/* Se o menu passar da borda direita da tela, ele alinha pela direita do chip.
   Quem poe esta classe e o `kd.js`, depois de medir — o CSS sozinho nao tem
   como saber se passou. */
.kd-menu-filtro-direita {
  left: auto;
  right: 0;
}

/* O item tem 48 por fora; por dentro, a caixa de 44 recuada 4 nos lados e 2 em
   cima e embaixo. E a caixa que leva o canto e o fundo do marcado — por isso
   ela existe como elemento, e nao como padding do botao. */
.kd-menu-item {
  display: block;
  width: 100%;
  padding: var(--md-sys-measurement-space25) var(--md-sys-measurement-space50);  /* 2 4 */
  cursor: pointer;
  text-align: left;
}

.kd-menu-item-caixa {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);               /* 8 */
  min-height: var(--kd-menu-item-altura);                /* 44 */
  padding-inline: var(--md-sys-measurement-space150);    /* 12 */
  border-radius: var(--md-sys-shape-corner-extra-small); /* 4 */
  color: var(--md-sys-color-on-surface);
}

.kd-menu-item-texto {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Marcado: fundo secondary, texto e check em on-secondary, canto 12.
   O kit pinta o selecionado em tertiary-container (o amarelo), que neste
   projeto e exclusivo do desconto — a instancia do Figma ja sobrescreve para
   secondary, que e a regra de Estado selecionado. */
.kd-menu-item[aria-checked="true"] > .kd-menu-item-caixa {
  border-radius: var(--md-sys-shape-corner-medium);      /* 12 */
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

/* O check fica no FIM do item (medido: `Trailing element`), e so no marcado. */
.kd-menu-item-check { display: none; }
.kd-menu-item[aria-checked="true"] .kd-menu-item-check { display: block; }

/* Hover: state layer on-surface sobre a caixa, com o mesmo canto dela — o
   mesmo `::after` que o Card de oferta e os chips usam. */
.kd-menu-item-caixa::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--md-sys-color-on-surface);
  opacity: 0;
  pointer-events: none;
}

.kd-menu-item:hover > .kd-menu-item-caixa::after {
  opacity: var(--md-sys-state-hover-state-layer-opacity);
}

/* NO ITEM MARCADO A CAMADA TROCA DE COR. O fundo dele e `secondary`, e uma
   camada de `on-surface` por cima some: no tema escuro os dois sao branco, e o
   item marcado era o unico do menu que nao respondia ao passar do mouse.
   `on-secondary` e a cor que contrasta com `secondary` — a mesma logica que o
   M3 usa quando pinta a state layer de um componente preenchido. */
.kd-menu-item[aria-checked="true"] > .kd-menu-item-caixa::after {
  background: var(--md-sys-color-on-secondary);
}

/* O anel de foco fica na CAIXA e nao no botao. O botao tem 48 e a caixa 44,
   centrada: sobram 2 em cima e 2 embaixo, que e exatamente o `outline-offset`
   do projeto. O anel encosta na borda do item, sem passar dela — em volta dos
   48 do botao ele avancaria 2 sobre o vizinho de cima e 2 sobre o de baixo.
   O `outline-offset: 2px` e o mesmo de todos os outros doze aneis do arquivo:
   um so valor de foco no projeto inteiro. */
.kd-menu-item:focus-visible { outline: none; }

.kd-menu-item:focus-visible > .kd-menu-item-caixa {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* --- O caminho sem JavaScript --------------------------------------------
   O `<select>` esticado por cima do chip, invisivel, dentro do `<noscript>`.
   So existe quando nao ha JavaScript; com JavaScript o navegador nem chega a
   montar este HTML. */
.kd-chip-filtro-menu {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  font: inherit;
}

.kd-chip-filtro:has(.kd-chip-filtro-menu:focus-visible) {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* Os destinos que so aparecem sem JavaScript (ver parciais/navegacao.php).
   O `<noscript>` ja garante que isto so existe quando nao ha JavaScript. */
.kd-nav-sem-js {
  display: flex;
  flex-wrap: wrap;
  gap: var(--md-sys-measurement-space100);              /* 8 */
  padding: var(--md-sys-measurement-space200);
}

/* --- Tabela do painel (Figma 60943:62130) -------------------------------- */
.kd-tabela-bloco {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);              /* 16 até a paginação */
}

/* A janela que recorta e rola. O canto 24 fica AQUI, e a tabela por dentro tem
   canto 0 — medido no Mobile do Figma.

   O `position: relative` NÃO É DECORAÇÃO: sem ele a PÁGINA INTEIRA rolava de
   lado. Medido em 24/09/2026, num viewport de 390: a tabela tem 872 de largura
   mínima, e o Chrome propagava esses 872 para a área rolável do documento
   mesmo com `overflow-x: auto` aqui — dava para arrastar a tela 482 px para a
   direita, para o vazio. É um comportamento próprio de `<table>`: `overflow`
   sozinho recorta a PINTURA (a captura provava que a tabela era cortada
   certinho) mas não continha o transbordo no cálculo da rolagem do documento.
   Testadas as alternativas: `overflow-x: clip`, `display: flow-root`,
   `isolation: isolate` e `overflow: hidden` no pai não resolvem; `contain:
   paint` resolve mas cria contexto de empilhamento e bloco contêiner sem
   necessidade. `position: relative` é o menor remédio que cura, e a tabela
   continua rolando por dentro normalmente. */
.kd-tabela-rolagem {
  position: relative;
  overflow-x: auto;
  border-radius: var(--md-sys-shape-corner-large-plus); /* 24 */
}

.kd-tabela {
  width: 100%;
  min-width: var(--kd-tabela-minima);                   /* 872 — o mínimo do Mobile */
  border-collapse: collapse;
  table-layout: fixed;
}

/* Larguras do Figma. A primeira coluna nao entra: com `table-layout: fixed`
   ela fica com o que sobra, e em 1280 isso da os 628 do desenho. */
.kd-col-140   { width: var(--kd-col-140); }             /* 140 */
.kd-col-160   { width: var(--kd-col-160); }             /* 160 */
.kd-col-acoes { width: var(--kd-tabela-acoes); }        /* 72  */

/* O CABECALHO TEM PADDING 16; AS LINHAS TEM 4/16. Medido no Figma: as celulas
   do cabecalho sao 16/16/16/16 e as das linhas 4/16/4/16. Com 16 em cima e
   embaixo a linha crescia para 72 (16 + miniatura de 40 + 16) e nunca fechava
   os 56 do desenho; com 4, a miniatura de 40 cabe (4+40+4 = 48) e o texto de
   duas linhas tambem (4+36+4 = 44), e a altura de 56 e quem manda. */
.kd-tabela th,
.kd-tabela td {
  padding: var(--md-sys-measurement-space200);          /* 16 */
  vertical-align: middle;
}

.kd-tabela tbody td {
  padding-block: var(--md-sys-measurement-space50);     /* 4 */
}

/* Medido: a coluna principal alinha a ESQUERDA e as quatro de dados a DIREITA,
   no cabecalho e nas linhas. Numero encostado a direita e o que deixa as casas
   alinhadas de uma linha para a outra. */
.kd-tabela-principal { text-align: left; }
.kd-tabela-dado      { text-align: right; }

.kd-tabela thead th {
  height: var(--kd-tabela-cabecalho);                   /* 52 */
  background: var(--md-sys-color-surface-container-high);
  color: var(--md-sys-color-on-surface);
}

.kd-tabela tbody tr { height: var(--kd-tabela-linha); } /* 56 */

/* Zebra: ímpar low, par container. É a ÚNICA separação — sem divisória, sem
   borda, sem sombra (medido: não existe nenhuma no Figma). */
.kd-tabela tbody tr:nth-child(odd)  > td { background: var(--md-sys-color-surface-container-low); }
.kd-tabela tbody tr:nth-child(even) > td { background: var(--md-sys-color-surface-container); }

/* Hover: state layer de on-surface na opacidade do documento (8%), misturada
   ao fundo da própria linha. `color-mix` evita o retângulo absoluto que o
   Figma usa e que numa `<table>` não teria onde se ancorar. */
.kd-tabela tbody tr:hover > td {
  background-image: linear-gradient(
    color-mix(in srgb, var(--md-sys-color-on-surface)
              calc(var(--md-sys-state-hover-state-layer-opacity) * 100%), transparent) 0 0);
}

.kd-tabela-dado { color: var(--md-sys-color-on-surface); }
.kd-tabela thead .kd-tabela-acoes { text-align: right; }

/* Padding assimétrico à esquerda, medido no Figma: 4/16/4/4 nas linhas.
   `.kd-tabela td` tem especificidade 0,1,1 e esta regra tinha 0,1,0 — o
   `padding-left: 4` NUNCA valeu, e a celula ficava com 16 dos dois lados. Com o
   `.kd-botao-icone` em 48 desde o lote 19.2, o botao passou a transbordar 4 px
   de cada lado de uma caixa util de 40. Medido em 24/09/2026; a especificidade
   agora empata pelo `.kd-tabela` na frente, que e o mesmo remedio que o arquivo
   usa no `.kd-busca-campo:focus-visible` e no `.kd-nav-item:focus-visible`. */
.kd-tabela .kd-tabela-acoes {
  width: var(--kd-tabela-acoes);                        /* 72 */
  padding-left: var(--md-sys-measurement-space50);      /* 4 */
}

.kd-tabela-celula-principal {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space150);              /* 12 */
  min-width: 0;
}

/* A cor de reserva aparece enquanto a imagem carrega e quando ela falha —
   medido: `Schemes/Surface Container Lowest`, canto 8, com recorte. */
.kd-tabela-miniatura {
  flex: none;
  width: var(--kd-botao-altura);                        /* 40 */
  height: var(--kd-botao-altura);
  border-radius: var(--md-sys-shape-corner-small);      /* 8 */
  background: var(--md-sys-color-surface-container-lowest);
  object-fit: contain;
  overflow: hidden;
}

/* Logo da loja Pequeno: círculo de 24 em surface-container-lowest, só iniciais. */
.kd-tabela-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--md-sys-measurement-space300);            /* 24 */
  height: var(--md-sys-measurement-space300);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
}

.kd-tabela-textos {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.kd-tabela-titulo {
  color: var(--md-sys-color-on-surface);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.kd-tabela-apoio { color: var(--md-sys-color-on-surface-variant); }

/* --- Paginação ----------------------------------------------------------- */
.kd-paginacao {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--md-sys-measurement-space100);              /* 8 */
}

.kd-paginacao-contagem { color: var(--md-sys-color-on-surface-variant); }

.kd-paginacao-botoes {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);              /* 8 */
}

/* A MARGEM SAIU NO LOTE 19.2. Ela existia para "dar 48 de area" a um botao de
   40 — mas margem nao recebe clique, entao o alvo continuava em 40. Agora os 48
   sao do proprio `.kd-botao-icone`, e a pilula de 40 e desenhada por dentro.
   No 1440 isso faz o "Sair" passar 4 px acima e abaixo da pilula da conta; e o
   que a decisao de 24/09/2026 pede, e o que se ve nao muda. */

.kd-paginacao-botao { color: var(--md-sys-color-on-surface-variant); }

/* Medido: o ícone de sair é on-surface-variant, mais claro que o nome ao lado,
   que é on-surface. */
.kd-conta-sair .kd-botao-icone { color: var(--md-sys-color-on-surface-variant); }

/* A AREA DE 48 PASSA DA PILULA EM VEZ DE ESTICA-LA (lote 19.2).
   No Figma a `Conta do painel` tem 148x40 e o `sair` é o único Icon button do
   projeto com 40 de caixa — os outros têm 48. A decisão de 24/09/2026 dá 48 de
   área a todos, "a área maior pode passar da pílula da conta; o que se vê não
   muda". Sem esta margem a pílula esticava de 148 para 156, que é justamente o
   que se vê. Com ela, o botão ocupa 40 de LAYOUT e 48 de ALVO: sobra 4 para
   cada lado, por cima do padding da pílula e do vão até o nome — e não há
   nenhum outro controle ali para disputar o clique. */
.kd-conta-sair .kd-botao-icone {
  margin-inline: calc(var(--md-sys-measurement-space50) * -1);   /* -4 */
}

/* Estado Disabled do kit: on-surface a 38%. O Figma não desenha o chevron
   desabilitado NA TABELA (os dois estão Enabled lá); este é o Disabled do
   próprio kit, não um cinza inventado. Está no relatório. */
.kd-paginacao-botao-off {
  color: var(--md-sys-color-on-surface);
  opacity: var(--kd-desabilitado);                      /* 0,38 */
  cursor: default;
}

/* Fim da lista nao responde ao mouse: sem camada de estado. */
.kd-paginacao-botao-off::after { content: none; }

/* =========================================================================
   Painel abaixo de 1024: a casca de 390
   ========================================================================= */
@media (max-width: 1023.98px) {
  .kd-trilho { display: none; }
  .kd-barra-nav { display: flex; }

  .kd-painel-conteudo {
    gap: var(--kd-painel-secao-movel);                  /* 40 */
    padding: var(--md-sys-measurement-space200);
    /* O conteúdo não pode terminar embaixo da barra presa no rodapé. */
    padding-bottom: calc(var(--kd-painel-secao-movel) + var(--kd-barra-nav-altura));
  }

  /* No 390 o Alternador e a Conta NÃO ficam no topo: eles só existem dentro da
     folha "Mais" (medido — zero instâncias no `conteudo` das telas de 390). */
  .kd-painel-conteudo .kd-conta-tema { display: none; }

  .kd-indicadores { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .kd-lista-topo {
    align-items: flex-start;
    flex-direction: column;
    gap: var(--md-sys-measurement-space200);
  }

  .kd-grafico-cliques-barras { gap: var(--md-sys-measurement-space25); }   /* 2 */
}

@media (max-width: 599.98px) {
  .kd-indicador { min-height: var(--kd-indicador-altura-movel); }          /* 148 */
  .kd-indicadores { gap: var(--md-sys-measurement-space150); }             /* 12 */
}

/* ===========================================================================
   FORMULÁRIOS DO PAINEL (lote 19)

   Medido no Figma em 24/09/2026, nas dez telas de formulário (cinco desenhos ×
   1440/390) e nos componentes Campo de texto (60940:1368), Opção com switch
   (60947:1533), Campo de upload (60940:1412), Ações do formulário (60940:1413)
   e Aviso de afiliados (60929:26708).

   NENHUM VALOR SOLTO E NENHUMA BORDA, com uma exceção nomeada: o trilho do
   switch desligado tem stroke de 2 em Schemes/Outline no próprio componente do
   kit. Ela não é invenção do código — é o desenho, e sem ela o switch desligado
   sumiria contra o bloco. Está no relatório.
   =========================================================================== */

/* --- "Novo …" (1440) e Extended FAB (390) --------------------------------
   O MESMO elemento: no 1440 ele é o Button filled ao lado dos chips; abaixo de
   1024 vira o Extended FAB preso no canto. Ver o comentário de painel/lista.php
   para por que não são dois. */
.kd-lista-acoes {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);               /* 8 — o frame `acoes` */
  flex-wrap: wrap;
}

/* O gap entre o `add` e o rótulo vem do tamanho do botão: 4 no XSmall (1440) e
   8 no Extended FAB (390) — os dois medidos. Por isso ele não fica aqui. */

/* --- O formulário --------------------------------------------------------- */
.kd-form {
  display: flex;
  flex-direction: column;
  gap: var(--kd-painel-secao);                           /* 48 — Space 600 */
  width: var(--kd-form-largura);                         /* 720 no 1440 */
  max-width: 100%;
}

.kd-form-secao {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);               /* 16 */
}

.kd-form-secao-titulo {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);                /* 4 */
}

.kd-form-secao-apoio { color: var(--md-sys-color-on-surface-variant); }

/* O bloco: surface-container-low, canto 24 (Corner/Large-plus), padding 16 e
   gap 16. Sem sombra e sem borda — ele se separa da página por empilhamento,
   como todo o resto do projeto (lei 6). */
.kd-form-bloco {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);               /* 16 */
  padding: var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-large-plus);  /* 24 */
  background: var(--md-sys-color-surface-container-low);
}

/* Dois campos de metade lado a lado (Preço/Preço antigo, Categoria/Marca…).
   `min-width: 0` é o que deixa o campo encolher dentro do flex — sem ele o
   conteúdo do `input` empurra a coluna e o par estoura o bloco. */
.kd-form-linha {
  display: flex;
  gap: var(--md-sys-measurement-space200);               /* 16 */
}

.kd-form-linha > * {
  flex: 1 1 0;
  min-width: 0;
}

.kd-form-acoes {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--md-sys-measurement-space100);               /* 8 */
}

/* Cancelar é o Button - text: sem fundo, rótulo em on-surface. */
.kd-botao-texto { color: var(--md-sys-color-on-surface); }

/* Salvar Disabled (lei 12, Figma 61084:14874): o Content vira o state layer de
   on-surface a 10% e o rótulo perde a cor própria. Mesma receita do botão do
   Cupom expirado — o Figma usa a mesma variável nos dois. */
.kd-botao-primario:disabled {
  background: color-mix(in srgb,
              var(--md-sys-color-on-surface) var(--kd-estado-apagado-opacidade),
              var(--md-sys-color-surface));
  color: var(--md-sys-color-on-surface);
  cursor: default;
}

.kd-botao-primario:disabled::after { content: none; }

/* --- Campo de texto (Figma 60940:1368) -----------------------------------
   48 de altura: 4 de folga, rótulo de 16 (body/small), valor de 24
   (body/large), 4 de folga. É uma coluna, e é por isso que ele não precisa de
   posicionamento absoluto nenhum.

   A LINHA DE APOIO NÃO É DO COMPONENTE: medido, `Show supporting text` é
   `false` em todos os campos das dez telas. O apoio é irmão do campo, 4 abaixo,
   com padding lateral 16 — que é o que alinha o texto dele com o texto de
   dentro do campo. */
.kd-campo-com-apoio {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);                /* 4 */
}

/* O CAMPO EM SI JA EXISTE DESDE O LOTE 17: `.kd-campo`, `.kd-campo-com-icone`,
   `.kd-campo-rotulo` e `.kd-campo-valor` foram escritos para o Login, e sao o
   MESMO componente do Figma (60940:1368). Repetir as regras aqui daria duas
   descricoes do mesmo desenho para manter em sincronia. O que entra no lote 19
   e so o que o Login nao tinha: a linha de apoio, o estado de erro, o campo
   calculado, a seta do campo de escolha e o `<select>` do `<noscript>`. */

/* O PADDING ABRE LUGAR PARA A SETA, QUE E ABSOLUTA — e a seta so existe no
   campo de escolha. No Login a mesma classe `kd-campo-com-icone` marca o campo
   de senha, mas ali o icone e o `.kd-campo-olho`, que e irmao FLEX: ele ja
   ocupa o lugar dele, e o padding somava 48 de vazio depois do texto. Medido em
   24/09/2026 (achado no lote 19.1, nascido no lote 19). O `:has` prende a regra
   ao caso que ela foi escrita para resolver. */
/* O vazio reservado para a seta tem a largura da SETA, que e um Icon button —
   e nao a altura do campo. Os dois valem 48; o nome e que estava trocado. */
.kd-campo:has(> .kd-campo-seta) > .kd-campo-valor { padding-right: var(--kd-botao-icone-area); }

.kd-campo-valor[readonly] { cursor: pointer; }

/* A seta do campo de escolha: 48×48 encostada à direita, `arrow_drop_down` de
   24 em on-surface-variant. Ela é decorativa — quem abre o menu é o campo, e o
   `pointer-events: none` faz o clique atravessar até ele. */
/* Os 48 vem do proprio `.kd-botao-icone` desde o lote 19.2 — antes esta regra
   os escrevia de novo, com o token do CAMPO. */
.kd-campo-seta {
  position: absolute;
  top: 0;
  right: 0;
  color: var(--md-sys-color-on-surface-variant);
  pointer-events: none;
}

/* Campo calculado (Preço final): o Disabled do kit — 38% sobre tudo. */
.kd-campo-desligado { opacity: var(--kd-desabilitado); }             /* 0,38 */
.kd-campo-desligado > .kd-campo-valor { cursor: default; }

.kd-campo-apoio {
  padding-inline: var(--md-sys-measurement-space200);     /* 16 — alinha com o valor */
  color: var(--md-sys-color-on-surface-variant);
}

/* ERRO. O Figma NÃO desenha estado de erro: o component set "Campo de texto" só
   tem as variantes de ícone final (Não / Sim / Escolha), e nenhuma das dez
   telas mostra campo errado. O lote manda pôr o campo em Error e a linha de
   apoio em Schemes/Error — então é isso, e nada além disso: o rótulo e a linha
   de apoio trocam de cor, sem borda inventada (lei 6) e sem ícone que o desenho
   não tem. Está no relatório. */
.kd-campo-erro { color: var(--md-sys-color-error); }
.kd-campo-com-erro > .kd-campo-rotulo { color: var(--md-sys-color-error); }

/* O `select` do `noscript`, para o campo de escolha sem JavaScript: ocupa o
   campo inteiro, invisível — o mesmo caminho do Chip de filtro. */
.kd-campo-sem-js {
  position: absolute;
  inset: 0;
  width: 100%;
  height: var(--kd-campo-altura);
  opacity: 0;
  cursor: pointer;
  font: inherit;
}

/* O anel do `<select>` e o do NAVEGADOR, e nao o do projeto — `select` nao esta
   na regra geral la de cima. Ele nao chega a aparecer, porque o elemento e
   `opacity: 0` e o `outline` some junto com o resto; a linha existe para que
   continue assim se um dia alguem devolver opacidade a este `<select>`. Quem
   mostra o foco e o `.kd-campo` em volta, pelo `:has(:focus-visible)` — medido
   sem JavaScript em 24/09/2026, com Tab de verdade. */
.kd-campo-sem-js:focus-visible { outline: none; }

/* --- Menu do campo de escolha -------------------------------------------
   MESMO DESENHO DO MENU DE FILTRO — é o que o documento manda — então a classe
   `.kd-menu-filtro` vem junto e só o que muda fica aqui: a largura é a do campo
   e a distância é 4, não 8. */
.kd-menu-escolha {
  --kd-menu-afastamento: var(--md-sys-measurement-space50);     /* 4 */

  top: calc(var(--kd-campo-altura) + var(--kd-menu-afastamento));  /* 48 + 4 */
  width: 100%;
}

/* O item de um campo de escolha é `role="option"`, e o marcado usa
   `aria-selected`. O Menu de filtro usa `aria-checked`, e o desenho é o mesmo —
   então as duas formas pintam igual. */
.kd-menu-item[aria-selected="true"] > .kd-menu-item-caixa {
  border-radius: var(--md-sys-shape-corner-medium);      /* 12 */
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

.kd-menu-item[aria-selected="true"] .kd-menu-item-check { display: block; }

.kd-menu-item[aria-selected="true"] > .kd-menu-item-caixa::after {
  background: var(--md-sys-color-on-secondary);
}

/* "Nenhum produto com esse texto." — o Figma não desenha o menu vazio da busca.
   O texto ocupa a caixa de um item, com o mesmo recuo, para não parecer que o
   menu quebrou. Está no relatório. */
.kd-menu-vazio {
  display: block;
  padding: var(--md-sys-measurement-space150) var(--md-sys-measurement-space200);
  color: var(--md-sys-color-on-surface-variant);
}

/* --- Menu de ações da linha (Figma 61082:86515) ---------------------------
   Mesmo desenho do Menu de filtro, sem item marcado, alinhado à DIREITA do
   botão: ele mora na última coluna da tabela, e à esquerda sairia da tela. */
/* ENCOSTADO A DIREITA, e nao centrado. Medido no Figma (`celula-6` da Tabela do
   painel): a celula tem 72 com padding 4/16/4/4 e `primaryAxisAlignItems = MAX`
   — o botao encosta no padding da direita. Centrado, ele ficava 18 da borda em
   vez de 16. So se viu depois que a celula passou a ter os 4 da esquerda que o
   desenho pede (a regra antiga perdia em especificidade). */
.kd-acoes-linha {
  position: relative;
  display: flex;
  justify-content: flex-end;
}

/* PRESO NA JANELA, E NAO NA CELULA (lote 19.1).
   O menu mora numa celula da tabela, e a tabela rola de lado — `overflow-x:
   auto` no `.kd-tabela-rolagem`, o que obriga o eixo y a recortar tambem.
   Medido em 24/09/2026 na ULTIMA linha de /ofertas: o menu abria em y 788..892
   e o recorte terminava em 788. Os tres itens ficavam INTEIROS fora da vista —
   o botao abria um menu que ninguem via.
   Com `fixed` ele sai do recorte. Quem poe `top` e `left` e o `kd.js`, que ja
   media a caixa do botao para calcular a altura maxima; sem JavaScript nao ha
   menu nenhum, entao nao ha o que posicionar. */
.kd-menu-acoes {
  position: fixed;
  top: auto;
  left: auto;
  right: auto;
  width: var(--kd-menu-filtro-largura);                  /* 208 */
}

/* O item de ação é um link ou um botão dentro de um `form`; nos dois casos o
   que se vê é a mesma caixa de 44. O `form` não pode virar linha de layout
   entre o menu e o item. */
.kd-menu-item-form { display: contents; }

/* --- Opção com switch (Figma 60947:1533) ---------------------------------
   Rótulo e apoio à esquerda, trilho de 52×32 à direita, gap 16, altura 48.
   O estado mora num `checkbox` escondido do olho e não da máquina; o trilho e a
   alça são desenho nosso, movidos pelo `:checked` do irmão — sem JavaScript. */
.kd-opcao {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space200);               /* 16 */
  min-height: var(--kd-campo-altura);                    /* 48 */
}

.kd-opcao-textos {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);                /* 4 */
  flex: 1 1 auto;
  min-width: 0;
}

.kd-opcao-rotulo {
  color: var(--md-sys-color-on-surface);
  cursor: pointer;
}

.kd-opcao-apoio { color: var(--md-sys-color-on-surface-variant); }

/* O TRILHO: 52×32, canto full. Desligado é surface-container-highest com o
   traço de 2 em Schemes/Outline (a exceção nomeada lá em cima) e a alça de 16
   encostada à esquerda, 8 de recuo. Ligado é secondary com a alça de 24 à
   direita, 4 de recuo. Tudo medido no componente.

   `box-shadow: inset` e não `border`: a borda mudaria a caixa e o trilho
   deixaria de ter 52×32. O stroke do Figma é INSIDE, que é exatamente isto. */
.kd-switch {
  position: relative;
  display: flex;
  align-items: center;
  flex: none;
  width: var(--kd-switch-largura);                       /* 52 */
  height: var(--kd-switch-altura);                       /* 32 */
  padding-inline: var(--md-sys-measurement-space100);    /* 8 — o desligado */
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest);
  box-shadow: inset 0 0 0 var(--kd-switch-traco) var(--md-sys-color-outline);
  cursor: pointer;
}

.kd-switch-alca {
  display: block;
  width: var(--kd-switch-alca-desligada);                /* 16 */
  height: var(--kd-switch-alca-desligada);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-outline);
}

/* A ÁREA DE TOQUE É 48×48, centrada na ALÇA — medido (`Target`), e não no
   trilho. Ela transborda 8 acima e 8 abaixo, e por isso é um pseudo-elemento:
   crescer o trilho mudaria o desenho. */
.kd-switch::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: var(--kd-campo-altura);                         /* 48 */
  height: var(--kd-campo-altura);
  transform: translateY(-50%);
}

.kd-switch-estado:checked + .kd-switch {
  justify-content: flex-end;
  padding-inline: var(--md-sys-measurement-space50);     /* 4 — o ligado */
  background: var(--md-sys-color-secondary);
  box-shadow: none;
}

.kd-switch-estado:checked + .kd-switch > .kd-switch-alca {
  width: var(--kd-switch-alca-ligada);                   /* 24 */
  height: var(--kd-switch-alca-ligada);
  background: var(--md-sys-color-on-secondary);
}

.kd-switch-estado:checked + .kd-switch::before { left: auto; right: 0; }

/* O ANEL FICA NO TRILHO, E SO NELE. O `<input type="checkbox">` que guarda o
   estado mede 1x1 e vive fora da tela (`.kd-oculto-visual`), mas a regra geral
   `input:focus-visible` acendia um anel nele tambem — dois aneis, um deles
   invisivel de 1x1. Medido em 24/09/2026. O `:focus-visible` na classe (0,2,0)
   vence a regra geral (0,1,1) e apaga o de dentro. */
.kd-switch-estado:focus-visible { outline: none; }

.kd-switch-estado:focus-visible + .kd-switch {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* --- Campo de upload (Figma 60940:1412) ----------------------------------
   Vazio: 192 de altura, coluna centrada, gap 12, com o círculo de 48 e o botão
   tonal. Com imagem: 128, linha que quebra, gap 16, miniatura de 96 e os dois
   botões no fim. Sem borda tracejada — medido, o campo é só fill sólido. */
.kd-upload {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--md-sys-measurement-space150);               /* 12 */
  min-height: var(--kd-upload-vazio);                    /* 192 */
  padding: var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-small);       /* 8 */
  background: var(--md-sys-color-surface-container-high);
  text-align: center;
}

.kd-upload-cheio {
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: var(--md-sys-measurement-space200);               /* 16, nos dois sentidos */
  min-height: var(--kd-upload-com-imagem);               /* 128 */
  text-align: left;
}

.kd-upload-circulo {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--kd-campo-altura);                         /* 48 */
  height: var(--kd-campo-altura);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
}

/* A miniatura: 96 fixos, canto 4, sobre surface-container. A imagem aparece
   INTEIRA, sem corte — é o que o texto da seção promete ("Ela aparece inteira,
   sem corte"), e é o mesmo `contain` das miniaturas da tabela. */
.kd-upload-miniatura {
  flex: none;
  width: var(--kd-upload-miniatura);                     /* 96 */
  height: var(--kd-upload-miniatura);
  border-radius: var(--md-sys-shape-corner-extra-small); /* 4 */
  background: var(--md-sys-color-surface-container);
  object-fit: contain;
}

.kd-upload-textos {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);                /* 4 */
  min-width: 0;
}

.kd-upload-cheio > .kd-upload-textos { flex: 1 1 var(--kd-upload-nome-minima); }

.kd-upload-titulo,
.kd-upload-nome { color: var(--md-sys-color-on-surface); }

/* O nome do arquivo pode ser longo e o Figma não define corte (`textTruncation`
   desligado, `maxLines` nulo): ele quebra, como o desenho deixa quebrar. */
.kd-upload-nome { overflow-wrap: anywhere; }

.kd-upload-medidas { color: var(--md-sys-color-on-surface-variant); }

/* O `label` do arquivo é o botão: o `input type="file"` fica escondido para o
   navegador não desenhar o dele. */
.kd-upload > .kd-botao { flex: none; }

/* Mesmo caso do switch: o `<input type="file">` esta escondido em 1x1 e ganhava
   um anel proprio da regra geral, junto com o da caixa. Medido: dois aneis. */
.kd-upload-arquivo:focus-visible { outline: none; }

.kd-upload:has(.kd-upload-arquivo:focus-visible) {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* O MESMO 40 PINTADO DO "Trocar" AO LADO (lote 19.1).
   Medido no Figma (Campo de upload 60940:1412, Estado=Com imagem): o Icon
   button do `delete` e `Round/Small`, caixa 48x48 com o miolo de 40x40 — igual
   ao tonal "Trocar", que e 75x48 com miolo 75x40. O lote 19 escreveu 48 aqui
   usando `--kd-campo-altura`, um token de CAMPO numa peca de botao, e o
   resultado eram duas caixas de tamanhos diferentes lado a lado.
   Os 40 pintados e os 48 de area vem os dois do `.kd-botao-icone` desde o lote
   19.2 — aqui nao se escreve medida nenhuma, so a cor. */
.kd-upload-tirar {
  flex: none;
  color: var(--md-sys-color-on-surface-variant);
}

/* --- Aviso de afiliados (Figma 60929:26708) -------------------------------
   Canto 16, padding 16, gap 16, ícone `info` de 24 e texto body/large.
   O FILL É surface-container-low, IGUAL AO DO BLOCO que o contém — medido, os
   dois são a mesma cor. Na tela ele não aparece como um retângulo dentro de
   outro: aparece como um ícone e um texto com o recuo certo, que é o que o
   desenho mostra. Está no relatório. */
.kd-aviso-afiliados {
  display: flex;
  align-items: flex-start;
  gap: var(--md-sys-measurement-space200);               /* 16 */
  padding: var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-large);       /* 16 */
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
}

.kd-aviso-afiliados > .kd-icone { flex: none; }

/* ===========================================================================
   Formulários do painel abaixo de 1024: o desenho de 390
   ========================================================================= */
@media (max-width: 1023.98px) {
  /* 358 de largura (`FILL`) e gap 40 entre seções — medido nas cinco telas. */
  .kd-form {
    gap: var(--kd-painel-secao-movel);                    /* 40 */
    width: 100%;
  }

  /* Medido: no 390 o frame `linha` NÃO EXISTE — os campos de metade viram
     filhos diretos do bloco, empilhados. */
  .kd-form-linha { flex-direction: column; }

  /* O EXTENDED FAB. Mesmo elemento do "Novo …" do 1440, outro desenho:
     56 de altura, canto 16 (Corner/Large), padding 16, gap 8, ícone de 24 e
     rótulo em title/medium. Preso no canto de baixo à direita, 16 da margem e
     16 acima da Barra de navegação — medido em Produtos · 390 (60947:66448),
     com `constraints` MAX/MAX.
     SEM SOMBRA: o FAB do M3 tem elevação, e a instância do Figma não tem
     efeito nenhum. É a lei 6 de novo — nada de sombra que o desenho não pede. */
  .kd-novo {
    position: fixed;
    right: var(--kd-margem);                              /* 16 */
    bottom: calc(var(--kd-barra-nav-altura) + var(--md-sys-measurement-space200));
    /* O FAB é o outro desenho do mesmo comando: 56 de altura, gap 8, padding 16
       — e nada do XSmall do 1440 vale aqui. */
    gap: var(--md-sys-measurement-space100);              /* 8 */
    /* 6: na frente da tabela e do menu de ações (5), atrás do drawer (11) e da
       folha do painel (40 e 50). */
    z-index: 6;
    min-height: var(--kd-fab-altura);                     /* 56 */
    margin-block: 0;
    padding: var(--md-sys-measurement-space200);          /* 16 */
    border-radius: var(--md-sys-shape-corner-large);      /* 16 */
    font-family: var(--md-sys-typescale-title-medium-font), system-ui, sans-serif;
    font-size: var(--md-sys-typescale-title-medium-size);
    line-height: var(--md-sys-typescale-title-medium-line-height);
    letter-spacing: var(--md-sys-typescale-title-medium-tracking);
    font-weight: var(--md-sys-typescale-title-medium-weight);
  }

  /* No 1440 o `add` tem 20 (é o Icon do Button); no FAB tem 24. */
  .kd-novo > .kd-icone-20 {
    width: var(--md-sys-measurement-space300);            /* 24 */
    height: var(--md-sys-measurement-space300);
  }

  /* A lista já reserva o rodapé para a Barra; o FAB fica 16 acima dela, então
     a última linha da tabela precisa de mais o tamanho dele para não ficar
     embaixo do botão. */
  .kd-painel-conteudo:has(.kd-novo) {
    padding-bottom: calc(var(--kd-painel-secao-movel) + var(--kd-barra-nav-altura)
                         + var(--kd-fab-altura) + var(--md-sys-measurement-space200));
  }
}


/* ===========================================================================
   O ANEL QUE NAO ACENDE NO TOQUE (lote 20.1)
   ---------------------------------------------------------------------------
   `.kd-sem-anel` e posta pelo `focar()` do kd.js no elemento que recebe foco
   POR SCRIPT logo depois de um toque ou clique, e sai sozinha no `blur` e na
   primeira tecla de navegacao. Ela existe para o SAFARI: o Chrome e o Firefox
   ja obedecem ao `focus({ focusVisible: false })`, e para eles este bloco nunca
   chega a valer. O Safari ignora a opcao, e sem isto a folha "Mais" abria no
   iPhone com o primeiro item cercado de anel, sem ninguem ter tocado numa tecla.

   POR QUE SAO DEZ SELETORES: porque o anel deste projeto e pintado de seis
   jeitos diferentes, e uma classe no elemento FOCADO tem de alcancar os seis.
   Levantados um a um no proprio arquivo, em 25/09/2026:

     no proprio elemento   a regra geral da linha 385 e mais nove de componente
                           (.kd-card, .kd-chip, .kd-botao, .kd-loja, ...)
     num pseudo            .kd-botao-icone:focus-visible::before  (o anel) e
                           ::after (a camada de estado do foco)
     num filho             .kd-nav-item > .kd-nav-indicador
                           .kd-menu-item > .kd-menu-item-caixa
     num irmao             .kd-switch-estado + .kd-switch
     num ancestral         .kd-busca, .kd-campo, .kd-chip-filtro e .kd-upload,
                           todos por `:has()`

   O `:focus` A MAIS NAO E ENFEITE. `.kd-sem-anel:focus-visible` daria 0,2,0 e
   EMPATARIA com `.kd-card:focus-visible`, `.kd-botao:focus-visible` e as outras
   sete regras de componente — empate que so se resolve por quem vem depois no
   arquivo, e isso e uma regra que quebra no dia em que alguem acrescentar CSS
   no fim. Com `:focus:focus-visible` a conta vai a 0,3,0 e ganha de todas sem
   depender de ordem nenhuma. Nao muda o que casa: todo elemento que casa
   `:focus-visible` casa `:focus` — o primeiro e um subconjunto do segundo.
   O mesmo motivo leva a classe do componente junto nos casos de filho, irmao e
   ancestral (0,4,0 contra os 0,3,0 de la). */
.kd-sem-anel:focus:focus-visible,
.kd-sem-anel:focus:focus-visible::before,
.kd-sem-anel:focus:focus-visible::after,
.kd-nav-item.kd-sem-anel:focus-visible > .kd-nav-indicador,
.kd-menu-item.kd-sem-anel:focus-visible > .kd-menu-item-caixa,
.kd-switch-estado.kd-sem-anel:focus-visible + .kd-switch,
.kd-busca:has(.kd-sem-anel:focus-visible),
.kd-campo:has(> .kd-campo-valor.kd-sem-anel:focus-visible),
.kd-campo:has(> .kd-campo-sem-js.kd-sem-anel:focus-visible),
.kd-chip-filtro:has(.kd-chip-filtro-menu.kd-sem-anel:focus-visible),
.kd-upload:has(.kd-upload-arquivo.kd-sem-anel:focus-visible) {
  outline: none;
}

/* A CAMADA DE ESTADO TAMBEM E MARCA DE FOCO. No Icon button o anel mora no
   `::before` e a camada de foco no `::after` (10% de opacidade, lote 19.1).
   Apagar so o anel deixaria o botao "Mais" com uma pastilha acesa depois de
   fechar a folha — o mesmo defeito de outra cor. Fica escrito com a classe do
   componente junto (0,4,1) para ganhar da regra de la (0,2,1) sem depender da
   ordem, e so nele: `::after` em outro elemento pode ser conteudo de verdade. */
.kd-botao-icone.kd-sem-anel:focus-visible::after { opacity: 0; }


/* ===========================================================================
   CATEGORIA E BUSCA (lote 21)
   Figma: telas 60890:8411 / 60896:9827 / 60897:10956 (Categoria) e
          60892:9148 / 60896:10811 / 60897:11754 (Busca)
   Componentes: Chip de filtro 60888:916 (a Barra de filtros 60888:1036 e a
                folha 60888:1037 sairam no lote 30),
          Filtros - Bottom sheet 60888:1037, Estado vazio 60840:566,
          Espaco de anuncio 60827:622 (Formato=In-feed)

   MEDIDO NO FIGMA EM 25/09/2026, nas tres larguras e nos dois temas. Quase
   tudo aqui ja existia: a grade, o menu, o scrim, o
   seletor de ordenacao, o carrossel de borda e o botao tonal vieram do feed da
   Home e do painel. O que este bloco acrescenta e o ARRANJO das duas paginas e
   os tres componentes que o site ainda nao tinha — a barra, o Estado vazio e o
   In-feed.
   =========================================================================== */

/* --- Topo da Categoria ----------------------------------------------------
   Medido: o `topo` tem 160 de altura nas tres larguras, e ele nao tem gap
   proprio — quem separa os tres blocos e o padding de cada um (breadcrumb
   16/16, titulo padding-bottom 16). Por isso aqui e `column` sem `gap`:
   inventar um gap somaria ao padding e o topo passaria dos 160.             */
.kd-categoria-topo {
  display: flex;
  flex-direction: column;
}

/* O `conteudo` da Categoria comeca colado no Header (paddingTop 0 no Figma),
   ao contrario da Home e da Busca, que tem 16. O breadcrumb ja traz os seus
   16 por dentro — somar os dois afastaria o topo em 32. */
.kd-categoria { padding-top: 0; }

.kd-categoria-identificacao {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);            /* 4 */
  padding-bottom: var(--md-sys-measurement-space200);/* 16 */
}

.kd-categoria-titulo,
.kd-pagina-busca-titulo {
  margin: 0;
  color: var(--md-sys-color-on-surface);
}

.kd-categoria-contador,
.kd-pagina-busca-contador {
  margin: 0;
  color: var(--md-sys-color-on-surface-variant);
}

/* As subcategorias somam 1462 no Figma contra 1440 de tela: a fila VAZA em
   toda largura, e rola como as Categorias da Home. O `.kd-rolagem-borda` do
   HTML ja faz a rolagem e a sangria ate a borda; aqui so fica a altura, que o
   desenho fixa em 32 mesmo com a fila vazia. */
.kd-categoria-subs { min-height: var(--kd-chip-altura); }   /* 32 */

/* --- Topo da Busca -------------------------------------------------------- */
.kd-pagina-busca-identificacao {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);            /* 4 */
}

/* --- Bloco de ofertas -----------------------------------------------------
   Barra, grade e "Carregar mais" com 16 entre eles — o mesmo gap do
   `.kd-secao`, repetido aqui porque este bloco e trocado inteiro pela resposta
   parcial e precisa manter o espacamento sozinho, fora da secao.             */
.kd-bloco-ofertas {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);           /* 16 */
}

/* --- Filtros sem JavaScript (lote 30, Etapa 5) ----------------------------
   A BARRA DE FILTROS SAIU DAQUI. No lugar dela ficou este bloco, que e o unico
   CSS proprio do caminho `<noscript>`: uma fila com os dois Campos de texto do
   projeto e o botao "Filtros". Saiu com ela: as duas variantes (Desktop e
   Compacta), a troca em 1200, a sangria ate a borda da tela, o rolavel lateral
   e o `display: none` que escondia o botao "Filtros" acima do ponto de troca.

   ESTE CAMINHO NAO TEM DESENHO NO FIGMA, como o `<noscript>` que a barra
   carregava tambem nao tinha. Entao aqui nao ha forma, cor nem tipografia
   nenhuma: `.kd-campo` e `.kd-botao` ja trazem tudo isso, e o que sobra e o
   arranjo. O gap e o mesmo Space 100 que a barra usava entre os chips.

   QUEBRA EM LINHAS em vez de rolar de lado. A barra rolava porque o desenho a
   desenhava numa linha so; este formulario nao tem desenho para obedecer, e
   rolagem lateral escondida e pior sem JavaScript, onde nao ha seta nem
   arrasto para chegar ao que ficou fora da vista (as setas do lote 25 sao do
   kd.js). `flex: 1 1 auto` deixa os campos usarem a largura que houver e
   descerem para a linha de baixo quando nao couberem — no 390 cada um fica com
   a linha inteira.

   COM JAVASCRIPT ESTE BLOCO NAO EXISTE: o `<noscript>` em volta e
   `display: none` pela folha do proprio navegador, e elemento com
   `display: none` nao entra no `gap` do `.kd-bloco-ofertas`. O espaco em volta
   da Barra de ordenacao e da grade fica igual nos dois caminhos.           */
.kd-filtros-sem-js {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--md-sys-measurement-space100);           /* 8 */
}

.kd-filtros-sem-js > .kd-campo {
  flex: 1 1 auto;
  min-width: 0;
}

/* --- Espaco de anuncio, In-feed (Figma 60827:622) -------------------------
   Uma celula da grade: a largura e a da coluna (256 / 224 / 173) e a altura
   vem do `align-items: stretch` da grade, que iguala a linha pela mais alta —
   e por isso ele acompanha o card sem nenhuma medida escrita. Os 240x392 do
   desenho sao o tamanho do componente, nao uma medida a copiar.              */
.kd-anuncio {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--md-sys-measurement-space25);            /* 2 */
  border-radius: var(--md-sys-shape-corner-large);   /* 16 */
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface-variant);
  text-align: center;
  overflow: hidden;
}

/* --- A faixa de anuncio da Home (Figma `anuncio` 60866:2892, lote 24) -----
   Entre "Melhores descontos agora" e "Melhores ofertas". Ela esta no desenho
   desde sempre e nunca tinha entrado no codigo.

   DOIS LADO A LADO, gap Space 200 (16), cada um com metade do que sobra:
   592 no 1440 ((1200 - 16) / 2) e 344 no 768 ((704 - 16) / 2). A altura e 100
   nas duas larguras, e nao sai de proporcao nenhuma — e medida.

   ABAIXO DE 600 O FIGMA DESENHA UM SO, com o conteudo inteiro (358 no 390) e
   gap 0 no frame, porque nao ha o que separar. Quem some e o SEGUNDO, pelo
   CSS — o mesmo caminho dos banners fixos da Home. Com `display: none` ele
   sai tambem da arvore de acessibilidade, entao quem usa leitor de tela no
   celular ouve um espaco de anuncio, e nao dois.

   A DISTANCIA PARA OS VIZINHOS NAO ESTA AQUI: ela e o gap do `.kd-principal`
   (40 acima de 600, 32 abaixo), que e exatamente o que o frame `conteudo` do
   Figma tem entre as secoes. Por isso esta faixa nao e uma `.kd-secao` — nao
   ha titulo nem gap interno para ela gerenciar.                            */
.kd-anuncio-home {
  display: flex;
  gap: var(--md-sys-measurement-space200);           /* 16 */
}

.kd-anuncio-home > .kd-anuncio {
  flex: 1 1 0;
  min-width: 0;
  height: var(--kd-anuncio-home-altura);             /* 100 */
}

.kd-anuncio-home > .kd-anuncio:nth-child(2) { display: none; }

@media (min-width: 600px) {
  .kd-anuncio-home > .kd-anuncio:nth-child(2) { display: flex; }
}

/* ===========================================================================
   Modo Lista (lote 24)

   O visitante escolhe Grade ou Lista no Menu de exibicao, e a escolha marca o
   <html> com `data-kd-modo="lista"`. A TROCA E SO DE CSS: o HTML do card e o
   mesmo nos dois modos — mesma marcacao, mesmas classes —, entao trocar de modo
   nao pede nada ao servidor, nao troca trecho nenhum e nao pisca. E a forma
   mais barata de cumprir a lei 23 que existe: nao ha requisicao para cancelar.

   QUEM ESCREVE O ATRIBUTO e o `<script>` do `<head>` (parciais/script-exibicao),
   antes do CSS, como o do tema: assim a pagina ja nasce no modo escolhido em vez
   de aparecer em grade e saltar para lista.

   AS COLUNAS SAO A CONTA DO DOCUMENTO, e ela cabe numa linha: com o piso de 340
   e gap 16, o `auto-fill` devolve piso((C + 16) / 356) — 1 coluna no 600, 2 de
   344 no 768 e 3 de 389,33 no 1440, que sao os tres numeros escritos la. Abaixo
   de 600 e uma por linha com gap 12. Como as tres grades de oferta do site leem
   as MESMAS duas variaveis, redefinir as duas aqui muda as tres de uma vez.

   O FIGMA NAO TEM NENHUMA TELA EM MODO LISTA — zero instancias de Layout=Lista
   nas 9.608 da pagina Site. A vitrine "Lista por largura" (61001:84688) desenha
   360, 390, 599, 600 e 768, e em todas com UMA coluna: no 768 ela mostra 1 card
   de 560, e nao 2 de 344. E conflito direto com a conta do documento, e o lote
   manda seguir "as colunas do documento". Esta registrado no relatorio.
   =========================================================================== */
:root[data-kd-modo="lista"] {
  --kd-grade-template: minmax(0, 1fr);
  --kd-grade-gap: var(--md-sys-measurement-space150);   /* 12 */
}

@media (min-width: 600px) {
  :root[data-kd-modo="lista"] {
    --kd-grade-template: repeat(auto-fill, minmax(var(--kd-card-lista-min), 1fr));
    --kd-grade-gap: var(--md-sys-measurement-space200); /* 16 */
  }
}

/* O IN-FEED PRECISA DE ALTURA AQUI, e so aqui. Na grade ele nao tem altura
   propria: ele e uma celula e o `align-items: stretch` da grade o iguala ao card
   mais alto da linha. Numa Lista de UMA coluna ele fica sozinho na linha, nao ha
   card para igualar, e ele desabaria para a altura de duas linhas de texto.
   A altura vem do proprio Figma, que escreve "altura do card" dentro do
   In-feed: 148 da Lista compacta abaixo de 600, 168 da Lista a partir dela.
   In-feed dentro de lista NAO EXISTE NO FIGMA — esta no relatorio.

   O SELETOR E `.kd-anuncio-infeed`, E NAO `.kd-anuncio`: a faixa da Home usa o
   MESMO componente, e com a classe geral ela crescia de 100 para 168 no modo
   Lista sem ter nada a ver com a grade. Medido em 25/09/2026. */
[data-kd-modo="lista"] .kd-anuncio-infeed {
  min-height: var(--kd-card-lista-compacta-altura);     /* 148 */
}

/* O ESQUELETO ACOMPANHA O CARD. O molde e o mesmo `parciais/skeleton-card` das
   duas grades, e o JavaScript clona uma copia por coluna — como ele le a grade
   computada, o numero de copias ja sai certo no modo Lista sem uma linha a
   mais. O que faltava era a forma. O Figma tem o Skeleton de Lista (60840:487,
   560x168) mas NAO tem o de Lista compacta: abaixo de 600 a forma aqui vem do
   card, com a imagem de 112, e esta registrado. */
[data-kd-modo="lista"] .kd-skeleton {
  flex-direction: row;
  align-items: center;
}

[data-kd-modo="lista"] .kd-skeleton .kd-skeleton-imagem {
  flex: none;
  width: var(--kd-card-lista-compacta-imagem);          /* 112 */
  height: var(--kd-card-lista-compacta-imagem);
  aspect-ratio: auto;
}

[data-kd-modo="lista"] .kd-skeleton .kd-skeleton-textos {
  flex: 1 1 auto;
  min-width: 0;
  height: auto;
}

/* A GRADE LIMITADA DA HOME NO MODO LISTA. Mesma regra do modo Grade — 3 linhas
   cheias, nunca linha torta —, com as colunas da Lista: 1, 2 ou 3. Os pontos de
   quebra saem da mesma conta (C >= 356k - 16, com a margem de 32 e a barra de
   rolagem do Chrome): 775 para a segunda coluna e 1131 para a terceira.
   O Figma nao desenha a Home em Lista — a regra e a do modo Grade, aplicada a
   contagem de colunas da Lista. */
[data-kd-modo="lista"] .kd-grade-limitada > :nth-child(n + 4) { display: none; }

@media (min-width: 600px) {
  [data-kd-modo="lista"] .kd-anuncio-infeed {
    min-height: var(--kd-card-lista-altura);            /* 168 */
  }

  [data-kd-modo="lista"] .kd-skeleton {
    align-items: flex-start;
    max-width: var(--kd-card-lista-largura);            /* 560 */
  }

  [data-kd-modo="lista"] .kd-skeleton .kd-skeleton-imagem {
    width: var(--kd-card-lista-imagem);                 /* 144 */
    height: var(--kd-card-lista-imagem);
  }

  [data-kd-modo="lista"] .kd-skeleton .kd-skeleton-titulo       { width: var(--kd-skeleton-lista-titulo); }
  [data-kd-modo="lista"] .kd-skeleton .kd-skeleton-titulo-curto { width: var(--kd-skeleton-lista-titulo-curto); }
  [data-kd-modo="lista"] .kd-skeleton .kd-skeleton-preco        { width: var(--kd-skeleton-lista-preco); }
}

@media (min-width: 775px) {
  [data-kd-modo="lista"] .kd-grade-limitada > :nth-child(n + 4) { display: flex; }
  [data-kd-modo="lista"] .kd-grade-limitada > :nth-child(n + 7) { display: none; }
}

@media (min-width: 1131px) {
  [data-kd-modo="lista"] .kd-grade-limitada > :nth-child(n + 7)  { display: flex; }
  [data-kd-modo="lista"] .kd-grade-limitada > :nth-child(n + 10) { display: none; }
}

/* --- Estado vazio (Figma 60840:566) ---------------------------------------
   Mobile: largura total, padding 48/16. Desktop: 680 FIXO e centrado, padding
   48 nos quatro lados. Canto 24, fundo surface-container-low, gap 24.        */
.kd-vazio {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--md-sys-measurement-space300);           /* 24 */
  padding: var(--md-sys-measurement-space600) var(--md-sys-measurement-space200);
  border-radius: var(--md-sys-shape-corner-large-plus);  /* 24 */
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
  text-align: center;
}

.kd-vazio-icone {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--md-sys-measurement-space800);         /* 64 */
  height: var(--md-sys-measurement-space800);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface-variant);
}

.kd-vazio-textos {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);           /* 8 */
}

.kd-vazio-titulo {
  margin: 0;
  color: var(--md-sys-color-on-surface);
}

.kd-vazio-texto {
  margin: 0;
  color: var(--md-sys-color-on-surface-variant);
}

.kd-vazio-sugestoes {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--md-sys-measurement-space100);           /* 8 */
}

/* O chip de sugestao NAO e o chip de categoria da Home. Medido nas duas
   variantes do Estado vazio: fundo surface-container-highest e rotulo
   on-surface-variant, contra o secondary-container / on-secondary-container da
   Home. E a mesma pilula; o que muda e a cor, porque aqui ela esta DENTRO de
   um bloco surface-container-low e la esta sobre a pagina. */
.kd-vazio-sugestoes > .kd-chip {
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface-variant);
}

/* Abaixo de 600 as acoes empilham e cada botao ocupa a linha (FILL, 326 no
   Figma); de 600 para cima elas ficam lado a lado com a largura do rotulo. */
.kd-vazio-acoes {
  display: flex;
  flex-direction: column;
  align-self: stretch;
  gap: var(--md-sys-measurement-space100);           /* 8 */
}

.kd-vazio-acoes > .kd-botao { justify-content: center; }

@media (min-width: 600px) {
  .kd-vazio {
    width: var(--kd-vazio-largura);                  /* 680 */
    max-width: 100%;
    margin-inline: auto;
    padding: var(--md-sys-measurement-space600);     /* 48 nos quatro lados */
  }

  .kd-vazio-acoes {
    flex-direction: row;
    justify-content: center;
    align-self: auto;
  }
}

/* --- Menu de exibicao (Figma 61139:2225, lote 24) -------------------------
   O MESMO RECIPIENTE DO MENU DE FILTRO, MIOLO DIFERENTE. Medido no e 25/09:
   fill surface-container-high, Corner/Large nos quatro, SEM sombra (effects
   vazio) e SEM stroke em no nenhum — identico ao Menu de filtro, que ja esta
   escrito acima. Por isso a classe base continua sendo `.kd-menu-filtro` e
   esta aqui so acrescenta o que muda: largura 320 (contra 208), padding
   Space 200 nos quatro lados (contra padding-block 4 e nada nas laterais) e
   gap Space 200 entre as tres faixas (o de filtro nao tem gap: os itens se
   encostam).

   PRESO NA JANELA como o menu de filtro do site, e pelo mesmo motivo: ele
   nasce dentro da Barra de ordenacao, que tem um rolavel lateral por dentro.
   Um menu `absolute` seria recortado por ele.

   SEM SEPARADOR entre as secoes: o Figma tem tres filhos e nada entre eles.
   Quem separa e o gap de 16.                                             */
.kd-menu-exibicao {
  position: fixed;
  top: auto;
  left: auto;
  right: auto;
  width: var(--kd-menu-exibicao-largura);            /* 320 */
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);           /* 16 */
  padding: var(--md-sys-measurement-space200);
  overflow-y: visible;
}

.kd-menu-exibicao-titulo {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space100);           /* 8 */
  margin: 0;
  color: var(--md-sys-color-on-surface);
}

/* As duas faixas: rotulo que estica e controle na ponta, gap 12. */
.kd-menu-exibicao-linha {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space150);           /* 12 */
  min-height: var(--md-sys-measurement-space400);    /* 32 */
}

.kd-menu-exibicao-rotulo {
  flex: 1 1 auto;
  color: var(--md-sys-color-on-surface-variant);
}

/* O rotulo do interruptor e um `<label for>`: clicar nele liga e desliga o
   Switch, entao ele tambem e clicavel e tambem leva a mao. O de cima nao — ele
   so da nome ao par grade/lista, e nao aciona nada. E o mesmo tratamento que o
   `.kd-opcao-rotulo` do painel ja tem. */
label.kd-menu-exibicao-rotulo { cursor: pointer; }

/* O par grade/lista. NAO HA MOLDURA em volta dos dois: o frame `modo`
   (61139:2232) nao tem fill nem stroke. */
.kd-modo-par {
  display: flex;
  align-items: center;
  gap: var(--md-sys-measurement-space50);            /* 4 */
  flex: none;
}

/* O NAO ESCOLHIDO E TRANSPARENTE, e nao surface-container-highest como era
   no seletor de ordenacao antigo: medido no 61139:2236, a lista de fills
   volta vazia. Copiar a regra do seletor daria a cor errada. */
.kd-modo-botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--kd-modo-botao);                       /* 32 */
  height: var(--kd-modo-botao);
  border-radius: var(--md-sys-shape-corner-small);   /* 8 */
  color: var(--md-sys-color-on-surface-variant);
  cursor: pointer;
}

.kd-modo-botao[aria-checked="true"] {
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

.kd-modo-botao:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* --- Os filtros dentro do Menu de exibicao (lote 30) ----------------------
   O Figma 61139:2225 ganhou um bloco `filtros` entre o titulo e as duas
   linhas de exibicao: 288 de largura, vertical, Space 200 entre o campo de
   Loja e a faixa de preco. Ele aparece na Categoria, na Busca e na Loja, e
   nao na Home — quem decide e quem inclui o parcial, por parametro.

   O GAP E O MESMO 16 DO MENU, E MESMO ASSIM ELE EXISTE COMO ELEMENTO. Os dois
   espacamentos sao duas medidas diferentes no desenho (Space 200 entre os
   blocos do menu, Space 200 dentro de `filtros`); escrever um so faria a
   proxima mudanca em um deles arrastar o outro junto. */
.kd-menu-exibicao-filtros {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);           /* 16 */
}

/* O involucro do campo de Loja. Ele nao pinta nada: existe para o campo e o
   menu dele serem UMA coisa no fluxo do bloco de filtros — sem ele, o menu
   (que e `hidden` ate abrir) seria um segundo filho do `flex` e o `gap` de 16
   contaria com ele. */
.kd-menu-exibicao-loja { position: relative; }

/* O CAMPO DE TEXTO 60940:1368, Icone final=Escolha — o MESMO componente do
   painel. `.kd-campo`, `.kd-campo-rotulo`, `.kd-campo-valor` e
   `.kd-campo-seta` ja desenham as quatro partes desde o lote 17; repetir as
   regras aqui daria duas descricoes do mesmo desenho para manter em
   sincronia. O que o lote 30 muda e so isto:

     a superficie   surface-container-lowest, e nao surface-container-high.
                    Medido no Figma do lote 30: o campo mora DENTRO do menu,
                    que ja e surface-container-high, e dois `high` encostados
                    seriam a mesma cor — o campo sumiria dentro do menu.
     o elemento     o campo INTEIRO e um <button>, e nao uma caixa com um
                    controle menor dentro. No Figma "tocar no campo abre o
                    menu", e o campo tem 288x48; com o botao so na linha do
                    valor, tocar na palavra "Loja" nao faria nada e o alvo
                    cairia de 48 para os 24 do texto.

   `text-align` PRECISA SER DITO: o reset de `button` la em cima zera fonte,
   cor, fundo, borda e padding, mas nao o `text-align: center` que o navegador
   poe em todo botao — o rotulo e o valor sairiam centrados dentro do campo. */
.kd-campo-loja {
  /* UM <button> NAO ESTICA SOZINHO, nem com `display: flex`. Medido no
     Chrome em 25/09/2026: o campo saiu com 173,7 em vez dos 288 do Figma —
     controle de formulario tem largura intrinseca de "cabe no conteudo", e
     `width: auto` num botao nao vira "ocupa a linha" como viraria num
     <div>. Com o texto da loja mudando de "Todas as lojas" para tres nomes,
     o campo mudaria de largura a cada marcacao. */
  width: 100%;
  background: var(--md-sys-color-surface-container-lowest);
  text-align: left;
  cursor: pointer;
}

/* "os nomes separados por virgula, com reticencias quando nao couberem"
   (documento). As reticencias sao do navegador: so ele sabe onde o texto
   deixou de caber nos 288 do campo, e a conta muda com a fonte do sistema.
   Fica preso ao campo de Loja, e nao no `.kd-campo` de todo mundo: os campos
   do painel sao <input>, que ja cortam sozinhos e nao mostram reticencia
   nenhuma. */
.kd-campo-loja > .kd-campo-valor {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* O MENU DE FILTRO DAS LOJAS (Figma 61077:2049) — o mesmo menu do resto do
   site. `.kd-menu-filtro` ja traz os 208 de largura, o padding de 4, o canto
   16, a superficie surface-container-high e a sombra flutuante;
   `.kd-menu-item` ja traz o item de 48 com a caixa de 44, o check no fim e o
   marcado em secondary. Aqui entra so onde ele se prende.

   PRESO NA JANELA (`fixed`), E NAO NO CAMPO. Ele nasce dentro do Menu de
   exibicao, que ja e `fixed` e que o `kd.js` reposiciona a cada rolagem; um
   menu `absolute` dentro dele acompanharia o de fora, mas continuaria preso ao
   `max-height` que o `kd.js` escreve quando o menu de exibicao nao cabe na
   tela — e a lista de lojas e justamente a parte que pode ficar comprida.
   Com `fixed` ele sai de qualquer recorte, e quem calcula `top` e `left` e o
   mesmo `criarMenu` que ja faz isso para o Menu de acoes do painel. A classe
   `kd-menu-acima` nao entra aqui: o
   `criarMenu` so a poe em menu que NAO e `fixo`, justamente porque `top` e
   `bottom` juntos tiram a altura propria do elemento. */
.kd-menu-lojas {
  position: fixed;
  top: auto;
  left: auto;
  right: auto;
  width: var(--kd-menu-filtro-largura);              /* 208 */
}

/* --- Faixa de preco: o cabecalho ------------------------------------------
   Figma: `faixa-de-preco` 288x72 = cabecalho 20 + Space 100 + slider 44.
   O cabecalho e uma linha com o rotulo a esquerda (on-surface-variant) e o
   valor a direita (on-surface), os dois em title/small. */
.kd-faixa-preco {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space100);           /* 8 */
}

.kd-faixa-cabecalho {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--md-sys-measurement-space100);           /* 8 */
}

.kd-faixa-rotulo { color: var(--md-sys-color-on-surface-variant); }

/* O valor nao quebra em duas linhas: ele cresce de "Qualquer preco" para
   "Ate R$ 1.230" enquanto se arrasta, e uma quebra faria o cabecalho pular de
   20 para 40 no meio do arrasto, empurrando o slider debaixo do dedo. */
.kd-faixa-valor {
  color: var(--md-sys-color-on-surface);
  white-space: nowrap;
}

/* --- Faixa de preco: o slider ---------------------------------------------
   O CONTROLE E UM `input type=range`, E O DESENHO E CSS POR CIMA DELE.
   -------------------------------------------------------------------------
   O range nativo entrega de graca, sem uma linha de JavaScript: o papel de
   slider para o leitor de tela, as setas, Home e End, o arrasto de mouse, o
   arrasto de dedo, o clique no meio do trilho que pula ate la, o `step`
   respeitado e o valor anunciado. Um `div` com `role="slider"` e `pointermove`
   teria de reimplementar tudo isso — e erraria alguma coisa: o ponteiro que
   escapa da janela, o `pointercancel` de quem rola a pagina com o dedo, a
   ordem em que o leitor de tela le rotulo e valor.

   Entao o `input` fica por cima, INVISIVEL, so tratando a interacao, e o
   desenho do Material 3 sai de quatro irmaos pintados a partir de UMA fracao
   (`--kd-slider-fracao`, de 0 a 1), que o PHP escreve na carga e o `kd.js`
   atualiza a cada movimento.

   `--kd-slider-centro` E A CONTA QUE O NAVEGADOR FAZ, e e por isso que o
   desenho nunca se descola do controle: o polegar de um range passeia com meia
   largura dele de recuo em cada ponta, e o polegar nativo continua com 4 mesmo
   quando a alca PINTADA afina para 2 no arrasto. Por isso o recuo da conta usa
   o token direto (4 e 2), e nao o `--kd-slider-alca-largura`, que muda de
   valor arrastando. */
.kd-slider {
  --kd-slider-fracao: 1;
  --kd-slider-alca-largura: var(--md-sys-measurement-space50);   /* 4 */
  --kd-slider-vao: var(--md-sys-measurement-space75);            /* 6 */
  --kd-slider-centro: calc(var(--md-sys-measurement-space25)
                    + (100% - var(--md-sys-measurement-space50)) * var(--kd-slider-fracao));
  --kd-slider-antes: calc(var(--kd-slider-centro)
                  - var(--kd-slider-alca-largura) / 2 - var(--kd-slider-vao));
  --kd-slider-depois: calc(var(--kd-slider-centro)
                   + var(--kd-slider-alca-largura) / 2 + var(--kd-slider-vao));

  position: relative;
  height: var(--kd-slider-altura);                   /* 44 */
}

/* Os dois trilhos: 16 de altura, centrados nos 44 da peca. As pontas de FORA
   tem 8 (metade da altura, a pilula do kit) e as que olham para a alca tem 2 —
   as duas medidas saidas do pixel da exportacao do Figma.
   `pointer-events: none` porque quem recebe o toque e o `input` de cima:
   clicar no trilho tem de pular a alca para la, e e o navegador que faz isso. */
.kd-slider-rastro,
.kd-slider-resto {
  position: absolute;
  top: 50%;
  height: var(--md-sys-measurement-space200);        /* 16 */
  transform: translateY(-50%);
  pointer-events: none;
}

/* O RASTRO E O QUE JA FOI PERCORRIDO — do comeco ate a alca, em secondary.
   `max()` com o zero da colecao segura o caso da alca em R$ 0: ali a conta
   daria -8, e largura negativa e valor invalido, o que faria a declaracao
   inteira ser jogada fora em vez de dar zero. */
.kd-slider-rastro {
  left: 0;
  width: max(var(--md-sys-measurement-space0), var(--kd-slider-antes));
  border-start-start-radius: var(--md-sys-shape-corner-small);   /* 8 */
  border-end-start-radius: var(--md-sys-shape-corner-small);
  border-start-end-radius: var(--kd-slider-canto-justo);         /* 2 */
  border-end-end-radius: var(--kd-slider-canto-justo);
  background: var(--md-sys-color-secondary);
}

/* O RESTO vai da alca ate o fim, em secondary-container. `min(100%, ...)`
   segura o caso da alca na ponta direita: ali a conta passa de 100% e o
   elemento ficaria com largura negativa. */
.kd-slider-resto {
  left: min(100%, var(--kd-slider-depois));
  right: 0;
  overflow: hidden;
  border-start-start-radius: var(--kd-slider-canto-justo);       /* 2 */
  border-end-start-radius: var(--kd-slider-canto-justo);
  border-start-end-radius: var(--md-sys-shape-corner-small);     /* 8 */
  border-end-end-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-secondary-container);
}

/* O PONTO DO FIM DO TRILHO. Ele nao estava na lista de medidas do lote, mas
   esta no componente: medido na exportacao do Figma, 4x4 em secondary, com a
   borda direita a 4 do fim do trilho inativo. Registrado no relatorio.
   Ele some sozinho quando a alca chega na ponta, pelo `overflow: hidden` do
   pai — la nao existe mais trilho inativo, e um ponto solto no fim nao aparece
   em desenho nenhum. */
.kd-slider-resto::after {
  content: "";
  position: absolute;
  top: 50%;
  right: var(--md-sys-measurement-space50);          /* 4 */
  width: var(--md-sys-measurement-space50);          /* 4 */
  height: var(--md-sys-measurement-space50);
  transform: translateY(-50%);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-secondary);
}

/* A ALCA E UMA BARRA VERTICAL DE 4x44, e nao uma bolinha: e assim que o
   Material 3 de hoje desenha o Handle, e e o que o Figma tem. */
.kd-slider-alca {
  position: absolute;
  top: 0;
  left: var(--kd-slider-centro);
  width: var(--kd-slider-alca-largura);              /* 4 — 2 arrastando */
  height: var(--kd-slider-altura);                   /* 44 */
  transform: translateX(-50%);
  border-radius: var(--kd-slider-canto-justo);       /* 2 */
  background: var(--md-sys-color-secondary);
  pointer-events: none;
}

/* ARRASTANDO (Figma 61205:2291, o slider em State=Pressed): a alca afina de 4
   para 2 e o indicador de valor aparece acima dela. Quem poe e tira a classe e
   o `kd.js`, no `pointerdown` e no `pointerup`.
   SO NO ARRASTO, e nao no teclado: o estado desenhado e o Pressed, que e
   ponteiro em cima da alca, e quem anda de seta ja tem o texto do cabecalho
   acompanhando. Esta no relatorio. */
.kd-slider-arrastando { --kd-slider-alca-largura: var(--md-sys-measurement-space25); }  /* 2 */

/* O INDICADOR DE VALOR do kit: 44 de altura, padding 12/16, canto full, fundo
   inverse-surface com texto inverse-on-surface, centrado na alca e 4 acima da
   peca (medido em 61205:2295: o Value indicator fica em y = -48 com 44 de
   altura, ou seja, a base dele a 4 do topo do slider). */
.kd-slider-indicador {
  position: absolute;
  bottom: calc(100% + var(--md-sys-measurement-space50));   /* 4 acima da peca */
  left: var(--kd-slider-centro);
  display: none;
  align-items: center;
  height: var(--kd-slider-indicador-altura);         /* 44 */
  padding-inline: var(--md-sys-measurement-space200);/* 16 */
  transform: translateX(-50%);
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
  white-space: nowrap;
  pointer-events: none;
}

.kd-slider-arrastando > .kd-slider-indicador { display: flex; }

/* O CONTROLE POR CIMA DE TUDO, SEM DESENHO NENHUM.
   -------------------------------------------------------------------------
   A AREA DE TOQUE TEM 48 E A PECA TEM 44. Num range o elemento INTEIRO e area
   de arrasto, e nao so a alca — entao os 48 de altura ja sao o alvo que o lote
   pede. A margem negativa de 2 em cima e embaixo devolve os 4 que sobram para
   fora da caixa, e assim a peca continua medindo os 44 do Figma sem o desenho
   inflar. E a mesma receita do `.kd-botao`, que pinta 40 dentro de 48. */
.kd-slider-controle {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: var(--kd-slider-toque);                    /* 48 */
  margin-block: calc(var(--md-sys-measurement-space25) * -1);   /* -2 */
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  background: none;
  cursor: pointer;
}

/* O trilho nativo some: quem pinta os dois trilhos sao os irmaos acima. */
.kd-slider-controle::-webkit-slider-runnable-track {
  height: 100%;
  background: none;
}

.kd-slider-controle::-moz-range-track {
  height: 100%;
  background: none;
}

/* O POLEGAR NATIVO E TRANSPARENTE, MAS TEM A LARGURA DE VERDADE. E ele que o
   navegador passeia de R$ 0 a R$ 2.000, e `--kd-slider-centro` repete a conta
   dele; se aqui a largura fosse outra, o desenho e o controle andariam
   separados e a alca pintada ficaria ate 2 px fora do lugar nas pontas. */
.kd-slider-controle::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: var(--md-sys-measurement-space50);          /* 4 */
  height: var(--kd-slider-altura);                   /* 44 */
  background: none;
}

.kd-slider-controle::-moz-range-thumb {
  width: var(--md-sys-measurement-space50);
  height: var(--kd-slider-altura);
  background: none;
  border: none;
}

/* A FOLHA DE FILTROS SAIU NO LOTE 30 (Figma 60888:1037, marcada obsoleta).
   Aqui moravam a superficie surface-container-high, os 640 do 768, os grupos de
   chips que quebravam em linhas, o par de chip-e-`<input>`-escondido e o rodape
   com "Limpar" e "Ver N ofertas". Tudo saiu com a Barra de filtros que a abria.
   `.kd-folha`, `.kd-folha-alca` e `.kd-folha-conteudo` FICAM: sao a folha
   "Mais" do painel, que continua de pe.                                    */


/* ===========================================================================
   LOJA E CUPONS (lote 22)
   Figma: telas 60908:17344 / 60915:18378 / 60915:47574 (Loja) e
          60909:17993 / 60915:48607 / 60915:49107 (Cupons)
   Componentes: Cabecalho da loja 60907:964, Logo da loja 60907:923,
          Chip de loja 60907:945, Cupom 60826:330
          (a Barra de filtros 60888:1036, com a propriedade `Chip Loja`, saiu
          no lote 30; quem decide hoje e a propriedade `Loja` do Menu de
          exibicao 61139:2225)

   MEDIDO NO FIGMA EM 25/09/2026, nas tres larguras e nos dois temas. As duas
   paginas reaproveitam quase tudo do lote 21 — a grade de ofertas, o Estado
   vazio, o carrossel de borda, o Cupom e o botao tonal. O que este bloco acrescenta e o ARRANJO das duas paginas e os tres
   componentes que o site ainda nao tinha: o Logo da loja, o Cabecalho da loja
   e o Chip de loja.

   O ESPACO ENTRE SECOES E 40/40/32, e nao 48/48/40. O `figma-componentes.md`
   afirma 48/48/40 em dois lugares; nenhuma das 24 telas de Categoria, Busca,
   Loja e Cupons tem 48 — todas medem 40/40/32 no `itemSpacing` e no
   `paddingBottom` do `conteudo`. O CSS do projeto ja estava certo desde a
   passada de densidade de 24/09/2026 (`--kd-secao`); o texto e que envelheceu.
   =========================================================================== */

/* --- Logo da loja (Figma 60907:923) ---------------------------------------
   Quatro tamanhos, Corner/Full, fundo surface-container-lowest, iniciais em
   on-surface. O salto de peso entre o 2o e o 3o NAO e escala: Pequeno e Medio
   sao Bold (700), Grande e Extra grande sao ExtraBold (800) — sao quatro
   estilos de tipografia, e cada um vem por classe no HTML.

   O modo claro fica preso (`kd-modo-claro` no HTML), como no Cupom e na Linha
   de loja: circulo branco com as iniciais escuras nos dois temas. Logo de loja
   e material de terceiro, desenhado para fundo claro.                        */
.kd-logo-loja {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  overflow: hidden;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
}

.kd-logo-loja-pequeno {
  width: var(--md-sys-measurement-space300);           /* 24 */
  height: var(--md-sys-measurement-space300);
}

.kd-logo-loja-medio {
  width: var(--md-sys-measurement-space500);           /* 40 */
  height: var(--md-sys-measurement-space500);
}

.kd-logo-loja-grande {
  width: var(--md-sys-measurement-space700);           /* 56 */
  height: var(--md-sys-measurement-space700);
}

.kd-logo-loja-extra-grande {
  width: var(--kd-logo-loja-extra);                    /* 72 */
  height: var(--kd-logo-loja-extra);
}

/* O LOGO DO CABECALHO TROCA DE TAMANHO COM O BLOCO. Medido: a variante Mobile
   usa Logo da loja `Grande` (56, iniciais em title/large-emphasized) e a
   Desktop usa `Extra grande` (72, headline/small-emphasized). Como o Cabecalho
   e um HTML so com duas variantes decididas pelo CSS, o logo tem de acompanhar
   aqui e nao no PHP — e por isso este tamanho nao traz classe de tipografia no
   HTML: os dois estilos sao ExtraBold e so o corpo muda, 22/28 contra 24/32. */
.kd-logo-loja-cabecalho {
  width: var(--md-sys-measurement-space700);           /* 56 */
  height: var(--md-sys-measurement-space700);
  font-family: var(--md-sys-typescale-title-large-font), system-ui, sans-serif;
  font-size: var(--md-sys-typescale-title-large-size);
  line-height: var(--md-sys-typescale-title-large-line-height);
  letter-spacing: var(--md-sys-typescale-title-large-tracking);
  font-weight: var(--md-sys-typescale-title-large-weight-emphasized);
}

@media (min-width: 600px) {
  .kd-logo-loja-cabecalho {
    width: var(--kd-logo-loja-extra);                  /* 72 */
    height: var(--kd-logo-loja-extra);
    font-family: var(--md-sys-typescale-headline-small-font), system-ui, sans-serif;
    font-size: var(--md-sys-typescale-headline-small-size);
    line-height: var(--md-sys-typescale-headline-small-line-height);
    letter-spacing: var(--md-sys-typescale-headline-small-tracking);
    font-weight: var(--md-sys-typescale-headline-small-weight-emphasized);
  }
}

/* A IMAGEM ENTRA INTEIRA, e nao preenchendo: `contain` deixa a marca do
   parceiro se ver por completo, com o fundo do circulo aparecendo em volta
   quando a proporcao nao for quadrada. `cover` cortaria a marca, e marca
   cortada e pior que marca nenhuma. E a mesma regra da caixa da foto de
   produto e da imagem do card. */
.kd-logo-loja-imagem {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* --- Cabecalho da loja (Figma 60907:964) ----------------------------------
   Mobile primeiro, que e o padrao do projeto: 358x208, VERTICAL, gap 12,
   padding 16, canto 24 (Corner/Large-plus), fundo surface-container-low. A
   altura fecha em 16 + 56 + 12 + 108 + 16 = 208.

   De 600 para cima vale a variante Desktop: 1376x116, HORIZONTAL, gap 16,
   mesmo padding, canto 16 (Corner/Large), conteudo centrado na vertical. A
   altura fecha em 16 + 84 + 16 = 116.

   O CANTO MUDA ENTRE AS VARIANTES, e isso nao e detalhe: 16 no Desktop e 24 no
   Mobile, cada um perto dos ~20% da propria altura. E a mesma logica do Banner
   de cookies, que o documento cita.                                          */
.kd-cabecalho-loja {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space150);             /* 12 */
  padding: var(--md-sys-measurement-space200);         /* 16 */
  border-radius: var(--md-sys-shape-corner-large-plus);/* 24 */
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface);
}

.kd-cabecalho-loja-textos {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);              /* 4 */
  min-width: 0;
}

.kd-cabecalho-loja-nome {
  margin: 0;
  color: var(--md-sys-color-on-surface);
}

.kd-cabecalho-loja-dados {
  margin: 0;
  color: var(--md-sys-color-on-surface-variant);
}

.kd-cabecalho-loja-contagem {
  margin: 0;
  color: var(--md-sys-color-on-surface);
}

@media (min-width: 600px) {
  /* VARIANTE DESKTOP. O ponto de troca e o 600 que o projeto inteiro usa — o
     mesmo do Header, da margem e da grade. O Figma so desenha 1440, 768 e 390,
     e no 768 o Cabecalho ja e o Desktop (medido: 704x116), entao a troca esta
     entre 391 e 768; 600 e o unico ponto que o projeto tem nesse intervalo, e
     usar um numero novo criaria mais um lugar onde o layout muda. */
  .kd-cabecalho-loja {
    flex-direction: row;
    align-items: center;
    gap: var(--md-sys-measurement-space200);           /* 16 */
    border-radius: var(--md-sys-shape-corner-large);   /* 16 */
  }
}

/* --- Topo da Loja ---------------------------------------------------------
   Breadcrumb (52) + Cabecalho (116 ou 208), sem gap: quem separa e o padding
   de 16 que o breadcrumb ja traz embaixo. Medido: `topo` = 168 no 1440 e no
   768, 260 no 390.

   O `conteudo` da Loja comeca colado no Header (paddingTop 0 no Figma), como o
   da Categoria — a Busca e a pagina Cupons e que tem 16.                     */
/* `kd-pagina-loja`, e nao `kd-loja`: `.kd-loja` JA EXISTE desde o lote 16 —
   e a Linha de loja da comparacao do produto, um `flex` de uma linha so.
   Escrito `kd-loja` no `<main>`, a pagina inteira virava uma linha e as cinco
   secoes saiam lado a lado, com 3000 px de rolagem lateral. Medido em
   25/09/2026, e o mesmo tropeco que o lote 21 teve com `.kd-busca` (o campo de
   busca do Header) na pagina de resultados. */
.kd-pagina-loja-topo {
  display: flex;
  flex-direction: column;
}

.kd-pagina-loja { padding-top: 0; }

/* --- Carrossel de cupons da Loja ------------------------------------------
   O `.kd-rolagem-borda` do HTML ja faz a rolagem, a sangria ate a borda e a
   folga do anel de foco, com gap 16 — que e exatamente o que o Figma mede
   aqui. Nao ha nada a acrescentar, e a regra existe para dizer que foi
   conferido: o carrossel de cupons da Home usa o mesmo par de classes desde o
   lote 11.                                                                   */

/* --- Topo da pagina Cupons ------------------------------------------------
   `topo` = 108: titulo e contador (60, gap 4) + gap 16 + a fila de lojas (32).
   A fila nao tem titulo proprio — igual as subcategorias da Categoria.       */
.kd-cupons-topo {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space200);             /* 16 */
}

.kd-cupons-identificacao {
  display: flex;
  flex-direction: column;
  gap: var(--md-sys-measurement-space50);              /* 4 */
}

.kd-cupons-titulo {
  margin: 0;
  color: var(--md-sys-color-on-surface);
}

.kd-cupons-contador {
  margin: 0;
  color: var(--md-sys-color-on-surface-variant);
}

/* A fila de chips de loja: 32 de altura, gap 8, comecando na margem e cortando
   na borda da tela. Medido: os 9 chips somam 1780 contra 1376 de conteudo no
   1440 — ela vaza em TODA largura, e rola como a fila de categorias da Home. */
.kd-cupons-lojas { min-height: var(--kd-chip-altura); }   /* 32 */

/* O INVOLUCRO DA TROCA NAO E UMA CAIXA. `display: contents` faz `topo` e
   `cupons` continuarem sendo irmaos para efeito de flex, e os dois precisam
   trocar juntos porque tocar num chip muda o chip ligado, o endereco dos
   outros chips, o contador e a grade de uma vez.

   SO QUE ELE NAO SOBE ATE O `.kd-principal`, e era ai que estava o defeito.
   Entre um e outro ha o `.kd-troca`, o involucro da lei 23 — e esse tem
   caixa. O `display: contents` daqui levantava `topo` e `cupons` UM nivel, e
   eles paravam dentro do `.kd-troca`, que e um bloco comum sem `gap`
   nenhum: o espaco de 40/40/32 nunca chegou a existir na pagina de Cupons.
   Medido em 25/09/2026, COM e SEM JavaScript, o mesmo zero nas tres
   larguras. Quem conserta e a regra do `.kd-troca`, logo abaixo. */
.kd-bloco-cupons { display: contents; }

/* --- O INVOLUCRO DA TROCA PARCIAL NAO MUDA O ESPACO (lote 27) -------------
   `.kd-troca` e o alvo que o `kd.js` substitui (lei 23). Ele e mecanismo, e
   nao layout: o espaco em volta do que esta dentro dele tem de ser o mesmo
   com e sem JavaScript, e o mesmo que seria sem ele.

   NA MAIORIA DOS LUGARES ISSO JA ACONTECE de graca, porque ele vive DENTRO
   de uma `.kd-secao` e leva um filho so: Home (melhores-descontos),
   Categoria, Busca, Loja e o Historico do Produto. Em todos, o gap de 16 da
   secao continua valendo.

   A PAGINA DE CUPONS E A UNICA em que ele e filho DIRETO do `.kd-principal`
   e leva DOIS blocos de secao — o `topo` e o `cupons`, levantados ate ele
   pelo `display: contents` do `.kd-bloco-cupons`. Ali ele precisa repetir o
   arranjo do pai, senao engole o espaco entre os dois.

   E O MESMO `--kd-secao` DO `.kd-principal`, e nao um numero novo: 40 de 600
   em diante e 32 abaixo, que e o que o Figma pede nas tres telas de Cupons
   (1440 60909:17993, 768 60915:48607 e 390 60915:49107).

   POR QUE NAO `display: contents` NO PROPRIO `.kd-troca`: ele precisa de
   caixa. O `kd.js` trava a altura dele durante a troca
   (`alvo.style.minHeight = alvo.offsetHeight`) para a pagina nao pular nem
   piscar um vazio, e um elemento sem caixa ignora `min-height`. A promessa
   da lei 23 depende disso.                                               */
.kd-principal > .kd-troca {
  display: flex;
  flex-direction: column;
  gap: var(--kd-secao);
}

/* --- Chip de loja (Figma 60907:945) ---------------------------------------
   Input chip do kit sem contorno e sem icone de fechar: 32 de altura, canto
   full, avatar de 24 a esquerda e rotulo a direita, gap 8.

   O PADDING E ASSIMETRICO, e nao por gosto: 4 em cima, 12 a direita, 4 embaixo
   e 4 a esquerda. E a mesma regra do Chip de filtro — 4 do lado que encosta em
   ICONE (o avatar) e 12 do lado que encosta em TEXTO. A conta do Figma fecha:
   4 + 24 + 8 + 54 + 12 = 102.

   O AVATAR NAO MUDA DE COR QUANDO O CHIP LIGA. Medido nos dois estados: o
   circulo fica em surface-container-lowest com as iniciais em on-surface
   sempre. So o fundo do chip e a cor do rotulo trocam — e por isso o
   `.kd-logo-loja` nao aparece na regra do ligado.                            */
.kd-chip-loja {
  display: inline-flex;
  align-items: center;
  flex: none;
  gap: var(--md-sys-measurement-space100);             /* 8 */
  height: var(--kd-chip-altura);                       /* 32 */
  padding: var(--md-sys-measurement-space50)           /* 4 em cima */
           var(--md-sys-measurement-space150)          /* 12 a direita */
           var(--md-sys-measurement-space50)           /* 4 embaixo */
           var(--md-sys-measurement-space50);          /* 4 a esquerda */
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-surface-container-highest);
  color: var(--md-sys-color-on-surface);
  white-space: nowrap;
  position: relative;
}

/* Estado selecionado: secondary / on-secondary, a mesma regra do Chip de
   filtro e do seletor de ordenacao. */
.kd-chip-loja-ligado {
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

.kd-chip-loja::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--md-sys-color-on-surface);
  opacity: 0;
  pointer-events: none;
}

.kd-chip-loja:hover::after { opacity: var(--md-sys-state-hover-state-layer-opacity); }

.kd-chip-loja:focus-visible {
  outline: 2px solid var(--md-sys-color-primary);
  outline-offset: 2px;
}

/* A TRUNCAGEM E UMA REDE, como no Chip de filtro: o chip tem largura de
   conteudo e o Figma tambem o desenha assim (HUG, de 169 a 218 nas 9
   instancias). Estas tres linhas so agem se a fila apertar o chip. */
.kd-chip-loja-texto {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* --- Grade de cupons (pagina Cupons) --------------------------------------
   Medido nas 6 telas:

              colunas   celula     gap coluna   gap linha
     1440        3       442,67        24           24
      768        2       340           24           24
      390        1       358           —            12

   O GAP DO 390 E 12, e nao 24 — a unica largura onde ele muda, conferida nas
   duas telas de 390. Com uma coluna so, o gap que resta e o de linha.

   TODAS AS CELULAS DE UMA LINHA COM A ALTURA DA MAIS ALTA: e o
   `align-items: stretch` que a grade ja faz por padrao, e por isso ele nao
   esta escrito aqui. O que precisa estar escrito e o outro lado da regra — o
   conteudo do cartao colado no TOPO, com a sobra embaixo do botao. Medido no
   Figma: num cupom de uma linha esticado para 178, os filhos ficam nas MESMAS
   coordenadas de um cartao de 160, e os 18 sobram depois do botao. Sem isto o
   `flex` do cartao distribuiria a sobra entre os quatro blocos.

   QUEM QUEBRA DEPENDE DA LARGURA DA CELULA, nao do cupom: a 442,67 nenhum dos
   12 quebra, a 358 quebram 2 e a 340 quebram 4. O servidor nao tem como saber
   a altura — quem resolve e a grade, aqui.                                   */
.kd-grade-cupons {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--md-sys-measurement-space150);             /* 12 */
}

/* No carrossel o Cupom tem largura fixa (400 / 320); na grade ele preenche a
   celula, como ja acontece na secao de cupons da pagina de produto. */
.kd-grade-cupons > .kd-cupom {
  width: 100%;
  justify-content: flex-start;
}

@media (min-width: 600px) {
  .kd-grade-cupons {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--md-sys-measurement-space300);           /* 24 */
  }
}

@media (min-width: 1200px) {
  .kd-grade-cupons { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
