/* Valores Sí/No en celdas sin badge: verde para "Sí", rojo para "No"
   (aplicado de forma centralizada por colorizeBooleanCells en tables.js). */
.table-wrap td.cell-bool-yes { color: var(--green); font-weight: 600; }

.table-wrap td.cell-bool-no  { color: var(--red);   font-weight: 600; }

/* Las acciones auxiliares que aún viven en una celda no deben recortarse. */
.table-wrap td:has(> .btn-table-action) {
  white-space: nowrap;
  min-width: 96px;
}

.detail-pane .table-wrap {
  max-width: 100%;
}

.detail-data-table {
  width: 100%;
  max-width: 100%;
}

.detail-data-table.resizable-cols {
  max-width: none;
}

.detail-costes-table th[data-col="fechaInicio"],
.detail-costes-table th[data-col="fechaFin"] {
  min-width: 160px;
}

.detail-costes-table td.col-date-cell {
  min-width: 160px;
  white-space: nowrap;
}

/* ══════════════════════════════════════════
   TABLE — Core
══════════════════════════════════════════ */

.table-wrap {
  overflow-x: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--bg2);
  box-shadow:
    0 1px 0 color-mix(in srgb, var(--surface-white) 5%, transparent) inset,
    0 8px 32px color-mix(in srgb, var(--shadow-color) 10%, transparent);
}

.table-responsive {
  width: 100%;
}

table { width: 100%; border-collapse: collapse; font-size: 13px; }

table.resizable-cols { table-layout: fixed; }

.table-wrap table.initiatives-data-table :is(th, td).col-id {
  white-space: nowrap;
  overflow-wrap: normal;
  word-break: keep-all;
}

.table-wrap table.initiatives-data-table td.col-id {
  line-height: 1.3;
}

/* El input de ID no debe forzar un ancho mayor que su columna: con
   table-layout:fixed un min-width superior al ancho de la columna hace que el
   input desborde y se solape con la columna Título. Llena la celda y ya. */
.initiatives-data-table .bulk-edit-input.bulk-edit-id {
  min-width: 0;
  padding-right: 8px;
}

/* ══════════════════════════════════════════
   TABLE — Header
══════════════════════════════════════════ */

th {
  background: var(--table-head-bg);
  padding: 9px 14px;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text3);
  border-bottom: 1px solid var(--border2);
  /* Estándar de cabeceras: en una línea si cabe y, si no, el salto es siempre
     por palabras enteras (nunca se parte una palabra: el motor común da a cada
     columna al menos el ancho de su palabra más larga, dcAnchoCabecera en
     shared/js/ui/tables.js). */
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
  vertical-align: top;
}

/* Headers de tablas resizables: posición relativa para el handle de resize. */
table.resizable-cols th {
  position: relative;
  white-space: normal;
  padding-right: 22px;
}

/* Thead — cabecera nunca se rompe en palabras cuando no es resizable */
.table-wrap th { white-space: nowrap; }

/* Cabeceras de la tabla de iniciativas: mantener las palabras enteras para que
   no se corten (p. ej. "Presentado" o "Negocio"); el salto a 2 líneas se
   controla con <br> en el propio encabezado. */
/* Cabeceras SIEMPRE alineadas a la izquierda, también en columnas numéricas
   (el número de la celda sí puede ir a la derecha). */
.table-wrap thead th,
table thead th { text-align: left !important; }

table.resizable-cols th.th-sort { white-space: normal; }

/* ══════════════════════════════════════════
   TABLE — Cells
══════════════════════════════════════════ */

td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  overflow-wrap: break-word;
  word-break: normal;
  white-space: pre-line;
  vertical-align: top;
  transition: background var(--transition);
}

.table-wrap td .badge {
  margin: 2px 4px 2px 0;
}

.table-wrap td .badge:last-child {
  margin-right: 0;
}

table.resizable-cols td { max-width: none !important; }

tr:last-child td { border-bottom: none; }

body[data-theme="dark"] .table-wrap tbody tr:nth-child(even):not(.bulk-edit-row) > td {
  background: color-mix(in srgb, var(--bg3) 34%, var(--bg2));
}

/* ══════════════════════════════════════════
   TABLE — Rows & hover
══════════════════════════════════════════ */

.table-row-action { cursor: pointer; }

@media (hover: hover) and (pointer: fine) {
  .table-row-action:hover td {
    background: color-mix(in srgb, var(--accent) 6%, var(--bg2));
  }
}

.table-row-action:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.table-row-action:focus-visible td,
.table-row-action:active td {
  background: color-mix(in srgb, var(--accent) 9%, var(--bg2));
}

.table-initiative-cell { white-space: nowrap; }

.table-initiative-link {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: 500 11px/1.25 var(--font-mono);
  letter-spacing: 0.02em;
  text-decoration: none;
  /* Seleccionable desde el cursor (como el texto normal) para poder copiarlo. */
  -webkit-user-drag: none;
  -webkit-user-select: text;
  user-select: text;
}

@media (hover: hover) and (pointer: fine) {
  .table-initiative-link:hover { text-decoration: none; font-weight: 700; }
}

.table-initiative-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ══════════════════════════════════════════
   TABLE — Row reveal stagger
   Cuando una tabla se re-renderiza (filtros, ordenación, búsqueda) las
   primeras filas hacen un fade-in en cascada corto. Sólo opacity para no
   forzar layout; las filas siguientes salen ya visibles para que el coste
   total no escale con el número de registros.
══════════════════════════════════════════ */

@keyframes rowFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.table-wrap tbody tr {
  animation: rowFadeIn 220ms ease-out both;
}

