/* ==========================================================================
   CooperApp · Estilo C «Bento» — COMPONENTES
   --------------------------------------------------------------------------
   Vocabulario común de toda la aplicación. Depende de tokens.css y base.css.

   Regla de oro: si un estilo sirve para más de una pantalla, va aquí. Si solo
   sirve para una, va en app/static/css/pages/<pantalla>.css.

   Los nombres de clase heredados de la hoja anterior (.btn-primary,
   .form-group, .modal-overlay, .estado-badge…) se conservan y se reestilan
   aquí mismo: así ninguna plantilla se queda sin estilo durante la migración.
   ========================================================================== */

/* ==========================================================================
   1. REJILLA BENTO
   ========================================================================== */
.bento{display:grid;grid-template-columns:repeat(12,1fr);gap:var(--hueco)}

/* Celda: la unidad de composición de todas las pantallas. */
.c{
  background:var(--sup);
  border:1px solid var(--borde);
  border-radius:var(--r);
  padding:var(--esp-4) var(--esp-5);
  box-shadow:var(--sombra);
  position:relative;
  overflow:hidden;
  transition:border-color var(--micro);
  min-width:0;
}
.c:hover{border-color:var(--borde-2)}
.c--plana{box-shadow:none}
.c--sin-relleno{padding:0}
.c--anidada{background:var(--sup-2);box-shadow:none}
/* Reparte el contenido en vertical y empuja el último bloque al pie. Útil
   cuando la celda es más alta que su contenido porque otra de la misma fila
   manda en la altura. */
.c--repartida{display:flex;flex-direction:column}
.c--repartida > *:last-child{margin-top:auto}

/* Celda destacada: la única con degradado. Reservada al dato principal de la
   pantalla; más de una por pantalla y deja de destacar. */
.c-hero{
  background:linear-gradient(150deg,var(--sup) 0%,var(--sup-2) 100%);
}
.c-hero::after{
  content:"";position:absolute;right:-70px;top:-70px;width:230px;height:230px;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,var(--acento-suave),transparent 68%);
}
.c-hero > *{position:relative}

.c-cab{display:flex;align-items:center;gap:var(--esp-3);margin-bottom:var(--esp-4)}
.c-cab h2,.c-cab h3{font-size:var(--t-s);font-weight:var(--peso-fuerte);letter-spacing:-.01em}
/* Cuando la cabecera de la celda lleva un botón en vez de un enlace. */
.c-cab > .btn{margin-left:auto}
.c-cab .mas{
  margin-left:auto;color:var(--texto-3);font-size:var(--t-s);
  display:inline-flex;align-items:center;gap:5px;white-space:nowrap;
}
.c-cab .mas:hover{color:var(--acento)}
.c-pie{margin-top:var(--esp-4);padding-top:var(--esp-3);border-top:1px solid var(--borde);
  display:flex;align-items:center;gap:var(--esp-3);font-size:var(--t-s);color:var(--texto-3)}

/* Anchos. En pantallas medianas todo baja a 6 y en móvil a 12. */
.g1{grid-column:span 1}   .g2{grid-column:span 2}   .g3{grid-column:span 3}
.g4{grid-column:span 4}   .g5{grid-column:span 5}   .g6{grid-column:span 6}
.g7{grid-column:span 7}   .g8{grid-column:span 8}   .g9{grid-column:span 9}
.g10{grid-column:span 10} .g11{grid-column:span 11} .g12{grid-column:span 12}

@media (max-width:1200px){
  .g1,.g2,.g3,.g4,.g5,.g6,.g7,.g8{grid-column:span 6}
  .g9,.g10,.g11{grid-column:span 12}
}
@media (max-width:780px){
  .bento{gap:var(--esp-3)}
  .g1,.g2,.g3,.g4,.g5,.g6,.g7,.g8,.g9,.g10,.g11,.g12{grid-column:span 12}
  .c{padding:var(--esp-4)}
}

/* Alias de la hoja anterior */
.detail-card,.form-card,.tarjeta{
  background:var(--sup);border:1px solid var(--borde);border-radius:var(--r);
  box-shadow:var(--sombra);padding:var(--esp-5);
}

/* ==========================================================================
   2. BOTONES
   ========================================================================== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:9px 16px;border-radius:var(--r-s);
  font-size:var(--t-s);font-weight:var(--peso-medio);line-height:1.2;
  border:1px solid var(--borde);background:var(--sup);color:var(--texto-2);
  transition:background var(--micro),border-color var(--micro),color var(--micro),
             box-shadow var(--micro);
  white-space:nowrap;text-align:center;
}
.btn:hover{border-color:var(--borde-2);color:var(--texto);background:var(--sup-2)}
.btn:active{transform:translateY(.5px)}

.btn-primary{
  background:linear-gradient(140deg,var(--acento),var(--acento-2));
  border-color:transparent;color:var(--acento-solido-txt);
  box-shadow:var(--sombra-btn);font-weight:var(--peso-fuerte);
}
.btn-primary:hover{filter:brightness(1.06);color:var(--acento-solido-txt);
  border-color:transparent;background:linear-gradient(140deg,var(--acento),var(--acento-2))}

.btn-secondary{background:var(--sup);border-color:var(--borde);color:var(--texto-2)}
.btn-secondary:hover{background:var(--sup-2);border-color:var(--borde-2);color:var(--texto)}

.btn-danger{background:var(--mal-bg);border-color:var(--mal-borde);color:var(--mal)}
.btn-danger:hover{background:var(--mal-bg);border-color:var(--mal);color:var(--mal)}

.btn-success{background:var(--ok-bg);border-color:var(--ok-borde);color:var(--ok)}
.btn-success:hover{background:var(--ok-bg);border-color:var(--ok);color:var(--ok)}

.btn-warning{background:var(--avisa-bg);border-color:var(--avisa-borde);color:var(--avisa)}
.btn-warning:hover{background:var(--avisa-bg);border-color:var(--avisa);color:var(--avisa)}

.btn-sm{padding:6px 11px;font-size:var(--t-xs);border-radius:var(--r-xs);gap:5px}
.btn-lg{padding:12px 22px;font-size:var(--t-m)}
.btn-bloque{width:100%}

/* Botón de icono: 34px de lado para cumplir el mínimo táctil junto al padding
   de la celda de tabla, que añade otros 10px por arriba y por abajo. */
