/* ============================================================
   Tiëtha — identidade "caderno de desenho arquitetônico"
   Porcelana + grafite quente + bronze (freijó dos renders do estúdio).
   Hairlines no lugar de sombras; rótulos como anotações de prancha.

   Fase 3 (CRM): a folha saiu do <style> do index.html porque agora serve
   seis módulos. As regras da Fase 1 estão intactas — o estúdio não muda de
   aparência, só de endereço.
   ============================================================ */
:root {
  --ground: #FAF9F6;
  --panel: #FFFFFF;
  --rail: #F5F3EF;
  --ink: #211E1A;
  --ink-soft: #6B655C;
  --ink-faint: #9B948A;
  --line: #E4E0D8;
  --line-soft: #EEEBE4;
  --accent: #8A6240;
  --accent-ink: #FFFFFF;
  --accent-wash: #F3ECE3;
  --ok: #56714F;   --ok-wash: #EBF0E7;
  --wait: #96702D; --wait-wash: #F5EDDD;
  --fail: #9C4530; --fail-wash: #F6E7E2;
  --carvao: #16130F;           /* painel editorial do login — fixo nos 2 temas */
  --carvao-ink: #EFEBE3;
  --display: "Instrument Serif", Georgia, "Times New Roman", serif;
  --sans: "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Spline Sans Mono", ui-monospace, "Cascadia Code", Consolas, monospace;
  --r: 2px;
}
@media (prefers-color-scheme: dark) {
  :root {
    --ground: #151310; --panel: #1C1915; --rail: #12100D;
    --ink: #EAE5DC; --ink-soft: #A39B8E; --ink-faint: #6E675C;
    --line: #2E2A24; --line-soft: #24201A;
    --accent: #C79A66; --accent-ink: #1A130B; --accent-wash: #2A2318;
    --ok: #8FB183;   --ok-wash: #1E241B;
    --wait: #CBA050; --wait-wash: #2A2314;
    --fail: #C97B63; --fail-wash: #2A1B15;
  }
}
:root[data-theme="dark"] {
  --ground: #151310; --panel: #1C1915; --rail: #12100D;
  --ink: #EAE5DC; --ink-soft: #A39B8E; --ink-faint: #6E675C;
  --line: #2E2A24; --line-soft: #24201A;
  --accent: #C79A66; --accent-ink: #1A130B; --accent-wash: #2A2318;
  --ok: #8FB183;   --ok-wash: #1E241B;
  --wait: #CBA050; --wait-wash: #2A2314;
  --fail: #C97B63; --fail-wash: #2A1B15;
}
:root[data-theme="light"] {
  --ground: #FAF9F6; --panel: #FFFFFF; --rail: #F5F3EF;
  --ink: #211E1A; --ink-soft: #6B655C; --ink-faint: #9B948A;
  --line: #E4E0D8; --line-soft: #EEEBE4;
  --accent: #8A6240; --accent-ink: #FFFFFF; --accent-wash: #F3ECE3;
  --ok: #56714F;   --ok-wash: #EBF0E7;
  --wait: #96702D; --wait-wash: #F5EDDD;
  --fail: #9C4530; --fail-wash: #F6E7E2;
}

* { box-sizing: border-box; }
/* O atributo `hidden` esconde pelo estilo do navegador, e QUALQUER `display`
   declarado aqui vence esse padrao. Foi o que aconteceu com o véu do menu:
   `.scrim { display: block }` na media query de celular deixou um botão
   transparente do tamanho da tela por cima de tudo, e o app inteiro parou de
   responder ao toque — sem nada visível para denunciar o motivo. */
[hidden] { display: none !important; }
html, body { height: 100%; }
body {
  margin: 0; font-family: var(--sans); background: var(--ground); color: var(--ink);
  font-size: 14px; line-height: 1.55; -webkit-font-smoothing: antialiased;
}
button { font-family: inherit; cursor: pointer; }
input, select, textarea { font-family: inherit; }
h1, h2, h3 { margin: 0; text-wrap: balance; }
a { color: var(--accent); }

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.eyebrow {
  font-size: 10px; text-transform: uppercase; letter-spacing: .16em;
  color: var(--ink-faint); font-weight: 500;
}
.faint { color: var(--ink-faint); }
.soft { color: var(--ink-soft); }
.right { text-align: right; }
.nowrap { white-space: nowrap; }

/* ---------- marca: cruz de registro de prancha ---------- */
.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark { width: 26px; height: 26px; flex: none; position: relative; }
.brand-mark::before {
  content: ""; position: absolute; inset: 4px;
  border: 1px solid currentColor; opacity: .85;
}
.brand-mark::after {
  content: ""; position: absolute; inset: 0;
  background:
    linear-gradient(currentColor 0 0) 50% 50% / 1px 100% no-repeat,
    linear-gradient(currentColor 0 0) 50% 50% / 100% 1px no-repeat;
  opacity: .9;
}
.brand-name { font-family: var(--display); font-size: 20px; letter-spacing: .01em; }

