/* ============================================================================
   schema-canvas.css — estilos COMPARTIDOS de la página "Esquema" (Ground,
   Atlas Núcleo y futuras apps del ecosistema).

   FUENTE ÚNICA: vive en ~/Knowledge/atlas-shared/schema-canvas/ y se copia
   (nunca se edita a mano en las dos apps) con sync-schema-canvas.sh.
   Editar SOLO aquí.
   ============================================================================ */

/* ---- Esquema (09/09/2026, portado tal cual de Ground-app, mismo diseño ---- */
/* Descripciones largas convertidas en tooltip del título (28/08/2026,
   pedido de Javi: "que esa descripción solo se vea al pasar el ratón por
   encima de la etiqueta" — antes eran un <p class="hint"> siempre
   visible debajo del título; ahora viven en su atributo title). El
   cursor de ayuda es la única pista de que ahí hay algo más que leer. */
h1[title],
h2[title],
h3[title],
.schema-detail-table[title] {
  cursor: help;
}

/* --- Esquema: mapa de tablas (28/08/2026) -------------------------------
   Tres columnas: lista de tablas a la izquierda, lienzo arrastrable en el
   centro, detalle de la tabla seleccionada a la derecha. Solo consulta —
   nada aquí escribe en la base. */

.schema-layout {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}

.schema-sidebar {
  flex: 0 0 220px;
}

.schema-sidebar-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.6rem;
}

.schema-sidebar-actions button {
  margin-top: 0;
  font-size: 0.78rem;
  padding: 0.3rem 0.55rem;
}

.schema-entity-list {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  max-height: 560px;
  overflow-y: auto;
  padding-right: 0.25rem;
}

/* Cabecera de cada dominio (28/08/2026, pedido de Javi: "tres dominios...
   universos y fuentes, Aprendizaje y Consultas"). Solo texto, sin
   checkbox — agrupa visualmente las tablas de abajo, no es seleccionable
   por sí misma. */
.schema-domain-heading {
  margin: 0.4rem 0 0.15rem;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.2rem;
}

.schema-domain-heading:first-child {
  margin-top: 0;
}

.schema-entity-item {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  cursor: pointer;
}

.schema-entity-item input {
  margin: 0;
}

.schema-entity-item span:last-of-type {
  flex: 1 1 auto;
}

/* "+rel" por tabla (28/08/2026, pedido de Javi: antes era un único botón
   global "+ Relacionadas" que expandía TODO lo marcado a la vez — ahora
   cada tabla tiene el suyo, para añadir solo las relacionadas con ESA. */
.schema-entity-related-btn {
  flex-shrink: 0;
  margin-top: 0;
  font-size: 0.68rem;
  padding: 0.15rem 0.4rem;
  cursor: pointer;
}

