/* ==========================================================================
   STHEFANY — componentes
   componentes.css · v0.8.0
   --------------------------------------------------------------------------
   Componentes que o protótipo e o design system compartilham. No plugin cada
   bloco vira um arquivo próprio, declarado em get_style_depends() do widget
   que o usa, para o Elementor só carregar onde há uso.
   ========================================================================== */

/* --- tratamento de foto -------------------------------------------------
   Preto e branco por padrão, cor no hover. A regra vive dentro de
   @media (hover: hover): no toque não existe hover e a foto ficaria
   dessaturada para sempre — que é o defeito clássico deste efeito.
   No celular a foto entra colorida direto. */

.sp-imagem {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--sp-fundo-alto);
}

.sp-imagem img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

@media (hover: hover) and (pointer: fine) {
  .sp-imagem--pb img,
  .sp-imagem--pb .sp-foto--simulada {
    filter: grayscale(1) contrast(1.08);
    transition: filter var(--sp-transicao-foto),
                transform var(--sp-transicao-foto);
  }

  .sp-imagem--pb:hover img,
  .sp-imagem--pb:hover .sp-foto--simulada,
  .sp-imagem--pb:focus-visible img,
  .sp-imagem--pb:focus-visible .sp-foto--simulada {
    filter: grayscale(0) contrast(1);
  }
}

/* Véu de baixo, para o texto sobre a foto ter contraste garantido sem
   depender do que a fotografia tem naquele canto. */
.sp-imagem--veu::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top,
              rgba(11, 5, 5, .92) 0%,
              rgba(11, 5, 5, .45) 38%,
              transparent 72%);
}

.sp-proporcao--retrato  { aspect-ratio: 3 / 4; }
.sp-proporcao--quadrado { aspect-ratio: 1 / 1; }
.sp-proporcao--paisagem { aspect-ratio: 16 / 9; }
.sp-proporcao--palco    { aspect-ratio: 4 / 5; }

/* --- cartão de artista --------------------------------------------------
   Sem caixa, sem borda, sem sombra: a foto é o cartão. Catorze cartões com
   moldura viram planilha; catorze fotos viram artistas. */

/* O cartão é uma superfície escura própria: a foto ocupa tudo e o nome fica
   sobre o véu. Herdar a cor da página branca deixaria o nome preto sobre foto
   preta — que foi o defeito da primeira montagem da grade. */
.sp-artista {
  position: relative;
  display: block;
  text-decoration: none;
  color: var(--sp-texto);
  --sp-tinta:   var(--sp-texto);
  --sp-tinta-2: var(--sp-texto-2);
  --sp-tinta-3: var(--sp-texto-3);
}

.sp-artista__foto { border-radius: var(--sp-raio); }

.sp-artista__texto {
  position: absolute;
  inset-inline: var(--sp-e-4);
  bottom: var(--sp-e-4);
  z-index: 2;
}

.sp-artista__nome {
  font-family: var(--sp-fonte-titulo);
  font-size: var(--sp-t-h3);
  font-weight: 600;
  line-height: 1.05;
  text-wrap: balance;
}

.sp-artista__genero {
  margin-block-start: var(--sp-e-1);
  color: var(--sp-texto-2);
  font-size: var(--sp-t-peq);
}

/* Fio que cresce sob o nome no hover. Substitui a seta apensa ao texto,
   que é o tique visual mais gasto deste tipo de cartão. */
.sp-artista__nome::after {
  content: "";
  display: block;
  width: 100%;
  height: 1px;
  margin-block-start: var(--sp-e-2);
  background: var(--sp-acento);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--sp-transicao);
}
.sp-artista:hover .sp-artista__nome::after,
.sp-artista:focus-visible .sp-artista__nome::after { transform: scaleX(1); }

/* --- item de agenda -----------------------------------------------------
   A data é o dado que a pessoa procura primeiro, então ela é o elemento
   tipográfico dominante da linha, não um rótulo pequeno ao lado. */

.sp-data {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--sp-e-5);
  align-items: center;
  padding-block: var(--sp-e-5);
  border-block-end: 1px solid var(--sp-linha-clara);
  text-decoration: none;
  color: inherit;
}

/* O realce sangra para fora da coluna de texto.

   Pintado no fundo do próprio elemento ele nascia rente ao dígito da esquerda
   e ao botão da direita, sem folga e sem canto: o "11" parecia cortado pela
   borda e a linha inteira lia como célula de planilha selecionada, não como
   item de lista sob o ponteiro.

   A régua inferior continua onde estava, alinhada à grade do resto da página
   — quem sangra é só o realce, num pseudo-elemento. `inset-block: 0 1px`
   deixa a régua aparecer por baixo dele; `isolation: isolate` prende o
   `z-index: -1` dentro da linha, senão o realce escorregaria para trás do
   fundo da página. */
.sp-data::before {
  content: "";
  position: absolute;
  z-index: -1;
  inset-block: 0 1px;
  inset-inline: calc(var(--sp-e-5) * -1);
  border-radius: var(--sp-raio);
  background: color-mix(in srgb, currentColor 5%, transparent);
  opacity: 0;
  transition: opacity var(--sp-transicao);
}

@media (hover: hover) and (pointer: fine) {
  .sp-data:hover::before { opacity: 1; }
}

.sp-data__quando {
  display: flex;
  align-items: baseline;
  gap: var(--sp-e-2);
  min-width: 6.5rem;
  font-family: var(--sp-fonte-titulo);
  font-variant-numeric: tabular-nums;
}

.sp-data__dia {
  font-size: 2.5rem;
  font-weight: 700;
  line-height: .85;
  color: var(--sp-acento-texto);
}

.sp-data__mes {
  font-family: var(--sp-fonte-texto);
  font-size: var(--sp-t-peq);
  font-weight: 500;
  color: var(--sp-tinta-3);
}

.sp-data__artista {
  font-family: var(--sp-fonte-titulo);
  font-size: var(--sp-t-h3);
  font-weight: 600;
  line-height: 1.1;
}

.sp-data__local {
  margin-block-start: var(--sp-e-1);
  color: var(--sp-tinta-2);
  font-size: var(--sp-t-peq);
}

