/* ==========================================================================
   components.css · Brasil Scat Comunidade V3 · requer tokens.css
   Regras: nenhum componente declara cor, espaço, raio ou tamanho próprio; tudo vem de tokens.
   Prefixo bs-. Estado desabilitado = atributo HTML, nunca classe.
   ========================================================================== */

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

/* Ícone (átomo): <span class="bs-icon bs-icon--nome" aria-hidden="true"></span>. Carregue icons.css (gerado por
   gerar-icones.py, uma classe --nome por ícone da Uicons; nome com hífen no lugar de _). O SVG é desenhado por
   mask, na cor do texto (currentColor), no tamanho do font-size (padrão --size-icon-md). Preenchido:
   bs-icon--filled (versão sólida). Sem JavaScript. Nunca desenhar SVG novo. */
:where(.bs-icon) {
  --ico: var(--ico-r);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  font-size: var(--size-icon-md);
  line-height: 1;
}
.bs-icon::before {
  content: '';
  display: block;
  flex: none;
  width: var(--ico-scale, 1em);
  height: var(--ico-scale, 1em);
  background: currentColor;
  -webkit-mask: var(--ico) center / contain no-repeat;
  mask: var(--ico) center / contain no-repeat;
  transform: rotate(var(--ico-rot, 0deg));
}
.bs-icon--filled { --ico: var(--ico-s, var(--ico-r)); }

/* Cor da categoria: define --bs-cat para qualquer componente que aceite cor de categoria */
.bs-cat-conversa  { --bs-cat: var(--cat-conversa); }   /* categoria sem classe própria usa a cor da marca (var(--bs-cat, ...)) */
.bs-cat-confissao { --bs-cat: var(--cat-confissao); }
.bs-cat-vontade   { --bs-cat: var(--cat-vontade); }
.bs-cat-duvida    { --bs-cat: var(--cat-duvida); }
.bs-cat-debate    { --bs-cat: var(--cat-debate); }
.bs-cat-enquete   { --bs-cat: var(--cat-enquete); }
.bs-cat-indicacao { --bs-cat: var(--cat-indicacao); }
.bs-cat-procuro   { --bs-cat: var(--cat-procuro); }
.bs-cat-vendo     { --bs-cat: var(--cat-vendo); }

/* Barra de rolagem: fina, rosa e só aparece enquanto se rola (components.js põe .is-scrolling por cerca de 1s).
   Chrome/Safari usam ::-webkit-scrollbar; Firefox usa as propriedades padrão. O trilho é transparente (4px de largura, sem desenho enquanto não se rola). */
::-webkit-scrollbar { width: var(--space-2); height: var(--space-2); }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background-color: transparent; border-radius: var(--radius-pill); transition: background-color var(--duration-slow) var(--ease-standard); }
.is-scrolling::-webkit-scrollbar-thumb { background-color: var(--interactive-accent); }
@supports not selector(::-webkit-scrollbar) {
  * { scrollbar-width: thin; scrollbar-color: transparent transparent; }
  .is-scrolling { scrollbar-color: var(--interactive-accent) transparent; }
}

/* ===== Button ================================================================
   3 eixos independentes, nesta ordem de classes:
   1) HIERARQUIA (obrigatório, 1): --primary · --secondary · --tertiary · --outline
   2) COR (opcional, sobre primary ou outline): --inverse (branco) · --category (usa --bs-cat) · --telegram (azul da marca, só sobre primary)
   3) TAMANHO (opcional): padrão 44 · --sm 36 · --lg 48
   + FORMA (opcional): --pill (pílula, exceção) · --block (largura total). Padrão: cantos 16 (--radius-lg).
   + ESTADO: atributo disabled. Foco: :focus-visible (anel rosa).
   Altura fixa por token, nunca por padding. Sem variante de perigo e sem ghost (decisão).
   ========================================================================== */
.bs-btn {
  --bs-btn-accent: var(--text-brand);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  height: var(--size-control-md);
  padding: 0 var(--space-6);
  box-sizing: border-box;
  font-family: var(--font-corpo);
  font-size: var(--font-size-16);
  font-weight: var(--font-weight-bold);
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  border: 0;
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: background var(--transition-default), color var(--transition-default), box-shadow var(--transition-default);
  -webkit-tap-highlight-color: transparent;
}
.bs-btn:focus-visible,
.bs-btn.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-btn:disabled,
.bs-btn[aria-disabled="true"] { opacity: var(--opacity-disabled); cursor: not-allowed; }

.bs-btn__icon { flex-shrink: 0; font-size: var(--size-icon-sm); }

/* 3) tamanho */
.bs-btn--sm { height: var(--size-control-sm); padding: 0 var(--space-5); font-size: var(--font-size-14); }
.bs-btn--sm .bs-btn__icon { font-size: var(--size-icon-xs); }
.bs-btn--lg { height: var(--size-control-lg); padding: 0 var(--space-7); }

/* forma */
.bs-btn--pill { border-radius: var(--radius-pill); }
.bs-btn--block { display: flex; width: 100%; }

/* 1) hierarquia */
.bs-btn--primary { background: var(--interactive-primary); color: var(--text-on-brand-fill); }
.bs-btn--primary:hover:not(:disabled),
.bs-btn--primary.is-hover { background: var(--interactive-primary-hover); }
.bs-btn--primary:active:not(:disabled),
.bs-btn--primary.is-pressed { background: var(--interactive-primary-active); }

.bs-btn--secondary { background: var(--bg-surface-raised); color: var(--text-primary); }
.bs-btn--secondary:hover:not(:disabled),
.bs-btn--secondary.is-hover { background: var(--bg-surface-overlay); }
.bs-btn--secondary:active:not(:disabled),
.bs-btn--secondary.is-pressed { background: color-mix(in srgb, var(--bg-surface-overlay), var(--white) 10%); }

.bs-btn--tertiary { background: transparent; color: var(--text-secondary); }
.bs-btn--tertiary:hover:not(:disabled),
.bs-btn--tertiary.is-hover { background: var(--bg-surface-raised); color: var(--text-primary); }
.bs-btn--tertiary:active:not(:disabled),
.bs-btn--tertiary.is-pressed { background: var(--bg-surface-overlay); color: var(--text-primary); }

.bs-btn--outline { background: transparent; color: var(--bs-btn-accent); box-shadow: inset 0 0 0 var(--stroke-thin) var(--bs-btn-accent); }
.bs-btn--outline:hover:not(:disabled),
.bs-btn--outline.is-hover { background: color-mix(in srgb, var(--bs-btn-accent) 12%, transparent); }
.bs-btn--outline:active:not(:disabled),
.bs-btn--outline.is-pressed { background: color-mix(in srgb, var(--bs-btn-accent) 22%, transparent); }

/* 2) cor: branco (inverse) e categoria */
.bs-btn--primary.bs-btn--inverse { background: var(--bg-inverse); color: var(--text-inverse); }
.bs-btn--primary.bs-btn--inverse:hover:not(:disabled),
.bs-btn--primary.bs-btn--inverse.is-hover { background: var(--gray-100); }
.bs-btn--primary.bs-btn--inverse:active:not(:disabled),
.bs-btn--primary.bs-btn--inverse.is-pressed { background: var(--gray-200); }

/* ===== Botão social (login) ===================================================
   bs-social-btn: botão de entrar com uma conta de fora. Vai junto de "bs-btn bs-btn--primary bs-btn--lg bs-btn--block" (tamanho e foco são do Button);
   o logo da marca vem do ::before, então o HTML é só o texto. Modificadores: --google (branco, logo colorido) e --telegram (azul da marca, texto e logo brancos).
   Exceções documentadas: o logo é de marca (cores fixas no SVG do Google) e o texto branco sobre o azul do Telegram foge da regra de texto escuro em fundo colorido (pedido do dono, 27/10/2026). */
.bs-social-btn::before { content: ""; flex: none; width: var(--size-icon-md); height: var(--size-icon-md); background: center / contain no-repeat; }
.bs-btn--primary.bs-social-btn--google { background: var(--bg-inverse); color: var(--text-inverse); }
.bs-btn--primary.bs-social-btn--google:hover:not(:disabled) { background: var(--gray-100); }
.bs-btn--primary.bs-social-btn--google:active:not(:disabled) { background: var(--gray-200); }
.bs-social-btn--google::before { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%234285F4' d='M23.5 12.27c0-.85-.08-1.67-.22-2.45H12v4.64h6.45a5.51 5.51 0 0 1-2.39 3.62v3h3.87c2.27-2.09 3.57-5.17 3.57-8.81z'/%3E%3Cpath fill='%2334A853' d='M12 24c3.24 0 5.96-1.07 7.94-2.91l-3.87-3c-1.08.72-2.45 1.15-4.07 1.15-3.13 0-5.78-2.11-6.73-4.96H1.27v3.1A12 12 0 0 0 12 24z'/%3E%3Cpath fill='%23FBBC05' d='M5.27 14.28A7.2 7.2 0 0 1 4.9 12c0-.79.14-1.56.37-2.28v-3.1H1.27A12 12 0 0 0 0 12c0 1.94.46 3.77 1.27 5.38l4-3.1z'/%3E%3Cpath fill='%23EA4335' d='M12 4.75c1.77 0 3.35.61 4.6 1.8l3.43-3.43C17.95 1.19 15.24 0 12 0A12 12 0 0 0 1.27 6.62l4 3.1C6.22 6.86 8.87 4.75 12 4.75z'/%3E%3C/svg%3E"); }
.bs-btn--primary.bs-social-btn--telegram { background: var(--brand-telegram); color: var(--white); }
.bs-btn--primary.bs-social-btn--telegram:hover:not(:disabled) { background: color-mix(in srgb, var(--brand-telegram), var(--black) 12%); }
.bs-btn--primary.bs-social-btn--telegram:active:not(:disabled) { background: color-mix(in srgb, var(--brand-telegram), var(--black) 24%); }
.bs-social-btn--telegram::before { background: currentColor; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z'/%3E%3C/svg%3E") center / contain no-repeat; }

.bs-btn--category { --bs-btn-accent: var(--bs-cat, var(--text-brand)); }
.bs-btn--primary.bs-btn--category { background: var(--bs-cat, var(--interactive-primary)); color: var(--text-on-solid); }
.bs-btn--primary.bs-btn--category:hover:not(:disabled),
.bs-btn--primary.bs-btn--category.is-hover { background: color-mix(in srgb, var(--bs-cat, var(--interactive-primary)), var(--white) 12%); }
.bs-btn--primary.bs-btn--category:active:not(:disabled),
.bs-btn--primary.bs-btn--category.is-pressed { background: color-mix(in srgb, var(--bs-cat, var(--interactive-primary)), var(--white) 24%); }

@media (prefers-reduced-motion: reduce) {
  .bs-btn { transition: none; }
}

/* Grupo de botões (bs-actions): a linha de ações de uma tela ou formulário (ex.: Salvar rascunho + Enviar).
   Desktop: em linha, à direita, na ordem do HTML (secundário antes do primário).
   Celular (< 960): nunca lado a lado; um embaixo do outro, largura total, primário em cima (a ordem visual inverte, a do HTML não). */
.bs-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-3); }
@media (max-width: 959.98px) {
  .bs-actions { flex-direction: column-reverse; align-items: stretch; }
  .bs-actions > .bs-btn { width: 100%; }
}

/* ===== IconButton ============================================================
   Botão circular só com ícone. Mesma lógica de cor do Button.
   HIERARQUIA (obrigatório, 1): --primary · --secondary · --tertiary · --inverse · --on-image
   TAMANHO (opcional): padrão 44 · --sm 36.   aria-label é OBRIGATÓRIO.
   Indicador de notificação: <span class="bs-icon-btn__dot"></span>
   ========================================================================== */
.bs-icon-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--size-control-md);
  height: var(--size-control-md);
  padding: 0;
  box-sizing: border-box;
  border: 0;
  border-radius: var(--radius-circle);
  background: transparent;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background var(--transition-default), color var(--transition-default);
  -webkit-tap-highlight-color: transparent;
}
.bs-icon-btn .bs-icon { font-size: var(--size-icon-md); }
.bs-icon-btn:focus-visible,
.bs-icon-btn.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-icon-btn:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }
.bs-icon-btn--sm { width: var(--size-control-sm); height: var(--size-control-sm); }
.bs-icon-btn--sm .bs-icon { font-size: var(--size-icon-sm); }

.bs-icon-btn--primary { background: var(--interactive-primary); color: var(--text-on-brand-fill); }
.bs-icon-btn--primary:hover:not(:disabled), .bs-icon-btn--primary.is-hover { background: var(--interactive-primary-hover); }
.bs-icon-btn--primary:active:not(:disabled), .bs-icon-btn--primary.is-pressed { background: var(--interactive-primary-active); }

.bs-icon-btn--secondary { background: var(--bg-surface-raised); color: var(--text-primary); }
.bs-icon-btn--secondary:hover:not(:disabled), .bs-icon-btn--secondary.is-hover { background: var(--bg-surface-overlay); }
.bs-icon-btn--secondary:active:not(:disabled), .bs-icon-btn--secondary.is-pressed { background: color-mix(in srgb, var(--bg-surface-overlay), var(--white) 10%); }

.bs-icon-btn--tertiary:hover:not(:disabled), .bs-icon-btn--tertiary.is-hover { background: var(--bg-surface-raised); color: var(--text-primary); }
.bs-icon-btn--tertiary:active:not(:disabled), .bs-icon-btn--tertiary.is-pressed { background: var(--bg-surface-overlay); color: var(--text-primary); }

.bs-icon-btn--inverse { background: var(--bg-inverse); color: var(--text-inverse); }
.bs-icon-btn--inverse:hover:not(:disabled), .bs-icon-btn--inverse.is-hover { background: var(--gray-100); }
.bs-icon-btn--inverse:active:not(:disabled), .bs-icon-btn--inverse.is-pressed { background: var(--gray-200); }

.bs-icon-btn--on-image { background: var(--bg-on-image); color: var(--white); }
.bs-icon-btn--on-image:hover:not(:disabled), .bs-icon-btn--on-image.is-hover { background: color-mix(in srgb, var(--bg-on-image), var(--white) 25%); }
.bs-icon-btn--on-image:active:not(:disabled), .bs-icon-btn--on-image.is-pressed { background: color-mix(in srgb, var(--bg-on-image), var(--white) 40%); }

.bs-icon-btn__dot {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  width: 10px;
  height: 10px;
  border-radius: var(--radius-circle);
  background: var(--indicator-notification);
  box-shadow: 0 0 0 var(--stroke-thin) var(--bs-icon-btn-ring, var(--bg-canvas));
  pointer-events: none;
}

/* ===== Avatar ================================================================
   FORMA: círculo (padrão) · --square (quadrado arredondado). Mesmos tamanhos nas duas.
   TAMANHO: --xs 24 · --sm 32 · --md 40 (padrão) · --lg 48 · --xl 64 · --2xl 96 · --3xl 128
   CONTEÚDO livre: <img>, iniciais em <span>, ou o fantasma (--anon). A cor de fundo
   dinâmica (por usuário) entra por --bs-avatar-bg. A decisão foto/iniciais é do template.
   ========================================================================== */
.bs-avatar {
  --bs-avatar-size: var(--size-avatar-md);
  --bs-avatar-rsq: var(--radius-avatar-md);
  --bs-avatar-radius: var(--radius-circle);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  box-sizing: border-box;
  width: var(--bs-avatar-size);
  height: var(--bs-avatar-size);
  border-radius: var(--bs-avatar-radius);
  overflow: hidden;
  background: var(--bs-avatar-bg, var(--bg-surface-raised));
  color: var(--bs-avatar-color, var(--text-secondary));
  font-family: var(--font-titulo);
  font-weight: var(--font-weight-black);
  font-size: calc(var(--bs-avatar-size) * 0.4);
  line-height: 1;
  user-select: none;
}
.bs-avatar img { display: block; width: 100%; height: 100%; object-fit: cover; }
.bs-avatar--xs  { --bs-avatar-size: var(--size-avatar-xs);  --bs-avatar-rsq: var(--radius-avatar-xs); }
.bs-avatar--sm  { --bs-avatar-size: var(--size-avatar-sm);  --bs-avatar-rsq: var(--radius-avatar-sm); }
.bs-avatar--md  { --bs-avatar-size: var(--size-avatar-md);  --bs-avatar-rsq: var(--radius-avatar-md); }
.bs-avatar--lg  { --bs-avatar-size: var(--size-avatar-lg);  --bs-avatar-rsq: var(--radius-avatar-lg); }
.bs-avatar--xl  { --bs-avatar-size: var(--size-avatar-xl);  --bs-avatar-rsq: var(--radius-avatar-xl); }
.bs-avatar--2xl { --bs-avatar-size: var(--size-avatar-2xl); --bs-avatar-rsq: var(--radius-avatar-2xl); }
.bs-avatar--3xl { --bs-avatar-size: var(--size-avatar-3xl); --bs-avatar-rsq: var(--radius-avatar-3xl); }
.bs-avatar--square { --bs-avatar-radius: var(--bs-avatar-rsq); }
.bs-avatar--anon svg { width: 48%; height: 48%; fill: var(--gray-400); }
/* Avatar da marca (conta oficial Brasil Scat): fundo holográfico em movimento (o mesmo do nível 8) e o logo em escuro no centro. */
.bs-avatar--brand { background: var(--gradient-nivel-holo); background-size: 300% 100%; animation: bs-lv-holo calc(var(--duration-lively) * 2) linear infinite; }
.bs-avatar__logo { display: block; width: 72%; aspect-ratio: 639 / 350; background: var(--text-on-solid); -webkit-mask: url("logo.svg") center / contain no-repeat; mask: url("logo.svg") center / contain no-repeat; }
@media (prefers-reduced-motion: reduce) { .bs-avatar--brand { animation: none; background-position: 30% 0; } }
.bs-avatar--ring { box-shadow: 0 0 0 var(--stroke-thick) var(--bs-avatar-ring, var(--bg-canvas)); }
.bs-avatar--on-image { border: var(--stroke-thin) solid var(--border-on-image, var(--white)); }

/* ===== Field / Input ==========================================================
   Um único campo de texto. Busca e texto grande são o MESMO componente.
   Estados: padrão · :focus · --error · --success · disabled · readonly.
   Altura 44 (--sm 36), fonte 16px (evita zoom no iPhone), fundo e contorno de campo.
   ========================================================================== */
.bs-field { display: flex; flex-direction: column; gap: var(--space-2); }
.bs-field__label { font-family: var(--font-corpo); font-size: var(--font-size-12); font-weight: var(--font-weight-medium); color: var(--text-secondary); }
.bs-field__hint { font-family: var(--font-corpo); font-size: var(--font-size-12); color: var(--text-tertiary); }
.bs-field__hint--error { color: var(--text-danger); }
.bs-field__hint--success { color: var(--text-success); }

.bs-input {
  display: block;
  width: 100%;
  height: var(--size-control-md);
  box-sizing: border-box;
  padding: 0 var(--space-5);
  font-family: var(--font-corpo);
  font-size: var(--font-size-16);
  font-weight: var(--font-weight-regular);
  color: var(--text-primary);
  background: var(--bg-field);
  border: var(--stroke-hairline) solid var(--border-field);
  border-radius: var(--radius-lg);
  outline: 0;
  transition: border-color var(--transition-default), box-shadow var(--transition-default);
}
.bs-input::placeholder { color: var(--text-tertiary); }
.bs-input:focus,
.bs-input.is-focus { border-color: var(--border-focus); box-shadow: 0 0 0 var(--stroke-hairline) var(--border-focus); }
.bs-input--error { border-color: var(--status-danger); }
.bs-input--error:focus { border-color: var(--status-danger); box-shadow: 0 0 0 var(--stroke-hairline) var(--status-danger); }
.bs-input--success { border-color: var(--status-success); }
.bs-input:disabled { background: var(--bg-surface-raised); color: var(--text-tertiary); border-color: var(--border-subtle); cursor: not-allowed; }
.bs-input[readonly] { opacity: var(--opacity-muted); }
.bs-input--sm { height: var(--size-control-sm); }
.bs-input--textarea { height: auto; min-height: 120px; padding: var(--space-4) var(--space-5); line-height: var(--line-height-normal); resize: vertical; }
/* --tall: área de texto grande (escrever um post). --grow: uma linha que cresce em altura ao digitar, até 3 linhas; depois rola na vertical (altura ajustada por components.js, atributo data-bs-grow) */
.bs-input--tall { min-height: calc(var(--size-control-lg) * 4); }
.bs-input--grow { height: auto; min-height: var(--size-control-md); max-height: calc(var(--size-control-md) * 3); padding: var(--space-3) var(--space-5); line-height: var(--line-height-normal); resize: none; overflow-y: auto; overflow-x: hidden; field-sizing: content; }

/* --grow + --tall: área de texto que começa grande e cresce com o texto, até 10 vezes a altura de um campo grande */
.bs-input--grow.bs-input--tall { min-height: calc(var(--size-control-lg) * 4); max-height: calc(var(--size-control-lg) * 10); }

.bs-input-group { position: relative; display: flex; align-items: center; }
.bs-input-group .bs-input { padding-left: calc(var(--space-5) + var(--size-icon-md) + var(--space-3)); }
.bs-input-group__icon { position: absolute; left: var(--space-5); top: 50%; transform: translateY(-50%); font-size: var(--size-icon-md); color: var(--text-tertiary); pointer-events: none; }

/* ===== Divider ================================================================ */
.bs-divider { border: 0; border-top: var(--stroke-hairline) solid var(--border-default); margin: var(--bs-divider-gap, var(--space-5)) 0; width: 100%; }
/* Espaço acima = espaço abaixo, sempre. Padrão 16; escolha: --gap-sm 12 · --gap-md 16 · --gap-lg 24 · --gap-xl 32. */
.bs-divider--gap-sm { --bs-divider-gap: var(--space-4); }
.bs-divider--gap-md { --bs-divider-gap: var(--space-5); }
.bs-divider--gap-lg { --bs-divider-gap: var(--space-7); }
.bs-divider--gap-xl { --bs-divider-gap: var(--space-8); }
.bs-divider--vertical { margin: 0; border-top: 0; border-left: var(--stroke-hairline) solid var(--border-default); width: 0; height: auto; align-self: stretch; }

/* ===== Container ==============================================================
   A coluna centralizada de uma página. É ele que decide a largura, nunca a tela.
   LARGURA (1 de 3): padrão 1040 (--layout-content: feeds, listas, perfil, editor, histórias) ·
   --form 760 (--layout-form: páginas de explicação e textos) · --narrow 580 (--layout-sheet: avisos rápidos, match, cartões de login).
   Recuo lateral 16, topo 24, base 48. Define --bs-rail-bleed (a margem lateral) para Rail e Filtro --scroll;
   no desktop a faixa não passa mais do container (bleed 0).
   Sem estados: é só layout. ========================================================== */
.bs-container { box-sizing: border-box; width: 100%; max-width: var(--bs-container-w, var(--layout-content)); margin-inline: auto; padding: var(--space-6) var(--space-5) var(--space-10); --bs-rail-bleed: var(--space-5); }
.bs-container--form { --bs-container-w: var(--layout-form); }
.bs-container--narrow { --bs-container-w: var(--layout-sheet); }
@media (min-width: 960px) { .bs-container { --bs-rail-bleed: 0px; } }

/* ===== Link ===================================================================
   Link de texto (átomo): rosa de marca, dentro de uma frase ou rótulo. É um <a>, nunca um botão com cara de link.
   Sem sublinhado em repouso; sublinha no hover e ao pressionar. Hover e pressionado ficam mais claros (rosa 300, regra do rosa).
   Herda tamanho, peso e entrelinha do texto em volta. Foco: :focus-visible.
   Com ícone (21/10/2026): bs-link--icon + <span class="bs-link__icon bs-icon bs-icon--nome"> antes do texto; o ícone herda a cor do link.
   ========================================================================== */
.bs-link { color: var(--text-brand); text-decoration: none; font: inherit; cursor: pointer; border-radius: var(--radius-xs); transition: color var(--transition-default); }
.bs-link:hover, .bs-link.is-hover, .bs-link:active, .bs-link.is-pressed { color: var(--interactive-primary-active); text-decoration: underline; text-underline-offset: var(--space-1); }
.bs-link:focus-visible, .bs-link.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-link--icon { display: inline-flex; align-items: center; gap: var(--space-2); }   /* com ícone antes do texto (21/10/2026) */
.bs-link__icon { width: var(--size-icon-sm); height: var(--size-icon-sm); flex: none; }

