/* Logger — Paleta clínica "Claridad clínica" (OFICIAL, cerrada)
   Tokens oficiales según CLAUDE.md §3 y .claude/agents/frontend.md.
   El Frontend REUTILIZA estos tokens; no inventa colores ni fuentes nuevas.

   NOTA sobre el nombre del archivo: se conserva `estilo-b.css` para no romper
   referencias existentes; su CONTENIDO ya es la paleta clínica oficial, no Estilo B. */

/* Fuentes (cargar en el <head> de las plantillas):
   <link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600;9..144,700&family=Public+Sans:wght@400;500;600;700&display=swap" rel="stylesheet"> */

:root {
  /* Superficies y tinta */
  --bg: #F5F7FA;          /* fondo general (frío) */
  --surface: #FFFFFF;     /* tarjetas, formularios */
  --surface-2: #F1F5F9;   /* fondos secundarios */
  --ink: #0F172A;         /* texto principal */
  --muted: #64748B;       /* texto secundario */
  --line: #E2E8F0;        /* bordes suaves */
  --line-strong: #CBD5E1; /* bordes fuertes / divisores marcados */

  /* Acentos — nombres semánticos oficiales */
  --blue: #2563EB;        /* acción principal, totales, foco */
  --blue-hover: #1D4ED8;  /* hover / activo del primario */
  --blue-soft: #EFF4FF;   /* fondo suave del primario */
  --amber: #B45309;       /* obligatorios, alertas suaves */
  --amber-soft: #FFF7ED;
  --green: #16A34A;       /* confirmaciones / enviar / estado "cuadra" */
  --green-soft: #ECFDF3;
  --red: #DC2626;         /* error de validación: rechazo del árbitro (Reglas 1, 2 y 3) */
  --red-soft: #FEF2F2;
  --red-line: #FECACA;    /* borde suave del rojo (fila señalada como culpable) */

  /* Bordes suaves de las otras tres familias — completan lo que --red-line ya
     hacía sola, más el escalón fuerte del azul que sostiene la escalera de
     fondos del COA (grupo > cuenta > subcuenta).

     Ninguno es un color nuevo: los cuatro hexes YA estaban escritos a mano en
     esta misma hoja (medido antes de nombrarlos, con `grep -rni` sobre app/:
     #BBF7D0 ×2, #FDE3C4 ×2, #BFDBFE ×5, #DBEAFE ×1). Esto les pone nombre; los
     literales existentes NO se sustituyen aquí, para que este commit no pueda
     mover ni un pixel de lo que hoy funciona.

     ⚠️ --amber-line va en #FDE3C4 —el que la app usa de verdad— y NO en el
     #F6DFC4 del mockup, que no aparece ni una vez en app/ (`grep -rn F6DFC4
     app/` → 0). Nombrarlo con el hex del mockup habría cambiado en silencio el
     borde de dos componentes que hoy funcionan. */
  --green-line: #BBF7D0;       /* borde suave del verde */
  --amber-line: #FDE3C4;       /* borde suave del ámbar */
  --blue-line:  #BFDBFE;       /* borde suave del azul */
  --blue-soft-strong: #DBEAFE; /* escalón fuerte del azul de fondo (fila de grupo) */

  /* Alias de compatibilidad (nombres antiguos Estilo B → apuntan al acento azul).
     Evitan romper cualquier código que aún use --teal*. Usar los nombres nuevos. */
  --teal: var(--blue);
  --teal-dark: var(--blue-hover);
  --teal-soft: var(--blue-soft);

  /* Espaciado — escala de 4px */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 22px;
  --sp-6: 32px;

  /* Forma */
  --radius: 14px;
  --shadow: 0 1px 2px rgba(15,23,42,.05), 0 6px 20px rgba(15,23,42,.05);

  /* Tipografía oficial Logger — sin cambios */
  --font-head: 'Fraunces', serif;                       /* títulos, cifras grandes */
  --font-body: 'Public Sans', system-ui, sans-serif;    /* cuerpo */
  --font-num: 'Public Sans', system-ui, sans-serif;     /* números (tabular) */
}

/* Cifras: siempre tabulares y alineadas a la derecha */
.num {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ─────────────────────────────────────────────────────────────────────────
   COMPONENTES — portados del sistema de diseño clínico oficial
   (docs/diseno-referencia-v3-clinica.html) a los tokens de arriba.
   SIN inventar colores ni fuentes: todo referencia var(--token).
   ───────────────────────────────────────────────────────────────────────── */
* { box-sizing: border-box; }
/* Utilidad global: cualquier elemento con .hide se oculta (banners, filas del
   picker, mensaje "sin resultados", etc.). Gana sobre el display del componente. */
.hide { display: none !important; }
body {
  margin: 0;
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--ink);
  font-size: 13.5px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

/* Layout general: sidebar + main */
.app { display: grid; grid-template-columns: 230px 1fr; min-height: 100vh; }

/* Sidebar */
.side {
  background: var(--surface); border-right: 1px solid var(--line);
  padding: 18px 13px; display: flex; flex-direction: column; gap: 3px;
  position: sticky; top: 0; height: 100vh;
}
.sbrand { display: flex; align-items: center; gap: 10px; padding: 4px 8px 16px; text-decoration: none; }
.logo {
  width: 34px; height: 34px; border-radius: 10px; background: var(--blue);
  color: #fff; display: grid; place-items: center;
  font-family: var(--font-head); font-weight: 700; font-size: 18px;
}
.sbrand h1 { font-family: var(--font-head); font-size: 18px; margin: 0; font-weight: 600; color: var(--ink); }
.sbrand small { display: block; color: var(--muted); font-size: 10.5px; }
/* Producción activa en el subtítulo del brand (pintada por pintarBarra):
   monograma mini (reutiliza .poster gN, mismo patrón que .prow) + nombre + caret. */
.sbrand small .poster {
  display: inline-grid; width: 15px; height: 15px; border-radius: 4px;
  font-size: 7.5px; vertical-align: -3px; margin-right: 3px;
}
.sbrand small .sb-caret { color: var(--line-strong); font-size: 9px; }
.sbrand:hover small { color: var(--ink); }
.slbl {
  font-size: 10px; text-transform: uppercase; letter-spacing: .7px;
  color: var(--muted); font-weight: 700; padding: 13px 10px 5px;
}
.snav {
  display: flex; align-items: center; gap: 10px; padding: 9px 11px;
  border-radius: 8px; cursor: pointer; color: var(--muted); font-weight: 600;
  border: none; background: none; width: 100%; text-align: left;
  font-size: 13.5px; font-family: inherit; text-decoration: none;
}
.snav svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.8; }
.snav:hover { background: var(--surface-2); }
.snav.on { background: var(--blue-soft); color: var(--blue); }
/* Grupos desplegables del sidebar (PO / CR): <details> nativo, sin JS.
   El <summary> reutiliza .snav; ocultamos el marcador nativo y añadimos
   un chevron propio que rota al abrir. */
.sgroup { display: flex; flex-direction: column; gap: 3px; }
.sgroup > summary { list-style: none; }
.sgroup > summary::-webkit-details-marker { display: none; }
.snav .scaret {
  margin-left: auto; width: 15px; height: 15px; color: var(--muted);
  transition: transform .18s ease;
}
.sgroup[open] > summary .scaret { transform: rotate(180deg); }
/* Sub-ítems Crear / Buscar: ligeramente indentados bajo su documento. */
.snav.ssub {
  padding-left: 38px; font-size: 13px; font-weight: 500;
}
/* Pie del sidebar: identidad arriba, "Salir" apilado debajo a lo ancho. Un correo
   largo se ENCOGE con elipsis (min-width:0, sin él flex no deja encoger y el
   contenido empujaba el botón fuera del borde de la barra). */
.sfoot { margin-top: auto; display: flex; flex-direction: column; gap: 8px; padding: 10px; border-top: 1px solid var(--line); }
.sfoot-id { display: flex; align-items: center; gap: 10px; min-width: 0; }
.sfoot-id .avatar { flex-shrink: 0; }
#user-info { flex: 1; min-width: 0; }
#user-info b, #user-info small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.avatar {
  width: 30px; height: 30px; border-radius: 50%; background: var(--blue-soft);
  color: var(--blue); display: grid; place-items: center; font-weight: 700; font-size: 12px;
}
.sfoot small { color: var(--muted); font-size: 10.5px; }

/* Main + barra superior */
.main { overflow: auto; }
.bar {
  position: sticky; top: 0; z-index: 5; background: rgba(245,247,250,.92);
  backdrop-filter: blur(8px); border-bottom: 1px solid var(--line);
  padding: 11px 26px; display: flex; align-items: center; justify-content: space-between; gap: 14px;
}
.crumb { font-size: 12.5px; color: var(--muted); }
.crumb b { color: var(--ink); }

/* BudgetChips (barra superior): Ejecutado / Comprometido / Disponible / Total */
.barbudget { display: flex; align-items: center; gap: 14px; font-size: 11.5px; color: var(--muted); flex-wrap: wrap; }
.barbudget .chip { display: flex; align-items: center; gap: 6px; }
.barbudget .chip b { color: var(--ink); font-variant-numeric: tabular-nums; }
.barbudget .dot { width: 8px; height: 8px; border-radius: 2px; }

/* Contenedor de contenido */
.wrap { max-width: 880px; margin: 0 auto; padding: 22px 26px 70px; }
.htitle { font-family: var(--font-head); font-size: 23px; font-weight: 600; letter-spacing: -.4px; margin: 0 0 2px; }
.hsub { color: var(--muted); font-size: 13px; margin: 0 0 20px; }

/* Tarjeta + bloques numerados */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: 11px; box-shadow: var(--shadow); overflow: hidden; }
.blk { padding: 17px 22px; border-bottom: 1px solid var(--line); }
.blk:last-child { border-bottom: none; }
.blk.hide { display: none; }
.blk-h { display: flex; align-items: center; gap: 9px; margin-bottom: 13px; }
.blk-h .n {
  font-family: var(--font-head); font-weight: 600; color: var(--blue);
  background: var(--blue-soft); width: 22px; height: 22px; border-radius: 6px;
  display: grid; place-items: center; font-size: 12px;
}
.blk-h h3 { margin: 0; font-size: 14px; font-weight: 700; }
.blk-h p { margin: 0 0 0 auto; font-size: 11.5px; color: var(--muted); }

/* Campos de formulario (InputField) */
.field { margin-bottom: 13px; }
.field:last-child { margin-bottom: 0; }
.row { display: grid; grid-template-columns: 1fr 1fr; gap: 13px; }
.row-3 { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 13px; }
label { display: block; font-weight: 600; font-size: 12px; margin-bottom: 5px; }
label .req { color: var(--amber); }
input, select, textarea {
  width: 100%; padding: 9px 11px; border: 1px solid var(--line-strong);
  border-radius: 8px; font-family: inherit; font-size: 13.5px; color: var(--ink); background: #fff;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px rgba(37,99,235,.15);
}
textarea { resize: vertical; min-height: 58px; }

/* LockedField (campo heredado / bloqueado) */
.locked { background: var(--surface-2); border-style: dashed; color: var(--muted); }
.lockrow {
  display: flex; align-items: center; gap: 6px; font-size: 11px;
  color: var(--green); font-weight: 600; margin-top: 6px;
}
.lockrow svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }

/* Prefijo $ para montos */
.prefix { position: relative; }
.prefix > span {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  color: var(--muted); font-weight: 600; font-family: var(--font-head);
}
.prefix input { padding-left: 24px; }

/* MoneyTotal (estado cuadra / error) */
.totalrow {
  display: flex; justify-content: space-between; align-items: center;
  background: var(--blue-soft); border: 1px solid #DBEAFE; border-radius: 9px;
  padding: 12px 17px; margin-top: 4px;
}
.totalrow .lab { font-size: 11px; text-transform: uppercase; letter-spacing: .6px; color: var(--blue); font-weight: 700; }
.totalrow .big { font-family: var(--font-head); font-size: 23px; font-weight: 600; color: var(--blue); font-variant-numeric: tabular-nums; }
.totalrow .ok { font-size: 11px; color: var(--green); font-weight: 600; display: flex; align-items: center; gap: 5px; }
.totalrow .ok svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2.4; }