.btn-icon,.icb{
  width:34px;height:34px;padding:0;border-radius:var(--r-s);flex:none;
  display:inline-grid;place-items:center;position:relative;
  background:var(--sup);border:1px solid var(--borde);color:var(--texto-2);
}
.btn-icon:hover,.icb:hover{background:var(--sup-2);border-color:var(--borde-2);color:var(--texto)}
.btn-icon.btn-danger:hover{background:var(--mal-bg);border-color:var(--mal);color:var(--mal)}
.btn-icon.btn-success:hover{background:var(--ok-bg);border-color:var(--ok);color:var(--ok)}
.btn-icon.btn-sm,.icb.btn-sm{width:28px;height:28px}

.btn:disabled,.btn.btn-disabled,.btn-icon.btn-disabled,.btn[aria-disabled="true"]{
  opacity:.5;cursor:not-allowed;filter:grayscale(.35);box-shadow:none;
}
.btn:disabled:hover{background:var(--sup);border-color:var(--borde);color:var(--texto-2)}

/* Punto de aviso sobre un botón de icono */
.icb .punto{
  position:absolute;top:7px;right:8px;width:6px;height:6px;border-radius:50%;
  background:var(--acento);box-shadow:0 0 0 2px var(--sup);
}

/* Grupo de acciones dentro de una fila de tabla. No envuelve: la columna de
   acciones se declara con .col-actions, que no encoge. */
.actions-cell,.acciones-fila{display:flex;gap:var(--esp-1);justify-content:flex-end;
  align-items:center;flex-wrap:nowrap}

/* ==========================================================================
   3. ETIQUETAS DE ESTADO
   El color nunca va solo: la etiqueta siempre lleva texto.
   ========================================================================== */
.eti,.estado-badge,.tipo-badge,.badge,.doc-badge{
  display:inline-flex;align-items:center;gap:5px;
  font-size:var(--t-xs);font-weight:var(--peso-fuerte);line-height:1.4;
  padding:3px 9px;border-radius:var(--r-pill);white-space:nowrap;
  background:var(--neutro-bg);color:var(--neutro);
  border:1px solid transparent;
}
.eti::before,.estado-badge::before,.tipo-badge::before{
  content:"";width:5px;height:5px;border-radius:50%;background:currentColor;flex:none;
}
.eti--sin-punto::before,.badge::before,.doc-badge::before{content:none}

.eti--ok,.estado-ejecucion{background:var(--ok-bg);color:var(--ok)}
.eti--avisa,.estado-justificacion{background:var(--avisa-bg);color:var(--avisa)}
.eti--mal{background:var(--mal-bg);color:var(--mal)}
.eti--info,.estado-aprobado{background:var(--info-bg);color:var(--info)}
.eti--lila,.estado-formulacion{background:var(--lila-bg);color:var(--lila)}
.eti--neutro,.estado-cerrado{background:var(--neutro-bg);color:var(--neutro)}
.eti--acento{background:var(--acento-suave);color:var(--acento)}

/* Estado del proyecto por el valor del enum */
.eti--formulacion{background:var(--est-formulacion-bg);color:var(--est-formulacion)}
.eti--aprobado{background:var(--est-aprobado-bg);color:var(--est-aprobado)}
.eti--ejecucion{background:var(--est-ejecucion-bg);color:var(--est-ejecucion)}
.eti--justificacion{background:var(--est-justificacion-bg);color:var(--est-justificacion)}
.eti--cerrado{background:var(--est-cerrado-bg);color:var(--est-cerrado)}
.eti--desarrollo,.tipo-desarrollo{background:var(--tipo-desarrollo-bg);color:var(--tipo-desarrollo)}
.eti--accion_humanitaria,.tipo-accion_humanitaria{
  background:var(--tipo-accion_humanitaria-bg);color:var(--tipo-accion_humanitaria)}

/* Insignia de documento: una sola letra o icono en un cuadrado. La usan gastos
   y transferencias para decir si el justificante está adjunto, falta o no
   procede. El texto lo pone el `title`/`aria-label` del botón. */
.doc-badge{width:28px;height:28px;padding:0;justify-content:center;
  border-radius:var(--r-xs);font-family:var(--mono);font-weight:var(--peso-fuerte)}
.doc-attached{background:var(--ok-bg);color:var(--ok)}
.doc-attached:hover{border-color:var(--ok-borde)}
.doc-missing{background:var(--avisa-bg);color:var(--avisa);cursor:pointer}
.doc-missing:hover{border-color:var(--avisa-borde)}
.doc-disabled{background:var(--sup-3);color:var(--texto-3);cursor:not-allowed}
.doc-buttons{display:flex;gap:var(--esp-1);justify-content:center}

/* Fuentes de financiación: el parcial `funding_sources_section.html` se incluye
   desde el formulario de proyecto y desde la pestaña de presupuesto, así que su
   estilo vive aquí y no duplicado en las dos hojas. */