/* ===== Breadcrumb =============================================================
   Caminho até a página atual (Artigos / Saúde / Título). Uma lista <ol class="bs-breadcrumb"> de itens
   (bs-breadcrumb__item); os anteriores são links (bs-breadcrumb__link), o último é a página atual
   (aria-current="page"), sem link. A página atual tem limite de caracteres (--breadcrumb-max 20ch no celular, --breadcrumb-max-desk 32ch no desktop): passou disso, termina em reticências; ponha o título inteiro no atributo title. O separador é o ícone chevron-right (bs-breadcrumb__sep), dentro de cada item
   que não é o último. Linha única: o item atual encolhe com reticências, os links nunca quebram.
   Sem tamanhos nem variantes. Estados do link: is-hover, is-focus (só para a documentação).
   ========================================================================== */
.bs-breadcrumb { display: flex; align-items: center; gap: var(--space-2); min-width: 0; margin: 0; padding: 0; list-style: none; font-family: var(--font-corpo); font-size: var(--font-size-14); font-weight: var(--font-weight-medium); }
.bs-breadcrumb__item { display: inline-flex; align-items: center; gap: var(--space-2); min-width: 0; color: var(--text-secondary); }
.bs-breadcrumb__item[aria-current="page"] { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: var(--breadcrumb-max); color: var(--text-primary); }
@media (min-width: 960px) { .bs-breadcrumb__item[aria-current="page"] { max-width: var(--breadcrumb-max-desk); } }
.bs-breadcrumb__link { color: inherit; text-decoration: none; white-space: nowrap; border-radius: var(--radius-xs); transition: color var(--transition-default); }
.bs-breadcrumb__link:hover, .bs-breadcrumb__link.is-hover { color: var(--text-primary); text-decoration: underline; text-underline-offset: var(--space-1); }
.bs-breadcrumb__link:focus-visible, .bs-breadcrumb__link.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-breadcrumb__sep { flex: none; font-size: var(--size-icon-sm); color: var(--text-tertiary); }
@media (prefers-reduced-motion: reduce) { .bs-link { transition: none; } }

/* ===== Progress ===============================================================
   Barra: trilho --bg-surface-raised, preenchimento em gradiente de marca. A única coisa
   dinâmica é a largura do __fill (style="width: 62%").
   Anel: .bs-progress-ring com --bs-progress (0 a 100). Enquete: .bs-poll (opção = botão
   com a barra como fundo, na cor da categoria via bs-cat-*).
   ========================================================================== */
.bs-progress { width: 100%; height: var(--size-progress-track); border-radius: var(--radius-pill); background: var(--bg-surface-raised); overflow: hidden; }
.bs-progress__fill { height: 100%; border-radius: inherit; background: var(--gradient-brand); transition: width var(--duration-slow) var(--ease-standard); }
.bs-progress--thin { height: var(--stroke-thin); border-radius: 0; }   /* linha fina de progresso (rodapé do assistente) */
.bs-progress--danger .bs-progress__fill { background: var(--status-danger); }
.bs-progress-row { display: grid; grid-template-columns: var(--size-avatar-3xl) minmax(0, 1fr); gap: var(--space-3); align-items: center; font-family: var(--font-corpo); font-size: var(--font-size-12); color: var(--text-secondary); }   /* barra com rótulo à esquerda (eixos do Estilo Pig) */
.bs-progress-row__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ===== Chart (barras de dados) ================================================
   Gráfico de barras horizontais para artigos: título, linhas (rótulo + valor + barra) e nota de fonte.
   Cada barra é um SVG (viewBox 360 x 36): trilho, preenchimento e o texto DENTRO da barra, escuro sobre o preenchimento e claro sobre o trilho (o mesmo texto desenhado duas vezes, a de cima recortada pelo preenchimento). Sem style inline, que o texto do artigo remove.
   Linha em destaque: .is-hl (rosa); as demais ficam neutras, para o gráfico contar uma coisa só.
   COR do destaque: --bs-chart (padrão --interactive-primary). Sem JS.
   ========================================================================== */
.bs-chart { container-type: inline-size; container-name: bs-chart; display: flex; flex-direction: column; gap: var(--space-5); box-sizing: border-box; margin: 0; padding: var(--space-6); border-radius: var(--radius-xl); background: var(--bg-surface); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-chart__title { margin: 0; font-size: var(--font-size-20); font-weight: var(--font-weight-bold); line-height: var(--line-height-snug); color: var(--text-primary); }
.bs-chart__sub { margin: calc(var(--space-2) * -1) 0 0; font-size: var(--font-size-14); line-height: var(--line-height-normal); color: var(--text-secondary); }
.bs-chart__bars { display: flex; flex-direction: column; gap: var(--space-3); }
.bs-chart__bar { display: block; width: 100%; height: auto; }
.bs-chart__bar--w { display: none; }
@container bs-chart (min-width: 460px) { .bs-chart__bar--n { display: none; } .bs-chart__bar--w { display: block; } }   /* gráfico largo: usa a versão larga da barra (640) para ela não ficar alta; literal 460px porque container query não aceita variável */
.bs-chart__track { fill: var(--bg-surface-raised); }
.bs-chart__fill { fill: var(--text-tertiary); }
.bs-chart__bar.is-hl .bs-chart__fill { fill: var(--bs-chart, var(--interactive-primary)); }
.bs-chart__bt, .bs-chart__bf { font-family: var(--font-corpo); font-weight: var(--font-weight-medium); }
.bs-chart__bt { fill: var(--text-primary); }
.bs-chart__bf { fill: var(--text-on-brand-fill); }
.bs-chart__bv { font-weight: var(--font-weight-bold); }
.bs-chart__note { margin: 0; font-size: var(--font-size-14); line-height: var(--line-height-normal); color: var(--text-tertiary); }

/* ===== Bignum (número grande) =================================================
   Um número em destaque com a legenda embaixo; vários em grade (bs-bignum-grid) viram uma linha de "placar".
   COR do número: --bs-bignum (padrão --text-brand). Sem JS.
   ========================================================================== */
.bs-bignum-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(var(--size-stat-min), 1fr)); gap: var(--space-4); }
.bs-bignum { display: flex; flex-direction: column; gap: var(--space-2); box-sizing: border-box; min-width: 0; padding: var(--space-6); border-radius: var(--radius-xl); background: var(--bg-surface); font-family: var(--font-corpo); }
.bs-bignum__value { font-family: var(--font-titulo); font-size: var(--font-size-48); font-weight: var(--font-weight-bold); line-height: var(--line-height-tight); letter-spacing: -.02em; color: var(--bs-bignum, var(--text-brand)); }
.bs-bignum__label { font-size: var(--font-size-14); line-height: var(--line-height-normal); color: var(--text-secondary); }
.bs-bignum--muted { --bs-bignum: var(--text-secondary); }
.bs-prose .bs-chart, .bs-prose .bs-bignum-grid { margin: var(--space-7) 0; }
/* Chart, partes extras (14/11/2026): PIZZA (donut) e BARRA ÚNICA para o que soma 100%, e MAPA de estados (tile map).
   Tudo em SVG com atributos (sem style inline, que o texto do artigo remove): as cores vêm das classes --bs-seg-N e dos níveis do mapa.
   Pizza: __plot (flex) + svg.bs-chart__donut (viewBox 36, círculos r=15.9155 = perímetro 100, cada fatia é um stroke-dasharray) + __legend.
   Barra única: svg.bs-chart__stack (viewBox 100 x 10, um rect por fatia) + __legend.
   Cores das fatias (ordem 1 a 6): rosa, azul-céu, verde, âmbar, roxo, cinza. A 1ª é a que conta a história. */
.bs-chart__plot { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--space-6); }
.bs-chart__donut { flex: none; display: block; width: var(--size-chart-donut); height: auto; }
.bs-chart__donut .bs-chart__seg { fill: none; stroke: var(--bs-seg); }
.bs-chart__donut .bs-chart__base { fill: var(--bs-seg); stroke: none; }
.bs-chart__donut-n { fill: var(--text-primary); font-family: var(--font-titulo); font-weight: var(--font-weight-bold); text-anchor: middle; }
.bs-chart__donut-l { fill: var(--text-secondary); font-family: var(--font-corpo); text-anchor: middle; }
.bs-chart__dots { flex: none; display: block; width: var(--size-chart-dots); max-width: 100%; height: auto; }
.bs-chart__dots circle { fill: var(--bs-seg); }
.bs-chart__bubbles { flex: none; display: block; width: var(--size-chart-bubbles); max-width: 100%; height: auto; }
.bs-chart__bubbles .bs-chart__seg { fill: var(--bs-seg); }
.bs-chart__bubble-n { fill: var(--text-on-brand-fill); font-family: var(--font-titulo); font-weight: var(--font-weight-bold); text-anchor: middle; }
.bs-chart__stack { display: block; width: 100%; height: var(--size-chart-stack); border-radius: var(--radius-pill); overflow: hidden; background: var(--bg-surface-raised); }
.bs-chart__stack .bs-chart__seg { fill: var(--bs-seg); }
.bs-chart__legend { display: flex; flex: 1 1 var(--size-stat-min); flex-direction: column; gap: var(--space-3); min-width: 0; }
.bs-chart__key { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: var(--space-3); font-size: var(--font-size-16); line-height: var(--line-height-snug); }
.bs-chart__swatch { width: var(--space-4); height: var(--space-4); border-radius: var(--radius-pill); background: var(--bs-seg); }
.bs-chart__key-label { min-width: 0; color: var(--text-secondary); }
.bs-chart__key-value { font-weight: var(--font-weight-bold); color: var(--text-primary); }
.bs-chart__seg--1 { --bs-seg: var(--stat-pink); }
.bs-chart__seg--2 { --bs-seg: var(--stat-sky); }
.bs-chart__seg--3 { --bs-seg: var(--stat-green); }
.bs-chart__seg--4 { --bs-seg: var(--stat-amber); }
.bs-chart__seg--5 { --bs-seg: var(--stat-purple); }
.bs-chart__seg--6 { --bs-seg: var(--text-tertiary); }
/* Mapa de estados (tile map): cada estado é um quadrado na posição aproximada do Brasil; a cor mostra a faixa, o número mostra a contagem. Níveis 0 a 4. */
.bs-map { display: block; width: 100%; max-width: var(--size-map-max); height: auto; margin: 0 auto; }
.bs-map__t rect { fill: var(--bs-lv, var(--bg-surface-raised)); }
.bs-map__uf { fill: var(--bs-lv-text, var(--text-tertiary)); font-family: var(--font-corpo); font-weight: var(--font-weight-medium); text-anchor: middle; }
.bs-map__n { fill: var(--bs-lv-text, var(--text-tertiary)); font-family: var(--font-titulo); font-weight: var(--font-weight-bold); text-anchor: middle; }
.bs-map__lv--0 { --bs-lv: var(--bg-surface-raised); --bs-lv-text: var(--text-tertiary); }
.bs-map__lv--1 { --bs-lv: color-mix(in srgb, var(--interactive-primary) 30%, var(--bg-surface-raised)); --bs-lv-text: var(--text-primary); }
.bs-map__lv--2 { --bs-lv: color-mix(in srgb, var(--interactive-primary) 58%, var(--bg-surface-raised)); --bs-lv-text: var(--text-on-brand-fill); }
.bs-map__lv--3 { --bs-lv: color-mix(in srgb, var(--interactive-primary) 80%, var(--bg-surface-raised)); --bs-lv-text: var(--text-on-brand-fill); }
.bs-map__lv--4 { --bs-lv: var(--interactive-primary); --bs-lv-text: var(--text-on-brand-fill); }
.bs-map__legend { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2) var(--space-5); font-size: var(--font-size-14); color: var(--text-secondary); }
.bs-map__key { display: inline-flex; align-items: center; gap: var(--space-2); }
.bs-map__swatch { width: var(--space-4); height: var(--space-4); border-radius: var(--radius-2xs); background: var(--bs-lv); }

.bs-prose .bs-chart .bs-chart__title { margin: 0; font-size: var(--font-size-20); font-weight: var(--font-weight-bold); line-height: var(--line-height-snug); text-align: left; color: var(--text-primary); }   /* vence o estilo de figcaption do Prose */

.bs-progress-ring {
  --bs-progress: 0;
  --bs-ring-size: 88px;
  --bs-ring-thickness: var(--space-3);
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: var(--bs-ring-size);
  height: var(--bs-ring-size);
  border-radius: var(--radius-circle);
  background: conic-gradient(var(--interactive-primary) calc(var(--bs-progress) * 1%), var(--bg-surface-raised) 0);
}
.bs-progress-ring--lg { --bs-ring-size: 152px; --bs-ring-thickness: var(--space-4); }
.bs-progress-ring__inner {
  display: grid;
  place-items: center;
  width: calc(100% - 2 * var(--bs-ring-thickness));
  height: calc(100% - 2 * var(--bs-ring-thickness));
  border-radius: var(--radius-circle);
  background: var(--bs-ring-inner, var(--bg-surface));
  font-family: var(--font-titulo);
  font-weight: var(--font-weight-black);
  font-size: var(--font-size-20);
}

.bs-poll { display: flex; flex-direction: column; gap: var(--space-3); }
.bs-poll__option {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--size-control-lg);
  padding: 0 var(--space-5);
  box-sizing: border-box;
  border: 0;
  border-radius: var(--radius-lg);
  background: var(--bg-surface-raised);
  color: var(--text-primary);
  font-family: var(--font-corpo);
  font-size: var(--font-size-16);
  font-weight: var(--font-weight-bold);
  text-align: left;
  cursor: pointer;
}
.bs-poll__option::before {
  content: '';
  position: absolute;
  inset: 0;
  width: 0;
  background: color-mix(in srgb, var(--bs-cat, var(--interactive-primary)) 35%, transparent);
  transition: width var(--duration-slow) var(--ease-standard);
}
.bs-poll__option > * { position: relative; }
.bs-poll__option:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-poll__pct { display: none; }
.bs-poll--voted .bs-poll__option::before { width: var(--bs-pct, 0%); }
.bs-poll--voted .bs-poll__pct { display: block; }
.bs-poll__option.is-selected { box-shadow: inset 0 0 0 var(--stroke-thin) var(--bs-cat, var(--interactive-primary)); }
.bs-poll__option:disabled { cursor: default; opacity: 1; }
.bs-poll__meta { font-size: var(--font-size-12); color: var(--text-secondary); }

/* ===== Spinner ================================================================
   TAMANHO: --sm 14 · padrão 20 · --lg 32.  Anuncie o carregamento com role="status" + texto oculto.
   ========================================================================== */
.bs-spinner {
  display: inline-block;
  width: var(--size-icon-md);
  height: var(--size-icon-md);
  box-sizing: border-box;
  border: var(--stroke-thin) solid var(--border-strong);
  border-top-color: var(--interactive-primary);
  border-radius: var(--radius-circle);
  animation: bs-spin 0.7s linear infinite;
}
.bs-spinner--sm { width: var(--size-icon-xs); height: var(--size-icon-xs); border-width: var(--stroke-medium); }
.bs-spinner--lg { width: var(--size-avatar-sm); height: var(--size-avatar-sm); border-width: var(--stroke-thick); }
@keyframes bs-spin { to { transform: rotate(360deg); } }
.bs-spinner--on-brand { border-color: color-mix(in srgb, var(--text-on-brand-fill) 25%, transparent); border-top-color: var(--text-on-brand-fill); }

/* ===== Switch =================================================================
   <label class="bs-switch"><input type="checkbox" role="switch"><span class="bs-switch__track"></span></label>
   ========================================================================== */
.bs-switch { position: relative; display: inline-block; flex-shrink: 0; width: var(--size-switch-w); height: var(--size-switch-h); cursor: pointer; }
.bs-switch__input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: inherit; }
.bs-switch__track {
  position: absolute;
  inset: 0;
  border-radius: var(--radius-pill);
  background: var(--bg-surface-raised);
  box-shadow: inset 0 0 0 var(--stroke-hairline) var(--border-field);
  transition: background var(--transition-default), box-shadow var(--transition-default);
  pointer-events: none;
}
.bs-switch__track::after {
  content: '';
  position: absolute;
  top: 4px;
  left: 4px;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-circle);
  background: var(--white);
  transition: transform var(--transition-default);
}
.bs-switch__input:checked + .bs-switch__track { background: var(--interactive-primary); box-shadow: none; }
.bs-switch__input:checked + .bs-switch__track::after { transform: translateX(22px); }
.bs-switch__input:focus-visible + .bs-switch__track { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-switch__input:disabled { cursor: not-allowed; }
.bs-switch__input:disabled + .bs-switch__track { opacity: var(--opacity-disabled); }

/* ===== Checkbox ===============================================================
   <label class="bs-checkbox"><input type="checkbox"><span class="bs-checkbox__box">…check…</span><span>Texto</span></label>
   ========================================================================== */
.bs-checkbox { position: relative; display: inline-flex; align-items: flex-start; gap: var(--space-4); font-family: var(--font-corpo); font-size: var(--font-size-16); color: var(--text-primary); cursor: pointer; }
.bs-checkbox__input { position: absolute; width: 22px; height: 22px; margin: 0; opacity: 0; cursor: inherit; }
.bs-checkbox__box {
  display: inline-grid;
  place-items: center;
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  box-sizing: border-box;
  border: var(--stroke-thin) solid var(--border-field);
  border-radius: var(--radius-xs);
  color: transparent;
  transition: background var(--transition-default), border-color var(--transition-default);
}
.bs-checkbox__box .bs-icon { font-size: var(--size-icon-xs); --ico: var(--ico-s, var(--ico-r)); }   /* check sólido: traço mais grosso */
.bs-checkbox__input:checked + .bs-checkbox__box { background: var(--interactive-primary); border-color: var(--interactive-primary); color: var(--text-on-brand-fill); }
.bs-checkbox__input:focus-visible + .bs-checkbox__box { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-checkbox__input:disabled { cursor: not-allowed; }
.bs-checkbox__input:disabled + .bs-checkbox__box { opacity: var(--opacity-disabled); }
.bs-checkbox:has(.bs-checkbox__input:disabled) { cursor: not-allowed; color: var(--text-tertiary); }

/* ===== Radio ==================================================================
   Escolha única entre poucas opções, todas visíveis. Bolinha de 22px; texto e descrição opcional ao lado.
   <div class="bs-radio-group" role="radiogroup"><label class="bs-radio"><input class="bs-radio__input" type="radio" name="x"><span class="bs-radio__dot"></span><span class="bs-radio__text"><b>Título</b><small>Descrição</small></span></label></div>
   ========================================================================== */
.bs-radio-group { display: flex; flex-direction: column; gap: var(--space-4); }
.bs-radio { position: relative; display: flex; align-items: flex-start; gap: var(--space-4); font-family: var(--font-corpo); font-size: var(--font-size-16); color: var(--text-primary); cursor: pointer; }
.bs-radio__input { position: absolute; width: 22px; height: 22px; margin: 0; opacity: 0; cursor: inherit; }
.bs-radio__dot { display: inline-grid; place-items: center; flex-shrink: 0; width: 22px; height: 22px; box-sizing: border-box; border: var(--stroke-thin) solid var(--border-field); border-radius: var(--radius-circle); transition: background var(--transition-default), border-color var(--transition-default); }
.bs-radio__dot::after { content: ""; width: 10px; height: 10px; border-radius: var(--radius-circle); background: var(--text-on-brand-fill); transform: scale(0); transition: transform var(--transition-default); }
.bs-radio:hover .bs-radio__dot { border-color: var(--interactive-primary); }
.bs-radio__input:checked + .bs-radio__dot { background: var(--interactive-primary); border-color: var(--interactive-primary); }
.bs-radio__input:checked + .bs-radio__dot::after { transform: scale(1); }
.bs-radio__input:focus-visible + .bs-radio__dot { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-radio__text { display: flex; flex-direction: column; min-width: 0; }
.bs-radio__text b { font-weight: var(--font-weight-medium); }
.bs-radio__text small { font-size: var(--font-size-14); color: var(--text-secondary); }
.bs-radio__input:disabled { cursor: not-allowed; }
.bs-radio__input:disabled + .bs-radio__dot { opacity: var(--opacity-disabled); }
.bs-radio:has(.bs-radio__input:disabled) { cursor: not-allowed; color: var(--text-tertiary); }

@media (prefers-reduced-motion: reduce) {
  .bs-spinner { animation-duration: 1.6s; }
  .bs-progress__fill, .bs-poll__option::before, .bs-switch__track, .bs-switch__track::after { transition: none; }
}

/* ===== Pill ===================================================================
   Tag informativa (não clicável): categoria, nível, afinidade, fetiche, status, presença.
   ESTILO (1, tonal é o padrão): --solid · --neutral
     tonal = cor a 16% sobre o card, texto na cor · solid = cor cheia, texto escuro
     neutral = cinza elevado, cor no ícone e no texto.
     Sobre imagem use só --solid ou --neutral: o tonal é translúcido e se perde na foto.
   CONTEÚDO: texto · ícone + texto (bs-pill__icon) · só ícone (--icon-only, exige aria-label) · prefixo + texto (bs-pill__prefix: rótulo menor e mais fraco, com um ponto depois, antes do texto; 27/10/2026, usado em Gosta de: "Scat · Assistir")
   COR: sem modificador = cinza · --brand · --cat-* (8) · --nivel-* (4) · --fetiche
        · --success · --danger · --warning · --info
        · --cat e --nivel (sem sufixo): pegam a cor do contêiner (bs-cat-* ou bs-level-* no mesmo elemento ou no card)
   TAMANHO: --sm 22 · padrão 30 · --lg 36.  Não é alvo de toque: se for clicável, use o Filtro.
   ========================================================================== */
.bs-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--size-pill-h);
  padding: 0 var(--space-4);
  box-sizing: border-box;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--bs-pill, var(--text-secondary)) 16%, var(--bg-surface));
  color: var(--bs-pill, var(--text-secondary));
  font-family: var(--font-corpo);
  font-size: var(--font-size-12);
  font-weight: var(--font-weight-bold);
  line-height: 1;
  white-space: nowrap;
}
.bs-pill__icon { flex: none; font-size: var(--size-icon-xs); }
.bs-pill__prefix { display: inline-flex; align-items: center; gap: var(--space-2); font-weight: var(--font-weight-regular); opacity: var(--opacity-muted); }
.bs-pill__prefix::after { content: ""; width: var(--space-1); height: var(--space-1); border-radius: var(--radius-circle); background: currentColor; }
.bs-pill--solid { background: var(--bs-pill, var(--text-secondary)); color: var(--text-on-solid); }
.bs-pill--neutral { background: var(--bg-surface-raised); }
.bs-pill--sm { height: var(--size-badge-h); padding: 0 var(--space-3); gap: var(--space-1); }
.bs-pill--sm .bs-pill__icon { font-size: var(--size-icon-2xs); }
.bs-pill--lg { height: var(--size-control-sm); padding: 0 var(--space-5); gap: var(--space-3); font-size: var(--font-size-14); }
.bs-pill--lg .bs-pill__icon { font-size: var(--size-icon-sm); }
.bs-pill.bs-pill--icon-only { width: var(--size-pill-h); padding: 0; }
.bs-pill.bs-pill--icon-only.bs-pill--sm { width: var(--size-badge-h); }
.bs-pill.bs-pill--icon-only.bs-pill--lg { width: var(--size-control-sm); }
.bs-pill--brand { --bs-pill: var(--interactive-accent); }
.bs-pill--cat { --bs-pill: var(--bs-cat, var(--text-brand)); }
.bs-pill--sm .bs-emblem { --bs-emblem-size: var(--size-icon-sm); }   /* o badge cabe na Pill pequena (22) */
.bs-pill--nivel { --bs-pill: var(--bs-lv, var(--bs-level, var(--nivel-bronze))); }
.bs-pill--cat-conversa { --bs-pill: var(--cat-conversa); }
.bs-pill--cat-confissao { --bs-pill: var(--cat-confissao); }
.bs-pill--cat-vontade { --bs-pill: var(--cat-vontade); }
.bs-pill--cat-duvida { --bs-pill: var(--cat-duvida); }
.bs-pill--cat-debate { --bs-pill: var(--cat-debate); }
.bs-pill--cat-enquete { --bs-pill: var(--cat-enquete); }
.bs-pill--cat-indicacao { --bs-pill: var(--cat-indicacao); }
.bs-pill--cat-procuro { --bs-pill: var(--cat-procuro); }
.bs-pill--cat-vendo { --bs-pill: var(--cat-vendo); }
.bs-pill--nivel-bronze { --bs-pill: var(--nivel-bronze); }
.bs-pill--nivel-prata { --bs-pill: var(--nivel-prata); }
.bs-pill--nivel-ouro { --bs-pill: var(--nivel-ouro); }
.bs-pill--nivel-diamante { --bs-pill: var(--nivel-diamante); }
.bs-pill--fetiche { --bs-pill: var(--fetiche); }
.bs-pill--success { --bs-pill: var(--text-success); }
.bs-pill--danger { --bs-pill: var(--text-danger); }
.bs-pill--warning { --bs-pill: var(--text-warning); }
.bs-pill--info { --bs-pill: var(--text-info); }
.bs-pill--rarity { --bs-pill: var(--bs-rarity, var(--raridade-comum)); }   /* cor da raridade da conquista (Achievement, Rarity) */

