/* Panel interno (sala de control) — consume los tokens del Design System (ds.css).
 * No redefine tokens: solo compone layout con las variables ya congeladas. */

*, *::before, *::after { box-sizing: border-box; }

/* Una clase con `display` (.btn, .dictado, .mesa-barra) le gana al atributo
 * [hidden] del navegador: sin esta línea, lo que nace oculto se ve siempre. */
[hidden] { display: none !important; }

body.panel,
body.panel-auth {
  margin: 0;
  font-family: var(--font-primary);
  color: var(--text);
  background: var(--bg);
  line-height: var(--leading-body);
}

/* --------------------------------------------------------------------------- */
/* Login                                                                        */
/* --------------------------------------------------------------------------- */
.panel-auth { min-height: 100vh; display: grid; place-items: center; padding: var(--space-6); }

.auth__card {
  width: 100%; max-width: 380px;
  display: flex; flex-direction: column; gap: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-8);
  box-shadow: var(--shadow-lg);
}
.auth__logo { height: 34px; width: auto; align-self: flex-start; }
.auth__title { margin: 0; font-family: var(--font-heading); font-size: var(--fs-h3); color: var(--heading-color); }
.auth__sub { margin: calc(-1 * var(--space-2)) 0 0; color: var(--text-soft); font-size: var(--fs-small); }
.auth__error {
  margin: 0; padding: var(--space-2) var(--space-3);
  background: #fdecec; color: #a12222;
  border: 1px solid #f3c2c2; border-radius: var(--radius-sm);
  font-size: var(--fs-small);
}
.auth__field { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--fs-small); color: var(--text-soft); }
.auth__field input {
  font: inherit; color: var(--text);
  padding: var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg);
}
.auth__field input:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-color: var(--brand-primary); }
.auth__btn {
  margin-top: var(--space-2);
  font: inherit; font-weight: var(--weight-heading);
  color: #fff;
  background: var(--brand-primary);
  border: 0; border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  cursor: pointer;
  transition: background var(--dur-2) var(--ease-standard);
}
.auth__btn:hover { background: var(--azul-800); }

/* --------------------------------------------------------------------------- */
/* Shell del panel                                                             */
/* --------------------------------------------------------------------------- */
.panel { display: grid; grid-template-columns: 248px 1fr; min-height: 100vh; }

.panel__side {
  display: flex; flex-direction: column; gap: var(--space-6);
  background: var(--brand-navy); color: var(--navy-text-soft);
  padding: var(--space-6) var(--space-4);
  position: sticky; top: 0; height: 100vh;
}
.panel__brand { display: block; }
.panel__brand img { height: 30px; width: auto; }

.panel__nav { display: flex; flex-direction: column; gap: var(--space-1); }
.panel__nav-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--navy-text-soft); text-decoration: none;
  font-size: var(--fs-small);
  transition: background var(--dur-2) var(--ease-standard), color var(--dur-2) var(--ease-standard);
}
.panel__nav-item:hover { background: var(--navy-surface-2); color: #fff; }
.panel__nav-item.is-active { background: var(--navy-surface-2); color: #fff; box-shadow: inset 3px 0 0 var(--brand-aqua); }
.panel__nav-item.is-soon { opacity: .55; cursor: default; }
.panel__nav-item small {
  font-size: 10px; text-transform: uppercase; letter-spacing: var(--tracking-caps);
  color: var(--brand-aqua); border: 1px solid var(--navy-border); border-radius: var(--radius-full);
  padding: 1px var(--space-2);
}
.panel__side-foot {
  margin-top: auto; color: var(--navy-text-soft); opacity: .6; font-size: var(--fs-small);
  display: grid; gap: var(--space-2); justify-items: start;
}
/* Manual de marca: consulta, no función del negocio. Discreto, al pie. */
.panel__nav-foot { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

.panel__main { display: flex; flex-direction: column; min-width: 0; }
.panel__top {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--space-4) var(--space-8);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 5;
}
.panel__crumb { font-family: var(--font-heading); font-weight: var(--weight-heading); color: var(--heading-color); }
.panel__user { display: flex; align-items: center; gap: var(--space-3); font-size: var(--fs-small); }
.panel__user-name { color: var(--text); }
.panel__badge {
  text-transform: uppercase; letter-spacing: var(--tracking-caps); font-size: 11px;
  color: var(--azul-700); background: var(--azul-100);
  border-radius: var(--radius-full); padding: 2px var(--space-2);
}
.panel__logout { color: var(--text-soft); text-decoration: none; }
.panel__logout:hover { color: var(--brand-primary-ink); text-decoration: underline; }

.panel__content { padding: var(--space-8); display: flex; flex-direction: column; gap: var(--space-6); }

/* --------------------------------------------------------------------------- */
/* Tarjetas                                                                     */
/* --------------------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
.card--hero { background: linear-gradient(180deg, var(--azul-50), var(--surface)); }
.card__title { margin: 0 0 var(--space-1); font-family: var(--font-heading); font-size: var(--fs-h2); color: var(--heading-color); }
.card__muted { margin: 0; color: var(--text-soft); }

.cards-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-4); }
.card--soon h3 { margin: 0 0 var(--space-2); font-family: var(--font-heading); color: var(--heading-color); }
.tag {
  display: inline-block; margin-top: var(--space-3);
  font-size: var(--fs-small); color: var(--text-muted);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-full); padding: 2px var(--space-3);
}

@media (max-width: 1024px) {
  .panel { grid-template-columns: 1fr; }
  /* Sidebar -> barra superior compacta y sticky; el nav fluye en horizontal. */
  .panel__side {
    position: sticky; top: 0; z-index: 20; height: auto;
    flex-direction: row; align-items: center; flex-wrap: wrap; gap: var(--space-2) var(--space-3);
    padding: var(--space-3) var(--space-4);
  }
  .panel__brand { flex: 0 0 auto; }
  .panel__brand img { height: 24px; }
  .panel__nav { flex: 1 1 auto; flex-direction: row; flex-wrap: wrap; gap: var(--space-1); }
  .panel__nav-item { white-space: nowrap; padding: var(--space-2); }
  .panel__nav-item.is-active { box-shadow: inset 0 -2px 0 var(--brand-aqua); }
  .panel__side-foot { display: none; }
  .panel__content, .panel__top { padding-left: var(--space-4); padding-right: var(--space-4); }
  .panel__content { padding-top: var(--space-5); gap: var(--space-4); }
}

/* --------------------------------------------------------------------------- */
/* CRUD de cotizaciones (lista / alta / editor)                                */
/* --------------------------------------------------------------------------- */
.muted { color: var(--text-soft); margin: 0; }
.mono { font-variant-numeric: tabular-nums; font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; }
.right { text-align: right; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.row-gap { display: flex; align-items: center; gap: var(--space-2); }
.section-title { margin: 0; font-family: var(--font-heading); font-size: var(--fs-h2); color: var(--heading-color); }
.empty { padding: var(--space-6); color: var(--text-soft); text-align: center; }

/* Botones */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font: inherit; font-weight: var(--weight-heading); line-height: 1;
  padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm);
  border: 1px solid transparent; cursor: pointer; text-decoration: none;
  transition: background var(--dur-2) var(--ease-standard), border-color var(--dur-2) var(--ease-standard);
}
.btn--sm { padding: var(--space-2) var(--space-3); font-size: var(--fs-small); }
.btn--primary { background: var(--brand-primary); color: #fff; }
.btn--primary:hover { background: var(--azul-800); }
.btn--secondary { background: var(--azul-100); color: var(--brand-primary-ink); }
.btn--secondary:hover { background: var(--azul-200); }
.btn--ghost { background: transparent; border-color: var(--border-strong); color: var(--text); }
.btn--ghost:hover { border-color: var(--brand-primary); color: var(--brand-primary-ink); }

/* Tabla */
.card--flush { padding: 0; overflow: hidden; }
.card__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); padding: var(--space-5) var(--space-6); border-bottom: 1px solid var(--border); }
.card__h { margin: 0; font-family: var(--font-heading); color: var(--heading-color); }
/* Vista previa del documento cargado. Alto fijo y generoso: el revisor tiene que
   poder juzgarlo sin abrirlo aparte, pero la página sigue siendo la del panel. */
.doc-preview { width: 100%; height: 70vh; min-height: 420px; border: 1px solid var(--border); border-radius: var(--radius-2, 6px); background: #fff; }
/* Documentos (14-oct-2026, «no despliega»). Alto base si el documento no avisa
   cuánto mide: casi la ventana entera, para que un HTML largo no quede reducido a
   su portada. `static/js/vista_previa.js` lo agranda al alto completo del
   documento (`--completo`) y entonces se recorre con la barra de la página. Un
   PDF lo pagina el visor del navegador: casi toda la ventana deja ver varias
   páginas. En el celular, un poco menos para que se vea el botón de arriba. */
.doc-preview--documento { height: 85vh; min-height: 480px; }
.doc-preview--pdf { height: calc(100vh - 80px); min-height: 520px; }
.doc-preview--completo { min-height: 0; }
.doc-preview__cabeza { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-4); }
.doc-preview__cabeza .card__title { margin: 0; }
@media (max-width: 640px) {
  .doc-preview--documento, .doc-preview--pdf { height: 78vh; min-height: 420px; }
  .doc-preview--completo { min-height: 0; }
}
.tbl-scroll { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; }
.tbl th, .tbl td { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); text-align: left; vertical-align: middle; }
.tbl thead th { font-size: var(--fs-small); color: var(--text-muted); text-transform: uppercase; letter-spacing: var(--tracking-caps); }
.tbl tbody tr:last-child td { border-bottom: 0; }
/* Números y códigos no se parten; feedback sutil de fila (firma DS). */
.tbl td.right, .tbl .mono, .tbl th.right { white-space: nowrap; }
.tbl tbody tr { transition: background-color var(--dur-2) var(--ease-standard); }
.tbl tbody tr:hover { background: var(--azul-50); }

