/* ==================================================================
   b2b.isell.pt/v2

   UMA cor saturada: o azul --pri. Tudo o resto e neutro com um vies QUENTE
   indigo ligeiro, para o conjunto ler como um sistema em vez de uma cor
   colada por cima de cinzentos.

   O que se guardou do legado nao foram os valores das cores de grade --
   lima e amarelo neon a competir com a primaria era barulho -- foi a
   LINGUAGEM: verde no topo, ambar em baixo. Fica numa rampa ordinal
   esbatida, e so como ponto de 7px.

   O estado seleccionado e SEMPRE indigo, em qualquer componente. Uma
   cor, um significado.

   Sem framework: ~430 linhas nao justificam 200kB de CDN, que alem do
   peso seria um pedido externo numa pagina atras de login.
   ================================================================== */
:root {
  color-scheme: light;

  /* --- primária --- */
  /* ACENTO — a única cor forte da página. Tudo o resto recua. */
  --pri:      #2b4ee0;   /* CTA — branco por cima: 6.42:1 */
  --pri-h:    #1f3cc4;   /* hover                  8.39:1 */
  --pri-a:    #182f9e;   /* active                        */
  --pri-txt:  #2340bd;   /* links a tamanho de corpo  8.27:1 */
  --pri-brd:  #c6d0f7;
  --pri-bg:   #eef1fd;
  --pri-bg-2: #f6f8ff;
  --anel:     #2b4ee040;

  /* NEUTROS QUENTES. Antes eram azuis -- a MESMA família do CTA -- e por isso
     o fundo nunca recuava e o azul nunca se destacava. Mudar a família dos
     neutros faz mais pela leitura da página do que trocar o acento. */
  --chao:     #f7f6f3;
  --sup:      #ffffff;
  --sup-2:    #faf9f6;
  --sup-3:    #f0eeea;
  --brd:      #e5e2db;
  --brd-2:    #efede7;
  --t1:       #1b1917;   /* 17.53:1 sobre --sup */
  --t2:       #57534c;   /*  7.64:1 */
  --t3:       #847e74;   /*  4.02:1 -- só para texto de apoio */

  /* RAMPA ORDINAL das grades: verde no topo, âmbar em baixo. Dessaturada de
     propósito, para ler como DADO e não como decoração. */
  --gr-novo:  #0f766e;
  --gr-prime: #4d7c0f;
  --gr-a:     #a16207;
  --gr-b:     #9a3412;
  /* `--gr-0` é a condição sintética: um produto sem grading nenhum mostra
     "Novo" e leva grade 0, que é o que o carrinho já usa para "sem condição".
     A cor é a do Novo porque é isso que ele é. */
  --gr-0: var(--gr-novo);
  --gr-5: var(--gr-novo);  --gr-1: var(--gr-prime);
  --gr-2: var(--gr-a);     --gr-3: var(--gr-b);

  /* SEMÂNTICA — reaproveita as pontas da rampa, para não abrir matiz nova. */
  /* O estado SELECCIONADO -- categoria activa, pagina actual, condicao
     escolhida. Nao e o CTA: se o for, uma barra de 22 categorias fica com uma
     mancha saturada permanente e o botao de "Adicionar" deixa de saltar.
     Mesmo tom do banner; o branco por cima da 10.6:1. */
  /* 80%, não 55%. Na ronda anterior desci-o até quase ao tom do banner e
     ficou apagado -- um estado seleccionado tem de se ver como escolha, não
     como fundo. Aqui tem presença e continua abaixo do CTA, que é o que
     impede a barra de 22 categorias de competir com o "Adicionar".
     Branco por cima: 8.07:1 (o CTA está em 6.42:1). */
  --sel:      color-mix(in srgb, var(--pri) 80%, #141827);
  --sel-brd:  color-mix(in srgb, var(--pri) 88%, #141827);

  --ok:       #15803d;
  --warn:     #a16207;
  --bad:      #b91c1c;

  --r-sm: 8px; --r: 12px; --r-lg: 16px; --r-xl: 22px;

  --sh-1: 0 1px 2px rgba(23,27,43,.05);
  --sh-2: 0 1px 2px rgba(23,27,43,.04), 0 6px 16px rgba(23,27,43,.06);
  --sh-3: 0 2px 4px rgba(23,27,43,.05), 0 16px 40px rgba(23,27,43,.10);
  --sh-pri: 0 1px 2px rgba(70,102,229,.2), 0 6px 18px rgba(70,102,229,.24);

  --ease: cubic-bezier(.4, 0, .2, 1);
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --t-fast: .13s var(--ease);
  --t-med: .22s var(--ease);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --pri: #7d9bff; --pri-h: #9ab2ff; --pri-a: #b3c5ff; --pri-txt: #9ab2ff;
    --pri-brd: #33417e; --pri-bg: #1b2145; --pri-bg-2: #161b36; --anel: #7d9bff55;
    --chao: #131211; --sup: #1c1a18; --sup-2: #232120; --sup-3: #2b2926;
    --brd: #33302c; --brd-2: #26241f;
    --t1: #f2f0ec; --t2: #b0aaa1; --t3: #8a847a;
    --gr-novo: #2dd4bf; --gr-prime: #a3e635; --gr-a: #fbbf24; --gr-b: #fb923c;
    /* No escuro o fundo ja e escuro: puxar o seleccionado para baixo
       apagava-o. Vai para cima. */
    --sel: color-mix(in srgb, var(--pri) 72%, #0b0e18); --sel-brd: var(--pri);
    --ok: #4ade80; --warn: #fbbf24; --bad: #f87171;
    --sh-1: 0 1px 2px rgba(0,0,0,.5);
    --sh-2: 0 1px 2px rgba(0,0,0,.5), 0 6px 16px rgba(0,0,0,.35);
    --sh-3: 0 2px 4px rgba(0,0,0,.5), 0 16px 40px rgba(0,0,0,.45);
    --sh-pri: 0 1px 2px rgba(0,0,0,.4), 0 6px 18px rgba(123,147,242,.18);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --pri: #7d9bff; --pri-h: #9ab2ff; --pri-a: #b3c5ff; --pri-txt: #9ab2ff;
  --pri-brd: #33417e; --pri-bg: #1b2145; --pri-bg-2: #161b36; --anel: #7d9bff55;
  --chao: #131211; --sup: #1c1a18; --sup-2: #232120; --sup-3: #2b2926;
  --brd: #33302c; --brd-2: #26241f;
  --t1: #f2f0ec; --t2: #b0aaa1; --t3: #8a847a;
  --gr-novo: #2dd4bf; --gr-prime: #a3e635; --gr-a: #fbbf24; --gr-b: #fb923c;
  --sel: color-mix(in srgb, var(--pri) 72%, #0b0e18); --sel-brd: var(--pri);
  --ok: #4ade80; --warn: #fbbf24; --bad: #f87171;
  --sh-1: 0 1px 2px rgba(0,0,0,.5);
  --sh-2: 0 1px 2px rgba(0,0,0,.5), 0 6px 16px rgba(0,0,0,.35);
  --sh-3: 0 2px 4px rgba(0,0,0,.5), 0 16px 40px rgba(0,0,0,.45);
  --sh-pri: 0 1px 2px rgba(0,0,0,.4), 0 6px 18px rgba(123,147,242,.18);
}

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

body {
  margin: 0; background: var(--chao); color: var(--t1);
  font: 400 15px/1.55 Inter, system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
h1, h2, h3 { font-family: "Inter Tight", Inter, system-ui, sans-serif; letter-spacing: -.021em; text-wrap: balance; margin: 0; }
.num { font-variant-numeric: tabular-nums; }
[hidden] { display: none !important; }

/* um anel de foco só, em todo o lado */
:where(a, button, input, select, [tabindex]):focus-visible {
  outline: 2px solid var(--pri); outline-offset: 2px; border-radius: var(--r-sm);
}

.wrap { max-width: 1264px; margin: 0 auto; padding: 0 20px; }
.stack { display: flex; flex-direction: column; }
.row { display: flex; align-items: center; }

/* ============ cabeçalho ============ */
.hd {
  position: sticky; top: 0; z-index: 30;
  background: color-mix(in srgb, var(--sup) 82%, transparent);
  backdrop-filter: blur(16px) saturate(1.5); -webkit-backdrop-filter: blur(16px) saturate(1.5);
  border-bottom: 1px solid var(--brd);
}
/* O LOGO
 *
 * O ficheiro e branco puro com alfa -- feito para fundo escuro. O cabecalho
 * aqui e claro (--sup: #fff), onde ele desaparecia; e ha tema escuro, onde
 * pinta-lo de preto seria o mesmo problema ao contrario.
 *
 * Por ser monocromatico, usa-se como MASCARA e nao como imagem: o desenho passa
 * a ser pintado com currentColor, que e --t1 e ja inverte sozinho entre os dois
 * temas. Um so ficheiro, sem filtros a adivinhar cores.
 */
.logo { display: inline-flex; align-items: center; text-decoration: none; color: var(--t1); }
.logo__img {
  display: block; width: 130px; height: 34px;
  background: currentColor;
  -webkit-mask: url("logo-b2b.png") left center / contain no-repeat;
          mask: url("logo-b2b.png") left center / contain no-repeat;
  transition: opacity var(--t-fast);
}
.logo:hover .logo__img { opacity: .74; }
.logo:focus-visible { outline: 2px solid var(--pri); outline-offset: 4px; border-radius: 4px; }

/* Sem mascara, `background: currentColor` seria um rectangulo solido -- pior do
 * que nao ter logo. Nesse caso mostra-se a imagem tal e qual. */
@supports not ((-webkit-mask-image: url("logo-b2b.png")) or (mask-image: url("logo-b2b.png"))) {
  .logo__img { background: url("logo-b2b.png") left center / contain no-repeat; }
}

.hd__end { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.stats { display: flex; gap: 28px; flex-wrap: wrap; }
.stats div { line-height: 1.15; }
.stats b { display: block; font: 700 20px/1 "Inter Tight", sans-serif; font-variant-numeric: tabular-nums; }
.stats span { font-size: 11px; opacity: .76; letter-spacing: .05em; text-transform: uppercase; }

/* ============ pesquisa ============ */
.search { position: relative; flex: 1 1 290px; max-width: 460px; }
.search__i {
  width: 100%; height: 46px; padding: 0 78px 0 42px;
  border: 1px solid var(--brd); border-radius: var(--r);
  background: var(--sup); color: var(--t1); font: 400 15px/1 Inter, sans-serif;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
}
.search__i::placeholder { color: var(--t3); }
.search__i:hover { border-color: var(--pri-brd); }
.search__i:focus { outline: none; border-color: var(--pri); box-shadow: 0 0 0 4px var(--anel); }
/* CENTRADOS PELA CAIXA, NÃO POR UM NÚMERO.
   Os três tinham o `top` em pixéis, calculado à mão para uma altura de 46px.
   A caixa da barra tem 42, por isso havia um segundo conjunto de números lá
   em baixo a corrigir estes -- e ficou 3px descaído mesmo assim. Com
   `top: 50%` e meia altura para trás, centram-se em qualquer altura e os
   números de correcção deixam de existir. */
.search__ic { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--t3); pointer-events: none; display: grid; transition: color var(--t-fast); }
.search__i:focus ~ .search__ic { color: var(--pri); }
.search__kbd {
  position: absolute; right: 13px; top: 50%; transform: translateY(-50%); pointer-events: none;
  font: 500 11px/1 ui-monospace, monospace; color: var(--t3);
  border: 1px solid var(--brd); border-radius: 6px; padding: 4px 7px; background: var(--sup-2);
}
/* `right` maior do que parece preciso: a caixa da barra é uma cápsula
   (raio 999px), e junto ao canto a moldura já vem a curvar para dentro. Com
   9px o botão quase lhe tocava nas pontas. */
.search__x {
  position: absolute; right: 13px; top: 50%; transform: translateY(-50%); width: 26px; height: 26px;
  border: 0; border-radius: 7px; background: var(--sup-3); color: var(--t2);
  cursor: pointer; font-size: 15px; line-height: 1; transition: background var(--t-fast), color var(--t-fast);
}
.search__x:hover { background: var(--pri-bg); color: var(--pri-txt); }
/* variante dentro do banner */
/* A PESQUISA DENTRO DA BARRA.
 *
 * As regras que aqui estavam pintavam-na sobre a faixa escura, com brancos a
 * martelo (`rgba(255,255,255,.13)`). A barra segue o TEMA -- e clara no tema
 * claro -- portanto brancos fixos deixavam-na invisivel metade do tempo.
 *
 * Tokens, e uma superficie um degrau acima da barra: e o que a separa do
 * fundo sem lhe por uma moldura pesada. */
.hd .search { flex: 1 1 440px; min-width: 0; max-width: 560px; }
.hd .search__i {
  height: 42px; border-radius: 999px;
  background: var(--sup-2); border-color: var(--brd);
}
.hd .search__i:hover { border-color: var(--t3); }
.hd .search__i:focus { border-color: var(--pri); background: var(--sup); box-shadow: 0 0 0 4px var(--anel); }


mark { background: var(--pri-bg); color: var(--pri-txt); border-radius: 3px; padding: 0 2px; font-weight: 600; }

/* ============ categorias ============ */
.cats { display: flex; gap: 6px; overflow-x: auto; padding: 18px 0 6px; scrollbar-width: none; scroll-snap-type: x proximity; }
.cats::-webkit-scrollbar { display: none; }
.cat {
  flex: 0 0 auto; scroll-snap-align: start;
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--brd); background: var(--sup); color: var(--t2);
  border-radius: var(--r); cursor: pointer; font: 500 13.5px/1 Inter, sans-serif; padding: 10px 14px;
  /* E um <a>: sem isto vem sublinhado do browser. A pastilha ja diz que se
     pode clicar -- o sublinhado por cima faz a barra parecer uma lista de
     links em vez de um filtro. */
  text-decoration: none;
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast),
              transform var(--t-fast), box-shadow var(--t-fast);
}
.cat svg { width: 17px; height: 17px; flex: none; }
.cat:hover { color: var(--t1); border-color: var(--pri-brd); transform: translateY(-1px); box-shadow: var(--sh-1); }
.cat:active { transform: translateY(0); }
.cat__n { font-size: 11.5px; padding: 2px 6px; border-radius: 6px; background: var(--sup-3); color: var(--t3); font-variant-numeric: tabular-nums; transition: background var(--t-fast), color var(--t-fast); }
.cat[aria-current="page"] { background: var(--sel); border-color: var(--sel-brd); color: #fff; font-weight: 600; box-shadow: none; }
.cat[aria-current="page"] .cat__n { background: rgba(255,255,255,.2); color: #fff; }

/* ============ botões ============ */
.btn:active { transform: scale(.98); }
.btn--pri { background: var(--pri); color: #fff; box-shadow: var(--sh-pri); }
.btn--pri:hover { background: var(--pri-h); }
.btn--pri:active { background: var(--pri-a); }
.btn--sec { background: var(--sup); border-color: var(--brd); color: var(--t1); }
.btn--sec:hover { border-color: var(--pri-brd); background: var(--pri-bg-2); color: var(--pri-txt); }
.btn--ghost { background: transparent; color: var(--t2); }
.btn--ghost:hover { background: var(--sup-3); color: var(--t1); }
.btn:disabled { opacity: .4; cursor: not-allowed; transform: none; }
.btn--full { width: 100%; }

.pill {
  min-width: 19px; height: 19px; padding: 0 5px; border-radius: 999px;
  background: var(--pri); color: #fff; font: 600 11px/1 Inter, sans-serif;
  display: inline-grid; place-items: center; font-variant-numeric: tabular-nums;
  transition: transform var(--t-med) var(--ease-out);
}
.pill--bump { animation: bump .34s var(--ease-out); }
@keyframes bump { 0% { transform: scale(1); } 40% { transform: scale(1.32); } 100% { transform: scale(1); } }

/* ============ barra de filtros ============ */
.bar { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin: 20px 0 16px; }
.bar__count { font-size: 14px; color: var(--t2); font-variant-numeric: tabular-nums; }
.bar__count b { color: var(--t1); font-weight: 600; }

.toggle { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; user-select: none; font-size: 13.5px; color: var(--t2); }
.toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.toggle__t { width: 36px; height: 21px; border-radius: 999px; background: var(--sup-3); border: 1px solid var(--brd); position: relative; transition: background var(--t-med), border-color var(--t-med); }
.toggle__t::after { content: ""; position: absolute; top: 2px; left: 2px; width: 15px; height: 15px; border-radius: 50%; background: var(--sup); box-shadow: var(--sh-1); transition: transform var(--t-med) var(--ease-out); }
.toggle input:checked + .toggle__t { background: var(--pri); border-color: var(--pri); }
.toggle input:checked + .toggle__t::after { transform: translateX(15px); }
.toggle:hover .toggle__t { border-color: var(--pri-brd); }
.toggle input:focus-visible + .toggle__t { outline: 2px solid var(--pri); outline-offset: 2px; }

.sort { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--t3); }
.sort select {
  height: 38px; border: 1px solid var(--brd); border-radius: 10px; background: var(--sup);
  color: var(--t1); font: 500 13.5px/1 Inter, sans-serif; padding: 0 30px 0 11px; cursor: pointer;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--t3) 50%), linear-gradient(135deg, var(--t3) 50%, transparent 50%);
  background-position: calc(100% - 15px) 17px, calc(100% - 11px) 17px;
  background-size: 4px 4px, 4px 4px; background-repeat: no-repeat;
  transition: border-color var(--t-fast);
}
.sort select:hover { border-color: var(--pri-brd); }

/* ============ grelha ============ */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(244px, 1fr)); gap: 15px; }

.card {
  background: var(--sup); border: 1px solid var(--brd); border-radius: var(--r-lg);
  overflow: hidden; display: flex; flex-direction: column;
  box-shadow: var(--sh-1);
  transition: box-shadow var(--t-med), border-color var(--t-med);
  animation: rise .32s var(--ease-out) backwards;
}
@keyframes rise { from { opacity: 0; transform: translateY(9px); } }

/* O CARTÃO NÃO SE MEXE AO PASSAR O RATO.
 *
 * Subia 3px, e o desenho lá dentro crescia e subia com ele. Numa grelha de
 * cartões encostados, o rato a atravessar a página deixa um rasto de coisas
 * a saltar -- e num catálogo percorre-se a grelha inteira a comparar preços,
 * portanto isso é o estado normal de uso, não um acaso.
 *
 * Fica o contorno e o realce: dizem exactamente a mesma coisa (é este que
 * está debaixo do rato) sem deslocar nada.
 *
 * O `transform` sai também da lista de transições -- nada aqui o muda. O
 * `rise` da entrada não é hover e fica: acontece uma vez, quando a grelha
 * aparece. */
.card:hover { box-shadow: var(--sh-3); border-color: var(--pri-brd); }

/* A MOLDURA DA IMAGEM
 *
 * `aspect-ratio` fixo e `object-fit: contain` -- as fotografias vem em
 * tamanhos e proporcoes diferentes, e sem isto cada cartao tinha a altura da
 * sua imagem e a grelha ficava aos degraus. Contain e nao cover: cortar meio
 * telemovel para encher um rectangulo e pior do que deixar ar a volta.
 *
 * O `content-visibility` deixa o browser saltar o que esta fora do ecra, e o
 * `contain-intrinsic-size` da-lhe a altura a reservar para nao haver salto. */
.thumb picture { display: contents; }
.thumb__i, .thumb img {
  width: 100%; height: 100%; object-fit: contain; padding: 9%;
  transition: transform var(--t-med) var(--ease-out);
}

/* Na ficha a imagem nao leva a lado nenhum. Sem cursor, sem hover: parecer
   clicavel e nao ser e uma promessa falhada em cada visita. */
.thumb--fixa { cursor: default; border-radius: var(--r-lg); border: 1px solid var(--brd); }
.thumb--fixa .thumb__i, .thumb--fixa img { transform: none !important; }
/* .thumb__wm e .thumb__ref sairam com o markup: o SKU estava POR CIMA da
   fotografia, onde tapava o produto e ninguem o conseguia seleccionar para
   copiar -- e copiar um SKU e a coisa mais frequente que aqui se faz. */

.card__b { padding: 13px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.card__t { font: 600 14.5px/1.32 Inter, sans-serif; letter-spacing: -.008em; }
/* O titulo e o link principal do cartao. Sem sublinhado em repouso -- numa
   grelha de 24 cartoes, 24 titulos sublinhados sao uma grade -- e com ele ao
   passar, para nao haver duvida de que se pode clicar. */
.card__t a { color: inherit; text-decoration: none; }
.card__t a:hover { color: var(--pri-txt); text-decoration: underline; text-underline-offset: 2px; }
.card__t a:focus-visible { outline: 2px solid var(--pri); outline-offset: 2px; border-radius: 3px; }
.card__c { font: 500 10.5px/1 Inter, sans-serif; color: var(--t3); text-transform: uppercase; letter-spacing: .08em; }

/* ---- grades: o ponto guarda a identidade, o índigo guarda o estado ---- */
.grades { display: flex; gap: 4px; flex-wrap: wrap; }
.grade {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--brd); background: var(--sup); color: var(--t2);
  border-radius: 9px; cursor: pointer; font: 500 11.5px/1 Inter, sans-serif;
  padding: 7px 9px; min-height: 30px;
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast),
              transform var(--t-fast), box-shadow var(--t-fast);
}
.grade__d { width: 7px; height: 7px; border-radius: 50%; background: var(--gc); flex: none; transition: background var(--t-fast), box-shadow var(--t-fast); }
.grade:hover:not(:disabled) { border-color: var(--pri-brd); color: var(--t1); transform: translateY(-1px); }
.grade[aria-pressed="true"] {
  background: var(--sel); border-color: var(--sel-brd); color: #fff; box-shadow: none;
}
.grade[aria-pressed="true"] .grade__d { background: #fff; box-shadow: 0 0 0 2.5px color-mix(in srgb, var(--gc) 85%, transparent); }
.grade:disabled { opacity: .38; cursor: not-allowed; }
.grade:disabled .grade__d { background: var(--t3); }

.price { display: flex; align-items: flex-end; justify-content: space-between; gap: 10px; margin-top: auto; }
.price__v { font: 700 21px/1.05 "Inter Tight", sans-serif; font-variant-numeric: tabular-nums; letter-spacing: -.028em; }
.price__s { display: block; font: 500 10.5px/1.3 Inter, sans-serif; color: var(--t3); letter-spacing: 0; margin-top: 4px; }

.stock { font: 600 11px/1 Inter, sans-serif; display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.stock::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.stock--ok { color: var(--ok); } .stock--low { color: var(--warn); } .stock--no { color: var(--t3); }

/* ---- quantidade ---- */
.qty { display: flex; border: 1px solid var(--brd); border-radius: 10px; overflow: hidden; transition: border-color var(--t-fast); }
.qty:focus-within { border-color: var(--pri); box-shadow: 0 0 0 3px var(--anel); }
.qty button {
  width: 38px; height: 38px; border: 0; background: var(--sup); color: var(--t2);
  font-size: 16px; cursor: pointer; transition: background var(--t-fast), color var(--t-fast);
}
.qty button:hover:not(:disabled) { background: var(--pri-bg); color: var(--pri-txt); }
.qty button:active:not(:disabled) { background: var(--pri-brd); }
.qty button:disabled { opacity: .3; cursor: not-allowed; }
.qty input {
  width: 100%; min-width: 42px; height: 38px; text-align: center; border: 0;
  border-left: 1px solid var(--brd); border-right: 1px solid var(--brd);
  background: var(--sup); color: var(--t1); font: 600 14.5px/1 Inter, sans-serif; font-variant-numeric: tabular-nums;
}
.qty input:focus { outline: none; }
.qty--on { border-color: var(--pri); }

/* ============ paginação ============ */
.pager { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; justify-content: space-between; margin: 30px 0 10px; }
.pager__r { font-size: 13.5px; color: var(--t3); font-variant-numeric: tabular-nums; }
.pager__r b { color: var(--t1); font-weight: 600; }
.pager nav { display: flex; gap: 4px; align-items: center; }
.pg {
  /* O `display` estava só em `a.pg`. A página ACTUAL é um <span>, que ficava
     `inline` -- e num inline nem `height` nem `line-height` centram nada, por
     isso o número flutuava dentro da caixa. A regra pertence à base: são todos
     a mesma peça, quer sejam <a>, <span> ou <button>. */
  display: inline-grid; place-items: center;
  min-width: 38px; height: 38px; padding: 0 10px; border-radius: 10px;
  border: 1px solid var(--brd); background: var(--sup); color: var(--t2);
  font: 500 13.5px/1 Inter, sans-serif; cursor: pointer; font-variant-numeric: tabular-nums;
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast), transform var(--t-fast);
}
.pg:hover:not(:disabled):not([aria-current]) { border-color: var(--pri-brd); color: var(--pri-txt); transform: translateY(-1px); }
.pg[aria-current="page"] { background: var(--sel); border-color: var(--sel-brd); color: #fff; font-weight: 600; box-shadow: none; }
.pg:disabled { opacity: .32; cursor: not-allowed; }
.pager__gap { color: var(--t3); padding: 0 2px; user-select: none; }

/* ============ ficha ============ */
.crumbs { display: flex; gap: 7px; align-items: center; font-size: 13px; color: var(--t3); margin: 22px 0 15px; flex-wrap: wrap; }
.crumbs a { color: var(--t2); text-decoration: none; transition: color var(--t-fast); }
.crumbs a:hover { color: var(--pri-txt); }
.detail { display: grid; grid-template-columns: minmax(0,5fr) minmax(0,7fr); gap: 26px; align-items: start; }
.detail .thumb { aspect-ratio: 1; border-radius: var(--r-lg); border: 1px solid var(--brd); cursor: default; box-shadow: var(--sh-2); }
.detail h1 { font-size: 25px; font-weight: 700; margin-bottom: 6px; }
.meta { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: var(--t3); margin-bottom: 20px; }
.meta b { color: var(--t2); font-weight: 600; font-variant-numeric: tabular-nums; }

.panel { background: var(--sup); border: 1px solid var(--brd); border-radius: var(--r-lg); padding: 20px; box-shadow: var(--sh-2); }
.label { font: 600 10.5px/1 Inter, sans-serif; text-transform: uppercase; letter-spacing: .1em; color: var(--t3); margin: 0 0 12px; }

.grow {
  display: grid; grid-template-columns: auto 1fr auto auto; gap: 13px; align-items: center;
  padding: 12px 13px; border: 1px solid var(--brd); border-radius: var(--r); cursor: pointer;
  background: var(--sup); margin-bottom: 7px; text-align: left; width: 100%;
  font-family: Inter, sans-serif; position: relative; overflow: hidden;
  transition: border-color var(--t-fast), background var(--t-fast), transform var(--t-fast);
}
.grow::before {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--gc); transform: scaleY(0); transform-origin: center;
  transition: transform var(--t-med) var(--ease-out);
}
.grow:hover:not(:disabled) { border-color: var(--pri-brd); transform: translateX(2px); }
.grow[aria-pressed="true"] { border-color: var(--pri); background: var(--pri-bg-2); }
.grow[aria-pressed="true"]::before { transform: scaleY(1); }
.grow:disabled { opacity: .45; cursor: not-allowed; }
.grow__s { width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center; background: var(--sup-3); color: var(--t2); font: 700 12px/1 "Inter Tight", sans-serif; transition: background var(--t-fast), color var(--t-fast); }
.grow[aria-pressed="true"] .grow__s { background: var(--pri); color: #fff; }
.grow__n { font-weight: 600; font-size: 14px; display: flex; align-items: center; gap: 7px; }
.grow__n i { width: 7px; height: 7px; border-radius: 50%; background: var(--gc); display: block; }
.grow__i { font-size: 12px; color: var(--t3); line-height: 1.35; }
.grow__p { font: 700 15.5px/1 "Inter Tight", sans-serif; font-variant-numeric: tabular-nums; }
.total-row { margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--brd); display: flex; align-items: flex-end; justify-content: space-between; gap: 14px; flex-wrap: wrap; }

/* ============ tabela ============ */
.pageoll { overflow-x: auto; border-radius: var(--r-lg); border: 1px solid var(--brd); box-shadow: var(--sh-2); }
.tbl th { font: 600 10.5px/1 Inter, sans-serif; text-transform: uppercase; letter-spacing: .09em; color: var(--t3); background: var(--sup-2); }
.tbl td.n, .tbl th.n { text-align: right; font-variant-numeric: tabular-nums; }
.tbl tbody tr { transition: background var(--t-fast); }
.tbl tbody tr:hover { background: var(--sup-2); }
.tbl tr:last-child td { border-bottom: 0; }
.tbl__p { font-weight: 600; }
/* O nome passou a ser um <a>, e um <a> traz o azul e o sublinhado do browser.
   Numa coluna de nomes isso é uma parede de azul: o que se quer é texto que se
   revela clicável ao passar por cima, como o cartão do catálogo faz. */
a.tbl__p { color: inherit; text-decoration: none; transition: color var(--t-fast); }
a.tbl__p:hover { color: var(--pri-txt); text-decoration: underline; text-underline-offset: 3px; }
a.tbl__p:focus-visible { outline: 2px solid var(--pri); outline-offset: 2px; border-radius: 3px; }
.tbl__note { display: block; font-size: 12px; margin-top: 3px; }

.totals { margin-left: auto; width: 100%; max-width: 330px; background: var(--sup); border: 1px solid var(--brd); border-radius: var(--r-lg); padding: 18px; box-shadow: var(--sh-2); }
.totals dl { margin: 0; display: grid; grid-template-columns: 1fr auto; gap: 9px 16px; }
.totals dt { color: var(--t2); font-size: 14px; }
.totals dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; font-weight: 500; }
.totals__end { border-top: 1px solid var(--brd); padding-top: 12px; margin-top: 4px; font-size: 18px; font-weight: 700; }
.totals__end dd { font-family: "Inter Tight", sans-serif; }
.ship { margin-top: 14px; padding: 11px 13px; border-radius: 10px; background: var(--pri-bg); color: var(--pri-txt); font-size: 12.5px; }

