/* =========================================================================
   components.css
   Regra de elevação do projeto: borda antes de sombra. Card usa filete de 1px
   e nenhuma sombra; sombra só em camada que flutua de verdade.
   Nenhum hex aqui: só var() de tokens.css.
   ========================================================================= */

/* =========================================================================
   Botão
   ========================================================================= */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  height: 36px;
  padding: 0 var(--sp-4);
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  font-family: var(--ff-body);
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              opacity var(--dur-fast) var(--ease);
}

/* Botão nunca sublinha: `a:hover` no base.css valia para o `a.btn` também, e
   o botão primário aparecia com o rótulo riscado embaixo. */
.btn:hover,
.btn:focus,
.btn:active { text-decoration: none; }

.btn:disabled,
.btn[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn--sm { height: 30px; padding: 0 var(--sp-3); font-size: var(--fs-sm); }

.btn .material-symbols-outlined { font-size: 18px; }

/* Primário: fundo da marca. O texto vem de --brand-ink, que a spec 04 escolhe
   por contraste. Em marca clara (amarelo) o brand-ink e preto. */
.btn--primary {
  background: var(--brand);
  color: var(--brand-ink);
  border-color: var(--brand);
}

.btn--primary:hover:not(:disabled) {
  background: color-mix(in srgb, var(--brand) 88%, var(--n-ink));
  border-color: color-mix(in srgb, var(--brand) 88%, var(--n-ink));
}

/* Secundário: superfície com filete. */
.btn--secondary {
  background: var(--n-surface);
  color: var(--n-ink);
  border-color: var(--n-line-strong);
}

.btn--secondary:hover:not(:disabled) { background: var(--n-sunken); }

/* Botão quadrado só de ícone: ação de linha de tabela e seta de navegação,
   onde rótulo escrito ocuparia a largura da coluna. Sempre com aria-label. */
.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--n-line);
  border-radius: var(--r-sm);
  background: var(--n-surface);
  color: var(--n-ink-2);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease);
}

.btn-icon:hover {
  background: var(--n-sunken);
  border-color: var(--n-line-strong);
  color: var(--n-ink);
}

/* Ponta da fila: fica no lugar para a dupla de setas não dançar. */
.btn-icon--off {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

/* Dentro de célula de tabela: sem moldura, e só ganha contorno no hover, para
   não competir com o número que é o conteúdo da linha. */
.btn-icon--sm {
  width: 24px;
  height: 24px;
  border-color: transparent;
  background: transparent;
}

.measure-cell {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

.lot-nav {
  display: inline-flex;
  gap: var(--sp-1);
  margin-right: var(--sp-2);
}

.btn--ghost {
  background: transparent;
  color: var(--n-ink-2);
}

.btn--ghost:hover:not(:disabled) {
  background: var(--n-sunken);
  color: var(--n-ink);
}

/* Destrutivo usa a cor de lote vendido: e a única vermelha do sistema. */
.btn--danger {
  background: var(--st-sold);
  color: var(--n-inverse);
  border-color: var(--st-sold);
}

.btn--danger:hover:not(:disabled) {
  background: color-mix(in srgb, var(--st-sold) 85%, var(--n-ink));
}

/* Acento: para ação que exige texto branco quando a marca e clara. */
.btn--accent {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

.btn--accent:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent) 85%, var(--n-inverse));
}

.btn--block { width: 100%; }

.btn__spinner {
  width: 14px;
  height: 14px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--r-full);
  animation: spin 700ms linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* =========================================================================
   Campo de formulário
   ========================================================================= */
.field { display: flex; flex-direction: column; gap: var(--sp-1); }

.field__label {
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--n-ink-2);
}

.field__required { color: var(--st-sold); margin-left: 2px; }

.field__topo { display: flex; align-items: center; gap: var(--sp-1); }

/* O rotulo ganha margem inferior mais adiante nesta folha, feita para quando
   ele e o unico da linha. Dentro do topo ele divide a linha com o `?`, e a
   margem desalinhava os dois. */
.field__topo .field__label { margin-bottom: 0; }

.field__control { position: relative; display: flex; align-items: center; }

/* O input divide a linha com a marca da unidade; sem isto o `width: 100%`
   dele empurra "%" e "R$" para fora do campo. */
.field__control > .input,
.field__control > .select,
.field__control > .textarea { flex: 1 1 auto; min-width: 0; }

/* -------------------------------------------------------------------------
   Unidade de medida colada ao campo
   "Entrada minima: 10,00" nao diz se sao dez por cento ou dez mil reais. A
   marca fica ao lado, e nao por dentro: dentro, ela tapa o numero assim que
   ele cresce.
   ------------------------------------------------------------------------- */
.field__unit {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  align-self: stretch;
  min-height: 36px;
  padding: 0 var(--sp-3);
  background: var(--n-sunken);
  border: 1px solid var(--n-line-strong);
  color: var(--n-ink-2);
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.field__unit {
  border-left: 0;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}

.field__unit--pre {
  border-left: 1px solid var(--n-line-strong);
  border-right: 0;
  border-radius: var(--r-sm) 0 0 var(--r-sm);
}

.field__control:has(.field__unit:not(.field__unit--pre)) .input {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}

.field__control:has(.field__unit--pre) .input {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
}

.field:focus-within .field__unit { border-color: var(--brand); }

/* -------------------------------------------------------------------------
   Explicacao do campo: o `?` e a bolha
   Quem vende decide com o cliente na frente. A explicacao tem de estar a um
   gesto de distancia -- nao num manual, nao em outra tela.
   ------------------------------------------------------------------------- */
.hint {
  position: relative;
  display: inline-flex;
  align-items: center;
  cursor: help;
  border-radius: var(--r-full);
  color: var(--n-ink-3);
  transition: color var(--dur-fast) var(--ease);
}

.hint__icone { font-size: 15px; font-variation-settings: "opsz" 20, "wght" 400; }

.hint:hover,
.hint:focus-visible { color: var(--brand); outline: none; }

.hint:focus-visible { box-shadow: 0 0 0 2px var(--brand-100); }

.hint__bolha {
  position: absolute;
  left: -6px;
  bottom: calc(100% + 8px);
  z-index: var(--z-drawer);
  width: max-content;
  max-width: min(280px, 60vw);
  padding: var(--sp-2) var(--sp-3);
  background: var(--n-ink);
  color: var(--n-inverse);
  border-radius: var(--r-sm);
  box-shadow: var(--sh-2);
  font-size: var(--fs-sm);
  font-weight: 400;
  line-height: var(--lh-normal);
  text-align: left;
  white-space: normal;
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
  transition:
    opacity var(--dur-fast) var(--ease),
    transform var(--dur-fast) var(--ease),
    visibility var(--dur-fast);
  pointer-events: none;
}

/* A setinha aponta para o `?`, para a bolha nao ficar boiando. */
.hint__bolha::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 10px;
  border: 5px solid transparent;
  border-top-color: var(--n-ink);
}

.hint:hover .hint__bolha,
.hint:focus-visible .hint__bolha {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}

/* Na primeira linha da tela nao ha espaco acima: a bolha desce. */
.field--radio .hint__bolha,
.hint--abaixo .hint__bolha {
  bottom: auto;
  top: calc(100% + 8px);
}

.field--radio .hint__bolha::after,
.hint--abaixo .hint__bolha::after {
  top: auto;
  bottom: 100%;
  border-top-color: transparent;
  border-bottom-color: var(--n-ink);
}

/* Na chave liga-desliga e na caixa de marcar o `?` vem no meio da frase. */
.switch__text .hint,
.check__text .hint { margin-left: var(--sp-1); vertical-align: middle; }


.field__icon {
  position: absolute;
  left: var(--sp-3);
  color: var(--n-ink-3);
  font-size: 18px;
  pointer-events: none;
}

.field__control:has(.field__icon) .input,
.field__control:has(.field__icon) .select,
.field__control:has(.field__icon) .textarea { padding-left: var(--sp-7); }

.input,
.select,
.textarea {
  width: 100%;
  min-height: 36px;
  padding: var(--sp-2) var(--sp-3);
  background: var(--n-surface);
  color: var(--n-ink);
  border: 1px solid var(--n-line-strong);
  border-radius: var(--r-sm);
  font-size: var(--fs-body);
  transition: border-color var(--dur-fast) var(--ease);
}

.input::placeholder,
.textarea::placeholder { color: var(--n-ink-3); }

.input:hover,
.select:hover,
.textarea:hover { border-color: var(--n-ink-3); }

.input:disabled,
.select:disabled,
.textarea:disabled {
  background: var(--n-sunken);
  color: var(--n-ink-3);
  cursor: not-allowed;
}

.textarea { min-height: 88px; resize: vertical; line-height: var(--lh-normal); }

/* Dado técnico digitado em mono: area, coordenada, matrícula. */
.input--data { font-family: var(--ff-data); font-variant-numeric: tabular-nums; }

.input[aria-invalid="true"],
.select[aria-invalid="true"],
.textarea[aria-invalid="true"] { border-color: var(--st-sold); }

.field__help { font-size: var(--fs-sm); color: var(--n-ink-3); }