/* ===== Like ===================================================================
   Curtir (ou comentar) dentro de uma pílula. Dois estados: normal e ativo (curtido).
   VARIANTE: padrão (marca: rosa, 36) · --category (preenchido na cor da categoria via bs-cat-*, 44) · --plain (solto: sem fundo, só coração e número, 20)
   TAMANHO: padrão 36 · --lg 44.  O ícone do coração e do balão é sempre preenchido
   (na variante category, o coração é contorno até curtir).  Contagem opcional.
   ========================================================================== */
.bs-like {
  --bs-like-h: var(--size-control-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  height: var(--bs-like-h);
  min-width: var(--bs-like-h);
  padding: 0 var(--space-4);
  box-sizing: border-box;
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--bg-surface-raised);
  color: var(--text-secondary);
  font-family: var(--font-corpo);
  font-size: var(--font-size-14);
  font-weight: var(--font-weight-bold);
  line-height: 1;
  cursor: pointer;
  transition: background var(--transition-default), color var(--transition-default), box-shadow var(--transition-default);
  -webkit-tap-highlight-color: transparent;
}
.bs-like:focus-visible, .bs-like.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-like:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }
.bs-like__icon { font-size: var(--size-icon-sm); --ico: var(--ico-s, var(--ico-r)); }
.bs-like__count { display: inline-block; height: var(--space-5); overflow: hidden; line-height: var(--space-5); font-variant-numeric: tabular-nums; }
.bs-like__track { display: flex; flex-direction: column; transition: transform var(--duration-slow) var(--ease-standard); }
.bs-like__track > span { display: block; height: var(--space-5); line-height: var(--space-5); }
.bs-like:hover:not(:disabled), .bs-like.is-hover { background: var(--interactive-primary-subtle); color: var(--text-brand); }
.bs-like.is-active { background: var(--interactive-primary); color: var(--text-on-brand-fill); }
.bs-like.is-active:hover:not(:disabled), .bs-like.is-active.is-hover { background: var(--interactive-primary-hover); color: var(--text-on-brand-fill); }
.bs-like--lg { --bs-like-h: var(--size-control-md); }
/* Solto (--plain): sem fundo nem pílula, só coração e número, bem pequeno (estilo link do Facebook). Curtido = coração e número na cor da marca. Usado no Comment. */
.bs-like--plain { --bs-like-h: var(--space-5); min-width: 0; padding: 0; gap: var(--space-2); background: none; font-size: var(--font-size-12); font-weight: var(--font-weight-medium); border-radius: var(--radius-xs); }
.bs-like--plain .bs-like__icon { font-size: var(--size-icon-xs); }
.bs-like--plain:hover:not(:disabled), .bs-like--plain.is-hover { background: none; color: var(--text-brand); }
.bs-like--plain.is-active, .bs-like--plain.is-active:hover:not(:disabled), .bs-like--plain.is-active.is-hover { background: none; color: var(--text-brand); }
.bs-like--lg .bs-like__icon { font-size: var(--size-icon-md); }
.bs-like.is-empty .bs-like__count { display: none; }
.bs-like:not(.is-empty) .bs-like__label { display: none; }

.bs-like--category { --bs-like-h: var(--size-control-md); background: var(--bs-cat, var(--interactive-primary)); color: var(--text-on-solid); }
.bs-like--category .bs-like__icon { font-size: var(--size-icon-md); --ico: var(--ico-r); }
.bs-like--category:hover:not(:disabled), .bs-like--category.is-hover { background: color-mix(in srgb, var(--bs-cat, var(--interactive-primary)), var(--white) 12%); color: var(--text-on-solid); }
.bs-like--category.is-active { background: var(--bs-cat, var(--interactive-primary)); color: var(--text-on-solid); }
.bs-like--category.is-active .bs-like__icon { --ico: var(--ico-s, var(--ico-r)); }
.bs-like--category.is-active:hover:not(:disabled), .bs-like--category.is-active.is-hover { background: color-mix(in srgb, var(--bs-cat, var(--interactive-primary)), var(--white) 12%); color: var(--text-on-solid); }

/* ===== Tabs ===================================================================
   Barra de abas com uma linha única que desliza até a aba ativa (components.js).
   Cada aba: texto, ou ícone + texto.  --fill: abas dividem a largura.
   ========================================================================== */
.bs-tabs { position: relative; display: flex; gap: var(--space-2); overflow-x: auto; scrollbar-width: none; box-shadow: inset 0 calc(var(--stroke-hairline) * -1) 0 var(--border-default); }
.bs-tabs::-webkit-scrollbar { display: none; }
.bs-tabs__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  flex: none;
  height: var(--size-control-lg);
  padding: 0 var(--space-5);
  border: 0;
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-corpo);
  font-size: var(--font-size-14);
  font-weight: var(--font-weight-bold);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--transition-default);
}
.bs-tabs__item:hover, .bs-tabs__item.is-hover { color: var(--text-primary); }
.bs-tabs__item:focus-visible { outline: var(--focus-ring); outline-offset: calc(var(--focus-offset) * -1); border-radius: var(--radius-sm); }
.bs-tabs__item.is-active { color: var(--text-brand); }
.bs-tabs__item:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }
.bs-tabs__icon { font-size: var(--size-icon-sm); }
.bs-tabs--fill .bs-tabs__item { flex: 1 1 0; min-width: 0; }
.bs-tabs__indicator { position: absolute; left: 0; bottom: 0; height: var(--stroke-thin); width: var(--tab-w, 0px); transform: translateX(var(--tab-x, 0px)); background: var(--interactive-primary); border-radius: var(--radius-pill); pointer-events: none; }
.bs-tabs.is-ready .bs-tabs__indicator { transition: transform var(--duration-slow) cubic-bezier(0.4, 0, 0.2, 1), width var(--duration-slow) cubic-bezier(0.4, 0, 0.2, 1); }
.bs-tabs:not(.is-ready) .bs-tabs__item.is-active { box-shadow: inset 0 calc(var(--stroke-thin) * -1) 0 var(--interactive-primary); }

/* ===== Filtro =================================================================
   Escolhe um (ou vários) valor para filtrar uma lista. Não é navegação (isso é Tabs).
   VARIANTE: padrão = segmentado (trilho) · --chips = opções soltas em linha/quebra; cada item é uma Pill
   (bs-pill bs-pill--neutral bs-pill--lg) e o Filtro só acrescenta hover, selecionado e foco.
   Selecionado: .is-active (ou aria-pressed="true").  Cor de categoria: .bs-cat-* + __dot.
   ========================================================================== */
.bs-filter { display: inline-flex; gap: var(--space-1); padding: var(--space-2); box-sizing: border-box; max-width: 100%; overflow-x: auto; scrollbar-width: none; border-radius: var(--radius-pill); background: var(--bg-surface-raised); }
.bs-filter::-webkit-scrollbar { display: none; }
.bs-filter__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  border: 0;
  font-family: var(--font-corpo);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--transition-default), color var(--transition-default), box-shadow var(--transition-default);
}
.bs-filter:not(.bs-filter--chips) .bs-filter__item {
  gap: var(--space-3);
  height: var(--size-control-sm);
  padding: 0 var(--space-5);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-secondary);
  font-size: var(--font-size-14);
  font-weight: var(--font-weight-bold);
}
.bs-filter__item:hover:not(:disabled), .bs-filter__item.is-hover { color: var(--text-primary); }
.bs-filter__item:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-filter__item:disabled { opacity: var(--opacity-disabled); cursor: not-allowed; }
.bs-filter__item.is-active, .bs-filter__item[aria-pressed="true"] { color: var(--text-brand); box-shadow: inset 0 0 0 var(--stroke-medium) var(--pink-400); }
.bs-filter__dot { width: var(--space-3); height: var(--space-3); border-radius: var(--radius-circle); background: var(--bs-cat, var(--pink-400)); flex-shrink: 0; }
.bs-filter__count { font-size: var(--font-size-12); font-weight: var(--font-weight-medium); opacity: var(--opacity-muted); }

.bs-filter--chips { display: flex; flex-wrap: wrap; gap: var(--space-3); padding: 0; border-radius: 0; background: transparent; overflow: visible; }
/* chip: não selecionado só com contorno; selecionado branco (a categoria fica só no ponto) */
.bs-filter--chips .bs-filter__item { background: transparent; box-shadow: inset 0 0 0 var(--stroke-medium) var(--border-control); }
.bs-filter--chips .bs-filter__item:hover:not(:disabled), .bs-filter--chips .bs-filter__item.is-hover { background: transparent; color: var(--text-primary); box-shadow: inset 0 0 0 var(--stroke-medium) var(--text-secondary); }
.bs-filter--chips .bs-filter__item.is-active, .bs-filter--chips .bs-filter__item[aria-pressed="true"] { background: var(--bg-inverse); color: var(--text-inverse); box-shadow: none; }
.bs-filter--chips .bs-filter__item.is-active:hover:not(:disabled), .bs-filter--chips .bs-filter__item.is-active.is-hover { background: color-mix(in srgb, var(--bg-inverse), var(--black) 8%); color: var(--text-inverse); }
/* Chips com "Ver mais": os itens depois do corte levam .bs-filter__item--extra e somem enquanto o grupo tem [data-collapsed]; o botão .bs-filter-more.bs-filter-toggle (dentro do grupo, não é .bs-filter__item) abre e fecha */
.bs-filter--chips[data-collapsed] .bs-filter__item--extra { display: none; }
.bs-filter-toggle[aria-expanded="true"] .bs-icon { transform: rotate(180deg); }
.bs-filter--scroll { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; max-width: none; margin-inline: calc(var(--bs-rail-bleed, 0px) * -1); padding-inline: var(--bs-rail-bleed, 0px); scroll-padding-inline: var(--bs-rail-bleed, 0px); }
.bs-filter--scroll::-webkit-scrollbar { display: none; }

/* Chips + "Mais": quando há mais opções do que cabem como chips, o último é um botão "Mais" que abre um Dropdown com o resto.
   O Dropdown fica FORA do .bs-filter (ao lado dele) e o gatilho é um .bs-filter-more, que parece um chip mas NÃO leva .bs-filter__item
   (senão o grupo trataria o clique como escolha). Quem monta a tela escuta bs:dropdownselect. Com uma opção do Dropdown escolhida,
   o gatilho vira o chip selecionado (.is-active) e mostra o nome dela; ao escolher um chip normal, volta a "Mais". */
.bs-filter-more { display: inline-flex; align-items: center; gap: var(--space-2); flex: none; height: var(--size-control-sm); padding: 0 var(--space-4) 0 var(--space-5); box-sizing: border-box; border: 0; border-radius: var(--radius-pill); background: transparent; box-shadow: inset 0 0 0 var(--stroke-medium) var(--border-control); color: var(--text-secondary); font-family: var(--font-corpo); font-size: var(--font-size-14); font-weight: var(--font-weight-bold); line-height: 1; white-space: nowrap; cursor: pointer; transition: background var(--transition-default), color var(--transition-default), box-shadow var(--transition-default); }
.bs-filter-more:hover, .bs-filter-more.is-hover { color: var(--text-primary); box-shadow: inset 0 0 0 var(--stroke-medium) var(--text-secondary); }
.bs-filter-more:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-filter-more.is-active { background: var(--bg-inverse); color: var(--text-inverse); box-shadow: none; }
.bs-filter-more .bs-icon { font-size: var(--size-icon-md); }

/* ===== Rail (carrossel) ========================================================
   Faixa horizontal que rola de lado (ex.: Top 10 em pontos). Não tem barra de rolagem visível.
   Vai até a borda da tela: o container define --bs-rail-bleed (a margem lateral dele) e a faixa
   "vaza" essa margem, então o item só some ao sair da tela, sem corte antes. Sem --bs-rail-bleed, fica dentro do container.
   Partes: __item (coluna centralizada, é botão ou link) · __badge (selo no canto, ex.: posição) · __label (legenda de 1 linha).
   ========================================================================== */
.bs-rail { display: flex; gap: var(--space-5); overflow-x: auto; margin-inline: calc(var(--bs-rail-bleed, 0px) * -1); padding: var(--space-2) var(--bs-rail-bleed, 0px) var(--space-3); scroll-padding-inline: var(--bs-rail-bleed, 0px); scrollbar-width: none; scroll-snap-type: x proximity; overscroll-behavior-x: contain; }
.bs-rail::-webkit-scrollbar { display: none; }
.bs-rail__item { position: relative; flex: 0 0 calc(var(--size-avatar-xl) + var(--space-6)); padding: 0; border: 0; background: none; color: var(--text-primary); font-family: var(--font-corpo); text-align: center; text-decoration: none; cursor: pointer; scroll-snap-align: start; min-width: 0; }
.bs-rail__item:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); border-radius: var(--radius-lg); }
.bs-rail__badge { position: absolute; top: 0; left: var(--space-2); z-index: var(--z-controls); }   /* acima do contorno de nível do Avatar (z-overlap) */
.bs-rail__label { display: block; width: 0; min-width: 100%; margin-top: var(--space-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--font-size-12); }

/* ===== Dropdown ===============================================================
   Lista de opções que abre por cima de tudo (components.js alterna .is-open e põe o menu na camada de topo).
   No celular (< 960) TODO dropdown abre como bottom sheet; no desktop abre ancorado no gatilho. Parte opcional: __group (título de grupo de opções).
   FORMA: campo (--field: o gatilho tem o visual do Input e mostra o valor) ·
   menu de ações (o gatilho é qualquer Button ou IconButton). Flutua; o Accordion empurra.
   ========================================================================== */
.bs-dropdown { position: relative; display: inline-block; }
.bs-dropdown--field { display: block; }
.bs-dropdown__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
  height: var(--size-control-md);
  box-sizing: border-box;
  padding: 0 var(--space-5);
  font-family: var(--font-corpo);
  font-size: var(--font-size-16);
  color: var(--text-primary);
  background: var(--bg-field);
  border: var(--stroke-hairline) solid var(--border-field);
  border-radius: var(--radius-lg);
  cursor: pointer;
  text-align: left;
  transition: border-color var(--transition-default), box-shadow var(--transition-default);
}
.bs-dropdown__trigger:focus-visible { outline: 0; border-color: var(--border-focus); box-shadow: 0 0 0 var(--stroke-hairline) var(--border-focus); }
.bs-dropdown.is-open > .bs-dropdown__trigger { border-color: var(--border-focus); box-shadow: 0 0 0 var(--stroke-hairline) var(--border-focus); }
.bs-dropdown__trigger:disabled { background: var(--bg-surface-raised); color: var(--text-tertiary); border-color: var(--border-subtle); cursor: not-allowed; }
.bs-dropdown__value { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bs-dropdown__value.is-placeholder { color: var(--text-tertiary); }
.bs-dropdown__chev { font-size: var(--size-icon-md); color: var(--text-secondary); transition: transform var(--transition-default); }
.bs-dropdown.is-open .bs-dropdown__chev { transform: rotate(180deg); }
.bs-dropdown__menu {
  display: none;
  position: absolute;
  top: calc(100% + var(--space-2));
  left: 0;
  z-index: var(--z-popover);
  min-width: 220px;
  box-sizing: border-box;
  padding: var(--space-3);
  background: var(--bg-surface);
  border: var(--stroke-hairline) solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.bs-dropdown--field .bs-dropdown__menu { right: 0; }
.bs-dropdown--right .bs-dropdown__menu { left: auto; right: 0; }
.bs-dropdown.is-open > .bs-dropdown__menu { display: block; }
/* Com a Popover API (components.js põe o atributo popover) o menu sobe para a camada de topo: nunca é cortado por card, modal ou rolagem.
   Celular (< 960): bottom sheet com fundo escurecido. Desktop (>= 960): ancorado no gatilho (posição vem de --bs-menu-x/-y/-w/-max). */
.bs-dropdown__menu:popover-open {
  position: fixed;
  inset: auto 0 0 0;
  width: 100%;
  min-width: 0;
  max-height: 70dvh;
  margin: 0;
  padding: var(--space-3) var(--space-3) calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
  border: 0;
  border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
  box-shadow: var(--shadow-xl);
  color: var(--text-primary);
  animation: bs-sheet-in var(--duration-slow) var(--ease-enter);
}
.bs-dropdown__menu:popover-open::backdrop { background: var(--bg-scrim); animation: bs-fade-in var(--duration-slow) var(--ease-enter); }
@media (min-width: 960px) {
  .bs-dropdown__menu:popover-open {
    inset: auto;
    top: var(--bs-menu-y, 0);
    left: var(--bs-menu-x, 0);
    width: var(--bs-menu-w, auto);
    min-width: 220px;
    max-height: var(--bs-menu-max, 70dvh);
    padding: var(--space-3);
    border: var(--stroke-hairline) solid var(--border-default);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    animation: none;
  }
  .bs-dropdown__menu:popover-open::backdrop { background: transparent; animation: none; }
}
@media (prefers-reduced-motion: reduce) { .bs-dropdown__menu:popover-open, .bs-dropdown__menu:popover-open::backdrop { animation: none; } }
.bs-dropdown__group { padding: var(--space-4) var(--space-4) var(--space-2); font-size: var(--font-size-12); font-weight: var(--font-weight-bold); color: var(--text-tertiary); text-transform: uppercase; }
.bs-dropdown__item {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  height: var(--size-control-md);
  padding: 0 var(--space-4);
  box-sizing: border-box;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font-corpo);
  font-size: var(--font-size-16);
  font-weight: var(--font-weight-medium);
  text-align: left;
  cursor: pointer;
}
.bs-dropdown__item:hover, .bs-dropdown__item.is-hover, .bs-dropdown__item:focus-visible { background: var(--bg-surface-raised); outline: 0; }
.bs-dropdown__item--danger { color: var(--text-danger); }
.bs-dropdown__item-icon { font-size: var(--size-icon-md); color: var(--text-secondary); }
.bs-dropdown__item--danger .bs-dropdown__item-icon { color: inherit; }
.bs-dropdown__check { margin-left: auto; font-size: var(--size-icon-md); color: var(--text-brand); visibility: hidden; }
.bs-dropdown__item.is-selected .bs-dropdown__check { visibility: visible; }
/* --multi: escolha de vários. Cada item leva a caixinha do Checkbox (bs-checkbox__box) antes do texto e o menu não fecha ao marcar. O valor do campo mostra o item ou "N selecionados" (texto sem escolha em data-placeholder). */
.bs-dropdown--multi .bs-dropdown__item.is-selected .bs-checkbox__box { background: var(--interactive-primary); border-color: var(--interactive-primary); color: var(--text-on-brand-fill); }

/* ===== Menu (lista vertical de seção) =========================================
   Menu de páginas irmãs dentro de uma tela (molécula): um card escuro com um título opcional e uma lista de itens, um por página.
   Partes: __title (opcional) · __item (<a> ou <button>) · __check (ícone check, só aparece no item atual).
   Estados do item: padrão · hover (fundo elevado) · selecionado (aria-current="page" ou is-selected: fundo rosa suave, texto rosa e check) · foco por teclado.
   Primeiro uso: menu da categoria na tela do fetiche do Glossário. Só desktop: no celular entra o Filtro em chips com rolagem horizontal. Não é o Dropdown (não abre nem fecha) nem a Sidebar (navegação principal).
   ========================================================================== */
.bs-menu { display: flex; flex-direction: column; gap: var(--space-2); box-sizing: border-box; padding: var(--space-4); border-radius: var(--radius-xl); background: var(--bg-surface); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-menu__title { margin: 0; padding: var(--space-3) var(--space-4); font-size: var(--font-size-14); font-weight: var(--font-weight-bold); color: var(--text-secondary); }
.bs-menu__item { display: flex; align-items: center; gap: var(--space-4); box-sizing: border-box; width: 100%; min-height: var(--size-control-md); padding: var(--space-3) var(--space-4); border: 0; border-radius: var(--radius-md); background: transparent; color: var(--text-primary); font-family: var(--font-corpo); font-size: var(--font-size-16); font-weight: var(--font-weight-medium); line-height: var(--line-height-snug); text-align: left; text-decoration: none; cursor: pointer; transition: background var(--transition-default), color var(--transition-default); }
.bs-menu__item:hover, .bs-menu__item.is-hover { background: var(--bg-surface-raised); }
.bs-menu__item:focus-visible, .bs-menu__item.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-menu__item[aria-current="page"], .bs-menu__item.is-selected { background: var(--interactive-primary-subtle); color: var(--text-brand); }
.bs-menu__check { margin-left: auto; flex: none; font-size: var(--size-icon-md); visibility: hidden; }
.bs-menu__item[aria-current="page"] .bs-menu__check, .bs-menu__item.is-selected .bs-menu__check { visibility: visible; }
@media (prefers-reduced-motion: reduce) { .bs-menu__item { transition: none; } }

/* ===== Accordion ==============================================================
   Item que abre e fecha empurrando o conteúdo, com a altura animada (components.js).
   Visual: fundo de card, raio 20. O "+" gira 45° ao abrir.  --raised: para usar dentro de um card.
   ========================================================================== */
.bs-accordion__item { background: var(--bg-surface); border-radius: var(--radius-xl); margin-bottom: var(--space-3); overflow: hidden; }
.bs-accordion--raised .bs-accordion__item { background: var(--bg-surface-raised); }
.bs-accordion__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  min-height: calc(var(--size-control-lg) + var(--space-3));
  padding: var(--space-3) var(--space-6);
  box-sizing: border-box;
  border: 0;
  background: transparent;
  color: var(--text-primary);
  font-family: var(--font-corpo);
  font-size: var(--font-size-16);
  font-weight: var(--font-weight-bold);
  text-align: left;
  cursor: pointer;
}
.bs-accordion__trigger:focus-visible { outline: var(--focus-ring); outline-offset: calc(var(--focus-offset) * -1); border-radius: var(--radius-xl); }
.bs-accordion__icon { flex-shrink: 0; width: var(--size-icon-md); line-height: 1; font-size: var(--font-size-24); font-weight: var(--font-weight-regular); color: var(--text-brand); text-align: center; transition: transform var(--duration-slow) var(--ease-standard); }
.bs-accordion__item.is-open .bs-accordion__icon { transform: rotate(45deg); }
.bs-accordion__panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--duration-slow) var(--ease-standard); }
.bs-accordion__item.is-open .bs-accordion__panel { grid-template-rows: 1fr; }
.bs-accordion__inner { overflow: hidden; min-height: 0; visibility: hidden; transition: visibility 0s linear var(--duration-slow); }
.bs-accordion__item.is-open .bs-accordion__inner { visibility: visible; transition-delay: 0s; }
.bs-accordion__content { padding: 0 var(--space-6) var(--space-5); font-family: var(--font-corpo); font-size: var(--font-size-16); line-height: var(--line-height-normal); color: var(--text-secondary); }

/* ===== Upload =================================================================
   Área tracejada clicável para adicionar imagem. <label> envolve o <input type="file" hidden>.
   FORMA: barra (padrão) · --tile (quadrado só com ícone) · --grid (quadrado 1:1 com ícone e texto)
   Imagem escolhida: troque o conteúdo por .bs-upload__preview (img + IconButton de remover).
   ========================================================================== */