.schema-canvas-col {
  flex: 1 1 auto;
  min-width: 420px;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.schema-canvas-wrap {
  /* flex: none a propósito (28/08/2026): con "flex: 1 1 auto" el propio
     flexbox se peleaba con el tirador de redimensionar en el eje
     horizontal (el ancho es el eje principal de la fila y flex-grow lo
     recalculaba por encima de lo que arrastrabas) — el vertical sí
     funcionaba porque la altura no es el eje que controla flex-grow aquí.
     Sin flex-grow/shrink, "resize" manda en los dos sentidos sin que nadie
     se lo pise. */
  flex: none;
  position: relative;
  /* Antes 900px fijos: con .schema-canvas-col ya ensanchado (ver
     main.is-wide-tab) eso dejaba un hueco enorme sin usar a la derecha
     (28/08/2026, "quedan áreas muy grandes vacías"). 100% lo hace
     arrancar ocupando todo el ancho disponible de la columna; el tirador
     de "resize" lo sigue pudiendo encoger hasta min-width. */
  width: 100%;
  height: 560px;
  min-width: 420px;
  min-height: 320px;
  /* Tope al ensanchar (28/08/2026, pedido de Javi): al ser "flex: none" el
     lienzo no participa en el reparto de flexbox, así que sin este límite
     el tirador de "resize" lo dejaba crecer por encima del ancho real que
     le queda a .schema-canvas-col y se comía el panel de "Detalle" de al
     lado. 100% aquí es 100% del contenedor (.schema-canvas-col), que sí
     respeta el sitio fijo reservado para el panel — así que el arrastre
     simplemente deja de moverse justo en ese borde, sin taparlo nunca. */
  max-width: 100%;
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: auto;
  background: var(--card-bg);
  resize: both;
  /* Arrastre con el botón central del ratón (09/09/2026) — el cursor de
     "mano abierta" avisa de que se puede arrastrar; ".is-panning" (puesto
     y quitado en JS mientras se mantiene pulsada la rueda) lo cambia a
     "mano cerrada" durante el propio arrastre, igual que Figma/Google
     Maps. */
  cursor: grab;
}

.schema-canvas-wrap.is-panning {
  cursor: grabbing;
  /* Evita seleccionar texto de las tarjetas sin querer mientras se
     arrastra el lienzo con el ratón. */
  user-select: none;
}

.schema-entity-card {
  position: absolute;
  width: 210px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
  cursor: grab;
  user-select: none;
  font-size: 0.78rem;
  /* display:flex (28/08/2026, tirador de redimensionar): con altura
     automática esto se comporta igual que antes (cabecera + columnas
     apiladas, alto = suma de ambas). Solo cambia algo cuando Javi fija un
     alto a mano con el tirador — entonces "overflow: hidden" es lo que
     hace que la tarjeta no crezca por su cuenta más allá de ese alto. */
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.schema-entity-card.is-dragging,
.schema-entity-card.is-resizing {
  z-index: 5;
}

.schema-entity-card.is-dragging {
  cursor: grabbing;
}

.schema-entity-card.is-selected {
  outline: 2px solid var(--accent);
}

/* Tirador de la esquina inferior derecha (28/08/2026, pedido de Javi:
   "cada caja de entidad que se pueda modificar la altura y la anchura
   con un tirador"). Rayitas diagonales dibujadas con gradiente, igual de
   discreto en claro y oscuro sin depender de una imagen. */
.schema-entity-card-resize-handle {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 14px;
  height: 14px;
  cursor: nwse-resize;
  background:
    linear-gradient(135deg, transparent 0 40%, var(--muted) 40% 55%, transparent 55% 100%),
    linear-gradient(135deg, transparent 0 65%, var(--muted) 65% 80%, transparent 80% 100%);
}

.schema-entity-card-header {
  padding: 0.4rem 0.55rem;
  border-radius: 8px 8px 0 0;
  font-weight: 600;
  color: #fff;
  /* Título a la izquierda, contador de filas a la derecha (09/09/2026,
     pedido de Javi). */
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
}

.schema-entity-card-header-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.schema-entity-card-header-count {
  flex-shrink: 0;
  font-weight: 400;
  font-size: 0.78rem;
  opacity: 0.85;
}

.schema-entity-card-columns {
  padding: 0.35rem 0.55rem;
  max-height: 150px;
  overflow-y: auto;
  /* flex:1 + min-height:0 (28/08/2026, tirador de redimensionar): cuando
     la tarjeta tiene un alto fijado a mano (más que la cabecera + 150px),
     esto es lo que deja que las columnas ocupen el hueco de más en vez de
     quedarse en 150px con espacio en blanco debajo. Sin min-height:0 un
     hijo flex nunca se encoge por debajo de su contenido, y el scroll no
     llegaría a activarse cuando el alto fijado es MENOR que el contenido. */
  flex: 1 1 auto;
  min-height: 0;
}

.schema-entity-card-column {
  display: flex;
  justify-content: space-between;
  gap: 0.4rem;
  padding: 0.1rem 0;
  color: var(--muted);
  white-space: nowrap;
}

.schema-entity-card-column.is-key {
  color: var(--fg);
  font-weight: 600;
}

.schema-entity-card-column-icon {
  flex-shrink: 0;
}

/* Insignias PK/FK y marca de obligatorio (10/09/2026, pedido de Javi:
   que se vea claro qué campos son clave primaria, clave foránea (puede
   ser las dos cosas a la vez, ver rol_nodo_menu/usuario_rol) y cuáles
   son obligatorios -- antes solo había un emoji ambiguo que ocultaba el
   caso de ser las dos cosas a la vez). */
.schema-col-badge {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 700;
  line-height: 1;
  padding: 0.12rem 0.28rem;
  border-radius: 3px;
  margin-right: 0.3rem;
  letter-spacing: 0.02em;
  vertical-align: middle;
}

.schema-col-badge-pk {
  background: var(--accent);
  color: #fff;
}

.schema-col-badge-fk {
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
}

.schema-col-required {
  color: var(--accent);
  font-weight: 700;
  margin-left: 0.15rem;
}

/* Tabla "fantasma" (28/08/2026, pedido de Javi: "ver los valores de las
   listas cerradas aunque no se puedan editar"): borde discontinuo y
   cabecera gris en vez del color por tabla, para que se note a simple
   vista que no es una tabla real de la base de datos. */
.schema-entity-card.is-ghost {
  border-style: dashed;
  border-color: var(--muted);
}

.schema-entity-card.is-ghost .schema-entity-card-header {
  background: var(--muted);
  font-style: italic;
}

/* Indicadores padre/hijo en cada línea de relación (28/08/2026, pedido de
   Javi). Antes eran <marker> de SVG colocados en los extremos exactos de
   la línea — que son el CENTRO de cada tarjeta, tapado por su fondo
   opaco, así que nunca se veían. Ahora son un <circle> (padre) y un
   <polygon> (hija, con forma de flecha) que se calculan y colocan a mano
   justo donde la línea sale del borde de cada tarjeta — ver
   drawSchemaRelationLines en app.js — con su propia opacidad, sin heredar
   la de la línea (que la dejaría demasiado tenue).*/
.schema-rel-parent-marker,
.schema-rel-child-marker {
  fill: var(--accent);
}

/* Modal "diagrama de acciones" al hacer doble clic en una tarea
   (29/08/2026, pedido de Javi: "que se abra un diagrama de acciones con
   lo que se ejecuta realmente en esa tarea"). Reutiliza la misma chapa de
   modal que Esquema (.schema-modal-overlay/.schema-modal en el HTML,
   línea de flujo vertical con círculos numerados y flechas propia de
   aquí). */
.learn-flow-action-modal {
  width: 560px;
}

/* Formulario de edición (tarea/fase/conexión), dentro del modal genérico
   reutilizado de Esquema (.schema-modal). */
.learn-flow-edit-modal {
  width: 620px;
}

/* Etiqueta "X a Y" en el punto medio de cada línea (28/08/2026, pedido de
   Javi). El "stroke" del mismo color que el fondo del lienzo, dibujado
   ANTES que el relleno (paint-order), hace de halo — así el texto se lee
   igual de bien encima de una línea o cruzando otra tarjeta, sin tapar
   nada por completo como haría un <rect> de fondo. */
.schema-rel-cardinality {
  font-size: 10px;
  font-family: inherit;
  fill: var(--fg);
  stroke: var(--card-bg);
  stroke-width: 3px;
  paint-order: stroke fill;
  text-anchor: middle;
  dominant-baseline: middle;
}

/* Antes era la tercera columna de .schema-layout, a la derecha del
   lienzo; Javi pidió que apareciera debajo de las flechas de mover en su
   lugar (28/08/2026) — ahora vive dentro de .schema-canvas-col, así que
   ya no necesita un ancho de columna fijo (flex: 0 0 260px), solo separarse
   visualmente de las flechas y no crecer sin límite si la tabla tiene
   muchas columnas. */
.schema-detail-panel {
  border-top: 1px solid var(--border);
  padding-top: 0.75rem;
  max-height: 320px;
  overflow-y: auto;
}

.schema-detail-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}

.schema-detail-header h2 {
  margin: 0;
  font-size: 1rem;
}

.schema-detail-header-actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.schema-detail-header button {
  margin-top: 0;
  font-size: 0.72rem;
  padding: 0.25rem 0.5rem;
  flex-shrink: 0;
}

.schema-detail-table {
  color: var(--accent);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.85rem;
}

.schema-detail-columns {
  margin-top: 0.6rem;
  border-top: 1px solid var(--border);
  padding-top: 0.5rem;
}

.schema-detail-column {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.82rem;
  padding: 0.2rem 0;
  border-bottom: 1px solid var(--border);
}

.schema-detail-column-type {
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.75rem;
}

/* Modo "Editar nombres" del panel de Detalle (28/08/2026, pedido de
   Javi): el nombre de la tabla y el de cada columna se convierten en
   estos inputs en vez de texto suelto. Mismo tamaño de letra que el
   texto que sustituyen, para que el cambio de modo no salte visualmente. */
.schema-detail-table-input {
  width: 100%;
  box-sizing: border-box;
  padding: 0.3rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--accent);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.85rem;
}

