:root {
  --bg: #f7f6f3;
  --panel: #ffffff;
  --border: #e0ddd6;
  --text: #2b2621;
  --muted: #766f64;
  --accent: #8a5a34;
  --accent-dark: #6e4527;
  --danger: #b3432f;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
}

header.topbar {
  background: var(--accent-dark);
  color: #fff;
  padding: 16px 24px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

header.topbar a { color: #fff; opacity: .85; text-decoration: none; }
header.topbar a:hover { opacity: 1; }

/* #logout-btn usa button.secondary (texto var(--accent-dark)) mas o topbar
   TAMBÉM usa var(--accent-dark) como fundo — texto marrom em cima de fundo
   marrom, botão funcional mas invisível (bug relatado pelo usuário: "não
   tem como deslogar" — o botão sempre funcionou, só nunca apareceu). */
header.topbar button.secondary {
  color: #fff;
  border-color: rgba(255, 255, 255, .55);
  margin-top: 0;
}
header.topbar button.secondary:hover { background: rgba(255, 255, 255, .15); }

main {
  max-width: 960px;
  margin: 0 auto;
  padding: 24px;
}

section.panel, details.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px;
  margin-bottom: 24px;
}

/* Modal de login/cadastro (pedido do usuário 2026-07-20: Galeria pública,
   login só quando precisa) — #po-auth-section deixou de ser um <section
   class="panel"> sempre visível bloqueando a tela e virou um overlay
   fixo, escondido por padrão, aberto via openAuthModal()/fechado via
   closeAuthModal() em portal.js. */
#po-auth-section {
  display: none; position: fixed; inset: 0; z-index: 3000;
  align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55); padding: 20px;
}
#po-auth-section.open { display: flex; }
.po-auth-modal-card {
  background: var(--panel); border-radius: 12px; padding: 28px;
  max-width: 420px; width: 100%; max-height: 90vh; overflow-y: auto;
  position: relative; box-shadow: 0 20px 60px rgba(0,0,0,0.35);
}
.po-auth-modal-close {
  position: absolute; top: 10px; right: 12px; background: none; border: none;
  font-size: 24px; line-height: 1; cursor: pointer; color: var(--muted); padding: 4px;
}
.po-auth-modal-close:hover { color: var(--text); }
/* Botão "Continuar com Google" — largura total, ícone + texto centralizados,
   visual neutro (branco/borda) igual o padrão real desse botão em outros
   sites, não a cor de destaque do app. */
.po-google-btn {
  width: 100%; margin-top: 10px; display: flex; align-items: center;
  justify-content: center; gap: 10px; font-weight: 600;
}
/* Modo visitante (sem login) — só a aba Galeria fica visível na navegação;
   o resto do app exige conta (pedido do usuário: Gallery pública, mas
   Customizar/Curtir pedem login). Ver showLoggedOut/showLoggedIn. */
#po-sidebar.guest-mode .portal-tab-btn:not([data-tab="po-tab-gallery"]) { display: none; }

/* Seções de "Configurar módulo" viraram <details> (fechadas por padrão —
   pedido do usuário: "colocar tudo sempre minimizado e abro só o que
   preciso"). Mesmo id/lógica de mostrar-esconder o bloco inteiro que já
   existia (admin.js continua fazendo display:none/block no elemento
   pai) — o <details> só controla se o CONTEÚDO interno aparece ou não. */
details.panel > summary {
  font-size: 16px;
  font-weight: 600;
  color: var(--accent-dark);
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: -20px -20px 0;
  padding: 20px;
  border-radius: 10px;
}
details.panel > summary::-webkit-details-marker { display: none; }
details.panel > summary::before {
  content: "▸";
  font-size: 11px;
  color: var(--muted);
  transition: transform .15s;
  flex-shrink: 0;
}
details.panel[open] > summary {
  margin-bottom: 16px;
  border-bottom: 1px solid var(--border);
  border-radius: 10px 10px 0 0;
}
details.panel[open] > summary::before { transform: rotate(90deg); }
details.panel > summary:hover { background: var(--bg); }

h1 { font-size: 20px; margin: 0; }
h2 { font-size: 16px; margin-top: 0; color: var(--accent-dark); }

label {
  display: block;
  font-size: 13px;
  color: var(--muted);
  margin-top: 10px;
  margin-bottom: 4px;
}

input, select, textarea {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  background: #fff;
  color: var(--text);
}

textarea { min-height: 50px; font-family: monospace; }

.row { display: flex; gap: 12px; flex-wrap: wrap; }
.row > div { flex: 1; min-width: 140px; }

button {
  background: var(--accent);
  color: #fff;
  border: none;
  padding: 9px 16px;
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
  margin-top: 14px;
}
button:hover { background: var(--accent-dark); }
button.secondary { background: transparent; color: var(--accent-dark); border: 1px solid var(--border); }
button.danger { background: var(--danger); }

/* Aba Controladoria (dashboard) — cards de KPI + gráfico de barras simples,
   sem biblioteca externa (mesmo espírito do resto do admin: HTML/CSS puro). */
.kpi-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 20px;
  min-width: 200px;
  flex: 1;
}
.kpi-card .kpi-value { font-size: 32px; font-weight: 700; color: var(--accent-dark); line-height: 1; }
.kpi-card .kpi-label { font-size: 13px; color: var(--muted); margin-top: 6px; }
.kpi-card .kpi-breakdown { font-size: 12px; color: var(--muted); margin-top: 10px; line-height: 1.7; }

.bar-chart-block { flex: 1; min-width: 260px; }
.bar-chart-block h3 { font-size: 13px; color: var(--muted); margin: 0 0 8px; font-weight: 600; }
.bar-chart {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 110px;
  border-bottom: 1px solid var(--border);
  padding-bottom: 2px;
}
.bar-chart .bar-col { flex: 1; display: flex; align-items: flex-end; height: 100%; }
.bar-chart .bar { width: 100%; background: var(--accent); border-radius: 2px 2px 0 0; min-height: 1px; cursor: default; }
.bar-chart-labels { display: flex; gap: 2px; margin-top: 4px; }
.bar-chart-labels span {
  flex: 1;
  font-size: 9px;
  color: var(--muted);
  text-align: center;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Botões do cabeçalho de cada peça em "Componentes deste módulo" (▲▼/Ver
   componente/+Duplicar/▸Configurar) — pedido do usuário: bem mais estreitos
   e sem o margin-top padrão de todo botão, senão a linha toda cresce em
   altura e (com as setas de reordenar) chega a quebrar em 2 linhas,
   dificultando enxergar vários componentes de uma vez na tela. */
.mc-row-btn { margin-top: 0; padding: 5px 10px; font-size: 12px; }
.mc-row-btn-arrow { padding: 5px 8px; min-width: 0; }

table { width: 100%; border-collapse: collapse; margin-top: 12px; font-size: 13px; }
th, td { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--border); }
th { color: var(--muted); font-weight: 600; }

.hint { font-size: 12px; color: var(--muted); margin-top: 4px; }
.error { color: var(--danger); font-size: 13px; margin-top: 8px; }

.total-price {
  font-size: 32px;
  font-weight: 700;
  color: var(--accent-dark);
  margin: 8px 0;
}

/* Cabeçalho da seção 2 (medidas/opcionais) com o preço no canto superior
   direito, ao lado do título — compacto, não o destaque grande de antes. */
.section-header-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  flex-wrap: wrap;
}
.section-header-row h2 { margin-bottom: 0; }
#price-section { text-align: right; flex-shrink: 0; }
.total-price-label { display: block; font-size: 11px; color: var(--muted); }
.total-price-mini {
  font-size: 20px;
  font-weight: 700;
  color: var(--accent-dark);
  margin: 0;
  white-space: nowrap;
}

.texture-thumb {
  width: 40px;
  height: 40px;
  border-radius: 6px;
  object-fit: cover;
  border: 1px solid var(--border);
  display: block;
}

/* Um grupo de swatches por papel de cor (migration 035) — número de grupos é
   dinâmico (depende de quantos papéis o módulo atual usa), por isso a regra
   é por CLASSE, criada via JS em client.js/portal.js (renderColorRoleSwatchGroups),
   não mais por uma lista fixa de 2x2 IDs (antigo box/door, calculadora/portal). */
.color-role-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}
.color-role-swatch-group {
  margin-top: 14px;
}
.color-role-swatch-group:first-child {
  margin-top: 0;
}
.color-swatch {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3px;
  border: 2px solid transparent;
  border-radius: 8px;
  cursor: pointer;
  margin-top: 0;
}
.color-swatch.selected { border-color: var(--accent); background: #fbf3ec; }
.color-swatch img { width: 36px; height: 36px; border-radius: 6px; object-fit: cover; border: 1px solid var(--border); display: block; }
.color-swatch .swatch-fallback { width: 36px; height: 36px; border-radius: 6px; background: var(--border); border: 1px solid var(--border); display: block; }
/* Ícones só (nome fica disponível via tooltip/title, pra ficar compacto). */
.color-swatch span:not(.swatch-fallback) { display: none; }
/* Nome da cor ESCOLHIDA (só ela — ver renderColorRoleSwatchGroups em
   portal.js), ao lado do rótulo do papel de cor ("Cor — Caixa: Preto"). */
.color-role-selected-name { color: var(--text); font-weight: 600; text-transform: none; letter-spacing: 0; }

/* Botão de cor do Plano de Corte (substitui o <select> nativo — pedido do
   usuário 2026-07-29: "quadrado pequeno do lado mostrando a cor", <option>
   não aceita HTML/imagem dentro, então virou botão+popup como o de
   order-detail). Popup é position:absolute pra não empurrar o resto da
   linha da tabela (linhas de outras colunas ficariam com altura extra). */
.cl-color-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 8px;
  margin-top: 0;
  font-family: inherit;
  font-size: 13px;
  cursor: pointer;
  min-width: 130px;
  max-width: 150px;
  text-align: left;
  color: var(--text);
}
.cl-color-btn:hover { border-color: var(--accent); }
/* Alinhamento da barra de aplicar-em-massa do Plano de Corte (pedido do
   usuário 2026-07-31: "alinha melhor") — o <button> global tem
   margin-top:14px, então os botões "Aplicar..." ficavam mais baixos que os
   <select>/<input> ao lado mesmo com align-items:center no wrap. Zera
   margem e unifica padding/altura de todo filho direto marcado. */
.po-cutlist-bulk-toolbar .cl-bulk-field {
  margin-top: 0;
  box-sizing: border-box;
  height: 34px;
}
.po-cutlist-bulk-toolbar button.cl-bulk-field { padding: 0 12px; font-size: 13px; }
.po-cutlist-bulk-toolbar select.cl-bulk-field,
.po-cutlist-bulk-toolbar input.cl-bulk-field { padding: 0 10px; }
.cl-color-dot {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  border: 1px solid var(--border);
  display: inline-block;
}
.cl-color-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Popup singleton, position:fixed, anexado no <body> (não filho da célula/
   tabela) — pedido do usuário 2026-07-29: o popup antigo (filho da célula)
   ficava cortado pelo overflow-x:auto de #po-cutlist-table-wrap. */
.cl-color-popup-fixed {
  position: fixed;
  z-index: 500;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  box-shadow: 0 6px 20px rgba(0,0,0,0.2);
  width: 220px;
}
/* Campo de busca (pedido do usuário 2026-07-31: "quero poder digitar as
   primeiras letras e puxar as cores conforme escrevo") — FORA do wrap que
   rola (.cl-color-list-wrap abaixo), fica sempre visível/fixo no topo do
   popup mesmo rolando a lista. */
.cl-color-search-input {
  display: block;
  margin: 2px 2px 6px;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
  width: calc(100% - 12px);
}
/* Só o WRAP da lista rola (antes era o popup inteiro, ver bug corrigido em
   getCutlistColorPopupEl — scroll dentro do popup fechava ele por engano) —
   max-height um pouco menor que os 320px de antes pra sobrar espaço pro
   campo de busca acima sem estourar a tela. */
.cl-color-list-wrap {
  max-height: 280px;
  overflow-y: auto;
}
/* Lista vertical (não grade) com nome sempre visível em texto — pedido do
   usuário 2026-07-29 ("quero em lista como antes mas com o icone na frente"),
   diferente do padrão .color-swatch (grade de ícones, nome só em tooltip)
   usado no resto do app. */
.cl-color-list-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
}
.cl-color-list-item:hover { background: var(--border); }
.cl-color-list-item.selected { background: #fbf3ec; font-weight: 600; }

/* Destaque de vermelho de verdade nos campos inválidos do Plano de Corte —
   pedido do usuário 2026-07-29 ("a mensagem nao esta clara do que esta
   faltando"): o aviso já dizia "corrija as linhas em vermelho" há tempos,
   mas nada realmente ficava vermelho. Ver getCutlistRowIssues/
   refreshCutlistRowHighlight em portal.js. */
.cl-field-invalid { border-color: var(--danger) !important; box-shadow: 0 0 0 1px var(--danger); }

.dim-field { margin-top: 16px; }
.dim-field:first-child { margin-top: 0; }
.dim-field label { display: block; margin-bottom: 4px; }
.dim-slider-row { display: flex; align-items: center; gap: 8px; }
.dim-bound { font-size: 12px; color: var(--muted); white-space: nowrap; min-width: 46px; }
.dim-bound.dim-bound-max { text-align: right; }
.dim-slider { flex: 1; accent-color: var(--accent); }
.dim-value-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; }
.dim-value { font-weight: 600; color: var(--accent-dark); white-space: nowrap; }
.dim-exact-wrap { display: flex; align-items: center; gap: 4px; }
.dim-exact-input { width: 78px; padding: 4px 6px; font-size: 13px; text-align: right; }
.dim-exact-unit { font-size: 12px; color: var(--muted); min-width: 20px; }

/* Sub-configuração de medidas por peça-módulo aninhada (migration 036) — um
   bloco por peça com "cliente pode configurar as medidas" ligado no admin,
   nasce fechado (mesmo espírito do "▸ Configurar" das listas do admin). */
.po-piece-subconfig { margin-top: 14px; border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; }
.po-piece-subconfig-toggle {
  background: none; border: none; padding: 0; margin: 0;
  font-weight: 600; color: var(--accent-dark); cursor: pointer; font-size: 14px;
}
.po-piece-subconfig-body { margin-top: 10px; }
.po-piece-subconfig-body .dim-field { margin-top: 14px; }
.po-piece-subconfig-body .dim-field:first-child { margin-top: 0; }
/* Some por padrão — só aparece quando o cliente mexe manualmente naquele
   eixo (ver renderPieceDimensionSubconfigs), como saída pra voltar a
   acompanhar o módulo pai. */
.po-piece-subconfig-reset {
  background: none; border: none; padding: 0; margin: 0;
  font-size: 12px; color: var(--muted); text-decoration: underline;
  cursor: pointer; white-space: nowrap;
}
.po-piece-subconfig-reset:hover { color: var(--accent-dark); }

/* Cor separada por peça-módulo aninhada (migration 046, client_color_configurable)
   — bloco visualmente igual a .po-piece-subconfig (borda própria, pra separar do
   grupo de cor "geral" do módulo pai logo acima), ver renderColorRoleSwatchGroups. */
.color-role-piece-block {
  margin-top: 14px; border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px;
}
.color-role-piece-block-title {
  font-weight: 600; color: var(--accent-dark); font-size: 14px; margin-bottom: 10px;
}

/* Valores sugeridos/travados de medida (migration 028). Modo travado: o
   dropdown assume o lugar da régua livre (mesma largura, mesmo espaço).
   Modo sugerido: chips clicáveis logo abaixo, empilham em telas estreitas. */
.dim-locked-select { width: 100%; margin-bottom: 6px; }
.dim-preset-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.dim-preset-chip {
  padding: 3px 10px;
  font-size: 12px;
  font-weight: 500;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--accent-dark);
  cursor: pointer;
  white-space: nowrap;
}
.dim-preset-chip:hover { border-color: var(--accent); background: var(--accent-light, #fdf3e6); }

/* Visualizador 3D + medidas lado a lado, compacto. Empilha em telas estreitas. */
#viewer-config-row { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; margin-bottom: 18px; }
#viewer3d-wrap { flex: 1 1 340px; margin-bottom: 0; }
#dims-col { flex: 1 1 240px; max-width: 320px; }
.dim-unit-wrap { max-width: 220px; }
#shelf-quantities-wrap:not(:empty) { margin-top: 14px; }

#viewer3d-canvas {
  width: 100%;
  height: 320px;
  border: none;
  overflow: hidden;
  background: #ffffff;
  touch-action: none;
}
#viewer3d-canvas canvas { display: block; width: 100%; height: 100%; }
/* #po-viewer3d-canvas é o id de verdade usado em portal.html (configurador
   "2. Configure" do módulo) — a regra "#viewer3d-canvas" acima nunca bateu
   com ele (só existe com esse id exato na calculadora legada,
   calculadora-legado.html; mantida intocada acima). Sem CSS própria, o
   container ficava sem altura definida e o viewer3d.js caía no fallback
   fixo de 320px (containerEl.clientHeight || 320, ver init()/onResize em
   viewer3d.js) — funcionava por coincidência, mas nunca aproveitava telas
   maiores. Revisão pra iPad Air 13" (2026-08-05, pedido: "aproveitar o
   maximo de espaco da tela"): altura agora escala com a viewport (mesmo
   padrão clamp(min, vh, max) já usado em #po-proj-3d-canvas/
   #po-proj-canvas-3d-edit), sem baixar do mínimo de antes. onResize já lê
   containerEl.clientHeight a cada resize, então isso é só CSS — nenhuma
   lógica de câmera/posicionamento foi tocada. */
#po-viewer3d-canvas {
  width: 100%;
  height: clamp(320px, 48vh, 640px);
  border: none;
  overflow: hidden;
  background: #ffffff;
  touch-action: none;
}
#po-viewer3d-canvas canvas { display: block; width: 100%; height: 100%; }
/* Botões de abrir/fechar porta e gaveta SEPARADOS (cada um com seu próprio
   estado — abrir a porta não mexe na gaveta, e vice-versa). Lado a lado, com
   a mesma margem de cima que o botão único tinha antes. */