.bs-upload {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  box-sizing: border-box;
  width: 100%;
  height: var(--space-11);
  border: var(--stroke-hairline) dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-corpo);
  font-size: var(--font-size-14);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  transition: border-color var(--transition-default), color var(--transition-default);
}
.bs-upload:hover, .bs-upload.is-hover { border-color: var(--interactive-primary); color: var(--text-brand); }
.bs-upload:focus-within { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-upload__icon { font-size: var(--size-icon-md); }
.bs-upload--tile { width: var(--size-avatar-xl); height: var(--size-avatar-xl); border-radius: var(--radius-md); }
.bs-upload--grid { height: auto; aspect-ratio: 1; flex-direction: column; background: var(--bg-surface-raised); border-style: solid; border-color: transparent; border-radius: var(--radius-md); font-size: var(--font-size-12); }
.bs-upload--grid:hover { border-color: var(--interactive-primary); }
.bs-upload__preview { position: relative; display: block; width: 100%; aspect-ratio: 1; overflow: hidden; border-radius: var(--radius-md); background: var(--bg-surface-raised); }
.bs-upload__preview img { display: block; width: 100%; height: 100%; object-fit: cover; }
.bs-upload__remove { position: absolute; top: var(--space-2); right: var(--space-2); }

/* ===== Card (casca) ===========================================================
   Uma única casca. Sem borda e sem sombra: a separação vem da cor da superfície.
   Slots (todos opcionais, exceto __body): __media · __header · __body · __footer
   MODIFICADORES: --raised (sobre outro card) · --lg (raio 24) · --interactive (clicável) · --outline (só contorno, sem fundo; exceção de 20/out/2026, usada nas Formas de praticar do Glossário)
   ========================================================================== */
.bs-card { display: flex; flex-direction: column; background: var(--bg-surface); border-radius: var(--radius-xl); overflow: hidden; color: var(--text-primary); font-family: var(--font-corpo); }
.bs-card--raised { background: var(--bg-surface-raised); }
.bs-card--lg { border-radius: var(--radius-2xl); }
.bs-card--outline { background: transparent; box-shadow: inset 0 0 0 var(--stroke-hairline) var(--border-strong); }
.bs-card--interactive { cursor: pointer; transition: transform var(--transition-default), background var(--transition-default); }
.bs-card--interactive:hover, .bs-card--interactive.is-hover { transform: translateY(calc(var(--space-1) * -1.5)); background: color-mix(in srgb, var(--bg-surface), var(--white) 3%); }
.bs-card--interactive:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-card__media { width: 100%; aspect-ratio: 16 / 9; overflow: hidden; background: var(--bg-surface-raised); }
.bs-card__media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.bs-card__header { display: flex; align-items: center; gap: var(--space-4); padding: var(--space-6) var(--space-6) 0; }
.bs-card__header-title { margin: 0; font-size: var(--font-size-16); font-weight: var(--font-weight-bold); color: var(--text-primary); }
.bs-card__header-meta { font-size: var(--font-size-12); color: var(--text-secondary); }
.bs-card__body { flex: 1; padding: var(--space-6); overflow-wrap: anywhere; }   /* texto de usuário sem espaços (ex.: "kkkkkkkk...") quebra dentro do card em vez de vazar */
.bs-card__body > p { margin: 0; font-size: var(--font-size-16); line-height: var(--line-height-normal); color: var(--text-secondary); }
.bs-card__footer { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-5) var(--space-6); }

/* ===== Toast ==================================================================
   Aviso rápido e passageiro, branco. Montado por BS.toast() (components.js) dentro de
   .bs-toast-region (fixa, centralizada na base). Ação opcional e barra de tempo.
   ========================================================================== */
.bs-toast-region { position: fixed; left: 50%; bottom: calc(env(safe-area-inset-bottom, 0px) + var(--space-5)); transform: translateX(-50%); z-index: var(--z-toast); display: flex; flex-direction: column; align-items: center; gap: var(--space-3); max-width: 92%; pointer-events: none; }
.bs-toast {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  max-width: 100%;
  box-sizing: border-box;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--bg-inverse);
  color: var(--text-inverse);
  font-family: var(--font-corpo);
  font-size: var(--font-size-16);
  font-weight: var(--font-weight-medium);
  box-shadow: var(--shadow-xl);
  pointer-events: auto;
  animation: bs-toast-in var(--duration-base) var(--ease-enter);
}
.bs-toast.is-leaving { opacity: 0; transform: translateY(var(--space-3)); transition: opacity var(--duration-base), transform var(--duration-base); }
.bs-toast__action { min-height: var(--size-control-sm); padding: 0 var(--space-2); border: 0; background: transparent; color: var(--pink-700); font: inherit; font-weight: var(--font-weight-bold); cursor: pointer; }
.bs-toast__action:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); border-radius: var(--radius-sm); }
.bs-toast__bar { position: absolute; left: 0; bottom: 0; height: 3px; background: var(--interactive-primary); animation: bs-toast-bar var(--bs-toast-ms, 5s) linear forwards; }
.bs-toast--static { position: relative; animation: none; display: inline-flex; }
@keyframes bs-toast-in { from { opacity: 0; transform: translateY(var(--space-3)); } to { opacity: 1; transform: none; } }
@keyframes bs-toast-bar { from { width: 100%; } to { width: 0; } }

@media (prefers-reduced-motion: reduce) {
  .bs-like__track, .bs-accordion__panel, .bs-accordion__icon, .bs-tabs.is-ready .bs-tabs__indicator, .bs-toast { transition: none; animation: none; }
}

/* ===== Utilitários de domínio ================================================= */
.bs-raridade-comum { --bs-rarity: var(--raridade-comum); }
.bs-raridade-rara { --bs-rarity: var(--raridade-rara); }
.bs-raridade-epica { --bs-rarity: var(--raridade-epica); }
.bs-raridade-lendaria { --bs-rarity: var(--raridade-lendaria); }
/* Categoria do blog: define --bs-pill para a tag do Article card e do Article */
.bs-artcat-scat          { --bs-pill: var(--artigo-scat); }
.bs-artcat-fetiche       { --bs-pill: var(--artigo-fetiche); }
.bs-artcat-saude         { --bs-pill: var(--artigo-saude); }
.bs-artcat-golden-shower { --bs-pill: var(--artigo-golden-shower); }
.bs-artcat-entrevistas   { --bs-pill: var(--artigo-entrevistas); }
.bs-artcat-contos        { --bs-pill: var(--artigo-contos); }
.bs-artcat-outras       { --bs-pill: var(--artigo-outras); }   /* qualquer outra categoria do blog (ABDL, BDSM, Pelos...) */
/* Nível (gamificação): define --bs-level para o badge de nível */
.bs-level-bronze   { --bs-level: var(--nivel-bronze); }
.bs-level-prata    { --bs-level: var(--nivel-prata); }
.bs-level-ouro     { --bs-level: var(--nivel-ouro); }
.bs-level-diamante { --bs-level: var(--nivel-diamante); }
/* Nível do Respeito (8 níveis): define --bs-lv (e --bs-lv-alt, nos níveis 5 a 7) para Emblem, Profile card e Pill de nível */
.bs-lv-1 { --bs-lv: var(--nivel-1); }
.bs-lv-2 { --bs-lv: var(--nivel-2); }
.bs-lv-3 { --bs-lv: var(--nivel-3); }
.bs-lv-4 { --bs-lv: var(--nivel-4); }
.bs-lv-5 { --bs-lv: var(--nivel-5); --bs-lv-alt: var(--nivel-5-alt); }
.bs-lv-6 { --bs-lv: var(--nivel-6); --bs-lv-alt: var(--nivel-6-alt); }
.bs-lv-7 { --bs-lv: var(--nivel-7); --bs-lv-alt: var(--nivel-7-alt); }
.bs-lv-8 { --bs-lv: var(--nivel-8); }
/* Seção do menu: define --bs-nav para o ícone colorido da Sidebar */
.bs-nav-inicio       { --bs-nav: var(--nav-inicio); }
.bs-nav-ler          { --bs-nav: var(--nav-ler); }
.bs-nav-artigos      { --bs-nav: var(--nav-artigos); }
.bs-nav-hentais      { --bs-nav: var(--nav-hentais); }
.bs-nav-mural        { --bs-nav: var(--nav-mural); }
.bs-nav-historias    { --bs-nav: var(--nav-historias); }
.bs-nav-glossario    { --bs-nav: var(--nav-glossario); }
.bs-nav-ranking      { --bs-nav: var(--nav-ranking); }
.bs-nav-perfis       { --bs-nav: var(--nav-perfis); }
.bs-nav-match        { --bs-nav: var(--nav-match); }
.bs-nav-mensagens    { --bs-nav: var(--nav-mensagens); }
.bs-nav-notificacoes { --bs-nav: var(--nav-notificacoes); }
.bs-nav-contos       { --bs-nav: var(--nav-contos); }
.bs-nav-livros       { --bs-nav: var(--nav-livros); }
.bs-nav-sites        { --bs-nav: var(--nav-sites); }
.bs-nav-perfil       { --bs-nav: var(--nav-perfil); }
.bs-nav-menu         { --bs-nav: var(--nav-menu); }
.bs-nav-conquistas   { --bs-nav: var(--nav-conquistas); }
.bs-nav-respeito     { --bs-nav: var(--nav-respeito); }
.bs-nav-estilopig    { --bs-nav: var(--nav-estilopig); }
.bs-nav-ajuda        { --bs-nav: var(--nav-ajuda); }
.bs-nav-avaliar      { --bs-nav: var(--nav-avaliar); }

/* Arquétipo (perfil): define --bs-arq para a linha de arquétipo do Profile card */
.bs-arq-name { color: var(--bs-arq, var(--text-primary)); overflow-wrap: anywhere; }   /* nome do Estilo Pig em texto grande: combine com bs-type-h3 e bs-arq-<tipo> */
.bs-arq-porquinho    { --bs-arq: var(--arquetipo-porquinho); }
.bs-arq-fluido       { --bs-arq: var(--arquetipo-fluido); }
.bs-arq-sensorial    { --bs-arq: var(--arquetipo-sensorial); }
.bs-arq-estrategista { --bs-arq: var(--arquetipo-estrategista); }
.bs-arq-jogador      { --bs-arq: var(--arquetipo-jogador); }
.bs-arq-showman      { --bs-arq: var(--arquetipo-showman); }

/* Esqueleto de carregamento */
.bs-skeleton { border-radius: var(--radius-md); background: linear-gradient(90deg, var(--bg-surface-raised) 25%, var(--bg-surface-overlay) 50%, var(--bg-surface-raised) 75%); background-size: 200% 100%; animation: bs-shimmer 1.4s infinite; }
@keyframes bs-shimmer { to { background-position: -200% 0; } }

/* ===== Comment ================================================================
   Comentário (molécula): avatar quadrado pequeno, nome, hora e texto. Usado no card do mural e na história.
   Partes: __body, __name (com __time dentro), __text. Bloco: .bs-comments = título “Comentários (n)” (__title) + comentários + formulário, em coluna com espaço de 20, e margem de 24 em cima e embaixo (o bloco já traz o respiro do conteúdo vizinho).
   O avatar fica alinhado ao topo do texto. O nome é um link (__author) quando a pessoa tem perfil.
   Curtir (__actions, opcional): abaixo do texto, um Like solto (--plain: sem fundo, só coração e número, pequeno); cada comentário tem o seu.
   Menu opcional (__menu): à direita do comentário, recebe um Dropdown de ações (gatilho IconButton terciário pequeno, ícone more_horiz). Dono: Excluir; outras pessoas: Denunciar.
   Formulário: .bs-comment-form = campo (Input --grow) + IconButton primário de enviar, alinhados pela base.
   ========================================================================== */
.bs-comments { display: flex; flex-direction: column; gap: var(--space-6); margin-block: var(--space-7); }
.bs-comments__title { margin: 0; font-size: var(--font-size-16); font-weight: var(--font-weight-bold); line-height: var(--line-height-snug); color: var(--text-primary); }
.bs-comment { display: flex; align-items: flex-start; gap: var(--space-4); }
.bs-comment__body { flex: 1; min-width: 0; }
.bs-comment__menu { flex: none; margin-top: calc(var(--space-3) * -1); margin-right: calc(var(--space-3) * -1); }
.bs-comment__name { display: block; font-weight: var(--font-weight-bold); line-height: var(--line-height-tight); }
.bs-comment__time { margin-left: var(--space-3); font-weight: var(--font-weight-regular); font-size: var(--font-size-12); color: var(--text-secondary); }
.bs-comment__author { color: inherit; text-decoration: none; cursor: pointer; transition: color var(--transition-default); }
.bs-comment__author:hover, .bs-comment__author.is-hover { color: var(--text-brand); }
.bs-comment__author:focus-visible, .bs-comment__author.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); border-radius: var(--radius-xs); }
.bs-comment__text { overflow-wrap: anywhere; margin: var(--space-2) 0 0; font-size: var(--font-size-16); font-weight: var(--font-weight-regular); line-height: var(--line-height-normal); }
.bs-comment__actions { display: flex; margin-top: var(--space-2); }
.bs-comment-form { display: flex; align-items: flex-end; gap: var(--space-3); }

/* ===== Alert ==================================================================
   Mensagem fixa dentro da tela (molécula): ícone, texto e, se precisar, uma ação e um fechar. Fica no lugar em que a pessoa precisa dela e só some se ela fechar ou se o problema se resolver.
   Não é o Toast (aviso passageiro, branco, some sozinho) nem o Banner (aviso do admin entre os posts do mural).
   TIPO (1): padrão (neutro, cinza) · --info · --success · --warning · --danger. A cor vai no fundo e no ícone; o texto é sempre branco e o ícone repete o sentido (nunca só a cor).
   Partes: __icon · __body (__title opcional, __text, __actions opcional) · __close (IconButton --sm com data-bs-dismiss=".bs-alert").
   Link dentro do texto: Link (bs-link), sempre sublinhado aqui (rosa e branco têm quase a mesma luz, só a cor não basta).
   Leitor de tela: role="status" (aviso calmo); só erro usa role="alert". Não recebe foco.
   ========================================================================== */
.bs-alert { display: flex; align-items: flex-start; gap: var(--space-4); box-sizing: border-box; padding: var(--space-4) var(--space-5); border-radius: var(--radius-lg); background: var(--bs-alert-bg, var(--bg-surface-raised)); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-alert--info { --bs-alert: var(--status-info); --bs-alert-bg: var(--status-info-bg); }
.bs-alert--success { --bs-alert: var(--status-success); --bs-alert-bg: var(--status-success-bg); }
.bs-alert--warning { --bs-alert: var(--status-warning); --bs-alert-bg: var(--status-warning-bg); }
.bs-alert--danger { --bs-alert: var(--status-danger); --bs-alert-bg: var(--status-danger-bg); }
.bs-alert__icon { flex: none; display: grid; place-items: center; height: calc(var(--font-size-14) * var(--line-height-normal)); font-size: var(--size-icon-md); color: var(--bs-alert, var(--text-secondary)); }
.bs-alert__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.bs-alert__title { margin: 0; font-size: var(--font-size-14); font-weight: var(--font-weight-bold); line-height: var(--line-height-normal); }
.bs-alert__text { margin: 0; font-size: var(--font-size-14); font-weight: var(--font-weight-medium); line-height: var(--line-height-normal); }
.bs-alert__actions { display: flex; flex-wrap: wrap; gap: var(--space-3) var(--space-5); margin-top: var(--space-2); font-size: var(--font-size-14); font-weight: var(--font-weight-bold); }
.bs-alert .bs-link { text-decoration: underline; text-underline-offset: var(--space-1); }
.bs-alert__close { flex: none; margin-block: calc(var(--space-3) * -1); margin-right: calc(var(--space-3) * -1); }

/* ===== Story card =============================================================
   Card de uma história na lista de Histórias (organismo). É um <button> ou <a> clicável.
   A pill (fetiche ou Entrevista) fica direto no card, empilhadas. Partes: __title, __excerpt (3 linhas), __footer (avatar + nome + __stat).
   Modificador: --featured (destaque do editor: ocupa a linha toda da grade). Grade: .bs-story-grid.
   Hover e foco iguais ao Card interativo.
   ========================================================================== */
.bs-story-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(var(--layout-sheet) * 0.6), 1fr)); gap: var(--space-6); }
.bs-story-card { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-4); box-sizing: border-box; width: 100%; padding: var(--space-6); border: 0; border-radius: var(--radius-xl); background: var(--bg-surface); color: var(--text-primary); font-family: var(--font-corpo); text-align: left; text-decoration: none; cursor: pointer; transition: transform var(--transition-default), background var(--transition-default); }
.bs-story-card:hover, .bs-story-card.is-hover { transform: translateY(calc(var(--space-1) * -1.5)); background: color-mix(in srgb, var(--bg-surface), var(--white) 3%); }
.bs-story-card:focus-visible, .bs-story-card.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-story-card--featured { grid-column: 1 / -1; }
.bs-story-card__title { font-size: var(--font-size-24); font-weight: var(--font-weight-regular); line-height: var(--line-height-tight); letter-spacing: -.02em; }
.bs-story-card__excerpt { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; font-size: var(--font-size-16); line-height: var(--line-height-normal); color: var(--text-secondary); }
.bs-story-card__footer { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-top: var(--space-2); font-size: var(--font-size-14); color: var(--text-secondary); }
.bs-story-card__stat { display: inline-flex; align-items: center; gap: var(--space-2); }
@media (prefers-reduced-motion: reduce) { .bs-story-card { transition: none; } .bs-story-card:hover, .bs-story-card.is-hover { transform: none; } }

/* ===== Stat ===================================================================
   Cartão de número (molécula): ícone num quadrado de cor + valor + rótulo. Grandes números do perfil
   (Pontos, Nível, Posts, Desde) e a Atividade. Não é clicável. Partes: __icon · __body · __value · __label.
   COR do ícone: --pink · --green · --sky · --purple · --amber, ou bs-level-* no mesmo elemento (Nível). Sem cor: rosa de marca.
   O ícone é sempre branco (decisão do dono do projeto; contraste de ícone abaixo de 3:1, ver página).
   FORMA: padrão (coluna, sobre o fundo da página) · --inline (linha, sobre um card: fundo elevado) · --wide (ocupa a linha toda da grade).
   Grade: .bs-stat-grid (fluida, sem breakpoint: auto-fit com --size-stat-min).
   ========================================================================== */
.bs-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(var(--size-stat-min), 1fr)); gap: var(--space-4); }
.bs-stat { display: flex; flex-direction: column; gap: var(--space-4); box-sizing: border-box; min-width: 0; padding: var(--space-6); border-radius: var(--radius-xl); background: var(--bg-surface); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-stat__icon { display: grid; place-items: center; flex: none; width: var(--size-control-md); height: var(--size-control-md); border-radius: var(--radius-md); background: var(--bs-stat, var(--bs-level, var(--interactive-primary))); color: var(--white); font-size: var(--size-icon-lg); }
.bs-stat__icon:has(.bs-emblem) { background: var(--bg-surface-raised); }   /* Stat de nível: o badge traz a própria cor */
.bs-stat__body { min-width: 0; }
.bs-stat__value { display: block; overflow: hidden; font-size: var(--font-size-24); font-weight: var(--font-weight-bold); line-height: var(--line-height-tight); white-space: nowrap; text-overflow: ellipsis; }
/* Stat --fit (28/10/2026): o valor é um texto que pode ser comprido (nome do Estilo Pig). Em grade larga (>= 640px) nunca quebra: a fonte diminui até caber numa linha (mínimo 12px).
   Em grade estreita quebra em no máximo 2 linhas, também diminuindo a fonte. A conta usa duas variáveis que o HTML informa: --bs-fit-n = letras do texto, --bs-fit-m = letras da maior linha na melhor quebra em 2 linhas. */
.bs-stat-grid { container-type: inline-size; container-name: bs-stat-grid; }
.bs-stat--fit { container-type: inline-size; }
.bs-stat--fit .bs-stat__value { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; white-space: normal; line-height: var(--line-height-snug); font-size: max(var(--font-size-12), min(var(--font-size-24), calc(100cqw / (var(--bs-fit-m, 12) * 0.6)))); }
@container bs-stat-grid (min-width: 640px) {
  .bs-stat--fit .bs-stat__value { display: block; white-space: nowrap; line-height: var(--line-height-tight); font-size: max(var(--font-size-12), min(var(--font-size-24), calc(100cqw / (var(--bs-fit-n, 12) * 0.6)))); }
}
.bs-stat__label { display: block; margin-top: var(--space-2); font-size: var(--font-size-14); color: var(--text-secondary); white-space: nowrap; }
.bs-stat--inline { flex-direction: row; align-items: center; padding: var(--space-5); border-radius: var(--radius-lg); background: var(--bg-surface-raised); }
.bs-stat--wide { grid-column: 1 / -1; }
.bs-stat--pink { --bs-stat: var(--stat-pink); }
.bs-stat--green { --bs-stat: var(--stat-green); }
.bs-stat--sky { --bs-stat: var(--stat-sky); }
.bs-stat--purple { --bs-stat: var(--stat-purple); }
.bs-stat--amber { --bs-stat: var(--stat-amber); }

/* ===== Profile hero ===========================================================
   Cabeçalho do perfil (organismo), a base de todos os cabeçalhos de perfil. Muda sozinho conforme a largura do
   próprio elemento (container query, literal 640px porque container query não aceita variável):
   CELULAR: a foto (o avatar) ocupa o quadro todo (__photo), com degradê até a cor da página (--gradient-profile-photo).
            Sobre ela: botões no topo (__top: voltar + __tools), nome grande (__name), linha de dados (__meta),
            pills (__tags) e a ação principal (__actions) em largura total. Sem capa.
   DESKTOP: capa (__cover, com o nome dentro: __cover-name) + avatar quadrado 3xl sobreposto (__avatar) + ação à direita
            (__actions) + pills (__tags). Sem foto cheia.
   O que é de um modo só leva __mob (só celular) ou __desk (só desktop); os dois textos existem no HTML e o outro some.
   A ação principal muda por caso de uso (dono, outra pessoa logada, visitante): quem monta o HTML decide; o componente só dispõe.
   O celular sangra até a borda da tela pela variável --bs-rail-bleed (a margem do container, como o Rail).
   Abas: ficam fora (irmãs do hero); o hero não conhece as abas.
   ========================================================================== */
.bs-profile-hero { container: bs-profile-hero / inline-size; }
.bs-profile-hero__frame { position: relative; display: flex; flex-direction: column; justify-content: flex-end; box-sizing: border-box; aspect-ratio: var(--ratio-profile-hero); margin-inline: calc(var(--bs-rail-bleed, 0px) * -1); padding: var(--space-5) var(--space-5) var(--size-control-lg); overflow: hidden; background: var(--bg-canvas); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-profile-hero__photo { position: absolute; inset: 0; display: grid; place-items: center; background: var(--bs-avatar-bg, var(--bg-surface)) center / cover no-repeat; color: var(--text-on-image); font-size: var(--font-size-48); font-weight: var(--font-weight-black); }
.bs-profile-hero__photo img { width: 100%; height: 100%; object-fit: cover; }
.bs-profile-hero__photo::after { content: ''; position: absolute; inset: 0; background: var(--gradient-profile-photo); pointer-events: none; }
.bs-profile-hero__cover { position: relative; display: none; height: calc(var(--size-avatar-3xl) * 2); border-radius: var(--radius-xl); overflow: hidden; }
.bs-profile-hero__cover::after { content: ''; position: absolute; inset: auto 0 0 0; height: 60%; background: linear-gradient(transparent, var(--bg-on-image)); pointer-events: none; }
.bs-profile-hero__cover-name { position: absolute; z-index: var(--z-raised); left: calc(var(--size-avatar-3xl) + var(--space-9) + var(--space-6)); right: var(--space-5); bottom: var(--space-5); display: flex; align-items: center; gap: var(--space-3); min-width: 0; margin: 0; font-size: var(--font-size-32); font-weight: var(--font-weight-black); line-height: var(--line-height-tight); }
/* Capa em gradiente animado (14/11/2026): sem foto. Cor do Respeito (bs-lv-N) + cor do Estilo Pig (bs-arq-X); sem Estilo Pig, dois tons do Respeito (--bs-cover-a / --bs-cover-b). */
.bs-profile-hero__cover--gradient { --bs-cover-a: color-mix(in srgb, var(--bs-lv) 65%, var(--white)); --bs-cover-b: color-mix(in srgb, var(--bs-lv) 70%, var(--black)); background: linear-gradient(115deg, var(--bs-cover-a), var(--bs-cover-b), var(--bs-cover-a)); background-size: 220% 220%; animation: bs-cover-flow calc(var(--duration-ambient) * 4) ease-in-out infinite; }
.bs-profile-hero__cover--gradient[class*="bs-arq-"] { --bs-cover-a: var(--bs-lv); --bs-cover-b: var(--bs-arq); }
@keyframes bs-cover-flow { 0%, 100% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } }
@media (prefers-reduced-motion: reduce) { .bs-profile-hero__cover--gradient { animation: none; background-position: 30% 50%; } }
.bs-profile-hero__top { position: absolute; z-index: var(--z-overlap); top: var(--space-5); left: var(--space-5); right: var(--space-5); display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); }
.bs-profile-hero__tools { display: flex; gap: var(--space-3); margin-left: auto; }
.bs-profile-hero__body { position: relative; z-index: var(--z-raised); display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.bs-profile-hero__name { display: flex; align-items: center; gap: var(--space-3); min-width: 0; margin: 0; font-size: var(--font-size-48); font-weight: var(--font-weight-black); line-height: var(--line-height-tight); overflow-wrap: anywhere; }
.bs-profile-hero__meta { margin: 0; font-size: var(--font-size-16); font-weight: var(--font-weight-medium); color: var(--text-secondary); }
.bs-profile-hero__tags { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.bs-profile-hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.bs-profile-hero__actions > .bs-btn:first-child:not(:only-child), .bs-profile-hero__actions > .bs-btn:only-child { flex: 1 1 auto; }
.bs-profile-hero__actions .bs-btn:disabled { opacity: 1; background: var(--bg-surface-raised); color: var(--text-secondary); }
.bs-profile-hero__avatar { position: relative; display: none; }
.bs-profile-hero__avatar-edit { position: absolute; right: calc(var(--space-2) * -1); bottom: calc(var(--space-1) * -1); }
.bs-profile-hero .bs-profile-hero__desk { display: none; }
@container bs-profile-hero (min-width: 720px) {
  .bs-profile-hero__frame { display: block; aspect-ratio: auto; margin-inline: 0; padding: 0; overflow: visible; background: none; }
  .bs-profile-hero .bs-profile-hero__mob { display: none; }
  .bs-profile-hero .bs-profile-hero__cover { display: block; }
  .bs-profile-hero .bs-profile-hero__avatar { display: inline-flex; }
  .bs-profile-hero .bs-profile-hero__tags.bs-profile-hero__desk { display: flex; }
  .bs-profile-hero .bs-profile-hero__actions > .bs-profile-hero__desk { display: inline-flex; }
  .bs-profile-hero__body { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: end; gap: var(--space-4) var(--space-5); padding-inline: var(--space-6); margin-top: calc(var(--size-avatar-3xl) / -2); }
  .bs-profile-hero__avatar { grid-area: 1 / 1; }
  .bs-profile-hero__actions { grid-area: 1 / 2; justify-content: flex-end; padding-bottom: var(--space-3); }
  .bs-profile-hero__tags { grid-area: 2 / 1 / 3 / -1; }
  .bs-profile-hero__actions > .bs-btn:first-child:not(:only-child), .bs-profile-hero__actions > .bs-btn:only-child { flex: 0 0 auto; }
}

/* ===== Modal / Sheet ==========================================================
   Uma casca única, em <dialog class="bs-modal"> (foco, Esc e fundo vêm do navegador).
   Celular (< 960): sobe da base como sheet.  Desktop (>= 960): modal centralizado.
   (O breakpoint é --bp-desktop; variáveis CSS não funcionam em @media, por isso o valor aparece escrito.)
   FORMA: padrão 580 · --wide 760 · --full (tela cheia sempre) · --page (tela cheia no celular, modal centralizado no desktop) · --drawer (celular: sheet; desktop: painel na borda direita, 480).  Slots: __header · __body · __footer
   Abrir/fechar: components.js (data-bs-open="#id" · data-bs-close).
   ========================================================================== */
.bs-modal {
  --bs-modal-w: var(--layout-sheet);
  flex-direction: column;
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  max-height: 92dvh;
  margin: auto 0 0;
  padding: 0;
  border: 0;
  border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
  background: var(--bg-surface);
  color: var(--text-primary);
  font-family: var(--font-corpo);
  box-shadow: var(--shadow-xl);
  overflow: hidden;
}
/* Entrada: no celular o sheet sobe de baixo para cima (bs-sheet-in) e o fundo escurece (bs-fade-in); no desktop o modal só sobe um pouco (bs-modal-in). Usa a propriedade translate, que não briga com transform. */
.bs-modal[open] { display: flex; animation: bs-sheet-in var(--duration-slow) var(--ease-enter); }
.bs-modal[open]::backdrop { animation: bs-fade-in var(--duration-slow) var(--ease-enter); }
.bs-modal::backdrop { background: var(--bg-scrim); }
.bs-modal--wide { --bs-modal-w: var(--layout-form); }
@media (min-width: 960px) {
  .bs-modal { margin: auto; width: min(var(--bs-modal-w), 92vw); max-height: 88dvh; border-radius: var(--radius-2xl); }
  .bs-modal[open] { animation-name: bs-modal-in; }
}
.bs-modal--full { width: 100%; max-width: 100%; height: 100dvh; max-height: 100dvh; margin: 0; border-radius: 0; }
.bs-modal--page { width: 100%; max-width: 100%; height: 100dvh; max-height: 100dvh; margin: 0; border-radius: 0; }
@media (min-width: 960px) {
  .bs-modal--page { margin: auto; width: min(var(--bs-modal-w), 92vw); height: auto; max-height: 88dvh; border-radius: var(--radius-2xl); }
}
/* --drawer: celular = sheet de sempre; desktop = painel colado na borda direita, altura total, largura --layout-drawer, entra deslizando da direita (filtros da lista de Perfis). */
@media (min-width: 960px) {
  .bs-modal--drawer { --bs-modal-w: var(--layout-drawer); width: min(var(--bs-modal-w), 92vw); height: 100dvh; max-height: 100dvh; margin: 0 0 0 auto; border-radius: var(--radius-2xl) 0 0 var(--radius-2xl); }
  .bs-modal--drawer[open] { animation-name: bs-drawer-in; }
}
@keyframes bs-drawer-in { from { translate: 100% 0; } to { translate: 0 0; } }
@keyframes bs-sheet-in { from { translate: 0 100%; } to { translate: 0 0; } }
@keyframes bs-modal-in { from { opacity: 0; translate: 0 var(--space-7); } to { opacity: 1; translate: 0 0; } }
@keyframes bs-fade-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .bs-modal[open], .bs-modal[open]::backdrop { animation: none; } }
.bs-scroll-lock { overflow: hidden; }

.bs-modal__header { display: flex; align-items: center; justify-content: space-between; flex: none; gap: var(--space-4); padding: var(--space-3) var(--space-3) var(--space-3) var(--space-6); border-bottom: var(--stroke-hairline) solid var(--border-default); }
.bs-modal__title { margin: 0; font-size: var(--font-size-18); font-weight: var(--font-weight-bold); }
.bs-modal__body { --bs-rail-bleed: var(--space-6); flex: 1; overflow-y: auto; padding: var(--space-5) var(--space-6) var(--space-6); font-size: var(--font-size-16); line-height: var(--line-height-normal); color: var(--text-secondary); }
.bs-modal__footer { display: flex; justify-content: flex-end; flex: none; flex-wrap: wrap; gap: var(--space-4); padding: var(--space-4) var(--space-6); padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px)); border-top: var(--stroke-hairline) solid var(--border-default); }
.bs-modal--menu .bs-modal__body { padding: var(--space-3); }
/* só para documentação: mostra a casca dentro da página, sem <dialog> */
.bs-modal--static { position: static; display: flex; margin: 0; width: 100%; max-width: 420px; max-height: none; border-radius: var(--radius-2xl); animation: none; }
.bs-modal--static.bs-modal--sheet { max-width: none; border-radius: var(--radius-2xl) var(--radius-2xl) 0 0; }