.table-wrap tbody tr:nth-child(1) { animation-delay: 0ms; }
.table-wrap tbody tr:nth-child(2) { animation-delay: 18ms; }
.table-wrap tbody tr:nth-child(3) { animation-delay: 36ms; }
.table-wrap tbody tr:nth-child(4) { animation-delay: 54ms; }
.table-wrap tbody tr:nth-child(5) { animation-delay: 72ms; }
.table-wrap tbody tr:nth-child(6) { animation-delay: 90ms; }
.table-wrap tbody tr:nth-child(7) { animation-delay: 108ms; }
.table-wrap tbody tr:nth-child(n+8) { animation: none; }

/* La cabecera y la fila bulk-edit nunca se animan: una está fija, la otra
   contiene inputs activos cuyo render no debe parpadear. */
.table-wrap thead tr,
.table-wrap tbody tr.bulk-edit-row {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .table-wrap tbody tr { animation: none; }
}

.mono { font-family: var(--font-mono); }

/* Fechas en tablas · tipografía ÚNICA de Digital Core (SSOT): la de las tablas de
   Portfolio IA, monoespaciada de 12 px y color secundario (equivale a «mono
   cell-muted-sm»). El motor de tablas marca como col-date / col-datetime las celdas
   de cualquier columna de fechas (también las de Hub Presupuestario y Portfolio
   Data), así que basta esta regla; .cell-date es para fechas sueltas dentro de una
   celda. No toca las celdas con controles de edición (input, select, textarea). */
.table-wrap td.col-date:not(:has(input, select, textarea)),
.table-wrap td.col-datetime:not(:has(input, select, textarea)),
.cell-date {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text2);
}

/* ══════════════════════════════════════════
   TABLE — Sort
══════════════════════════════════════════ */

.th-sort { cursor: pointer; -webkit-user-select: none; user-select: none; white-space: nowrap; }

.th-sort:hover {
  color: var(--text2);
  background: color-mix(in srgb, var(--accent) 6%, var(--table-head-bg));
}

.th-filter {
  outline: none;
}

.th-filter.has-column-filter {
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 8%, var(--table-head-bg));
}

.th-filter.has-column-filter .sort-icon {
  opacity: 1;
  color: var(--accent);
}

.th-filter:focus-visible {
  box-shadow: inset 0 0 0 2px var(--accent);
}

.th-sort .th-label { display: inline; }

.sort-icon {
  display: inline-block;
  margin-left: 5px;
  opacity: 0;
  font-size: 9px;
  line-height: 1;
  vertical-align: middle;
  transform-origin: center;
  transition:
    opacity var(--transition),
    color var(--transition),
    transform 200ms cubic-bezier(0.22, 1, 0.36, 1);
}

.th-sort:hover .sort-icon { opacity: 0.45; }

.th-sort.asc,
.th-sort.desc { color: var(--accent); }

.th-sort.asc .sort-icon,
.th-sort.desc .sort-icon { opacity: 1; color: var(--accent); }

/* La dirección se transmite girando la misma punta de flecha 180°, así el
   cambio asc↔desc es un gesto continuo en vez de un salto de glifo. El
   neutro mantiene ↕ porque es un estado cualitativamente distinto. */
.th-sort.asc  .sort-icon::after { content: '↑'; }
.th-sort.desc .sort-icon::after { content: '↑'; }
.th-sort.desc .sort-icon { transform: rotate(180deg); }
.th-sort:not(.asc):not(.desc) .sort-icon::after { content: '↕'; }

@media (prefers-reduced-motion: reduce) {
  .sort-icon { transition: opacity 0.01s, color 0.01s; }
  .th-sort.desc .sort-icon { transform: none; }
  .th-sort.desc .sort-icon::after { content: '↓'; }
}

.table-row-filter-hidden {
  display: none !important;
}

.table-column-filter-popover {
  position: fixed;
  z-index: 1500;
  display: none;
  flex-direction: column;
  gap: 4px;
  max-width: min(320px, calc(100vw - 24px));
  max-height: min(420px, calc(100vh - 24px));
  overflow: auto;
  padding: 8px;
  border: 1px solid var(--border2);
  border-radius: var(--radius-sm);
  background: var(--bg2);
  color: var(--text);
  box-shadow: var(--shadow-pop);
}

.table-column-filter-popover.open {
  display: flex;
}

/* Móvil (≤ 640 px): hoja inferior a ancho completo, con opciones más altas para
   el dedo (positionTableFilterPopover pone .is-sheet). */
.table-column-filter-popover.is-sheet {
  left: 0;
  right: 0;
  bottom: 0;
  top: auto;
  width: auto;
  max-width: none;
  max-height: 75vh;
  padding: 12px 14px calc(12px + env(safe-area-inset-bottom, 0px));
  border-radius: var(--radius) var(--radius) 0 0;
}
.table-column-filter-popover.is-sheet .table-filter-options { max-height: 45vh; }
.table-column-filter-popover.is-sheet .table-filter-option { min-height: 40px; font-size: 13px; }

.table-filter-head {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 1px 0 5px;
}