/* Pills de estado */
.pill { display: inline-block; white-space: nowrap; font-size: 11px; line-height: 1.5; text-transform: uppercase; letter-spacing: var(--tracking-caps); padding: 2px var(--space-2); border-radius: var(--radius-full); background: var(--surface-2); color: var(--text-muted); border: 1px solid var(--border); vertical-align: middle; }
.pill--publicada, .pill--enviada, .pill--aceptada, .pill--aprobada_para_envio { background: #e6f6ec; color: #1c7a43; border-color: #bfe6cd; }
.pill--creada, .pill--en_preparacion { background: var(--azul-100); color: var(--azul-700); border-color: var(--azul-200); }
.pill--revision_comercial, .pill--revision_director { background: #fff4e0; color: #a15c00; border-color: #f3dcb0; }
.pill--ajustes_internos, .pill--cambios_solicitados { background: #fdecec; color: #a12222; border-color: #f3c2c2; }
.pill--rechazada { background: #fdecec; color: #a12222; border-color: #f3c2c2; }
.pill--vista_por_cliente { background: var(--azul-100); color: var(--azul-700); border-color: var(--azul-200); }
.pill--vencida { background: #f3f4f6; color: #6b7280; border-color: #d8dbe0; }
/* Entregada a satisfacción: el ciclo cerrado. Lleno, para que no se confunda con «aceptada». */
.pill--entregada { background: #1c7a43; color: #fff; border-color: #1c7a43; }
.pill--off { background: var(--surface-2); color: var(--text-muted); }

/* Seguimiento: pestañas-filtro (conteo + filtro en una fila) */
.seg-tabs { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-4); }
.seg-tab {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-full);
  border: 1px solid var(--border); background: var(--surface); color: var(--text-soft);
  text-decoration: none; font-size: var(--fs-small); font-weight: var(--weight-heading);
  transition: background var(--dur-2) var(--ease-standard), border-color var(--dur-2) var(--ease-standard), color var(--dur-2) var(--ease-standard);
}
.seg-tab:hover { border-color: var(--brand-primary); color: var(--brand-primary-ink); }
.seg-tab.is-active { background: var(--brand-navy); border-color: var(--brand-navy); color: #fff; }
.seg-tab__n { font-variant-numeric: tabular-nums; background: var(--surface-2); color: var(--text-muted); border-radius: var(--radius-full); padding: 0 var(--space-2); font-size: 11px; }
.seg-tab.is-active .seg-tab__n { background: rgba(255,255,255,.22); color: #fff; }
.seg-hint { display: block; color: var(--text-muted); font-size: var(--fs-small); }
.seg-hint--warn { color: #a12222; }
.seg-actions { display: inline-flex; gap: var(--space-2); justify-content: flex-end; white-space: nowrap; }

/* Editor de propuesta: bloques (macros) */
.prop-macro { margin-top: var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-md); overflow: hidden; }
.prop-macro__h { padding: var(--space-3) var(--space-4); background: var(--surface-2); font-size: var(--fs-small); border-bottom: 1px solid var(--border); }
.prop-macro .tbl td { padding: var(--space-3) var(--space-4); }
.prop-sec { border-top: 1px solid var(--border); }
.prop-sec:first-of-type { border-top: 0; }
.prop-sec__row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-3) var(--space-4); }
.prop-sec__t { font-size: var(--fs-small); }
.prop-sec__edit { padding: 0 var(--space-4) var(--space-3); }
.prop-sec__edit > summary { cursor: pointer; color: var(--brand-primary-ink); font-size: var(--fs-small); font-weight: var(--weight-heading); }

/* Tiles-enlace del Inicio (KPIs clicables hacia Seguimiento) */
.home-tile { text-decoration: none; transition: border-color var(--dur-2) var(--ease-standard), transform var(--dur-2) var(--ease-standard); }
.home-tile:hover { border-color: var(--brand-primary); transform: translateY(-1px); }
.home-tile.totales__cell--big:hover { border-color: var(--brand-aqua); }

/* Flujo de aprobación */
.flujo-actions { display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start; }
.flujo-actions form { display: inline-flex; }
.w-comment { font: inherit; color: var(--text); background: var(--bg); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); min-width: 220px; }
.audit { margin-top: var(--space-5); border-top: 1px solid var(--border); padding-top: var(--space-4); }
.audit > summary { cursor: pointer; color: var(--text-soft); font-size: var(--fs-small); }
.audit__list { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.audit__list li { display: flex; justify-content: space-between; gap: var(--space-4); font-size: var(--fs-small); border-bottom: 1px dashed var(--border); padding-bottom: var(--space-2); }
.audit__t { color: var(--text); font-weight: var(--weight-heading); }
.audit__meta { color: var(--text-muted); }
.audit__coment { font-style: italic; color: var(--text-soft); }

/* Totales */
.totales { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.totales__cell { flex: 1; min-width: 160px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: var(--space-4) var(--space-5); display: flex; flex-direction: column; gap: var(--space-1); }
.totales__cell span { font-size: var(--fs-small); color: var(--text-soft); }
.totales__cell strong { font-family: var(--font-heading); font-size: var(--fs-h3); color: var(--heading-color); font-variant-numeric: tabular-nums; }
.totales__cell--big { background: var(--brand-navy); border-color: var(--brand-navy); }
.totales__cell--big span { color: var(--navy-text-soft); }
.totales__cell--big strong { color: #fff; }

/* Formularios */
.form { display: flex; flex-direction: column; gap: var(--space-4); }
.field { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--fs-small); color: var(--text-soft); }
/* El :not() excluye casillas y radios: heredaban el padding y el borde de un
 * campo de texto, con lo cual una casilla se dibujaba como una caja grande y
 * vacía y nadie entendía qué era. */
.field input:not([type="checkbox"]):not([type="radio"]),
.field select,
.rowform input:not([type="checkbox"]):not([type="radio"]),
.items-grid__form input,
.seccion__form textarea {
  font: inherit; color: var(--text); background: var(--bg);
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
}
.field input:focus-visible, .field select:focus-visible, .rowform input:focus-visible,
.items-grid__form input:focus-visible, .seccion__form textarea:focus-visible {
  outline: none; box-shadow: var(--shadow-focus); border-color: var(--brand-primary);
}
.form-error { margin: 0 0 var(--space-4); padding: var(--space-3) var(--space-4); background: #fdecec; color: #a12222; border: 1px solid #f3c2c2; border-radius: var(--radius-sm); }

/* Filas de ítems */
.cell-form { padding-top: var(--space-2); padding-bottom: var(--space-2); }
.rowform { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }

/* ---- Grilla de ítems del editor -------------------------------------------
 * Las columnas se declaran UNA sola vez y las heredan el encabezado, cada fila
 * y el formulario de agregar. Definirlas por separado es justo lo que dejaba
 * los títulos corridos respecto de los campos que nombran. */
.items-grid, .rowform--add {
  --items-cols: 2.25rem minmax(180px, 1fr) 7.5rem 4.5rem 5.5rem 8rem 5.5rem 8.5rem 8.5rem auto;
}
/* Regla 16: quien no es administrador no tiene las columnas Costo y Margen.
 * La misma grilla con ocho columnas, declarada también una sola vez. */
.items-grid--sin-costos, .rowform--sin-costos {
  --items-cols: 2.25rem minmax(180px, 1fr) 7.5rem 4.5rem 5.5rem 8.5rem 8.5rem auto;
}

/* El aviso de agrupación a medias va a todo el ancho de la tarjeta, que es
 * `card--flush` y no trae padding propio. */
.items-grid__banda { margin: 0 var(--space-6) var(--space-4); }

/* Calidad de la propuesta en el editor: dos pestañas que son botones de un
 * form, y el aviso para volver a tomar los costos de esa calidad. */
.cot-calidad { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); padding: var(--space-4) var(--space-6); }
.cot-calidad__tabs { margin-bottom: 0; }
button.seg-tab { font-family: inherit; cursor: pointer; }
.cot-calidad__aviso { flex-wrap: wrap; align-items: center; }
.cot-calidad__aviso .alert__body { flex: 1 1 260px; }

.items-grid {
  display: grid; grid-template-columns: var(--items-cols);
  align-items: center; column-gap: var(--space-2); row-gap: var(--space-2);
  min-width: 1020px;                /* debajo de esto scrollea .tbl-scroll */
  padding: 0 var(--space-6) var(--space-4);
}
.items-grid--sin-costos { min-width: 800px; }   /* dos columnas menos */

/* `display: contents` disuelve la caja del form y deja que sus campos caigan
 * directamente en las columnas de la grilla. Es lo que permite que cada fila
 * siga siendo un form independiente sin romper la alineación. */
.items-grid__form { display: contents; }

.items-grid__th {
  font-size: var(--fs-small); color: var(--text-muted);
  text-transform: uppercase; letter-spacing: var(--tracking-caps);
  padding: var(--space-3) 0; border-bottom: 1px solid var(--border);
}
.items-grid__n { font-variant-numeric: tabular-nums; }
.items-grid__form > .right { text-align: right; }
.items-grid__form input { min-width: 0; }   /* sin esto un valor largo desborda su columna */

/* La banda de acciones cierra cada ítem: sirve de separador entre uno y otro,
 * así no hace falta pintarle un borde a cada celda por separado. */
.items-grid__acciones, .items-grid__sep {
  grid-column: 1 / -1; display: flex; gap: var(--space-2);
  padding-bottom: var(--space-3); border-bottom: 1px solid var(--border);
}
.items-grid__acciones { justify-content: flex-end; }
.items-grid__acciones:last-child, .items-grid__sep:last-child { border-bottom: 0; }
.items-grid__vacio { grid-column: 1 / -1; }

.rowform--add {
  display: grid; grid-template-columns: var(--items-cols);
  align-items: center; column-gap: var(--space-2);
  padding: var(--space-4) var(--space-6); border-top: 1px solid var(--border);
  background: var(--surface-2);
}
/* Arranca en la segunda columna: la primera es la numeración, que acá no aplica. */
.rowform--add > :first-child { grid-column-start: 2; }
.rowform--add input { min-width: 0; }

/* Debajo de tablet la grilla no entra: cada campo pasa a ocupar el ancho
 * completo y el encabezado se oculta, porque ya no encabeza nada. */
@media (max-width: 1024px) {
  .items-grid, .rowform--add { display: block; min-width: 0; }
  .items-grid__th { display: none; }
  .items-grid__form { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
  .items-grid__form input { flex: 1 1 120px; }
}
/* Solo los campos de texto se estiran. Sin el :not(), un checkbox dentro de un
 * .rowform recibía flex:1 y min-width:120px, se despegaba de su etiqueta y
 * quedaba flotando en el medio del filtro como si fuera un selector de filas. */
.rowform input:not([type="checkbox"]):not([type="radio"]) { flex: 1; min-width: 120px; }
.rowform input[type="checkbox"], .rowform input[type="radio"] { flex: 0 0 auto; min-width: 0; }
.rowform .w-sm { flex: 0 0 72px; min-width: 72px; }
.rowform .w-md { flex: 0 0 130px; min-width: 130px; }
.rowform__actions { display: flex; gap: var(--space-2); margin-top: var(--space-2); }
/* Acciones al final de una fila de tabla: pegadas a la derecha y sin envolver. */
.rowform--fin { justify-content: flex-end; flex-wrap: nowrap; }

/* Acción destructiva: se lee en rojo solo al acercarse, para que no compita con
 * las acciones del flujo normal pero tampoco se apriete por accidente. */
.btn--peligro { color: #a12222; }
.btn--peligro:hover { border-color: #c0392b; color: #c0392b; background: #fdecec; }
.ico-btn { font: inherit; width: 30px; height: 30px; border: 1px solid var(--border-strong); background: var(--bg); border-radius: var(--radius-sm); cursor: pointer; color: var(--text-soft); }
.ico-btn:hover { border-color: var(--brand-primary); color: var(--brand-primary-ink); }
.ico-btn:disabled { opacity: .4; cursor: default; }
.ico-btn--danger:hover { border-color: #c0392b; color: #c0392b; }

/* Secciones */
.seccion { padding: var(--space-5) var(--space-6); border-bottom: 1px solid var(--border); }
.seccion:last-child { border-bottom: 0; }
.seccion__bar { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--space-3); }
.seccion__form { display: flex; flex-direction: column; gap: var(--space-3); }
.seccion__form textarea { width: 100%; font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: 13px; line-height: 1.5; resize: vertical; }
.check { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--fs-small); color: var(--text-soft); }

/* Ayuda contextual (alta de cotización) */
.help-box { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.help-box p { margin: 0; font-size: var(--fs-small); color: var(--text-soft); }

/* Formulario amable de contenido (sin JSON) */
.doc-form { display: flex; flex-direction: column; gap: var(--space-5); }
.fs { border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-4) var(--space-5); display: flex; flex-direction: column; gap: var(--space-3); margin: 0; }
.fs > legend { font-family: var(--font-heading); font-weight: var(--weight-heading); color: var(--heading-color); padding: 0 var(--space-2); }
.fs > legend small { font-weight: 400; color: var(--text-soft); }
.fs-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
.field textarea { font: inherit; color: var(--text); background: var(--bg); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); resize: vertical; }
.field textarea:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-color: var(--brand-primary); }

.rep { display: flex; flex-direction: column; gap: var(--space-2); }
.rep [data-rows] { display: flex; flex-direction: column; gap: var(--space-2); }
.rep__row { display: flex; align-items: center; gap: var(--space-2); }
.rep__row input { flex: 1; font: inherit; color: var(--text); background: var(--bg); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); }
.rep__row input:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-color: var(--brand-primary); }
.rep__row--pair .w-lbl { flex: 0 0 180px; }
.rep__row--stack { flex-direction: column; align-items: stretch; border: 1px dashed var(--border); border-radius: var(--radius-sm); padding: var(--space-3); }
.rep__row--stack textarea { font: inherit; color: var(--text); background: var(--bg); border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); resize: vertical; }
.rep__row--stack .ico-btn { align-self: flex-end; }
.rep > .btn { align-self: flex-start; }

@media (max-width: 1024px) { .fs-grid { grid-template-columns: 1fr; } .rep__row--pair .w-lbl { flex-basis: 120px; } }

/* ── Modal del editor: «Buscar en la base» ────────────────────────────────────
 * Solo composición sobre los tokens ya congelados en ds.css: no se redefine
 * ninguna variable de marca aquí. */

/* El bug conocido del sprint: un selector de clase con `display` le gana al
 * atributo [hidden] del navegador. Sin esta línea, el modal arranca abierto. */
.modal[hidden] { display: none; }

.modal {
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  padding: var(--space-4);
  background: color-mix(in srgb, var(--navy, #07152E) 70%, transparent);
}

.modal__caja {
  display: flex; flex-direction: column;
  width: min(880px, 100%); max-height: min(80vh, 720px);
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius-lg, 12px);
  box-shadow: 0 24px 64px rgba(7, 21, 46, .28);
  padding: var(--space-5);
  gap: var(--space-4);
}

.modal__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }

/* El formulario es el flex-item REAL de la caja, no el cuerpo: sin darle altura
 * flexible propia crecía con todo su contenido, empujaba la caja más allá del
 * max-height y las últimas filas quedaban fuera del modal, sin scroll posible. */
.modal__form {
  display: flex; flex-direction: column;
  flex: 1 1 auto; min-height: 0; gap: var(--space-4);
}

/* El cuerpo es lo único que scrollea: el buscador y el pie quedan siempre
 * visibles. `min-height: 0` es obligatorio — el mínimo automático de un
 * flex-item es su contenido, y con eso `overflow-y` nunca llega a activarse. */
.modal__cuerpo { flex: 1 1 auto; overflow-y: auto; min-height: 0; }

.modal__pie {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4); padding-top: var(--space-3);
  border-top: 1px solid var(--border);
}

/* Chip de categoría seleccionado en el listado de catálogo. */
.tag.is-active {
  color: var(--on-accent, #fff);
  background: var(--azul, #0091E2);
  border-color: var(--azul, #0091E2);
}


/* Contador de leads sin revisar en el nav. Compone sobre los tokens de ds.css. */
.panel__badge-n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; margin-left: var(--space-2); padding: 0 6px;
  font-size: var(--fs-small); font-variant-numeric: tabular-nums; line-height: 1;
  color: #fff; background: var(--aqua, #13B8C9);
  border-radius: var(--radius-full);
}

/* ---- COTI ------------------------------------------------------------------
 * Una sola columna angosta. La pantalla del comercial tiene tres campos y un
 * boton: todo lo que no sea eso compite con la unica decision que importa, que
 * es qué escribir en el textarea. */
/* `width: 100%` no es adorno. `.coti` es item flex de `.panel__content` y los
 * margenes automaticos le quitan el estirado: sin un ancho propio toma el de su
 * contenido mas largo, que es el texto de las opciones del selector de formato
 * (556 px medidos en una pantalla de 349, 1-oct-2026). El formulario entero se
 * salia por la derecha en el telefono y `overflow-x: clip` lo cortaba. */
.coti { width: 100%; max-width: 760px; margin: 0 auto; }
.coti__head { margin-bottom: var(--space-5); }
.coti__lead { color: var(--text-muted); max-width: 60ch; }
.coti__form { margin-bottom: var(--space-4); }

/* 160px de alto minimo: el tamano del campo comunica cuanto se espera que
 * escribas. Un input de una linea invita a poner «valvulas» y eso produce
 * borradores que hay que rehacer enteros. */
.coti__solicitud { min-height: 160px; resize: vertical; line-height: 1.55; }
.coti__ayuda { font-size: var(--fs-small); color: var(--text-muted); margin: calc(var(--space-2) * -1) 0 var(--space-4); }
.coti__generar { min-height: 48px; padding-inline: var(--space-6); font-size: var(--fs-body); }
.coti__espera { font-size: var(--fs-small); color: var(--text-muted); margin-top: var(--space-3); }

.coti__progreso { border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-5); background: var(--surface-2); }
.pasos { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3); }
.pasos__item { display: flex; align-items: center; gap: var(--space-3); color: var(--text-muted); }
.pasos__item::before {
  content: ""; flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%;
  background: var(--border-strong); transition: background .2s ease, box-shadow .2s ease;
}
.pasos__item.is-activo { color: var(--text); font-weight: 500; }
.pasos__item.is-activo::before { background: var(--brand-primary); box-shadow: 0 0 0 4px var(--azul-100); }
.pasos__item.is-hecho::before { background: #1f9d6b; }

/* Semaforo de COTI en la grilla de items del editor. Sigue el patron `.pill--*`
 * que ya usan los estados de la cotizacion. */
.pill--verde { background: #e6f6ec; color: #1c7a43; border-color: #bfe6cd; }
.pill--ambar { background: #fff4e0; color: #a15c00; border-color: #f3dcb0; }
.pill--rojo  { background: #fdecec; color: #a12222; border-color: #f3c2c2; }

/* Franja de resultado del borrador generado. No es un flash que se pierde al
 * recargar: se deriva del estado de los items y se va sola cuando el comercial
 * revisa los precios marcados. */
.franja {
  display: grid; gap: var(--space-2);
  border: 1px solid var(--azul-200); border-left: 3px solid var(--brand-primary);
  border-radius: var(--radius-md); background: var(--azul-100);
  padding: var(--space-4) var(--space-5); margin-bottom: var(--space-5);
}
.franja__titulo { font-weight: 600; }
.franja__avisos { margin: 0; padding-left: var(--space-5); display: grid; gap: var(--space-1); }
.franja__aviso--bloquea { font-weight: 500; }

.prompt-editor { min-height: 420px; line-height: 1.5; font-size: 13px; }
/* Ajustes de COTI: la versión propuesta se puede leer antes de activarla. */
.prompt-propuesto { flex: 1 1 auto; min-width: 0; }
.prompt-propuesto__texto { margin-top: var(--space-3); }
.prompt-propuesto__texto > summary { cursor: pointer; color: var(--text-soft); font-size: var(--fs-small); }
.prompt-propuesto__texto pre { margin: var(--space-3) 0 0; max-height: 420px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; line-height: 1.5; font-size: 13px; }
.items-grid__aviso {
  grid-column: 1 / -1; display: flex; align-items: center; gap: var(--space-2);
  padding-bottom: var(--space-2);
}

/* Robot de COTI en el menu. El icono existe para que se lea de un vistazo que
 * esa pestana la atiende un modelo y no una pantalla mas del CRUD. */
/* `justify-content: flex-start` es el arreglo, no un detalle: el `.panel__nav-item`
 * base usa `space-between` para empujar el contador de Leads a la derecha, y esta
 * variante lo heredaba — el icono quedaba en un extremo y la palabra en el otro. */
.panel__nav-item--ia { justify-content: flex-start; gap: var(--space-2); }
.ico-ia { flex: 0 0 auto; }
/* Los ojos en aqua: es el mismo acento de marca que ya senala la pestana activa,
 * asi el icono no introduce un color nuevo al sistema. */
.ico-ia__ojo { fill: var(--brand-aqua); }
.panel__nav-item--ia:hover .ico-ia__ojo,
.panel__nav-item--ia.is-active .ico-ia__ojo { fill: #fff; }

/* ---- Dictado por voz -------------------------------------------------------
 * Un comercial describiendo lo que necesita un cliente habla mucho mas rapido
 * de lo que escribe, y muchas veces lo hace desde el celular en planta. */
.dictado { display: flex; align-items: center; gap: var(--space-3); margin-top: var(--space-2); }
.dictado__btn { display: inline-flex; align-items: center; gap: var(--space-2); }
.dictado__estado { font-size: var(--fs-small); color: var(--text-muted); }

/* El punto rojo late solo mientras graba: es la unica senal de que el microfono
 * esta abierto, y esa no puede ser ambigua. */
.dictado__btn.is-grabando { border-color: #c0392b; color: #a5322a; }
.dictado__punto { width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.dictado__btn.is-grabando .dictado__punto { animation: latido 1.2s ease-in-out infinite; }
@keyframes latido { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

@media (prefers-reduced-motion: reduce) {
  .dictado__btn.is-grabando .dictado__punto { animation: none; }
}

/* ---- Chat de ajuste --------------------------------------------------------
 * `<details>` nativo: plegable sin JavaScript, sin estado que sincronizar y
 * accesible por teclado de fabrica. Nace cerrado para no competir con el
 * editor, que es donde el comercial pasa el tiempo. */
.chat { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface-1); margin-bottom: var(--space-5); }
.chat__summary { display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap; cursor: pointer; padding: var(--space-4) var(--space-5); list-style: none; }
.chat__summary::-webkit-details-marker { display: none; }
.chat__summary::before { content: "▸"; color: var(--text-muted); transition: transform var(--dur-2) var(--ease-standard); }
.chat[open] .chat__summary::before { transform: rotate(90deg); }
.chat__titulo { font-weight: 600; }
.chat__cuerpo { padding: 0 var(--space-5) var(--space-5); display: grid; gap: var(--space-4); }
.chat__campo { min-height: 76px; resize: vertical; }
.chat__nota { font-size: var(--fs-small); color: var(--text-muted); margin: 0; }
.chat__h4 { margin: 0 0 var(--space-3); font-size: var(--fs-small); text-transform: uppercase; letter-spacing: var(--tracking-caps); color: var(--text-muted); }
.chat__historial { border-top: 1px solid var(--border); padding-top: var(--space-4); }
.chat__pasos { list-style: none; margin: 0 0 var(--space-3); padding: 0; display: grid; gap: var(--space-2); }
.chat__paso { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: var(--space-2) 0; border-bottom: 1px solid var(--border); }
.chat__paso:last-child { border-bottom: 0; }
.chat__instruccion { display: block; }

/* Pestanas de Ajustes. Sin ellas `/panel/ajustes/coti` era inalcanzable desde la
 * interfaz: una pantalla a la que solo se llega escribiendo la URL no existe. */
.subtabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--border); margin-bottom: var(--space-5); }
.subtabs__item { padding: var(--space-3) var(--space-4); color: var(--text-muted); text-decoration: none; font-size: var(--fs-small); border-bottom: 2px solid transparent; margin-bottom: -1px; }
.subtabs__item:hover { color: var(--text); }
.subtabs__item.is-active { color: var(--brand-primary); border-bottom-color: var(--brand-primary); font-weight: 500; }

/* --------------------------------------------------------------------------- */
/* Compacto (≤1024px): teléfono y tablet, el panel cabe en el ancho               */
/* --------------------------------------------------------------------------- */
@media (max-width: 1024px) {
  html, body.panel { overflow-x: hidden; }
  .panel__main { overflow-x: clip; }
  /* LA LÍNEA QUE HACE QUE EL PANEL QUEPA. El aside es ítem de la rejilla y el
     nav es ítem flex dentro de él; el tamaño mínimo automático de un ítem es su
     contenido, y el del nav son las siete pestañas sin envolver: unos 750 px.
     Sin esto, el aside, la barra superior y el contenido medían 756 px en una
     pantalla de 375 —el doble—, y el `overflow-x: hidden` de arriba escondía la
     mitad sin dejar llegar a ella: botones cortados y nada que hacer.
     De paso es lo que devuelve el deslizamiento del menú: con el nav tan ancho
     como su contenido no había nada que desplazar y se sentía congelado. */
  .panel__side, .panel__nav { min-width: 0; }
  /* Barra superior compacta: el menú es una sola fila que se desliza con el dedo. */
  .panel__side { padding: var(--space-2) var(--space-3); gap: var(--space-2); }
  .panel__brand img { height: 22px; }
  .panel__nav {
    flex: 1 1 100%; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    -webkit-overflow-scrolling: touch; margin: 0 calc(-1 * var(--space-3)); padding: 0 var(--space-3) 2px;
  }
  .panel__nav::-webkit-scrollbar { display: none; }
  .panel__nav-item { flex: 0 0 auto; font-size: 14px; padding: var(--space-2) var(--space-3); }
  .panel__top { padding: var(--space-2) var(--space-3); gap: var(--space-2); }
  .panel__crumb { flex: 1; min-width: 0; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .panel__user-name, .panel__badge { display: none; }
  .panel__content { padding: var(--space-4) var(--space-3); gap: var(--space-4); }
  .section-title { font-size: var(--fs-h3); }
  .card { padding: var(--space-4); }
  .card--flush { padding: 0; overflow-x: auto; }
  .row-between > * { min-width: 0; }
  .row-between .btn { flex: 1 1 auto; justify-content: center; text-align: center; }
  /* iOS hace zoom al enfocar un campo con letra menor a 16px. */
  input, select, textarea { font-size: 16px; }
  .tbl th, .tbl td { padding: var(--space-2) var(--space-3); }
  .seg-actions { white-space: normal; flex-wrap: wrap; justify-content: flex-start; }

  /* Listas como fichas: cada fila es una tarjeta y cada celda lleva su rótulo
     (`data-l`). Las celdas de número, cliente y título van sin rótulo: se leen solas. */
  .tbl--fichas thead { display: none; }
  .tbl--fichas, .tbl--fichas tbody, .tbl--fichas tr, .tbl--fichas td { display: block; width: 100%; }
  .tbl--fichas tr { padding: var(--space-3) var(--space-4); border-bottom: 1px solid var(--border); }
  .tbl--fichas tr:last-child { border-bottom: 0; }
  .tbl--fichas tbody tr:hover { background: transparent; }
  .tbl--fichas td { padding: 2px 0; border: 0; text-align: left; white-space: normal; }
  .tbl--fichas td[data-l]::before {
    content: attr(data-l) ": "; color: var(--text-muted); font-size: 11px;
    text-transform: uppercase; letter-spacing: var(--tracking-caps);
  }
  .tbl--fichas td.fichas__k { font-weight: 700; font-size: 15px; color: var(--heading-color); }
  .tbl--fichas td.fichas__t { font-size: 15px; }
  .tbl--fichas td.fichas__c { color: var(--text-soft); }
  .tbl--fichas .seg-hint { display: inline; margin-left: 4px; }
  .tbl--fichas td.seg-actions, .tbl--fichas .rowform--fin { display: flex; flex-wrap: wrap; gap: var(--space-2); justify-content: flex-start; padding-top: var(--space-2); }
  .tbl--fichas td.seg-actions form { display: contents; }
}

/* --------------------------------------------------------------------------- */
/* Editor de cotizaciones, catálogo y clientes en el teléfono                  */
/* --------------------------------------------------------------------------- */
/* En escritorio el rótulo de cada campo de la grilla de ítems no existe: las
   columnas ya tienen encabezado. `display: contents` deja caer el campo en su
   columna como si el rótulo no estuviera. */
.ig { display: contents; }
.ig__l { display: none; }

@media (max-width: 1024px) {
  /* Formularios en filas: cada campo a su renglón. */
  .rowform { flex-wrap: wrap; }
  .rowform > .field { flex: 1 1 100%; margin-bottom: 0; }
  .rowform__actions { width: 100%; }
  .rowform--fin { flex-wrap: wrap; justify-content: flex-start; }
  .rep__row--pair { flex-wrap: wrap; }
  .rep__row--pair > .field { flex: 1 1 100%; }
  .rep__row--pair .w-lbl { flex: 1 1 100%; }
  .rep__row--pair input:not(.w-lbl) { flex: 1 1 calc(100% - 44px); }
  .row-gap { flex-wrap: wrap; }
  .audit__list li { flex-direction: column; gap: 2px; }
  .prop-sec__row { flex-wrap: wrap; }

  /* Grilla de ítems del editor: cada ítem es una ficha con sus campos rotulados. */
  .items-grid__form { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); padding: var(--space-3) 0; align-items: flex-end; }
  .items-grid__form > .ig { display: block; flex: 1 1 calc(50% - var(--space-3)); min-width: 0; }
  .items-grid__form > .ig--ancha { flex: 1 1 100%; }
  .ig__l { display: block; font-size: 10.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--text-muted); margin-bottom: 2px; }
  .items-grid__form > .ig input, .items-grid__form > .ig span { display: block; width: 100%; text-align: left; }
  .items-grid__form > .btn { flex: 1 1 100%; }
  .items-grid__n { display: block; padding-top: var(--space-3); }
  .items-grid__acciones { justify-content: flex-start; }
  .rowform--add { display: flex; flex-wrap: wrap; gap: var(--space-2); padding: var(--space-3) var(--space-4); }
  .rowform--add input, .rowform--add .w-sm, .rowform--add .w-md { flex: 1 1 calc(50% - var(--space-2)); min-width: 0; }
  .rowform--add input[name="descripcion"] { flex: 1 1 100%; }
  .rowform--add > span { display: none; }
  .rowform--add .btn { flex: 1 1 100%; }

  /* Catálogo y clientes: fichas con sus acciones en varias filas. */
  .tbl--fichas td.fichas__acciones { display: flex; flex-wrap: wrap; gap: var(--space-2); padding-top: var(--space-2); }
  .tbl--fichas td.fichas__acciones form { display: contents; }
}
.coti__guardado { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin: var(--space-2) 0 var(--space-3); }

/* ---------- Mesa de la propuesta técnico-económica ----------
   Se edita a la izquierda y se ve el documento a la derecha, en el formato
   aprobado (regla 15). Es la misma forma de trabajo de la cotización sencilla:
   antes había que abrir la vista previa en otra pestaña para saber cómo iba
   quedando, y eso es lo que hacía que el formato se perdiera de vista. */
.mesa-prop { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, var(--vista, 520px)); gap: var(--space-5); align-items: start; }
.mesa-prop__edita { min-width: 0; display: flex; flex-direction: column; gap: var(--space-6); }
.mesa-prop__vista { position: sticky; top: var(--space-4); min-width: 0; }
.mesa-prop__cab { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-2); font-size: var(--fs-small); }
.mesa-prop__cab b { color: var(--heading-color); font-size: 15px; }
.mesa-prop__cab .grow { flex: 1; }
.mesa-prop__vista iframe { width: 100%; height: 70vh; border: 1px solid var(--border); border-radius: var(--radius-md); background: #fff; display: block; }
@media (max-width: 1180px) {
  /* Debajo de esto la columna de edición queda impracticable: el documento
     pasa abajo, donde sigue sirviendo para revisar antes de aprobar. */
  .mesa-prop { grid-template-columns: 1fr; }
  .mesa-prop__vista { position: static; }
  .mesa-prop__vista iframe { height: 60vh; }
}

/* --------------------------------------------------------------------------- */
/* Repartir el espacio: menú plegable y división móvil (Cristian, 28-sep-2026)  */
/* «cuando estoy editando despliego más la edición, cuando estoy revisando      */
/* despliego más la previsualización, y el menú lo oculto según la necesidad».  */
/* --------------------------------------------------------------------------- */
/* La rejilla base (248 px + contenido) ya está declarada arriba, y NO se repite
   aquí. Repetirla costó el móvil entero: esta línea vivía después del bloque
   `@media (max-width: 1024px)`, con la misma especificidad, así que ganaba
   también en el teléfono. El panel seguía reservando 248 px para el lateral y
   al contenido le quedaban ~110 px en una pantalla de 360: una palabra por
   renglón, embebido en Gestión y también abriendo COTI directo.

   Regla para la próxima: una propiedad que el bloque móvil cambia no se vuelve
   a declarar más abajo. Si hace falta reafirmarla, va dentro de
   `@media (min-width: 1025px)`. */
/* Con el lateral oculto la rejilla pasa a UNA columna. Dejarla en dos con la
   primera en cero mete el contenido en esa columna vacia y lo aplasta: el
   `display:none` saca al aside de la rejilla, no al hueco que ocupaba. */
/* SOLO de 1025 px para arriba. En el teléfono el aside es la barra de pestañas,
   así que esconderlo deja el panel sin menú — y como la preferencia se guarda
   por navegador, quien plegó el menú alguna vez se quedaba sin pestañas en el
   celular sin entender por qué. El móvil ya pinta una sola columna por su
   cuenta (bloque ≤1024 px), así que aquí no hace falta nada para él. */
@media (min-width: 1025px) {
  .panel--sin-lado { grid-template-columns: 1fr; }
  .panel--sin-lado .panel__side { display: none; }
  /* La fila de agregar del editor vive en la grilla de items: el minimo de
     120 px de `.rowform input` sacaba las casillas chicas (Und, Cant) de su
     columna y tapaban a la vecina. En escritorio mandan las columnas; en el
     telefono esa fila es flex y sigue como estaba. */
  .rowform.rowform--add input:not([type="checkbox"]):not([type="radio"]) { min-width: 0; width: 100%; }
}

.panel__plegar {
  flex: 0 0 auto; width: 30px; height: 30px; margin-right: var(--space-3);
  display: grid; align-content: center; gap: 4px; padding: 0 7px; cursor: pointer;
  background: transparent; border: 1px solid var(--border); border-radius: var(--radius-sm);
}
.panel__plegar span { display: block; height: 2px; border-radius: 2px; background: var(--text-soft); }
.panel__plegar:hover { border-color: var(--brand-primary); }
.panel__plegar:hover span { background: var(--brand-primary-ink); }
/* Plegar el lateral no significa nada donde no hay lateral: en el teléfono el
   aside ES la barra de pestañas. El botón se esconde ahí.
   Va DESPUÉS de la regla base y no en el bloque móvil de más arriba: con la
   misma especificidad gana la última, y puesto antes no servía de nada. Es el
   mismo tropiezo que dejó el panel aplastado el 29-sep. */
@media (max-width: 1024px) {
  .panel__plegar { display: none; }
}

/* El tirador vive en la canal del grid, entre las dos columnas. */
.mesa-tirador {
  position: absolute; top: 0; bottom: 0; width: 11px; cursor: col-resize;
  /* Centrado sobre el borde de la columna derecha, sea cual sea el gap. */
  right: var(--vista, 520px); transform: translateX(50%);
  display: flex; align-items: center; justify-content: center;
}
.mesa-tirador::before {
  content: ""; width: 3px; height: 46px; border-radius: 3px; background: var(--border-strong);
  transition: background var(--dur-2) var(--ease-standard), height var(--dur-2) var(--ease-standard);
}
.mesa-tirador:hover::before, .mesa-tirador:focus-visible::before { background: var(--brand-primary); height: 90px; }
.mesa-tirador:focus-visible { outline: none; }
/* Mientras se arrastra, el iframe de la vista previa se traga el puntero. */
.esta-arrastrando { cursor: col-resize; user-select: none; }
.esta-arrastrando iframe { pointer-events: none; }

/* Motivo de un freno, en su sitio y no en una página en blanco con JSON. */
.panel__aviso {
  margin: 0 0 var(--space-5); padding: var(--space-4) var(--space-5);
  border-left: 3px solid #C0392B; border-radius: var(--radius-md);
  background: color-mix(in srgb, #C0392B 7%, var(--surface));
  color: var(--heading-color); font-size: var(--fs-small); line-height: 1.5;
}
.panel__aviso b { color: #9c2f22; }
.flujo-pdf { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--border);
  font-size: var(--fs-small); color: var(--text-soft); }

/* Base de conocimiento de costos (prefijo kb-). Costos de compra, no precios
 * de venta: cada costo muestra su fecha, su fuente y su confianza. */
.kb-familias { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: var(--space-3); margin-top: var(--space-4); }
.kb-familia { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); text-decoration: none; color: var(--text); }
.kb-familia:hover { border-color: var(--brand-primary); }
.kb-familia b { color: var(--heading-color); }
/* Confianza: R real (verde), W web (azul), E y P estimados (ámbar). */
.kb-cod {
  display: inline-grid; place-items: center; width: 22px; height: 22px;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  font-size: 12px; font-weight: 700; line-height: 1; cursor: help;
  background: var(--surface-2); color: var(--text-muted);
}
.kb-cod--R { background: #e6f6ec; color: #1c7a43; border-color: #bfe6cd; }
.kb-cod--W { background: var(--azul-100); color: var(--azul-700); border-color: var(--azul-200); }
.kb-cod--E, .kb-cod--P { background: #fff4e0; color: #a15c00; border-color: #f3dcb0; }
.kb-grupo { margin-top: var(--space-4); }
.kb-grupo__sub { margin: var(--space-3) var(--space-6) var(--space-2); font-size: var(--fs-small); color: var(--text-muted); text-transform: uppercase; letter-spacing: var(--tracking-caps); }
.kb-datos { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-1) var(--space-4); margin: var(--space-4) 0; font-size: var(--fs-small); }
.kb-datos dt { color: var(--text-muted); }
.kb-datos dd { margin: 0; color: var(--text); }
.kb-fila-costo { margin-top: var(--space-2); text-align: left; }
.kb-fila-costo > summary { list-style: none; display: inline-flex; }
.kb-fila-costo > summary::-webkit-details-marker { display: none; }
.kb-actualizar { margin-top: var(--space-3); max-width: 520px; text-align: left; }
.kb-agregar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); justify-content: flex-end; }
.kb-agregar .w-sm { width: 72px; }
.kb-agregar .w-md { width: 130px; }
/* Tarjeta de resultado del buscador dentro del editor. */
.kb-res { border: 1px solid var(--border); border-radius: var(--radius-md); padding: var(--space-3) var(--space-4); display: flex; flex-direction: column; gap: var(--space-2); }
.kb-res + .kb-res { margin-top: var(--space-3); }
.kb-obs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--fs-small); }
.kb-obs li { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.kb-historial > summary { cursor: pointer; color: var(--text-soft); font-size: var(--fs-small); }
.kb-res__cab { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-3); }
.kb-res__acciones { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.kb-res__acciones .w-sm { width: 72px; }
.kb-res__avisos { color: #a15c00; }
.kb-res__grupo { margin: var(--space-4) 0 var(--space-2); font-size: var(--fs-small); font-weight: 600; }
.kb-res .kb-actualizar, .kb-nuevo { display: grid; gap: var(--space-2); max-width: 520px; }
.kb-res .kb-actualizar[hidden], .kb-nuevo[hidden] { display: none; }
.items-grid__aviso--confirmar { border-left: 3px solid var(--warn, #B57200); padding-left: var(--space-3); }
/* Cargas: pasos (no se pulsan), la revisión y la lista de hojas. */
.kb-pasos .seg-tab { cursor: default; }
.kb-pasos .seg-tab:hover { border-color: var(--border); color: inherit; }
.kb-pasos .seg-tab.is-active:hover { color: #fff; border-color: var(--brand-navy); }
.kb-cargar { max-width: 640px; }
.kb-columnas > summary { cursor: pointer; }
.kb-columnas .fs { margin-top: var(--space-3); }
.kb-contadores { margin: var(--space-4) 0 var(--space-2); font-size: var(--fs-small); color: var(--text-soft); }
.kb-revision select { max-width: 220px; }
.kb-excluida td { opacity: .55; }
.kb-excluida td:first-child { opacity: 1; }
.kb-botones { margin: var(--space-4) 0; }
.kb-hojas { margin: var(--space-3) 0 0; padding-left: var(--space-5); font-size: var(--fs-small); color: var(--text-soft); }
/* «Por revisar» y los choques de la ficha. */
.kb-versal { font-variant: small-caps; letter-spacing: .03em; }
.card .kb-choque + .kb-choque { margin-top: var(--space-4); padding-top: var(--space-4); border-top: 1px solid var(--border); }
.kb-choque p { margin: 0 0 var(--space-2); }
.kb-choque__botones { flex-wrap: wrap; margin-top: var(--space-2); }
.kb-revisar__lista { margin: var(--space-3) 0; }
.kb-revisar__form { display: grid; gap: var(--space-2); max-width: 520px; }
@media (max-width: 1024px) {
  .kb-agregar { justify-content: flex-start; }
  .kb-datos { grid-template-columns: 1fr; }
}

/* Barra de guardado de la mesa de items (una sola, para toda la tabla). Vive
 * pegada bajo la grilla: es donde termina la vista al revisar precios de arriba
 * a abajo, y es donde se busca la confirmacion de que quedo guardado. */
.mesa-barra {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-4) 0;
}
.mesa-barra small { margin: 0; }
.mesa-barra__error { color: #a12222; font-weight: 500; }
@media (max-width: 1024px) {
  .mesa-barra { flex-wrap: wrap; gap: var(--space-2); }
}

/* El número de la sección en el editor: el MISMO que imprime el documento. Se
 * pinta como el del documento (cifra en azul, tabular) para que la vista de la
 * izquierda y la de la derecha se lean como la misma lista. */
.prop-sec__n {
  color: var(--brand-primary); font-variant-numeric: tabular-nums;
  font-size: 12.5px; letter-spacing: var(--tracking-caps); margin-right: 2px;
}

/* ---- Guion de la propuesta: la entrada base de COTI ------------------------
 * Nueve pasos al lado del texto (debajo y plegable cuando no caben los dos).
 * Es una guia, no un formulario: cada paso dice «Listo» o «Falta» con texto,
 * no solo con color, y tocar uno que falta escribe su frase de arranque. Los
 * pasos los pinta `static/js/guion.js`; aqui solo va como se ven. */
.coti--guion { max-width: 1120px; }
.coti--guion .coti__head,
.coti--guion .coti__form > .field,
.coti--guion .coti__ayuda { max-width: 760px; }
.coti__entrada { display: grid; gap: var(--space-4); min-width: 0; }
.coti__texto { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }

.guion { min-width: 0; border: 1px solid var(--azul-200); border-radius: var(--radius-md); background: var(--surface); }
.guion__summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  min-height: 48px; padding: var(--space-2) var(--space-4); cursor: pointer;
  font-weight: 600; color: var(--heading-color);
}
.guion__summary:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-md); }
.guion__cuenta {
  font-size: var(--fs-small); font-variant-numeric: tabular-nums; white-space: nowrap;
  color: var(--brand-primary-ink); background: var(--azul-100);
  border-radius: var(--radius-full); padding: 2px var(--space-3);
}
.guion__cuenta:empty { display: none; }
.guion__cuerpo { display: grid; gap: var(--space-3); padding: 0 var(--space-3) var(--space-3); }
.guion__nota { margin: 0; padding: 0 var(--space-1); font-size: var(--fs-small); color: var(--text-muted); }
.guion__pasos { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.guion__paso {
  width: 100%; min-height: 44px; display: grid; grid-template-columns: 3.5rem minmax(0, 1fr);
  gap: var(--space-2); align-items: start; text-align: left;
  font: inherit; line-height: 1.35; color: var(--text); background: transparent; cursor: pointer;
  border: 1px solid transparent; border-radius: var(--radius-sm); padding: 6px var(--space-2);
}
.guion__paso.is-falta:hover { background: var(--azul-100); border-color: var(--azul-200); }
.guion__paso:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-color: var(--brand-primary); }
.guion__paso.is-listo { cursor: default; }
.guion__estado {
  margin-top: 2px; text-align: center; font-size: 11px; line-height: 1.5; text-transform: uppercase;
  letter-spacing: var(--tracking-caps); padding: 2px 0; border-radius: var(--radius-full);
  border: 1px solid #f3dcb0; background: #fff4e0; color: #a15c00;
}
.guion__paso.is-listo .guion__estado { border-color: #bfe6cd; background: #e6f6ec; color: #1c7a43; }
.guion__texto { display: grid; gap: 0; min-width: 0; }
.guion__cab { display: block; }
.guion__nombre { font-weight: 600; font-size: 14.5px; color: var(--heading-color); }
.guion__frases { font-size: var(--fs-small); color: var(--brand-primary-ink); overflow-wrap: anywhere; }
.guion__que, .guion__nota-paso, .guion__parcial { font-size: 12.5px; color: var(--text-muted); overflow-wrap: anywhere; }
.guion__nota-paso { font-style: italic; }
.guion__parcial { color: #a15c00; }
.guion__pie { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); padding: 0 var(--space-1); }
.guion__insertar { min-height: 44px; }
.guion__aviso { flex: 1 1 200px; font-size: var(--fs-small); color: var(--text-muted); }
/* La version de bolsillo: una linea bajo el texto y el guion, a todo el ancho. */
.guion__bolsillo { grid-column: 1 / -1; margin: 0; font-size: var(--fs-small); color: var(--text-muted); }
.guion__bolsillo-t { font-weight: 600; color: var(--text); }

/* «Generar» ocupa el ancho, como siempre; cuando el guion tiene algo que decir
 * («Faltan 3 de 9…») el texto va a su lado y baja de renglon si no cabe. */
.coti__accion { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); }
.coti__accion .coti__generar { flex: 1 1 auto; justify-content: center; }
.coti__faltan { font-size: var(--fs-small); color: var(--text-muted); }

@media (min-width: 1200px) {
  .coti--guion .coti__entrada { grid-template-columns: minmax(0, 1fr) minmax(320px, 400px); gap: var(--space-5); align-items: start; }
  .coti--guion .coti__solicitud { min-height: 600px; }
  /* Al lado del texto el guion no se pliega: el encabezado deja de ser boton. */
  .guion__summary { pointer-events: none; cursor: default; list-style: none; }
  .guion__summary::-webkit-details-marker { display: none; }
}

/* En la mesa de la propuesta: lo que no venia en la solicitud. Interno. */
.franja--falto { border-color: #f3dcb0; border-left-color: #b57200; background: #fffaf0; }
.falto__nota { margin: 0; font-size: var(--fs-small); color: var(--text-soft); }
.falto__item strong { color: var(--heading-color); }
/* Cuando el guion va debajo del texto se pliega: la flecha lo dice. */
@media (max-width: 1199px) {
  .guion__summary { list-style: none; justify-content: flex-start; }
  .guion__summary::-webkit-details-marker { display: none; }
  .guion__summary::before { content: '▸'; color: var(--text-muted); }
  .guion[open] > .guion__summary::before { content: '▾'; }
  .guion__titulo { flex: 1 1 auto; }
}
/* En el telefono el aviso de cada item («Por confirmar», su rastro y el boton)
 * no cabe en un renglon: sin esto «Confirmo este precio» quedaba cortado contra
 * el borde de la tarjeta y no se podia tocar. */
@media (max-width: 1024px) {
  .items-grid__aviso { flex-wrap: wrap; }
  .items-grid__aviso > small { flex: 1 1 180px; }
}

/* ---- Metrado en la mesa de la propuesta ------------------------------------
 * Bloque opcional y plegado: no es un paso del flujo. Lo pinta
 * `static/js/metrado.js`; aqui solo va como se ve. La mesa de la propuesta
 * reparte el ancho con la vista previa, asi que este bloque puede medir 520 px
 * en una pantalla de 1366: por eso su forma base es la angosta (la del
 * telefono) y la ancha se enciende con una consulta al CONTENEDOR, no a la
 * pantalla. Nada en rojo: los pendientes del metrado son informacion, no un
 * error de la cotizacion. */
.metrado { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); min-width: 0; container-type: inline-size; container-name: metrado; }
.metrado__summary { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--space-1) var(--space-3); min-height: 44px; padding: var(--space-3) var(--space-5); cursor: pointer; list-style: none; }
.metrado__summary::-webkit-details-marker { display: none; }
.metrado__summary::before { content: "▸"; color: var(--text-muted); }
.metrado[open] > .metrado__summary::before { content: "▾"; }
.metrado__summary:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-md); }
.metrado__titulo { font-weight: 600; color: var(--heading-color); }
.metrado__summary small { flex: 1 1 240px; min-width: 0; }
.metrado__cuerpo { display: grid; gap: var(--space-4); min-width: 0; padding: 0 var(--space-5) var(--space-5); }
.metrado__cuerpo:empty { display: none; }
/* El minimo automatico de un item de rejilla o de flex es su contenido, y un
 * <select> mide lo que su opcion mas larga: sin esto un capitulo con el rubro
 * «Planeacion y administracion (componente interno)» ensancha todo el bloque
 * y lo saca de la pantalla del telefono. */