/* ---------- login editorial: prancha + formulario ---------- */
#login { min-height: 100vh; min-height: 100dvh; display: grid; grid-template-columns: 1.15fr 1fr; }
@media screen and (max-width: 860px) { #login { grid-template-columns: 1fr; } }

.login-hero {
  background: var(--carvao); color: var(--carvao-ink);
  display: flex; flex-direction: column; justify-content: space-between;
  padding: 48px 52px; position: relative; overflow: hidden; min-height: 380px;
}
.login-hero .brand { color: var(--carvao-ink); }
.login-hero .brand-mark { color: #C79A66; }
.hero-plan {
  position: absolute; right: -6%; bottom: -4%; width: 78%; max-width: 640px;
  opacity: .5; pointer-events: none;
}
.hero-plan path { stroke: #C79A66; stroke-width: .8; fill: none; }
.hero-copy { position: relative; max-width: 30ch; margin-top: 9vh; }
.hero-copy h1 {
  font-family: var(--display); font-weight: 400; font-size: clamp(30px, 3.6vw, 44px);
  line-height: 1.12; letter-spacing: .005em;
}
.hero-copy p { color: #B4AB9D; font-size: 14px; margin: 18px 0 0; max-width: 34ch; }
.hero-meta {
  position: relative; font-size: 11px; color: #8D8474; letter-spacing: .08em;
  display: flex; gap: 18px;
}
@media screen and (max-width: 860px) {
  .login-hero { min-height: 0; padding: 32px 28px; }
  .hero-copy { margin-top: 12px; }
  .hero-plan { display: none; }
  .hero-meta { display: none; }
}

.login-pane { display: grid; place-items: center; padding: 40px 24px; }
.login-card { width: 100%; max-width: 340px; }
.login-sub { color: var(--ink-soft); margin: 6px 0 30px; font-size: 13px; }

/* ---------- formulario ---------- */
.field { margin-bottom: 16px; }
.field label {
  display: block; font-size: 10px; text-transform: uppercase; letter-spacing: .14em;
  color: var(--ink-soft); margin-bottom: 7px; font-weight: 500;
}
.field input, .field select, .field textarea {
  width: 100%; padding: 11px 12px; border: 1px solid var(--line);
  border-radius: var(--r); background: var(--panel); color: var(--ink); font-size: 14px;
  transition: border-color .15s;
}
.field textarea { min-height: 78px; resize: vertical; line-height: 1.5; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent);
}
.field .dica { font-size: 11px; color: var(--ink-faint); margin-top: 5px; }
.grid-campos { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
.grid-campos .largo { grid-column: 1 / -1; }
@media screen and (max-width: 560px) { .grid-campos { grid-template-columns: 1fr; } }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 18px; border-radius: var(--r); border: 1px solid var(--line);
  background: var(--panel); color: var(--ink);
  font-size: 12px; font-weight: 500; letter-spacing: .06em;
  transition: border-color .15s, background .15s, color .15s;
}
.btn:hover { border-color: var(--ink-faint); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn-primary {
  background: var(--accent); color: var(--accent-ink); border-color: var(--accent);
  text-transform: uppercase; letter-spacing: .1em; font-size: 11.5px;
}
.btn-primary:hover { filter: brightness(1.07); border-color: var(--accent); }
.btn-sm { padding: 7px 14px; font-size: 11px; }
.btn-perigo { color: var(--fail); border-color: color-mix(in srgb, var(--fail) 35%, transparent); }
.btn-perigo:hover { border-color: var(--fail); }
.btn:disabled { opacity: .45; cursor: not-allowed; }
.login-card .btn-primary, .rail-actions .btn-primary { width: 100%; padding: 12px 18px; }
.btn-linha { background: none; border: none; color: var(--accent); padding: 0; font-size: 12px; }
.btn-linha:hover { text-decoration: underline; }

.link-row { margin-top: 22px; font-size: 13px; color: var(--ink-soft); }
.link-row button {
  background: none; border: none; color: var(--accent); font-weight: 500; padding: 0;
  font-size: 13px;
}
.msg { font-size: 13px; padding: 10px 12px; border-radius: var(--r); margin-bottom: 16px; }
.msg-err { background: var(--fail-wash); color: var(--fail); border: 1px solid color-mix(in srgb, var(--fail) 25%, transparent); }

/* ---------- casca da aplicacao ----------
   `dvh` (dynamic viewport height) e nao `vh`: no celular a barra de endereco
   entra e sai conforme a rolagem, e `100vh` mede a tela COM ela recolhida. O
   resultado era um app 60-90px mais alto que o visivel, com o rodape do menu
   cortado embaixo. `100vh` fica como reserva para navegador antigo. */
#app { display: none; grid-template-columns: 236px 1fr; height: 100vh; height: 100dvh; }
.rail {
  background: var(--rail); border-right: 1px solid var(--line);
  display: flex; flex-direction: column; min-height: 0;
}
.rail-head {
  padding: 22px 20px 18px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
/* `.topbar`, `.scrim` e `.so-mobile` nascem escondidos, mas a regra está lá no
   fim do arquivo, junto da media query que os liga. Aqui em cima ela perdia:
   `.so-mobile { display: none }` e `.icon-btn { display: grid }` têm a mesma
   especificidade, e o ✕ de fechar o menu — que é um `.icon-btn` — aparecia no
   desktop, onde não há menu para fechar. */
.rail-head .brand-mark { color: var(--accent); }
.rail-nav { padding: 12px 10px 6px; display: flex; flex-direction: column; gap: 1px; }
.nav-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 9px 12px; border-radius: var(--r); border: 1px solid transparent;
  background: none; color: var(--ink-soft); font-size: 13px; font-weight: 500;
}
.nav-item:hover { background: var(--line-soft); color: var(--ink); }
.nav-item.ativo { background: var(--panel); border-color: var(--line); color: var(--ink); }
.nav-item .glifo {
  width: 16px; text-align: center; font-size: 13px; color: var(--ink-faint); flex: none;
}
.nav-item.ativo .glifo { color: var(--accent); }
.nav-item .selo {
  margin-left: auto; font-family: var(--mono); font-size: 10px; padding: 1px 6px;
  border-radius: var(--r); background: var(--fail-wash); color: var(--fail);
}
.rail-sep {
  margin: 10px 22px 6px; border-top: 1px solid var(--line);
  padding-top: 10px; font-size: 9.5px; text-transform: uppercase;
  letter-spacing: .16em; color: var(--ink-faint);
}
.rail-ctx { flex: 1; min-height: 0; flex-direction: column; }
.rail-actions { padding: 6px 16px 10px; }
.rail-list { flex: 1; overflow-y: auto; padding: 4px 10px 16px; min-height: 0; }
.rail-foot {
  padding: 12px 16px; border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 11px; color: var(--ink-soft);
}
.rail-foot #userEmail { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.proj-item {
  width: 100%; text-align: left; padding: 10px 12px; border-radius: var(--r);
  border: 1px solid transparent; background: none; color: var(--ink);
  display: flex; flex-direction: column; gap: 2px; margin-bottom: 2px;
}
.proj-item:hover { background: var(--line-soft); }
.proj-item.active { background: var(--panel); border-color: var(--line); }
.proj-item .pname { font-weight: 500; font-size: 13px; }
.proj-item .pmeta { font-size: 10.5px; color: var(--ink-faint); font-family: var(--mono); }
.rail-empty { padding: 22px 14px; color: var(--ink-faint); font-size: 13px; text-align: center; }

.icon-btn {
  border: 1px solid var(--line); background: var(--panel); border-radius: var(--r);
  width: 30px; height: 30px; display: grid; place-items: center; color: var(--ink-soft);
  flex: none;
}
.icon-btn:hover { color: var(--ink); border-color: var(--ink-faint); }
.icon-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- painel de trabalho ---------- */
.work { overflow-y: auto; min-height: 0; }
.work-inner { max-width: 1080px; margin: 0 auto; padding: 40px 44px 90px; }
.work-inner.estreito { max-width: 900px; }
@media screen and (max-width: 720px) { .work-inner { padding: 28px 20px 70px; } }
.work-empty { display: grid; place-items: center; height: 100%; color: var(--ink-faint); text-align: center; }

.phead { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.phead h1 {
  font-family: var(--display); font-weight: 400; font-size: 32px; letter-spacing: .005em;
}
.phead .acoes { display: flex; gap: 8px; flex-wrap: wrap; }
.pdims {
  color: var(--ink-faint); font-size: 11px; margin: 8px 0 8px;
  font-family: var(--mono); letter-spacing: .04em;
}
/* etapa do funil na ficha do cliente: parece o selo que era antes, mas é um
   <select> — é o único caminho para mover de etapa em quem não tem mouse */
.seletor-etapa {
  font-family: var(--sans); font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em;
  padding: 5px 8px; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--accent-wash); color: var(--accent);
}
.seletor-etapa:focus { outline: none; border-color: var(--accent); }

.voltar {
  background: none; border: none; color: var(--ink-faint); padding: 0;
  font-size: 11.5px; letter-spacing: .06em; margin-bottom: 10px;
}
.voltar:hover { color: var(--accent); }

.section { margin-top: 34px; }
.section-head {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  border-bottom: 1px solid var(--line); padding-bottom: 10px; margin-bottom: 16px;
}
.section-head h2 {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .16em;
  color: var(--ink-soft); font-weight: 500; flex: none;
}
.section-head .btn { flex: none; }
.section-head .direita { display: flex; gap: 8px; align-items: center; }

/* ---------- KPIs (carimbos de prancha) ---------- */
/* flex em vez de grid: com grid, uma última linha incompleta deixava um bloco
   cinza (o fundo que faz as hairlines) sobrando à direita. No flex os cartões
   da última linha se esticam e a faixa vazia não existe. */
.kpis {
  display: flex; flex-wrap: wrap; background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
}
.kpi {
  flex: 1 1 168px; padding: 14px 16px;
  box-shadow: inset -1px -1px 0 var(--line);   /* hairline direita + baixo */
}
.kpi .k {
  font-size: 9.5px; color: var(--ink-faint); text-transform: uppercase;
  letter-spacing: .12em; font-weight: 500;
}
.kpi .v {
  font-size: 21px; margin-top: 4px; font-family: var(--mono);
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}
.kpi .h { font-size: 11px; color: var(--ink-faint); margin-top: 2px; }
.kpi.ok .v { color: var(--ok); }
.kpi.alerta .v { color: var(--fail); }
.kpi.espera .v { color: var(--wait); }

/* ---------- tabelas ---------- */
.tabela-wrap {
  border: 1px solid var(--line); border-radius: var(--r); overflow-x: auto;
  background: var(--panel);
}
table.tabela { width: 100%; border-collapse: collapse; font-size: 13px; }
table.tabela th {
  text-align: left; font-size: 9.5px; text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-faint); font-weight: 500; padding: 10px 14px;
  border-bottom: 1px solid var(--line); white-space: nowrap; background: var(--panel);
}
table.tabela td {
  padding: 11px 14px; border-bottom: 1px solid var(--line-soft); vertical-align: middle;
}
table.tabela tbody tr:last-child td { border-bottom: none; }
table.tabela tbody tr.clicavel { cursor: pointer; }
table.tabela tbody tr.clicavel:hover { background: var(--line-soft); }
table.tabela td.num, table.tabela th.num {
  text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums;
}
table.tabela td .acoes-linha { display: flex; gap: 10px; justify-content: flex-end; }
.tabela-vazia { padding: 26px 16px; text-align: center; color: var(--ink-faint); font-size: 13px; }

/* ---------- selo de estado (carimbo) ---------- */
.pill {
  display: inline-flex; align-items: center; gap: 7px; padding: 4px 10px;
  border-radius: var(--r); font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .1em; white-space: nowrap;
}
.pill .dot { width: 6px; height: 6px; border-radius: 50%; }
.pill-ok   { background: var(--ok-wash);   color: var(--ok); }
.pill-ok .dot { background: var(--ok); }
.pill-wait { background: var(--wait-wash); color: var(--wait); }
.pill-wait .dot { background: var(--wait); }
.pill-fail { background: var(--fail-wash); color: var(--fail); }
.pill-fail .dot { background: var(--fail); }
.pill-run  { background: var(--accent-wash); color: var(--accent); }
.pill-run .dot { background: var(--accent); animation: pulse 1.1s ease-in-out infinite; }
.pill-neutro { background: var(--line-soft); color: var(--ink-soft); }
.pill-neutro .dot { background: var(--ink-faint); }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) { .pill-run .dot { animation: none; } }

/* ---------- cartoes ---------- */
.cartao {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  padding: 16px 18px; margin-bottom: 12px;
}
.cartao-topo { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.cartao h3 { font-size: 14px; font-weight: 600; }
.cartao .meta { font-size: 11px; color: var(--ink-faint); font-family: var(--mono); }
.cartoes { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 12px; }

/* ---------- kanban do funil ---------- */
.kanban { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 10px; }
/* 7 etapas não cabem numa tela de notebook; a coluna é estreita e o kanban
   rola na horizontal — encolher mais só tornaria o nome do cliente ilegível. */
.coluna {
  flex: 0 0 196px; background: var(--rail); border: 1px solid var(--line);
  border-radius: var(--r); display: flex; flex-direction: column; min-height: 220px;
}
.coluna.alvo { border-color: var(--accent); background: var(--accent-wash); }
.coluna-topo {
  padding: 11px 13px; border-bottom: 1px solid var(--line);
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
}
.coluna-topo .nome {
  font-size: 10px; text-transform: uppercase; letter-spacing: .13em;
  font-weight: 600; color: var(--ink-soft);
}
.coluna-topo .qtd { font-family: var(--mono); font-size: 11px; color: var(--ink-faint); }
.coluna-valor {
  padding: 6px 13px; font-family: var(--mono); font-size: 11px; color: var(--ink-faint);
  border-bottom: 1px solid var(--line-soft);
}
.coluna-corpo { padding: 8px; display: flex; flex-direction: column; gap: 7px; flex: 1; }
.cartao-funil {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  padding: 10px 11px; cursor: grab; font-size: 12.5px;
}
.cartao-funil:hover { border-color: var(--ink-faint); }
.cartao-funil.arrastando { opacity: .45; }
.cartao-funil .nome { font-weight: 500; }
.cartao-funil .sub {
  font-size: 10.5px; color: var(--ink-faint); font-family: var(--mono); margin-top: 3px;
  display: flex; justify-content: space-between; gap: 8px;
}
.coluna-vazia { color: var(--ink-faint); font-size: 11.5px; text-align: center; padding: 14px 6px; }

/* ---------- timeline de interacoes ---------- */
.linha-tempo { position: relative; padding-left: 18px; }
.linha-tempo::before {
  content: ""; position: absolute; left: 4px; top: 4px; bottom: 4px;
  width: 1px; background: var(--line);
}
.evento { position: relative; padding: 0 0 18px 0; }
.evento::before {
  content: ""; position: absolute; left: -18px; top: 6px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--panel); border: 1px solid var(--accent);
}
.evento .cab { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.evento .tipo {
  font-size: 9.5px; text-transform: uppercase; letter-spacing: .12em;
  color: var(--accent); font-weight: 600;
}
.evento .quando { font-size: 11px; color: var(--ink-faint); font-family: var(--mono); }
.evento .corpo { margin-top: 4px; font-size: 13px; }
.evento .passo {
  margin-top: 7px; font-size: 12px; padding: 7px 10px; border-radius: var(--r);
  background: var(--wait-wash); color: var(--wait);
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.evento .passo.feito { background: var(--ok-wash); color: var(--ok); }
.evento .passo button { background: none; border: none; color: inherit; font-size: 11px; text-decoration: underline; }

/* ---------- cronograma de etapas ---------- */
.etapas { border: 1px solid var(--line); border-radius: var(--r); background: var(--panel); }
.etapa-linha {
  display: flex; align-items: center; gap: 12px; padding: 11px 14px;
  border-bottom: 1px solid var(--line-soft);
}
.etapa-linha:last-child { border-bottom: none; }
.etapa-linha .ordem {
  width: 20px; font-family: var(--mono); font-size: 11px; color: var(--ink-faint); flex: none;
}
.etapa-linha .nome { flex: 1; font-size: 13px; }
.etapa-linha.concluida .nome { color: var(--ink-faint); text-decoration: line-through; }
.etapa-linha select { padding: 5px 8px; font-size: 11px; border: 1px solid var(--line);
  border-radius: var(--r); background: var(--panel); color: var(--ink); }
.barra {
  height: 4px; background: var(--line-soft); border-radius: 2px; overflow: hidden;
  margin-top: 8px;
}
.barra > i { display: block; height: 100%; background: var(--accent); }

/* ---------- grafico de fluxo (SVG inline) ---------- */
/* `height: auto` com viewBox proporcional = escala uniforme. A versao anterior
   fixava a altura e deixava a largura esticar, o que achatava o texto. */
.gfx { width: 100%; height: auto; display: block; max-height: 320px; }
.gfx .eixo { stroke: var(--line); stroke-width: 1; }
.gfx .rot { font-family: var(--mono); font-size: 14px; fill: var(--ink-faint); }
.gfx .rot-forte { fill: var(--accent); font-weight: 500; }
.gfx .b-receita { fill: var(--ok); }
.gfx .b-despesa { fill: var(--fail); }
.gfx .b-atual { stroke: var(--accent); stroke-width: 1; stroke-dasharray: 2 2; fill: none; }
.legenda { display: flex; gap: 16px; flex-wrap: wrap; font-size: 11px; color: var(--ink-soft); padding: 10px 2px 0; }
.legenda i { width: 10px; height: 10px; display: inline-block; margin-right: 6px; vertical-align: -1px; }

/* ---------- alertas / agenda ---------- */
.alerta {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px 13px;
  border: 1px solid var(--line); border-left-width: 3px; border-radius: var(--r);
  background: var(--panel); margin-bottom: 8px; font-size: 13px;
}
.alerta.alta { border-left-color: var(--fail); }
.alerta.media { border-left-color: var(--wait); }
.alerta.baixa { border-left-color: var(--ink-faint); }
.alerta .modulo {
  font-size: 9.5px; text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-faint); margin-left: auto; white-space: nowrap;
}
.agenda-dia {
  display: flex; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line-soft);
  align-items: baseline;
}
.agenda-dia:last-child { border-bottom: none; }
.agenda-dia .data {
  font-family: var(--mono); font-size: 11px; color: var(--ink-faint); width: 62px; flex: none;
}
.agenda-dia .titulo { flex: 1; font-size: 13px; }
.agenda-dia .ctx { font-size: 11px; color: var(--ink-faint); }
.agenda-dia.atrasado .data { color: var(--fail); }

/* ---------- filtros ---------- */
.filtros { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 14px; }
.filtros input, .filtros select {
  padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); color: var(--ink); font-size: 12.5px;
}
.filtros input[type=search] { min-width: 220px; }
.filtros input:focus, .filtros select:focus { outline: none; border-color: var(--accent); }
.chip {
  padding: 6px 12px; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--panel); color: var(--ink-soft); font-size: 11.5px;
}
.chip.ativo { border-color: var(--accent); color: var(--accent); background: var(--accent-wash); }

