/* Central LudoSoftware — camada de UI/UX (P0): paleta de comandos (Ctrl+K),
   cheat sheet de atalhos, abas de visões salvas, chips de filtro ativo,
   cartões de KPI com minigráfico e esqueletos de carregamento.

   Arquivo separado de propósito: static/css/app.css é compartilhado por todos
   os módulos e não deve crescer com estilo de um recurso só. Tudo aqui usa as
   variáveis do Tabler (--tblr-*), então o tema escuro funciona sem regra
   duplicada. */

/* --- Paleta de comandos --------------------------------------------------- */

.command-palette .modal-dialog {
    max-width: 640px;
    margin-top: 8vh;
}

.command-palette .modal-content {
    overflow: hidden;
}

.command-palette-input {
    border: 0;
    border-radius: 0;
    box-shadow: none !important;
    font-size: 1rem;
    padding: .875rem 1rem;
}

.command-palette-input:focus {
    border: 0;
    outline: none;
}

.command-palette-header {
    border-bottom: 1px solid var(--tblr-border-color);
}

.command-palette-results {
    max-height: 56vh;
    overflow-y: auto;
    padding: .25rem 0 .5rem;
}

.command-palette-group-title {
    color: var(--tblr-secondary);
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .04em;
    padding: .625rem 1rem .25rem;
    text-transform: uppercase;
}

.command-palette-item {
    align-items: center;
    background: none;
    border: 0;
    color: inherit;
    display: flex;
    gap: .75rem;
    padding: .5rem 1rem;
    text-align: left;
    text-decoration: none;
    width: 100%;
}

.command-palette-item:hover,
.command-palette-item.is-active {
    background: var(--tblr-active-bg, rgba(var(--tblr-primary-rgb), .08));
    color: inherit;
}

.command-palette-item.is-active {
    box-shadow: inset 3px 0 0 var(--tblr-primary);
}

.command-palette-item .ti {
    color: var(--tblr-secondary);
    flex: 0 0 auto;
    font-size: 1.125rem;
}

.command-palette-item.is-active .ti {
    color: var(--tblr-primary);
}

.command-palette-item-text {
    min-width: 0;
}