.schema-detail-column-label-input {
  flex: 1 1 auto;
  min-width: 0;
  box-sizing: border-box;
  padding: 0.15rem 0.35rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg);
  color: var(--fg);
  font-size: 0.82rem;
  font-family: inherit;
}

.schema-detail-edit-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

/* Importante: si aquí se fija "display" sin más, el
   modal se ve siempre — vacío, tapando la página entera — desde que carga,
   y el botón de cerrar tampoco sirve (bug real, visto por Javi 27/08/2026). */
.schema-modal-overlay[hidden] {
  display: none;
}

.schema-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 20;
  padding: 1.5rem;
}

.schema-modal {
  position: relative;
  background: var(--bg);
  border-radius: 10px;
  border: 1px solid var(--border);
  max-width: 90vw;
  max-height: 85vh;
  width: 900px;
  padding: 1.25rem 1.5rem;
  overflow-y: auto;
}

/* Tiras invisibles en los cuatro bordes (28/08/2026, pedido de Javi):
   arrastrarlas cambia el tamaño del panel en cualquier dirección. La
   primera vez que se arrastra una, el JS pasa el panel de "centrado por
   flexbox" a posición fija con su ancho/alto exactos — a partir de ahí el
   tamaño y la posición quedan en tus manos. */
.schema-modal-resize-handle {
  position: absolute;
  z-index: 5;
}