.funding-sources-section{
  margin-bottom:var(--esp-4);padding:var(--esp-4);
  background:var(--sup-2);border:1px solid var(--borde);border-radius:var(--r-s);
}
.funding-sources-section .section-header{margin-bottom:var(--esp-3)}
.funding-sources-section .section-header h4{
  font-family:var(--mono);font-size:var(--t-eti);letter-spacing:var(--track-eti);
  text-transform:uppercase;font-weight:var(--peso-fuerte);color:var(--texto-3);
}
.funding-sources-list{display:flex;flex-wrap:wrap;gap:var(--esp-2);margin-bottom:var(--esp-3)}
.funding-source-item{
  display:inline-flex;align-items:center;gap:var(--esp-2);
  padding:5px var(--esp-2) 5px var(--esp-3);background:var(--sup);
  border:1px solid var(--borde);border-radius:var(--r-pill);font-size:var(--t-s);
}
.funding-source-item .source-name{font-weight:var(--peso-medio)}
.funding-source-add-form .form-inline{display:flex;gap:var(--esp-2);flex-wrap:wrap;
  align-items:center}
.funding-source-add-form .form-input{flex:1;min-width:180px}
.funding-source-add-form .form-select{min-width:150px}

/* Marca monoespaciada pequeña: recuentos, desfases, avisos numéricos. */
.tag{
  display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);
  font-size:10.5px;letter-spacing:.03em;padding:2px 7px;border-radius:var(--r-xs);
  background:var(--neutro-bg);color:var(--neutro);white-space:nowrap;
}
.tag--ok{background:var(--ok-bg);color:var(--ok)}
.tag--avisa{background:var(--avisa-bg);color:var(--avisa)}
.tag--mal{background:var(--mal-bg);color:var(--mal)}
.tag--info{background:var(--info-bg);color:var(--info)}

/* ==========================================================================
   4. CHIPS Y BARRA DE FILTROS
   ========================================================================== */
.filtros,.filters-bar{
  display:flex;align-items:center;gap:var(--esp-2);flex-wrap:wrap;
  margin-bottom:var(--esp-4);
}
.filtros .separa{margin-left:auto}

.chip{
  display:inline-flex;align-items:center;gap:6px;
  background:var(--sup);border:1px solid var(--borde);border-radius:var(--r-pill);
  padding:6px 12px;font-size:var(--t-s);color:var(--texto-2);
  transition:border-color var(--micro),background var(--micro),color var(--micro);
}
.chip:hover{border-color:var(--borde-2);color:var(--texto)}
.chip--puesto{background:var(--acento-suave);border-color:var(--acento-borde);
  color:var(--acento);font-weight:var(--peso-medio)}
.chip .x{opacity:.7;font-size:var(--t-base);line-height:1}

/* Buscador */
.buscador,.search-box{position:relative;flex:1;min-width:200px;max-width:420px;
  display:flex;align-items:center}
.buscador input,.search-box input{
  width:100%;padding:9px 34px 9px 34px;border-radius:var(--r-s);
  background:var(--sup);border:1px solid var(--borde);color:var(--texto);
  font-size:var(--t-s);transition:border-color var(--micro),box-shadow var(--micro);
}
.buscador input::placeholder,.search-box input::placeholder{color:var(--texto-3)}
.buscador input:hover,.search-box input:hover{border-color:var(--borde-2)}
.buscador input:focus,.search-box input:focus{
  outline:none;border-color:var(--acento);box-shadow:0 0 0 3px var(--acento-suave);
}
.buscador .lupa,.search-box .lupa{
  position:absolute;left:11px;color:var(--texto-3);pointer-events:none;display:flex;
}
.buscador .spinner-en-linea,.search-box .spinner-en-linea{position:absolute;right:11px}

/* Grupo de desplegables de filtro */
.filter-group{display:flex;gap:var(--esp-2);flex-wrap:wrap;flex:1 1 auto;min-width:0}
/* `width:auto` es necesario: la regla genérica de formulario pone los `select`
   al 100 %, y aquí van en fila, no apilados. */
.filter-group select,.filter-select{
  width:auto;min-width:150px;flex:0 1 auto;
  padding:9px 32px 9px 12px;border-radius:var(--r-s);
  background:var(--sup);border:1px solid var(--borde);color:var(--texto);
  font-size:var(--t-s);cursor:pointer;appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),
                   linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 16px) center,calc(100% - 11px) center;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat;
}
.filter-group select:hover,.filter-select:hover{border-color:var(--borde-2)}
.filter-group select:focus,.filter-select:focus{
  outline:none;border-color:var(--acento);box-shadow:0 0 0 3px var(--acento-suave);
}

/* Vistas guardadas */
.vistas{display:flex;gap:2px;background:var(--sup);border:1px solid var(--borde);
  border-radius:var(--r-s);padding:3px;overflow-x:auto;scrollbar-width:none}
.vistas::-webkit-scrollbar{display:none}
.vista{padding:6px 12px;border-radius:var(--r-xs);font-size:var(--t-s);
  color:var(--texto-2);white-space:nowrap}
.vista:hover{background:var(--sup-2);color:var(--texto)}
.vista.act,.vista[aria-pressed="true"]{background:var(--acento-suave);color:var(--acento);
  font-weight:var(--peso-fuerte)}
.vista .n{font-family:var(--mono);font-size:var(--t-xs);opacity:.7;margin-left:4px}

/* ==========================================================================
   5. TABLAS
   ========================================================================== */