.metrado__cuerpo * { min-width: 0; }
.metrado.is-ocupado .metrado__cuerpo { opacity: .55; pointer-events: none; }
.metrado__nota { margin: 0; font-size: var(--fs-small); color: var(--text-soft); overflow-wrap: anywhere; }
.metrado__h { margin: 0; font-family: var(--font-heading); font-size: 1.05rem; color: var(--heading-color); }
.metrado__msg { margin: 0; }
.metrado__msg--ok { padding: var(--space-2) var(--space-3); border: 1px solid #bfe6cd; border-radius: var(--radius-sm); background: #e6f6ec; color: #1c7a43; font-size: var(--fs-small); }
.metrado__parcial { margin: 0; padding: var(--space-2) var(--space-3); border: 1px solid var(--azul-200); border-left: 3px solid var(--brand-primary); border-radius: var(--radius-sm); background: var(--azul-50); font-size: var(--fs-small); }
.metrado__btn { min-height: 44px; white-space: normal; text-align: left; line-height: 1.25; justify-content: center; }
.metrado__acciones { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; }
.metrado__acciones--pie { padding-top: var(--space-2); }
.metrado select, .metrado input[type="search"], .metrado__sim-i input {
  font: inherit; color: var(--text); background: var(--bg); min-height: 44px; max-width: 100%; min-width: 0;
  border: 1px solid var(--border-strong); border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
}
.metrado select:focus-visible, .metrado input:focus-visible, .metrado textarea:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-color: var(--brand-primary); }
.metrado__campo { min-width: 0; }
.metrado__campo input, .metrado__campo select, .metrado__campo textarea { min-height: 44px; width: 100%; max-width: 100%; }
.metrado__campo--corto { max-width: 220px; }