/* Show que já aconteceu é o estado apagado da lista — mas apagar com
   `opacity` derruba TUDO junto, texto incluído: a .42 de antes deixava a
   linha inteira abaixo de 2:1 e o filtro "Passados" entregava uma tela que
   não dá para ler. O apagamento agora é de cor, um degrau abaixo da tinta
   normal, e de saturação na fotografia. Continua nitidamente secundário e
   continua legível. */
.sp-data--passado {
  --sp-tinta:   var(--sp-tinta-2);
  --sp-tinta-2: var(--sp-tinta-3);
  color: var(--sp-tinta-2);
}
.sp-data--passado .sp-imagem img,
.sp-data--passado .sp-foto--simulada { filter: grayscale(1) opacity(.55); }
.sp-data--passado .sp-data__dia { color: var(--sp-tinta-2); }

.sp-selo {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-e-1);
  padding: var(--sp-e-1) var(--sp-e-3);
  border: 1px solid var(--sp-linha-clara);
  border-radius: var(--sp-raio-botao);
  font-size: var(--sp-t-mini);
  font-weight: 500;
  color: var(--sp-tinta-2);
  white-space: nowrap;
}
.sp-selo--vinho {
  border-color: transparent;
  background: var(--sp-vinho-fundo);
  color: #F6D5D2;
}

@media (max-width: 48rem) {
  .sp-data { grid-template-columns: auto 1fr; gap: var(--sp-e-4); }
  .sp-data > .sp-selo { grid-column: 2; justify-self: start; }
  .sp-data__dia { font-size: 2rem; }
}

/* --- rótulo ---------------------------------------------------------------
   Só onde nomeia um dado que o título não diz, como a etiqueta do painel do
   próximo show. Não vai acima de título de seção: ali o título já nomeia, e o
   rótulo vira ruído. Sem seta: ela era ornamento do kit, não informação. */

.sp-rotulo {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-e-3);
  margin-block-end: var(--sp-e-4);
  font-family: var(--sp-fonte-texto);
  font-size: var(--sp-t-mini);
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--sp-acento-texto);
}

.sp-rotulo--claro { color: var(--sp-vinho); }

/* --- mídia: foto ou vídeo -------------------------------------------------
   O mesmo espaço aceita imagem ou vídeo. O vídeo é decoração, nunca conteúdo:
   sem som, sem controles, em laço curto, e sempre com poster — se ele não
   carregar, o quadro fica com a foto no lugar de um buraco preto.

   Ele não toca sozinho o tempo todo: o script só dá play quando o bloco está
   visível, e nem chega a baixar quando o visitante pediu menos movimento ou
   está no modo de economia de dados. */

.sp-midia > video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Enquanto o vídeo não está pronto, o poster já ocupa o quadro; a transição
   evita o pulo de brilho entre o poster e o primeiro quadro. */
.sp-midia > video {
  opacity: 0;
  transition: opacity 400ms linear;
}
.sp-midia > video[data-pronto="sim"] { opacity: 1; }

.sp-midia__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* O vídeo só ocupa o quadro quando a mídia está em modo vídeo. Em modo foto
   ele nem é observado — o script ignora elemento sem caixa. */
.sp-midia[data-midia="foto"] > video { display: none; }

/* --- campo de formulário ---------------------------------------------------
   Um campo só, colado ao botão, no formato do kit. Herda a superfície: dentro
   de bloco escuro o contorno vem de `currentColor`, então não há variante. */

.sp-campo {
  display: flex;
  align-items: center;
  gap: var(--sp-e-2);
  width: min(28rem, 100%);
  padding: 5px 5px 5px var(--sp-e-5);
  border: 1px solid color-mix(in srgb, currentColor 26%, transparent);
  border-radius: var(--sp-raio-botao);
  transition: border-color var(--sp-transicao);
}
.sp-campo:focus-within { border-color: currentColor; }

.sp-campo input {
  flex: 1 1 auto;
  min-width: 0;
  padding-block: var(--sp-e-3);
  border: 0;
  background: none;
  color: inherit;
  font-family: var(--sp-fonte-texto);
  font-size: var(--sp-t-peq);
}
.sp-campo input::placeholder { color: var(--sp-tinta-3); }
.sp-campo input:focus { outline: none; }

.sp-campo .sp-botao { flex: 0 0 auto; }

/* --- título de seção --------------------------------------------------------
   Um só, em componentes, porque toda seção tem um. Antes cada seção definia o
   seu (`.sp-artistas__titulo`, `.sp-shows__titulo`, `.sp-videos__titulo`), e usar
   o título de uma seção em outra página exigia carregar o CSS dela inteiro —
   quando isso não acontecia, o título perdia o estilo. */

.sp-titulo {
  font-size: var(--sp-t-h2);
}

/* --- migalha ---------------------------------------------------------------
   O caminho de volta no topo das páginas internas. */

.sp-migalha {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-e-2);
  margin-block-end: var(--sp-e-4);
  color: var(--sp-tinta-2);
  font-size: var(--sp-t-peq);
  transition: color var(--sp-transicao), gap var(--sp-transicao);
}
.sp-migalha:hover { color: var(--sp-tinta); gap: var(--sp-e-3); }

/* --- cartão de apoio --------------------------------------------------------
   Caixa contornada com título, texto e ação. Aparece ao lado do conteúdo
   principal em mais de uma página — na do show apresenta o artista, na do post
   chama para a contratação. Por isso mora aqui, e não no CSS de uma delas. */

.sp-cartao {
  display: grid;
  gap: var(--sp-e-4);
  padding: var(--sp-e-6);
  border: 1px solid var(--sp-linha-clara);
  border-radius: var(--sp-raio-bloco);
}

.sp-cartao__foto {
  border-radius: var(--sp-raio-peq);
  aspect-ratio: 16 / 10;
}

.sp-cartao__titulo {
  font-family: var(--sp-fonte-titulo);
  font-size: var(--sp-t-h3);
  font-weight: 600;
  line-height: 1.15;
}

.sp-cartao__texto {
  margin-block-start: var(--sp-e-2);
  color: var(--sp-tinta-2);
  font-size: var(--sp-t-peq);
}