.table-filter-title {
  flex: 1 1 auto;
  min-width: 0;
  padding: 2px 4px;
  color: var(--text2);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.table-filter-clear-column {
  width: 24px;
  min-width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text2);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.table-filter-clear-column svg {
  width: 13px;
  height: 13px;
}

.table-filter-sort {
  width: 100%;
  min-height: 30px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
  padding: 7px 9px;
}

.table-filter-sort:hover,
.table-filter-clear-column:hover {
  background: var(--bg3);
}

.table-filter-sort.active {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}

.table-filter-clear-column:disabled {
  opacity: 0.45;
  cursor: default;
}

.table-filter-clear-column:disabled:hover {
  background: transparent;
}

.table-filter-divider {
  height: 1px;
  margin: 5px 0;
  background: var(--border);
}

.table-filter-options {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 220px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.table-filter-option {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 28px;
  padding: 5px 7px;
  border-radius: var(--radius-sm);
  color: var(--text);
  cursor: pointer;
  font-size: 12px;
}

.table-filter-option:hover {
  background: var(--bg3);
}

.table-filter-option input {
  accent-color: var(--accent);
}

.table-filter-all.is-disabled {
  cursor: default;
  color: var(--text3);
}

.table-filter-all.is-disabled:hover {
  background: transparent;
}

.table-filter-option-text {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* «Solo»: muestra únicamente ese valor. Al pasar el ratón en escritorio; en
   táctil, siempre visible. */
.table-filter-option-only {
  flex: 0 0 auto;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--accent);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 6px;
  cursor: pointer;
  opacity: 0;
}

.table-filter-option:hover .table-filter-option-only,
.table-filter-option-only:focus-visible {
  opacity: 1;
}

.table-filter-option-only:hover {
  background: var(--accent-soft);
}

@media (pointer: coarse) {
  .table-filter-option-only { opacity: 1; }
}

/* Buscador sobre la lista de opciones del filtro choice (listas largas). */
.table-filter-choice-search {
  display: flex;
  margin-bottom: 6px;
}

/* «Filtrar por coincidencias (N)»: aparece al escribir en el buscador. */
.table-filter-apply-matches {
  width: 100%;
  margin-bottom: 6px;
  padding: 7px 9px;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--on-accent);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}

.table-filter-apply-matches[hidden] {
  display: none;
}

/* Casilla maestra "(Todas)": encabeza la lista de opciones del filtro choice. */
.table-filter-all {
  font-weight: 600;
  margin-bottom: 3px;
  padding-bottom: 7px;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
}

.table-filter-empty {
  padding: 8px;
  color: var(--text2);
  font-size: 12px;
}

.table-filter-search {
  width: 100%;
}

.table-filter-search .filter-input {
  width: 100%;
  min-width: 0;
}

.table-filter-range {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
}

.table-filter-range label {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: 8px;
  align-items: center;
  color: var(--text2);
  font-size: 12px;
}

.table-filter-input {
  min-width: 0;
  height: 32px;
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--bg3);
  color: var(--text);
  padding: 0 12px;
  font: inherit;
  font-size: 12px;
}

.table-filter-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* ══════════════════════════════════════════
   TABLE — Column resize handle
══════════════════════════════════════════ */

.col-resizer {
  position: absolute;
  top: 0;
  right: -7px;
  width: 15px;
  height: 100%;
  cursor: col-resize;
  -webkit-user-select: none;
  user-select: none;
  touch-action: none;
  z-index: 2;
}

/* El asa de la última columna se posiciona en right:-7px y sobresale ~8px más
   allá del borde derecho de la tabla, lo que provocaba un scroll horizontal
   mínimo en la versión por defecto de las tablas. La última columna no tiene un
   borde a su derecha que arrastrar, así que se oculta su asa. */
.table-wrap table.resizable-cols th:last-child .col-resizer { display: none; }

.col-resizer::after {
  content: '';
  position: absolute;
  top: 8px;
  bottom: 8px;
  left: 7px;
  width: 1px;
  background: transparent;
  transition: background 0.15s;
  border-radius: 1px;
}

@media (hover: hover) and (pointer: fine) {
  .col-resizer:hover::after { background: var(--accent); opacity: 0.65; }
}

.col-resizer.active::after {
  width: 2px;
  background: var(--accent);
  opacity: 0.9;
}

body.is-table-resizing {
  cursor: col-resize;
  -webkit-user-select: none;
  user-select: none;
}

/* ══════════════════════════════════════════
   TABLE — Bulk edit
══════════════════════════════════════════ */

.bulk-edit-toolbar {
  display: flex;
  gap: 8px;
  align-items: center;
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--bg2);
  flex-wrap: wrap;
}
.bulk-edit-toolbar .btn-primary,
.bulk-edit-toolbar .btn-secondary {
  padding: 6px 12px;
  font-size: 12px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.bulk-edit-toolbar [data-action="bulk-edit-init-save"] { margin-left: auto; }
.bulk-edit-hint {
  font-size: 12px;
  color: var(--text2);
  margin-right: 8px;
}

.bulk-edit-row td { vertical-align: top; padding: 8px 10px; }
.bulk-edit-cell { padding: 8px 10px; }
.bulk-edit-input,
.bulk-edit-select {
  width: 100%;
  min-width: 0;
  padding: 7px 28px 7px 9px;
  font: inherit;
  font-size: 13px;
  line-height: 1.35;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
  box-sizing: border-box;
}

/* Los inputs de texto no llevan caret de despliegue: recuperar ese espacio. */
.bulk-edit-input { padding-right: 9px; }
.bulk-edit-input.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.bulk-edit-input.bulk-edit-num { width: 90px; }
/* Textos largos (nombre, descripción, observaciones): área que crece con el
   contenido (autoGrowTextarea), redimensionable y con los saltos de línea. */
.bulk-edit-input.bulk-edit-textarea {
  display: block;
  min-height: 56px;
  max-height: 240px;
  resize: vertical;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}
.bulk-edit-input[type="date"] { max-width: 160px; }
/* Celda cambiada y pendiente de guardar; control con error de validación. */
.bulk-edit-input.bulk-dirty,
.bulk-edit-select.bulk-dirty,
.bulk-multi-trigger.bulk-dirty {
  border-color: color-mix(in srgb, var(--accent) 60%, var(--border));
  background: color-mix(in srgb, var(--accent) 7%, var(--bg));
}
.bulk-edit-input.bulk-edit-invalid,
.bulk-edit-select.bulk-edit-invalid {
  border-color: var(--red);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--red) 18%, transparent);
}
/* Filas que el usuario no puede editar: atenuadas (el motivo va en el title). */
.bulk-edit-row.is-locked > td { opacity: 0.6; }
.bulk-edit-row.is-locked { cursor: not-allowed; }
.bulk-edit-input:focus,
.bulk-edit-select:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}
.bulk-edit-readonly { vertical-align: middle; padding: 8px 10px; }