.tabla-caja,.table-container{
  background:var(--sup);border:1px solid var(--borde);border-radius:var(--r);
  box-shadow:var(--sombra);overflow:hidden;
}
/* Toda tabla ancha vive dentro de un contenedor con desplazamiento propio:
   sin esto las columnas de la derecha quedan físicamente inalcanzables. */
.table-scroll,.tabla-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}

.tabla,.projects-table,.data-table{width:100%;border-collapse:collapse}
.tabla thead th,.projects-table thead th,.data-table thead th{
  font-family:var(--mono);font-size:var(--t-eti);letter-spacing:var(--track-eti);
  text-transform:uppercase;font-weight:var(--peso-medio);color:var(--texto-3);
  text-align:left;padding:10px var(--esp-4);background:var(--sup-2);
  border-bottom:1px solid var(--borde);white-space:nowrap;position:sticky;top:0;z-index:1;
}
.tabla thead th.num,.projects-table thead th.num,
.tabla thead th.col-amount,.projects-table thead th.col-amount{text-align:right}
.tabla tbody td,.projects-table tbody td,.data-table tbody td{
  padding:11px var(--esp-4);border-bottom:1px solid var(--borde);vertical-align:middle;
}
.tabla tbody tr:last-child td,.projects-table tbody tr:last-child td,
.data-table tbody tr:last-child td{border-bottom:none}
.tabla tbody tr,.projects-table tbody tr,.data-table tbody tr{transition:background var(--micro)}
.tabla tbody tr:hover,.projects-table tbody tr:hover,.data-table tbody tr:hover{
  background:var(--sup-2);
}
.tabla tfoot td,.projects-table tfoot td{
  padding:11px var(--esp-4);border-top:1px solid var(--borde-2);
  background:var(--sup-2);font-weight:var(--peso-fuerte);
}

/* Celdas tipadas */
.col-amount,.amount-cell,.imp-celda{text-align:right;font-family:var(--mono);
  font-variant-numeric:tabular-nums;white-space:nowrap;font-weight:var(--peso-medio)}
.col-code,.code-cell{font-family:var(--mono);font-size:var(--t-s);white-space:nowrap}
.col-date,.dates-cell{font-size:var(--t-s);color:var(--texto-2);white-space:nowrap}
.col-actions,.col-action-sm{width:1%;white-space:nowrap}
.col-estado{width:1%;white-space:nowrap}
.col-documents{width:1%;white-space:nowrap;text-align:center}
.celda-titulo,.card-title{font-weight:var(--peso-medio);min-width:0}
.celda-titulo a,.project-link{color:var(--texto);font-weight:var(--peso-medio)}
.celda-titulo a:hover,.project-link:hover{color:var(--acento)}
.celda-sub{font-size:var(--t-s);color:var(--texto-3);margin-top:2px}

/* Tarjeta en móvil: la tabla se reordena en fichas apiladas y cada celda
   recupera su cabecera desde data-label. Requiere data-label en cada <td>. */
@media (max-width:780px){
  .table-cards thead{position:absolute;width:1px;height:1px;overflow:hidden;
    clip:rect(0,0,0,0);white-space:nowrap}
  .table-cards tbody tr{
    display:block;background:var(--sup-2);border:1px solid var(--borde);
    border-radius:var(--r-s);margin:var(--esp-3);padding:var(--esp-2) var(--esp-3);
  }
  .table-cards tbody td{
    display:flex;gap:var(--esp-3);align-items:center;justify-content:space-between;
    padding:7px 0;border-bottom:1px solid var(--borde);text-align:right;
  }
  .table-cards tbody tr td:last-child{border-bottom:none}
  .table-cards tbody td::before{
    content:attr(data-label);font-family:var(--mono);font-size:var(--t-eti);
    letter-spacing:var(--track-eti);text-transform:uppercase;color:var(--texto-3);
    text-align:left;flex:none;
  }
  .table-cards tbody td[data-label=""]::before,
  .table-cards tbody td:not([data-label])::before{content:none}
  .table-cards .col-actions,.table-cards .actions-cell{justify-content:flex-end}
}

/* ==========================================================================
   6. LISTAS DE FILA (avisos, vencimientos, movimientos)
   ========================================================================== */
.fila{display:flex;align-items:center;gap:var(--esp-3);padding:10px 0;
  border-bottom:1px solid var(--borde)}
.fila:last-child{border-bottom:none}
.fila-ic{
  width:30px;height:30px;border-radius:9px;flex:none;display:grid;place-items:center;
  background:var(--neutro-bg);color:var(--neutro);
}
.fila-ic--ok{background:var(--ok-bg);color:var(--ok)}
.fila-ic--avisa{background:var(--avisa-bg);color:var(--avisa)}
.fila-ic--mal{background:var(--mal-bg);color:var(--mal)}
.fila-ic--info{background:var(--info-bg);color:var(--info)}
.fila-ic--lila{background:var(--lila-bg);color:var(--lila)}
.fila-txt{min-width:0;flex:1}
.fila-txt b{display:block;font-size:var(--t-s);font-weight:var(--peso-medio)}
.fila-txt small{display:block;font-size:var(--t-s);color:var(--texto-3)}
.fila .der{margin-left:auto;text-align:right;flex:none}

/* ==========================================================================
   7. INDICADORES Y GRÁFICOS
   ========================================================================== */

/* Cifra grande */
.grande{font-family:var(--mono);font-size:var(--t-3xl);font-weight:var(--peso-fuerte);
  letter-spacing:-.035em;line-height:1.05;font-variant-numeric:tabular-nums}
.grande small{font-size:var(--t-m);font-weight:var(--peso-normal);color:var(--texto-3);
  letter-spacing:0}