.sp-cartao__acoes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-e-3);
}
.sp-cartao__acoes .sp-botao { flex: 1 1 auto; justify-content: center; }

/* --- carrossel --------------------------------------------------------------
   A casca do carrossel: topo com setas e trilho com encaixe. Usada por seis
   seções — agenda, artistas, vídeos, discografia, fotos e notícias — então
   mora aqui. Enquanto vivia em `shows.css`, qualquer página que usasse
   carrossel sem carregar aquele arquivo perdia as setas e a rolagem.

   Cada seção define a largura da célula pelo `grid-auto-columns` próprio.
   ========================================================================== */

.sp-shows[data-exibicao="carrossel"] .sp-shows__foto,
.sp-shows[data-exibicao="carrossel"] .sp-shows__lista { display: none; }

.sp-shows[data-exibicao="lista"] .sp-carrossel { display: none; }

.sp-carrossel__topo {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-e-4);
  margin-block-end: var(--sp-e-5);
}

.sp-carrossel__setas { display: flex; gap: var(--sp-e-2); }

/* O `hidden` do HTML só define `display: none` na folha do navegador, que
   perde para qualquer `display` declarado em seletor de classe. Sem esta
   linha, o par de setas continua visível quando o script o esconde. */
.sp-carrossel__setas[hidden] { display: none; }

/* No toque a seta não serve para nada: o dedo arrasta o trilho direto, e a
   fração de célula que sobra na borda já avisa que há mais coisa. O par ocupa
   5,5 rem de uma tela de 360 px e, sem ponteiro, nunca recebe hover — fica
   como enfeite que rouba espaço do título da seção.

   Vale para todos os carrosséis do site: artistas, agenda, vídeos, discografia,
   fotos, loja e notícias. O script continua rodando e as setas voltam sozinhas
   se a janela crescer. */
@media (hover: none), (pointer: coarse) {
  .sp-carrossel__setas { display: none; }
}

.sp-seta {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: 1px solid var(--sp-linha-clara);
  border-radius: var(--sp-raio-botao);
  background: transparent;
  color: inherit;
  font-size: 1.25rem;
  line-height: 0;
  cursor: pointer;
  transition: border-color var(--sp-transicao), background var(--sp-transicao),
              opacity var(--sp-transicao);
}
.sp-seta:hover { border-color: currentColor; }
.sp-seta[disabled] { opacity: .3; cursor: default; }
.sp-seta[disabled]:hover { border-color: var(--sp-linha-clara); }

/* A largura da célula é calculada a partir de quantas devem caber na tela,
   e não por `minmax`. Com `minmax` as células encolhem para caber e o trilho
   nunca estoura a largura — ou seja, nunca rola.

   `--sp-visiveis` aceita fração de propósito: 4,3 mostra quatro inteiras e um
   pedaço da quinta, que é o que avisa que existe mais coisa. Cada seção
   sobrescreve esse número; ninguém mexe no cálculo. */
.sp-carrossel__trilho {
  --sp-vao: var(--sp-e-4);
  --sp-visiveis: 4.3;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc(
    (100% - (var(--sp-visiveis) - 1) * var(--sp-vao)) / var(--sp-visiveis)
  );
  gap: var(--sp-vao);

  /* OS DOIS EIXOS SÃO DECLARADOS, e o `hidden` do vertical é o que resolve a
     briga com a rolagem da página.
     -------------------------------------------------------------------------
     Pela especificação, quando um eixo do `overflow` não é `visible`, o OUTRO
     deixa de poder ser `visible` e computa `auto`. Escrever só `overflow-x:
     auto` não faz um trilho horizontal: faz um trilho que também rola na
     VERTICAL. Bastam os 2px de `padding-block` mais um subpixel de altura para
     ele ganhar um ou dois pixels de curso — e aí a roda do mouse sobre o
     carrossel move esses dois pixels em vez de mover a página. É a sensação de
     que há dois scrolls disputando: há mesmo.

     `hidden` no vertical corta no limite do padding, e os 2px de folga que
     existem para o anel de foco continuam dentro dele. Nada muda na aparência. */
  overflow-x: auto;
  overflow-y: hidden;

  /* Sem isto, chegar ao fim do trilho repassa o restante do gesto para a
     página — e no trackpad do macOS vira o gesto de voltar do navegador. */
  overscroll-behavior-x: contain;

  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
  /* A sombra do card e o foco não podem ser cortados pelo overflow. */
  padding-block: 2px;
  margin-inline: -2px;
  padding-inline: 2px;
}
.sp-carrossel__trilho::-webkit-scrollbar { display: none; }

@media (prefers-reduced-motion: reduce) {
  .sp-carrossel__trilho { scroll-behavior: auto; }
}

/* Sangria à direita no celular — para TODO carrossel do site.
   ---------------------------------------------------------------------------
   O trilho vive dentro do recuo lateral do site, e no celular os 24px da
   direita são desperdício: recuo serve para separar o conteúdo da borda, mas o
   que está na borda de um carrossel é uma célula CORTADA, que já comunica "tem
   mais" sem precisar de respiro.

   Devolvendo esse espaço ao trilho, toda célula ganha cerca de 7% de largura
   sem que nenhum carrossel mostre menos itens. À esquerda o recuo fica: é o
   que mantém a primeira célula alinhada com o título da seção.

   Aqui e não em cada folha porque eram sete lugares para escrever a mesma
   coisa — e sete lugares para esquecer no próximo carrossel que aparecer. */
@media (max-width: 48rem) {
  .sp-carrossel__trilho {
    margin-inline-end: calc(var(--sp-margem) * -1);
    padding-inline-end: var(--sp-margem);
  }
}


/* --- estado vazio ------------------------------------------------------------
   Tela vazia é convite para agir, não aviso de erro: diz o que aconteceu e
   oferece a saída. Mesma lógica da 404.

   Toda página de arquivo filtra por GET, e toda combinação de filtros pode
   chegar a zero. A contagem dentro de cada ficha evita a maior parte dessas
   viagens, mas não cobre link antigo nem URL montada na mão.

   A seção declara `data-estado`. Em `vazio` a lista some e este bloco aparece
   — mesmo mecanismo de `data-exibicao`. No Elementor isto NÃO vira controle:
   quem decide é a consulta do WordPress, no `else` do loop.

   Estava em arquivo.css e foi promovido para cá quando passou a ser usado
   também pela documentação, que não carrega aquele arquivo.
   ========================================================================== */