/* ===== Sidebar ================================================================
   Navegação vertical do desktop (>= 960): um card flutuante e arredondado, na altura total da coluna (o header fica só à direita dele), com o logo no topo e os itens
   em grupos (bs-sidebar__group: Ler, Comunidade). O espaço ao redor do card é de quem o encaixa. Sem perfil, sem pontos, sem "Voltar".
   Ícone colorido por seção (bs-nav-*), contador e cadeado. Ativo: sem fundo, texto e ícone na cor da seção
   e uma barrinha na mesma cor na borda esquerda.
   Compartilha a lista de seções e os ícones com a Tab bar (celular).
   ========================================================================== */
.bs-sidebar { display: flex; flex-direction: column; gap: var(--space-1); box-sizing: border-box; width: var(--layout-sidebar); padding: var(--space-7) var(--space-4); border-radius: var(--radius-2xl); background: var(--bg-surface); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-logo, .bs-sidebar__logo { display: block; flex: none; width: var(--size-logo-sidebar); aspect-ratio: 639 / 350; background: var(--text-primary); -webkit-mask: url("logo.svg") center / contain no-repeat; mask: url("logo.svg") center / contain no-repeat; }
.bs-logo--header { width: var(--size-logo-header); }
.bs-logo--lg { width: var(--size-logo-lg); }   /* logo grande (modal de login) */
.bs-sidebar__logo { margin: var(--space-2) var(--space-5) var(--space-7); }
a.bs-logo:focus-visible, a.bs-sidebar__logo:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); border-radius: var(--radius-xs); }   /* logo como link para o Início */
.bs-sidebar__group { padding: var(--space-6) var(--space-5) var(--space-3); font-size: var(--font-size-12); font-weight: var(--font-weight-black); letter-spacing: .1em; text-transform: uppercase; color: var(--text-tertiary); }
.bs-sidebar__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-5);
  width: 100%;
  min-height: var(--size-control-md);
  padding: 0 var(--space-5);
  box-sizing: border-box;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--text-secondary);
  font-family: var(--font-corpo);
  font-size: var(--font-size-16);
  font-weight: var(--font-weight-bold);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition-default), color var(--transition-default);
}
.bs-sidebar__icon { flex-shrink: 0; font-size: var(--size-icon-md); color: var(--bs-nav, var(--text-secondary)); }
.bs-sidebar__item:hover, .bs-sidebar__item.is-hover { background: var(--bg-canvas); color: var(--text-primary); }
.bs-sidebar__item:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-sidebar__item.is-active, .bs-sidebar__item[aria-current="page"] { background: transparent; color: var(--bs-nav, var(--text-primary)); }
.bs-sidebar__item.is-active::before, .bs-sidebar__item[aria-current="page"]::before { content: ""; position: absolute; left: calc(var(--space-4) * -1); top: 50%; translate: 0 -50%; width: var(--stroke-thick); height: var(--space-7); border-radius: 0 var(--radius-xs) var(--radius-xs) 0; background: var(--bs-nav, var(--text-brand)); }
.bs-sidebar__badge { margin-left: auto; display: grid; place-items: center; min-width: 22px; height: 22px; padding: 0 var(--space-3); box-sizing: border-box; border-radius: var(--radius-pill); background: var(--interactive-primary); color: var(--text-on-brand-fill); font-size: var(--font-size-12); font-weight: var(--font-weight-bold); }
.bs-sidebar__lock { margin-left: auto; font-size: var(--size-icon-sm); color: var(--text-tertiary); }

/* ===== Action pill ============================================================
   Cápsula flutuante com os botões de ação do topo (ajuda, mensagens, notificações, perfil): só
   bs-icon-btn (e o avatar) lado a lado, fundo de card e sombra de flutuante. Não é uma barra:
   fica no canto da tela e o conteúdo passa por baixo dela. Quem encaixa decide a posição.
   ========================================================================== */
.bs-action-pill { --bs-icon-btn-ring: var(--bg-surface); display: inline-flex; align-items: center; gap: var(--space-2); padding: var(--space-2); box-sizing: border-box; border-radius: var(--radius-pill); background: var(--bg-surface); box-shadow: var(--shadow-lg); }

/* ===== Tab bar ================================================================
   Navegação inferior do celular (< 960): uma barra clara e arredondada que flutua perto da base
   (--fixed). Cada item é um círculo só com ícone; o ATIVO vira uma pílula escura com o ícone na cor da
   seção (bs-nav-*, a mesma da Sidebar) e o nome ao lado (__label). O nome também vai em aria-label;
   os outros têm ícone escuro sobre a barra clara. Cinco itens no máximo.
   ========================================================================== */
.bs-tabbar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); box-sizing: border-box; height: calc(var(--size-tab-item) + var(--space-5)); padding: 0 var(--space-3); border-radius: var(--radius-2xl); background: var(--bg-tabbar); box-shadow: var(--shadow-lg); position: relative; z-index: var(--z-sticky); font-family: var(--font-corpo); }
.bs-tabbar--fixed { position: fixed; left: var(--space-5); right: var(--space-5); bottom: calc(var(--space-5) + env(safe-area-inset-bottom, 0px)); z-index: var(--z-sticky); }
.bs-tabbar__item {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 1 var(--size-tab-item);   /* 09/nov/2026: o item inativo pode encolher até --size-control-sm para o nome longo (Comunidade) caber no item ativo */
  min-width: var(--size-control-sm);
  height: var(--size-tab-item);
  padding: 0;
  box-sizing: border-box;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text-inverse);
  cursor: pointer;
  transition: background var(--transition-default), color var(--transition-default), padding var(--duration-slow) var(--ease-spring);
  -webkit-tap-highlight-color: transparent;
}
.bs-tabbar__item .bs-icon { flex: none; font-size: var(--size-icon-lg); color: currentColor; transition: color var(--transition-default); }
.bs-tabbar__item:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
/* O nome sempre existe no HTML; fechado ele tem largura 0. Ao ativar, a largura cresce com folga elástica e os vizinhos são empurrados junto (a barra é space-between), então tudo se move em uma curva só. */
.bs-tabbar__label { max-width: 0; margin-left: 0; overflow: hidden; opacity: 0; font-size: var(--font-size-14); font-weight: var(--font-weight-bold); white-space: nowrap; transition: max-width var(--duration-slow) var(--ease-spring), margin-left var(--duration-slow) var(--ease-spring), opacity var(--duration-slow) var(--ease-standard); }
.bs-tabbar__item.is-active, .bs-tabbar__item[aria-current="page"] { flex: none; padding: 0 var(--space-4); background: var(--bg-canvas); color: var(--text-primary); }
.bs-tabbar__item.is-active .bs-tabbar__label, .bs-tabbar__item[aria-current="page"] .bs-tabbar__label { max-width: var(--size-tab-label-max); margin-left: var(--space-3); opacity: 1; }
.bs-tabbar__item.is-active .bs-icon, .bs-tabbar__item[aria-current="page"] .bs-icon { color: var(--bs-nav, var(--text-brand)); }
@media (prefers-reduced-motion: reduce) { .bs-tabbar__item, .bs-tabbar__label { transition: none; } }
.bs-tabbar__badge { position: absolute; top: var(--space-2); right: var(--space-2); display: grid; place-items: center; min-width: 18px; height: 18px; padding: 0 var(--space-2); box-sizing: border-box; border-radius: var(--radius-pill); background: var(--interactive-primary); color: var(--text-on-brand-fill); font-size: var(--font-size-12); font-weight: var(--font-weight-bold); }

/* ===== Post card (card do mural) ==============================================
   Construído sobre a casca do Card. Categoria via bs-cat-* no <article>.
   FORMATO: curto (--short) · longo (--long, 7 linhas + Ver mais) · enquete (--poll) · com foto (--photo)
   TEXTO QUE SE AJUSTA (data-bs-fit no <article>, só texto): o JS escolhe o degrau sozinho, do maior ao menor: 24/30 (--short) > 20/25 (--short --text-md) > 16/24 (--long, 7 linhas + Ver mais). Desce um degrau só quando o texto empurrou o avatar até o espaço mínimo.
   FORMATO POR LARGURA (automático): celular (< 480) espaço MÍNIMO de 32 entre a tag e o avatar, elástico até a altura mínima do card · desktop (≥ 480) espaço FIXO de 40 e card sem altura mínima (a altura é a do conteúdo; o texto desce de degrau quando o card passaria de 380, o que dá cerca de 4 linhas no 24/30 e 5 no 20/25).
   Estados: --empty · --skeleton · --hidden · --sold.   Raio 24, sem sombra, sem borda.
   ========================================================================== */
.bs-post {
  --bs-post-min: 480px;
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-2xl);
  background: var(--bg-surface);
  color: var(--text-primary);
  font-family: var(--font-corpo);
  overflow: hidden;
  isolation: isolate;
  container-type: inline-size; container-name: bs-post;   /* o card se mede sozinho: celular até 479px, desktop a partir de 480px */
}
.bs-post--short { --bs-post-min: 456px; }
.bs-post__inner { position: relative; z-index: 2; display: flex; flex-direction: column; flex: 1 0 auto; min-height: var(--bs-post-min); gap: var(--space-8); padding: var(--space-3) var(--space-6) var(--space-6); padding-left: var(--space-6); }   /* gap = espaço mínimo entre a tag e o avatar (celular 32; desktop 40, ver @container no fim) */
.bs-post__top { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); min-height: var(--size-control-md); }
.bs-post__top > .bs-icon-btn, .bs-post__top > .bs-dropdown { margin-right: calc(var(--space-3) * -1); }
.bs-post__body { display: flex; flex-direction: column; gap: var(--space-5); margin-top: auto; }
.bs-post__author { display: flex; align-items: center; gap: var(--space-5); }
.bs-post__who { display: flex; flex-direction: column; gap: var(--space-1); min-width: 0; flex: 1; }
.bs-post__name { display: flex; align-items: center; gap: var(--space-2); min-width: 0; font-size: var(--font-size-16); line-height: 24px; font-weight: var(--font-weight-bold); }
.bs-post__name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; text-decoration: none; }
.bs-post__name .bs-pill { flex: none; }
.bs-post__verified { flex: none; font-size: var(--size-icon-sm); color: var(--text-brand); --ico: var(--ico-s, var(--ico-r)); }
.bs-post__time { font-size: var(--font-size-12); line-height: 18px; color: var(--text-secondary); }
.bs-post__link { color: var(--text-brand); text-decoration: none; overflow-wrap: anywhere; }   /* link digitado no texto do post: rosa e clicável, abre em outra aba (14/nov/2026; antes só a cor) */
.bs-post__link:hover { text-decoration: underline; }
.bs-post__text { overflow-wrap: anywhere; margin: 0; font-size: var(--font-size-24); line-height: var(--line-height-snug); font-weight: var(--font-weight-bold); text-wrap: balance; }
.bs-post--poll .bs-post__text, .bs-post--text-md .bs-post__text { font-size: var(--font-size-20); line-height: 25px; }   /* --text-md: degrau do meio do texto que se ajusta (data-bs-fit) */
.bs-post--regular .bs-post__text { font-weight: var(--font-weight-regular); }   /* texto que se ajusta com mais de ~140 caracteres: peso regular em qualquer degrau (o JS põe a classe; texto curto continua bold) */
@container bs-post (max-width: 420px) { .bs-post--text-md:not(.bs-post--poll) .bs-post__text { font-size: var(--font-size-18); line-height: 22px; } }   /* celular estreito: o degrau do meio é 18/22, não 20/25 (decisão de 10/11/2026) */
.bs-post--long .bs-post__text { font-size: var(--font-size-16); line-height: 24px; font-weight: var(--font-weight-regular); text-wrap: auto; display: -webkit-box; -webkit-line-clamp: 7; -webkit-box-orient: vertical; overflow: hidden; }
.bs-post--long.is-open .bs-post__text { display: block; -webkit-line-clamp: unset; }
.bs-post--long .bs-post__inner { gap: var(--space-8); }
.bs-post__more { align-self: flex-start; padding: var(--space-2) 0; border: 0; background: transparent; color: var(--bs-cat, var(--text-brand)); font-family: inherit; font-size: var(--font-size-16); font-weight: var(--font-weight-bold); cursor: pointer; margin-top: calc(var(--space-4) * -1); }
.bs-post__more:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); border-radius: var(--radius-sm); }
.bs-post__meta { font-size: var(--font-size-12); color: var(--text-secondary); text-align: center; margin-top: calc(var(--space-3) * -1); }
.bs-post__footer { display: flex; align-items: center; gap: var(--space-3); }
.bs-post__share { margin-left: auto; }
/* comentários: filho direto do .bs-post, DEPOIS de __inner (ou __rest). O card não muda de estrutura ao abrir; os comentários só entram embaixo. */
.bs-post__comments { position: relative; z-index: 2; display: flex; flex-direction: column; margin-block: 0; margin-inline: var(--space-6); padding: var(--space-5) 0 var(--space-6); border-top: var(--stroke-hairline) solid var(--border-default); animation: bs-comments-in var(--duration-base) var(--ease-enter); }
@keyframes bs-comments-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .bs-post__comments { animation: none; } }

/* com foto (27/10/2026, versão A2): a foto fica DENTRO do card, entre a tag e o autor, com cantos de 16 e proporção 3:2 (teto --size-post-photo-max).
   Estrutura = a do post de texto (__inner: __top, __media, __body). Mais de uma foto: carrossel de uma por vez, com o contador "1/3" (__count) no canto de cima da foto. */
.bs-post--photo { --bs-post-min: 0px; }
.bs-post--photo .bs-post__inner { gap: var(--space-5); min-height: 0; }
.bs-post__media { position: relative; flex: none; aspect-ratio: var(--ratio-post-photo); max-height: var(--size-post-photo-max); width: 100%; border-radius: var(--radius-lg); overflow: hidden; }
.bs-post--photo .bs-post__text { font-size: var(--font-size-16); line-height: 24px; font-weight: var(--font-weight-regular); text-wrap: auto; }
.bs-post__carousel { position: absolute; inset: 0; z-index: 0; background: var(--gray-900); }
.bs-post__track { display: flex; height: 100%; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; overscroll-behavior-x: contain; outline: none; }
.bs-post__track::-webkit-scrollbar { display: none; }
.bs-post__slide { flex: 0 0 100%; scroll-snap-align: center; scroll-snap-stop: always; background-size: cover; background-position: center; cursor: zoom-in; }
.bs-post__count { position: absolute; z-index: 3; top: var(--space-4); right: var(--space-4); display: inline-flex; align-items: center; height: var(--size-badge-h); padding: 0 var(--space-3); border-radius: var(--radius-pill); background: var(--bg-on-image); color: var(--text-on-image); font-size: var(--font-size-12); font-weight: var(--font-weight-bold); font-variant-numeric: tabular-nums; pointer-events: none; }
.bs-post__arrow { position: absolute; top: 50%; z-index: 3; display: none; transform: translateY(-50%); }
.bs-post__arrow--prev { left: var(--space-4); }
.bs-post__arrow--next { right: var(--space-4); }
@media (hover: hover) { .bs-post__carousel:hover .bs-post__arrow { display: inline-flex; } }
.bs-post--sold .bs-post__slide { filter: grayscale(1) brightness(0.6); }
/* dentro do __media, no canto de cima à esquerda (o contador fica à direita) */
.bs-post__sold { position: absolute; z-index: 3; top: var(--space-4); left: var(--space-4); display: inline-flex; align-items: center; height: var(--size-pill-h); padding: 0 var(--space-4); border-radius: var(--radius-pill); background: var(--bg-inverse); color: var(--text-inverse); font-size: var(--font-size-12); font-weight: var(--font-weight-bold); }

/* desktop: o espaço entre a tag e o avatar é SEMPRE 40, com texto grande ou pequeno: o card não tem altura mínima e acompanha o conteúdo.
   --bs-fit-limit é a altura em que o texto deixa de caber e desce um degrau (lido pelo BS.fitPost; era 480 até 10/11/2026, que deixava até 7 linhas em 24/30 no desktop). O 480 da query @container e o 380 do limite são literais: container query não aceita variável e o JS lê o número. */
@container bs-post (min-width: 480px) {
  .bs-post__inner, .bs-post--long .bs-post__inner { gap: var(--space-9); min-height: 0; --bs-fit-limit: 380px; }
  .bs-post__body { margin-top: 0; }
}

/* estados */
.bs-post--empty { min-height: 0; align-items: center; text-align: center; gap: var(--space-3); padding: var(--space-9) var(--space-7); }
.bs-post--empty .bs-icon { font-size: var(--size-avatar-lg); color: var(--text-secondary); }
.bs-post--empty b { font-size: var(--font-size-18); }
.bs-post--empty span.bs-post__desc { font-size: var(--font-size-14); color: var(--text-secondary); }
.bs-post--empty .bs-btn { margin-top: var(--space-3); }
.bs-post--hidden > .bs-post__inner { opacity: 0; pointer-events: none; }
.bs-post__hidden { position: absolute; inset: 0; z-index: 5; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-3); padding: var(--space-8); text-align: center; background: var(--bg-surface); }
.bs-post__hidden .bs-icon { font-size: var(--size-avatar-lg); color: var(--text-secondary); }
.bs-post__pinned { display: inline-flex; align-items: center; gap: var(--space-2); height: var(--size-pill-h); padding: 0 var(--space-4); border-radius: var(--radius-pill); background: var(--bg-surface-raised); color: var(--text-primary); font-size: var(--font-size-12); font-weight: var(--font-weight-bold); }
.bs-post__pinned .bs-icon { font-size: var(--size-icon-sm); }
.bs-post--skeleton .bs-post__inner { gap: var(--space-6); }

/* ===== Banner =================================================================
   Aviso do admin entre os posts do mural. FORMA: padrão · --image (foto de fundo com sombra).
   TIPO: --notice (rosa) · --blog (verde-água).  Fechar com o IconButton do canto.
   ========================================================================== */