.viewer-toggle-btns { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.viewer-toggle-btns button { margin-top: 0; }

/* Balão de info da peça (duplo-clique no 3D) — posicionado perto do ponto
   clicado via left/top em JS (position:fixed, coordenadas de tela). Mostra
   só nome/medidas/cor, nunca preço (o breakdown de custo é interno/admin). */
.piece-info-tooltip {
  position: fixed;
  z-index: 500;
  max-width: 240px;
  background: #1f2430;
  color: #fff;
  padding: 10px 12px;
  border-radius: 8px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
  font-size: 13px;
  line-height: 1.5;
}
.piece-info-tooltip strong { display: block; font-size: 14px; margin-bottom: 2px; padding-right: 16px; }
.piece-info-tooltip .piece-info-close {
  position: absolute;
  top: 4px;
  right: 6px;
  background: none;
  border: none;
  color: #fff;
  opacity: 0.7;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 2px;
}
.piece-info-tooltip .piece-info-close:hover { opacity: 1; }

/* Painel admin mais largo (tem sidebar de abas) do que a calculadora do cliente.
   margin:0 (em vez do "margin:0 auto" herdado de main{}) tira a centralização —
   pedido do usuário: "colunas jogarem mais pra esquerda" (em monitores largos,
   1200px centralizado deixava uma sobra enorme e simétrica dos 2 lados). Cap
   de 1600px só pra não esticar o texto/formulários até virar ilegível em
   monitores ultrawide. */
.admin-page main { max-width: 1600px; margin: 0; padding: 24px 32px; }

/* Painel admin em preto e branco, sem cantos arredondados — pedido do
   usuário. Escopado em body.admin-page (mesmo padrão de body.portal-page
   logo abaixo) pra não afetar o portal do cliente nem a calculadora
   (index.html), que ficam com a paleta/cantos de sempre. */
body.admin-page {
  --bg: #f0f0f0;
  --panel: #ffffff;
  --border: #000000;
  --text: #000000;
  --muted: #595959;
  --accent: #000000;
  --accent-dark: #000000;
  --danger: #000000;
}
/* !important porque border-radius aparece espalhado em dezenas de regras
   (botões, painéis, pills, tabelas, badges, tooltips...) — resetar tudo de
   uma vez aqui é bem mais confiável do que caçar regra por regra. Também
   bate um inline style (ver banners de "editando X" em admin.html). */
.admin-page, .admin-page * { border-radius: 0 !important; }
/* Excluir (danger) ficaria idêntico a um botão comum já que os dois usam
   --accent/--danger pretos agora — invertido (fundo branco, borda preta)
   pra continuar distinguível sem usar cor nenhuma. */
.admin-page button.danger {
  background: #fff;
  color: #000;
  border: 1px solid #000;
  font-weight: 600;
}
.admin-page button.danger:hover { background: #000; color: #fff; }

/* Abas do painel admin: sidebar fixa à esquerda + conteúdo da aba ativa à
   direita — antes tudo ficava empilhado numa rolagem só, gigante. Cada
   seção existente (Cores, Taxonomia, Componentes...) vira o conteúdo de
   uma aba, sem mudar nenhum id usado pelo admin.js. */
.admin-layout {
  display: flex;
  align-items: flex-start;
  gap: 20px;
}
.admin-sidebar {
  flex: 0 0 200px;
  position: sticky;
  top: 24px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px;
}
.admin-tab-btn {
  background: transparent;
  color: var(--text);
  border: none;
  border-radius: 6px;
  padding: 10px 12px;
  margin-top: 0;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  line-height: 1.3;
}
.admin-tab-btn:hover { background: var(--bg); }
.admin-tab-btn.active { background: var(--accent); color: #fff; }
.admin-tab-content { flex: 1; min-width: 0; }
.admin-tab-page section.panel:last-child, .admin-tab-page details.panel:last-child { margin-bottom: 0; }

@media (max-width: 720px) {
  .admin-layout { flex-direction: column; }
  .admin-sidebar { flex-direction: row; flex-wrap: wrap; position: static; width: 100%; }
}

/* ---------- Modo embutido (admin.html dentro do ERP) ----------
   Quando o ERP abre um cadastro num iframe (?embed=1), o topo e a barra
   lateral daqui somem: a navegação passa a ser a do ERP. Nada é removido
   do DOM — só escondido — porque o admin.js continua consultando esses
   elementos (o botão de logout, por exemplo) e sumir com eles de verdade
   quebraria a inicialização. Abrir admin.html direto continua idêntico. */
body.admin-embed > .topbar { display: none; }
body.admin-embed .admin-sidebar { display: none; }
body.admin-embed.admin-page main { padding: 18px 20px 40px; }
body.admin-embed #login-section { max-width: 460px; margin: 40px auto; }

/* ---------- "Configurar módulo": árvore de módulos + sub-abas ----------
   Antes era um <select> no topo + 5 seções empilhadas numa rolagem só,
   comprida e fácil de se perder. Agora, mesma ideia do .admin-sidebar de
   abas, só que um nível mais fundo: árvore de módulos (agrupada por
   família/categoria/subcategoria — campos que cada módulo já tem, não é
   critério novo) à esquerda, sub-abas por tipo de configuração à direita.
   Puramente visual — não muda nenhum id nem lógica de dados do admin.js. */
.module-config-shell {
  display: flex;
  align-items: flex-start;
  gap: 20px;
}
.module-config-tree-col {
  flex: 0 0 300px;
  position: sticky;
  top: 24px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px;
  max-height: calc(100vh - 48px);
  overflow-y: auto;
}
.module-config-tree-col h2 { margin-bottom: 4px; }
.module-config-search { margin-top: 8px; margin-bottom: 10px; }
.module-config-tree { font-size: 13px; }

/* Família/categoria viraram <details> (fechados por padrão). O antigo
   formulário de criar/editar módulo não mora mais aqui — foi pra
   #module-form-section, como mais uma aba na tira de Cores/Modelos/etc na
   coluna da direita (ver .module-subtabs). Esta coluna só tem busca + a
   árvore em si; "+ Novo módulo"/Editar/Duplicar/Excluir continuam
   disparando a partir daqui (botão no topo da coluna direita + botões por
   item da árvore), só o CONTEÚDO do formulário que fica ao lado. */
.module-tree-family { margin-top: 10px; }
.module-tree-family:first-child { margin-top: 0; }
.module-tree-family > summary {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--accent-dark);
  cursor: pointer;
  list-style: none;
  padding: 4px 2px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.module-tree-family > summary::-webkit-details-marker { display: none; }
.module-tree-family > summary::before { content: "▸"; font-size: 10px; color: var(--muted); transition: transform .15s; }
.module-tree-family[open] > summary::before { transform: rotate(90deg); }
.module-tree-family-body { padding-left: 4px; }

.module-tree-category { margin-top: 6px; }
.module-tree-category > summary {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  list-style: none;
  padding: 3px 4px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.module-tree-category > summary::-webkit-details-marker { display: none; }
.module-tree-category > summary::before { content: "▸"; font-size: 10px; color: var(--muted); transition: transform .15s; }
.module-tree-category[open] > summary::before { transform: rotate(90deg); }
.module-tree-category-body { padding-left: 8px; }

.module-tree-subcategory-label {
  font-size: 11px;
  color: var(--muted);
  margin-top: 4px;
  padding-left: 12px;
}
.module-tree-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  padding: 5px 4px 5px 16px;
  border-radius: 6px;
  cursor: pointer;
  line-height: 1.3;
}
.module-tree-item:hover { background: var(--bg); }
.module-tree-item.active { background: var(--accent); color: #fff; }
.module-tree-item-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Ações (editar/duplicar/excluir) só aparecem no hover/foco da linha ou
   quando o item está ativo — reduz ruído visual da árvore quando fechada. */
.module-tree-item-actions { display: none; flex-shrink: 0; gap: 2px; }
.module-tree-item:hover .module-tree-item-actions,
.module-tree-item.active .module-tree-item-actions { display: flex; }
.module-tree-item-actions button {
  margin-top: 0;
  padding: 2px 6px;
  font-size: 11px;
  line-height: 1.4;
  border-radius: 4px;
}
.module-tree-item.active .module-tree-item-actions button.secondary {
  background: rgba(255,255,255,.15);
  color: #fff;
  border-color: rgba(255,255,255,.4);
}

/* "+ Novo módulo" + formulário recolhido (migrado da antiga aba "Módulos") —
   fica na coluna da direita (module-config-main-col), com o mesmo espaço
   generoso dos outros painéis (Cores/Modelos/...) — não mais espremido na
   árvore estreita de 300px, onde os 3 campos por linha (largura/altura/
   profundidade) quebravam feio. */
#module-new-btn { margin: 0 0 14px; }

.module-config-main-col { flex: 1; min-width: 0; }
.module-config-header { margin-bottom: 4px; }
.module-config-header h2 { margin: 0; }

/* Tira de abas (Cores/Modelos/Imagem 3D/Medidas/Componentes/Teste de
   cálculo) de volta no topo — pedido do usuário: o accordion vertical
   ficava "muito afastado" (gap de 24px entre cada seção); a tira horizontal
   é bem mais compacta e só um bloco fica visível por vez. */
.module-subtabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
  position: sticky;
  top: 24px;
  background: var(--bg);
  padding: 4px 0;
  z-index: 5;
}
.module-subtab-btn {
  background: var(--panel);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 7px 14px;
  margin-top: 0;
  font-size: 13px;
  cursor: pointer;
}
.module-subtab-btn:hover { background: var(--bg); }
.module-subtab-btn.active { background: var(--accent); color: #fff; border-color: var(--accent); }

/* Árvore + coluna de configuração ficam lado a lado SEMPRE (pedido do
   usuário) — antes, abaixo de 860px de largura a coluna da direita
   (Cores/Modelos/Imagem 3D/...) empilhava embaixo da árvore em vez de ficar
   ao lado; removido de propósito, mesmo que fique apertado em tela bem
   estreita (o admin é usado em desktop). */

/* ---------- Portal do cliente ---------- */

.portal-page main { max-width: 1100px; }

/* Mesma ideia de sidebar+abas do painel admin, com nome próprio pra não
   acoplar o estilo do portal ao do admin (podem divergir no futuro). */
.portal-tabs {
  display: flex;
  align-items: flex-start;
  gap: 20px;
}
.portal-sidebar {
  flex: 0 0 180px;
  position: sticky;
  top: 24px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 10px;
}
.portal-tab-btn {
  background: transparent;
  color: var(--text);
  border: none;
  border-radius: 6px;
  padding: 10px 12px;
  margin-top: 0;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}
.portal-tab-btn:hover { background: var(--bg); }
.portal-tab-btn.active { background: var(--accent); color: #fff; }
.portal-tab-content { flex: 1; min-width: 0; }

@media (max-width: 720px) {
  .portal-tabs { flex-direction: column; }
  .portal-sidebar { flex-direction: row; flex-wrap: wrap; position: static; width: 100%; }
}

/* Linha de item do pedido (carrinho ou histórico) — imagem, dados, preço. */
.portal-item-row {
  display: flex;
  gap: 14px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}
.portal-item-row:last-child { border-bottom: none; }
.portal-item-thumb {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: #fff;
  flex-shrink: 0;
}
.portal-item-thumb-empty { background: var(--bg); }
.portal-item-info { flex: 1; min-width: 0; font-size: 13px; color: var(--muted); }
.portal-item-title { font-size: 15px; font-weight: 600; color: var(--text); }
.portal-item-price {
  flex-shrink: 0;
  text-align: right;
  font-weight: 700;
  color: var(--accent-dark);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}
.portal-item-remove { margin-top: 0; font-size: 12px; padding: 5px 10px; }

.portal-cart-total-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 18px;
  font-weight: 700;
  color: var(--accent-dark);
  padding: 14px 0 4px;
  border-top: 2px solid var(--border);
  margin-top: 8px;
}

.portal-order-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  margin-bottom: 16px;
}
.portal-order-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding-bottom: 8px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border);
  font-size: 15px;
}
.portal-order-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Só o total em destaque — antes essa regra pegava QUALQUER <span> dentro do
   header (inclusive o badge de status novo), deixando o badge com o mesmo
   negrito/cor do preço, o que ficava estranho. */
.portal-order-total { color: var(--accent-dark); font-weight: 700; }

/* Ações do pedido salvo ("Ver detalhes"/"Gerar PDF") e o painel de detalhes
   que só aparece depois de "entrar" no pedido (fica recolhido por padrão). */
.portal-order-actions {
  display: flex;
  gap: 8px;
  margin: 10px 0 4px;
}
.portal-order-actions button { margin-top: 0; font-size: 12px; padding: 6px 12px; }
.portal-order-details { margin-top: 8px; }

/* ---------- Tela do pedido (migration 047, 2026-07-19) ----------
   Aberta a partir de "Meus Pedidos" (ver openOrderDetail/renderOrderDetail
   em portal.js) — substitui o antigo expand-inline. Read-only por padrão
   (produto não se edita direto aqui); "Editar" por módulo reabre o
   configurador de sempre, "Aprovar Pedido" trava a tela inteira. */
.po-order-detail-header {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
}
.po-order-detail-header .secondary { margin-top: 0; flex-shrink: 0; }
.po-order-detail-title-wrap { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.po-order-detail-title-wrap h2 { margin: 0; font-size: 18px; }

.po-order-detail-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px 16px;
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--border);
}
.po-order-detail-field-wide { grid-column: 1 / -1; }
/* Depois de aprovado (ou enquanto ainda carrega), os campos viram texto
   simples em vez de <input> disabled — disabled tem aparência "cinza
   quebrado" que parece erro; um valor só-leitura deve parecer uma resposta
   normal, não um campo travado. */
.po-order-detail-fields.readonly input {
  border: none;
  background: none;
  padding: 4px 0;
  color: var(--text);
  font-weight: 600;
}

.po-order-item-card {
  display: flex;
  gap: 18px;
  align-items: flex-start;
  padding: 18px 0;
  border-bottom: 1px solid var(--border);
}
.po-order-item-card:last-child { border-bottom: none; }
.po-order-item-number {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  background: var(--text);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.po-order-item-image {
  flex-shrink: 0;
  /* Pedido do usuário 2026-07-19: "quero o tamanho maior" (era 200px). */
  width: 260px;
  height: 260px;
  object-fit: contain;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #fff;
}
.po-order-item-image-empty { background: var(--bg); }
/* Código de referência (SKU) grande ao lado do ícone do módulo — pedido do
   usuário (2026-07-29): "quando tiver referencia cadastrada quero ela bem
   grande no lado do icone do modulo". Só aparece quando
   findMatchingSkuReference (portal.js) acha um código cadastrado batendo com
   a largura/altura do item — sem código, este bloco nem entra no HTML. */
.po-order-item-sku-code {
  flex-shrink: 0;
  align-self: center;
  font-size: 32px;
  font-weight: 800;
  color: var(--text);
  letter-spacing: .01em;
}
.po-order-item-info { flex: 1; min-width: 0; }
/* Pedido do usuário 2026-07-29: "deixa as informacoes do produto maiores,
   tem espaco" — o card tinha bastante largura livre à direita da imagem
   (.po-order-item-info é flex:1), texto pequeno demais pra ela. Aumentado
   em toda a coluna de informações (medidas/nome/descrição/cores). */
.po-order-item-dims { color: var(--muted); font-size: 14px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.po-order-item-reference { font-size: 22px; font-weight: 700; color: var(--text); margin-top: 8px; }
.po-order-item-description { color: var(--muted); font-size: 15px; margin-top: 4px; }
.po-order-item-colors { margin-top: 12px; font-size: 15px; display: flex; flex-direction: column; gap: 8px; }
/* Cada linha de cor virou um BOTÃO clicável (pedido do usuário 2026-07-29:
   "quero uma opcao de trocar a cor por modulo tambem") — reset de aparência
   de botão nativo, mantendo o mesmo layout de antes (bolinha + texto), só
   que agora abre um seletor de cor SÓ deste item (ver
   toggleOrderItemColorPicker/applyColorToSingleOrderItem em portal.js;
   diferente do painel de abas no topo, que troca em todos os itens de uma
   vez). */
.po-order-item-color-line { display: flex; flex-direction: column; align-items: flex-start; }
.po-order-item-color-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  background: none;
  border: none;
  padding: 2px 0;
  margin-top: 0;
  font-size: 15px;
  font-family: inherit;
  color: var(--text);
  cursor: pointer;
  text-align: left;
}
.po-order-item-color-btn:hover:not(:disabled) { color: var(--accent-dark); text-decoration: underline; }
.po-order-item-color-btn:disabled { cursor: default; color: var(--text); }
.po-order-item-color-picker {
  margin: 4px 0 2px 24px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
}
/* Preview da cor/textura escolhida, ao lado do nome do papel — pedido do
   usuário 2026-07-19 (era só uma "bolinha") e 2026-07-29 (era um círculo
   pequeno de 20px): "quero a imagem escolhida em cada modulo bem maior, hoje
   ela ta pequena circular e cinza" — trocado de círculo pra quadrado
   arredondado bem maior (44px), mesma linguagem visual dos swatches do
   seletor de cor (.color-swatch img/.swatch-fallback, 36px), só um pouco
   maior ainda pra ficar em destaque na tela do pedido. */
.po-order-item-color-dot {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 8px;
  border: 1px solid var(--border);
  display: inline-block;
  object-fit: cover;
}
.po-order-item-actions {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  min-width: 110px;
}
.po-order-item-unit-price { font-size: 22px; font-weight: 700; color: var(--accent-dark); }
.po-order-item-edit-btn { margin-top: 0; font-size: 13px; padding: 7px 16px; }
/* Quantidade editável (pedido do usuário 2026-07-29: "quero opcao de
   quantidade, pode ser alterada e salvar alteracao. muda preco."; campo
   aumentado no mesmo dia, feedback seguinte: "quero quantidade maior") — ver
   updateOrderItemQuantity em portal.js. */
.po-order-item-qty-row { display: flex; align-items: center; gap: 8px; font-size: 15px; color: var(--muted); }
.po-order-item-qty-input { width: 72px; padding: 8px 6px; margin-top: 0; text-align: center; font-size: 18px; font-weight: 700; }

.po-order-detail-footer { margin-top: 8px; }
.po-order-detail-total-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 20px;
  font-weight: 700;
  color: var(--accent-dark);
  padding: 14px 0;
  border-top: 2px solid var(--border);
}
#po-order-detail-approve-hint { text-align: right; margin: 4px 0 0; }

.badge {
  display: inline-block;
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--muted);
}

/* Filtros de família/categoria/subcategoria da biblioteca de módulos do
   portal (substituem os <select> por pills clicáveis, tipo abas). */
.po-filter-group {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
}
.po-tabbar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 4px;
}
.po-tab-pill {
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
  margin-top: 0;
}
.po-tab-pill:hover { background: var(--bg); }
.po-tab-pill.active { background: var(--accent); border-color: var(--accent); color: #fff; }

/* Biblioteca visual de módulos (cartões com desenho, tipo Promob) — cada
   cartão troca o antigo <select> de módulo por um clique direto. */
.po-module-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 12px;
  margin-top: 8px;
}
.po-module-card {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px;
  text-align: center;
  background: var(--panel);
  transition: border-color 0.15s, background 0.15s;
}
.po-module-card:hover { border-color: var(--accent); }
.po-module-card.selected { border-color: var(--accent); background: #fbf3ec; }
.po-module-card svg { width: 100%; height: 72px; display: block; cursor: pointer; }
/* Imagem 3D de verdade (modules.thumbnail_data_url, gerada no admin) — mesmo
   espaço/comportamento do ícone SVG genérico que ela substitui. */
.po-module-card .po-module-card-image { width: 100%; height: 72px; object-fit: contain; display: block; cursor: pointer; }
.po-module-card .po-module-card-name {
  margin-top: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--accent-dark);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}
/* Linha de medidas padrão — mesmo clique do nome/desenho, abre a
   configuração completa. Escondida a pedido do usuário (2026-07-25): nos
   cards do catálogo, mostrar só ícone + nome, sem as medidas. Reversível:
   só tirar o display:none. */
.po-module-card .po-module-card-dims {
  margin-top: 2px;
  font-size: 11px;
  color: var(--muted);
  cursor: pointer;
  display: none;
}
.po-module-gallery-empty {
  color: var(--muted);
  font-size: 13px;
  grid-column: 1 / -1;
}

/* Busca + faixas de Largura/Altura/Profundidade acima da vitrine (fase 1 da
   reformulação do portal). */
.po-search-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 14px;
}
.po-module-search {
  flex: 1 1 220px;
  margin-top: 0;
}
.po-dim-filter-select {
  flex: 0 1 150px;
  margin-top: 0;
}

/* "Adicionar módulo" rápido, direto no card — quantidade + botão, separado
   visualmente do corpo clicável (nome/desenho/medidas) que abre a
   configuração completa. */
.po-module-card-quickadd {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  align-items: center;
}
.po-quickadd-qty {
  width: 46px;
  padding: 4px 6px;
  font-size: 12px;
  text-align: center;
  margin-top: 0;
}
.po-quickadd-btn {
  flex: 1;
  font-size: 12px;
  padding: 5px 8px;
  margin-top: 0;
  white-space: nowrap;
}
.po-quickadd-error {
  font-size: 11px;
  margin-top: 4px;
  text-align: left;
}

/* ==========================================================================
   Portal — reskin "contractor portal" (2026-07-09)
   Referência: mockup compartilhado pelo usuário (nav superior + catálogo em
   grade + carrinho fixo do lado), confirmado em [[portal_redesign_reference]].
   Paleta/tipografia ficam ESCOPADAS em body.portal-page — os componentes
   admin/cliente (que usam o mesmo style.css) não são afetados, porque essas
   variáveis só existem dentro desse seletor mais específico.
   ========================================================================== */

body.portal-page {
  --bg: #faf9f6;
  --panel: #ffffff;
  --border: #e6e2da;
  --text: #171613;
  --muted: #6b655c;
  --accent: #171613;
  --accent-dark: #000000;
  --accent-light: #f2f0ea;
  font-family: "Inter", -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
}

/* Largura do portal: aproveita telas grandes (antes 1400px deixava muita
   faixa branca dos lados num monitor largo) — 1800px de teto, e o grid de
   módulos (auto-fill) preenche sozinho com mais colunas. Telas menores não
   mudam nada (max-width só limita, não estica além da janela). */
body.portal-page main { max-width: 1800px; padding: 28px 32px 0; }

/* ---- Aba Projetos em tela cheia (pedido do Matt, 2026-08-12: "toda essa
   sobra na esquerda e direita tem como aproveitar e ajustar conforme o máximo
   da tela de cada computador? quanto mais área melhor pra desenhar") ----
   O teto de 1800px continua valendo pro RESTO do portal de propósito: linha
   de texto e formulário atravessando um monitor ultrawide fica ruim de ler.
   Só a tela de desenho solta — lá a área é a ferramenta.
   A classe entra no <body> na troca de aba (setProjectFullBleed em
   portal.js), não por seletor tipo :has() — que o Safari mais velho do iPad
   não suporta e esta tela é usada no iPad. */
