/* Trilho · componentes (skill ux-simples, componentes.md). Um bloco por componente; partial em app/views/shared/ui/. */

/* ── Botões ── */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2); min-height: var(--tap); padding: 0 var(--s-4);
  border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface); color: var(--ink);
  font: inherit; font-weight: 500; text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: transform var(--t-press), background var(--t-fast), box-shadow var(--t-fast); }
@media (min-width: 768px) { .btn { min-height: 40px; } }
.btn:hover { background: var(--surface-2); }
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: none; box-shadow: var(--focus); }
.btn-primary { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
.btn-primary:hover { background: var(--ink); box-shadow: var(--shadow-2); }
.btn-ghost { border-color: transparent; background: transparent; }
.btn-ghost:hover { background: var(--surface-2); }
.btn-danger { color: var(--bad); border-color: var(--bad); background: transparent; }
.btn-link { border: 0; background: none; padding: 0; min-height: auto; color: var(--link); text-decoration: underline; font-weight: 500; }
.btn-sm { min-height: 36px; padding: 0 var(--s-3); font-size: var(--fs-sm); }
.btn-icon { width: var(--tap); padding: 0; }
.btn-block { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"], .btn[aria-busy="true"] { opacity: .55; cursor: not-allowed; box-shadow: none; transform: none; }
.btn .icon { width: 18px; height: 18px; flex: none; }
.button-to { display: inline; margin: 0; }

/* ── Ícones ── */
.icon { width: 20px; height: 20px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.icon-lg { width: 40px; height: 40px; }

/* ── Avatar ── */
.avatar { display: inline-grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: var(--link-soft);
  color: var(--link); font-size: var(--fs-sm); font-weight: 600; flex: none; letter-spacing: .02em; }
.avatar-lg { width: 44px; height: 44px; font-size: var(--fs-md); }

/* ── Cartão ── */
.card { position: relative; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: var(--s-5); box-shadow: var(--shadow-1); display: grid; gap: var(--s-3); min-width: 0; }
.card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.card-title { margin: 0; font-size: var(--fs-lg); font-weight: 600; display: flex; align-items: center; gap: var(--s-2); }
.card-title .count { color: var(--muted); font-weight: 500; font-variant-numeric: tabular-nums; }
.card-link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.card-link { color: inherit; text-decoration: none; }
.card-link:hover { text-decoration: underline; }
.card-actions { display: flex; gap: var(--s-2); flex-wrap: wrap; position: relative; z-index: 1; }
.card-ghost { border: 1.5px dashed var(--edge); background: transparent; box-shadow: none; color: var(--muted); }
.grid { display: grid; gap: var(--s-4); grid-template-columns: 1fr; }
@media (min-width: 720px)  { .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

/* ── Pill (status: luz + palavra, nunca só cor) ── */
.pill { display: inline-flex; align-items: center; gap: 6px; min-height: 24px; padding: 0 10px; border-radius: var(--r-pill);
  font-size: var(--fs-sm); font-weight: 500; white-space: nowrap; background: var(--surface-2); color: var(--muted); }
.pill .light { width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: none; }
.pill-ok   { background: var(--ok-soft);   color: var(--ok); }
.pill-warn { background: var(--warn-soft); color: var(--warn); }
.pill-bad  { background: var(--bad-soft);  color: var(--bad); }
.pill-info { background: var(--link-soft); color: var(--link); }
.pill-muted{ background: var(--surface-2); color: var(--muted); }
.pill-outline { background: transparent; border: 1px solid var(--line); color: var(--muted); }

/* ── Barra de gasto (cor + número sempre) ── */
.bar { display: inline-flex; align-items: center; gap: var(--s-2); min-width: 0; }
.bar-track { width: 72px; height: 8px; border-radius: var(--r-pill); background: var(--surface-2); border: 1px solid var(--line); overflow: hidden; flex: none; }
.bar-fill { display: block; height: 100%; background: var(--bar-ok); border-radius: inherit; } /* <span>: block para valer a largura */
.bar-warn .bar-fill { background: var(--bar-warn); }
.bar-bad .bar-fill { background: var(--bar-bad); }
.bar-label { font-size: var(--fs-sm); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ── Tabela responsiva (≤ 640 px vira cartão) ── */
.table { width: 100%; border-collapse: collapse; }
.table th { text-align: left; font-size: var(--fs-xs); font-weight: 500; color: var(--muted); padding: var(--s-2) var(--s-3); white-space: nowrap; }
.table td { padding: var(--s-3); border-top: 1px solid var(--line); height: 48px; vertical-align: middle; }
.table tbody tr:hover td { background: var(--surface-2); }
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table tfoot td { font-weight: 600; border-top: 2px solid var(--line); }
@media (max-width: 640px) {
  .table thead { display: none; }
  .table tr { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-1) var(--s-3); padding: var(--s-3) 0; border-top: 1px solid var(--line); }
  .table td { display: block; border: 0; height: auto; padding: 0; min-width: 0; }
  .table td::before { content: attr(data-label); display: block; font-size: var(--fs-xs); color: var(--muted); }
  .table td[data-primary] { grid-column: 1 / -1; font-weight: 500; }
  .table td[data-primary]::before { display: none; }
  .table td.actions { grid-column: 1 / -1; }
  .table .num { text-align: left; }
}

/* ── Lista ── */
.list { list-style: none; margin: 0; padding: 0; }
.list-item { position: relative; display: flex; align-items: flex-start; gap: var(--s-3); min-height: var(--tap); padding: var(--s-3) 0; border-top: 1px solid var(--line); }
.list-item:first-child { border-top: 0; }
.list-item > .icon { margin-top: 2px; color: var(--muted); }
.list-main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.list-main > a, .list-title { font-weight: 500; color: var(--ink); text-decoration: none; overflow-wrap: anywhere; }
.list-main > a:hover { text-decoration: underline; }
.list-meta { font-size: var(--fs-sm); color: var(--muted); overflow-wrap: anywhere; }
.list-side { display: flex; align-items: center; gap: var(--s-2); flex: none; }
.list-item.is-unread .list-title, .list-item.is-unread > .list-main > a { font-weight: 600; }
.list-item.is-unread::before { content: ""; position: absolute; left: -12px; top: 20px; width: 6px; height: 6px; border-radius: 50%; background: var(--link); }

/* ── Formulário ── */
.form { display: grid; gap: var(--s-5); max-width: 560px; }
.field { display: grid; gap: var(--s-1); }
.field label, .field .label { font-size: var(--fs-sm); font-weight: 500; }
.label-hint { font-weight: 400; color: var(--muted); }
.label-hint::before { content: "· "; }
.field input:not([type="checkbox"]):not([type="radio"]), .field select, .field textarea {
  min-height: var(--tap); width: 100%; padding: 0 var(--s-3); font: inherit; font-size: 16px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--edge); border-radius: var(--r-md); }
@media (min-width: 768px) { .field input:not([type="checkbox"]):not([type="radio"]), .field select { font-size: var(--fs-md); } }
.field textarea { padding: var(--s-3); min-height: 120px; resize: vertical; }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { outline: none; border-color: var(--link); box-shadow: var(--focus); }
.field .hint { margin: 0; }
.field .error { margin: 0; font-size: var(--fs-sm); color: var(--bad); display: flex; gap: var(--s-1); align-items: center; }
.field-error input, .field-error select, .field-error textarea { border-color: var(--bad) !important; }
.check { display: flex; align-items: flex-start; gap: var(--s-3); min-height: var(--tap); padding: var(--s-2) 0; cursor: pointer; }
.check input { width: 20px; height: 20px; margin-top: 2px; accent-color: var(--ink); flex: none; }
.form-actions { display: flex; gap: var(--s-2); align-items: center; flex-wrap: wrap; }
.error-summary { border: 2px solid var(--bad); border-radius: var(--r-md); padding: var(--s-4); background: var(--surface); display: grid; gap: var(--s-2); }
.error-summary h2 { font-size: var(--fs-lg); }
.error-summary ul { margin: 0; padding-left: var(--s-5); }
.error-summary a { color: var(--bad); font-weight: 500; }

/* ── Faixa de aviso ── */
.banner { display: flex; align-items: flex-start; gap: var(--s-3); padding: var(--s-3) var(--s-4); border-radius: var(--r-md);
  background: var(--surface-2); color: var(--ink); border: 1px solid var(--line); }
.banner .icon { margin-top: 2px; }
.banner-body { flex: 1; min-width: 0; display: grid; gap: 2px; }
.banner-warn { background: var(--warn-soft); border-color: transparent; }
.banner-warn .icon { color: var(--warn); }
.banner-bad { background: var(--bad-soft); border-color: transparent; }
.banner-bad .icon { color: var(--bad); }
.banner-ok { background: var(--ok-soft); border-color: transparent; }
.banner-ok .icon { color: var(--ok); }
.banner-info { background: var(--link-soft); border-color: transparent; }
.banner-info .icon { color: var(--link); }

/* ── Timeline (histórico) ── */
.timeline { list-style: none; margin: 0; padding: 0; position: relative; }
.timeline::before { content: ""; position: absolute; left: 7px; top: 8px; bottom: 8px; width: 2px; background: var(--line); }
.timeline-item { position: relative; display: grid; grid-template-columns: 16px 1fr; gap: var(--s-3); padding: var(--s-2) 0; }
.timeline-item .dot { width: 16px; height: 16px; border-radius: 50%; background: var(--surface); border: 3px solid var(--muted); margin-top: 3px; }
.timeline-item.ok .dot { border-color: var(--ok); }
.timeline-item.bad .dot { border-color: var(--bad); }
.timeline-item.warn .dot { border-color: var(--warn); }
.timeline-item.info .dot { border-color: var(--link); }
.timeline-text { margin: 0; }
.timeline time { font-size: var(--fs-sm); color: var(--muted); }
.timeline details { font-size: var(--fs-sm); color: var(--muted); }

/* ── Toast (com Desfazer) ── */
.toasts { position: fixed; right: var(--s-4); bottom: var(--s-4); display: grid; gap: var(--s-2); z-index: 300; width: min(420px, calc(100vw - 32px)); }
@media (max-width: 767px) { .toasts { right: var(--s-4); left: var(--s-4); width: auto; bottom: calc(var(--bottomnav-h) + var(--s-3) + env(safe-area-inset-bottom)); } }
.toast { display: flex; align-items: center; gap: var(--s-3); padding: var(--s-2) var(--s-2) var(--s-2) var(--s-4); background: var(--ink); color: var(--on-ink);
  border-radius: var(--r-md); box-shadow: var(--shadow-2); animation: toast-in var(--t-base) var(--ease-out); }
.toast > span { flex: 1; min-width: 0; }
.toast .btn { color: inherit; border-color: transparent; background: transparent; }
.toast .btn:hover { background: rgb(127 127 127 / .2); }
.toast-undo { text-decoration: underline; font-weight: 600; }
.toast.bad { background: var(--bad); color: var(--on-ink); }
.toast.is-leaving { opacity: 0; transform: translateY(8px); transition: opacity var(--t-fast), transform var(--t-fast); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } }

/* ── Estado vazio e esqueleto ── */
.empty { display: grid; justify-items: center; text-align: center; gap: var(--s-2); padding: var(--s-8) var(--s-4); color: var(--muted); }
.empty h2, .empty h3 { margin: 0; color: var(--ink); font-size: var(--fs-md); font-weight: 600; max-width: 44ch; }
.empty p { margin: 0; max-width: 44ch; }
.empty-compact { padding: var(--s-4) 0; justify-items: start; text-align: left; }
.skeleton { background: var(--surface-2); border-radius: var(--r-sm); min-height: 1em; animation: shimmer 1.2s ease-in-out infinite; }
.skeleton-line { height: 12px; margin: 6px 0; }
@keyframes shimmer { 50% { opacity: .5; } }
.steps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.steps li { display: flex; align-items: center; gap: var(--s-2); color: var(--muted); }
.steps li.done { color: var(--ok); }
.steps li.current { color: var(--ink); font-weight: 500; }

/* ── Abas roláveis com fade (princípio 9) ── */
.tabs { position: relative; display: flex; gap: var(--s-1); overflow-x: auto; scrollbar-width: none; border-bottom: 1px solid var(--line);
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); }
.tabs.is-end { -webkit-mask-image: none; mask-image: none; }
/* Mesmo fade para qualquer faixa que rola na horizontal (planilha, chips); o Stimulus "tabs" põe .is-end no fim. */
.fade-x { -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); }
.fade-x.is-end { -webkit-mask-image: none; mask-image: none; }
.tabs::-webkit-scrollbar { display: none; }
.tab { display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 var(--s-3); white-space: nowrap; color: var(--muted);
  text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; font-weight: 500; }