.bs-banner { position: relative; display: flex; flex-direction: column; gap: var(--space-4); padding: var(--space-6); border-radius: var(--radius-2xl); background: var(--bg-surface); color: var(--text-primary); font-family: var(--font-corpo); overflow: hidden; isolation: isolate; }
.bs-banner--notice { --bs-cat: var(--text-brand); }
.bs-banner--blog { --bs-cat: var(--cat-indicacao); }
.bs-banner--neutral { --bs-cat: var(--text-secondary); }
/* Cores de marca: fundo com 16% da cor sobre o card; o texto fica branco (o cinza secundário não passa de 4,5:1 aqui). */
.bs-banner--pink { --bs-cat: var(--banner-pink); background: color-mix(in srgb, var(--banner-pink) 16%, var(--bg-surface)); }
.bs-banner--purple { --bs-cat: var(--banner-purple); background: color-mix(in srgb, var(--banner-purple) 16%, var(--bg-surface)); }
.bs-banner--pink .bs-banner__text, .bs-banner--purple .bs-banner__text { color: var(--text-primary); }
/* Cor da seção: o banner do feed leva a cor do item do menu a que se refere (token --nav-<seção>); fundo na cor pura, texto escuro (--text-on-solid), tag em pílula escura. */
.bs-banner--nav-artigos { --bs-cat: var(--nav-artigos); }
.bs-banner--nav-hentais { --bs-cat: var(--nav-hentais); }
.bs-banner--nav-historias { --bs-cat: var(--nav-historias); }
.bs-banner--nav-mensagens { --bs-cat: var(--nav-mensagens); }
.bs-banner--nav-avaliar { --bs-cat: var(--nav-avaliar); }
.bs-banner--nav-estilopig { --bs-cat: var(--nav-estilopig); }
.bs-banner--nav-sites { --bs-cat: var(--nav-sites); }
.bs-banner--nav-livros { --bs-cat: var(--nav-livros); }
.bs-banner--nav-glossario { --bs-cat: var(--nav-glossario); }
.bs-banner--nav-perfis { --bs-cat: var(--nav-perfis); }
[class*="bs-banner--nav-"] { background: var(--bs-cat); color: var(--text-on-solid); }
[class*="bs-banner--nav-"] .bs-pill { background: var(--bg-surface-raised); }
.bs-banner > .bs-pill { align-self: flex-start; }
.bs-banner--image .bs-pill:not(.bs-pill--solid) { background: var(--bg-surface-raised); }
.bs-banner__close { position: absolute; top: var(--space-2); right: var(--space-2); z-index: 2; }
.bs-banner__title { margin: 0; padding-right: var(--space-8); font-size: var(--font-size-20); line-height: var(--line-height-snug); font-weight: var(--font-weight-bold); }
.bs-banner__text { margin: 0; font-size: var(--font-size-16); line-height: 24px; color: var(--text-secondary); }
.bs-banner__action { align-self: flex-start; }
.bs-banner--image { min-height: 260px; justify-content: flex-end; color: var(--text-primary); }
.bs-banner--image .bs-banner__text { color: var(--text-on-image); }
/* Com capa (28/out/2026): uma capa 3:4 à direita, ao lado da tag, do título e do botão (hentai no Mural). Mesma tag, título e botão do banner comum. */
.bs-banner--cover { display: grid; grid-template-columns: minmax(0, 1fr) var(--size-banner-cover); column-gap: var(--space-5); align-items: start; }
.bs-banner--cover > * { grid-column: 1; }
.bs-banner--cover > .bs-banner__cover { grid-column: 2; grid-row: 1 / span 3; width: 100%; aspect-ratio: 3 / 4; object-fit: cover; border-radius: var(--radius-lg); background: var(--bg-surface-raised); }
.bs-banner--cover .bs-banner__title { padding-right: 0; }
.bs-banner--cover .bs-banner__action { justify-self: start; }
.bs-banner--cover > .bs-pill { justify-self: start; }   /* a tag não estica na largura: no grid o align-self do flex não vale na horizontal */
.bs-banner__bg { position: absolute; inset: 0; z-index: -2; background-size: cover; background-position: center; }
.bs-banner__shade { position: absolute; inset: 0; z-index: -1; background: var(--gradient-image-shade); }

/* ===== Menu tile ==============================================================
   Atalho para uma seção do site: quadrado com ícone + título pequeno + uma linha de texto. Sem card ao redor (fica solto no fundo).
   Cor: a classe da seção (bs-nav-artigos, bs-nav-mural…) define --bs-nav; o quadrado e o ícone usam essa cor.
   Partes: __icon (quadrado, recebe um bs-icon) · __body · __title · __text. O ícone tem a altura do tile e o texto cabe nela.
   Estados: hover (quadrado mais claro) e foco por teclado (:focus-visible). É sempre um <a> ou <button>.
   ========================================================================== */
.bs-menu-tile { display: flex; align-items: center; gap: var(--space-5); min-width: 0; border-radius: var(--radius-2xl); color: var(--text-primary); font-family: var(--font-corpo); text-align: left; text-decoration: none; cursor: pointer; }
.bs-menu-tile__icon { flex: none; display: grid; place-items: center; width: var(--size-menu-tile-icon); height: var(--size-menu-tile-icon); border-radius: var(--radius-2xl); background: color-mix(in srgb, var(--bs-nav, var(--text-secondary)) 16%, var(--bg-canvas)); color: var(--bs-nav, var(--text-secondary)); font-size: var(--size-icon-xl); transition: background var(--transition-default); }
.bs-menu-tile:hover .bs-menu-tile__icon, .bs-menu-tile.is-hover .bs-menu-tile__icon { background: color-mix(in srgb, var(--bs-nav, var(--text-secondary)) 26%, var(--bg-canvas)); }
.bs-menu-tile:focus-visible, .bs-menu-tile.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-menu-tile__body { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.bs-menu-tile__title { font-size: var(--font-size-18); line-height: var(--line-height-snug); font-weight: var(--font-weight-medium); }
.bs-menu-tile__text { font-size: var(--font-size-14); line-height: var(--line-height-snug); color: var(--text-secondary); }
@media (prefers-reduced-motion: reduce) { .bs-menu-tile__icon { transition: none; } }

/* ===== Hero card ==============================================================
   Card largo de convite no meio de uma página: texto à esquerda (título, frase e um botão) e imagem à direita.
   Cor sólida (--bg-hero-card), sem gradiente e sem tag. A imagem entra por --bs-hero-card-img (url(...)); sem ela, mostra o fundo de apoio.
   Partes: __body · __title · __text · __action (o Button) · __media. Responde à própria largura: abaixo de 640 a imagem vai para cima do texto.
   VARIANTE --brand (26/10/2026): fundo rosa primário e texto escuro (o botão é o primário --inverse). O enquadramento da imagem vem de --bs-hero-card-pos (position) e --bs-hero-card-zoom (size, ex.: 210% auto); sem eles a imagem cobre o espaço, centrada.
   Sem estados: o clique é do botão. ========================================================================== */
.bs-hero-card { container: bs-hero-card / inline-size; border-radius: var(--radius-2xl); background: var(--bg-hero-card); color: var(--text-primary); font-family: var(--font-corpo); overflow: hidden; }
.bs-hero-card__inner { display: flex; flex-direction: column-reverse; }
.bs-hero-card__body { display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: var(--space-4); padding: var(--space-7); }
.bs-hero-card__title { margin: 0; font-size: var(--font-size-24); line-height: var(--line-height-tight); font-weight: var(--font-weight-regular); letter-spacing: -.02em; }
.bs-hero-card__text { margin: 0; font-size: var(--font-size-16); line-height: var(--line-height-normal); color: var(--text-on-hero-card); }
.bs-hero-card__media { min-height: calc(var(--size-hero-card-min) - var(--space-9)); background: var(--bg-surface-raised) var(--bs-hero-card-img, none) var(--bs-hero-card-pos, center) / var(--bs-hero-card-zoom, cover) no-repeat; }
.bs-hero-card--brand { background: var(--interactive-primary); color: var(--text-on-brand-fill); --text-on-hero-card: var(--text-on-brand-fill); }
@container bs-hero-card (min-width: 720px) {
  .bs-hero-card__inner { flex-direction: row; min-height: var(--size-hero-card-min); }
  .bs-hero-card__body { flex: 1 1 0; padding: var(--space-8) var(--space-9); }
  .bs-hero-card__media { flex: 1 1 0; min-height: 0; }
  .bs-hero-card__title { font-size: var(--font-size-32); }
}

/* ===== Emblem (badge de nível) ===============================================
   O badge do nível do Respeito: uma arte própria por nível (8 SVGs em badges/, criados pelo dono do projeto em 16/10/2026).
   Aparece na Pill de nível do Profile card e, depois, em post, comentário, sidebar, perfil e ranking.
   NÍVEL: a classe bs-lv-1 … bs-lv-8 no próprio badge ou em quem o contém (Profile card, Pill) escolhe a arte.
   TAMANHO: --xs 20 · --sm 32 · padrão 48 · --lg 96. A altura é o tamanho; a arte mantém a proporção dentro do quadrado.
   Sem partes e sem texto: é só imagem (aria-hidden); o texto "Nível N" fica ao lado ou em bs-profile-card__sr.
   Sem estados. O caminho badges/ é relativo a este arquivo (como fonts/ no tokens.css). */
.bs-emblem {
  display: inline-block; flex: none; vertical-align: middle;
  width: var(--bs-emblem-size, var(--size-avatar-lg)); height: var(--bs-emblem-size, var(--size-avatar-lg));
  background: center / contain no-repeat;
}
.bs-emblem--xs { --bs-emblem-size: var(--size-icon-md); }
.bs-emblem--sm { --bs-emblem-size: var(--size-avatar-sm); }
.bs-emblem--lg { --bs-emblem-size: var(--size-avatar-2xl); }
.bs-lv-1 .bs-emblem, .bs-emblem.bs-lv-1 { background-image: url('badges/badge_01.svg'); }
.bs-lv-2 .bs-emblem, .bs-emblem.bs-lv-2 { background-image: url('badges/badge_02.svg'); }
.bs-lv-3 .bs-emblem, .bs-emblem.bs-lv-3 { background-image: url('badges/badge_03.svg'); }
.bs-lv-4 .bs-emblem, .bs-emblem.bs-lv-4 { background-image: url('badges/badge_04.svg'); }
.bs-lv-5 .bs-emblem, .bs-emblem.bs-lv-5 { background-image: url('badges/badge_05.svg'); }
.bs-lv-6 .bs-emblem, .bs-emblem.bs-lv-6 { background-image: url('badges/badge_06.svg'); }
.bs-lv-7 .bs-emblem, .bs-emblem.bs-lv-7 { background-image: url('badges/badge_07.svg'); }
.bs-lv-8 .bs-emblem, .bs-emblem.bs-lv-8 { background-image: url('badges/badge_08.svg'); }

/* ===== Profile card ===========================================================
   Card de perfil da lista de Perfis. Foto cheia, texto sobre o degradê, o card inteiro é o link.
   TAMANHO: automático, pela largura do próprio card (container query): grande (> 300px, celular, 358px)
            · pequeno (até 300px, desktop de 1280px com 4 colunas, 228px). Mesma proporção e mesmo raio.
   Partes: __photo (img) · __shade · __top (2 × __tag) · __body (__name (__nick, __verified) · __row (__info (__meta, __archetype (__status)) · __go))
   TAG: nível (cor pela classe bs-level-*) · --affinity · --max (100%, gradiente animado) · --you ("Seu perfil")
   CARD: --long-name (apelido com mais de 9 letras) · --wrap-name (apelido em 2 linhas, em teste) · --locked (visitante: foto embaçada)
   Carregando: bs-skeleton dentro de __sk. Arquétipo: cor pela classe bs-arq-*.
   Estado: foco :focus-visible. is-hover e is-focus só para a documentação. Sem borda e sem sombra. */
.bs-profile-card {
  position: relative; display: block; width: 100%; aspect-ratio: var(--ratio-profile-card); overflow: hidden;
  border-radius: var(--radius-card-photo); background: var(--bg-canvas); color: var(--text-primary);
  font-family: var(--font-corpo); text-decoration: none; cursor: pointer;
  container-type: inline-size; container-name: bs-profile-card;
  transition: transform var(--transition-default);
}
@supports (corner-shape: squircle) { .bs-profile-card, .bs-profile-card::before, .bs-profile-card::after { corner-shape: squircle; } }   /* o contorno e o brilho (pseudo-elementos) precisam da mesma forma de canto: corner-shape não é herdado */   /* efeito iOS: só onde o navegador suporta */
.bs-profile-card:hover, .bs-profile-card.is-hover { transform: translateY(calc(-1 * var(--space-2))); }
.bs-profile-card:focus-visible, .bs-profile-card.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }

.bs-profile-card__photo { position: absolute; inset: 0; background: var(--bg-surface-raised); }
.bs-profile-card__photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.bs-profile-card__shade { position: absolute; inset: 0; background: var(--gradient-profile-photo); }

/* topo: duas tags com o mesmo peso */
.bs-profile-card__top { position: absolute; top: var(--space-6); left: var(--space-6); right: var(--space-6); display: flex; align-items: center; justify-content: space-between; }
.bs-profile-card__max {
  background: var(--gradient-affinity-max); background-size: 300% 100%;
  animation: bs-profile-gradient var(--duration-ambient) var(--ease-standard) infinite alternate;
}
@keyframes bs-profile-gradient { from { background-position: 0% 0; } to { background-position: 100% 0; } }

/* base: apelido, dados e seta */
.bs-profile-card__body { position: absolute; left: var(--space-7); right: var(--space-7); bottom: var(--space-7); display: flex; flex-direction: column; gap: var(--space-3); }
.bs-profile-card__name { display: flex; align-items: flex-end; gap: var(--space-3); min-width: 0; font-size: var(--font-size-40); font-weight: var(--font-weight-black); line-height: var(--line-height-tight); letter-spacing: -0.025em; }
.bs-profile-card__nick { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bs-profile-card__verified { flex: none; margin-bottom: var(--space-2); font-size: var(--size-icon-lg); color: var(--interactive-accent); --ico: var(--ico-s, var(--ico-r)); }
.bs-profile-card__row { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-4); }
.bs-profile-card__info { flex: 1; min-width: 0; }
.bs-profile-card__meta { display: block; font-size: var(--font-size-14); font-weight: var(--font-weight-medium); line-height: var(--line-height-snug); color: var(--text-on-image); }
.bs-profile-card__archetype { display: block; margin-top: var(--space-4); font-size: var(--font-size-14); font-weight: var(--font-weight-bold); color: var(--bs-arq, var(--text-secondary)); }
.bs-profile-card__status { font-weight: var(--font-weight-medium); color: var(--text-secondary); }
.bs-profile-card__go {
  flex: none; display: inline-flex; align-items: center; justify-content: center; width: var(--size-card-action); height: var(--size-card-action);
  border-radius: var(--radius-circle); background: var(--interactive-accent); color: var(--text-on-brand-fill);
}
.bs-profile-card__go .bs-icon { font-size: var(--size-icon-lg); }
.bs-profile-card__sr { position: absolute; width: var(--space-1); height: var(--space-1); overflow: hidden; clip-path: inset(50%); white-space: nowrap; }   /* texto só para leitor de tela */

.bs-profile-card--long-name .bs-profile-card__name { font-size: var(--font-size-32); }
.bs-profile-card--wrap-name .bs-profile-card__nick { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; white-space: normal; overflow-wrap: anywhere; }
.bs-profile-card--locked .bs-profile-card__photo img[data-foto] { filter: blur(var(--blur-photo-locked)); transform: scale(1.2); }

/* NÍVEL DO RESPEITO: bs-lv-1 … bs-lv-8 no próprio card e no Avatar (o mesmo contorno). Sem a classe, o card não ganha contorno (compatível com o que já existe).
   Contorno de 2px, forte em cima e sumindo embaixo, igual em todos os níveis: 1 e 2 sem contorno · 3 e 4 uma cor ·
   5 a 7 duas cores que se alternam (rápido, --duration-lively) · 8 holográfico animado (--gradient-nivel-holo) com um véu iridescente no topo.
   Sem sombra. Exceção consciente à regra "cards sem borda": o contorno é o sinal do nível (decidido em 16/10/2026). */
@property --bs-s1 { syntax: '<color>'; inherits: false; initial-value: transparent; }
@property --bs-s2 { syntax: '<color>'; inherits: false; initial-value: transparent; }
.bs-profile-card[class*="bs-lv-"]::before,
.bs-avatar[class*="bs-lv-"]::before {
  content: ''; position: absolute; inset: 0; z-index: var(--z-overlap); pointer-events: none;
  border-radius: inherit; padding: var(--stroke-thin);
  background: linear-gradient(180deg, var(--bs-lv), var(--bs-lv) 45%, transparent 90%);
  -webkit-mask: linear-gradient(var(--black) 0 0) content-box, linear-gradient(var(--black) 0 0); -webkit-mask-composite: xor;
  mask: linear-gradient(var(--black) 0 0) content-box exclude, linear-gradient(var(--black) 0 0);
}
.bs-profile-card.bs-lv-1::before,
.bs-profile-card.bs-lv-2::before,
.bs-avatar.bs-lv-1::before,
.bs-avatar.bs-lv-2::before { display: none; }   /* níveis 1 e 2: card padrão, sem contorno */
.bs-profile-card.bs-lv-5::before,
.bs-profile-card.bs-lv-6::before,
.bs-profile-card.bs-lv-7::before,
.bs-avatar.bs-lv-5::before,
.bs-avatar.bs-lv-6::before,
.bs-avatar.bs-lv-7::before {
  background: linear-gradient(180deg, var(--bs-s1), var(--bs-s2) 45%, transparent 90%);
  animation: bs-lv-shift var(--duration-lively) var(--ease-standard) infinite;
}
@keyframes bs-lv-shift {
  0%, 100% { --bs-s1: var(--bs-lv); --bs-s2: var(--bs-lv-alt); }
  50% { --bs-s1: var(--bs-lv-alt); --bs-s2: var(--bs-lv); }
}
/* nível 8: holográfico. O contorno é o gradiente corrido na diagonal; o sumir embaixo vem de uma máscara de três camadas (fade ∩ anel). */
.bs-profile-card.bs-lv-8::before,
.bs-avatar.bs-lv-8::before {
  background: var(--gradient-nivel-holo); background-size: 300% 100%;
  animation: bs-lv-holo calc(var(--duration-lively) * 2) linear infinite;
  -webkit-mask: linear-gradient(180deg, var(--black) 45%, transparent 90%) border-box, linear-gradient(var(--black) 0 0) border-box, linear-gradient(var(--black) 0 0) content-box;
  -webkit-mask-composite: source-in, xor;
  mask: linear-gradient(180deg, var(--black) 45%, transparent 90%) border-box, linear-gradient(var(--black) 0 0) border-box, linear-gradient(var(--black) 0 0) content-box;
  mask-composite: intersect, exclude;
}
.bs-profile-card.bs-lv-8::after,
.bs-avatar.bs-lv-8::after {
  content: ''; position: absolute; inset: 0; z-index: var(--z-overlap); pointer-events: none; border-radius: inherit;
  background: var(--gradient-nivel-holo); background-size: 300% 100%; opacity: 0.32;
  -webkit-mask-image: linear-gradient(180deg, var(--black), transparent 55%); mask-image: linear-gradient(180deg, var(--black), transparent 55%);
  animation: bs-lv-holo calc(var(--duration-lively) * 2) linear infinite;
}
@keyframes bs-lv-holo { from { background-position: 0% 0; } to { background-position: 100% 0; } }
.bs-avatar[class*="bs-lv-"] { position: relative; }   /* o contorno é um ::before dentro do avatar */
/* nível 8: tags, seta e badge preenchidos com o mesmo holográfico (texto e ícone escuros, 9:1 ou mais sobre o creme e 7:1 sobre o lilás) */
.bs-profile-card.bs-lv-8 .bs-profile-card__go,
.bs-profile-card.bs-lv-8 .bs-pill--brand,
.bs-profile-card.bs-lv-8 .bs-profile-card__max,
.bs-profile-card.bs-lv-8 .bs-pill--nivel {
  background: var(--gradient-nivel-holo); background-size: 300% 100%; color: var(--text-on-solid);
  animation: bs-lv-holo calc(var(--duration-lively) * 2) linear infinite;
}

/* carregando: esqueleto com a mesma geometria (usa o bs-skeleton) */
.bs-profile-card--loading { background: var(--bg-surface); cursor: default; pointer-events: none; }
.bs-profile-card__sk { display: block; }
.bs-profile-card__sk--tag { width: 20%; height: var(--size-control-sm); border-radius: var(--radius-pill); }
.bs-profile-card__sk--tag-wide { width: 38%; }
.bs-profile-card__sk--name { width: 62%; height: var(--space-9); }
.bs-profile-card__sk--line { width: 80%; height: var(--space-5); border-radius: var(--radius-sm); }
.bs-profile-card__sk--short { width: 32%; margin-top: var(--space-3); }
.bs-profile-card__sk--go { width: var(--size-card-action); height: var(--size-card-action); border-radius: var(--radius-circle); }

/* tamanho pequeno (o 300px é literal: container query não aceita variável) */
@container bs-profile-card (max-width: 300px) {
  .bs-profile-card__top { top: var(--space-5); left: var(--space-5); right: var(--space-5); }
  .bs-profile-card__top .bs-pill { height: var(--size-pill-h); padding: 0 var(--space-4); gap: var(--space-2); font-size: var(--font-size-12); }   /* pequeno: a Pill passa de grande (36) para média (30) */
  .bs-profile-card__top .bs-pill__icon { font-size: var(--size-icon-xs); }
  .bs-profile-card__body { left: var(--space-5); right: var(--space-5); bottom: var(--space-5); }
  .bs-profile-card__name { font-size: var(--font-size-24); }
  .bs-profile-card--long-name .bs-profile-card__name { font-size: var(--font-size-20); }
  .bs-profile-card__verified { margin-bottom: 0; font-size: var(--size-icon-md); }
  .bs-profile-card__meta, .bs-profile-card__archetype { font-size: var(--font-size-12); }
  .bs-profile-card__archetype { margin-top: var(--space-3); }
  .bs-profile-card__go { width: var(--size-control-lg); height: var(--size-control-lg); }
  .bs-profile-card__go .bs-icon { font-size: var(--size-icon-md); }
  .bs-profile-card__sk--tag { height: var(--size-pill-h); }
  .bs-profile-card__sk--name { height: var(--space-8); }
  .bs-profile-card__sk--go { width: var(--size-control-lg); height: var(--size-control-lg); }
}

/* tamanho extra-pequeno (até 200px; o 200px é literal: container query não aceita variável).
   Criado em 19/10/2026 para a tela Início no celular (2 por linha, ~160px): fica só o apelido e o "Eu sou"
   (bs-profile-card__eu). Somem as tags do topo, a seta, o arquétipo e o resto da linha de dados (bs-profile-card__more). */
@container bs-profile-card (max-width: 200px) {
  .bs-profile-card__top, .bs-profile-card__archetype, .bs-profile-card__go, .bs-profile-card__more { display: none; }
  .bs-profile-card__body { left: var(--space-4); right: var(--space-4); bottom: var(--space-4); gap: var(--space-2); }
  .bs-profile-card__name { font-size: var(--font-size-20); }
  .bs-profile-card--long-name .bs-profile-card__name { font-size: var(--font-size-18); }
  .bs-profile-card__verified { font-size: var(--size-icon-sm); }
}

/* grade: sem breakpoint (colunas automáticas); com 1004px de conteúdo cabem 4 colunas de 228px */
.bs-profile-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--size-profile-card-min), 1fr)); gap: var(--space-7); }
@media (min-width: 960px) { .bs-profile-grid { gap: var(--space-8); } }
/* grade compacta (09/11/2026): sempre 2 por linha (quem usa decide onde aplicar; a tela Perfis só a liga no celular).
   Com ~160px por card, o Profile card cai sozinho no tamanho extra-pequeno (só apelido e "Eu sou"). */
.bs-profile-grid--compact { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }

@media (prefers-reduced-motion: reduce) {
  .bs-profile-card { transition: none; }
  .bs-profile-card:hover, .bs-profile-card.is-hover { transform: none; }
  .bs-profile-card__max { animation: none; background-position: 30% 0; }
  .bs-profile-card.bs-lv-8::before, .bs-profile-card.bs-lv-8::after, .bs-profile-card.bs-lv-8 .bs-profile-card__go, .bs-profile-card.bs-lv-8 .bs-pill--brand, .bs-profile-card.bs-lv-8 .bs-profile-card__max, .bs-profile-card.bs-lv-8 .bs-pill--nivel { animation: none; }
  .bs-avatar.bs-lv-5::before, .bs-avatar.bs-lv-6::before, .bs-avatar.bs-lv-7::before, .bs-avatar.bs-lv-8::before, .bs-avatar.bs-lv-8::after { animation: none; }
  .bs-profile-card.bs-lv-5::before, .bs-profile-card.bs-lv-6::before, .bs-profile-card.bs-lv-7::before { animation: none; --bs-s1: var(--bs-lv); --bs-s2: var(--bs-lv-alt); }
}

@media (prefers-reduced-motion: reduce) {
  .bs-modal[open], .bs-skeleton { animation: none; }
}