/* Acciones + botones */
.actions { display: flex; justify-content: flex-end; gap: 10px; padding: 15px 22px; align-items: center; }
.btn {
  font-family: inherit; padding: 9px 18px; border-radius: 8px; font-weight: 700;
  font-size: 13.5px; cursor: pointer; border: 1px solid var(--line-strong);
  background: #fff; color: var(--muted);
}
.btn:hover { background: var(--surface-2); }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn-primary { background: var(--blue); border-color: var(--blue); color: #fff; }
.btn-primary:hover { background: var(--blue-hover); border-color: var(--blue-hover); }
.btn-amber { background: var(--amber); border-color: var(--amber); color: #fff; }
.btn-amber:hover { background: var(--amber); filter: brightness(.94); }

/* POPickerRow (buscador + filas de PO) */
.picker { border: 1px solid var(--line-strong); border-radius: 9px; overflow: hidden; }
.picker-s { display: flex; align-items: center; gap: 9px; padding: 9px 13px; background: var(--surface-2); border-bottom: 1px solid var(--line); }
.picker-s svg { width: 15px; height: 15px; stroke: var(--muted); fill: none; stroke-width: 2; }
.picker-s input { border: none; background: none; padding: 0; box-shadow: none !important; }
.po { display: grid; grid-template-columns: auto 1fr auto; gap: 11px; align-items: center; padding: 10px 14px; border-bottom: 1px solid var(--line); cursor: pointer; }
.po:last-child { border-bottom: none; }
.po:hover, .po.sel { background: var(--blue-soft); }
.po.hide { display: none; }
.rad { width: 16px; height: 16px; border-radius: 50%; border: 2px solid var(--line-strong); }
.po.sel .rad { border-color: var(--blue); background: radial-gradient(circle, var(--blue) 42%, #fff 46%); }
.po .id { font-weight: 700; font-size: 13px; }
.po .meta { font-size: 11.5px; color: var(--muted); }
.po .amt { font-weight: 700; font-variant-numeric: tabular-nums; }
.picker-empty { padding: 14px; font-size: 12px; color: var(--muted); text-align: center; }

/* --- Picker de PO: modos "Proveedor" / "Número" (mockup aprobado 2026-07-22) ---
   Con pocas PO el buscador de texto basta; con 100 nadie quiere hacer scroll una
   por una. El modo Proveedor agrupa en <details> colapsables (mismo componente
   nativo del sidebar, cero JS de librería) y el modo Número da la lista plana por
   consecutivo, con tope de altura para que la página nunca se alargue. */
.view-toggle {
  display: flex; gap: 4px; padding: 9px 13px; background: var(--surface-2);
  border-bottom: 1px solid var(--line); align-items: center;
}
.view-toggle .lab { font-size: 11.5px; color: var(--muted); font-weight: 600; margin-right: 4px; }
.vt-btn {
  font-family: inherit; font-size: 12px; font-weight: 700; padding: 5px 12px; border-radius: 7px;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--muted); cursor: pointer;
}
.vt-btn.active { background: var(--blue); border-color: var(--blue); color: #fff; }
.vt-count { margin-left: auto; font-size: 11.5px; color: var(--muted); }

/* La fila "Sin Orden de Compra" vive fuera de la lista: siempre visible, sin
   importar el modo ni el filtro (la lista se re-dibuja al cambiar de modo). */
.fixed-row { border-bottom: 1px solid var(--line); }

/* Tope de altura de la lista de POs, en LOS DOS modos (Proveedor y Número).
   Este comentario decía que el modo Proveedor "no lo necesita, los grupos
   colapsados ya limitan el alto". Era falso: abrir un grupo alarga la lista, y
   al buscar se abren de golpe todos los que coinciden. Corregido 2026-07-27. */
.scroll-flat { max-height: 340px; overflow-y: auto; }
.scroll-flat::-webkit-scrollbar { width: 8px; }
.scroll-flat::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 8px; }

/* Grupos por proveedor: <details> nativo, mismo criterio que .sgroup del sidebar. */
.po-group { border-bottom: 1px solid var(--line); }
.po-group:last-child { border-bottom: none; }
.po-group > summary {
  list-style: none; cursor: pointer; padding: 11px 14px; display: flex; align-items: center;
  gap: 10px; background: var(--surface); user-select: none;
}
.po-group > summary::-webkit-details-marker { display: none; }
.po-group > summary .chev {
  width: 14px; height: 14px; stroke: var(--muted); fill: none; stroke-width: 2.2;
  transition: transform .15s ease; flex-shrink: 0;
}
.po-group[open] > summary .chev { transform: rotate(90deg); }
.po-group > summary .vendor-name { font-weight: 700; font-size: 13px; flex: 1; }
.po-group > summary .vendor-count {
  font-size: 10.5px; font-weight: 700; color: var(--muted); background: var(--surface-2);
  padding: 2px 9px; border-radius: 20px; border: 1px solid var(--line);
}
.po-group .po { padding-left: 30px; }
.po-group.hide { display: none; }
.pill { display: inline-block; font-size: 9.5px; font-weight: 700; padding: 1px 8px; border-radius: 20px; background: var(--green-soft); color: var(--green); }
.pill.open { background: var(--amber-soft); color: var(--amber); }
.pill.anulada { background: var(--surface-2); color: var(--muted); }
/* StatusPill junto al título del detalle (PO-0003 · Registrada) */
.htitle .pill { font-size: 11px; padding: 3px 10px; vertical-align: middle; }

/* InheritBanner (herencia PO→CR) — verde informativo */
.banner {
  display: flex; align-items: center; gap: 10px; background: var(--green-soft);
  border: 1px solid #BBF7D0; border-radius: 9px; padding: 10px 14px;
  margin-bottom: 14px; font-size: 12.5px;
}
.banner.hide { display: none; }
.banner svg { width: 17px; height: 17px; stroke: var(--green); fill: none; stroke-width: 2; flex-shrink: 0; }
.banner b { color: var(--green); }

/* ErrorBanner — NO existía en el mockup; muestra el rechazo del backend TAL CUAL
   (CLAUDE.md §3: el Frontend no redacta ni recalcula el mensaje). */
.errbanner {
  display: flex; align-items: flex-start; gap: 10px; background: var(--red-soft);
  border: 1px solid #FECACA; border-radius: 9px; padding: 11px 14px;
  margin-bottom: 16px; font-size: 12.5px; color: var(--ink);
}
.errbanner.hide { display: none; }
.errbanner svg { width: 17px; height: 17px; stroke: var(--red); fill: none; stroke-width: 2; flex-shrink: 0; margin-top: 1px; }
.errbanner .et { font-weight: 700; color: var(--red); }
.errbanner .em { color: var(--ink); }

/* SuccessBanner (confirmación de registro) — verde, reutiliza tono confirma */
.okbanner {
  display: flex; align-items: center; gap: 10px; background: var(--green-soft);
  border: 1px solid #BBF7D0; border-radius: 9px; padding: 11px 14px;
  margin-bottom: 16px; font-size: 12.5px; color: var(--ink);
}
.okbanner.hide { display: none; }
.okbanner svg { width: 17px; height: 17px; stroke: var(--green); fill: none; stroke-width: 2; flex-shrink: 0; }
.okbanner b { color: var(--green); }
/* Enlace "Descargar PDF" dentro del banner de éxito (punto de entrada al documento) */
.pdf-link {
  display: inline-block; margin-left: 4px; padding: 3px 11px; border-radius: 7px;
  background: var(--blue); color: #fff; font-weight: 700; font-size: 12px;
  text-decoration: none; white-space: nowrap;
}
.pdf-link:hover { background: var(--blue-hover); }

/* Responsive: colapsa el sidebar en pantallas angostas */
@media (max-width: 720px) {
  .app { grid-template-columns: 1fr; }
  .side { position: static; height: auto; flex-direction: row; flex-wrap: wrap; }
  .sfoot { margin-top: 0; border-top: none; }
  .row, .row-3 { grid-template-columns: 1fr; }
}

/* ─────────────────────────────────────────────────────────────────────────
   RESUMEN DE MIGRACIÓN — Estilo B (cálido) → Paleta clínica (fría, oficial)
   ─────────────────────────────────────────────────────────────────────────
   Superficies / tinta:
     --bg           #F4EFE7 → #F5F7FA
     --surface      #FFFDFA → #FFFFFF
     --ink          #2A2622 → #0F172A
     --muted        #8A7F73 → #64748B
     --line         #E7DECE → #E2E8F0
     --line-strong  #D8CBB6 → #CBD5E1
   Acento (teal → azul; renombrado, con alias):
     --teal      → --blue        #0F766E → #2563EB
     --teal-dark → --blue-hover  #0B5A53 → #1D4ED8
     --teal-soft → --blue-soft   #E5F1EF → #EFF4FF
   Ámbar / verde:
     --amber        #C2620E → #B45309
     --amber-soft   #FBEEDD → #FFF7ED
     --green        #3F7D3A → #16A34A
     --green-soft   #EAF3E6 → #ECFDF3
   Sombra:
     --shadow    tinta cálida rgba(60,46,30,…) → tinta fría rgba(15,23,42,…)
                 (mismas opacidades .05/.05)
   AGREGADO (no existía):
     --surface-2  #F1F5F9
     --red        #DC2626   (error de validación / rechazo del árbitro)
     --red-soft   #FEF2F2
     --sp-1..--sp-6  4·8·12·16·22·32px  (escala de espaciado 4px)
     --teal / --teal-dark / --teal-soft  → alias de compatibilidad hacia el azul
   SIN CAMBIOS:
     tipografía (Fraunces + Public Sans), .num (tabular + derecha), --radius 14px
   ───────────────────────────────────────────────────────────────────────── */

/* ─────────────────────────────────────────────────────────────────────────
   Consulta (Buscar PO / Buscar CR + detalles) — SOLO tokens existentes de la
   paleta clínica; ninguna fuente ni color nuevo.
   ───────────────────────────────────────────────────────────────────────── */

/* Tabla de resultados */
.tblwrap { overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.tbl th {
  text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--muted); font-weight: 700; padding: 9px 14px;
  border-bottom: 1px solid var(--line-strong); background: var(--surface-2);
  white-space: nowrap;
}
.tbl td { padding: 10px 14px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.tbl tbody tr:last-child td { border-bottom: none; }
.tbl tbody tr.link { cursor: pointer; }
.tbl tbody tr.link:hover { background: var(--blue-soft); }
.tbl .docid { font-weight: 700; white-space: nowrap; }
.tbl .money { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.tbl th.money { text-align: right; }
.tbl .muted { color: var(--muted); }
.tbl-empty { padding: 22px; font-size: 12.5px; color: var(--muted); text-align: center; }

/* Buscadores de PO/CR: la tabla de resultados tiene muchas columnas (hasta 8
   en PO tras sumar Pagado/Remanente) y el .wrap de 880px —pensado para los
   formularios de una columna— la ahogaba, partiendo nombres largos como
   "Locaciones del Valle S.A.S." en 2-3 líneas. Contenedor propio, más ancho,
   SOLO para estas pantallas de tabla (no toca crear/detalle). */
.wrap-busqueda { max-width: 1180px; }
/* Mismo caso y mismo ancho, ganado por el mismo motivo (tabla de muchas columnas
   y nombres largos), NO heredado: el catálogo de cuentas del COA y el tablero de
   presupuesto. Contenedor propio; el .wrap de 880px que comparten las cinco
   pantallas NO se toca — a 880 el nombre de subcuenta más largo mide 133px
   contra 128 útiles, y por eso se partían exactamente cuatro. */
.wrap-coa { max-width: 1180px; }
/* Y cada celda en una sola línea: el ancho extra ya alcanza para los nombres
   largos; si algún dato excepcional excediera, .tblwrap scrollea en horizontal
   en vez de partir el texto. Acotado a las búsquedas para no tocar la tabla de
   historial del detalle de PO. */
.wrap-busqueda .tbl td { white-space: nowrap; }

/* Encabezado de detalle: título + acciones (Descargar PDF) */
.dhead { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.dhead .htitle { margin: 0; }
.dhead .actions-inline { margin-left: auto; display: flex; gap: 10px; }

/* Ficha clave→valor del detalle */
.kvgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 13px; }
.kv .k { font-size: 10.5px; text-transform: uppercase; letter-spacing: .6px; color: var(--muted); font-weight: 700; margin-bottom: 3px; }
.kv .v { font-size: 13.5px; color: var(--ink); }

/* Trío de cifras del detalle (Total · Pagado · Remanente) */
.trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: 13px; }
.stat { background: var(--surface-2); border: 1px solid var(--line); border-radius: 9px; padding: 12px 14px; }
.stat .lab { font-size: 10.5px; text-transform: uppercase; letter-spacing: .6px; color: var(--muted); font-weight: 700; margin-bottom: 4px; }
.stat .big { font-family: var(--font-head); font-size: 20px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.stat.accent .big { color: var(--blue); }
.stat.good .big { color: var(--green); }

@media (max-width: 720px) {
  .kvgrid, .trio { grid-template-columns: 1fr; }
}

/* ─────────────────────────────────────────────────────────────────────────
   PANTALLAS DE SISTEMA — selector de proyectos · crear proyecto · Panel de Admin
   (mockup aprobado: disenos/logger-selector-proyectos-admin-2026-07-22.html)

   Ocurren FUERA de una producción, por eso usan el shell `base_top.html` (barra
   superior, sin sidebar ni chips de presupuesto). SOLO layout: cada color sale
   de un var(--token) de la paleta clínica; los pocos literales (#BFDBFE, #FECACA)
   son bordes suaves del mismo acento, igual que los que ya usan .totalrow
   (#DBEAFE), .banner (#BBF7D0) y .errbanner (#FECACA). Ninguna fuente nueva.
   ───────────────────────────────────────────────────────────────────────── */

/* Barra superior del shell */
.top {
  position: sticky; top: 0; z-index: 10; background: var(--surface);
  border-bottom: 1px solid var(--line); display: flex; align-items: center;
  justify-content: space-between; padding: 11px 24px;
}
.brand { display: flex; align-items: center; gap: 11px; text-decoration: none; }
.brand h1 { font-family: var(--font-head); font-size: 18px; margin: 0; font-weight: 600; color: var(--ink); }
.brand small { display: block; color: var(--muted); font-size: 10.5px; }
.userbox { display: flex; align-items: center; gap: 10px; font-size: 12.5px; }
.userbox .who { text-align: right; }
.userbox .who b { display: block; font-size: 12.5px; }
.userbox .who small { display: block; color: var(--muted); font-size: 10.5px; }
.adm-tag {
  font-size: 9.5px; font-weight: 700; color: var(--blue); background: var(--blue-soft);
  border: 1px solid #BFDBFE; border-radius: 20px; padding: 2px 8px; margin-top: 2px;
  display: inline-block;
}
/* Botón discreto del pie de la barra. Lo comparten DOS elementos distintos, y
   por eso lleva `text-align`/`text-decoration` explícitos:
     · en el lobby (base_top.html) es un <button> real, POST a /logout
       ("Cerrar sesión");
     · dentro de un proyecto (base.html) es un <a> a "/" ("← Cambiar de
       proyecto"): navegar no cambia nada, así que no necesita ser POST.
   Un <a> no centra su texto ni pierde el subrayado por sí solo. */
.salir-form { margin: 0; }
.salir-btn {
  font-family: var(--font-body); font-size: 12px; color: var(--muted);
  background: transparent; border: 1px solid var(--line); border-radius: 8px;
  padding: 6px 12px; cursor: pointer; transition: background .12s, color .12s;
  width: 100%; /* apilado bajo el bloque de usuario, a lo ancho del pie */
  display: block; text-align: center; text-decoration: none;
}
.salir-btn:hover { background: var(--surface-2); color: var(--ink); }

/* Contenedor de estas pantallas (más ancho que el .wrap de formularios) */
.wrap-sistema { max-width: 1080px; }
.wrap-angosto { max-width: 660px; }
.volver { display: inline-block; font-size: 12.5px; color: var(--muted); text-decoration: none; margin-bottom: 14px; }
.volver:hover { color: var(--blue); }
.seclbl {
  font-size: 11px; text-transform: uppercase; letter-spacing: .7px;
  color: var(--muted); font-weight: 700; margin: 0 0 12px;
}
label .opt { color: var(--muted); font-weight: 400; }
.fhint { font-size: 11.5px; color: var(--muted); margin-top: 6px; }
.plus { font-size: 15px; line-height: 1; }

/* Zona de administrador (solo se dibuja si es_admin) */
.adminbar {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  background: var(--surface); border: 1px solid #BFDBFE; border-radius: var(--radius);
  padding: 14px 18px; margin-bottom: 22px; box-shadow: var(--shadow); flex-wrap: wrap;
}
.ab-left { display: flex; flex-direction: column; gap: 3px; }
.ab-badge {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700;
  color: var(--blue); background: var(--blue-soft); border: 1px solid #BFDBFE;
  border-radius: 20px; padding: 3px 10px; width: max-content;
}
.ab-note { font-size: 11.5px; color: var(--muted); }
.ab-actions { display: flex; gap: 10px; flex-wrap: wrap; }
/* Los botones de la zona admin son enlaces: mismo .btn, sin subrayado */
.ab-actions .btn { text-decoration: none; display: inline-flex; align-items: center; gap: 8px; }
.actions .btn { text-decoration: none; display: inline-flex; align-items: center; }

/* Badges de cargo */
.badge {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 700;
  padding: 3px 10px; border-radius: 20px; white-space: nowrap;
}
.b-admin { background: var(--blue); color: #fff; }
.b-conta { background: var(--blue-soft); color: var(--blue); }
.b-lect  { background: var(--surface-2); color: var(--muted); }
.b-coord { background: var(--amber-soft); color: var(--amber); }
/* Persona dada de baja (activo=false): rojo suave, como una alerta discreta. */
.b-inactiva { background: var(--red-soft); color: var(--red); border: 1px solid #FECACA; }

/* Grilla de proyectos */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 16px; }
.pcard {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden; cursor: pointer; text-decoration: none;
  color: inherit; display: block; transition: transform .12s, box-shadow .12s;
}
.pcard:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(15,23,42,.10); }
.poster {
  height: 96px; display: grid; place-items: center; color: #fff;
  font-family: var(--font-head); font-weight: 700; font-size: 30px;
}
/* Tres variantes de portada, derivadas de los tokens (azul · tinta · ámbar) */
.poster.g1 { background: linear-gradient(135deg, var(--blue), var(--blue-hover)); }
.poster.g2 { background: linear-gradient(135deg, var(--ink), #334155); }
.poster.g3 { background: linear-gradient(135deg, var(--amber), #92400E); }
.pbody { padding: 14px 16px; }
.pbody .pn { font-family: var(--font-head); font-size: 16px; font-weight: 600; margin: 0; }
.pbody .pmeta { color: var(--muted); font-size: 11.5px; margin: 2px 0 12px; }

/* Aviso informativo del selector */
.hint {
  display: flex; align-items: center; gap: 8px; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px;
  margin-bottom: 20px; font-size: 12.5px; color: var(--ink);
}
.hint b { color: var(--blue); }

/* Estado vacío del selector */
.vacio {
  background: var(--surface); border: 1px dashed var(--line-strong); border-radius: var(--radius);
  padding: 30px 22px; text-align: center; color: var(--muted); font-size: 12.5px;
}
.vacio .vh { font-family: var(--font-head); font-size: 17px; color: var(--ink); margin-bottom: 6px; }
.vacio p { margin: 0; }

/* Crear proyecto: variante informativa (azul) del banner ya existente */
.banner-info { background: var(--blue-soft); border-color: #BFDBFE; align-items: flex-start; }
.banner-info svg { stroke: var(--blue); margin-top: 1px; }
.banner-info b { color: var(--blue); }
.next { background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; padding: 14px 16px; margin-top: 18px; }
.next .nh { font-size: 12px; font-weight: 700; margin-bottom: 8px; }
.steps { display: flex; gap: 8px; flex-wrap: wrap; }
.step {
  display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--muted);
  background: var(--surface); border: 1px solid var(--line); border-radius: 8px; padding: 6px 10px;
}
.step .n {
  width: 18px; height: 18px; border-radius: 50%; background: var(--blue-soft); color: var(--blue);
  display: grid; place-items: center; font-size: 10px; font-weight: 700;
}

/* Panel de Admin: dos columnas */
.admin { display: grid; grid-template-columns: 320px 1fr; gap: 18px; align-items: start; }
.panel {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden;
}
.panel-h { padding: 14px 16px; border-bottom: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.panel-h h3 { margin: 0; font-size: 14px; font-weight: 700; }
.btn-mini { padding: 6px 12px; font-size: 12px; border-radius: 7px; }
.search { display: flex; align-items: center; gap: 8px; padding: 9px 13px; border-bottom: 1px solid var(--line); background: var(--surface-2); }
.search svg { width: 15px; height: 15px; stroke: var(--muted); fill: none; stroke-width: 2; flex-shrink: 0; }
.search input { border: none; background: none; padding: 0; box-shadow: none !important; }

/* Alta de persona por correo */
.nuevo-box { padding: 14px 16px; border-bottom: 1px solid var(--line); background: var(--surface-2); }
.nuevo-box .fld { margin-bottom: 9px; }
.nuevo-acciones { display: flex; justify-content: flex-end; gap: 8px; margin-top: 10px; }
.check { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; margin: 0; }
.check input { width: auto; }

/* Lista de personas */
.ulist { max-height: 520px; overflow: auto; }
.urow {
  display: flex; align-items: center; gap: 11px; padding: 11px 15px;
  border-bottom: 1px solid var(--line); cursor: pointer; border-left: 3px solid transparent;
}
.urow:last-child { border-bottom: none; }
.urow:hover { background: var(--surface-2); }
.urow.on { background: var(--blue-soft); border-left-color: var(--blue); }
.urow .nm { font-weight: 600; font-size: 13px; }
.urow .em { color: var(--muted); font-size: 11px; }
.urow .cnt { margin-left: auto; }
.urow.inactiva .avatar, .urow.inactiva .nm { opacity: .5; }
/* Cuando la fila trae Admin + Inactiva, solo el primero empuja a la derecha. */
.urow .cnt ~ .cnt { margin-left: 6px; }

/* Detalle de la persona */
.dvacio { padding: 30px 22px; color: var(--muted); font-size: 12.5px; text-align: center; }
.dvacio-sm { color: var(--muted); font-size: 12.5px; margin: 0 0 4px; }
.dhead-u { padding: 18px 20px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.dhead-u .big {
  width: 46px; height: 46px; border-radius: 50%; background: var(--blue-soft); color: var(--blue);
  display: grid; place-items: center; font-weight: 700; font-size: 17px; flex-shrink: 0;
}
.dhead-u .nm { font-family: var(--font-head); font-size: 19px; font-weight: 600; margin: 0; }
.dhead-u .em { color: var(--muted); font-size: 12.5px; }

/* Interruptores del encabezado (Dueño del sistema + Activo), apilados a la derecha */
.toggles { margin-left: auto; display: flex; flex-direction: column; gap: 8px; }
.toggle {
  margin-left: auto; display: flex; align-items: center; gap: 10px; background: var(--surface-2);
  border: 1px solid var(--line); border-radius: 10px; padding: 8px 12px;
}
.toggles .toggle { margin-left: 0; min-width: 210px; }
.toggle .tt { font-size: 12px; font-weight: 600; }
.toggle .ts { font-size: 10.5px; color: var(--muted); }
.sw {
  width: 40px; height: 23px; border-radius: 20px; background: var(--line-strong); border: none;
  position: relative; cursor: pointer; transition: background .15s; flex-shrink: 0; padding: 0;
}
.sw::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 19px; height: 19px;
  border-radius: 50%; background: #fff; transition: left .15s; box-shadow: 0 1px 2px rgba(15,23,42,.2);
}
.sw.on { background: var(--blue); }
.sw.on::after { left: 19px; }

/* Pases */
.dsec { padding: 18px 20px; }
.dsec-h { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.dsec-h h4 { margin: 0; font-size: 13px; font-weight: 700; }
.dsec-h small { color: var(--muted); font-size: 11.5px; }
.arow { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px; margin-bottom: 9px; flex-wrap: wrap; }
.arow .proj { font-weight: 700; font-size: 13.5px; min-width: 150px; }
.arow .dept { font-size: 11.5px; color: var(--muted); }
.arow .rm {
  margin-left: auto; font-size: 11.5px; color: var(--muted); border: 1px solid var(--line);
  background: var(--surface); border-radius: 7px; padding: 5px 10px; cursor: pointer; font-family: inherit;
}
.arow .rm:hover { border-color: #FECACA; color: var(--red); background: var(--red-soft); }

/* Formulario "Asignar a un proyecto" */
.addbox { border: 1.5px dashed var(--line-strong); border-radius: 10px; padding: 14px; background: var(--surface-2); margin-top: 14px; }
.addbox .ah { font-size: 12px; font-weight: 700; margin-bottom: 10px; color: var(--ink); }
.addgrid { display: grid; grid-template-columns: 1.4fr 1.2fr 1.2fr auto; gap: 9px; align-items: end; }
/* El botón no se estira cuando el campo Departamento se esconde (cargos que no
   son coordinador): conserva su ancho natural en vez de ocupar la columna libre. */
.addgrid > .btn { justify-self: start; }
.fld label { display: block; font-size: 11px; font-weight: 600; margin-bottom: 4px; color: var(--muted); }
.fld select, .fld input { width: 100%; padding: 8px 10px; border: 1px solid var(--line-strong); border-radius: 8px; font-family: inherit; font-size: 12.5px; background: var(--surface); color: var(--ink); }
.note { font-size: 11px; color: var(--amber); margin-top: 9px; display: flex; align-items: center; gap: 6px; }

@media (max-width: 900px) {
  .admin { grid-template-columns: 1fr; }
  .addgrid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 560px) {
  .top { flex-wrap: wrap; gap: 10px; }
  .adminbar { align-items: flex-start; }
}

/* ==========================================================================
   Pantalla "Editar / archivar / eliminar producción" (solo admin)
   Diseño aprobado 2026-07-23 (disenos/logger-editar-eliminar-proyecto-2026-07-23.html).
   Reutiliza los tokens oficiales: el rojo es --red / --red-soft, el ámbar de
   archivar es --amber / --amber-soft. No hay ningún color nuevo; el único valor
   literal es #FECACA, el borde rojo claro que ya usaban .b-inactiva y .arow .rm.
   ========================================================================== */

/* Cabecera de la producción (póster + nombre + pastilla de estado).
   `.poster` nace como PORTADA de la tarjeta del selector (96px de alto y todo el
   ancho de la tarjeta). Aquí y en la lista se reusa como MINIATURA, así que se le
   fija un cuadrado: sin `flex-shrink: 0` el flex lo estruja y las iniciales salen
   deformadas cuando el nombre de al lado es largo. */
.phead { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.phead .poster {
  width: 56px; height: 56px; border-radius: 12px; font-size: 22px; flex-shrink: 0;
}
.phead .pn { font-family: var(--font-head); font-size: 20px; font-weight: 600; margin: 0; }
.phead .pmeta { color: var(--muted); font-size: 12.5px; }
.state-pill { margin-left: auto; font-size: 11px; font-weight: 700; padding: 4px 11px; border-radius: 20px; white-space: nowrap; }
.sp-data { background: var(--green-soft); color: var(--green); }
.sp-empty { background: var(--surface-2); color: var(--muted); }
.sp-archivada { background: var(--amber-soft); color: var(--amber); }

/* Zona de peligro: sección aparte, borde rojo */
.danger-lbl { font-size: 11px; text-transform: uppercase; letter-spacing: .7px; color: var(--red); font-weight: 700; margin: 26px 0 12px; }
.dzone { border: 1px solid #FECACA; border-radius: var(--radius); background: linear-gradient(180deg, var(--surface), #FFFBFB); overflow: hidden; }
.dblock { padding: 18px 20px; display: flex; gap: 16px; align-items: flex-start; }
.dblock + .dblock { border-top: 1px solid var(--line); }
.dblock .ico { width: 36px; height: 36px; border-radius: 10px; display: grid; place-items: center; flex-shrink: 0; }
.dblock .ico svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ico-amber { background: var(--amber-soft); color: var(--amber); }
.ico-red { background: var(--red-soft); color: var(--red); }
.dblock .body { flex: 1; }
.dblock h4 { margin: 0 0 4px; font-size: 14px; font-weight: 700; }
.dblock p { margin: 0; font-size: 12.5px; color: var(--muted); }
.dblock .act { margin-left: auto; }

.btn-archive {
  font-family: inherit; padding: 9px 16px; border-radius: 9px; font-weight: 700;
  font-size: 13px; cursor: pointer; border: 1px solid var(--amber);
  background: var(--surface); color: var(--amber); white-space: nowrap;
}
.btn-archive:hover { background: var(--amber-soft); }
.btn-del {
  font-family: inherit; padding: 9px 16px; border-radius: 9px; font-weight: 700;
  font-size: 13px; cursor: pointer; border: 1px solid var(--red);
  background: var(--red); color: #fff; white-space: nowrap;
}
.btn-del:hover { background: #B91C1C; }
.btn-del:disabled { background: var(--surface); color: var(--line-strong); border-color: var(--line); cursor: not-allowed; }
.btn-archive:disabled, .btn-restore:disabled { opacity: .55; cursor: not-allowed; }
.btn-restore {
  font-family: inherit; padding: 9px 16px; border-radius: 9px; font-weight: 700;
  font-size: 13px; cursor: pointer; border: 1px solid var(--green);
  background: var(--surface); color: var(--green); white-space: nowrap;
}
.btn-restore:hover { background: var(--green-soft); }

/* Checklist de elegibilidad para borrar */
.checklist { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.chk { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.chk .mk { width: 17px; height: 17px; border-radius: 50%; display: grid; place-items: center; font-size: 11px; font-weight: 700; flex-shrink: 0; }
.mk-ok { background: var(--green-soft); color: var(--green); }
.mk-no { background: var(--red-soft); color: var(--red); }
.mk-wait { background: var(--surface-2); color: var(--muted); }
.chk .val { margin-left: auto; color: var(--muted); font-size: 11.5px; }

/* Confirmación de borrado: escribir el nombre exacto */
.confirm { margin-top: 14px; background: var(--red-soft); border: 1px solid #FECACA; border-radius: 10px; padding: 14px; }
.confirm label { color: var(--red); font-size: 12px; }
.confirm input { border-color: #FECACA; }
.confirm input:focus { border-color: var(--red); box-shadow: 0 0 0 3px rgba(220,38,38,.14); }
.confirm .row { display: flex; gap: 10px; align-items: flex-end; margin-top: 4px; }
.confirm .row .field { flex: 1; margin: 0; }

/* Nota de bloqueo: por qué no se puede borrar y qué hacer en su lugar */
.blocked-note {
  margin-top: 12px; background: var(--amber-soft); border: 1px solid #FDE3C4;
  border-radius: 10px; padding: 12px 14px; font-size: 12px; color: var(--amber);
  display: flex; gap: 9px; align-items: flex-start;
}
.blocked-note b { color: var(--amber); }

/* Aviso de producción archivada (solo lectura) */
.archived-note {
  background: var(--amber-soft); border: 1px solid #FDE3C4; border-radius: 10px;
  padding: 12px 14px; font-size: 12.5px; color: var(--amber); margin-bottom: 20px;
  display: flex; gap: 9px; align-items: flex-start;
}
.archived-note b { color: var(--amber); }

/* Lista "Gestionar producciones" */
.plist { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; }
.prow { display: flex; align-items: center; gap: 14px; padding: 13px 18px; }
.prow + .prow { border-top: 1px solid var(--line); }
.prow .poster {
  width: 44px; height: 44px; border-radius: 10px; font-size: 16px; flex-shrink: 0;
}
.prow .pinfo { flex: 1; min-width: 0; }
.prow .pn { font-weight: 700; font-size: 13.5px; margin: 0; }
.prow .pmeta { color: var(--muted); font-size: 11.5px; }
.prow .btn-mini { text-decoration: none; white-space: nowrap; }
.prow.archivada .pn { color: var(--muted); }
.toggle-archivadas { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--muted); margin: 14px 0 0; cursor: pointer; }
.toggle-archivadas input { width: auto; margin: 0; cursor: pointer; }

@media (max-width: 560px) {
  .dblock { flex-wrap: wrap; }
  .dblock .act { margin-left: 0; width: 100%; }
  .btn-archive, .btn-del, .btn-restore { width: 100%; }
  .prow { flex-wrap: wrap; }
}

/* ============================================================================
   Tabla de LÍNEAS (rediseño PO/CR multi-cuenta, Fase 6)
   Cada documento reparte su plata en N líneas (cuenta · descripción · valor).
   Reutiliza los tokens de la paleta clínica; no introduce colores ni fuentes.
   ============================================================================ */
.lines { width: 100%; border-collapse: collapse; font-size: 13px; }
.lines th {
  text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--muted); font-weight: 700; padding: 0 8px 8px; border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.lines th.num { text-align: right; }
.lines td { padding: 7px 8px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.lines tbody tr:last-child td { border-bottom: none; }
.lines td.idx { color: var(--muted); width: 26px; font-size: 12px; text-align: center; }
.lines td.num { text-align: right; font-variant-numeric: tabular-nums; }
/* Los inputs/selects dentro de la tabla son más compactos que los de un .field */
.lines .gi { padding: 8px 9px; font-size: 13px; }
.lines input.gi.num { min-width: 120px; max-width: 150px; margin-left: auto; text-align: right; }
.lines .desc-in { min-width: 160px; }
.lines td.acc { min-width: 190px; }
/* Aquí vivían `.lines tr.line-iva` y `.iva-tag`, que pintaban de ámbar la línea
   de IVA. Se retiraron el 2026-07-27 con toda la UI del IVA: era presentación
   (D10) y el IVA es una cuenta de presupuesto como cualquier otra. Se borran en
   vez de dejarlas huérfanas, para no repetir el caso de `--teal` (alias vivos
   sin ningún consumidor, anotado en CLAUDE.md §3). */
/* Fila señalada por el backend como la culpable de un rechazo ({regla,motivo,linea}).
   Es un borde rojo suave, del mismo acento que el ErrorBanner; no redacta nada. */
.lines tr.line-bad td { background: var(--red-soft); }
.lines tr.line-bad td:first-child { box-shadow: inset 3px 0 0 var(--red); }
/* Botón ✕ para quitar una línea */
.rmline {
  border: 1px solid var(--line); background: #fff; border-radius: 7px; padding: 4px 9px;
  cursor: pointer; font-family: inherit; color: var(--muted); font-size: 12px; line-height: 1;
}
.rmline:hover { border-color: var(--red-line); color: var(--red); background: var(--red-soft); }
/* Celdas de solo-lectura dentro de la tabla del CR anclado (comprometido / queda),
   que el backend calcula por línea — el Frontend nunca las recalcula. */
.lines .ro { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; font-size: 12px; }
.lines .ro.queda { color: var(--green); font-weight: 600; }
/* Si lo que se paga excede el remanente, el "queda" avisa en rojo (aviso temprano
   de la Regla 2; el backend sigue siendo el único que valida). */
.lines .ro.queda.excede { color: var(--red); }

/* Texto apagado "Borradores: pronto" en la zona de acciones — lo que aún no
   funciona no compite por atención (reemplaza al botón muerto deshabilitado). */
.actions .soon-note { color: var(--muted); font-size: 12px; align-self: center; }

/* Botones "＋ Agregar línea" / "＋ Agregar IVA" */
.addrow { margin-top: 12px; display: flex; gap: 10px; flex-wrap: wrap; }
.addline {
  font-family: inherit; font-size: 13px; font-weight: 700; padding: 8px 14px; border-radius: 8px;
  border: 1.5px dashed var(--line-strong); background: var(--surface-2); color: var(--blue); cursor: pointer;
}
.addline:hover { border-color: var(--blue); background: var(--blue-soft); }
/* `.addline.addiva` (el botón ámbar "＋ Agregar IVA") se retiró el 2026-07-27
   junto con el botón mismo: ya no queda ningún elemento que lleve esa clase. */

/* Caja de total (Σ líneas). El titular en Fraunces/azul, como el resto de totales. */
.totalsbox { margin-top: 18px; display: flex; justify-content: flex-end; }
.totalsbox .box {
  min-width: 280px; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 12px; padding: 14px 18px;
}
.trow { display: flex; justify-content: space-between; font-size: 13px; padding: 3px 0; }
.trow .lbl { color: var(--muted); }
.trow .val { font-variant-numeric: tabular-nums; }
.trow.grand {
  border-top: 1px solid var(--line-strong); margin-top: 6px; padding-top: 8px;
  font-family: var(--font-head); font-size: 19px; font-weight: 600;
}
.trow.grand .val { color: var(--blue); }

/* Interruptor de modo del CR (Pago contra PO / CR directo) */
.modeswitch { display: flex; align-items: center; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.modeswitch .lab { font-size: 12.5px; color: var(--muted); font-weight: 600; }
.modeswitch .tab {
  font-family: inherit; font-size: 13px; font-weight: 700; padding: 8px 15px; border-radius: 8px;
  border: 1px solid var(--line-strong); background: #fff; color: var(--muted); cursor: pointer;
}
.modeswitch .tab.on { background: var(--blue); border-color: var(--blue); color: #fff; }

/* ═════════════════════════════════════════════════════════════════════════
   CATÁLOGO DE CUENTAS (COA) — la tabla-árbol de tres niveles
   Plan `docs/PLAN-COA-FRONTEND-2026-07-26.md`, ficha P2.

   Todo lo de aquí usa las variables clínicas que ya existen arriba: cero hex
   nuevos, cero fuentes nuevas. La jerarquía se lee por SANGRÍA + PESO
   DECRECIENTE (grupo fuerte, cuenta media, subcuenta normal), que es como se
   lee un plan de cuentas en papel.
   ═════════════════════════════════════════════════════════════════════════ */

.coa-filtros { flex-wrap: wrap; }
.coa-chk {
  margin-left: auto; display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; color: var(--muted); font-weight: 600; cursor: pointer;
  white-space: nowrap;
}
.coa-chk input { width: 14px; height: 14px; box-shadow: none !important; }

/* ══ F5 · LAS TRES CAPAS PEGAJOSAS DEL COA ═══════════════════════════════════
   Con 187 filas, lo que se pierde al bajar no es "un poco de contexto": son los
   rótulos que dicen QUÉ significa cada columna. Y con la jerarquía de F3 puesta
   eso se volvió una dependencia, no una comodidad — "en blanco" pasó a
   significar DOS cosas distintas en la misma fila (heredado, en Módulo y
   ATL/BTL; normal, en Estado), y la cabecera es lo único que las separa.

   Tres capas, cada una pegada bajo la anterior:
     1. `.bar`      — la barra de migas de la app. Ya existía (línea 171).
     2. `.trabajo`  — buscador, filtros y contador.
     3. `thead th`  — los rótulos de las columnas.

   ⚠️ Las alturas NO están tecleadas: las MIDE el JavaScript con
   getBoundingClientRect y las escribe en `--h-bar` y `--h-trabajo`. Los valores
   de aquí son solo el arranque, para el primer cuadro antes de la medición.
   Están tecleados a mano en un solo sitio y se sustituyen solos.

   ⚠️ Y POR QUÉ ESTA FASE VA LA ÚLTIMA: su defecto solo existe cuando ya existe
   la columna de F6. Abrir la columna estrecha la barra de trabajo, la barra se
   parte en dos líneas y CRECE de alto — y el `top` del `thead` seguiría
   valiendo la altura medida cuando la barra iba en una línea, así que las
   primeras filas se colarían por encima. Construida antes de F6 esta fase salía
   "correcta" a un ancho fijo y F6 la habría roto en silencio. El bug vive en la
   costura; se construye la costura al final para encontrarlo a tiempo.
   ══════════════════════════════════════════════════════════════════════════ */
:root { --h-bar: 44px; --h-trabajo: 52px; }

.trabajo {
  position: sticky; top: var(--h-bar); z-index: 4;
  background: var(--surface); border: 1px solid var(--line); border-radius: 11px;
  box-shadow: var(--shadow); padding: 9px 13px; margin-bottom: 14px;
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
}
/* El buscador dentro de la barra: mismo aire que `.search`, pero en línea con
   los filtros en vez de ocupando su propia banda dentro de la tarjeta. */
.trabajo .buscador {
  display: flex; align-items: center; gap: 7px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 9px;
  padding: 6px 11px; flex: 1 1 210px; min-width: 180px;
}
.trabajo .buscador svg { width: 14px; height: 14px; stroke: var(--muted); fill: none; stroke-width: 2; flex-shrink: 0; }
.trabajo .buscador input {
  border: 0; background: none; outline: none; padding: 0; box-shadow: none !important;
  font-family: inherit; font-size: 12.5px; color: var(--ink); width: 100%;
}
.trabajo-sep { width: 1px; height: 20px; background: var(--line-strong); opacity: .7; }

/* ⭐ COA-F10 · HALLAZGO 6 — el par «Plegar todo / Desplegar todo».
   `flex: none` para que la barra de trabajo, que es `flex-wrap`, no los estire
   ni los parta entre sí: son DOS acciones opuestas y se leen como una sola
   pieza. Van juntos o van a línea nueva juntos. */
.par-botones { display: inline-flex; gap: 6px; flex: none; }

/* ⭐ LA CABECERA DE LA TABLA (capa 3).
   ⚠️ Con `border-collapse: collapse` un `th` pegajoso PIERDE su borde inferior
   —el borde se resuelve en el colapso y el elemento pegado se lo deja atrás—,
   así que la línea se dibuja con `box-shadow: inset`. El `border-collapse` NO
   se toca: es lo que hace continuo el riel de los tres niveles. */
.coa-tbl thead th {
  position: sticky; top: calc(var(--h-bar) + var(--h-trabajo)); z-index: 3;
  background: var(--surface-2);
  box-shadow: inset 0 -1px 0 var(--line);
}
/* La trampa: sin esto la cabecera no se pega y NO avisa. Ver el comentario de
   la plantilla, en el `div.tblwrap.coa-wrap`. Acotado a esta pantalla. */
.tblwrap.coa-wrap { overflow: visible; }

/* ══ ⭐⭐ LAS OTRAS DOS TRAMPAS DE LA MISMA CADENA (UAT 2026-07-29) ═══════════
   `coa-wrap` anula UN contenedor de overflow: el de dentro. Pero entre la tabla
   y el viewport hay TRES, y quitar el de abajo solo asciende el problema al
   siguiente. Medido en navegador el 2026-07-29 sobre esta misma hoja:

       div.tblwrap.coa-wrap   overflow: visible   ← ya anulado (arriba)
       div.card               overflow: hidden    ← `:191`, LA OCLUSIÓN
       main.main              overflow: auto      ← `:170`, LA NO-ADHERENCIA

   ⛔ EL DE LA `.card` ES EL QUE SE VE, y no se ve como "no se pega": se ve como
   la cabecera FLOTANDO EN MITAD DE LA TABLA Y TAPANDO UNA FILA. Un `overflow`
   que no scrollea sigue siendo el scrollport del sticky, así que el `top` de
   `calc(--h-bar + --h-trabajo)` se aplica igual — desde el borde de la CARD, que
   está quieta. Resultado: el `thead` baja 140,75 px y se queda ahí, opaco
   (`background: var(--surface-2)`) y por encima (`z-index: 3`), comiéndose las
   filas que caen debajo. Medido con scroll 0: `th.top - tabla.top = 140,8 px`,
   dos filas tapadas (una al 90 %, la de abajo al 13 %) — dato OCULTO, no un
   detalle estético.

   ⚠️ `clip`, NO `visible`: la `.card` necesita seguir recortando, o la tabla se
   sale de sus esquinas redondeadas. `overflow: clip` recorta igual que `hidden`
   pero NO crea scrollport, que es exactamente la diferencia que importa aquí.

   ⛔ EL DE `.main` NO SE VE, y por eso es el peligroso: `.main` tiene
   `overflow: auto` pero NUNCA scrollea —quien scrollea es el documento, porque
   `.app` es `min-height: 100vh` y `.main` crece con su contenido (medido:
   `main.scrollHeight === main.clientHeight`, 2561 === 2561)—. Un scrollport que
   no scrollea mata el sticky de todo lo que lleva dentro. Con la `.card` ya
   arreglada y esto no, la cabecera vuelve a su sitio y NO SE PEGA: se ve
   correcta al cargar y se va con las filas al bajar. Medido: `th.top` en
   scroll 900 = -646 px. Es la mitad silenciosa del arreglo, la que se cuela.

   ⚠️ ACOTADO A ESTA PANTALLA A PROPÓSITO. `.main` lo comparten las cinco, y
   `.bar` (`:171`, `position: sticky; top: 0`) tampoco se pega en NINGUNA por
   esta misma causa. Eso es un hallazgo aparte y una decisión de Stiven, no un
   efecto lateral de arreglar el COA: va propuesto en el acta, no hecho aquí.

   `:has()` en vez de una clase nueva: la cadena entera cuelga de `coa-wrap`,
   que es la clase que la plantilla YA declara y que el guardián de F5 YA
   vigila. Una clase más sería un cuarto sitio del que acordarse. Es el mismo
   idioma de `:1147`. Si un navegador no soporta `:has()`, las dos reglas se
   caen y queda el comportamiento de hoy — degrada al estado actual, no a peor.
   ═══════════════════════════════════════════════════════════════════════════ */
.card:has(> .tblwrap.coa-wrap) { overflow: clip; }
.main:has(> .wrap-coa) { overflow: visible; }

/* ⭐ HALLAZGO 9 — "Mostrando N de M". Cifras tabulares para que el número no
   baile mientras se teclea en el buscador, y `margin-left:auto` para que se
   vaya al extremo: es un dato de estado, no un control más de la fila.
   Cuando hay filtro pasa a azul — el mismo azul del resto de lo activo. */
.trabajo-cuenta {
  margin-left: auto; font-size: 11.5px; color: var(--muted);
  white-space: nowrap; font-variant-numeric: tabular-nums;
}
.trabajo-cuenta b { color: var(--ink); }
.trabajo-cuenta.filtrando, .trabajo-cuenta.filtrando b { color: var(--blue); }

.coa-tbl td { padding-top: 7px; padding-bottom: 7px; }
.coa-cod { font-variant-numeric: tabular-nums; white-space: nowrap; }
.coa-nom { color: var(--ink); }

/* ═══ LA JERARQUÍA DE TRES NIVELES ═══════════════════════════════════════════
   Un contador tiene que distinguir grupo, cuenta y subcuenta de un vistazo. Los
   nombres se repiten entre niveles (hay un grupo "Arte", una cuenta "Arte" y una
   subcuenta "Arte"), así que la diferencia tiene que estar en la FORMA.

   Lo que fallaba, medido: la sangría existía SOLO en la columna del código
   (`.coa-n2 .coa-cod { padding-left: 30px }`) y NO en la del nombre — que es la
   más ancha y a la que va el ojo. Los tres niveles tenían sus nombres alineados
   a la izquierda, o sea sin ninguna pista de quién colgaba de quién. Esa era la
   causa principal, y se arregla con las dos líneas de `padding-left` de abajo.

   Cuatro señales, no una, porque una sola se pierde:
     1. RIEL de color a la izquierda, con la intensidad del nivel. Ata la rama
        entera y se corta en azul al empezar otro grupo. Con `border-collapse:
        collapse` el borde más ancho gana en el cruce, así que el riel sale
        CONTINUO y la línea de separación de filas no lo parte.
     2. SANGRÍA en las DOS columnas visibles: 0 / 22 / 44 px.
     3. TRES PESOS de verdad: Fraunces 14 · Public Sans 12.5 semibold ·
        Public Sans 12.5 normal apagado. Antes eran 13 y 12.5 px, medio píxel
        de diferencia, o sea ninguna.
     4. La fila del grupo pasa de `--surface-2` a `--blue-soft`. El gris era el
        MISMO de la cabecera de la tabla y del pie, así que el ancla del grupo
        se leía como otro encabezado.
   Cero colores nuevos: --blue, --blue-soft, --line-strong, --line, --muted,
   --ink y --font-head ya existían todos.
   ══════════════════════════════════════════════════════════════════════════ */

/* ══ LA ESCALERA DE FONDOS POR NIVEL (F4) ════════════════════════════════════
   El nivel vive en el riel, la sangría y el peso — y ahora también en el FONDO.
   Tres escalones, del más marcado al papel:

       Grupo      --blue-soft-strong  #DBEAFE
       Cuenta     --blue-soft         #EFF4FF
       Subcuenta  --surface           #FFFFFF

   Los saltos son 1.107 y 1.102, o sea PAREJOS: los tres escalones se ven como
   tres. Se descartó la versión "sutil" (`--surface-2` para la cuenta) porque
   entre grupo y cuenta daba 1.006 —luminancia idéntica, dos escalones que se
   ven como uno— y porque ese gris es el mismo de la cabecera de la tabla.

   ⚠️⚠️ `background-color`, NUNCA la forma corta `background`. Medido: con la
   forma corta, la regla del nivel gana por especificidad a `.coa-inactiva > td`
   y le RESETEA el `background-image` — o sea que el rayado de la fila apagada
   no perdía contraste: DESAPARECÍA. La longhand toca solo el color y deja vivo
   el rayado.

   ⚠️ Y por qué el fondo NO marca el "editando": ver el bloque del defecto vivo,
   más abajo. El fondo dice lo que la fila ES; el contorno, lo que le PASA.
   ══════════════════════════════════════════════════════════════════════════ */

/* Nivel 1 — GRUPO: el ancla visual de la rama, y donde arranca el riel azul. */
.coa-n1 > td {
  background-color: var(--blue-soft-strong);
  border-top: 2px solid var(--line-strong);
}
.coa-n2 > td { background-color: var(--blue-soft); }
.coa-n3 > td { background-color: var(--surface); }

/* ⛔ MINA PARA EL QUE VENGA A HACER CLICABLES LAS FILAS DEL COA — está escrita
   aquí porque es justo donde vas a mirar.

   La app tiene UNA convención de hover de fila, y es esta:
       .tbl tbody tr.link:hover { background: var(--blue-soft); }   (línea 428)

   Hoy el COA no la usa: no emite la clase `link` en ninguna fila (medido:
   `grep -c 'class="link' app/templates/accounts/gestionar.html` → 0), así que
   esta pantalla no tiene hover de fila y no había nada que perder.

   Pero con la escalera puesta, `--blue-soft` YA NO ESTÁ LIBRE: es el fondo de
   TODAS las filas de cuenta. El día que alguien añada `class="link"` aquí, ese
   hover será INVISIBLE en el nivel de cuenta (pinta el color que la fila ya
   tiene) e indistinguible de una cuenta en los otros dos niveles. No dará
   error y no romperá ningún test: simplemente no se notará.

   Si hace falta hover en esta pantalla va por CONTORNO, nunca por fondo, por la
   misma separación de canales que gobierna todo este bloque. Un anillo más
   tenue que el de `.coa-editando` es la forma correcta. */
.coa-n1 > td:first-child { border-left: 3px solid var(--blue); padding-left: 11px; }
/* ⚠️ UNA SOLA FAMILIA EN LAS FILAS (F3). Esto era Fraunces 14 px: una serif de
   título dentro de una tabla de datos, que además hacía la fila más alta que
   las otras dos. Fraunces se queda donde es la voz de la app —los títulos y las
   cifras grandes de totales— y el árbol pasa a ser todo Public Sans. El grupo
   sigue siendo el más marcado, pero por PESO (700), no por familia. */
.coa-n1 .coa-cod, .coa-n1 .coa-nom {
  font-family: var(--font-body); font-size: 13px; font-weight: 700;
  color: var(--ink);
}
.coa-n1 .coa-cod { font-variant-numeric: tabular-nums; }

/* Nivel 2 — CUENTA: un paso de sangría, riel más tenue, peso intermedio. */
.coa-n2 > td:first-child { border-left: 3px solid var(--line-strong); }
.coa-n2 .coa-cod { padding-left: 33px; }
.coa-n2 .coa-nom { color: var(--ink); font-weight: 600; padding-left: 22px; }

/* Nivel 3 — SUBCUENTA (la hoja, donde cae el dinero): dos pasos y riel mínimo.
   ⭐ SU NOMBRE ES LO MÁS OSCURO DE LA FILA (F3), y es la decisión que ordena
   toda la pantalla: la subcuenta es DONDE CAE EL DINERO — es el dato que el
   contador viene a buscar—, así que no puede ser lo más tenue del árbol. Era
   `--muted` porque es la fila más numerosa, y ese razonamiento confundía
   "cuántas hay" con "cuánto importa cada una".
   El NIVEL no se pierde: lo siguen diciendo el riel, la sangría y el peso. El
   código sí se queda en `--muted` — eso es la referencia, no el dato. */
.coa-n3 > td:first-child { border-left: 3px solid var(--line); }
.coa-n3 .coa-cod { padding-left: 57px; color: var(--muted); }
.coa-n3 .coa-nom { color: var(--ink); font-weight: 400; padding-left: 44px; }

/* El rótulo bajo el nombre: "2 cuentas" / "3 subcuentas". Da el tamaño de la
   rama sin gastar una columna, y cuenta lo que se está MOSTRANDO.
   ⚠️ Pasa de versalitas 10,5 px con letter-spacing a texto normal de 11: en
   versalitas parecía otra etiqueta del sistema, y lo que dice es un número
   que se lee. */
.coa-nivel {
  display: block; margin-top: 1px;
  font-family: var(--font-body); font-size: 11px; font-weight: 400;
  letter-spacing: 0; text-transform: none; color: var(--muted);
}
/* El azul del rótulo del grupo se retira: competía con el riel, que ya es azul
   y ya dice lo mismo. */
.coa-n1 .coa-nivel { color: var(--muted); opacity: 1; }

/* ⭐ LA PALABRA DEL NIVEL SE CALLA. «grupo · » / «cuenta · » se sigue EMITIENDO
   en el HTML (ver `rotuloDeNivel` en la plantilla) y se esconde aquí: con el
   riel, la sangría y el peso puestos, el nivel ya está dicho tres veces.
   Quitar esta línea lo devuelve entero, sin tocar el JavaScript. */
.coa-nivel-que { display: none; }

/* ⭐⭐ EL CONTADOR ES CONDICIONAL — y esta regla es la única del pase que
   entregó premio de ALTO, así que ⛔ NO SE BORRA AL "SIMPLIFICAR".
   «3 subcuentas» informa exactamente cuando NO se pueden ver las subcuentas: con
   la rama PLEGADA. Desplegada, están ahí debajo, contables con el ojo, y el
   rótulo solo hace de dos líneas la fila padre. Se lee el estado del chevrón
   con :has(), sin una sola línea de JavaScript.
   Quien la quite no romperá nada — y por eso no se va a enterar: la tabla
   simplemente saldrá más alta que antes. */
.coa-tbl tbody tr:has(.coa-chev.abierto) .coa-nivel { display: none; }

/* Fila inactiva: rayado diagonal suave + texto apagado. NO se oculta el dato,
   se marca — desactivar conserva la historia, no la borra.

   ⭐⭐ Y LA FILA APAGADA SALE DE LA ESCALERA (F4): vuelve al blanco. Por dos
   medidas, no por gusto:

     · El rayado se dibuja con `--surface-2` SOBRE el fondo de la fila:
           contra el blanco de la subcuenta ......... 1.096  (se ve)
           contra el azul de la cuenta (escalera) ... 1.006  (NO se ve)
       Sobre el escalón azul el rayado no perdía fuerza: desaparecía.
     · Y el ámbar del estado anómalo sobre el azul marcado del grupo da
       4.12 : 1, por debajo del 4.5 que pide AA para texto normal — el único
       punto del pase que se quedaba corto. Sobre blanco sube a 5.02 : 1.

   Encaja además con la doctrina: el fondo dice lo que la fila ES, y una fila
   apagada YA NO ESTÁ participando del árbol de trabajo. Su nivel lo siguen
   diciendo el riel y la sangría, que aquí no se tocan.

   Va DESPUÉS de las tres reglas de la escalera a propósito: misma
   especificidad (0,1,1), así que gana la última, que es esta. */
.coa-inactiva > td {
  color: var(--muted);
  background-color: var(--surface);
  background-image: repeating-linear-gradient(
    45deg, transparent, transparent 5px,
    var(--surface-2) 5px, var(--surface-2) 10px);
}
.coa-inactiva .coa-nom, .coa-inactiva .coa-cod { text-decoration: line-through; opacity: .75; }

/* Chevron de plegado. El hueco mantiene alineadas las filas sin hijos. */
.coa-chev {
  border: none; background: none; padding: 0; margin-right: 7px; cursor: pointer;
  width: 14px; height: 14px; vertical-align: middle; color: var(--muted);
}
.coa-chev svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2.2; transition: transform .15s ease; }
.coa-chev.abierto svg { transform: rotate(90deg); }
.coa-chev:hover { color: var(--blue); }
.coa-chev-hueco { display: inline-block; width: 14px; margin-right: 7px; vertical-align: middle; }

/* "No aplica" (D37): un grupo de Balance no tiene ATL/BTL, y eso no es un hueco
   por llenar. El title explica el porqué al pasar el cursor. */
.coa-na { color: var(--line-strong); font-weight: 700; cursor: help; }

/* ⭐⭐ EL ESTADO SE CALLA CUANDO ES NORMAL (F3).
   Había 42 filas gritando en verde «Activa» — el color más fuerte de la tabla
   gastado en decir lo que nunca cambia. Y el efecto era el contrario del que
   se busca: con todo en verde, la fila ANÓMALA quedaba en gris, o sea era la
   MENOS visible de la pantalla.
   Ahora «Activa» no se pinta (la celda vacía ES el estado normal, igual que la
   celda vacía de Módulo ES la herencia, D8) y lo apagado habla en ámbar. Es el
   único cambio de este pase que AÑADE color, y añade porque el punto entero es
   que el color signifique algo. */
.coa-ok  { display: none; }
.coa-off { font-size: 11.5px; color: var(--amber); font-weight: 700; }

/* ⭐ HALLAZGO 13 (F3) — el hueco vacío deja de ser un cartel y pasa a ser el
   punto de entrada. Los tres pasos en fila enseñan que el botón hace LOS TRES
   de una vez (D20), que es justo lo que el texto anterior no decía. */
.vacio-caja { padding: 38px 26px; text-align: center; }
.vacio-caja h3 { font-size: 17px; margin-bottom: 6px; }
.vacio-caja p { color: var(--muted); font-size: 12.5px; max-width: 430px; margin: 0 auto 16px; }
.vacio-caja .paso {
  display: inline-flex; align-items: center; gap: 7px; font-size: 11.5px;
  color: var(--muted); background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 99px; padding: 5px 13px; margin: 0 3px 14px;
  font-variant-numeric: tabular-nums;
}

/* Pie con las cifras derivadas y la declaración del orden. */
.coa-pie {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  flex-wrap: wrap; padding: 11px 16px; border-top: 1px solid var(--line);
  background: var(--surface-2); font-size: 11.5px; color: var(--muted);
}
.coa-pie-orden { font-style: italic; }

/* --- COA · controles de ESCRITURA (fase F3) --------------------------------
   Toda esta zona solo se muestra si el backend confirma `puede_escribir`; el
   CSS no decide nada de permisos, solo cómo se ve lo que se decidió mostrar. */
.coa-acciones { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; flex-wrap: wrap; }
.coa-acciones-nota { font-size: 11.5px; color: var(--muted); }
.coa-form { margin-bottom: 18px; }

/* Bloque del grupo nuevo ANIDADO dentro del alta de cuenta: se ve que es una
   parte de este envío, no un formulario aparte. */
.coa-anidado {
  margin-top: 12px; padding: 14px; border-radius: 10px;
  background: var(--blue-soft); border: 1px solid #BFDBFE;
}

/* Contexto heredado y fijo del alta de subcuenta. */
.coa-contexto {
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 9px;
  padding: 10px 13px; font-size: 12px; color: var(--muted); margin-bottom: 13px;
}

/* Vista previa del código compuesto ("así quedará"). */
.coa-preview { font-size: 12.5px; color: var(--ink); margin-top: 4px; }
.coa-preview b { font-variant-numeric: tabular-nums; }
.coa-preview-nota { color: var(--muted); font-size: 11.5px; }

/* ⭐ HALLAZGO 1 (F2) — la LISTA de subcuentas del alta.
   Cada fila enseña el número que le va a tocar a su izquierda, en azul y con
   cifras tabulares: es lo que convierte la lista en una previsualización del
   resultado en vez de en cuatro cajas de texto. El ✕ solo aparece cuando hay
   más de una — la primera no se puede quitar (D7: nunca menos de una). */
.sublista { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.subfila {
  display: flex; align-items: center; gap: 9px; padding: 7px 11px;
  border-bottom: 1px solid var(--line); background: var(--surface);
}
.subfila:last-child { border-bottom: 0; }
.sublista > div:last-child .subfila:last-child { border-bottom: 0; }
.subfila .seq {
  font-variant-numeric: tabular-nums; font-weight: 700; color: var(--blue);
  font-size: 12px; min-width: 62px;
}
.subfila input { flex: 1; }
.subquitar {
  border: 1px solid var(--line); background: var(--surface); border-radius: 7px;
  padding: 3px 8px; color: var(--muted); cursor: pointer; font-size: 12px;
  font-family: inherit;
}
.subquitar:hover { border-color: var(--red-line); color: var(--red); background: var(--red-soft); }
.subadd { margin-top: 9px; }

/* ⭐ HALLAZGO 3 (F2) — la confirmación de la TANDA, junto al panel.
   Deliberadamente MUDA comparada con el `.okbanner` de arriba: no lleva icono
   ni borde, porque no es una noticia que haya que ir a leer — es el acuse de
   que lo que acabas de ver aparecer en la tabla se guardó. El banner grande
   sigue existiendo para el final del trabajo. */
.ok-junto {
  margin: 0; padding: 9px 20px; background: var(--green-soft); color: var(--green);
  font-size: 11.5px; font-weight: 600; border-bottom: 1px solid var(--line);
  border-radius: 11px 11px 0 0;
}

/* --- COA · EDITAR EN LA PROPIA FILA ----------------------------------------
   El panel se traslada dentro de la tabla, bajo la fila que se edita, en vez de
   mandar al contador al formulario de arriba. En una lista de 60 subcuentas,
   editar la número 40 ya no arranca de donde estabas mirando.

   La fila que se está editando queda MARCADA (barra azul + fondo suave), para
   que se vea sin dudas a quién pertenece el formulario que hay debajo. */
/* ⭐⭐ EL DEFECTO VIVO DEL «EDITANDO», Y SU ARREGLO (F3).
   ══════════════════════════════════════════════════════════════════════════
   AQUÍ PONÍA:  .coa-fila.coa-editando > td { background: var(--blue-soft); }

   Y NO PINTABA NADA en las filas de GRUPO, porque cuatro líneas más arriba
   `.coa-n1 > td` ya tiene `background: var(--blue-soft)`: se pintaba el mismo
   color encima del mismo color. Pasaba en la app que corre, todos los días,
   cada vez que alguien elegía «grupo» en el alta o pulsaba ✎ sobre un grupo —
   el formulario se abría anclado bajo una fila que no se distinguía de las
   otras 200. No daba error, no rompía ningún test: simplemente no se veía.

   El arreglo NO es cambiarle el tono al fondo, porque el mismo choque volvería
   con cualquier fila que tenga fondo propio (la escalera de F4, la inactiva).
   Es SEPARAR LOS DOS CANALES, que es la regla y no el parche:

       EL FONDO dice lo que la fila ES          (nivel · permanente)
       EL CONTORNO dice lo que le está PASANDO  (foco · temporal)

   Así que «editando» conserva el fondo de SU nivel y se marca con un ANILLO
   azul. Funciona sobre los tres escalones y sobre la fila apagada, porque no
   compite con ninguno.

   ⚠️ El anillo va con `box-shadow: inset`, no con `border`: la tabla es
   `border-collapse: collapse`, donde un borde de celda se fusiona con el de la
   vecina y desplazaría el riel de la jerarquía. Un `inset` se dibuja DENTRO de
   la celda y no participa del colapso, así que el riel no se mueve.

   ⭐ VA CON LÍNEA PROPIA Y SOBREVIVE A LA ESCALERA: si algún día se revierte el
   color de F4, este arreglo se queda — el defecto es anterior a la escalera y
   no lo causó ella.
   ══════════════════════════════════════════════════════════════════════════ */
.coa-fila.coa-editando .coa-cod,
.coa-fila.coa-editando .coa-nom { color: var(--blue); }
.coa-fila.coa-editando > td {
  box-shadow: inset 0 1px 0 var(--blue), inset 0 -1px 0 var(--blue);
}
.coa-fila.coa-editando > td:first-child {
  box-shadow: inset 5px 0 0 var(--blue), inset 0 1px 0 var(--blue), inset 0 -1px 0 var(--blue);
}
.coa-fila.coa-editando > td:last-child {
  box-shadow: inset -1px 0 0 var(--blue), inset 0 1px 0 var(--blue), inset 0 -1px 0 var(--blue);
}

/* ⭐ F8 · el rechazo DENTRO del panel. Es el mismo `.errbanner` clonado, así
   que hereda color, icono y forma; lo único que cambia es que aquí va a
   sangre —sin margen ni esquinas— porque no es una tarjeta suelta en la
   página, es una banda dentro de la columna, pegada a su cabecera. */
.errbanner-panel { margin: 0; border-radius: 0; border-left: 0; border-right: 0; }

/* ⭐ F7 · LA FILA FANTASMA — la previsualización.
   Azul DISCONTINUO = todavía no existe. El punteado es la señal, no el color:
   el azul solo dice "esto es lo que estás escribiendo", y la línea rota dice
   "no está guardado". Una fila fantasma con borde continuo se confundiría con
   una fila real recién creada, que es exactamente el malentendido caro.

   Conserva el fondo de SU nivel (la escalera de F4 sigue mandando) y se marca
   con contorno, por la misma separación de canales que el "editando". */
.coa-fantasma > td {
  border-bottom: 1px dashed var(--blue);
  opacity: .92;
}
.coa-fantasma > td:first-child { box-shadow: inset 3px 0 0 var(--blue); }
.coa-fantasma .coa-cod, .coa-fantasma .coa-nom { color: var(--blue); font-style: italic; }
.coa-fantasma-tag {
  display: inline-block; margin-left: 8px; font-size: 9.5px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--blue);
  border: 1px dashed var(--blue); border-radius: 99px; padding: 1px 7px;
  font-style: normal;
}

/* Las pastillas Budget/BTL bajan a METADATO (F3), y solo dentro del árbol de
   cuentas: `.badge` es compartido con los cargos del panel de admin, donde el
   color sí es la información. Aquí no lo era — el módulo y el ATL/BTL son
   propiedades del grupo que se consultan de vez en cuando, no un estado que
   haya que vigilar, y en azul competían con el nombre, que es el dato. */
.coa-tbl .badge {
  background: var(--surface-2); border: 1px solid var(--line); color: var(--muted);
  font-weight: 600; letter-spacing: .02em; text-transform: none; font-size: 10.5px;
}
/* ⛔ `.coa-editor-fila` se RETIRÓ en F6: era el `<tr>` postizo en el que
   viajaba el panel cuando se anclaba dentro de la tabla. Desde F6 el panel vive
   en una columna propia y ya no entra en el `<tbody>`, así que esas dos reglas
   no tenían ningún elemento al que aplicarse. Se recuenta con:
       grep -c "coa-editor-fila" app/templates/accounts/gestionar.html   → 0
   Si algún día se vuelve al anclaje, están en el historial de este archivo. */

/* ══ F6 · LA COLUMNA DE ENTRADA ══════════════════════════════════════════════
   El formulario ocupa una columna propia de alto completo pegada al menú, y NO
   se mueve. El catálogo entero vive a su derecha y scrollea por detrás.

   NO es un modal —sin velo, sin trampa de foco, el catálogo se sigue usando al
   lado— y NO es un cajón que tape: el contenido se APARTA con el padding de
   `body.con-panel`. Tapar el catálogo con el formulario sería quedarse con lo
   peor de las dos formas: perder el sitio Y perder la vista.
   ══════════════════════════════════════════════════════════════════════════ */
:root { --w-panel-coa: 400px; }

.coa-form.acoplado {
  position: fixed; left: 230px; top: 0; bottom: 0;   /* 230px = ancho del menú */
  width: var(--w-panel-coa); z-index: 40; margin: 0;
  border: 0; border-right: 1px solid var(--line-strong); border-radius: 0;
  box-shadow: 10px 0 30px rgba(15, 23, 42, .10);
  display: flex; flex-direction: column; overflow: auto;
}
.coa-form.acoplado .blk { flex: none; }
/* El pie de acciones se queda pegado abajo: con el formulario largo, "Crear
   cuenta" no se va nunca al fondo del scroll de la columna. */
.coa-form.acoplado .actions {
  position: sticky; bottom: 0; margin-top: auto;
  background: var(--surface-2); border-radius: 0; box-shadow: 0 -1px 0 var(--line);
}

/* El contenido se aparta. Y suelta su corsé de ancho mientras la columna está
   puesta: con 400 px menos, mantenerlo dejaría el catálogo en una tira estrecha
   con aire a los lados, que es lo contrario de lo que se está pagando. */
.main { transition: padding-left .18s ease; }
body.con-panel .main { padding-left: var(--w-panel-coa); }
body.con-panel .wrap-coa { max-width: none; }

/* La cabecera de la columna: con qué fila trabaja, y el camino de vuelta. */
.panel-cabecera {
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 18px; background: var(--blue-soft);
  border-bottom: 1px solid var(--blue-line);
  font-size: 11.5px; color: var(--blue); font-weight: 600;
}
.panel-cabecera .ver-fila {
  border: 1px solid var(--blue); background: var(--surface); color: var(--blue);
  border-radius: 7px; padding: 3px 9px; font-size: 11px; font-weight: 700;
  cursor: pointer; margin-left: auto; font-family: inherit;
}
.panel-cabecera .ver-fila:hover { background: var(--blue); color: #fff; }
/* Ámbar, no rojo: que el filtro esconda la fila no es un error de nadie. */
.panel-oculta { color: var(--amber); }

/* Botones por fila: discretos, para que la tabla siga siendo una tabla. */
.coa-acc { text-align: right; white-space: nowrap; }
.coa-ico {
  border: 1px solid var(--line); background: var(--surface); border-radius: 7px;
  padding: 3px 7px; margin-left: 3px; cursor: pointer; font-family: inherit;
  font-size: 12px; line-height: 1.4; color: var(--muted);
}
.coa-ico:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-soft); }
.coa-ico-danger:hover { border-color: var(--red-line); color: var(--red); background: var(--red-soft); }

/* Separador entre lo que AÑADE (＋, ✎) y lo que QUITA DE EN MEDIO (apagar,
   borrar). Los cuatro iconos iban pegados y desactivar se pulsaba sin querer. */
.coa-sep {
  display: inline-block; width: 1px; height: 15px; vertical-align: middle;
  margin: 0 5px 0 9px; background: var(--line-strong);
}

/* Confirmación de la desactivación, EN LA PROPIA CELDA — no hay ventanas
   flotantes en esta app. Ámbar porque es una alerta suave y reversible: el rojo
   está reservado para los rechazos del árbitro contable, y usarlo aquí mentiría
   sobre la gravedad. Reactivar no pregunta: no le quita nada a nadie. */
.coa-confirma {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 4px 2px 9px; border-radius: 8px;
  background: var(--amber-soft); border: 1px solid var(--line-strong);
  color: var(--amber); font-size: 11.5px; font-weight: 700; white-space: nowrap;
}
.coa-confirma button {
  border: 1px solid var(--line-strong); background: var(--surface);
  border-radius: 6px; padding: 2px 9px; cursor: pointer;
  font-family: inherit; font-size: 11.5px; font-weight: 700; line-height: 1.5;
}
.coa-confirma .coa-si { color: var(--amber); border-color: var(--amber); }
.coa-confirma .coa-si:hover { background: var(--amber); color: var(--surface); }
.coa-confirma .coa-no { color: var(--muted); }
.coa-confirma .coa-no:hover { background: var(--surface-2); }

/* Botón de peligro: mismo acento rojo del ErrorBanner, sin colores nuevos. */
.btn-danger { background: var(--red); border-color: var(--red); color: #fff; }
.btn-danger:hover { background: var(--red); filter: brightness(.93); }

/* Aviso PREVIO al borrado: enumera lo que se irá. Cuenta lo servido; no predice
   ningún veredicto — el veredicto es del servidor. */
.coa-peligro { font-size: 12.5px; color: var(--ink); }
.coa-peligro p { margin: 0 0 8px; }
.coa-peligro-nota { color: var(--muted); font-size: 11.5px; }
.coa-lista {
  margin: 0 0 10px; padding: 9px 13px 9px 30px; border-radius: 9px;
  background: var(--red-soft); border: 1px solid var(--red-line);
  font-variant-numeric: tabular-nums;
}
.coa-lista li { margin: 2px 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   TABLERO DE PRESUPUESTO — la casilla editable (FE2)
   ═══════════════════════════════════════════════════════════════════════════
   Bloque AÑADIDO AL FINAL a propósito: es la superficie más pequeña posible en un
   archivo que comparten todas las pantallas.

   Cero tokens nuevos. Todo sale de los que ya existen (`--line-strong`, `--red*`,
   `--amber*`, `--green-soft`). El aviso ámbar se dibuja con una BARRA lateral en
   vez de un borde completo.

   ⚠️ Aquí decía «porque `--amber-line` no existe en esta paleta». Dejó de ser
   cierto en F0 del rediseño del COA (2026-07-28): el token ya existe, en el hex
   que la hoja usaba a mano (#FDE3C4). La BARRA lateral se conserva tal cual —
   este bloque no se rediseña aquí—, pero si algún día se le pone borde completo,
   ya hay token con el que hacerlo sin inventar color.
   ═══════════════════════════════════════════════════════════════════════════ */
.celda { position: relative; }
/* El campo del dinero: angosto, a la derecha y con cifras de ancho fijo, para que
   las columnas de miles se alineen entre filas. Hereda del `input` global. */
.budget-in {
  max-width: 170px; margin-left: auto; display: block;
  text-align: right; font-variant-numeric: tabular-nums;
  padding: 6px 10px; font-size: 12.5px;
}
/* ⭐ SIN CELDA vs CELDA EN CERO. Los dos llegan como "0.00" y significan lo
   contrario. Con permiso de escritura los separa EL CONTORNO: la caja dice "aquí
   se escribe", el punteado dice "todavía no se escribió", el 0 dice "se escribió
   cero". Sin campo no hay contorno — por eso en solo lectura se escribe con
   palabras, y esas dos formas son EL MISMO ESTADO: no las unifiques. */
.budget-in.vacia { border-style: dashed; }
.budget-in::placeholder { color: var(--line-strong); font-style: italic; }
.budget-in:disabled { opacity: .55; cursor: progress; }
.celda-vuelo { opacity: .7; }

/* El mensaje vive JUNTO A SU CASILLA, nunca en un banner de arriba: con 187 filas,
   un banner en la cabecera te arranca de donde estabas. */
.celda-msg {
  display: block; margin: 4px 0 2px; padding: 6px 9px; border-radius: 8px;
  font-size: 11.5px; text-align: left; max-width: 340px; margin-left: auto;
  white-space: normal;
}
.celda-msg.err { background: var(--red-soft); border: 1px solid var(--red-line); color: var(--red); }
.celda-msg.adv { background: var(--amber-soft); border-left: 3px solid var(--amber); color: var(--amber); }

/* La fila que falló SE QUEDA MARCADA hasta que alguien la atienda. No se desvanece
   al repintar: el estado vive en JavaScript, no en el HTML. */
.tbl tbody tr.fila-err > td { background-color: var(--red-soft); }
.tbl tbody tr.fila-err > td:first-child { box-shadow: inset 3px 0 0 var(--red); }

.pie-sin-guardar { color: var(--red); font-weight: 700; }

/* Éxito: un destello y nada más. Un banner por celda, con cuarenta celdas, es ruido. */
.guardada-flash { animation: budget-flash 1.1s ease; }
@keyframes budget-flash {
  0%   { background-color: var(--green-soft); }
  100% { background-color: transparent; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   ⭐⭐ `B-2` · EL FOCO SE VE EN LOS BOTONES DE LA TABLA
   ═══════════════════════════════════════════════════════════════════════════

   NO ES COSMÉTICO, y esa es la trampa de este hueco. Los botones de la fila
   salieron del recorrido de Tab (`tabindex="-1"`, decisión de `B-2`) y la ÚNICA
   ruta de vuelta a ellos son las flechas. Sin señal de foco, el atajo que el pie
   del tablero anuncia lleva a un sitio que el usuario no puede ver: **lo
   construido dependía de lo que faltaba**.

   Hasta hoy no existía en NINGUNA rama — ni Budget ni el COA lo escribieron:
       grep -c "focus-visible" app/static/css/estilo-b.css   → 0
   (los dos aciertos de `grep -rn "focus-visible" app/` eran los dos comentarios
   de `budget/tablero.html` que decían que faltaba).

   ── LAS CUATRO FAMILIAS, y por qué son cuatro ─────────────────────────────
   `.coa-chev` · `.coa-ico` (con su `.coa-ico-danger`) · `.coa-si` · `.coa-no`.
   Las dos últimas solo aparecen con una confirmación de borrado abierta — que
   es justo el momento en que el dedo está en el teclado. Contarlas como dos
   familias en vez de cuatro es el error que ya se cometió una vez.

   ── SIRVE A LAS DOS PANTALLAS, A PROPÓSITO ────────────────────────────────
   Las cuatro clases las emiten TANTO `budget/tablero.html` COMO
   `accounts/gestionar.html`. La regla no lleva ningún ancestro que la acote a
   una de las dos, y eso es la decisión: un `.budget-in ~ .coa-ico` que la
   escondiera en la otra pantalla dejaría la mitad del problema sin resolver y
   además parecería hecha. Por eso entra en el UAT de LAS DOS.

   ── POR QUÉ `:focus-visible` Y NO `:focus` ────────────────────────────────
   `:focus` pinta el anillo también al pulsar con el ratón, y estos botones se
   pulsan con el ratón todo el rato: la pantalla se llenaría de anillos que no
   informan de nada. `:focus-visible` lo deja para cuando el navegador cree que
   el usuario está navegando con el teclado, que es exactamente el caso que este
   arreglo existe para servir.

   ── EL ANILLO, Y NADA MÁS ─────────────────────────────────────────────────
   No se cambia el color del glifo: eso ya lo hace `:hover`, y hacer que foco y
   hover se vean igual borra la distinción justo donde hace falta. El anillo va
   en `var(--blue)` —el azul de la acción, el mismo del foco de los campos
   (`estilo-b.css:215`)— y CERO colores nuevos.

   ⛔ QUE EL ANILLO SE VEA es del UAT y no lo cierra ninguna prueba: aquí no hay
   navegador ni hay ojo. En concreto hay que mirarlo sobre los TRES fondos de la
   escalera y sobre la fila apagada rayada, y en las dos pantallas.
   ═══════════════════════════════════════════════════════════════════════════ */
.coa-chev:focus-visible,
.coa-ico:focus-visible,
.coa-si:focus-visible,
.coa-no:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
}

/* ── El subtotal de rama SALTA sobre las hojas ──────────────────────────────
   El mockup (`disenos/logger-budget-tablero-2026-07-28.html:238`) pide peso
   **700**; `.tbl .money` da 600, que se lee bien pero no destaca sobre las
   filas de abajo — y el subtotal es la única cifra de la pantalla que resume.
   El `padding: 0 10px` es lateral y solo lateral: el vertical subía la fila de
   40 a 42 px, medido en el mockup, y el árbol volvía a latir.
   Va en un `<span>` DENTRO del `<td class="money">`, no en el `td`: la clase
   `money` sostiene la alineación de la columna y hay pruebas que la buscan
   literal. ⛔ Que se VEA el salto es del UAT. */
.subtotal {
  display: block; text-align: right; font-variant-numeric: tabular-nums;
  padding: 0 10px; font-weight: 700;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA CAPA VISUAL PROPIA DEL TABLERO DE PRESUPUESTO
   ═══════════════════════════════════════════════════════════════════════════

   El árbol —riel, escalera de fondos, jerarquía de la fila y el ancho de 1180—
   NO se construye aquí: **ya estaba**, y se comprobó antes de escribir nada en
   vez de darlo por supuesto. Cuelga de `.coa-n1/.coa-n2/.coa-n3`, que el tablero
   ya pinta, y ninguna de esas 13 reglas exige `.coa-tbl` de ancestro. Lo que
   falta es lo PROPIO de Budget: la caja del departamento, el aviso de solo
   lectura, y las dos puertas.

   ⛔ AQUÍ NO ENTRA LA CABECERA PEGAJOSA, y no es un olvido. Sus tres causas
   —`coa-wrap` en el envoltorio, medir `--h-trabajo` y una capa 2 pegajosa— siguen
   SIN copiarse a esta pantalla. El trinquete
   `tests/test_trinquete_coa_tbl_en_el_tablero.py` está puesto a propósito, sigue
   armado, y su hermano `test_el_tablero_NO_copio_la_costura_de_lo_pegajoso`
   vigila las otras dos causas.

   ⚠️ 2026-07-29, AL FUSIONAR: **la RAZÓN que este bloque daba ya no vale, y la
   decisión sí.** Decía *«F5 es una de las fases que todavía no ha pasado por el
   UAT. Copiarla antes duplicaría el error si lo hay»*. Las dos mitades cayeron:
   la costura del COA pasó por el UAT ese día, y **el error que se temía existía
   de verdad** —la cabecera dejaba de pegarse y TAPABA UNA FILA del plan—, se
   arregló en `coa/sticky` (`b4103fe`) y Stiven lo miró en pantalla. Así que ya no
   se está esperando a nada. Lo que queda en pie es más simple: esta pantalla no
   la necesita hoy, coserla es un encargo con su acta, y **cada causa por
   separado la deja igual de rota y con el mismo aspecto de estar puesta** — que
   es el motivo real por el que los dos guardianes siguen armados.

   Cero colores nuevos y cero tokens nuevos: todo sale de la paleta clínica que
   ya existe.
   ═══════════════════════════════════════════════════════════════════════════ */

/* La caja del departamento. NO es adorno: el presupuesto se asigna POR
   departamento, y la celda es el cruce (producción · rubro · departamento).
   Enseñar los montos de UNO haciéndolos pasar por los de la producción entera
   sería el peor error posible en esta pantalla, así que de qué departamento son
   las cifras tiene que leerse antes que las cifras. Por eso va en azul y en caja,
   y no como un rótulo gris más de la barra de filtros. */
.depto {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  background: var(--blue-soft); border: 1px solid var(--blue-line);
  border-radius: 9px; padding: 5px 10px;
}
/* ⚠️ ESTA REGLA GANA POR ORDEN, NO POR PESO, y hay que saberlo antes de mover
   nada. `.depto .lab` y `.view-toggle .lab` (línea 286) tienen la MISMA
   especificidad (0,2,0): quien gane depende de cuál se lea después, y esta se lee
   después porque este bloque está al final de la hoja. Subir este bloque de sitio
   devolvería el rótulo a gris de 11,5 px sin que nadie tocara una declaración.
   Lo vigila `test_la_caja_del_departamento_GANA_a_la_barra_de_filtros`, que
   compara las dos posiciones en el archivo — no basta con leer las dos reglas. */
.depto .lab {
  font-size: 10px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--blue); font-weight: 700; margin-right: 0;
}
.depto select {
  width: auto; border: 1px solid var(--blue-line); background: var(--surface);
  border-radius: 7px; padding: 4px 8px; font-size: 12.5px; color: var(--ink);
  font-weight: 600;
}

/* El aviso de solo lectura, en azul. Es información, no un rechazo: el rojo está
   reservado al árbitro contable y usarlo aquí mentiría sobre la gravedad.
   Reutiliza la forma del `.errbanner` (mismo `display:flex`, mismo `.et`/`.em`)
   con la familia del azul.
   ⚠️ HOY NO LLEVA TÍTULO (`.et`), y es deliberado: el mockup dibuja dos motivos
   distintos —rol y producción archivada— y el endpoint todavía no sirve
   `motivo_no_escribe` (encargo `E1`). Inventar aquí un título sería redactar un
   motivo que el backend no ha dicho. Cuando `E1` llegue, el título tiene su
   hueco ya hecho. */
.infobanner {
  display: flex; align-items: flex-start; gap: 10px;
  background: var(--blue-soft); border: 1px solid var(--blue-line);
  border-radius: 9px; padding: 11px 14px; margin-bottom: 16px;
  font-size: 12.5px; color: var(--ink);
}
.infobanner.hide { display: none; }
.infobanner .et { font-weight: 700; color: var(--blue); }
.infobanner .em { color: var(--ink); margin-top: 2px; }

/* Las dos puertas: el 400 que pide elegir departamento y el 403 que dice que ese
   departamento no es el tuyo. Van centradas y con aire, porque son la pantalla
   ENTERA en ese momento — no un aviso dentro de otra cosa. Sustituyen a cuatro
   `style="…"` en línea, que hacían el mismo trabajo escondidos donde ningún
   guardián de la paleta los ve. */
.puerta { padding: 40px 26px; text-align: center; }
.puerta h3 { font-size: 17px; margin-bottom: 8px; }
.puerta p { color: var(--muted); font-size: 12.5px; max-width: 520px; margin: 0 auto 16px; }
.puerta .lista {
  display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin-bottom: 16px;
}

/* La nota del rubro apagado. Va en ámbar y en negrita porque dice algo que hay
   que creerse: **su Budget sigue contando**. En gris de 11 px se lee como un
   metadato más y el contador la salta — que es justo el malentendido caro.
   ⚠️ Lo que esta nota NO dice es QUÉ nivel lo apagó: el endpoint sirve
   `activo_efectivo` (el resultado), no su origen. Igualar el color es de
   frontend; igualar el TEXTO del mockup («apagado por su propio interruptor»)
   necesita el backend (`D-3`) y no se inventa aquí. */
.apagada-nota {
  display: block; font-size: 10.5px; color: var(--amber); font-weight: 700;
}