/* ---------- modal ---------- */
.modal-fundo {
  position: fixed; inset: 0; background: rgba(22,19,15,.42);
  display: grid; place-items: center; padding: 24px; z-index: 60;
  overflow-y: auto;
}
.modal {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  width: 100%; max-width: 520px; max-height: 88vh; overflow-y: auto;
}
.modal.largo { max-width: 720px; }
.modal-cab {
  padding: 20px 24px 14px; border-bottom: 1px solid var(--line);
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
}
.modal-cab h2 { font-family: var(--display); font-weight: 400; font-size: 22px; }
.modal-cab p { margin: 4px 0 0; font-size: 12px; color: var(--ink-faint); }
.modal-corpo { padding: 20px 24px; }
.modal-pe {
  padding: 14px 24px 20px; display: flex; gap: 10px; justify-content: flex-end;
  border-top: 1px solid var(--line-soft);
}
.modal-pe .esquerda { margin-right: auto; }

/* ---------- estudio (Fase 1) ---------- */
.slots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
@media screen and (max-width: 680px) { .slots { grid-template-columns: 1fr; } }
.slot {
  border: 1px dashed var(--line); border-radius: var(--r); padding: 18px 16px;
  background: var(--panel);
  display: flex; flex-direction: column; gap: 9px; min-height: 124px;
  transition: border-color .15s, background .15s;
}
.slot.filled { border-style: solid; }
.slot.drag { border-color: var(--accent); background: var(--accent-wash); }
.slot-role {
  font-size: 10px; text-transform: uppercase; letter-spacing: .14em;
  font-weight: 500; color: var(--ink-soft);
}
.slot-hint { font-size: 12px; color: var(--ink-faint); line-height: 1.5; flex: 1; }
.slot-file { font-size: 12.5px; color: var(--ink); display: flex; align-items: center; gap: 7px; word-break: break-all; flex: 1; }
.slot-file .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); flex: none; }
.slot label.upl { font-size: 12px; font-weight: 500; color: var(--accent); cursor: pointer; }
.slot input[type=file] { display: none; }