.sp-vazio {
  display: none;
  justify-items: start;
  gap: var(--sp-e-4);
  padding-block: var(--sp-e-9);
  max-width: 46ch;
}

[data-estado="vazio"] .sp-vazio { display: grid; }

[data-estado="vazio"] .sp-artistas__grade,
[data-estado="vazio"] .sp-loja__grade,
[data-estado="vazio"] .sp-blog__grade,
[data-estado="vazio"] .sp-fotos__grade,
[data-estado="vazio"] .sp-shows__lista,
[data-estado="vazio"] .sp-carrossel { display: none; }

.sp-vazio i { font-size: 2rem; color: var(--sp-tinta-3); }

.sp-vazio__titulo {
  font-family: var(--sp-fonte-titulo);
  font-size: var(--sp-t-h3);
  font-weight: 600;
}

.sp-vazio__texto { color: var(--sp-tinta-2); }

.sp-vazio__acoes {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-e-3);
}

/* --- selo: estados do show ---------------------------------------------------
   Confirmado é o estado silencioso: cinco selos iguais em sequência viram
   textura, não informação. Os estados abaixo existem porque mudam o que a
   pessoa faz a seguir — comprar, esperar aviso ou parar de esperar.

   Adiado e cancelado não somem da agenda: quem viu a data precisa encontrar o
   aviso onde procurou a data. */

.sp-selo--esgotado {
  border-color: color-mix(in srgb, var(--sp-tinta) 24%, transparent);
  color: var(--sp-tinta-2);
}

.sp-selo--adiado {
  border-color: color-mix(in srgb, var(--sp-acento) 46%, transparent);
  color: var(--sp-acento-texto);
}

.sp-selo--cancelado {
  border-color: color-mix(in srgb, var(--sp-tinta) 24%, transparent);
  color: var(--sp-tinta-3);
  text-decoration: line-through;
}

/* ==========================================================================
   Campo de formulário
   --------------------------------------------------------------------------
   Estava em `contato.css`, mas a área do contratante também usa — e ela não
   carrega aquela folha, porque não tem nada a ver com a página de contato.
   Componente usado por duas páginas mora aqui, mesma regra do carrossel.
   ========================================================================== */

.sp-campo-bloco { display: grid; gap: var(--sp-e-2); }
.sp-campo-bloco--largo { grid-column: 1 / -1; }

.sp-campo-bloco__rotulo {
  font-size: var(--sp-t-peq);
  font-weight: 600;
}
.sp-campo-bloco__rotulo span { color: var(--sp-acento-texto); }

/* A linha de apoio de um campo. Nasceu no alcance do credenciamento, onde a
   regra de preenchimento não cabe no rótulo e não pode virar `placeholder`:
   placeholder some no instante em que a pessoa escolhe, e é aí que a dúvida
   ("a audiência da rádio ou a do meu perfil?") aparece.

   Fica DEPOIS do controle, e não entre rótulo e campo: entre os dois ela
   empurra o campo para longe do nome dele e quebra a leitura de cima para
   baixo de um formulário inteiro. */
.sp-campo-bloco__ajuda {
  margin: 0;
  font-size: var(--sp-t-mini);
  color: var(--sp-tinta-2);
}

/* Um controle só para entrada, seleção e área de texto: o desenho é o mesmo e
   separar em três regras é onde a diferença começa a aparecer sozinha. */
.sp-campo-bloco input,
.sp-campo-bloco select,
.sp-campo-bloco textarea {
  width: 100%;
  padding: var(--sp-e-4);
  border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
  border-radius: var(--sp-raio);
  background: transparent;
  color: inherit;
  font-family: var(--sp-fonte-texto);
  font-size: var(--sp-t-peq);
  transition: border-color var(--sp-transicao);
}
.sp-campo-bloco textarea { min-height: 9rem; resize: vertical; }

.sp-campo-bloco input::placeholder,
.sp-campo-bloco textarea::placeholder { color: var(--sp-tinta-3); }

.sp-campo-bloco input:focus,
.sp-campo-bloco select:focus,
.sp-campo-bloco textarea:focus {
  outline: none;
  border-color: var(--sp-acento);
}

/* A seta do `select` é do navegador e some no fundo escuro. */
.sp-campo-bloco select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.25rem) 55%, calc(100% - 1rem) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-inline-end: var(--sp-e-8);
}
.sp-campo-bloco select option { background: var(--sp-fundo); color: var(--sp-texto); }

/* --- isca de robô ----------------------------------------------------------
   Campo que existe só no HTML: robô preenche tudo o que encontra, pessoa
   nenhuma vê nem alcança. Não usa `display: none` nem `hidden` porque robô
   que se dá ao trabalho de olhar o CSS pula os dois; sai da tela de verdade.

   O `aria-hidden` e o `tabindex="-1"` vêm do JavaScript que o injeta, e são o
   que o mantêm fora do caminho de quem usa leitor de tela ou teclado.
   --------------------------------------------------------------------------- */
.sp-isca {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- campo que chegou preenchido -------------------------------------------
   Artista, cidade e local vêm na querystring do botão "Contratar" da página
   anterior. O fio à esquerda diz "isto veio pronto, confira" — sem travar
   nada: o campo continua editável, e quem chegou por outro caminho não vê
   diferença nenhuma. */
[data-vindo-da-url="sim"] {
  border-inline-start: 2px solid var(--sp-acento-texto);
}

/* --- assinar a agenda ------------------------------------------------------
   Mora nos componentes porque é usado por duas páginas: o arquivo da agenda,
   com o feed do artistas inteiro, e a página do artista, com o dele. Mesma
   regra do carrossel e do campo em bloco.

   Fica alinhado à esquerda e não ganha destaque de bloco: assinar é ação de
   quem já decidiu acompanhar, não a conversão da página.
   --------------------------------------------------------------------------- */
.sp-assinar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-e-3) var(--sp-e-5);
  margin-block-end: var(--sp-e-6);
}