.bulk-edit-switch-cell { vertical-align: middle; }
/* El interruptor Sí/No es el componente común .switch-toggle (toggles.css). */

.bulk-multi {
  position: relative;
  width: 100%;
}
.bulk-multi-trigger {
  cursor: pointer;
  position: relative;
  display: flex;
  gap: 6px;
  align-items: flex-start;
  flex-wrap: wrap;
  padding: 5px 28px 5px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  min-height: 30px;
  /* Altura dinámica: el desplegable crece con los chips seleccionados y, al
     estar la celda con vertical-align:top, la fila se adapta sin scroll interno. */
  max-height: none;
  overflow: visible;
  list-style: none;
}
.bulk-multi-trigger::-webkit-details-marker { display: none; }
.bulk-multi-trigger::marker { content: ''; }
.bulk-multi-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  flex: 1 1 auto;
  min-width: 0;
  max-width: 100%;
}

/* Los badges (p. ej. "MIR Asturias") pueden saltar de línea entre palabras,
   pero nunca partir una palabra por la mitad: la etiqueta coloreada cortada a
   media palabra parecía un error visual. El ancho mínimo de la columna
   (data-col-min-width en la cabecera) garantiza que la palabra más larga cabe. */
.bulk-multi-chips .badge {
  white-space: normal;
  overflow-wrap: normal;
  word-break: keep-all;
  max-width: 100%;
}
.bulk-multi-placeholder { color: var(--text3, var(--text2)); font-style: italic; font-size: 12px; }
.bulk-multi-caret {
  position: absolute;
  top: 50%;
  right: 11px;
  width: 8px;
  height: 8px;
  color: var(--text2);
  font-size: 0;
  transform: translateY(-60%);
  pointer-events: none;
}
.bulk-multi-caret::before {
  content: '';
  display: block;
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
}
.bulk-multi-popover {
  position: fixed;
  z-index: 20;
  min-width: 0;
  width: max-content;
  max-width: min(280px, calc(100vw - 32px));
  padding: 6px 8px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 12px 28px color-mix(in srgb, var(--shadow-color) 16%, transparent);
  max-height: 220px;
  overflow-y: auto;
}
.bulk-multi-option {
  display: flex;
  gap: 6px;
  align-items: center;
  padding: 3px 0;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}

/* ══════════════════════════════════════════
   TABLE — Estado column specifics
══════════════════════════════════════════ */

.detail-estado-table th:first-child,
.detail-estado-table td:first-child {
  min-width: 190px;
  white-space: nowrap;
}

.detail-estado-table td:first-child .badge {
  white-space: nowrap;
}

/* Cabeceras de agrupación de tabla plegables (usadas por el histórico de
   Estados agrupado por fase). El JS que las pliega vive en tables.js
   (toggleGroupCollapse) y las construye detail-tables.js. */