/* ===== Chat (conversa) =========================================================
   Três peças da tela de Mensagens: Conversation item (card da lista), Message bubble (balão) e Chat (a conversa: cabeçalho, mensagens, rodapé).
   CONVERSATION ITEM  .bs-conversation (button) dentro de .bs-conversation-list (coluna, espaço 8).
     Partes: Avatar lg + __body > (__top: __name + __time) + (__bottom: __preview + __dot).
     Estados: padrão (card) · hover · .is-active (conversa aberta: fundo branco, texto escuro) · .is-unread (nome e prévia em destaque, hora rosa, __dot) · foco.
   MESSAGE BUBBLE  .bs-bubble (da outra pessoa, cinza, à esquerda) · --me (suas, branco, à direita). Parte: __body e __time (hora fora do balão, abaixo).
     O canto inferior do lado de quem fala é menos curvado (raio sm). Sem visto de “lida”.
     COM FOTOS (09/11/2026): --media no balão + __media (grade de 1 a 3 fotos: --1, --2, --3) com __photo (botão que abre a foto no Lightbox; foto única pode ter --wide ou --tall)
     e __text (legenda opcional embaixo). __photo--off ocupa o lugar de uma foto removida ou indisponível (ícone e aviso, sem clique; quando é a única foto do balão vira uma faixa baixa, não um quadrado).
   CHAT  .bs-chat: coluna com __header (voltar, quem, menu), __messages (rola), __notice (aviso central), __footer (campo + enviar, ou __footer--request com Aceitar/Recusar) e __hint (com __hint-desktop e __hint-mobile).
     __attachments (09/11/2026): fileira das fotos escolhidas, antes de enviar, entre as mensagens e o rodapé; cada __attachment leva um Upload __preview com o botão de tirar. Estado is-busy enquanto envia.
     --framed: moldura de contorno. EXCEÇÃO à regra 11 (cards sem borda), decidida em 18/out/2026 e válida só para este componente: use no desktop; no celular a conversa é tela cheia, sem moldura.
   ========================================================================== */
.bs-conversation-list { display: flex; flex-direction: column; gap: var(--space-3); }
.bs-conversation {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  width: 100%;
  min-height: var(--size-avatar-xl);
  box-sizing: border-box;
  padding: var(--space-4);
  border: 0;
  border-radius: var(--radius-lg);
  background: var(--bg-surface);
  color: var(--text-primary);
  font-family: var(--font-corpo);
  text-align: left;
  cursor: pointer;
  transition: background var(--transition-default), color var(--transition-default);
}
.bs-conversation:hover, .bs-conversation.is-hover { background: var(--bg-surface-raised); }
.bs-conversation:focus-visible, .bs-conversation.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-conversation__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.bs-conversation__top, .bs-conversation__bottom { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); min-width: 0; }
.bs-conversation__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--font-weight-bold); line-height: var(--line-height-snug); }
.bs-conversation__time { flex: none; font-size: var(--font-size-12); color: var(--text-tertiary); }
.bs-conversation__preview { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--font-size-14); line-height: var(--line-height-snug); color: var(--text-secondary); }
.bs-conversation__dot { flex: none; width: var(--space-3); height: var(--space-3); border-radius: var(--radius-circle); background: var(--indicator-notification); }
.bs-conversation.is-unread .bs-conversation__preview { color: var(--text-primary); font-weight: var(--font-weight-bold); }
.bs-conversation.is-unread .bs-conversation__time { color: var(--text-brand); font-weight: var(--font-weight-bold); }
.bs-conversation.is-active, .bs-conversation.is-active:hover { background: var(--bg-inverse); color: var(--text-inverse); }
.bs-conversation.is-active .bs-conversation__preview, .bs-conversation.is-active .bs-conversation__time { color: var(--text-inverse-secondary); }

.bs-bubble { display: flex; flex-direction: column; gap: var(--space-2); max-width: 78%; align-self: flex-start; }
.bs-bubble--me { align-self: flex-end; align-items: flex-end; }
.bs-bubble__body { overflow-wrap: anywhere; padding: var(--space-3) var(--space-4); border-radius: var(--radius-xl); border-bottom-left-radius: var(--radius-sm); background: var(--bg-surface-raised); color: var(--text-primary); font-size: var(--font-size-16); line-height: var(--line-height-normal); overflow-wrap: anywhere; }
.bs-bubble--me .bs-bubble__body { border-bottom-left-radius: var(--radius-xl); border-bottom-right-radius: var(--radius-sm); background: var(--bg-inverse); color: var(--text-inverse); }
.bs-bubble__time { padding-inline: var(--space-2); font-size: var(--font-size-10); color: var(--text-tertiary); }
/* Balão com fotos: moldura fina (o raio das fotos é o raio do balão menos a moldura) e grade de 1 a 3 fotos. */
.bs-bubble--media { width: var(--size-bubble-media); }
.bs-bubble--media .bs-bubble__body { align-self: stretch; padding: var(--space-2); }
.bs-bubble__media { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
.bs-bubble__media--1 { grid-template-columns: minmax(0, 1fr); }
.bs-bubble__photo { position: relative; display: block; box-sizing: border-box; width: 100%; aspect-ratio: 1; margin: 0; padding: 0; border: 0; overflow: hidden; border-radius: var(--radius-lg); background: var(--bg-surface); cursor: zoom-in; transition: opacity var(--transition-default); }
.bs-bubble__photo img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }
.bs-bubble__photo:hover, .bs-bubble__photo.is-hover { opacity: .85; }
.bs-bubble__photo:focus-visible, .bs-bubble__photo.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-bubble__photo--wide { aspect-ratio: var(--ratio-bubble-photo-wide); }
.bs-bubble__photo--tall { aspect-ratio: var(--ratio-bubble-photo-tall); }
.bs-bubble__media--3 .bs-bubble__photo:first-child { grid-row: span 2; height: 100%; aspect-ratio: auto; }
.bs-bubble__photo--off { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2); padding: var(--space-3); color: var(--text-secondary); font-size: var(--font-size-12); line-height: var(--line-height-snug); text-align: center; cursor: default; pointer-events: none; }
.bs-bubble__media--1 .bs-bubble__photo--off { aspect-ratio: auto; min-height: var(--size-avatar-2xl); }
.bs-bubble__text { padding: var(--space-3) var(--space-3) var(--space-2); }

.bs-chat { display: flex; flex-direction: column; min-width: 0; min-height: 0; font-family: var(--font-corpo); color: var(--text-primary); }
.bs-chat--framed { border: var(--stroke-medium) solid var(--border-strong); border-radius: var(--radius-2xl); overflow: hidden; }
.bs-chat__header { display: flex; align-items: center; gap: var(--space-3); min-height: var(--layout-topbar); padding: var(--space-3); border-bottom: var(--stroke-hairline) solid var(--border-default); }
.bs-chat__who { display: flex; align-items: center; flex: 1; min-width: 0; gap: var(--space-3); color: var(--text-brand); font-weight: var(--font-weight-bold); text-decoration: none; }
.bs-chat__who:focus-visible, .bs-chat__who.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); border-radius: var(--radius-xs); }
.bs-chat__messages { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-5); }
.bs-chat__notice { align-self: center; text-align: center; font-size: var(--font-size-14); color: var(--text-secondary); }
.bs-chat__footer { display: flex; align-items: flex-end; gap: var(--space-3); padding: var(--space-3); border-top: var(--stroke-hairline) solid var(--border-default); }
.bs-chat__footer .bs-input { flex: 1; min-width: 0; }
.bs-chat__footer--request { align-items: center; flex-wrap: wrap; }
.bs-chat__footer-text { flex: 1; min-width: 200px; margin: 0; font-size: var(--font-size-14); color: var(--text-secondary); }
/* Fotos escolhidas, antes de enviar. O Upload __preview (quadrado) e o botão de tirar vêm do Upload. */
.bs-chat__attachments { display: flex; gap: var(--space-3); padding: var(--space-3) var(--space-3) 0; overflow-x: auto; border-top: var(--stroke-hairline) solid var(--border-default); }
.bs-chat__attachments[hidden] { display: none; }
.bs-chat__attachments + .bs-chat__footer { border-top: 0; }
.bs-chat__attachment { position: relative; flex: none; width: var(--size-avatar-2xl); }
.bs-chat__attachments.is-busy .bs-chat__attachment { opacity: var(--opacity-muted); pointer-events: none; }
.bs-chat__hint { padding: 0 var(--space-5) var(--space-3); font-size: var(--font-size-12); color: var(--text-tertiary); }
/* dica de teclado: --desktop (atalhos) só em telas de 960 em diante; --mobile (só o aviso de texto) no resto. No celular o Enter do teclado quebra a linha e o envio é pelo botão. */
.bs-chat__hint-desktop { display: none; }
@media (min-width: 960px) { .bs-chat__hint-desktop { display: inline; } .bs-chat__hint-mobile { display: none; } }

/* ===== Prose ==================================================================
   O texto corrido de um artigo, do jeito que vem do WordPress: HTML solto (p, h2-h4, ul, ol, blockquote, img, a).
   O contêiner recebe bs-prose e os filhos são estilizados pela tag; ninguém põe classe em parágrafo.
   Subtítulos de seção (h2 28, h3 24, h4 20) em rosa de marca e negrito, com bastante ar em cima e pouco embaixo (colam no parágrafo deles). O texto é branco (--text-prose). Lista com marcador: traço rosa de 16 encostado na borda esquerda, sem recuo. Lista numerada: números rosa em negrito.
   Blockquote = frase em destaque: sem card, texto grande e aspas rosa em cima. Imagens com raio xl, links rosa sublinhados.
   Sem variantes nem estados.
   ========================================================================== */
.bs-prose { font-family: var(--font-corpo); font-size: var(--font-size-20); line-height: var(--line-height-prose); color: var(--text-prose); overflow-wrap: anywhere; }
.bs-prose > :first-child { margin-top: 0; }
.bs-prose p, .bs-prose ul, .bs-prose ol { margin: 0 0 var(--space-6); }
.bs-prose h2, .bs-prose h3, .bs-prose h4 { margin: var(--space-9) 0 var(--space-3); font-weight: var(--font-weight-bold); line-height: var(--line-height-snug); letter-spacing: -.01em; color: var(--text-brand); }
.bs-prose h2 { font-size: var(--font-size-28); }
.bs-prose h3 { font-size: var(--font-size-24); }
.bs-prose h4 { font-size: var(--font-size-20); }
.bs-prose ol { padding-left: var(--space-7); }
.bs-prose li { margin-bottom: var(--space-3); }
.bs-prose li::marker { color: var(--text-brand); }
.bs-prose ol li::marker { font-weight: var(--font-weight-bold); }
/* lista com marcador: traço rosa encostado na borda esquerda do texto (sem recuo), texto logo ao lado */
.bs-prose ul { padding-left: 0; list-style: none; }
.bs-prose ul > li { position: relative; padding-left: var(--space-7); }
.bs-prose ul > li::before { content: ""; position: absolute; left: 0; top: calc(var(--font-size-20) * var(--line-height-prose) / 2 - var(--stroke-thin) / 2); width: var(--space-5); height: var(--stroke-thin); background: var(--text-brand); }
.bs-prose a { color: var(--text-brand); text-decoration: underline; text-underline-offset: var(--space-1); }
.bs-prose img { display: block; max-width: 100%; height: auto; margin: var(--space-7) auto; border-radius: var(--radius-xl); }
.bs-prose iframe, .bs-prose video { max-width: 100%; border-radius: var(--radius-xl); }
.bs-prose blockquote { margin: var(--space-9) 0; padding: 0; border: 0; background: none; color: var(--text-primary); font-size: var(--font-size-28); line-height: 1.35; letter-spacing: -.01em; }
.bs-prose blockquote::before { content: "\201C"; display: block; height: var(--space-9); font-size: calc(var(--font-size-48) * 2); line-height: 1; color: var(--text-brand); }
.bs-prose blockquote p { margin: 0; }

/* ===== Prose, widgets e edição ================================================
   Blocos que o admin insere no texto (data-bs-w): figure (imagem com legenda), figure com iframe (vídeo 16:9), Alert (aviso) e
   __related (Veja também: rótulo + Article card --compact). Dentro de .bs-prose só acertam margem e cor herdada do texto.
   Edição (só admin): .bs-prose.is-editing mostra contorno de foco; .bs-edit-bar é a barra fixa no topo (rótulo, inserir, cancelar/salvar);
   .bs-edit-bubble é a barra flutuante sobre o texto selecionado (um Filtro de itens que ligam e desligam o estilo + campo de link);
   .bs-edit-remove é o botão de remover um bloco. Flutuantes têm sombra (exceção da regra 11, como menu e modal).
   ========================================================================== */
.bs-prose figure { margin: var(--space-7) 0; }
.bs-prose figure img { margin: 0; }
.bs-prose figcaption { margin-top: var(--space-3); font-size: var(--font-size-14); font-weight: var(--font-weight-medium); line-height: var(--line-height-normal); text-align: center; color: var(--text-tertiary); }
.bs-prose figure iframe { display: block; width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; }
.bs-prose .bs-alert { margin: var(--space-7) 0; }
.bs-prose .bs-alert__text { margin: 0; font-size: var(--font-size-16); }
.bs-prose-related { display: flex; flex-direction: column; gap: var(--space-3); margin: var(--space-7) 0; padding: var(--space-5); border-radius: var(--radius-xl); background: var(--bg-surface); }
.bs-prose-related__label { font-size: var(--font-size-12); font-weight: var(--font-weight-bold); letter-spacing: .1em; text-transform: uppercase; color: var(--text-tertiary); }
.bs-prose .bs-article-card { text-decoration: none; color: var(--text-primary); }
.bs-prose .bs-article-card img { margin: 0; border-radius: inherit; }
.bs-prose.is-editing { outline: var(--focus-ring); outline-offset: var(--space-4); border-radius: var(--radius-lg); caret-color: var(--text-brand); }
.bs-prose.is-editing [data-bs-w] { position: relative; }
.bs-prose.is-editing figcaption[contenteditable], .bs-prose.is-editing .bs-alert__text[contenteditable] { outline: none; }
.bs-edit-remove { position: absolute; top: var(--space-3); right: var(--space-3); z-index: var(--z-controls); }
.bs-edit-bar { position: fixed; top: var(--space-4); left: 50%; transform: translateX(-50%); z-index: var(--z-sticky); display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--space-3) var(--space-5); box-sizing: border-box; max-width: calc(100% - var(--space-6)); padding: var(--space-3) var(--space-4); border-radius: var(--radius-xl); background: var(--bg-surface-overlay); box-shadow: var(--shadow-xl); font-family: var(--font-corpo); color: var(--text-primary); }
.bs-edit-bar__label { font-size: var(--font-size-14); font-weight: var(--font-weight-bold); color: var(--text-brand); }
.bs-edit-bar__tools, .bs-edit-bar__actions { display: flex; align-items: center; gap: var(--space-2); }
.bs-edit-bar__group { font-size: var(--font-size-12); font-weight: var(--font-weight-bold); letter-spacing: .1em; text-transform: uppercase; color: var(--text-tertiary); margin-right: var(--space-2); }
.bs-edit-bubble { position: fixed; z-index: var(--z-popover); display: flex; align-items: center; max-width: calc(100% - var(--space-4)); padding: var(--space-2); border-radius: var(--radius-xl); background: var(--bg-surface-overlay); box-shadow: var(--shadow-lg); font-family: var(--font-corpo); }
.bs-edit-bubble[hidden], .bs-edit-bubble__link[hidden] { display: none; }
.bs-edit-bubble .bs-filter { flex-wrap: nowrap; }
.bs-edit-bubble__link { display: flex; align-items: center; gap: var(--space-2); }
.bs-article__edit { display: flex; }

/* ===== Gallery e Lightbox ======================================================
   Galeria de imagens dentro de um texto (Prose): grade de quadrados: no máximo 4 por linha, menos quando a largura não deixa (colunas de pelo menos 144px; no celular ficam 2). Cada item (bs-gallery__item) é um <a> para a imagem grande, com <img> dentro; sem legenda.
   Ao clicar, o components.js abre o Lightbox: um <dialog class="bs-lightbox"> em tela cheia com a imagem grande, Fechar, anterior,
   próximo e contador "3 / 40" (setas do teclado e deslizar no celular também; Esc e clicar fora fecham).
   Estado: o item tem hover e foco visíveis. Lightbox: figura (__figure), __close, __prev, __next, __count.
   LIGHTBOX NO CHAT (09/11/2026): BS.lightbox(itens, índice, opções) abre a mesma janela fora da Gallery. Cada item aceita { src, alt, cap, prev }: cap vira texto ao lado do contador
   ("3 / 12 · Ana · 14:20") e prev é uma miniatura que aparece enquanto a grande carrega. opções.action = { label, icon, fn(item, i), show(item, i) } liga o botão __action
   (canto de cima à esquerda; show decide por foto se ele aparece). O Lightbox não sabe o que a ação faz: quem chama decide.
   ========================================================================== */
.bs-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(max(calc(var(--size-control-lg) * 3), calc((100% - var(--space-3) * 3) / 4 - var(--stroke-thin))), 1fr)); gap: var(--space-3); margin: var(--space-7) 0; }
.bs-gallery__item { display: block; position: relative; overflow: hidden; aspect-ratio: 1 / 1; border-radius: var(--radius-lg); background: var(--bg-surface-raised); cursor: zoom-in; text-decoration: none; transition: opacity var(--transition-default); }
.bs-gallery__item img { display: block; width: 100%; height: 100%; margin: 0; border-radius: 0; object-fit: cover; }
.bs-gallery__item:hover, .bs-gallery__item.is-hover { opacity: .85; }
.bs-gallery__item:focus-visible, .bs-gallery__item.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-lightbox { position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none; margin: 0; padding: var(--space-9) var(--space-5); box-sizing: border-box; border: 0; background: var(--bg-scrim); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-lightbox[open] { display: flex; align-items: center; justify-content: center; }
.bs-lightbox::backdrop { background: var(--bg-scrim); }
.bs-lightbox__figure { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; margin: 0; min-width: 0; min-height: 0; }
.bs-lightbox__figure img { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; border-radius: var(--radius-lg); }
.bs-lightbox__close { position: absolute; top: var(--space-5); right: var(--space-5); z-index: var(--z-controls); }
.bs-lightbox__action { position: absolute; top: var(--space-5); left: var(--space-5); z-index: var(--z-controls); }
.bs-lightbox__action[hidden] { display: none; }
.bs-lightbox__prev, .bs-lightbox__next { position: absolute; top: 50%; transform: translateY(-50%); z-index: var(--z-controls); }
.bs-lightbox__prev { left: var(--space-4); }
.bs-lightbox__next { right: var(--space-4); }
.bs-lightbox__count { position: absolute; bottom: var(--space-5); left: 0; right: 0; text-align: center; font-size: var(--font-size-14); font-weight: var(--font-weight-medium); color: var(--text-secondary); pointer-events: none; }

/* ===== Article card ===========================================================
   Card de um artigo do blog: imagem em card arredondado e o texto FORA dele (sem fundo, sem borda, regra 11).
   É um <a>. Partes: __cover (imagem), __body, __title, __meta, __date; a tag é uma Pill (bs-pill bs-pill--sm) com a cor da categoria
   (bs-artcat-*). Ordem dentro do __body: título e, embaixo, a linha __meta com a tag e, ao lado, a data (a tag é opcional;
   sem tag, a data fica sozinha).
   FORMA (1): padrão (capa 4:3 em cima, texto embaixo) · --compact (linha: miniatura de 80 + título; sem tag; ex.: Continue lendo)
     · --ranked (posição grande atrás da capa, __rank dentro de __top; ex.: Mais lidos)
   MODIFICADOR: --lg (título 24, passa a 32 quando o card tem 480 ou mais de largura; ex.: destaque do topo).
   Para a capa preencher a altura de uma grade, o contêiner da tela dá altura ao card e à capa (flex: 1); o componente não decide isso.
   O título corta em 3 linhas (4 no --lg). Estados: hover sublinha o título; foco :focus-visible.
   ========================================================================== */
.bs-article-card { container: bs-article-card / inline-size; display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; color: var(--text-primary); text-decoration: none; font-family: var(--font-corpo); }
.bs-article-card:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); border-radius: var(--radius-lg); }
.bs-article-card__cover { display: block; position: relative; overflow: hidden; aspect-ratio: 4 / 3; border-radius: var(--radius-xl); background: var(--bg-surface-raised); }
.bs-article-card__cover img { display: block; width: 100%; height: 100%; object-fit: cover; }
.bs-article-card__body { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); min-width: 0; }
.bs-article-card__title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; font-size: var(--font-size-18); font-weight: var(--font-weight-regular); line-height: var(--line-height-snug); }
.bs-article-card:hover .bs-article-card__title { text-decoration: underline; text-underline-offset: var(--space-2); }
.bs-article-card__meta { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.bs-article-card__date { font-size: var(--font-size-14); font-weight: var(--font-weight-medium); color: var(--text-tertiary); }
.bs-article-card--lg .bs-article-card__title { -webkit-line-clamp: 4; font-size: var(--font-size-24); line-height: var(--line-height-tight); letter-spacing: -.02em; }
@container bs-article-card (min-width: 480px) { .bs-article-card--lg .bs-article-card__title { font-size: var(--font-size-32); } }
.bs-article-card--compact { flex-direction: row; align-items: flex-start; }
.bs-article-card--compact .bs-article-card__cover { flex: none; width: var(--size-article-thumb); height: var(--size-article-thumb); aspect-ratio: auto; border-radius: var(--radius-lg); }
.bs-article-card--ranked .bs-article-card__top { display: flex; align-items: flex-end; height: var(--size-article-rank-h); }
.bs-article-card--ranked .bs-article-card__rank { margin-right: calc(var(--space-3) * -1); font-size: calc(var(--font-size-48) * 2.5); font-weight: var(--font-weight-black); line-height: .8; letter-spacing: -.06em; color: var(--border-strong); }
.bs-article-card--ranked .bs-article-card__cover { flex: none; width: var(--size-article-rank-w); height: 100%; aspect-ratio: auto; border-radius: var(--radius-lg); }

/* ===== Article ================================================================
   A tela de leitura de um artigo (organismo). Muda sozinha conforme a largura do próprio elemento (container query, literal
   760px, como o Profile hero com 640): estreito = uma coluna (texto, depois a lateral); largo = texto + lateral fixa.
   Partes: __crumb (Breadcrumb) · __cols · __main (__head: __tag, __title, __date; __cover; __body com bs-prose; __nav; __comments)
   · __side (__share, __related com __related-title e Article cards --compact).
   __tag é uma Pill que leva à lista da categoria: exceção documentada ao "Pill não é clicável" (tem hover e foco).
   __nav = Anterior e Próximo: DUAS SETAS, um IconButton secundário (bs-icon-btn bs-icon-btn--secondary) com a seta para a esquerda e outro com a seta para a direita,
   cada um nas pontas da linha. É um <a> para o artigo; o nome do artigo fica no aria-label e no title ("Anterior: ..."). Se só existir um, o outro lado fica vazio.
   __comments recebe o bloco bs-comments (o título dele fica regular). Cada slot é opcional.
   ========================================================================== */
.bs-article { container: bs-article / inline-size; display: flex; flex-direction: column; gap: var(--space-7); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-article__cols { display: flex; flex-direction: column; gap: var(--space-9); }
.bs-article__main { display: flex; flex-direction: column; gap: var(--space-6); min-width: 0; }
.bs-article__head { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-4); }
.bs-article__tag { text-decoration: none; cursor: pointer; transition: background var(--transition-default); }
.bs-article__tag:hover { background: color-mix(in srgb, var(--bs-pill, var(--text-secondary)) 28%, var(--bg-surface)); }
.bs-article__tag:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-article__title { margin: 0; font-size: var(--font-size-32); font-weight: var(--font-weight-regular); line-height: var(--line-height-tight); letter-spacing: -.02em; }
.bs-article__date { font-size: var(--font-size-14); font-weight: var(--font-weight-medium); color: var(--text-tertiary); }
.bs-article__cover { display: block; overflow: hidden; aspect-ratio: 4 / 3; border-radius: var(--radius-lg); background: var(--bg-surface-raised); }
.bs-article__cover img { display: block; width: 100%; height: 100%; object-fit: cover; }
.bs-article__nav { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); margin-top: var(--space-7); }
.bs-article__comments { margin-top: var(--space-7); }
.bs-article__comments .bs-comments { margin-block: 0; }
.bs-article__comments .bs-comments__title { font-size: var(--font-size-24); font-weight: var(--font-weight-regular); }
.bs-article__side { display: flex; flex-direction: column; gap: var(--space-7); }
.bs-article__share { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: var(--space-4) var(--space-4) var(--space-4) var(--space-5); border-radius: var(--radius-xl); background: var(--bg-surface); font-weight: var(--font-weight-bold); }
.bs-article__related { display: flex; flex-direction: column; gap: var(--space-5); }
.bs-article__related-title { margin: 0; font-size: var(--font-size-20); font-weight: var(--font-weight-black); line-height: var(--line-height-snug); }
@container bs-article (min-width: 760px) {
  .bs-article__cols { flex-direction: row; align-items: flex-start; }
  .bs-article__main { flex: 1 1 0; }
  .bs-article__title { font-size: var(--font-size-40); }
  .bs-article__cover { aspect-ratio: 16 / 9; border-radius: var(--radius-xl); }
  .bs-article__side { flex: none; width: var(--size-article-side); position: sticky; top: var(--space-5); }
}