/* Caixa de marcar: a marca antes do texto, e o rótulo envolvendo as duas para
   o clique valer na frase inteira. `accent-color` faz a marca sair na cor da
   imobiliária sem desenhar caixa falsa por cima do controle nativo. */
.check {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--sp-2);
  cursor: pointer;
}

.check__box {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  accent-color: var(--brand);
  cursor: pointer;
}

.check__text {
  font-size: var(--fs-body);
  color: var(--n-ink);
  line-height: var(--lh-normal);
}

.check:hover .check__text { color: var(--n-ink); }

.check__box:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* Escolha entre poucas opcoes. Cartao clicavel em vez de radio solto: o alvo
   do toque passa a ser a opcao inteira, e a escolha feita fica visivel de
   longe -- num formulario que decide para quem vai a documentacao de alguem,
   ler errado qual opcao esta marcada e caro. */
.radio-group {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--sp-2);
}

/* `fieldset` traz borda e recuo proprios do navegador. */
.field--radio {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.radio {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3);
  border: 1px solid var(--n-line);
  border-radius: var(--r-md);
  background: var(--n-surface);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.radio:hover { border-color: var(--n-line-strong); }

.radio:has(.radio__input:checked),
.radio:has(> input[type="radio"]:checked) {
  border-color: var(--brand);
  background: var(--brand-soft);
}

/* O foco mora no controle nativo, mas quem aparece em tela e o cartao. */
.radio:has(.radio__input:focus-visible),
.radio:has(> input[type="radio"]:focus-visible) {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.radio__input,
.radio > input[type="radio"] {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  accent-color: var(--brand);
  cursor: pointer;
}

.radio__text {
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
  color: var(--n-ink);
}

/* O apoio se alinha ao texto, não a marca. */
.field__help--check { padding-left: calc(18px + var(--sp-2)); }

.field__error {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-sm);
  color: var(--st-sold-ink);
}

.field__error .material-symbols-outlined { font-size: 16px; }

/* =========================================================================
   Card
   ========================================================================= */
.card {
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-md);
}

.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--n-line);
}

.card__title {
  font-family: var(--ff-display);
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: var(--lh-tight);
}

.card__subtitle { font-size: var(--fs-sm); color: var(--n-ink-3); }

.card__body { padding: var(--sp-5); }

.card__footer {
  padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--n-line);
}

.card--flush .card__body { padding: 0; }

/* =========================================================================
   Badge de situação do lote
   Cor nunca sozinha: sempre com icone e texto (daltonismo).
   ========================================================================= */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  height: 22px;
  padding: 0 var(--sp-2);
  border-radius: var(--r-xs);
  font-size: var(--fs-sm);
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
}

.badge .material-symbols-outlined { font-size: 14px; }

.badge--available { background: var(--st-available-soft); color: var(--st-available-ink); }
.badge--reserved  { background: var(--st-reserved-soft);  color: var(--st-reserved-ink); }
.badge--proposal  { background: var(--st-proposal-soft);  color: var(--st-proposal-ink); }
.badge--sold      { background: var(--st-sold-soft);      color: var(--st-sold-ink); }
.badge--settled   { background: var(--st-settled-soft);   color: var(--st-settled-ink); }
.badge--blocked   { background: var(--st-blocked-soft);   color: var(--st-blocked-ink); }

.badge--neutral { background: var(--n-sunken); color: var(--n-ink-2); }
.badge--brand   { background: var(--brand-soft); color: var(--brand-link); }

/* -------------------------------------------------------------------------
   Par solida + tinta de cada situação.
   Existe porque a cor solida sozinha não basta como indicador: o amarelo do
   reservado tem 2.47:1 sobre a superfície branca e some para quem enxerga
   pouco. Todo indicador solido (ponto, amostra da legenda) ganha contorno na
   tinta escura, que passa folgado no piso de 3:1.
   ------------------------------------------------------------------------- */
.status-color--available { --status-solid: var(--st-available); --status-ink: var(--st-available-ink); }
.status-color--reserved  { --status-solid: var(--st-reserved);  --status-ink: var(--st-reserved-ink); }
.status-color--proposal  { --status-solid: var(--st-proposal);  --status-ink: var(--st-proposal-ink); }
.status-color--sold      { --status-solid: var(--st-sold);      --status-ink: var(--st-sold-ink); }
.status-color--settled   { --status-solid: var(--st-settled);   --status-ink: var(--st-settled-ink); }
.status-color--blocked   { --status-solid: var(--st-blocked);   --status-ink: var(--st-blocked-ink); }

/* Ponto de cor solida, para legenda do mapa. */
.badge__dot {
  width: 9px;
  height: 9px;
  border-radius: var(--r-full);
  background: var(--status-solid, currentColor);
  box-shadow: inset 0 0 0 1px var(--status-ink, transparent);
  flex: 0 0 auto;
}

/* =========================================================================
   Cota - a medida do desenho técnico, não um card genérico
   ========================================================================= */
.dimension {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  min-width: 96px;
}

.dimension__label {
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  color: var(--n-ink-3);
}

.dimension__line {
  position: relative;
  height: 12px;
  display: flex;
  align-items: center;
}

/* O traco de cota, com terminação em seta nas duas pontas. */
.dimension__line::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--n-line-strong);
}

.dimension__cap {
  position: absolute;
  top: 0;
  width: 1px;
  height: 12px;
  background: var(--n-line-strong);
}

.dimension__cap--start { left: 0; }
.dimension__cap--end   { right: 0; }

.dimension__cap::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 0;
  height: 0;
  border-block: 3px solid transparent;
  transform: translateY(-50%);
}

.dimension__cap--start::after {
  left: 0;
  border-right: 5px solid var(--n-line-strong);
}

.dimension__cap--end::after {
  right: 0;
  border-left: 5px solid var(--n-line-strong);
}

.dimension__value {
  font-family: var(--ff-data);
  font-size: var(--fs-data);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--n-ink);
}

.dimension--vertical { min-width: 0; }

/* =========================================================================
   Tabela
   ========================================================================= */
.table-wrap {
  overflow-x: auto;
  border: 1px solid var(--n-line);
  border-radius: var(--r-md);
  background: var(--n-surface);
}

.table { font-size: var(--fs-body); }

.table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: var(--sp-3) var(--sp-4);
  background: var(--n-surface);
  border-bottom: 1px solid var(--n-line);
  text-align: left;
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  color: var(--n-ink-3);
  white-space: nowrap;
}

.table tbody td {
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--n-line);
  vertical-align: middle;
}

.table tbody tr:last-child td { border-bottom: 0; }

.table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--n-sunken) 35%, transparent); }

.table tbody tr:hover { background: var(--n-sunken); }

.table .cell--data {
  font-family: var(--ff-data);
  font-size: var(--fs-data);
  font-variant-numeric: tabular-nums;
}

.table .cell--right { text-align: right; }

/* Número e unidade na mesma linha. Em coluna estreita o "12,61 m" quebrava e a
   unidade caía sozinha na linha de baixo. */
.table .cell--nowrap { white-space: nowrap; }

.table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  color: inherit;
  font: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
}

.table__sort .material-symbols-outlined { font-size: 14px; }

.table__sort[aria-sort="ascending"],
.table__sort[aria-sort="descending"] { color: var(--n-ink); }

/* =========================================================================
   Estado vazio - nunca só "Nenhum registro"
   ========================================================================= */
.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-3);
  padding: var(--sp-7) var(--sp-5);
}

.empty__icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--n-line);
  border-radius: var(--r-md);
  color: var(--n-ink-3);
}

.empty__icon .material-symbols-outlined { font-size: 24px; }

.empty__title { font-family: var(--ff-display); font-size: var(--fs-h3); font-weight: 600; }

.empty__text { max-width: 46ch; color: var(--n-ink-2); }

.empty__actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; justify-content: center; }

/* =========================================================================
   Modal - substitui confirm() e alert(), que são proibidos
   ========================================================================= */
/* <dialog> nativo: foco preso e ESC saem de graca e sem bug de acessibilidade
   caseiro. O ::backdrop e estilizado por completo. */
.modal {
  width: min(560px, calc(100vw - var(--sp-6)));
  max-height: 85vh;
  padding: 0;
  border: 0;
  border-radius: var(--r-md);
  background: var(--n-surface);
  color: var(--n-ink);
  box-shadow: var(--sh-3);
  overflow: hidden;
}

.modal::backdrop { background: color-mix(in srgb, var(--n-ink) 45%, transparent); }

.modal--sm { width: min(420px, calc(100vw - var(--sp-6))); }
.modal--md { width: min(560px, calc(100vw - var(--sp-6))); }
.modal--lg { width: min(760px, calc(100vw - var(--sp-6))); }
.modal--xl { width: min(1000px, calc(100vw - var(--sp-6))); }

.modal__panel {
  display: flex;
  flex-direction: column;
  max-height: 85vh;
  min-height: 0;
}

/* Modal cujo conteudo mora dentro de um `<form>`: sem isto o formulario nao
   participa da coluna, o corpo cresce sem limite e o rodape -- com os botoes de
   confirmar e cancelar -- sai para fora da tela, sem rolagem que o alcance.
   Aconteceu na remarcacao de vencimento, onde o impacto alonga a janela. */