body.portal-page.proj-fullbleed main { max-width: none; padding: 14px 16px 0; }
body.portal-page.proj-fullbleed .po-support-footer { max-width: none; }
/* O painel da aba também aperta as próprias bordas: 16px de cada lado em vez
   dos ~24px do padrão, tudo que sobra vai pro canvas. */
body.portal-page.proj-fullbleed #po-tab-projects > section.panel { padding: 16px; }

/* ---- TELA CHEIA DE VERDADE (2026-08-14) ----
   .proj-fullbleed acima só solta a largura; a barra do navegador e o topo do
   portal continuavam comendo altura. Esta classe entra junto com o
   requestFullscreen (setProjectTelaCheia em portal.js) e some com o topo e o
   rodapé — em fullscreen a navegação por abas não faz sentido mesmo, e é
   altura que vai direto pro desenho (os viewers são vh, então crescem
   sozinhos). Classe separada de propósito: sair do fullscreen pelo Esc não
   pode deixar o portal sem menu, e o fullscreenchange tira só esta.
   O :fullscreen do documento NÃO é usado como seletor — Safari mais velho do
   iPad (esta tela roda em iPad) não entrega o pseudo-classe no <html> de
   forma confiável, e iPhone não tem Fullscreen API nenhuma. */
body.portal-page.proj-tela-cheia header.po-topnav { display: none; }
body.portal-page.proj-tela-cheia .po-support-footer { display: none; }
body.portal-page.proj-tela-cheia main { padding-top: 8px; }
/* Ícone do botão: as duas setas viram "encolher" enquanto está em tela cheia. */
body.portal-page.proj-tela-cheia #po-proj-fullscreen-btn .po-fs-abrir { display: none; }
body.portal-page.proj-tela-cheia #po-proj-fullscreen-btn .po-fs-fechar { display: inline; }

/* ---------- Nav superior ---------- */

header.po-topnav {
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  padding: 0 32px;
  height: 72px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  position: sticky;
  top: 0;
  z-index: 30;
}
.po-topnav-left { display: flex; align-items: center; gap: 32px; min-width: 0; }
.po-logo { display: flex; flex-direction: column; line-height: 1; flex-shrink: 0; }
.po-logo-main { font-size: 20px; font-weight: 800; letter-spacing: 0.5px; color: var(--text); }
.po-logo-sub { font-size: 9px; font-weight: 600; letter-spacing: 3px; color: var(--muted); margin-top: 3px; }
/* Logo do Dealer (migration 075) — max-height trava o cabeçalho numa altura
   consistente mesmo que a imagem enviada tenha proporção bem diferente do
   wordmark LEGNO; largura livre (width:auto) preserva o aspecto original. */
.po-logo-dealer-img { max-height: 34px; width: auto; display: block; }
/* Toggle "Legno / Dealer" — mesmo espírito visual do po-lang-switcher
   (borda fina, canto arredondado), só que como par de botões segmentados em
   vez de <select>, pra trocar num clique só na frente do cliente final. */
.po-portal-mode-toggle {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  flex-shrink: 0;
}
.po-portal-mode-btn {
  background: var(--panel);
  border: none;
  padding: 6px 12px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  margin-top: 0;
}
.po-portal-mode-btn + .po-portal-mode-btn { border-left: 1px solid var(--border); }
.po-portal-mode-btn.active { background: var(--text); color: #fff; }
.po-portal-mode-btn:hover:not(.active) { background: var(--accent-light, #f2f0ea); color: var(--text); }
.po-topnav-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
  padding-left: 24px;
  border-left: 1px solid var(--border);
  white-space: nowrap;
}
.po-topnav-tabs#po-sidebar {
  display: flex;
  gap: 4px;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0;
  position: static;
}
.po-topnav-tabs .portal-tab-btn {
  background: transparent;
  color: var(--muted);
  border: none;
  border-radius: 0;
  padding: 10px 4px;
  margin: 0 10px;
  font-size: 14px;
  font-weight: 500;
  position: relative;
}
.po-topnav-tabs .portal-tab-btn:hover { background: transparent; color: var(--text); }
.po-topnav-tabs .portal-tab-btn.active {
  color: var(--text);
  font-weight: 700;
  background: transparent;
}
.po-topnav-tabs .portal-tab-btn.active::after {
  content: "";
  position: absolute;
  left: 4px; right: 4px; bottom: -1px;
  height: 2px;
  background: var(--text);
}
.po-topnav-right { display: flex; align-items: center; gap: 20px; flex-shrink: 0; }
.po-help-link { font-size: 13px; color: var(--muted); cursor: default; }
/* Seletor de idioma (js/i18n.js monta o <select> dentro deste span) — mesmo
   visual discreto do resto do topnav, sem herdar o width:100%/margin-top dos
   <select> genéricos do resto do site. */
.po-lang-switcher .po-lang-select {
  width: auto; margin-top: 0; padding: 4px 8px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 6px; background: var(--panel); color: var(--text);
}
/* Seletor de unidade de medida (mm/cm/m/pol/ft) — pedido do usuário: é global
   (régua do configurador, totais da Composição, tooltip do 3D), então mora
   aqui no topo junto do idioma em vez de escondido dentro da tela "2.
   Configure". Mesmo visual discreto do seletor de idioma ao lado. Começa
   sempre em polegada fracionada (ver option[selected] no HTML) — o cliente
   troca a qualquer momento, sem persistir entre sessões. */
.po-topnav-unit-select {
  width: auto; margin-top: 0; padding: 4px 8px; font-size: 12px;
  border: 1px solid var(--border); border-radius: 6px; background: var(--panel); color: var(--text);
}
/* Pé direito (ceiling) + rodapé (baseboard) da casa — campos globais no topo,
   ao lado do idioma/unidade (pedido do usuário). O valor é digitado na
   unidade global do po-unit-select e re-formatado no blur (ver
   setupRoomSettingsInputs em portal.js). */
.po-topnav-room-wrap { display: flex; align-items: center; gap: 10px; }
.po-topnav-room-field {
  display: flex; align-items: center; gap: 6px;
  margin: 0; font-size: 12px; color: var(--muted, #6b6459); white-space: nowrap;
}
.po-topnav-room-field input {
  width: 64px; margin-top: 0; padding: 4px 6px; font-size: 12px; text-align: right;
  border: 1px solid var(--border); border-radius: 6px; background: var(--panel); color: var(--text);
}

/* Menu de Configurações (pé direito/rodapé/unidade/idioma) — antes esses 4
   controles ficavam soltos e sempre visíveis na barra superior; pedido do
   usuário: "a barra de ferramentas esta baguncada, precisa deixar algumas
   coisas ocultas, pra dar espaco e deixar bem clean". Agora atrás de um
   ícone de engrenagem, painel dropdown simples (mesmo visual de --panel/
   --border do resto do app). */
.po-topnav-settings { position: relative; }
.po-topnav-settings-toggle {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  width: 36px;
  height: 36px;
  font-size: 16px;
  color: var(--muted);
  padding: 0;
  line-height: 1;
}
.po-topnav-settings-toggle:hover { background: var(--accent-light, #f2f0ea); color: var(--text); }
.po-topnav-settings-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 40;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  padding: 14px;
  min-width: 240px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.po-topnav-settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
  color: var(--muted);
}
.po-topnav-settings-menu .po-topnav-room-field { justify-content: space-between; }
.po-topnav-settings-menu .po-lang-switcher .po-lang-select,
.po-topnav-settings-menu .po-topnav-unit-select { margin-left: auto; }
.po-user-chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-left: 20px;
  border-left: 1px solid var(--border);
}
.po-user-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent-light);
  color: var(--text);
  font-weight: 700;
  font-size: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.po-user-meta { display: flex; flex-direction: column; line-height: 1.3; }
.po-user-name { font-size: 13px; font-weight: 600; color: var(--text); max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.po-logout-link {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 11px;
  padding: 0;
  margin: 2px 0 0;
  cursor: pointer;
  text-decoration: underline;
}
.po-logout-link:hover { background: none; color: var(--text); }

/* ---------- Layout de 2 colunas (catálogo + carrinho) ---------- */

.po-shell {
  display: flex;
  align-items: flex-start;
  gap: 28px;
  margin-top: 24px;
  padding-bottom: 40px;
}
.po-main-col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 20px; }
.po-cart-col { flex: 0 0 340px; position: sticky; top: 96px; }

@media (max-width: 960px) {
  .po-shell { flex-direction: column; }
  .po-cart-col { width: 100%; position: static; }
}

.po-section-heading-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 4px;
}
.po-section-heading-row h2 { margin: 0; }

.po-view-toggle {
  display: flex;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  flex-shrink: 0;
}
.po-view-toggle-btn {
  background: var(--panel);
  color: var(--muted);
  border: none;
  border-radius: 0;
  margin: 0;
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 600;
}
.po-view-toggle-btn:hover { background: var(--accent-light); }
.po-view-toggle-btn.active { background: var(--text); color: #fff; }
.po-view-toggle-btn + .po-view-toggle-btn { border-left: 1px solid var(--border); }

/* ---------- Tabs de família (tira principal, estilo "Base Cabinets") ---------- */

.po-family-tabbar {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-top: 6px;
}
.po-family-tabbar .po-tab-pill {
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 7px 14px;
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.po-family-tabbar .po-tab-pill:hover { background: var(--accent-light); color: var(--text); }
.po-family-tabbar .po-tab-pill.active {
  background: transparent;
  color: var(--text);
  border-bottom-color: var(--text);
}

/* Categoria/subcategoria — filtros secundários, menores, sob a tira de família.
   gap usa dois valores (row-gap column-gap): pouco espaço vertical quando
   Categoria/Subcategoria quebram linha (telas estreitas ou lista comprida de
   pills), mantendo respiro horizontal normal quando cabem lado a lado. Label
   com margin próprio (em vez do "label { margin-top:10px }" global) — a
   herança do global tava somando com o gap e deixando a faixa toda mais alta
   do que precisava (pedido do usuário — "bem juntinho"). */
.po-filter-group-secondary { margin-top: 6px; gap: 4px 20px; }
.po-filter-group-secondary label {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--muted);
  margin-top: 0; margin-bottom: 2px;
}
.po-filter-group-secondary .po-tab-pill { font-size: 12px; padding: 4px 10px; }

/* ---------- Grid de módulos (catálogo) ---------- */

.po-module-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 16px;
}
.po-module-card {
  border-radius: 10px;
  padding: 8px;
}
.po-module-card.selected { background: var(--panel); border-color: var(--text); box-shadow: 0 0 0 1px var(--text); }
.po-module-card-image-wrap {
  background: #ffffff;
  border-radius: 8px;
  padding: 4px;
  margin-bottom: 10px;
}
.po-module-card .po-module-card-image-wrap svg,
.po-module-card .po-module-card-image-wrap .po-module-card-image { height: 130px; }
.po-module-card .po-module-card-name { color: var(--text); font-size: 13px; }
.po-module-card .po-module-card-dims { color: var(--muted); display: none; }
.po-module-card-quickadd { margin-top: 10px; }
.po-quickadd-qty { border-radius: 6px; }
.po-quickadd-btn {
  background: var(--text);
  color: #fff;
  border: none;
  border-radius: 6px;
  font-weight: 600;
}
.po-quickadd-btn:hover { background: #000; }
.po-quickadd-btn.secondary { background: var(--text); color: #fff; border: none; }

/* Dropdown de referência (SKU) abaixo do card do catálogo — pedido do
   usuário 2026-07-29, ver renderModuleGallery/addModuleToCartWithSku em
   portal.js. Só existe quando o módulo tem referência cadastrada (largura +
   altura com o mesmo código); selecionar uma opção já insere no carrinho,
   sem botão. */
.po-module-card-sku { margin-top: 8px; }
.po-module-card-sku-select {
  width: 100%;
  font-size: 12px;
  padding: 5px 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--text);
  cursor: pointer;
}

/* Modo lista — mesma galeria, card vira linha horizontal. */
.po-module-gallery.po-view-list { grid-template-columns: 1fr; }
.po-module-gallery.po-view-list .po-module-card {
  display: flex;
  align-items: center;
  gap: 16px;
  text-align: left;
}
.po-module-gallery.po-view-list .po-module-card-image-wrap {
  width: 110px;
  flex-shrink: 0;
  margin-bottom: 0;
}
.po-module-gallery.po-view-list .po-module-card-body { flex: 1; min-width: 0; }
.po-module-gallery.po-view-list .po-module-card-quickadd { margin-top: 0; flex-shrink: 0; width: 220px; }
.po-module-gallery.po-view-list .po-module-card-sku { margin-top: 0; flex-shrink: 0; width: 200px; }
.po-module-gallery.po-view-list .po-quickadd-error { flex-basis: 100%; order: 99; }

/* ---------- Carrinho lateral fixo ("Seu Pedido") ---------- */

.po-project-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px;
}
.po-project-card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.po-project-title { font-size: 15px; font-weight: 700; color: var(--text); }

.po-project-fields { display: flex; flex-direction: column; gap: 6px; }
.po-project-input {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  font-size: 13px;
  margin-top: 0;
  width: 100%;
}
.po-project-input-sub { color: var(--muted); font-size: 12px; }

.po-project-divider { height: 1px; background: var(--border); margin: 14px 0; }

.po-selected-modules-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  color: var(--muted);
  margin-bottom: 6px;
}
.po-cart-list { max-height: 420px; overflow-y: auto; }
.po-cart-list .portal-item-row { padding: 10px 0; gap: 10px; }
.po-cart-list .portal-item-thumb { width: 48px; height: 48px; }
.po-cart-list .portal-item-info { font-size: 11px; }
.po-cart-list .portal-item-title { font-size: 13px; }
.po-cart-empty { font-size: 12px; padding: 8px 0; }

.po-project-summary { display: flex; flex-direction: column; gap: 6px; }
.po-summary-row { display: flex; justify-content: space-between; font-size: 13px; color: var(--muted); }
.po-summary-row.po-summary-total { font-size: 17px; font-weight: 700; color: var(--text); }

.po-project-phone-row { margin-top: 14px; }
.po-project-phone-row label { font-size: 11px; color: var(--muted); }

.po-btn-primary-block {
  width: 100%;
  margin-top: 14px;
  background: var(--text);
  font-weight: 700;
  padding: 12px;
}
.po-btn-primary-block:hover { background: #000; }

/* ---------- Rodapé de suporte ---------- */

.po-support-footer {
  max-width: 1800px; /* acompanha o main (ver body.portal-page main acima) */
  margin: 24px auto 0;
  padding: 24px 32px 32px;
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
}
.po-support-item { font-size: 13px; color: var(--muted); display: flex; flex-direction: column; gap: 4px; }
.po-support-item strong { color: var(--text); font-size: 13px; }
.po-support-item a { color: var(--text); font-weight: 600; text-decoration: underline; }

@media (max-width: 720px) {
  header.po-topnav { flex-wrap: wrap; height: auto; padding: 12px 16px; gap: 12px; }
  .po-topnav-title { display: none; }
  body.portal-page main { padding: 16px; }
}

/* ---------- "Visualizar no meu ambiente" — overlay manual de módulo sobre
   foto do cliente (sem IA, tudo client-side). O stage tem display:inline-
   block + line-height:0 pra encolher exatamente do tamanho da <img> da foto
   (senão getBoundingClientRect() no JS não bateria com o que o cliente vê),
   e cada "camada" (módulo colocado em cima) é um <div> position:absolute
   dentro do stage, arrastável e redimensionável via Pointer Events (cobre
   mouse E touch com o mesmo código — importante porque o uso alvo é celular). */

#po-room-upload-wrap input[type="file"] { padding: 8px; }

#po-room-stage-wrap {
  margin-top: 14px;
  max-width: 100%;
  overflow-x: auto;
}
#po-room-stage {
  position: relative;
  display: inline-block;
  line-height: 0;
  touch-action: none; /* evita o navegador roubar o gesto pra scroll/zoom da página ao arrastar uma camada */
}
#po-room-photo {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: 8px;
}

.po-room-layer {
  position: absolute;
  cursor: move;
  touch-action: none;
  user-select: none;
  border: 2px dashed transparent;
}
.po-room-layer:hover,
.po-room-layer:active { border-color: var(--accent); }
.po-room-layer img {
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none; /* clique/drag sempre resolve no wrapper .po-room-layer, nunca na <img> em si */
  -webkit-user-drag: none;
}
.po-room-layer-remove {
  position: absolute;
  top: -10px;
  right: -10px;
  width: 22px;
  height: 22px;
  min-width: 0;
  padding: 0;
  margin-top: 0;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
}
.po-room-layer-resize-handle {
  position: absolute;
  right: -8px;
  bottom: -8px;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  background: var(--accent);
  border: 2px solid #fff;
  cursor: nwse-resize;
  touch-action: none;
}

#po-room-toolbar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 14px;
}
#po-room-toolbar button { margin-top: 0; }

#po-room-picker { margin-top: 22px; }
.po-room-cart-picker-list {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 6px;
}
.po-room-cart-picker-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  width: 84px;
  padding: 8px 6px;
  margin-top: 0;
  background: #fff;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 11px;
  line-height: 1.25;
  cursor: pointer;
  text-align: center;
}
.po-room-cart-picker-item:hover { border-color: var(--accent); background: var(--bg); }
.po-room-cart-picker-item img { width: 56px; height: 56px; object-fit: contain; }

/* ---------- Composição — fileira de slots esquerda->direita ---------- */

.po-comp-mode-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: #fbf3ec;
  border: 1px solid var(--accent);
  border-radius: 8px;
  padding: 10px 14px;
  margin-bottom: 16px;
  font-size: 13px;
  color: var(--accent-dark);
}
.po-comp-mode-banner button { margin-top: 0; padding: 5px 12px; }
/* Editando post da Galeria como admin — mesma marcação/layout de
   .po-comp-mode-banner, cor azul só pra distinguir visualmente do banner
   laranja de "Configurando módulo X" (contextos diferentes, mas podem
   coexistir na tela). */
.po-comp-admin-edit-banner { background: #eaf1fb; border-color: #6b8fc9; color: #2c4a75; }

.po-comp-slots {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 14px;
}
.po-comp-slot {
  width: 190px;
  min-height: 210px;
  border-radius: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  position: relative;
  padding: 10px;
}
.po-comp-slot.empty {
  border: 2px dashed var(--border);
  color: var(--muted);
  cursor: pointer;
  gap: 6px;
  font-size: 13px;
}
.po-comp-slot.empty:hover { border-color: var(--accent); color: var(--accent-dark); background: var(--bg); }
.po-comp-slot-plus { font-size: 28px; line-height: 1; color: var(--accent); }

.po-comp-slot.filled {
  border: 1px solid var(--border);
  background: #fff;
  justify-content: flex-start;
  cursor: pointer;
}
.po-comp-slot.filled:hover { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent) inset; }
.po-comp-slot-thumb { width: 140px; height: 140px; object-fit: contain; margin-top: 4px; }

/* Divisor clicável "inserir módulo aqui" entre dois cards já preenchidos
   (pedido do usuário: "acrescentar algum módulo no meio de dois já
   configurados") — fica discreto até o hover, pra não competir visualmente
   com os cards de verdade. */
