/* Linguagem visual do Pool — vidro, monoespaçado nos micro-rótulos, azul
 * #1d96cb como única cor, container queries em vez de media queries.
 *
 * Compartilhado entre as páginas de /patrimonio. Estático servido pelo
 * @fastify/static, sem build. Cache por cabeçalho: max-age=0 + ETag, então o
 * navegador revalida a cada carga e recebe 304 se nada mudou — editar e dar
 * F5 sempre mostra a mudança, sem querystring de versão para alguém esquecer
 * de incrementar.
 */
html,body{margin:0;padding:0;height:100%}
  body{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
  a{color:#1d96cb;text-decoration:none}
  @keyframes poolRise{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:none}}
  @keyframes poolHalo{0%,100%{opacity:.5;transform:scale(1)}50%{opacity:.85;transform:scale(1.07)}}
  @keyframes poolDrift{0%{transform:translate3d(0,0,0) scale(1)}34%{transform:translate3d(5%,-4%,0) scale(1.1)}
    67%{transform:translate3d(-4%,5%,0) scale(.94)}100%{transform:translate3d(0,0,0) scale(1)}}
  @keyframes poolSlide{from{opacity:0;transform:translateX(36px)}to{opacity:1;transform:none}}
  /* .f e .qmeta são flex/grid — sem isto o atributo hidden não esconde nada. */
  [hidden]{display:none!important}

  :root{--brand:#1d96cb;--ink:#14161a;--ink-2:#3f474f;--ink-3:#98a1a9;--ink-4:#a4acb3;
    --good:#0ca30c;--warn:#b8860b;--crit:#c0392b}

  .root{container-type:inline-size;position:relative;overflow:hidden;min-height:100%;box-sizing:border-box;
    font-family:-apple-system,BlinkMacSystemFont,'SF Pro Display','Segoe UI Variable Display','Segoe UI','Helvetica Neue',Helvetica,sans-serif;
    color:var(--ink);background-color:#e7ecf1;
    background-image:linear-gradient(178deg,#fbfdfe 0%,#eef2f6 42%,#dfe6ed 100%)}
  .mono{font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace}

  .stack{position:relative;z-index:1;min-height:100%;box-sizing:border-box;
    padding:clamp(16px,2.4cqw,30px);display:flex;flex-direction:column;gap:clamp(26px,3.4cqw,44px)}

  .pill{position:relative;display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:space-between;
    padding:14px clamp(18px,2.4cqw,30px);border-radius:999px;border:1px solid rgba(255,255,255,.9);
    background-image:linear-gradient(180deg,rgba(255,255,255,.66),rgba(255,255,255,.34));
    backdrop-filter:blur(20px) saturate(190%);-webkit-backdrop-filter:blur(20px) saturate(190%);
    box-shadow:inset 0 1px 0 rgba(255,255,255,1),inset 0 -1px 1px rgba(24,48,74,.05),0 16px 34px -24px rgba(18,30,46,.4);
    font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:#8b949d;white-space:nowrap;
    animation:poolRise .8s cubic-bezier(.2,.8,.2,1) both}
  .pill .home{display:flex;align-items:center}
  .pill .home img{height:19px;width:auto;display:block}
  .pill .crumb b{color:#6d757d;font-weight:400}

  /* cabeçalho da página */
  .phead{position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;
    gap:clamp(16px,2cqw,24px);padding:clamp(22px,4.4cqw,64px) 0 clamp(4px,1cqw,14px);
    animation:poolRise 1s cubic-bezier(.2,.8,.2,1) both;animation-delay:.08s}
  .phead .mark{position:relative;display:flex;align-items:center;justify-content:center}
  .phead .mark .halo{position:absolute;width:190%;height:190%;border-radius:50%;
    background-image:radial-gradient(circle at 50% 50%,rgba(29,150,203,.3),rgba(29,150,203,0) 62%);
    filter:blur(18px);animation:poolHalo 11s ease-in-out infinite}
  .phead .mark svg{position:relative;width:clamp(72px,9cqw,116px);height:auto;display:block}
  .phead h1{margin:0;font-size:clamp(30px,4.2cqw,54px);font-weight:600;letter-spacing:-.034em}
  .phead p{margin:0;font-size:clamp(14px,1.4cqw,17px);color:var(--ink-3);letter-spacing:-.008em}

  /* UMA FILEIRA, QUATRO COLUNAS:
       Property details · Values · Payment progress · [Contacts / Search]
     ⚠️ A quarta coluna é uma PILHA de duas caixas, não duas colunas. Com seis
     caixas soltas a grade quebrava em duas fileiras, e aí cada caixa esticava
     para preencher a altura da fileira — era daí que vinha o espaço vazio.
     `align-items:stretch` (o padrão) é o que deixa as quatro com a MESMA
     altura, alinhadas em cima e embaixo. */
  .kpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
    gap:clamp(10px,1.2cqw,14px);align-items:stretch;
    animation:poolRise 1s cubic-bezier(.2,.8,.2,1) both;animation-delay:.16s}
  .kstack{display:flex;flex-direction:column;gap:clamp(10px,1.2cqw,14px);min-width:0}
  /* Contatos absorve a sobra; a busca fica da altura do conteúdo dela. */
  .kstack .kpi.people{flex:1}
  .kstack .kpi.find{flex:none}
  /* Cabeçalho de caixa: o mesmo micro-rótulo monoespaçado dos cartões. */
  .kh{font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:#9aa2a9;
    margin-bottom:9px}

  /* Linha de dado: rótulo à esquerda, valor à direita. Duas colunas, e não
     rótulo-em-cima, porque são oito linhas — empilhar dobraria a altura. */
  .pr{display:grid;grid-template-columns:auto 1fr;gap:0 12px;align-items:baseline;
    padding:3px 0;border-top:1px solid rgba(24,48,74,.055)}
  .pr:first-of-type{border-top:0;padding-top:0}
  .pr .k{font-size:8.5px;letter-spacing:.12em;text-transform:uppercase;color:#a4acb3;
    font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace;white-space:nowrap}
  .pr .v{font-size:12.5px;color:var(--ink);text-align:right;font-variant-numeric:tabular-nums;
    line-height:1.3;min-width:0;overflow-wrap:anywhere}
  .pr .v .sub{display:block;font-size:9px;color:#b4bbc1;letter-spacing:.04em;line-height:1.3}
  .pr .s{grid-column:2;text-align:right;font-size:9px;color:#a4acb3;letter-spacing:.04em;
    font-variant-numeric:tabular-nums;line-height:1.3}
  .kpi.values .pr .v{font-size:14px;font-weight:600;letter-spacing:-.02em}

  /* O DONUT. Duas fatias, monocromático — o pago em tinta escura e o restante
     em cinza claro, com 2px de folga entre as duas. 🚫 Sem legenda de cor e sem
     cor nova: a regra do site é cor só no logo. */
  /* O donut cresce até o que a coluna der, com um teto — é o desenho que dá
     sentido à caixa, e apertá-lo para caber num quadrado fixo desperdiçaria a
     largura que a coluna já tem. */
  .kpi.prog{display:flex;flex-direction:column}
  .donut{position:relative;width:min(100%,190px);aspect-ratio:1;margin:4px auto 14px;flex:none}
  .donut svg{width:100%;height:100%;display:block}
  .donut .paid{stroke:var(--ink)}
  .donut .rest{stroke:rgba(24,48,74,.12)}
  .dnum{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
    justify-content:center;line-height:1;
    font-size:clamp(24px,3.4cqw,34px);font-weight:600;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
  .dnum i{font-style:normal;font-size:11px;font-weight:500;color:#a4acb3;margin-top:4px}
  .dlegend{display:flex;flex-direction:column;gap:5px;margin-top:auto}
  .dlegend > div{display:flex;align-items:baseline;gap:8px;font-variant-numeric:tabular-nums}
  .dlegend b{font-size:12.5px;font-weight:600;letter-spacing:-.01em}
  .dlegend .l{font-size:8.5px;letter-spacing:.12em;text-transform:uppercase;color:#a4acb3;
    font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace}
  .dlegend .sw{width:9px;height:9px;border-radius:3px;flex:none;align-self:center}
  .dlegend .sw.paid{background:var(--ink)}
  .dlegend .sw.rest{background:rgba(24,48,74,.12)}

  /* A faixa de mercado e o histórico dela, dentro da caixa Values. */
  .mvh{border:0;background:none;padding:0 0 0 6px;cursor:pointer;line-height:0;color:#b4bbc1;
    vertical-align:-2px}
  .mvh svg{width:12px;height:12px;stroke:currentColor;fill:none}
  .mvh:hover,.mvh[aria-expanded="true"]{color:var(--brand)}
  .mvlist{margin:6px 0 2px;padding:7px 9px;border-radius:12px;
    background:rgba(24,48,74,.045);max-height:150px;overflow:auto}
  .mvrow{display:flex;align-items:baseline;gap:8px;padding:3px 0;font-size:11px}
  .mvrow + .mvrow{border-top:1px solid rgba(24,48,74,.06)}
  .mvrow .d{font-size:8.5px;letter-spacing:.1em;color:#b4bbc1;flex:none;min-width:74px}
  .mvrow .r{flex:1;text-align:right;font-variant-numeric:tabular-nums;color:#5b6169}
  .mvrow.now .r{color:var(--ink);font-weight:600}
  .tag2{flex:none;font-size:7.5px;letter-spacing:.14em;text-transform:uppercase;color:#fff;
    background:rgba(23,120,159,.85);padding:2px 5px;border-radius:999px}

  /* 🚫 `.dnote` e `.sw.over` saíram: o donut passou a ser 100% contrato e não
     passa mais de 100%, então não há excedente a explicar.
     A contagem de parcelas fica sob o desenho — contexto, não base do cálculo. */
  .dcount{font-size:8.5px;letter-spacing:.12em;text-transform:uppercase;color:#a4acb3;
    text-align:center;margin:-8px 0 10px}
  /* Lançamento sem tipo não entra no plano — e some do donut sem dizer nada, se
     esta linha não existir. Amarelo porque pede ação: classificar. */
  .dmiss{font-size:8.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--warn);
    text-align:center;margin:-6px 0 10px}

  /* 🚫 `.kpi.drop` saiu: o dropzone voltou para o topo de Documents. */
  .kpi.find{display:flex;flex-direction:column}
  .kpi.find .dsearch{margin:0;padding:7px 11px}
  .kpi.find .dsn{margin-top:7px;text-align:right}
  /* ⚠️ Altura do CONTEÚDO, não de um mínimo inventado: nada de min-height aqui.
     O que iguala as quatro é o stretch da grade. */
  .kpi{position:relative;overflow:hidden;display:flex;flex-direction:column;gap:0;
    padding:14px 16px;border-radius:18px;
    border:1px solid rgba(255,255,255,.9);
    background-image:linear-gradient(168deg,rgba(255,255,255,.82) 0%,rgba(255,255,255,.44) 52%,rgba(255,255,255,.58) 100%);
    backdrop-filter:blur(28px) saturate(190%);-webkit-backdrop-filter:blur(28px) saturate(190%);
    box-shadow:inset 0 1.5px 0 rgba(255,255,255,1),inset 0 -22px 38px -32px rgba(29,150,203,.35),
      0 26px 46px -26px rgba(18,30,46,.4),0 2px 6px rgba(18,30,46,.05)}
  /* 🚫 `.kpi .v/.l/.s` gigantes e `.kpi.two .fig` saíram em 05/08/2026: as
     caixas deixaram de ser um número enorme cada e viraram listas de linhas —
     ver `.pr` abaixo. Manter as duas gramáticas seria manter duas verdades
     sobre como uma caixa se desenha. */
  /* Contatos: a caixa cresce até um teto e depois rola, para não esticar a
     faixa inteira quando o imóvel tiver seis contatos. */
  .kpi.people{gap:0}
  /* Rola dentro da caixa em vez de esticar a fileira inteira. */
  .kpi.people #contacts{flex:1;min-height:0;overflow:auto;margin:0 -4px;padding:0 4px}
  .kpi.people .who{grid-template-columns:28px 1fr auto;padding:7px 8px;border-radius:12px}
  .kpi.people .who + .who{margin-top:6px}
  .kpi.people .av{width:30px;height:30px;border-radius:10px;font-size:11px}
  .kpi.people .nm2{font-size:12.5px}
  .kpi.people .chip{font-size:10.5px;padding:4px 9px}
  .fxnote{width:100%;text-align:center;font-size:10px;letter-spacing:.1em;color:#a4acb3;
    font-variant-numeric:tabular-nums;margin:0}
  .fxnote .stale{color:var(--warn)}

  .rule{display:flex;align-items:center;gap:16px;font-size:10px;letter-spacing:.22em;
    text-transform:uppercase;color:var(--ink-4)}
  .rule i{flex:1;height:1px;font-style:normal}
  .rule i.l{background-image:linear-gradient(90deg,rgba(24,48,74,0),rgba(24,48,74,.13))}
  .rule i.r{background-image:linear-gradient(90deg,rgba(24,48,74,.13),rgba(24,48,74,0))}

  .section{display:flex;flex-direction:column;gap:clamp(16px,2.2cqw,26px);
    animation:poolRise 1s cubic-bezier(.2,.8,.2,1) both;animation-delay:.24s}

  .toolbar{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  .btn{font:inherit;font-size:13px;font-weight:500;padding:10px 18px;border-radius:14px;cursor:pointer;
    border:1px solid rgba(255,255,255,.9);color:var(--ink);display:inline-flex;align-items:center;gap:8px;
    background-image:linear-gradient(168deg,rgba(255,255,255,.8),rgba(255,255,255,.42));
    backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%);
    box-shadow:inset 0 1px 0 rgba(255,255,255,1),0 12px 24px -18px rgba(18,30,46,.42);
    transition:transform .35s cubic-bezier(.2,.8,.2,1),box-shadow .35s}
  .btn:hover{transform:translateY(-2px);box-shadow:inset 0 1px 0 rgba(255,255,255,1),0 20px 34px -18px rgba(18,30,46,.5)}
  .btn.primary{background-image:linear-gradient(168deg,#2ba6da,#1780ad);border-color:rgba(255,255,255,.4);color:#fff;
    box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 16px 30px -16px rgba(23,120,159,.7)}
  .btn.ghost{background-image:none;border-color:transparent;box-shadow:none;color:#6d757d}
  .btn.ghost:hover{transform:none;color:var(--ink)}
  .btn.danger{background-image:linear-gradient(168deg,#d0533f,#ab3423);border-color:rgba(255,255,255,.35);color:#fff;
    box-shadow:inset 0 1px 0 rgba(255,255,255,.45),0 16px 30px -16px rgba(171,52,35,.6)}
  .btn:disabled{opacity:.45;cursor:default}
  .btn:disabled:hover{transform:none}
  .btn svg{width:15px;height:15px;flex:none}
  .spacer{flex:1}
  .lock{font-size:11px;letter-spacing:.02em;color:#a4acb3;
    display:inline-flex;align-items:center;gap:8px}

  .banner{display:flex;gap:13px;align-items:flex-start;padding:15px 22px;border-radius:20px;
    border:1px solid rgba(255,255,255,.78);
    background-image:linear-gradient(180deg,rgba(255,255,255,.56),rgba(255,255,255,.3));
    backdrop-filter:blur(18px) saturate(170%);-webkit-backdrop-filter:blur(18px) saturate(170%);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.95);font-size:12.5px;color:#5b6169;line-height:1.55}
  .banner svg{width:16px;height:16px;flex:none;margin-top:1px;stroke:var(--brand)}
  .banner b{color:var(--ink);font-weight:600}
  /* Mesmo amarelo da nota de câmbio quando cai para a taxa de referência:
     o precedente do projeto para "está funcionando, mas degradado". */
  .banner.warn{border-color:rgba(184,134,11,.34);
    background-image:linear-gradient(180deg,rgba(184,134,11,.11),rgba(184,134,11,.04))}
  .banner.warn svg{stroke:var(--warn)}
  .banner.warn b{color:var(--warn)}
  .banner code{font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace;font-size:11.5px}

  /* cabeçalho de colunas */
  .lhead{display:grid;grid-template-columns:96px 2.15fr 1.3fr .8fr 1.2fr 1.05fr 70px;gap:18px;
    align-items:end;padding:0 clamp(18px,2cqw,26px) 2px;font-size:9.5px;letter-spacing:.18em;
    text-transform:uppercase;color:#a4acb3}
  .lhead span{white-space:nowrap}
  .lhead .r{text-align:right}

  .list{display:flex;flex-direction:column;gap:11px}
  .row{position:relative;overflow:hidden;display:grid;
    grid-template-columns:96px 2.15fr 1.3fr .8fr 1.2fr 1.05fr 70px;gap:18px;align-items:center;
    padding:14px clamp(18px,2cqw,26px);border-radius:24px;border:1px solid rgba(255,255,255,.9);
    background-image:linear-gradient(168deg,rgba(255,255,255,.8) 0%,rgba(255,255,255,.42) 52%,rgba(255,255,255,.56) 100%);
    backdrop-filter:blur(28px) saturate(190%);-webkit-backdrop-filter:blur(28px) saturate(190%);
    box-shadow:inset 0 1.5px 0 rgba(255,255,255,1),0 22px 42px -28px rgba(18,30,46,.36),0 2px 6px rgba(18,30,46,.04);
    transition:transform .45s cubic-bezier(.2,.8,.2,1),box-shadow .45s;cursor:pointer}
  .row:hover{transform:translateY(-3px);
    box-shadow:inset 0 1.5px 0 rgba(255,255,255,1),0 36px 58px -28px rgba(18,30,46,.44),0 2px 6px rgba(18,30,46,.05)}
  .row.off{opacity:.5}
  .spec{position:absolute;inset:0;border-radius:inherit;opacity:0;transition:opacity .5s;
    pointer-events:none;mix-blend-mode:overlay}

  .thumb{position:relative;width:96px;height:70px;border-radius:16px;overflow:hidden;display:grid;place-items:center;
    border:1px solid rgba(255,255,255,.85);
    background-image:linear-gradient(180deg,rgba(255,255,255,.7),rgba(255,255,255,.28));
    box-shadow:inset 0 1px 0 rgba(255,255,255,1),inset 0 -6px 12px -10px rgba(24,48,74,.35)}
  .thumb img{width:100%;height:100%;object-fit:cover;display:block}
  .thumb svg{width:34px;height:34px;opacity:.34}
  .nm{position:relative;font-size:15px;font-weight:600;letter-spacing:-.022em;line-height:1.3}
  .nm .un{font-weight:400;color:#6d757d}
  .cx{position:relative;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:#a4acb3;margin-top:5px}
  .cell{position:relative;font-size:13px;color:#5b6169;line-height:1.4}
  .cell.strong{color:var(--ink);font-weight:600;text-align:right;font-variant-numeric:tabular-nums;font-size:14px}
  .usd{display:block;font-size:10px;font-weight:500;color:#a4acb3;margin-top:3px;letter-spacing:.04em}
  .todo{color:#b4bbc1;font-style:italic}
  .tag{position:relative;display:inline-flex;align-items:center;gap:7px;font-size:9.5px;letter-spacing:.14em;
    text-transform:uppercase;color:#7d858d;padding:5px 11px;border-radius:999px;
    border:1px solid rgba(255,255,255,.85);background-image:linear-gradient(180deg,rgba(255,255,255,.66),rgba(255,255,255,.24));
    box-shadow:inset 0 1px 0 rgba(255,255,255,.95);white-space:nowrap}
  .dot{width:5px;height:5px;border-radius:50%;flex:none;background:#b6bec5}
  .tag.ok .dot{background:var(--good)} .tag.build .dot{background:var(--warn)} .tag.dead .dot{background:var(--crit)}
  .acts{position:relative;display:flex;gap:4px;justify-content:flex-end;opacity:0;transition:opacity .25s}
  .row:hover .acts{opacity:1}
  .icobtn{width:32px;height:32px;border-radius:11px;display:grid;place-items:center;cursor:pointer;
    border:1px solid transparent;background:transparent;transition:.18s;text-decoration:none}
  .icobtn:hover{border-color:rgba(255,255,255,.9);
    background-image:linear-gradient(180deg,rgba(255,255,255,.8),rgba(255,255,255,.4));
    box-shadow:inset 0 1px 0 rgba(255,255,255,1)}
  .icobtn svg{width:15px;height:15px;stroke:#6d757d}
  .icobtn.del:hover svg{stroke:var(--crit)}
  .confirm{position:relative;grid-column:1/-1;display:flex;align-items:center;gap:12px;flex-wrap:wrap;
    margin-top:13px;padding-top:13px;border-top:1px solid rgba(24,48,74,.1);font-size:12.5px;color:#5b6169;
    cursor:default}

  /* formulário */
  /* container-type próprio: #scrim fica FORA de .root, então sem isto nenhuma
     container query alcança o modal e ele nunca colapsava para uma coluna. */
  .scrim{container-type:inline-size;container-name:modal;
    position:fixed;inset:0;z-index:60;background:rgba(24,40,58,.34);
    backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:grid;place-items:center;
    padding:22px;overflow:auto}
  .scrim[hidden]{display:none}
  .modal{width:min(660px,100%);border-radius:30px;padding:30px;border:1px solid rgba(255,255,255,.92);
    background-image:linear-gradient(168deg,rgba(255,255,255,.94),rgba(255,255,255,.76));
    backdrop-filter:blur(44px) saturate(190%);-webkit-backdrop-filter:blur(44px) saturate(190%);
    box-shadow:inset 0 1.5px 0 rgba(255,255,255,1),0 40px 90px -24px rgba(15,22,32,.44);
    font-family:inherit}
  .modal h2{margin:0;font-size:20px;font-weight:600;letter-spacing:-.028em}
  .mh{display:flex;justify-content:space-between;align-items:center;margin-bottom:22px}
  .fields{display:grid;grid-template-columns:1fr 1fr;gap:14px}
  .f{display:flex;flex-direction:column;gap:6px}
  .f.full{grid-column:1/-1}
  .f label{font-size:9.5px;letter-spacing:.18em;text-transform:uppercase;color:#a4acb3}
  .f input,.f select{font:inherit;font-size:14px;padding:11px 13px;border-radius:13px;
    border:1px solid rgba(24,48,74,.14);background:rgba(255,255,255,.78);color:var(--ink);width:100%}
  .f input:focus,.f select:focus{outline:2px solid rgba(29,150,203,.35);outline-offset:1px;border-color:var(--brand)}
  .f .hint{font-size:11px;color:#a4acb3}
  .mfoot{display:flex;gap:10px;justify-content:flex-end;margin-top:26px;flex-wrap:wrap}

  .foot{margin-top:auto;display:flex;flex-wrap:wrap;gap:8px 24px;align-items:center;justify-content:space-between;
    padding:15px clamp(18px,2.4cqw,30px);border-radius:999px;border:1px solid rgba(255,255,255,.78);
    background-image:linear-gradient(180deg,rgba(255,255,255,.56),rgba(255,255,255,.3));
    backdrop-filter:blur(18px) saturate(170%);-webkit-backdrop-filter:blur(18px) saturate(170%);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.95),0 14px 28px -22px rgba(18,30,46,.34);
    font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:#96a0a8;white-space:nowrap}
  .foot a{color:#6d757d;letter-spacing:.1em;text-transform:none}

  /* ------------------------------------------------------------------ documentos
     Painel lateral com o cofre de um imóvel. É um container próprio, então os
     cqw daqui para dentro medem o painel, não a página. */
  .dscrim{position:fixed;inset:0;z-index:70;background:rgba(24,40,58,.34);
    backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:flex;justify-content:flex-end}
  .drawer{container-type:inline-size;container-name:drawer;
    position:relative;width:min(760px,100%);height:100%;box-sizing:border-box;
    display:flex;flex-direction:column;overflow:hidden;border-left:1px solid rgba(255,255,255,.92);
    background-image:linear-gradient(168deg,rgba(255,255,255,.95),rgba(255,255,255,.8));
    backdrop-filter:blur(44px) saturate(190%);-webkit-backdrop-filter:blur(44px) saturate(190%);
    box-shadow:-40px 0 90px -20px rgba(15,22,32,.44);
    animation:poolSlide .45s cubic-bezier(.2,.8,.2,1) both}
  .dhead{flex:none;display:flex;align-items:flex-start;gap:16px;
    padding:clamp(20px,3cqw,30px) clamp(20px,3cqw,32px) clamp(14px,2cqw,20px);
    border-bottom:1px solid rgba(24,48,74,.09)}
  .dhead .t{flex:1;min-width:0}
  .dhead h2{margin:0;font-size:clamp(18px,2.6cqw,23px);font-weight:600;letter-spacing:-.028em;line-height:1.25}
  .dhead h2 .un{font-weight:400;color:#6d757d}
  .dhead .sub{margin:6px 0 0;font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;color:#a4acb3}
  .dmsg{flex:none;margin:0;padding:11px clamp(20px,3cqw,32px);font-size:12.5px;color:var(--crit);
    background:rgba(192,57,43,.06);border-bottom:1px solid rgba(24,48,74,.09)}
  .dbody{flex:1;overflow:auto;padding:clamp(18px,2.6cqw,26px) clamp(20px,3cqw,32px) 40px;
    display:flex;flex-direction:column;gap:clamp(16px,2.2cqw,22px)}

  .drop{border-radius:24px;padding:clamp(22px,4cqw,34px) 20px;text-align:center;cursor:pointer;
    border:1.5px dashed rgba(29,150,203,.42);
    background-image:linear-gradient(168deg,rgba(255,255,255,.66),rgba(255,255,255,.3));
    box-shadow:inset 0 1px 0 rgba(255,255,255,.95);
    transition:border-color .3s,background-image .3s,transform .3s}
  .drop:hover,.drop:focus-visible{border-color:rgba(29,150,203,.75);outline:none}
  .drop.over{border-color:var(--brand);border-style:solid;transform:scale(1.006);
    background-image:linear-gradient(168deg,rgba(29,150,203,.14),rgba(29,150,203,.05))}
  .drop svg{width:26px;height:26px;stroke:var(--brand);opacity:.8}
  .drop .t{margin-top:9px;font-size:14px;font-weight:600;letter-spacing:-.02em}
  .drop .h{margin-top:5px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:#a4acb3}

  .queue{display:flex;flex-direction:column;gap:10px}
  .qitem{border-radius:20px;padding:14px 16px;border:1px solid rgba(255,255,255,.9);
    background-image:linear-gradient(168deg,rgba(255,255,255,.82),rgba(255,255,255,.46));
    box-shadow:inset 0 1px 0 rgba(255,255,255,1),0 14px 28px -22px rgba(18,30,46,.34)}
  .qtop{display:flex;align-items:center;gap:12px}
  .qname{flex:1;min-width:0;font-size:13.5px;font-weight:600;letter-spacing:-.018em;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .qsize{font-size:10px;letter-spacing:.1em;color:#a4acb3;font-variant-numeric:tabular-nums;white-space:nowrap}
  .qmeta{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:11px;margin-top:13px}
  .bar{position:relative;height:4px;border-radius:999px;margin-top:13px;overflow:hidden;background:rgba(24,48,74,.1)}
  .bar i{position:absolute;top:0;bottom:0;left:0;width:0;border-radius:999px;
    background-image:linear-gradient(90deg,#2ba6da,#1780ad);transition:width .25s linear}
  .qstat{margin-top:8px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:#a4acb3;
    font-variant-numeric:tabular-nums}
  .qstat.ok{color:var(--good)}
  .qstat.err{margin-top:11px;color:var(--crit);letter-spacing:0;text-transform:none;font-size:12.5px}

  .grp{display:flex;flex-direction:column;gap:9px}
  .glabel{display:flex;align-items:center;gap:12px;font-size:9.5px;letter-spacing:.2em;
    text-transform:uppercase;color:#a4acb3}
  .glabel i{flex:1;height:1px;font-style:normal;
    background-image:linear-gradient(90deg,rgba(24,48,74,.13),rgba(24,48,74,0))}
  .glabel .btn{font-size:12px;padding:7px 14px}

  /* 🚫 .tlabel, .doc, .dicon, .dname, .dmeta e .dinfo saíram em 05/08/2026 com
     docHtml() e typedHtml(): as cinco seções não pagáveis passaram todas para a
     GRADE de cartões (.gal/.gcard), e a parcela já era linha de tabela. */

  /* situação de pagamento — derivada dos comprovantes, não é campo no banco */
  .st{display:inline-flex;align-items:center;gap:5px}
  .st .dot{background:#b6bec5}
  .st.paid .dot{background:var(--good)}
  .st.open .dot,.st.partial .dot{background:var(--warn)}

  /* totais do grupo: Billed e Paid nunca somam na mesma conta */
  /* 🚫 .gtot saiu com a linha de totais da seção (05/08/2026). */

  /* 🚫 .rcpts e o cartão .rcpt saíram junto: comprovante só existe em
     Invoices & Payments, e lá quem o desenha é payReceiptHtml(), com .ritem.
     ⚠️ E `.rcpt` continua sendo a MARCA de um <tr> na tabela — deixar o
     `display:grid` do cartão morto ali era um `<tr>` virando grade, com o único
     <td> caindo na coluna de 26px. Some com o cartão, some o risco. */

  /* "Attach receipt" fica sempre visível: é o caminho mais usado, o boleto
     chega hoje e o comprovante três semanas depois. */
  .attach{grid-column:1/-1;margin-top:9px}
  .attach button{font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace;
    font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--brand);
    background:none;border:0;padding:4px 0;cursor:pointer;display:inline-flex;align-items:center;gap:7px}
  .attach button:hover{color:#1780ad}
  .attach svg{width:13px;height:13px;stroke:currentColor;fill:none}
  /* 🚫 .warnnote saiu: o aviso de que anexar move o documento para
     Invoices & Payments vivia no cartão de lista, que morreu. */
  /* "+ Add New Type" sem sair da tela */
  /* Plano de pagamento: gerar a série inteira de uma vez */
  .planbox{margin:2px 0 12px;padding:14px;border-radius:18px;
    border:1px solid rgba(29,150,203,.28);
    background-image:linear-gradient(168deg,rgba(29,150,203,.07),rgba(29,150,203,.02))}
  .planbox .qmeta{margin-top:0}
  .planrow{display:flex;flex-wrap:wrap;gap:6px 12px;align-items:center;margin-bottom:8px;
    font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:#a4acb3;
    font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace}
  .planrow b{color:#6d757d;font-weight:600}
  .planrow button{font-family:inherit;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;
    color:var(--brand);background:none;border:0;padding:2px 0;cursor:pointer}
  .planrow button:hover{color:#1780ad}
  .planrow button.del{color:var(--crit)}
  .planrow .warn{color:var(--warn);text-transform:none;letter-spacing:.02em}
  /* Editar valor é clicar no número, não abrir formulário */
  .cell{font:inherit;font-family:inherit;font-size:inherit;color:inherit;background:none;
    border:0;border-bottom:1px dashed rgba(29,150,203,.45);padding:0 1px;cursor:text;
    font-variant-numeric:tabular-nums;letter-spacing:inherit}
  .cell:hover{color:var(--brand);border-bottom-color:var(--brand)}
  /* ⚠️ Vazio é um MARCADOR com a FORMA do conteúdo real (XXX,XXX e
     XX/XX/XXXX), não um traço. O traço é curto, e num grupo com valor em cima
     e data embaixo a célula vazia mudava a altura da linha — a tabela perdia
     o alinhamento, que é a razão de ela existir. O sublinhado tracejado
     continua dizendo que dá para clicar. */
  .cell.empty{color:#ccd2d8;border-bottom-color:rgba(29,150,203,.28)}
  .cell.empty:hover{color:var(--brand)}
  /* ⚠️ Derivado não se edita, mas usa a MESMA caixa da célula editável: mesma
     fonte, mesmo padding, mesma borda — só transparente. Sem isso a linha
     mudava de altura conforme a coluna estivesse cheia ou vazia. */
  /* ⚠️ Sem `color` aqui: .cell.ro vem DEPOIS de .cell.empty e, com a mesma
     especificidade, anularia o cinza do marcador. A cor fica a cargo de
     .cell.empty; aqui só a caixa. */
  .cell.ro{border-bottom-color:transparent;cursor:pointer}
  .cell.ro[disabled]{cursor:default}
  .cell.ro:not([disabled]):hover{color:var(--brand);border-bottom-color:rgba(29,150,203,.5)}
  .cellinput{font:inherit;font-size:12px;width:9em;padding:2px 6px;border-radius:8px;
    border:1px solid var(--brand);background:rgba(255,255,255,.9);color:var(--ink);
    font-variant-numeric:tabular-nums}
  .cellinput.date{width:11.5em;text-transform:none;letter-spacing:0}

  /* ---------------------------------------------- tabela das parcelas
     São 37 por imóvel, e alguns terão mais. Cartão por parcela é
     impraticável: a página fica quilométrica antes de existir um documento.
     Aqui a linha é fina e cabem dezenas de uma vez.

     O cabeçalho gruda no topo da janela ao rolar (sticky, top:0). Sem
     container de rolagem próprio de propósito — barra dentro de barra é pior
     que rolar a página, e não há nada fixo no topo para cobri-lo. */
  /* A barra de lote. Só aparece com linha marcada — barra permanente com
     "0 selected" é ruído fixo. Gruda no topo: com 25 linhas abertas, barra no
     rodapé sairia da tela junto com a rolagem.
     ⚠️ z-index acima do thead (3), senão o cabeçalho sticky passa por cima. */
  .bulk{position:sticky;top:0;z-index:5;display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;
    padding:9px 13px;border-radius:16px;border:1px solid rgba(29,150,203,.3);
    background-image:linear-gradient(180deg,rgba(233,246,252,.97),rgba(222,240,250,.97));
    backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
    box-shadow:0 10px 22px -16px rgba(18,30,46,.5)}
  .bulk.danger{border-color:rgba(192,57,43,.32);
    background-image:linear-gradient(180deg,rgba(252,236,234,.97),rgba(250,227,224,.97))}
  .bulk .bn{font-size:12.5px;font-weight:600;letter-spacing:-.01em}
  .bulk .bd{font-size:11.5px;color:#5b6169}
  .bulk .bsp{flex:1}
  .bulk .bf{display:flex;align-items:center;gap:7px}
  .bulk .bf span{font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:#8b949d}
  .bulk select{font:inherit;font-size:12px;padding:5px 9px;border-radius:11px;
    border:1px solid rgba(255,255,255,.9);background:rgba(255,255,255,.75);color:var(--ink);cursor:pointer}
  .bulk .btn{font-size:12px;padding:6px 13px}
  .bulk .btn.ghost.del{color:var(--crit)}

  /* ------------------------------------------------ Marketing: grade
     ⚠️ A miniatura tem proporção DECLARADA (4/3) e object-fit:cover. Deixar a
     imagem decidir daria uma grade em dente de serra — retrato ao lado de
     paisagem —, que é exatamente o que uma grade existe para não fazer.
     O ícone do formato ocupa o MESMO cartão, pela mesma razão. */
  /* A busca por nome, no topo de Documents. Se o nome do arquivo é o que
     identifica o documento, procurar por nome é o caminho principal. */
  .dsearch{display:flex;align-items:center;gap:9px;margin:0 0 12px;
    padding:9px 14px;border-radius:14px;border:1px solid rgba(255,255,255,.9);
    background-image:linear-gradient(168deg,rgba(255,255,255,.8),rgba(255,255,255,.42))}
  .dsearch svg{width:15px;height:15px;flex:none;stroke:#a4acb3;fill:none}
  .dsearch input{flex:1;min-width:0;font:inherit;font-size:13px;border:0;background:none;
    color:var(--ink);padding:2px 0;outline:none}
  .dsearch input::-webkit-search-cancel-button{display:none}
  .dsn{flex:none;font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:#a4acb3;
    font-variant-numeric:tabular-nums}
  .dsx{flex:none;border:0;background:none;cursor:pointer;padding:3px;border-radius:8px;
    line-height:0;color:#b4bbc1}
  .dsx svg{width:13px;height:13px;stroke:currentColor}
  .dsx:hover{color:var(--crit);background:rgba(192,57,43,.08)}

  /* Os grupos de Section do Marketing. Mesma gramática dos grupos da tabela de
     parcelas: cabeçalho clicável, contagem à direita, e nascem FECHADOS. */
  .mgrp + .mgrp{margin-top:8px}
  .mghead{display:flex;align-items:center;gap:9px;width:100%;text-align:left;font:inherit;
    padding:9px 12px;border-radius:13px;border:1px solid rgba(255,255,255,.88);cursor:pointer;
    background-image:linear-gradient(168deg,rgba(255,255,255,.7),rgba(255,255,255,.32))}
  .mghead:hover .t{color:var(--brand)}
  .mghead .ch{width:14px;height:14px;flex:none;stroke:#8b949d;fill:none;transition:transform .25s}
  .mgrp.open .ch{transform:rotate(90deg)}
  .mghead .t{flex:1;font-size:13px;font-weight:600;letter-spacing:-.01em;transition:color .2s;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .mghead .n{flex:none;font-size:8.5px;letter-spacing:.12em;text-transform:uppercase;color:#a4acb3}
  .mgrp .gal{margin-top:9px}

  /* 🚫 `.gtp` saiu: o rótulo da Section vive no cabeçalho do grupo. */

  .gal{display:grid;grid-template-columns:repeat(auto-fill,minmax(168px,1fr));gap:12px}
  .gcard{position:relative;border-radius:16px;overflow:hidden;
    border:1px solid rgba(255,255,255,.9);
    background-image:linear-gradient(168deg,rgba(255,255,255,.78),rgba(255,255,255,.4));
    transition:box-shadow .25s,transform .25s}
  .gcard:hover{transform:translateY(-2px);box-shadow:0 16px 28px -20px rgba(18,30,46,.55)}
  .gcard.iscover{border-color:rgba(29,150,203,.5)}
  .gcard.sel{border-color:rgba(29,150,203,.55);box-shadow:0 0 0 2px rgba(29,150,203,.18)}
  /* A caixa de seleção do cartão: canto superior esquerdo, sobre a miniatura.
     Aparece no hover e fica visível enquanto marcada — senão o dono perde de
     vista o que selecionou ao mover o mouse. */
  .gpick{position:absolute;top:6px;left:6px;z-index:2;display:grid;place-items:center;
    width:22px;height:22px;border-radius:7px;background:rgba(255,255,255,.9);
    backdrop-filter:blur(6px);opacity:0;transition:opacity .2s;cursor:pointer}
  .gcard:hover .gpick,.gcard:focus-within .gpick,.gcard.sel .gpick{opacity:1}
  .gpick input{width:14px;height:14px;margin:0;cursor:pointer;accent-color:var(--brand)}
  .gopen{display:block;text-decoration:none}
  .gthumb{display:block;position:relative;width:100%;aspect-ratio:4/3;overflow:hidden;
    background:rgba(24,48,74,.055)}
  .gthumb img{width:100%;height:100%;object-fit:cover;display:block}
  .gph{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;
    justify-content:center;gap:6px}
  .gph svg{width:34px;height:34px;stroke:#b4bbc1;fill:none}
  .gph i{font-style:normal;font-size:8.5px;letter-spacing:.16em;color:#b4bbc1;
    font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace}
  .gmeta{padding:9px 11px 11px}
  .gnm{font-size:12px;font-weight:500;letter-spacing:-.01em;color:var(--ink);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .gsb{margin-top:3px;font-size:9px;letter-spacing:.1em;text-transform:uppercase;color:#b4bbc1}
  .gcov{position:absolute;top:8px;left:8px;font-size:8px;letter-spacing:.16em;text-transform:uppercase;
    color:#fff;background:rgba(23,120,159,.9);padding:3px 7px;border-radius:999px}
  /* As ações flutuam sobre a miniatura, no hover — no rodapé roubariam a altura
     de todos os cartões para servir a um de cada vez. */
  .gcard .dacts{position:absolute;top:6px;right:6px;display:flex;gap:2px;padding:2px;
    border-radius:11px;background:rgba(255,255,255,.86);backdrop-filter:blur(8px);
    opacity:0;transition:opacity .2s}
  .gcard:hover .dacts,.gcard:focus-within .dacts{opacity:1}
  .gcard .dacts .icobtn{width:24px;height:24px;border-radius:7px}
  .gcard .dacts .icobtn svg{width:13px;height:13px}
  /* Formulário e confirmação ocupam o cartão inteiro: dentro de 168px não cabe
     um formulário ao lado de nada. */
  .gcard .dedit,.gcard .confirm{padding:11px}
  @container (max-width: 620px){
    .gal{grid-template-columns:repeat(auto-fill,minmax(132px,1fr))}
    .gcard .dacts{opacity:1}
  }
  /* O formulário em modo lote: a faixa diz em quantas ele vai mexer, e a borda
     azul separa "estou editando uma linha" de "estou editando 23". */
  .dedit.lote{box-shadow:inset 3px 0 0 var(--brand)}
  .bnote{margin:0 0 12px;font-size:12px;color:#3f474f;line-height:1.5}
  .bnote b{color:var(--brand)}
  .bulk .btn.ghost.del:hover{background:rgba(192,57,43,.09)}

  .ptwrap{margin:0 -4px;overflow-x:auto}
  .ptable{width:100%;border-collapse:separate;border-spacing:0;
    font-size:12px;font-variant-numeric:tabular-nums}
  .ptable th{position:sticky;top:0;z-index:3;
    font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace;
    font-size:9px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;
    color:#a4acb3;text-align:left;padding:7px 8px;white-space:nowrap;
    background:#eef2f6;border-bottom:1px solid rgba(24,48,74,.12)}

  .ptable th.c-g{text-align:right}
  /* A nota na cabeça da coluna: por que este total é menor do que parece.
     🚫 Não é alerta — é informação sobre o número, no lugar onde ele está. */
  .thnote{display:block;font-style:normal;font-weight:400;font-size:8px;letter-spacing:.06em;
    text-transform:none;color:var(--warn);margin-top:2px;white-space:nowrap}
  .ptable th.c-st{text-align:center}
  .ptable th .hd{display:inline-block;width:13px;height:13px}
  .ptable th .hd svg{width:13px;height:13px;stroke:#a4acb3;fill:none;vertical-align:top}
  /* ⚠️ ALTURA DECLARADA. Sem ela a linha media o conteúdo, e conteúdo diferente
     dava altura diferente — linha vazia mais alta que linha cheia, que é o
     oposto do que uma tabela existe para fazer. Com altura fixa e
     vertical-align:middle, cheia e vazia ocupam o mesmo espaço por construção,
     não por coincidência de métricas. */
  .ptable td{padding:2px 8px;border-bottom:1px solid rgba(24,48,74,.055);
    vertical-align:middle;line-height:1.5;height:40px;box-sizing:border-box}
  .ptable tr.prow{height:40px}
  .prow:hover td{background:rgba(29,150,203,.05)}
  /* Vencido chama atenção sem gritar: uma faixa na borda, não a linha inteira
     vermelha — com 37 linhas, o vermelho em bloco vira ruído. */
  .prow.st-overdue td:first-child{box-shadow:inset 2px 0 0 var(--crit)}
  .prow.st-paid .c-lb{color:#6d757d}

  /* ⚠️ A primeira coluna é a IDENTIFICAÇÃO da linha: é a última que pode
     encolher, não a primeira. Com `max-width:1px` ela cedia todo o espaço às
     outras e o rótulo virava "0" com reticências. Agora tem piso, e quem cede
     é a rolagem horizontal do .ptwrap. */
  .c-lb{min-width:190px;width:99%}
  .pname{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
    font-weight:500;letter-spacing:-.01em}
  .pfile{display:block;font-style:normal;font-size:9px;letter-spacing:.04em;color:#c3c9ce;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:1px}

  /* A linha de GRUPO de tipo. É uma linha da própria tabela, e não um cabeçalho
     por cima dela: só assim os totais do grupo caem exatamente sob Contract,
     Bank Slip e Bank Receipt. Mesma altura declarada das outras — 40px — porque
     nesta tabela altura é construção, não medida.
     🚫 Nascem FECHADAS: a seção inteira tem de caber numa tela. */
  .pgrp{cursor:pointer;background:rgba(24,48,74,.035)}
  .pgrp:hover{background:rgba(29,150,203,.07)}
  .pgrp:focus-visible{outline:2px solid var(--brand);outline-offset:-2px}
  .pgrp td{border-bottom:1px solid rgba(24,48,74,.09)}
  .pgrp .gname{display:flex;align-items:center;gap:5px;height:18px;
    font-weight:600;font-size:12.5px;letter-spacing:-.01em;
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pgrp .ch{width:13px;height:13px;flex:none;stroke:#8b949d;fill:none;transition:transform .25s}
  .pgrp.open .ch{transform:rotate(90deg)}
  .pgrp .gsub{display:block;height:14px;font-size:9px;letter-spacing:.12em;text-transform:uppercase;
    font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace;color:#b4bbc1;
    padding-left:18px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .pgrp .gv{font-weight:600;color:#5b6169}
  /* ⚠️ Escondida por CLASSE, nunca removida do DOM: commitOrder() lê todas as
     .prow para mandar a ordem INTEIRA da seção ao servidor, e meia lista
     apagaria a outra metade. */
  .prow.hid,.xrow.hid{display:none}

  /* Grupo de coluna: VALOR em cima, DATA embaixo. Contract traz o vencimento do
     PLANO e Bank Slip o do BOLETO — as duas verdades lado a lado, que é a única
     janela para a carência da obra.
     ⚠️ Largura declarada: .c-lb pede 99% e espreme o resto até o mínimo; sem
     isto a data corta. */
  .c-g{min-width:132px;width:132px;white-space:nowrap;text-align:right}
  /* ⚠️ FLEX, não linha de texto. Enquanto isto era layout em linha, a altura
     dependia da caixa de linha — e a caixa de linha muda com o que está dentro:
     um ícone de 17px, um botão com borda, ou nada. Era daí que vinha a célula
     vazia deslocada, com o valor caindo na linha de baixo.
     Com flex, o ícone e o texto são itens na MESMA linha por construção, a
     altura é a declarada, e o alinhamento à direita é o mesmo nos dois estados. */
  .gv,.gd{display:flex;align-items:center;justify-content:flex-end;
    white-space:nowrap;margin:0;overflow:hidden}
  .gv{height:18px}
  .gd{height:14px;font-size:10px;color:#b4bbc1}
  .gv .cell,.gd .cell,.gv .clip,.gd .clip,.gv .corr,.gv .fxretry{flex:none}
  .gd .cell{font-size:10px;line-height:12px}
  .gv .cell{line-height:16px}
  .gd .cell{color:inherit;font-size:10px}
  /* O boleto veio com outra data que a do contrato: a data do plano fica
     amarela, e as duas continuam visíveis. */
  .gd.slip .cell{color:var(--warn);border-bottom-color:rgba(184,134,11,.5)}
  .c-g .cellinput{width:8.5em;font-size:11px}
  .c-g .cellinput.date{width:10.5em}
  /* Boleto acima do contrato: um triângulo discreto, e o quanto no title. */
  .corr{font-style:normal;font-size:8px;color:var(--warn);margin-left:3px;cursor:help}
  /* Total dos comprovantes: é SOMA, não campo — corrigir se faz no pagamento,
     na linha dele. Clicar abre a lista, que é onde a soma se explica. */
  .parts{font-style:normal;font-size:8.5px;color:var(--brand);margin-left:4px;
    font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace}
  /* A cotação usada, sob o valor convertido: número pequeno, sem competir com
     o dinheiro. O título da célula traz a conta inteira, pagamento a pagamento. */
  .c-usd .gd{font-variant-numeric:tabular-nums}
  .fxretry{border:0;background:none;padding:0;margin-left:5px;cursor:pointer;
    color:var(--warn);display:inline-grid;place-items:center;width:14px;height:14px}
  .fxretry svg{width:11px;height:11px;stroke:currentColor;fill:none}
  .fxretry:hover{color:#8a6508}
  .c-st{text-align:center;white-space:nowrap;width:1%}
  /* A nota, logo depois do Status. Coluna estreita: ela carrega um ícone que
     diz sim ou não, e o texto abre embaixo da linha. */
  .c-nt{width:26px;text-align:center;padding-left:2px;padding-right:2px}
  .noteline{margin:0;padding:8px 12px;border-radius:12px;font-size:12.5px;color:#5b6169;
    line-height:1.5;background:rgba(24,48,74,.045);white-space:pre-wrap;overflow-wrap:anywhere}
  .c-st .st{font-size:9px;letter-spacing:.1em;text-transform:uppercase}
  /* Boleto e Comprovante: duas colunas estreitas logo depois do nome, sempre
     visíveis. Largura fixa para os clipes ficarem em coluna, não dançando com
     o comprimento do rótulo ao lado. */

  /* Punho: só ele arrasta. Linha inteira arrastável impede selecionar texto e
     briga com o clique que edita a célula. */
  .c-gr{width:20px;padding-left:4px;padding-right:0}
  /* Caixa de seleção: coluna estreita, primeira de todas. */
  .c-ck{width:22px;padding-left:6px;padding-right:0}
  .c-ck input{width:14px;height:14px;margin:0;cursor:pointer;accent-color:var(--brand);
    vertical-align:middle}
  .prow.sel td{background:rgba(29,150,203,.075)}
  .grip{display:inline-grid;place-items:center;width:16px;height:20px;cursor:grab;
    color:#d2d8dd;transition:color .2s}
  .grip svg{width:14px;height:14px;stroke:currentColor;fill:none}
  .prow:hover .grip{color:#a4acb3}
  .grip:active{cursor:grabbing}
  .prow.dragging{opacity:.4}
  .prow.dropmark td{box-shadow:inset 0 2px 0 var(--brand)}

  .c-ac{width:1%;text-align:right;white-space:nowrap}
  .rowacts{display:inline-flex;gap:1px;vertical-align:middle}
  .c-ac .icobtn{width:26px;height:26px;border-radius:8px;opacity:0;transition:opacity .2s}
  .c-ac .icobtn svg{width:13px;height:13px}
  .prow:hover .c-ac .icobtn,.prow:focus-within .c-ac .icobtn{opacity:1}

  /* O clipe DIZ se o documento existe: cheio abre, apagado anexa. */
  /* O clipe vive DENTRO do grupo, à esquerda do valor: é o ícone do arquivo
     daquele grupo. Cinza = não há arquivo e clicar anexa; marcado = há e clicar
     abre. O estado é o do ARQUIVO, nunca o dos números. */
  /* ⚠️ O clipe cabe DENTRO da linha de 17px e não a estica: sem isto ele
     empurrava a caixa de linha para ~24px, e a coluna com clipe ficava mais
     alta que a sem — Paid (USD), por exemplo. */
  .clip{position:relative;display:inline-grid;place-items:center;width:17px;height:17px;
    border-radius:5px;border:0;background:none;cursor:pointer;padding:0;margin-right:4px;
    color:#d2d8dd;transition:color .2s,background .2s}
  .clip svg{width:12px;height:12px;stroke:currentColor;fill:none}
  .clip:hover{color:#8b949d;background:rgba(24,48,74,.06)}
  /* ⚠️ A diferença não pode ser SÓ a cor. Com 37 linhas, cinza-claro e azul no
     mesmo desenho de 13px não se lê de relance — e a coluna existe justamente
     para dizer, batendo o olho, o que falta anexar. Cheio vira um chip azul
     preenchido: muda a mancha da coluna, não só o tom. */
  .clip.on{color:#fff;background:var(--brand);box-shadow:0 1px 3px rgba(23,120,159,.4)}
  .clip.on:hover{background:#1780ad;color:#fff}
  .clip.off{color:#dde2e6;cursor:default}
  .clip .cnt{position:absolute;top:-2px;right:-3px;font-style:normal;font-size:7.5px;font-weight:600;
    line-height:1;padding:1.5px 3px;border-radius:5px;background:var(--brand);color:#fff}

  /* .grow era o cabeçalho de subgrupo por tipo dentro da tabela. Saiu: a
     parcela sem tipo fica na MESMA lista, sem virar grupo. */
  .xrow td{padding:0 8px 9px;border-bottom:1px solid rgba(24,48,74,.055)}

  /* Comprovantes: abertos sob demanda pelo clipe, some da altura quando
     ninguém está olhando e continua alcançável. */
  .rlist{padding-left:14px;border-left:2px solid rgba(29,150,203,.22);
    display:flex;flex-direction:column;gap:4px}
  .ritem{display:flex;align-items:center;gap:9px;padding:4px 0}
  /* Cada comprovante é um PAGAMENTO: valor e data próprios, editáveis na
     própria linha dele. Sem isso, cinco Pix numa parcela tinham um campo só e
     cada lançamento apagava o anterior. */
  .rpaid{flex:none;min-width:96px;text-align:right;font-size:11.5px;
    font-variant-numeric:tabular-nums}
  .rdate{flex:none;min-width:96px;text-align:right;font-size:10px;color:#b4bbc1}
  .rdate .cell{font-size:10px;color:inherit}
  .ric{width:20px;height:20px;display:grid;place-items:center;flex:none}
  .ric svg{width:13px;height:13px;stroke:#a4acb3}
  .rname{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:11.5px}
  .rmeta{font-size:9px;letter-spacing:.1em;color:#b4bbc1;white-space:nowrap}
  .racts{display:flex;gap:1px;flex:none}
  .racts .icobtn{width:25px;height:25px;border-radius:8px}
  .racts .icobtn svg{width:12px;height:12px}
  .rmore button{font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace;
    font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--brand);
    background:none;border:0;padding:3px 0;cursor:pointer;display:inline-flex;align-items:center;gap:6px}
  .rmore svg{width:12px;height:12px;stroke:currentColor;fill:none}

  /* O formulário da metade, embaixo da parcela: valor, data e arquivo. */
  .halfbox{display:flex;flex-wrap:wrap;align-items:flex-end;gap:9px 12px;
    margin:2px 0 8px;padding:10px 12px;border-radius:14px;
    border:1px solid rgba(29,150,203,.28);
    background-image:linear-gradient(168deg,rgba(29,150,203,.07),rgba(29,150,203,.02))}
  .hlab{font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--brand);
    align-self:center}
  .hf{display:flex;flex-direction:column;gap:4px}
  .hf span{font-size:8.5px;letter-spacing:.14em;text-transform:uppercase;color:#a4acb3}
  .hf input{font:inherit;font-size:12px;padding:5px 8px;border-radius:9px;
    border:1px solid rgba(24,48,74,.16);background:rgba(255,255,255,.9);color:var(--ink);
    font-variant-numeric:tabular-nums}
  .hf.file input{font-size:10.5px;padding:4px 0;border:0;background:none;max-width:190px}
  .hnote{font-size:9px;letter-spacing:.14em;color:#b4bbc1;align-self:center}
  .halfbox .btn{font-size:12px;padding:6px 13px}
  .hmsg{margin:0 0 9px;font-size:11.5px;color:var(--crit)}
  /* Amarelo: está funcionando, mas confira — o mesmo precedente da nota de
     câmbio e da faixa do índice de deduplicação. */
  .hwarn{margin:0 0 9px;padding:8px 11px;border-radius:11px;font-size:11.5px;color:#7a5c07;
    background:rgba(184,134,11,.1);border:1px solid rgba(184,134,11,.3)}
  /* O vencimento do contrato, mostrado só quando o boleto veio com outra data.
     É a única janela para o deslize da obra. */
  /* 🚫 .dmeta .plan saiu com .dmeta: o deslize do plano hoje é .gd.slip. */
  .newtype{display:flex;gap:7px;margin-top:8px;flex-wrap:wrap}
  .newtype input{flex:1;min-width:130px;font:inherit;font-size:14px;padding:9px 12px;border-radius:12px;
    border:1px solid rgba(24,48,74,.14);background:rgba(255,255,255,.82);color:var(--ink)}
  .newtype .btn{font-size:12px;padding:8px 14px}

  /* comprovante anexado ainda na fila, antes de subir */
  .qrcpts{margin-top:11px;padding-left:13px;display:flex;flex-direction:column;gap:9px;
    border-left:2px solid rgba(29,150,203,.22)}
  .qrcpt{border-radius:14px;padding:10px 12px;border:1px solid rgba(255,255,255,.85);
    background-image:linear-gradient(168deg,rgba(255,255,255,.64),rgba(255,255,255,.32))}
  .qrcpt .qname{font-size:12px}
  .dacts{display:flex;gap:2px;justify-content:flex-end;opacity:0;transition:opacity .25s}
  .doc:hover .dacts,.doc:focus-within .dacts{opacity:1}
  .dedit{grid-column:1/-1;margin-top:13px;padding-top:13px;border-top:1px solid rgba(24,48,74,.1)}
  .dedit .mfoot{margin-top:16px}
  .empty{padding:24px 0;text-align:center;font-size:12.5px;color:#a4acb3}

  /* container queries — a grade se reorganiza pela largura do container, sem media query */
  @container drawer (max-width: 560px){
    .qmeta{grid-template-columns:1fr}
    .dacts{opacity:1}
  }
  @container modal (max-width: 620px){
    .fields{grid-template-columns:1fr}
  }
  /* Abaixo de 1100px a grade cai para 2 colunas: as listas ocupam a fileira
     inteira e as outras quatro ficam lado a lado, duas a duas. */
  @container (max-width: 1100px){
    .kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
  }
  @container (max-width: 620px){
    .kpis{grid-template-columns:1fr}
  }

  @container (max-width: 1020px){
    .lhead{display:none}
    .row{grid-template-columns:88px 1fr auto;
      grid-template-areas:"th nm act" "th meta meta" "th tags val";gap:6px 16px;padding:16px}
    .row .thumb{grid-area:th;align-self:start}
    .row .c-nm{grid-area:nm}
    .row .c-loc{grid-area:meta;font-size:12.5px}
    .row .c-type{display:none}
    .row .c-tags{grid-area:tags;margin-top:6px}
    .row .c-val{grid-area:val;text-align:right;align-self:center;white-space:nowrap;margin-top:6px}
    .row .acts{grid-area:act;opacity:1}
  }
  /* No computador é tabela; no celular vira lista. A largura que manda é a do
     CARTÃO DA SEÇÃO, não a da janela — por isso @container. */
  @container (max-width: 780px){
    .ptwrap{overflow-x:visible}
    .ptable,.ptable tbody,.ptable tr,.ptable td{display:block;width:auto}
    .ptable thead{display:none}
    .prow{position:relative;margin-top:7px;padding:9px 12px;border-radius:14px;
      border:1px solid rgba(255,255,255,.9);
      background-image:linear-gradient(168deg,rgba(255,255,255,.8),rgba(255,255,255,.42));
      display:grid;grid-template-columns:1fr auto;gap:1px 10px}
    .prow td{border-bottom:0;padding:1px 0}
    .prow.st-overdue td:first-child{box-shadow:none}
    .prow.st-overdue{border-left:2px solid var(--crit)}
    .prow:hover td{background:none}
    /* O rótulo da coluna some com o cabeçalho, então volta em cada célula. */
    .prow td[data-l]::before{content:attr(data-l) " ";
      font-family:ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace;
      font-size:8.5px;letter-spacing:.14em;text-transform:uppercase;color:#b4bbc1;
      margin-right:6px}
    .prow .c-lb{grid-column:1/-1}
    .prow .c-lb::before{content:none}
    .prow .c-g,.prow .c-st,.prow .c-nt{text-align:left;grid-column:1;min-width:0;width:auto}
    /* Na lista o grupo vira uma linha só: rótulo, valor e data em sequência —
       empilhar de novo dobraria a altura sem ganhar nada numa tela estreita. */
    .prow .c-g .gv,.prow .c-g .gd{display:inline}
    .ritem{flex-wrap:wrap}
    .rpaid,.rdate{min-width:0;text-align:left}
    .prow .c-g .gd{margin-left:8px}
    /* Na lista o grupo também vira bloco — rótulo em cima, totais em sequência. */
    .pgrp{margin-top:9px;padding:8px 12px;border-radius:12px;
      display:grid;grid-template-columns:1fr auto;gap:1px 10px}
    .pgrp td{border-bottom:0;padding:1px 0}
    .pgrp .c-lb{grid-column:1/-1}
    .pgrp .c-g,.pgrp .c-st{text-align:left;grid-column:1;min-width:0;width:auto}
    .pgrp .c-g .gv,.pgrp .c-g .gd{display:inline}
    .prow .c-ck{position:absolute;top:8px;right:34px;width:auto;padding:0}
    .pgrp .c-ck{grid-column:1;width:auto}
    .prow .c-gr{position:absolute;top:8px;right:10px;width:auto;padding:0}
    .prow .c-ac{grid-column:1/-1;text-align:left;width:auto;margin-top:5px}
    .prow .c-ac .icobtn{opacity:1}
    .halfbox{flex-direction:column;align-items:stretch}
    .prow .pon{display:inline;margin-left:6px}
    .xrow td{padding:0 0 8px}
  }

  @container (max-width: 1020px){
    .kpis{grid-template-columns:repeat(2,minmax(0,1fr))}
  }
  @container (max-width: 620px){
    .kpis{grid-template-columns:1fr}
    .thumb{width:74px;height:58px}
    .row{grid-template-columns:74px 1fr auto}
    /* .kpis já é grade de 1 coluna aqui; a regra antiga de flex saiu junto. */
  }
  @media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