.list-group-header {
  cursor: pointer; user-select: none;
  --group-text: var(--text);
  --group-bg-start: var(--accent-soft);
  --group-bg-end: var(--bg3);
  --group-count: var(--text3);
}
.list-group-header > td {
  font-size: 0.82rem; font-weight: 700; color: var(--group-text);
  padding: 10px 14px;
  background: linear-gradient(90deg, var(--group-bg-start), var(--group-bg-end));
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.list-group-header > td > .group-line {
  display: flex; align-items: center; gap: 8px;
}
.list-group-header .group-count { color: var(--group-count); font-weight: 400; font-family: var(--font-mono); font-size: 0.75rem; }
.list-group-header .group-chevron { transition: transform var(--transition); }
.list-group-header.collapsed .group-chevron { transform: rotate(-90deg); }
.list-group-header.collapsed ~ tr { display: none; }

/* Las filas-cabecera de agrupación por Fase ("Fase 1", "Fase 2"…) del histórico
   de estados se muestran en tipografía monoespaciada (consola) y color gris. */
.detail-estado-table .list-group-header > td {
  font-family: var(--font-mono);
  color: var(--text2);
}

/* Toggle segmentado de vista (Tarjetas/Tabla en Iniciativas y Edición). */
.view-toggle {
  display: inline-flex; border: 1px solid var(--border2);
  border-radius: var(--radius-sm); overflow: hidden; padding: 2px;
  background: var(--bg2);
}
.view-toggle .toggle-btn {
  padding: 5px 14px; font-size: 12px; cursor: pointer;
  background: transparent; color: var(--text2); border: none;
  font-family: var(--font-body); border-radius: calc(var(--radius-sm) - 3px);
  transition: background var(--transition), color var(--transition);
}
.view-toggle .toggle-btn.active {
  background: var(--accent-soft); color: var(--accent); font-weight: 600;
}
.view-toggle .toggle-btn:hover:not(.active) { background: var(--bg3); }
/* Móvil: los botones se reparten el ancho disponible en lugar de desbordarlo
   (p. ej. Kanban · Lista · Cronograma · Calendario en Tareas). */
@media (max-width: 640px) {
  /* Nunca se recorta el texto: los botones se reparten el ancho y, si no caben en una
     línea, pasan a la siguiente (Tarjetas · Tabla · Kanban · Cronograma, Tabla · Kanban…). */
  .view-toggle { display: flex; flex-wrap: wrap; max-width: 100%; }
  .view-toggle .toggle-btn { flex: 1 1 auto; min-width: 0; padding: 6px 10px; white-space: nowrap; text-align: center; }
}

/* ══════════════════════════════════════════
   TABLE — KPI cells
══════════════════════════════════════════ */

.filter-clear.icon-clear { min-width: auto; width: auto; padding: 0 10px; gap: 6px; }

.kpi-value-cell { min-width: 110px; }

.kpi-value-main { display: block; font-family: var(--font-display); font-size: 18px; font-weight: 700; color: var(--text); line-height: 1.1; }

.kpi-value-sub { display: block; font-size: 10px; color: var(--text3); margin-top: 3px; text-transform: uppercase; letter-spacing: .04em; }


/* ══════════════════════════════════════════
   TABLE — Catalog
══════════════════════════════════════════ */

.catalog-readonly {
  border-color: var(--accent-soft) !important;
  background: linear-gradient(0deg, var(--accent-soft), var(--accent-soft)), var(--bg3) !important;
  color: var(--text2) !important;
  cursor: not-allowed;
}

.catalog-row { cursor: pointer; }

.catalog-row:hover td { background: color-mix(in srgb, var(--accent) 5%, transparent); }

.catalog-row-readonly { cursor: default; }

.catalog-row-readonly:hover td { background: transparent; }

.catalog-name {
  display:block; white-space:normal; overflow-wrap:anywhere;
  line-height:1.3;
}

.catalog-table-tech .catalog-col-name { width: 200px; }
.catalog-table-tech .catalog-col-company { width: 140px; }
.catalog-table-tech .catalog-col-status { width: 110px; }
.catalog-table-tech .catalog-col-description { min-width: 300px; }

.catalog-table-kpis .catalog-col-name { width: 220px; }
.catalog-table-kpis .catalog-col-description { min-width: 240px; }
.catalog-table-kpis .catalog-col-iniciativas { min-width: 220px; }
.catalog-table-kpis .catalog-col-unit { width: 80px; }

/* Popup de un KPI de catálogo: iniciativas asignadas y el objetivo de cada una. */
.kpi-asig-list { display:flex; flex-direction:column; gap:8px; margin-bottom:8px; }
.kpi-asig-row { display:grid; grid-template-columns:minmax(0, 1fr) 120px auto; gap:8px; align-items:center; }
.kpi-asig-row .form-select, .kpi-asig-row .form-input { min-width:0; max-width:100%; }
.kpi-asig-vacio { color:var(--text3); font-size:var(--field-fs); }
@media (max-width: 640px) {
  .kpi-asig-row { grid-template-columns:minmax(0, 1fr) 96px auto; }
}

.catalog-table-impacts .catalog-col-name { width: 240px; }
.catalog-table-impacts .catalog-col-scope { width: 110px; }
.catalog-table-impacts .catalog-col-description { min-width: 320px; }

.catalog-table-equipo .catalog-col-name { width: 190px; }
.catalog-table-equipo .catalog-col-email { width: 230px; }
.catalog-table-equipo .catalog-col-roles { min-width: 280px; }
.catalog-table-equipo .catalog-col-activo { width: 90px; }

.catalog-description {
  font-size: 12px;
  color: var(--text2);
}

/* ══════════════════════════════════════════
   TABLE — Mobile responsive
══════════════════════════════════════════ */

@media (max-width: 768px) {
  .date-filter-shell.is-empty .date-filter-placeholder {
    position: absolute;
    inset: 0 auto 0 12px;
    z-index: 1;
    display: flex;
    align-items: center;
    max-width: calc(100% - 42px);
    color: var(--text3);
    font-size: 12px;
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    pointer-events: none;
  }

  .date-filter-shell :is(.filter-date, .month-filter)[type="date"] {
    min-width: 150px;
    -webkit-text-fill-color: var(--text);
  }

  #page-catalogos .catalog-table .catalog-description {
    white-space: normal;
    overflow-wrap: anywhere;
  }
}

@media (max-width: 768px) {
  .table-responsive table.mobile-scroll-table.resizable-cols :is(th, td).col-text-lg {
    width: clamp(190px, 58vw, 240px);
    min-width: clamp(190px, 58vw, 240px);
    max-width: clamp(190px, 58vw, 240px) !important;
  }

  .table-responsive table.mobile-scroll-table.resizable-cols td.col-text-lg {
    white-space: normal;
    overflow-wrap: anywhere;
  }

  .table-responsive table.initiatives-data-table.mobile-scroll-table {
    min-width: 720px;
  }
}