/* Subir o pegar */
.metrado__subir { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3); }
.metrado__subir .metrado__campo { flex: 1 1 240px; }
.metrado__pegar-form { display: grid; gap: var(--space-3); padding-top: var(--space-2); justify-items: start; }
.metrado__pegar-form .metrado__campo { width: 100%; }
.metrado__sub { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); min-height: 44px; cursor: pointer; font-weight: 600; color: var(--heading-color); }
.metrado__sub { list-style: none; }
.metrado__sub::-webkit-details-marker { display: none; }
.metrado__sub::before { content: "▸"; color: var(--text-muted); font-weight: 400; }
details[open] > .metrado__sub::before { content: "▾"; }
.metrado__respaldos { display: grid; gap: var(--space-2); border-top: 1px solid var(--border); padding-top: var(--space-3); }
.metrado__lista { list-style: none; margin: 0; padding: 0; display: grid; }
.metrado__respaldo, .metrado__prod { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-3); padding: var(--space-2) 0; border-top: 1px solid var(--border); font-size: var(--fs-small); }
.metrado__respaldo > span:first-child, .metrado__prod-t { flex: 1 1 200px; min-width: 0; display: grid; overflow-wrap: anywhere; }
.metrado__check { min-height: 44px; flex: 1 1 100%; }