.modal__panel > form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.modal__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-5) var(--sp-5) var(--sp-3);
}

.modal__title {
  font-family: var(--ff-display);
  font-size: var(--fs-h2);
  font-weight: 600;
  line-height: var(--lh-tight);
}

/* `min-height: 0` e o que faz a rolagem acontecer dentro de um flex: sem ele o
   item nunca encolhe abaixo do proprio conteudo, e o `overflow-y` nao tem o que
   cortar. */
.modal__body {
  padding: 0 var(--sp-5) var(--sp-5);
  overflow-y: auto;
  min-height: 0;
}

.modal__footer {
  display: flex;
  flex: none;
  justify-content: flex-end;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-5);
  background: var(--n-surface);
  border-top: 1px solid var(--n-line);
}

.modal__close {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: var(--r-sm);
  color: var(--n-ink-3);
  flex: 0 0 auto;
}

.modal__close:hover { background: var(--n-sunken); color: var(--n-ink); }

/* =========================================================================
   Faixa de identidade
   Abre a tela de um registro: o que é, como se chama, como está e o que dá
   para fazer com ele. Nasceu no painel da plataforma; aqui esta a versão em
   tokens do sistema, que serve a qualquer tela de detalhe do tenant. O painel
   redefine a dele depois, em platform.css.
   ========================================================================= */
.entity-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-5);
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-5) var(--sp-6);
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-lg);
}

.entity-bar__identity { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

.entity-bar__eyebrow {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--n-ink-3);
}

.entity-bar__name {
  font-family: var(--ff-display);
  font-size: var(--fs-h1);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: var(--lh-tight);
  color: var(--n-ink);
}

.entity-bar__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 2px var(--sp-3);
  font-family: var(--ff-data);
  font-size: var(--fs-sm);
  color: var(--n-ink-3);
}

.entity-bar__meta span + span::before { content: "·"; margin-right: var(--sp-3); }

.entity-bar__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  align-items: center;
}

.entity-bar__actions {
  display: flex;
  gap: var(--sp-2);
  align-items: center;
  flex-wrap: wrap;
}

.entity-bar__actions .btn { white-space: nowrap; }

/* Situação em uma palavra, com o ponto na frente. */
.state {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--n-ink-2);
}

.state::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: var(--r-full);
  background: var(--n-line-strong);
}

/* Lista de dados: rótulo à esquerda, valor à direita, um filete entre linhas.
   Serve a ficha de gleba, de lote e de cliente. */
.data-list { display: flex; flex-direction: column; }

.data-list > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-4);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--n-line);
}

.data-list > div:last-child { border-bottom: 0; }

.data-list dt { font-size: var(--fs-sm); color: var(--n-ink-3); }
/* Valor longo sem espaço (e-mail, endereço, protocolo) quebra dentro da
   própria célula: nenhuma informação pode passar por cima da vizinha. */
.data-list dd { min-width: 0; color: var(--n-ink); text-align: right; overflow-wrap: anywhere; }

/* Aviso em bloco: informação, cuidado ou impedimento, com o ícone na frente.
   Morava em customers.css e por isso aparecia sem estilo em qualquer outra
   tela -- o ícone caía numa linha e o texto na seguinte. */
.callout {
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border-radius: var(--r-md);
  border: 1px solid var(--n-line);
  background: var(--n-sunken);
  font-size: var(--fs-sm);
}

/* Aviso dentro de painel estreito -- o do lote no mapa, por exemplo, onde o
   recuo cheio come metade da largura útil. */
.callout--tight {
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  align-items: flex-start;
  font-size: var(--fs-xs);
  line-height: 1.4;
}

.callout--tight .material-symbols-outlined { font-size: 16px; }

.callout p + p { margin-top: var(--sp-1); }

.callout--info {
  background: var(--st-proposal-soft);
  color: var(--st-proposal-ink);
  border-color: transparent;
}

.callout--warning {
  background: var(--st-reserved-soft);
  color: var(--st-reserved-ink);
  border-color: transparent;
}

.callout--danger {
  background: var(--st-sold-soft);
  color: var(--st-sold-ink);
  border-color: transparent;
}

.callout .material-symbols-outlined { flex: 0 0 auto; font-size: 20px; }

/* =========================================================================
   Bloco de formulário (slab)
   Cartão com cabeçalho, corpo e rodapé de ações. Nasceu no painel da
   plataforma; esta é a versão em tokens do sistema, para as telas do tenant.
   O painel redefine a dele depois, em platform.css.
   ========================================================================= */
.slab {
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-lg);
}

.slab__head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--n-line);
}

.slab__title {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--ff-display);
  font-size: var(--fs-h3);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--n-ink);
}

.slab__title .material-symbols-outlined { font-size: 20px; color: var(--n-ink-3); }

.slab__meta {
  margin-left: auto;
  font-family: var(--ff-data);
  font-size: var(--fs-sm);
  color: var(--n-ink-3);
}

.slab__body { padding: var(--sp-5); }
.slab__body--flush { padding: 0; }

.slab__foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
  padding: var(--sp-4) var(--sp-5);
  border-top: 1px solid var(--n-line);
  background: var(--n-sunken);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
}

/* Tela de formulário: coluna única, largura de leitura. */
.form-page {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
  max-width: 880px;
}

.form-page__actions { display: flex; justify-content: flex-end; gap: var(--sp-2); }

/* Retrato grande: cabeçalho de perfil. */
.avatar--lg { width: 56px; height: 56px; font-size: var(--fs-h3); }

/* =========================================================================
   Régua de contagem (tally)
   Número por situação, e cada número é um filtro. Serve a qualquer lista com
   estados: propostas, vendas, contratos.
   ========================================================================= */
.tally {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--sp-3);
}

.tally__item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-lg);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.tally__item:hover { border-color: var(--brand); box-shadow: var(--sh-1); }

.tally__item.is-active {
  border-color: var(--brand);
  box-shadow: inset 0 0 0 1px var(--brand);
}

.tally__icon {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  border-radius: var(--r-md);
  background: var(--n-sunken);
  color: var(--n-ink-3);
}

.tally__icon .material-symbols-outlined { font-size: 20px; }
.tally__item.is-active .tally__icon { background: var(--brand-soft); color: var(--brand-link); }

.tally__text { display: flex; flex-direction: column; min-width: 0; }

.tally__count {
  font-family: var(--ff-data);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-h3);
  font-weight: 600;
  line-height: 1.1;
  color: var(--n-ink);
}

.tally__label { font-size: var(--fs-sm); color: var(--n-ink-3); }

/* Célula de tabela com duas linhas: o que se procura em cima, o contexto
   embaixo. Evita uma coluna só para o dado de apoio. */
.cell-lead { display: block; font-weight: 500; color: var(--n-ink); text-decoration: none; }
.cell-lead:hover { color: var(--brand-link); }

.cell-sub {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 2px;
  font-size: var(--fs-sm);
  color: var(--n-ink-3);
}

.cell-sub--right { justify-content: flex-end; }
.cell-sub .material-symbols-outlined { font-size: 14px; }

/* Tabela longa dentro de cartão: rola sozinha em vez de esticar a página. */
.table-wrap--tall { max-height: 420px; overflow-y: auto; }

/* Andamento em três passos: onde o registro está no caminho dele. */
.steps { display: flex; flex-direction: column; list-style: none; }

.steps__item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 0 0 var(--sp-4) var(--sp-5);
  border-left: 2px solid var(--n-line);
}

.steps__item:last-child { padding-bottom: 0; border-left-color: transparent; }

.steps__dot {
  position: absolute;
  left: -6px;
  top: 3px;
  width: 10px;
  height: 10px;
  border-radius: var(--r-full);
  background: var(--n-surface);
  border: 2px solid var(--n-line-strong);
}

.steps__item.is-done .steps__dot { background: var(--brand); border-color: var(--brand); }
.steps__item.is-done { border-left-color: var(--brand); }
.steps__item.is-done:last-child { border-left-color: transparent; }

.steps__label { font-weight: 500; color: var(--n-ink); }
.steps__when { font-size: var(--fs-sm); color: var(--n-ink-3); }

/* Barra de proporção. Morava em developments.css e por isso sumia em
   qualquer outra tela. A cor e a da marca: proporção e resultado, não erro. */
.progress {
  height: 6px;
  border-radius: var(--r-full);
  background: var(--n-sunken);
  overflow: hidden;
}

.progress__bar {
  display: block;
  height: 100%;
  background: var(--brand);
  border-radius: var(--r-full);
}

/* =========================================================================
   Painel com filtros
   Barra de recorte de um painel: vários campos em grade e as ações embaixo.
   Diferente da `filter-bar`, que e de uma linha só.
   ========================================================================= */
/* Barra de recorte de um painel. Fluxo, e não grade: com `auto-fit` os campos
   esticavam para preencher a linha e sobrava um vão enorme entre um e outro.
   Aqui cada campo pede a largura de que precisa e a linha quebra quando acaba
   o espaço -- como uma barra de ferramentas, que e o que ela é. */