.command-palette-item-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.command-palette-item-subtitle {
    color: var(--tblr-secondary);
    font-size: .75rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.command-palette-footer {
    border-top: 1px solid var(--tblr-border-color);
    color: var(--tblr-secondary);
    display: flex;
    flex-wrap: wrap;
    font-size: .75rem;
    gap: .75rem;
    padding: .5rem 1rem;
}

.command-palette-empty {
    color: var(--tblr-secondary);
    padding: 2rem 1rem;
    text-align: center;
}

kbd.kbd-hint {
    background: var(--tblr-bg-surface-secondary, rgba(var(--tblr-body-color-rgb), .06));
    border: 1px solid var(--tblr-border-color);
    border-radius: .25rem;
    color: var(--tblr-body-color);
    font-size: .6875rem;
    padding: .0625rem .3125rem;
}

/* --- Visões salvas -------------------------------------------------------- */

.saved-views {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
}

.saved-views .nav-link {
    border-radius: 999px;
    font-size: .8125rem;
    padding: .25rem .75rem;
}

.saved-views .nav-link.active {
    background: rgba(var(--tblr-primary-rgb), .1);
    color: var(--tblr-primary);
    font-weight: 600;
}

.saved-view-dirty {
    color: var(--tblr-warning);
    font-size: .625rem;
    vertical-align: super;
}

/* --- Chips de filtro ativo ------------------------------------------------ */

.filter-chips {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
}

.filter-chip {
    align-items: center;
    background: var(--tblr-bg-surface-secondary, rgba(var(--tblr-body-color-rgb), .05));
    border: 1px solid var(--tblr-border-color);
    border-radius: 999px;
    display: inline-flex;
    font-size: .8125rem;
    gap: .375rem;
    padding: .125rem .5rem .125rem .625rem;
}

.filter-chip-label {
    color: var(--tblr-secondary);
}

.filter-chip-remove {
    color: var(--tblr-secondary);
    display: inline-flex;
    line-height: 1;
    text-decoration: none;
}

.filter-chip-remove:hover {
    color: var(--tblr-danger);
}

/* --- Cartão de KPI com drill-down e minigráfico --------------------------- */

.kpi-card-link {
    color: inherit;
    display: block;
    text-decoration: none;
    transition: transform .12s ease, box-shadow .12s ease;
}

.kpi-card-link:hover {
    color: inherit;
    transform: translateY(-2px);
}

.kpi-card-link:hover .kpi-drill {
    opacity: 1;
}

.kpi-drill {
    color: var(--tblr-secondary);
    font-size: .875rem;
    opacity: 0;
    transition: opacity .12s ease;
}

/* Variantes de cor do círculo do ícone — app.css só define .icon-circle na
   cor primária, e cada tela vinha repetindo o style inline. */
.icon-circle-success { background: var(--tblr-success-lt); color: var(--tblr-success); }
.icon-circle-danger { background: var(--tblr-danger-lt); color: var(--tblr-danger); }
.icon-circle-warning { background: var(--tblr-warning-lt); color: var(--tblr-warning); }
.icon-circle-info { background: var(--tblr-info-lt); color: var(--tblr-info); }
.icon-circle-graphite { background: var(--tblr-secondary-lt); color: var(--tblr-secondary); }

.kpi-spark {
    color: var(--tblr-primary);
    display: block;
    height: 28px;
    width: 100%;
}

.kpi-accent-success .kpi-spark { color: var(--tblr-success); }
.kpi-accent-danger .kpi-spark { color: var(--tblr-danger); }
.kpi-accent-warning .kpi-spark { color: var(--tblr-warning); }
.kpi-accent-info .kpi-spark { color: var(--tblr-info); }
.kpi-accent-graphite .kpi-spark { color: var(--tblr-secondary); }

.kpi-spark-line {
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
    stroke-width: 1.75;
}

.kpi-spark-area {
    opacity: .12;
    stroke: none;
}

/* --- Esqueleto de carregamento -------------------------------------------- */

.skeleton-line {
    animation: skeleton-pulse 1.2s ease-in-out infinite;
    background: var(--tblr-border-color);
    border-radius: .25rem;
    display: block;
    height: .75rem;
}

@keyframes skeleton-pulse {
    0%, 100% { opacity: .45; }
    50% { opacity: .9; }
}

@media (prefers-reduced-motion: reduce) {
    .skeleton-line { animation: none; }
    .kpi-card-link { transition: none; }
    /* A gaveta e o painel de avisos entram deslizando: para quem pediu menos
       movimento, aparecem direto no lugar. */
    .ux-drawer,
    .ux-inbox,
    .bulk-bar { transition: none !important; }
}

/* --- Cheat sheet de atalhos ----------------------------------------------- */

.shortcut-table td {
    vertical-align: middle;
}

.shortcut-keys {
    white-space: nowrap;
}

/* ==========================================================================
   Fase P1 — lote, gaveta, avisos, densidade e colunas
   ========================================================================== */

/* --- Barra de ações em lote ----------------------------------------------- */

.bulk-bar {
    background: var(--tblr-bg-surface);
    border-top: 1px solid var(--tblr-border-color);
    bottom: 0;
    box-shadow: 0 -.5rem 1rem -.75rem rgba(0, 0, 0, .3);
    position: sticky;
    z-index: 5;
}

.bulk-bar-inner {
    align-items: center;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem .75rem;
    padding: .625rem 1rem;
}

.bulk-bar-count {
    font-size: .875rem;
}

.bulk-bar-over-limit {
    border-top-color: var(--tblr-warning);
    box-shadow: inset 0 3px 0 -1px var(--tblr-warning);
}

/* Checkbox de seleção: some da impressão e não empurra a coluna de conteúdo. */
.table .bulk-check-cell {
    padding-right: 0;
    width: 2.25rem;
}

/* Célula que acumula a caixa de seleção e o que já estava lá (o ícone de
   receita/despesa da lista de lançamentos). Sem o nowrap, a caixa empurra o
   ícone para uma segunda linha e a linha da tabela cresce sozinha. */
.table td.bulk-check-inline,
.table th.bulk-check-inline {
    text-align: left;
    white-space: nowrap;
    width: 1%;
}

@media print {
    .bulk-bar,
    .bulk-check-cell {
        display: none !important;
    }
}

/* --- Densidade das tabelas ------------------------------------------------ */
/* Alturas de linha do contrato: 40px (condensada), 48px (padrão), 56px
   (relaxada). O padding é o que muda; a fonte não encolhe, senão "condensada"
   viraria "ilegível". */

.table-density-compact > :not(caption) > * > * {
    padding-bottom: .3rem;
    padding-top: .3rem;
}

.table-density-default > :not(caption) > * > * {
    padding-bottom: .55rem;
    padding-top: .55rem;
}

.table-density-relaxed > :not(caption) > * > * {
    padding-bottom: .85rem;
    padding-top: .85rem;
}

.table-tools-menu {
    min-width: 16rem;
}

/* --- Colunas escondidas (lista de lançamentos) ---------------------------- */
/* A linha vem de finance/_transaction_row.html, que também é devolvido na
   troca de linha de "pagar"/"estornar": tirar um <td> de lá deixaria a linha
   recarregada com menos células que o cabeçalho. Por isso a coluna some por
   CSS, com os mesmos seletores que finance.css já usa para esconder essas
   duas colunas em telas estreitas. */

.tx-table.cols-hide-category .tx-cat,
.tx-table.cols-hide-category thead th:nth-child(3) {
    display: none;
}

.tx-table.cols-hide-client .tx-client,
.tx-table.cols-hide-client thead th:nth-child(4) {
    display: none;
}

/* --- Gaveta de detalhe ---------------------------------------------------- */

/* Largura: a grade do Bootstrap responde à janela, não ao contêiner — um
   col-md-8/col-md-4 vindo de um modal continua em duas colunas aqui dentro.
   42rem é o que faz esse par caber sem espremer o texto.

   A largura vai na variável, não em `width`: o Tabler usa
   `.offcanvas.offcanvas-end` (duas classes) e ganharia de `.ux-drawer` na
   especificidade — mexer na variável que aquela regra lê evita a briga (e
   evita um !important). */
.ux-drawer {
    --tblr-offcanvas-width: min(42rem, 100vw);
    --bs-offcanvas-width: min(42rem, 100vw);
}

.ux-drawer .offcanvas-body {
    padding-top: 0;
}

/* O conteúdo vem de endpoints que também servem modais: o cabeçalho de lá
   repetiria o título que a gaveta já mostra, e o "fechar" dele viraria um
   segundo botão de fechar ao lado do primeiro. */
.ux-drawer .modal-header .modal-title,
.ux-drawer .modal-header .btn-close {
    display: none;
}

.ux-drawer .modal-header,
.ux-drawer .modal-footer,
.ux-drawer .modal-body {
    padding-left: 0;
    padding-right: 0;
}

/* --- Centro de avisos ----------------------------------------------------- */

.ux-inbox {
    --tblr-offcanvas-width: min(28rem, 100vw);
    --bs-offcanvas-width: min(28rem, 100vw);
}

.ux-inbox .offcanvas-body {
    overflow-y: auto;
}

.ux-inbox-group {
    background: var(--tblr-bg-surface-secondary);
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .04em;
    padding-bottom: .25rem;
    padding-top: .25rem;
    text-transform: uppercase;
}

.ux-inbox-item {
    border-left: 3px solid transparent;
}

.ux-inbox-item-warning { border-left-color: var(--tblr-warning); }
.ux-inbox-item-danger { border-left-color: var(--tblr-danger); }
.ux-inbox-item-success { border-left-color: var(--tblr-success); }

.inbox-badge {
    border-radius: 1rem;
    font-size: .625rem;
    line-height: 1;
    padding: .2rem .35rem;
    position: absolute;
    right: .1rem;
    top: .1rem;
}

/* --- Aviso com "Desfazer" ------------------------------------------------- */

.ux-toast-undo .btn-white {
    --tblr-btn-color: var(--tblr-dark);
    white-space: nowrap;
}

/* --- Foco visível --------------------------------------------------------- */
/* Linha que abre a gaveta é operável por teclado: sem anel de foco, quem
   navega por Tab não sabe onde está. */

[data-drawer-url]:focus-visible,
[data-bulk-item]:focus-visible,
[data-bulk-toggle-all]:focus-visible {
    outline: 2px solid var(--tblr-primary);
    outline-offset: -2px;
}

[data-drawer-url] {
    cursor: pointer;
}

/* ==========================================================================
   Fase P2 — edição inline, comentários, rascunho, favoritos e Panorama
   ========================================================================== */

/* --- Edição direto na célula ---------------------------------------------- */
/* O lápis só aparece no hover/foco da linha: uma coluna de lápis permanentes
   transformaria a tabela num formulário, e a leitura é o uso mais comum. */

.inline-edit {
    display: inline-flex;
    align-items: center;
    gap: .25rem;
    max-width: 100%;
}

.inline-edit-value {
    min-width: 0;
}

.inline-edit-btn {
    border: 0;
    background: transparent;
    color: var(--tblr-secondary);
    padding: 0 .15rem;
    line-height: 1;
    border-radius: var(--tblr-border-radius);
    opacity: 0;
    transition: opacity .12s ease, color .12s ease;
}

tr:hover .inline-edit-btn,
.inline-edit:hover .inline-edit-btn,
.inline-edit-btn:focus-visible {
    opacity: 1;
}

.inline-edit-btn:hover,
.inline-edit-btn:focus-visible {
    color: var(--tblr-primary);
    outline: 2px solid var(--tblr-primary);
    outline-offset: 1px;
}

.inline-edit-editor {
    display: inline-flex;
    flex-direction: column;
    gap: .15rem;
    min-width: 8rem;
}

.inline-edit-editor.is-saving {
    opacity: .6;
    pointer-events: none;
}

.inline-edit-input {
    min-width: 7rem;
}

.inline-edit-error {
    color: var(--tblr-danger);
    font-size: .75rem;
    line-height: 1.2;
}

.inline-edit-help {
    color: var(--tblr-secondary);
    font-size: .7rem;
}

/* Confirmação silenciosa: um piscar verde na célula em vez de mais um toast
   por campo — quem edita cinco células seguidas não quer cinco avisos. */
.inline-edit.is-saved .inline-edit-value {
    animation: inline-edit-saved 1.1s ease;
    border-radius: var(--tblr-border-radius);
}

@keyframes inline-edit-saved {
    0% { background: rgba(47, 179, 68, .32); }
    100% { background: transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .inline-edit.is-saved .inline-edit-value { animation: none; }
}

@media print {
    .inline-edit-btn { display: none; }
}

/* --- Thread de comentários ------------------------------------------------ */

.ux-comments-head {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: .75rem;
}

.ux-comment-list {
    display: flex;
    flex-direction: column;
    gap: .85rem;
    max-height: 26rem;
    overflow-y: auto;
}

.ux-comment {
    display: flex;
    gap: .65rem;
    align-items: flex-start;
}

/* Resposta: recuo curto e um fio à esquerda. Uma árvore com muitos níveis
   fica ilegível em coluna estreita — a thread é rasa de propósito. */
.ux-comment-reply {
    margin-left: 2.25rem;
    padding-left: .65rem;
    border-left: 2px solid var(--tblr-border-color);
}

.ux-comment-avatar {
    flex: 0 0 auto;
    background: var(--tblr-primary);
    color: #fff;
}

.ux-comment-body {
    min-width: 0;
    flex: 1 1 auto;
}

.ux-comment-meta {
    display: flex;
    align-items: center;
    gap: .4rem;
    flex-wrap: wrap;
}

.ux-comment-actions {
    margin-left: auto;
    display: inline-flex;
    gap: .1rem;
    opacity: 0;
    transition: opacity .12s ease;
}

.ux-comment:hover .ux-comment-actions,
.ux-comment-actions:focus-within {
    opacity: 1;
}

.ux-comment-text {
    word-break: break-word;
    white-space: normal;
}

/* Marcação gerada por Comment.render_body() — o texto já chegou escapado. */
.ux-comment-text .mention {
    color: var(--tblr-primary);
    background: var(--tblr-primary-lt);
    border-radius: var(--tblr-border-radius);
    padding: 0 .2rem;
    font-weight: 500;
}

.ux-comment-mentions {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem;
    margin-top: .3rem;
}

.ux-comment-empty {
    padding: 1rem 0;
}

.ux-comment-input {
    position: relative;
}

.ux-comment-replying {
    display: flex;
    align-items: center;
    gap: .25rem;
    font-size: .8125rem;
    color: var(--tblr-secondary);
    margin-bottom: .35rem;
}

/* --- Autocompletar da menção ---------------------------------------------- */

.ux-mention-menu {
    position: absolute;
    z-index: 1060;
    left: 0;
    right: 0;
    bottom: calc(100% + .25rem);
    max-height: 12rem;
    overflow-y: auto;
    background: var(--tblr-bg-surface);
    border: 1px solid var(--tblr-border-color);
    border-radius: var(--tblr-border-radius);
    box-shadow: var(--tblr-box-shadow-dropdown);
    padding: .25rem;
}

.ux-mention-item {
    display: block;
    width: 100%;
    text-align: left;
    border: 0;
    background: transparent;
    border-radius: var(--tblr-border-radius);
    padding: .3rem .5rem;
    color: inherit;
}

.ux-mention-item.is-active,
.ux-mention-item:hover {
    background: var(--tblr-primary-lt);
    color: var(--tblr-primary);
}

/* --- Rascunho automático -------------------------------------------------- */

.ux-autosave-status {
    font-size: .75rem;
    color: var(--tblr-secondary);
    margin-top: .35rem;
    opacity: 0;
    transition: opacity .2s ease;
}

.ux-autosave-status.is-visible {
    opacity: 1;
}

.ux-autosave-offer {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .5rem;
}

/* --- Estrela de favorito -------------------------------------------------- */

.ux-fav-btn {
    border: 0;
    background: transparent;
    color: var(--tblr-secondary);
}

.ux-fav-btn:hover,
.ux-fav-btn:focus-visible {
    color: var(--tblr-warning);
}

.ux-fav-btn.is-on {
    color: var(--tblr-warning);
}

/* --- Favoritos e recentes na barra lateral -------------------------------- */

.navbar-vertical .nav-quick {
    border-bottom: 1px solid rgba(255, 255, 255, .06);
    margin-bottom: .25rem;
}

.navbar-vertical .nav-quick-list {
    list-style: none;
    margin: 0 0 .35rem;
    padding: 0;
}

.navbar-vertical .nav-quick-list .nav-link-title {
    display: block;
    max-width: 10.5rem;
}

/* --- Panorama ------------------------------------------------------------- */

.panorama-chart {
    width: 100%;
}

.panorama-memo {
    margin-top: 1rem;
    padding-top: .75rem;
    border-top: 1px dashed var(--tblr-border-color);
}

.panorama-table th,
.panorama-table td {
    vertical-align: middle;
}

.panorama-heat td.heat-empty { background: var(--tblr-bg-surface-secondary); }
.panorama-heat td.heat-low { background: rgba(66, 153, 225, .18); }
.panorama-heat td.heat-ideal { background: rgba(47, 179, 68, .20); }
.panorama-heat td.heat-high { background: rgba(245, 159, 0, .22); }
.panorama-heat td.heat-alert { background: rgba(208, 60, 68, .22); font-weight: 600; }
.panorama-heat td.heat-unknown { color: var(--tblr-secondary); }

.ux-dot {
    display: inline-block;
    width: .55rem;
    height: .55rem;
    border-radius: 50%;
    margin-right: .25rem;
    vertical-align: baseline;
}

.apex-tt {
    padding: .4rem .6rem;
    font-size: .8125rem;
}