/* Confirmar hojas y columnas */
.metrado__hojas { display: grid; gap: var(--space-4); min-width: 0; }
.metrado__hoja { display: grid; gap: var(--space-3); min-width: 0; margin: 0; padding: var(--space-3) var(--space-4) var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-md); }
.metrado__hoja-t { padding: 0 var(--space-2); font-weight: 600; color: var(--heading-color); }
.metrado__hoja-t small { font-weight: 400; }
.metrado__cols { list-style: none; margin: 0; padding: 0; display: grid; }
.metrado__col { display: grid; grid-template-columns: 2rem minmax(0, 1fr); gap: var(--space-1) var(--space-2); align-items: center; padding: var(--space-2) 0; border-top: 1px dashed var(--border); font-size: var(--fs-small); }
.metrado__col-l { font-weight: 600; color: var(--text-muted); text-align: center; }
.metrado__col-t { display: grid; min-width: 0; overflow-wrap: anywhere; }
.metrado__col select { grid-column: 1 / -1; width: 100%; }
.metrado__notas { margin: 0; padding-left: var(--space-5); display: grid; gap: var(--space-1); font-size: var(--fs-small); overflow-wrap: anywhere; }

/* Que falta y a quien le toca */
.metrado__cab { display: grid; gap: var(--space-3); }
.metrado__datos { margin: 0; font-size: var(--fs-small); color: var(--text); }
.metrado__avance { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.metrado__punto { display: grid; grid-template-columns: 3.75rem minmax(0, 1fr); gap: var(--space-2); align-items: start; font-size: var(--fs-small); line-height: 1.4; }
.metrado__punto-e { margin-top: 1px; text-align: center; font-size: 11px; line-height: 1.5; text-transform: uppercase; letter-spacing: var(--tracking-caps); padding: 2px 0; border-radius: var(--radius-full); border: 1px solid var(--azul-200); background: var(--azul-100); color: var(--azul-700); }
.metrado__punto.is-listo .metrado__punto-e { border-color: #bfe6cd; background: #e6f6ec; color: #1c7a43; }

/* El simulador: costo, utilidad y precio sugerido (solo administrador) */
.metrado__sim { display: grid; gap: var(--space-3); min-width: 0; padding: var(--space-4); border: 1px solid var(--azul-200); border-radius: var(--radius-md); background: var(--azul-50); }
.metrado__sim-tabla { display: grid; min-width: 0; }
.metrado__sim-fila { display: grid; grid-template-columns: minmax(0, 1fr) 68px minmax(0, 1fr); gap: var(--space-1) var(--space-2); align-items: end; padding: var(--space-2) 0; border-top: 1px solid var(--azul-200); font-size: var(--fs-small); }
.metrado__sim-fila--cab { display: none; }
.metrado__sim-n { grid-column: 1 / -1; font-weight: 600; color: var(--heading-color); overflow-wrap: anywhere; }
.metrado__sim-c { font-variant-numeric: tabular-nums; white-space: nowrap; }
.metrado__sim-fila--total .metrado__sim-c { padding: var(--space-2) 0; }
.metrado__sim-c[data-rot]::before, .metrado__sim-i[data-rot]::before { content: attr(data-rot); display: block; font-size: 10px; text-transform: uppercase; letter-spacing: var(--tracking-caps); color: var(--text-muted); white-space: nowrap; }
.metrado__sim-i { display: block; min-width: 0; }
.metrado__sim-i input { width: 100%; text-align: right; font-variant-numeric: tabular-nums; padding-left: var(--space-2); padding-right: var(--space-2); }
.metrado__sim-fila--total { border-top: 2px solid var(--brand-navy); font-weight: 600; }
.metrado__sim-pie { margin: 0; font-size: var(--fs-small); }

/* Capitulos, filtros y grupos */
.metrado__bloque { border-top: 1px solid var(--border); min-width: 0; }
.metrado__bloque-c { display: grid; gap: var(--space-3); padding-bottom: var(--space-2); min-width: 0; }
.metrado__caps { list-style: none; margin: 0; padding: 0; display: grid; }
.metrado__cap { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); padding: var(--space-2) 0; border-top: 1px dashed var(--border); font-size: var(--fs-small); }
.metrado__cap-t { flex: 1 1 180px; display: grid; min-width: 0; overflow-wrap: anywhere; }
.metrado__cap-t--solo { flex-basis: 100%; }
.metrado__cap-n { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); }
.metrado__cap-r { color: var(--text); }
.metrado__cap select { flex: 1 1 170px; }
.metrado__recordadas { justify-content: space-between; font-size: var(--fs-small); }
.metrado__filtros { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); }
.metrado__tabs { margin: 0; }
.metrado__tab { min-height: 44px; }
.metrado__grupos { display: grid; gap: var(--space-2); min-width: 0; }
.metrado__grupo { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface); min-width: 0; }
.metrado__grupo-s { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-3); min-height: 44px; padding: var(--space-2) var(--space-4); cursor: pointer; list-style: none; }
.metrado__grupo-s::-webkit-details-marker { display: none; }
.metrado__grupo-s::before { content: "▸"; color: var(--text-muted); }
.metrado__grupo[open] > .metrado__grupo-s::before { content: "▾"; }
.metrado__grupo-s:focus-visible { outline: none; box-shadow: var(--shadow-focus); border-radius: var(--radius-md); }
.metrado__grupo-n { flex: 1 1 140px; min-width: 0; font-weight: 600; color: var(--heading-color); overflow-wrap: anywhere; }
.metrado__grupo-m { order: 3; flex: 1 1 100%; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); font-size: var(--fs-small); color: var(--text-soft); }
.metrado__grupo-tot { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--heading-color); white-space: nowrap; }
.metrado__grupo-c { display: grid; gap: var(--space-2); padding: 0 var(--space-4) var(--space-3); min-width: 0; }
.metrado__falta, .metrado__desglose { margin: 0; font-size: var(--fs-small); overflow-wrap: anywhere; }
.metrado__desglose { color: var(--text-soft); font-variant-numeric: tabular-nums; }
.metrado__comps { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-1); font-size: var(--fs-small); }
.metrado__comps strong { font-variant-numeric: tabular-nums; }