.panel-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-3) var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-lg);
}

.panel-filters__grid {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--sp-3) var(--sp-4);
  flex: 1 1 auto;
}

/* Larguras pelo tamanho do dado, não pela sobra da linha. */
.panel-filters .field { flex: 0 1 200px; }
/* Loteamento e situação carregam rótulo comprido no vazio ("Todos os
   loteamentos"), e select cortado no meio da palavra não se lê. */
.panel-filters .field--scope { flex: 0 1 230px; }
.panel-filters .field--wide { flex: 1 1 260px; }
.panel-filters .field--month { flex: 0 1 180px; }
/* O seletor de pessoa carrega ícone, texto e o botão de limpar na mesma linha:
   "Todos os corretores" não cabe em 190px. */
.panel-filters .picker { flex: 0 1 260px; }
.panel-filters .field--shortcuts { flex: 0 0 auto; }
.panel-filters .field--range { flex: 0 0 auto; }

/* As ações fecham a barra, na mesma linha quando cabem. */
.panel-filters__actions {
  display: flex;
  align-items: flex-end;
  gap: var(--sp-2);
  flex-wrap: wrap;
  margin-left: auto;
}

/* Rótulo com ícone: o ícone diz o tipo do filtro antes de a pessoa ler. */
.field__label {
  display: flex;
  align-items: center;
  gap: 5px;
}

.field__label .material-symbols-outlined { font-size: 15px; color: var(--n-ink-3); }

/* Alternador de atalhos: dois botões colados, o ativo em destaque. */
.switcher {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: var(--n-sunken);
  border: 1px solid var(--n-line);
  border-radius: var(--r-md);
}

.switcher__item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0 var(--sp-3);
  height: 32px;
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--n-ink-2);
  text-decoration: none;
  white-space: nowrap;
}

.switcher__item:hover { background: var(--n-surface); color: var(--n-ink); }

.switcher__item.is-active {
  background: var(--n-surface);
  color: var(--n-ink);
  box-shadow: var(--sh-1);
}

.switcher__item .material-symbols-outlined { font-size: 16px; }

/* Intervalo de datas: um controle só, com a seta entre as duas pontas. */
.range {
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding: 0 var(--sp-2);
  background: var(--n-surface);
  border: 1px solid var(--n-line-strong);
  border-radius: var(--r-md);
  transition: border-color var(--dur-fast) var(--ease);
}

.range:focus-within { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }

.range__input {
  width: 10.5ch;
  border: 0;
  background: transparent;
  font-family: var(--ff-data);
  font-size: var(--fs-sm);
  color: var(--n-ink);
  text-align: center;
}

.range__input:focus { outline: none; }
.range__input::placeholder { color: var(--n-ink-3); }

.range__sep {
  display: grid;
  place-items: center;
  color: var(--n-ink-3);
}

.range__sep .material-symbols-outlined { font-size: 16px; }

/* Cartão de recorte: um por loteamento, produto ou canal. */
.split-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--sp-4);
}

.split-card {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-left: 3px solid var(--brand);
  border-radius: var(--r-lg);
  color: inherit;
  text-decoration: none;
  transition: box-shadow var(--dur-fast) var(--ease);
}

.split-card:hover { box-shadow: var(--sh-2); }

.split-card__head { display: flex; align-items: baseline; gap: var(--sp-3); }

.split-card__name {
  font-family: var(--ff-display);
  font-weight: 600;
  color: var(--n-ink);
  min-width: 0;
}

.split-card__tag {
  margin-left: auto;
  padding: 2px var(--sp-2);
  border-radius: var(--r-full);
  background: var(--n-sunken);
  font-size: var(--fs-xs);
  color: var(--n-ink-3);
  white-space: nowrap;
}

.split-card__grid { display: flex; gap: var(--sp-5); }
.split-card__item { display: flex; flex-direction: column; gap: 2px; }
.split-card__label { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: var(--tracking-label); color: var(--n-ink-3); }

.split-card__value {
  font-family: var(--ff-data);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-h3);
  font-weight: 600;
  color: var(--n-ink);
}

.split-card__value--money { color: var(--st-settled-ink, var(--n-ink)); }

/* Posição no ranking. Os três primeiros ganham cor; o resto e neutro. */
.rank {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--r-full);
  background: var(--n-sunken);
  color: var(--n-ink-2);
  font-family: var(--ff-data);
  font-size: var(--fs-sm);
  font-weight: 600;
}

.rank--1 { background: var(--brand); color: var(--brand-ink); }
.rank--2 { background: var(--n-line-strong); color: var(--n-surface); }
.rank--3 { background: var(--st-reserved-soft); color: var(--st-reserved-ink); }

/* Pessoa numa linha de tabela: retrato e nome. */
.person { display: inline-flex; align-items: center; gap: var(--sp-2); min-width: 0; }

.avatar--sm { width: 26px; height: 26px; font-size: var(--fs-xs); }

/* Participação: barra e o número, lado a lado. */
.share { display: flex; align-items: center; gap: var(--sp-2); min-width: 120px; }
.share .progress { flex: 1 1 auto; min-width: 60px; }

.share__value {
  font-family: var(--ff-data);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-sm);
  color: var(--n-ink-2);
}

/* Contagem no cabeçalho do cartão e coluna estreita de tabela. */
.card__count {
  margin-left: auto;
  font-family: var(--ff-data);
  font-size: var(--fs-sm);
  color: var(--n-ink-3);
}

.card__body--flush { padding: 0; }
.cell--narrow { width: 1%; white-space: nowrap; }

/* =========================================================================
   Seletor de pessoa com busca
   Campo de texto que filtra a lista embaixo. A lista flutua sobre o resto do
   formulário -- empurrar o conteúdo faria a tela pular a cada tecla.
   ========================================================================= */
.picker { position: relative; }

/* Loteamento e lote lado a lado: são uma escolha só, em duas etapas. Separá-los
   em campos soltos da grade faria o segundo parecer independente do primeiro. */
.picker-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--sp-4);
  align-items: start;
}

@media (max-width: 640px) {
  .picker-pair { grid-template-columns: 1fr; }
}

/* Em coluna estreita os dois campos vão um sobre o outro: lado a lado, cada um
   fica com menos da metade do cartão e corta o nome do loteamento. */
.picker-pair--stacked { grid-template-columns: 1fr; }

/* Sem loteamento escolhido, a busca de lote está desabilitada e precisa
   parecer desabilitada -- senão a pessoa clica e acha que a tela travou. */
.picker__input:disabled {
  background: var(--n-sunken);
  color: var(--n-ink-3);
  cursor: not-allowed;
}

.picker__input { padding-right: var(--sp-7); }

.picker__clear {
  position: absolute;
  right: var(--sp-2);
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: var(--r-full);
  color: var(--n-ink-3);
  cursor: pointer;
}

.picker__clear:hover { background: var(--n-sunken); color: var(--n-ink); }
.picker__clear .material-symbols-outlined { font-size: 16px; }

.picker__list {
  position: absolute;
  z-index: var(--z-sticky);
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 280px;
  overflow-y: auto;
  margin: 0;
  padding: var(--sp-1);
  list-style: none;
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-md);
  box-shadow: var(--sh-3);
}

.picker__option {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-2);
  border-radius: var(--r-sm);
  text-align: left;
  cursor: pointer;
}

.picker__option:hover { background: var(--n-sunken); }

.picker__mark {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  border-radius: var(--r-full);
  background: var(--brand);
  color: var(--brand-ink);
  font-size: var(--fs-xs);
  font-weight: 600;
}

.picker__mark--all { background: var(--n-sunken); color: var(--n-ink-3); }
.picker__mark--all .material-symbols-outlined { font-size: 18px; }

.picker__text { display: flex; flex-direction: column; min-width: 0; }
.picker__name { color: var(--n-ink); }
.picker__role { font-size: var(--fs-sm); color: var(--n-ink-3); }
.picker__empty { padding: var(--sp-3); font-size: var(--fs-sm); color: var(--n-ink-3); }

/* =========================================================================
   Acordeão por ano
   Carnê de sessenta parcelas em lista corrida não se lê. Cada ano vira um
   bloco fechado que já diz, no cabeçalho, quantas parcelas tem e quanto soma.
   ========================================================================= */
.year {
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.year + .year { margin-top: var(--sp-3); }

.year__head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  cursor: pointer;
  list-style: none;
}

.year__head::-webkit-details-marker { display: none; }
.year__head:hover { background: var(--n-sunken); }

.year[open] .year__head { border-bottom: 1px solid var(--n-line); }
.year[open] .year__chevron { transform: rotate(180deg); }

.year__chevron {
  font-size: 20px;
  color: var(--n-ink-3);
  transition: transform var(--dur-fast) var(--ease);
}

.year__label {
  font-family: var(--ff-display);
  font-size: var(--fs-h3);
  font-weight: 600;
  color: var(--n-ink);
}

.year__meta { font-size: var(--fs-sm); color: var(--n-ink-3); }

.year__total {
  margin-left: auto;
  font-family: var(--ff-data);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--n-ink);
}