/* ===== Help page ==============================================================
   Página de ajuda (organismo): o esqueleto de toda tela que explica algo (Pontos, Arquétipos, Verificação, Regras,
   Reivindicação, Central de ajuda). Vai dentro de um Container --form (760); a largura nunca é dele.
   PARTES, nesta ordem: __crumb (Breadcrumb: Central de ajuda > Tela, ou a tela de onde a pessoa veio) · __head (__title + __lead) · um ou mais __section (__heading + conteúdo).
   __icon: quadradinho de ícone (44, cor de marca suave) no topo de um Card de assunto, sempre alinhado à esquerda.
   CONTEÚDO da section: texto livre · __steps (lista numerada) · __cards (grade de Cards, só quando precisar) · Accordion · Stat.
   Sem estados: é só layout. Os itens do crumb são links (foco visível); o último leva aria-current="page".
   ========================================================================== */
.bs-help { display: flex; flex-direction: column; gap: var(--space-9); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-help__crumb { min-width: 0; }   /* o caminho em si é o Breadcrumb (bs-breadcrumb); aqui só o encaixe no topo da página */
.bs-help__head { display: flex; flex-direction: column; gap: var(--space-3); }
.bs-help__title { margin: 0; font-family: var(--font-titulo); font-size: var(--font-size-40); font-weight: var(--font-weight-bold); line-height: var(--line-height-tight); }
.bs-help__lead { margin: 0; font-size: var(--font-size-18); line-height: var(--line-height-relaxed); color: var(--text-secondary); }
.bs-help__section { display: flex; flex-direction: column; gap: var(--space-5); }
.bs-help__heading { margin: 0; font-family: var(--font-titulo); font-size: var(--font-size-24); font-weight: var(--font-weight-bold); line-height: var(--line-height-snug); }
.bs-help__section > p { margin: 0; font-size: var(--font-size-16); line-height: var(--line-height-normal); }
.bs-help__steps { display: flex; flex-direction: column; gap: var(--space-5); margin: 0; padding: 0; list-style: none; counter-reset: bs-help-step; }
.bs-help__steps > li { display: flex; align-items: flex-start; gap: var(--space-4); counter-increment: bs-help-step; font-size: var(--font-size-16); line-height: var(--line-height-normal); }
.bs-help__steps > li::before { content: counter(bs-help-step); flex-shrink: 0; display: grid; place-items: center; width: var(--size-avatar-sm); height: var(--size-avatar-sm); border-radius: var(--radius-circle); background: var(--interactive-primary-subtle); color: var(--text-brand); font-size: var(--font-size-14); font-weight: var(--font-weight-bold); }
.bs-help__steps > li > * { margin: 0; padding-top: var(--space-2); }
.bs-help__cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--size-help-card-min), 1fr)); gap: var(--space-5); }
.bs-help__icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: var(--size-control-md); height: var(--size-control-md); border-radius: var(--radius-md); background: var(--interactive-primary-subtle); color: var(--text-brand); }

/* ===== Help page: variante larga ===============================================
   --wide: a Help page dentro de um Container padrão (1040) em vez do --form (760), para quem mostra grades (Conquistas).
   Textos corridos e passos continuam na largura de leitura (--layout-form); grades, seções e perguntas (Accordion) usam a largura toda. */
.bs-help--wide > .bs-help__head, .bs-help--wide .bs-help__section > p, .bs-help--wide .bs-help__steps { max-width: var(--layout-form); }

/* ===== Gems ====================================================================
   Losangos que repetem a raridade além da cor (1 comum, 2 rara, 3 épica, 4 lendária). Decorativo (aria-hidden); o nome da raridade vem no texto.
   Cor: bs-raridade-* (--bs-rarity) no próprio elemento ou num ancestral. */
.bs-gems { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--bs-rarity, var(--raridade-comum)); }
.bs-gems > i { display: block; width: var(--space-3); height: var(--space-3); border-radius: var(--radius-2xs); background: currentColor; transform: rotate(45deg); }

/* ===== Achievement =============================================================
   Card de uma conquista (ou de uma etapa dela): medalha com ícone na cor da raridade, nome, status no canto superior direito, regra e valor na mesma linha e barra de progresso (Progress) fixa no rodapé.
   COR: bs-raridade-* no próprio card (cor do ícone).   ESTADO: is-locked (ainda não: nome em cinza) · is-done (conquistada: barra verde). A medalha tem sempre o fundo tingido e o ícone na cor da raridade, em qualquer estado. Sem classe = em andamento.
   Partes: __top (medalha, nome, tags) · __medal · __name · __tags (status em Pill, alinhado ao topo da medalha) · __line (__rule + __value). */
.bs-achievement { display: flex; flex-direction: column; gap: var(--space-4); box-sizing: border-box; min-width: 0; padding: var(--space-5); border-radius: var(--radius-xl); background: var(--bg-surface); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-achievement__top { display: flex; align-items: flex-start; gap: var(--space-4); }
.bs-achievement__medal { display: grid; place-items: center; flex: none; width: var(--size-avatar-lg); height: var(--size-avatar-lg); border-radius: var(--radius-md); background: color-mix(in srgb, var(--bs-rarity, var(--raridade-comum)) 16%, var(--bg-surface)); color: var(--bs-rarity, var(--raridade-comum)); font-size: var(--size-icon-lg); }
.bs-achievement__name { flex: 1; align-self: center; min-width: 0; margin: 0; font-family: var(--font-titulo); font-size: var(--font-size-18); font-weight: var(--font-weight-bold); line-height: var(--line-height-snug); overflow-wrap: anywhere; }
.bs-achievement__tags { display: flex; flex: none; flex-direction: column; align-items: flex-end; gap: var(--space-2); }
.bs-achievement > .bs-progress { margin-top: auto; }   /* a barra fica sempre no rodapé do card, mesmo com regras de alturas diferentes */
.bs-achievement__line { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); font-size: var(--font-size-14); line-height: var(--line-height-normal); }
.bs-achievement__rule { flex: 1; min-width: 0; margin: 0; color: var(--text-secondary); }
.bs-achievement__value { flex: none; font-weight: var(--font-weight-bold); font-variant-numeric: tabular-nums; white-space: nowrap; }
.bs-achievement.is-locked .bs-achievement__name { color: var(--text-secondary); }
.bs-achievement.is-done .bs-progress__fill { background: var(--status-success); }
.bs-achievement-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(var(--size-achievement-min), 1fr)); gap: var(--space-4); }

/* ===== Rarity ==================================================================
   Seção de uma raridade: título na cor dela, losangos (Gems), prêmio, contagem "X de Y" e, dentro, uma grade de Achievement.
   Sem fundo nem card em volta: só o cabeçalho e a grade. COR: bs-raridade-* na própria seção.
   Partes: __head · __title · __prize · __count (vai para a direita). Rarity card (bs-rarity-card): resumo curto de uma raridade (pill, prêmio, texto, progresso). */
.bs-rarity { display: flex; flex-direction: column; gap: var(--space-6); box-sizing: border-box; color: var(--text-primary); font-family: var(--font-corpo); }
.bs-rarity__head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4); }
.bs-rarity__title { margin: 0; font-family: var(--font-titulo); font-size: var(--font-size-24); font-weight: var(--font-weight-bold); line-height: var(--line-height-snug); color: var(--bs-rarity, var(--raridade-comum)); }
.bs-rarity__prize { font-weight: var(--font-weight-bold); color: var(--text-brand); }
.bs-rarity__count { margin-inline-start: auto; font-size: var(--font-size-14); color: var(--text-secondary); }
.bs-rarity-card { display: flex; flex-direction: column; gap: var(--space-3); box-sizing: border-box; min-width: 0; padding: var(--space-6); border-radius: var(--radius-xl); background: var(--bg-surface); color: var(--text-primary); font-family: var(--font-corpo); }
.bs-rarity-card__top { display: flex; align-items: center; gap: var(--space-3); }
.bs-rarity-card__prize { margin: 0; font-size: var(--font-size-24); font-weight: var(--font-weight-bold); line-height: var(--line-height-tight); color: var(--text-brand); }
.bs-rarity-card__unit { font-size: var(--font-size-14); font-weight: var(--font-weight-regular); color: var(--text-secondary); }
.bs-rarity-card__text { margin: 0; font-size: var(--font-size-14); color: var(--text-secondary); }

/* ===== Stepper ================================================================
   Passos de um assistente em coluna: marcador (círculo) + rótulo, ligados por uma linha. Navegação, não aba: cada passo é um <button> em <ol>.
   ESTADOS do passo (<li class="bs-stepper__step">): padrão (a fazer, cinza) · is-done (rosa, linha rosa) · is-current (círculo maior com anel rosa e miolo cheio).
   Foco: :focus-visible. O passo atual leva aria-current="step". Tamanho único (compacto).
   ========================================================================== */
.bs-stepper { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.bs-stepper__step { position: relative; min-height: calc(var(--space-10) + var(--space-2)); }
.bs-stepper__step:last-child { min-height: 0; }
.bs-stepper__step::after { content: ""; position: absolute; left: calc(var(--space-7) / 2 - var(--stroke-thin) / 2); top: calc(var(--space-7) + var(--space-2)); bottom: var(--space-2); width: var(--stroke-thin); border-radius: var(--radius-pill); background: var(--border-strong); }
.bs-stepper__step:last-child::after { display: none; }
.bs-stepper__step.is-done::after { background: var(--interactive-primary); }
.bs-stepper__btn { display: flex; align-items: flex-start; gap: var(--space-4); padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; border-radius: var(--radius-sm); }
.bs-stepper__btn:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-stepper__marker { position: relative; flex: none; width: var(--space-7); height: var(--space-7); }
.bs-stepper__marker::before { content: ""; position: absolute; left: 50%; top: 50%; width: var(--space-4); height: var(--space-4); box-sizing: border-box; transform: translate(-50%, -50%); border-radius: var(--radius-circle); border: var(--stroke-thin) solid var(--border-control); transition: border-color var(--transition-default), width var(--transition-default), height var(--transition-default); }
.bs-stepper__marker::after { content: ""; position: absolute; left: 50%; top: 50%; width: var(--space-3); height: var(--space-3); transform: translate(-50%, -50%) scale(0); border-radius: var(--radius-circle); background: var(--interactive-primary); transition: transform var(--transition-default); }
.bs-stepper__step.is-done .bs-stepper__marker::before { border-color: var(--interactive-primary); }
.bs-stepper__step.is-current .bs-stepper__marker::before { width: var(--space-7); height: var(--space-7); border-color: var(--interactive-primary); }
.bs-stepper__step.is-current .bs-stepper__marker::after { transform: translate(-50%, -50%) scale(1); }
.bs-stepper__label { font-family: var(--font-corpo); font-size: var(--font-size-14); line-height: var(--space-7); font-weight: var(--font-weight-medium); color: var(--text-tertiary); transition: color var(--transition-default); }
.bs-stepper__btn:hover .bs-stepper__label { color: var(--text-primary); }
.bs-stepper__step.is-done .bs-stepper__label { color: var(--text-secondary); }
.bs-stepper__step.is-current .bs-stepper__label { color: var(--text-primary); font-weight: var(--font-weight-bold); }
@media (prefers-reduced-motion: reduce) { .bs-stepper__marker::before, .bs-stepper__marker::after, .bs-stepper__label { transition: none; } }

/* ===== List (lista de links numerados) ========================================
   Lista vertical de links, um por linha: número num círculo, título e seta. Fica dentro de um Card (sem fundo próprio).
   Partes: __item (o <a>) · __num · __title · __chevron. Fio fino entre os itens. Sem número: omita o __num.
   Estados: hover sublinha o título; foco :focus-visible. É navegação: o contêiner é um <nav> com aria-label.
   ========================================================================== */
.bs-list { display: flex; flex-direction: column; font-family: var(--font-corpo); }
.bs-list__item { display: flex; align-items: center; gap: var(--space-4); padding: var(--space-4) 0; color: var(--text-primary); text-decoration: none; }
.bs-list__item:first-child { padding-top: 0; }
.bs-list__item:last-child { padding-bottom: 0; }
.bs-list__item + .bs-list__item { border-top: var(--stroke-hairline) solid var(--border-subtle); }
.bs-list__item:focus-visible, .bs-list__item.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); border-radius: var(--radius-md); }
.bs-list__num { flex: none; display: grid; place-items: center; width: var(--size-control-sm); height: var(--size-control-sm); border-radius: var(--radius-circle); background: var(--bg-surface-raised); font-size: var(--font-size-14); font-weight: var(--font-weight-bold); }
.bs-list__title { flex: 1; min-width: 0; font-size: var(--font-size-16); line-height: var(--line-height-snug); }
.bs-list__item:hover .bs-list__title, .bs-list__item.is-hover .bs-list__title { text-decoration: underline; text-underline-offset: var(--space-2); }
.bs-list__chevron { flex: none; color: var(--text-tertiary); }

/* ===== Rating (nota em estrelas) ==============================================
   Escolha de 1 a 5 estrelas. O contêiner é role="radiogroup" e cada estrela é um <button role="radio"> (__star) com um ícone de estrela.
   Estados: is-on = estrela cheia (da primeira até a nota escolhida); hover mostra a prévia (a estrela e as anteriores); foco :focus-visible.
   TAMANHO: padrão (caixa de 44, ícone 32) · --lg (caixa de 48, ícone 40). Cor das estrelas cheias: --stat-amber. O JavaScript (components.js) marca is-on e aria-checked, guarda a nota em data-value e dispara bs:rating.
   ========================================================================== */
.bs-rating { display: inline-flex; gap: var(--space-2); }
.bs-rating__star { display: grid; place-items: center; width: var(--size-control-md); height: var(--size-control-md); padding: 0; border: 0; border-radius: var(--radius-md); background: none; color: var(--text-tertiary); font-size: var(--size-icon-xl); cursor: pointer; transition: color var(--transition-default); }
.bs-rating__star .bs-icon { font-size: inherit; }   /* o ícone acompanha o tamanho da estrela (senão fica nos 20 do ícone padrão) */
.bs-rating__star.is-on, .bs-rating__star:hover, .bs-rating__star:has(~ .bs-rating__star:hover), .bs-rating__star.is-hover { color: var(--stat-amber); }
.bs-rating__star.is-on .bs-icon, .bs-rating__star:hover .bs-icon, .bs-rating__star:has(~ .bs-rating__star:hover) .bs-icon, .bs-rating__star.is-hover .bs-icon { --ico: var(--ico-s, var(--ico-r)); }
.bs-rating__star:focus-visible, .bs-rating__star.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
/* --lg: estrelas maiores (caixa de 48, ícone de 40) para um card de avaliação; cinco cabem em 272 de largura (celular). */
.bs-rating--lg .bs-rating__star { width: var(--size-control-lg); height: var(--size-control-lg); font-size: calc(var(--size-icon-xl) * 1.25); }
@media (prefers-reduced-motion: reduce) { .bs-rating__star { transition: none; } }


/* ===== Profile body (corpo da aba Perfil) ======================================
   Template da aba Perfil de uma pessoa (organismo): duas colunas quando há espaço, uma coluna quando não há. Vai DENTRO do container da página, abaixo das abas.
   PARTES: bs-profile-body (mede a própria largura) > __cols (a grade) > __main (coluna maior, 2fr: o que se lê: Estilo Pig, Sobre mim, Gosta de, Curioso e tanto faz, Não curte)
                                                                     + __side (coluna menor, 1fr: o que se confere num olhar: Perfil completo/Match, Identidade, Estilo de vida, O que procuro, Meu scat, Atividade, Contato, Histórias).
   Cada filho de __main e __side é um Card (bs-card). UMA COLUNA (largura < 720, vale também para o quadro de celular do protótipo): as colunas somem (display: contents)
   e os Cards ficam empilhados na ordem da variável --bs-order de cada Card (sem ela, vale a ordem do HTML). DUAS COLUNAS (>= 640): a ordem é a do HTML dentro de cada coluna e --bs-order não conta.
   Sem estados: é só layout.
   ========================================================================== */
.bs-profile-body { container-type: inline-size; container-name: bs-profile-body; }
.bs-profile-body__cols { display: flex; flex-direction: column; gap: var(--space-5); }
.bs-profile-body__main, .bs-profile-body__side { display: contents; }
.bs-profile-body__cols > * > * { order: var(--bs-order, 0); min-width: 0; }
@container bs-profile-body (min-width: 720px) {
  .bs-profile-body__cols { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); align-items: start; }
  .bs-profile-body__main, .bs-profile-body__side { display: flex; flex-direction: column; gap: var(--space-5); min-width: 0; }
  .bs-profile-body__cols > * > * { order: 0; }
}


/* ===== Key-value (lista rótulo e valor) =========================================
   Lista de pares "rótulo: resposta" dentro de um Card (Identidade, Estilo de vida, Meu scat da aba Perfil). É um <dl>.
   PARTES: bs-kv > __row (um par) > __key (rótulo, largura fixa, cor secundária) + __value (resposta, medium).
   FORMA: padrão = rótulo e resposta juntos (rótulo com largura fixa) · --split = rótulo na esquerda e resposta alinhada à direita.
   O rótulo nunca quebra em duas linhas. Sem estados: não é interativo.
   ========================================================================== */
.bs-kv { display: flex; flex-direction: column; gap: var(--space-3); margin: 0; font-family: var(--font-corpo); }
.bs-kv__row { display: flex; align-items: baseline; gap: var(--space-4); }
.bs-kv__key { flex: 0 0 var(--size-avatar-2xl); margin: 0; color: var(--text-secondary); white-space: nowrap; }
.bs-kv__value { margin: 0; min-width: 0; font-weight: var(--font-weight-medium); overflow-wrap: anywhere; }
.bs-kv--split .bs-kv__row { justify-content: space-between; gap: var(--space-5); }
.bs-kv--split .bs-kv__key { flex: none; }
.bs-kv--split .bs-kv__value { text-align: right; }


/* ===== Pill group (grupo de tags com título) ====================================
   Um título curto com contagem e, abaixo, tags (Pill). Usado em Gosta de, Curioso e tanto faz e Não curte da aba Perfil
   ("Já fiz 6", "Ainda não fiz 2", "Tenho curiosidade 7"). Vários grupos seguidos num Card ficam separados por espaço.
   PARTES: bs-pill-group > __head (__icon opcional · __title · __count) + __pills (as Pills, com quebra de linha).
   COR: padrão = título branco · --info = título azul (Curioso). Sem estados.
   ========================================================================== */
.bs-pill-group { display: flex; flex-direction: column; gap: var(--space-4); font-family: var(--font-corpo); }
.bs-pill-group + .bs-pill-group { margin-top: var(--space-6); }
.bs-pill-group__head { display: flex; align-items: center; gap: var(--space-3); }
.bs-pill-group__icon { display: inline-flex; color: var(--text-secondary); }
.bs-pill-group__title { margin: 0; font-size: var(--font-size-16); font-weight: var(--font-weight-bold); color: var(--text-primary); }
.bs-pill-group__count { font-size: var(--font-size-14); color: var(--text-secondary); }
.bs-pill-group__pills { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.bs-pill-group--info .bs-pill-group__title { color: var(--text-info); }

/* Card: legenda curta ao lado do título (bs-card__header-meta dentro do bs-card__header-title) */
.bs-card__header-title .bs-card__header-meta { margin-left: var(--space-3); font-weight: var(--font-weight-regular); }

/* ===== CTA card (09/nov/2026) ===================================
   Faixa de convite com texto e ações: "Entre para criar o seu perfil" (login), "Oi, Nina" (conta) e "Fale com o Kaio" (--brand).
   Criado para a tela Menu. Partes: __inner (linha ou coluna) · __body (opcional __media à esquerda, __title, __text) · __actions (Buttons). Mede a própria largura (o container é o card; quem muda de direção é o __inner):
   até 560px empilha (ações embaixo, em linha e quebrando se não couberem; os botões se dividem a largura); a partir de 560px vira uma linha (texto à esquerda, ações à direita).
   Modificador --brand: fundo --bg-hero-card e texto de apoio --text-on-hero-card (mesma cor do Hero card). Modificador --lg: título maior (20px, 24px a partir de 560px), para convites de conversa como o do Kaio. Sem estados: o clique é dos botões.
   ========================================================================== */
.bs-cta-card { container: bs-cta-card / inline-size; box-sizing: border-box; padding: var(--space-5); border-radius: var(--radius-xl); background: var(--bg-surface); color: var(--text-secondary); font-family: var(--font-corpo); }
.bs-cta-card--brand { background: var(--bg-hero-card); color: var(--text-on-hero-card); }
.bs-cta-card__inner { display: flex; flex-direction: column; gap: var(--space-5); }
.bs-cta-card__body { display: flex; align-items: center; gap: var(--space-4); min-width: 0; }
.bs-cta-card__media { flex: none; }
.bs-cta-card__text-wrap { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.bs-cta-card__title { margin: 0; font-size: var(--font-size-18); line-height: var(--line-height-snug); font-weight: var(--font-weight-bold); color: var(--text-primary); }
.bs-cta-card--lg .bs-cta-card__title { font-size: var(--font-size-20); }
.bs-cta-card__text { margin: 0; font-size: var(--font-size-14); line-height: var(--line-height-snug); }
.bs-cta-card__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.bs-cta-card__actions > .bs-btn { flex: 1 1 auto; }
@container bs-cta-card (min-width: 560px) {
  .bs-cta-card__inner { flex-direction: row; align-items: center; justify-content: space-between; }
  .bs-cta-card__body { flex: 1 1 0; }
  .bs-cta-card--lg .bs-cta-card__title { font-size: var(--font-size-24); }
  .bs-cta-card__actions { flex: none; flex-wrap: nowrap; }
  .bs-cta-card__actions > .bs-btn { flex: none; }
  .bs-cta-card__actions .bs-btn--block { width: auto; }
}

/* ===== Menu list (09/nov/2026) ================================================
   Lista de todos os destinos do site, em grupos (Comunidade, Ler, Meu espaço, Ajuda e site). Usada na tela Menu (último item da Tab bar e da Sidebar).
   Partes: __groups (grade dos grupos) · __group · __title · __item (<a> ou <button>) com __icon, __label, __tag e __chevron opcional.
   Cor do ícone: a classe bs-nav-* no item (define --bs-nav). Sem divisórias: a separação vem do espaço e do hover.
   Mede a própria largura: 1 coluna até 639px, 2 colunas a partir de 640px, 4 a partir de 900px (os 4 grupos da tela Menu, sem rolagem no desktop). Estados do item: padrão · hover (fundo surface) · foco.
   O item que ainda não existe leva a tag "Em breve" (__tag). Não é a Sidebar (navegação principal) nem o Menu (irmãs de uma tela).
   ========================================================================== */
.bs-menu-list { container: bs-menu-list / inline-size; font-family: var(--font-corpo); color: var(--text-primary); }
.bs-menu-list__groups { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-7); align-items: start; }
.bs-menu-list__group { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.bs-menu-list__title { margin: 0; padding: 0 var(--space-4) var(--space-2); font-size: var(--font-size-14); font-weight: var(--font-weight-bold); color: var(--text-secondary); }
.bs-menu-list__item { display: flex; align-items: center; gap: var(--space-4); box-sizing: border-box; width: 100%; min-height: var(--size-control-lg); padding: var(--space-3) var(--space-4); border: 0; border-radius: var(--radius-md); background: transparent; color: var(--text-primary); font-family: var(--font-corpo); font-size: var(--font-size-16); font-weight: var(--font-weight-medium); line-height: var(--line-height-snug); text-align: left; text-decoration: none; cursor: pointer; transition: background var(--transition-default); }
.bs-menu-list__item:hover, .bs-menu-list__item.is-hover { background: var(--bg-surface); }
.bs-menu-list__item:focus-visible, .bs-menu-list__item.is-focus { outline: var(--focus-ring); outline-offset: var(--focus-offset); }
.bs-menu-list__icon { flex: none; font-size: var(--size-icon-lg); color: var(--bs-nav, var(--text-secondary)); }
.bs-menu-list__label { flex: 1; min-width: 0; }
.bs-menu-list__tag { flex: none; padding: var(--space-1) var(--space-3); border-radius: var(--radius-pill); background: var(--interactive-primary-subtle); color: var(--text-brand); font-size: var(--font-size-12); font-weight: var(--font-weight-bold); }
.bs-menu-list__chevron { flex: none; font-size: var(--size-icon-md); color: var(--text-tertiary); }
@container bs-menu-list (min-width: 640px) { .bs-menu-list__groups { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--space-8); } }
@container bs-menu-list (min-width: 900px) { .bs-menu-list__groups { grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--space-5); } }
@media (prefers-reduced-motion: reduce) { .bs-menu-list__item { transition: none; } }