.sp-assinar__apoio {
  color: var(--sp-tinta-3);
  font-size: var(--sp-t-peq);
  line-height: 1.5;
  max-width: 34ch;
}

/* --- item de material ------------------------------------------------------
   Uma linha de arquivo: ícone do formato, nome, formato e peso, e a seta de
   ação. Veio de `contratante.css` na 0.55.0, quando a página de imprensa
   passou a usar o mesmo item — e ela não carrega a folha do contratante.

   O recuo e o raio são de ITEM, não de bloco: cinco linhas de arquivo com
   raio de bloco viram uma parede de botões, e a linha de arquivo não é uma
   chamada para ação.
   --------------------------------------------------------------------------- */
.sp-item-material {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--sp-e-3);
  align-items: center;
  padding: var(--sp-e-4);
  border: 1px solid var(--sp-linha-clara);
  border-radius: var(--sp-raio);
  transition: border-color var(--sp-transicao), background var(--sp-transicao);
}
.sp-item-material:hover {
  border-color: currentColor;
  background: color-mix(in srgb, currentColor 4%, transparent);
}

.sp-item-material > i:first-child { font-size: 1.25rem; color: var(--sp-acento-texto); }
.sp-item-material > i:last-child { font-size: 1rem; color: var(--sp-tinta-3); }

/* `display: block` nos dois: são `<span>` dentro de `<span>`, e em linha eles
   fluem na mesma linha — o nome e o formato saíam grudados num parágrafo só,
   e o `margin-block-start` da meta não valia. */
.sp-item-material__nome {
  display: block;
  font-weight: 600;
  font-size: var(--sp-t-peq);
}
.sp-item-material__meta {
  display: block;
  margin-block-start: 2px;
  color: var(--sp-tinta-3);
  font-size: var(--sp-t-mini);
}

/* --- subgrupo por assunto --------------------------------------------------
   Rótulo miúdo que separa imagem, texto, áudio e documento dentro de uma
   lista de material. Veio de `contratante.css` na 0.55.0, quando a página de
   imprensa passou a agrupar do mesmo jeito.

   Bloco com um assunto só não ganha subgrupo: rotular "Documentos" uma lista
   que só tem documentos repete o que a lista inteira já diz. */
.sp-subgrupo__titulo {
  margin-block-end: var(--sp-e-3);
  color: var(--sp-tinta-3);
  font-family: var(--sp-fonte-texto);
  font-size: var(--sp-t-mini);
  font-weight: 500;
}

/* --- retorno de formulário -------------------------------------------------
   Região `role="status"` que já existe vazia no HTML desde o carregamento —
   região criada no momento do envio não é anunciada de forma confiável. Veio
   de `contato.css` na 0.57.0, quando o credenciamento de imprensa passou a
   usar a mesma peça. */
.sp-forma__retorno:empty { display: none; }

.sp-forma__retorno {
  margin-block-start: var(--sp-e-5);
  padding: var(--sp-e-3) var(--sp-e-4);
  border-inline-start: 2px solid var(--sp-linha);
  font-size: var(--sp-t-peq);
  color: var(--sp-texto-2);
}

.sp-forma__retorno[data-tom="certo"] { border-inline-start-color: var(--sp-acento); }
.sp-forma__retorno[data-tom="erro"]  { border-inline-start-color: var(--sp-acento); color: var(--sp-texto); }

/* --- cartão de credenciado -------------------------------------------------
   Material que aparece sem explicação faz a pessoa duvidar se pode usar. O
   rótulo responde antes de ela perguntar. */
.sp-cartao__rotulo {
  display: flex;
  align-items: center;
  gap: var(--sp-e-2);
  margin-block-end: var(--sp-e-2);
  color: var(--sp-acento-texto);
  font-size: var(--sp-t-mini);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.sp-cartao__saida {
  margin-block-start: var(--sp-e-4);
  padding: 0;
  border: 0;
  background: none;
  color: var(--sp-tinta-3);
  font-family: inherit;
  font-size: var(--sp-t-peq);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, currentColor 45%, transparent);
  cursor: pointer;
}

.sp-cartao__saida:hover { color: var(--sp-tinta-2); }


/* ==========================================================================
   Últimas atualizações — o registro do que andou acontecendo
   --------------------------------------------------------------------------
   Veio de `contratante.css` na 0.52.0, quando a área de imprensa passou a
   usá-lo para a trilha do credenciamento. Componente usado por duas áreas mora
   no arquivo que as duas carregam.

   Ele NÃO é menu nem navegação: é a resposta para "perdi alguma coisa desde
   que estive aqui?".
   ========================================================================== */

/* `sticky` porque na área do contratante a lista de shows pode ser longa e a
   coluna é curta — sem isso ela sai da tela no primeiro rolar e vira decoração
   do topo. Na área de imprensa ele é anulado, em `imprensa.css`: lá o bloco
   está dentro de uma caixa centrada, e grudar não significa nada. */
.sp-novidades {
  position: sticky;
  inset-block-start: var(--sp-e-5);
  padding: var(--sp-e-5);
  border: 1px solid var(--sp-linha-clara);
  border-radius: var(--sp-raio-cartao);
  background: var(--sp-papel);
}

.sp-novidades__titulo {
  margin-block-end: var(--sp-e-4);
  color: var(--sp-tinta-3);
  font-family: var(--sp-fonte-texto);
  font-size: var(--sp-t-mini);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.sp-novidades__lista { display: grid; margin: 0; padding: 0; list-style: none; }

.sp-novidade {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--sp-e-3);
  padding-block: var(--sp-e-3);
  color: inherit;
  text-decoration: none;
}
.sp-novidades__lista li + li .sp-novidade { border-block-start: 1px solid var(--sp-linha-clara); }
.sp-novidade:hover .sp-novidade__oque { color: var(--sp-acento-texto); }

/* O ponto é o menor marcador possível, e é o suficiente: a lista é curta e
   ícone por linha viraria uma coluna de símbolos disputando com o texto. Só o
   que ainda COBRA alguma coisa ganha o acento. */
.sp-novidade__ponto {
  inline-size: .4375rem;
  block-size: .4375rem;
  margin-block-start: .45rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--sp-tinta) 24%, transparent);
}
.sp-novidade__ponto--acao { background: var(--sp-acento); }