/* Un renglon: forma angosta (la base) */
.metrado__filas { list-style: none; margin: 0; padding: 0; min-width: 0; }
.metrado__fila { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: var(--space-1) var(--space-2); align-items: start; padding: var(--space-2) 0; border-top: 1px solid var(--border); font-size: var(--fs-small); line-height: 1.4; }
.metrado__sel { grid-column: 1; grid-row: 1 / span 2; display: flex; align-items: center; justify-content: center; width: 44px; min-height: 44px; cursor: pointer; }
.metrado__sel input { width: 18px; height: 18px; margin: 0; }
.metrado__fila-t { grid-column: 2; display: grid; min-width: 0; overflow-wrap: anywhere; }
.metrado__fila-d { color: var(--text); }
.metrado__n { color: var(--brand-primary); font-variant-numeric: tabular-nums; }
.metrado__fila-q { grid-column: 3; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.metrado__fila-q small { color: var(--text-muted); }
.metrado__fila-e { grid-column: 2 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-2); min-width: 0; }
.metrado__fila-e small { flex: 1 1 100%; overflow-wrap: anywhere; }
.metrado__fila-c { grid-column: 2 / -1; display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2); font-variant-numeric: tabular-nums; }
.metrado__fila-c:empty { display: none; }
.metrado__fila-a { grid-column: 2 / -1; display: flex; flex-wrap: wrap; gap: var(--space-2); }
.metrado__fila--fija .metrado__fila-t { grid-column: 1 / 3; }
.metrado__fila--fija .metrado__fila-e, .metrado__fila--fija .metrado__fila-c, .metrado__fila--fija .metrado__fila-a { grid-column: 1 / -1; }
.metrado__par { grid-column: 1 / -1; display: grid; gap: var(--space-3); min-width: 0; margin-top: var(--space-2); padding: var(--space-3) var(--space-4); border: 1px solid var(--azul-200); border-radius: var(--radius-md); background: var(--azul-50); }