.schema-modal-resize-handle.edge-top,
.schema-modal-resize-handle.edge-bottom {
  left: 10px;
  right: 10px;
  height: 8px;
  cursor: ns-resize;
}

.schema-modal-resize-handle.edge-top {
  top: -4px;
}

.schema-modal-resize-handle.edge-bottom {
  bottom: -4px;
}

.schema-modal-resize-handle.edge-left,
.schema-modal-resize-handle.edge-right {
  top: 10px;
  bottom: 10px;
  width: 8px;
  cursor: ew-resize;
}

.schema-modal-resize-handle.edge-left {
  left: -4px;
}

.schema-modal-resize-handle.edge-right {
  right: -4px;
}

.schema-modal-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.schema-modal-toolbar .hint {
  margin: 0;
}

.schema-modal-toolbar button {
  margin-top: 0;
  font-size: 0.78rem;
  padding: 0.3rem 0.6rem;
  flex-shrink: 0;
}

.schema-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.schema-modal-header h2 {
  margin: 0;
}

.schema-modal-close {
  margin-top: 0;
  background: none;
  color: var(--muted);
  border: none;
  font-size: 1.1rem;
  padding: 0.2rem 0.5rem;
}

/* Altura de las filas y anchura de las columnas, ambas arrastrables
   (28/08/2026, pedido de Javi). La altura es UNA sola tira arrastrable
   para toda la tabla (--schema-row-pad, en px) porque lo que pidió fue
   "la altura", en singular — no el alto de cada fila por separado. La
   anchura, en cambio, la pidió "de cada columna", así que cada `<th>`
   lleva su propio tirador a la derecha; para que eso funcione, la tabla
   pasa a table-layout:fixed con un <colgroup> que fija el ancho inicial
   de cada columna en JS (renderSchemaModalTable). */
.schema-modal-row-height-handle {
  height: 10px;
  margin-top: 0.5rem;
  border-radius: 4px;
  background: var(--card-bg);
  border: 1px dashed var(--border);
  cursor: ns-resize;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.6rem;
  letter-spacing: 0.02em;
  color: var(--muted);
  user-select: none;
}

.schema-modal-body {
  overflow-x: auto;
  margin-top: 0.4rem;
}

.schema-modal-body table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.78rem;
  table-layout: fixed;
}

.schema-modal-body th,
.schema-modal-body td {
  border: 1px solid var(--border);
  padding: calc(0.3rem + var(--schema-row-pad, 0px)) 0.5rem;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  position: relative;
}

/* En cuanto la fila tiene algo de aire extra, aprovecharlo: el texto
   envuelve en vez de cortarse con "…" (si no, el espacio ganado con la
   altura no serviría para ver más contenido). */
.schema-modal-body.is-tall th,
.schema-modal-body.is-tall td {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  word-break: break-word;
}