.sp-novidade__corpo { display: flex; flex-direction: column; gap: 1px; min-inline-size: 0; }
.sp-novidade__oque { font-size: var(--sp-t-peq); font-weight: 600; line-height: 1.3; }
.sp-novidade__onde { color: var(--sp-tinta-3); font-size: var(--sp-t-mini); }

/* O "quando" não quebra linha: ele é curto e é a âncora da leitura em diagonal. */
.sp-novidade__quando {
  color: var(--sp-tinta-3);
  font-size: var(--sp-t-mini);
  white-space: nowrap;
  padding-block-start: 1px;
}

/* --- sobre superfície escura -----------------------------------------------
   O bloco declara fundo próprio, e componente com fundo próprio TEM de dizer o
   que faz no escuro. Sem isto ele leva o branco para dentro do bloco escuro
   enquanto as variáveis de texto já foram remapeadas para claro — e o
   resultado é um retângulo branco com texto branco dentro, onde só o ponto de
   acento sobrevive.

   Aconteceu de verdade, na trilha do credenciamento: a tela inteira ficou
   ilegível e nada acusou, porque as regras existem e as cores são válidas.

   Aqui o cartão abre mão do fundo e fica só com a borda: dentro de um bloco
   escuro não há o que separar do papel, e a moldura já dá o recorte. */
.sp-escuro .sp-novidades {
  background: transparent;
  border-color: var(--sp-linha);
}

.sp-novidades__pe {
  margin-block-start: var(--sp-e-4);
  padding-block-start: var(--sp-e-3);
  border-block-start: 1px solid var(--sp-linha-clara);
  color: var(--sp-tinta-3);
  font-size: var(--sp-t-mini);
}

/* Sozinha — coluna sem nenhum evento —, a nota perde o fio: não há lista acima
   dela para separar. É o estado normal de uma instalação nova, e não um erro:
   o registro de eventos começa vazio e só enche com o uso. */
.sp-novidades__pe--so { margin-block-start: 0; padding-block-start: 0; border-block-start: 0; }

/* --- selo de confirmação ---------------------------------------------------
   O traço que se desenha quando algo deu certo: assinatura enviada, endereço
   confirmado.

   Não é ícone do Phosphor. Os ícones do projeto são caminhos PREENCHIDOS, e
   caminho preenchido não se desenha — só aparece. Aqui o círculo e o risco são
   contorno, e é o contorno que permite `stroke-dasharray` riscar do começo ao
   fim. Por isso este SVG é escrito à mão no template em vez de sair da folha.

   O movimento tem trabalho a fazer: marca a passagem de "eu enviei" para
   "chegou". Um ícone que simplesmente aparece no mesmo quadro do texto é lido
   como decoração dele, e não como resposta ao que a pessoa acabou de fazer.

   Quem pediu menos movimento recebe o selo inteiro, parado, no primeiro
   quadro. O estado final é igual dos dois lados — a animação nunca é o que
   informa, só o que chama atenção para a informação.
   ------------------------------------------------------------------------- */

.sp-certo {
  inline-size: 3.5rem;
  block-size: 3.5rem;
  color: var(--sp-acento-texto);
  flex: 0 0 auto;
}

.sp-certo__circulo,
.sp-certo__risco {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sp-certo__circulo {
  stroke-width: 2;
  stroke-dasharray: 151;
  stroke-dashoffset: 151;
  animation: sp-certo-risca 520ms cubic-bezier(.65, 0, .35, 1) forwards;
}

.sp-certo__risco {
  stroke-width: 3;
  stroke-dasharray: 36;
  stroke-dashoffset: 36;
  animation: sp-certo-risca 260ms cubic-bezier(.65, 0, .35, 1) 380ms forwards;
}

@keyframes sp-certo-risca {
  to { stroke-dashoffset: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .sp-certo__circulo,
  .sp-certo__risco {
    stroke-dashoffset: 0;
    animation: none;
  }
}

.sp-cred__tipos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-e-2) var(--sp-e-5);
  margin: var(--sp-e-4) 0 0;
  padding: 0;
  list-style: none;
}

.sp-cred__tipo {
  display: flex;
  align-items: baseline;
  gap: var(--sp-e-2);
  font-size: var(--sp-t-peq);
}

.sp-cred__tipo-nome { color: var(--sp-tinta-2); }

.sp-cred__tipo-vaga {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--sp-acento-texto);
}

/* Esgotado continua na lista, apagado — mesma decisão do material com prazo
   logo abaixo nesta página. Sumir faria o jornalista achar que aquele tipo não
   existe e perguntar por fora. */
.sp-cred__tipo-vaga--fim { color: var(--sp-tinta-3); font-weight: 500; }

/* Um tipo por linha no celular, com a vaga encostada na direita. Lado a lado
   numa coluna estreita o nome quebra em duas linhas e a vaga fica pendurada no
   meio do texto — a comparação entre os tipos, que é o motivo da lista, some. */
@media (max-width: 48rem) {
  .sp-cred__tipos { flex-direction: column; gap: var(--sp-e-2); }
  .sp-cred__tipo { width: 100%; justify-content: space-between; }
}

/* ==========================================================================
   FILA DE PEDIDOS DE CREDENCIAL — `.sp-pedido` e a cota (0.105.0)
   --------------------------------------------------------------------------
   Veio de `producao.css` porque a mesma fila passou a aparecer na área do
   contratante: **componente usado em duas páginas não mora no CSS de uma
   delas.** É a decisão da 0.104.0 com `.sp-cred__tipos`, e antes dela com
   `.sp-data` e `.sp-selo`.

   O que ficou em `producao.css` é o que é do painel e não do componente:
   `.sp-fila__acoes`, que são as ações do EVENTO — cobrar, assumir — e não as
   de um pedido.
   ========================================================================== */

/* --- fila de credenciamento -------------------------------------------------
   Cada pedido traz tudo o que a pessoa declarou, junto. Aprovar sem ver o
   endereço do veículo é aprovar no escuro, e abrir a ficha para depois voltar
   é o que faz a fila parar de ser processada. */

