/* app/assets/stylesheets/04_components.css — vocabulario de componente */

/* ---- cabecalho de pagina ---- */

.page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s5);
}

/* Area de acao do cabecalho: um botao na maioria das telas, tres filhos no Financeiro
   (mes anterior, mes corrente, proximo). Ate agora so o space-between do pai a posicionava. */
.page-header__action { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); }

/* ---- card ---- */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: var(--s5);
}
.card + .card { margin-top: var(--s5); }
/* Titulo de secao dentro do card (dia da semana na Grade, blocos da ficha). */
.card__title { font-size: var(--t4); margin: 0 0 var(--s3); }
/* Texto de apoio no topo do card: e irmao do .form, entao nao participa do gap dele e
   precisa da propria margem inferior. */
.card__intro {
  margin: 0 0 var(--s5);
  max-width: var(--measure);
  font-size: var(--t3);
  color: var(--ink-muted);
}
/* A tabela dentro do card ja esta sobre superficie: dispensa a propria moldura. */
.card > .data-table { border: 0; box-shadow: none; border-radius: 0; }

/* ---- botoes ----
   button_to gera <form><button>; a margem do form ja foi zerada em 02_base.css. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 36px;
  padding: var(--s2) var(--s4);
  font-size: var(--t3);
  font-weight: 600;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  text-decoration: none;
  transition: background-color 120ms ease, border-color 120ms ease;
}
.btn:hover { border-color: var(--ink-faint); }

.btn--primary { background: var(--accent); border-color: var(--accent); color: var(--surface); }
.btn--primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

/* Densidade de linha de tabela: mesmo componente, menos respiro. Aplicada na view, e nao
   por seletor descendente, para o botao continuar sendo estilizado so por classe propria. */
.btn--compact { min-height: 0; padding: var(--s1) var(--s2); font-size: var(--t2); }
.btn--compact .icon { font-size: var(--t3); }

.btn--ghost { background: none; border-color: transparent; color: var(--ink-muted); font-weight: 400; }
.btn--ghost:hover { border-color: var(--line); color: var(--ink); }

.btn--danger { color: var(--danger); border-color: var(--line); background: none; }
.btn--danger:hover { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 6%, transparent); }

/* Alvo de toque na postura transitoria. */
@media (max-width: 47.999rem) {
  .btn { min-height: 44px; }
}

/* ---- filtro segmentado (ativas / arquivadas) ---- */

.filter-tabs { display: inline-flex; gap: var(--s1); }
.filter-tabs__tab {
  padding: var(--s1) var(--s3);
  font-size: var(--t2);
  color: var(--ink-muted);
  text-decoration: none;
  border-radius: var(--radius);
}
.filter-tabs__tab--current { background: var(--surface); color: var(--ink); font-weight: 600; box-shadow: var(--shadow-card); }

/* ---- numero-destaque (painel do mes) ---- */

/* Coluna larga e linha curta: com cinco numeros o grid quebra em 3+2, e gaps iguais nos
   dois eixos faziam a segunda fila parecer um bloco solto em vez da continuacao da primeira. */
.stat-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s5) var(--s6); }
.stat { display: flex; flex-direction: column; gap: var(--s1); }
.stat__label { font-size: var(--t2); color: var(--ink-muted); }
/* Cormorant aqui e o segundo dos dois usos que a regra 4 libera: numero-destaque. */
.stat__value {
  font-family: var(--font-display);
  font-size: var(--t6);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.stat__value--muted { color: var(--ink-muted); }
.stat__value--warn { color: var(--warm-ink); }

@media (min-width: 48rem) {
  .stat-row { grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); }
}

/* ---- navegacao de mes no cabecalho ---- */

.month-nav__current {
  font-size: var(--t4);
  font-weight: 600;
  color: var(--ink);
  padding-inline: var(--s2);
}

/* ---- tabela densa ---- */

.data-table {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.data-table th {
  font-size: var(--t1);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--ink-muted);
  border-bottom: 1px solid var(--line);
  padding-block: var(--s2);
}
/* `vertical-align: top`: quando a coluna de acoes empilha botoes, a linha fica alta e o
   resto do conteudo boiava no meio dela, longe do proprio cabecalho de coluna. */