/* ============ entrar / doc ============ */
.auth { max-width: 392px; margin: 6vh auto; }
.auth .panel { padding: 30px; border-radius: 20px; box-shadow: var(--sh-3); }
.auth h1 { font-size: 22px; margin-bottom: 6px; }
.auth__sub { margin: 0 0 22px; color: var(--t3); font-size: 14px; }
.field { margin-bottom: 15px; }
.field input:hover { border-color: var(--pri-brd); }
.note { padding: 12px 14px; border-radius: var(--r); font-size: 13.5px; margin: 0 0 18px; }
.note--bad { background: color-mix(in srgb, var(--bad) 11%, transparent); color: var(--bad); }
.under { text-align: center; margin: 16px 0 0; font-size: 13.5px; color: var(--t3); }
.under a { color: var(--pri-txt); font-weight: 600; text-decoration: none; }
.under a:hover { text-decoration: underline; }

.doc { background: var(--sup); border: 1px solid var(--brd); border-radius: var(--r-lg); padding: 34px; box-shadow: var(--sh-2); max-width: 68ch; margin: 22px auto; }
.doc h1 { font-size: 24px; margin-bottom: 7px; }
.doc__d { color: var(--t3); font-size: 12.5px; margin: 0 0 26px; }
.doc h2 { font: 600 15px/1.4 Inter, sans-serif; margin: 26px 0 8px; letter-spacing: 0; }
.doc p, .doc li { color: var(--t2); font-size: 14.5px; line-height: 1.7; }
.doc ul { padding-left: 20px; }
.src { margin-top: 28px; padding: 13px 15px; border-radius: var(--r); background: var(--sup-2); border: 1px dashed var(--brd); color: var(--t3); font-size: 12.5px; }
.src code { font-family: ui-monospace, monospace; color: var(--t2); }