.sp-pedidos { display: grid; gap: var(--sp-e-4); }

/* AS TRÊS COLUNAS SÃO FIXAS, e a das ações tem largura declarada.
   ---------------------------------------------------------------------------
   Com `auto` na terceira, cada cartão decidia a própria grade a partir do que
   tinha dentro: a nota do pedido esgotado alargava as ações, espremia a coluna
   do meio, e a ficha caía de quatro campos numa linha para três mais um. Dois
   cartões vizinhos ficavam com os rótulos em posições diferentes, e a fila
   deixava de ser lista para virar uma pilha de cartões parecidos.

   Numa fila, alinhamento não é estética: o olho compara os pedidos varrendo a
   MESMA coluna para baixo. Se "Pediu" muda de lugar a cada linha, não há
   varredura — há leitura, um cartão de cada vez.

   `start` e não `center` pelo mesmo motivo: com alturas diferentes, o conteúdo
   centralizado flutua, e nem o nome do veículo nem o primeiro botão começam na
   mesma altura em dois cartões seguidos. */
.sp-pedido {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr) 13rem;
  gap: var(--sp-e-5);
  align-items: start;
  padding: var(--sp-e-5);
  border: 1px solid var(--sp-linha-clara);
  border-radius: var(--sp-raio-cartao, 16px);
}

.sp-pedido__quem { min-width: 0; }

.sp-pedido__veiculo { font-size: var(--sp-t-corpo); font-weight: 600; }

.sp-pedido__meta {
  margin-block-start: 2px;
  color: var(--sp-tinta-2);
  font-size: var(--sp-t-peq);
}

.sp-pedido__endereco {
  display: inline-block;
  margin-block-start: var(--sp-e-2);
  color: var(--sp-acento-texto);
  font-size: var(--sp-t-peq);
  word-break: break-word;
}

/* OS CAMPOS FICAM SEMPRE NUMA LINHA SÓ, quantos forem.
   ---------------------------------------------------------------------------
   `auto-fit` com `minmax` conta quantas colunas CABEM, e o resultado muda com a
   largura sobrante — que muda de cartão para cartão. `grid-auto-flow: column`
   com colunas iguais conta quantos campos EXISTEM: quatro na área do
   contratante, cinco no painel (que também vê o e-mail), e em qualquer um dos
   dois eles ficam alinhados entre si.

   O preço é campo mais estreito quando há cinco. É o preço certo: o valor
   quebra em duas linhas e continua no lugar, enquanto a coluna que muda de
   posição não tem conserto. */
.sp-pedido__ficha {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: var(--sp-e-3) var(--sp-e-4);
  margin: 0;
}

.sp-pedido__ficha dt {
  color: var(--sp-tinta-3);
  font-size: var(--sp-t-mini);
  font-weight: 500;
}

.sp-pedido__ficha dd {
  margin: 0;
  margin-block-start: 2px;
  font-size: var(--sp-t-peq);
  word-break: break-word;
}

/* Os botões ocupam a coluna inteira, e por isso saem todos do mesmo tamanho —
   dentro do cartão e entre cartões. Larguras por conteúdo dariam uma escada de
   botões, e a escada sugere hierarquia onde não há: "Recusar" não é menos
   importante que "Aprovar em outro tipo" por ter menos letras. */
.sp-pedido__acoes {
  display: flex;
  flex-direction: column;
  gap: var(--sp-e-2);
}
.sp-pedido__acoes .sp-botao { justify-content: center; width: 100%; }

/* Abaixo de 60rem as três colunas viram uma, e a ficha passa a DUAS colunas
   fixas — não a uma por campo, que faria o cartão crescer cinco linhas, nem a
   `auto-fit`, que traria de volta a contagem variável que esta regra existe
   para eliminar. */