/* -------------------------------------------------------------------------
   Bloco que abre e fecha
   `<details>` nativo, como o carnê já fazia: o navegador dá o estado, o teclado
   funciona sozinho e nada depende de script. O que muda aqui é o tamanho -- o
   do carnê é um cabeçalho de ano, este cabe numa lista de consultas.
   ------------------------------------------------------------------------- */
.accordion {
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-md);
  overflow: hidden;
}

.accordion + .accordion { margin-top: var(--sp-2); }

.accordion__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  padding: var(--sp-3);
  cursor: pointer;
  list-style: none;
  transition: background var(--dur-fast) var(--ease);
}

.accordion__head::-webkit-details-marker { display: none; }
.accordion__head:hover { background: var(--n-sunken); }
.accordion__head:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--brand);
}

.accordion[open] .accordion__head { border-bottom: 1px solid var(--n-line); }
.accordion[open] .accordion__chevron { transform: rotate(180deg); }

.accordion__chevron {
  flex: none;
  font-size: 20px;
  color: var(--n-ink-3);
  transition: transform var(--dur-fast) var(--ease);
}

.accordion__label {
  font-weight: 500;
  color: var(--n-ink);
}

.accordion__meta {
  flex: 0 1 auto;
  min-width: 0;
  font-size: var(--fs-sm);
  color: var(--n-ink-3);
  white-space: nowrap;
}

.accordion__right {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}

.accordion__body { padding: var(--sp-3); }

/* A barra na borda diz o resultado antes de abrir: vermelha e restricao. */
.accordion--danger { border-left: 3px solid var(--st-sold); }
.accordion--ok { border-left: 3px solid var(--st-available); }
.accordion--muted { border-left: 3px solid var(--n-line-strong); }

/* Linha de baixo, quando o cabecalho quebra: o valor continua a direita. */
.accordion__head > .accordion__right:not(:first-child) { margin-left: auto; }

/* Pares curtos que quebram bem em coluna estreita -- a `data-list` punha
   rotulo e valor lado a lado e partia "Consultado por" no meio. */
.accordion__par {
  display: flex;
  flex-wrap: wrap;
  gap: 2px var(--sp-2);
  font-size: var(--fs-sm);
}

.accordion__par dt {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--n-ink-3);
}

.accordion__par dd { margin: 0; color: var(--n-ink-2); }

.accordion__ico { font-size: 15px; color: var(--n-ink-3); }

/* As ocorrencias por tipo: uma linha por especie, com o icone dela. Protesto e
   cheque devolvido somam igual e nao sao a mesma conversa. */
.ocorrencias {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.ocorrencias__item {
  padding: var(--sp-2) var(--sp-3);
  background: var(--n-sunken);
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
}

.ocorrencias__linha {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

/* A lista de uma a uma: fechada por padrao, aberta por quem quiser conferir. */
.ocorrencias__lista { margin-top: var(--sp-2); }

.ocorrencias__lista > summary {
  cursor: pointer;
  color: var(--brand-link);
  font-size: var(--fs-sm);
  list-style: none;
}

.ocorrencias__lista > summary::-webkit-details-marker { display: none; }
.ocorrencias__lista > summary::before { content: "+ "; }
.ocorrencias__lista[open] > summary::before { content: "- "; }
.ocorrencias__lista > summary:hover { text-decoration: underline; }
/* As ocorrencias: grade de tres colunas com cabecalho. Sem os rotulos em cima,
   "09/11/2022 LEME/SP R$ 1.500,00" quebrava na coluna estreita e virava tres
   pedacos soltos, sem dizer o que era cada um. */
.ocorrencia-tabela {
  margin-top: var(--sp-2);
  background: var(--n-surface);
  border-radius: var(--r-sm);
  overflow: hidden;
}

/* Largura fixa na coluna da data: com `auto`, o cabecalho "DATA" (curto) e a
   data em mono (larga) mediam diferente, e as tres colunas do cabecalho nao
   caiam em cima das tres da linha. */
/* As medidas saem de medicao, e nao de palpite: na coluna da ficha do cliente a
   linha tem 226px, e data (83) + praca (48) + valor (66) pedem 197. O que
   sobra e para o respiro entre elas -- por isso o gap e o recuo sao curtos
   aqui, e a coluna da data tem a largura exata do formato dd/mm/aaaa em mono. */
.ocorrencia-tabela__head,
.ocorrencia-tabela__linha {
  display: grid;
  grid-template-columns: 5.25rem minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 6px;
  padding: 6px var(--sp-2);
  font-size: var(--fs-xs);
}

.ocorrencia-tabela__head {
  background: var(--n-sunken);
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--n-ink-3);
}

.ocorrencia-tabela__linha { border-top: 1px solid var(--n-line); }

.ocorrencia-tabela__linha > span { min-width: 0; }

/* A praca cabe inteira nesta fonte; so corta quando o nome e longo demais --
   partida no meio, "LEME/SP" virava "LEME/S" numa linha e "P" na outra. */
.ocorrencia-tabela__linha > span:nth-child(2) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ocorrencia-tabela__linha .cell--right,
.ocorrencia-tabela__head .cell--right {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.ocorrencia-tabela__linha > span:nth-child(2) { color: var(--n-ink-3); }

/* O titulo da praca aparece inteiro ao passar o mouse, quando cortado. */
.ocorrencia-tabela__linha > span:nth-child(2):hover { overflow: visible; }

/* Ficha da consulta: rotulo em cima, valor embaixo. Lado a lado eles quebravam
   na coluna estreita e o valor de um encostava no rotulo do outro. */
.ficha-spc {
  display: grid;
  gap: var(--sp-3);
  margin: 0;
}

.ficha-spc > div { display: flex; flex-direction: column; gap: 1px; }

.ficha-spc dt {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--fs-xs);
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--n-ink-3);
}

.ficha-spc dd {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--n-ink);
  overflow-wrap: anywhere;
}

.ocorrencias__icone {
  flex: none;
  font-size: 18px;
  color: var(--st-sold);
}

.ocorrencias__tipo { color: var(--n-ink); }

.ocorrencias__desde { color: var(--n-ink-3); }

.ocorrencias__valor {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--n-ink);
}

/* -------------------------------------------------------------------------
   Espera de uma chamada que sai da casa
   A consulta ao birô leva segundos e pode levar trinta. Sem sinal nenhum, quem
   clicou clica de novo -- e cada clique e uma consulta cobrada.
   ------------------------------------------------------------------------- */
.aguardando {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--brand-soft);
  border: 1px solid var(--brand-100);
  border-radius: var(--r-sm);
  color: var(--brand-700);
  font-size: var(--fs-sm);
}

.aguardando__roda {
  flex: none;
  width: 18px;
  height: 18px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--r-full);
  animation: spin 700ms linear infinite;
}

/* Ação com um "?" colado: a dúvida nasce ao ver o botão, e é ali que a
   resposta precisa estar. */
.action-with-help { display: flex; align-items: center; gap: var(--sp-2); }
.action-with-help > form { flex: 1 1 auto; }

/* Lista de pendências: o que impede vem em vermelho, o que é aviso em âmbar. */
.pending-list { list-style: none; margin: 0; padding: 0; }

.pending-list__item {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--n-line);
}

.pending-list__item:last-child { border-bottom: 0; }

.pending-list__icon {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  border-radius: var(--r-md);
  background: var(--st-reserved-soft);
  color: var(--st-reserved-ink);
}

.pending-list__item--blocking .pending-list__icon {
  background: var(--st-sold-soft);
  color: var(--st-sold-ink);
}

.pending-list__icon .material-symbols-outlined { font-size: 18px; }

.pending-list__text { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; }
.pending-list__message { color: var(--n-ink); }
.pending-list__note { font-size: var(--fs-sm); color: var(--n-ink-3); }

/* Papel de uma pessoa, com o símbolo dele na frente. Não é badge de situação:
   papel não muda de cor, muda de ícone. */
.role-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: var(--fs-sm);
  color: var(--n-ink);
}

.role-chip .material-symbols-outlined { font-size: 16px; color: var(--n-ink-3); }

/* Rodapé de formulário: cancelar à esquerda do salvar, os dois à direita. */
.form-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}

/* Lista de impedimentos: por que a ação não vai acontecer. */
.reasons { display: flex; flex-direction: column; gap: var(--sp-2); list-style: none; }

.reasons li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--n-ink);
}

.reasons .material-symbols-outlined { font-size: 18px; color: var(--st-sold); flex: 0 0 auto; }

/* Variante em colunas: rótulo em cima, valor embaixo, tudo à esquerda. Serve
   a ficha com muitos campos curtos, onde a lista de linhas ficaria alta demais.
   Existia duplicada em customers.css e brigava com a versão de linhas -- o
   valor herdava o alinhamento à direita e o endereço saía espremido. */
.data-list--cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--sp-4);
}

.data-list--cols > div {
  display: block;
  min-width: 0;
  padding: 0;
  border-bottom: 0;
}

.data-list--cols dt {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--n-ink-3);
}

/* Texto sem espaço não invade a coluna vizinha. `break-word` só quebra quando
   a palavra não cabe inteira na célula -- e o e-mail ganha duas colunas para
   isso quase nunca acontecer. */