/* Indicador con barra */
.kpi{display:flex;flex-direction:column;gap:6px}
.kpi .v{font-family:var(--mono);font-size:var(--t-xl);font-weight:var(--peso-fuerte);
  letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.kpi .e{font-family:var(--mono);font-size:var(--t-eti);letter-spacing:var(--track-eti);
  text-transform:uppercase;color:var(--texto-3)}

/* Cinta de indicadores: una tarjeta dividida, no cuatro cajas sueltas. */
.kpis,.stats-grid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  background:var(--sup);border:1px solid var(--borde);border-radius:var(--r);
  box-shadow:var(--sombra);margin-bottom:var(--esp-4);overflow:hidden;
}
.kpis > *,.stats-card{padding:var(--esp-4) var(--esp-5);border-right:1px solid var(--borde);
  display:flex;flex-direction:column;gap:5px;background:none}
.kpis > *:last-child,.stats-card:last-child{border-right:none}
.stats-value,.stats-card .stats-value{font-family:var(--mono);font-size:var(--t-xl);
  font-weight:var(--peso-fuerte);letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.stats-label,.stats-card .stats-label{font-family:var(--mono);font-size:var(--t-eti);
  letter-spacing:var(--track-eti);text-transform:uppercase;color:var(--texto-3)}
.stats-content{display:flex;flex-direction:column;gap:3px;min-width:0}
.stats-icon{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  background:var(--acento-suave);color:var(--acento);margin-bottom:2px;flex:none}
.icon-primary{background:var(--acento-suave);color:var(--acento)}
.icon-success{background:var(--ok-bg);color:var(--ok)}
.icon-warning{background:var(--avisa-bg);color:var(--avisa)}
.icon-info{background:var(--info-bg);color:var(--info)}
@media (max-width:780px){
  .kpis > *,.stats-card{border-right:none;border-bottom:1px solid var(--borde)}
  .kpis > *:last-child,.stats-card:last-child{border-bottom:none}
}

/* Barra de progreso fina */
.mini{display:block;height:5px;border-radius:var(--r-pill);background:var(--pista);
  position:relative;overflow:hidden}
.mini i{position:absolute;inset:0 auto 0 0;border-radius:var(--r-pill);
  background:var(--acento);display:block}
.mini i.ok{background:var(--ok)} .mini i.avisa{background:var(--avisa)}
.mini i.mal{background:var(--mal)} .mini i.info{background:var(--info)}
.mini i.neutro{background:var(--texto-3)}

/* Medidor de ejecución contra plazo: la barra dice cuánto se ha gastado y la
   marca vertical, cuánto plazo se ha consumido. Sin la marca, el porcentaje
   de ejecución no dice si el proyecto va adelantado o atrasado. */
.medidor{min-width:160px}
.medidor .pista{position:relative;height:6px;background:var(--pista);
  border-radius:var(--r-pill)}
.medidor .relleno{height:100%;border-radius:var(--r-pill);background:var(--ok);display:block}
.medidor .relleno--retraso{background:var(--avisa)}
.medidor .relleno--exceso{background:var(--mal)}
.medidor .relleno--nulo{background:var(--borde-2)}
.medidor .marca{position:absolute;top:-3px;width:2px;height:12px;border-radius:1px;
  background:var(--texto);opacity:.75}
.medidor .txt{font-family:var(--mono);font-size:var(--t-xs);color:var(--texto-3);
  margin-top:5px;display:flex;align-items:center;gap:6px;white-space:nowrap}
.medidor .txt b{color:var(--texto);font-weight:var(--peso-fuerte)}

/* Barra apilada + leyenda */
.apilada{display:flex;height:12px;border-radius:var(--r-pill);overflow:hidden;gap:2px;
  margin:var(--esp-4) 0 var(--esp-3)}
.apilada i{display:block;height:100%}
.leyenda{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:var(--esp-2) var(--esp-5)}
.ley{display:flex;align-items:center;gap:var(--esp-2);font-size:var(--t-s);color:var(--texto-2)}
.ley .pt{width:8px;height:8px;border-radius:3px;flex:none}
.ley .v{margin-left:auto;font-family:var(--mono);font-size:var(--t-s);color:var(--texto);
  font-variant-numeric:tabular-nums}

/* Anillo de progreso (SVG con stroke-dasharray) */
.anillo{display:grid;place-items:center;position:relative;margin:var(--esp-1) auto var(--esp-3)}
.anillo svg{transform:rotate(-90deg)}
.anillo .pista-c{stroke:var(--pista)}
.anillo-t{position:absolute;text-align:center;pointer-events:none}
.anillo-t b{display:block;font-family:var(--mono);font-size:var(--t-2xl);
  font-weight:var(--peso-fuerte);letter-spacing:-.04em;font-variant-numeric:tabular-nums}
.anillo-t span{font-size:var(--t-xs);color:var(--texto-3)}

/* Curva de evolución */
.curva{margin:var(--esp-1) -4px 0}
.curva svg{width:100%;height:92px;display:block}
.curva--alta svg{height:158px}
.curva-pie{display:flex;justify-content:space-between;gap:var(--esp-3);margin-top:6px;
  font-family:var(--mono);font-size:var(--t-eti);letter-spacing:var(--track-eti);
  text-transform:uppercase;color:var(--texto-3)}

/* ==========================================================================
   8. TARJETAS DE PROYECTO
   ========================================================================== */
.proys{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));
  gap:var(--hueco)}
.py{
  background:var(--sup-2);border:1px solid var(--borde);border-radius:var(--r-s);
  padding:var(--esp-4);display:flex;gap:var(--esp-4);align-items:flex-start;
  transition:border-color var(--micro),transform var(--micro);color:var(--texto);
}
.py:hover{border-color:var(--acento);transform:translateY(-2px);color:var(--texto)}
.py-txt{min-width:0;flex:1}
.py-cod{font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;color:var(--texto-3);
  text-transform:uppercase}
