/* menu-impressao-programacao.css — menu da central + o @media print e o @page GLOBAIS + quadro da programação + paginação. Nome comprido de propósito: quem mexe aqui mexe na impressão de cinco ferramentas
   Cortado de index.html por scripts/cortar-css.js. A ORDEM dos <link> no
   index.html é a ordem original do arquivo e não pode mudar: em CSS quem
   vem depois ganha. O grupo `css` da fumaça guarda isso. */
  /* ---- menu da central ---- */
  .hub-h{position:relative}
  .hub-actions{position:absolute;right:0;top:4px;display:flex;gap:8px;align-items:center}
  .gear{font-size:19px;line-height:1;text-decoration:none;color:var(--mut);border:1px solid var(--line);border-radius:10px;padding:9px 12px;background:var(--card);cursor:pointer}
  .gear:hover{color:var(--acc);border-color:var(--acc)}
  .userbadge{font-size:12px;color:var(--mut);background:var(--card2);border:1px solid var(--line);border-radius:20px;padding:7px 14px;white-space:nowrap}
  .userbadge b{color:var(--tx);font-weight:600}
  .chips{display:flex;flex-wrap:wrap;gap:8px}
  .chip{border:1px solid var(--line);border-radius:20px;padding:7px 14px;cursor:pointer;background:var(--card2);color:var(--tx);font:inherit;font-size:13px}
  .chip:hover{border-color:var(--acc)}
  .chip.act{border-color:var(--acc);color:var(--acc);font-weight:600}
  input.cor{height:42px;padding:4px;cursor:pointer}

  #toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(20px);
    background:#1c241f;border:1px solid var(--acc);color:var(--tx);padding:10px 18px;border-radius:8px;
    font-size:13.5px;opacity:0;pointer-events:none;transition:all .25s;z-index:300}
  #toast.on{opacity:1;transform:translateX(-50%) translateY(0)}

  /* Canal de erro: separado do toast e persistente. Um erro que some sozinho em
     2,8s faz o usuário acreditar que salvou — ver spec de 2026-08-02. */
  #erro{position:fixed;left:50%;top:16px;transform:translateX(-50%);
    display:none;gap:12px;align-items:flex-start;
    max-width:min(560px,92vw);padding:12px 14px;
    background:var(--card);border:1px solid var(--red);border-radius:8px;
    color:var(--tx);font-size:13.5px;line-height:1.45;
    box-shadow:0 12px 32px rgba(0,0,0,.45);z-index:300}
  #erro.on{display:flex}
  #erro .msg{flex:1;min-width:0;overflow-wrap:anywhere}
  #erro .x{background:none;border:0;color:var(--mut);font-size:17px;line-height:1;
    cursor:pointer;padding:2px 6px;min-width:24px;min-height:24px;
    display:flex;align-items:center;justify-content:center;flex:0 0 auto}
  #erro .x:hover{color:var(--tx)}

  /* Versão nova disponível. Canto inferior direito de propósito: o #erro ocupa
     o topo do centro e o #toast o rodapé do centro, e os três podem estar na
     tela ao mesmo tempo. Borda de acento, não vermelha nem verde -- não é
     falha nem sucesso, é uma oferta. */
  #atualizar{position:fixed;right:16px;bottom:16px;
    display:none;gap:10px;align-items:center;
    max-width:min(420px,calc(100vw - 32px));padding:10px 12px;
    background:var(--card);border:1px solid var(--acc);border-radius:8px;
    color:var(--tx);font-size:13.5px;line-height:1.45;
    box-shadow:0 12px 32px rgba(0,0,0,.45);z-index:300}
  #atualizar.on{display:flex}
  #atualizar .msg{flex:1;min-width:0}
  /* 44px nos dois botões, contra os 24px do × do #erro: esta faixa aparece
     também no tablet em obra, onde se toca de luva. Alvo pequeno ali erra. */
  #atualizar .btn{min-height:44px}
  #atualizar .x{background:none;border:0;color:var(--mut);font-size:17px;line-height:1;
    cursor:pointer;padding:2px 6px;min-width:44px;min-height:44px;
    display:flex;align-items:center;justify-content:center;flex:0 0 auto}
  #atualizar .x:hover{color:var(--tx)}

  .modalbg{position:fixed;inset:0;background:var(--scrim);display:flex;align-items:center;justify-content:center;z-index:200}
  .modalbg[hidden]{display:none}
  .modalbox{background:var(--card);border:1px solid var(--line);border-radius:var(--radius-md);padding:22px 24px;width:340px;max-width:90vw;box-shadow:0 20px 50px rgba(0,0,0,.4)}
  .modalbox h3{margin:0 0 8px;font-size:15px;font-weight:600}
  .modalbox .btnrow{justify-content:flex-end}
  .modalbox-lg{width:720px}
  .modalbox-hd{display:flex;align-items:center;justify-content:space-between;margin-bottom:14px}
  .modalbox-hd h3{margin:0}
  .obtablewrap{max-height:60vh;overflow-y:auto;margin-top:12px}

  @media (max-width:860px){
    .g6{grid-template-columns:repeat(2,1fr)}
    /* Sem esta linha o `repeat(2,1fr)` acima NÃO TEM EFEITO. Cada campo
       carrega `grid-column:span N` no próprio atributo `style` (são 79 no
       arquivo, com N de 1 a 6), e um span maior que o número de colunas faz o
       navegador criar COLUNAS IMPLÍCITAS: medido em tela de 390px, a grade
       voltava a ter seis colunas, de 18px cada, com o seletor de tipo do
       cliente em 48px e o e-mail em 48px — inutilizáveis. `!important` é
       necessário porque estilo inline vence folha de estilo.
       `auto` e não `span 2`: em duas colunas, cada campo ocupa uma célula, o
       que mantém a densidade em tablet. Abaixo de 560px a grade vira uma
       coluna só (regra logo abaixo) e cada campo ocupa a linha inteira. */
    .g6>*{grid-column:auto !important}
    .perbar{grid-template-columns:repeat(2,1fr)}
    .totcard{grid-template-columns:repeat(2,1fr)}
    .lanwrap{overflow-x:auto}
  }
  /* Celular: uma coluna. Duas colunas em 390px dariam ~150px por campo, que é
     estreito demais para CNPJ, e-mail ou endereço. */
  @media (max-width:560px){
    .g6{grid-template-columns:1fr}
    /* A tabela rola DENTRO dela mesma, em vez de empurrar a página inteira.
       Medido em 390px: a lista de clientes tem 345px e a de usuários 590px,
       e sem isto a página toda ganhava rolagem lateral — o cabeçalho, os
       campos e os botões saíam do lugar junto. `display:block` é o que torna
       a tabela um bloco rolável; as linhas continuam se comportando como
       linhas de tabela. Mesma ideia do `.lanwrap` que a tela de lançamento
       de horas já usava. */
    table.list{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}
    /* A fila de abas de filtro não cabe em 390px (medido: passava 24px). Rolar
       por dentro mantém as abas na mesma linha, que é como elas se leem; quebrar
       em duas linhas empurraria o formulário inteiro para baixo. */
    .repfilter-tabs{overflow-x:auto;-webkit-overflow-scrolling:touch}
    .rftab{white-space:nowrap}
  }
  @media (prefers-reduced-motion:reduce){ *{transition:none !important} }

  @media print{
    body{background:#fff}
    *{-webkit-print-color-adjust:exact;print-color-adjust:exact}
    #home,.back,.app-h,nav.tabs,.panel,.opanel,.cpanel,.alpanel,.cfgpanel,.mpanel,.cvpanel,.pagpanel,.medpanel,.pv-bar,#toast,#erro,#atualizar{display:none !important}
    .sb-spacer,.sidebar{display:none !important}
    .shell{min-height:0}
    .main{padding:0}
    .app{padding:0;max-width:none}
    #previewWrap{margin:0}
     #preview{box-shadow:none;border-radius:0;max-width:none;padding:0;margin:0}
      /* reduzir o espaço superior (padding-top) e aumentar bottom padding
        para dar mais espaço antes das assinaturas em impressão */
      .rep,.opage,.cpage,.alpage,.al2-folha,.rh2-folha,.pg2-folha{padding:6mm 8mm 10mm}
      /* aumentar especificamente o espaçamento acima da seção de assinaturas */
      .rep .sigs,.opage .sigs,.cpage .sigs,.alpage .sigs{margin-top:80px}
      /* 30px (7,9 mm) até 2026-09-06, e era TODO o espaço que a caneta tinha.
         Agora este padding é o PISO, não o total: ele fica DENTRO da caixa do
         rodapé, então soma com o `margin-top:auto` (relatorio-horas.css:53),
         que é por fora e cresce com o que sobrar da folha. Numa folha folgada a
         assinatura ganha os dois -- o relatório em branco de 15 linhas, que é o
         que vai para a obra ser assinado à mão, mede 18,5 mm de papel limpo.

         Na folha mais cheia que este relatório produz -- 15 linhas MAIS o bloco
         de totais -- a margem automática vale zero e sobra só este piso. Ele NÃO
         pode subir: aquela folha fecha em 285,0 mm dos 285 mm úteis, então cada
         milímetro a mais aqui é milímetro cortado pelo `overflow:hidden` logo
         abaixo (medido: com 10 mm, 3,3 mm da linha "Cidade — UF, __ de __"
         sumiam). Quem quiser mais folga ali tem de tirar uma linha da folha, e
         isso é uma segunda folha com uma linha só -- avaliado e recusado em
         2026-09-06, com o motivo em horas.js, na definição de CHUNK. */
      .rh2-folha .rh2-rodape{padding-top:18px}
      /* Menos 4 mm no pé, pelo mesmo orçamento: a folha do relatório de horas é
         a única aqui que enche até a borda, e 6 mm continuam acima da margem
         morta de qualquer impressora jato/laser comum (5 mm). */
      .rh2-folha{padding-bottom:6mm}
      /* O bloco de totais aperta o cinto no papel (na tela fica como estava):
         margem de 10px para 4px e padding vertical de 8px para 5px devolvem
         2,6 mm. É o único lugar da folha cheia de onde ainda dava para tirar
         espaço, e ele vai inteiro para a assinatura -- sem isso o relatório
         PREENCHIDO fica com 5,7 mm de caneta, menos que os 7,9 mm de antes
         deste conserto, porque ali a folha já está no limite e o `margin-top:auto`
         não tem sobra nenhuma para dar. */
      .rh2-folha .rh2-tot{margin-top:4px;padding:5px 12px}
     .rep:last-child,.opage:last-child,.cpage:last-child,.alpage:last-child,.al2-folha:last-child,.rh2-folha:last-child,.pg2-folha:last-child{page-break-after:auto}
     .rep+.rep,.alpage+.alpage,.rh2-folha+.rh2-folha{border-top:none;margin-top:0;padding-top:12mm}
     .opage,.cpage,.alpage,.al2-folha,.pg2-folha{min-height:287mm;box-sizing:border-box}
     /* A PAISAGEM SAIU em 2026-08-28, no mesmo dia em que entrou. A ideia era boa no
        papel -- a fachada e 2,15:1, o quadro e 6:1 -- mas a `@page` nomeada VAZOU no
        Chromium: medido em PDF, 56 folhas viraram 195 paginas, 176 delas em paisagem e 59
        praticamente em branco. Orientacao mista so volta com prova em PDF, nao com
        promessa de suporte.

        UMA FOLHA = UMA PAGINA, e agora e altura FIXA, nao minima: `min-height` deixava o
        conteudo empurrar a folha para alem da pagina e a sobra caia numa pagina seguinte
        meio vazia. Com altura fixa e overflow escondido, a folha ou cabe ou o defeito
        aparece na conferencia -- em vez de virar papel picado na fabrica. */
     .pg2-folha{height:297mm;min-height:0;overflow:hidden;
       break-inside:avoid;page-break-inside:avoid;display:flex;flex-direction:column}
     .pg2-folha:last-child{break-after:auto;page-break-after:auto}
     /* O RODAPÉ DE ASSINATURA VOLTOU A DESCER ATÉ O PÉ DA PÁGINA (2026-09-06).
        Até aqui esta regra era `min-height:auto;height:auto`, e o efeito colateral
        passou despercebido: `.rh2-folha` é um flex em coluna e o rodapé desce pelo
        `margin-top:auto` de relatorio-horas.css:53 -- que só empurra alguma coisa
        quando existe altura SOBRANDO. Com altura automática a folha encolhe até o
        conteúdo, sobra vira zero, e o rodapé gruda na tabela. Medido com a sonda:
        7,9 mm de papel limpo acima da linha de assinatura (os 30px da regra logo
        acima, e nada mais), tanto na folha de 13 linhas quanto na de 15 -- pouco
        para assinar à caneta, que é como este documento é usado.

        Na TELA nunca apareceu porque lá vale o `min-height:296mm` do arquivo do
        relatório; era só no papel. Numa folha de 13 linhas sobravam 33 mm de papel
        em branco ABAIXO do rodapé enquanto a assinatura ficava espremida em cima.

        É PISO, não teto -- e aqui está a diferença para o `.pg2-folha` logo acima,
        que usa altura FIXA com `overflow:hidden`. A altura fixa foi tentada neste
        relatório em 2026-09-06 e recusada pela bateria (h8, fumaça): o número de
        linhas não determina a altura da folha, porque a coluna "Atividades
        executadas" é texto livre. Com atividade longa, 14 e 15 dias preenchidos
        passam da página -- medido, 92,5 px (24,5 mm) no pior caso -- e o
        `overflow:hidden` cortava isso EM SILÊNCIO, levando junto a linha de
        assinatura. Num documento que existe para ser assinado, perder conteúdo é
        pior do que gastar meia folha a mais.

        Com `min-height` o comportamento é o certo nos dois lados: sobrando altura,
        o `margin-top:auto` empurra a assinatura até o pé da página (o conserto);
        faltando altura, a folha cresce e o navegador quebra, como sempre fez --
        nada some. 296 mm, e não 297, deixa 1 mm de folga contra o arredondamento
        que jogaria uma página em branco atrás de cada folha. */
     .rh2-folha{min-height:296mm}
     .rh2-folha+.rh2-folha{padding-top:6mm;page-break-before:always}
    .al2-folha+.al2-folha,.opage+.opage,.cpage+.cpage,.pg2-folha+.pg2-folha{border-top:none;margin-top:0;padding-top:0;page-break-before:always}
    /* Cada esquadria comeca em pagina nova -- mesmo desenho de
       .opage+.opage/.cpage+.cpage NA QUEBRA (page-break-before:always), logo
       acima. Nao existe regra `page-break-after:always` para .rep neste
       projeto (a de :last-child acima e resto de uma que sumiu), entao a
       quebra tem de vir daqui.
       As irmas tambem zeram padding-top (:1215); esta nao, de proposito: as
       folhas de medicao continuam com a classe `.rep`, entao `.rep+.rep`
       (:1212) empurraria 12mm de padding-top -- o espaco que fazia sentido
       ENTRE folhas de um fluxo continuo, antes de cada .medrep virar uma
       pagina propria. `padding-top:6mm` aqui reafirma o valor que a PRIMEIRA
       folha ja tem (herdado de `.rep,.opage,...{padding:6mm 8mm 10mm}`,
       :1207), pra toda folha imprimir com a mesma margem superior. Achado da
       revisao (Menor 2): sem isto, a folha 1 imprime a 6mm do topo e a 2
       em diante a 12mm -- 6mm de desalinhamento visivel folheando o PDF,
       que so aparece na conferencia humana. */
    .medrep+.medrep{padding-top:6mm;page-break-before:always}
    /* NENHUMA unidade e partida ao meio: se o bloco nao cabe no resto da
       pagina, desce inteiro. Uma unidade com muitas fotos PODE ocupar mais
       que uma pagina -- nesse caso ela parte, e o navegador ignora a regra
       sozinho; o contrario seria esconder foto, e a regra desta etapa e
       mostrar mais.
       Rodada 2 (Importante 1 da revisao): `.medrep-cauda` somada a esta
       MESMA regra, nao uma regra nova -- a cauda da folha (observacao +
       legenda, medRepCaudaHtml em medicao.js) podia escorregar sozinha
       para uma pagina final sem identificacao nenhuma (janela medida de
       51px em 290,84, 17,5%, review.md Importante 1). Ela ganhou a MESMA
       linha de identificacao dos blocos de unidade (.medrep-un-id) e
       precisa da MESMA garantia de nao ser partida, senao a linha nova
       podia ficar numa pagina e o resto da cauda na seguinte -- o mesmo
       defeito, um nivel abaixo.
       A MESMA RESSALVA da unidade vale para a cauda, e faltava dizer
       (Nit da re-revisao): bloco mais alto que a pagina PARTE assim mesmo,
       porque o navegador ignora a regra sozinho. Para a cauda isso comeca
       por volta de 16.500 caracteres de observacao -- longe do uso real,
       mas nao e garantia absoluta, e afirmar que e seria a mesma frase
       falsa que a Rodada 2 veio consertar. */
    .medrep-un,.medrep-cauda{page-break-inside:avoid}
    .grade tr,.rh2-tab tr,.al2-tab tr,.al2-perf,.medrep-tab tr{page-break-inside:avoid}
    .al2-aten,.al2-rodape,.al2-topo,.al2-meta{page-break-inside:avoid}
    .ohead,.otb,.osec,.oitem,.opay,.cmeta,.csec,.ctb tr{page-break-inside:avoid}
    /* Segundo modelo do orçamento (css/orcamento-proposta.css). A distribuição
       real é medida em js/orcamento-proposta.js, como no contrato; isto é a rede
       de segurança para o caso de o navegador quebrar diferente do que se mediu
       -- e um item partido no meio deixaria as medidas numa folha e o preço na
       seguinte. */
    .op2-item,.op2-cab,.op2-tot,.op2-sigs,.op2-rod{page-break-inside:avoid}
    /* Reafirma os 6mm do topo da folha 2 em diante, pelo mesmo motivo e com a
       mesma forma de `.medrep+.medrep` (:211): `.opage+.opage` (:195) zera o
       padding-top, e medido em 2026-09-07 a linha "Obra:" da folha de
       continuação saía a 0,3mm da borda física do papel -- dentro da faixa que
       impressora comum não imprime (2 a 5mm), e 6mm desalinhada da folha 1.
       `.opage.op2+.opage.op2` (0,4,0) vence `.opage+.opage` (0,2,0) sem
       encostar no contrato, que imprime hoje como imprimia. O contrato tem o
       mesmo desalinhamento, e continua tendo: consertá-lo mudaria a aparência
       de um documento que o DESIGN.md congela, e isso é decisão do dono.
       Não muda a distribuição: `espaco()` já reserva 271mm dos 287. */
    .opage.op2+.opage.op2{padding-top:6mm}

    /* Task 6 (financeiro-entrega-2, adendo Ruling 23): a folha do
       Financeiro ESTENDE o bloco acima em vez de abrir um segundo
       @media print -- ele já esconde o cromo do app inteiro por uma lista
       nomeada (não por "apaga tudo, reacende o resto": #tool-financeiro não
       é filho direto do body, então body>*{display:none} apagaria um
       ancestral que nenhum display:block em descendente ressuscita). Falta
       nessa lista só o cromo do PRÓPRIO #tool-financeiro: as abas
       (.repfilter-tabs, que embrulha todo .rftab desta ferramenta) e os
       dois blocos que só fazem sentido na tela. #finResSerieCard sai pelo
       id, não por :has() -- suporte que precisa de conferência não é o
       lugar certo para pendurar um critério de bateria (fin30). Os outros
       .tool e os outros .finpane já ficam com [hidden] e não têm display de
       autor (conferido: não existe regra .tool{} nem .finpane{} de
       display neste arquivo) -- o display:none do navegador já resolve,
       nada a fazer aqui por eles. */
    #tool-financeiro .repfilter-tabs,#finResCtr,#finResSerieCard{display:none !important}

    /* Ruling 24: a regra *{print-color-adjust:exact} logo acima manda
       imprimir o fundo do tema, que é escuro -- os cards sairiam quase
       pretos. Em vez de desligar esse ajuste só para a subárvore (o
       resultado dependeria de como cada navegador decide "economizar"
       tinta, não é determinístico), a folha do Financeiro força fundo
       BRANCO e texto ESCURO de propósito, redefinindo as variáveis CSS que
       o resto da tela já usa (var(--mut), var(--green), var(--red)...),
       inclusive as duas que finResRenderFaixa aplica via style.color
       inline (financeiro-resultado.js) -- variável CSS resolve de novo em
       cada elemento da árvore, então um único ponto de troca aqui já
       alcança tabela, faixa e números sem duplicar regra por regra.
       --green/--red originais foram pensados para fundo escuro e ficam
       claros demais sobre papel branco (verde #22c55e mede ~2,3:1 de
       contraste em branco, abaixo do piso de leitura) -- aqui usam a
       versão escurecida, mesma direção (verde entra, vermelho sai),
       distinguível e legível no papel. --acc não muda: marca não é
       status. */
    #finPaneResultado{color:#000;--card:#fff;--mut:#4b5563;--green:#15803d;--red:#b91c1c;
      padding:6mm 8mm 10mm}
    #finPaneResultado .card{break-inside:avoid;border:none}

    /* S1 (task-6-fix-1): @media(max-width:900px) (base.css) empilha o
       .finband porque uma consulta de midia em impressao avalia contra a
       CAIXA DE PAGINA, nao a janela -- A4 retrato com @page{margin:0} mede
       ~794px CSS, abaixo do breakpoint de 900. Sem isto a faixa de tres
       numeros da folha do Financeiro sai empilhada, uma sobre a outra, em
       vez das tres colunas que a tela mostra. Reafirma as 3 colunas e as
       bordas verticais so para esta folha -- o seletor com #finPaneResultado
       na frente (especificidade 1,1,0) vence o `.finband` sozinho de
       base.css (0,1,0) mesmo os dois arquivos carregando em ordem qualquer:
       especificidade decide, não ordem de <link>, quando os dois seletores
       têm pesos diferentes. */
    #finPaneResultado .finband{grid-template-columns:repeat(3,1fr)}
    #finPaneResultado .finband>div{border-right:1px solid var(--line);border-bottom:none}
    #finPaneResultado .finband>div:last-child{border-right:none}
  }
  /* margem 0 na página elimina a data, o título e o endereço do arquivo que o
     navegador imprime no topo e no rodapé; as margens do papel viram o padding
     interno de cada folha (.rep) */
  @page{size:A4;margin:0}
  .progboard{display:flex;gap:14px;overflow-x:auto;padding-bottom:10px}
  .progcol{flex:0 0 230px;background:var(--card2);border:1px solid var(--line);border-radius:var(--radius-md);padding:10px}
  .progcol h4{margin:2px 4px 10px;font-size:12.5px;text-transform:uppercase;letter-spacing:.03em;color:var(--mut);display:flex;justify-content:space-between}
  .progcard{background:var(--card);border:1px solid var(--line);border-radius:var(--radius-sm);padding:10px 11px;margin-bottom:9px}
  .progcard b{display:block;font-size:13.5px;margin-bottom:3px}
  .progcard .cli{font-size:12px;color:var(--mut);margin-bottom:7px}
  .progsub{margin-left:14px;border-left:2px solid var(--line);padding-left:9px}
  .stpill.fase-atrasada{background-color:rgba(239,68,68,.15);color:var(--red);font-weight:700}
  .stpill.sub-obra{background-color:rgba(245,158,11,.15);color:var(--amber)}
  .stpill.locked{background-color:rgba(99,102,241,.15);color:var(--acc);margin-left:6px}
  #tool-estr .es-ped-row{display:grid;grid-template-columns:1fr auto auto;gap:8px;align-items:center;padding:8px 0;border-bottom:1px solid var(--line)}
  #tool-estr .es-ped-row .nm b{display:block;font-size:13.5px}
  #tool-estr .es-ped-row .nm span{color:var(--mut);font-size:12px}
  #tool-estr .es-ped-row input{width:70px}
  /* Cinco colunas, não sete: a agenda é de dias úteis (decisão do dono,
     2026-08-10). Ao mexer aqui, mexa junto no cabeçalho e no salto de fim de
     semana em agRender() — os três têm de contar a mesma semana. */
  /* `minmax(0,1fr)` e NÃO `1fr`: `1fr` é `minmax(auto,1fr)`, e `auto` tem como
     piso o min-content da célula. Com as gavetas de período (2026-08-12) esse
     piso subiu — o rótulo "Manhã" mais uma etiqueta de compromisso —, e no
     celular as cinco colunas viraram 173px, 27px, 27px, 27px e 64px, com o
     calendário rolando 75px de lado. `minmax(0,...)` deixa a coluna encolher
     abaixo do conteúdo, e quem apara é o `text-overflow` da etiqueta, que já
     existia.

     Essa mesma regra, sem mais nada, deixava a coluna encolher até ~39px no
     celular — a página parava de rolar, mas "MANHÃ" virava "M..." e o
     calendário ficava ilegível (relatado pelo dono, uso diário). O piso de
     legibilidade mora no `@media(max-width:560px)` abaixo: um MÍNIMO
     explícito por coluna, e não mais o piso implícito do conteúdo — a lição
     de agTarLista/celular.js é a mesma, "1fr tem o conteúdo como piso", só
     que aqui o piso agora é ESCOLHIDO, não acidental. */
  .ag-grade{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px;margin-top:12px}
  /* Piso de legibilidade no celular — mesma ideia de `table.list` no bloco de
     560px lá em cima, mas DECLARADA AQUI, depois da regra base: mesma
     especificidade (uma classe), então quem vem depois no arquivo é quem
     vale, e a regra base é `.ag-grade` sem media query nenhuma — colocar o
     conserto no bloco de 560px do topo (antes da regra base) o deixava sem
     efeito nenhum, sabotado pela ordem, achado rodando o critério contra a
     tela de verdade. Cada coluna ganha um MÍNIMO de 96px — dá pro rótulo do
     período por inteiro — e quem rola de lado é a GRADE, não a página:
     cabeçalho e dias moram no mesmo elemento (#agGrade), então rolam juntos
     sem precisar sincronizar um cabeçalho fixo com o corpo por JavaScript. */
  @media (max-width:560px){
    .ag-grade{grid-template-columns:repeat(5,minmax(96px,1fr));overflow-x:auto;-webkit-overflow-scrolling:touch}
  }
  .ag-cab{font-weight:600;text-align:center;padding:6px 0;opacity:.7;font-size:13px}
  .ag-dia{min-height:96px;border:1px solid var(--line);border-radius:8px;padding:6px;cursor:pointer;background:var(--card)}
  .ag-dia:hover{border-color:var(--acc)}
  .ag-dia.fora{opacity:.35}
  .ag-dia.hoje{border-color:var(--acc);border-width:2px}
  .ag-num{font-size:12px;font-weight:600;opacity:.8}
  /* A GAVETA de período. O riscado saiu da célula e veio para cá em
     2026-08-12: travar passou a ser por metade de dia, e uma célula riscada
     inteira deixaria a manhã travada parecendo dia travado.
     Gaveta vazia não é desenhada (agenda.js) — exceto no modo travar, senão
     não haveria onde clicar num dia sem compromisso. */
  /* SEM margem negativa. A primeira versão sangrava 4px para cada lado, para
     o riscado encostar na borda da célula — e com isso a gaveta ficava 8px
     mais larga que a célula. Vezes cinco colunas, no celular, a Agenda passou
     a rolar 59px de lado (cl5 pegou). O riscado inset é mais discreto e não
     custa layout. */
  .ag-periodo{margin:6px 0 0;padding:3px 4px;border-radius:6px}
  /* Apara em vez de VAZAR. Com a coluna ainda podendo chegar a ~39px em telas
     mais largas que 560px (a legibilidade abaixo disso é o que o
     `@media(max-width:560px)` resolve), "MANHÃ" continua podendo não caber
     por inteiro: sem isto o rótulo invadia a célula do dia seguinte
     (fotografado). Fica como rede de segurança mesmo com o piso de largura —
     um compromisso com título comprido no chip usa a mesma regra. */
  .ag-periodo-rot{font-size:10px;font-weight:700;letter-spacing:.06em;
    text-transform:uppercase;color:var(--mut);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .ag-periodo.travado{background:repeating-linear-gradient(45deg,transparent,transparent 6px,rgba(128,128,128,.18) 6px,rgba(128,128,128,.18) 12px);cursor:not-allowed}
  .ag-chip{display:block;margin-top:4px;padding:2px 6px;border-radius:6px;font-size:11px;color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

  /* ================= PAGINAÇÃO DE ACM =================
     Cartões/tabela reaproveitam .card/.grid.g6/.fld/table.list já genéricos
     (ver Corte ACM). Só o que é específico desta ferramenta mora aqui: a
     linha de cada trecho, o desenho SVG e o mapa de painéis/chapas do
     resultado -- cores portadas do paginador avulso original (styles.css)
     para a paleta escura do app. */
  .pagpanel[hidden]{display:none}
  .pag-addrow{display:flex;flex-wrap:wrap;align-items:end;gap:10px;margin-bottom:10px}
  .pag-addrow .fld{width:160px}
  /* #pagTrechos rola por dentro (mesmo molde de .crowwrap, index.html:809) --
     "→ Esquerda" + campo de medida + "Apagar" não cabem nos ~210px de um
     cartão a 380px de largura (minmax(120px,1fr) sozinho já passa disso), e
     sem esta rolagem PRÓPRIA o vazamento empurra a PÁGINA inteira pro lado
     (medido: 34px de botão pra fora do cartão, 4px de scrollWidth na página --
     achado menor 5 da revisão final). Rolar aqui dentro mantém a página
     parada e ainda dá pra ver o botão "Apagar", só que arrastando. */
  #pagTrechos{overflow-x:auto}
  .pag-linha{display:grid;grid-template-columns:2rem minmax(120px,1fr) 90px auto;gap:8px;align-items:center;padding:7px 0;border-top:1px solid var(--line)}
  .pag-linha:first-child{border-top:0}
  .pag-linha .pdir{color:var(--mut);font-size:13px;font-weight:600}
  #pagDesenho{display:block;width:100%;aspect-ratio:1.5/1;min-height:280px;max-height:min(80vh,760px);border:1px solid var(--line);border-radius:8px;background:var(--card2);cursor:crosshair;margin-top:10px}
  .pag-recgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;margin:10px 0}
  .pag-metric{padding:10px;border:1px solid var(--line);border-radius:8px;background:var(--card2)}
  .pag-metric dt{color:var(--mut);font-size:11.5px;font-weight:600}
  .pag-metric dd{margin:3px 0 0;font-size:15px;font-weight:700;overflow-wrap:anywhere}
  .pag-legend{display:flex;flex-wrap:wrap;gap:12px;margin:8px 0;font-size:12.5px;color:var(--mut)}
  .pag-legend span::before{display:inline-block;width:12px;height:12px;margin-right:5px;border:1px solid var(--line);vertical-align:-2px;content:""}
  .pag-legend .inteira::before{background:#3fae63}
  .pag-legend .recorte::before{background:#e0a63a}
  .pag-legend .router::before{background:repeating-linear-gradient(135deg,#8d56b1 0 4px,#3a2c46 4px 8px)}
  .pag-svgmap{display:block;width:100%;max-height:520px;border:1px solid var(--line);border-radius:8px;background:var(--card2)}
  .pag-sheets{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px}
  .pag-sheet{padding:10px;border:1px solid var(--line);border-radius:8px}
  .pag-sheet h4{margin:0 0 6px;font-size:13.5px}
  .pag-sheet .pag-svgmap{aspect-ratio:1/1.4;max-height:320px}
  .pag-piece{stroke:#0b0d10;vector-effect:non-scaling-stroke;stroke-width:1.2}
  .pag-piece.inteira{fill:#3fae63}
  .pag-piece.recorte{fill:#e0a63a}
  .pag-piece.router{fill:url(#pag-router-hatch)}
  .pag-maplabel{fill:#0b0d10;font:700 44px system-ui,sans-serif;text-anchor:middle;dominant-baseline:middle;pointer-events:none}
  .pag-recomendacao{padding:10px;border-radius:8px;background:color-mix(in srgb,var(--green) 20%,var(--card2));color:var(--tx)}
  .pag-incompleto{margin:10px 0;padding:10px;border:2px solid var(--red);border-radius:8px;color:var(--tx);font-weight:600}


/* Avisos da estrutura de alumínio: o quadro sobre painel router, a sobra curta demais
   para virar quadro. Não é erro -- o cálculo saiu -- é coisa para conferir na obra
   antes de mandar cortar tubo. */
.est-avisos { margin: 10px 0 0; padding-left: 18px; }
.est-avisos li { color: #d08b26; font-size: 13px; line-height: 1.5; }

/* Um desenho por TIPO de quadro, em milímetros reais no viewBox -- a proporção do
   desenho é a proporção da peça. A travessa central sai visivelmente mais larga
   quando é 50×25, que é a diferença que o dono precisa ver antes de mandar cortar. */
.est-quadros { display: grid; gap: 14px; margin-top: 12px; }
.est-quadro figcaption { font-size: 13px; opacity: .8; margin-bottom: 4px; }
.est-tubo { fill: #4a5568; stroke: #1a202c; stroke-width: 2; vector-effect: non-scaling-stroke; }
.est-tubo.central { fill: #b7791f; }
/* A horizontal ocupou o lugar do montante em 2026-08-28: mesma peça longitudinal, regra
   invertida -- ela passa direito e pica a intermediária. O nome mudou junto para o
   desenho da tela e o do impresso falarem a mesma língua. */
.est-tubo.horizontal { fill: #2c5282; }

/* O mapa dos quadros sobre a fachada. Tracejado = resultante (uma peça de painel,
   não duas) -- é o quadro que o montador confere duas vezes. */
.est-mapa { fill: rgba(74, 85, 104, .35); stroke: #2d3748; stroke-width: 2; vector-effect: non-scaling-stroke; }
.est-mapa.resultante { fill: rgba(183, 121, 31, .35); stroke-dasharray: 6 4; }
/* O quadro com dente sai como POLIGONO, e nao retangulo: e o contorno da chapa. */
.est-mapa.dente { fill: rgba(183, 121, 31, .5); }
/* O contorno da chapa por baixo dos tubos, no desenho do tipo: e ele que mostra por que a
   longarina corre em dois niveis. */
.est-chapadente { fill: rgba(255, 255, 255, .06); stroke: #718096; stroke-width: 1.5;
  stroke-dasharray: 5 4; vector-effect: non-scaling-stroke; }
.est-dobra { stroke: #c05621; stroke-width: 2; stroke-dasharray: 6 4; vector-effect: non-scaling-stroke; }

/* A pegada do caixote em U por cima do contorno. Hachurada e translúcida: o contorno e
   os marcadores de canto continuam legíveis por baixo, que é o que o dono confere. */
.cx-pegada { fill: rgba(99, 102, 241, .22); stroke: #6366f1; stroke-width: 4; stroke-dasharray: 24 16; vector-effect: non-scaling-stroke; }

/* ============ O IMPRESSO DA PAGINAÇÃO DE ACM ============
   Uma folha por bloco `.pg2-folha`, na ordem do CAD do dono: paginação do ACM,
   paginação da estrutura, os pedaços peça por peça, e um quadro por folha. As quebras
   de página vêm das listas do @media print acima, junto das irmãs -- este bloco cuida
   só da aparência.

   Preto no branco de propósito: o tema escuro da tela gastaria tinta e sairia ilegível
   na impressora do canteiro. */
/* A PRANCHA. Redesenhada em 2026-08-28 sobre as tres queixas do dono: faltava cota,
   faltava identificacao, estava confuso.

   COR COMO CODIGO, nao decoracao. Preto para geometria e cota; AZUL DE PRANCHA (--pg-id)
   so para IDENTIDADE -- balao da peca, codigo da folha, a horizontal do quadro. Se esta
   azul, e um nome; se esta preto, e medida. Os preenchimentos sao a legenda que o dono ja
   usa no CAD dele, so que reclareados para o texto preto ficar legivel por cima no papel.

   Preto no branco de proposito: o tema escuro da tela gastaria tinta e sairia ilegivel na
   impressora do canteiro. */
.pg2-folha {
  --pg-ink: #14181D; --pg-ink2: #5A626C; --pg-hair: #D3D8DE; --pg-rule: #A8B0B9;
  --pg-id: #1F4E79; --pg-campo: #FBFCFC;
  --pg-inteira: #CBE3D3; --pg-recorte: #F3E3C3; --pg-router: #D9DDE3; --pg-caixote: #F6D6D2;
  background: #fff; color: var(--pg-ink); border-top: 1px solid var(--pg-hair);
  padding: 12px 16px 16px; display: flex; flex-direction: column;
  font-family: 'IBM Plex Sans', system-ui, sans-serif;
}
.pg2-folha:first-child { border-top: none; }

/* SOBRANCELHA em cima -- codigo, titulo e data -- para achar a folha folheando o maco. */
.pg2-olho { display: flex; align-items: baseline; gap: 10px; border-bottom: 1.4px solid var(--pg-ink); padding-bottom: 4px; }
/* A MARCA ABRE A SOBRANCELHA, separada do resto por um filete. `align-self:center` porque
   a sobrancelha alinha pela LINHA DE BASE do texto -- uma imagem alinhada pela base fica
   pendurada acima da linha e desalinha tudo o que vem depois. */
.pg2-marca { align-self: center; display: flex; align-items: center;
  border-right: 1.4px solid var(--pg-rule); padding-right: 10px; margin-right: 2px; }
.pg2-marca img { max-height: 9mm; max-width: 34mm; object-fit: contain; display: block; }
.pg2-marca b { font-family: 'IBM Plex Sans Condensed', 'IBM Plex Sans', sans-serif; font-weight: 700;
  font-size: 16px; letter-spacing: .16em; text-transform: uppercase; color: var(--pg-id); }
.pg2-cod { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-weight: 600; font-size: 11px;
  color: #fff; background: var(--pg-id); padding: 2px 7px; letter-spacing: .06em; }
.pg2-tit { font-family: 'IBM Plex Sans Condensed', 'IBM Plex Sans', sans-serif; font-weight: 700;
  font-size: 17px; text-transform: uppercase; letter-spacing: .1em; }
/* A ESCALA NA SOBRANCELHA, ao lado do titulo. Numa prancha ela e informacao de primeira
   linha: sem ela, desenho pequeno ao lado de desenho grande parece defeito -- que foi
   exatamente como o dono leu a primeira entrega. */
.pg2-esc { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10px; font-weight: 600;
  color: var(--pg-ink); border: 1px solid var(--pg-rule); padding: 1px 6px; letter-spacing: .04em; }
.pg2-fl { margin-left: auto; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 10.5px; color: var(--pg-ink2); }
/* O CAMPO ENCOLHE, O BLOCO DE TITULO NAO. Sem os `min-height:0` em CADA nivel do
   aninhamento, o conteudo do campo impunha a propria altura, empurrava o rodape para fora
   da folha, e o `overflow:hidden` -- que existe para garantir uma pagina -- ENGOLIA o
   bloco de titulo. Medido em PDF: a fachada e as 38 folhas de quadro sairam sem obra,
   cliente nem numero. Um desenho de fabricacao sem identificacao e papel solto. */
.pg2-campo { flex: 1 1 auto; padding: 7mm 0 5mm; min-height: 0; display: flex; overflow: hidden; }
.pg2-bloco { flex: 0 0 auto; }

.pg2-pilha { display: flex; flex-direction: column; gap: 4mm; width: 100%; min-height: 0; }
.pg2-faixa { flex: 0 0 auto; }
.pg2-pecas, .pg2-chapas { min-height: 0; }
.pg2-cx { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center;
  background: var(--pg-campo); border: 1px solid var(--pg-hair); padding: 4mm; }
/* O SVG TEM TAMANHO PROPRIO, em milimetro, vindo do atributo width/height. Nao pode ser
   esticado pelo CSS: e o par (tamanho em mm + viewBox do mesmo formato) que trava a
   ESCALA no papel, e escala travada e o que faz a cota sair igual em toda folha. Esticar
   aqui reencaixaria o desenho e a escala escrita na sobrancelha viraria mentira.

   Ate 2026-08-28 era `width:100%;height:100%` e o desenho se ajustava a caixa que o CSS
   desse -- dai as 28,9 vezes de diferenca de escala que o dono viu folheando. */
.pg2-svg { display: block; width: auto; height: auto; max-width: 100%; flex: 0 0 auto; margin: 0 auto; }
.pg2-cx { flex: 0 0 auto; }

.pg2-faixa { display: flex; gap: 7mm; align-items: flex-start; border-top: 1px solid var(--pg-hair); padding-top: 3mm; }
.pg2-faixa > div:first-child { flex: 1; min-width: 0; }
.pg2-lat { width: 44mm; flex: 0 0 44mm; }
.pg2-faixa h3 { font-family: 'IBM Plex Sans Condensed', 'IBM Plex Sans', sans-serif; font-size: 10.5px;
  text-transform: uppercase; letter-spacing: .12em; color: var(--pg-ink2); margin: 0 0 4px;
  border-bottom: 1px solid var(--pg-hair); padding-bottom: 3px; }
.pg2-leg { list-style: none; margin: 0; padding: 0; columns: 4; column-gap: 5mm;
  font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 8.6px; }
/* `nowrap` porque `2.450 x 1.480` quebrado em duas linhas vira duas medidas na leitura
   rapida -- e a lista existe justamente para ler rapido. */
.pg2-leg li { display: flex; gap: 4px; align-items: center; padding: 1.5px 0;
  border-bottom: 1px dotted var(--pg-hair); break-inside: avoid; white-space: nowrap; }
.pg2-leg i { width: 9px; height: 7px; border: .6px solid var(--pg-ink); flex: 0 0 9px; }
.pg2-leg i.inteira { background: var(--pg-inteira); }
.pg2-leg i.recorte { background: var(--pg-recorte); }
.pg2-leg i.router { background: var(--pg-router); }
.pg2-leg .c { color: var(--pg-id); font-weight: 600; min-width: 16px; }
.pg2-leg .m { flex: 1; }
.pg2-leg .q { color: var(--pg-ink2); }
.pg2-leg li.pg2-mais { border: 0; color: var(--pg-ink2); font-style: italic; }
.pg2-cor { list-style: none; margin: 0; padding: 0; font-size: 9.5px; }
.pg2-cor li { display: flex; align-items: center; gap: 6px; padding: 1.5px 0; }
.pg2-cor i { width: 13px; height: 9px; border: .7px solid var(--pg-ink); display: inline-block; }
.pg2-cor i.inteira { background: var(--pg-inteira); }
.pg2-cor i.recorte { background: var(--pg-recorte); }
.pg2-cor i.router { background: var(--pg-router); }
.pg2-cor i.cx { background: var(--pg-caixote); }
.pg2-mini { width: 100%; border-collapse: collapse; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 9.5px; }
.pg2-mini td { padding: 1.6px 3px; border-bottom: 1px dotted var(--pg-hair); }

/* BLOCO DE TITULO no rodape, como manda a prancha: e onde a mao procura ao pegar a folha
   pelo canto de baixo. */
.pg2-bloco { border-top: 1.4px solid var(--pg-ink); display: grid;
  grid-template-columns: 1.6fr 1fr 1fr; padding-top: 3mm; }
.pg2-b { border-left: 1px solid var(--pg-hair); padding: 0 3mm; display: flex; flex-direction: column; gap: 2px; }
.pg2-b1 { border-left: 0; padding-left: 0; }
.pg2-b b { font-family: 'IBM Plex Sans Condensed', 'IBM Plex Sans', sans-serif; font-size: 8px;
  letter-spacing: .14em; color: var(--pg-ink2); font-weight: 600; }
.pg2-b span { font-size: 10px; line-height: 1.35; }
.pg2-be { text-align: right; align-items: flex-end; }
/* A imagem saiu daqui em 2026-08-28: a marca subiu para a sobrancelha, e o mesmo logo duas
   vezes na mesma folha e ruido. Aqui fica o nome por extenso com o CNPJ, que e o dado
   fiscal -- outra funcao, nao repeticao. */
.pg2-emp { font-family: 'IBM Plex Sans Condensed', 'IBM Plex Sans', sans-serif; font-weight: 700;
  font-size: 15px; letter-spacing: .14em; color: var(--pg-id); }
.pg2-be span:last-child { font-size: 8.4px; color: var(--pg-ink2); }

/* O DESENHO. Traco preto, preenchimento pela legenda do CAD dele. */
.pg2-peca { fill: var(--pg-inteira); stroke: var(--pg-ink); stroke-width: .6; vector-effect: non-scaling-stroke; }
.pg2-peca.recorte { fill: var(--pg-recorte); }
.pg2-peca.router { fill: var(--pg-router); }
.pg2-ctr { fill: none; stroke: var(--pg-ink); stroke-width: 1.6; vector-effect: non-scaling-stroke; }
.pg2-cxpeg { fill: var(--pg-caixote); stroke: #A8342B; stroke-width: 1; vector-effect: non-scaling-stroke; }
.pg2-quadro { fill: none; stroke: var(--pg-ink); stroke-width: 1.1; vector-effect: non-scaling-stroke; }
.pg2-quadro.resultante { stroke-dasharray: 7 5; }
/* O QUADRO QUE ACOMPANHA PECA COM DENTE sai em L, aparado no contorno, e nao mais como
   retangulo cheio atravessando a parede. Marcar em vermelho e avisar em texto nao
   resolveu: o dono mandou duas fotos do mesmo defeito dizendo "quadro passando pra fora".
   Desenho que precisa de legenda para nao parecer errado esta errado. */
.pg2-quadro.dente { stroke-dasharray: none; stroke-width: 1.4; }
/* O recorte na folha do tipo: hachura leve por dentro do quadro, para o montador ver
   ONDE o tubo acompanha o dente. */
.pg2-chapadente { fill: none; stroke: #A8342B; stroke-width: 1.4; stroke-dasharray: 9 5; vector-effect: non-scaling-stroke; }
/* O QUADRICULADO DE AMPLIACAO: fino e azul, porque e identidade de folha e nao geometria
   da obra. Na folha de conjunto ele diz onde procurar; na ampliacao, onde se esta. */
.pg2-bloco-marca { fill: none; stroke: var(--pg-id); stroke-width: 1.1; stroke-dasharray: 5 4;
  vector-effect: non-scaling-stroke; opacity: .75; }
/* O ROTULO DO TRECHO virou eixo de margem em 2026-08-28: numero embaixo, letra a direita,
   os dois FORA do desenho. A tarja branca que o protegia de cair sobre o desenho saiu
   junto -- fora do desenho nao ha o que tapar. */
.pg2-bloco-nome { fill: var(--pg-id); font-family: 'IBM Plex Mono', ui-monospace, monospace; font-weight: 700; }
.pg2-chapafundo { fill: #fff; stroke: var(--pg-ink); stroke-width: 1.2; vector-effect: non-scaling-stroke; }
/* O PERFIL TEM DE SE DISTINGUIR NO DESENHO, e nao so na tabela: o dono olhou a folha e
   disse que nao dava para ver qual travessa era a de 50x25. Ela e a unica que emenda duas
   chapas; cortar um 25x25 no lugar dela poe a junta sem apoio. Fundo escuro cheio, contra
   o cinza claro das outras -- e o rotulo `50x25` escrito em cima, no desenho. */
.pg2-tubo { fill: #DDE1E6; stroke: var(--pg-ink); stroke-width: .8; vector-effect: non-scaling-stroke; }
/* Escuro = 50x25, o unico perfil que emenda duas chapas. Chaveado pelo PERFIL e nao pelo
   papel: quadro resultante tem travessa central de 25x25, e pinta-la de escuro fazia o
   desenho contradizer a legenda ao lado. */
.pg2-tubo.junta { fill: #4A5561; }
/* A legenda de perfil do quadro, em linha e em tamanho de ler -- o rotulo dentro do tubo
   saia a 2,9 pt, medido em PDF. */
.pg2-corlinha { display: flex; gap: 7mm; flex-wrap: wrap; flex: 0 0 auto; }
.pg2-cor i.t50 { background: #4A5561; }
.pg2-cor i.t25 { background: #DDE1E6; }
.pg2-cor i.th { background: #b6c6d8; border-color: #1F4E79; }
.pg2-tubo.horizontal { fill: var(--pg-id); fill-opacity: .28; stroke: var(--pg-id); stroke-width: 1.1; }

/* O BALAO: identidade, e por isso azul. E o unico texto do desenho que nao e medida. */
.pg2-bal { fill: var(--pg-id); font-family: 'IBM Plex Mono', ui-monospace, monospace; font-weight: 600; text-anchor: middle; }
.pg2-balc { display: inline-flex; align-items: center; justify-content: center; min-width: 17px; height: 17px;
  padding: 0 4px; border-radius: 9px; background: var(--pg-id); color: #fff;
  font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 9.5px; font-weight: 600; }

/* A COTA: extensao fina, linha de cota media, tique inclinado, numero com halo branco
   para nunca sumir em cima do preenchimento.

   TODAS NA MESMA LINHA. O escalonamento (uma cota acima, a vizinha abaixo) e recurso de
   prancha densa, mas o dono leu como desalinhamento -- "uma esta para baixo outra para
   cima fora de alinhamento" -- e ele e quem le. Quem resolve a colisao agora e a fusao da
   cadeia, que junta o que nao cabe em vez de empilhar em dois niveis. */
.pg2-cota .lin, .pg2-cota .tiq { stroke: var(--pg-ink); stroke-width: .7; vector-effect: non-scaling-stroke; }
.pg2-cota .ext { stroke: var(--pg-ink2); stroke-width: .4; vector-effect: non-scaling-stroke; }
.pg2-cota .num { fill: var(--pg-ink); font-family: 'IBM Plex Mono', ui-monospace, monospace;
  text-anchor: middle; paint-order: stroke; stroke: #fff; stroke-linejoin: round; }

/* A LINHA DA DOBRA: onde o operador fresa o V antes de dobrar. Vermelha e tracejada -- e a
   unica marca do impresso que manda FAZER alguma coisa na chapa, e nao so medir. */
.pg2-dobra { stroke: #A8342B; stroke-width: 1; stroke-dasharray: 6 4; vector-effect: non-scaling-stroke; }

.pg2-pecas { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4mm; width: 100%; align-content: start; }
/* OS AVISOS DO CALCULO, no pé da folha da estrutura. Nao sao decoracao: e onde aparece o
   vao livre que passou do que o dono pediu, e o caixote que a ferramenta nao cobre. */
.pg2-avisos { flex: 0 0 auto; border-top: 1px solid var(--pg-hair); padding-top: 2.5mm; }
.pg2-avisos h3 { font-family: 'IBM Plex Sans Condensed', 'IBM Plex Sans', sans-serif; font-size: 10px;
  text-transform: uppercase; letter-spacing: .12em; color: #A8342B; margin: 0 0 3px; }
.pg2-avisos ul { list-style: none; margin: 0; padding: 0; columns: 2; column-gap: 6mm; font-size: 8.4px; line-height: 1.35; }
.pg2-avisos li { break-inside: avoid; padding-left: 9px; position: relative; margin-bottom: 1.5px; color: var(--pg-ink); }
.pg2-avisos li::before { content: '!'; position: absolute; left: 0; color: #A8342B; font-weight: 700; }
.pg2-chapas { display: grid; grid-template-columns: repeat(6, 1fr); gap: 3mm; width: 100%; align-content: start; }
/* A GRADE DOS QUADROS: duas colunas, e cada desenho ocupa uma, duas ou quatro casas
   conforme o tamanho que ele tem NA PROPRIA ESCALA. Dividir a folha nao encolhe ninguem
   -- so evita a folha quase vazia que um quadro de 101 mm deixava para tras. */
/* `align-items: start` para a caixa não esticar até a altura da vizinha: um quadro de
   meia folha ao lado de um de um quarto deixava o segundo com metade de moldura vazia. */
.pg2-quadros { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4mm; width: 100%;
  align-content: start; align-items: start; }
/* Os trechos de ampliação, empilhados: cada um com a altura que o conteúdo dele pede. */
.pg2-trechos { display: flex; flex-direction: column; gap: 4mm; width: 100%; align-content: start; }
.pg2-trecho { margin: 0; border: 1px solid var(--pg-hair); padding: 2.5mm; background: var(--pg-campo);
  display: flex; flex-direction: column; page-break-inside: avoid; break-inside: avoid; }
.pg2-trecho figcaption { display: flex; align-items: center; gap: 5px; margin-bottom: 1.5mm; }
.pg2-quadrobox.pg2-qcheia, .pg2-quadrobox.pg2-qfaixa { grid-column: span 2; }
.pg2-pecabox, .pg2-chapa, .pg2-quadrobox { margin: 0; border: 1px solid var(--pg-hair); padding: 2.5mm;
  background: var(--pg-campo); display: flex; flex-direction: column;
  page-break-inside: avoid; break-inside: avoid; }
.pg2-pecabox figcaption, .pg2-chapa figcaption, .pg2-quadrobox figcaption {
  display: flex; align-items: center; gap: 5px; margin-bottom: 1.5mm; flex-wrap: nowrap; }
.pg2-med { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 9.5px; font-weight: 500; }
.pg2-qtd { font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 9.5px; color: var(--pg-ink2); }
/* A escala fica na propria celula, e nao so na sobrancelha: numa folha com quatro
   quadros cada um tem a sua, e o numero solto la em cima serviria para nenhum. */
.pg2-cesc { margin-left: auto; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 8.6px;
  color: var(--pg-ink2); border: 1px solid var(--pg-hair); padding: 0 4px; white-space: nowrap; }
.pg2-pn { margin: 1.5mm 0 0; font-size: 8.2px; color: var(--pg-ink2); }
.pg2-tab { width: 100%; border-collapse: collapse; font-family: 'IBM Plex Mono', ui-monospace, monospace; font-size: 8.8px; }
.pg2-tab th { text-align: left; font-weight: 500; color: var(--pg-ink2); border-bottom: 1px solid var(--pg-rule); padding: 1.8px 5px; }
.pg2-tab td { padding: 1.8px 5px; border-bottom: 1px dotted var(--pg-hair); white-space: nowrap; }
.pg2-tab td.pg2-tq { color: var(--pg-id); font-weight: 700; font-size: 10px; border-right: 1px solid var(--pg-hair);
  vertical-align: middle; text-align: center; }
.pg2-tab tr.pg2-tsep td { color: var(--pg-ink2); font-size: 8px; border-bottom: 1px solid var(--pg-rule); padding-bottom: 3px; }

/* A barra do desenho: enquadrar e zoom. Fica ACIMA do SVG e não flutuando por cima dele —
   sobreposta, ela cobriria justamente o canto superior esquerdo, que é onde o contorno
   começa (o primeiro trecho parte de 0,0). */
.dv-barra { display: flex; align-items: center; gap: 6px; margin: 8px 0 4px; flex-wrap: wrap; }
.dv-barra .hint { margin: 0; font-size: 11px; }

/* O foco continua visível, agora por outro motivo: ele não decide mais a roda (que exige
   Ctrl), mas decide o TECLADO -- Enter confirma o trecho, U desfaz, F fecha. Quem digita
   precisa ver onde a tecla vai cair. */
#pagDesenho:focus, #pagDesenho:focus-visible { outline: 2px solid var(--acc, #6366f1); outline-offset: 2px; }

/* O TRAÇO VIVO e a medida em cima dele. Tracejado e âmbar para não se confundir com o
   contorno já desenhado (contínuo, índigo): o dono precisa ver de relance o que já existe
   e o que ainda é proposta.

   `paint-order: stroke` com contorno escuro é o que mantém o número legível por cima de
   qualquer coisa do desenho -- sem isso ele some em cima de uma aresta. */
/* O TRACO DO CAIXOTE em verde, contra o indigo do contorno e o ambar da linha viva.
   Cor separada porque os tres aparecem juntos na mesma tela, e confundir o rascunho do
   caixote com o contorno e desenhar parede onde nao tem. */
.cxd-traco { fill: none; stroke: #10b981; stroke-width: 5; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.cxd-canto { fill: #10b981; stroke: #04352a; stroke-width: 2; vector-effect: non-scaling-stroke; }
.dv-barra button[aria-pressed="true"] { background: #10b981; color: #04231b; border-color: #10b981; font-weight: 700; }
.dv-traco { stroke: #f59e0b; stroke-width: 3; stroke-dasharray: 14 10; vector-effect: non-scaling-stroke; pointer-events: none; }
.dv-medida { fill: #f59e0b; text-anchor: middle; font-family: system-ui, sans-serif; font-weight: 700; paint-order: stroke; stroke: #11151c; stroke-width: 6px; pointer-events: none; }
.dv-medida.digitando { fill: #e8eaed; }