@media (max-width: 60rem) {
  .sp-pedido { grid-template-columns: 1fr; }
  .sp-pedido__ficha {
    grid-auto-flow: row;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .sp-pedido__acoes { flex-direction: row; }
  .sp-pedido__acoes .sp-botao { width: auto; }
}

/* A cota INTEIRA, com denominador — ao contrário do lado do jornalista, que vê
   só o estado. Quem decide precisa saber quanto falta; quem pede, não: para
   ele o número vira corrida. */
.sp-cotas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-e-2) var(--sp-e-5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.sp-cota {
  display: flex;
  align-items: baseline;
  gap: var(--sp-e-2);
  font-size: var(--sp-t-peq);
  color: var(--sp-tinta-2);
}
.sp-cota b { color: var(--sp-tinta); font-variant-numeric: tabular-nums; }
.sp-cota .sp-cota--fim { color: var(--sp-acento-texto); }

/* A marca de prazo estourado. É de TEMPO e não de gravidade: não acusa
   ninguém, só diz o que a agência prometeu e onde o pedido está. Sem ela o
   prazo configurável é promessa que nada cobra. */
/* Abaixo de 60rem as ações viram fileira, e sem `wrap` elas empurravam o
   cartão para fora da janela: a triagem de show tem QUATRO botões — aprovar,
   aprovar em outro tipo, pedir informação e recusar —, contra dois da fila de
   acesso. O componente foi desenhado com dois e nunca viu quatro. */
.sp-pedido__acoes { flex-wrap: wrap; }

.sp-pedido__prazo { margin-block-start: var(--sp-e-3); }
.sp-pedido__nota { margin-block-start: var(--sp-e-2); }

.sp-pedido[data-atrasado] { border-color: var(--sp-acento-texto); }

.sp-pedido__prazo {
  display: flex;
  align-items: center;
  gap: var(--sp-e-2);
  color: var(--sp-acento-texto);
  font-size: var(--sp-t-mini);
  font-weight: 600;
}
.sp-pedido__prazo .sp-i { width: 1em; height: 1em; }

.sp-pedido__nota {
  color: var(--sp-tinta-2);
  font-size: var(--sp-t-mini);
}

/* ==========================================================================
   BANNER INSTITUCIONAL
   --------------------------------------------------------------------------
   Veio de `imprensa.css` na 0.67.2, e a mudança consertou um defeito real: o
   banner passou a aparecer em catorze posições, e `imprensa.css` só é
   enfileirada na sala de imprensa. Em toda outra página ele saía SEM FOLHA
   NENHUMA — sem proporção, sem `object-fit`, sem as setas —, e a arte esticava
   na altura natural do arquivo.

   É a terceira vez que esta regra aparece nesta rodada: **componente usado em
   mais de uma página não mora no CSS de uma delas.** Antes foi `.sp-cred__tipos`
   e depois `.sp-pedido`.
   ========================================================================== */

/* --- banner institucional --------------------------------------------------
   Peça por dispositivo, trocada por media query e não por recorte: o texto
   mora dentro da arte, e cortar o centro de uma peça larga corta a frase.

   As proporções estão fixadas aqui porque é em cima delas que a equipe de arte
   trabalha — 4:1 no desktop, 4:3 no celular. Trocar depois significa refazer
   peça, então é decisão de agora e não de implementação.

   É um `<picture>` com `<source media>`: a escolha acontece antes de o
   navegador pedir o arquivo, e a peça que não vale nunca é baixada. Esconder
   com `display` trocaria um problema de layout por um de rede — e o de rede
   não aparece na tela de quem testa. */

/* O bloco só existe quando há peça: o template não imprime nada sem banner
   válido, então esta regra nunca desenha caixa vazia. A margem é dele e não do
   irmão de cima — margem no vizinho sobraria nos dias em que não há banner. */
/* O RESPIRO É NOS DOIS LADOS, porque o bloco passou a viver ENTRE conteúdos —
   entre duas seções da home, ou entre o fim da página e o rodapé. Com margem só
   embaixo ele encostava no que vinha antes e parecia continuação daquilo.

   SUBIU DE `--sp-e-7` PARA `--sp-e-8` NA 0.67.6 (48px a 72px, contra 36px a
   52px). O `e-7` foi calibrado quando o banner ainda vinha depois de uma seção
   com folga própria; na página do artista a última seção montada nem sempre tem
   `padding-block-end`, e ali a peça encostava. O token maior resolve os dois
   casos sem uma regra por template — e continua respondendo à largura da tela,
   que um valor fixo em pt não faria. */
.sp-banner {
  position: relative;
  display: block;
  margin-block: var(--sp-e-8);
}

/* Só a peça visível ocupa espaço: as outras têm `hidden`, que é o que impede o
   navegador de baixar a arte delas — imagem `lazy` dentro de elemento sem caixa
   de layout nunca entra na janela de visão. É esta linha que sustenta a decisão
   de pôr todas as peças no HTML. */
/* O empilhador das peças. Não é grade nem carrossel: só a peça visível existe
   no fluxo, e a troca é feita pelo `hidden` de cada uma. Um trilho com todas
   lado a lado colocaria as artes escondidas dentro da janela de visão, e aí o
   `lazy` não seguraria o download de nenhuma. */
.sp-banner__pecas { display: block; }

.sp-banner__slide[hidden] { display: none; }

/* AS SETAS FICAM SOBRE A ARTE, no canto inferior direito, e não numa barra
   acima. O banner não tem título nem topo onde ancorá-las, e uma barra só para
   elas acrescentaria altura a um bloco cujo assunto é a arte.

   Elas NÃO somem no toque, ao contrário das do carrossel: lá o dedo arrasta o
   trilho e a seta é redundante; aqui não há o que arrastar, e escondê-las no
   celular deixaria a segunda peça inalcançável justamente para a maioria. */
.sp-banner__setas {
  position: absolute;
  inset-block-end: var(--sp-e-3);
  inset-inline-end: var(--sp-e-3);
  display: flex;
  align-items: center;
  gap: var(--sp-e-2);
  padding: var(--sp-e-2);
  border-radius: var(--sp-raio-botao);

  /* Véu sob os controles. Quem escolhe a arte é a equipe da Paulinas, e uma
     peça de fundo claro deixaria as setas invisíveis — o mesmo defeito que o
     topo sobre fotografia teve na 0.59.8. */
  background: color-mix(in srgb, var(--sp-fundo) 62%, transparent);
  color: var(--sp-claro);
}
.sp-banner__setas[hidden] { display: none; }

.sp-banner__setas .sp-seta {
  width: 2.25rem;
  height: 2.25rem;
  border-color: color-mix(in srgb, currentColor 45%, transparent);
}
.sp-banner__setas .sp-seta:hover { border-color: currentColor; }

.sp-banner__conta {
  font-size: var(--sp-t-mini);
  font-variant-numeric: tabular-nums;
}

.sp-banner__peca { display: block; }

.sp-banner__arte {
  display: block;
  border-radius: var(--sp-raio-cartao);
  overflow: hidden;
}

/* A CAIXA TEM PROPORÇÃO FIXA, e a arte preenche.
   ---------------------------------------------------------------------------
   4:1 no desktop, 4:3 no celular — as duas validadas no protótipo com arte real,
   e é em cima delas que a equipe de arte trabalha.

   **Isto foi removido na 0.67.3 e voltou na 0.67.4**, e o registro do vaivém
   importa mais do que a regra. Tirei a proporção para resolver um banner que
   aparecia alto demais, supondo que o arquivo estivesse fora de medida. Sem ela
   o bloco passa a ser "o que o arquivo for" — e aí ele deixa de parecer um
   banner e passa a parecer uma imagem solta no meio da página, que foi o
   resultado.

   **Uma decisão validada no protótipo não se desfaz para perseguir um sintoma.**
   Se o arquivo está fora de medida, quem avisa é o painel — e ele avisa desde a
   1.57.3.

   O ponto de corte é o MESMO do `media` do `<picture>`: separados, existe uma
   faixa de larguras em que a arte de celular cai numa caixa 4:1 e o `cover` come
   metade dela. */
.sp-banner__arte { aspect-ratio: 4 / 1; }

@media (max-width: 48rem) {
  .sp-banner__arte { aspect-ratio: 4 / 3; }
}

/* `cover` e não `contain`: com a arte na medida, a proporção do arquivo é a
   mesma da caixa e não há o que cortar. `contain` deixaria faixa vazia no
   primeiro arquivo que viesse com um pixel de diferença — e o defeito sairia do
   painel para a tela de quem visita. */
.sp-banner__arte img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