.tab:hover { color: var(--ink); }
.tab[aria-current="page"], .tab[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--ink); font-weight: 600; }

/* ── Gaveta (Turbo Frame "drawer" ou <dialog>) ── */
.drawer-scrim { position: fixed; inset: 0; background: var(--scrim); z-index: 200; }
.drawer-panel, dialog.drawer { position: fixed; z-index: 210; background: var(--surface); color: var(--ink); border: 0; padding: 0;
  box-shadow: var(--shadow-3); display: flex; flex-direction: column; overflow: hidden; }
dialog.drawer { margin: 0; max-height: none; max-width: none; }
dialog.drawer::backdrop { background: var(--scrim); }
@media (min-width: 768px) {
  .drawer-panel, dialog.drawer { top: 0; right: 0; left: auto; bottom: 0; width: min(var(--drawer-w), 100vw); height: 100vh; border-left: 1px solid var(--line); }
}
@media (max-width: 767px) {
  .drawer-panel, dialog.drawer { inset: 0; width: 100vw; height: 100dvh; }
}
.drawer-host { display: none; }
.drawer-host.is-open { display: block; }
.drawer-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); padding: var(--s-4) var(--s-5); border-bottom: 1px solid var(--line); }
.drawer-head h2 { font-size: var(--fs-lg); font-weight: 600; }
.drawer-body { flex: 1; overflow-y: auto; padding: var(--s-5); display: grid; gap: var(--s-5); align-content: start; }
/* Abas dentro da gaveta: a grade com rolagem encolhia a faixa de abas (overflow-x) a zero. */
.drawer-body > .tabs { min-height: calc(var(--tap) + 1px); flex: none; overflow-y: hidden; }
/* Cabeçalho da gaveta: pill e fechar na mesma linha (o fechar não cai para baixo no celular). */
.drawer-head > .row { flex-wrap: nowrap; flex: none; }
.drawer-head > .stack-sm { min-width: 0; }
.drawer-foot { padding: var(--s-4) var(--s-5); border-top: 1px solid var(--line); display: grid; gap: var(--s-3); }