.job {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  padding: 16px 18px; margin-bottom: 12px;
}
.job-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.job-id { font-size: 10.5px; color: var(--ink-faint); font-family: var(--mono); letter-spacing: .03em; }
.job-when { font-size: 11px; color: var(--ink-faint); font-family: var(--mono); }
.state-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 1px; margin-top: 14px; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--r); overflow: hidden;
}
.stat { background: var(--panel); padding: 11px 14px; }
.stat .k {
  font-size: 9.5px; color: var(--ink-faint); text-transform: uppercase;
  letter-spacing: .12em; font-weight: 500;
}
.stat .v { font-size: 16px; margin-top: 3px; font-family: var(--mono); }
.warn-line {
  margin-top: 12px; font-size: 12px; color: var(--wait);
  display: flex; gap: 8px; align-items: flex-start;
}
.warn-line .w-mark { flex: none; margin-top: 1px; }
details.raw { margin-top: 12px; }
details.raw summary { font-size: 11px; color: var(--ink-soft); cursor: pointer; user-select: none; letter-spacing: .04em; }
details.raw pre {
  margin: 10px 0 0; padding: 14px; background: var(--ground); border: 1px solid var(--line);
  border-radius: var(--r); overflow-x: auto; font-family: var(--mono); font-size: 11px;
  color: var(--ink-soft); line-height: 1.55;
}

.planta-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  overflow: hidden;
}
.planta-card canvas { width: 100%; display: block; cursor: crosshair; }
.planta-foot {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 11px 16px; border-top: 1px solid var(--line-soft);
  font-size: 11px; color: var(--ink-soft); letter-spacing: .03em;
}
.planta-foot .legend { display: inline-flex; align-items: center; gap: 7px; }
.planta-foot .sw { width: 16px; height: 2px; display: inline-block; }
.sw-per { background: var(--accent); }
.sw-out { background: var(--line); }
.sw-vao { width: 7px; height: 7px; border-radius: 50%; background: var(--fail); }
.planta-foot #plantaStats { margin-left: auto; color: var(--ink); font-family: var(--mono); font-size: 11.5px; }
.planta-hint { padding: 0 16px 12px; font-size: 11px; color: var(--ink-faint); }