.data-table td { border-bottom: 1px solid var(--line); font-size: var(--t3); vertical-align: top; }
.data-table tbody tr:last-child td { border-bottom: 0; }
.data-table__secondary { color: var(--ink-muted); }
/* Dado de apoio embaixo do principal, em linha propria: solto ao lado, o telefone
   quebrava no meio do numero e o erro de envio colava no badge. */
.data-table__meta {
  display: block;
  margin-top: var(--s1);
  font-size: var(--t2);
  color: var(--ink-muted);
}

/* Regra 8. O alinhamento a direita serve para COLUNA de numero, onde as casas se
   empilham e se comparam. Fora de tabela ele joga o valor contra a borda, longe do
   proprio rotulo — media ~370px na ficha da aluna —, entao `.numeric` carrega so os
   algarismos tabulares. */
.data-table__numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
  /* Valor nao quebra no meio: "R$ 300,00" em duas linhas deixa de ser legivel como valor. */
  white-space: nowrap;
}
.numeric { font-variant-numeric: tabular-nums; }
/* A divergencia de valor e informacao secundaria: na mesma linha do valor pago ela
   inchava a coluna em 70px e empurrava a tabela para fora do cartao a 900px. */
.data-table__delta { display: block; font-size: var(--t1); color: var(--ink-muted); }
/* Quatro acoes com icone e rotulo nao cabem numa linha de 1030px: sem quebra elas
   empurravam a tabela para fora da tela. Quebram como texto — e a celula continua
   `display: table-cell`, porque um <td> em flex sai do algoritmo de tabela e a linha
   deixa de fechar com as vizinhas. */
.data-table__actions { text-align: right; }
/* nowrap no BOTAO, nao na celula: o rotulo nao quebra no meio ("Registrar / pagamento"),
   mas os botoes ainda podem quebrar entre si quando a coluna aperta. */
.data-table__actions .btn { margin: 0 0 var(--s1) var(--s2); vertical-align: middle; white-space: nowrap; }
/* Com duas acoes curtas elas cabem lado a lado, mas o layout automatico dava a folga da
   linha para a coluna vizinha e empilhava os botoes assim mesmo. `width: 1%` + nowrap faz a
   coluna pedir exatamente a largura dos botoes. NAO usar onde ha tres ou mais acoes: ali o
   min-content passa da largura da tabela e volta a estourar. */
.data-table__actions--inline { width: 1%; white-space: nowrap; }
/* button_to gera um <form> em volta do <button>: sem isto a acao destrutiva quebra linha sozinha. */
.data-table__actions form { display: inline-block; }

/* Na postura transitoria a tabela vira lista de cards — o <table> do ERB nao muda.
   O rotulo de cada celula vem do atributo data-label escrito no <td>. */
@media (max-width: 47.999rem) {
  .data-table, .data-table tbody, .data-table tr, .data-table td {
    display: block;
    width: 100%;
  }
  .data-table { border: 0; background: none; box-shadow: none; overflow: visible; }
  .data-table thead { display: none; }
  .data-table tr {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    padding: var(--s3) var(--s4);
    margin-bottom: var(--s3);
  }
  .data-table td { border-bottom: 0; padding: var(--s1) 0; text-align: left; }
  .data-table td[data-label]::before {
    content: attr(data-label);
    display: block;
    font-size: var(--t1);
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--ink-muted);
  }
  .data-table__actions { text-align: left; padding-top: var(--s3); }
  /* No cartao do celular a largura e a linha unica do modificador nao valem: o cartao tem
     390px e os botoes precisam quebrar. */
  .data-table__actions--inline { width: auto; white-space: normal; }
}

/* ---- icone (regra 11: nunca aparece sem rotulo) ---- */

/* Dimensiona pelo contexto, nunca por atributo no HTML: 1em segue o font-size de quem o
   contem. Traco de 1.5px com canto vivo — a mesma lingua das bordas de 1px do sistema. */
.icon {
  width: 1em;
  height: 1em;
  flex: none;
  /* Em contexto flex (btn, nav) o alinhamento vem do container. Solto em texto corrido o
     svg assenta na linha de base e sobe demais — este recuo o centra na altura da minuscula. */
  vertical-align: -0.125em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: butt;
  stroke-linejoin: miter;
}
.btn .icon { font-size: var(--t4); }