.po-comp-slot-divider {
  width: 22px;
  min-height: 210px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: transparent;
  font-size: 18px;
  border-radius: 6px;
  transition: color 0.15s, background 0.15s;
}
.po-comp-slot-divider:hover { color: var(--accent-dark); background: var(--bg); }
.po-comp-slot-name { font-size: 12px; font-weight: 600; color: var(--text); margin-top: 6px; line-height: 1.25; }
.po-comp-slot-dims { font-size: 11px; color: var(--muted); margin-top: 2px; }
.po-comp-slot-remove {
  position: absolute;
  top: -8px;
  right: -8px;
  width: 22px;
  height: 22px;
  min-width: 0;
  padding: 0;
  margin-top: 0;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Empilhamento vertical (2026-07-16): altura do chão editável direto no
   card (pedido do usuário: "poder escolher a altura de cada item... que eu
   possa mexer depois de inserido vendo os dois no mesmo ambiente") — input
   pequeno, sem o padding/width padrão de input (que ocupa 100% e é alto
   demais pra um card de 190px), e o botão "Colocar em cima" (topo da
   coluna, acima do quadro, ver comentário no columnWrap em portal.js).
   stopPropagation nos dois evita abrir o configurador ao clicar neles. */
.po-comp-slot-floor-height {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 10px;
  color: var(--muted);
  cursor: default;
}
.po-comp-slot-floor-height-input {
  width: 60px;
  padding: 3px 5px;
  font-size: 11px;
  text-align: right;
}
.po-comp-slot-floor-height-unit { font-size: 10px; color: var(--muted); }
.po-comp-slot-stack-btn {
  width: 100%;
  padding: 6px 10px;
  font-size: 12px;
  margin-top: 0;
}

#po-comp-generate-btn { max-width: 320px; }
#po-comp-generate-hint { margin-top: 8px; }

/* Checkboxes de habilitar/desabilitar cada medida total + a linha de chips
   com o resultado (largura = soma dos slots, altura/profundidade = maior
   entre os slots — ver renderCompositionTotals em portal.js). */
.po-comp-totals-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 18px;
  margin-top: 10px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
}
.po-comp-totals-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted);
  margin-top: 0;
  cursor: pointer;
}
.po-comp-totals-toggle input { width: auto; margin-top: 0; }
.po-comp-totals-line {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  width: 100%;
}
.po-comp-total-chip {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

/* Cena 3D combinada (ver js/viewer3d_composition.js) — mais larga/alta que
   o viewer de um módulo só (#viewer3d-canvas), já que mostra vários módulos
   lado a lado em escala real. */
/* Canvas + painel de troca rápida de cor das laterais lado a lado (pedido
   do usuário: "deve ficar em quadros do lado do 3d, sem espremer o
   visualizador") — mesmo padrão de #viewer-config-row (configurador de um
   módulo só): flex-wrap pra empilhar em telas estreitas, canvas com
   flex:1 (cresce/encolhe livre) e o painel lateral com largura própria
   limitada, então o painel nunca "espreme" o canvas — ele só ocupa o
   espaço que sobra depois do painel reservar a própria faixa. */
#po-comp-3d-row { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
/* Canvas + botões "Abrir portas"/"Abrir gavetas" (ver portal.html) agrupados
   num wrap próprio — é ELE que ocupa a faixa flex:1 da fileira agora (canvas
   sozinho não tem mais espaço pros botões abaixo dele senão). */
#po-comp-3d-canvas-wrap { flex: 1 1 420px; min-width: 0; }
#po-comp-3d-canvas {
  width: 100%;
  height: 420px;
  border: none;
  overflow: hidden;
  background: #ffffff;
  touch-action: none;
}
#po-comp-3d-canvas canvas { display: block; width: 100%; height: 100%; }
/* Visualizar 3D da aba Projetos (ViewerProject, própria instância — ver
   viewer3d_composition.js/createInstance) — mesmo visual do canvas 3D da
   Composição acima, só sem o painel de troca rápida de cor ao lado (não
   pedido pra esta fase). */
#po-proj-close-3d-btn { display: block; margin-bottom: 10px; }
#po-proj-3d-canvas-wrap { width: 100%; }
#po-proj-3d-canvas {
  width: 100%;
  /* 2026-08-03 (pedido: "deixa essa janela maior pra trabalhar, muito
     espaço vazio dos lados") — altura acompanha a TELA em vez dos 420px
     fixos; canvas mais alto = câmera de fit-automático chega mais perto e
     o móvel preenche a largura (o vazio lateral era consequência do fit
     limitado pela altura baixa).
     2026-08-06 (iPad Air 13"): mesma subida do #po-proj-canvas-3d-edit.
     2026-08-12: teto 1200 -> 1600px. Em monitor 1440p/4K o 88vh já passava de
     1200 e o teto é que estava segurando — a faixa branca dos lados era só
     metade do problema. */
  height: clamp(420px, 88vh, 1600px);
  border: none;
  overflow: hidden;
  background: #ffffff;
  touch-action: none;
}
#po-proj-3d-canvas canvas { display: block; width: 100%; height: 100%; }
#po-comp-side-color-panel {
  flex: 0 1 220px;
  max-width: 240px;
  min-width: 180px;
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px;
  background: #fff;
}
#po-comp-side-color-panel label { display: block; font-weight: 600; margin-bottom: 2px; }
/* Mesmo painel de troca rápida de cor (abas por papel de cor), só que na
   tela do pedido (#po-order-detail-color-panel) não tem canvas 3D ao lado
   pra dividir espaço com — ocupa a largura toda, acima da lista de itens. */
.po-order-detail-save-info-row { display: flex; align-items: center; gap: 10px; margin: 10px 0; }
.po-order-detail-save-info-row button { margin-top: 0; }
.po-order-detail-color-panel {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px;
  background: #fff;
  margin: 12px 0;
}
.po-order-detail-color-panel label { display: block; font-weight: 600; margin-bottom: 2px; }
/* "Processando" (pedido do usuário 2026-07-29: "talvez uma janela de
   carregamento mostrando que esta processando ate finalizar") — desabilita
   visualmente as abas/swatches enquanto applyPendingColorChangesToOrderItems
   roda, pra não deixar clicar de novo no meio do processamento. */
.po-order-detail-color-panel-busy #po-order-detail-color-tabs,
.po-order-detail-color-panel-busy #po-order-detail-color-swatches {
  opacity: 0.5;
  pointer-events: none;
}
.po-order-detail-color-panel-busy { cursor: progress; }
/* Abas do painel de troca rápida de cor (pedido do usuário, 2026-07-16:
   "pode fazer por abas pra nao ocupar muito espaco na tela") — mesmo visual
   de chip de .dim-preset-chip, só com estado .active (mesma cor sólida de
   .portal-tab-btn.active) pra marcar qual papel de cor está sendo mostrado. */
.po-comp-color-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.po-comp-color-tab-btn {
  padding: 3px 10px;
  font-size: 12px;
  font-weight: 500;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--accent-dark);
  cursor: pointer;
  white-space: nowrap;
}
.po-comp-color-tab-btn:hover { border-color: var(--accent); background: var(--accent-light, #fdf3e6); }
.po-comp-color-tab-btn.active { background: var(--accent); border-color: var(--accent); color: #fff; }
#po-comp-side-color-swatches { margin-top: 8px; }
.po-comp-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.po-comp-title-row h2 { margin-bottom: 0; }
.po-comp-3d-total {
  margin: 12px 0;
  font-size: 18px;
  font-weight: 600;
  color: var(--text);
}
/* Linha de ações da Composição — botão de IA (chamativo) à esquerda,
   carrinho jogado pra direita (pedido do usuário, 2026-07-19: "joga esse
   botao de carrinho pra direita e deixa um botao chamativo de gerar ia").
   .po-btn-primary-block normalmente é width:100% (ver definição genérica) —
   aqui dentro vira automático pra caber ao lado do botão de IA sem esticar. */
.po-comp-actions-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 14px;
}
.po-comp-actions-row .po-btn-primary-block {
  width: auto;
  margin-top: 0;
  min-width: 220px;
}
.po-comp-ai-cta-btn {
  background: linear-gradient(135deg, #f7971e 0%, #d64ec2 55%, #7b5cff 100%);
  color: #fff;
  border: none;
  font-weight: 700;
  padding: 12px 22px;
  border-radius: 999px;
  box-shadow: 0 4px 14px rgba(123, 92, 255, 0.35);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.po-comp-ai-cta-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(123, 92, 255, 0.45);
}
#po-comp-add-cart-btn { max-width: 320px; }

/* "Novo Orçamento" abrindo como MODAL de tela cheia por cima da aba
   Composição (ver startCompositionSlotConfig em portal.js) — mesma
   marcação/lógica de sempre (nada duplicado), só muda a apresentação: em
   vez de virar a aba ativa (o que esconderia a Composição por trás), fica
   fixo cobrindo a tela toda, com scroll próprio, enquanto a Composição
   continua "por baixo" sem nunca ter sido escondida. Fechar o modal (Cancelar
   ou Adicionar) é só voltar o display a 'none' — a Composição reaparece
   sozinha, sem precisar recarregar nada. */
#po-tab-new-order.po-modal-mode {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--bg);
  overflow-y: auto;
  padding: 20px 16px 40px;
  margin: 0;
}

/* ---------- Galeria pública de composições (migration 048) ---------- */

.po-gallery-ai-disclaimer {
  background: #fff8e6;
  border: 1px solid #f0d999;
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 13px;
  color: #7a5c00;
  margin: 8px 0 16px;
}

.po-gallery-publish-wrap { margin-top: 14px; }
#po-gallery-publish-form {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px;
  margin-top: 8px;
  max-width: 420px;
}
#po-gallery-publish-form label { display: block; font-size: 13px; color: var(--muted); margin-top: 8px; }
#po-gallery-publish-form select { width: 100%; margin-top: 4px; }
.po-gallery-anon-label { display: flex !important; align-items: center; gap: 6px; cursor: pointer; }
.po-gallery-anon-label input { width: auto; }
#po-gallery-ai-preview-wrap { margin: 10px 0; }
#po-gallery-ai-preview-img {
  display: block;
  width: 100%;
  max-width: 320px;
  height: 220px;
  object-fit: contain;
  background: #ffffff;
  cursor: zoom-in;
  border: 1px solid var(--border);
  border-radius: 8px;
}
.po-gallery-ai-preview-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; max-width: 320px; }
.po-gallery-ai-preview-actions button { margin-top: 0; }
#po-gallery-base-preview-wrap { margin-top: 8px; }
#po-gallery-base-preview-img {
  display: block;
  width: 100%;
  max-width: 200px;
  height: 140px;
  object-fit: contain;
  background: #ffffff;
  cursor: zoom-in;
  border: 1px dashed var(--border);
  border-radius: 8px;
}

.po-gallery-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: flex-end;
  margin-bottom: 16px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel);
}
.po-gallery-filter-field { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--muted); }
.po-gallery-filter-field select { min-width: 140px; }
.po-gallery-filter-range { display: flex; align-items: center; gap: 6px; }
.po-gallery-filter-range input { width: 80px; }

.po-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
}
.po-gallery-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel);
  overflow: hidden;
  transition: border-color 0.15s;
}
.po-gallery-card:hover { border-color: var(--accent); }
/* aspect-ratio (em vez de height fixo) + object-fit:cover — a imagem
   preenche o quadro do card sem distorcer nem sobrar faixa branca dos
   lados quando o render da IA sai em proporção diferente do card; ver
   quem quiser sem corte, `.po-gallery-card-image` abre no lightbox
   (object-fit:contain lá, ninguém perde detalhe). */