@media (max-width: 640px) {
  .mobile-card-table {
    border-collapse: separate;
    border-spacing: 0;
    background: transparent;
  }

  table.mobile-card-table.resizable-cols {
    width: 100%;
    min-width: 0;
    table-layout: auto;
  }

  table.mobile-card-table.resizable-cols col {
    width: auto !important;
  }

  .table-wrap:has(> .mobile-card-table) {
    border: 0;
    border-radius: 0;
    overflow: visible;
    box-shadow: none;
  }

  .mobile-card-table colgroup,
  .mobile-card-table thead {
    display: none;
  }

  .mobile-card-table,
  .mobile-card-table tbody,
  .mobile-card-table tr,
  .mobile-card-table td {
    display: block;
    width: 100%;
  }

  .mobile-card-table tbody {
    display: grid;
    gap: 10px;
  }

  .mobile-card-table tbody tr {
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--bg3);
    overflow: hidden;
    box-shadow:
      0 1px 0 color-mix(in srgb, var(--surface-white) 4%, transparent) inset,
      0 4px 12px color-mix(in srgb, var(--shadow-color) 8%, transparent);
  }

  .mobile-card-table tbody tr:hover td {
    background: transparent;
  }

  .mobile-card-table td {
    display: grid;
    grid-template-columns: minmax(104px, 36%) minmax(0, 1fr);
    align-items: start;
    gap: 12px;
    min-width: 0 !important;
    max-width: none !important;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border);
    white-space: normal !important;
    overflow: visible;
    overflow-wrap: anywhere;
  }

  .mobile-card-table td::before {
    content: attr(data-label);
    color: var(--text3);
    font-size: 10px;
    font-weight: 600;
    line-height: 1.4;
    letter-spacing: 0.07em;
    text-transform: uppercase;
  }

  .mobile-card-table td:last-child {
    border-bottom: 0;
  }

  .mobile-card-table td[colspan] {
    display: block;
    padding: 0;
    border: 0;
  }

  .mobile-card-table td[colspan]::before {
    display: none;
  }

  .mobile-card-table tbody tr:has(td[colspan]) {
    border: 0;
    border-radius: 0;
    background: transparent;
    overflow: visible;
    box-shadow: none;
  }

  .mobile-card-table .catalog-name,
  .mobile-card-table .catalog-description,
  .mobile-card-table .cell-iaact-justification-xs {
    white-space: normal;
    overflow-wrap: anywhere;
  }
}

@media (max-width: 360px) {
  .mobile-card-table td {
    grid-template-columns: 1fr;
    gap: 4px;
  }
}

/* ── Favoritos (común a todas las apps: shared/js/ui/favorites.js) ── */
/* Columna final de favorito (fija, estrecha y centrada). */
.favorite-cell,
.initiative-favorite-cell,
.col-favorite {
  width: 46px;
  min-width: 46px;
  padding-inline: 7px !important;
  text-align: center;
}

/* Estrella de fila, tarjeta o ficha: estilo original de Portfolio IA (el
   borde transparente evita el borde nativo del botón, que se veía sombreado). */
.favorite-btn {
  display: inline-grid;
  width: 32px;
  height: 32px;
  flex: 0 0 32px;
  place-items: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  box-shadow: none;
  color: var(--text3);
  cursor: pointer;
  transition: color var(--transition-fast), background-color var(--transition-fast), border-color var(--transition-fast), transform 120ms var(--ease-out);
}
.favorite-btn svg { width: 17px; height: 17px; }
.favorite-btn.is-favorite {
  color: var(--favorite);
  background: var(--favorite-soft);
  border-color: color-mix(in srgb, var(--favorite) 34%, transparent);
}
@media (hover: hover) and (pointer: fine) {
  .favorite-btn:hover {
    color: var(--favorite);
    background: var(--favorite-soft);
    border-color: color-mix(in srgb, var(--favorite) 34%, transparent);
  }
}
.favorite-btn:active { transform: scale(0.94); }
.favorite-btn.is-compact {
  width: 28px;
  height: 28px;
  flex-basis: 28px;
}
.favorite-btn.is-compact svg { width: 15px; height: 15px; }

/* Botón «Solo favoritos» de la barra de la tabla, junto al de columnas.
   Mismo tamaño que el botón de filtros (.filter-toggle: 32×32, svg 15px) para
   que todos los controles-icono de la barra queden igualados. */
.favorite-filter-btn.is-active,
.favorite-filter-btn[aria-pressed="true"] {
  color: var(--favorite);
  border-color: color-mix(in srgb, var(--favorite) 40%, transparent);
  background: var(--favorite-soft);
}

/* ══════════════════════════════════════════
   TABLAS DE LISTA (shared/js/ui/data-table.js · renderTablaDatos)
   Mismo aspecto en Portfolio Data y Hub Presupuestario: cabeceras que pueden
   partir línea, identificadores sin partir, cabecera de grupo con subtotales,
   fila de total y 1–2 columnas fijas al desplazar en horizontal.
══════════════════════════════════════════ */
.list-data-table th { white-space: normal; }
.list-data-table td.col-id, .list-data-table th.col-id { white-space: nowrap; }
.list-data-table td.col-id .mono { font-size: 12px; }
.list-data-table tr.is-muted td { color: var(--text2); }

/* Cabecera de grupo: etiqueta y subtotales de las filas visibles del grupo; la
   línea queda fija a la izquierda al desplazar la tabla en horizontal. */
.list-data-table .list-group-header { --group-bg-start: var(--group-row-bg); --group-bg-end: var(--group-row-bg); }
.list-data-table .list-group-header > td { background: var(--group-row-bg); }
.list-data-table .list-group-header .group-line {
  position: sticky;
  left: 14px;
  width: max-content;
  max-width: calc(100vw - 120px);
  flex-wrap: wrap;
}
.list-data-table .list-group-header .group-line strong { font-weight: 700; }
.list-data-table .list-group-header .group-line .badge { margin: 0; }
.list-group-totals {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  margin-left: 10px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text2);
}
.list-group-totals strong { color: var(--text); font-weight: 600; }

/* Fila de total general (en el pie: la reordena y oculta el motor común). */
/* Estándar de Digital Core para toda fila «Total» (pie de tabla, .list-total-row):
   negrita y gris oscuro (--text-total), también en sus <strong>, nunca negro. */