.data-list--cols dd { margin-top: 3px; text-align: left; overflow-wrap: break-word; }

/* Campo que ocupa a linha inteira: endereço, observação, qualificação. */
.data-list--cols .span-all { grid-column: 1 / -1; }

/* Campo longo de uma linha só (e-mail): duas colunas quando há espaço para
   duas; em tela estreita volta a ser uma, sem criar coluna fantasma. */
@media (min-width: 720px) {
  .data-list--cols .span-2 { grid-column: span 2; }
}

/* Chips de recorte: opção curta que já é o próprio filtro. Um clique, e não
   escolher numa lista e apertar Aplicar. */
.chips { display: flex; flex-wrap: wrap; gap: var(--sp-1); }

.chips__item {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0 var(--sp-3);
  height: 34px;
  border: 1px solid var(--n-line);
  border-radius: var(--r-full);
  background: var(--n-surface);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--n-ink-2);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.chips__item:hover { border-color: var(--n-ink-3); color: var(--n-ink); }

.chips__item.is-active {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--brand-ink);
}

.chips__item .material-symbols-outlined { font-size: 16px; }

/* Fila de etiquetas clicáveis: quadras, filtros salvos, marcadores. */
.chip-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 6px var(--sp-3);
  border: 1px solid var(--n-line);
  border-radius: var(--r-full);
  font-size: var(--fs-sm);
  color: var(--n-ink);
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.chip:hover { border-color: var(--brand); background: var(--n-sunken); }

.chip__count {
  font-family: var(--ff-data);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--n-ink-3);
}

/* Quem é você, em uma linha: retrato, nome e o dado que desambigua. Usada em
   confirmação de saída e em qualquer diálogo que fale com a pessoa pelo nome. */
.identity {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3);
  background: var(--n-sunken);
  border-radius: var(--r-sm);
}

.identity__text { display: flex; flex-direction: column; min-width: 0; }

.identity__name {
  font-weight: 600;
  color: var(--n-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.identity__meta {
  font-size: var(--fs-sm);
  color: var(--n-ink-3);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* =========================================================================
   Toast
   ========================================================================= */
.toast-region {
  position: fixed;
  right: var(--sp-5);
  bottom: var(--sp-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  width: min(380px, calc(100vw - var(--sp-8)));
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-left: 3px solid var(--n-line-strong);
  border-radius: var(--r-sm);
  box-shadow: var(--sh-2);
}

.toast--success { border-left-color: var(--st-available); }
.toast--error   { border-left-color: var(--st-sold); }
.toast--warning { border-left-color: var(--st-reserved); }
.toast--info    { border-left-color: var(--st-settled); }

.toast__icon { flex: 0 0 auto; margin-top: 1px; }
.toast--success .toast__icon { color: var(--st-available-ink); }
.toast--error   .toast__icon { color: var(--st-sold-ink); }
.toast--warning .toast__icon { color: var(--st-reserved-ink); }
.toast--info    .toast__icon { color: var(--st-settled-ink); }

.toast__icon .material-symbols-outlined { font-size: 20px; }

.toast__content { flex: 1 1 auto; min-width: 0; }
.toast__title { font-weight: 600; }
.toast__text  { font-size: var(--fs-sm); color: var(--n-ink-2); }

.toast__close {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: var(--r-xs);
  color: var(--n-ink-3);
}

.toast__close:hover { background: var(--n-sunken); }
.toast__close .material-symbols-outlined { font-size: 16px; }

.toast__action {
  display: inline-block;
  margin-top: var(--sp-1);
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--brand-link);
}

/* Barra do tempo restante. Pausa junto com o timer no hover e no foco. */
.toast__progress {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  transform-origin: left;
  background: currentColor;
  opacity: 0.35;
  animation: toast-progress linear forwards;
}

.toast { position: relative; }

.toast--success .toast__progress { color: var(--st-available); }
.toast--error   .toast__progress { color: var(--st-sold); }
.toast--warning .toast__progress { color: var(--st-reserved); }
.toast--info    .toast__progress { color: var(--st-settled); }

@keyframes toast-progress {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0); }
}

@media (prefers-reduced-motion: reduce) {
  .toast__progress { animation: none; }
}

/* =========================================================================
   Paginação
   ========================================================================= */
/* Menu centralizado: a paginação fica no eixo da tabela, e a contagem
   embaixo dela -- ler "121 a 150 de 400" e trocar de página são dois gestos
   diferentes e não disputam o mesmo canto. */
.pagination {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-4) 0;
}

.pagination__pages { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; justify-content: center; }

.pagination__info { font-size: var(--fs-sm); color: var(--n-ink-3); text-align: center; }

.pagination__item {
  display: grid;
  place-items: center;
  min-width: 32px;
  height: 32px;
  padding: 0 var(--sp-2);
  border: 1px solid var(--n-line);
  border-radius: var(--r-sm);
  background: var(--n-surface);
  color: var(--n-ink-2);
  font-size: var(--fs-sm);
}

.pagination__item:hover { background: var(--n-sunken); text-decoration: none; }

.pagination__item[aria-current="page"] {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--brand-ink);
  font-weight: 600;
}

.pagination__item--disabled { opacity: 0.4; pointer-events: none; }

/* =========================================================================
   Barra de filtros
   ========================================================================= */
.filter-bar {
  display: flex;
  align-items: flex-end;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding: var(--sp-4);
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-md);
}

.filter-bar__search { flex: 1 1 260px; min-width: 200px; }
.filter-bar__field  { flex: 0 1 180px; }
.filter-bar__actions { display: flex; gap: var(--sp-2); margin-left: auto; }

/* =========================================================================
   Breadcrumb
   ========================================================================= */
.breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  flex-wrap: wrap;
  font-size: var(--fs-sm);
  color: var(--n-ink-3);
}

.breadcrumb__item { color: var(--n-ink-3); }
.breadcrumb__item:hover { color: var(--n-ink-2); }
.breadcrumb__item[aria-current="page"] { color: var(--n-ink); font-weight: 500; }

.breadcrumb__sep {
  color: var(--n-line-strong);
  font-size: 16px;
  user-select: none;
}

/* =========================================================================
   Skeleton
   ========================================================================= */
.skeleton {
  background: var(--n-sunken);
  border-radius: var(--r-xs);
  animation: skeleton-pulse 1.4s ease-in-out infinite;
}

.skeleton--text  { height: 12px; }
.skeleton--title { height: 20px; width: 40%; }
.skeleton--block { height: 96px; border-radius: var(--r-md); }

@keyframes skeleton-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.55; }
}

/* =========================================================================
   Upload
   ========================================================================= */
.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-6);
  text-align: center;
  background: var(--n-surface);
  border: 1px dashed var(--n-line-strong);
  border-radius: var(--r-md);
  color: var(--n-ink-2);
  transition: border-color var(--dur-fast) var(--ease),
              background-color var(--dur-fast) var(--ease);
  cursor: pointer;
}

.dropzone:hover,
.dropzone--active {
  border-color: var(--brand);
  background: var(--brand-soft);
}

.dropzone__icon { color: var(--n-ink-3); }
.dropzone__icon .material-symbols-outlined { font-size: 28px; }
.dropzone__hint { font-size: var(--fs-sm); color: var(--n-ink-3); }

.dropzone__preview {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  padding: var(--sp-3);
  border: 1px solid var(--n-line);
  border-radius: var(--r-sm);
  text-align: left;
}

.dropzone__progress {
  width: 100%;
  height: 4px;
  background: var(--n-sunken);
  border-radius: var(--r-full);
  overflow: hidden;
}

.dropzone__bar {
  height: 100%;
  background: var(--brand);
  border-radius: var(--r-full);
  transition: width var(--dur-normal) var(--ease);
}

/* =========================================================================
   Banner (aviso de tenant inadimplente, por exemplo)
   ========================================================================= */
.banner {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-5);
  font-size: var(--fs-sm);
  background: var(--st-reserved-soft);
  color: var(--st-reserved-ink);
  border-bottom: 1px solid var(--n-line);
}

.banner .material-symbols-outlined { font-size: 18px; }


/* =========================================================================
   Barra de acesso de suporte

   Vermelha e no topo de tudo de propósito: acesso de fora ao sistema de uma
   imobiliária não pode passar despercebido por quem esta trabalhando.
   ========================================================================= */
/* Barra de acesso da plataforma.
   Era um bloco vermelho-escuro atravessado na tela do cliente, brigando com a
   marca dele. Agora é uma faixa de aviso: fundo âmbar claro, tinta escura e um
   filete na lateral -- continua impossível de ignorar, sem parecer erro. */
/* Barra de acesso da plataforma dentro da imobiliária.

   Não é `sticky`: presa no topo do `app__main`, ela passava por cima do
   cabeçalho da página e o texto encavalava no título. Ela abre a página, rola
   junto com o resto, e não some -- quem está sendo observado percebe pelo
   bloco inteiro, não por uma tarja pendurada. */