/* Mover varios renglones de una vez */
.metrado__lote { position: sticky; bottom: var(--space-3); z-index: 5; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); padding: var(--space-3) var(--space-4); border-radius: var(--radius-md); background: var(--brand-navy); color: #fff; font-size: var(--fs-small); box-shadow: var(--shadow-md); }
.metrado__lote select { flex: 1 1 180px; }
.metrado__lote .btn--ghost { color: #fff; border-color: rgba(255, 255, 255, .5); }

/* Por confirmar (la hoja de observaciones) */
.metrado__pend { list-style: none; margin: 0; padding: 0; display: grid; }
.metrado__pend-i { display: grid; gap: 2px; padding: var(--space-2) 0; border-top: 1px dashed var(--border); font-size: var(--fs-small); overflow-wrap: anywhere; }
.metrado__pend-t { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }

/* Forma ancha: cuando el bloque (no la pantalla) tiene espacio */
@container metrado (min-width: 460px) {
  .metrado__sim-fila { grid-template-columns: minmax(0, 1.2fr) minmax(92px, auto) 64px minmax(104px, 132px); align-items: center; }
  .metrado__sim-fila--cab { display: grid; border-top: 0; font-size: 10px; text-transform: uppercase; letter-spacing: var(--tracking-caps); color: var(--text-muted); }
  .metrado__sim-fila--cab span:not(:first-child) { text-align: right; }
  .metrado__sim-n { grid-column: auto; }
  .metrado__sim-c { text-align: right; }
  .metrado__sim-c[data-rot]::before, .metrado__sim-i[data-rot]::before { display: none; }
  .metrado__col { grid-template-columns: 2rem minmax(0, 1fr) minmax(150px, 190px); }
  .metrado__col select { grid-column: auto; }
}
@container metrado (min-width: 640px) {
  .metrado__col { grid-template-columns: 2rem minmax(0, 1fr) minmax(180px, 240px); }
  .metrado__cap-t { flex: 1 1 220px; }
  .metrado__cap select { flex: 0 1 240px; }
  .metrado__sim-fila { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr) 96px minmax(120px, 150px); }
  .metrado__cab { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
}
@container metrado (min-width: 860px) {
  .metrado__fila { grid-template-columns: 44px minmax(0, 2fr) minmax(72px, .6fr) minmax(0, 1.7fr); column-gap: var(--space-3); }
  .metrado__filas--costos .metrado__fila { grid-template-columns: 44px minmax(0, 2fr) minmax(72px, .6fr) minmax(0, 1.6fr) minmax(104px, .8fr); }
  .metrado__sel { grid-row: 1; }
  .metrado__fila-t, .metrado__fila--fija .metrado__fila-t { grid-column: 2; }
  .metrado__fila-q { grid-column: 3; }
  .metrado__fila-e, .metrado__fila--fija .metrado__fila-e { grid-column: 4; }
  .metrado__fila-c, .metrado__fila--fija .metrado__fila-c { grid-column: 5; flex-direction: column; align-items: flex-end; gap: 0; text-align: right; }
  .metrado__fila-a, .metrado__fila--fija .metrado__fila-a { grid-column: 2 / -1; }
}
@media (max-width: 1024px) {
  .metrado__summary { padding: var(--space-3) var(--space-4); }
  .metrado__cuerpo { padding: 0 var(--space-4) var(--space-4); }
  .metrado__hoja, .metrado__sim, .metrado__par { padding-left: var(--space-3); padding-right: var(--space-3); }
  .metrado__grupo-s, .metrado__grupo-c { padding-left: var(--space-3); padding-right: var(--space-3); }
}

/* Documentos del cliente en la mesa. Bloque plegado y secundario: es un recurso
 * complementario, no un paso del flujo, y la jerarquía tiene que decirlo. */
.recursos { padding: var(--space-4) var(--space-5); }
.recursos__summary { cursor: pointer; display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap; }
.recursos__summary small { margin: 0; }
.recursos__fila { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
  padding: var(--space-3) 0; border-top: 1px solid var(--border); }
.recursos__datos { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; flex: 1; min-width: 0; }
.recursos__nombre { display: flex; flex-direction: column; min-width: 0; flex: 1 1 240px; }
.recursos__nombre small { margin: 0; }
.recursos__usar { display: flex; align-items: center; gap: var(--space-1); font-size: var(--fs-small); white-space: nowrap; }
.recursos__subir { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap;
  padding-top: var(--space-3); border-top: 1px solid var(--border); }
@media (max-width: 1024px) {
  .recursos__datos, .recursos__subir { gap: var(--space-2); }
  .recursos__nombre { flex-basis: 100%; }
}

/* Lo que se le pidió a COTI. Se lee, no se edita: por eso es un <pre> con el
 * texto tal cual se escribió —los saltos de línea de una solicitud larga son
 * parte de lo que se quiso decir— y por eso el bloque nace plegado. */
.pedido { padding: var(--space-4) var(--space-5); }
.pedido__summary { cursor: pointer; display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap; }
.pedido__summary small { margin: 0; }
.pedido__item { padding-top: var(--space-3); margin-top: var(--space-3); border-top: 1px solid var(--border); }
.pedido__item:first-of-type { border-top: 0; }
.pedido__cab { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-2); }
.pedido__cab small { margin: 0; flex: 1; }
.pedido__texto {
  margin: 0; white-space: pre-wrap; word-break: break-word;
  font-family: inherit; font-size: var(--fs-small); line-height: 1.55;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4);
  max-height: 340px; overflow: auto;
}
.recursos__instruccion { flex: 1 1 260px; min-width: 0; }

/* Archivos elegidos y todavía no enviados: una pastilla por archivo con su
 * tamaño y su X. Es lo que faltaba para notar que la segunda tanda se comía a
 * la primera; ahora se ven todos antes de mandarlos. */
.elegidos { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-2); }
.elegidos:empty { display: none; }
.elegidos__item {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 2px var(--space-2) 2px var(--space-3);
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-full);
  font-size: var(--fs-small); max-width: 100%;
}
.elegidos__n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 260px; }
.elegidos__item small { margin: 0; white-space: nowrap; }