.list-total-row td {
  background: var(--bg3);
  border-top: 1px solid var(--border2);
  font-weight: 600;
  vertical-align: middle;
}
.list-total-row td, .list-total-row td strong,
table > tfoot > tr > :is(td, th), table > tfoot > tr > :is(td, th) strong { color: var(--text-total); font-weight: 600; }
.list-total-label { font-size: 12px; color: var(--text-total); white-space: nowrap; }

/* Columnas fijas con scroll horizontal, SOLO en escritorio (≥ 769 px): en móvil
   ninguna tabla de Digital Core fija columnas, toda la tabla se desplaza a la
   vez (regla única; las apps no añaden overrides propios). El motor común
   publica el ancho de la 1.ª columna visible en --freeze-col2-left;
   data-table.js marca .freeze-one-col cuando la tabla pide congelar: 1. */
@media (min-width: 769px) {
  .list-data-table.freeze-lead-cols > :is(thead, tbody, tfoot) > tr > :is(th, td):is(:nth-child(1), :nth-child(2)) {
    position: sticky;
    z-index: 2;
    background: var(--bg2);
  }
  .list-data-table.freeze-lead-cols > :is(thead, tbody, tfoot) > tr > :is(th, td):nth-child(1) { left: 0; }
  .list-data-table.freeze-lead-cols > :is(thead, tbody, tfoot) > tr > :is(th, td):nth-child(2) {
    left: var(--freeze-col2-left, 84px);
    box-shadow: 1px 0 0 var(--border);
  }
  .list-data-table.freeze-lead-cols > thead > tr > th:is(:nth-child(1), :nth-child(2)) { z-index: 4; background: var(--table-head-bg); }
  .list-data-table.freeze-lead-cols > tfoot > tr > td:is(:nth-child(1), :nth-child(2)) { z-index: 3; background: var(--bg3); }
  .list-data-table.freeze-lead-cols > tbody > tr.list-group-header > td { position: static; box-shadow: none; background: var(--group-row-bg); }
  :root[data-theme="dark"] .list-data-table.freeze-lead-cols > tbody > tr:nth-child(even):not(.list-group-header) > td:is(:nth-child(1), :nth-child(2)) {
    background: color-mix(in srgb, var(--bg3) 34%, var(--bg2));
  }
  .list-data-table.freeze-lead-cols.freeze-one-col > :is(thead, tbody, tfoot) > tr > :is(th, td):nth-child(1) { box-shadow: 1px 0 0 var(--border); }
  .list-data-table.freeze-lead-cols.freeze-one-col > :is(thead, tbody, tfoot) > tr > :is(th, td):nth-child(2) { position: static; box-shadow: none; }
  @media (hover: hover) and (pointer: fine) {
    .list-data-table.freeze-lead-cols > tbody > .table-row-action:hover > td:is(:nth-child(1), :nth-child(2)) {
      background: color-mix(in srgb, var(--accent) 6%, var(--bg2));
    }
  }
}

/* Badges dentro de celdas de tabla: en una columna estrecha el badge salta de
   línea en lugar de invadir la columna siguiente (regla común de las tres apps). */