/* ---- badge: regra 7, cor + palavra, nunca cor sozinha ---- */

.badge {
  display: inline-block;
  padding: 2px var(--s2);
  font-size: var(--t1);
  font-weight: 600;
  border-radius: var(--radius);
  white-space: nowrap;
}
/* Tingimento derivado do token com color-mix() em vez de rgba() cru: se o tom base mudar em
   01_tokens.css, o fundo do badge acompanha. Alfas .16/.16/.18/.07 sao os medidos na fase 6. */
.badge--paid,     .badge--active   { background: color-mix(in srgb, var(--accent) 16%, transparent);    color: var(--accent-ink); }
.badge--pending                    { background: color-mix(in srgb, var(--ink-faint) 16%, transparent); color: var(--ink-muted); }
.badge--overdue                    { background: color-mix(in srgb, var(--warm) 18%, transparent);      color: var(--warm-ink); }
.badge--canceled, .badge--archived,
.badge--inactive                   { background: color-mix(in srgb, var(--ink) 7%, transparent);        color: var(--ink-muted); }
.badge--sent                       { background: color-mix(in srgb, var(--accent) 16%, transparent);    color: var(--accent-ink); }
.badge--failed                     { background: color-mix(in srgb, var(--danger) 12%, transparent);    color: var(--danger); }

/* ---- dl da ficha ---- */

.field-list { display: grid; gap: var(--s3) var(--s5); }
.field-list dt { font-size: var(--t2); color: var(--ink-muted); }
.field-list dd { margin: 0; font-size: var(--t4); color: var(--ink); }

@media (min-width: 48rem) {
  .field-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- estado vazio ---- */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s3);
  padding: var(--s6);
  background: var(--surface);
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
}
.empty-state__message { color: var(--ink-muted); }

/* ---- flash ---- */

.flash {
  max-width: var(--container);
  margin: var(--s4) auto 0;
  padding: var(--s3) var(--s4);
  font-size: var(--t3);
  border: 1px solid var(--line);
  /* 3px porque a faixa continua a borda de 1px da propria caixa: em 2px ela nao se le como
     faixa, so como borda mais grossa. Excecao de espessura nomeada na regra 1 da spec. */
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--surface);
}
.flash--notice { border-left-color: var(--accent); }
.flash--alert  { border-left-color: var(--warm); }

/* ---- lista empilhada (horarios, mensagens) ---- */

.stacked-list { display: flex; flex-direction: column; }
.stacked-list__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--line);
}
.stacked-list__item:last-child { border-bottom: 0; }
.stacked-list__item--stacked { flex-direction: column; align-items: flex-start; gap: var(--s1); }

.message-meta { font-size: var(--t1); color: var(--ink-muted); }

/* ---- form de uma linha (adicionar horario) ---- */

.inline-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-top: var(--s4);
}
.inline-form select { width: auto; flex: 1; min-width: 12rem; }

/* Espaco entre o h2 do card e o conteudo — o reset zerou a margem. */
.card h2 { margin-bottom: var(--s4); }

/* ---- formulario: coluna unica de 32rem (postura soberana) ---- */

.form { max-width: 32rem; display: flex; flex-direction: column; gap: var(--s4); }
.form__field { display: block; }
/* --ink-faint da so 3,15:1 contra o texto — abaixo do piso AA de 4,5:1. */
.form__hint { font-size: var(--t2); color: var(--ink-muted); margin-top: var(--s1); }

/* Erro junto ao campo, nunca numa lista no topo (About Face: erro escusavel). */
.form__error { font-size: var(--t2); color: var(--danger); margin-top: var(--s1); }
.form__field:has(.form__error) input,
.form__field:has(.form__error) select { border-color: var(--danger); }

.form__check {
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin-bottom: var(--s2);
}
.form__check input { width: auto; }

/* 02_base.css poe todo label em bloco, t2, 600 e ink-muted — o do checkbox e inline e comum. */
.form__check label {
  display: inline;
  margin-bottom: 0;
  font-size: var(--t3);
  font-weight: 400;
  color: var(--ink);
}

.form__actions {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding-top: var(--s2);
}