.support-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
  padding: var(--sp-4) var(--sp-5);
  background: var(--st-reserved-soft);
  border: 1px solid var(--st-reserved);
  border-left-width: 4px;
  border-radius: var(--r-lg);
  color: var(--st-reserved-ink);
}

.support-bar__icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  border-radius: var(--r-full);
  background: var(--n-surface);
  border: 1px solid var(--st-reserved);
}

.support-bar__icon .material-symbols-outlined { font-size: 22px; }

.support-bar__text { display: flex; flex-direction: column; gap: 5px; min-width: 0; }

.support-bar__lead { font-size: var(--fs-body); color: var(--st-reserved-ink); }
.support-bar__lead strong { color: var(--n-ink); font-weight: 600; }

.support-bar__meta { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); }

.support-bar__tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--r-full);
  background: var(--n-surface);
  font-size: var(--fs-xs);
  color: var(--n-ink-2);
}

.support-bar__tag .material-symbols-outlined { font-size: 14px; }

/* Acesso que pode escrever é outro nível de risco: ele se anuncia em vermelho. */
.support-bar__tag--write {
  background: var(--st-sold-soft);
  color: var(--st-sold-ink);
  font-weight: 600;
}

.support-bar__action { margin-left: auto; flex: 0 0 auto; }

@media (max-width: 860px) {
  .support-bar { flex-wrap: wrap; }
  .support-bar__action { margin-left: 0; width: 100%; }
  .support-bar__action .btn { width: 100%; }
}

.support-bar .btn {
  height: 32px;
  padding: 0 12px;
  background: var(--n-surface);
  border: 1px solid var(--st-reserved);
  color: var(--st-reserved-ink);
  font-size: var(--fs-sm);
}

.support-bar .btn:hover { background: var(--st-reserved-soft); }

/* =========================================================================
   Abas de filtro (lista com contagem por situação)

   Nasceram no painel master e valem para as listas da imobiliária também: a
   contagem em cada aba responde "quanto tem de cada" antes de qualquer clique.
   ========================================================================= */
.filter-tabs {
  display: flex;
  gap: var(--sp-1);
  overflow-x: auto;
  border-bottom: 1px solid var(--n-line);
}

.filter-tabs__item {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 10px 14px;
  white-space: nowrap;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--n-ink-3);
  border-bottom: 2px solid transparent;
  text-decoration: none;
}

.filter-tabs__item:hover { color: var(--n-ink); text-decoration: none; }

.filter-tabs__item.is-active {
  color: var(--n-ink);
  font-weight: 600;
  border-bottom-color: var(--brand);
}

.filter-tabs__count {
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  height: 20px;
  padding: 0 6px;
  border-radius: var(--r-full);
  background: var(--n-sunken);
  color: var(--n-ink-3);
  font-size: var(--fs-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.filter-tabs__item.is-active .filter-tabs__count {
  background: var(--brand-soft);
  color: var(--brand-link);
}

/* =========================================================================
   Ação de linha em ícone

   Em tabela, o rótulo escrito em cada linha vira ruído. O nome da ação vive no
   `title` e no `aria-label` -- quem usa leitor de tela continua ouvindo.
   ========================================================================= */
.row-actions { display: inline-flex; align-items: center; gap: 2px; justify-content: flex-end; }

.icon-action {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--n-ink-3);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.icon-action:hover {
  background: var(--n-sunken);
  color: var(--n-ink);
  text-decoration: none;
}

.icon-action--danger:hover { background: var(--st-sold-soft); color: var(--st-sold-ink); }

.icon-action:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }

.icon-action .material-symbols-outlined { font-size: 19px; }

/* =========================================================================
   AJUSTE FINO DOS COMPONENTES COMPARTILHADOS

   As medidas nasceram no painel master e valem para o sistema da imobiliária
   também -- o que muda entre os dois é a cor, que vem dos tokens de marca, não
   o tamanho do botão nem o raio do campo.
   ========================================================================= */
.btn {
  height: 40px;
  padding: 0 16px;
  gap: 6px;
  border-radius: var(--r-md);
  font-weight: 500;
}

.btn--sm { height: 34px; padding: 0 12px; font-size: var(--fs-sm); }

.btn .material-symbols-outlined,
.btn .icon { font-size: 18px; }

.btn--primary:active:not(:disabled) { transform: translateY(1px); }

.input,
.select {
  height: 40px;
  border-radius: var(--r-md);
}

/* Espaço para a seta do navegador: sem isso, opção longa como "Todos os
   colaboradores" encosta na seta e parece cortada. */
.select { padding-right: var(--sp-6); }

.textarea { border-radius: var(--r-md); }

.input:focus,
.select:focus,
.textarea:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-soft);
}

.field__label {
  display: block;
  margin-bottom: 5px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--n-ink-2);
}

.card { border-radius: var(--r-lg); }

.card__header { padding: 18px 20px; }

.card__title {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-family: var(--ff-display);
  font-size: var(--fs-h3);
  font-weight: 600;
}

.card__title .material-symbols-outlined { font-size: 18px; color: var(--n-ink-3); }

.card__body { padding: 20px; }

.card__footer {
  padding: 14px 20px;
  background: var(--n-canvas);
  border-top: 1px solid var(--n-line);
  border-radius: 0 0 var(--r-lg) var(--r-lg);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
}

/* Cabeçalho de página: o título é o assunto da tela, e o assunto merece peso. */
.page-header__title {
  font-family: var(--ff-display);
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.03em;
}

.page-header__subtitle { font-size: var(--fs-sm); color: var(--n-ink-3); }

/* Campo de arquivo desenhado pelo projeto, também no lado da imobiliária. */
.file-field {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: var(--n-surface);
  border: 2px dashed var(--n-line);
  border-radius: var(--r-lg);
  transition: border-color var(--dur-fast) var(--ease);
}

.file-field:hover { border-color: var(--brand); }

.file-field:focus-within {
  border-color: var(--brand);
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

.file-field input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.file-field__icon,
.file-field__preview {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border-radius: var(--r-md);
  background: var(--n-canvas);
  border: 1px solid var(--n-line);
  color: var(--n-ink-3);
  object-fit: contain;
}

.file-field__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.file-field__title {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--brand-link);
}

.file-field__title .material-symbols-outlined { font-size: 18px; }

.file-field__hint { font-size: var(--fs-sm); color: var(--n-ink-3); overflow-wrap: anywhere; }

/* O que já está gravado. Fica fora do `.file-field` porque lá dentro o input
   transparente cobre a área toda e roubaria o clique dos links. */
.file-field__current {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--n-ink-2);
}

.file-field__current .material-symbols-outlined {
  font-size: 16px;
  color: var(--st-available);
}

.file-field__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-field__current a { white-space: nowrap; }

/* =========================================================================
   BLOCOS DE PAINEL (KPI, cartela de números, seção com régua)

   Nasceram no painel master e sobem para cá porque o dashboard da imobiliária
   pede a mesma gramática. A cor sai dos tokens de marca do tenant: a mesma
   estrutura veste a paleta de cada imobiliária.
   ========================================================================= */
.kpi-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--sp-4);
}

.kpi-tile {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: 4px var(--sp-3);
  padding: var(--sp-5);
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  overflow: hidden;
  /* O valor mede a largura do próprio cartão (unidade cqi), e não a da janela. */
  container-type: inline-size;
}

/* Filete da cor do indicador no topo: com quatro cartões iguais lado a lado,
   e ele que diz de longe qual é qual. */
.kpi-tile::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--cor, var(--brand));
}

.kpi-tile__label { grid-column: 1; align-self: center; }
/* Valor e notas ocupam a largura toda, embaixo do ícone: "R$ 14.927.000,00"
   dividindo a linha com o ícone passava por cima dele. */
.kpi-tile__value,
.kpi-tile__note { grid-column: 1 / -1; }

/* O ícone num quadrado da cor do indicador: dá leitura de relance a uma faixa
   de cartões que, de resto, é toda igual. */
.kpi-tile__icon {
  grid-column: 2;
  grid-row: 1;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--r-md);
  background: var(--cor, var(--brand));
  color: var(--n-inverse);
}

.kpi-tile__icon .material-symbols-outlined { font-size: 22px; }

.kpi-tile--ok   { --cor: var(--st-available); --cor-tinta: var(--st-available-ink); }
.kpi-tile--warn { --cor: var(--st-reserved);  --cor-tinta: var(--st-reserved-ink); }
.kpi-tile--bad  { --cor: var(--st-sold);      --cor-tinta: var(--st-sold-ink); }
.kpi-tile--info { --cor: var(--st-settled);   --cor-tinta: var(--st-settled-ink); }

.kpi-tile__label {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--n-ink-3);
}

/* O valor cresce com o dinheiro: "R$ 135.000,00" a 30px quebrava em duas linhas
   dentro do cartão, e o "R$" ficava sozinho em cima. O corpo acompanha a
   largura do cartão e o número nunca quebra -- KPI que quebra linha deixa de
   ser lido de relance, que é a única serventia dele. Pela largura da janela
   ele passava do cartão com "R$ 14.927.000,00". */
.kpi-tile__value {
  font-family: var(--ff-display);
  font-size: clamp(16px, 9.5cqi, 30px);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: var(--tracking-display);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--cor-tinta, var(--brand-link));
}