.schema-modal-body th {
  background: var(--card-bg);
  position: sticky;
  top: 0;
}

.schema-col-resize-handle {
  position: absolute;
  top: 0;
  right: -3px;
  width: 6px;
  height: 100%;
  cursor: col-resize;
  z-index: 2;
}

.schema-col-resize-handle:hover,
.schema-col-resize-handle.is-resizing {
  background: var(--accent);
  opacity: 0.5;
}


#schema-canvas {
  position: relative;
  width: 1600px;
  height: 1100px;
  transform-origin: 0 0;
}

#schema-canvas-svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 1600px;
  height: 1100px;
  pointer-events: none;
  transform-origin: 0 0;
  overflow: visible; /* 02/10/2026: líneas también hacia coordenadas negativas (lienzo infinito) */
}

#schema-canvas-svg line,
#schema-canvas-svg polyline {
  stroke: var(--accent);
  stroke-width: 1.5;
  opacity: 0.6;
}

.schema-db-info {
  margin: -0.5rem 0 0.75rem;
  color: var(--muted, #6b7280);
  font-size: 0.85rem;
}

/* Tamaño justo (26/09/2026): clic derecho en el título de una tarjeta, o
   botón "ajustar todas". La caja crece lo necesario para que se vea toda
   su información, sin cortar nombres ni columnas. */
.schema-entity-card.is-autoajuste {
  width: max-content;
  min-width: 180px;
  height: auto !important;
}
.schema-entity-card.is-autoajuste .schema-entity-card-columns {
  max-height: none;
  overflow: visible;
}
.schema-entity-card.is-autoajuste .schema-entity-card-header-label,
.schema-entity-card.is-autoajuste .schema-entity-card-column span {
  overflow: visible;
  text-overflow: clip;
  white-space: nowrap;
}
.schema-entity-card.is-autoajuste .schema-entity-card-column {
  gap: 1.5rem;
}

/* Crear relación arrastrando (28/09/2026, atlas-bd) */
.schema-conector { font-style: normal; cursor: crosshair; color: var(--accent, #2a7); opacity: 0.25; flex-shrink: 0; padding: 0 0.15rem; }
.schema-entity-card-column:hover .schema-conector { opacity: 1; }
.schema-conector-capa { position: fixed; inset: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 1000; }
.schema-conector-capa line { stroke: var(--accent, #2a7); stroke-width: 2; stroke-dasharray: 6 4; }
.schema-conector-destino { outline: 2px solid var(--accent, #2a7); outline-offset: 1px; border-radius: 4px; }
body.schema-conectando, body.schema-conectando * { cursor: crosshair !important; user-select: none; }

/* Clic en una línea de relación (28/09/2026, atlas-bd) */
#schema-canvas-svg .schema-rel-franja { stroke: transparent; stroke-width: 12; opacity: 1; pointer-events: stroke; cursor: pointer; }
#schema-canvas-svg .schema-rel-franja:hover { stroke: var(--accent); opacity: 0.15; }
#schema-canvas-svg polyline.is-elegida { stroke-width: 3.5; opacity: 1; }
/* El lienzo de tarjetas va encima del SVG: se deja "atravesable" para que
   las líneas reciban el clic; las tarjetas siguen recibiéndolo normal. */
#schema-canvas { pointer-events: none; }
#schema-canvas .schema-entity-card { pointer-events: auto; }

/* 23/10/2026 (atlas-bd): grupos de campos dentro de una tarjeta */
.schema-grupo-fila { font-weight: 700; background: rgba(47, 125, 85, 0.07); cursor: pointer; color: #1f5c3d; }
.schema-grupo-fila:hover { background: rgba(47, 125, 85, 0.14); }
.schema-grupo-fila .schema-grupo-n { font-weight: 500; opacity: 0.7; }
/* 23/10/2026: ⇄ traer las tablas relacionadas (en la cabecera de cada tarjeta) */
.schema-card-rel { margin-left: 6px; padding: 0 6px; border: 1px solid rgba(255,255,255,.7); border-radius: 6px; background: rgba(255,255,255,.2); color: inherit; font: inherit; font-size: 11px; line-height: 18px; cursor: pointer; flex: none; }
.schema-card-rel:hover { background: rgba(255,255,255,.4); }
.schema-card-rel.todas { opacity: .55; }
