/* ==========================================================================
   workspace.css — GIS Workspace (MapLibre GL JS)
   Usa tokens del design-system.css y Bootstrap 5.
   ========================================================================== */

/* ── Layout principal: panel + mapa a pantalla completa ───────────────────── */

.workspace-layout {
  display: flex;
  height: calc(100vh - var(--navbar-height, 56px));
  overflow: hidden;
  position: relative;
}

/* Sin navbar (body.no-navbar, ver layout_detector.py hide_navbar) — el mapa
   ocupa el 100% del viewport en vez de restar la altura del navbar oculto.
   navbar.css:56-58 aplica "body { padding-top: navbar-height }" como
   fallback SIEMPRE (no solo cuando el navbar existe) — sin esta anulación
   queda un espacio en blanco del alto del navbar aunque este no se renderice. */
body.no-navbar {
  padding-top: 0;
}

body.no-navbar .workspace-layout {
  height: 100vh;
}

/* ── Panel lateral ─────────────────────────────────────────────────────────── */

.workspace-panel {
  width: 300px;
  min-width: 260px;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  background: var(--color-surface, #ffffff);
  border-right: 1px solid var(--color-outline-variant, #e0e0e0);
  overflow: hidden;
  transition:
    width 0.25s ease,
    min-width 0.25s ease;
  z-index: 10;
}

/* Panel colapsado */
.workspace-layout.panel-collapsed .workspace-panel {
  width: 0;
  min-width: 0;
  border-right: none;
}

.panel-header {
  padding: 0.75rem 0.875rem;
  border-bottom: 1px solid var(--color-outline-variant, #e0e0e0);
  background: var(--color-surface, #ffffff);
}

.workspace-title {
  font-size: 0.88rem;
  max-width: 180px;
}

.panel-section {
  padding: 0.75rem 0.875rem;
  border-bottom: 1px solid var(--color-outline-variant, #e0e0e0);
}

.panel-footer {
  padding: 0.4rem 0.875rem;
  border-top: 1px solid var(--color-outline-variant, #e0e0e0);
  background: var(--color-surface-variant, #f5f5f5);
  font-size: 0.72rem;
}

/* ── Upload zone ───────────────────────────────────────────────────────────── */

/* Header de sección colapsable del panel de capas ("Importar archivo" /
   "Dibujar en", ver _setupCollapsiblePanelSection en workspace-layers.js) --
   mismo criterio visual que .dataset-group-header (chevron + d-none), pero
   con estilo propio porque estas dos secciones son de primer nivel, no
   anidadas dentro de la lista de capas. */
.panel-section-header {
  cursor: pointer;
  padding: 0.25rem 0;
  user-select: none;
}

.panel-section-header:hover {
  color: var(--color-primary, #1a73e8);
}

.panel-section-toggle-icon {
  font-size: 11px;
  transition: transform 0.15s;
}

.upload-zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  padding: 1rem 0.5rem;
  border: 2px dashed var(--color-primary, #1a73e8);
  border-radius: var(--radius-md, 8px);
  background: var(--color-primary-container, #e8f0fe);
  text-align: center;
  cursor: pointer;
  transition:
    background 0.15s,
    border-color 0.15s;
}

.upload-zone:hover,
.upload-zone.drag-over {
  background: color-mix(in srgb, var(--color-primary, #1a73e8) 10%, transparent);
  border-color: var(--color-primary, #1a73e8);
}

[data-bs-theme='dark'] .upload-zone {
  background: rgba(66, 133, 244, 0.1);
  border-color: rgba(66, 133, 244, 0.5);
}

/* ── Lista de capas ────────────────────────────────────────────────────────── */

.layer-item {
  padding: 0.5rem 0.25rem;
  border-bottom: 1px solid var(--color-outline-variant, #f0f0f0);
  border-radius: var(--radius-sm, 4px);
  transition: background 0.1s;
  cursor: pointer; /* clic en la fila (fuera de .layer-actions) selecciona la capa */
}

.layer-item:hover {
  background: var(--color-surface-variant, #f5f5f5);
}

.layer-item.layer-hidden {
  opacity: 0.5;
}

/* Feedback visual mientras se arrastra una fila para reordenar (ver
   _onLayerDragStart, workspace-layers.js) */
.layer-item.ws-layer-dragging {
  opacity: 0.4;
}

.ws-layer-drag-handle:active {
  cursor: grabbing;
}

/* Capa seleccionada (clic en la fila del panel -- ver toggleLayerSelection,
   workspace-layers.js; independiente de la selección de features del mapa) */
.layer-item.layer-selected {
  background: rgba(26, 115, 232, 0.08);
  border-left: 3px solid var(--color-primary, #1a73e8);
  padding-left: calc(0.25rem - 3px);
}

.layer-color-dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* Botones xs (no existen en BS5 por defecto) */
.btn-xs {
  padding: 0.15rem 0.4rem;
  font-size: 0.75rem;
  line-height: 1.4;
  border-radius: var(--radius-sm, 4px);
}

.dropdown-toggle-no-caret::after {
  display: none;
}

/* ── Contenedor del mapa ───────────────────────────────────────────────────── */

.workspace-map-container {
  flex: 1;
  position: relative;
  overflow: hidden;
}

#map {
  width: 100%;
  height: 100%;
}

/* mapbox-gl-draw usa clase .mapboxgl-ctrl (Mapbox naming), no .maplibregl-ctrl.
   MapLibre restaura pointer-events solo para .maplibregl-ctrl → los botones
   de draw heredan pointer-events:none del contenedor y los clicks van al canvas.
   Fix: restaurar explicitamente para .mapboxgl-ctrl dentro de contenedores MapLibre.
   Ref: https://maplibre.org/maplibre-gl-js/docs/API/interfaces/IControl/ */
.maplibregl-ctrl-top-left > .mapboxgl-ctrl,
.maplibregl-ctrl-top-right > .mapboxgl-ctrl,
.maplibregl-ctrl-bottom-left > .mapboxgl-ctrl,
.maplibregl-ctrl-bottom-right > .mapboxgl-ctrl {
  pointer-events: visiblePainted;
}

/* Diagnóstico via getComputedStyle confirmó:
   - .mapboxgl-ctrl-group → background: rgba(0,0,0,0) [transparente] → mapa oscuro se filtra
   - .mapbox-gl-draw_ctrl-draw-btn → background: rgb(107,107,107) [gris browser]
                                    + border: 1.6px outset rgba(0,0,0,0.9) [borde nativo]
   Los controles nativos MapLibre tienen:
   - grupo → rgb(255,255,255) + box-shadow: 0 0 0 2px rgba(0,0,0,.1)
   - botón → rgba(0,0,0,0) [transparente, sin borde] */
.mapboxgl-ctrl-group {
  background: rgb(255, 255, 255);
  box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.1);
}
.mapbox-gl-draw_ctrl-draw-btn {
  background-color: transparent;
  border: none;
}

/* ── Panel de propiedades del feature ─────────────────────────────────────── */

.feature-props-panel {
  position: absolute;
  bottom: 2.5rem;
  right: 0.75rem;
  z-index: 200;
  width: 340px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--color-surface, #ffffff);
  border: 1px solid var(--color-outline-variant, #e0e0e0);
  border-radius: var(--radius-md, 8px);
  padding: 0.75rem;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  font-size: 0.8rem;
}

/* table-layout: fixed + ancho de columna fijo en el nombre del campo --
   sin esto, un nombre de campo largo (ej. "NUM_PRE_ANT_COLINDANTE", típico
   de un esquema importado de un GDB) hace que el navegador reduzca la
   columna del input a un ancho casi nulo (table-layout: auto reparte el
   espacio según el contenido más largo de cada columna) -- el input seguía
   siendo funcional pero visualmente "comprimido" hasta ser inusable. */
#propsTable {
  table-layout: fixed;
  width: 100%;
}

#propsTable td:first-child {
  width: 40%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#propsTable td:last-child {
  width: 60%;
}

/* #featurePropsPanel es una "ventana" flotante real: movible desde su
   encabezado y redimensionable desde cualquiera de sus 4 bordes/4 esquinas
   (ver initFeaturePropsPanelWindow, workspace-editing.js). La clase
   .feature-props-panel comparte estilo base con #bulkSelectionBar (que NO
   es movible/redimensionable, se queda con max-height:320px) -- por eso
   este override va sobre el ID, no sobre la clase. */
#featurePropsPanel {
  max-height: min(80vh, 640px);
  min-width: 260px;
  min-height: 160px;
  box-sizing: border-box;
  overflow: auto;
}

#featurePropsPanelHeader {
  cursor: move;
  user-select: none;
}

.ws-panel-resize-handle {
  position: absolute;
  z-index: 5;
}

.ws-panel-resize-n,
.ws-panel-resize-s {
  left: 8px;
  right: 8px;
  height: 6px;
}
.ws-panel-resize-n {
  top: -3px;
  cursor: n-resize;
}
.ws-panel-resize-s {
  bottom: -3px;
  cursor: s-resize;
}

.ws-panel-resize-e,
.ws-panel-resize-w {
  top: 8px;
  bottom: 8px;
  width: 6px;
}
.ws-panel-resize-e {
  right: -3px;
  cursor: e-resize;
}
.ws-panel-resize-w {
  left: -3px;
  cursor: w-resize;
}

.ws-panel-resize-ne,
.ws-panel-resize-nw,
.ws-panel-resize-se,
.ws-panel-resize-sw {
  width: 14px;
  height: 14px;
}
.ws-panel-resize-ne {
  top: -4px;
  right: -4px;
  cursor: ne-resize;
}
.ws-panel-resize-nw {
  top: -4px;
  left: -4px;
  cursor: nw-resize;
}
.ws-panel-resize-se {
  bottom: -4px;
  right: -4px;
  cursor: se-resize;
}
.ws-panel-resize-sw {
  bottom: -4px;
  left: -4px;
  cursor: sw-resize;
}

[data-bs-theme='dark'] .feature-props-panel {
  background: var(--bs-body-bg);
  border-color: var(--bs-border-color);
}

/* Tooltip flotante de "Medir distancia"/"Medir área" -- sigue al cursor
   mientras se mide (ver _updateMeasureTooltip, workspace-editing.js).
   closeButton:false/closeOnClick:false en el Popup, así que no necesita
   los estilos de cierre del picker de features superpuestos. Mismo color
   que la línea/vértices de la regla en el mapa (MEASURE_COLOR, #ff5722)
   para que quede claro que son la misma herramienta. */
.ws-measure-tooltip .maplibregl-popup-content {
  padding: 4px 10px;
  border-radius: 8px;
  background: #ff5722;
  color: #fff;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.3;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
}

.ws-measure-tooltip .maplibregl-popup-tip {
  display: none;
}

.ws-measure-tooltip-sub {
  font-weight: 400;
  opacity: 0.85;
}

/* Maqueta CSS del layout de impresión (#printLayoutPreview, ver
   _updatePrintPreview en workspace-print.js) -- NO es un render real, solo
   una previsualización aproximada con badges posicionados por anclaje
   (mismos 8 nombres que _ANCHORS en print_layout_service.py) para que el
   usuario pueda "cuadrar" el layout sin pagar el costo de generar un PDF
   real en cada cambio. */
.ws-print-preview {
  position: relative;
  width: 100%;
  aspect-ratio: 1.414 / 1; /* default A4 horizontal -- reajustado por JS según tamaño/orientación */
  border: 1px solid var(--bs-border-color, #dee2e6);
  background: var(--color-surface-variant, #f5f5f5);
  border-radius: var(--radius-sm, 4px);
  overflow: hidden;
}

.ws-print-preview-badge {
  position: absolute;
  font-size: 0.62rem;
  line-height: 1;
  padding: 3px 6px;
  border-radius: 3px;
  background: rgba(13, 110, 253, 0.85);
  color: #fff;
  white-space: nowrap;
  transition: top 0.15s, left 0.15s, right 0.15s, bottom 0.15s, transform 0.15s, opacity 0.15s;
}

.ws-print-preview-badge.is-disabled {
  opacity: 0.2;
}

.ws-print-preview-badge.anchor-top_left {
  top: 6px;
  left: 6px;
}
.ws-print-preview-badge.anchor-top_center {
  top: 6px;
  left: 50%;
  transform: translateX(-50%);
}
.ws-print-preview-badge.anchor-top_right {
  top: 6px;
  right: 6px;
}
.ws-print-preview-badge.anchor-center_left {
  top: 50%;
  left: 6px;
  transform: translateY(-50%);
}
.ws-print-preview-badge.anchor-center_right {
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
}
.ws-print-preview-badge.anchor-bottom_left {
  bottom: 6px;
  left: 6px;
}
.ws-print-preview-badge.anchor-bottom_center {
  bottom: 6px;
  left: 50%;
  transform: translateX(-50%);
}
.ws-print-preview-badge.anchor-bottom_right {
  bottom: 6px;
  right: 6px;
}

/* #bulkSelectionBar reusa la clase .feature-props-panel (mismo estilo de
   tarjeta) pero SIEMPRE arriba centrado -- deliberadamente NO abajo a la
   derecha como #featurePropsPanel, para que ambos paneles puedan estar
   visibles a la vez sin superponerse (ver _updateSelectionIndicators,
   workspace-layers.js, que ahora muestra esta barra para cualquier
   selección, incluida una sola geometría clickeada normalmente). */
#bulkSelectionBar {
  bottom: auto;
  top: 0.75rem;
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  width: auto;
  min-width: 260px;
  max-width: min(90vw, 420px);
}

/* Rectángulo de arrastre del modo "Seleccionar features" (box-select, ver
   _onSelectMouseDown en workspace-editing.js) -- posicionado en píxeles de
   pantalla sobre map.getContainer(), no en coordenadas del mapa. */
.ws-select-box-overlay {
  position: absolute;
  z-index: 100;
  border: 1px dashed var(--color-primary-500, #0d6efd);
  background: rgba(13, 110, 253, 0.15);
  pointer-events: none;
}

/* Segmento "goma elástica" de "Medir distancia"/"Medir área" (último punto
   puesto -> cursor, ver _updateMeasureRubberBand en workspace-editing.js) --
   MISMA técnica que .ws-select-box-overlay (overlay posicionado en píxeles
   de pantalla sobre map.getContainer(), fuera del pipeline de renderizado
   WebGL de MapLibre) en vez de una fuente GeoJSON actualizada por
   setData() en cada mousemove -- ese primer enfoque (fuente GeoJSON) era
   la causa real del lag reportado: cada setData() dispara un ciclo
   completo de re-tiling + reprocesamiento en el source de MapLibre, caro
   de hacer decenas de veces por segundo. Un <svg> posicionado por CSS es
   una operación de DOM, no de WebGL -- mismo motivo por el que el
   rectángulo de selección (ya probado fluido en esta app) nunca usó una
   fuente GeoJSON para su propio overlay en tiempo real. */
.ws-measure-rubberband {
  position: absolute;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  overflow: visible;
}

.ws-measure-rubberband-line {
  fill: none;
  stroke: #ff5722;
  stroke-width: 2;
  stroke-dasharray: 4 4;
}

/* ── Panel de chat con IA (tercera columna, colapso independiente del panel de capas) ── */

.workspace-chat-panel {
  border-right: none;
  border-left: 1px solid var(--color-outline-variant, #e0e0e0);
}

/* Colapso independiente: 'chat-collapsed' en #workspaceApp, no 'panel-collapsed'
   (ese ya colapsa el panel de capas — deben poder ocultarse por separado). */
.workspace-layout.chat-collapsed .workspace-chat-panel {
  width: 0;
  min-width: 0;
  border-left: none;
}

.workspace-chat-fab {
  position: absolute;
  bottom: 1rem;
  right: 1rem;
  z-index: 500;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}

/* Botón flotante para volver a mostrar el panel de capas cuando está
   colapsado — vive en .workspace-map-container (fuera de .workspace-panel),
   a diferencia de los botones que lo colapsan (btnTogglePanel/Desktop), que
   están DENTRO del panel y por eso quedan inaccesibles una vez colapsado. */
.workspace-panel-fab {
  position: absolute;
  bottom: 1rem;
  left: 1rem;
  z-index: 500;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}

.chat-msg {
  max-width: 90%;
  padding: 0.5rem 0.75rem;
  border-radius: var(--radius-md, 8px);
  margin-bottom: 0.5rem;
  font-size: 0.82rem;
  line-height: 1.4;
  word-break: break-word;
}

.chat-msg-user {
  background: var(--color-primary-500, #0d6efd);
  color: #fff;
  margin-left: auto;
}

.chat-msg-assistant {
  background: var(--color-surface-variant, #f1f3f5);
  color: var(--color-on-surface, #212529);
  margin-right: auto;
}

.chat-msg-tool {
  background: transparent;
  border: 1px dashed var(--color-outline-variant, #dee2e6);
  color: var(--color-on-surface, #6c757d);
  font-size: 0.72rem;
  margin-right: auto;
  max-width: 100%;
}

/* Markdown-lite renderizado por _renderMarkdownLite() en workspace-chat.js
   -- el modelo (Claude Opus) genera markdown por defecto (negritas, listas,
   código inline para nombres de capa) sin que se le pida explícitamente. */
.chat-msg p {
  margin: 0 0 0.5rem 0;
}

.chat-msg ul {
  margin: 0 0 0.5rem 0;
  padding-left: 1.15rem;
}

.chat-msg p:last-child,
.chat-msg ul:last-child {
  margin-bottom: 0;
}

.chat-msg li {
  margin-bottom: 0.2rem;
}

.chat-msg li:last-child {
  margin-bottom: 0;
}

.chat-msg strong {
  font-weight: 600;
}

.chat-msg code {
  /* Overlay gris neutro semitransparente: se ve bien tanto sobre el fondo
     claro de .chat-msg-assistant como sobre el azul de .chat-msg-user, y no
     necesita override para dark mode (--color-surface-variant se oscurece
     ahí, ver design-system.css) porque no depende de blanco/negro fijos. */
  background: rgba(127, 127, 127, 0.18);
  padding: 0.1rem 0.35rem;
  border-radius: 4px;
  font-size: 0.85em;
  font-family: var(--font-family-mono);
}

.chat-msg a {
  /* color: inherit + subrayado en vez de un azul fijo: funciona sobre
     cualquier fondo de burbuja (gris claro del asistente, azul del usuario)
     sin necesitar override de dark mode, mismo criterio que .chat-msg code. */
  color: inherit;
  text-decoration: underline;
  font-weight: 600;
}

.chat-msg a:hover,
.chat-msg a:focus {
  opacity: 0.85;
}

/* ── Responsive ───────────────────────────────────────────────────────────── */

@media (max-width: 767.98px) {
  .workspace-panel {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    width: 85vw;
    max-width: 320px;
    box-shadow: 4px 0 20px rgba(0, 0, 0, 0.18);
  }

  .workspace-layout.panel-collapsed .workspace-panel {
    width: 0;
    min-width: 0;
  }

  /* El chat comparte .workspace-panel (position:absolute; left:0) — en mobile
     debe quedar anclado a la DERECHA para no superponerse al panel de capas. */
  .workspace-chat-panel {
    left: auto;
    right: 0;
    box-shadow: -4px 0 20px rgba(0, 0, 0, 0.18);
  }

  .workspace-layout.chat-collapsed .workspace-chat-panel {
    width: 0;
    min-width: 0;
  }
}

/* ── Dark mode overrides ───────────────────────────────────────────────────── */

[data-bs-theme='dark'] .workspace-panel {
  background: var(--bs-body-bg);
  border-right-color: var(--bs-border-color);
}

[data-bs-theme='dark'] .panel-header,
[data-bs-theme='dark'] .panel-footer {
  background: var(--bs-body-bg);
  border-color: var(--bs-border-color);
}

[data-bs-theme='dark'] .layer-item:hover {
  background: var(--bs-tertiary-bg);
}

/* ── Workspace List page ───────────────────────────────────────────────────── */

.workspace-card {
  transition:
    transform 0.15s,
    box-shadow 0.15s;
  cursor: default;
}

.workspace-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.1) !important;
}

/* ── Typeahead de CRS en el modal "Exportar plano PDF" ────────────────────────
   Mismas reglas que reproject.css/datum-converter.css -- consistencia visual
   del mismo componente reutilizado en varias herramientas. */
.crs-dropdown {
  background: var(--color-surface);
  border-color: var(--color-outline-variant) !important;
}

.crs-option {
  color: var(--color-on-surface);
  transition: background-color 0.1s ease;
  border-bottom: 1px solid var(--color-outline-variant);
}

.crs-option:last-child {
  border-bottom: none;
}

.crs-option.crs-active {
  background-color: var(--color-surface-variant) !important;
}

.crs-option .text-muted {
  color: var(--color-on-surface-variant) !important;
}