/* ---------- toast ---------- */
.toast {
  position: fixed; bottom: calc(24px + env(safe-area-inset-bottom));
  left: 50%; transform: translateX(-50%) translateY(16px);
  max-width: calc(100vw - 32px); text-align: center;
  background: var(--carvao); color: var(--carvao-ink); padding: 10px 20px;
  border-radius: var(--r); border: 1px solid #2E2921;
  font-size: 12.5px; letter-spacing: .02em; opacity: 0; pointer-events: none;
  transition: opacity .2s, transform .2s; z-index: 80;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* o bloco responsivo mudou de lugar: foi para o FIM do arquivo. Media query nao
   aumenta especificidade, entao regra de tela estreita escrita aqui no meio
   perdia para qualquer regra de componente declarada depois — foi o que
   escondia as acoes da tarefa no celular mesmo com a correcao escrita. */

/* ---------- lista de tarefas ---------- */
.grupo-tarefas {
  border: 1px solid var(--line); border-left-width: 3px; border-radius: var(--r);
  background: var(--panel); margin-bottom: 14px; overflow: hidden;
}
.grupo-tarefas.alta { border-left-color: var(--fail); }
.grupo-tarefas.media { border-left-color: var(--wait); }
.grupo-cab {
  display: flex; justify-content: space-between; align-items: center;
  padding: 9px 14px; border-bottom: 1px solid var(--line-soft);
  font-size: 10px; text-transform: uppercase; letter-spacing: .14em;
  color: var(--ink-soft); font-weight: 600;
}
.grupo-cab .mono { color: var(--ink-faint); letter-spacing: 0; }
.tarefa {
  display: flex; align-items: flex-start; gap: 12px; padding: 11px 14px;
  border-bottom: 1px solid var(--line-soft);
}
.tarefa:last-child { border-bottom: none; }
.tarefa .corpo { flex: 1; min-width: 0; }
.tarefa .titulo { font-size: 13.5px; }
.tarefa .meta { font-size: 11.5px; color: var(--ink-faint); margin-top: 3px; }
.tarefa .meta .vencido { color: var(--fail); }
.tarefa.feita .titulo { color: var(--ink-faint); text-decoration: line-through; }
.tarefa .marca-prio { color: var(--fail); margin-right: 6px; font-size: 11px; }
.tarefa .acoes-linha { opacity: 0; transition: opacity .12s; }
.tarefa:hover .acoes-linha, .tarefa:focus-within .acoes-linha { opacity: 1; }
.caixa {
  width: 20px; height: 20px; flex: none; margin-top: 1px;
  border: 1px solid var(--line); border-radius: var(--r); background: var(--panel);
  color: var(--accent-ink); font-size: 12px; line-height: 1;
  display: grid; place-items: center;
}
.caixa:hover { border-color: var(--accent); }
.caixa.marcada { background: var(--ok); border-color: var(--ok); color: #fff; }

/* ---------- bloco recolhivel (informacao de segunda ordem) ---------- */
details.recolhivel > summary {
  cursor: pointer; user-select: none; list-style: none;
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .16em;
  color: var(--ink-soft); font-weight: 500;
  border-bottom: 1px solid var(--line); padding-bottom: 10px; margin-bottom: 16px;
}
details.recolhivel > summary::marker { content: ""; }
details.recolhivel > summary::before { content: "▸ "; color: var(--ink-faint); }
details.recolhivel[open] > summary::before { content: "▾ "; }
details.recolhivel > summary:hover { color: var(--ink); }

/* ============================================================
   Documento da proposta — identidade extraída do modelo do escritório
   (VIVERE-proposta-comercial). Valores MEDIDOS do PDF, não estimados:

     fundo   #F5F1E5 · vinho #470A1B · vinho claro #661E2E
     apoio   #D5D3CB (números decorativos)
     corpo   Montserrat 200/300 — a mesma fonte do modelo
     títulos "Against"

   Sobre a Against: o arquivo em id-visual/ é a versão DEMO, e a licença que
   vem junto diz "PERSONAL USE ONLY, NO COMMERCIAL USE ALLOWED". Proposta
   comercial é exatamente o uso proibido, e publicar o arquivo como webfont
   ainda o redistribuiria. Então ela NÃO é embutida aqui.

   O que existe é melhor que embutir: `"Against"` encabeça a pilha abaixo, e o
   navegador usa a fonte INSTALADA na máquina de quem abre o documento. Como o
   PDF é gerado pelo navegador do próprio arquiteto, o arquivo sai com a fonte
   certa embutida no PDF — sem servidor nenhum distribuindo a fonte. Basta
   instalar a Against no sistema (e comprar a licença comercial em
   177studio.com/product/against-font). Sem ela instalada, cai em Prata, didone
   de contraste alto e proporção próxima — e nada quebra.
   ============================================================ */
.doc {
  --doc-creme: #F6F2E6;        /* medido do PDF do modelo */
  --doc-vinho: #470A1B;
  --doc-apoio: #D5D3CB;
  /* Base sob a textura de sombra. É o próprio creme, medido na folha de contato
     do modelo: nas áreas claras (onde a sombra é quase transparente) o tom é
     #F3F0E4, a um passo do creme #F6F2E6; nas sombras, #CDCCC5. Antes eu havia
     estimado #E9E7DD a partir de amostras de alfa, e a página saía mais
     acinzentada que a do modelo. */
  --doc-fundo-textura: #F6F2E6;
  --doc-display: "Against", "Prata", "Instrument Serif", Georgia, serif;
  --doc-texto: "Montserrat", system-ui, sans-serif;
  max-width: 860px; margin: 0 auto; padding: 24px 16px 90px;

  /* Contêiner de consulta AQUI, e não em `.doc-pagina`.
     As medidas tiradas do modelo são porcentagens da FOLHA, e `cqw` mede a
     caixa de CONTEÚDO do contêiner. Em `.doc-pagina`, que tem 9% de padding de
     cada lado, `36cqw` valia 36% de 82% = 29,5% da folha — o logotipo da capa
     saía visivelmente menor que o do modelo. A caixa de conteúdo de `.doc` tem
     exatamente a largura da folha, na tela e no papel, então aqui `1cqw` é 1%
     da folha e as medidas do modelo entram como estão. */
  container-type: inline-size;
}

/* A4 já na tela: a folha aparece com a proporção que vai sair impressa, para
   o arquiteto conferir a quebra de página antes de gerar o PDF. */
.doc-pagina {
  position: relative; overflow: hidden;
  width: 100%; aspect-ratio: 210 / 297;
  background: var(--doc-creme); color: var(--doc-vinho);
  font-family: var(--doc-texto); font-weight: 300;
  padding: 10% 9%; margin: 0 auto 22px;
  display: flex; flex-direction: column;
  border: 1px solid var(--line);
}
.doc-pagina.escura { background: var(--doc-vinho); color: var(--doc-creme); }

/* cabeçalho de seção: traço grosso, título à direita, número decorativo */
.doc-cab { position: relative; margin-bottom: 8%; }
.doc-cab::before {
  content: ""; display: block; width: 62%; height: 3px;
  background: currentColor; margin-bottom: 5%;
}
/* Título CENTRADO, como no modelo: em "Etapas de projeto" ele fica no meio da
   folha; em "Modalidade de contratação", que é mais longo, chega às duas
   margens sozinho. A versão anterior alinhava à direita e reservava 15% para o
   número decorativo — reserva que deixou de ser necessária quando o número saiu
   destas folhas (ver `cabecalho` em documento.js). */
.doc-cab h2 {
  font-family: var(--doc-display); font-weight: 400;
  font-size: clamp(26px, 5vw, 44px); line-height: 1; text-align: center;
}
.doc-cab .doc-sub {
  text-align: right; font-size: clamp(9px, 1.3vw, 12px); margin-top: 6px;
  opacity: .85;
}
/* na folha de orçamento o número existe, e aí o título cede a faixa da direita */
.doc-orcamentos .doc-cab h2 { text-align: right; padding-right: 20%; }
.doc-orcamentos .doc-cab .doc-sub { padding-right: 20%; }
/* sem opacidade: o número decorativo do modelo sai exatamente em #D5D4CD, que
   é o próprio --doc-apoio. Com `opacity: .55` ele saía #E3E0D6, claro demais */
.doc-num-deco {
  position: absolute; right: 0; top: -6%;
  font-family: var(--doc-display); font-size: clamp(64px, 12vw, 118px);
  color: var(--doc-apoio); line-height: 1; pointer-events: none;
}
.escura .doc-num-deco { color: var(--doc-creme); opacity: .12; }

/* ---------- capa ----------
   Medidas tiradas do PDF do modelo, em porcentagem da FOLHA:

     título   Against 41,3pt numa folha de 595pt  = 6,94% da largura
              de 7,8% a 92,2% na horizontal (uma linha só, margem a margem)
              de 29,7% a 36,4% na vertical
     marca    de 34,3% a 69,9% na horizontal, pé em 92,5%

   `cqw` (1% da largura do contêiner) e não `vw`: o resto do documento usa
   `clamp(vw)`, que funciona porque na impressão `vw` é a largura da folha —
   mas na TELA a folha tem no máximo 860px enquanto `vw` mede a janela inteira,
   e aí a proporção escorrega. Aqui, onde a medida veio do modelo com uma casa
   decimal, o tamanho é amarrado à folha e não à janela. */
/* Tudo na capa é posicionado por `top`/`bottom`, e não por margem.
   Motivo que custou uma rodada de medição: margem e padding em porcentagem
   resolvem contra a LARGURA do contêiner, mesmo na vertical. `margin-top: 19.7%`
   numa folha A4 vale 19,7% de 210mm = 41mm, que é 14% da altura — não 19,7%.
   `top` em porcentagem, esse sim, resolve contra a altura. */
.doc-capa { text-align: center; }
.doc-capa h1 {
  position: absolute; left: 7.8%; right: 7.8%; top: 29.7%;
  font-family: var(--doc-display); font-weight: 400;
  font-size: 6.94cqw; line-height: 1; letter-spacing: -.005em;
  white-space: nowrap;
}
.doc-capa-sub {
  position: absolute; left: 12%; right: 12%; top: 38%;
  font-size: 1.9cqw; opacity: .8;
}

/* a marca fecha a capa, centrada, como no modelo */
.doc-capa-marca {
  position: absolute; left: 0; right: 0; bottom: 7.5%;
  display: flex; justify-content: center;
}
.doc-marca {
  font-family: var(--doc-display); font-size: clamp(24px, 4.2vw, 42px); line-height: 1;
}
.doc-marca small {
  display: block; font-family: var(--doc-texto); font-weight: 300;
  font-size: .3em; letter-spacing: .5em; text-transform: lowercase;
  margin-top: .4em; padding-left: .25em;
}
/* Cliente · nº · emissão.
   O modelo NÃO traz esses dados — a capa dele é só título e marca, e o nome do
   cliente não aparece em folha nenhuma. Ficam aqui de propósito, discretos no
   alto: proposta sem destinatário é indistinguível de outra, e duas propostas
   iguais no e-mail do arquiteto viram um problema de verdade. Apagar a linha é
   remover este bloco — a capa continua idêntica ao modelo. */
/* posição absoluta para NÃO empurrar o título: a altura deste bloco depende do
   nome do cliente, e o título tem posição medida do modelo (29,7% da folha) */
.doc-capa-dados {
  position: absolute; left: 9%; right: 9%; top: 8%;
  display: flex; justify-content: center; gap: 4.5%;
  font-size: 1.45cqw; opacity: .75; text-align: center;
}
.doc-capa-dados span {
  display: block; opacity: .62; letter-spacing: .18em; text-transform: uppercase;
  font-size: .78em; margin-bottom: .35em;
}
.doc-capa-dados strong { font-weight: 400; }

/* blocos com traço curto (INCLUSO / INVESTIMENTO) */
.doc-corpo { flex: 1; display: flex; flex-direction: column; justify-content: center; }
.doc-colunas { display: grid; grid-template-columns: 1fr 1fr; gap: 7%; }
.doc-bloco::before {
  content: ""; display: block; width: 42px; height: 2px;
  background: currentColor; margin-bottom: 14px;
}
.doc-bloco h3 {
  font-size: clamp(10px, 1.5vw, 14px); font-weight: 400;
  text-transform: uppercase; letter-spacing: .06em; margin-bottom: 18px;
}
.doc-item { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 12px; }
.doc-bolha {
  width: 22px; height: 22px; flex: none; border-radius: 50%;
  border: 1px solid currentColor; display: grid; place-items: center;
  font-size: 11px; opacity: .8;
}
.doc-item-txt { font-size: clamp(10px, 1.45vw, 13.5px); line-height: 1.6; }
.doc-valor-grande { font-size: clamp(15px, 2.2vw, 21px); font-weight: 400; }

/* etapas: número gigante + entregáveis com traço, como no modelo */
/* `margin: auto 0` centraliza verticalmente SEM esticar: com `flex: 1` o bloco
   ocupava a folha inteira e o trilho vertical passava muito acima e abaixo das
   etapas, o que nao acontece no modelo. */
.doc-etapas {
  display: flex; flex-direction: column; gap: 3%;
  flex: none; margin: auto 0; position: relative;
}
/* trilho vertical ligando as etapas — no modelo ele amarra a sequencia */
.doc-etapas::before {
  content: ""; position: absolute; left: 14.5%; top: 8%; bottom: 8%;
  width: 1px; background: currentColor; opacity: .3;
}
.doc-etapa {
  display: grid; grid-template-columns: 13% 1fr 1fr; gap: 3%;
  align-items: center; position: relative;
}
.doc-etapa::before {
  content: ""; position: absolute; left: 14.5%; top: 50%;
  width: 7px; height: 7px; margin: -3.5px 0 0 -3px;
  border-radius: 50%; background: currentColor; opacity: .55;
}
.doc-etapa-num {
  font-family: var(--doc-display); font-size: clamp(34px, 6.2vw, 60px);
  line-height: .9; opacity: .3;
}
.doc-etapa-nome {
  font-size: clamp(11px, 1.75vw, 17px); font-weight: 300;
  text-transform: uppercase; letter-spacing: .04em;
  padding-bottom: 7px; border-bottom: 1px solid currentColor;
}
.doc-etapa-prazo { font-size: clamp(9px, 1.3vw, 12.5px); margin-top: 7px; opacity: .9; }
.doc-etapa-itens { font-size: clamp(8.5px, 1.2vw, 11.5px); line-height: 2; opacity: .92; }
.doc-etapa-itens div { position: relative; padding-left: 14px; }
.doc-etapa-itens div::before {
  content: ""; position: absolute; left: 0; top: .9em;
  width: 7px; height: 1px; background: currentColor; opacity: .6;
}

/* texto corrido e lista de ambientes */
.doc-texto { font-size: clamp(9.5px, 1.4vw, 13px); line-height: 1.85; white-space: pre-wrap; }
.doc-lista {
  columns: 2; column-gap: 8%; margin: 0; padding: 0; list-style: none;
  font-size: clamp(9px, 1.3vw, 12.5px); line-height: 2.1;
}
.doc-lista li { position: relative; padding-left: 15px; break-inside: avoid; }
.doc-lista li::before {
  content: ""; position: absolute; left: 0; top: .95em;
  width: 8px; height: 1px; background: currentColor; opacity: .55;
}

/* nota com ícone circular, como no modelo */
.doc-nota-caixa {
  margin-top: auto; display: flex; align-items: center; gap: 10px;
  font-size: clamp(8px, 1.1vw, 10.5px); line-height: 1.6;
}
.doc-nota-caixa .doc-bolha { width: 26px; height: 26px; font-style: italic; }
.doc-nota-caixa p {
  margin: 0; background: var(--doc-vinho); color: var(--doc-creme);
  padding: 10px 16px; border-radius: 14px; flex: 1;
}
.escura .doc-nota-caixa p { background: var(--doc-creme); color: var(--doc-vinho); }

/* contato: marca em cima, faixa vinho embaixo com texto à direita */
.doc-contato { padding: 0; }
/* `min-height: 0` e o que permite o topo ENCOLHER. Sem isso o bloco da marca
   nao cede espaco, a faixa de contato transborda a folha de altura fixa e o
   telefone e cortado — o proprio corte que apareceu no primeiro teste. */
.doc-contato-topo {
  flex: 1; min-height: 0; display: grid; place-items: center; padding: 9%;
}
.doc-contato-faixa {
  background: var(--doc-vinho); color: var(--doc-creme);
  padding: 7% 9%; text-align: right; flex: none;
}
.doc-contato-faixa .doc-resp {
  font-family: var(--doc-display); font-size: clamp(20px, 3.4vw, 34px); line-height: 1.1;
}
.doc-contato-faixa .doc-cargo { font-size: clamp(9px, 1.35vw, 13px); margin-top: 6px; opacity: .9; }
.doc-contato-faixa .doc-linhas {
  margin-top: 18px; font-size: clamp(8.5px, 1.15vw, 11.5px); line-height: 1.9; opacity: .85;
}

/* ---------- impressão ----------
   O MESMO HTML da tela: só se retira a interface e se força uma folha por
   seção. `print-color-adjust: exact` é obrigatório — sem ele o navegador
   descarta os fundos e a página vinho sai branca. */
@media print {
  @page { size: A4; margin: 0; }

  /* A CASCA DO APP PRECISA SUMIR DA CONTA, e não só da vista.
     `#app` tem `height: 100dvh` e `.work` rola por dentro; `html`/`body` têm
     `height: 100%`. Nada disso aparece impresso, mas tudo isso entra no cálculo
     do layout de impressão, e o Chrome fazia duas coisas erradas por causa
     disso: encolhia o documento inteiro em 1,14% (a folha vinho ficava com
     3,5mm de papel branco embaixo, e a "sangria" da capa deixava de sangrar) e
     emitia uma folha em branco no fim.

     Medido: com estas cinco linhas, a folha passa a cobrir 99,9% × 99,9% do
     papel — antes cobria 98,7% × 98,7% — e o PDF sai com o número exato de
     páginas. Nenhuma regra de tamanho do documento mudou; só pararam de
     competir com as da casca. */
  html, body { background: #fff; height: auto; width: auto; margin: 0; padding: 0; }
  #app { display: block !important; height: auto !important; width: auto !important; }
  .work { overflow: visible; height: auto; }

  .rail, .barra-doc, .nao-imprime, .toast,
  .topbar, .scrim { display: none !important; }
  .doc { max-width: none; width: auto; margin: 0; padding: 0; }
  .doc-pagina {
    width: 210mm; height: 297mm; aspect-ratio: auto;
    margin: 0; border: none;
    break-after: page; page-break-after: always;
    -webkit-print-color-adjust: exact; print-color-adjust: exact;
  }
  .doc-pagina:last-child { break-after: auto; page-break-after: auto; }
  .doc-etapa, .doc-bloco { break-inside: avoid; page-break-inside: avoid; }
}

/* ---------- campo de imagem (logotipo, foto da proposta) ---------- */
.campo-imagem { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.previa-imagem {
  width: 92px; height: 62px; flex: none; border: 1px solid var(--line);
  border-radius: var(--r); background: var(--ground);
  display: grid; place-items: center; overflow: hidden;
}
.previa-imagem img { max-width: 100%; max-height: 100%; object-fit: contain; }
.previa-imagem span { font-size: 10px; color: var(--ink-faint); }

/* ---------- logotipo enviado pelo escritório ----------
   O logotipo é repintado com a tinta da página ANTES de virar <img> — a
   repintura acontece em JavaScript, num canvas (ver `tingir` em documento.js).

   O motivo de repintar: o arquivo que o escritório tem costuma existir numa cor
   só. O da Vivere é creme — feito para fundo escuro — e a capa do modelo é
   creme. Colado como está, o logotipo sumiria no próprio fundo.

   O motivo de repintar NO CANVAS, e não com `mask` no CSS: máscara funciona
   perfeitamente na tela e se estraga na impressão. O Chrome exporta o elemento
   mascarado como um retângulo PRETO opaco por baixo dos traços (visto no PDF:
   um `fill (0,0,0)` de 375,84×138,96pt sob a marca de 375×137,25pt), e as
   frações que sobram desenham um fio escuro na borda direita e inferior. Numa
   proposta que vai para o cliente, isso é um defeito impresso. */
.doc-logo { display: block; height: auto; }

/* Medidas do modelo, em % da FOLHA: 36% na capa, 63% na página de contato.
   Em `cqw` e não em `%`: o logotipo da página de contato mora dentro de um
   bloco com 9% de padding, então `63%` renderizaria 63% de 82% = 52% da folha —
   e a marca sairia visivelmente menor que a do modelo. */
.doc-logo.na-capa { width: 36cqw; }
.doc-logo.na-contato { width: 63cqw; }

/* textura de fundo (sombra de janela): PNG cinza com alfa baixíssimo — é uma
   SOMBRA, não uma foto. Sozinha ela quase não aparece; o que dá o tom da
   página do modelo é a cor de base por baixo. `right top` reproduz o
   enquadramento do modelo, que mostra a parte direita da imagem. */
.doc-contato-topo.com-foto {
  background-color: var(--doc-fundo-textura);
  background-size: cover; background-position: right top;
}

/* ---------- indice (folha vinho, numeros gigantes translucidos) ---------- */
.doc-indice .doc-corpo { justify-content: center; gap: 1.5%; }
.doc-indice-linha { display: flex; align-items: center; gap: 4%; }
.doc-indice-num {
  font-family: var(--doc-display); font-size: clamp(30px, 6vw, 58px);
  line-height: 1; opacity: .22; width: 16%; text-align: right; flex: none;
}
.doc-indice-txt { font-size: clamp(11px, 1.7vw, 16px); font-weight: 300; }
.doc-indice-txt::before {
  content: ""; display: block; width: 30px; height: 1px;
  background: currentColor; opacity: .5; margin-bottom: 8px;
}
.doc-indice-txt small { font-size: .72em; opacity: .75; }

/* ---------- cronograma: quatro blocos numerados ---------- */
.doc-crono { display: grid; grid-template-columns: 1fr 1fr; gap: 7% 8%; }
.doc-crono-bloco { break-inside: avoid; page-break-inside: avoid; }
.doc-crono-num {
  font-family: var(--doc-display); font-size: clamp(38px, 7vw, 66px);
  line-height: .9; color: var(--doc-apoio); margin-bottom: 6px;
}
.doc-crono-nome {
  font-size: clamp(11px, 1.7vw, 16px); text-transform: uppercase;
  letter-spacing: .04em; padding-top: 10px; border-top: 1px solid currentColor;
}
.doc-crono-bloco ul {
  margin: 10px 0 0; padding-left: 14px;
  font-size: clamp(8.5px, 1.25vw, 11.5px); line-height: 1.75;
}
.doc-crono-bloco li { margin-bottom: 5px; }

/* ---------- tabela comparativa ---------- */
.doc-tabela {
  width: 100%; border-collapse: collapse; font-size: clamp(8px, 1.15vw, 11px);
}
.doc-tabela th, .doc-tabela td {
  padding: 9px 12px; border: 1px solid currentColor; text-align: left;
  vertical-align: middle;
}
.doc-tabela th { font-weight: 500; font-size: clamp(8.5px, 1.2vw, 11.5px); }
.doc-tabela .centro { text-align: center; }
/* a coluna da direita e a que o escritorio quer vender: no modelo ela tem
   fundo proprio, destacando-se da coluna vizinha */
.doc-tabela .destaque { background: rgba(255, 255, 255, .07); }
.escura .doc-tabela .destaque { background: rgba(245, 241, 229, .08); }
.doc-sim { font-size: 1.35em; }
.doc-nao { opacity: .5; }

/* ---------- pagina de orcamento com dois blocos ---------- */
.doc-orcamentos { justify-content: space-evenly; }
.doc-orcamento + .doc-orcamento { margin-top: 6%; }
.doc-orcamentos .doc-cab { margin-bottom: 5%; }
.doc-orcamentos .doc-num-deco { top: -14%; }

/* A página de orçamento NÃO leva textura, e isso foi MEDIDO, não suposto.
   O PDF do modelo tem sim um objeto de imagem nessa folha (3000×2000 posto a
   44% da largura), o que fez parecer que a textura aparecia ali. Amostrando o
   canto superior direito da folha renderizada: 65 mil pixels de creme puro
   (#F6F2E6) e nenhum tom intermediário — a imagem está no arquivo e não aparece
   no resultado. Repeti-la aqui deixava um retângulo cinza de borda dura sobre
   metade da folha, que o modelo não tem. */

/* barra de ferramentas do documento (não sai na impressão).
   Ficava sem regra nenhuma: o `<div style="flex:1">` que separa os botões não
   empurrava nada porque o contêiner não era flex. */
.barra-doc {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  position: sticky; top: 0; z-index: 20;
  padding: 12px 16px; background: var(--ground);
  border-bottom: 1px solid var(--line);
}

/* ============================================================
   TELA ESTREITA — celular e tablet
   ------------------------------------------------------------
   Este bloco fica no FIM do arquivo de propósito. `@media` não altera
   especificidade: uma regra de tela estreita escrita antes da regra de
   componente perde para ela em qualquer largura. Escrevendo por último, ganha.

   Três larguras de corte, cada uma por um motivo concreto:
     860px  a casca — abaixo disso o menu fixo de 236px come um quarto da tela
     640px  tabela e modal — abaixo disso cinco colunas não cabem lado a lado
     hover  ponteiro sem passagem do mouse (toque), independente da largura

   TODAS as regras aqui são `@media screen and (...)`, e o `screen` não é
   decoração. Sem ele, a folha A4 impressa (794px de largura) casa com
   `max-width: 860px` e herda o layout de celular — foi exatamente o que
   aconteceu: `.doc { padding: 14px 10px }` empurrava a folha 10px para a
   direita, o documento ficava 10px mais largo que o papel e o Chrome ENCOLHIA
   tudo em 1,3% para caber. O resultado eram 3,5mm de papel branco no rodapé de
   toda página vinho e uma folha em branco no fim do PDF — dois defeitos
   visíveis cuja causa era uma media query de celular vencendo a de impressão,
   porque este bloco vem depois dela no arquivo.
   ============================================================ */

/* -------- casca: menu vira gaveteiro -------- */
.topbar, .scrim, .so-mobile { display: none; }

@media screen and (max-width: 860px) {
  #app { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }

  .topbar {
    display: flex; align-items: center; gap: 12px;
    padding: 8px 12px; padding-top: calc(8px + env(safe-area-inset-top));
    background: var(--rail); border-bottom: 1px solid var(--line);
  }
  .topbar-titulo {
    font-family: var(--display); font-size: 19px; letter-spacing: .01em;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .topbar .brand { margin-left: auto; color: var(--accent); }
  .so-mobile { display: grid; }

  /* o menu sai da tela pela esquerda e volta por cima do conteúdo */
  .rail {
    position: fixed; z-index: 70; top: 0; bottom: 0; left: 0;
    width: min(84vw, 300px); border-right: 1px solid var(--line);
    padding-top: env(safe-area-inset-top);
    transform: translateX(-101%);          /* 101% esconde também a borda */
    transition: transform .22s ease;
    box-shadow: 0 0 40px rgba(0, 0, 0, .18);
  }
  #app.menu-aberto .rail { transform: none; }
  .scrim {
    display: block; position: fixed; inset: 0; z-index: 65;
    border: none; padding: 0; background: rgba(22, 19, 15, .45);
  }
  .rail-foot { padding-bottom: calc(12px + env(safe-area-inset-bottom)); }

  /* alvo de toque: 44px é a medida que a Apple e o Google recomendam, e é
     também a largura média de uma ponta de dedo adulta */
  .nav-item { padding: 12px; min-height: 44px; font-size: 14px; }
  .proj-item { min-height: 44px; }

  .work-inner { padding-bottom: calc(70px + env(safe-area-inset-bottom)); }

  /* 16px é o limiar abaixo do qual o Safari do iPhone dá zoom sozinho ao focar
     um campo — e depois não volta, deixando a tela deslocada para a direita */
  .field input, .field select, .field textarea,
  .filtros input, .filtros select, .etapa-linha select { font-size: 16px; }

  .phead h1 { font-size: 26px; }
  .phead .acoes { width: 100%; }
  .phead .acoes .btn { flex: 1 1 auto; }
  .filtros input[type=search] { flex: 1 1 100%; min-width: 0; }
  .barra-doc { padding: 10px 12px; }
  .barra-doc .btn { flex: 1 1 auto; }
  .doc { padding: 14px 10px 60px; }
}
@media screen and (max-width: 860px) and (prefers-reduced-motion: reduce) {
  .rail { transition: none; }
}

/* -------- tabela vira cartão empilhado -------- */
/* A alternativa seria rolar na horizontal, e aí some justamente a coluna da
   direita — que nas nossas tabelas é o valor e as ações. O `data-rotulo` que
   `T.tabela` grava em cada célula vira o nome do campo aqui. */
@media screen and (max-width: 640px) {
  table.tabela thead { display: none; }
  table.tabela, table.tabela tbody, table.tabela td { display: block; }
  /* flex-column e não block: é o que permite reordenar as células (ver abaixo) */
  table.tabela tr {
    display: flex; flex-direction: column;
    padding: 6px 0 10px; border-bottom: 1px solid var(--line);
  }
  table.tabela tbody tr:last-child { border-bottom: none; }

  /* linha comum do cartão: nome do campo à esquerda, conteúdo à direita */
  table.tabela td {
    display: flex; gap: 14px; align-items: baseline; justify-content: space-between;
    padding: 6px 14px; border-bottom: none; text-align: right;
  }
  table.tabela td::before {
    content: attr(data-rotulo); flex: none; text-align: left;
    font-size: 9.5px; text-transform: uppercase; letter-spacing: .12em;
    color: var(--ink-faint); font-weight: 500;
  }

  /* A célula que traz o nome da coisa é sempre a que usa <strong> (com a linha
     de contexto logo abaixo). Ela vira o título do cartão: largura inteira,
     alinhada à esquerda, sem rótulo. O `order: -1` a leva para o topo mesmo
     quando não é a primeira coluna — no extrato do financeiro a primeira coluna
     é o vencimento, e sem isso o cartão abria pela data enquanto a descrição
     do lançamento saía espremida numa coluna de 130px, quebrada em cinco
     linhas e alinhada à direita. */
  table.tabela td:has(strong) {
    order: -1; display: block; text-align: left; font-size: 14px;
    padding: 8px 14px 4px;
  }
  /* tabela sem célula em destaque (Estúdio: nome | data): título é a 1ª coluna */
  table.tabela tr:not(:has(strong)) td:first-child {
    display: block; text-align: left; font-size: 14px; padding: 8px 14px 4px;
  }
  table.tabela td:has(strong)::before,
  table.tabela tr:not(:has(strong)) td:first-child::before,
  table.tabela td[data-rotulo=""]::before { display: none; }
  table.tabela td:empty { display: none; }
  table.tabela td .acoes-linha { justify-content: flex-end; }

  .kpi { flex: 1 1 44%; min-width: 0; padding: 12px 13px; }
  .kpi .v { font-size: 18px; }
  .cartoes { grid-template-columns: 1fr; }
}

/* -------- modal vira folha que sobe pela base -------- */
/* Centralizado no meio da tela, o modal briga com o teclado do celular: o
   teclado ocupa a metade de baixo e empurra o formulário para fora. Ancorado na
   base, o campo em foco fica logo acima do teclado, que é onde o polegar está. */
@media screen and (max-width: 640px) {
  .modal-fundo { display: flex; align-items: flex-end; padding: 0; }
  .modal {
    max-width: none; max-height: 92dvh; margin-top: auto;
    border-radius: 14px 14px 0 0; border-bottom: none;
  }
  .modal.largo { max-width: none; }
  .modal-cab { padding: 16px 18px 12px; }
  .modal-corpo { padding: 16px 18px; }
  .modal-pe {
    position: sticky; bottom: 0; background: var(--panel);
    padding: 12px 18px calc(16px + env(safe-area-inset-bottom));
  }
  .modal-pe .btn { flex: 1 1 auto; padding: 12px 16px; }
  .modal-pe .esquerda { flex: 0 0 100%; margin-right: 0; }
}

/* -------- gráfico: rola na horizontal em vez de encolher a tipografia -------- */
/* Espremido em 340px, o rótulo do mês sai com 5px de altura. Melhor manter o
   desenho no tamanho legível e deixar o dedo arrastar. */
.gfx-rolagem { overflow-x: auto; }
@media screen and (max-width: 640px) {
  .gfx { min-width: 600px; }
  .gfx .rot { font-size: 17px; }
  .legenda { font-size: 10.5px; gap: 12px; }
}

/* -------- kanban: uma coluna por vez, com encaixe -------- */
@media screen and (max-width: 640px) {
  .kanban { scroll-snap-type: x mandatory; }
  .coluna { flex: 0 0 min(78vw, 260px); scroll-snap-align: start; }
}

/* -------- toque: sem mouse, não existe "passar por cima" -------- */
/* Ações reveladas no hover ficam invisíveis E inalcançáveis num celular. */
@media screen and (hover: none) {
  .tarefa .acoes-linha { opacity: 1; }
  /* "editar"/"excluir" são links de texto: 23px de altura é metade de uma ponta
     de dedo, e errar o alvo aqui é apagar a linha errada. Cresce a área
     clicável, não a fonte. */
  .btn-linha { min-height: 34px; display: inline-flex; align-items: center; padding: 4px 2px; }
  .icon-btn { width: 38px; height: 38px; }
  .chip { padding: 9px 14px; }
  /* a caixa de concluir é a ação principal da lista de tarefas — merece o dedo
     inteiro, não a unha */
  .caixa { width: 32px; height: 32px; font-size: 15px; }
}
button, .chip, .nav-item, summary { touch-action: manipulation; }