.po-gallery-card-image-wrap { background: #ffffff; aspect-ratio: 4 / 3; overflow: hidden; position: relative; }
.po-gallery-card-image { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
.po-gallery-card-image-empty { width: 100%; height: 100%; background: var(--accent-light, #f2f0ea); }
.po-gallery-card-image-zoom-hint {
  position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; border-radius: 50%;
  background: rgba(0,0,0,0.45); color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 14px; pointer-events: none;
}
.po-gallery-card-body { padding: 10px 12px 12px; }
.po-gallery-card-name { font-weight: 600; color: var(--accent-dark); font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.po-gallery-card-meta { font-size: 12px; margin-top: 2px; }
.po-gallery-card-author { font-size: 11px; margin-top: 2px; }
/* Preço no estilo "Starting at $X" da referência (pedido do usuário
   2026-07-19: foto de catálogo com botão "Customize →") — rótulo pequeno em
   cima, valor grande embaixo, sem casas decimais nem separador de milhar
   (ver formatGalleryPrice em portal.js — diferente do formatMoney usado no
   carrinho/pedidos, que continua com centavos). */
.po-gallery-card-price-label { font-size: 11px; color: var(--muted); margin-top: 8px; }
.po-gallery-card-price { font-weight: 700; color: var(--ink, #1a1a1a); font-size: 19px; margin-top: 2px; }
.po-gallery-card-actions { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
/* Curtir (♥) vira um botão circular flutuante sobre a FOTO (canto superior
   esquerdo), igual à referência — antes ficava ao lado do botão principal,
   embaixo do card. */
.po-gallery-like-btn {
  position: absolute; top: 8px; left: 8px; z-index: 2;
  width: 26px; height: 26px; padding: 0; margin-top: 0;
  border-radius: 50%; border: 1px solid var(--border); background: #fff;
  display: flex; align-items: center; justify-content: center; gap: 1px; font-size: 11px;
  box-shadow: 0 1px 4px rgba(0,0,0,0.18);
}
/* Pedido do usuário 2026-07-20: menor e SEMPRE círculo perfeito, mesmo com
   número (nada de virar pill/oval — ver galleryLikeButtonContent). */
.po-gallery-like-heart { color: #e0245e; line-height: 1; font-size: 12px; }
.po-gallery-like-count { font-size: 9px; font-weight: 700; color: var(--ink, #1a1a1a); line-height: 1; }
/* Botão principal ("Customize →" na referência) — pill de borda fina,
   largura total do card, texto + seta, preenche na cor de destaque no
   hover. Mesmo tamanho/proporção da referência (padding generoso, bem
   arredondado). */
.po-gallery-use-btn {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  flex: 1; height: 40px; padding: 0 16px; border-radius: 999px;
  border: 1.5px solid var(--accent-dark); background: #fff; color: var(--accent-dark);
  font-weight: 600; font-size: 14px; transition: background 0.15s, color 0.15s;
}
.po-gallery-use-btn:hover { background: var(--accent-dark); color: #fff; }
/* Botão "Compartilhar" (pedido do usuário 2026-07-20) — MESMA altura exata
   do botão principal (height:40px nos dois, em vez de depender de padding
   pra chegar num tamanho parecido — era o que desalinhava), só que
   circular. Reduzido de 44px pra 40px (pedido: "deixa o botão... menor"). */
.po-gallery-share-btn {
  flex: none; width: 40px; height: 40px; padding: 0; margin-top: 0;
  border-radius: 50%; border: 1.5px solid var(--border); background: #fff;
  display: flex; align-items: center; justify-content: center;
  color: #1a1a1a; /* ícone SVG usa stroke="currentColor" */
  transition: border-color 0.15s, background 0.15s;
}
.po-gallery-share-btn:hover { border-color: var(--accent-dark); background: var(--accent-light, #f2f0ea); }
.po-gallery-share-menu {
  display: none; position: absolute; z-index: 2100; min-width: 180px;
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.18); padding: 6px; flex-direction: column; gap: 2px;
}
.po-gallery-share-item {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 6px;
  font-size: 13px; text-align: left; color: var(--ink, #1a1a1a); background: none; border: none;
  cursor: pointer; text-decoration: none; width: 100%; font-family: inherit;
}
.po-gallery-share-item:hover { background: var(--accent-light, #f2f0ea); }

.po-gallery-lightbox-overlay {
  display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.86);
  z-index: 2000; align-items: center; justify-content: center; padding: 24px;
}
.po-gallery-lightbox-img { max-width: 92vw; max-height: 92vh; object-fit: contain; border-radius: 6px; box-shadow: 0 10px 40px rgba(0,0,0,0.5); }
.po-gallery-lightbox-close {
  position: absolute; top: 16px; right: 20px; background: none; border: none;
  color: #fff; font-size: 34px; line-height: 1; cursor: pointer;
}

/* ---------- "Meus Projetos" (grid de cards, pedido do usuário 2026-08-02:
   "essa tela ta muito baguncada... quer mais alinhados, quadrado para cada
   pedido") — mesmo esqueleto visual de .po-gallery-card acima (card
   panel + imagem no topo + corpo com nome/meta/ações), só que a imagem é
   QUADRADA (1/1, não 4/3) e pode vir "partida" ao meio quando o projeto tem
   as duas imagens (snapshot 3D automático + última imagem de IA publicada,
   ver captureProjectThumbnail/publishProjectToGallery em portal.js) — cada
   metade abre sozinha no lightbox (openGalleryLightbox reaproveitado). */
.po-myproj-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}
.po-myproj-card {
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel);
  overflow: hidden;
  transition: border-color 0.15s;
}
.po-myproj-card:hover { border-color: var(--accent); }
.po-myproj-card-image-wrap { background: #ffffff; aspect-ratio: 1 / 1; overflow: hidden; position: relative; }
.po-myproj-card-image { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
.po-myproj-card-image-empty { width: 100%; height: 100%; background: var(--accent-light, #f2f0ea); }
.po-myproj-card-image-split { display: flex; width: 100%; height: 100%; }
.po-myproj-card-image-half { position: relative; width: 50%; height: 100%; }
.po-myproj-card-image-half + .po-myproj-card-image-half { border-left: 1px solid rgba(0,0,0,0.08); }
.po-myproj-card-image-badge {
  position: absolute; bottom: 6px; left: 6px; z-index: 2;
  background: rgba(0,0,0,0.55); color: #fff; font-size: 10px; font-weight: 700;
  padding: 2px 6px; border-radius: 999px; pointer-events: none; letter-spacing: 0.02em;
}
.po-myproj-card-image-zoom-hint {
  position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; border-radius: 50%;
  background: rgba(0,0,0,0.45); color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 14px; pointer-events: none;
}
.po-myproj-card-body { padding: 10px 12px 12px; }
.po-myproj-card-name { font-weight: 600; color: var(--accent-dark); font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.po-myproj-card-meta { font-size: 12px; margin-top: 2px; }
.po-myproj-card-total { font-size: 13px; font-weight: 600; color: var(--accent-dark); margin-top: 4px; }
.po-myproj-card-actions { display: flex; align-items: center; gap: 6px; margin-top: 10px; flex-wrap: wrap; }
.po-myproj-card-actions button { margin-top: 0; }

/* Grade de fotos realistas salvas (migration 077, aba Projetos) — mesma
   miniatura quadrada com zoom da lista "Meus Projetos", só que com botão de
   excluir por versão em vez de badge/split. */
.po-photoreal-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
  margin-top: 6px;
}
.po-photoreal-gallery-item {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--border);
  background: #fff;
}
.po-photoreal-gallery-item img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
.po-photoreal-gallery-delete {
  position: absolute; top: 4px; right: 4px; width: 26px; height: 26px; border-radius: 50%;
  background: rgba(0,0,0,0.55); color: #fff; border: none; display: flex; align-items: center;
  justify-content: center; font-size: 13px; cursor: pointer; padding: 0; margin: 0;
  line-height: 1;
}
.po-photoreal-gallery-delete:hover { background: rgba(179,38,30,0.85); }

/* ---------- Projetos (canvas 2D, Fase 1 — pedido do usuário 2026-07-21) ----------
   "tela de projetos... vista frontal 2D paralela (não perspectiva)... deve
   dar pra arrastar... tipo ímã que puxe os cantos... ao colocar um módulo na
   frente do outro, ele deve levar o módulo novo pra frente". Canvas é um DOM
   simples (divs posicionados em px, escala = po-proj-canvas.dataset.pxPerMm),
   não Three.js — mais simples de arrastar/snapar e mais fiel ao mockup
   (retângulos com cota, não uma cena 3D vista de frente). */
/* FAIXA SUPERIOR ÚNICA da aba Projetos (2026-08-08, etapa 1 do redesenho
   mandado pelo usuário como mockup). Substitui .po-proj-wall-shape-row +
   .po-proj-wall-settings, que eram blocos empilhados. Um cartão só, com as
   coisas do AMBIENTE (formato, parede ativa, medidas) e a ação à direita.
   align-items:flex-end alinha tudo pela BASE — os campos têm label em cima,
   os toggles não, e sem isso um flutuaria no meio do outro. */
.po-proj-topbar {
  display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap;
  padding: 10px 12px; margin: 8px 0 10px;
  border: 1px solid var(--border); border-radius: 12px; background: var(--panel);
}
.po-proj-topbar-group { display: flex; flex-direction: column; gap: 5px; }
.po-proj-topbar-label {
  font-size: 11px; color: var(--muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.03em;
}
.po-proj-topbar-fields { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
/* Campos compactos: o valor é curto (uma medida) e o rótulo é que ocupa
   espaço — 132px cabe "Largura da parede" em 2 linhas sem espremer o input. */
.po-proj-topbar-field { width: 132px; max-width: 132px; margin: 0; }
.po-proj-topbar-field label { font-size: 11px; }
/* margin-left:auto empurra a ação pro fim da faixa; quando a linha quebra em
   tela estreita, ela simplesmente vai pra baixo, sem regra extra. */
.po-proj-topbar-actions { margin-left: auto; }
.po-proj-topbar-actions button { margin: 0; white-space: nowrap; }

/* Abas de parede (só aparecem com 2-3 paredes, ver refreshProjectWallTabs em
   portal.js) — estilo discreto de pill pra não competir com o toggle de
   formato ao lado. Agora vivem DENTRO da faixa, por isso a margem zerada. */
.po-proj-wall-tabs {
  display: flex; gap: 6px; flex-wrap: wrap;
  margin: 0;
}
.po-proj-wall-tab-btn {
  background: var(--panel); color: var(--muted);
  border: 1px solid var(--border); border-radius: 999px;
  margin: 0; padding: 4px 12px; font-size: 12px; font-weight: 600;
}
.po-proj-wall-tab-btn:hover { background: var(--accent-light); }
.po-proj-wall-tab-btn.active { background: var(--text); color: #fff; border-color: var(--text); }
.po-proj-layout {
  display: grid;
  /* Colunas ajustáveis (pedido do usuário, 2026-07-21) — largura em
     variáveis CSS setadas por applyProjectColumnWidths() (portal.js),
     arrastando .po-proj-resize-handle-left/right. Padrão só entra em uso se
     o JS ainda não rodou (var() sem fallback nunca acontece na prática). */
  grid-template-columns: var(--proj-lib-w, 200px) 8px 1fr 8px var(--proj-cfg-w, 240px);
  gap: 10px;
  margin-top: 8px;
  align-items: start;
}
@media (max-width: 980px) {
  .po-proj-layout { grid-template-columns: 1fr; }
  .po-proj-resize-handle { display: none; }
}
.po-proj-resize-handle {
  align-self: stretch;
  width: 8px;
  min-height: 200px;
  cursor: col-resize;
  position: relative;
}
.po-proj-resize-handle::after {
  content: '';
  position: absolute; left: 50%; top: 8%; bottom: 8%; width: 3px;
  transform: translateX(-50%); background: var(--border); border-radius: 2px;
  transition: background 0.15s;
}
.po-proj-resize-handle:hover::after, .po-proj-resize-handle.resizing::after { background: var(--accent); }
.po-proj-library {
  border: 1px solid var(--border); border-radius: 10px; padding: 10px;
  background: var(--panel);
  /* 2026-08-12: era 640px fixo — numa tela alta a lista parava no meio com
     espaço sobrando embaixo. Agora acompanha a tela, igual aos canvas. */
  max-height: clamp(420px, 82vh, 1500px);
  overflow-y: auto;
}

/* ---- Colunas recolhíveis (pedido do usuário 2026-08-06, no iPad Air 13") ----
   Recolhida, a coluna vira uma tira de PROJECT_COLUMN_COLLAPSED_PX (ver
   portal.js) só com o botão de expandir; todo o resto do conteúdo some e o
   espaço vai pro centro, que é onde mora o visualizador 3D. As classes
   .lib-collapsed/.cfg-collapsed ficam no .po-proj-layout (setadas por
   applyProjectColumnWidths). */
.po-proj-config-col { min-width: 0; position: relative; }

.po-proj-col-toggle {
  width: 100%; margin: 0 0 8px; padding: 4px 0;
  background: transparent; color: var(--muted);
  border: 1px solid var(--border); border-radius: 6px;
  font-size: 13px; line-height: 1; cursor: pointer;
  /* Alvo confortável de dedo no tablet sem virar um bloco no desktop. */
  min-height: 32px;
}
.po-proj-col-toggle:hover { color: var(--text); border-color: var(--accent); }
/* O glifo é CSS pra não duplicar string em 2 lugares nem passar por i18n —
   a direção da seta é a AÇÃO (‹ recolhe, › expande). */
.po-proj-col-toggle::after { content: '‹'; font-size: 16px; }
.po-proj-col-toggle-right::after { content: '›'; }
.po-proj-layout.lib-collapsed .po-proj-col-toggle::after { content: '›'; }
.po-proj-layout.cfg-collapsed .po-proj-col-toggle-right::after { content: '‹'; }

/* Recolhida: some tudo menos o botão, e a moldura/padding do painel some
   junto (senão sobra uma caixa vazia de 40px com borda). */
.po-proj-layout.lib-collapsed .po-proj-library {
  padding: 0; border: none; background: transparent; overflow: visible;
}
.po-proj-layout.lib-collapsed .po-proj-library > *:not(.po-proj-col-toggle) { display: none; }
.po-proj-layout.cfg-collapsed .po-proj-config-panel { display: none; }
/* Sem coluna pra redimensionar, o handle de arrastar não faz sentido. */
.po-proj-layout.lib-collapsed #po-proj-resize-handle-left,
.po-proj-layout.cfg-collapsed #po-proj-resize-handle-right { visibility: hidden; }
.po-proj-library-search {
  margin-bottom: 8px;
}
.po-proj-library-search button {
  width: 100%; margin-top: 0;
}
.po-proj-library-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
}
.po-proj-library-card {
  border: 1px solid var(--border); border-radius: 8px; padding: 6px;
  text-align: center; cursor: grab; background: #fff;
  transition: border-color 0.15s, background 0.15s;
  font-size: 11px;
}
.po-proj-library-card:hover { border-color: var(--accent); background: #fbf3ec; }
.po-proj-library-card:active { cursor: grabbing; }
.po-proj-library-card svg, .po-proj-library-card .po-module-card-image { width: 100%; height: 56px; display: block; pointer-events: none; object-fit: contain; }
.po-proj-library-card-name { font-weight: 600; margin-top: 4px; line-height: 1.2; }
.po-proj-library-card-dims { color: var(--muted); margin-top: 2px; display: none; }
.po-proj-library-empty { grid-column: 1 / -1; color: var(--muted); font-size: 12px; text-align: center; padding: 12px 0; }

/* Modal de busca de módulos (botão "Buscar" da aba Projetos, pedido do
   usuário 2026-07-23) — mesmo padrão de overlay do #po-auth-section
   (fixed/inset:0/z-index alto, escondido por padrão, classe .open abre),
   só com um card bem mais largo pra caber as 3 camadas + grade de módulos. */
#po-proj-search-modal {
  display: none; position: fixed; inset: 0; z-index: 3000;
  align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55); padding: 20px;
}
#po-proj-search-modal.open { display: flex; }
/* Pedido do usuário (2026-07-23): "a tela muda de tamanho conforme os
   modulos que tem disponivel. quero deixar ela fixa sempre. maior possivel.
   arrastando pra baixo se tiver mais do que a tela" — card com ALTURA FIXA
   (não mais max-height que encolhia com poucos resultados), maior possível
   dentro da viewport; só a GRADE de módulos rola por dentro quando não cabe
   (título/filtros ficam sempre visíveis, fixos no topo). */
.po-proj-search-modal-card {
  background: var(--panel); border-radius: 12px; padding: 24px;
  width: 960px; max-width: 100%; height: 85vh; max-height: 85vh;
  display: flex; flex-direction: column;
  position: relative; box-shadow: 0 20px 60px rgba(0,0,0,0.35);
}
.po-proj-search-modal-card > h2 { flex: none; }
.po-proj-search-modal-filters {
  display: flex; flex-direction: column; gap: 6px; margin: 10px 0 16px;
  flex: none;
}
.po-proj-search-modal-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 10px; align-content: start;
  flex: 1 1 auto; overflow-y: auto; min-height: 0;
}

/* Modal do gerador por IA (aba Projetos, migration 080) — mesmo overlay do
   modal de busca acima, mas card estreito e com altura pelo conteúdo: é um
   formulário curto, não uma grade. */
#po-proj-ai-modal {
  display: none; position: fixed; inset: 0; z-index: 3000;
  align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55); padding: 20px;
}
#po-proj-ai-modal.open { display: flex; }
.po-proj-ai-modal-card {
  background: var(--panel); border-radius: 12px; padding: 24px;
  width: 460px; max-width: 100%; max-height: 90vh; overflow-y: auto;
  position: relative; box-shadow: 0 20px 60px rgba(0,0,0,0.35);
}
.po-proj-ai-modal-card .dim-field { margin-bottom: 12px; }
.po-proj-ai-modal-card select,
.po-proj-ai-modal-card input[type="text"] { width: 100%; }
.po-proj-ai-modal-actions {
  display: flex; gap: 8px; justify-content: flex-end; margin-top: 18px;
}
/* (.po-proj-ai-field saiu em 2026-08-08 — o botão "Gerar com IA" foi pra
   .po-proj-topbar-actions, encostado à direita da faixa superior.) */

.po-proj-canvas-outer { min-width: 0; }
/* Frontal/Superior mora DENTRO da barra flutuante — não centraliza sozinho. */
.po-proj-view-toggle { margin: 0; width: fit-content; }

/* ---------- Barras FLUTUANTES do canvas (2026-08-08, etapa 2) ----------
   Antes eram uma faixa própria acima do desenho (.po-proj-canvas-tools);
   viraram overlays por cima dele, como no mockup, devolvendo a altura que
   ocupavam pro canvas — que era o objetivo, ainda mais no iPad.
   O "palco" é quem dá o position:relative; ele NÃO pode ser
   .po-proj-canvas-wrap (overflow:auto — as barras rolariam junto com o
   desenho na vista 2D e sumiriam). */
/* Voltou a ser linha: as duas barras são absolutas na direita (ver
   .po-proj-hud-tl), então o palco não precisa reservar espaço pra elas. */
.po-proj-canvas-stage { position: relative; flex: 1; min-width: 0; display: flex; }
.po-proj-canvas-stage > .po-proj-canvas-wrap { flex: 1; min-width: 0; min-height: 0; }

.po-proj-canvas-hud {
  position: absolute; z-index: 30; display: flex; align-items: center; gap: 4px;
  padding: 4px; border: 1px solid var(--border); border-radius: 10px;
  /* Fundo semiopaco: a barra fica POR CIMA do desenho, então precisa se
     destacar sem tapar o que está atrás dela. */
  background: rgba(255,255,255,0.92);
  box-shadow: 0 2px 10px rgba(0,0,0,0.12);
}
/* BARRA DE CIMA FORA DO DESENHO (2026-08-13). Ela era absolute dentro do
   palco e ficava POR CIMA da cena — o Matt: "essa barra tá incomodando a
   visualização, como as paredes vão sair, pode jogar essa barra pra cima".
   Com parede sólida e ambiente fechado, o canto superior esquerdo passou a ser
   justamente onde o desenho acontece.
   Agora ela é estática e mora ACIMA do palco (ver .po-proj-canvas-stage, que
   virou coluna): não tapa nada e não rouba área do canvas.
   A barra da DIREITA (câmera) continua flutuando — ela é estreita, fica no
   meio da altura e some fora da cena 3D. */
/* 2ª tentativa (2026-08-13): tirar a barra de cima do desenho custou uma FAIXA
   INTEIRA de altura — "piorou, usou mais espaço ainda". Agora ela é uma coluna
   colada na DIREITA, junto da barra de câmera que já morava lá: não tapa o
   ambiente (que cresce da esquerda pro centro), não gasta linha nenhuma da
   página, e as duas ferramentas ficam no mesmo lugar em vez de uma em cada
   canto. */
/* 3ª e definitiva (2026-08-13): a barra MUDOU DE LUGAR NO HTML — saiu de
   dentro do palco e virou parte da faixa de cima, na mesma linha do "Ajustar
   paredes". Era o que o Matt pediu desde o começo ("joga essa barra pra
   cima... elimina completamente daqui e coloca a barra que tava dentro").
   Como a faixa já existia (ela tinha o formato do ambiente, as abas de parede
   e a largura — tudo isso saiu), a barra não custa NENHUMA altura nova.
   Aqui ela só perde o visual de flutuante: sem posição absoluta, sem fundo,
   sem sombra. */
.po-proj-hud-tl {
  position: static; background: transparent; box-shadow: none;
  border-color: transparent; padding: 0; max-width: none;
}
/* A barra da câmera volta pro meio da altura, na direita — ela é a única que
   continua flutuando sobre a cena. */
.po-proj-hud-right { top: 50%; bottom: auto; transform: translateY(-50%); }
.po-proj-hud-right { top: 50%; right: 8px; transform: translateY(-50%); flex-direction: column; }
.po-proj-hud-sep { width: 1px; align-self: stretch; min-height: 20px; background: var(--border); margin: 0 2px; }

/* Botão da barra: quadrado, alvo confortável pro dedo (32px), só o ícone. */
.po-proj-hud-btn {
  width: 32px; height: 32px; padding: 0; margin: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; line-height: 1; font-weight: 700;
  background: transparent; color: var(--text);
  border: 1px solid transparent; border-radius: 8px;
}
.po-proj-hud-btn:hover { background: var(--accent-light); }
.po-proj-hud-btn.active { background: var(--text); color: #fff; }
/* Seletor de estilo de exibição na barra flutuante — mesmo tamanho/altura dos
   botões ao lado, pra não quebrar a linha da barra. */
.po-proj-hud-select {
  height: 28px; max-width: 190px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--panel); color: var(--text);
  font-size: 11px; font-weight: 600; padding: 0 6px; cursor: pointer;
}
.po-proj-hud-select:hover { border-color: var(--accent); }
.po-proj-hud-btn:disabled { opacity: 0.3; cursor: default; }
.po-proj-hud-btn:disabled:hover { background: transparent; }
/* (.po-proj-hud-danger ficou sem uso quando a lixeira saiu da barra em
   2026-08-08 — mantida a regra fora, não há mais botão destrutivo aqui.) */
/* Frontal/Superior dentro da barra fica um pouco menor que o padrão. */
.po-proj-hud-tl .po-view-toggle-btn { padding: 5px 10px; font-size: 11px; }

/* (.po-proj-tool-btn/.po-proj-canvas-tools da 2ª rodada viraram
   .po-proj-hud-btn/.po-proj-canvas-hud aqui em cima — as regras antigas foram
   removidas junto com a faixa que elas estilizavam.) */

/* Aviso de GIRO (Shift + arrastar, 2026-08-12) — "me informe quando esta
   rotacionando no canto inferior da tela visivel". Fica no canto de baixo da
   PRÓPRIA cena 3D (não da janela): o wrap do canvas é o que o Matt está
   olhando, e assim o aviso acompanha a cena mesmo com a página rolada.
   pointer-events:none — é só informação, nunca rouba o arraste em andamento. */
.po-proj-rotate-hud {
  position: absolute; left: 50%; bottom: 12px; transform: translateX(-50%);
  z-index: 40; pointer-events: none;
  padding: 6px 14px; border-radius: 999px;
  background: rgba(23,22,19,0.92); color: #fff;
  font-size: 13px; font-weight: 700; letter-spacing: 0.3px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.25);
  white-space: nowrap;
}
/* Encostou num múltiplo de 90° (o ímã pegou) — verde discreto de confirmação. */
.po-proj-rotate-hud.snapped { background: rgba(28,110,64,0.94); }

/* Ações do módulo selecionado — flutuam SOBRE o canvas 3D, posicionadas em px
   por refreshProjectSlotActions (portal.js). position:fixed porque a conta vem
   de worldToClient, que devolve coordenada de viewport (client), não relativa
   ao container — assim não depende de nenhum offsetParent nem de o wrap ter
   position:relative. Alvo grande (34px) pra acertar com o dedo no iPad. */
.po-proj-slot-actions {
  /* BARRA ÚNICA ABAIXO DO MÓDULO (2026-08-13, ajustada à referência do Matt).
     Ele comparou a minha com a dele: a dele é MENOR, mais AFASTADA do móvel e
     menos arredondada — e fica mais elegante justamente por isso. Três ajustes,
     nessa ordem de impacto:
       · raio 12→8px: canto quase reto pesa menos que pílula;
       · botão 34→29px e ícone menor: a barra encolhe ~20% no total;
       · afastamento 8→24px: colada, ela lê como parte do móvel; afastada, lê
         como ferramenta DELE — e para de disputar com a linha da base. */
  position: fixed; z-index: 60; display: flex; align-items: center; gap: 0;
  transform: translate(-50%, 24px); pointer-events: auto;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 8px; padding: 2px;
  box-shadow: 0 4px 14px rgba(0,0,0,0.13);
}
/* BOLINHAS (2026-08-08, pedido do usuário: "troca os quadrados de duplicar e
   excluir por bolinhas, fica uma area menor"). O círculo ocupa ~78% da área de
   um quadrado do mesmo lado, e o diâmetro caiu de 34 pra 28px — no total,
   pouco menos da metade do que tapava o móvel antes. 28px continua acima do
   mínimo confortável de alvo de toque porque as duas bolinhas ficam FORA do
   contorno do módulo (canto superior direito), sem vizinho pra confundir. */
.po-proj-slot-action-btn {
  width: 28px; height: 28px; padding: 0; margin: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1; font-weight: 700;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border); border-radius: 50%;
  box-shadow: 0 3px 10px rgba(0,0,0,0.22);
}
.po-proj-slot-action-btn:hover { background: var(--accent-light); }
.po-proj-slot-action-danger { color: #b0503c; }
.po-proj-slot-action-danger:hover { background: #f7e4e0; }

/* Card da biblioteca sendo ARRASTADO pra dentro da cena (ver
   attachProjectLibraryDragToScene em portal.js) — o card original fica
   apagado e um "fantasma" preso ao dedo/cursor é criado em JS. */
/* SELEÇÃO DE TEXTO no arraste (2026-08-08, relato do usuário no iPad: "ao
   arrastar o modulo ele seleciona tudo que esta atras, fica azul"). Não era
   bug de 3D nenhum: é a seleção NATIVA do navegador. Um arraste longo com o
   dedo/mouse por cima de uma tela cheia de texto (nomes dos módulos, painel de
   config, biblioteca) faz o iOS/Safari começar a selecionar tudo no caminho e
   pintar de azul. Como NENHUM texto da aba Projetos é pra ser selecionado com
   o dedo, a aba inteira desliga seleção e o menu de "copiar/definir" do toque
   longo do iOS (-webkit-touch-callout). Campos de digitação são reabertos
   logo abaixo — sem isso, digitar uma medida no painel ficaria impossível. */
#po-tab-projects {
  -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none;
  -webkit-touch-callout: none;
}
#po-tab-projects input,
#po-tab-projects textarea,
#po-tab-projects select {
  -webkit-user-select: text; -moz-user-select: text; -ms-user-select: text; user-select: text;
}

/* pan-y: o navegador continua rolando a lista na vertical sozinho; o
   movimento HORIZONTAL chega até o JS e vira o arraste do módulo pra dentro
   da cena (ver attachProjectLibraryCardDrag). */
.po-proj-library-card { touch-action: pan-y; }
.po-proj-library-card.dragging-to-scene { opacity: 0.35; }
.po-proj-drag-ghost {
  position: fixed; z-index: 4000; pointer-events: none;
  width: 132px; padding: 6px 8px;
  background: var(--panel); border: 2px solid var(--text); border-radius: 10px;
  box-shadow: 0 12px 28px rgba(0,0,0,0.28);
  font-size: 11px; font-weight: 600; color: var(--text);
  text-align: center; transform: translate(-50%, -50%);
}
.po-proj-drag-ghost img { width: 100%; height: 64px; object-fit: contain; display: block; margin-bottom: 4px; }
/* Realce do canvas 3D enquanto um módulo está sendo arrastado por cima dele. */
#po-proj-canvas-3d-edit-wrap.drop-target,
.po-proj-canvas.drop-target { outline: 2px dashed var(--text); outline-offset: -4px; }
/* Pedido do usuário (3ª rodada): "tem muita borda lá em cima só com umas
   coisas escritas que ninguém vai ler" — bem discreto, quase um detalhe. */
.po-proj-canvas-scale-label {
  font-size: 9px; color: var(--muted); opacity: 0.6; margin-bottom: 1px; text-align: center;
}
.po-proj-canvas-wrap {
  border: 1px solid var(--border); border-radius: 10px; background: #f4f1ea;
  overflow: auto; display: flex; justify-content: center;
}
.po-proj-canvas {
  position: relative; background: #f8f6f1;
  background-image: linear-gradient(#e9e4d8 1px, transparent 1px), linear-gradient(90deg, #e9e4d8 1px, transparent 1px);
  background-size: 40px 40px;
  flex: none; /* largura/altura setadas via JS em px, escala real da parede */
  overflow: hidden; /* trava o traçado fantasma (.po-proj-ghost-slot) dentro do canvas */
}
.po-proj-canvas-baseboard {
  position: absolute; left: 0; right: 0; bottom: 0;
  background: #fff;
  border-top: 1px solid #a89f8a;
  pointer-events: none;
}
.po-proj-canvas-ceiling-line {
  position: absolute; left: 0; right: 0; top: 0;
  border-top: 2px dashed var(--muted);
  pointer-events: none;
}
.po-proj-empty-hint { margin-top: 6px; text-align: center; }

/* Vista de cima (pedido do usuário 2026-07-24) — parede desenhada como uma
   linha grossa no TOPO do canvas (y=0), profundidade cresce pra baixo. Só
   leitura: sem cursor de arraste, borda tracejada pra deixar claro que é uma
   aproximação (a profundidade real vem de z_order + depth_mm, ver
   computeProjectSlotsTopViewLayout em portal.js), não uma posição travada. */
.po-proj-canvas-top-wall-line {
  position: absolute; left: 0; right: 0; top: 0; height: 4px;
  background: #a89f8a; pointer-events: none; z-index: 5;
}
/* Paredes de retorno (forma dupla/C-U, pedido do usuário 2026-07-25) — linha
   vertical em cada ponta da parede principal, mesmo estilo/espessura da
   horizontal acima, só girada 90°. Altura setada via JS (renderProjectCanvasTop,
   proporcional à largura de verdade daquela parede lateral). */
.po-proj-canvas-top-wall-line-side {
  position: absolute; top: 0; width: 4px;
  background: #a89f8a; pointer-events: none; z-index: 5;
}
.po-proj-canvas-top-wall-line-left { left: 0; }
.po-proj-canvas-top-wall-line-right { right: 0; }
/* PLANTA BAIXA DE VERDADE (2026-08-18) — uma linha por parede DESENHADA, na
   posicao e no angulo dela (ver computeProjectTopViewPlan/renderProjectCanvasTop
   em portal.js). Substitui .po-proj-canvas-top-wall-line + as duas -side, que
   so sabiam desenhar "topo do canvas" e "cada ponta", geometria das 3 formas
   fixas de ambiente ja aposentadas. transform-origin no canto esquerdo: o JS
   posiciona a PONTA da parede e gira em torno dela; a espessura de 4px cresce
   pro lado de DENTRO do ambiente, que e o sentido de intoDir. */
.po-proj-canvas-top-wall-seg {
  position: absolute; height: 4px; background: #a89f8a;
  transform-origin: 0 0; z-index: 5; cursor: pointer;
}
.po-proj-canvas-top-wall-seg.active { background: var(--text); }
.po-proj-slot-top {
  cursor: pointer; border-style: dashed;
  /* Parede em angulo gira o modulo junto (transform inline no JS) — o giro
     tem que ser em torno do canto que o JS posicionou, nao do centro. */
  transform-origin: 0 0;
}
.po-proj-slot-top:active { cursor: pointer; }
#po-proj-top-view-hint { margin-top: 6px; text-align: center; }

/* ---------- Rodapé do canvas: empty state + resumo (2026-08-08, etapa 3) ----------
   Dois cartões lado a lado logo abaixo do desenho, como no mockup. O empty
   state some quando existe módulo (display:none via JS) e aí o resumo, sendo
   o único filho com flex, ocupa a linha inteira sozinho — sem precisar de
   nenhuma regra condicional. */
.po-proj-bottom {
  display: flex; gap: 12px; align-items: stretch; flex-wrap: wrap;
  margin-top: 10px;
}
.po-proj-empty-card {
  flex: 1 1 260px; min-width: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; padding: 22px 16px; text-align: center;
  border: 1px dashed var(--border); border-radius: 12px; background: var(--panel);
}
.po-proj-empty-icon { font-size: 26px; color: var(--muted); opacity: 0.7; line-height: 1; }
.po-proj-empty-title { margin: 4px 0 0; font-size: 13px; font-weight: 600; color: var(--text); }
.po-proj-empty-or { font-size: 11px; color: var(--muted); }
.po-proj-empty-hint-line { font-size: 12px; color: var(--muted); }

.po-proj-summary {
  flex: 1 1 260px; min-width: 0;
  padding: 14px 16px;
  border: 1px solid var(--border); border-radius: 12px; background: var(--panel);
}
.po-proj-summary-title {
  font-size: 13px; font-weight: 700; color: var(--text); margin-bottom: 8px;
}
.po-proj-summary-row {
  display: flex; justify-content: space-between; gap: 12px;
  font-size: 12px; color: var(--muted); padding: 3px 0;
}
.po-proj-summary-row span:last-child { color: var(--text); font-weight: 600; }
.po-proj-summary-total {
  display: flex; justify-content: space-between; gap: 12px; align-items: baseline;
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border);
  font-size: 13px; font-weight: 700; color: var(--text);
}
.po-proj-summary-total span:last-child { font-size: 17px; }
.po-proj-summary-cta {
  width: 100%; margin: 10px 0 0; padding: 8px 12px;
  font-size: 12px; font-weight: 600;
  background: var(--accent-light); color: var(--text);
  border: 1px solid var(--border); border-radius: 8px;
}
.po-proj-summary-cta:hover { background: var(--border); }
.po-proj-summary-details { margin-top: 8px; max-height: 220px; overflow-y: auto; }
.po-proj-summary-detail-row {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
  padding: 6px 4px; border-top: 1px solid var(--border); cursor: pointer;
}
.po-proj-summary-detail-row:hover { background: var(--accent-light); }
.po-proj-summary-detail-name { font-size: 12px; font-weight: 600; color: var(--text); }
.po-proj-summary-detail-price { font-size: 12px; font-weight: 600; color: var(--text); text-align: right; }
.po-proj-summary-detail-meta { font-size: 11px; color: var(--muted); grid-column: 1 / -1; }

/* Mini Vista Superior fixa ao lado da Frontal (pedido do usuário,
   2026-07-26) — reaproveita a mesma geometria de computeProjectWallTopViewPlacements,
   só desenhada bem menor e com escala LOCAL própria (renderProjectMiniTopView
   em portal.js não mexe na variável global projectPxPerMm, que a Frontal
   grande usa pro cálculo de arrastar/esticar — ver comentário lá). */
.po-proj-canvas-row { display: flex; gap: 14px; align-items: flex-start; }
.po-proj-canvas-row .po-proj-canvas-wrap { flex: 1 1 auto; min-width: 0; }
.po-proj-mini-top-wrap {
  flex: none; width: 190px; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--panel); padding: 8px;
}
.po-proj-mini-top-title {
  font-size: 11px; font-weight: 600; color: var(--muted);
  text-align: center; margin-bottom: 6px;
}
.po-proj-mini-top-canvas-wrap {
  display: flex; justify-content: center; overflow: auto; max-height: 280px;
}
.po-proj-mini-top-canvas {
  position: relative; background: #f8f6f1; flex: none;
}
.po-proj-mini-top-hint {
  font-size: 9px; color: var(--muted); opacity: 0.7;
  text-align: center; margin: 6px 0 0;
}
/* Faixa clicável por parede (atrás dos módulos) — destaca qual trecho da
   planta corresponde à parede ATIVA na Frontal ao lado, e clicar em
   qualquer parede troca a ativa (mesma função das abas em cima do canvas,
   setProjectActiveWallIndex). */
.po-proj-mini-wall-zone {
  position: absolute; cursor: pointer; z-index: 2; transition: background 0.15s;
}
.po-proj-mini-wall-zone:hover { background: rgba(0,0,0,0.06); }
.po-proj-mini-wall-zone.active { background: var(--accent-light); }
.po-proj-mini-slot {
  position: absolute; box-sizing: border-box; z-index: 6; cursor: pointer;
  border: 1px solid rgba(0,0,0,0.28); border-radius: 2px;
}
.po-proj-mini-slot.selected { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }

/* Traçado fantasma dos módulos da parede VIZINHA perto da esquina, dentro do
   canvas da Frontal (pedido do usuário 2026-07-26, ver renderProjectCanvasFront
   em portal.js) — hachurado tracejado pra ficar claramente diferente dos
   módulos de VERDADE desta parede (.po-proj-slot), z-index baixo pra ficar
   atrás de qualquer módulo real que esteja no mesmo lugar. Clicável (troca
   de parede + seleciona), mas não arrastável/redimensionável — pertence a
   outro plano/parede. */
.po-proj-ghost-slot {
  position: absolute; box-sizing: border-box; z-index: 2;
  border: 1px dashed var(--muted);
  background: repeating-linear-gradient(45deg, rgba(0,0,0,0.05), rgba(0,0,0,0.05) 4px, rgba(0,0,0,0.1) 4px, rgba(0,0,0,0.1) 8px);
  cursor: pointer;
}
.po-proj-ghost-slot:hover { border-color: var(--accent); }

/* Vista de Canto 3D interativa (paredes L/C-U — pedido do usuário
   2026-07-26). 1ª versão usava uma "dobra" de CSS 3D (perspective+rotateY)
   que saiu QUEBRADA (parede vizinha virava uma fatia torta) — descartada
   por completo, substituída por uma cena Three.js de verdade (ver
   renderProjectCanvasFrontCorner/ViewerProjectEdit em portal.js,
   #po-proj-canvas-3d-edit-wrap em portal.html). Módulo de parede vizinha
   dobrada (buildProjectWallPaneDom, interactive=false) continua clicável
   sem cursor de arraste — usado só pela vista Frontal de 1 parede agora
   (nunca mais numa parede "dobrada" de verdade). */
.po-proj-slot-readonly { cursor: pointer; }
.po-proj-slot-readonly:active { cursor: pointer; }

#po-proj-canvas-3d-edit-wrap { width: 100%; }
#po-proj-canvas-3d-edit {
  width: 100%;
  /* mesma razão do #po-proj-3d-canvas: altura de tela, não fixa (2026-08-03).
     2026-08-06 (iPad Air 13"): 74vh -> 88vh. Num tablet em paisagem a página
     inteira cabe numa tela só, então sobra altura; o teto de 950px é que
     estava segurando, subiu junto. O ganho maior vem das colunas recolhíveis
     (largura), este é o complemento vertical.
     2026-08-12: teto 1200 -> 1600px, junto com a tela cheia da aba (ver
     .proj-fullbleed) — em 1440p/4K o teto é que segurava, não o 88vh. */
  height: clamp(520px, 88vh, 1600px);
  border: none;
  overflow: hidden;
  background: #ffffff;
  touch-action: none;
}
#po-proj-canvas-3d-edit canvas { display: block; width: 100%; height: 100%; cursor: grab; }

/* Setas de esticar a parede (pedido do usuário, 2026-07-21: "uma setinha na
   parede pra esticar ela pro lado direito e esquerdo") — mesma ideia dos
   handles de redimensionar as colunas, só que arrastando muda
   projectWallWidthMm em vez da largura de uma coluna. Fica colado na borda
   interna do canvas (não negativo — ia poder ser cortado pelo overflow:auto
   do wrap) e sempre no meio da altura, acima de tudo (z-index alto). */
/* Pedido do usuário (4ª rodada): "quando coloco o mouse aparecem 2 setas e
   confunde, pode deletar o círculo e deixar só a seta que aparece quando
   chego perto... assim como no módulo" — mesmo padrão discreto das setinhas
   de módulo (.po-proj-slot-resize): tira fina, invisível até passar perto,
   sem círculo nem glifo de seta permanente. */
.po-proj-wall-resize-handle {
  position: absolute; top: 0; bottom: 0; width: 10px;
  cursor: ew-resize; z-index: 500; user-select: none;
}
.po-proj-wall-resize-handle:hover, .po-proj-wall-resize-handle.dragging {
  background: rgba(0,0,0,0.16);
}
.po-proj-wall-resize-left { left: 0; }
.po-proj-wall-resize-right { right: 0; }

.po-proj-slot {
  position: absolute; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: 4px;
  background: #e4d9c8; display: flex; flex-direction: column;
  align-items: center; justify-content: center; text-align: center;
  overflow: hidden; cursor: grab; user-select: none;
  transition: box-shadow 0.15s, border-color 0.15s;
  font-size: 11px; line-height: 1.2; padding: 2px;
}
.po-proj-slot:active { cursor: grabbing; }
.po-proj-slot.dragging { box-shadow: 0 6px 18px rgba(0,0,0,0.28); z-index: 999 !important; opacity: 0.92; }
.po-proj-slot.selected { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent) inset; }
/* Vista frontal 2D real (pedido do usuário: "não me serve esse bloco
   cinza... quero ver com as cores escolhidas e os componentes") — peças de
   verdade (ver projectSlotElevationHtml/portal.js) desenhadas por cima do
   preenchimento sólido de fundo, com o nome/medidas flutuando por cima de
   tudo num "selo" legível. */
.po-proj-slot-elevation { position: absolute; inset: 0; z-index: 1; }
.po-proj-slot-piece { position: absolute; box-sizing: border-box; border: 1px solid rgba(0,0,0,0.16); }
.po-proj-slot-label {
  position: relative; z-index: 2; background: rgba(255,255,255,0.82);
  border-radius: 4px; padding: 2px 5px; pointer-events: none;
}
.po-proj-slot-name { font-weight: 600; }
.po-proj-slot-dims { color: var(--muted); }

/* Setinhas de esticar cada módulo (pedido do usuário: "sem círculo", mesma
   ideia das setas da parede mas discretas — tiras finas nas bordas,
   escurecem no hover/arraste em vez de um botão chamativo). */
.po-proj-slot-resize { position: absolute; z-index: 30; }
.po-proj-slot-resize-left, .po-proj-slot-resize-right {
  top: 0; bottom: 0; width: 7px; cursor: ew-resize;
}
.po-proj-slot-resize-left { left: 0; }
.po-proj-slot-resize-right { right: 0; }
.po-proj-slot-resize-top { left: 0; right: 0; top: 0; height: 7px; cursor: ns-resize; }
.po-proj-slot-resize:hover, .po-proj-slot-resize.dragging { background: rgba(0,0,0,0.16); }

/* ---- Setas visíveis no módulo SELECIONADO (2026-08-06) ----
   No iPad não existe :hover, então as setinhas eram literalmente invisíveis:
   "não consigo esticar o móvel, não tem a seta, nenhum controle sobre isso".
   Agora o módulo selecionado mostra as setas o tempo todo — e continua
   selecionado depois de tirar o dedo, que foi o pedido explícito. No mouse
   nada muda enquanto nada estiver selecionado (o :hover discreto de sempre). */
.po-proj-slot.selected .po-proj-slot-resize {
  background: var(--accent);
  opacity: 0.55;
}
.po-proj-slot.selected .po-proj-slot-resize:hover,
.po-proj-slot.selected .po-proj-slot-resize.dragging { opacity: 1; }

/* Alvo de dedo: 7px é mira de mouse. Em tela de toque as setas ficam bem
   mais largas (a área clicável, não o visual — o retângulo colorido cobre a
   faixa inteira mesmo). Só em ponteiro grosso, pra não engordar no desktop. */
@media (pointer: coarse) {
  .po-proj-slot-resize-left, .po-proj-slot-resize-right { width: 18px; }
  .po-proj-slot-resize-top { height: 18px; }
}

/* ---- Janela de propriedades do módulo (segurar o clique) ---- */
/* Criador de armário embutido (2026-08-12) — quase tela cheia: a tela do
   construtor tem três colunas (árvore, desenho, propriedades) e não cabe num
   card estreito. O iframe carrega o ERP na MESMA origem. */
#po-proj-builder-modal {
  display: none; position: fixed; inset: 0; z-index: 3300;
  align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55); padding: 12px;
}
#po-proj-builder-modal.open { display: flex; }
/* Janela MENOR (pedido do Matt: "ao clicar quero uma tela menor com as
   configuracoes e salvar volta configurado pro projetos. simples") — não é
   tela cheia: dá pra ver o ambiente por trás e entender que aquilo é uma
   janela sobre o projeto, não outra página. Ainda assim larga o bastante pras
   três colunas do criador (árvore, desenho, propriedades). */
.po-proj-builder-card {
  background: var(--panel); border-radius: 12px;
  width: 1100px; max-width: 96vw;
  height: 720px; max-height: 88vh;
  display: flex; flex-direction: column; overflow: hidden;
  position: relative; box-shadow: 0 20px 60px rgba(0,0,0,0.4);
}
.po-proj-builder-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--border); flex: none;
}
.po-proj-builder-header .po-auth-modal-close { position: static; }

/* Duas colunas: o vão desenhado (grande) e as peças (estreita). Sem formulário
   nenhum — ver o comentário no portal.html. */
.po-proj-builder-body { flex: 1; display: flex; min-height: 0; }
/* display:block (e não flex): o palco é UM svg que ocupa tudo e se centraliza
   sozinho pelo preserveAspectRatio="xMidYMid meet". Com flex + align-items
   center o svg perderia a altura (item flex de altura automática) e o desenho
   viraria uma faixa. */
.po-proj-builder-stage {
  flex: 1; min-width: 0; position: relative;
  background: #faf9f6; display: block;
  padding: 18px; overflow: hidden;
}
/* ==========================================================================
   PAINEL DE COMPONENTES (coluna direita do construtor) — 2026-08-16
   ==========================================================================
   Redesenho pedido pelo Matt ("na parte direita da pra melhorar muito"), a
   partir de um mockup: cabeçalho com título e subtítulo, campo de busca,
   chips de filtro por grupo, GRID de 2 colunas com o desenho da peça grande,
   e um rodapé com o contador e o "Limpar módulo".

   A coluna virou um LAYOUT DE TRÊS FAIXAS (head / grid rolável / foot). Isso
   é o que permite a busca e os chips ficarem SEMPRE visíveis enquanto a lista
   rola — antes a coluna inteira era um único bloco com overflow-y.
   O grid é 2 colunas porque o desenho da peça é o que identifica o
   componente (ver .po-proj-builder-item-icon svg): numa lista de uma coluna
   o ícone precisaria ser pequeno de novo, que é justamente o problema que o
   card em grade resolve. */
.po-proj-builder-lib {
  flex: 0 0 300px; border-left: 1px solid var(--border);
  padding: 0; overflow: hidden;
  display: flex; flex-direction: column; min-height: 0;
  background: var(--panel);
}

/* ---- Faixa 1: cabeçalho fixo (título, busca, filtros) ---- */
.po-proj-lib-head { flex: none; padding: 14px 14px 10px; }
.po-proj-lib-title { font-size: 16px; font-weight: 700; color: var(--text); line-height: 1.2; }
.po-proj-lib-sub { font-size: 11.5px; color: var(--muted); margin-top: 3px; }

.po-proj-lib-search { position: relative; margin-top: 12px; }
.po-proj-lib-search input {
  width: 100%; box-sizing: border-box;
  border: 1px solid var(--border); border-radius: 10px;
  background: #fff; padding: 9px 32px 9px 12px;
  font-size: 12.5px; color: var(--text); font-family: inherit;
}
.po-proj-lib-search input:focus { outline: none; border-color: var(--accent); }
.po-proj-lib-search svg {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  width: 14px; height: 14px; color: var(--muted); pointer-events: none;
}

/* Chips de filtro: "Todos" + um por GRUPO do catálogo (não é lista fixa — o
   grupo vem do cadastro, então a barra acompanha o que a fábrica cadastrar). */
.po-proj-lib-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.po-proj-lib-chip {
  border: 1px solid var(--border); background: #fff; border-radius: 999px;
  padding: 4px 10px; font-size: 10.5px; font-weight: 600; color: var(--muted);
  cursor: pointer; white-space: nowrap; font-family: inherit; line-height: 1.25;
}
.po-proj-lib-chip:hover { border-color: var(--accent); color: var(--accent); }
.po-proj-lib-chip.active {
  background: var(--text); border-color: var(--text); color: #fff;
}

/* ---- Faixa 2: o grid rolável ---- */
.po-proj-lib-grid {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 4px 14px 14px;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px; align-content: start;
}
.po-proj-lib-grid::-webkit-scrollbar { width: 8px; }
.po-proj-lib-grid::-webkit-scrollbar-thumb { background: var(--border); border-radius: 4px; }

/* Título de grupo: ocupa a linha inteira do grid. */
.po-proj-builder-group {
  grid-column: 1 / -1;
  font-size: 10px; letter-spacing: 1px; text-transform: uppercase;
  color: var(--muted); margin-top: 4px;
}
.po-proj-lib-empty {
  grid-column: 1 / -1; text-align: center;
  font-size: 12px; color: var(--muted); padding: 20px 6px; line-height: 1.5;
}

/* ---- O card da peça ---- */
/* Vertical e centralizado: desenho grande em cima, nome embaixo, ação por
   último. O card INTEIRO continua sendo o alvo do clique (bom pro dedo no
   iPad) — o ⊕ é só a afordância visual de "isto entra no vão". */
.po-proj-builder-item {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  border: 1px solid var(--border); border-radius: 12px;
  padding: 12px 8px 10px; background: #fff; cursor: grab;
  font-size: 11.5px; font-weight: 600; color: var(--text);
  text-align: center; user-select: none; touch-action: none;
  transition: border-color .12s, box-shadow .12s, transform .12s;
}
.po-proj-builder-item:hover {
  border-color: var(--accent); background: #fff;
  box-shadow: 0 4px 14px rgba(0,0,0,0.07); transform: translateY(-1px);
}
.po-proj-builder-item.dragging { opacity: 0.5; }
/* Nome em até 2 linhas — "Prateleira fixa" não cabe numa linha de 130px. */
.po-proj-builder-item-name {
  line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; word-break: break-word;
}
/* O SVG herda a cor do card (currentColor), inclusive no hover. */
.po-proj-builder-item-icon { flex: none; line-height: 0; color: var(--muted); }
/* 56px, era 34 (2026-08-16). O card em grade tem espaço vertical de sobra e o
   desenho é o que faz reconhecer a peça sem ler o nome. */
/* stroke-width no CSS vence o atributo do <svg> (que é 1.4 num viewBox de 22).
   Em 56px aquele 1.4 vira um traço de ~3.6px — o desenho fica pesado e as
   linhas internas quase se encostam. 0.9 dá ~2.3px, a mesma leveza que o
   ícone tinha em 34px. */
.po-proj-builder-item-icon svg { width: 50px; height: 50px; display: block; stroke-width: 0.95; }
.po-proj-builder-item:hover .po-proj-builder-item-icon { color: var(--accent); }

/* ⊕ das peças SEM quantidade. Quem aceita quantidade mostra o stepper no
   lugar dele (ver .po-proj-builder-qty) — dois controles no mesmo card
   confundiriam qual deles insere. */
.po-proj-lib-add {
  width: 26px; height: 26px; border-radius: 50%;
  border: 1.5px solid var(--accent); background: #fff; color: var(--accent);
  font-size: 15px; line-height: 1; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: inherit;
}
.po-proj-builder-item:hover .po-proj-lib-add { background: var(--accent); color: #fff; }

/* Quantidade: caixa compacta com setas (2026-08-15). Substituiu a fileira de
   botões numerados — com o limite em 10 ela não cabia mais na coluna.
   Clicar no card insere naquela quantidade; as setas ajustam ao vivo. */
.po-proj-builder-qty {
  display: inline-flex; align-items: center; align-self: center;
  border: 1px solid var(--border); border-radius: 999px; overflow: hidden;
  background: #fff;
}
.po-proj-qty-step {
  border: none; background: transparent; cursor: pointer;
  width: 22px; height: 22px; line-height: 1; font-size: 13px;
  color: var(--muted); padding: 0; font-family: inherit;
}
.po-proj-qty-step:hover { background: var(--accent-light); color: var(--accent); }
.po-proj-qty-val {
  min-width: 20px; text-align: center; font-size: 11.5px; font-weight: 700;
  border-left: 1px solid var(--border); border-right: 1px solid var(--border);
  line-height: 22px;
}
.po-proj-qty-btn {
  flex: 1; border: 1px solid var(--border); background: #fff; border-radius: 6px;
  padding: 3px 0; font-size: 11px; font-weight: 700; color: var(--muted);
  cursor: pointer; line-height: 1.2;
}
.po-proj-qty-btn:hover { border-color: var(--accent); background: var(--accent); color: #fff; }

/* ---- Faixa 3: rodapé (contador + limpar) ---- */
.po-proj-lib-foot {
  flex: none; border-top: 1px solid var(--border);
  padding: 9px 14px; display: flex; align-items: center;
  justify-content: space-between; gap: 8px;
  font-size: 11px; color: var(--muted); background: var(--panel);
}
.po-proj-lib-count { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Mesma ação do ↺ do cabeçalho (resetProjectBuilder) — aqui com nome, porque
   no rodapé sobra largura e "recomeçar do zero" é destrutivo o bastante pra
   não merecer só um ícone. */
.po-proj-lib-clear {
  flex: none; border: 1px solid var(--border); background: #fff;
  border-radius: 8px; padding: 6px 10px; font-size: 11px; font-weight: 600;
  color: var(--text); cursor: pointer; font-family: inherit;
  display: inline-flex; align-items: center; gap: 5px; line-height: 1;
}
.po-proj-lib-clear svg { width: 12px; height: 12px; }
.po-proj-lib-clear:hover { border-color: #d8442f; color: #d8442f; }
/* Barra do cabeçalho: desfazer e recomeçar. Só ícone — a tela inteira é
   "sem texto" por pedido do Matt. */
.po-proj-builder-tools { display: flex; align-items: center; gap: 6px; }
.po-proj-builder-tool {
  border: 1px solid var(--border); background: #fff; border-radius: 8px;
  width: 30px; height: 30px; font-size: 15px; line-height: 1;
  color: var(--text); cursor: pointer;
}
.po-proj-builder-tool:hover { border-color: var(--accent); background: var(--accent-light); }
.po-proj-builder-save {
  border: none; background: var(--accent); color: #fff;
  border-radius: 8px; padding: 7px 16px; font-size: 12px; font-weight: 700;
  cursor: pointer;
}
.po-proj-builder-save:hover { filter: brightness(0.94); }
.po-proj-builder-status { font-size: 11px; color: var(--muted); margin-right: 4px; }

/* O palco é um SVG em MILÍMETROS que ocupa o espaço todo (ver
   renderProjectBuilderStage). */
.po-proj-builder-svg { width: 100%; height: 100%; display: block; }

/* Vão desenhado: retângulo clicável. O selecionado ganha a borda de destaque
   e é onde a próxima peça entra. */
.po-proj-void { fill: #fff; fill-opacity: 0.35; stroke: #c9c2b4; stroke-width: 1; cursor: pointer; }
.po-proj-void:hover { fill: var(--accent-light); fill-opacity: 0.8; }
.po-proj-void.selected { fill: #f2f0ea; fill-opacity: 0.9; }
.po-proj-void.drop-target { stroke: #d8442f; stroke-width: 3; fill: #fdeeea; fill-opacity: 0.9; }
/* Peça gerada pela árvore: clicar tira. */
.po-proj-void-item { cursor: pointer; }
.po-proj-void-item:hover { fill: #d8442f; stroke: #a8231d; }
/* Pegador da divisória: arrastar move, clicar tira. */
.po-proj-div-h { cursor: ew-resize; touch-action: none; }
.po-proj-div-v { cursor: ns-resize; touch-action: none; }
.po-proj-builder-empty {
  position: absolute; bottom: 10px; left: 0; right: 0; text-align: center;
  font-size: 11px; color: var(--muted); pointer-events: none;
}

#po-proj-props-modal {
  display: none; position: fixed; inset: 0; z-index: 3200;
  align-items: center; justify-content: center;
  background: rgba(0,0,0,0.5); padding: 16px;
}
#po-proj-props-modal.open { display: flex; }
.po-proj-props-card {
  background: var(--panel); border-radius: 12px;
  width: 420px; max-width: 100%; max-height: 88vh;
  display: flex; flex-direction: column;
  position: relative; box-shadow: 0 20px 60px rgba(0,0,0,0.35);
}
.po-proj-props-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 14px 16px; border-bottom: 1px solid var(--border);
  flex: none;
}
.po-proj-props-header .po-auth-modal-close { position: static; }
/* Só o corpo rola: o nome do módulo fica sempre visível, senão a pessoa
   perde a referência do que está editando ao descer até as prateleiras. */
#po-proj-props-body { padding: 14px 16px; overflow-y: auto; flex: 1 1 auto; min-height: 0; }
/* Dentro da janela o painel não precisa da moldura dele — o card já é a
   moldura. Sem isso ficam duas bordas encaixadas. */
#po-proj-props-body .po-proj-config-panel {
  border: none; padding: 0; background: transparent; max-height: none;
}
/* Profundidade (z_order) — cada "camada" mais pra frente (mais longe da
   parede) ganha uma sombra levemente mais forte, pra dar noção visual de
   frente/fundo mesmo numa vista frontal 2D sem eixo Z desenhado de verdade. */
.po-proj-slot[data-z-order="1"] { box-shadow: 2px 2px 5px rgba(0,0,0,0.18); }
.po-proj-slot[data-z-order="2"] { box-shadow: 3px 3px 7px rgba(0,0,0,0.24); }
.po-proj-slot[data-z-order="3"] { box-shadow: 4px 4px 9px rgba(0,0,0,0.3); }

/* Guias de imã (snap) — linha fina que aparece só durante o arraste, quando
   a borda do módulo alinha com a de outro módulo/parede (ver snapProjectSlotPosition
   em portal.js). */
.po-proj-snap-guide-v, .po-proj-snap-guide-h {
  position: absolute; background: var(--accent); pointer-events: none; z-index: 1000;
}
.po-proj-snap-guide-v { width: 1px; top: 0; bottom: 0; }
.po-proj-snap-guide-h { height: 1px; left: 0; right: 0; }

.po-proj-config-panel {
  border: 1px solid var(--border); border-radius: 10px; padding: 14px;
  background: var(--panel); min-height: 160px;
}
.po-proj-config-panel h3 { margin: 0 0 8px; font-size: 15px; }
.po-proj-config-row { display: flex; justify-content: space-between; gap: 8px; font-size: 13px; margin-bottom: 6px; }
.po-proj-config-row span:first-child { color: var(--muted); }
.po-proj-config-panel .secondary, .po-proj-config-panel .po-btn-primary-block { margin-top: 10px; width: 100%; }
.po-proj-config-remove-btn { color: #b3261e; border-color: #e3b3ae; }
.po-proj-config-remove-btn:hover { background: #fdeceb; }

/* ---------- Ajustes Fase 1.1 (feedback do usuário, 2026-07-21) ----------
   1) Filtros de categoria/subcategoria pequenos na biblioteca.
   2) Espaço vertical acima do canvas reduzido + escala do canvas agora leva
      a ALTURA disponível da tela em conta também (não só a largura), pra
      parede inteira caber sem rolar (ver renderProjectCanvas em portal.js).
   3) Clique no módulo da biblioteca insere direto (config padrão) — painel
      da direita virou editor de verdade (steppers de medida + cor), não só
      um resumo. */
.po-proj-library-filters { margin: 6px 0 4px; }
.po-proj-library-filter-select {
  width: 100%;
  font-size: 12px;
  padding: 5px 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: #fff;
  color: var(--text);
}
.po-proj-library-filter-select + .po-proj-library-filter-select { margin-top: 6px; }

#po-tab-projects .po-comp-title-row { margin-bottom: 2px; }
/* A CAIXA em volta da barra (2026-08-18). O padding de 10px em cima e embaixo
   (.po-proj-topbar) mais o alinhamento flex-end deixavam os icones altos e com
   uma faixa vazia embaixo. Metade do padding e alinhamento CENTRALIZADO: a
   caixa encolhe e o conteudo fica no meio dela de verdade. */
#po-tab-projects .po-proj-topbar { margin: 4px 0 8px; padding: 5px 12px; align-items: center; }
#po-tab-projects .po-comp-mode-banner { margin-bottom: 8px; padding: 6px 12px; }

/* Pedido do usuário (3ª rodada, 2026-07-21): sem botão +/-, e label colado
   no valor (nada de space-between empurrando o campo pra longe do rótulo). */
.po-proj-config-dims { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.po-proj-config-dim-row { display: flex; align-items: center; gap: 6px; }
.po-proj-config-dim-row label { font-size: 12px; color: var(--muted); min-width: 58px; }
.po-proj-dim-value-wrap { display: flex; align-items: center; gap: 3px; }
.po-proj-dim-input { width: 56px; padding: 3px 4px; font-size: 12px; text-align: right; }
.po-proj-dim-unit { font-size: 11px; color: var(--muted); min-width: 16px; }

.po-proj-config-section-label { display: block; font-size: 12px; color: var(--muted); margin: 10px 0 4px; }
.po-proj-color-role-group { margin-bottom: 8px; }
.po-proj-color-role-group label { display: block; font-size: 11px; color: var(--muted); margin-bottom: 3px; }
.po-proj-color-swatches { display: flex; flex-wrap: wrap; gap: 5px; }
.po-proj-color-swatch {
  width: 24px; height: 24px; border-radius: 5px; border: 2px solid transparent;
  overflow: hidden; cursor: pointer; box-shadow: 0 0 0 1px var(--border) inset;
}
.po-proj-color-swatch img, .po-proj-color-swatch span { display: block; width: 100%; height: 100%; object-fit: cover; }
.po-proj-color-swatch:hover { box-shadow: 0 0 0 1px var(--accent) inset; }
.po-proj-color-swatch.selected { border-color: var(--accent); }

/* Movimentação fina (2026-08-23, pedido do Matt com print do Promob de
   referência) — passo em mm/pol + setas que somam exatamente esse passo por
   clique (ver nudgeProjectWallSlot/nudgeProjectFloorSlot/
   nudgeProjectFloorSlotRotation em portal-06c-projetos-canvas-3d-acoes.js).
   Especificidade `.po-proj-config-panel .po-proj-move-btn` de propósito —
   precisa vencer `.po-proj-config-panel .secondary` (linha ~3324, que força
   width:100%/margin-top:10px em QUALQUER botão .secondary do painel) sem
   tocar naquela regra genérica, que outros botões do painel ainda usam. */
.po-proj-config-move { margin-bottom: 10px; }
.po-proj-move-step-row { display: flex; align-items: center; gap: 6px; margin-bottom: 6px; }
.po-proj-move-step-row label { font-size: 12px; color: var(--muted); min-width: 40px; }
.po-proj-move-step-row .po-proj-move-step-input { width: 56px; padding: 3px 4px; font-size: 12px; text-align: right; }
.po-proj-move-pad { display: flex; flex-direction: column; gap: 4px; }
.po-proj-move-axis-row { display: flex; align-items: center; gap: 6px; }
.po-proj-move-axis-label { font-size: 12px; color: var(--muted); min-width: 58px; flex: 1; }
.po-proj-config-panel .po-proj-move-btn {
  width: 30px; height: 26px; padding: 0; margin-top: 0; font-size: 13px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.po-proj-move-rotate-row { display: flex; align-items: center; gap: 6px; margin-top: 6px; }
.po-proj-move-rotate-row label { font-size: 12px; color: var(--muted); min-width: 40px; }
.po-proj-move-rotate-step-input { width: 40px; padding: 3px 4px; font-size: 12px; text-align: right; }

/* ---------- CTAs da aba Projetos: Visualizar 3D + Foto realista ----------
   (2026-08-03, pedido do usuário: "deixa os botoes mais atraentes, esta so
   um grande quadrado preto") — classes PRÓPRIAS, sem tocar na genérica
   po-btn-primary-block (usada em carrinho/pedido/galeria). Atenção: os
   :hover precisam redeclarar o gradiente porque a regra global
   `button:hover { background: var(--accent-dark) }` usa o shorthand
   `background` (zera background-image) e venceria por ordem/pseudo. */
.po-proj-cta-row { display: flex; gap: 10px; margin-top: 14px; }
.po-proj-cta {
  flex: 1;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 13px 16px;
  border: none; border-radius: 10px;
  font-weight: 700; font-size: 14px; color: #fff;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
.po-proj-cta:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2); filter: brightness(1.06); }
.po-proj-cta:active:not(:disabled) { transform: translateY(0); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15); }
.po-proj-cta:disabled { opacity: 0.45; cursor: default; box-shadow: none; }
.po-proj-cta-3d, .po-proj-cta-3d:hover { background: linear-gradient(135deg, var(--accent) 0%, var(--accent-dark) 100%); }
.po-proj-cta-3d::before { content: '🧊'; font-size: 17px; }
.po-proj-cta-photo, .po-proj-cta-photo:hover { background: linear-gradient(135deg, #2e6b4f 0%, #1d4a36 100%); }
.po-proj-cta-photo::before { content: '📸'; font-size: 17px; }
.po-proj-cta-badge {
  font-size: 10px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  background: rgba(255, 255, 255, 0.22);
  padding: 2px 7px; border-radius: 999px;
}
@media (max-width: 640px) { .po-proj-cta-row { flex-direction: column; } }

/* Moldura "área da foto realista" nos viewers 3D da aba Projetos
   (2026-08-03, pedido do usuário: "mostrar a area da foto realista no 3d")
   — a foto sai travada em 4:3 com a MESMA câmera/fov vertical do viewer,
   então o recorte real é: altura inteira, largura = altura×4/3, centrado.
   Puro CSS (aspect-ratio) — nenhum recálculo por JS em resize. Injetada por
   ensurePhotoFrameOverlay (portal.js) dentro do container de cada viewer. */
.po-photoframe {
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  transform: translateX(-50%);
  height: 100%;
  aspect-ratio: 4 / 3;
  max-width: 100%;
  border-left: 2px dashed rgba(0, 0, 0, 0.3);
  border-right: 2px dashed rgba(0, 0, 0, 0.3);
  pointer-events: none;
  z-index: 5;
}
.po-photoframe-label {
  position: absolute;
  top: 6px; left: 50%;
  transform: translateX(-50%);
  font-size: 10px;
  color: rgba(0, 0, 0, 0.45);
  background: rgba(255, 255, 255, 0.7);
  padding: 1px 8px;
  border-radius: 999px;
  white-space: nowrap;
}

/* ==========================================================================
   EDITOR DE PAREDES (planta baixa) — 2026-08-13
   ==========================================================================
   Ver js/wall-editor.js. A janela é criada em JS (não existe no portal.html)
   porque o editor é independente do projeto: ele recebe uma lista de
   segmentos e devolve outra. */
#po-wall-editor-modal {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(0,0,0,0.35); display: none;
  align-items: center; justify-content: center;
}
#po-wall-editor-modal.open { display: flex; }
.po-wall-card {
  background: var(--panel); border-radius: 14px; width: min(1100px, 94vw);
  height: min(760px, 92vh); display: flex; flex-direction: column;
  box-shadow: 0 18px 60px rgba(0,0,0,0.3); overflow: hidden;
}
.po-wall-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
}
.po-wall-tools { display: flex; gap: 6px; }
.po-wall-tool {
  border: 1px solid var(--border); background: #fff; border-radius: 8px;
  padding: 6px 10px; font-size: 12px; font-weight: 600; cursor: pointer; color: var(--text);
}
.po-wall-tool:hover { border-color: var(--accent); background: var(--accent-light); }
.po-wall-tool-danger { color: #b0503c; }
.po-wall-body { flex: 1; display: flex; min-height: 0; }
/* display:block e não flex: o SVG ocupa tudo e se centraliza sozinho pelo
   preserveAspectRatio (mesma armadilha do palco do construtor de armário). */
.po-wall-stage { flex: 1; min-width: 0; background: #faf9f6; display: block; padding: 14px; }
.po-wall-svg { width: 100%; height: 100%; display: block; }
.po-wall-seg { cursor: pointer; }
.po-wall-handle { cursor: grab; touch-action: none; }
.po-wall-side {
  width: 230px; flex: none; border-left: 1px solid var(--border);
  padding: 14px; display: flex; flex-direction: column; gap: 10px; overflow-y: auto;
}
.po-wall-side-title { font-size: 11px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.po-wall-side label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; font-weight: 600; color: var(--text); }
.po-wall-side input {
  border: 1px solid var(--border); border-radius: 8px; padding: 6px 8px; font-size: 13px;
}
.po-wall-un { color: var(--muted); font-weight: 400; }
.po-wall-hint { font-size: 11px; color: var(--muted); line-height: 1.5; margin: 0; }
.po-wall-footer {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 12px 16px; border-top: 1px solid var(--border);
}
.po-wall-ok {
  border: none; background: var(--accent); color: #fff; border-radius: 8px;
  padding: 8px 20px; font-size: 13px; font-weight: 700; cursor: pointer;
}

/* ==========================================================================
   MENU DE ESTILO DE EXIBIÇÃO (com ícone) — 2026-08-13
   ==========================================================================
   <select> nativo não aceita SVG dentro de <option>, e o pedido do Matt era
   justamente "um ícone bem bonitinho colorido na frente da escrita". Então é
   um menu próprio: botão + lista. Ver montaMenuEstilo() em portal.js. */
.po-style-menu { position: relative; }
.po-style-btn, .po-style-item {
  display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--border); background: var(--panel); color: var(--text);
  border-radius: 8px; padding: 4px 8px; height: 30px;
  font-size: 11px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.po-style-btn { min-width: 190px; }
.po-style-btn:hover { border-color: var(--accent); }
.po-style-caret { margin-left: auto; font-style: normal; color: var(--muted); }
.po-style-list {
  display: none; position: absolute; top: calc(100% + 4px); left: 0; z-index: 80;
  background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.18); padding: 4px; min-width: 240px;
}
.po-style-menu.aberto .po-style-list { display: block; }
.po-style-item {
  width: 100%; border: none; background: transparent; height: 32px; border-radius: 6px;
}
.po-style-item:hover { background: var(--accent-light); }
.po-style-item.ativo { background: var(--text); color: #fff; }

/* ==========================================================================
   BARRA DE FERRAMENTAS DA ABA PROJETOS — layout do mockup (2026-08-13)
   ==========================================================================
   Cartão branco arredondado com grupos ROTULADOS separados por filete, botão
   ativo em pílula preta e ícone sempre ao lado do texto. Substitui a fileira
   de botões só-ícone, que obrigava a decorar o que cada símbolo fazia. */
#po-proj-canvas-tools.po-proj-hud-tl {
  display: flex; align-items: stretch; gap: 0;
  background: var(--panel); border: 1px solid var(--border); border-radius: 16px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.06);
  padding: 8px 10px; margin-bottom: 8px;
}
.po-tb-group { display: flex; flex-direction: column; gap: 4px; padding: 0 10px; justify-content: flex-end; }
.po-tb-group-solo { justify-content: flex-end; align-items: center; }
.po-tb-label { font-size: 10px; color: var(--muted); letter-spacing: 0.02em; padding-left: 2px; }
.po-tb-sep { width: 1px; background: var(--border); margin: 4px 0; flex: none; }

/* Segmentado: fundo claro, item ativo em pílula preta. */
.po-tb-seg {
  display: flex; gap: 2px; background: #f6f4ef;
  border: 1px solid var(--border); border-radius: 12px; padding: 3px;
}
.po-tb-seg-btn {
  display: flex; align-items: center; gap: 6px;
  border: none; background: transparent; color: var(--text);
  border-radius: 9px; padding: 5px 11px; cursor: pointer;
  font-size: 12px; font-weight: 600; white-space: nowrap; line-height: 1;
}
/* Ícones menores (2026-08-13, pedido do Matt) — 15px lê igual e a barra
   inteira encolhe junto. */
.po-tb-seg-btn svg { width: 15px; height: 15px; flex: none; }
.po-tb-seg-btn:hover { background: rgba(0,0,0,0.05); }
.po-tb-seg-btn.active { background: var(--text); color: #fff; box-shadow: 0 2px 8px rgba(0,0,0,0.18); }
/* Ícone do item ativo em âmbar, como no mockup — é o detalhe que separa
   "selecionado" de "apenas escuro". */
.po-tb-seg-btn.active svg { color: #e0a44b; }

/* Cartão de ícone (Medidas, desfazer, encaixe). */
.po-tb-icon-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  position: relative;
  border: 1px solid var(--border); background: var(--panel); color: var(--text);
  border-radius: 12px; padding: 7px 10px; cursor: pointer;
  font-size: 11px; font-weight: 600; min-width: 52px;
}
.po-tb-icon-card svg { width: 18px; height: 18px; }
.po-tb-icon-card:hover { border-color: var(--accent); background: var(--accent-light); }
.po-tb-icon-card:disabled { opacity: 0.35; cursor: default; }
.po-tb-icon-card:disabled:hover { border-color: var(--border); background: var(--panel); }
.po-tb-icon-only { min-width: 46px; }
/* Pontinho de "ligado" no encaixe — mesma pista visual do mockup. */
.po-tb-dot { display: none; position: absolute; top: 6px; right: 6px; width: 7px; height: 7px; border-radius: 50%; background: #e6007e; }
#po-proj-collision-btn.active .po-tb-dot { display: block; }
#po-proj-collision-btn.active { border-color: var(--text); }

/* Menu de estilo dentro da barra: mesma altura e raio dos segmentados. */
#po-proj-style-menu .po-style-btn {
  height: 36px; border-radius: 12px; padding: 6px 10px; min-width: 210px;
  font-size: 12px; background: var(--panel);
}
#po-proj-style-menu .po-style-btn svg { flex: none; }

/* Par Render + Linhas no cabeçalho: colados, porque "Linhas" é um interruptor
   DO render, não uma ação irmã. Visual idêntico aos vizinhos (Send to order /
   New project), só sem o vão entre os dois. */
.po-proj-render-pair { display: inline-flex; gap: 0; }
.po-proj-render-pair > button:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.po-proj-render-pair > button:last-child { border-top-left-radius: 0; border-bottom-left-radius: 0; margin-left: -1px; }
.po-proj-render-linhas.active { background: var(--text); color: #fff; border-color: var(--text); }

/* Barra única (2026-08-13): as ações do projeto entraram na MESMA barra das
   ferramentas. Antes eram dois containers, um por linha — e bastava a janela
   estreitar pra eles aparecerem desalinhados, um em cima do outro.
   A barra rola na horizontal em tela apertada em vez de quebrar linha: manter
   tudo num eixo só é o que o Matt pediu. */
#po-proj-canvas-tools.po-proj-hud-tl {
  flex-wrap: nowrap; overflow-x: auto; overflow-y: visible;
  scrollbar-width: thin;
}
.po-tb-group { flex: none; }
/* Grupo de ações: sem a moldura do segmentado (são ações, não escolha entre
   opções) — só os botões alinhados na mesma altura dos outros. */
.po-tb-seg-plano { background: transparent; border-color: transparent; padding: 0; gap: 6px; }
.po-tb-seg-plano .po-tb-seg-btn { border: 1px solid var(--border); background: var(--panel); }
.po-tb-seg-plano .po-tb-seg-btn:hover { border-color: var(--accent); background: var(--accent-light); }
.po-tb-primaria { background: var(--text) !important; color: #fff !important; border-color: var(--text) !important; }
.po-tb-primaria:hover { filter: brightness(0.92); }
.po-tb-seg-btn:disabled { opacity: 0.4; cursor: default; }
/* Título dentro da barra, como no mockup — mesma linha de tudo. */
.po-tb-titulo { font-size: 15px; font-weight: 700; color: var(--text); padding: 0 12px 0 4px; align-self: center; white-space: nowrap; }

/* ==========================================================================
   BARRA DE FERRAMENTAS — refinamento (2026-08-13, referência do Matt)
   ==========================================================================
   "está muito grotesco, quero mais delicado, refinado, mais fino e com mais
   espaço pra visualização em vez de espaço perdido nas barras."

   O que muda em relação à versão anterior, e por quê:
   · SEM rótulo de grupo (Vista/Visual/…): eram três linhas de texto miúdo que
     só existiam pra explicar botões que já têm nome. Sozinhos, comiam ~14px de
     altura da barra inteira.
   · SEM pílula preta: o preto pesa e disputa atenção com o desenho. Ativo agora
     é ÂMBAR — cor de marca, leve, e suficiente pra separar do inativo.
   · SEM moldura em volta dos segmentados: o filete fino entre grupos já separa.
   · Altura ~46px no total, contra ~80px de antes: o que sobra vai pro ambiente.
   ========================================================================== */
#po-proj-canvas-tools.po-proj-hud-tl {
  align-items: center; gap: 2px;
  /* CAIXA MAIS BAIXA, ICONES NO MEIO (2026-08-18, Matt: "tem muito espaco
     sobrando, os icones estao meio flutuando no meio dela, reduz pela metade,
     os icones todos bem no meio").
     Duas sobras somavam altura sem servir pra nada:
       · margin-bottom de 10px, que existia so pra afastar do filete de baixo —
         e o filete saiu ("tem uma linha correndo embaixo de todos icones, pode
         eliminar"), entao a margem foi junto;
       · o padding proprio, agora colado no minimo (a caixa de fora,
         .po-proj-topbar, ja da o respiro).
     Os filetes ENTRE grupos (.po-tb-sep) continuam — esses agrupam. */
  padding: 2px 10px; margin: 0;
  border: none;
  border-radius: 0; box-shadow: none; background: transparent;
}
/* Rótulos de grupo saem de cena (ver comentário acima). */
#po-proj-canvas-tools .po-tb-label { display: none; }
#po-proj-canvas-tools .po-tb-group { padding: 0 3px; flex-direction: row; align-items: center; gap: 2px; }
#po-proj-canvas-tools .po-tb-sep { margin: 6px 6px; opacity: 0.7; }
#po-proj-canvas-tools .po-tb-seg { background: transparent; border: none; padding: 0; gap: 2px; }

/* Botão da barra: texto discreto, ícone fino, alvo confortável sem volume. */
/* PRETO, NAO CINZA (2026-08-18, Matt: "os itens em cinza nao estao se
   destacando, pode deixar eles pretos"). O cinza (#4a4740 no texto, #8d8478 no
   icone) veio do refinamento de 13/08, que perseguia leveza — mas leveza
   virou apagado: sobre o fundo creme do painel o contraste caia demais e a
   barra sumia. Preto no texto E no icone; quem separa ativo de inativo
   continua sendo o AMBAR do .active, nao o tom de cinza. */
#po-proj-canvas-tools .po-tb-seg-btn {
  gap: 7px; padding: 7px 11px; border-radius: 9px;
  font-size: 12.5px; font-weight: 500; color: var(--text);
  background: transparent; box-shadow: none;
}
#po-proj-canvas-tools .po-tb-seg-btn svg { width: 16px; height: 16px; color: var(--text); }
#po-proj-canvas-tools .po-tb-seg-btn:hover { background: #f4f2ed; }
/* ATIVO = âmbar (texto + ícone + fundo bem claro). */
#po-proj-canvas-tools .po-tb-seg-btn.active,
#po-proj-canvas-tools .po-tb-seg-btn.active:hover {
  background: #fdf4e6; color: #c98a1f; box-shadow: none;
}
#po-proj-canvas-tools .po-tb-seg-btn.active svg { color: #e0a44b; }

/* Cartões de ícone (Medidas, desfazer, Encaixe) na mesma régua dos demais. */
#po-proj-canvas-tools .po-tb-icon-card {
  flex-direction: row; gap: 7px; padding: 7px 11px; border: none;
  border-radius: 9px; background: transparent; min-width: 0;
  font-size: 12.5px; font-weight: 500; color: var(--text);
}
#po-proj-canvas-tools .po-tb-icon-card svg { width: 16px; height: 16px; color: var(--text); }
#po-proj-canvas-tools .po-tb-icon-card:hover { background: #f4f2ed; }
#po-proj-canvas-tools .po-tb-dot { top: 4px; right: 4px; width: 6px; height: 6px; }
#po-proj-collision-btn.active { background: #fdf4e6; }
#po-proj-collision-btn.active svg { color: #c98a1f; }

/* Menu de estilo: mesma pegada dos botões, sem caixa pesada. */
#po-proj-style-menu .po-style-btn {
  height: auto; padding: 7px 11px; border-radius: 9px; min-width: 0;
  border: none; background: transparent; font-size: 12.5px; font-weight: 500; color: var(--text);
}
#po-proj-style-menu .po-style-btn:hover { background: #f4f2ed; }

/* Voltar, à esquerda de tudo — o "← Projects" da referência. */
.po-tb-voltar {
  display: flex; align-items: center; gap: 8px; border: none; background: transparent;
  padding: 7px 10px 7px 4px; border-radius: 9px; cursor: pointer;
  font-size: 13px; font-weight: 600; color: var(--text);
}
.po-tb-voltar svg { width: 17px; height: 17px; }
.po-tb-voltar:hover { background: #f4f2ed; }

/* Ações encostadas na direita. */
.po-tb-direita { margin-left: auto; }
#po-proj-canvas-tools .po-tb-seg-plano .po-tb-seg-btn {
  border: 1px solid var(--border); background: var(--panel); border-radius: 999px; padding: 7px 14px;
}
#po-proj-canvas-tools .po-tb-primaria {
  background: var(--text) !important; color: #fff !important; border-color: var(--text) !important;
}
#po-proj-canvas-tools .po-tb-primaria svg { color: #fff; }

/* Ícones da barra do módulo: quadrados, sem borda própria, filete entre eles. */
.po-proj-slot-actions .po-proj-slot-action-btn {
  width: 29px; height: 26px; border: none; border-radius: 6px;
  background: transparent; box-shadow: none; font-size: 12.5px; color: #4a4740;
}
.po-proj-slot-actions .po-proj-slot-action-btn + .po-proj-slot-action-btn {
  border-left: 1px solid var(--border); border-radius: 0 6px 6px 0;
}
.po-proj-slot-actions .po-proj-slot-action-btn:hover { background: #f4f2ed; }
.po-proj-slot-actions .po-proj-slot-action-danger { color: #b0503c; }
.po-proj-slot-actions .po-proj-slot-action-danger:hover { background: #f7e4e0; }

/* Botão só-ícone dentro da barra: some o vão do texto e encolhe o alvo, que é
   o que permite os quatro (portas, gavetas, ocultar, mostrar) caberem sem
   empurrar as ações pra fora da linha. */
#po-proj-canvas-tools .po-tb-so-icone { padding: 7px 8px; gap: 0; }

/* ==========================================================================
   PEÇAS DO MÓVEL — lista de corte + explodida (2026-08-13)
   ========================================================================== */
#po-pieces-modal { position: fixed; inset: 0; z-index: 320; background: rgba(0,0,0,0.35); display: none; align-items: center; justify-content: center; }
#po-pieces-modal.open { display: flex; }
.po-pieces-card {
  background: var(--panel); border-radius: 14px; width: min(1180px, 95vw); height: min(780px, 92vh);
  display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 18px 60px rgba(0,0,0,0.3);
}
.po-pieces-header { display: flex; align-items: center; justify-content: space-between; padding: 12px 16px; border-bottom: 1px solid var(--border); }
.po-pieces-tools { display: flex; align-items: center; gap: 14px; }
.po-pieces-explode { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 600; color: var(--muted); }
.po-pieces-explode input { width: 140px; }
.po-pieces-header .po-auth-modal-close { position: static; }
.po-pieces-body { flex: 1; display: flex; min-height: 0; }
/* 3D à esquerda e lista à direita: o desenho é o que orienta, a lista é o que
   se confere item a item — e listas se leem melhor encostadas na borda. */
.po-pieces-3d { flex: 1; min-width: 0; background: #faf9f6; }
.po-pieces-list { width: 560px; flex: none; border-left: 1px solid var(--border); overflow: auto; padding: 12px 14px; }
.po-pieces-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.po-pieces-table th {
  text-align: left; font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--muted); font-weight: 700; padding: 6px 6px; border-bottom: 1px solid var(--border);
  position: sticky; top: -12px; background: var(--panel);
}
.po-pieces-table td { padding: 6px; border-bottom: 1px solid #efece5; color: var(--text); }
.po-pieces-table tbody tr:hover { background: #faf8f3; }

/* Remover/restaurar/trocar cor por peça (2026-08-20) — "quero remover
   qualquer peca", modal Peças do móvel. Linha removida fica riscada e
   meio apagada em vez de sumir: é assim que dá pra restaurar sem precisar
   de confirm() nativo (trava a automação/extensão do Chrome) — a ação
   nunca é destrutiva de verdade, só um filtro. */
.po-pieces-table tr.po-piece-removed td { opacity: 0.45; text-decoration: line-through; }
.po-pieces-table tr.po-piece-removed td:last-child { text-decoration: none; } /* botão de restaurar continua legível */
.po-piece-removed-badge { text-decoration: none; opacity: 1; font-size: 10px; color: var(--muted); }
.po-piece-color-select { font-size: 12px; padding: 2px 4px; max-width: 140px; }
.po-piece-remove-btn, .po-piece-restore-btn {
  width: 26px; height: 26px; padding: 0; line-height: 1; font-size: 15px;
  border-radius: 6px;
}
.po-piece-remove-btn { color: #b23b3b; border-color: #e7c9c9; }
.po-piece-remove-btn:hover { background: #fbeaea; }
.po-piece-restore-btn { color: #2f7a3d; border-color: #c8e0cc; }
.po-piece-restore-btn:hover { background: #eaf6ec; }

/* ==========================================================================
   BARRA CABENDO NA TELA — 2026-08-13
   ==========================================================================
   "minha barra passou da tela pra direita. faz ela caber dentro da tela. tem
   muito espaço vazio entre os ícones, mas deixa eles em harmonia, separados de
   forma igual."

   Três mecanismos, do mais suave pro mais drástico — nessa ordem, pra a barra
   só perder informação quando não houver mais espaço:
     1. space-between distribui a sobra por igual entre os grupos (é o que dá a
        "harmonia" pedida) em vez de amontoar tudo à esquerda e vazar à direita;
     2. abaixo de 1600px somem os RÓTULOS dos botões secundários — o ícone
        sozinho já identifica quem é usado o tempo todo;
     3. abaixo de 1180px (iPad deitado) somem os rótulos dos segmentados também.
   O que NUNCA some é "Send to order": é a ação final do fluxo. */
#po-proj-canvas-tools.po-proj-hud-tl {
  justify-content: space-between; gap: 0;
  /* Esta regra vem DEPOIS da de cima e e quem manda no padding — baixar so la
     em cima nao adiantava nada (2026-08-18). */
  padding: 2px 12px; overflow: visible; flex-wrap: nowrap;
}
#po-proj-canvas-tools .po-tb-group { padding: 0; min-width: 0; }
#po-proj-canvas-tools .po-tb-sep { margin: 6px 2px; }
#po-proj-canvas-tools .po-tb-seg-btn,
#po-proj-canvas-tools .po-tb-icon-card,
#po-proj-style-menu .po-style-btn { padding: 6px 9px; }
/* O nome do estilo é o texto mais longo da barra — ele encolhe primeiro. */
#po-proj-style-menu .po-style-btn { max-width: 190px; overflow: hidden; }
#po-proj-style-menu .po-style-btn span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}

@media (max-width: 1600px) {
  /* Secundários viram só ícone (o title= continua explicando no hover). */
  #po-proj-wall-editor-btn span,
  #po-proj-render-btn span,
  #po-proj-render-linhas-btn span,
  #po-proj-style-menu .po-style-btn span,
  #po-proj-style-menu .po-style-caret { display: none; }
  #po-proj-style-menu .po-style-btn { max-width: none; }
}
@media (max-width: 1180px) {
  /* iPad deitado: sobra só ícone em tudo, menos a ação final. */
  #po-proj-canvas-tools .po-tb-seg-btn span,
  #po-proj-canvas-tools .po-tb-icon-card span,
  .po-tb-voltar span { display: none; }
  #po-proj-send-to-order-btn span,
  #po-proj-send-to-order-btn { display: inline-flex !important; }
  #po-proj-canvas-tools .po-tb-seg-btn { padding: 6px 8px; }
}

/* ==========================================================================
   $ ORÇAMENTO / $ FÁBRICA (2026-08-15)
   ========================================================================== */
#po-money-modal {
  display: none; position: fixed; inset: 0; z-index: 3400;
  align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55); padding: 16px;
}
#po-money-modal.open { display: flex; }
.po-money-card {
  background: var(--panel); border-radius: 12px;
  width: 780px; max-width: 96vw; max-height: 88vh;
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: 0 20px 60px rgba(0,0,0,0.4);
}
.po-money-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px; border-bottom: 1px solid var(--border); flex: none;
}
.po-money-tabs { display: flex; gap: 6px; }
.po-money-tab {
  border: 1px solid var(--border); background: none; cursor: pointer;
  padding: 6px 14px; border-radius: 6px; font-size: 13px; color: var(--muted);
}
.po-money-tab.active { background: var(--accent-light); color: var(--accent); font-weight: 600; }
.po-money-body { padding: 14px 16px; overflow-y: auto; }
.po-money-sub { font-size: 12px; color: var(--muted); margin: 0 0 10px; }
.po-money-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.po-money-table th {
  text-align: left; font-size: 11px; text-transform: uppercase;
  letter-spacing: .06em; color: var(--muted); padding: 4px 6px;
  border-bottom: 1px solid var(--border);
}
.po-money-table td { padding: 5px 6px; border-bottom: 1px solid #f0ece3; }
.po-money-table .num { text-align: right; }
.po-money-table .dim { color: var(--muted); font-size: 12px; }
.po-money-table .pct { color: var(--muted); width: 58px; }
/* Cabeçalho de natureza: separa material / fita / mão de obra / ferragem. */
.po-money-sec td {
  padding-top: 12px; font-size: 11px; text-transform: uppercase;
  letter-spacing: .08em; color: #8a8378; border-bottom: none;
}
.po-money-total {
  display: flex; justify-content: space-between; align-items: baseline;
  margin-top: 12px; padding-top: 8px; border-top: 2px solid var(--border);
  font-size: 15px;
}
.po-money-total.secundario {
  border-top: none; margin-top: 4px; padding-top: 0;
  font-size: 12px; color: var(--muted);
}
.po-money-lock { text-align: center; padding: 28px 10px; }
.po-money-lock input {
  width: 200px; text-align: center; margin: 10px auto 8px; display: block;
}
.po-money-erro { color: #b0503c; font-size: 12px; min-height: 16px; }

/* Mais largo (2026-08-15, "deixa mais aberto"): a tabela por peça tem 12
   colunas e precisa respirar. O scroll horizontal é só dela, não do modal. */
.po-money-card { width: 1180px; }
.po-money-h {
  margin: 20px 0 4px; font-size: 12px; text-transform: uppercase;
  letter-spacing: .08em; color: #8a8378;
}
.po-money-scroll { overflow-x: auto; }
.po-money-peca { min-width: 900px; }
.po-money-peca td, .po-money-peca th { padding: 4px 5px; font-size: 12px; }
.po-money-table .zero { color: #cfc9bd; }

/* Subtotal por natureza (matéria-prima / mão de obra): destaque sem virar
   total — o total geral continua sendo o de baixo. */
.po-money-subtotal td {
  font-weight: 600; border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border); background: #faf8f4;
}
