.geoviewer-shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
}

#geoviewer-map {
  min-height: 100vh;
  position: relative;
  overflow: hidden;
  background: #dfe8ef;
}

.geoviewer-notice {
  position: absolute;
  left: 50%;
  bottom: 1rem;
  transform: translateX(-50%);
  z-index: 1000;
  max-width: 80%;
  background: rgba(255, 255, 255, .94);
  padding: .45rem .7rem;
  border-radius: .35rem;
  font-size: .82rem;
  text-align: center;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .15);
  pointer-events: none;
}

.geoviewer-panel {
  max-height: 100vh;
  overflow: auto;
  border-left: 1px solid var(--tblr-border-color, #d9dbde);
  background: var(--tblr-bg-surface, #fff);
}

.geoviewer-coordinates {
  position: absolute;
  z-index: 1000;
  pointer-events: none;
  top: .75rem;
  right: .75rem;
  background: rgba(255, 255, 255, .94);
  padding: .35rem .55rem;
  border-radius: .35rem;
  font-size: .8rem;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .15);
}

.geoviewer-layer-row {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: .35rem;
}

/* BIO-448: collapsible accordion per context-layer group (theme or source). */
.geoviewer-layer-group {
  margin-bottom: .5rem;
}
.geoviewer-layer-group > summary {
  cursor: pointer;
  margin-bottom: .35rem;
}
.geoviewer-layer-group > .geoviewer-layer-row {
  margin-left: 1rem;
}

.geoviewer-legend-row,
.geoviewer-metadata-row {
  display: flex;
  justify-content: space-between;
  gap: .75rem;
  padding: .2rem 0;
  border-bottom: 1px solid var(--tblr-border-color, #d9dbde);
  font-size: .82rem;
}

/* Legend colour chip — fills with the per-band colour the contract emits (viridis
   for the favorability deciles, matching the tile). BIO-384/BIO-432. */
.geoviewer-legend-swatch {
  display: inline-block;
  width: 1rem;
  height: 1rem;
  flex: 0 0 auto;
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, .15);
}

.geoviewer-legend-swatch--nodata {
  background:
    linear-gradient(45deg, #e9ecef 25%, transparent 25%, transparent 75%, #e9ecef 75%),
    #fff;
  background-size: .5rem .5rem;
}

.geoviewer-context-legend-img {
  max-width: 100%;
  height: auto;
}

@media (max-width: 992px) {
  .geoviewer-shell {
    grid-template-columns: 1fr;
    grid-template-rows: 65vh auto;
  }

  #geoviewer-map {
    min-height: 65vh;
  }

  .geoviewer-panel {
    max-height: none;
    border-left: 0;
    border-top: 1px solid var(--tblr-border-color, #d9dbde);
  }
}

/* BIO-560: blocked context layers (authenticated / restricted) rendered as
   non-toggle rows — a lock glyph plus the login link or the license notice. */
.geoviewer-layer-locked {
  display: flex;
  align-items: center;
  gap: .375rem;
  color: var(--tblr-secondary, #6c757d);
}

.geoviewer-layer-locked > summary {
  display: flex;
  align-items: center;
  gap: .375rem;
  cursor: pointer;
  list-style: none;
}

.geoviewer-lock-icon {
  font-size: .85em;
  opacity: .7;
}

.geoviewer-login-link {
  font-size: .8125rem;
  white-space: nowrap;
}

.geoviewer-license-note {
  padding: .25rem 0 .25rem 1.25rem;
}

/* BIO-555 (ADR-018): species-comparison overlays panel + legend. Functional styling
   only; the panel's visual redesign is BIO-561. */
.geoviewer-comparison-add {
  width: 100%;
  padding: .25rem .5rem;
}

.geoviewer-comparison-hint {
  font-style: italic;
}

/* Issue 1363: el aviso de una comparación que llegó COMPUESTA en la dirección y no se pudo dar
   entera. Va ARRIBA del control de agregar —es lo primero que hay que leer al llegar— y con
   separación propia para que no se lea como parte del campo que le sigue. */
.geoviewer-comparison-link-notice {
  margin-bottom: .5rem;
  padding: .375rem .5rem;
  border-left: 3px solid var(--tblr-warning, #f76707);
  background: var(--tblr-bg-surface-secondary, rgba(247, 103, 7, .06));
}

.geoviewer-comparison-row {
  padding: .375rem 0;
  border-top: 1px solid var(--tblr-border-color, #e6e7e9);
}

.geoviewer-comparison-row:first-child {
  border-top: none;
}

.geoviewer-comparison-title {
  font-size: .875rem;
}

.geoviewer-comparison-swatch {
  display: inline-block;
  width: 1.5rem;
  height: .75rem;
  border-radius: 2px;
  border: 1px solid rgba(0, 0, 0, .2);
  flex: 0 0 auto;
}

.geoviewer-comparison-row input[type="range"] {
  flex: 1 1 auto;
}

/* BIO-1364 · la rampa del índice, UNA para la leyenda principal y las de comparación.
   Compacta a propósito: flota sobre el mapa, y diez filas de deciles le robaban altura al objeto
   que el visor vino a mostrar. La barra es el degradado del mismo colormap que pinta la tesela. */
.gv-legend-ramp {
  height: .6rem;
  border-radius: .2rem;
  border: 1px solid var(--tblr-border-color, #d9dbde);
}

.gv-legend-ramp__scale {
  margin-top: .15rem;
}

/* Optional multiply blend to emphasise where favorabilities coincide (BIO-555).

   `.gv-overlay-tile` es la `className` que `buildOverlayTileLayer` le pasa a Leaflet, y Leaflet la
   pone en el **contenedor** de la capa — el mismo elemento que recibe la opacidad. Que sean el
   mismo elemento no es casual y es lo que hace que esto funcione (BIO-1362): un elemento con
   `opacity` **sí** se mezcla contra su backdrop; lo que queda aislado son sus hijos. Colgar la
   mezcla de un descendiente —la tesela, por ejemplo— la dejaría dentro del contexto de apilamiento
   que la opacidad crea, y no mezclaría con nada.

   Y las capas que se mezclan tienen que compartir pane: `mix-blend-mode` no cruza contextos de
   apilamiento, así que un pane por capa deja a cada tesela multiplicándose contra su propio fondo
   vacío. Eso es lo que estuvo pasando entre BIO-1345 y BIO-1362.

   **La capa del RESULTADO también comparte ese pane desde BIO-1394** (`RESULT_OVERLAY_Z` = 0 en
   `geoviewer-map.js`), y por la misma regla: hasta entonces vivía en el `tilePane`, y con UNA sola
   comparación encendida —el caso común— esta regla se aplicaba y no mezclaba con nada. El selector
   sigue sin tocar al resultado: el resultado es el BACKDROP contra el que se mezcla, no el que se
   mezcla. */
.gv-multiply-on .gv-overlay-tile {
  mix-blend-mode: multiply;
}

/* BIO-474: la fila de una capa de contexto con sus dos controles nuevos — opacidad y orden.
   Reusa la gramática visual de la fila de comparación (separador arriba, el slider ocupando el
   hueco) en vez de acuñar una segunda: son el mismo tipo de control por capa y deben leerse
   igual. La sangría hereda de `.geoviewer-layer-group > .geoviewer-layer-row`, que ahora ya no
   alcanza a la casilla —queda envuelta— así que se aplica al contenedor. */
.geoviewer-layer-group > .geoviewer-context-row {
  margin-left: 1rem;
}

.geoviewer-context-row {
  padding: .25rem 0;
  border-top: 1px solid var(--tblr-border-color, #e6e7e9);
}

.geoviewer-context-row:first-of-type {
  border-top: none;
}

/* Los controles cuelgan bajo el rótulo, alineados con el texto y no con la casilla: son sobre
   la capa, no sobre el acto de encenderla. */
.geoviewer-context-controls {
  margin-left: 1.5rem;
  margin-bottom: .35rem;
}

.geoviewer-context-controls input[type="range"] {
  flex: 1 1 auto;
  min-width: 0;
}

/* =============================================================================================
   BIO-1343 · la forma nueva del visor por PROYECCIÓN: riel de asuntos + un panel a la vez.

   Todo lo de arriba queda BYTE-IDÉNTICO, y no es prolijidad: esta hoja la cargan DOS plantillas
   —`geo_viewer_map.html` y `geo_viewer_synthesis_map.html`—, y el visor de síntesis está fuera del
   alcance de BIO-561. Lo que comparten son cuatro selectores (`.geoviewer-shell`, `#geoviewer-map`,
   `.geoviewer-panel`, `.geoviewer-coordinates`): redefinirlos habría rediseñado el otro visor de
   paso, que es justo lo que su cabecera pide que no pase. La forma nueva cuelga entera de
   `.geoviewer-shell--rail`, una clase que sólo lleva la plantilla de proyección, así que síntesis
   no puede retroceder — no porque se haya tenido cuidado, sino porque nada de lo suyo cambió.
   ============================================================================================= */

.geoviewer-shell--rail {
  /* BIO-1361 · el riel va sobre MATERIAL PROPIO, y los tres tonos salen de tokens.
   *
   * Antes eran `#efede8`, `#e4efe7` y `#d7e6dc`: hexadecimales inventados para una lámina, que no
   * pertenecen a ningún set de tokens. Nahim lo vio en pantalla —«la primera barra de menú
   * vertical me la entregó en blanco»— y la superficie del visor es decisión suya, no de la
   * lámina.
   *
   * **Y hay una consecuencia que no depende de la preferencia:** el acento de la marca
   * (`--biolitica-primary`, un lima) dibuja las TRES señales del riel —franja, anillo de foco y
   * contador— y sobre blanco ninguna llega a su umbral: 1,61 : 1 la franja, 1,90 : 1 el anillo y
   * el contador. `--biolitica-primary-strong` tampoco (2,66 : 1). Sobre blanco **no hay token de
   * marca que pueda dibujarlas legalmente**; el mismo lima sobre `--biolitica-panel` da 8,17 : 1.
   * El riel claro no era una variante de estilo: era la razón por la que el acento no se podía
   * usar.
   *
   * Los tres veos son el MISMO lima a tres opacidades, no tres colores: así el estado se lee como
   * una escala y no como una paleta, y ninguno inventa un valor. `rgba(var(--…-rgb), a)` en vez de
   * `color-mix` porque estos tres sí tienen que funcionar en cualquier navegador — son los que
   * dicen dónde está parado el lector. */
  --gv-rail-hover: rgba(var(--biolitica-primary-rgb), .10);
  --gv-rail-selected: rgba(var(--biolitica-primary-rgb), .18);
  --gv-rail-selected-hover: rgba(var(--biolitica-primary-rgb), .26);

  /* La tinta del riel. El atenuado es la ÚNICA pieza que usa `color-mix`, y va declarado en dos
   * pasos a propósito: un navegador que no lo soporte descarta la segunda línea y se queda con el
   * claro pleno —14,84 : 1, legible de sobra—, perdiendo jerarquía y no legibilidad. */
  --gv-rail-ink: var(--biolitica-surface);
  --gv-rail-ink-muted: var(--biolitica-surface);
  --gv-rail-ink-muted: color-mix(in srgb, var(--biolitica-surface) 72%, var(--biolitica-panel));
  display: grid;
  /* La regla base declara `grid-template-columns: minmax(0, 1fr) 380px` para la barra fija, y esa
     declaración SOBREVIVE a este modificador: las dos reglas tienen la misma especificidad y ésta
     sólo gana en las propiedades que nombra. Sin esta línea el armazón hereda dos columnas y
     reparte la barra superior, el aviso y el escenario en celdas distintas — se ve exactamente
     como una pantalla rota, y así se vio en el gate visual antes de escribirla. Añadir un
     modificador NO es lo mismo que sustituir la regla: hay que anular lo que no se quiere. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto auto minmax(0, 1fr);
  height: 100vh;
  min-height: 100vh;
}

/* La barra superior: una FILA de tres celdas — vuelta · identidad · escenario.

   Antes reservaba el hueco de «Volver» con `padding-left: 7.5rem` mientras el ancla seguía fija
   en la esquina. El gate visual lo midió: el botón llega a 141 px y el padding reservaba 120, así
   que tapaba el rótulo del servicio y mordía el nombre de la especie. El número no podía estar
   bien — el ancho del botón depende del texto traducido, así que reservar a ojo falla distinto en
   cada idioma. Con las dos cosas en la misma fila, el reparto lo hace el `flex` y no hay número
   que acertar. La identidad se lleva el espacio sobrante; las otras dos ocupan el suyo. */
.gv-topbar {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
  padding: .6rem 1rem;
  border-bottom: 1px solid var(--tblr-border-color, #d9dbde);
  background: var(--tblr-bg-surface, #fff);
}

.gv-topbar__identity {
  flex: 1 1 18rem;
  min-width: 0;
}

/* `flex-shrink: 0`: la vuelta no se estruja hasta partir su propia palabra. Si el ancho aprieta,
   el `flex-wrap` de la fila la baja entera, que se lee; una palabra rota, no. */
.gv-topbar__return {
  flex: 0 0 auto;
  align-self: center;
  white-space: nowrap;
}

/* El servicio, en versalitas y encima del sujeto: contexto, no titular. */
.gv-topbar__service {
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tblr-secondary, #6c757d);
}

/* El selector de escenario entra a la barra CON SU MARCADO INTACTO: es un parcial compartido y
   hay aserciones vivas sobre su estructura (enlaces con `data-scenario-option`, nunca un
   `<select>`). Lo que cambia es cómo se presenta en este sitio — el cromo de tarjeta, que en una
   barra superior costaba 164 px de alto medidos, y ese alto sale del mapa. */
.gv-topbar__scenario {
  max-width: 34rem;
}

.gv-topbar__scenario .card {
  border: 0;
  background: transparent;
  box-shadow: none;
  margin-bottom: 0 !important;
}

.gv-topbar__scenario .card-header {
  border: 0;
  background: transparent;
  padding: 0;
  min-height: 0;
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tblr-secondary, #6c757d);
}

/* 1446: from 768 px the scenario block sits at the END of the bar, so a tip that opens toward the
   end of the line runs past the window — measured in production, cut mid-word at 1440 px. Here
   it opens toward the start instead. Below 768 px the bar stacks and the term sits at the start,
   where the default direction is the right one, so the rule does not reach it. */
@media (min-width: 768px) {
  .gv-topbar__scenario .glossary-term__tip {
    inset-inline-start: auto;
    inset-inline-end: 0;
  }
}

.gv-topbar__scenario .card-body {
  padding: 0;
}

/* Los escenarios en fila: son hermanos entre sí, y apilados verticalmente empujan la barra. */
.gv-topbar__scenario ul {
  display: flex;
  flex-wrap: wrap;
  gap: .25rem .9rem;
  font-size: .82rem;
}

.gv-stage {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  min-height: 0;
  /* La fila se declara EXPLÍCITA y no se deja a la colocación automática. El aviso de cobertura
     nace `hidden`, así que la mayoría de las veces el armazón tiene DOS hijos y no tres: con
     colocación automática el escenario cae en la fila `auto` del medio, se queda del alto de su
     contenido y la fila `1fr` queda vacía al final — el mapa medía 184 px de 966 disponibles.
     Medido en el gate visual; es el modo de fallo que sólo aparece cuando el aviso NO está, que
     es justo el caso común. */
  grid-row: 3;
}

/* --- El riel ------------------------------------------------------------------------------- */

.gv-rail {
  --gv-rail-pad-x: .5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .25rem;
  width: 6rem;  /* 96 px */
  padding: .5rem var(--gv-rail-pad-x);
  /* El material del riel. Con la superficie oscura, la separación del panel deja de depender de
     una línea de 1 px: el borde queda como remate, no como la frontera que hace el trabajo. */
  border-right: 1px solid var(--biolitica-ink);
  background: var(--biolitica-panel);
  z-index: 1001;
}

/* El mosaico del riel — seis estados y UN tamaño (lámina «Anatomía y estados», 2026-09-17).

   La regla dura que esta hoja hace cumplir: **el tamaño no cambia entre estados**. Antes sí
   cambiaba, y por dos vías distintas: el seleccionado ganaba peso 600, y el contador era un hijo
   más del `flex`, así que el mosaico que llevaba contador era más alto que sus vecinos. Las dos
   movían la columna justo cuando el lector acababa de elegir, que es el peor momento para perder
   la posición. Ahora el alto y el ancho son fijos y el contador sale del flujo.

   El estado se dice con FONDO, PESO y FRANJA. Nunca con la caja. */
.gv-rail__item {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .25rem;
  width: 5rem;      /* 80 px */
  height: 4.5rem;   /* 72 px */
  padding: .35rem .25rem;
  border: 0;
  border-radius: .625rem;  /* 10 px */
  background: transparent;
  color: var(--gv-rail-ink-muted);
  font-size: .6875rem;  /* 11 px */
  line-height: 1.2;
  text-align: center;
  flex-direction: column;
  cursor: pointer;
  transition: background-color 120ms ease, color 120ms ease;
}

/* El icono en reposo pesa menos que su rótulo: es el acompañante, no el mensaje. */
.gv-rail__icon {
  flex: 0 0 auto;
  opacity: .75;
  transition: opacity 120ms ease;
}

/* UNA línea, siempre — y esto es la segunda mitad de «el tamaño no cambia entre estados».

   La caja del mosaico está clavada arriba, así que el seleccionado no empuja a sus vecinos. Pero
   el peso 600 del seleccionado ensancha el texto, y un rótulo que en redonda entra en los 72 px
   útiles y en negrita no, **salta a dos líneas**: la caja sigue midiendo lo mismo y el contenido
   se reacomoda igual. Es el mismo defecto por otra puerta, y lo encontró el barrido de `7d14593b`.

   No se quita el peso —el peso es lo que dice el estado—: se acota el rótulo a una línea. Medido
   sobre la pantalla desplegada, con «Inter Var» a 11 px y peso 600 y contra los 72 px útiles del
   mosaico (80 − 2 × 4 de relleno): el más largo de los cinco en castellano, «Procedencia», mide
   61,7 px —61,0 en redonda, o sea que la negrita le suma 0,7—; el más largo en inglés,
   «Provenance», 58,4. Los cinco entran con holgura en los dos idiomas.

   El `text-overflow` es la degradación **declarada** para la traducción que nadie previó: recorta,
   que se ve y no mueve nada, en vez de reflujo, que mueve todo. Y es lo que hace que la regla
   valga en cualquier idioma y no sólo en los dos que medí. */
.gv-rail__label {
  display: block;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.gv-rail__item:hover {
  background: var(--gv-rail-hover);
  color: var(--gv-rail-ink);
}

.gv-rail__item:hover .gv-rail__icon {
  opacity: 1;
}

/* Foco ≠ hover, a propósito y no por simetría: quien navega con teclado tiene que ver dónde está
   aunque el puntero esté en otro sitio, así que el anillo NO trae el fondo del hover. Y es
   `:focus-visible`, no `:focus`: con `:focus` el anillo aparecería también al hacer clic con el
   ratón, donde nadie lo pidió y sólo ensucia. */
.gv-rail__item:focus-visible {
  /* El token va SIN respaldo: el respaldo que había era un azul de Tabler, o sea la marca
     equivocada dibujando la señal de foco el día que el token faltara. Sin respaldo, si el token
     no existiera la declaración se descarta y el navegador pinta su propio anillo — que es lo
     correcto para una señal de accesibilidad. */
  outline: 2px solid var(--biolitica-primary);
  outline-offset: 2px;
}

/* El asunto abierto se marca con FRANJA además de color: el color solo no distingue para quien no
   lo percibe, y el riel es la única señal de dónde está parado el lector.

   La franja se pega al borde IZQUIERDO DEL RIEL, no al del mosaico — por eso es un `::before`
   desplazado por el padding lateral del riel y no un `box-shadow: inset`. Pegada al mosaico
   quedaba flotando a 5,6 px del borde, que se lee como un adorno en vez de como un indicador de
   posición en la columna. */
.gv-rail__item.is-open {
  background: var(--gv-rail-selected);
  color: var(--gv-rail-ink);
  font-weight: 600;
}

.gv-rail__item.is-open .gv-rail__icon {
  opacity: 1;
}

.gv-rail__item.is-open::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(-1 * var(--gv-rail-pad-x));
  width: 3px;
  border-radius: 0 2px 2px 0;
  background: var(--biolitica-primary);
}

.gv-rail__item.is-open:hover {
  background: var(--gv-rail-selected-hover);
}

/* Fuera del flujo, en la esquina superior derecha del mosaico: dentro del flujo estiraba el
   mosaico que lo llevaba y desalineaba la columna entera. */
.gv-rail__count {
  position: absolute;
  top: .25rem;
  right: .25rem;
  min-width: 1.125rem;   /* 18 px */
  height: 1.125rem;
  padding: 0 .25rem;
  border-radius: 999px;
  /* Tinta OSCURA sobre el lima, no blanca: blanco sobre lima da 1,90 : 1 y el texto de 10 px
     exige 4,5. Invertir el par da 8,17 : 1 con los mismos dos tokens. */
  background: var(--biolitica-primary);
  color: var(--biolitica-panel);
  font-size: .625rem;
  font-weight: 600;
  line-height: 1.125rem;
}

/* --- La columna de panel ------------------------------------------------------------------- */

.gv-panel-column {
  display: flex;
  flex-direction: column;
  width: 340px;
  max-width: 100%;
  min-height: 0;
  border-right: 1px solid var(--tblr-border-color, #d9dbde);
  background: var(--tblr-bg-surface, #fff);
  z-index: 1001;
}

.gv-panel-column[hidden] {
  display: none;
}

/* El panel abierto es el único que crece y el único que hace scroll. */
.gv-panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 auto;
}

.gv-panel[hidden] {
  display: none;
}

/* BIO-1365 · los TRES niveles del panel, declarados. Ninguno hereda por omisión.
   La columna tenía dos jerarquías y sólo una escrita, y la escrita era la más chica de la
   pantalla: el encabezado heredaba 14 px en peso normal y el rótulo de sección declaraba 11.

   BIO-1371 · el tamaño se MUDÓ de acá al título, y el contenedor se queda sin `font-size` a
   propósito. `.gv-panel__head` es el contenedor flex, y sus dos hijos declaran el suyo: el título
   (antes por `.h6`, ahora por `.gv-panel__title`) y el botón de cierre. Una declaración de tamaño
   acá no gobernaba a nadie — y una declaración que no gobierna a nadie es peor que ninguna,
   porque el caso que la lee sale verde con el defecto en pantalla. Fue exactamente lo que pasó.

   `align-items` pasa a `flex-start`: el encabezado ya no es una línea, y la × se ancla arriba. */
.gv-panel__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .5rem;
  padding: .55rem .75rem;
  border-bottom: 1px solid var(--tblr-border-color, #d9dbde);
  color: var(--tblr-body-color, #1d273b);
}

/* BIO-1371 · las dos líneas del encabezado: el asunto y qué se hace en él. */
.gv-panel__heading {
  display: flex;
  flex-direction: column;
  gap: .1rem;
  min-width: 0;
}

.gv-panel__title {
  font-size: 1rem;      /* 16 px — el mayor de la columna, declarado SOBRE el nodo que se ve */
  font-weight: 600;
  line-height: 1.25;
  color: var(--tblr-body-color, #1d273b);
}

/* 12 px: por debajo del rótulo de sección (13) y por encima del rótulo del riel (11), que es
   donde le toca — es contexto del encabezado, no un nivel nuevo de la jerarquía. La lámina lo
   dibuja a 10.5; se sube, porque 1365 existió para sacar de la columna los tamaños ilegibles y
   reintroducir uno más chico que el riel sería deshacerla por la puerta de al lado. */
.gv-panel__descriptor {
  margin: 0;
  font-size: .75rem;
  font-weight: 400;
  line-height: 1.3;
  color: var(--tblr-secondary, #6c757d);
}

.gv-panel__close {
  border: 0;
  background: transparent;
  color: var(--tblr-secondary, #6c757d);
  font-size: 1.15rem;
  line-height: 1;
  padding: 0 .25rem;
  cursor: pointer;
}

.gv-panel__body {
  padding: .75rem;
  overflow: auto;
  min-height: 0;
  flex: 1 1 auto;
  font-size: .875rem;   /* 14 px — el cuerpo, declarado: es lo que ya computaba heredando */
}

/* La barra de mapa base, fijada al PIE de la columna: el suelo del mapa, no una capa del estudio. */
.gv-basemap {
  flex: 0 0 auto;
  padding: .5rem .75rem;
  border-top: 1px solid var(--tblr-border-color, #d9dbde);
  background: var(--tblr-bg-surface-secondary, #f8f9fa);
}

.gv-basemap:empty {
  display: none;
}

.gv-operator-foot {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .5rem .75rem;
  border-top: 1px solid var(--tblr-border-color, #d9dbde);
}

.gv-operator-foot__label {
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tblr-secondary, #6c757d);
}

/* --- El mapa y la leyenda flotante ---------------------------------------------------------- */

.gv-map-area {
  position: relative;
  min-height: 0;
}

/* `#geoviewer-map` conserva su `min-height: 100vh` de la regla compartida, que dentro de esta
   rejilla desbordaría la fila. Se neutraliza SÓLO bajo el modificador. */
.geoviewer-shell--rail #geoviewer-map {
  min-height: 0;
  height: 100%;
}

/* La leyenda vive sobre el mapa, no dentro de la columna: es lo que hace que cerrar el panel siga
   dejando el mapa legible. Plegable, porque una leyenda WMS es una imagen de alto arbitrario. */
.gv-legend-float {
  position: absolute;
  z-index: 1000;
  left: .75rem;
  bottom: .75rem;
  max-width: min(20rem, calc(100% - 1.5rem));
  max-height: calc(100% - 1.5rem);
  display: flex;
}

.gv-legend-float__box {
  background: rgba(255, 255, 255, .94);
  border-radius: .35rem;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .15);
  overflow: auto;
  min-height: 0;
}

.gv-legend-float__head {
  cursor: pointer;
  padding: .4rem .6rem;
  font-size: .82rem;
  font-weight: 600;
}

.gv-legend-float__body {
  padding: 0 .6rem .6rem;
  font-size: .82rem;
}

/* Sin leyenda que mostrar, la caja no se anuncia: un recuadro vacío flotando sobre el mapa es
   ruido que además tapa territorio. */
.gv-legend-float__body:empty {
  display: none;
}

/* La tableta (768–992 px): el riel y la columna se APILAN sobre el mapa. Es la degradación honesta
   que BIO-1343 dejó escrita — no la forma móvil, que vive en el bloque de abajo. A esos anchos el
   mapa todavía conserva alto útil con las dos piezas apiladas; en un teléfono no, y por eso son
   dos reglas y no una. */
@media (min-width: 768px) and (max-width: 992px) {
  .geoviewer-shell--rail {
    height: auto;
  }

  .gv-stage {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto 65vh;
  }

  .gv-rail {
    flex-direction: row;
    width: auto;
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--biolitica-ink);
  }

  .gv-panel-column {
    width: 100%;
    border-right: 0;
    border-bottom: 1px solid var(--tblr-border-color, #d9dbde);
    max-height: 60vh;
  }
}

/* =============================================================================================
   BIO-1348 · el recorrido móvil: la HOJA INFERIOR ARRASTRABLE.

   Decidida por Nahim el 2026-09-17 entre las tres salidas posibles, y la razón de la elección es
   una sola: **el mapa es el objeto que se está leyendo, y las otras dos lo tapan**. Un panel a
   pantalla completa convierte cada consulta en un viaje de ida y vuelta —encendés una capa, no ves
   el efecto, volvés—. La hoja es la única que deja ver el mapa y el control A LA VEZ.

   `.gv-sheet` no existe en escritorio: es `display: contents`, así que el riel y la columna siguen
   siendo hijos directos de la rejilla y la forma de escritorio no cambia en un solo píxel. Acá la
   misma clase se convierte en caja.

   **`absolute` y no `fixed`, y es la decisión que hace funcionar la puerta pública embebida.** El
   caso móvil más probable de este visor es un `iframe` dentro del sitio de un tercero. Una hoja
   `fixed` se ancla al viewport del documento de nivel superior en unos navegadores y al del iframe
   en otros: se sale de la pantalla del visor o se pega al pie de la página que lo embebe. Anclada a
   `.gv-stage` —que es el rectángulo del visor— hace lo mismo embebida que suelta.
   ============================================================================================= */

/* El asidero sólo existe a anchos de teléfono. Va con `display: none` y no con el atributo
   `hidden`: el atributo no lo puede revertir una media query. */
.gv-sheet__handle {
  display: none;
}

/* Sin caja en escritorio: el riel y la columna atraviesan el envoltorio y siguen siendo ítems de
   la rejilla de `.gv-stage`. Es lo que permite UN marcado para los dos recorridos. */
.gv-sheet {
  display: contents;
}

@media (max-width: 767.98px) {
  /* `100dvh` es el alto del viewport DESCONTANDO el cromo del navegador móvil, que aparece y
     desaparece al desplazarse. Con `100vh` la hoja queda cortada por la barra de direcciones justo
     cuando está abierta del todo. Se declara en dos pasos: el navegador que no conozca `dvh`
     descarta la segunda línea y se queda con `vh`, que funciona y sólo pierde precisión. */
  .geoviewer-shell--rail {
    height: 100vh;
    height: 100dvh;
  }

  /* El mapa se queda con la fila entera y la hoja sale del flujo. `position: relative` es lo que
     hace de `.gv-stage` el bloque contenedor de la hoja — sin esta línea, `absolute` treparía
     hasta el viewport y volveríamos al problema del `fixed`. */
  .gv-stage {
    position: relative;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr);
  }

  .gv-sheet {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1002;
    display: flex;
    flex-direction: column;
    min-height: 0;
    background: var(--tblr-bg-surface, #fff);
    border-top-left-radius: .9rem;
    border-top-right-radius: .9rem;
    box-shadow: 0 -2px 12px rgba(0, 0, 0, .18);
    transition: height 180ms ease;
  }

  /* Las TRES alturas ancladas. No hay altura libre a propósito: una hoja que se queda donde el dedo
     la soltó obliga a apuntar, y apuntar con el pulgar en movimiento es justo lo que no se puede
     pedir. Tres destinos, y el gesto elige el más cercano en la dirección del movimiento. */
  .gv-sheet[data-gv-sheet-anchor="closed"] {
    height: auto;
  }

  .gv-sheet[data-gv-sheet-anchor="half"] {
    height: 50vh;
    height: 50dvh;
  }

  .gv-sheet[data-gv-sheet-anchor="full"] {
    height: 92vh;
    height: 92dvh;
  }

  /* Quien prefiere menos movimiento no recibe el deslizamiento: la hoja salta a su altura. */
  @media (prefers-reduced-motion: reduce) {
    .gv-sheet {
      transition: none;
    }
  }

  .gv-sheet__handle {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 100%;
    /* 44 px de alto: es el objetivo táctil mínimo y acá no es una holgura, es la zona que el pulgar
       tiene que encontrar sin mirar. */
    min-height: 2.75rem;
    padding: 0;
    border: 0;
    border-radius: .9rem .9rem 0 0;
    background: var(--tblr-bg-surface, #fff);
    cursor: grab;
    /* El navegador NO se queda con el gesto vertical sobre el asidero: sin esto, el arrastre de la
       hoja lo interpreta como desplazamiento de la página y el control no se mueve. Va SÓLO acá —
       ponerlo en la hoja entera mataría el desplazamiento de las listas que viven dentro. */
    touch-action: none;
  }

  .gv-sheet__handle:focus-visible {
    outline: 2px solid var(--biolitica-primary);
    outline-offset: -4px;
  }

  .gv-sheet__grip {
    display: block;
    width: 2.5rem;
    height: .25rem;
    border-radius: 999px;
    background: var(--tblr-border-color, #d9dbde);
  }

  /* El riel pasa a ser el ENCABEZADO de la hoja: cinco mosaicos de 80 px no entran en vertical en
     390 px, y en horizontal sí — con desplazamiento lateral cuando el idioma los ensancha. */
  .gv-rail {
    flex: 0 0 auto;
    flex-direction: row;
    width: auto;
    overflow-x: auto;
    border-right: 0;
    border-bottom: 1px solid var(--biolitica-ink);
  }

  /* La franja del asunto abierto se pega al borde SUPERIOR cuando el riel es horizontal: pegada al
     izquierdo marcaría el borde de la hoja y no el mosaico. Los seis estados, los tres tonos y el
     tamaño del mosaico NO se tocan — son de BIO-1361 y siguen valiendo. */
  .gv-rail__item.is-open::before {
    top: calc(-1 * var(--gv-rail-pad-x));
    bottom: auto;
    left: 0;
    right: 0;
    width: auto;
    height: 3px;
    border-radius: 0 0 2px 2px;
  }

  .gv-panel-column {
    width: 100%;
    min-height: 0;
    flex: 1 1 auto;
    border-right: 0;
  }

  /* El objetivo táctil de los controles que en escritorio son casillas y flechas de 13 px. El
     mínimo de 44 px sale de la misma regla que el asidero, y se aplica al control, no a la fila:
     ensanchar la fila entera no agranda el blanco, sólo el espacio alrededor. */
  .geoviewer-layer-row input[type="checkbox"],
  .geoviewer-layer-row input[type="radio"] {
    width: 1.35rem;
    height: 1.35rem;
    margin-right: .35rem;
  }

  .geoviewer-layer-row {
    min-height: 2.75rem;
    align-items: center;
  }

  .gv-panel__close,
  [data-comparison-handle],
  [data-context-handle] {
    min-width: 2.75rem;
    min-height: 2.75rem;
  }

  /* El selector de escenario deja de estar acotado a 34 rem: en 390 px ese tope no recorta nada y
     el tope de la barra es el ancho de la pantalla. Siguen siendo enlaces y siguen funcionando sin
     JavaScript — eso no lo toca ninguna regla de acá. */
  .gv-topbar__scenario {
    max-width: 100%;
  }

  /* La leyenda flotante se sube por encima de la hoja cerrada, que mide ~7 rem entre asidero y
     riel: dejarla abajo la escondería detrás justo cuando el mapa es todo lo que se ve. */
  .gv-legend-float {
    bottom: 8.5rem;
    max-width: calc(100% - 1.5rem);
  }
}

/* =============================================================================================
   BIO-1344 · el panel «Especie»: la tarjeta de la capa del resultado y el bloque del umbral.

   Como el bloque de BIO-1343, todo cuelga de clases NUEVAS: nada de lo que el visor de síntesis
   usa se redefine acá.
   ============================================================================================= */

/* La tarjeta de una capa: su control arriba y colgando de ella su opacidad, su paleta y su
   leyenda. La sangría a la izquierda es lo que dice «esto pertenece a esa capa» — sin ella son
   controles sueltos apilados, que es la forma que este issue viene a corregir. */
.gv-layer-card {
  border-left: 3px solid var(--tblr-border-color, #d9dbde);
  padding-left: .6rem;
}

.gv-layer-card__legend:empty {
  display: none;
}

.gv-layer-card__legend {
  margin-top: .5rem;
  padding-top: .5rem;
  border-top: 1px dashed var(--tblr-border-color, #e6e7e9);
}

/* El deslizador de opacidad ocupa el hueco, como el de contexto (BIO-474) y el de comparación. */
.geoviewer-result-opacity input[type="range"] {
  flex: 1 1 auto;
  min-width: 0;
}

/* El umbral exploratorio, en BLOQUE DESTACADO y ya no como una nota al pie. El realce no es
   decoración: este control produce un número que NO es publicable, y el aviso tiene que leerse
   antes que el resultado de moverlo, no después. */
.gv-threshold {
  margin-top: .75rem;
  padding: .55rem .6rem;
  border: 1px solid var(--tblr-warning, #f59f00);
  border-radius: .35rem;
  background: rgba(245, 159, 0, .06);
}

/* Encendido, el realce sube: el mapa está pintando un corte exploratorio y eso tiene que ser
   evidente de un vistazo, no algo que se deduzca mirando si la casilla está marcada. */
.gv-threshold.is-on {
  background: rgba(245, 159, 0, .14);
  box-shadow: inset 3px 0 0 0 var(--tblr-warning, #f59f00);
}

/* Ámbar OSCURO explícito, y no `var(--tblr-warning-fg)`.
   Medido en pantalla: ese token vale `#f9fafb` —casi blanco— porque en Tabler significa «texto
   SOBRE fondo de advertencia», no «texto de color advertencia». Usarlo como color de texto sobre
   un fondo pálido borra la línea: el encabezado y el aviso salían ilegibles, y el aviso es
   justamente el que dice que este número NO es publicable. El fallback nunca entró porque la
   variable SÍ está definida — un fallback sólo cubre la ausencia, no el malentendido. */
.gv-threshold__head {
  color: #8a5a00;
}

/* El valor SANCIONADO, al lado del exploratorio. Es la mitad que convierte el aviso en algo
   accionable: «este número no es el oficial» sin decir cuál es el oficial deja al lector con la
   advertencia y sin la salida. */
.gv-threshold__sanctioned {
  margin-top: .4rem;
  padding-top: .35rem;
  border-top: 1px solid rgba(0, 0, 0, .08);
  /* Más oscuro que el secundario del tema: medido sobre este fondo ámbar, `--tblr-secondary` da
     4.39:1 y AA pide 4.5. Es un NÚMERO que el lector tiene que poder leer para distinguirlo del
     exploratorio — la línea entera existe para eso. */
  color: #4b5563;
}

.gv-threshold__notice {
  margin-top: .4rem;
  color: #8a5a00;
  font-weight: 500;
}

.geoviewer-threshold-controls input[type="range"] {
  flex: 1 1 auto;
  min-width: 0;
}

/* =============================================================================================
   BIO-1345 · el panel «Comparar»: la tarjeta de cada otra especie, con su asidero de reordenar.
   Clases nuevas: nada de lo que usa el visor de síntesis se redefine.
   ============================================================================================= */

/* El asidero. Es un `<button>` y no un `<span>` con `draggable` por una razón que se ve en
   teclado: un botón entra en el orden de tabulación y recibe foco sin `tabindex` inventado, que
   es lo que hace que las flechas puedan moverlo. El `cursor: grab` anuncia la otra vía. */
.gv-drag-handle {
  border: 0;
  background: transparent;
  color: var(--tblr-secondary, #6c757d);
  cursor: grab;
  padding: 0 .15rem;
  line-height: 1;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
}

/* BIO-1346 (residuo `27c6c94a`) · el asidero era un glifo braille, y por eso esta regla llevaba
   `font-size: 1rem`: el tamaño del dibujo dependía del tamaño de letra. Ahora es un SVG con su
   alto declarado en el marcado, así que el `font-size` no sólo sobra — mentiría, porque sugiere
   que tocarlo cambia algo. El `inline-flex` es lo que centra el dibujo dentro del botón, que el
   glifo resolvía por línea base. */
.gv-drag-handle__icon {
  display: block;
}

.gv-drag-handle:active {
  cursor: grabbing;
}

/* El foco se marca SIEMPRE, y no sólo con `:focus-visible`: este control se opera con el teclado
   por diseño, así que perder de vista cuál fila está tomada lo vuelve inusable justo para quien
   depende de él. */
.gv-drag-handle:focus {
  outline: 2px solid var(--biolitica-primary, #206bc4);
  outline-offset: 1px;
  border-radius: .2rem;
}

/* La fila tomada se atenúa: el arrastre nativo pinta su propia imagen fantasma, y sin esta marca
   el original y el fantasma se ven iguales y no se sabe cuál se está moviendo. */
.geoviewer-comparison-row.is-dragging {
  opacity: .45;
}

/* La tarjeta de una especie hereda la gramática de la del resultado (BIO-1344): sangría a la
   izquierda que dice «esto pertenece a esa capa», y su leyenda colgando separada. */
.geoviewer-comparison-row.gv-layer-card {
  border-left: 3px solid var(--tblr-border-color, #d9dbde);
  padding-left: .6rem;
  border-top: 1px solid var(--tblr-border-color, #e6e7e9);
  margin-top: .375rem;
}

.geoviewer-comparison-row.gv-layer-card:first-child {
  border-top: none;
  margin-top: 0;
}

/* =============================================================================================
   BIO-1346 · el panel «Capas»: la tarjeta de una capa de contexto y sus estados.
   ============================================================================================= */

/* El candado ya no es un emoji: un SVG en línea rinde igual en todas las plataformas y hereda el
   color del texto, cosa que un emoji no hace. Se alinea con la línea base del rótulo. */
.geoviewer-lock-icon {
  flex: 0 0 auto;
  vertical-align: -1px;
  opacity: .7;
}

/* Una capa APAGADA es una línea: sin controles colgando. El v5 lo pide así, y no por ahorrar
   píxeles — un deslizador de opacidad sobre una capa que no se está pintando es un control sobre
   nada, y veinte de ellos convierten la lista en un muro de mandos inertes. El borde de la
   izquierda sólo se marca cuando la capa está encendida: es lo que hace que la vista de un
   vistazo diga cuáles están pintando. */
.geoviewer-context-row.gv-layer-card {
  border-left: 3px solid transparent;
  padding-left: .6rem;
}

.geoviewer-context-row.gv-layer-card.is-on {
  border-left-color: var(--biolitica-primary, #206bc4);
}

/* La leyenda WMS es una imagen de alto ARBITRARIO y nace plegada (fila 34): la tarjeta la acomoda,
   no la recorta. Sin tope de alto a propósito — un `max-height` la cortaría, que es lo prohibido. */
.gv-legend-wms > summary {
  cursor: pointer;
}

/* El «Punto consultado» mientras no hay punto: la fila se atenúa y dice por qué, en vez de
   afirmar con una casilla marcada que el punto está visible. */
.geoviewer-queried-point {
  color: var(--tblr-secondary, #6c757d);
}

.geoviewer-queried-point.is-on {
  color: inherit;
}

.geoviewer-queried-point small {
  font-size: .72rem;
}

/* El bloque de referencias del mapa, separado de las capas del proyecto: son el instrumento, no
   el territorio del estudio. */
.gv-map-references {
  margin-top: .75rem;
  padding-top: .5rem;
  border-top: 1px solid var(--tblr-border-color, #d9dbde);
}

/* =============================================================================================
   BIO-1347 · el panel «Consultar»: la consulta puntual y el par A/B en una sola superficie.
   ============================================================================================= */

/* «Detalle técnico» al PIE, separado de lo que se lee. Es lo que se abre cuando algo no cuadra,
   no parte del recorrido — y hasta ahora quedaba por encima del par A/B. */
.gv-identify-detail {
  margin-top: .75rem;
  padding-top: .5rem;
  border-top: 1px solid var(--tblr-border-color, #d9dbde);
}

.gv-identify-detail:empty {
  display: none;
}

/* El volcado crudo no desborda la columna de 340 px: se envuelve y hace su propio scroll en vez
   de empujar el panel a lo ancho. */
.gv-identify-detail pre {
  max-height: 14rem;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

/* --- Las secciones de un panel son PARES ----------------------------------------------------

   Regla de la lámina «Anatomía y estados», y la causa que la motiva es un defecto que Nahim
   nombró mirando «Consultar»: el panel se estaba titulando con el nombre de su PRIMERA sección.
   El riel decía «Consultar» y el encabezado «Consulta puntual», así que «Comparar dos lugares»
   —que es su par— se leía como subordinada suya, y el formato lo remachaba: una en versalitas
   grises sin caja, la otra en negrita dentro de una tarjeta con borde.

   Las tres reglas, para los cinco paneles:
     1. el encabezado del panel es el nombre de su asunto del riel, sin excepción;
     2. las secciones son pares — mismo rótulo de 11 px en versalitas, misma regla de 1 px, el
        mismo aire de 16 px;
     3. la tarjeta con borde queda reservada a lo que de verdad es un OBJETO —una capa, una
        especie de comparación—, nunca a una sección del panel.

   La jerarquía la dice el ORDEN, no el peso ni un borde. */
.gv-panel__section-label {
  margin: 1rem 0 .5rem;
  padding-top: .75rem;
  border-top: 1px solid var(--tblr-border-color, #d9dbde);
  /* BIO-1365 · sube de 11 px a 13 y se oscurece. Los 11 px salieron de igualarlo al rótulo del
     riel «para que se lean como la misma familia», y era una simetría equivocada: el del riel es
     una etiqueta de navegación bajo un icono, éste es un ENCABEZADO DE CONTENIDO. No hacen el
     mismo trabajo y no miden lo mismo — el del riel se queda en 11 px y deja de estar acoplado.

     Las versalitas y el tracking se conservan y el tamaño los compensa: mayúsculas con tracking a
     11 px en gris secundario es justo donde se pierde la legibilidad. */
  font-size: .8125rem;  /* 13 px */
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tblr-body-color, #1d273b);
}

/* La primera sección de un panel no lleva regla ni aire arriba: no separa de nada. */
.gv-panel__body > .gv-panel__section-label:first-child {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* --- El botón de ubicación, junto al zoom ----------------------------------------------------

   «Mi ubicación» dejó de ser una casilla del catálogo de capas (decisión de Nahim: «Capas» es el
   catálogo del proyecto y nada más) y además una casilla marcada AFIRMA que algo está encendido,
   cosa que la geolocalización no puede prometer. Un botón se pulsa y puede decir que no pudo.

   Hereda el cromo de `leaflet-bar` para que se lea como hermano de `+`/`−` y no como un adorno. */
.gv-locate__button {
  display: flex !important;
  align-items: center;
  justify-content: center;
  color: var(--tblr-body-color, #1d273b);
}

/* Mientras el navegador resuelve la posición el botón lo dice: `getCurrentPosition` puede tardar
   segundos y un botón que no acusa el clic invita a pulsarlo otra vez. */
.gv-locate__button.is-busy {
  opacity: .55;
  pointer-events: none;
}

/* --- Los bloques de la leyenda flotante, los TRES plegables ----------------------------------

   El del resultado era el único sin su flecha: «Leyenda» plegaba el contenedor entero y cada capa
   de contexto el suyo, y el gradiente quedaba en medio sin forma de cerrarse — justo el bloque
   más alto de los tres.

   **Plegar plegaban los tres; lo que no era uno era el dibujo** (residuo `7d14593b`): el del
   resultado traía ▸/▾ y los otros dos el marcador nativo del navegador, que cambia de forma según
   el navegador. Tres bloques hermanos con dos flechas distintas son la misma clase de
   inconsistencia que hizo decir que las secciones no se distinguen bien.

   Los tres van **nombrados en una lista**, no unificados por un ancestro común: el bloque del
   resultado se monta en DOS sitios —la leyenda flotante y la tarjeta de «Especie»—, así que
   colgar la regla de `.gv-legend-float` le habría quitado la flecha al montaje de la tarjeta sin
   que nada lo dijera. La lista se lee de un vistazo; el ancestro habría escondido la excepción. */
.gv-legend-block > summary,
.gv-legend-float__box > summary,
.geoviewer-context-legend > summary {
  cursor: pointer;
  list-style: none;
}

.gv-legend-block > summary::-webkit-details-marker,
.gv-legend-float__box > summary::-webkit-details-marker,
.geoviewer-context-legend > summary::-webkit-details-marker {
  display: none;
}

.gv-legend-block > summary::before,
.gv-legend-float__box > summary::before,
.geoviewer-context-legend > summary::before {
  content: "▸ ";
  color: var(--tblr-secondary, #6c757d);
}

.gv-legend-block[open] > summary::before,
.gv-legend-float__box[open] > summary::before,
.geoviewer-context-legend[open] > summary::before {
  content: "▾ ";
}

/* --- Las tres secciones de «Consultar», como pares --------------------------------------------

   La regla general y su lámina viven arriba, con el armazón; acá va la instancia de este panel.
   «Detalle técnico» sigue plegado —es el volcado crudo del payload, no algo que se lea de
   corrido— pero su `<summary>` lleva el mismo rótulo de sección que sus dos hermanas en vez de
   anunciarse con otra tipografía. El marcador nativo se retira para que la flecha sea la misma
   que la de los demás plegables de esta pantalla. */
summary.gv-panel__section-label {
  cursor: pointer;
  list-style: none;
}

summary.gv-panel__section-label::-webkit-details-marker {
  display: none;
}

summary.gv-panel__section-label::after {
  content: " ▸";
  color: var(--tblr-secondary, #6c757d);
}

details[open] > summary.gv-panel__section-label::after {
  content: " ▾";
}

/* El aviso de por qué este punto no trae lectura. Ámbar y no rojo: no es un error del visor — el
   punto simplemente cae donde el resultado no dice nada, y decirlo en rojo sugeriría que algo
   falló. */
.gv-identify-notice {
  padding: .45rem .6rem;
  border-left: 3px solid var(--tblr-warning, #f76707);
  border-radius: .25rem;
  background: var(--tblr-warning-lt, #fff5e6);
  color: var(--tblr-body-color, #1d273b);
}

/* BIO-1399 · el veredicto de idoneidad y la vara contra la que se emitió, en UN bloque.
   El margen inferior separa el bloque de la fila siguiente más de lo que la nota se separa de su
   propio veredicto: la cercanía es lo que dice que los dos renglones son una sola lectura, y sin
   ella la vara se lee como otra fila de la lista, que es el defecto de partida con otro aspecto. */
.gv-verdict {
  margin-bottom: .45rem;
}

/* El corte sancionado. Secundario en peso —el veredicto manda—, y NO en el gris secundario del
   tema: medido sobre el fondo del panel, `--tblr-secondary` queda por debajo del 4.5:1 de AA, y
   acá viaja un NÚMERO que el lector tiene que poder leer. Es la misma razón, y el mismo color, que
   BIO-1344 fijó para el umbral sancionado del panel «Especie». */
.gv-verdict__cut {
  margin-top: .1rem;
  color: #4b5563;
}

/* --- La marca de Biolítica en la barra superior ----------------------------------------------

   Sólo la rinde la puerta pública. La caja existe para alinearla con la fila —el emisor compartido
   trae clases de `navbar` que fuera de una barra de navegación no centran nada— y NO redefine el
   alto: ése lo fija `.product-ui-public-brand .product-ui-public-logo` en `overrides.css`, que es
   el arreglo del issue 1259, y duplicarlo acá sería una segunda fuente para el mismo número. */
.gv-topbar__brand {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
}

.gv-topbar__brand .navbar-brand {
  margin: 0;
}

/* El marco de validez del resultado, al pie de su tarjeta. Separado por una línea porque no es
   otro control del resultado —no cambia cómo se pinta— sino el recorte dentro del cual ese
   resultado significa algo. */
.gv-layer-card__scope {
  margin-top: .5rem;
  padding-top: .5rem;
  border-top: 1px dotted var(--tblr-border-color, #d9dbde);
}

/* BIO-1376 · las dos frases de lectura segura, en el panel «Consultar».
   Secundarias en peso y primeras en orden: el número que califican lo pinta el cliente debajo, y
   una advertencia que aparece después del dato ya llegó tarde. Sin fondo ni icono a propósito —
   un recuadro de alerta se lee como un error del sistema, y esto no es un error: es cómo se lee
   el número. */
.gv-panel__note {
  margin: 0 0 .5rem;
  font-size: .8125rem;
  line-height: 1.35;
  color: var(--tblr-secondary, #6c757d);
}

.gv-panel__note:last-of-type {
  margin-bottom: .75rem;
}

/* Issue 1460 · la misma frase en el panel «Comparar», FUERA de su cuerpo (el script lo reescribe
   entero) y antes de él: lleva el margen interior que el cuerpo le daría. */
.gv-panel__note--lead {
  padding: .75rem .75rem 0;
  margin-bottom: 0;
}

/* Issue 1395 · la declaración de la capa de evidencia, colgada de su fila.

   Sangrada como la fila de la que cuelga (`.geoviewer-layer-group > .geoviewer-layer-row` ya usa
   1rem) para que se lea como parte de esa capa y no como un aviso del panel. Sin fondo de alerta
   y por la misma razón que `.gv-panel__note`: esto no es un error del sistema — la capa cargó,
   trajo sus registros y están en otra parte —, y pintarlo de rojo diría lo contrario.

   El `[hidden]` lo gobierna el script: mientras la capa está apagada no hay nada que declarar. */
.gv-evidence-census {
  margin: .25rem 0 .5rem 1rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .35rem;
}

.gv-evidence-census__notice {
  font-size: .8125rem;
  line-height: 1.35;
  color: var(--tblr-secondary, #6c757d);
}

/* La SALIDA. Alineada a la izquierda bajo su aviso y no a lo ancho: es una acción opcional sobre
   el mapa, no el botón primario de la pantalla. */
.gv-evidence-census__action {
  align-self: flex-start;
}
