/* haruo-ds — primitivas
 * ============================================================================
 * As poucas peças que são a MESMA COISA em qualquer um dos três produtos.
 *
 * QUANTAS SÃO, medido: o `styles.css` do Tamperlens tem 256 classes distintas.
 * 53 têm prefixo de página e a maioria das outras é composição daquela tela
 * (`.daybar-fill`, `.compare-dropzone`, `.console-issuer`). Genéricas de
 * verdade são estas ~20. Ou seja, ~92% daquele CSS não é sistema — é aquela
 * tela, e deve continuar lá.
 *
 * A REGRA QUE MANTÉM ISSO VIVO:
 *   tokens        → 100% compartilhados. É onde a marca mora.
 *   primitivas    → este arquivo. Botão, campo, card, chip, tabela, código.
 *   composições   → ZERO compartilhamento, de propósito. Hero de marketing e
 *                   visualizador de laudo têm trabalhos diferentes; forçar os
 *                   dois no mesmo componente é como design system morre.
 *
 * É CLASSE CSS, NÃO COMPONENTE. De propósito: Astro, HTML estático e string
 * gerada em Python emitem todos `<button class="btn">` e ficam idênticos, sem
 * JS compartilhado, sem build acoplado, sem framework. Nenhuma outra forma de
 * compartilhamento atravessa esses três.
 *
 * Depende de `tokens.css`. Nada aqui declara uma cor literal.
 */

/* ── base ──────────────────────────────────────────────────────────────── */
.ds-base {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
}

/* ── botão ─────────────────────────────────────────────────────────────── */
.btn {
  appearance: none;
  font: inherit;
  font-weight: var(--weight-semibold);
  cursor: pointer;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-accent);
  background: var(--color-accent);
  color: var(--color-on-accent);
  padding: 0.6rem 1rem;
  transition: background var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
.btn:hover:not(:disabled) { background: var(--color-accent-strong); border-color: var(--color-accent-strong); }
.btn:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
/* Desativado NÃO é opacidade. Baixar a opacidade do botão principal faz duas
 * coisas erradas ao mesmo tempo: derruba o contraste do rótulo abaixo do
 * mínimo AA, e deixa a peça parecendo um botão SECUNDÁRIO ativo — foi
 * exatamente o que a prévia mostrou, no claro e no escuro. Inerte se sinaliza
 * tirando a cor de marca, não apagando o texto. */
.btn:disabled,
.btn[aria-disabled="true"] {
  background: var(--color-bg-inset);
  border-color: var(--color-border);
  color: var(--color-text-faint);
  cursor: default;
}
.btn.ghost:disabled { background: none; }

/* `ghost` é a ação secundária: a borda é neutra em repouso porque duas bordas
 * na cor da marca lado a lado tiram o peso da ação principal.
 * A borda é `--color-control-edge`, e não `--color-border-strong`: a auditoria
 * de contraste mostrou que a segunda dá 1,74:1 sobre o papel — abaixo do 3:1
 * que a WCAG 1.4.11 exige para o limite de um controle. Um botão cuja borda
 * quase não se vê é um botão que quase não existe. */
.btn.ghost { background: none; color: var(--color-accent); border-color: var(--color-control-edge); }
.btn.ghost:hover:not(:disabled) { background: var(--color-accent-wash); border-color: var(--color-accent); color: var(--color-accent-strong); }

/* Grupo de alternância (tema, filtro, aba). O estado ativo é `aria-pressed`,
 * não uma classe: quem usa leitor de tela precisa ouvir qual está ligado, e
 * estilo pendurado no atributo não deixa os dois divergirem.
 *
 * FICA DEPOIS DE `.btn.ghost` DE PROPÓSITO. As duas regras têm a mesma
 * especificidade (0-2-0), então quem vem por último vence — e um `ghost`
 * pressionado precisa ficar preenchido, não fantasma. Estava acima até a
 * prévia mostrar o botão de tema ativo sem marcação nenhuma. */
.btn[aria-pressed="true"],
.btn.ghost[aria-pressed="true"] {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-on-accent);
}
.btn.small { padding: 0.35rem 0.7rem; font-size: var(--text-sm); }
.btn.block { width: 100%; }
.btn-row { display: flex; gap: var(--space-3); flex-wrap: wrap; }

/* ── chip / badge de estado ────────────────────────────────────────────
 * A cor NUNCA carrega o significado sozinha — o chip sempre tem palavra
 * dentro. É a mesma regra que o painel do agentservice já segue. */
.chip {
  display: inline-block;
  padding: 0.18rem 0.6rem;
  border-radius: var(--radius-full);
  border: 1px solid var(--color-border-strong);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.01em;
  color: var(--color-text-muted);
  background: var(--color-bg-inset);
}
.chip-ok     { color: var(--color-ok-text);     background: var(--color-ok-bg);     border-color: var(--color-ok-border); }
.chip-warn   { color: var(--color-warn-text);   background: var(--color-warn-bg);   border-color: var(--color-warn-border); }
.chip-danger { color: var(--color-danger-text); background: var(--color-danger-bg); border-color: var(--color-danger-border); }
.chip-muted  { color: var(--color-text-faint);  background: var(--color-bg-code);   border-color: var(--color-border-strong); }

/* ── card ──────────────────────────────────────────────────────────────── */
.card {
  background: var(--color-bg-raised);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
.card > :first-child { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }

/* ── callout ───────────────────────────────────────────────────────────── */
.callout {
  border: 1px solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-sm);
  background: var(--color-bg-inset);
  padding: 0.9rem 1.1rem;
  margin: 0 0 var(--space-6);
}
.callout > :last-child { margin-bottom: 0; }
.callout.warn  { border-left-color: var(--color-warn); }
.callout.stern { border-left-color: var(--color-danger); }

/* ── campo ─────────────────────────────────────────────────────────────── */
.field {
  font: inherit;
  width: 100%;
  padding: 0.55rem 0.7rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-control-edge);
  background: var(--color-bg-raised);
  color: var(--color-text);
}
.field:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; border-color: var(--color-accent); }
.field::placeholder { color: var(--color-text-faint); }
.label { display: block; font-size: var(--text-sm); font-weight: var(--weight-medium); color: var(--color-text-muted); margin-bottom: var(--space-1); }

/* ── tabela ────────────────────────────────────────────────────────────── */
.table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.table th, .table td { text-align: left; padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--color-border); }
.table th { font-weight: var(--weight-semibold); color: var(--color-text-muted); }
.table tbody tr:hover { background: var(--color-bg-inset); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── código ────────────────────────────────────────────────────────────── */
.code, code, kbd, samp {
  font-family: var(--font-mono);
  font-size: 0.92em;
  background: var(--color-bg-code);
  color: var(--color-text-code);
  border-radius: 4px;
  padding: 0.12em 0.35em;
}
pre.code { padding: var(--space-4); overflow-x: auto; border: 1px solid var(--color-border); }
pre.code code { background: none; padding: 0; }

/* ── prosa ─────────────────────────────────────────────────────────────── */
.prose { max-width: var(--width-prose); color: var(--color-text-article); line-height: var(--leading-relaxed); }
.prose h1, .prose h2, .prose h3 { color: var(--color-text); line-height: var(--leading-tight); font-family: var(--font-display); }
.prose a { color: var(--color-accent); text-underline-offset: 0.2em; }

/* ── movimento ─────────────────────────────────────────────────────────
 * Inegociável, e no sistema em vez de em cada produto: quem pediu para parar,
 * para. Um site cheio de movimento sem isto dá enjoo em quem tem distúrbio
 * vestibular. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