.empty { text-align: center; padding: 62px 20px; color: var(--t3); grid-column: 1/-1; }
.empty h2 { color: var(--t1); font-size: 18px; margin-bottom: 6px; }
.empty p { margin: 0 0 18px; }

.ft { border-top: 1px solid var(--brd); margin-top: 48px; padding: 24px 0 42px; }
.ft__l { display: flex; gap: 18px; flex-wrap: wrap; align-items: center; font-size: 13px; color: var(--t3); }
.ft__l a { color: var(--t2); text-decoration: none; transition: color var(--t-fast); }
.ft__l a:hover { color: var(--pri-txt); }
.ft__l .end { margin-left: auto; }

@media (max-width: 860px) { .detail { grid-template-columns: 1fr; } }
@media (max-width: 640px) {
    .who { display: none; }
  .grid { grid-template-columns: repeat(auto-fill, minmax(152px, 1fr)); gap: 10px; }
  .card__b { padding: 11px; gap: 9px; } .price__v { font-size: 18px; }
  .totals { max-width: none; } .doc { padding: 22px; }
  .search__kbd { display: none; } .search__i { padding-right: 44px; }
  .pager { justify-content: center; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
}

/* ============ o que as vistas do portal acrescentam ============ */
.ttl { font-size: 24px; margin: 26px 0 18px; }
.cart-foot { display: flex; gap: 12px; align-items: flex-start; margin-top: 22px; flex-wrap: wrap; }
.btn--sm { min-height: 32px; padding: 0 11px; font-size: 12.5px; border-radius: 9px; }
.grades-rows { margin-bottom: 4px; }
.tbl__none { color: var(--t3); }
.tbl form { margin: 0; }

/* a fotografia real, quando existe, entra no mesmo lugar do desenho */
.thumb { aspect-ratio: 4/3; position: relative; display: grid; place-items: center; cursor: pointer; overflow: hidden; border-radius: var(--r) var(--r) 0 0; background: var(--sup-2); content-visibility: auto; contain-intrinsic-size: auto 220px; text-decoration: none; color: inherit; }

/* O DESENHO DE PLACEHOLDER: herda a cor do tema, por isso serve claro e escuro.
   Havia um par igual sem o `[data-tipo]`, escrito antes deste e completamente
   tapado por ele -- o Placeholders::svg() põe sempre o atributo, e nenhuma
   vista mete outro svg dentro de um .thumb. Duas definições da mesma coisa é
   como a anterior ficou a mentir. */
.thumb svg[data-tipo] { width: 56%; height: 56%; color: var(--pri); opacity: .34;
  transition: opacity var(--t-med); }
.card:hover .thumb svg[data-tipo] { opacity: .5; }
.detail .thumb svg[data-tipo] { width: 46%; height: 46%; }

/* a paginação do servidor usa <a> e <span>, não <button> */
a.pg { text-decoration: none; }   /* o display subiu para .pg */
.pg[aria-disabled="true"] { opacity: .32; pointer-events: none; }
span.pg[aria-current="page"] { background: var(--sel); border-color: var(--sel-brd); color: #fff; font-weight: 600; box-shadow: none; }

/* ============ formulário de contacto ============ */
.form-contacto { margin-top: 34px; padding-top: 28px; border-top: 1px solid var(--brd); }
.form-contacto h2 { font: 600 16px/1.4 Inter, sans-serif; margin: 0 0 18px; letter-spacing: 0; }
.form-contacto .field { margin-bottom: 16px; }
.form-contacto textarea {
  width: 100%; padding: 12px 13px; border: 1px solid var(--brd); border-radius: var(--r);
  background: var(--sup-2); color: var(--t1); font: 400 15px/1.55 Inter, sans-serif;
  resize: vertical; min-height: 120px;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background var(--t-fast);
}
.form-contacto textarea:hover { border-color: var(--pri-brd); }
.form-contacto textarea:focus { outline: none; border-color: var(--pri); box-shadow: 0 0 0 4px var(--anel); background: var(--sup); }
.note--ok { background: color-mix(in srgb, var(--ok) 12%, transparent); color: var(--ok); }

/* ============ o asterisco das condições ============
   O legado usava o tooltip do Bootstrap num <span title="">. Aqui é um
   <button>: abre com hover, com foco de teclado, e com toque — o title do
   browser não faz nenhuma das duas últimas, e quem usa isto está muitas vezes
   ao balcão com o telemóvel. */

/* =====================================================================
   ACRESCENTOS DE 2026-08-22
   ===================================================================== */

/* ---- SKU: texto a sério, ao lado do nome ----
   Estava por cima da fotografia. Um código que se copia dez vezes por dia tem
   de ser seleccionável, e não pode tapar o produto. */
.card__h { display: flex; align-items: flex-start; gap: 8px; justify-content: space-between; }
.card__h .card__t { flex: 1; min-width: 0; }
.sku {
  flex: none; font: 500 10.5px/1 ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--t3); background: var(--sup-3); border: 1px solid var(--brd-2);
  border-radius: 6px; padding: 4px 6px; white-space: nowrap;
  font-variant-numeric: tabular-nums; user-select: all;
}
.sku b { font-weight: 600; color: var(--t2); }

/* ---- etiquetas do produto ---- */
/* ---- interruptor de tema ---- */
.icon-btn {
  flex: none; width: 36px; height: 36px; display: grid; place-items: center;
  border: 1px solid var(--brd); border-radius: 10px; background: var(--sup);
  color: var(--t2); cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}
.icon-btn:hover { background: var(--sup-3); color: var(--t1); border-color: var(--t3); }
.icon-btn:focus-visible { outline: 2px solid var(--pri); outline-offset: 2px; }
.icon-btn svg { fill: none; stroke: currentColor; stroke-width: 1.7; }
/* Um ícone de cada vez: o sol quando está escuro (é o que o clique faz),
   a lua quando está claro. Mostrar o estado actual em vez da acção é o erro
   clássico deste botão.

   Dependia de um `data-tema` que só o JS escrevia -- um segundo atributo, com
   valores em português, a viver ao lado do `data-theme` que o CSS usa a
   sério. Antes do JS correr, o botão mostrava o ícone errado.

   Agora segue exactamente as mesmas três condições dos tokens de cor: claro
   por omissão, escuro quando o sistema é escuro e não há escolha em
   contrário, escuro quando foi escolhido. Fica certo à primeira pintura, e
   sem JS também. */
.icon-btn__sol { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .icon-btn__sol { display: block; }
  :root:not([data-theme="light"]) .icon-btn__lua { display: none; }
}
:root[data-theme="dark"] .icon-btn__sol { display: block; }
:root[data-theme="dark"] .icon-btn__lua { display: none; }

/* ---- barra do topo ---- */
.hd__in { display: flex; align-items: center; gap: 12px; min-height: 60px; padding: 8px 0; flex-wrap: wrap; }

/* ---- painel sem condições ----
   Sem grades o painel tem uma secção só, e o risco que separava duas passava
   a separar o preço de nada. */
.panel--so-total .total-row { border-top: 0; padding-top: 0; margin-top: 0; }

/* ---- preço da ficha ---- */
/* COLUNA, não linha-que-quebra.
   Era `flex-wrap: wrap` com `flex-basis: 100%` no sufixo para o atirar para a
   linha de baixo. Isso põe-no na linha de baixo, sim -- e com a LARGURA TODA.
   Enquanto o sufixo era um <span> não se notava; desde que passou a ser o
   botão da nota, a área sensível ao rato passou a ser a linha inteira, e o
   balão abria com o rato em qualquer sítio do vazio à direita.

   Em coluna, cada um ocupa o que precisa: o número em cima, o "s/ IVA" por
   baixo, e a área do botão é o texto do botão. */
.price__v--lg { font-size: 30px; line-height: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
.price__v--lg .price__n { letter-spacing: -.03em; }

/* ---------------------------------------------------------------------
   O PVR RISCADO.

   Fica DELIBERADAMENTE discreto -- --t3, mais pequeno, peso normal. O que
   interessa a quem compra e o numero que vai pagar; o riscado e so a prova
   de que ha desconto. Se competisse em tamanho com o preco, obrigava a ler
   dois numeros para perceber qual e qual.

   `tabular-nums` porque os dois numeros ficam encostados e alinham melhor.
   --------------------------------------------------------------------- */
.price__pvr {
  font: 400 12.5px/1 Inter, sans-serif; color: var(--t3);
  font-variant-numeric: tabular-nums; letter-spacing: 0;
  text-decoration-thickness: 1px;
}
.price__v .price__pvr { margin-left: 6px; }

/* Na ficha, o riscado e a poupanca partilham a linha por baixo do preco. */
.price__desc { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.price__v--lg .price__pvr { font-size: 14px; margin-left: 0; }

/* AZUL, NAO VERDE. O verde e a cor do STOCK neste portal -- "Em stock" nos
   cartoes, na ficha e nas condicoes. Uma poupanca a verde ao lado disso
   lia-se como mais um sinal de disponibilidade. */
.price__poup {
  font: 600 12px/1 Inter, sans-serif; color: var(--pri-txt);
  background: var(--pri-bg); border: 1px solid var(--pri-brd);
  border-radius: 999px; padding: 3px 9px;
  font-variant-numeric: tabular-nums; letter-spacing: 0;
}

/* No carrinho o riscado desce para debaixo do unitario: a coluna e estreita
   e os dois lado a lado partiam a tabela. */
.tbl .price__pvr { display: block; margin: 2px 0 0; }

/* ---- stock e condição, sem números ---- */
.grow__q { font-size: 11.5px; color: var(--t3); font-variant-numeric: tabular-nums; text-align: right; font-weight: 600; white-space: nowrap; }
.grow__q.is-ok { color: var(--ok); }
.grow__q.is-no { color: var(--t3); }
.grade--novo { cursor: default; pointer-events: none; }

/* ---- avisos do carrinho ---- */
.tbl__note--warn { color: var(--warn); }
.tbl__note--bad  { color: var(--bad); }

/* ---- a tabela do carrinho, com cantos ----
   `border-collapse: collapse` mata os cantos arredondados: as células
   sobrepõem-se à moldura e os cantos voltam a ser rectos. Com `separate` e
   `border-spacing: 0` fica igual à vista e os cantos aguentam. */
/* O contentor que faz a tabela rolar DENTRO dela.
 *
 * A vista do carrinho ja tinha `<div class="scroll">` a volta da tabela; a
 * regra e que nunca existiu. A tabela tem `min-width: 560px`, portanto num
 * ecra estreito empurrava a PAGINA para o lado -- e uma pagina que rola na
 * horizontal e uma pagina onde o cabecalho foge quando se quer ler um preco.
 *
 * Apanhado pelo pino das classes por definir, nao a olho. */
.scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.tbl { width: 100%; border-collapse: separate; background: var(--sup); min-width: 560px; border-spacing: 0; border: 1px solid var(--brd); border-radius: var(--r-lg); overflow: hidden; }
.tbl th, .tbl td { padding: 13px 16px; text-align: left; border-bottom: 1px solid var(--brd-2); }
.tbl thead th:first-child { border-top-left-radius: var(--r-lg); }
.tbl thead th:last-child  { border-top-right-radius: var(--r-lg); }
.tbl tbody tr:last-child td { border-bottom: 0; }

/* =====================================================================
   RONDA 2 — 2026-08-22
   ===================================================================== */

/* ---- a linha de números do banner ----
   Substituiu três caixas. Uma caixa sozinha, com a mesma moldura das três que
   estavam lá, lia-se como um erro de layout — texto corrido com o número em
   destaque diz o mesmo sem fingir que ainda são vários. */

/* ---- disponibilidade ----
   Era texto simples ao lado de "Categoria X". Passa à mesma linguagem do stock
   nos cartões — ponto e cor — para a mesma informação não ter dois aspectos. */
.disp {
  display: inline-flex; align-items: center; gap: 7px;
  font: 600 12.5px/1 Inter, sans-serif; padding: 7px 12px;
  border-radius: 999px; border: 1px solid var(--brd);
  background: var(--sup-2);
}
.disp__d { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.disp--ok { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 28%, var(--brd)); }
.disp--no { color: var(--t3); }
.disp b { font-weight: 600; }

/* O SKU ao lado dela: mesma moldura e mesma sombra do painel de baixo, para as
   duas peças de identificação lerem como um par. */
/* Na ficha o SKU e uma pastilha com a mesma moldura e sombra do painel de
   baixo, para as duas pecas de identificacao lerem como um par. (Havia uma
   segunda definicao, mais acima, que esta anulava em silencio.) */
.sku--lg {
  background: var(--sup); border: 1px solid var(--brd);
  box-shadow: var(--sh-1); padding: 7px 12px; border-radius: 999px;
  font-size: 12.5px;
}
.detail .meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 18px; }

/* ---- compatibilidade ----
   As etiquetas destes produtos são listas de referências de modelo — dezenas
   delas. Em pastilhas davam um bloco de confetti ilegível. É uma descrição
   técnica, e trata-se como tal: um painel, com o texto a correr. */
/* DESCRIÇÃO, não painel técnico.
 *
 * A primeira versão era um bloco com moldura e tipo monoespaçado. Lia-se como
 * uma saída de terminal -- e o que ali está é a informação que descreve o
 * produto: para que modelos serve. Um revendedor lê isto para decidir se
 * compra, não para copiar.
 *
 * Fica com a tipografia do corpo, largura de leitura, e um filete em vez de
 * uma caixa: presente sem se impor entre o título e o preço.
 */
.compat { margin: 0 0 20px; padding: 2px 0 2px 14px; border-left: 2px solid var(--brd); max-width: 68ch; }
.compat__l {
  margin: 0 0 4px; font: 600 10.5px/1 Inter, sans-serif; color: var(--t3);
  text-transform: uppercase; letter-spacing: .09em;
}
.compat__v { margin: 0; font: 400 13.5px/1.7 Inter, sans-serif; color: var(--t2); }
.compat__sep { color: var(--brd); padding: 0 2px; }

/* .tag ficou sem markup quando as etiquetas passaram a descrição. */

/* ---- botão de adicionar, quando já adicionou ---- */
/* Azul, nao verde. O verde e a cor do STOCK neste portal -- "Em stock" nos
   cartoes, na ficha e nas condicoes -- e um botao verde ao lado disso lia-se
   como uma indicacao de disponibilidade e nao como "entrou no carrinho". A
   confirmacao fica no tom seleccionado, que e a familia do proprio CTA. */
.btn--feito { background: var(--sel) !important; border-color: var(--sel-brd) !important; }

/* ---- o placeholder que entra quando a fotografia falha ----
   Vem de um <template>, portanto nasce sem os estilos que o SVG do servidor
   apanha por estar dentro de .thumb desde o início. */
.thumb > svg { width: 56%; height: 56%; color: var(--pri); opacity: .32; }

/* ---- quem está ligado ----
   Eram duas linhas de texto soltas encostadas ao carrinho. Passa a cartão com
   a inicial: dá-lhe uma âncora visual e resolve os nomes compridos — há sempre
   por onde começar a ler, mesmo quando o nome corta. */
.who {
  display: flex; align-items: center; gap: 9px;
  background: var(--sup-2); border: 1px solid var(--brd-2);
  border-radius: 999px; padding: 4px 12px 4px 4px; max-width: 34ch;
}
.who__a {
  flex: none; width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--pri); color: #fff;
  font: 600 12px/1 "Inter Tight", sans-serif;
}
.who__t { min-width: 0; line-height: 1.25; }
.who__t b { display: block; font-size: 12.5px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.who__t span { display: block; font-size: 11px; color: var(--t3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* O tema encosta ao extremo direito, separado das acções por uma folga maior:
   é uma preferência de quem está a ver, não uma acção do portal. */
.icon-btn--tema { margin-left: 4px; }

/* O ícone dentro dos botões de texto (carrinho) alinha com a linha de base. */
.btn svg { flex: none; }
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 42px; padding: 0 17px; border-radius: var(--r); border: 1px solid transparent; font: 600 14px/1 Inter, sans-serif; cursor: pointer; text-decoration: none; white-space: nowrap; transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast),
              box-shadow var(--t-fast), transform var(--t-fast); }

@media (max-width: 720px) {
  /* Fica a inicial. O nome da empresa comia a barra toda e empurrava o
     carrinho para uma segunda linha. */
  .who { padding: 4px; }
  .who__t { display: none; }
}

/* =====================================================================
   RONDA 3 — 2026-08-22
   ===================================================================== */

/* ---- estados seleccionados mais calados ----
   A categoria activa, a página actual e a condição escolhida eram o azul do
   CTA em cheio, os três. Numa barra de 22 categorias isso é uma mancha
   saturada permanente, e o botão de "Adicionar" — que é a única coisa que
   devia gritar — passava a ser mais um azul entre outros.
   
   Passam ao mesmo tom do banner: reconhecem-se como "seleccionado" pelo
   contraste com os vizinhos, não pela saturação. O branco por cima fica em
   10.6:1, melhor do que estava. */
/* Os tokens --sel vivem com os outros, nos tres blocos la de cima. A primeira
   versao definia o valor escuro em `:root:not([data-theme="light"])` FORA da
   media query -- o que o aplicava sempre, tema claro incluido. */

/* Uma pastilha cheia e desactivada ao mesmo tempo dizia duas coisas
   contrárias. Sem stock não se acende, aconteça o que acontecer. */
.grade:disabled[aria-pressed="true"],
.grade:disabled { background: var(--sup-2); border-color: var(--brd-2); color: var(--t3); }

/* ---- a nota do IVA ----
   Era um parágrafo solto num tooltip, com a tipografia do corpo e nada que o
   ligasse ao resto. É uma nota fiscal: trata-se como uma, com a mesma família
   de superfícies do painel e um filete do lado que a marca como aparte. */
/* O BALÃO DA NOTA, colocado à mão pelo JS.
   `position: fixed` para não ser recortado por nenhum antepassado com
   overflow -- foi isso que o cortou dentro da tabela do carrinho. As
   coordenadas vêm do JS; aqui só está o aspecto. */
.nota-flutua {
  position: fixed; left: 0; top: 0; z-index: 60; width: max-content; max-width: 34ch;
  background: var(--sup-3); color: var(--t2); text-align: left;
  font: 400 12.5px/1.6 Inter, sans-serif; padding: 11px 13px;
  border-radius: var(--r-sm); box-shadow: var(--sh-2);
  border: 1px solid var(--brd); border-left: 3px solid var(--pri);
  pointer-events: none;
}
.nota-flutua p { margin: 0; }
.nota-flutua br { display: none; }   /* o texto vem do backoffice com <br> a fechar */
@media (max-width: 520px) { .nota-flutua { max-width: 210px; } }
/* A NOTA VIVE NO "s/ IVA", JÁ NÃO NUM ASTERISCO.
   A bolinha com `*` ao lado do preço não dizia a que se referia -- era preciso
   carregar nela para descobrir -- e metia um ponto de paragem de teclado entre
   o número e a unidade. A nota é sobre o imposto, portanto vive na etiqueta do
   imposto.

   Herda tudo do `.price__s` e acrescenta só o que a torna tocável: o sublinhado
   a tracejado é a convenção de «isto explica-se», e o `position: relative` é o
   que o balão precisa para se ancorar. */
.price__s--nota {
  /* A folga é só vertical, e o `gap` do contentor desconta-a: a área tocável
     passa de 14px de altura para ~22 sem que nada se mexa no ecrã. A largura
     continua a ser a do texto -- era a largura que estava errada, quando o
     botão ocupava a linha inteira e o balão abria com o rato no vazio à
     direita. */
  position: relative; border: 0; padding: 4px 0; background: none; cursor: help;
  /* SEM `font: inherit` nem `color: inherit`.
     Pareciam necessários para desfazer o estilo que o browser dá a um
     <button> -- e não são: qualquer regra de autor já lhe ganha, portanto o
     `.price__s` (que este elemento também tem) manda. Herdar era herdar do
     BLOCO DO PREÇO, e na ficha esse bloco é o preço grande: o "s/ IVA" saía
     do tamanho do preço, a gritar, com um sublinhado da mesma grossura. */
  text-decoration: underline dotted currentColor; text-underline-offset: 3px;
  transition: color var(--t-fast), text-decoration-color var(--t-fast);
}
.price__s--nota:hover, .price__s--nota:focus-visible { color: var(--pri-txt); text-decoration-color: var(--pri); }
.price__s--nota:focus-visible { outline: 2px solid var(--pri); outline-offset: 3px; border-radius: 3px; }
/* ANCORADO À ESQUERDA, não centrado.
   O balão herda `left: 50%` do tempo em que pendia de um asterisco no meio da
   linha. O "s/ IVA" fica encostado à esquerda da coluna do preço, e centrar um
   balão de 34ch nele fazia-o sair do painel e ir por cima da imagem. Preso ao
   canto esquerdo do rótulo, cresce para dentro. */
.price__s--nota 
/* Sem stock não há preço: fica o traço, calado, para a grelha não saltar de
   altura de cartão para cartão. */
.price__nao { color: var(--t3); font-variant-numeric: normal; }

/* ---- a conta ---- */
.pg-t { font: 600 26px/1.2 "Inter Tight", sans-serif; letter-spacing: -.025em; margin: 4px 0 18px; }
.conta { display: flex; flex-direction: column; gap: 16px; max-width: 720px; }
.conta .panel { padding: 18px 20px; }
.campos { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; margin-top: 12px; }
.field--w { grid-column: 1 / -1; }
.field label { display: block; font: 600 11.5px/1 Inter, sans-serif; margin-bottom: 6px; color: var(--t2); }
.field input { width: 100%; height: 40px; padding: 0 12px; border: 1px solid var(--brd); border-radius: var(--r-sm); background: var(--sup); color: var(--t1); font: 400 14px/1 Inter, sans-serif; transition: border-color var(--t-fast), box-shadow var(--t-fast); }
.field input:focus { outline: none; border-color: var(--pri); box-shadow: 0 0 0 3px var(--anel); background: var(--sup); }
.field__h { display: block; margin-top: 6px; font: 400 11.5px/1.5 Inter, sans-serif; color: var(--t3); }
/* Um campo que se mostra mas não se edita: sem moldura de input, para não
   convidar ao clique que não faz nada. */
.field__ro { margin: 0; font: 500 14px/1.4 Inter, sans-serif; color: var(--t1); }
.field__ro-x { color: var(--t3); font-weight: 400; margin-left: 8px; font-variant-numeric: tabular-nums; }
/* A secção que guarda TUDO.
   Os botões estavam dentro do painel "Dados de entrega", o último da página --
   e um botão dentro de um painel parece guardar esse painel. Guardava os dois.
   Aqui saem para uma faixa própria, com moldura, a seguir a ambos, e a legenda
   diz o que abrange. A dúvida deixa de existir sem precisar de a explicar. */
.conta__a { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; justify-content: space-between;
            padding: 14px 18px; border: 1px solid var(--brd); border-radius: var(--r); background: var(--sup-2); }
.conta__a > div { display: flex; flex-wrap: wrap; gap: 10px; }
.conta__a-n { margin: 0; font: 400 12.5px/1.4 Inter, sans-serif; color: var(--t3); }

/* Em ecrã estreito a legenda passa a vir primeiro: diz o que o botão faz
   ANTES de o oferecer, e os botões ficam a toda a largura, lado a lado. */
@media (max-width: 560px) {
  .conta__a { flex-direction: column; align-items: stretch; }
  .conta__a-n { order: -1; }
  .conta__a > div { display: grid; grid-template-columns: 1fr 1fr; }
  .conta__a .btn { width: 100%; }
}

/* O cartão do utilizador passou a ser um <a>. */
a.who { text-decoration: none; color: inherit; transition: border-color var(--t-fast), background var(--t-fast); }
a.who:hover { border-color: var(--pri-brd); background: var(--sup-3); }
a.who:focus-visible { outline: 2px solid var(--pri); outline-offset: 2px; }

/* =====================================================================
   RONDA 4 — 2026-08-22
   ===================================================================== */

/* ---- a caixa de pesquisa: um X, não dois ----
   `type="search"` traz um botão de limpar do próprio browser, desenhado por
   ele e fora do nosso controlo. Ao lado do nosso ficavam dois — e o do
   browser não sabe repintar a grelha. Fica o nosso. */
.search__i::-webkit-search-cancel-button,
.search__i::-webkit-search-decoration { -webkit-appearance: none; appearance: none; display: none; }
.search__i[type="search"] { -webkit-appearance: none; appearance: none; }

/* ---- a conta em duas colunas ---- */
.conta-g { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: 16px; align-items: start; }
.conta-g__m, .conta-g__l { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
/* NUMA COLUNA, A EMPRESA VEM PRIMEIRO.
   Em duas colunas a leitura é lado a lado e a ordem do código não se nota.
   Quando as colunas colapsam, a ordem passa a ser a do código: nome e email
   primeiro, e a empresa -- que é quem a conta é, e o que explica porque é que
   o NIF não se edita -- só lá para baixo.

   `display: contents` dissolve a coluna da direita: as duas secções que ela
   tinha passam a ser itens da grelha por direito próprio, e cada uma pode ir
   para o seu sítio. A password fica no fim, que é onde uma acção rara deve
   estar. O formulário do meio não se toca -- é um <form>, e os campos que
   guarda juntos têm de continuar juntos. */
@media (max-width: 860px) {
  .conta-g { grid-template-columns: minmax(0, 1fr); }
  .conta-g__l { display: contents; }
  .conta-g__emp { order: -1; }
}

/* Os dados que se vêem mas não se editam. Sem molduras de input: não convidam
   a um clique que não faz nada. */
.ro { margin: 12px 0 0; display: grid; grid-template-columns: auto 1fr; gap: 8px 16px; }
.ro dt { font: 600 11.5px/1.6 Inter, sans-serif; color: var(--t3); }
.ro dd { margin: 0; font: 500 14px/1.6 Inter, sans-serif; color: var(--t1); font-variant-numeric: tabular-nums; }

/* =====================================================================
   RONDA 5 — 2026-08-22
   ===================================================================== */

/* ---- a pastilha alinha com a caixa de pesquisa ----
   Tinham alturas diferentes (46px contra o que o padding desse) e, num flex
   com `align-items: center`, isso lê-se como desalinhamento — que é o que é.
   A altura passa a ser a mesma, e o texto centra-se por flex em vez de por
   line-height. */

.ro__vazio { color: var(--t3); font-weight: 400; }


/* =====================================================================
   O PAINEL DE RESULTADOS E O MENU DE CONTA — 2026-08-23
   ===================================================================== */

/* ---- o bloco da pesquisa ----
   `position: relative` para o painel se ancorar nele, e `z-index` acima do
   resto da faixa: um painel por baixo do banner não se vê. */
/* O bloco da pesquisa dentro da barra. `position: relative` para o painel se
   ancorar nele; `flex: 1` para ocupar o espaco entre o logo e as accoes. */
.busca { position: relative; flex: 1 1 440px; min-width: 0; max-width: 560px; }

/* O sinal de que está a pensar. Só aparece durante o pedido -- um spinner
   permanente é ruído, e um pedido sem sinal nenhum parece uma caixa avariada
   quando a rede está lenta. */
.search__spin {
  position: absolute; right: 46px; top: 50%; margin-top: -7px;
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--brd); border-top-color: var(--pri);
  animation: gira .6s linear infinite;
}
@keyframes gira { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .search__spin { animation-duration: 2s; } }

/* ---- o painel ---- */
.painel {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0;
  max-height: min(70vh, 520px); overflow-y: auto;
  background: var(--sup); border: 1px solid var(--brd);
  border-radius: var(--r-lg); box-shadow: var(--sh-3);
  padding: 6px; z-index: 40;
}
/* Numa faixa estreita o painel acompanha a caixa, não a linha toda. */
@media (min-width: 720px) { .painel { right: auto; width: min(620px, 100%); } }

.res {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto;
  align-items: center; gap: 12px;
  padding: 8px 10px; border-radius: var(--r); text-decoration: none; color: inherit;
}
/* O realce é o MESMO para rato e teclado: duas aparências para o mesmo estado
   fazem duvidar de qual delas conta. */
.res:hover, .res--on { background: var(--sup-3); }
.res--on { outline: 2px solid var(--pri); outline-offset: -2px; }

.res__i {
  width: 44px; height: 44px; border-radius: 8px; overflow: hidden;
  background: var(--sup-2); display: grid; place-items: center; flex: none;
}
.res__i img, .res__i svg { width: 100%; height: 100%; object-fit: contain; padding: 4px; }
.res__t { min-width: 0; }
.res__n {
  display: block; font: 600 13.5px/1.35 Inter, sans-serif; color: var(--t1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.res__m { display: flex; align-items: center; gap: 8px; margin-top: 3px; }
.res__c { font: 400 11px/1 Inter, sans-serif; color: var(--t3); text-transform: uppercase; letter-spacing: .06em; }
.res__p { text-align: right; white-space: nowrap; }
.res__p b { display: block; font: 600 14px/1.2 "Inter Tight", sans-serif; font-variant-numeric: tabular-nums; }
.res__p .stock { font-size: 10.5px; }

.painel__vazio { margin: 0; padding: 20px 12px; text-align: center; color: var(--t3); font-size: 13.5px; }
.painel__mais {
  display: block; margin-top: 4px; padding: 11px; border-top: 1px solid var(--brd-2);
  text-align: center; font: 600 13px/1 Inter, sans-serif; color: var(--pri-txt); text-decoration: none;
}
.painel__mais:hover { background: var(--sup-3); }

/* ---- o menu de conta ---- */
.conta-m { position: relative; }
.conta-m__b {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--sup-2); border: 1px solid var(--brd-2);
  border-radius: 999px; padding: 4px 10px 4px 4px; cursor: pointer;
  max-width: 26ch; transition: background var(--t-fast), border-color var(--t-fast);
}
.conta-m__b:hover, .conta-m--on .conta-m__b { background: var(--sup-3); border-color: var(--t3); }
.conta-m__b:focus-visible { outline: 2px solid var(--pri); outline-offset: 2px; }
.conta-m__n {
  /* Coluna: o nome em cima, o tier por baixo. O `min-width: 0` é o que deixa
     o ellipsis funcionar dentro de um flex item -- sem ele o nome empurra a
     barra em vez de ser cortado. */
  display: flex; flex-direction: column; gap: 1px; min-width: 0;
  font: 600 12.5px/1.15 Inter, sans-serif; color: var(--t1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.conta-m__t {
  font: 500 10.5px/1 Inter, sans-serif; color: var(--t3);
  letter-spacing: .04em; text-transform: uppercase;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* A marca do tier no lugar da inicial. Fundo próprio: a inicial é branca sobre
   --pri, e um traço branco a 1.4 sobre esse azul desaparecia. */
.who__a--t { background: var(--pri-bg); color: var(--pri-txt); border: 1px solid var(--pri-brd); }
.tier__i { width: 17px; height: 17px; }

/* A linha do tier dentro do menu. */
.menu__quem .tier {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 6px;
  padding: 3px 9px 3px 6px; border-radius: 999px;
  background: var(--pri-bg); border: 1px solid var(--pri-brd);
  font: 600 11px/1 Inter, sans-serif; color: var(--pri-txt);
  letter-spacing: .03em; text-transform: uppercase;
}

/* A linha do desconto no carrinho. A AZUL, como a poupanca na ficha -- e
   pela mesma razao: o verde e a cor do stock neste portal. */
.totals__desc { color: var(--pri-txt); font-weight: 600; }


/* ---------------------------------------------------------------------
   Os cartões dos comerciais, acima do rodapé.

   `auto-fit` com um mínimo: com um comercial o cartão não se estica pela
   largura toda da página, e com quatro passam a duas linhas sozinhos, sem
   media query nenhuma a adivinhar quantos são.
   --------------------------------------------------------------------- */
.reps { margin-top: 48px; padding-top: 28px; border-top: 1px solid var(--brd); }
.reps__t { font: 600 14px/1.2 "Inter Tight", Inter, sans-serif; color: var(--t2); margin: 0 0 14px; }

/* LARGURA LIMITADA, e por duas razoes.
   Com dois comerciais, o `1fr` esticava cada cartao por meia pagina para
   mostrar um nome e um numero -- uma caixa quase vazia le-se como espaco por
   preencher. E um cartao muito largo separa a cara do botao ao ponto de
   deixarem de se ler como a mesma coisa.
   O `auto-fill` em vez de `auto-fit` e o que os impede de esticar: com
   `auto-fit` as colunas vazias colapsam e as que restam crescem. */
.reps__g {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 240px), 1fr));
}

/* O cartao passa a ter DUAS zonas: a identidade em cima (cara + nome +
   numero) e a accao em baixo, encostada ao fundo pelo `margin-top:auto`.
   Assim os botoes alinham-se entre cartoes mesmo quando um nome ocupa duas
   linhas -- antes cada botao ficava a altura do seu proprio texto. */
.rep {
  display: flex; flex-direction: column; gap: 10px;
  max-width: 340px;
  padding: 16px; border: 1px solid var(--brd-2); border-radius: 14px;
  background: var(--sup-2);
  transition: border-color var(--t-fast), background var(--t-fast);
}
.rep:hover { border-color: var(--brd); background: var(--sup); }

/* A cara. As iniciais ficam POR BAIXO da imagem, na mesma caixa: quando a
   imagem falha e se remove, o que estava atras aparece sem saltar nada. */
.rep__f {
  position: relative; width: 46px; height: 46px; flex: none;
  border-radius: 50%; overflow: hidden;
  background: var(--pri-bg); border: 1px solid var(--pri-brd);
  display: grid; place-items: center;
}
.rep__i { font: 600 15px/1 "Inter Tight", sans-serif; color: var(--pri-txt); letter-spacing: .01em; }
.rep__f img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.rep__n { margin: 0; font: 600 14px/1.25 Inter, sans-serif; color: var(--t1); }

.rep__tel {
  display: inline-flex; align-items: center; gap: 7px;
  font: 500 13px/1 Inter, sans-serif; color: var(--t2); text-decoration: none;
  font-variant-numeric: tabular-nums;
}
.rep__tel:hover { color: var(--pri-txt); }
.rep__tel svg { width: 15px; height: 15px; flex: none; color: var(--t3); }

/* O WhatsApp e a accao do cartao -- ocupa a largura toda, encostado ao fundo,
   para nao haver duvida sobre onde se carrega. Verde porque e a cor que as
   pessoas ja associam ao servico; fica fora da rampa das grades de proposito. */
.rep__wa {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  margin-top: auto; padding: 9px 13px; border-radius: 10px;
  background: #128c7e; color: #fff; text-decoration: none;
  font: 600 12.5px/1 Inter, sans-serif;
  transition: background var(--t-fast);
}
.rep__wa:hover { background: #0e6f64; }
.rep__wa:focus-visible { outline: 2px solid var(--pri); outline-offset: 2px; }
.rep__wa svg { width: 15px; height: 15px; flex: none; }
.conta-m__v { color: var(--t3); flex: none; transition: transform var(--t-fast); }
.conta-m--on .conta-m__v { transform: rotate(180deg); }

.menu {
  position: absolute; top: calc(100% + 8px); right: 0; min-width: 248px;
  background: var(--sup); border: 1px solid var(--brd);
  border-radius: var(--r-lg); box-shadow: var(--sh-3); padding: 6px; z-index: 60;
}
.menu__quem { padding: 10px 12px 12px; border-bottom: 1px solid var(--brd-2); margin-bottom: 6px; }
.menu__quem b { display: block; font-size: 13.5px; }
.menu__quem span { display: block; font-size: 12px; color: var(--t3); margin-top: 2px; }
.menu__i {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 10px 12px; border: 0; border-radius: var(--r-sm);
  background: none; color: var(--t1); text-align: left; cursor: pointer;
  font: 500 13.5px/1 Inter, sans-serif; text-decoration: none;
}
.menu__i:hover { background: var(--sup-3); }
.menu__i:focus-visible { outline: 2px solid var(--pri); outline-offset: -2px; }
.menu__i svg { width: 17px; height: 17px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; }
.menu__i--sair { color: var(--bad); margin-top: 6px; border-top: 1px solid var(--brd-2); border-radius: 0 0 var(--r-sm) var(--r-sm); }

/* Só para leitores de ecrã. */
.sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

@media (max-width: 720px) {
  /* Fica a inicial e a seta: o nome da empresa comia a barra toda. */
  .conta-m__n { display: none; }   /* o tier vai com o nome: fica a marca */
  .conta-m__b { padding: 4px 8px 4px 4px; }
  .btn__t { display: none; }

  /* DUAS LINHAS, NÃO TRÊS.
     A barra é `flex-wrap: wrap` e a pesquisa pede 440px de base. Num
     telemóvel isso não cabe ao lado do logo, e o que se seguia -- as duas
     acções, com `margin-left: auto` -- era empurrado para uma TERCEIRA linha.
     O logo ficava sozinho numa linha inteira e a barra ocupava metade do que
     há acima da dobra.

     A pesquisa passa a pedir a linha toda de propósito, e vai para o fim.
     Sobra uma linha com o logo à esquerda e o carrinho e a conta à direita,
     que é onde a mão chega.

     Cuidado com o alvo: o item flex da barra e o `.busca` de fora, nao o
     `.search` de dentro -- esse e um <form> dentro dele, e propriedades de
     flex escritas nele nao fazem nada. */
  .busca { flex: 1 0 100%; order: 3; max-width: none; }
  .hd__end { order: 2; }
}

/* =====================================================================
   NAVEGAR SEM REPINTAR — 2026-08-24
   ===================================================================== */

/* O <main> recebe o foco ao trocar de página, para quem navega por teclado
   ou com leitor de ecrã não ficar preso num link que já não existe. Tem
   `tabindex="-1"`, portanto não é alcançável pelo Tab: este foco é sempre
   programático e desenhar-lhe um anel só piscava um rectângulo à volta da
   página inteira a cada clique. */
#pagina:focus { outline: none; }

/* A ESPERA TEM DE SE VER.
   Ao recarregar a página inteira, o browser mostrava a sua própria barra de
   progresso -- era ela que dizia "estou a tratar disso". Trocando só o miolo,
   essa barra desaparece e um clique numa ligação lenta fica sem resposta
   nenhuma, o que se lê como avaria e leva a carregar outra vez.

   Um fio no topo, e não um véu por cima do conteúdo: o que está no ecrã ainda
   é válido e continua a poder ler-se enquanto o seguinte não chega. */
.a-navegar::before {
  content: ""; position: fixed; inset: 0 auto auto 0; z-index: 60;
  height: 2px; width: 100%; transform-origin: 0 50%;
  background: var(--pri);
  animation: fio 12s cubic-bezier(0, .6, .3, 1) forwards;
}
@keyframes fio { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Sem animação, o fio fica: continua a dizer "estou à espera" sem se mexer. */
@media (prefers-reduced-motion: reduce) {
  .a-navegar::before { animation: none; transform: scaleX(1); opacity: .55; }
}

/* Enquanto o seguinte não chega, o que está no ecrã não aceita cliques: dois
   destinos pedidos ao mesmo tempo dão a página de um com o endereço do outro.
   O `navegar()` já cancela o pedido anterior, mas isto evita o clique. */
#pagina[aria-busy="true"] { pointer-events: none; }

/* A etiqueta do regime na linha do carrinho: por baixo do nome, no mesmo tom
   das outras notas da tabela. O `.price__s` traz `display: block`, que aqui
   dava uma linha inteira sensível ao rato -- o mesmo defeito que a ficha já
   teve. */
.tbl__iva { display: block; margin-top: 3px; }
.tbl__iva .price__s { display: inline-block; margin-top: 0; }