.kpi-tile__note { font-size: var(--fs-sm); color: var(--n-ink-3); }
.kpi-tile > .kpi__note { grid-column: 1 / -1; }
.kpi-tile__total { padding-top: 6px; margin-top: 2px; border-top: 1px solid var(--n-line); }
.kpi-tile__total strong { color: var(--n-ink); font-variant-numeric: tabular-nums; }

/* Cartela: números pequenos lado a lado, separados por fio. */
.ledger {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  background: var(--n-surface);
  border: 1px solid var(--n-line);
  border-radius: var(--r-lg);
  overflow: hidden;
}

.ledger__cell {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: var(--sp-4) var(--sp-5);
  border-right: 1px solid var(--n-line);
  min-width: 0;
}

.ledger__cell:last-child { border-right: 0; }

.ledger__label {
  /* Flex por causa do ponto de situação: `.badge__dot` e um span com medida,
     e fora de um container flex a medida não vale e ele some. */
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--n-ink-3);
}

.ledger__value {
  font-family: var(--ff-data);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--n-ink);
}

.ledger__note { font-size: var(--fs-sm); color: var(--n-ink-3); }

/* Célula que pede ação: filete âmbar na borda de cima. Só cor, sem ícone extra
   -- o rótulo já diz o que é, e alarme repetido deixa de ser alarme. */
.ledger__cell--warn { box-shadow: inset 0 3px 0 var(--st-reserved); }

/* Seção com régua: rótulo miúdo sobre um fio, no lugar de mais uma caixa. */
.section { display: flex; flex-direction: column; gap: var(--sp-4); }

.section__head {
  display: flex;
  align-items: baseline;
  gap: var(--sp-4);
  padding-bottom: var(--sp-2);
  border-bottom: 1px solid var(--n-line);
}

.section__title {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--n-ink-3);
  white-space: nowrap;
}

.section__count { font-family: var(--ff-data); font-size: var(--fs-sm); color: var(--n-ink-3); }

.section__link {
  margin-left: auto;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--brand-link);
  white-space: nowrap;
}

.slab-grid { display: grid; gap: var(--sp-4); align-items: start; }
.slab-grid--2 { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
.slab-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

@media (max-width: 1024px) {
  .slab-grid--2,
  .slab-grid--3 { grid-template-columns: 1fr; }
  .ledger__cell { border-right: 0; border-bottom: 1px solid var(--n-line); }
  .ledger__cell:last-child { border-bottom: 0; }
}

/* A cor que o lote tem na planta de venda: amostra ao lado do código, no painel
   da planta e na tela do lote. O valor vem do banco (a cor do documento, não do
   design), por isso o componente só dá forma -- a cor entra inline. */
.plat-swatch {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 3px;
  border: 1px solid var(--n-line-strong);
  vertical-align: -2px;
  flex: none;
}

.plat-swatch-line {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
}

/* Formulario nao acompanha a largura da tela: linha longa demais faz o olho
   perder o comeco da proxima. Vive aqui, e nao numa folha de app, porque toda
   tela de formulario precisa dela. */
.narrow-form { width: 100%; max-width: 640px; }

/* Preview de arquivo. Mora aqui, e nao na folha de loteamentos, porque o modal
   e componente compartilhado: na pasta do cliente ele carregava sem estilo
   nenhum -- mesma armadilha do `.narrow-form`. */
.file-preview {
  display: flex;
  justify-content: center;
  background: var(--n-sunken);
}

.file-preview__image {
  max-width: 100%;
  max-height: 70vh;
  object-fit: contain;
}

/* PDF precisa de altura propria: `max-height` num quadro vazio o encolhe a
   zero e o documento nao aparece. */
.file-preview__frame {
  width: 100%;
  height: 70vh;
  border: 0;
  background: var(--n-surface);
}

/* Frase curta lida inteira antes do clique: centrada, com quebra equilibrada.
   Paragrafo longo e outra coisa -- centrado ele fica esfarrapado nas duas
   pontas, e ai o justificado le melhor. */
.confirm__text--center { text-align: center; text-wrap: balance; }

.confirm__text--justify {
  text-align: justify;
  text-wrap: pretty;
  hyphens: auto;
}

/* ---------- Ajuda de contexto ---------- */

/* O "?" ao lado do titulo. Abre a explicacao no lugar, sem tirar a pessoa da
   tela e sem JavaScript -- e `<details>` nativo. */
.hint { display: inline-block; vertical-align: middle; }

.hint__botao {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  color: var(--n-ink-3);
  cursor: pointer;
  list-style: none;
}

.hint__botao::-webkit-details-marker { display: none; }
.hint__botao .material-symbols-outlined { font-size: 18px; }

.hint__botao:hover { background: var(--n-sunken); color: var(--n-ink-2); }

.hint[open] .hint__botao { background: var(--brand-soft); color: var(--brand); }

.hint__texto {
  margin: var(--sp-2) 0 0;
  padding: var(--sp-3);
  border-left: 2px solid var(--brand-200);
  background: var(--n-sunken);
  border-radius: var(--r-sm);
  font-size: var(--fs-sm);
  line-height: var(--lh-normal);
  color: var(--n-ink-2);
}

/* Dentro do cabecalho de card o texto ocupa a largura toda, e nao a do "?". */
.card__header .hint { position: static; }
.card__header .hint[open] .hint__texto {
  position: absolute;
  left: var(--sp-5);
  right: var(--sp-5);
  z-index: 5;
  box-shadow: var(--sh-2);
  background: var(--n-surface);
}
.card__header { position: relative; }

/* ---------- Chave liga-desliga ---------- */

/* Desenhada sobre a propria caixa de marcar, com `appearance: none`. Nao e
   caixa falsa por cima do controle: o que recebe foco, tecla e leitor de tela
   continua sendo o input nativo. */
.switch {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--sp-3);
  max-width: 100%;
  padding: var(--sp-2) 0;
}

.switch__text {
  font-size: var(--fs-body);
  line-height: var(--lh-normal);
  color: var(--n-ink);
}

.switch__input {
  position: relative;
  flex: 0 0 auto;
  width: 40px;
  height: 22px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--n-line-strong);
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}

.switch__input::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--n-surface);
  box-shadow: var(--sh-1);
  transition: transform var(--dur-fast) var(--ease);
}

.switch__input:checked { background: var(--brand); }
.switch__input:checked::after { transform: translateX(18px); }

.switch__input:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

.field--switch + .field--switch { border-top: 1px solid var(--n-line); }


/* ---------- Grupo de chaves ---------- */

/* Escolha de varias opcoes com a mesma chave do resto do sistema. Uma caixa so,
   com as opcoes empilhadas: o grupo tem borda, e nao cada linha, senao tres
   cartoes soltos competem com os cartoes de secao da tela. */
.field--switchgroup {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.switch-group {
  border: 1px solid var(--n-line);
  border-radius: var(--r-md);
  background: var(--n-surface);
  overflow: hidden;
}

.switch-group__linha {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-3);
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}

.switch-group__linha + .switch-group__linha { border-top: 1px solid var(--n-line); }
.switch-group__linha:hover { background: var(--n-sunken); }

/* A chave em si e a mesma do `.switch__input`. O seletor alcanca o controle
   pelo tipo para o formulario nao precisar lembrar de passar classe nenhuma --
   e essa exigencia que produz campo quebrado na proxima tela. */
.switch-group__linha > input[type="checkbox"] {
  position: relative;
  flex: 0 0 auto;
  width: 40px;
  height: 22px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--n-line-strong);
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}

.switch-group__linha > input[type="checkbox"]::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--n-surface);
  box-shadow: var(--sh-1);
  transition: transform var(--dur-fast) var(--ease);
}

.switch-group__linha > input[type="checkbox"]:checked { background: var(--brand); }
.switch-group__linha > input[type="checkbox"]:checked::after { transform: translateX(18px); }

.switch-group__linha > input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* A data com o lapis ao lado: o botao de remarcar fica colado nela, e nao no
   grupo de acoes da direita -- e na data que a pessoa olha quando quer muda-la.
   Ele so aparece com o mouse na linha, para a coluna nao virar um paredao de
   icones. */
.cell-data-edit {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
}

.cell-data-edit .icon-action {
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease);
}

tr:hover .cell-data-edit .icon-action,
.cell-data-edit .icon-action:focus-visible { opacity: 1; }

@media (hover: none) {
  .cell-data-edit .icon-action { opacity: 1; }
}

/* ---------- Abas (detalhe da imobiliária, SPC Brasil) ---------- */
.tabs {
  display: flex;
  gap: var(--sp-1);
  overflow-x: auto;
  border-bottom: 1px solid var(--n-line);
}

.tabs__item {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  white-space: nowrap;
  color: var(--n-ink-2);
  border-bottom: 2px solid transparent;
  text-decoration: none;
}

.tabs__item:hover { color: var(--n-ink); text-decoration: none; }

.tabs__item.is-active {
  color: var(--n-ink);
  font-weight: 600;
  border-bottom-color: var(--brand);
}

.tabs__item .material-symbols-outlined { font-size: 18px; }