.py-t{font-size:var(--t-s);font-weight:var(--peso-medio);margin:4px 0 var(--esp-2);
  line-height:1.35;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden}
.py-meta{display:flex;align-items:center;gap:var(--esp-2);flex-wrap:wrap}
.py-imp{font-family:var(--mono);font-size:var(--t-s);color:var(--texto-2);
  font-variant-numeric:tabular-nums}
.py-anillo{flex:none;position:relative;display:grid;place-items:center}
.py-anillo svg{transform:rotate(-90deg)}
.py-anillo b{position:absolute;font-family:var(--mono);font-size:var(--t-xs);
  font-weight:var(--peso-fuerte)}

/* ==========================================================================
   9. PESTAÑAS
   ========================================================================== */
.pest,.detail-tabs{
  display:flex;gap:2px;padding:var(--esp-2);background:var(--sup-2);
  border-top:1px solid var(--borde);border-bottom:1px solid var(--borde);
  overflow-x:auto;scrollbar-width:thin;
}
.pest button,.detail-tabs .tab-btn{
  padding:7px 13px;border-radius:var(--r-xs);font-size:var(--t-s);color:var(--texto-2);
  display:inline-flex;align-items:center;gap:7px;white-space:nowrap;
  transition:background var(--micro),color var(--micro);border:none;background:none;
}
.pest button:hover,.detail-tabs .tab-btn:hover{background:var(--sup);color:var(--texto)}
.pest button.act,.detail-tabs .tab-btn.active,
.pest button[aria-selected="true"],.detail-tabs .tab-btn[aria-selected="true"]{
  background:var(--sup);color:var(--acento);font-weight:var(--peso-fuerte);
  box-shadow:var(--sombra);
}
.tab-count,.pest .n{
  font-family:var(--mono);font-size:10.5px;background:var(--pista);color:var(--texto-3);
  border-radius:var(--r-pill);padding:1px 6px;line-height:1.5;
}
.tab-content{display:none}
.tab-content.active{display:block}

/* ==========================================================================
   10. FORMULARIOS
   ========================================================================== */
.form-card,.formulario{max-width:100%}
.form-section{margin-bottom:var(--esp-7)}
.form-section:last-child{margin-bottom:0}
.form-section-title,.form-section > legend{
  display:flex;align-items:center;gap:var(--esp-2);
  font-family:var(--mono);font-size:var(--t-eti);letter-spacing:var(--track-eti);
  text-transform:uppercase;font-weight:var(--peso-fuerte);color:var(--acento);
  padding-bottom:var(--esp-2);margin-bottom:var(--esp-4);
  border-bottom:1px solid var(--borde);width:100%;
}
fieldset{border:none;min-width:0}

.form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:var(--esp-4) var(--esp-5)}
.form-grid-3{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  gap:var(--esp-4) var(--esp-5)}
.form-group{display:flex;flex-direction:column;gap:6px;min-width:0}
.form-group--ancho{grid-column:1/-1}

.form-group label,.etiqueta-campo{
  font-size:var(--t-s);font-weight:var(--peso-medio);color:var(--texto-2);
}
.form-group label .obligatorio,.form-group label abbr{
  color:var(--mal);text-decoration:none;margin-left:2px;
}

.form-group input,.form-group select,.form-group textarea,
.form-control,.form-select,input[type="text"],input[type="number"],input[type="date"],
input[type="email"],input[type="password"],input[type="search"],input[type="tel"],
select,textarea{
  width:100%;padding:9px 12px;border-radius:var(--r-s);
  /* `background-color` y no el atajo `background`: el atajo borraría la
     flecha en `background-image` que el propio `select` se dibuja debajo. */
  background-color:var(--sup);border:1px solid var(--borde);color:var(--texto);
  font-size:var(--t-s);font-family:inherit;
  transition:border-color var(--micro),box-shadow var(--micro);
}
textarea{resize:vertical;min-height:88px;line-height:1.55}
select{cursor:pointer;appearance:none;padding-right:32px;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),
                   linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 16px) center,calc(100% - 11px) center;
  background-size:5px 5px,5px 5px;background-repeat:no-repeat}
input::placeholder,textarea::placeholder{color:var(--texto-3)}
input:hover,select:hover,textarea:hover{border-color:var(--borde-2)}
input:focus,select:focus,textarea:focus{
  outline:none;border-color:var(--acento);box-shadow:0 0 0 3px var(--acento-suave);
}
input:disabled,select:disabled,textarea:disabled,input[readonly]{
  background:var(--sup-3);color:var(--texto-3);cursor:not-allowed;
}
input[type="file"]{padding:8px;font-size:var(--t-s);cursor:pointer}
input[type="file"]::file-selector-button{
  margin-right:var(--esp-3);padding:6px 12px;border-radius:var(--r-xs);
  border:1px solid var(--borde);background:var(--sup-2);color:var(--texto-2);
  font-size:var(--t-xs);font-weight:var(--peso-medio);cursor:pointer;
}
input[type="file"]::file-selector-button:hover{border-color:var(--borde-2);color:var(--texto)}

/* Campo con error: borde, anillo y texto. Nunca solo el color. */
.form-group.error input,.form-group.error select,.form-group.error textarea,
input[aria-invalid="true"],select[aria-invalid="true"],textarea[aria-invalid="true"]{
  border-color:var(--mal);box-shadow:0 0 0 3px var(--mal-bg);
}
.error-campo,.field-error{display:flex;align-items:center;gap:6px;
  font-size:var(--t-s);color:var(--mal);font-weight:var(--peso-medio)}