.table-wrap td .badge {
  max-width: 100%;
  white-space: normal;
  text-align: left;
  /* En línea (no inline-flex): si el nombre salta de línea, el color de fondo solo
     cubre el texto de cada línea (cada fragmento con su padding y esquinas), no toda
     la columna, y cada línea mide lo que su texto (no el ancho de la más larga).
     line-height 2 (22 px con el texto de 11 px) y padding vertical de 5 px: el fondo
     de cada línea (14 + 10 px) se solapa un poco con el de la siguiente, así un valor
     partido en dos líneas se ve como un único bloque y no como dos selecciones. Para
     que el solape no se vea más oscuro, en las celdas los tonos suaves son OPACOS (el
     mismo color ya mezclado con la superficie de la tabla). Radio pequeño para que
     las esquinas de las líneas encajen sin muesca. */
  display: inline;
  line-height: 2;
  padding-top: 5px;
  padding-bottom: 5px;
  border-radius: 3px;
  --accent-soft: color-mix(in srgb, var(--accent) 12%, var(--bg2));
  --green-soft: color-mix(in srgb, var(--green) 13%, var(--bg2));
  --amber-soft: color-mix(in srgb, var(--amber) 14%, var(--bg2));
  --red-soft: color-mix(in srgb, var(--red) 13%, var(--bg2));
  --pink-soft: color-mix(in srgb, var(--pink) 13%, var(--bg2));
  --teal-soft: color-mix(in srgb, var(--teal) 13%, var(--bg2));
  --warning-soft: color-mix(in srgb, var(--warning) 15%, var(--bg2));
  --capex-soft: color-mix(in srgb, var(--capex) 14%, var(--bg2));
  --opex-soft: color-mix(in srgb, var(--opex) 14%, var(--bg2));
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
.table-wrap td .badge-tono { background: color-mix(in srgb, var(--tono, var(--text3)) 24%, var(--bg2)); }
/* Celda con VARIOS badges (p. ej. Ámbito con varios valores): cada uno es su propio
   bloque (inline-block) con su margen, para que el fondo de un badge no se monte
   sobre el de la línea siguiente; el solape de líneas de arriba solo sirve para
   un valor único partido en dos líneas. */
.table-wrap td:has(.badge ~ .badge) .badge {
  display: inline-block;
  line-height: 1.35;
  padding-top: 3px;
  padding-bottom: 3px;
  margin: 2px 4px 2px 0;
  vertical-align: top;
}

/* ── Móvil (≤ 768 px): la cabecera de toda tabla queda FIJA y solo se desplazan las filas ──
   Regla común de las tres apps. El contenedor pasa a tener su propio scroll vertical
   (altura acotada a la pantalla) y la cabecera de una sola fila se queda pegada arriba
   con fondo opaco; overscroll-behavior: none evita el «rebote» de iOS que arrastraba la
   tabla entera con su cabecera. Las tablas en tarjetas (mobile-card-table) no tienen
   cabecera, y las de cabecera de varias filas (edición masiva) llevan su propia lógica. */
@media (max-width: 768px) {
  .table-wrap {
    max-height: calc(100dvh - 130px);
    overflow: auto;
    overscroll-behavior: none;
    -webkit-overflow-scrolling: touch;
  }
  .table-wrap > table:not(.mobile-card-table) > thead:not(:has(> tr:nth-child(2))) > tr > th {
    position: sticky;
    top: 0;
    z-index: 3;
  }
}

/* ── Toda tabla mide lo que queda de pantalla (dcAjustarAltoTabla, shared/js/ui/tables.js) ──
   El máximo lo pone el script (CSSOM); aquí, el scroll interior y la cabecera fija con fondo
   opaco, igual que en la Bolsa de proyectos: las filas se desplazan por dentro y la página no
   suma un segundo scroll. Las cabeceras de varias filas (edición masiva) llevan su propia lógica. */
.table-wrap.dc-alto-ajustado { overflow: auto; }
.table-wrap.dc-alto-ajustado > table:not(.mobile-card-table) > thead:not(:has(> tr:nth-child(2))) > tr > th {
  position: sticky; top: 0; z-index: 3; background: var(--table-head-bg);
}
.table-wrap.dc-alto-ajustado > table.freeze-lead-cols:not(.mobile-card-table) > thead:not(:has(> tr:nth-child(2))) > tr > th:is(:nth-child(1), :nth-child(2)) { z-index: 5; }

/* ── Barras de desplazamiento de las tablas (dcScrollTabla, shared/js/ui/tables.js) ──
   El MISMO componente para la barra horizontal y la vertical de toda tabla y para la
   barra flotante: carril redondeado de 10 px a 10 px de los bordes de la tabla y pulgar
   en píldora de 6 px centrado en el carril. Las barras del navegador se ocultan en la caja
   de la tabla para que se vean igual en cualquier navegador y tema. */
.table-wrap.dc-sb-host { position: relative; scrollbar-width: none; }
.table-wrap.dc-sb-host::-webkit-scrollbar { display: none; width: 0; height: 0; }
.table-wrap.dc-sb-host.dc-sb-con-x { padding-bottom: 16px; }
/* Con fila resumen fija (tfoot) la barra horizontal va encima de ella: sin relleno bajo el total. */
.table-wrap.dc-sb-host.dc-sb-con-x.dc-sb-con-pie { padding-bottom: 0; }
/* Orden de abajo arriba: última fila · barra horizontal · fila resumen. La fila resumen es fija abajo y
   reserva en su parte superior el hueco de la barra (16 px), así la barra nunca tapa la última fila. */
.table-wrap > table > tfoot > tr > :is(td, th) { position: sticky; bottom: 0; z-index: 2; }
.table-wrap > table.freeze-lead-cols > tfoot > tr > :is(td, th):is(:nth-child(1), :nth-child(2)) { z-index: 4; }
.table-wrap.dc-sb-host.dc-sb-con-x.dc-sb-con-pie > table > tfoot > tr > :is(td, th) { padding-top: 26px; }
.dc-sb {
  position: absolute; top: 0; left: 0; z-index: 6; box-sizing: border-box;
  border-radius: var(--radius-pill); background: var(--bg3);
  box-shadow: inset 0 0 0 1px var(--border);
  opacity: .9; transition: opacity var(--transition-fast);
}
.dc-sb[hidden] { display: none; }
.dc-sb-x { height: 10px; }
.dc-sb-y { width: 10px; }
.dc-sb-pulgar {
  position: absolute; top: 2px; left: 2px; border-radius: var(--radius-pill);
  background: var(--border2); cursor: grab; transition: background-color var(--transition-fast);
}
.dc-sb-x .dc-sb-pulgar { height: 6px; }
.dc-sb-y .dc-sb-pulgar { width: 6px; }
.dc-sb:hover { opacity: 1; }
.dc-sb:hover .dc-sb-pulgar, .dc-sb.is-arrastrando .dc-sb-pulgar { background: var(--text3); }
.dc-sb.is-arrastrando .dc-sb-pulgar { cursor: grabbing; }
body:has(.dc-sb.is-arrastrando) { user-select: none; }

/* Barra flotante: la misma barra (.dc-sb-x) dentro de una píldora pegada al borde
   inferior de la ventana, dentro de los bordes de la tabla (solo escritorio). */
.dc-hscroll {
  position: fixed; bottom: 10px; z-index: 40; box-sizing: border-box; padding: 5px 8px;
  background: color-mix(in srgb, var(--bg2) 94%, transparent);
  border: 1px solid var(--border2); border-radius: var(--radius-pill);
  box-shadow: var(--shadow-pop);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: 0; transform: translateY(6px);
  transition: opacity var(--transition-fast), transform var(--transition-fast);
}
.dc-hscroll.is-visible { opacity: 1; transform: none; }
.dc-hscroll[hidden] { display: none; }
.dc-hscroll > .dc-sb { position: relative; display: block; width: 100%; transform: none; }
@media (max-width: 768px), (pointer: coarse) { .dc-hscroll { display: none !important; } }