/* ── Modal de confirmação (só destrutivo/caro) ── */
dialog.modal { width: min(440px, calc(100vw - 32px)); border: 0; border-radius: var(--r-lg); padding: var(--s-6); background: var(--surface);
  color: var(--ink); box-shadow: var(--shadow-3); }
dialog.modal::backdrop { background: var(--scrim); }
.modal-body { display: grid; gap: var(--s-4); }
.modal-body h2 { font-size: var(--fs-lg); }
.modal-actions { display: flex; justify-content: flex-end; gap: var(--s-2); flex-wrap: wrap; }

/* ── Chips de filtro ── */
.chips { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.chip { display: inline-flex; align-items: center; gap: var(--s-1); min-height: 40px; padding: 0 var(--s-3); border: 1px solid var(--line);
  border-radius: var(--r-pill); background: var(--surface); font-size: var(--fs-sm); cursor: pointer; color: var(--ink); text-decoration: none; }
.chip[aria-pressed="true"], input:checked + .chip { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }

/* ── Resumo em pares (rótulo · valor) ── */
.facts { display: grid; grid-template-columns: max-content 1fr; gap: var(--s-2) var(--s-4); margin: 0; }
.facts dt { color: var(--muted); font-size: var(--fs-sm); }
.facts dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
dialog.drawer:not([open]), dialog.modal:not([open]) { display: none; }

/* Linha inteira clicável (alvo ≥ 44 px): o link do título se estica sobre a linha/cartão; botões da linha ficam por cima. */
.has-stretched { position: relative; }
.has-stretched .stretched::after { content: ""; position: absolute; inset: 0; z-index: 0; border-radius: inherit; }
.has-stretched :is(a, button, summary, input, select, label, form):not(.stretched) { position: relative; z-index: 1; }
.has-stretched:has(.stretched:hover) { background: var(--surface-2); }
.has-stretched .stretched:focus-visible { box-shadow: none; }
.has-stretched:has(.stretched:focus-visible) { box-shadow: var(--focus); border-radius: var(--r-md); }

/* ── Sobre e licenças: inventário recolhido com busca simples ── */
.components-list { display: grid; gap: var(--s-3); }
.components-list > summary { list-style: none; justify-self: start; }
.components-list > summary::-webkit-details-marker { display: none; }
.components-list[open] > summary { margin-bottom: var(--s-1); }
.components-search { position: relative; display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.components-search .icon { position: absolute; left: var(--s-3); width: 18px; height: 18px; color: var(--muted); pointer-events: none; }
.components-search input { flex: 1 1 220px; min-height: var(--tap); padding: 0 var(--s-3) 0 calc(var(--s-3) * 2 + 18px); border: 1px solid var(--line-strong, var(--line));
  border-radius: var(--r-md); background: var(--surface); color: var(--ink); font: inherit; font-size: 16px; }
.components-search input:focus-visible { outline: none; box-shadow: var(--focus); }