.help-text,.form-hint,.campo-ayuda{font-size:var(--t-s);color:var(--texto-3);line-height:1.45}
.nota-obligatorios{font-size:var(--t-s);color:var(--texto-3);margin-bottom:var(--esp-5)}
.nota-obligatorios span[aria-hidden]{color:var(--mal);font-weight:var(--peso-fuerte)}

.checkbox-group{display:flex;flex-wrap:wrap;gap:var(--esp-2) var(--esp-5)}
.checkbox-group label,.check{display:inline-flex;align-items:center;gap:var(--esp-2);
  font-size:var(--t-s);color:var(--texto-2);cursor:pointer;font-weight:var(--peso-normal)}
input[type="checkbox"],input[type="radio"]{
  width:16px;height:16px;flex:none;accent-color:var(--acento);cursor:pointer;padding:0;
}

.form-actions{
  display:flex;gap:var(--esp-3);justify-content:flex-end;flex-wrap:wrap;
  margin-top:var(--esp-6);padding-top:var(--esp-4);border-top:1px solid var(--borde);
}
.form-actions--pegada{
  position:sticky;bottom:0;background:var(--sup);margin-inline:calc(var(--esp-5) * -1);
  padding:var(--esp-4) var(--esp-5);border-radius:0 0 var(--r) var(--r);
  box-shadow:0 -6px 20px rgba(0,0,0,.06);
}

/* Progreso de subida de fichero (lo rellena app.js) */
.upload-progreso{display:flex;align-items:center;gap:var(--esp-3);margin-top:var(--esp-2)}
.upload-progreso-barra{
  flex:1;height:6px;appearance:none;border:none;border-radius:var(--r-pill);
  background:var(--pista);overflow:hidden;
}
.upload-progreso-barra::-webkit-progress-bar{background:var(--pista);border-radius:var(--r-pill)}
.upload-progreso-barra::-webkit-progress-value{background:var(--acento);
  border-radius:var(--r-pill);transition:width var(--micro)}
.upload-progreso-barra::-moz-progress-bar{background:var(--acento);border-radius:var(--r-pill)}
.upload-progreso-texto{font-family:var(--mono);font-size:var(--t-xs);color:var(--texto-2);
  min-width:4ch;text-align:right}
.upload-limites{font-size:var(--t-s);color:var(--texto-3)}

/* ==========================================================================
   11. MODALES
   ========================================================================== */
.modal-overlay,.modal{
  position:fixed;inset:0;z-index:var(--z-modal);
  background:var(--velo);backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;padding:var(--esp-4);
  overflow-y:auto;
}
.modal-content{
  background:var(--sup);border:1px solid var(--borde);border-radius:var(--r);
  box-shadow:var(--sombra-alta);width:100%;max-width:620px;
  max-height:calc(100vh - 2 * var(--esp-4));display:flex;flex-direction:column;
  animation:entrar-modal .2s cubic-bezier(.2,.8,.3,1);
}
.modal-content--ancho{max-width:960px}
.modal-content--estrecho{max-width:440px}
@keyframes entrar-modal{from{opacity:0;transform:translateY(12px) scale(.98)}}

.modal-header{
  display:flex;align-items:center;gap:var(--esp-3);
  padding:var(--esp-4) var(--esp-5);border-bottom:1px solid var(--borde);flex:none;
}
.modal-header h2,.modal-header h3{font-size:var(--t-m);flex:1;min-width:0}
.modal-close,.btn-close{
  flex:none;width:32px;height:32px;border-radius:var(--r-xs);display:grid;place-items:center;
  color:var(--texto-3);font-size:var(--t-l);line-height:1;margin-left:auto;
}
.modal-close:hover,.btn-close:hover{background:var(--sup-2);color:var(--texto)}
.modal-body{padding:var(--esp-5);overflow-y:auto;flex:1;min-height:0}
.modal-footer,.modal-actions{
  display:flex;gap:var(--esp-3);justify-content:flex-end;flex-wrap:wrap;flex:none;
  padding:var(--esp-4) var(--esp-5);border-top:1px solid var(--borde);
}
/* Cuando el formulario ocupa todo el modal, el cuerpo lleva su propio relleno. */
.modal-content > form{display:flex;flex-direction:column;min-height:0;overflow:hidden}
.modal-content > form > .modal-body{flex:1}
.upload-info{padding:var(--esp-4) var(--esp-5);background:var(--sup-2);
  border-bottom:1px solid var(--borde);font-size:var(--t-s);color:var(--texto-2);
  display:flex;flex-direction:column;gap:4px}

/* Contenedor de modal cargado por htmx: el servidor manda un `<div>` vacío con
   esta clase y lo rellena con el parcial. Lo usan documentos, marco lógico y
   la edición de proyecto, así que vive aquí y no en la hoja de una pantalla. */
.modal-container{display:none}
.modal-container.active{display:block}

/* ==========================================================================
   12. AVISOS EN LÍNEA
   ========================================================================== */
.aviso,.alert,.project-alert{
  display:flex;align-items:flex-start;gap:var(--esp-3);
  padding:var(--esp-3) var(--esp-4);border-radius:var(--r-s);
  background:var(--neutro-bg);border:1px solid var(--neutro-borde);
  color:var(--texto);font-size:var(--t-s);line-height:1.5;
}
.aviso .ic,.alert .ic,.alert-icon{flex:none;display:flex;margin-top:1px}
.aviso b,.alert b{font-weight:var(--peso-fuerte)}
.aviso--ok,.alert-success,.project-alert-success{background:var(--ok-bg);
  border-color:var(--ok-borde);color:var(--ok)}
