:root { font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color: #16202a; background: #eef2f5; font-synthesis: none; }
* { box-sizing: border-box; }
body { margin: 0; min-width: 1120px; }
button, input, select { font: inherit; }
.topbar { display: flex; justify-content: space-between; align-items: center; gap: 24px; padding: 18px 24px; background: #101820; color: white; border-bottom: 4px solid #b4232f; }
.topbar h1 { margin: 2px 0 0; font-size: 24px; }
.eyebrow { margin: 0; color: #ffb06b; font-weight: 800; font-size: 11px; letter-spacing: .13em; }
.top-actions, .button-row, .section-title-row, .plan-toolbar, .pdf-controls { display: flex; gap: 8px; align-items: center; }
.section-title-row { justify-content: space-between; }
button, .button { border: 0; border-radius: 8px; padding: 10px 13px; cursor: pointer; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
button:disabled { opacity: .45; cursor: not-allowed; }
.primary { background: #1c728e; color: white; }
.primary:hover { background: #175f76; }
.secondary { background: #263746; color: white; }
.secondary:hover { background: #344b5f; }
.tertiary { background: #e9f0f4; color: #274151; border: 1px solid #cfdbe2; }
.tertiary:hover { background: #dfe9ee; }
.danger { background: #ffdfdf; color: #9e1c1c; }
.small { padding: 7px 10px; font-size: 11px; }
.file-label input { display: none; }
.full-width { width: 100%; }
.layout { display: grid; grid-template-columns: 310px minmax(620px, 1fr) 320px; gap: 14px; padding: 14px; align-items: start; }
.panel { background: white; border: 1px solid #dce3e8; border-radius: 12px; padding: 16px; box-shadow: 0 4px 16px rgba(23,35,45,.05); }
.panel section + section { border-top: 1px solid #e7ecef; margin-top: 18px; padding-top: 16px; }
h2 { font-size: 15px; margin: 0 0 12px; }
label { display: block; font-size: 12px; font-weight: 700; color: #43515d; margin-bottom: 12px; }
input[type="text"], input[type="number"], select { width: 100%; margin-top: 5px; border: 1px solid #cfd8df; border-radius: 7px; padding: 9px; background: white; color: #16202a; }
input[type="range"] { width: 100%; margin: 0; accent-color: #1c728e; }
input:disabled { opacity: .5; cursor: not-allowed; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; }
.slider-number { display: grid; grid-template-columns: minmax(120px, 1fr) 105px; gap: 10px; align-items: center; margin-top: 6px; }
.slider-number .inline-input input, .slider-number .inline-input span { margin-top: 0; }
.inline-input { display: grid; grid-template-columns: minmax(0, 1fr) 40px; gap: 5px; align-items: center; }
.inline-input.compact { grid-template-columns: 75px 25px; }
.inline-input span { margin-top: 5px; font-size: 11px; color: #667681; }
.check-row { display: flex; align-items: center; gap: 8px; font-weight: 700; margin: 4px 0 12px; }
.check-row input { width: 16px; height: 16px; margin: 0; accent-color: #1c728e; }
.scale-label { display: grid; grid-template-columns: auto 16px 1fr 16px; align-items: center; gap: 6px; }
.scale-label > span { text-align: center; font-size: 14px; color: #71808a; }
.hint { margin: 4px 0 0; font-size: 12px; line-height: 1.45; color: #667681; }
.warning { padding: 11px; border-radius: 8px; background: #fff1d4; color: #6e4a00; font-size: 12px; line-height: 1.4; margin-top: 12px; }
/* V92 · aviso constructivo de talud: la altura declarada no cabe en la superficie. No es un error del
   usuario (le pasa a la mayoría de acopios reales), así que se presenta como dato, no como alarma. */
.hint.talud-aviso { margin-top: 6px; padding: 8px 10px; border-radius: 8px; background: #fff8e8; border: 1px solid #eeddb4; color: #6e4a00; }
.hint.talud-aviso b { color: #4d3400; }
.camera-list { display: flex; flex-direction: column; gap: 6px; max-height: 190px; overflow: auto; margin-bottom: 9px; }
.camera-list button { width: 100%; padding: 8px 9px; border: 1px solid #d9e2e7; background: #f7f9fa; color: #31424d; justify-content: flex-start; gap: 8px; font-size: 11px; }
.camera-list button.selected { border-color: #1c728e; background: #e8f4f8; color: #144f62; }
.camera-color { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }
.camera-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.workspace { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.view-block { overflow: hidden; background: white; border: 1px solid #dce3e8; border-radius: 12px; box-shadow: 0 4px 16px rgba(23,35,45,.04); }
.view-heading { min-height: 48px; padding: 10px 14px; border-bottom: 1px solid #e4eaee; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.view-heading > div { display: flex; align-items: baseline; gap: 9px; }
.view-heading strong { font-size: 13px; }
.view-heading span { color: #71808a; font-size: 11px; }
.badge-group { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.orientation-badge { border: 1px solid #ced9df; border-radius: 999px; padding: 5px 9px; background: #f5f8fa; font-weight: 800; color: #44545f !important; white-space: nowrap; }
.plan-toolbar { min-height: 54px; padding: 8px 12px; border-bottom: 1px solid #e4eaee; flex-wrap: wrap; }
.plan-toolbar label { margin: 0; }
.plan-toolbar .button { font-size: 11px; padding: 8px 10px; }
.toolbar-spacer { flex: 1 1 auto; }
.opacity-control { display: grid; grid-template-columns: auto 90px; gap: 7px; align-items: center; }
.calibration-distance { display: flex; align-items: center; gap: 8px; white-space: nowrap; }
.pdf-controls label { display: flex; align-items: center; gap: 5px; margin: 0; }
.pdf-controls input { width: 58px; margin: 0; padding: 6px; }
.canvas-shell { position: relative; overflow: hidden; }
.plan-canvas { display: block; width: 100%; height: 650px; cursor: crosshair; }
.plan-canvas.dragging { cursor: grabbing; }
.profile-canvas { display: block; width: 100%; height: 340px; cursor: default; }
.calibration-notice { position: absolute; top: 14px; left: 50%; transform: translateX(-50%); z-index: 2; padding: 9px 13px; background: rgba(18, 32, 42, .92); color: white; border-radius: 8px; font-size: 12px; font-weight: 700; }
.legend { position: absolute; left: 14px; bottom: 14px; display: flex; flex-wrap: wrap; gap: 10px 14px; max-width: calc(100% - 28px); padding: 9px 12px; background: rgba(255,255,255,.94); border: 1px solid #dce3e8; border-radius: 8px; font-size: 11px; font-weight: 700; }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.camera-dot { background: #d9534f; }.camera-other-dot { background: #71808a; }.coverage-dot { background: #36a77c; }.range-dot { background: #e18b27; }.range-out-dot { background: #8d99a1; }.calibration-dot { background: #7a4ec2; }
.ipi-section[hidden] { display: none; }
.ipi-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.ipi-score { font-size: 34px; font-weight: 900; line-height: 1; }
.ipi-score span { font-size: 14px; font-weight: 700; color: #98a2ab; }
.ipi-head-meta { flex: 1; min-width: 0; }
.ipi-label { display: inline-block; color: #fff; font-size: 11px; font-weight: 800; padding: 2px 9px; border-radius: 999px; margin-bottom: 6px; }
.ipi-gauge { height: 8px; border-radius: 999px; background: linear-gradient(90deg,#d0432f,#d1791f,#c99215,#6fae3a,#2f9b6f); position: relative; }
.ipi-marker { position: absolute; top: -2px; bottom: -2px; width: 3px; border-radius: 2px; background: #14202a; box-shadow: 0 0 0 1.5px #fff; transform: translateX(-50%); }
.ipi-headline { font-size: 11.5px; color: #46535c; margin: 4px 0 10px; line-height: 1.5; }
.ipi-headline b { color: #14202a; }
.ipi-subhead { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: #8a949c; margin: 12px 0 4px; font-weight: 800; }
.ipi-table { width: 100%; border-collapse: collapse; font-size: 11px; }
.ipi-table th { text-align: left; color: #6a7580; font-weight: 700; font-size: 10px; border-bottom: 1px solid #e4e9ed; padding: 4px 6px 4px 0; }
.ipi-table td { padding: 5px 6px 5px 0; border-bottom: 1px dashed #eef1f4; }
.ipi-table td:not(:first-child), .ipi-table th:not(:first-child) { text-align: right; white-space: nowrap; }
.ipi-mag { color: #8a949c; font-weight: 700; font-size: 10px; }
.score-hint { color: #8a949c; font-size: 11px; line-height: 1.35; margin: 4px 2px 2px; }
.ipi-scopebar { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 0 6px; }
.ipi-scopename { font-size: 11px; font-weight: 700; color: #6a737c; text-transform: uppercase; letter-spacing: .02em; }
.ipi-filter { font-size: 12px; padding: 3px 6px; border: 1px solid #d5dade; border-radius: 6px; background: #fff; color: #2b3238; max-width: 55%; }
.ipi-floorline { font-size: 11px; color: #b06a1f; margin: 4px 2px 0; }
/* V98 · no conformidad de continuidad de suelo: es una conformidad binaria fuera del indice, asi que
   se marca con color propio y nunca con el ambar de la marca, reservado a la identidad. */
.ipi-nc { color: #c0392b; }
.ipi-grouprow { cursor: pointer; }
.ipi-grouprow:hover { background: rgba(0,0,0,.035); }
.ipi-grouprow.sel { background: rgba(185,137,66,.14); }

/* Resumen de diseño (Bloque 4) */
.summary-card { max-width: 860px; }
.summary-titleblock { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 16px; margin: 8px 0 6px; }
.summary-titleblock .score-row { justify-content: space-between; }
.summary-titleblock input, .summary-titleblock textarea { flex: 1; min-width: 0; margin-left: 10px; padding: 4px 7px; border: 1px solid #d5dade; border-radius: 6px; font-size: 12px; font-family: inherit; }
/* Datos del sistema para el informe: se pliegan para que el cajetín siga siendo corto en el uso diario. */
.meta-more { margin: 4px 0 8px; border: 1px solid #e7ecef; border-radius: 8px; padding: 6px 10px; background: #fafbfc; }
.meta-more > summary { cursor: pointer; font-size: 11.5px; font-weight: 700; color: #3E4B63; }
.meta-h { margin: 9px 0 2px; font-size: 10px; text-transform: uppercase; letter-spacing: .07em; color: #8a949c; }
.meta-obs { display: grid; gap: 6px; margin: 8px 0 2px; }
.meta-obs .score-row, .meta-row-area { align-items: flex-start; flex-direction: column; }
.meta-obs select { width: 100%; margin: 5px 0 0; }
.meta-obs textarea, .meta-row-area textarea { width: 100%; margin: 5px 0 0; min-width: 0; padding: 5px 7px; border: 1px solid #d5dade; border-radius: 6px; font-size: 12px; font-weight: 400; line-height: 1.45; font-family: inherit; resize: vertical; }
.sum-proj { border: 1px solid #e2e7ea; border-radius: 10px; padding: 12px 14px; margin: 8px 0 4px; background: #fbfcfd; }
.sum-projname { font-size: 17px; font-weight: 800; color: #1f2a30; }
.sum-ipi { margin: 4px 0; }
.sum-ipi-score { font-size: 30px; font-weight: 800; }
.sum-ipi-lbl { display: inline-block; color: #fff; border-radius: 6px; padding: 2px 9px; font-size: 12px; font-weight: 700; vertical-align: middle; }
.sum-projmeta { color: #55636c; font-size: 12px; margin-top: 3px; }
.sum-h { font-size: 12.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .02em; color: #55606a; margin: 16px 0 5px; }
.sum-table th, .sum-table td { text-align: left; padding: 4px 8px; }
.sum-table thead th { border-bottom: 1px solid #dce2e6; color: #6a737c; font-size: 11px; }
.sum-table tbody tr:nth-child(even) { background: rgba(0,0,0,.02); }
.sum-notes { margin: 4px 0 0; padding-left: 18px; color: #46525b; font-size: 12px; line-height: 1.5; }
.sum-notes li { margin: 2px 0; }
/* Ficha de cobertura (por elemento o zona) */
.ficha-card { max-width: 900px; }
.ipi-ficha-btn { border: 1px solid #d5dade; background: #fff; color: #55636c; border-radius: 5px; font-size: 11px; line-height: 1; padding: 1px 4px; cursor: pointer; margin-right: 2px; }
.ipi-ficha-btn:hover { background: #eef2f4; color: #2b3238; }
.fb-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; border: 1px solid #e2e7ea; border-radius: 10px; padding: 12px 14px; background: #fbfcfd; }
.fb-name { font-size: 17px; font-weight: 800; color: #1f2a30; }
.fb-sub { color: #55636c; font-size: 12px; margin-top: 3px; }
.fb-ipi-score { font-size: 30px; font-weight: 800; }
.fb-ipi-lbl { display: inline-block; color: #fff; border-radius: 6px; padding: 2px 9px; font-size: 12px; font-weight: 700; vertical-align: middle; }
.fb-bar { display: flex; height: 18px; border-radius: 5px; overflow: hidden; border: 1px solid #d9dee2; background: repeating-linear-gradient(45deg,#f4f5f6,#f4f5f6 5px,#eceef0 5px,#eceef0 10px); }
.fb-seg { display: block; height: 100%; }
.fb-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 6px 0 0; font-size: 11.5px; color: #46525b; }
.fb-legend span { display: inline-flex; align-items: center; gap: 5px; }
.fb-legend i { width: 16px; height: 11px; border-radius: 2px; display: inline-block; }
.fb-figs { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 8px; }
.fb-fig { margin: 0; border: 1px solid #e2e7ea; border-radius: 8px; overflow: hidden; background: #fff; }
.fb-fig img { display: block; width: 100%; height: auto; }
.fb-fig figcaption { font-size: 11px; color: #6a737c; padding: 4px 8px; border-top: 1px solid #eef1f3; }
.fb-fig-empty { padding: 20px; text-align: center; color: #9aa4ac; }
.fb-projbar { display: flex; align-items: center; gap: 8px; font-size: 12px; color: #55636c; border-bottom: 1px solid #e7ebee; padding-bottom: 6px; margin-bottom: 8px; }
.fb-projbar-tag { margin-left: auto; font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: #8a949c; }
.ficha-orient { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: #8a949c; }

/* Término técnico + glosa en lenguaje llano (visible también en papel) */
.gl { white-space: normal; }
.gl-h { color: #8a949c; font-weight: 400; font-style: normal; font-size: .9em; margin-left: 4px; }
/* Cabecera de columna glosada: etiqueta en una línea y glosa debajo en tipo menor, para que un <th>
   estrecho no se coma cinco líneas de alto de hoja. */
.gl-th { display: block; }
.gl-th > b { display: block; white-space: nowrap; }
.gl-th > .gl-h { display: block; margin-left: 0; font-size: .82em; line-height: 1.15; letter-spacing: 0; text-transform: none; }

/* Grado de protección: la banda manda, el número acompaña */
.fb-id { min-width: 0; }
.fb-eyebrow { font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; color: #9aa4ac; margin-bottom: 2px; }
.fb-grade { text-align: right; flex: 0 0 auto; }
.fb-grade-lbl { display: inline-block; color: #fff; border-radius: 7px; padding: 5px 12px; font-size: 15px; font-weight: 800; letter-spacing: .01em; }
.fb-grade-score { font-size: 12px; color: #6a737c; margin-top: 4px; }
.fb-grade-score b { font-size: 19px; }
.fb-grade-help { margin: 7px 0 0; font-size: 12.5px; color: #46525b; line-height: 1.45; }
.fb-gauge { margin-top: 10px; }
.fb-gbar { position: relative; display: flex; height: 16px; border-radius: 4px; margin-top: 14px; }
.fb-gseg:first-of-type { border-radius: 4px 0 0 4px; }
.fb-gseg:last-of-type { border-radius: 0 4px 4px 0; }
.fb-gseg { display: flex; align-items: center; justify-content: center; overflow: hidden; padding: 0 1px; font-size: 8.5px; font-weight: 700; color: rgba(255,255,255,.95); opacity: .5; white-space: nowrap; }
.fb-gseg.is-cur { opacity: 1; }
.fb-gmark { position: absolute; top: -9px; bottom: -3px; width: 0; border-left: 2px solid #1f2a30; }
.fb-gmark b { position: absolute; top: -12px; left: 50%; transform: translateX(-50%); font-size: 10px; font-weight: 800; color: #1f2a30; background: #fff; padding: 0 3px; border-radius: 3px; }
.fb-gscale { font-size: 10px; color: #8a949c; margin-top: 4px; }
.fb-minilbl { display: inline-block; color: #fff; border-radius: 4px; padding: 1px 6px; font-size: 10px; font-weight: 700; white-space: nowrap; }
/* Carné de cámara: mismo color y referencia en planta, isométrica y tablas */
.fb-cchip { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 4px; vertical-align: baseline; }
.fb-camline { margin-top: 9px; font-size: 12px; color: #46525b; display: flex; align-items: center; flex-wrap: wrap; gap: 5px; }
.fb-camline-t { font-weight: 700; }
.fb-cref { display: inline-flex; align-items: center; border: 1px solid #dde2e6; border-radius: 5px; padding: 1px 6px; font-size: 11.5px; font-weight: 700; color: #2b3238; background: #fff; }
.fb-cref-none { color: #b4232f; font-weight: 700; }
.fb-camline-n { font-size: 10.5px; color: #9aa4ac; }
.fb-ind td:first-child { max-width: 320px; }
.fb-model { display: block; font-size: 10px; color: #8a949c; font-weight: 400; margin-top: 1px; }

/* ---- Bloque 2: hoja de cámara y matriz elemento x camara ---- */
.fb-cchip-big { width: 12px; height: 12px; border-radius: 3px; margin-right: 6px; }
/* Indicadores de una cámara: no tiene IPI, se muestran las magnitudes que sí le son propias. */
.fb-camkpi { display: block; margin-bottom: 5px; }
.fb-camkpi b { font-size: 20px; color: #2b3238; line-height: 1; }
.fb-camkpi span { display: block; font-size: 10px; color: #8a949c; max-width: 150px; margin-left: auto; }
.fb-sole { display: inline-block; background: #b4232f; color: #fff; border-radius: 4px; padding: 0 5px; font-size: 9.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; }
.fb-why { font-size: 11px; color: #6a737c; }
.fb-dim td { color: #9aa4ac; }
.fb-matrix th.mx-c { text-align: center; white-space: nowrap; font-size: 10px; }
.fb-matrix td { text-align: center; }
.fb-matrix td.mx-e { text-align: left; }
.fb-matrix td.mx-0 { color: #c8ced3; }
.fb-matrix td.mx-lo { background: #eaf5ef; }
.fb-matrix td.mx-md { background: #c7e6d5; }
.fb-matrix td.mx-hi { background: #92cfae; font-weight: 700; }
.fb-matrix td.mx-alone { background: #fdeaec; color: #b4232f; font-weight: 800; }

/* ---- Bloque 3: reencuadre manual de las capturas ---- */
.ficha-frame { display: inline-flex; align-items: center; gap: 3px; margin-right: 8px; }
.ficha-frame-t { font-size: 11px; color: #8a949c; margin-right: 2px; }
.ficha-fbtn { border: 1px solid #d5dade; background: #fff; color: #55636c; border-radius: 5px; font-size: 11px; line-height: 1; padding: 3px 6px; cursor: pointer; }
.ficha-fbtn:hover { background: #eef2f4; color: #2b3238; }
/* V92 · F1: la barra vive dentro de su figura, como primera línea, para que el mando y la imagen que
   gobierna estén siempre a la vista a la vez. Se pega arriba al desplazar la ficha: en una ficha
   larga la figura ocupa más que el alto de la ventana y, sin esto, los mandos volverían a quedarse
   fuera de pantalla —que es justo el defecto que se está corrigiendo—. */
.fb-frame { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; margin: 0; padding: 5px 8px;
  background: #f7f9fa; border-bottom: 1px solid #eef1f3; position: sticky; top: 0; z-index: 2; }
.fb-frame .ficha-frame-t { margin: 0 2px 0 0; }
.fb-frame .ficha-frame-sep { width: 1px; align-self: stretch; background: #dde3e7; margin: 0 4px; }
.fb-frame .ficha-frame-v { font-size: 11px; color: #55636c; font-variant-numeric: tabular-nums; margin-left: auto; padding-left: 6px; }
.fb-fig { position: relative; }

/* ---- Bloque 4: ensamblador de informe ----
   El panel es a la vez vista previa EN PAPEL: cada .rep-pg mide la caja imprimible de un A4
   vertical con margen de 10 mm (190 × 277 mm), así que lo que se ve en pantalla es exactamente
   lo que sale del PDF. Por eso estas reglas viven FUERA de @media print: la tipografía compacta
   de impresión se aplica también en pantalla, en vez de tener dos maquetaciones distintas. */
/* V136 · el dimensionado del compositor vive en su bloque de abajo (junto a .composer):
   las reglas aquí arriba perdían la cascada frente a .history-card y al bloque tardío. */
#reportPanel { padding: 10px; }
.rep-opts { display: flex; flex-wrap: wrap; gap: 4px 18px; padding: 8px 11px; background: #f4f7f8; border: 1px solid #e3e8eb; border-radius: 8px; margin-bottom: 14px; }
.rep-opt { font-size: 12px; color: #46525b; display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
#reportContent { display: flex; flex-direction: column; align-items: center; gap: 16px; background: #e6ebee; padding: 16px; border-radius: 8px; }
#reportContent:empty { display: none; }
.rep-pg { box-sizing: border-box; width: 190mm; min-height: 277mm; background: #fff; color: #2b3238; display: flex; flex-direction: column; box-shadow: 0 2px 12px rgba(0,0,0,.16); }
.rep-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.rep-body > * { flex: 0 0 auto; }
.rep-body > .rep-ficha, .rep-body > .rep-cover { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
/* Cabecera y pie: identifican el documento en cada hoja para que una página suelta siga siendo
   trazable. La maqueta reproduce la de la evaluación de diseño que se emite hoy: marca y código de
   documento a la izquierda, proyecto y NIVEL en el centro y bloque de dirección a la derecha tras un
   filete ámbar; abajo, el pie legal de la sociedad y la paginación. Todo en una sola banda de dos
   líneas: en A4 cada milímetro de cabecera se resta al cuerpo útil de la hoja. */
.rep-hd { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; border-bottom: 2px solid #141414; padding-bottom: 1.2mm; margin-bottom: 0; font-size: 9.5px; color: #55636c; } /* V148 · la separación la pone la banda de nivel */
.rep-hd-l { flex: 0 0 auto; display: flex; flex-direction: column; gap: 0; line-height: 1.15; }
.rep-hd-code { font-size: 7.5px; letter-spacing: .04em; color: #8a949c; font-weight: 700; white-space: nowrap; }
.rep-hd-c { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; align-items: center; text-align: center; }
.rep-hd-proj { font-weight: 700; color: #2b3238; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; line-height: 1.2; }
.rep-hd-lvl { display: flex; align-items: center; gap: 1.6mm; min-width: 0; max-width: 100%; }
.rep-hd-bits { font-size: 8.5px; color: #6a7580; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rep-hd-r { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 0; font-size: 7px; line-height: 1.3; color: #6a7580; border-left: 1.5px solid #F1C02E; padding-left: 2mm; text-align: right; white-space: nowrap; }
.rep-hd-web { color: #B9862A; font-weight: 800; }
.rep-hd-tag { flex: 0 0 auto; text-transform: uppercase; letter-spacing: .05em; font-weight: 800; color: #3E4B63; }
.rep-wm { flex: 0 0 auto; font-size: 14px; font-weight: 900; letter-spacing: -.02em; color: #141414; line-height: 1.05; }
.rep-wm b { color: #F1C02E; }
/* Distintivo de NIVEL: el rótulo que impide confundir la escala de lectura de la hoja. */
.rep-lvl-b { flex: 0 0 auto; font-size: 7px; font-weight: 900; letter-spacing: .09em; text-transform: uppercase; padding: 1px 5px; border-radius: 2px; white-space: nowrap; }
.rep-lvl-t { flex: 0 1 auto; min-width: 0; font-size: 8.5px; color: #6a7580; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rep-ft { flex: 0 0 auto; display: flex; align-items: baseline; justify-content: space-between; gap: 10px; border-top: 1px solid #d5dade; margin-top: 2.4mm; padding-top: 1.2mm; font-size: 6.8px; line-height: 1.25; color: #8a949c; }
.rep-ft-legal { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rep-ft-pg { flex: 0 0 auto; font-size: 8px; color: #55636c; white-space: nowrap; }
.rep-ft-pg b { color: #141414; }
/* V96 · SELLO DE REVISIÓN EN EL PIE. Va entre la razón social y la paginación, a la misma escala de
   6,8 px del pie: es una marca de trazabilidad, no un titular. No se recorta con puntos suspensivos
   —quien lea «Rev. R3 · 27/07/2026 · JMR» debe leerlo entero o no leerlo—, así que el que cede
   espacio cuando la hoja va justa es el texto legal de la izquierda, que ya lleva su ellipsis. */
.rep-ft-rev { flex: 0 0 auto; white-space: nowrap; font-weight: 700; color: #55636c; }
/* Historial de revisiones de la portada. Seis columnas y la descripción es la única que respira:
   las demás son datos cortos (etiqueta, fecha, iniciales, versión de app, huella) y partirlas de
   línea sólo hace la tabla más alta sin hacerla más legible. */
.rep-rev-t td, .rep-rev-t th { vertical-align: top; }
.rep-rev-t td:first-child, .rep-rev-t th:first-child { width: 16mm; }
.rep-rev-t td:nth-child(2), .rep-rev-t th:nth-child(2) { width: 22mm; text-align: left; white-space: nowrap; }
.rep-rev-t td:nth-child(3), .rep-rev-t th:nth-child(3) { width: 20mm; text-align: left; white-space: nowrap; }
.rep-rev-t td:nth-child(4), .rep-rev-t th:nth-child(4) { text-align: left; white-space: normal; }
.rep-rev-t td:nth-child(5), .rep-rev-t th:nth-child(5) { width: 18mm; text-align: left; white-space: nowrap; }
.rep-rev-t td:last-child, .rep-rev-t th:last-child { width: 24mm; text-align: right; white-space: nowrap; }
/* La huella es un identificador, no una cifra que se compare a ojo: en monoespaciada y un punto por
   debajo del cuerpo de la tabla, para que no gane peso visual ni ensanche la columna. */
.rep-rev-hash { font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace; font-size: .88em; color: #8a949c; letter-spacing: -.01em; }
/* Aclaración de qué es (y qué NO es) la huella. Pegada a su tabla, no al final de la portada. */
#reportContent .rep-cover .rep-rev-note { margin: 1.2mm 0 0; font-size: 8px; line-height: 1.35; }
/* Títulos de apartado: centrados, versalitas y navy, como en el documento corporativo. */
.rep-h2 { margin: 0 0 3mm; font-size: 14px; color: #3E4B63; text-align: center; text-transform: uppercase; letter-spacing: .07em; font-weight: 800; border-bottom: 1px solid #F1C02E; padding-bottom: 1.2mm; }
.rep-h2 + .rep-h2, .rep-body > .rep-h2:not(:first-child) { margin-top: 5mm; }
/* Cabeceras de tabla en ámbar corporativo (imagen del informe en Word). */
.rep-t-amber thead th { background: #F1C02E; color: #141414 !important; font-weight: 800; border-bottom: 0; }
.rep-t-amber tbody tr:nth-child(even) { background: rgba(241,192,46,.08); }
/* Tablas de texto (identificación, cuestiones generales, tramos de red): el valor va a la izquierda
   y puede partir de línea, al contrario que las tablas de cifras. */
.rep-t-text td:not(:first-child), .rep-t-text th:not(:first-child) { text-align: left; white-space: normal; }
.rep-t-text td:first-child { width: 46mm; color: #55636c; }
/* Caja de observaciones y comentarios. */
.rep-obs { border: 1px solid #d5dade; border-left: 3px solid #F1C02E; border-radius: 3px; padding: 2mm 3mm; min-height: 16mm; font-size: 10px; line-height: 1.45; color: #2b3238; }
.rep-obs-empty { color: #9aa4ac; font-style: italic; }
/* V97 · párrafos de alcance y condiciones: texto corrido justificado, denso, sin viñetas ni marcos.
   Es una hoja de lectura, no una tabla: se busca aprovechar el ancho útil del A4. */
.rep-scope-p { font-size: 10px; line-height: 1.5; color: #2b3238; text-align: justify; margin: 0 0 2.2mm; }
.rep-scope-p:last-child { margin-bottom: 0; }
/* Figura de plano a ancho de página (plano general y topología). */
/* Figura de plano a página completa. Absorbe el hueco libre de la hoja y, si la tabla que la acompaña
   crece, se encoge en lugar de empujar el texto sobre el pie: en A4 la hoja no se puede estirar. */
.rep-planfig { margin: 0 0 3mm; }
.rep-body > .rep-planfig { flex: 1 1 auto; min-height: 30mm; display: flex; justify-content: center; }
.rep-planfig img { display: block; width: 100%; height: auto; border: 1px solid #e3e8eb; border-radius: 3px; }
.rep-body > .rep-planfig img { height: 100%; object-fit: contain; object-position: center top; }
/* La planta también encabeza el hueco libre de la portada: rellena el aire muerto entre el historial
   de revisiones y la nota de alcance con la información que el lector busca primero. */
.rep-cover > .rep-cover-plan { flex: 0 1 auto; height: 104mm; min-height: 0; display: flex; justify-content: center; margin: 4mm 0 3mm; }
.rep-cover > .rep-cover-plan img { width: 100%; height: 100%; object-fit: contain; }
/* Separador de nivel: hoja de portadilla que anuncia el cambio de escala. */
.rep-div { flex: 1 1 auto; display: flex; flex-direction: column; }
.rep-div-tag { align-self: flex-start; font-size: 10px; font-weight: 900; letter-spacing: .12em; padding: 2px 9px; border-radius: 3px; margin-top: 14mm; }
.rep-div-h1 { margin: 3mm 0 1mm; font-size: 26px; line-height: 1.12; color: #141414; }
.rep-div-scope { margin: 0 0 5mm; font-size: 12px; color: #55636c; max-width: 130mm; }
.rep-div-t { margin-bottom: 2mm; }
.rep-div-t td:first-child { width: 42mm; color: #6a7580; }
.rep-div-t td:not(:first-child) { text-align: left; white-space: normal; }
.rep-div-levels { list-style: none; margin: 1mm 0 0; padding: 0; font-size: 9.5px; }
.rep-div-levels li { display: flex; align-items: baseline; gap: 3mm; padding: 1mm 0; border-bottom: 1px dotted #e3e8eb; color: #8a949c; }
.rep-div-levels li.on { color: #2b3238; font-weight: 600; }
.rep-div-levels li .rep-lvl-b { flex: 0 0 26mm; text-align: center; }
.rep-div .rep-toc { margin-top: 0; }
.rep-cover-top { display: flex; align-items: flex-start; gap: 11px; border-bottom: 2px solid #F1C02E; padding-bottom: 3mm; }
.rep-cover-addr { margin-left: auto; display: flex; flex-direction: column; align-items: flex-end; font-size: 7.5px; line-height: 1.35; color: #6a7580; border-left: 1.5px solid #F1C02E; padding-left: 2mm; text-align: right; }
.rep-toc-lv .rep-toc-h { border-bottom: 0; padding: 2.4mm 0 .8mm; gap: 3mm; }
.rep-toc-lv .rep-toc-h .rep-lvl-b { flex: 0 0 auto; font-size: 8px; padding: 1.5px 7px; }
.rep-toc-scope { flex: 1 1 auto; min-width: 0; font-size: 9px; color: #8a949c; }
.rep-idx-lead { margin: 0 0 2mm; font-size: 9.5px; line-height: 1.4; color: #55636c; }
.rep-t-bands td:first-child, .rep-t-bands th:first-child { width: 50mm; white-space: normal; text-align: left; }
.rep-t-bands td:nth-child(2), .rep-t-bands th:nth-child(2) { width: 26mm; }
.rep-t-bands td:last-child { text-align: left; white-space: normal; }
.rep-wm-big { font-size: 30px; }
.rep-cover-fam { font-size: 10px; color: #55636c; }
.rep-cover-h1 { margin: 16mm 0 2mm; font-size: 26px; line-height: 1.15; color: #141414; }
.rep-cover-proj { font-size: 15px; font-weight: 700; color: #3E4B63; margin-bottom: 8mm; }
.rep-cover-grade { display: flex; align-items: center; gap: 11px; margin-bottom: 2mm; }
.rep-cover-meta { margin-top: 8mm; }
.rep-toc { margin: 2mm 0 0; padding-left: 0; list-style: none; font-size: 11px; }
.rep-toc li { display: flex; align-items: baseline; gap: 6px; border-bottom: 1px dotted #d5dade; padding: 1.2mm 0; }
.rep-toc li span { flex: 1 1 auto; }
.rep-toc li b { flex: 0 0 auto; color: #3E4B63; }
.rep-cover .ipi-note { margin-top: auto; }
/* Las fichas embebidas reproducen la maqueta de la ficha VERTICAL suelta (datos arriba, dos figuras
   repartiéndose la altura restante), sin depender de las reglas scoped a body.printing-ficha. */
#reportContent .rep-ficha .fb-sheet { display: grid; grid-template-rows: auto minmax(0, 1fr); flex: 1 1 auto; min-height: 0; }
#reportContent .rep-ficha .fb-col-data { flex: 0 0 auto; }
#reportContent .rep-ficha .fb-col-figs { display: flex; flex-direction: column; gap: 4mm; flex: 1 1 auto; min-height: 0; }
/* V285 · LA BANDA DE FIGURAS DEJA DE SER «LO QUE SOBRE». Era `flex: 1 1 auto; min-height: 0`
   dentro de una fila `minmax(0, 1fr)`: con muchos datos se quedaba en nada y las imágenes salían
   diminutas o no salían ⟨reporte de Sergi, 15/09/2026⟩. Ahora mide siempre lo mismo — 72 mm dan a
   cada imagen sus 82 × 65,6 mm naturales (proporción 1,25) más el pie— y si los datos no caben al
   lado, el ensamblador reparte la hoja en dos en vez de aplastarlas. */
#reportContent .rep-ficha .fb-figs { display: grid; grid-template-columns: 1fr 1fr; gap: 5mm; flex: 0 0 auto; height: 72mm; margin: 5mm 0 0; }
/* Lo que es idéntico en todas las hojas vive en el anexo de términos y se retira de cada hoja: el
   párrafo de cabecera y la columna «Qué significa». Se retira SOLO en el informe — la ficha suelta
   se imprime sola, sin anexo donde apoyarse, y ahí se queda entera. */
#reportContent .rep-ficha .fb-howto, #reportContent .rep-ficha .fb-why { display: none; }
/* Y la línea «Vigila: B3-3 B2-6 …», que repite nombre por nombre la tabla que va justo debajo, a dos
   centímetros. Repetir una lista dentro de la misma hoja no ayuda a leerla: son 11,4 mm por hoja
   ⟨medido⟩ que le hacían falta a las figuras. En la ficha suelta se conserva. */
#reportContent .rep-ficha .fb-camline-dup { display: none; }
/* Nodo de medida del ensamblador: vive dentro de #reportContent para heredar sus reglas y sale del
   flujo. `visibility: hidden` y no `display: none`, que no maquetaría y devolvería altura cero. */
.rep-medidor { position: absolute; left: -20000px; top: 0; width: 190mm; visibility: hidden; pointer-events: none; }
#reportContent .rep-ficha .fb-fig { display: flex; flex-direction: column; min-height: 0; }
#reportContent .rep-ficha .fb-fig img { flex: 1 1 auto; min-height: 0; width: 100%; height: 100%; object-fit: contain; image-rendering: auto; }
#reportContent .rep-ficha .fb-col-figs .ipi-note { flex: 0 0 auto; margin: 0; }
/* Tipografía a densidad de papel (misma escala que la ficha impresa). */
#reportContent .sum-table th, #reportContent .sum-table td { padding: 1px 5px; font-size: 9.5px; line-height: 1.25; }
#reportContent .sum-h { margin: 2.4mm 0 1.2mm; }
#reportContent .fb-sub { font-size: 10.5px; }
#reportContent .fb-grade-help { font-size: 10.5px; line-height: 1.4; }
#reportContent .fb-camline { font-size: 11px; }
#reportContent .fb-camline-n { display: none !important; }
#reportContent .fb-legend { font-size: 10px; gap: 3px 12px; }
#reportContent .fb-gseg { font-size: 7.5px; }
#reportContent .fb-gscale { font-size: 8.5px; }
#reportContent .sum-notes { font-size: 10px; line-height: 1.35; margin: 0; padding-left: 5mm; }
#reportContent .fb-model { font-size: 8.5px; }
#reportContent .ipi-note { font-size: 9px; line-height: 1.4; }
#reportContent .ipi-floorline { font-size: 10px; }
#reportContent .fb-matrix th.mx-c, #reportContent .fb-matrix td { font-size: 8.5px; padding: 1px 3px; }
#reportContent .fb-camkpi b { font-size: 16px; }
#reportContent .fb-why { font-size: 9px; }
#reportContent .gl { white-space: normal; }
#reportContent .rep-obs { font-size: 9.5px; }
#reportContent .rep-scope-p { font-size: 9.5px; line-height: 1.45; }
#reportContent .rep-div-levels { font-size: 9px; }

@media print {
  body.printing-summary > *:not(#summaryPanel) { display: none !important; }
  body.printing-summary #summaryPanel { position: static !important; display: block !important; background: #fff; }
  body.printing-summary #summaryPanel .history-card { box-shadow: none; border: 0; max-height: none; overflow: visible; }
  /* El fondo del lienzo lo pinta :root, no body: en papel debe ser blanco. */
  html, body { background: #fff !important; }
  /* Los fondos de color son PARTE de la información (bandas de grado, rótulos de nivel, cabeceras
     de tabla ámbar): hay que forzar su impresión, no dejarla a criterio del navegador. */
  * { -webkit-print-color-adjust: exact !important; print-color-adjust: exact !important; }
  /* CLAVE: sin esto el min-width de la app (1120px ≈ 296 mm) es más ancho que el papel
     y Chrome reduce toda la hoja para encajarla, encogiendo textos e imágenes. */
  body.printing-ficha, body.printing-summary { min-width: 0 !important; width: auto !important; }
  body.printing-ficha > *:not(#fichaPanel) { display: none !important; }
  body.printing-ficha #fichaPanel { position: static !important; display: block !important; background: #fff; overflow: visible; padding: 0 !important; margin: 0 !important; border: 0 !important; }
  /* Aprovechar todo el papel: sin marco ni ancho máximo, y las imágenes lo más grandes posible. */
  body.printing-ficha #fichaPanel .history-card { box-shadow: none; border: 0; max-width: none !important; width: 100%; max-height: none; overflow: visible; padding: 0; margin: 0; }
  body.printing-ficha .fb-fig img { width: 100%; height: auto; image-rendering: auto; }
  body.printing-ficha .fb-head, body.printing-ficha .sum-table, body.printing-ficha .fb-fig { break-inside: avoid; }
  body.printing-ficha .sum-h { margin: 3mm 0 1.5mm; }
  body.printing-ficha .ficha-orient, body.printing-ficha .ficha-frame { display: none !important; }
  body.printing-ficha .fb-matrix th.mx-c, body.printing-ficha .fb-matrix td { font-size: 8.5px; padding: 1px 3px; }
  body.printing-ficha .fb-camkpi b { font-size: 16px; }
  body.printing-ficha .fb-why { font-size: 9px; }
  /* La hoja se identifica con la barra de proyecto y el nombre: la cabecera del panel no se imprime. */
  body.printing-ficha #fichaPanel .section-title-row, body.printing-ficha #fichaPanel .hint { display: none !important; }
  body.printing-ficha .fb-camline-n { display: none !important; }
  /* Compactación común a los dos formatos: el texto se dimensiona en papel, no en pantalla,
     y no baja de ~2 mm de altura de letra para que siga siendo legible impreso. */
  body.printing-ficha .sum-table th, body.printing-ficha .sum-table td { padding: 1.5px 5px; font-size: 9.5px; line-height: 1.3; }
  body.printing-ficha .fb-sub { font-size: 10.5px; }
  body.printing-ficha .fb-grade-help { font-size: 10.5px; line-height: 1.4; }
  body.printing-ficha .fb-camline { font-size: 11px; }
  body.printing-ficha .fb-legend { font-size: 10px; gap: 3px 12px; }
  body.printing-ficha .fb-gseg { font-size: 7.5px; }
  body.printing-ficha .fb-gscale { font-size: 8.5px; }
  body.printing-ficha .sum-notes { font-size: 10px; line-height: 1.35; margin: 0; padding-left: 5mm; }
  body.printing-ficha .fb-model { font-size: 8.5px; }
  body.printing-ficha .ipi-note { font-size: 9px; line-height: 1.4; }
  body.printing-ficha .ipi-floorline { font-size: 10px; }
  /* Términos técnicos: la glosa nunca se separa del término al partir línea. */
  body.printing-ficha .gl { white-space: normal; }

  /* VERTICAL: los datos fluyen a ancho completo arriba y las dos figuras se reparten
     TODA la altura que sobra, apiladas, para que la hoja quede llena y no salte a una segunda página. */
  body.printing-ficha:not(.printing-ficha-land) .fb-sheet { display: grid; grid-template-rows: auto minmax(0, 1fr); height: 269mm; }
  body.printing-ficha:not(.printing-ficha-land) .fb-col-data { flex: 0 0 auto; }
  body.printing-ficha:not(.printing-ficha-land) .fb-col-figs { display: flex; flex-direction: column; gap: 4mm; flex: 1 1 auto; min-height: 0; }
  /* En vertical las figuras van una al lado de la otra: con poca altura libre, media hoja
     de ancho aprovecha mucho más que el ancho completo (la imagen es más ancha que alta). */
  body.printing-ficha:not(.printing-ficha-land) .fb-figs { display: grid; grid-template-columns: 1fr 1fr; gap: 5mm; flex: 1 1 auto; min-height: 0; margin: 5mm 0 0; }
  body.printing-ficha:not(.printing-ficha-land) .fb-fig { display: flex; flex-direction: column; min-height: 0; }
  body.printing-ficha:not(.printing-ficha-land) .fb-fig img { flex: 1 1 auto; min-height: 0; width: 100%; height: 100%; object-fit: contain; }
  body.printing-ficha:not(.printing-ficha-land) .fb-col-figs .ipi-note { flex: 0 0 auto; margin: 0; font-size: 9px; line-height: 1.4; }

  /* APAISADO: dos columnas. Izquierda los datos, derecha las dos figuras ocupando TODA la altura útil. */
  body.printing-ficha-land .fb-sheet { display: grid; grid-template-columns: 43% 1fr; column-gap: 6mm; align-items: stretch; }
  body.printing-ficha-land .fb-col-figs { display: flex; flex-direction: column; gap: 4mm; height: 181mm; min-height: 0; }
  body.printing-ficha-land .fb-figs { display: flex; flex-direction: column; gap: 4mm; flex: 1 1 auto; min-height: 0; margin: 0; }
  body.printing-ficha-land .fb-fig { display: flex; flex-direction: column; flex: 1 1 0; min-height: 0; }
  body.printing-ficha-land .fb-fig img { flex: 1 1 auto; min-height: 0; width: 100%; height: 100%; object-fit: contain; }
  body.printing-ficha-land .fb-col-figs .ipi-note { flex: 0 0 auto; margin: 0; font-size: 8.5px; line-height: 1.35; }
  /* La columna de datos es estrecha: identificación y grado se apilan en vez de competir por el ancho. */
  body.printing-ficha-land .fb-head { display: block; }
  body.printing-ficha-land .fb-grade { text-align: left; margin-top: 2mm; }
  body.printing-ficha-land .fb-grade-lbl { font-size: 12.5px; padding: 3px 9px; }
  body.printing-ficha-land .fb-grade-score { display: inline-block; margin: 0 0 0 8px; }
  body.printing-ficha-land .fb-grade-help { margin-top: 1.5mm; font-size: 10px; line-height: 1.35; }
  body.printing-ficha-land .fb-name { font-size: 17px; }
  body.printing-ficha-land .fb-sub { font-size: 10px; }
  body.printing-ficha-land .fb-gauge { margin-top: 2.5mm; }
  body.printing-ficha-land .fb-gbar { margin-top: 4.5mm; }
  body.printing-ficha-land .fb-gseg { font-size: 7px; }
  body.printing-ficha-land .fb-gscale { font-size: 8px; }
  body.printing-ficha-land .fb-camline { margin-top: 2mm; font-size: 10.5px; }
  /* Leyenda en columna: cada estado con su glosa en su propia línea, más legible en poco ancho. */
  body.printing-ficha-land .fb-legend { display: block; font-size: 9.5px; line-height: 1.4; margin-bottom: 2mm; }
  body.printing-ficha-land .fb-legend span { display: flex; }
  body.printing-ficha-land .sum-table th, body.printing-ficha-land .sum-table td { padding: 1px 4px; font-size: 9px; line-height: 1.3; }
  body.printing-ficha-land .fb-model { font-size: 8px; }
  body.printing-ficha-land .sum-notes { margin: 0; padding-left: 4mm; font-size: 9.5px; line-height: 1.35; }
  body.printing-ficha-land .fb-bar { height: 12px; }

  /* ---- Informe completo (Bloque 4): una hoja A4 vertical por .rep-pg ---- */
  body.printing-report { min-width: 0 !important; width: auto !important; }
  body.printing-report > *:not(#reportPanel) { display: none !important; }
  body.printing-report #reportPanel { position: static !important; display: block !important; background: #fff; overflow: visible; padding: 0 !important; margin: 0 !important; border: 0 !important; }
  /* V139 · BUG impresión recortada (captura Sergi 02/08/2026): regresión del compositor a pantalla
     completa (V136). Sus reglas tardías (.report-card overflow:hidden + height:100% y la rejilla
     340px del compositor) ganaban a estas por ORDEN de cascada y en papel la tarjeta recortaba el
     documento a la altura de una pantalla. En impresión mandan estas, con !important. */
  body.printing-report #reportPanel .history-card { box-shadow: none; border: 0; max-width: none !important; width: 100% !important; height: auto !important; max-height: none !important; overflow: visible !important; padding: 0; margin: 0; }
  body.printing-report .composer { display: block !important; }
  body.printing-report .comp-left, body.printing-report .composer-foot { display: none !important; }
  body.printing-report .comp-right { overflow: visible !important; padding: 0 !important; background: #fff !important; }
  body.printing-report #reportContent { padding-bottom: 0 !important; }
  body.printing-report #reportPanel .section-title-row, body.printing-report #reportPanel .hint, body.printing-report .rep-opts { display: none !important; }
  body.printing-report #reportContent { display: block; background: #fff; padding: 0; gap: 0; border-radius: 0; }
  /* En papel la hoja tiene ALTURA DEFINIDA (no min-height): así el cuerpo se estira hasta el pie
     y las figuras de las fichas llenan la hoja en vez de quedarse como miniaturas arriba. */
  body.printing-report .rep-pg { width: 100%; height: 269mm; min-height: 0; box-shadow: none; overflow: hidden; break-after: page; page-break-after: always; }
  body.printing-report .rep-pg:last-child { break-after: auto; page-break-after: auto; }
  body.printing-report .rep-hd, body.printing-report .sum-table, body.printing-report .fb-head, body.printing-report .fb-fig, body.printing-report .rep-planfig { break-inside: avoid; }
  #closeSummaryBtn, #printSummaryBtn, #closeFichaBtn, #printFichaBtn, #closeReportBtn, #printReportBtn { display: none !important; }
  @page { margin: 10mm; }
}

/* Leyenda: acordeón por apartados con muestras rectangulares grandes */
.lg-acc { border-bottom: 1px solid #e7ebee; }
.lg-acc:last-child { border-bottom: 0; }
.lg-acc > summary { cursor: pointer; list-style: none; padding: 6px 2px; font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .03em; color: #55606a; user-select: none; }
.lg-acc > summary::-webkit-details-marker { display: none; }
.lg-acc > summary::before { content: '▸'; display: inline-block; width: 12px; color: #9aa4ac; }
.lg-acc[open] > summary::before { content: '▾'; }
.lg-acc-body { padding: 0 2px 8px; }
.lg-row { display: flex; align-items: flex-start; gap: 9px; margin: 6px 0; line-height: 1.3; }
.lg-row b { color: #2b3238; }
.legend i.lg-sw { flex: 0 0 auto; width: 30px; height: 17px; border-radius: 3px; border: 1px solid rgba(0,0,0,.22); margin-top: 1px; box-sizing: border-box; }
.legend i.lg-line { flex: 0 0 auto; width: 30px; height: 17px; border-radius: 0; margin-top: 1px; position: relative; }
.legend i.lg-line::before { content: ''; position: absolute; left: 0; right: 0; top: 50%; border-top-width: 2.5px; border-top-style: solid; }
.lg-cover { background: #2f9b71; }
.lg-seen { background: #e2b22c; }
.lg-blind { background: #59687d; }
/* V311 · la muestra de la leyenda es la de la planta: carmesí rayado (clase 6), no el rojo claro del
   suelo cubierto, que es otra clase y tiene su propia fila. */
.lg-nocam { background: repeating-linear-gradient(45deg, rgba(180,35,47,.75), rgba(180,35,47,.75) 3px, #fff 3px, #fff 8px); }
.lg-ground { background: rgba(217,79,79,.24); }
.lg-zone { background: rgba(181,137,66,.28); border: 1.5px solid #b58942; }
.lg-plane { background: rgba(181,137,66,.16); border: 1.5px dashed #b58942; }
.lg-camsel { background: #d9534f; }
.lg-camoth { background: #71808a; }
.lg-camvis { background: #1c6e93; }
.lg-station { background: #3E4B63; }
.lg-proj { background: linear-gradient(90deg, rgba(54,167,124,.85), rgba(54,167,124,.15)); }
.lg-range { background: #e18b27; }
.lg-rangeout { background: #8d99a1; }
.lg-wall { background: #6b4730; }
.legend i.lg-net { background: #b8862f; border-radius: 50%; width: 17px; }
.lg-line-vis::before { border-top-color: #1c6e93; border-top-style: dashed; }
.lg-line-sec::before { border-top-color: #B4232F; border-top-style: dashed; }
.lg-line-eth::before { border-top-color: #3E4B63; border-top-style: solid; }
.lg-line-fib::before { border-top-color: #2f9b71; border-top-style: solid; }
.lg-line-wl::before { border-top-color: #3E4B63; border-top-style: dotted; }

.ipi-note { font-size: 9.5px; color: #8a949c; line-height: 1.45; margin: 10px 0 0; }
/* Apunte secundario dentro de una celda de tabla del informe (p. ej. la cota de apoyo de un volumen). */
.rep-sub { color: #8a949c; font-size: .88em; white-space: nowrap; }
.metrics { margin: 0; }
.metrics div { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; padding: 7px 0; border-bottom: 1px dashed #e4e9ed; }
.metrics dt { font-size: 12px; color: #677782; }
.metrics dd { margin: 0; font-size: 12px; font-weight: 800; text-align: right; max-width: 165px; }
.empty { padding: 18px 12px; text-align: center; background: #f5f7f9; color: #76838d; border-radius: 8px; font-size: 12px; }
footer { padding: 0 18px 18px; font-size: 11px; color: #687782; }
@media (max-width: 1360px) { body { min-width: 1080px; }.layout { grid-template-columns: 285px minmax(520px, 1fr) 290px; }.slider-number { grid-template-columns: minmax(100px, 1fr) 98px; }.plan-toolbar { align-items: flex-start; } }
.zone-list button.selected { border-color: #8a5b21; background: #fff5e8; color: #654019; }
.zone-dot { background: #b98942; }
.zone-covered-dot { background: #2f9b71; }
.wall-edge-list { display: flex; flex-direction: column; gap: 7px; margin-top: 8px; }
.wall-edge-row { display: grid; grid-template-columns: auto 1fr 82px; gap: 7px; align-items: center; padding: 7px; border: 1px solid #dde5e9; border-radius: 7px; background: #f8fafb; }
.wall-edge-row label { margin: 0; display: flex; align-items: center; gap: 6px; font-size: 11px; }
.wall-edge-row input[type="checkbox"] { width: 15px; height: 15px; margin: 0; }
.wall-edge-row input[type="number"] { margin: 0; padding: 6px; }
.zone-empty { padding: 10px; font-size: 11px; color: #78858d; background: #f5f7f8; border-radius: 7px; text-align: center; }

.profile-toolbar { display:flex; gap:12px; align-items:end; flex-wrap:wrap; padding:9px 12px; border-bottom:1px solid #e2e8ec; background:#f8fafb; }
.profile-toolbar label { margin:0; min-width:180px; }
.profile-toolbar select { margin-top:4px; }
.inline-hint { margin:0 0 7px; }
.handle-label { font-size:10px; }
.plan-canvas.drag-handle { cursor: crosshair; }
.plan-canvas.over-dmax-label { cursor: move; }

/* V10 · organización operativa */
.layout { grid-template-columns: 350px minmax(620px, 1fr) 320px; }
.controls { padding: 0; overflow: hidden; }
.control-group { padding: 18px 16px; }
.control-group + .control-group { border-top: 8px solid #eef2f5 !important; margin-top: 0 !important; padding-top: 18px !important; }
.first-group { padding-top: 16px; }
.group-heading { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 16px; }
.group-heading h2 { margin: 0 0 2px; font-size: 16px; }
.group-heading p { margin: 0; font-size: 11px; color: #75838d; line-height: 1.35; }
.group-number { width: 25px; height: 25px; border-radius: 50%; background: #1c728e; color: white; display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 900; flex: 0 0 auto; }
.subgroup { border-top: 1px solid #e7ecef; margin-top: 16px; padding-top: 14px; }
.subgroup h3 { margin: 0 0 12px; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: #52616b; }
.compact-heading { margin: 4px 0 8px; }
.compact-heading strong { font-size: 12px; color: #43515d; }
.inline-tools { flex-wrap: nowrap; }
.zone-tools-heading { align-items: center; }
.visual-buttons { margin: 8px 0 12px; flex-wrap: wrap; }
textarea { width: 100%; margin-top: 5px; border: 1px solid #cfd8df; border-radius: 7px; padding: 9px; background: white; color: #16202a; resize: vertical; font: inherit; }
.technical-fields input:disabled { background: #f1f5f7; color: #53636d; }
.admin-panel { border-top: 8px solid #eef2f5; padding: 0; }
.admin-panel summary { cursor: pointer; padding: 15px 16px; font-size: 12px; font-weight: 800; color: #344b59; background: #f8fafb; }
.admin-content { padding: 0 16px 18px; }
.admin-content .hint { margin-bottom: 12px; }
.plan-canvas { cursor: grab; }
.plan-canvas.dragging, .profile-canvas.dragging { cursor: grabbing; }
.profile-canvas { cursor: grab; }
.camera-other-dot { background: #2b7ca5; }
.coverage-dot { background: linear-gradient(90deg, #d9534f 0 50%, #2b7ca5 50% 100%); }
.zone-covered-dot { background: #2f9b71; }
.occluded-dot { background: #596c7d; }
.legend i.coverage-dot { border-radius: 2px; }
#forcedIfovField[hidden] { display: none; }
#measurementStatus.measure-active { color: #1c728e; font-weight: 800; }
@media (max-width: 1420px) { .layout { grid-template-columns: 330px minmax(540px, 1fr) 295px; } }

/* V11 · IRTIMfire internal beta */
:root {
  --irtim-red: #b4232f;
  --irtim-red-dark: #8e1721;
  --irtim-orange: #ef7f1a;
  --irtim-charcoal: #171d23;
  --irtim-slate: #384955;
  --irtim-bg: #eef1f3;
}
body { background: var(--irtim-bg); }
.irtim-topbar { display:grid; grid-template-columns:auto minmax(520px,1fr) auto; gap:18px; background:linear-gradient(135deg,#151a20,#222b32); border-bottom:4px solid var(--irtim-red); padding:14px 18px; }
.brand-lockup { display:flex; align-items:center; gap:11px; min-width:210px; }
.brand-mark { width:45px; height:45px; border-radius:10px; background:linear-gradient(145deg,var(--irtim-red),var(--irtim-orange)); display:flex; align-items:center; justify-content:center; color:#fff; font-weight:950; letter-spacing:-.08em; font-size:20px; box-shadow:0 0 0 1px rgba(255,255,255,.18) inset; }
.irtim-topbar .eyebrow { color:#ffb06b; }
.project-bar { display:grid; grid-template-columns:110px 110px minmax(180px,1fr) minmax(190px,1fr) auto; gap:8px; align-items:end; }
.project-bar label { margin:0; color:#dce4e8; font-size:10px; }
.project-bar label span { display:block; margin-bottom:4px; }
.project-bar select,.project-name-input { margin:0; height:36px; background:#fff; border:1px solid #66727b; border-radius:7px; padding:7px 9px; }
.project-status { display:inline-flex; align-items:center; justify-content:center; min-width:86px; height:36px; border-radius:999px; padding:0 12px; background:#39434a; color:#fff; font-size:11px; font-weight:900; }
.project-status.draft { background:#c9a227; }.project-status.finished { background:#3a6958; }
.project-actions { justify-content:flex-end; flex-wrap:wrap; max-width:520px; }
.accent { background:var(--irtim-orange); color:#fff; }.accent:hover { background:#d96c0a; }
.primary { background:var(--irtim-red); }.primary:hover { background:var(--irtim-red-dark); }
input[type="range"] { accent-color:var(--irtim-red); }
.check-row input { accent-color:var(--irtim-red); }
.group-number { background:var(--irtim-red); }
.camera-list button.selected { border-color:var(--irtim-red); background:#fff0f1; color:#761822; }
.visibility-eye { margin-left:auto; font-size:11px; opacity:.75; padding:2px 4px; }
.compact-check { margin:0; font-size:10px; }
.network-add-row { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:8px; align-items:end; margin-bottom:10px; }
.network-add-row select { margin:0; }
.network-mini-icon { min-width:24px; height:24px; border-radius:6px; background:#394b59; color:white; display:inline-flex; align-items:center; justify-content:center; font-weight:900; font-size:10px; }
.visibility-box { padding:10px 11px; border:1px solid #d8e0e5; border-radius:8px; background:#f7f9fa; margin:10px 0 12px; }
.visibility-box strong { display:block; font-size:11px; margin-bottom:7px; text-transform:uppercase; letter-spacing:.05em; color:#56636c; }
.visibility-box .check-row { margin:6px 0; }
.map-controls { padding:9px; background:#f7f9fa; border:1px solid #dce3e8; border-radius:8px; margin-bottom:10px; }
.map-attribution { position:absolute; right:8px; bottom:6px; z-index:3; padding:3px 6px; background:rgba(255,255,255,.9); color:#45545e; font-size:9px; border-radius:4px; }
.network-dot { background:#394b59; }.ethernet-line-dot { background:#34495e; border-radius:2px!important; width:14px!important; height:3px!important; }.fiber-line-dot { background:#7a4ec2; border-radius:2px!important; width:14px!important; height:3px!important; }
.history-panel { position:fixed; inset:0; z-index:100; background:rgba(8,13,17,.66); display:flex; align-items:center; justify-content:center; padding:30px; }
.history-panel[hidden] { display:none; }
.history-card { width:min(900px,92vw); max-height:82vh; overflow:auto; background:#fff; border-radius:14px; padding:20px; box-shadow:0 24px 80px rgba(0,0,0,.3); }
.history-card h3 { margin:18px 0 8px; font-size:13px; text-transform:uppercase; letter-spacing:.05em; color:#57656e; }
.history-entry,.change-entry { border:1px solid #dde4e8; border-left:4px solid var(--irtim-red); border-radius:8px; padding:10px 12px; margin:8px 0; display:grid; grid-template-columns:1fr auto; gap:3px 12px; }
.history-entry span,.change-entry span { font-size:10px; color:#7a858d; }.history-entry p,.change-entry p { grid-column:1/-1; margin:3px 0; font-size:11px; }.history-entry button { justify-self:start; grid-column:1/-1; }
.admin-panel { border-top-color:#f3d8db; }.admin-panel summary { color:#7e1d26; background:#fff5f5; }
.catalog-io { margin-bottom:9px; }
.controls { max-height:calc(100vh - 120px); overflow-y:auto; overflow-x:hidden; padding-bottom:36px; overscroll-behavior:contain; }
.results { max-height:calc(100vh - 120px); overflow-y:auto; overflow-x:hidden; padding-bottom:36px; overscroll-behavior:contain; }
.legend { max-height:88px; overflow:auto; }
@media (max-width:1700px) { .irtim-topbar { grid-template-columns:220px 1fr; }.project-actions { grid-column:1/-1; max-width:none; justify-content:flex-start; }.project-bar { grid-template-columns:100px 100px 1fr 1fr auto; } }

/* V12 · UX workflow beta */
.workflow-group { padding:0; border-top:8px solid #eef2f5; }
.workflow-group[open] { padding-bottom:16px; }
.workflow-summary { margin:0; padding:16px; cursor:pointer; list-style:none; user-select:none; }
.workflow-summary::-webkit-details-marker { display:none; }
.workflow-summary::after { content:'▾'; margin-left:10px; color:#6d7b85; font-size:15px; transition:transform .15s ease; align-self:center; }
.group-status { margin-left:auto; align-self:center; font-size:10.5px; font-weight:800; color:#4a5a64; background:#eef2f4; border:1px solid #dbe3e7; border-radius:999px; padding:3px 9px; white-space:nowrap; }
.group-status:empty { display:none; }
.group-status.warn { color:#8a6d1c; background:var(--irtim-yellow-soft); border-color:#eeddb4; }
.toggle-item { display:flex; align-items:center; gap:8px; cursor:pointer; }
.toggle-item input { width:auto; margin:0; }
.toggle-item span { font-size:12px; font-weight:700; color:#2a2f35; }
.workflow-group:not([open]) .workflow-summary::after { transform:rotate(-90deg); }
.workflow-group > :not(summary) { margin-left:16px; margin-right:16px; }
.project-bar { grid-template-columns:110px 110px minmax(220px,1fr) auto minmax(165px,auto); }
.project-storage-hint { align-self:center; color:#b8c5cc; font-size:10px; line-height:1.2; max-width:190px; }
.projects-card { width:min(980px,94vw); }
.project-library-item { border:1px solid #dbe3e8; border-left:4px solid var(--irtim-red); border-radius:9px; padding:12px; margin:9px 0; display:grid; grid-template-columns:1fr auto; gap:6px 14px; align-items:center; }
.project-library-item h3 { margin:0; font-size:14px; color:#26353f; text-transform:none; letter-spacing:0; }
.project-library-meta { font-size:11px; color:#6c7880; }
.project-library-actions { display:flex; gap:7px; flex-wrap:wrap; grid-row:1/3; grid-column:2; }
.canvas-toolbar { position:absolute; z-index:8; top:10px; left:50%; transform:translateX(-50%); display:flex; align-items:center; gap:4px; padding:5px; background:rgba(24,30,36,.88); border:1px solid rgba(255,255,255,.18); border-radius:10px; box-shadow:0 5px 18px rgba(0,0,0,.25); backdrop-filter:blur(6px); }
.canvas-toolbar button { width:34px; height:32px; padding:0; border-radius:7px; color:#f4f7f9; background:transparent; font-size:15px; }
.canvas-toolbar button:hover { background:rgba(255,255,255,.13); }
.canvas-toolbar button.active { background:var(--irtim-red); color:#fff; }
.toolbar-divider { width:1px; height:21px; background:rgba(255,255,255,.22); margin:0 3px; }
.map-search-row { display:grid; grid-template-columns:1fr auto; gap:7px; margin-bottom:8px; }
.map-search-row input { margin:0; }
.map-search-results { max-height:150px; overflow:auto; margin-bottom:7px; }
.map-search-result { width:100%; display:block; text-align:left; background:#fff; border:1px solid #d9e1e6; color:#263842; padding:7px 8px; margin:4px 0; border-radius:6px; font-size:11px; font-weight:600; }
.map-search-result:hover { border-color:var(--irtim-red); background:#fff5f5; }
.plan-canvas.calibrating { cursor:crosshair !important; }
.plan-canvas.placing-plan { cursor:move !important; }

/* V91 · lista de planos del proyecto (multiplano) */
.plan-list { display:flex; flex-direction:column; gap:4px; margin:6px 0 2px; }
.plan-row { display:flex; align-items:center; gap:7px; padding:5px 7px; border:1px solid #dfe3ea; border-radius:7px; background:#fbfbfc; }
.plan-row.active { border-color:#F1C02E; background:#fffaf0; box-shadow:inset 0 0 0 1px rgba(241,192,46,.35); }
.plan-row-main { display:flex; flex-direction:column; gap:2px; flex:1 1 auto; min-width:0; }
.plan-row .plan-name { font-size:12px; font-weight:600; color:#141414; border:1px solid transparent; background:transparent; border-radius:4px; padding:1px 3px; width:100%; min-width:0; }
.plan-row .plan-name:hover { border-color:#dfe3ea; background:#fff; }
.plan-row .plan-name:focus { border-color:#F1C02E; background:#fff; outline:none; }
.plan-row-meta { font-size:10px; color:#6b7280; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.plan-row-actions { display:flex; align-items:center; gap:3px; flex:0 0 auto; }
.plan-row-actions button { padding:2px 6px; font-size:10px; line-height:1.5; }
.plan-eye { flex:0 0 auto; margin:0; }
.calibration-notice { pointer-events:none; }
@media (max-width:1700px) { .project-bar { grid-template-columns:100px 100px minmax(220px,1fr) auto; }.project-storage-hint { display:none; } }

/* V13 · Identidad corporativa IRTIM + cabecera compacta */
:root {
  --irtim-yellow: #F1C02E;
  --irtim-yellow-dark: #D8A81B;
  --irtim-yellow-soft: #FBF1DA;
  --irtim-ink: #141414;
  --irtim-navy: #3E4B63;
  --irtim-cream: #FDFAF3;
  --irtim-red: #B4232F; /* reservado para peligro */
}
.irtim-topbar { display:flex; align-items:center; gap:18px; grid-template-columns:none; background:var(--irtim-cream); color:var(--irtim-ink); border-bottom:3px solid var(--irtim-yellow); padding:8px 16px; min-height:56px; box-shadow:0 2px 10px rgba(20,20,20,.06); }
.brand-lockup { min-width:auto; gap:10px; }
.brand-logo { height:32px; width:auto; display:block; }
.brand-text .eyebrow { color:var(--irtim-navy); letter-spacing:.14em; font-size:9px; margin:0; }
.irtim-topbar .eyebrow { color:var(--irtim-navy); }
.project-bar { display:flex; flex:1 1 auto; grid-template-columns:none; align-items:center; gap:10px; min-width:0; }
/* V227 · el título del documento se PARECE a un título: sin borde ni fondo hasta que se pasa por
   encima o se enfoca. Así hay una sola pista —«esto se puede tocar»— y no dos afordancias para lo
   mismo. Al enfocar sí toma forma de campo, que es lo que dice «ahora estás escribiendo». */
.project-name-input { flex:1 1 220px; min-width:140px; max-width:420px; height:34px; border:1px solid transparent; background:transparent; font-weight:700; font-size:15px; color:#1d2731; }
.project-name-input:hover:not(:focus) { border-color:#d8cfb8; background:#fffdf6; cursor:text; }
.project-name-input:focus { border-color:#F1C02E; background:#fff; font-weight:600; }
.project-name-input::placeholder { font-weight:500; color:#8a949c; }
.project-status { min-width:auto; height:26px; padding:0 11px; font-size:10px; background:var(--irtim-navy); }
.project-status.draft { background:#c9a227; } .project-status.finished { background:#3a6958; }
.project-storage-hint { color:#8a8271; font-size:10px; max-width:none; cursor:help; }
.top-menus { display:flex; gap:8px; align-items:center; }
.top-quick { display:inline-flex; gap:4px; align-items:center; margin-right:2px; }
.quick-btn { width:34px; height:34px; padding:0; display:inline-flex; align-items:center; justify-content:center; font-size:16px; font-weight:800; line-height:1; color:var(--irtim-ink); background:#fff; border:1px solid #e2d9c4; border-radius:8px; cursor:pointer; }
.quick-btn:hover:not(:disabled) { background:var(--irtim-yellow-soft); border-color:var(--irtim-yellow-dark); }
.quick-btn:disabled { opacity:.38; cursor:default; }
.menu-item .menu-shortcut { margin-left:auto; padding-left:14px; font-size:10px; font-weight:700; color:#9a927f; letter-spacing:.02em; }
.menu { position:relative; }
.menu > summary { list-style:none; cursor:pointer; user-select:none; padding:8px 12px; border-radius:8px; font-weight:800; font-size:12px; color:var(--irtim-ink); background:#fff; border:1px solid #e2d9c4; white-space:nowrap; }
.menu > summary::-webkit-details-marker { display:none; }
.menu[open] > summary { background:var(--irtim-yellow); border-color:var(--irtim-yellow-dark); }
.menu-panel { position:absolute; right:0; top:calc(100% + 6px); z-index:60; min-width:250px; background:#fff; border:1px solid #e0d8c4; border-radius:10px; box-shadow:0 14px 40px rgba(20,20,20,.16); padding:6px; display:flex; flex-direction:column; }
.menu-item { display:flex; width:100%; justify-content:flex-start; text-align:left; background:transparent; color:#2a2f35; font-weight:700; font-size:12px; padding:9px 10px; border-radius:7px; }
.menu-item:hover { background:var(--irtim-yellow-soft); }
.menu-item.strong { color:#141414; background:var(--irtim-yellow-soft); border:1px solid #eeddb4; margin:2px 0; }
.menu-item.strong:hover { background:var(--irtim-yellow); }
.menu-sep { height:1px; background:#eee5d0; margin:5px 4px; }
.menu-field { margin:6px 8px; font-size:10px; color:#5c5646; }
.menu-field select { margin-top:4px; }
.menu-field input[type="text"] { margin-top:4px; width:100%; }
/* V96 · pie de menú: estado de la revisión y aclaraciones de un campo. No es interactivo. */
.menu-note { margin:2px 10px 6px; font-size:10px; line-height:1.35; color:#8a8271; }
#revisionHint { font-weight:700; color:#5c4708; }
.optional-tag { font-weight:600; font-size:10px; color:#8a8271; text-transform:uppercase; letter-spacing:.05em; }
/* acentos corporativos */
.primary { background:var(--irtim-ink); color:#fff; } .primary:hover { background:#2c2c2c; }
.accent { background:var(--irtim-yellow); color:#141414; } .accent:hover { background:var(--irtim-yellow-dark); }
input[type="range"] { accent-color:var(--irtim-yellow-dark); }
.check-row input { accent-color:var(--irtim-yellow-dark); }
.group-number { background:var(--irtim-ink); color:var(--irtim-yellow); }
.group-heading h2, h2 { color:var(--irtim-navy); }
.camera-list button.selected { border-color:var(--irtim-yellow-dark); background:#fdf4dd; color:#5c4708; }
.zone-list button.selected { border-color:var(--irtim-yellow-dark); background:#fdf4dd; color:#5c4708; }
.canvas-toolbar button.active { background:var(--irtim-yellow); color:#141414; }
.history-entry, .change-entry, .project-library-item { border-left-color:var(--irtim-yellow); }
.map-search-result:hover { border-color:var(--irtim-yellow-dark); background:var(--irtim-yellow-soft); }
.admin-panel summary { color:#5c4708; background:var(--irtim-yellow-soft); }
.admin-panel { border-top-color:#f0e3c2; }
@media (max-width:1500px) { .project-storage-hint { display:none; } .brand-text { display:none; } }

/* V14 · cursores de herramienta */
.plan-canvas.drawing-zone, .plan-canvas.drawing-wall, .plan-canvas.measuring { cursor: crosshair !important; }

/* V15 · herramientas en cabecera de vista, maximizar, estaciones PT */
.view-tools { display:flex; align-items:center; gap:3px; padding:3px 5px; background:#f2f4f6; border:1px solid #dfe6ea; border-radius:9px; }
.view-tools button { width:30px; height:28px; padding:5px; border-radius:6px; background:transparent; color:#43525c; display:inline-flex; align-items:center; justify-content:center; }
.view-tools button svg { width:16px; height:16px; display:block; }
.view-tools button:hover { background:#e2e8ec; }
.view-tools button.active { background:var(--irtim-yellow); color:#141414; }
.view-tools .toolbar-divider { width:1px; height:18px; background:#d5dde2; margin:0 2px; }
.view-heading { flex-wrap:wrap; gap:8px; }
/* Maximizar una vista (planta o perfil) a PANTALLA COMPLETA: ancho y alto totales. */
.view-block.maximized { position:fixed; inset:0; z-index:95; margin:0; border-radius:0; box-shadow:none; display:flex; flex-direction:column; background:#fff; }
.view-block.maximized .canvas-shell { flex:1 1 auto; min-height:0; }
.view-block.maximized .plan-canvas, .view-block.maximized .profile-canvas { height:100% !important; }
.max-btn.active { background:var(--irtim-yellow,#F1C02E); border-radius:6px; }
.appearance-card { width:min(460px, 92vw); }
.appearance-grid { display:flex; flex-direction:column; gap:6px; margin-top:6px; }
.color-row { display:flex; align-items:center; gap:12px; margin:0; padding:7px 8px; border:1px solid #e7ecef; border-radius:8px; font-weight:700; font-size:12px; color:#3a4650; }
.color-row input[type="color"] { width:40px; height:26px; margin:0; padding:0; border:1px solid #cfd8df; border-radius:6px; background:#fff; cursor:pointer; flex:0 0 auto; }
.score-card { width:min(460px, 92vw); max-height:86vh; }
.score-card h3 { margin:16px 0 6px; font-size:11px; text-transform:uppercase; letter-spacing:.05em; color:#57656e; }
.score-grid { display:grid; grid-template-columns:1fr 1fr; gap:6px; }
.score-row { display:flex; align-items:center; justify-content:space-between; gap:8px; margin:0; padding:6px 9px; border:1px solid #e7ecef; border-radius:8px; font-weight:700; font-size:11.5px; color:#3a4650; }
.score-row .inline-input { flex:0 0 auto; }
.score-row .inline-input input { width:56px; }
.station-list { max-height:130px; }
.station-list button.selected { border-color:var(--irtim-yellow-dark); background:#fdf4dd; color:#5c4708; }
.plan-canvas.sectioning { cursor: crosshair !important; }

/* V16 */
.collapsible-subgroup { border-top:1px solid #e7ecef; margin-top:16px; padding-top:0; }
.collapsible-subgroup > summary { list-style:none; cursor:pointer; padding:12px 0 10px; user-select:none; display:flex; align-items:center; }
.collapsible-subgroup > summary::-webkit-details-marker { display:none; }
.collapsible-subgroup > summary h3 { margin:0; }
.collapsible-subgroup > summary::after { content:'▾'; margin-left:auto; color:#8b98a1; font-size:12px; transition:transform .15s ease; }
.collapsible-subgroup:not([open]) > summary::after { transform:rotate(-90deg); }
.eye-btn { margin-left:auto; display:inline-flex; padding:2px 3px; border-radius:5px; background:transparent; opacity:.8; }
.eye-btn:hover { background:#e8eef2; }
.eye-btn svg { width:15px; height:15px; display:block; }
.profile-toolbar label { min-width:150px; }

/* V17 · espacio de trabajo: paneles plegables + reparto vertical ajustable */
.layout { position:relative; grid-template-columns: 350px minmax(520px, 1fr) 320px; }
body.collapse-left .layout { grid-template-columns: 0 minmax(520px,1fr) 320px; }
body.collapse-right .layout { grid-template-columns: 350px minmax(520px,1fr) 0; }
body.collapse-left.collapse-right .layout { grid-template-columns: 0 minmax(520px,1fr) 0; }
/* colocación explícita: con display:none la autocolocación del grid desplazaría el workspace a la columna 0 */
.layout > .controls { grid-column: 1; }
.layout > .workspace { grid-column: 2; }
.layout > .results { grid-column: 3; }
body.collapse-left .controls, body.collapse-right .results { display:none; }
.side-toggle { position:fixed; top:50%; transform:translateY(-50%); z-index:40; width:18px; height:64px; padding:0; border-radius:0 8px 8px 0; background:var(--irtim-ink); color:var(--irtim-yellow); font-size:12px; font-weight:900; opacity:.75; }
.side-toggle:hover { opacity:1; }
.side-toggle-left { left:0; }
.side-toggle-right { right:0; border-radius:8px 0 0 8px; }
.workspace { height: calc(100vh - 86px); min-height:420px; }
.view-block { display:flex; flex-direction:column; min-height:110px; }
.view-block:not(.profile-block) { flex: var(--plan-share, 62) 1 0; }
.profile-block { flex: var(--profile-share, 38) 1 0; }
.canvas-shell { flex:1 1 auto; min-height:0; }
.plan-canvas, .profile-canvas { height:100% !important; }
.split-divider { flex:0 0 8px; margin:2px 0; border-radius:4px; background:linear-gradient(90deg, transparent 15%, #d8dee3 15%, #d8dee3 85%, transparent 85%); cursor:ns-resize; position:relative; }
.split-divider::after { content:'⋯'; position:absolute; left:50%; top:50%; transform:translate(-50%,-56%); color:#7d8b94; font-size:14px; letter-spacing:2px; }
.split-divider:hover { background:linear-gradient(90deg, transparent 15%, var(--irtim-yellow) 15%, var(--irtim-yellow) 85%, transparent 85%); }
.view-heading { min-height:38px; padding:5px 12px; }
.view-heading strong { font-size:12px; }
.view-heading span { font-size:10px; }
.plan-canvas.connecting { cursor: crosshair !important; }
.legend { max-height:74px; font-size:10px; padding:6px 9px; }
@media (max-width:1500px) { body:not(.collapse-left) .layout { grid-template-columns: 320px minmax(480px,1fr) 300px; } }


/* === V17 · conexiones y listas === */
#canvas.connecting { cursor: crosshair; }
.vis-delete { color: #B4232F; font-weight: 700; margin-left: 4px; }
.vis-delete:hover { color: #7d1620; }
.project-library-actions .danger.small { margin-left: 4px; }
.history-entry .danger.small { margin-left: 6px; }

.legend .wireless-line-dot { display:inline-block; width:18px; height:0; border-top: 2px dotted #3E4B63; vertical-align: middle; margin-right:5px; }
.legend .visible-line-dot { display:inline-block; width:18px; height:0; border-top: 2px dashed #1c6e93; vertical-align: middle; margin-right:5px; }


/* === V18 === */
.legend-flyout { position: absolute; left: 10px; bottom: 10px; z-index: 6; max-width: 300px; background: rgba(255,255,255,.96); border: 1px solid #d8dfe5; border-radius: 9px; box-shadow: 0 4px 14px rgba(23,35,45,.12); font-size: 11px; }
.legend-flyout summary { cursor: pointer; padding: 5px 12px; font-weight: 700; color: #3E4B63; user-select: none; list-style: none; }
.legend-flyout summary::before { content: '▸ '; }
.legend-flyout[open] summary::before { content: '▾ '; }
.legend-flyout .legend-body { display: flex; flex-direction: column; gap: 4px; padding: 2px 12px 10px; max-height: 300px; overflow: auto; position: static; border: 0; box-shadow: none; background: transparent; }
.legend-flyout .legend-body span { display: flex; align-items: center; gap: 6px; }
.plan-shell { position: relative; }
.plan-shell .map-attribution { position: absolute; right: 8px; bottom: 6px; font-size: 10px; color: #5c6a75; background: rgba(255,255,255,.8); padding: 1px 6px; border-radius: 4px; }
.legend .visible-cam-dot { display:inline-block; width:10px; height:10px; border-radius:3px; background:#1c6e93; }
.legend .wall-dot { display:inline-block; width:16px; height:5px; background:#6b4730; border-radius:2px; }
.legend .section-dot { display:inline-block; width:18px; height:0; border-top:2px dashed #B4232F; }
.legend .station-dot { display:inline-block; width:11px; height:11px; border-radius:50%; background:#3E4B63; color:#fff; font-size:7px; font-weight:700; text-align:center; line-height:11px; }
.legend .station-dot::after { content:'E1'; }

.profile-source-row { display: flex; gap: 6px; align-items: center; margin-left: 10px; }
.profile-source-row select { font-size: 11px; padding: 3px 6px; border: 1px solid #ccd5db; border-radius: 6px; background: #fff; max-width: 210px; }
.profile-source-row select:disabled { opacity: .45; }
.view-heading { min-height: 0; }

.history-card.threed-card { max-width: 1160px; width: min(96vw, 1160px); }
/* V304 · esta regla es de la MODAL y solo de ella. Suelta gobernaba también el lienzo del panel
   del área de trabajo, y un alto fijo dentro de una caja que se mide por su contenido es media
   circularidad. */
#threeDPanel #threeDCanvas { width: 100%; height: min(66vh, 640px); border: 1px solid #dfe5ea; border-radius: 8px; background: linear-gradient(#f6f9fb, #eef3f6); cursor: grab; touch-action: none; }
#threeDCanvas.orbiting { cursor: grabbing; }
.sync3d-note { margin: 10px 2px 0; font-size: 11px; font-weight: 700; color: #2f9b6f; display: flex; align-items: center; gap: 6px; }
.sync3d-note[hidden] { display: none; }
/* Modo "ventana aparte": solo se muestra el 3D, a pantalla completa, sincronizado en vivo. */
body.solo3d > header.topbar, body.solo3d > .layout, body.solo3d .side-toggle { display: none !important; }
body.solo3d #threeDPanel { position: fixed; inset: 0; z-index: 10; background: #0d1216; padding: 12px; }
body.solo3d #threeDPanel .history-card.threed-card { width: 100%; max-width: none; height: 100%; max-height: none; display: flex; flex-direction: column; margin: 0; }
body.solo3d #threeDCanvas { flex: 1 1 auto; height: auto; min-height: 0; }
body.solo3d #open3DWindowBtn, body.solo3d #close3DBtn { display: none; }

textarea#networkNotes { width: 100%; font: inherit; font-size: 12px; padding: 6px 8px; border: 1px solid #ccd5db; border-radius: 7px; resize: vertical; }

/* iconos por cámara: tres conmutadores */
.camera-flags { display: inline-flex; gap: 2px; margin-left: auto; }
.camera-flags .flag-btn { width: 20px; height: 18px; display: inline-flex; align-items: center; justify-content: center; border-radius: 4px; color: #7d8b96; }
.camera-flags .flag-btn.on { color: #3E4B63; background: #eef2f6; }
.camera-flags .flag-btn:hover { background: #e4eaef; }
/* V313 · flechas de reordenar (cámaras y elementos). Discretas: se leen al pasar por la fila. */
.ord-flags { display: inline-flex; gap: 1px; margin-left: 2px; }
.ord-flags .flag-btn { width: 16px; height: 18px; display: inline-flex; align-items: center; justify-content: center; border-radius: 4px; color: #7d8b96; font-size: 11px; cursor: pointer; }
.ord-flags .flag-btn:hover { background: #e4eaef; color: #3E4B63; }
.ord-flags .flag-btn.off { opacity: .25; pointer-events: none; }

[hidden] { display: none !important; }

.attached-vis-row { margin-left: 16px; width: calc(100% - 16px); opacity: .92; font-size: 11px; padding-top: 4px; padding-bottom: 4px; }

/* V37 · controles de edición en planta (snap + dimensiones/rotación de zona) */
.toolbar-select{height:26px;border:1px solid var(--line,#d9d2c4);border-radius:7px;background:#fff;font-size:11px;color:#3a3a3a;padding:0 4px;margin:0 2px;cursor:pointer}
#toolbarSnap.active{background:#F1C02E;color:#141414;border-color:#F1C02E}
.zone-dims{display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin:6px 0}
.zone-dims label{font-size:11px}
.zone-dims.poly #zoneWidthField,.zone-dims.poly #zoneDepthField{opacity:.45;pointer-events:none}

/* V89 · alta de cámara IR: se pregunta modelo, orientación, visible y criterio de
   dimensionado antes de crear la cámara. Reutiliza .history-panel/.history-card
   (no <dialog>) para no depender de showModal. */
.history-card.newcam-card { width: min(520px, 92vw); }
.newcam-card label { display: block; margin: 10px 0 0; font-size: 11px; }
.newcam-card .hint { margin: 4px 2px 0; }
.newcam-card .button-row.newcam-actions { margin-top: 16px; display: flex; justify-content: flex-end; gap: 8px; }

/* V92 · F2 · «Zona de destino»: el desplegable que decide dentro de qué zona nace cada elemento que
   se dibuje. Se coloca inmediatamente antes de los botones de geometría —y se marca con el ámbar de
   la casa— porque la elección tiene que hacerse ANTES de trazar; llevarla a una ventana emergente
   en mitad del dibujo interrumpiría el trabajo en cada elemento. */
.zone-active-field { display: block; margin: 2px 0 6px; font-size: 11px; }
.zone-active-field select { width: 100%; height: 28px; margin-top: 3px; border: 1px solid #F1C02E;
  border-radius: 7px; background: #fffdf7; font-size: 12px; color: #3a3a3a; padding: 0 6px; cursor: pointer; }
#activeZoneNew { width: 100%; height: 28px; margin: 0 0 6px; border: 1px solid #F1C02E; border-radius: 7px;
  background: #fff; font-size: 12px; padding: 0 8px; }
.zone-group-tag { display: inline-block; margin-left: 6px; padding: 0 5px; border-radius: 6px;
  background: #efe3c6; color: #6b5426; font-size: 10px; vertical-align: 1px; }

/* V109 · C-S21 · buscador de los desplegables largos (modelo, tarifa, catálogo) */
.select-search {
  display: block;
  width: 100%;
  margin: 2px 0 4px;
  padding: 5px 8px;
  font-size: 12px;
  border: 1px solid var(--border, #cdd5da);
  border-radius: 6px;
  background: var(--panel, #fff);
  color: inherit;
  box-sizing: border-box;
}
.select-search:focus { outline: 2px solid #F1C02E33; border-color: #F1C02E; }


/* ===== V112 · C-S22 · buscador integrado en los desplegables (combobox) ===== */
.combo-host { position: relative; }
.combo-panel { position: absolute; z-index: 80; left: 0; right: 0; top: 100%; margin-top: 2px; background: #fff; border: 1px solid #c9ccd1; border-radius: 8px; box-shadow: 0 8px 22px rgba(20, 20, 20, .16); }
.combo-search { padding: 6px; border-bottom: 1px solid #e4e6e9; }
.combo-search .combo-input { width: 100%; box-sizing: border-box; margin: 0; }
.combo-list { max-height: 240px; overflow: auto; padding: 4px 0; }
.combo-opt { display: block; width: 100%; text-align: left; padding: 5px 10px; background: none; border: 0; cursor: pointer; font: inherit; color: inherit; }
.combo-opt:hover { background: #f4f1e8; }
.combo-opt.sel { background: #f7edd2; font-weight: 600; }
.combo-group { padding: 6px 10px 2px; font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; color: #8a8d8a; }

/* ===== V112 · barras de encuadre de la ficha: una sola linea + barra Vista propia ===== */
.ficha-frame { flex-wrap: nowrap; white-space: nowrap; overflow-x: auto; }
.ficha-frame .ficha-fbtn { padding: 1px 7px; }
.ficha-frame-hint { font-size: 10px; color: #8a8d8a; margin-left: auto; padding-left: 8px; }
.fb-viewbar { justify-content: flex-end; margin-bottom: 4px; }
.fb-fig img { cursor: grab; }
.fb-fig img:active { cursor: grabbing; }

/* ===== V113 · vista previa del arrastre en la ficha ===== */
.fb-fig { overflow: hidden; }


/* ===== V117 · logo IRTIMfire real (linea de imagen irtim.cloud) ===== */
.brand-logo { height: 34px; width: auto; display: block; }
.rep-logo { height: 8mm; width: auto; display: block; }
.rep-logo-big { height: 13mm; width: auto; display: block; }
.fb-logo { height: 15px; width: auto; display: inline-block; vertical-align: -3px; margin-right: 7px; }

/* ─── V118 · barra de estado, tira de pasos del panel plegado y modo presentación ─── */
.statusbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 35; display: flex; align-items: center; gap: 18px; padding: 4px 14px; background: var(--irtim-ink); color: #ececec; font-size: 12px; line-height: 1.3; }
.statusbar .hint { margin: 0; color: #c9c9c9; font-size: 12px; }
.statusbar .hint.measure-active { color: var(--irtim-yellow); font-weight: 700; }
.statusbar-spacer { flex: 1; }
.statusbar-ver { opacity: .6; }
body > footer { margin-bottom: 34px; }
body.solo3d .statusbar { display: none !important; }

.side-strip { display: none; position: fixed; left: 0; top: 108px; z-index: 39; flex-direction: column; gap: 6px; padding: 8px 5px; background: var(--irtim-ink); border-radius: 0 10px 10px 0; opacity: .9; }
.side-strip:hover { opacity: 1; }
body.collapse-left .side-strip { display: flex; }
.side-strip button { width: 30px; height: 30px; border: none; border-radius: 8px; background: transparent; color: var(--irtim-yellow); font-size: 14px; font-weight: 900; cursor: pointer; }
.side-strip button:hover { background: rgba(255,255,255,.16); }

body.presentation > header.topbar,
body.presentation .controls,
body.presentation .results,
body.presentation .side-toggle,
body.presentation .side-strip,
body.presentation > footer { display: none !important; }
body.presentation .layout { grid-template-columns: 0 minmax(520px,1fr) 0; }
#toolbarPresentation.active { background: var(--irtim-yellow); }

/* ─── V119 · panel contextual (Lote C), toolbar de creación (Lote D) e informe (Lote E) ─── */
.context-panel { position: fixed; right: 348px; top: 96px; z-index: 38; width: 330px; max-height: calc(100vh - 150px); overflow-y: auto; background: #fff; border: 1px solid #d5dade; border-top: 3px solid var(--irtim-yellow); border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.18); }
.context-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px; border-bottom: 1px solid #e6eaee; position: sticky; top: 0; background: #fff; z-index: 1; }
.context-head strong { font-size: 13px; }
.context-head button { border: none; background: transparent; font-size: 14px; cursor: pointer; color: #5a646c; padding: 2px 6px; border-radius: 6px; }
.context-head button:hover { background: #f0f2f4; color: #141414; }
.context-body { padding: 8px 10px 12px; }
.context-body .subgroup, .context-body details.subgroup { margin-top: 8px; }
body.collapse-right .context-panel { right: 14px; }
@media (max-width:1500px) { body:not(.collapse-right) .context-panel { right: 328px; } }
body.presentation .context-panel, body.solo3d .context-panel { display: none !important; }

.view-tools-sep { display: inline-block; width: 1px; height: 16px; background: #cfd6db; margin: 0 3px; vertical-align: middle; }
.view-tools .tool-create { font-weight: 700; }
.view-tools .tool-create-zone { color: #8a6a00; }

.rep-obs-warn { border-left: 3px solid #F1C02E; background: #fdf6e3; padding: 1mm 2mm; margin: 1mm 0; color: #6b5200; }
.rep-obs-crit { border-left: 3px solid #c0392b; background: #fdeeec; padding: 1mm 2mm; margin: 1mm 0; color: #8f2013; font-weight: 700; }
.rep-cover-obs { margin-top: 2mm; }
.rep-bom-total { text-align: right; font-size: 11px; margin: 2mm 0; }
.rep-num { text-align: right; }

/* ─── V120 · panel único compacto (estilo paleta AutoCAD) ─── */
/* la rejilla pierde la tercera columna: el aside de resultados vive DENTRO del panel izquierdo */
main.layout { grid-template-columns: 300px minmax(0,1fr); }
#toggleRightPanel, .side-toggle-right { display: none !important; }
aside.panel.controls { width: 300px; min-width: 300px; font-size: 11px; }

/* pestañas de paso */
.step-tabs { display: flex; gap: 2px; padding: 5px 6px; background: #f2f4f6; border-bottom: 1px solid #d7dce0; position: sticky; top: 0; z-index: 5; }
.step-tabs button { flex: 1; border: 1px solid #d7dce0; background: #fff; border-radius: 6px; padding: 2px 0 1px; font-size: 9px; color: #68727a; cursor: pointer; line-height: 1.15; }
.step-tabs button b { display: block; font-size: 12px; color: #20262b; }
.step-tabs button.on { background: var(--irtim-ink, #141414); border-color: var(--irtim-ink, #141414); color: #ddd; }
.step-tabs button.on b { color: #F1C02E; }
.step-tabs .group-status { display: block; font-size: 8px; font-weight: 400; letter-spacing: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 54px; margin: 0 auto; }

/* los pasos pierden su cabecera grande: mandan las pestañas */
.controls .workflow-group > summary.workflow-summary { display: none; }
.controls .workflow-group { border-bottom: 1px solid #e2e6ea; }
.controls .workflow-group:not([open]) { display: none; }

/* compactación tipográfica del panel (paleta) */
.controls label { font-size: 11px; margin: 4px 0 2px; }
.controls input[type="text"], .controls input[type="number"], .controls select, .controls textarea { font-size: 11px; padding: 2px 5px; min-height: 22px; }
.controls .hint { font-size: 10px; line-height: 1.3; margin: 3px 0; color: #7b858d; }
.controls h3 { font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase; margin: 6px 0 3px; }
.controls .button-row button, .controls button.small { font-size: 10.5px; padding: 3px 7px; }
.controls .camera-list > *, .controls .zone-list > * { padding: 2px 4px; font-size: 11px; }
.controls details.collapsible-subgroup > summary { padding: 3px 4px; }

/* bloque PROPIEDADES acoplado (antes flotante V119) */
.context-panel.docked { position: static; width: auto; max-height: none; box-shadow: none; border: 0; border-top: 3px solid #F1C02E; border-bottom: 1px solid #d7dce0; border-radius: 0; overflow: visible; }
.context-panel.docked .context-head { padding: 4px 8px; }
.context-panel.docked .context-head strong { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; }
@media (max-width:1500px) { body:not(.collapse-right) .context-panel.docked { right: auto; } }

/* bloque RESULTADOS acoplado: el aside pierde su piel de columna */
.results-block > summary.results-heading { display: flex; align-items: center; gap: 6px; padding: 4px 8px; background: #f2f4f6; border-top: 3px solid #F1C02E; cursor: pointer; }
.results-block .rb-title { font-size: 10.5px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; flex: 1; }
.undock-btn { border: 1px solid #d7dce0; background: #fff; border-radius: 4px; width: 22px; height: 20px; font-size: 11px; cursor: pointer; color: #68727a; }
.undock-btn:hover { background: #fff6dd; }
#resultsHost aside.panel.results, .float-body aside.panel.results { position: static; width: auto; min-width: 0; max-width: none; border: 0; box-shadow: none; padding: 4px 8px 8px; overflow: visible; font-size: 11px; }
#resultsHost .results h2, .float-body .results h2 { font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; margin: 8px 0 3px; }
#resultsHost .results table, .float-body .results table { font-size: 10.5px; }

/* tarjeta flotante arrastrable */
.float-card { position: fixed; right: 24px; top: 60px; width: 300px; max-height: calc(100vh - 120px); overflow-y: auto; background: #fff; border: 1px solid #d5dade; border-top: 3px solid #F1C02E; border-radius: 10px; box-shadow: 0 12px 32px rgba(0,0,0,.24); z-index: 38; }
.float-head { display: flex; align-items: center; gap: 7px; padding: 5px 9px; background: #f2f4f6; cursor: grab; position: sticky; top: 0; z-index: 1; border-radius: 8px 8px 0 0; user-select: none; touch-action: none; }
.float-head:active { cursor: grabbing; }
.float-head strong { font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; }
.float-grip { color: #9aa4ab; letter-spacing: 2px; }
.fh-sp { flex: 1; }
#floatDockBtn { border: 1px solid #d7dce0; background: #fff; border-radius: 4px; width: 22px; height: 20px; font-size: 11px; cursor: pointer; color: #68727a; }
body.presentation .float-card, body.solo3d .float-card { display: none !important; }

/* ─── V121 · dock de TRES tarjetas independientes ─── */
aside.panel.controls { background: transparent; border-right: 0; padding: 8px 6px 8px 8px; display: flex; flex-direction: column; gap: 8px; overflow: hidden; }
.dock-card { background: #fbfbfc; border: 1px solid #c9d0d6; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,.10); display: flex; flex-direction: column; overflow: hidden; }
.card-head { display: flex; align-items: center; gap: 6px; padding: 4px 8px; background: var(--irtim-ink, #141414); color: #e8e8e8; font-size: 10px; letter-spacing: .06em; text-transform: uppercase; }
.card-head strong, .card-head .rb-title { font-size: 10px; color: #e8e8e8; }
.ch-ico { color: #F1C02E; } .ch-sp { flex: 1; }
.card-head .hb { border: 0; background: transparent; color: #aab3ba; font-size: 11px; cursor: pointer; padding: 0 3px; }
.card-head .hb:hover { color: #fff; }
#cardDesign.collapsed .card-body { display: none; }
#cardDesign .card-body { overflow-y: auto; min-height: 0; }
.context-panel.docked .context-body { overflow-y: auto; }
.context-panel.docked .context-head.card-head { position: static; border-radius: 0; }
#contextCloseBtn { color: #aab3ba; }
.results-block.dock-card > summary.card-head { border-top: 0; }
.results-block .rb-caret { pointer-events: none; }
#resultsHost { overflow-y: auto; min-height: 0; }
.rs-sub { border-top: 1px solid #e2e6ea; }
.rs-sub > summary { padding: 3px 8px; font-size: 10px; font-weight: 700; color: #3a444c; background: #eef1f3; cursor: pointer; }
.rs-sub[open] > summary { border-bottom: 1px solid #e2e6ea; }
/* V137 · BUG (2ª captura Sergi): con la tarjeta ACOPLADA, el panel izquierdo entero hace scroll y
   la cabecera «Diseño» + pestañas desaparecían por arriba (el arreglo V136 solo cubría flotantes).
   Patrón de mercado (VS Code/Photoshop): la cabecera del panel queda PEGADA al hacer scroll.
   Requiere overflow visible en la tarjeta (overflow hidden rompe el sticky respecto al scroller). */
#cardDesign.dock-card { overflow: visible; }
#cardDesign > .card-head { position: sticky; top: 0; z-index: 12; }
/* V141 · BUG latente del V137: las pestañas viven dentro de .card-body (overflow:auto), que se
   convertía en SU contenedor sticky — como ese body no es quien hace scroll, nunca pegaban y con
   paneles largos desaparecían bajo la cabecera. Sin altura fijada por el splitter, el body deja de
   recortar y las pestañas pegan al aside; con altura fijada (style="height…"), el body vuelve a
   ser el scroller y las pestañas pegan dentro de él. Cubierto en el arnés V137 con scroll largo. */
#cardDesign:not([style*="height"]) > .card-body { overflow: visible; }
#cardDesign .step-tabs { position: sticky; top: 24px; z-index: 11; background: #fff; }
.step-tabs button.on { background: #fff6dd; border-color: #F1C02E; color: #6b5200; }
.step-tabs button.on b { color: #8a6a00; }
.controls .workflow-group { border-bottom: 0; }
.float-head { background: var(--irtim-ink, #141414); color: #e8e8e8; }
.float-head strong { color: #e8e8e8; font-size: 10px; }
#floatDockBtn, #floatDockDesignBtn, #floatDockPropsBtn { background: transparent; border: 0; color: #aab3ba; }

/* ─── V122 · espacios mínimos, estética plana moderna, colapso y splitters ─── */
aside.panel.controls { padding: 3px; gap: 0; }
.dock-card { border-radius: 4px; border-color: #d9dee3; box-shadow: none; }
.card-head { padding: 4px 7px; min-height: 24px; background: #1b1f23; cursor: pointer; user-select: none; }
.dock-card.collapsed .card-body, #contextPanel.collapsed .context-body { display: none !important; }
.card-splitter { height: 5px; cursor: row-resize; background: transparent; position: relative; flex: 0 0 5px; }
.card-splitter::after { content: ''; position: absolute; left: 40%; right: 40%; top: 2px; height: 1px; background: #c3cad0; border-radius: 1px; }
.card-splitter:hover { background: #fff3cf; }
main.layout { grid-template-columns: 296px minmax(0,1fr); gap: 0; }
.workspace { padding: 3px 3px 3px 0; }
.controls .bi, .controls .workflow-group > :not(summary) { }
.controls .workflow-group { padding: 4px 6px; }
.step-tabs { padding: 3px 4px; gap: 2px; }
.statusbar { padding: 3px 10px; }
/* IPI flotante por defecto: arriba a la derecha, compacto */
#floatWrap { top: 64px; right: 10px; }
.float-card { border-radius: 6px; box-shadow: 0 6px 18px rgba(0,0,0,.18); }
.ipi-more > summary { padding: 3px 6px; margin: 4px 0 2px; font-size: 10px; font-weight: 700; color: #3a444c; background: #eef1f3; border-radius: 4px; cursor: pointer; }
.ipi-more[open] > summary { margin-bottom: 4px; }
#adminOverlay .history-card { max-width: 900px; }
#adminHost details.admin-panel { border: 0; }

/* ─── V123 · plegado robusto: la tarjeta plegada mide SOLO su cabecera ─── */
.dock-card.collapsed { height: auto !important; max-height: none !important; flex: 0 0 auto !important; }
.dock-card.collapsed > *:not(.card-head):not(summary) { display: none !important; }
.rb-caret { cursor: pointer; }
.dock-card.collapsed { padding: 0 !important; border-width: 1px; }
.dock-card.collapsed > .card-head { margin: 0; }

/* ─── V124 · pestañas sin scroll horizontal y cuerpos sin desbordes laterales ─── */
.step-tabs { flex-wrap: nowrap; overflow: hidden; }
.step-tabs button { flex: 1 1 0; min-width: 0; overflow: hidden; padding: 2px 1px 1px; }
.step-tabs button b { font-size: 11px; }
.step-tabs button span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.step-tabs button:not(.on) .group-status { display: none; }
.step-tabs .group-status { max-width: 100%; }
.card-body, #resultsHost, .context-body, .float-body { overflow-x: hidden; }
.controls .workflow-group { overflow-x: hidden; }
/* flotantes: posiciones por defecto escalonadas (no se tapan entre sí) */
#floatWrapProps { top: 64px; right: 380px; }
#floatWrapDesign { top: 64px; right: 750px; }

/* ─── V125 · barra de creación agrupada (paso 2) y dock desplazable ─── */
.create-bar { display: flex; gap: 3px; align-items: center; margin: 4px 0 6px; }
.create-bar .create-chip { padding: 3px 7px; font-size: 10.5px; }
aside.panel.controls { overflow-y: auto; }
#cardDesign, .context-panel.docked.dock-card, .results-block.dock-card { flex-shrink: 0; }
.results-block.dock-card { min-height: 26px; }

/* ─── V126 · la cabecera del Grado, IDÉNTICA a las demás (el flex:1 heredado la partía en dos líneas) ─── */
.card-head .rb-title { flex: 0 1 auto; font-size: 10px; font-weight: 700; letter-spacing: .06em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card-head { flex-wrap: nowrap; }
.card-head strong { white-space: nowrap; }

/* ─── V127 · paso 2 coherente: Finalizar contextual en la barra, subsecciones limpias ─── */
.create-bar button[disabled] { display: none; }
.list-subhead { font-size: 10px; letter-spacing: .05em; text-transform: uppercase; color: #3a444c; background: #eef1f3; padding: 3px 6px; border-radius: 4px; margin: 8px 0 3px; }
.subhead-note { font-weight: 400; text-transform: none; color: #7b858d; }
.hint-fold { margin: 2px 0 5px; }
.hint-fold > summary { font-size: 10px; color: #7b858d; cursor: pointer; }
.hint-fold .hint { margin-top: 3px; }

/* ═══ V128 · NORMALIZACIÓN DEFINITIVA: un solo camino de render para las tres tarjetas ═══
   Regla de oro: .dock-card > .card-head (24px, oscura) + .dock-card > .card-body (blanca, 11px,
   padding 6/8). Nada de pieles heredadas del viejo panel derecho. Tamaño natural = contenido;
   el splitter es un override opcional con tope de contenido; plegado = solo cabecera. */
.dock-card { flex: 0 1 auto; max-height: none; display: flex; flex-direction: column; min-height: 26px; }
.context-panel.docked.dock-card { flex: 0 1 auto; border-top: 0; }
.dock-card > .card-body { background: #fff; padding: 6px 8px; font-size: 11px; overflow-y: auto; overflow-x: hidden; min-height: 0; }
#resultsHost aside.panel.results, .float-body aside.panel.results { padding: 0; margin: 0; background: transparent; border: 0; box-shadow: none; }
#resultsHost .results h2, .float-body .results h2, .context-body h3 { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: #3a444c; margin: 8px 0 3px; background: transparent; padding: 0; border: 0; }
#resultsHost .results > *:first-child h2, #resultsHost .results h2:first-child { margin-top: 2px; }
.step-tabs { background: #fff; border-bottom: 1px solid #e2e6ea; }
.controls .workflow-group { padding: 0 0 4px; background: #fff; }

/* ─── V129 · el título interno del IPI no duplica la cabecera de la tarjeta ─── */
#resultsHost #ipiSection > h2, .float-body #ipiSection > h2 { display: none; }
.results-block.dock-card { margin: 0; padding: 0; border-radius: 8px; }

/* ═══ V130 · flotantes de nivel profesional: UN solo scroller, ancho de trabajo y resize nativo ═══
   Regla: la tarjeta flotante es flex-columna con overflow hidden; SOLO .float-body desplaza;
   el contenido (aside de resultados, cuerpos de tarjeta) NUNCA lleva scroll propio dentro de un
   flotante. Redimensionable por la esquina con `resize` nativo del navegador. */
.float-card { display: flex; flex-direction: column; overflow: hidden; resize: both; min-width: 300px; min-height: 120px; width: 360px; max-width: 92vw; max-height: calc(100vh - 100px); }
.float-body { overflow-y: auto; overflow-x: hidden; min-height: 0; flex: 1 1 auto; padding: 6px 10px 10px; }
.float-body aside.panel.results, .float-body .card-body, .float-body .context-body, .float-body #resultsHost { overflow: visible !important; max-height: none !important; height: auto !important; padding: 0; }
.float-body .ipi-table { width: 100%; }
#floatWrap { width: 360px; }
#floatWrapProps, #floatWrapDesign { width: 340px; }
.float-head { flex: 0 0 auto; }

/* ─── V131 · orden de capas DOCUMENTADO, cabecera bloqueada, flujo de informe y paleta ─── */
/* capas: modales(100) > cabecera(60, y sus menús desplegables) > flotantes(55) > barra estado(35) > dock */
header.topbar { position: sticky; top: 0; z-index: 60; }
.float-card { z-index: 55; }
.cmdk { position: fixed; inset: 0; z-index: 110; background: rgba(8,13,17,.45); display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh; }
.cmdk-card { width: 520px; max-width: 92vw; background: #fff; border-radius: 10px; box-shadow: 0 18px 50px rgba(0,0,0,.35); overflow: hidden; }
.cmdk-card input { width: 100%; border: 0; border-bottom: 1px solid #e2e6ea; padding: 12px 14px; font-size: 14px; outline: none; }
.cmdk-item { padding: 7px 14px; font-size: 12px; cursor: pointer; }
.cmdk-item.sel, .cmdk-item:hover { background: #fff6dd; }
.flow-crumbs { display: flex; gap: 6px; align-items: center; margin-top: 4px; font-size: 10.5px; }
.fc { color: #7b858d; } .fc.done::before { content: '✓ '; color: #2e7d32; }
.fc.here { color: #141414; background: #fff6dd; border: 1px solid #F1C02E; border-radius: 10px; padding: 2px 8px; }
.fc.next { border: 1px solid #d7dce0; background: #fff; border-radius: 10px; padding: 2px 8px; cursor: pointer; font-weight: 700; }
.fc.next:hover { background: #fff6dd; border-color: #F1C02E; }
.report-edit { margin: 6px 0; border: 1px solid #e2d9b8; background: #fffbee; border-radius: 8px; }
.report-edit > summary { padding: 6px 10px; font-size: 11px; font-weight: 700; cursor: pointer; }
.report-edit #reportMetaHost { padding: 4px 10px 10px; max-height: 46vh; overflow-y: auto; }
.fb-zobs { font-style: italic; color: #5a646c; }

/* ═══ V132 · COMPOSITOR DE INFORME: índice de hojas | vista A4 · imprimir aparte ═══ */
/* V135 · vista cortada al navegar: la tarjeta del modal heredaba overflow:auto de .history-card y
   scrollIntoView la desplazaba TAMBIÉN a ella, escondiendo hojas bajo el pie. La tarjeta ya no
   desplaza nunca (overflow:hidden); el único scroll de la vista es #compRight, las hojas llevan
   scroll-margin-top y el contenido reserva al pie fijo su altura (padding-bottom). */
/* V136 · «Preparar informe» a pantalla (casi) completa, patrón vista previa de impresión de
   mercado (Word / AutoCAD Plot / Bluebeam): el documento manda y el índice es barra lateral fija.
   Sustituye el diálogo de 1020 px que dejaba hoja e índice comprimidos y difíciles de editar. */
.report-card { display: flex; flex-direction: column; width: 100%; max-width: none; height: 100%; max-height: none; overflow: hidden; }
.composer { display: grid; grid-template-columns: 340px minmax(0,1fr); gap: 10px; flex: 1 1 auto; min-height: 0; } /* V136 · índice 340px */
.comp-left { overflow-y: auto; min-height: 0; padding-right: 2px; }
.comp-right { overflow-y: auto; min-height: 0; background: #e8ebee; border-radius: 8px; padding: 10px; scroll-behavior: smooth; }
.comp-right #reportContent { padding-bottom: 56px; }
.comp-right .rep-pg { scroll-margin-top: 10px; }
.comp-index-head { font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: #3a444c; margin: 10px 0 4px; }
/* V135 · índice por grupos con subcabeceras y filas más legibles (26-28 px, tipografía 11.5) */
.comp-group { font-size: 9.5px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: #8a6a00; background: #fbf4dd; border-radius: 6px; padding: 3px 8px; margin: 8px 0 2px; }
.comp-group:first-child { margin-top: 0; }
.comp-sub { flex-basis: 100%; display: inline-flex; align-items: center; gap: 5px; font-size: 10.5px; color: #6b5410; padding: 1px 0 3px 26px; cursor: pointer; }
.comp-sub input { margin: 0; }
.hint-inline { font-weight: 400; text-transform: none; letter-spacing: 0; color: #7b858d; }
.comp-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0 6px; min-height: 26px; padding: 3px 4px; border-radius: 6px; border: 1px solid transparent; }
.comp-row:hover { background: #fff6dd; border-color: #f0e3b0; }
.comp-row.off .comp-nav { color: #9aa4ab; text-decoration: line-through; }
.comp-row .rep-opt { margin: 0; display: flex; }
.comp-nav { flex: 1; text-align: left; border: 0; background: transparent; font-size: 11.5px; color: #20262b; cursor: pointer; padding: 2px 0; }
.comp-nav:hover { color: #8a6a00; }
.comp-chip { font-size: 9.5px; color: #68727a; background: #eef1f3; border-radius: 8px; padding: 1px 6px; min-width: 30px; text-align: center; }
.composer-foot { display: flex; align-items: center; gap: 10px; border-top: 2px solid #141414; margin-top: 8px; padding-top: 8px; }
.comp-summary { font-size: 11px; font-weight: 700; color: #20262b; }
.cf-sp { flex: 1; }
.comp-print { font-size: 13px; padding: 8px 22px; background: #F1C02E; border: 1px solid #d9a713; border-radius: 8px; font-weight: 800; cursor: pointer; }
.comp-print:hover { background: #f7cf55; }
.report-edit > summary { font-size: 11px; }
.report-edit #reportMetaHost { max-height: 34vh; }

/* ─── V133 · puerta única «Datos del proyecto» ─── */
.pn-edit { border: 1px solid #d7dce0; background: #fff; border-radius: 6px; width: 26px; height: 26px; cursor: pointer; margin-left: 4px; }
.pn-edit:hover { background: #fff6dd; border-color: #F1C02E; }
.pdata-card { max-width: 760px; }
.pd-titlerow { display: flex; align-items: flex-end; gap: 8px; margin: 6px 0; }
.pd-title { flex: 1; font-size: 11px; font-weight: 700; }
.pd-title input { width: 100%; margin-top: 2px; }
.pd-missing { font-size: 11px; margin: 6px 0; padding: 6px 8px; background: #fff6dd; border: 1px solid #f0e3b0; border-radius: 6px; }
.pd-miss { border: 0; background: transparent; color: #8a6a00; text-decoration: underline; cursor: pointer; font-size: 11px; padding: 0; }
.pd-default { display: block; margin-top: 8px; font-size: 11px; }
/* V138 · el diálogo «Datos del proyecto» tenía DOS scrolls (tarjeta + este contenedor): queda UNO,
   el de la tarjeta. */
#pdataHost { max-height: none; overflow: visible; }

/* ─── V134 · campos visibles en portada ─── */
/* (V135: cabecera de versión del fichero — reorganización de menús y compositor unificado) */
.pd-vis { margin-top: 8px; border: 1px solid #e2e6ea; border-radius: 6px; }
.pd-vis > summary { padding: 5px 8px; font-size: 11px; font-weight: 700; cursor: pointer; }
#pdVisHost { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 2px 10px; padding: 4px 10px; }
.pd-vis-item { font-size: 11px; }

/* ─── V137 · edición sobre el documento (portada) ─── */
.rep-fld { cursor: pointer; border-bottom: 1px dashed #d8b93e; padding: 0 2px; border-radius: 2px; }
.rep-fld:hover, .rep-fld:focus { background: #fdf3d0; outline: none; }
.rep-fld-empty { color: #b06a00; font-weight: 700; }
.rep-fld-editing { background: #fff6dd; outline: 2px solid #F1C02E; border-bottom-color: transparent; }
.rep-fld-inp { font: inherit; font-weight: 700; border: 0; background: transparent; outline: none; width: 100%; min-width: 120px; padding: 0; }
@media print { .rep-fld { border-bottom: 0; padding: 0; background: none !important; } .rep-fld-empty { visibility: hidden; } }


/* ─── V138 · mini-formato de observaciones por línea ─── */
.rep-obs-h { font-weight: 800; font-size: 12.5px; text-transform: uppercase; letter-spacing: .04em; color: #3E4B63; margin: 8px 0 2px; }
.rep-obs-li { position: relative; padding-left: 14px; margin: 2px 0; }
.rep-obs-li::before { content: '•'; position: absolute; left: 2px; color: #b98f12; }
.rep-obs-note { color: #5c6a75; font-style: italic; border-left: 3px solid #d8dee3; padding-left: 8px; margin: 3px 0; }

/* ─── V138 · encuadre de fichas desde el compositor + navegación honesta ─── */
.rep-ficha { position: relative; }
.rep-encuadre { position: absolute; top: 6px; right: 6px; z-index: 3; font-size: 11px; padding: 3px 9px; border: 1px solid #d8b93e; background: #fdf6de; border-radius: 7px; cursor: pointer; opacity: 0; transition: opacity .15s; }
.rep-ficha:hover .rep-encuadre { opacity: 1; }
.comp-nav-off { opacity: .45; cursor: default; text-decoration: none; }
@media print { .rep-encuadre { display: none !important; } }

/* ─── V141 · barra de formato de observaciones ─── */
.obs-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 5px 0 2px; }
.obs-toolbar button { font-size: 10.5px; padding: 2px 8px; border: 1px solid #d5dade; background: #f6f8f9; border-radius: 6px; cursor: pointer; }
.obs-toolbar button:hover { background: #fdf3d0; border-color: #d8b93e; }
.obs-toolbar-hint { font-size: 9.5px; color: #8a949c; margin-left: 4px; }

/* ─── V141 · encuadre directo sobre las figuras del informe + fichas a dos páginas ─── */
.rep-ficha [data-figix], .rep-ficha .fb-fig { position: relative; }
.rep-ficha [data-figix] img, .rep-ficha .fb-fig img { cursor: grab; touch-action: none; }
.rep-ficha [data-figix]:hover::after, .rep-ficha .fb-fig:hover::after { content: '🖼 arrastra para encuadrar · rueda = zoom'; position: absolute; top: 8px; left: 50%; transform: translateX(-50%); background: rgba(20,20,20,.78); color: #F1C02E; font-size: 11px; padding: 3px 10px; border-radius: 7px; pointer-events: none; z-index: 3; }
.fbr-fig { margin: 4mm 0 0; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.fbr-fig img { width: 100%; height: auto; max-height: 100%; object-fit: contain; border: 1px solid #dfe4e8; border-radius: 4px; background: #fff; }
.fbr-fig figcaption { font-size: 9.5px; color: #6a7680; margin-top: 1mm; }
.fbr-data .fb-col-data, .fbr-data { font-size: 11px; }
@media print { .rep-ficha [data-figix]:hover::after, .rep-ficha .fb-fig:hover::after { display: none !important; } }

/* ═══ V142 · panel «Datos» del compositor (pestañas + índice por hoja de destino) ═══ */
.comp-tabs { display: flex; gap: 4px; margin: 0 0 8px; border-bottom: 1px solid #e2e7ea; }
.comp-tab { font-size: 11.5px; font-weight: 700; padding: 5px 12px; border: 1px solid transparent; border-bottom: 0; background: none; color: #6a7680; cursor: pointer; border-radius: 6px 6px 0 0; }
.comp-tab.on { background: #fdf6de; border-color: #e6d69b; color: #141414; }
.rep-data { display: flex; flex-direction: column; gap: 10px; }
.rd-group { border: 1px solid #e2e7ea; border-radius: 8px; padding: 6px 7px 7px; background: #fff; }
.rd-group.rd-off { opacity: .62; background: #fafbfb; }
.rd-group.rd-live-on { border-color: #d8b93e; box-shadow: 0 0 0 2px #fdf3d0; }
.rd-head { display: flex; align-items: center; gap: 6px; font-size: 11.5px; margin-bottom: 4px; }
.rd-live { color: transparent; font-size: 9px; }
.rd-live-on .rd-live { color: #d8b93e; }
.rd-pg { margin-left: auto; font-size: 9.5px; color: #8a949c; white-space: nowrap; }
.rd-nope { color: #b4232f; }
.rd-row { display: flex; align-items: baseline; gap: 6px; width: 100%; text-align: left; font-size: 11px; padding: 3px 5px; border: 0; border-radius: 5px; background: none; cursor: pointer; }
.rd-row:hover { background: #fdf6de; }
.rd-dot { width: 11px; flex: 0 0 11px; color: #2f9b6f; font-size: 10px; }
.rd-missing .rd-dot { color: #c0392b; }
.rd-empty .rd-dot { color: #c3ccd2; }
.rd-lbl { flex: 0 0 44%; color: #3E4B63; }
.rd-val { flex: 1 1 auto; color: #6a7680; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rd-empty .rd-val { color: #a8b2b9; }
.rd-include { width: 100%; margin-top: 4px; font-size: 10.5px; padding: 3px 8px; border: 1px solid #d8b93e; background: #fdf6de; border-radius: 6px; cursor: pointer; }

/* resaltado recíproco panel ↔ papel */
.rd-hi { outline: 2px solid #d8b93e !important; outline-offset: 2px; background: #fffbe9 !important; }
.rd-flash { animation: rdflash 1.1s ease-out 1; }
@keyframes rdflash { 0% { background: #f6d35a; } 100% { background: transparent; } }

/* ═══ V142 · edición WYSIWYG de observaciones sobre el documento ═══ */
.rep-obs[data-obs], .rep-scope-text[data-text] { border-radius: 5px; transition: background .12s, outline-color .12s; outline: 1px dashed transparent; outline-offset: 3px; }
.rep-obs[data-obs]:hover, .rep-scope-text[data-text]:hover { background: #fffdf3; outline-color: #e0c766; cursor: text; }
.rep-obs-editing { background: #fffdf3 !important; outline: 2px solid #d8b93e !important; outline-offset: 3px; }
.rep-obs-editing:focus { outline: 2px solid #d8b93e !important; }
.obs-wysi-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 4px 0 3px; padding: 4px 5px; background: #141414; border-radius: 7px; }
.obs-wysi-t { font-size: 9.5px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: #F1C02E; margin-right: 3px; }
.obs-wysi-bar button { font-size: 10.5px; padding: 2px 8px; border: 1px solid #3a3a3a; background: #232323; color: #e9edef; border-radius: 5px; cursor: pointer; }
.obs-wysi-bar button:hover { background: #333; border-color: #6a6a6a; }
.obs-wysi-bar button.on { background: #F1C02E; border-color: #F1C02E; color: #141414; font-weight: 800; }
.obs-wysi-sp { flex: 1 1 auto; }
.obs-wysi-ok { background: #2f9b6f !important; border-color: #2f9b6f !important; color: #fff !important; font-weight: 700; }
.rep-obs-vacio .rep-obs-empty { color: #a8b2b9; font-style: italic; }
.rep-eye { margin-left: 6px; font-size: 10px; padding: 0 4px; border: 1px solid #e2e7ea; background: #fff; border-radius: 4px; cursor: pointer; opacity: 0; transition: opacity .12s; }
tr:hover .rep-eye { opacity: .75; }
.rep-eye:hover { opacity: 1 !important; border-color: #d8b93e; background: #fdf6de; }
.rep-hidden-fields { font-size: 9.5px; color: #8a949c; margin: 2px 0 0; }
.rep-unhide { font-size: 9.5px; padding: 1px 6px; border: 1px dashed #c3ccd2; background: #fff; border-radius: 5px; cursor: pointer; color: #6a7680; }

/* ═══ V142 · previsualización bajo el textarea de respaldo ═══ */
.obs-preview:not(:empty) { margin: 4px 0 2px; padding: 5px 7px; border: 1px dashed #dfe4e8; border-radius: 6px; background: #fcfdfd; }
.obs-preview-t { display: block; font-size: 9px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: #a8b2b9; margin-bottom: 2px; }
.obs-preview .rep-obs { font-size: 10.5px; }
.meta-dest { margin-left: 6px; font-size: 9.5px; padding: 0 6px; border: 1px solid #e2e7ea; background: #f7f9fa; border-radius: 5px; color: #6a7680; cursor: pointer; }
.meta-dest:hover { border-color: #d8b93e; background: #fdf6de; color: #141414; }

/* nada de mandos en el papel */
@media print {
  .rep-onlyscreen, .obs-wysi-bar, .rep-eye, .rep-hidden-fields, .comp-tabs { display: none !important; }
  .rep-obs[data-obs], .rep-scope-text[data-text] { outline: 0 !important; background: none !important; }
}

/* ═══ V143 · diálogo «Datos del documento»: arranque + lista de navegación ═══ */
.pd-start { border: 1px solid #e6d69b; background: #fffdf3; border-radius: 8px; padding: 8px 10px 4px; margin: 0 0 12px; }
.pd-start-h { font-size: 10px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: #3E4B63; margin: 0 0 6px; }
.pd-nav-h { margin-top: 4px; }
#pdStartHost .score-row { margin-bottom: 6px; }
#pdDataIndex { max-height: 46vh; overflow-y: auto; }
.pdata-card { max-width: 720px; }
.menu-check { align-items: flex-start; gap: 6px; }
.menu-check span { font-weight: 400; line-height: 1.25; }

/* celdas editables del historial de revisiones sobre la portada */
.rep-rev-c { cursor: pointer; border-bottom: 1px dotted #d8b93e; }
.rep-rev-add { margin: 2px 0 0; }
@media print { .rep-rev-add { display: none !important; } .rep-rev-c { border-bottom: 0; } }

/* ═══ V144 · huecos explicativos de los editores sin selección ═══ */
.ctx-empty { margin: 2px 0 8px; padding: 6px 8px; border: 1px dashed #dfe4e8; border-radius: 6px; background: #fafbfb; font-size: 11px; }

/* ═══ V144 · lo que nombra una hoja, enlaza a ella (B7) ═══ */
.rd-goto { font-size: 11.5px; font-weight: 700; color: #141414; background: none; border: 0; padding: 0; cursor: pointer; text-align: left; }
.rd-goto:hover { color: #b98f12; text-decoration: underline; }
.rep-toc-go { cursor: pointer; }
.rep-toc-go:hover { background: #fdf6de; }
@media print { .rep-toc-go { cursor: auto; } }

/* ═══ V144 · condiciones del diseño con estilos por línea: mantienen su aire de pliego ═══ */
.rep-scope-text p { text-align: justify; margin: 0 0 2.5mm; }
.rep-scope-text .rep-obs-h { text-align: left; }

/* ═══ V144 · el Resumen MUESTRA el cajetín (solo lectura) ═══ */
.summary-meta-view .meta-h { margin: 10px 0 4px; }
.smv-t { width: 100%; border-collapse: collapse; font-size: 11.5px; }
.smv-t th { text-align: left; font-weight: 600; color: #3E4B63; width: 32%; padding: 3px 6px 3px 0; vertical-align: top; }
.smv-t td { padding: 3px 6px 3px 0; vertical-align: top; }
.smv-t td i { color: #a8b2b9; }
.smv-dest { width: 26%; font-size: 10px; color: #8a949c; text-align: right; white-space: nowrap; }
.smv-t tr + tr th, .smv-t tr + tr td { border-top: 1px solid #f0f3f4; }

/* ═══ V145 · tirador inferior de «Grado de protección» y separadores visibles ═══ */
.card-splitter { position: relative; }
.card-splitter::after { content: '⣿'; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); font-size: 7px; line-height: 1; color: #b6c0c7; letter-spacing: -1px; pointer-events: none; }
.card-splitter:hover::after { color: #d8b93e; }
.card-grip-b { flex: 0 0 auto; height: 11px; display: flex; align-items: center; justify-content: center; cursor: row-resize; border-top: 1px solid #2b2b2b; background: #1b1b1b; border-radius: 0 0 8px 8px; }
.card-grip-b span { font-size: 8px; line-height: 1; color: #7d7d7d; letter-spacing: -1px; }
.card-grip-b:hover span { color: #F1C02E; }

/* ═══ V145 · el nivel se declara en la hoja, no en una portadilla ═══ */
.rep-hd-scope { font-size: 7.5px; color: #8a949c; line-height: 1.2; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rep-h2-ficha { display: flex; align-items: center; gap: 2.2mm; }
.rep-h2-ficha .rep-lvl-b { font-size: 8px; padding: 1px 6px; border-radius: 3px; font-weight: 900; letter-spacing: .06em; flex: 0 0 auto; }
.rep-h2-ficha .rep-h2-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.rep-ficha .fb-projbar { display: none; }

/* ═══ V146 · ficha a dos hojas: datos en la I, los DOS planos en la II con alto garantizado ═══ */
.rep-ficha-figs { display: flex; flex-direction: column; min-height: 0; height: 100%; }
.rep-ficha-figs .fbr-fig { flex: 1 1 0; min-height: 78mm; }
.rep-ficha-figs .fbr-fig img { flex: 1 1 auto; min-height: 0; }
.fbr-data-solo { overflow: visible; }

/* ═══ V146 · la banda «QUÉ SE PROTEGE» gana tamaño: es la identificación de la hoja ═══ */
.fb-eyebrow { font-size: 9.5px; letter-spacing: .1em; }
.fb-name { font-size: 21px; line-height: 1.1; }
.fb-sub { font-size: 11px; }

/* ═══ V146 · la tabla valorada no puede salirse de la hoja ═══ */
.rep-bom-t { table-layout: fixed; width: 100%; font-size: 8.5px; }
.rep-bom-t th, .rep-bom-t td { overflow-wrap: anywhere; word-break: break-word; padding: 1px 3px; }
.rep-bom-t col.c-fam { width: 13%; } .rep-bom-t col.c-nom { width: 20%; }
.rep-bom-t col.c-mod { width: 27%; } .rep-bom-t col.c-ref { width: 20%; }
.rep-bom-t col.c-ud { width: 6%; } .rep-bom-t col.c-pu { width: 7%; } .rep-bom-t col.c-tot { width: 7%; }
/* V283 · EL TEXTO LARGO DE LA RELACIÓN VALORADA SE PARTE EN LÍNEAS. Reporte de Sergi con captura
   (14/09/2026): «cuando el texto es largo no se divide en líneas y sobrepasa». La tabla YA pedía
   envolver —`overflow-wrap: anywhere` y `word-break: break-word` dos líneas más arriba— pero la regla
   general de `.ipi-table` le impone `white-space: nowrap` a toda celda que no sea la primera, y con
   `nowrap` lo otro no puede hacer nada: gana por especificidad (0,2,1 frente a 0,1,1).
   Se repite aquí la misma especificidad y más abajo en el fichero, que es lo que la desempata, y se
   vuelve a fijar `nowrap` DESPUÉS para las celdas de cifra: un importe partido en dos líneas se lee
   como dos importes. El orden de estas dos reglas es, por tanto, parte del arreglo. */
.rep-bom-t th:not(:first-child), .rep-bom-t td:not(:first-child) { white-space: normal; }
.rep-bom-t .rep-num { text-align: right; }
/* V284 · reparto de proyectos. La casilla y el nombre son UN solo blanco de pulsación: una casilla
   suelta de 13 px es difícil de acertar y aquí cada acierto fallido comparte o descomparte un
   proyecto con alguien. */
.acceso-celda { display: flex; align-items: center; gap: 8px; cursor: pointer; }
/* V299 · el filtro del panel «Abrir». A todo lo ancho: se escribe en él nada más abrir el panel. */
.projects-filtro { display: block; margin: 0 0 10px; }
.projects-filtro input { width: 100%; box-sizing: border-box; padding: 7px 10px; font-size: 13px;
  border: 1px solid #d7dde2; border-radius: 8px; }
.projects-filtro input:focus { outline: 2px solid rgba(60,110,160,.35); outline-offset: 1px; }
/* V287 · modo de consulta. Lo bloqueado se atenúa pero NO se esconde: un visor tiene que poder ver
   que el proyecto tiene una altura de montaje, aunque no pueda cambiarla. Esconderlo le ocultaría
   el diseño, que es justo lo que ha venido a mirar. */
.modo-solo-vista .bloqueado-vista { opacity: .55; cursor: not-allowed; }
.modo-solo-vista .bloqueado-vista:hover { opacity: .55; }
.aviso-solo-vista { flex: 0 0 auto; margin-left: 10px; padding: 3px 10px; border-radius: 999px;
  background: rgba(60, 110, 160, .12); color: #2d5a86; font-size: 12px; white-space: nowrap;
  border: 1px solid rgba(60, 110, 160, .28); }
.aviso-solo-vista.parpadea { background: rgba(60, 110, 160, .38); color: #12354f; transition: none; }
@media (max-width: 900px) { .aviso-solo-vista { display: none; } }
.acceso-celda input { flex: 0 0 auto; margin: 0; }
.acceso-dado { background: rgba(60, 160, 90, 0.10); }
.rep-bom-t th.rep-num, .rep-bom-t td.rep-num { white-space: nowrap; }

/* ═══ V147 · la cámara, con entidad propia en su hoja ═══ */
.fb-id-cam { display: flex; align-items: flex-start; gap: 3mm; }
.fb-camref { flex: 0 0 auto; min-width: 15mm; text-align: center; color: #fff; font-weight: 900; font-size: 22px; line-height: 1; padding: 2.4mm 2mm; border-radius: 5px; letter-spacing: -.02em; box-shadow: inset 0 -2px 0 rgba(0,0,0,.18); }
.fb-camtxt { min-width: 0; }
.fb-camid { font-size: 10.5px; color: #3E4B63; font-weight: 700; margin: .6mm 0 .4mm; }

/* ═══ V147 · logotipo del cliente ═══ */
.pd-clogo { margin-top: 10px; border-top: 1px dashed #e6d69b; padding-top: 8px; }
.pd-clogo-row { display: flex; align-items: center; gap: 10px; }
.pd-clogo-prev { flex: 0 0 129px; height: 40px; border: 1px dashed #d5dade; border-radius: 6px; display: flex; align-items: center; justify-content: center; background: #fff; overflow: hidden; padding: 3px; }
.pd-clogo-prev img { max-width: 100%; max-height: 100%; object-fit: contain; }
/* V148 · con logotipo cargado, la vista previa ES el visor de encuadre: se arrastra para recolocar */
.pd-clogo-prev.pd-clogo-vp { cursor: grab; padding: 0; touch-action: none; }
.pd-clogo-prev.pd-clogo-vp:active { cursor: grabbing; }
.pd-clogo-prev.pd-clogo-vp img { width: 100%; height: 100%; object-fit: contain; transform-origin: center; pointer-events: none; user-select: none; }
.pd-clogo-zoom { font-size: 11px; display: flex; align-items: center; gap: 5px; }
.pd-clogo-zoom input[type="range"] { width: 92px; }
.pd-clogo-prev .hint { font-size: 9px; text-align: center; line-height: 1.2; }
.pd-clogo-btns { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.pd-clogo-sw { font-size: 11px; display: flex; align-items: center; gap: 4px; }
.rep-cover-clogo { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; margin-left: auto; padding-left: 4mm; border-left: 1px solid #e2e7ea; }
.rep-clogo-t { font-size: 6.5px; letter-spacing: .12em; text-transform: uppercase; color: #a8b2b9; font-weight: 800; }
/* V148 · el logo del cliente se imprime a través de su VISOR de encuadre: caja fija con la misma
   proporción que la vista previa del panel (42:13) y recorte por overflow. Con el encuadre de
   fábrica (zoom 1, sin desplazamiento) el resultado es el de V147. */
.rep-clogo-vp { display: block; width: 42mm; height: 13mm; overflow: hidden; }
.rep-clogo-vp img { width: 100%; height: 100%; object-fit: contain; transform-origin: center; }


/* ─── V148 · banda de NIVEL en grande en la cabecera de cada hoja (decisión Sergi 03/08/2026) ───
   El nivel deja de ser una insignia diminuta: banda de color a lo ancho, rótulo del nivel en grande
   a la izquierda y título de la hoja a continuación. Colores en REPORT_LEVELS (app.js); el verde y
   el carmesí quedan reservados a los sombreados del cálculo y no se usan aquí. */
.rep-lvl-band { flex: 0 0 auto; display: flex; align-items: baseline; gap: 3mm; padding: 1.3mm 2.6mm; margin: 1.2mm 0 2.6mm; border-radius: 1.5px; min-width: 0; }
.rep-band-tag { font-size: 12.5px; font-weight: 900; letter-spacing: .14em; text-transform: uppercase; white-space: nowrap; }
.rep-band-title { font-size: 10.5px; font-weight: 700; opacity: .95; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* V149 · la etiqueta del título de ficha crece (decisión Sergi 03/08/2026): es el rótulo que debe
   verse de un vistazo al hojear el papel. */
.rep-h2-ficha .rep-lvl-b.rep-lvl-b-ficha { font-size: 11px; padding: 2.5px 9px; border-radius: 3px; }

/* V154 · panel «Anotaciones» del compositor: familia, fila con interruptor, etiqueta y vista previa */
.comp-obsfam { font-size: 10px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: #7a8695; margin: 6px 4px 2px; }
.comp-obsrow .comp-obsnav { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; min-width: 0; }
.comp-obsrow .comp-obsnav b { font-size: 11.5px; }
.comp-obsprev { font-size: 10.5px; color: #8a95a3; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 190px; }
.comp-obsrow.off .comp-obsnav b, .comp-obsrow.off .comp-obsprev { text-decoration: line-through; opacity: .55; }

/* V158 · panel «Precios de la oferta» (decisión Sergi 07/08/2026): línea por referencia con
   descripción y PVP editables sobre la base oficial de la tarifa; ✎ y resalte marcan la
   desviación en el panel (el papel sale limpio) y «↺» vuelve al oficial. */
.comp-ovhint { font-size: 10px; color: #8a95a3; margin: 0 4px 4px; }
.comp-ovrow { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.comp-ovref { font-size: 10px; font-weight: 700; color: #7a8695; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 150px; flex: 0 0 auto; }
.comp-ovdesc { flex: 1 1 120px; min-width: 90px; font-size: 10.5px; padding: 2px 5px; }
.comp-ovprice { flex: 0 0 76px; width: 76px; font-size: 10.5px; padding: 2px 5px; text-align: right; }
.comp-ovreset { flex: 0 0 auto; font-size: 11px; padding: 1px 6px; cursor: pointer; }
/* V161 · reordenar líneas de la oferta (↑/↓) */
.comp-ovmove { display: flex; gap: 1px; flex: 0 0 auto; }
.comp-ovarrow { font-size: 10px; padding: 0 4px; cursor: pointer; line-height: 16px; }
.comp-ovreset:disabled { opacity: .35; cursor: default; }
.comp-ovrow.comp-ovmod { border-left: 3px solid #c9a227; padding-left: 4px; }
.comp-ovrow.comp-ovmod .comp-ovref { color: #9a7b1c; }

/* V159 · panel de sincronización de tarifa: grupos con casilla maestra, filas con casilla
   individual; ⚠ = desmarcada o avisada por un motivo concreto (óptica, tarifa parcial…).
   El panel se abre DESDE el modal de Administración (adminOverlay, también .history-panel a
   z-index 100 y posterior en el DOM): sin este escalón quedaba por detrás (reporte Sergi). */
#tarifaSyncPanel { z-index: 105; }
.tarifa-sync-card { max-width: 860px; width: min(94vw, 860px); }
.tarifa-sync-body { max-height: min(58vh, 560px); overflow-y: auto; margin: 8px 0; display: flex; flex-direction: column; gap: 8px; }
.ts-group { border: 1px solid rgba(122,134,149,.25); border-radius: 6px; padding: 6px 8px; }
.ts-ghead { display: flex; align-items: center; gap: 6px; font-size: 12px; margin-bottom: 4px; }
/* V160 · diff tabular (norma «referencia de mercado», directrices §3.7): columnas Actual/Nuevo
   como la vista previa de importación de un ERP; altas en verde, bajas en rojo, avisos en ámbar. */
.ts-table { width: 100%; border-collapse: collapse; font-size: 11px; }
.ts-table th { text-align: left; font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: #7a8695; padding: 2px 6px; border-bottom: 1px solid rgba(122,134,149,.3); }
.ts-table td { padding: 3px 6px; border-bottom: 1px solid rgba(122,134,149,.14); vertical-align: top; }
.ts-check { width: 22px; }
.ts-ref { font-weight: 700; white-space: nowrap; font-size: 10px; color: #55636f; }
.ts-art { max-width: 260px; }
.ts-actual { color: #7a8695; }
.ts-nuevo { font-weight: 600; }
.ts-nuevo em { display: block; color: #9a7b1c; font-style: normal; font-weight: 700; font-size: 10px; }
.ts-row.ts-warn td:first-child { border-left: 3px solid #c9a227; }
.ts-g-alta .ts-nuevo { color: #1e7c3a; }
.ts-g-baja .ts-nuevo { color: #9c2f38; }

/* V163 · Administración Apliter rediseñada (mejores prácticas de gestores de catálogo):
   línea de estado con procedencia, UN botón primario de actualización, acciones raras en
   «⋯ Más acciones» (progressive disclosure) y la ficha del modelo en su propio marco. */
.admin-estado { font-size: 11px; color: #55636f; margin: 2px 0 8px; font-weight: 600; }
.admin-estado.admin-estado-aviso { color: #9a7b1c; } /* V164 · emisión nueva pendiente de validar */
/* V165 · panel de configuración de la sincronización (por delante del modal de Administración) */
#syncCfgPanel { z-index: 105; }
#loginPanel { z-index: 105; } /* V167 · sesión del ecosistema, por delante del modal admin */
.sync-cfg-card { max-width: 560px; width: min(94vw, 560px); }
.sync-cfg-estado { font-size: 11px; font-weight: 700; color: #55636f; margin: 4px 0 8px; }
.sync-cfg-keyrow { display: flex; gap: 4px; align-items: center; }
.sync-cfg-keyrow input { flex: 1 1 auto; }
.sync-cfg-test { font-size: 11px; font-weight: 700; color: #55636f; align-self: center; }
.admin-more { position: relative; display: inline-block; }
.admin-more > summary { list-style: none; cursor: pointer; }
.admin-more > summary::-webkit-details-marker { display: none; }
.admin-more[open] > .admin-more-menu { display: flex; }
.admin-more-menu { position: absolute; left: 0; top: calc(100% + 4px); z-index: 60; min-width: 240px;
  background: #fff; border: 1px solid #d5dade; border-radius: 8px; box-shadow: 0 10px 28px rgba(20,20,20,.16);
  padding: 6px; flex-direction: column; gap: 4px; }
.admin-more-menu .button, .admin-more-menu button { justify-content: flex-start; text-align: left; width: 100%; }
.admin-ficha { border: 1px solid #d8dfe5; border-radius: 8px; padding: 10px 12px; margin-top: 10px; }
.admin-ficha legend { font-size: 11px; font-weight: 800; color: #55636f; padding: 0 6px; }

/* V155 · leyenda de elementos y enlaces IRTIMfire (hoja de infraestructura): rejilla compacta a dos
   columnas con el icono real de la planta. */
.rep-netlegend { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4mm 4mm; margin: 1.5mm 0 2.5mm; }
.rep-netleg-i { display: flex; align-items: center; gap: 2mm; min-width: 0; }
.rep-netleg-i img { width: 8.2mm; height: 9mm; object-fit: contain; flex: 0 0 auto; }
.rep-netleg-i.rep-netleg-link img { height: 3mm; }
.rep-netleg-i b { display: block; font-size: 8.6px; color: #273640; }
.rep-netleg-i span { display: block; font-size: 8px; color: #5c6a76; line-height: 1.25; }

/* V170 · ACCESO POR SESIÓN (decisión de Sergi 12/08/2026). Sin sesión Apliter la aplicación no
   se usa: una portada tapa el editor y ofrece el login. Es protección de EXPERIENCIA, no de
   servidor — el JS es público —; la barrera real, si se quiere, va delante del dominio.
   Va por encima de los modales (100-110) pero POR DEBAJO del panel de sesión, que es la salida. */
.app-gate { position: fixed; inset: 0; z-index: 150; background: rgba(8,13,17,.92); display: flex; align-items: center; justify-content: center; padding: 24px; }
.app-gate[hidden] { display: none; }
.app-gate-card { max-width: 460px; width: 100%; background: var(--panel, #fff); border: 1px solid var(--line, #d9dee3); border-radius: 14px; padding: 26px 28px; box-shadow: 0 18px 48px rgba(0,0,0,.35); text-align: center; }
.app-gate-card h2 { margin: 6px 0 10px; }
.app-gate-actions { display: flex; gap: 8px; justify-content: center; margin: 18px 0 4px; flex-wrap: wrap; }
.app-gate-pie { margin-top: 14px; font-size: 12px; opacity: .8; }
#loginPanel { z-index: 200; } /* V170 · la salida del candado: siempre por delante de la portada */

/* V175 · Indicador de sesión en la barra del proyecto. Saber CON QUÉ CUENTA se trabaja deja de
   estar enterrado en Administración: con la fase A cada proyecto registra a su propietario. */
.sesion-chip { display: inline-flex; align-items: center; gap: 6px; margin-left: 8px; padding: 2px 6px 2px 8px; border: 1px solid var(--line, #d9dee3); border-radius: 999px; font-size: 12px; white-space: nowrap; }
.sesion-chip[hidden] { display: none; }
.sesion-salir { border: 0; background: transparent; cursor: pointer; font-size: 12px; text-decoration: underline; padding: 0 2px; color: inherit; opacity: .8; }
.sesion-salir:hover { opacity: 1; }

/* V176 · Usuarios y accesos. La tabla reutiliza el estilo del panel de validación de tarifa. */
.usuarios-card { max-width: 720px; }
.usuarios-tabla { max-height: 46vh; overflow: auto; margin: 10px 0; }
.usuarios-tabla .usuario-baja { opacity: .55; text-decoration: line-through; }
#usuariosPanel { z-index: 106; }
/* V288 · el reparto se abre DESDE el padrón, así que tiene que quedar por delante de él. Con el 100
   de `.history-panel` salía detrás y había que cerrar el primero para verlo ⟨reporte de Sergi,
   15/09/2026⟩. «Compartir» va al mismo nivel: también puede abrirse con otro panel ya puesto. */
#accesosPanel, #compartirPanel { z-index: 107; }

/* V177 · Proyectos en la nube. La fila del proyecto abierto se destaca para que nadie suba
   encima de otro creyendo que está en el suyo. */
.nube-abierto { background: rgba(241,192,46,.14); }
#nubePanel { z-index: 106; }

/* V178 · «Abrir…» muestra las dos procedencias en una sola lista: el lugar es una sección,
   no un menú distinto. */
.abrir-sec { margin: 14px 0 4px; font-size: 13px; opacity: .85; }

/* V179 · Diálogo de tres salidas: la segura primero. Sustituye al aviso que solo ofrecía
   «continuar y perder» o «cancelar». */
.pregunta-card { max-width: 470px; }
.pregunta-card h2 { margin: 0 0 8px; }
#preguntaPanel { z-index: 120; }

/* V180 · Estado de sincronización por proyecto: una sola entrada en la lista, como en Drive o
   Dropbox. El color no es el único portador del significado — cada estado lleva su símbolo. */
.sync-chip { font-size: 11px; font-weight: 400; padding: 1px 7px; border-radius: 999px; border: 1px solid var(--line, #d9dee3); white-space: nowrap; vertical-align: middle; }
.sync-ok { background: rgba(46,160,67,.12); }
.sync-pendiente { background: rgba(241,192,46,.22); }
.sync-nueva { background: rgba(62,75,99,.14); }
.sync-local, .sync-espera { opacity: .75; }

/* V230 · Calidad de la aplicación. La insignia de gravedad/utilidad lleva el color en el borde y no
   en el fondo: en una lista de doce fichas, doce rectángulos de color compiten con el texto y no se
   lee ninguno. El borde marca sin gritar. */
.calidad-chip { display:inline-block; border:1px solid #4a5560; border-radius:10px; padding:1px 7px; font-size:11px; font-weight:700; margin-right:6px; vertical-align:2px; }
.calidad-encargo { display:block; font-size:12px; color:#2c3a45; margin:2px 0 0; }
.calidad-resolucion { background:#f2f7f2; border-left:3px solid #4b7a4b; padding:6px 9px; margin:6px 0 0; font-size:12px; }
.calidad-voto.votada { background:#fff6dd; border-color:#F1C02E; font-weight:700; }

/* V231 · la gestión de una ficha va dentro de ella, en una fila compacta: asignar y poner fecha se
   hace mirando lo que dice el fallo. */
.calidad-gestion { display:flex; flex-wrap:wrap; gap:8px; align-items:flex-end; margin:8px 0 0; padding:8px; background:#f7f8f9; border:1px solid #e3e7ea; border-radius:7px; }
.calidad-gestion label { display:flex; flex-direction:column; font-size:11px; font-weight:700; color:#4a5560; gap:2px; }
.calidad-gestion select, .calidad-gestion input { height:28px; font-size:12px; border:1px solid #ccd3d8; border-radius:5px; padding:2px 6px; background:#fff; }
.calidad-gestion .calidad-resol { flex:1 1 220px; }
.calidad-gestion .calidad-resol input { width:100%; }

/* V233 · CALIDAD — tabla y filtros como en el Portal. Las insignias llevan el color en el fondo
   igual que allí (`.b` del portal), para que quien use las dos aplicaciones reconozca lo mismo. */
.calidad-card { max-width: 1040px; }
.calidad-barra { display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin:0 0 10px; }
.calidad-barra .calidad-sep { flex:1 1 auto; }
.calidad-barra input[type="search"] { width:160px; }
.calidad-barra select, .calidad-barra input { height:30px; font-size:12px; border:1px solid #ccd3d8; border-radius:6px; padding:2px 6px; background:#fff; }
.cal-b { display:inline-block; border-radius:9px; padding:1px 6px; font-size:9.5px; font-weight:800; letter-spacing:.02em; color:#fff; background:#8a949c; }
.cal-b.bad { background:#b3261e; } .cal-b.warn { background:#c05621; } .cal-b.blue { background:#2c5c8a; }
.cal-b.ok { background:#3f7a3f; } .cal-b.na { background:#8a949c; }
.cal-kpi-on { outline:2px solid #F1C02E; }
.cal-tabla { overflow-x:auto; }
.cal-tabla table { width:100%; border-collapse:collapse; font-size:12.5px; }
.cal-tabla th { text-align:left; font-size:10.5px; text-transform:uppercase; letter-spacing:.04em; color:#6b757d; border-bottom:1px solid #dfe4e8; padding:4px 6px; }
.cal-tabla td { border-bottom:1px solid #eef1f3; padding:6px; vertical-align:top; }
.cal-tabla tr.cal-cerrada { opacity:.55; }
.cal-tabla tr.cal-pend { background:#fffaf0; }
.cal-tabla .cal-acc { text-align:right; white-space:nowrap; }
.cal-desc { color:#3a464f; margin:3px 0 0; white-space:pre-wrap; }
.cal-voto-on { background:#fff6dd; border-color:#F1C02E; font-weight:700; }

/* V240 · el diagnóstico de rendimiento: texto tal cual, monoespaciado y con desplazamiento propio.
   Se lee y se copia; no es una tabla que haya que interpretar. */
.perf-texto { background:#f7f8f9; border:1px solid #e3e7ea; border-radius:7px; padding:10px 12px; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:11.5px; line-height:1.5; white-space:pre-wrap; max-height:52vh; overflow:auto; margin:0 0 10px; }

/* V255 · PARTIDAS Y SERVICIOS de la oferta. Reutilizan la fila de «Precios de la oferta»
   —misma anatomía, mismo resalte ✎ cuando se desvían de la tarifa— y añaden solo lo que no
   existía: la cantidad y la fila de alta. */
.comp-ovqty { flex: 0 0 58px; width: 58px; font-size: 10.5px; padding: 2px 5px; text-align: right; }
.comp-parnew { gap: 6px; margin-top: 4px; }
.comp-parnew select { flex: 1 1 140px; min-width: 100px; font-size: 10.5px; padding: 2px 4px; }


/* V258 · RELACIÓN VALORADA POR BLOQUES (petición de Sergi 08/09/2026: «quedan todas las líneas
   consecutivas y es confuso»). Cada bloque cierra con su total en negrita y deja un hueco antes del
   siguiente; el TOTAL GENERAL cierra la tabla, más marcado.
   El hueco es una FILA y no un margen: entre filas de una tabla un margen no existe, y al imprimir
   el navegador lo descartaría. */
.rep-bom-sub td { font-weight: 700; background: #fdf6e3; border-top: 1.2px solid #c8a54a; padding-top: 3px; padding-bottom: 3px; }
.rep-bom-sub td:first-child { text-align: right; padding-right: 8px; }
.rep-bom-gap td { height: 7px; padding: 0; border: 0; background: transparent; }
.rep-bom-sub.rep-bom-grand td { font-size: 1.06em; background: #f6e6c2; border-top: 2.2px double #a97c12; border-bottom: 1.2px solid #a97c12; }
/* Un subtotal separado de su bloque por un salto de página se lee como el total de la página
   siguiente: ni la fila se parte ni se queda huérfana al principio de una hoja. */
.rep-bom-sub, .rep-bom-gap { break-inside: avoid; page-break-inside: avoid; }
.rep-bom-sub { break-before: avoid; page-break-before: avoid; }

/* V263 · el grado de protección se recalcula en cuanto la mano se para; mientras tanto se enseña el
   anterior Y SE DICE. Ámbar, no rojo: no es un error, es un dato que está llegando. */
.ipi-calculando { color: #9a7b1c; font-weight: 600; }

/* V264 · «Preparando el informe…». Ocupa el sitio del documento, que es donde se mira, en vez de una
   línea pequeña en el pie con el panel en blanco. Sin animación a propósito: la generación bloquea el
   hilo y una rueda parada se lee como «colgado». */
.rep-cargando { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; padding: 48px 24px; text-align: center; color: #5c6a75; }
.rep-cargando-icono { font-size: 34px; line-height: 1; }
.rep-cargando-t { font-size: 15px; font-weight: 700; margin: 2px 0 0; }
.rep-cargando-s { font-size: 12px; max-width: 440px; margin: 0; opacity: .85; }

/* ============================================================================================
   V300 · ESPACIO DE TRABAJO: UNA SOLA BARRA Y EL ÁREA REPARTIDA EN PANELES
   Medido antes de tocar nada (20/09/2026, Chrome, 1920×1080): el lienzo de planta se quedaba con
   546 px de 1080 (50,6 %). Encima llevaba tres franjas horizontales apiladas —cabecera 58 + barra
   de planta 39 + barra de perfil 43 = 140 px— y debajo el perfil permanente al 33 %.
   En 16:9 el alto es el recurso escaso y el ancho sobra: la planta tenía 1.576 px de ancho.
   De ahí el reparto de esta versión, que es el de las suites de dibujo:
     · lo que es de MIRAR (capas, disposición) → barra general, arriba;
     · lo que es de DIBUJAR                    → carril VERTICAL sobre el lienzo (gasta ancho);
     · lo que es de NAVEGAR                    → HUD flotante sobre el propio lienzo (gasta cero);
     · perfil y 3D                             → paneles opcionales del área de trabajo.
   Ningún control se ha eliminado: todos conservan su id y su escuchador.
   ============================================================================================ */

/* --- barra general: grupos nuevos ---------------------------------------------------------- */
.top-tools { display:inline-flex; gap:6px; align-items:center; }
.top-screen { display:inline-flex; gap:4px; align-items:center; margin-left:4px; }
.quick-btn.icon-btn svg { width:16px; height:16px; display:block; }
.quick-btn.icon-btn.active { background:var(--irtim-yellow); border-color:var(--irtim-yellow-dark); }
.menu.tool-menu > summary { padding:8px 10px; }

/* --- «Capas ▾»: los ocho interruptores, ahora con NOMBRE ----------------------------------- */
/* Eran ocho iconos sin rótulo en una barra de 26 px: al sacarlos de la barra dejan de pagar alto,
   así que por fin caben con su nombre escrito, que es lo que se pedía desde siempre. */
.capas-panel { min-width:264px; }
.capas-grid { display:flex; flex-direction:column; gap:1px; }
.capas-grid button { display:flex; align-items:center; gap:9px; width:100%; justify-content:flex-start;
  text-align:left; background:transparent; color:#2a2f35; font-weight:700; font-size:12px;
  padding:7px 9px; border-radius:7px; border:1px solid transparent; }
.capas-grid button svg { width:16px; height:16px; flex:0 0 16px; display:block; color:#7d8b96; }
.capas-grid button:hover { background:var(--irtim-yellow-soft); }
.capas-grid button.active { background:#fff; border-color:#e6dcc2; color:#141414; }
.capas-grid button.active svg { color:var(--irtim-navy, #3E4B63); }
/* El estado se lee sin depender del color: punto lleno = encendida. */
.capas-grid button::after { content:''; margin-left:auto; width:9px; height:9px; border-radius:50%;
  border:1.5px solid #b9c2c9; background:transparent; flex:0 0 9px; }
.capas-grid button.active::after { background:var(--irtim-yellow); border-color:var(--irtim-yellow-dark); }
.capas-panel .menu-field select { width:100%; }

/* --- «Disposición ▾»: cuatro presets con su dibujo ------------------------------------------ */
.layout-panel { min-width:290px; }
.layout-opt { display:flex; align-items:center; gap:10px; width:100%; justify-content:flex-start;
  text-align:left; background:transparent; padding:7px 9px; border-radius:7px;
  border:1px solid transparent; }
.layout-opt:hover { background:var(--irtim-yellow-soft); }
.layout-opt.active { background:#fff; border-color:#e6dcc2; }
.layout-txt { display:flex; flex-direction:column; gap:1px; }
.layout-txt b { font-size:12px; color:#141414; }
.layout-txt small { font-size:10px; color:#8a8271; }
.layout-ico { flex:0 0 30px; width:30px; height:23px; display:grid; gap:2px; padding:2px;
  border:1.5px solid #b9c2c9; border-radius:4px; background:#fff; }
.layout-opt.active .layout-ico { border-color:var(--irtim-yellow-dark); }
.layout-ico i { background:#ccd5db; border-radius:1px; display:block; }
.layout-opt.active .layout-ico i { background:var(--irtim-yellow); }
.li-single { grid-template:1fr / 1fr; }
.li-stack  { grid-template:1fr 1fr / 1fr; }
.li-side   { grid-template:1fr / 1fr 1fr; }
.li-tri    { grid-template:1fr 1fr / 1fr 1fr; }
.li-tri i:first-child { grid-row:1 / span 2; }

/* --- área de trabajo: cuatro disposiciones -------------------------------------------------- */
/* «single» y «stack» siguen siendo COLUMNA FLEX: así el divisor arrastrable y su reparto
   (--plan-share / --profile-share, números sin unidad que alimentan flex-grow) siguen funcionando
   exactamente igual que antes. Una unidad fr no se puede componer con un var() sin unidad, y forzarlo por
   rejilla dejaba el divisor a 0 px: con dos ejes de reparto distintos, cada uno con su mecanismo.
   «side» y «tri» sí son rejilla: ahí el reparto es fijo y el divisor no pinta nada. */
.workspace { display:flex; flex-direction:column; gap:10px; min-width:0; }
.workspace > .view-block { min-width:0; }
.workspace[data-layout="single"] > .pane-plan { flex:1 1 auto; }
.workspace[data-layout="stack"] > .pane-plan { flex: var(--plan-share, 62) 1 0; }
.workspace[data-layout="stack"] > .pane-profile { flex: var(--profile-share, 38) 1 0; }
.workspace[data-layout="side"], .workspace[data-layout="tri"] { display:grid; }
.workspace[data-layout="side"] { grid-template:1fr / minmax(0,1.35fr) minmax(0,1fr);
  grid-template-areas:"plan tresd"; }
.workspace[data-layout="tri"]  { grid-template:1fr 1fr / minmax(0,1.3fr) minmax(0,1fr);
  grid-template-areas:"plan tresd" "plan perfil"; }
.workspace[data-layout="side"] > .pane-plan, .workspace[data-layout="tri"] > .pane-plan { grid-area:plan; }
.workspace[data-layout="tri"] > .pane-profile { grid-area:perfil; }
.workspace[data-layout="side"] > .pane-3d, .workspace[data-layout="tri"] > .pane-3d { grid-area:tresd; }
/* El divisor solo tiene sentido en «stack»; en el resto estorba y miente sobre lo que hace. */
.workspace:not([data-layout="stack"]) > .split-divider { display:none; }

/* --- cabecera de panel: 26 px, y NINGUNA cuando solo hay planta ----------------------------- */
.pane-head { min-height:26px; padding:3px 10px; display:flex; align-items:center; gap:10px;
  justify-content:space-between; border-bottom:1px solid #e4eaee; flex-wrap:wrap; }
.pane-head .pane-title { display:flex; align-items:baseline; gap:8px; }
.pane-head .pane-title strong { font-size:11px; }
.pane-head .pane-title span { font-size:10px; color:#71808a; }
/* Con un solo panel no hay nada que distinguir ni dónde cambiar de vista: la franja sobra y el
   dibujo se queda sus 26 px. Es la ganancia que pedía el encargo. */
.workspace[data-layout="single"] .pane-plan > .pane-head { display:none; }

/* --- carril vertical de herramientas de dibujo ---------------------------------------------- */
.plan-shell { position:relative; }
.tool-rail { position:absolute; left:8px; top:8px; z-index:7; display:flex; flex-direction:column;
  gap:2px; padding:4px; background:rgba(255,255,255,.95); border:1px solid #dfe6ea;
  border-radius:10px; box-shadow:0 4px 14px rgba(23,35,45,.12); }
.tool-rail button { width:32px; height:30px; padding:4px; border-radius:7px; background:transparent;
  color:#43525c; display:inline-flex; align-items:center; justify-content:center; font-size:14px;
  line-height:1; }
.tool-rail button svg { width:16px; height:16px; display:block; }
.tool-rail button:hover { background:#e2e8ec; }
.tool-rail button.active { background:var(--irtim-yellow); color:#141414; }
.tool-rail .rail-sep { height:1px; margin:2px 3px; background:#dde4e9; }

/* --- HUD de navegación sobre el propio lienzo ----------------------------------------------- */
.canvas-hud { position:absolute; right:8px; top:8px; z-index:7; display:flex; align-items:center;
  gap:2px; padding:4px 5px; background:rgba(255,255,255,.95); border:1px solid #dfe6ea;
  border-radius:10px; box-shadow:0 4px 14px rgba(23,35,45,.12); }
.canvas-hud button { width:30px; height:28px; padding:5px; border-radius:6px; background:transparent;
  color:#43525c; display:inline-flex; align-items:center; justify-content:center; }
.canvas-hud button svg { width:16px; height:16px; display:block; }
.canvas-hud button:hover { background:#e2e8ec; }
.canvas-hud button.active { background:var(--irtim-yellow); color:#141414; }
.canvas-hud .hud-sep { width:1px; height:18px; background:#d5dde2; margin:0 2px; }
/* El salto del imán ocupaba 169 px en la barra vieja —el 15 % de toda la barra— porque el ancho lo
   fijaba el texto más largo. Aquí el ancho no le cuesta alto a nadie, pero se compacta igual. */
.canvas-hud .hud-select { font-size:10px; padding:3px 4px; height:26px; max-width:74px;
  border:1px solid #ccd5db; border-radius:6px; background:#fff; }

/* --- panel del 3D dentro del área de trabajo ------------------------------------------------ */
.threed-shell { position:relative; padding:6px; display:flex; }
.threed-shell #threeDCanvas { width:100%; height:100% !important; min-height:0; flex:1 1 auto;
  border:1px solid #dfe5ea; border-radius:8px; background:linear-gradient(#f6f9fb, #eef3f6);
  cursor:grab; touch-action:none; }
#pane3DTools { flex-wrap:wrap; }
#pane3DTools button { width:auto; min-width:30px; height:24px; padding:3px 7px; font-size:10px;
  font-weight:700; }
#pane3DTools button svg { width:14px; height:14px; }
#pane3DTools .pane3d-moved { display:inline-flex; align-items:center; gap:3px; flex-wrap:wrap; }

/* --- perfil: botones nuevos de su cabecera -------------------------------------------------- */
#profileFloatBtn, #profileCloseBtn, #pane3DCloseBtn { font-size:13px; font-weight:800; line-height:1; }

/* --- tarjeta flotante del perfil ------------------------------------------------------------ */
.float-card-perfil { width:min(60vw, 720px); height:min(46vh, 380px); }
.float-card-perfil .float-body { display:flex; padding:6px; }
.float-card-perfil .profile-shell { flex:1 1 auto; min-height:0; width:100%; }

/* --- la salvedad metodológica, por fin visible ---------------------------------------------- */
.statusbar-aviso { font-size:11px; color:#ffd7a1; cursor:help; white-space:nowrap; }

/* --- pantallas estrechas: la barra general se parte antes de comerse el dibujo -------------- */
@media (max-width:1560px) {
  .brand-lockup .brand-logo { max-width:150px; }
  .menu.tool-menu > summary, .top-menus .menu > summary { padding:8px 8px; font-size:11px; }
}

/* V300 · medir o capturar el 3D no puede depender de qué disposición tuviera el técnico. Con esta
   clase el panel se saca de la pantalla con un tamaño fijo: el lienzo tiene layout de verdad (si no,
   mide 0 y no se dibuja nada) y no hay parpadeo. Lo ponen y lo quitan abre3DParaMedir / cierra3DTrasMedir. */
.pane-3d.midiendo-3d { position: fixed; left: -10000px; top: 0; width: 1100px; height: 640px; z-index: -1; }
.float-card-perfil .float-body > .view-block { flex: 1 1 auto; min-height: 0; width: 100%; border: 0; box-shadow: none; }

/* ================== V303 · PLEGAR EL PANEL LATERAL VOLVÍA A UNA MAQUETA MUERTA ==================
   Reporte de Sergi (21/09/2026): con las tres vistas y el panel lateral plegado «queda un espai buit
   a la dreta». Medido a 1920×1080, y era peor que un hueco:

     desplegado       → columnas `296px 1581px`     · área de trabajo 1.581 px
     plegado (antes)  → columnas `0px 1557px 320px` · área de trabajo 1.557 px  ← MÁS PEQUEÑA
     ambos plegados   → columnas `0px 1877px 0px`   · área de trabajo 1.877 px

   O sea que plegar el panel para ganar sitio PERDÍA 24 px y dejaba 320 px muertos a la derecha.
   Dos causas, las dos de código viejo que nadie volvió a mirar:

   1 · La maqueta REAL es de DOS columnas desde la V120, cuando el panel de resultados se mudó al
       lateral izquierdo: `main.layout { grid-template-columns: 296px minmax(0,1fr) }`. Pero la regla
       de plegado seguía siendo la de TRES (`0 minmax(520px,1fr) 320px`) y, por especificidad, ganaba:
       resucitaba una tercera columna de 320 px sin ocupante desde entonces.
   2 · `body.collapse-left .controls { display:none }` (línea 810) y `aside.panel.controls
       { display:flex }` (línea 1059) tienen la MISMA especificidad, y la segunda va después: ganaba
       ella. El panel «plegado» seguía dibujándose a 300 px, desbordando una columna de 0.

   Se escriben contra la maqueta que existe hoy y con especificidad suficiente para no depender del
   orden del fichero. Medido después: plegado → `0px 1877px`, área de trabajo 1.877 px y 29 px a la
   derecha, que son el relleno de la página. */
body.collapse-left main.layout { grid-template-columns: 0 minmax(0, 1fr); }
body.collapse-left aside.panel.controls { display: none; }
/* `collapse-right` es vestigial desde la V120 —no hay panel derecho que plegar— pero mientras su
   interruptor exista no puede reintroducir la tercera columna. */
body.collapse-right main.layout { grid-template-columns: 296px minmax(0, 1fr); }
body.collapse-left.collapse-right main.layout { grid-template-columns: 0 minmax(0, 1fr); }

/* ============= V304 · EL PANEL DEL 3D SE REPARTE POR REJILLA, NO POR CONTENIDO =============
   Tercer y último acto del reporte de Sergi (21/09/2026): «la imatge de la vista 3D es mou cap avall
   sola amb petits salts». La V303 lo dejó diagnosticado y sin arreglar, y con razón: los tres
   intentos de aquel día compensaban el síntoma sin quitar la causa.

   LA CAUSA, medida: el alto del lienzo se calculaba a partir de una caja cuyo alto se calculaba a
   partir de su contenido — que es el propio lienzo. Un círculo. Mientras nadie volviera a medir, el
   círculo dormía; el `ResizeObserver` de la V302 existe justo para volver a medir, así que lo puso
   en marcha: 395 → 398 → 401 → 404 → 407 → 410 px en dos segundos, tres píxeles por pasada.

   Y había un segundo círculo encima, que es el que despistó: la CABECERA del panel también crecía
   —medidos 487 px de cabecera dentro de un panel de 489— y se comía el hueco que el lienzo intentaba
   ocupar. Por eso cada arreglo parcial movía el problema de sitio en vez de cerrarlo.

   LA SALIDA no es un cuarto parche, es quitar el círculo: el panel se reparte por REJILLA con filas
   `auto 1fr`. La cabecera pide lo que ocupa, la caja del lienzo recibe EXACTAMENTE el resto, y una
   fila `1fr` con `min-height:0` NO consulta a su contenido: no hay a quién preguntar. Y el lienzo va
   posicionado en absoluto, así que tampoco aporta alto a nadie.

   Resultado: nada de lo que el lienzo mida puede influir en el sitio que se le da. El observador de
   la V302 puede seguir mirando; no hay bucle que encender.

   La planta y el perfil NO se tocan: llevan años funcionando y su caja nunca compitió con una
   cabecera de nueve botones. */
.workspace .pane-3d { display: grid; grid-template-rows: auto minmax(0, 1fr); min-height: 0; }
.workspace .pane-3d > .pane-head { min-width: 0; overflow: hidden; }
.workspace .pane-3d > .threed-shell { position: relative; min-height: 0; padding: 0; display: block; }
/* OJO con el `auto`: un <canvas> es un elemento REEMPLAZADO, y en posicionamiento absoluto un
   `height:auto` NO se estira entre `top` y `bottom` — toma su tamaño intrínseco, o sea el atributo
   `height` que le acaba de escribir `resizeOneCanvas`. Eso es el bucle otra vez, disfrazado. Se le da
   el alto EXPLÍCITO contra la caja, que sí tiene altura definida por la rejilla. */
.workspace .pane-3d > .threed-shell > #threeDCanvas { position: absolute; top: 6px; left: 6px;
  width: calc(100% - 12px) !important; height: calc(100% - 12px) !important;
  display: block; box-sizing: border-box; }

/* La cabecera medía 487 px CONSTANTES dentro de un panel de 489: no crecía, es que nacía así. En un
   panel estrecho el título no encogía, los nueve mandos se quedaban con ~100 px de ancho y se partían
   uno por línea (y algunos en dos). Las reglas de arriba no la arreglaban porque `#pane3DTools` lleva
   `flex-wrap: wrap` desde la V300 y un id gana a cualquier combinación de clases: se anula con el
   mismo peso, que es lo honesto — reescribir la regla vieja habría dejado la modal sin su reparto. */
.workspace .pane-3d #pane3DTools { flex-wrap: nowrap; min-width: 0; overflow-x: auto; overflow-y: hidden; }
.workspace .pane-3d #pane3DMoved { flex-wrap: nowrap; }
.workspace .pane-3d > .pane-head .pane-title { flex: 0 1 auto; min-width: 0; overflow: hidden; }
/* El subtítulo («solo visualización · arrastra para orbitar») es una ayuda, no un dato: en un panel
   estrecho compite con los mandos y gana el que no debe. Se queda en el `title` de la cabecera. */
.workspace[data-layout="tri"] .pane-3d > .pane-head .pane-title span,
.workspace[data-layout="side"] .pane-3d > .pane-head .pane-title span { display: none; }

/* ============ V307 · LA FILA DE UNA PARTIDA NO SE DESMONTA, Y EL QUITAR SE VE ============
   Reporte de Sergi (22/09/2026): «las líneas de partidas y servicios se deberían poder borrar».
   Se podían —el botón estaba y funcionaba—; lo que no se podía era encontrarlo. Medido en el
   compositor, cuyo panel de opciones mide 299 px: los cinco controles en una fila flexible no caben,
   la fila se partía en TRES líneas de 90 px de alto y el «×» —de 20 px— acababa en la segunda,
   pegado al campo de precio y con la misma pinta que el «↺» de «Precios de la oferta», que significa
   otra cosa (volver al valor oficial, no quitar la línea).

   Rejilla de dos filas, y deja de depender del ancho: arriba la referencia y el quitar —pinchado a la
   derecha, siempre en el mismo sitio—; abajo los tres campos. El quitar tiene además su propio
   aspecto: en rojo al pasar por encima, porque quita una línea de la oferta y eso no se deshace
   solo. */
.comp-row.comp-parrow { display: grid; grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "ref quitar" "campos campos"; gap: 3px 6px; align-items: center; }
.comp-parrow > .comp-ovref { grid-area: ref; max-width: none; }
.comp-parrow > .comp-parquita { grid-area: quitar; }
.comp-parrow > .comp-parcampos { grid-area: campos; display: flex; align-items: center; gap: 4px;
  flex-wrap: wrap; min-width: 0; }
.comp-parquita { flex: 0 0 auto; width: 22px; height: 20px; padding: 0; line-height: 1;
  font-size: 11px; font-weight: 700; cursor: pointer; color: #8a95a3;
  background: transparent; border: 1px solid #d9dfe6; border-radius: 5px; }
.comp-parquita:hover { color: #fff; background: var(--irtim-red, #b4232f); border-color: var(--irtim-red, #b4232f); }
.comp-parquita:focus-visible { outline: 2px solid var(--irtim-red, #b4232f); outline-offset: 1px; }

/* V323 · PT automática: modo binario y lista de elementos a vigilar. */
.pt-modo { display: flex; gap: 14px; margin: 4px 0 8px; }
.pt-objetivo-lista { max-height: 220px; overflow: auto; border: 1px solid #d8dfe5; border-radius: 6px; padding: 4px 8px; margin: 6px 0; font-size: 12px; }
.pt-objetivo-lista .pt-grupo { font-weight: 700; margin: 6px 0 2px; }
.pt-objetivo-lista label { display: flex; gap: 6px; align-items: center; margin: 2px 0 2px 10px; }
.pt-objetivo-lista .pt-grupo label { margin-left: 0; }
/* V325 · informe ejecutivo */
.rep-modo { display: inline-flex; gap: 0; margin: 4px 0 2px; border: 1px solid #c9d2da; border-radius: 6px; overflow: hidden; }
.rep-modo button { border: 0; border-radius: 0; background: #fff; color: #2b3238; padding: 4px 12px; }
.rep-modo button.selected { background: #1f2a33; color: #fff; }
.rep-clave-kpi { display: flex; gap: 12px; flex-wrap: wrap; margin: 6px 0 10px; }
.rep-clave-kpi > div { flex: 1 1 140px; border: 1px solid #e3e8ec; border-radius: 6px; padding: 8px 10px; }
.rep-clave-kpi b { display: block; font-size: 20px; }
.rep-cover-ejec { display: inline-block; margin-top: 3mm; font-size: 18px; font-weight: 700; color: #8a6a00; letter-spacing: .02em; }
/* V325 · P-37: lo no emitido sale como BORRADOR, en pantalla y en papel */
.rep-borrador .rep-pg { position: relative; }
.rep-borrador .rep-pg::after { content: 'BORRADOR · no emitido'; position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) rotate(-35deg);
  font: 900 54px/1 system-ui, sans-serif; letter-spacing: .04em; color: rgba(180, 35, 47, .13); white-space: nowrap; pointer-events: none; z-index: 5;
  -webkit-print-color-adjust: exact; print-color-adjust: exact; }
/* V323 · PT con estaciones desactualizadas */
.pt-caduca { background: #fff1d6; color: #8a4b00; border-color: #e0a640; cursor: pointer; }
/* V323 · rango mecánico de la PT */
.pt-rango { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin: 4px 0; }
.pt-rango label { font-size: 12px; }