.aviso--avisa,.alert-warning,.project-alert-warning{background:var(--avisa-bg);
  border-color:var(--avisa-borde);color:var(--avisa)}
.aviso--mal,.alert-error,.alert-danger,.project-alert-error{background:var(--mal-bg);
  border-color:var(--mal-borde);color:var(--mal)}
.aviso--info,.alert-info,.project-alert-info{background:var(--info-bg);
  border-color:var(--info-borde);color:var(--info)}
.aviso p,.alert p,.project-alert p{color:inherit}
.aviso .acciones{margin-left:auto;display:flex;gap:var(--esp-2);flex:none;flex-wrap:wrap}

/* ==========================================================================
   13. ESTADO VACÍO
   ========================================================================== */
.empty-state,.vacio{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;gap:var(--esp-3);padding:var(--esp-8) var(--esp-5);
  color:var(--texto-2);
}
.empty-icon,.vacio-ic{
  width:56px;height:56px;border-radius:var(--r);display:grid;place-items:center;
  background:var(--sup-2);border:1px solid var(--borde);color:var(--texto-3);
  font-size:22px;margin-bottom:var(--esp-1);
}
.empty-state h2,.empty-state h3,.vacio h2{font-size:var(--t-l);color:var(--texto)}
.empty-state p,.vacio p{max-width:52ch;color:var(--texto-3);font-size:var(--t-s)}

/* ==========================================================================
   14. PAGINACIÓN Y MIGA DE PAN
   ========================================================================== */
.pagination,.paginacion{
  display:flex;align-items:center;gap:var(--esp-3);flex-wrap:wrap;
  padding:var(--esp-3) var(--esp-4);border-top:1px solid var(--borde);
  background:var(--sup-2);
}
.pagination-info{font-size:var(--t-s);color:var(--texto-3)}
.pagination-controls{margin-left:auto;display:flex;gap:var(--esp-1);align-items:center;
  flex-wrap:wrap}
.page-current{
  display:inline-grid;place-items:center;min-width:30px;height:30px;padding:0 8px;
  border-radius:var(--r-xs);background:var(--acento-suave);color:var(--acento);
  font-family:var(--mono);font-size:var(--t-s);font-weight:var(--peso-fuerte);
}
.page-ellipsis{color:var(--texto-3);padding:0 4px}

.breadcrumb,.miga{
  display:flex;align-items:center;gap:var(--esp-2);flex-wrap:wrap;
  font-size:var(--t-s);color:var(--texto-3);margin-bottom:var(--esp-3);
}
.breadcrumb-item{color:var(--texto-3)}
a.breadcrumb-item:hover{color:var(--acento)}
.breadcrumb-current{color:var(--texto-2);font-weight:var(--peso-medio)}
.breadcrumb-sep{display:flex;opacity:.6}

/* ==========================================================================
   15. LISTAS DE DEFINICIÓN
   ========================================================================== */
.dl,.detail-list{display:grid;grid-template-columns:minmax(120px,auto) 1fr;gap:0}
.dl dt,.dl dd,.detail-list dt,.detail-list dd{
  padding:9px 0;border-bottom:1px solid var(--borde);min-width:0;
}
.dl dt,.detail-list dt{
  font-family:var(--mono);font-size:var(--t-eti);letter-spacing:var(--track-eti);
  text-transform:uppercase;color:var(--texto-3);padding-right:var(--esp-4);
  align-self:center;
}
.dl dd,.detail-list dd{font-size:var(--t-s);color:var(--texto);
  font-weight:var(--peso-medio);align-self:center}
.dl dd.num,.detail-list dd.num{font-family:var(--mono);font-variant-numeric:tabular-nums}
.dl > dt:last-of-type,.dl > dd:last-child{border-bottom:none}

.detail-section{min-width:0}
.detail-section > h2,.detail-section > h3,.bloque > h2{
  font-family:var(--mono);font-size:var(--t-eti);letter-spacing:var(--track-eti);
  text-transform:uppercase;font-weight:var(--peso-medio);color:var(--texto-3);
  padding-bottom:var(--esp-2);margin-bottom:var(--esp-3);
  border-bottom:1px solid var(--borde);display:flex;align-items:center;gap:7px;
}

/* ==========================================================================
   16. UTILIDADES
   ========================================================================== */
.rejilla-2{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  gap:var(--esp-5) var(--esp-6)}
.pila{display:flex;flex-direction:column;gap:var(--esp-3)}
.linea{display:flex;align-items:center;gap:var(--esp-3);flex-wrap:wrap}
.linea--fin{justify-content:flex-end}
.empuja{margin-left:auto}
.oculto{display:none!important}
.nowrap{white-space:nowrap}
.truncar{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}

/* ==========================================================================
   17. AJUSTES DE ORDEN
   Reglas que tienen que ganar a las genéricas de formulario de la sección 10,
   que se declaran después y con la misma especificidad.
   ========================================================================== */

/* El buscador reserva sitio a la lupa y al indicador de carga; sin esto la
   regla genérica de `input` le devuelve el relleno de 12px y el icono se come
   la primera letra del texto. */
.buscador input,.search-box input{padding-left:34px;padding-right:34px}

/* El interruptor de modo de las pantallas sin sesión va anclado a la esquina.
   Se declara aquí y no en base.css porque `.icb` lo pone en `position:relative`
   y esta hoja se carga después. */
.auth-tema{position:fixed;top:var(--esp-4);right:var(--esp-4);z-index:var(--z-cab)}
