/* ══════════════════════════════════════════════════════════════════════
   EL MERCADO — layout de la sección.
   ──────────────────────────────────────────────────────────────────────
   Se carga DESPUÉS de liquid-glass.css y de styles.css, y como el resto de
   las secciones no define ni un color de tema ni una sombra de vidrio: todo
   sale de los tokens (`--c-ink`, `--accent`, `--glass-*`, `--hairline`…). Si
   aquí aparece un `#fff` escrito a mano, está mal — en oscuro el acento es
   blanco y la tinta que va encima, negra.

   Las TARJETAS reutilizan `.product-card` entera (styles.css): el material,
   la foto a sangre, la cejilla, el título y el pie son exactamente los
   mismos que en la tienda. Este archivo solo añade lo que un avión tiene y
   un producto no: la chapa de la categoría, los cuentahoras, el sello de
   vendido y el precio.

   ── POR QUÉ REPITE `.btn-ghost`, EL `<select>` Y EL COMBO ────────────
   Porque esta página NO carga css/portal.css ni css/schools.css, que es
   donde viven. Traerse cualquiera de las dos —1.900 y 1.100 líneas de panel
   y de mapa— para heredar cuarenta sería pagar todo eso por nada. Es la
   misma decisión —y la misma copia— que ya tomó css/activities.css.

   ── EL ORDEN ─────────────────────────────────────────────────────────
     1. Estructura      migas, titular, filtros
     1 bis. Dónde       el radio, el punto de partida y el mapa
     2. La rejilla      la tarjeta de un avión y el estado vacío
     3. La ficha        el avión entero, encima de la página
     3 bis. El navegador de modelos — el catálogo, encima de la página
     4. La guía
     5. El panel        puertas, lista de los tuyos, formulario y fotos
   ══════════════════════════════════════════════════════════════════════ */

/* ══════════════════════════════════════════════════════════════════════
   1 · ESTRUCTURA
   ══════════════════════════════════════════════════════════════════════ */

.mk-main {
  gap: clamp(1.5rem, 3.5vw, 2.5rem);
}

/* Con la ficha abierta, la página de debajo no se desplaza. Sin esto, rodar
   la rueda dentro de la ficha arrastra el tablón por detrás y al cerrarla
   se aparece a mitad de una rejilla que no se había tocado. */
body.mk-locked {
  overflow: hidden;
}

/* ── EL TITULAR, ENCIMA DEL PASE ──────────────────────────────────────
   Es la MISMA pieza que abre el ranking (`.rk-hero` / `.rk-hero__title` en
   css/ranking.css), copiada aquí palabra por palabra porque esta página no
   carga aquel archivo — la misma decisión, y por el mismo motivo, que ya
   documenta este archivo con `.btn-ghost` y el `<select>`. Los dos valores
   que se toquen allí hay que tocarlos aquí: dos secciones de la misma casa
   que abren con dos letras distintas se leen como dos webs pegadas.

   Centrado, y es la única pieza centrada de la página. No es un capricho:
   va sobre una banda de foto a todo lo ancho y hace de cabecera de la
   sección, mientras que todo lo de debajo —filtros, mapa, rejilla— es
   material que se recorre en columna y va alineado a la izquierda.

   En VERSALES y con la letra abierta, porque nombra la sección entera: «THE
   WORLDWIDE AIRCRAFT MARKET» tiene que leerse como un rótulo, no como la
   primera frase de un párrafo. En árabe, japonés, chino y coreano
   `text-transform` no hace nada —esas escrituras no tienen caja— y el
   titular sale tal cual, que es lo correcto.

   Antes esto era un rótulo alineado a la izquierda de 62ch con hueco para
   un segundo hijo que nunca llegó; de ahí que ya no haya ni `flex` ni
   `gap`: es una caja de bloque con un solo hijo. */
.mk-intro {
  text-align: center;
  padding-top: clamp(0.25rem, 1.5vw, 1rem);
}

.mk-intro__title {
  font-size: clamp(1.55rem, 4.4vw, 3rem);
  font-weight: 900;
  line-height: 1.06;
  letter-spacing: 0.015em;
  text-transform: uppercase;
  text-wrap: balance;
}

/* ── LA BANDA DE FOTOS ────────────────────────────────────────────────
   Las mismas medidas EXACTAS que la del ranking (`.rk-slideshow`): 2,8/1 y
   el mismo tope. Aquí hace lo mismo que allí —una banda entre el titular y
   el trabajo de la página— y con la proporción de la tienda (21/9) los
   filtros se irían por debajo del pliegue en un portátil.

   Se pinta VACÍA y oculta: las diapositivas son aviones publicados y las
   mete js/market.js cuando contesta /api/market. Sin ni un avión con foto
   se queda oculta — una banda gris a todo lo ancho no es una banda, es un
   agujero. */
.mk-slideshow {
  aspect-ratio: 2.8 / 1;
  max-height: min(44vh, 420px);
}

.mk-slideshow[hidden] {
  display: none;
}

/* ── LA BALDOSA DE VENDER ─────────────────────────────────────────────
   Copiada palabra por palabra de `.rk-gate` (css/ranking.css) por el mismo
   motivo que el titular de aquí arriba: es la MISMA pieza, en el mismo
   sitio de la página, y esta página no carga aquel archivo.

   El botón se va a la DERECHA en cuanto hay sitio. En una pantalla ancha,
   un botón al final de una línea de texto se pierde; pegado al canto
   derecho es lo primero que encuentra el ojo después de leer la frase. */
.mk-sell {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 1.8vw, 1.15rem);
  flex-wrap: wrap;
  padding: clamp(0.8rem, 1.8vw, 1.05rem) clamp(1rem, 2.2vw, 1.35rem);
}

.mk-sell__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border-radius: 9999px;
  color: var(--accent-on);
  background: var(--accent);
  box-shadow: var(--accent-shadow);
}

.mk-sell__icon svg {
  width: 19px;
  height: 19px;
}

/* La frase se queda con lo que sobre, pero con una base ancha para que no
   arrastre al botón a una línea propia hasta que de verdad no quepa: por
   debajo de 14 rem se parte en tres renglones de dos palabras, y entonces
   la baldosa vuelve a ser alta, que es justo lo que se le ha quitado. */
.mk-sell__line {
  flex: 1 1 14rem;
  min-width: 0;
  color: rgb(var(--c-ink));
  font-size: clamp(1rem, 2vw, 1.2rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

/* `.btn-primary` viene con `margin-top` y `align-self: flex-start` pensados
   para ir al final de un formulario en columna; dentro de esta fila los dos
   descuadran la línea con la frase de al lado. */
.mk-sell__cta {
  margin-top: 0;
  margin-inline-start: auto;
  align-self: center;
}

/* ── Filtros ───────────────────────────────────────────────────────────
   Tres alturas y no una fila: las pastillas de categoría son la pregunta
   grande —qué clase de avión—, el buscador es la pregunta libre, y la fila
   de desplegables es el afinado. Apiladas se leen en ese orden; en una sola
   línea, en un móvil, ninguna de las tres cabría. */
.mk-filters {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

/* Se desplaza en horizontal en pantallas estrechas, como el dock: doce
   pastillas no caben en un móvil y partirlas en cuatro renglones convierte
   un filtro en un menú. */
.mk-cats {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 0.15rem;
}

.mk-cats::-webkit-scrollbar {
  display: none;
}

/* ── La baldosa de cada categoría ──────────────────────────────────────
   La silueta ARRIBA y el rótulo DEBAJO, no en fila. Puestos en fila, la
   silueta tenía que caber en la altura de una línea de texto —veintiún
   píxeles— y ahí un bimotor y un turbohélice son la misma mancha. Apilados,
   la silueta manda en el tamaño y el rótulo se acomoda debajo: es la
   diferencia entre un icono que decora y un dibujo que se puede mirar.

   Y CUADRADA, todas del mismo tamaño. Antes cada baldosa medía lo que medía
   SU rótulo, y una fila donde «Todo» ocupa ochenta píxeles y «Pistón
   monomotor» ciento setenta se lee como doce cosas distintas puestas una al
   lado de otra, no como las doce opciones de una misma lista. Con todas
   iguales, lo único que cambia de una a otra es el dibujo, que es
   exactamente lo que hay que mirar.

   El precio es el renglón partido, que es justo lo que aquí se evitaba: son
   catorce idiomas y el ruso tiene «Экспериментальные», diecisiete letras sin
   un sitio por donde cortar. Casi todos los rótulos parten solos por el
   espacio entre palabras y quedan bien; los dos que no —ése y el neerlandés
   «Zweefvliegtuigen»— llevan guiones blandos puestos a mano en
   `js/market-content.js`, y sólo por eso parten por sílaba y CON guión.
   Puestos a probar: `hyphens: auto` no basta, porque el navegador únicamente
   silabea los idiomas de los que tiene diccionario y el ruso no lo trae.

   Medido en los catorce idiomas: doce baldosas de 112 × 112, ninguna etiqueta
   se sale y ninguna pasa de dos renglones.

   El rótulo va a `width: 100%` y se centra con márgenes automáticos, NO
   haciéndolo `display: flex`. Con flex, la caja del rótulo se mide por su
   contenido y puede salirse de la baldosa: «Экспериментальные» se montaba
   encima de las vecinas, y ni el guionado ni el `overflow-wrap` llegaban a
   actuar porque, para el navegador, ahí nunca faltó sitio. Atado al 100 %
   del ancho, falta sitio y entonces sí parte. Los márgenes automáticos hacen
   el centrado que hacía el flex, y las siluetas quedan todas a la misma
   altura, que es de lo que iba todo esto. */
.mk-chip {
  display: inline-flex;
  flex-shrink: 0;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  /* Siete rem: no es un número redondo por gusto, es lo que mide el rótulo
     más ancho que cabe en UN renglón de los catorce idiomas —«Zweefvlieg-
     tuigen», noventa y seis píxeles— más el relleno. Por debajo de esto se
     parte también el neerlandés; por encima, la fila entera crece por una
     sola palabra. */
  width: 7rem;
  height: 7rem;
  padding: 0.75rem 0.4rem 0.55rem;
  /* Ya no es una pastilla: a esta altura, el radio de estadio la volvería
     un óvalo. El de 1,25 rem es el mismo de las chapas de la casa. */
  border-radius: 1.25rem;
  color: rgb(var(--c-body));
  background: var(--pill);
  font-size: 0.7rem;
  font-weight: 700;
  line-height: 1.15;
  text-align: center;
  transition:
    background 0.25s var(--lg-ease),
    color 0.25s var(--lg-ease);
}

.mk-chip__name {
  width: 100%;
  margin: auto 0;
  /* `anywhere` y no `break-word`: el segundo no cuenta para el ancho mínimo
     de la caja, así que una palabra más larga que la baldosa la ensancha en
     vez de partirse. `anywhere` sí cuenta, y es lo que garantiza que ninguna
     de las ciento cincuenta y tres etiquetas de los catorce idiomas se salga.
     El guionado va delante: si el navegador sabe silabear ese idioma corta
     por sílaba y con guión, y sólo si no sabe se parte a hueso. */
  overflow-wrap: anywhere;
  hyphens: auto;
}

/* Treinta y ocho píxeles: por encima de eso la fila se come la pantalla
   de un móvil, y por debajo vuelve el problema de antes — que las once
   siluetas se distingan entre sí pide ver dónde están los motores, y eso
   necesita sitio. */
.mk-chip__icon {
  width: 38px;
  height: 38px;
  flex-shrink: 0;
}

.mk-chip:hover {
  color: rgb(var(--c-ink));
  background: var(--hover-soft);
}

/* La encendida va en la TINTA del tema, sólida. En una paleta sin color de
   marca, el contraste pleno es lo único que separa «este filtro está puesto»
   de «este filtro se puede poner». */
.mk-chip--on {
  color: var(--accent-on);
  background: var(--accent);
  box-shadow: var(--accent-shadow);
}

.mk-chip--on:hover {
  color: var(--accent-on);
  background: var(--accent-hover);
}

.mk-chip:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.mk-search {
  max-width: 34rem;
}

.mk-refine {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Los cuatro afinados: marca y modelo (un solo control, que abre el
   catálogo), tipo de anuncio y los dos topes de precio. `auto-fit` con un
   mínimo de 9,5 rem los reparte solos —cuatro en una pantalla ancha, dos en
   una tableta y uno en un móvil— sin una sola media query. */
.mk-refine__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 9.5rem), 1fr));
  gap: 0.6rem;
}

.mk-field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.mk-field__label {
  padding-left: 0.9rem;
  color: rgb(var(--c-muted));
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* El control de los filtros es más bajo que el del formulario a propósito:
   arriba se están tocando cinco seguidos y la altura de un campo de
   formulario los convertiría en un muro. */
.mk-select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  min-width: 0;
  border: none;
  border-radius: 2.5rem;
  padding: 0.6rem 2.2rem 0.6rem 0.95rem;
  background-color: rgb(var(--c-elevated));
  color: rgb(var(--c-ink));
  font-size: 0.85rem;
  font-family: inherit;
  box-shadow: var(--fieldgroup-shadow);
  transition: box-shadow 0.25s var(--lg-ease);
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.1rem) 55%, calc(100% - 0.85rem) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

/* Un campo numérico no lleva flecha dibujada: la que se ve es la del propio
   navegador, y las dos juntas son dos flechas. */
.mk-field--num .mk-select {
  padding-right: 0.95rem;
  background-image: none;
}

.mk-select:focus {
  outline: none;
  box-shadow: var(--fieldgroup-shadow), var(--accent-ring);
}

.mk-select:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.mk-refine__flags {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
}

/* La casilla y su rótulo son UN objetivo de pulsación: el `<label>` envuelve
   a los dos, así que el texto también marca. En un móvil, una casilla de
   16 px suelta se falla una de cada tres veces. */
.mk-check {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: rgb(var(--c-body));
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}

.mk-check input {
  width: 1.05rem;
  height: 1.05rem;
  accent-color: var(--accent);
  cursor: pointer;
}

.mk-count {
  color: rgb(var(--c-muted));
  font-size: 0.8rem;
  font-weight: 600;
}

/* El aviso de que la lista viene cortada. Existe porque un tope callado se
   lee como «esto es todo lo que hay». */
.mk-note {
  color: rgb(var(--c-body));
  font-size: 0.8rem;
  padding: 0.6rem 1rem;
  border-radius: 1rem;
  border: 1px solid rgb(var(--c-warn-rgb) / 0.35);
  background: rgb(var(--c-warn-rgb) / 0.10);
}

.mk-note[hidden] {
  display: none;
}

/* ══════════════════════════════════════════════════════════════════════
   1 bis · DÓNDE — el radio, el punto de partida y el mapa
   ──────────────────────────────────────────────────────────────────────
   Puerto del mapa de penny.flights, el mismo que ya vive en
   /flight-schools (css/schools.css). Se copia en vez de compartirse por lo
   que ya explica la cabecera de este archivo: esta página no carga
   css/schools.css, y traerse 1.100 líneas de directorio para heredar
   ciento cincuenta sería pagar todo aquello por esto.

   Lo que cambia respecto a las escuelas, y no es cosmético:

     · la chincheta lleva PRECIO, no número de orden. Es un mercado: lo
       primero que se mira de un avión es cuánto vale, y un mapa de puntos
       idénticos obliga a abrirlos uno a uno para saberlo. Es además lo que
       hace el mapa de penny.flights, del que sale toda esta pieza.
     · dos o más aviones en el MISMO aeródromo se juntan en una sola
       chincheta con su cuenta. Sin agrupar, seis Cessna en Sabadell son
       seis pastillas encima de la misma coordenada y no se lee ninguna.
     · el círculo de radio sólo existe cuando hay radio. Aquí el estado de
       partida es «todo el mundo».
   ══════════════════════════════════════════════════════════════════════ */

/* La superficie sólida —no vidrio— por lo mismo que en las escuelas: lo que
   se teclea tiene que leerse sin depender de lo que pase por detrás. */
.mk-geo {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0 0.5rem 0 1.1rem;
  min-height: 56px;
  border-radius: 2.5rem;
  background: rgb(var(--c-elevated));
  box-shadow: var(--fieldgroup-shadow);
  transition: box-shadow 0.25s var(--lg-ease);
}

.mk-geo:focus-within {
  box-shadow: var(--fieldgroup-shadow), var(--accent-ring);
}

.mk-geo__icon {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  color: rgb(var(--c-subtle));
}

.mk-geo__input {
  flex: 1;
  min-width: 0;
  height: 54px;
  border: none;
  background: none;
  outline: none;
  color: rgb(var(--c-ink));
  font-family: inherit;
  font-size: 0.98rem;
  font-weight: 500;
}

.mk-geo__input::placeholder {
  color: rgb(var(--c-subtle));
  font-weight: 400;
}

.mk-geo__input::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
}

.mk-geo__clear {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border-radius: 9999px;
  color: rgb(var(--c-muted));
  background: var(--track);
  transition: background 0.2s var(--lg-ease), color 0.2s var(--lg-ease);
}

.mk-geo__clear svg {
  width: 14px;
  height: 14px;
}

.mk-geo__clear:hover {
  color: rgb(var(--c-ink));
  background: var(--hover-soft);
}

.mk-geo__clear[hidden] {
  display: none;
}

/* El filete que separa los mandos dentro de la misma superficie. Un hueco no
   bastaba: sin línea, el desplegable de la distancia parecía flotar suelto
   dentro del campo de texto. */
.mk-geo__divider {
  width: 1px;
  height: 26px;
  flex-shrink: 0;
  background: var(--hairline);
}

/* «Mi ubicación» va DENTRO del campo y no suelto al lado: es la otra forma
   de contestar a la misma pregunta que el campo de texto —desde dónde—, no
   una acción aparte. */
.mk-geo__locate {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 40px;
  padding: 0 0.9rem;
  flex-shrink: 0;
  border-radius: 9999px;
  color: rgb(var(--c-body));
  background: var(--pill);
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  white-space: nowrap;
  transition: background 0.2s var(--lg-ease), color 0.2s var(--lg-ease);
}

.mk-geo__locate:hover {
  color: rgb(var(--c-ink));
  background: var(--hover-soft);
}

.mk-geo__locate svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

/* Mientras el navegador resuelve el GPS —que puede tardar segundos— la diana
   gira. Sin señal, el botón parece no haber hecho nada y se vuelve a pulsar,
   que es justo lo que aborta la primera petición. */
.mk-geo__locate.is-busy svg {
  animation: mk-locate-spin 1s linear infinite;
}

@keyframes mk-locate-spin {
  to { transform: rotate(360deg); }
}

/* Cuando hay un continente puesto, el desplegable se enciende en la tinta
   del tema. Es el mismo criterio que la pastilla de categoría: en una paleta
   sin color de marca, el contraste pleno es lo único que separa «este filtro
   está puesto» de «este filtro se puede poner» — y aquí importa el doble,
   porque un continente puesto ESCONDE aviones. */
.mk-geo__region {
  appearance: none;
  -webkit-appearance: none;
  height: 40px;
  flex-shrink: 0;
  max-width: 11rem;
  padding: 0 2rem 0 0.9rem;
  border: none;
  border-radius: 9999px;
  color: rgb(var(--c-body));
  background-color: var(--pill);
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2.5'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.65rem center;
  background-size: 11px;
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: background-color 0.2s var(--lg-ease), color 0.2s var(--lg-ease);
}

.mk-geo__region:hover {
  color: rgb(var(--c-ink));
  background-color: var(--hover-soft);
}

.mk-geo__region--on {
  color: var(--accent-on);
  background-color: var(--accent);
}

.mk-geo__region--on:hover {
  color: var(--accent-on);
  background-color: var(--accent-hover);
}

.mk-geo__region option {
  color: rgb(var(--c-ink));
  background: rgb(var(--c-elevated));
}

.mk-geo__status {
  padding: 0.15rem 1.1rem 0;
  color: rgb(var(--c-muted));
  font-size: 0.78rem;
}

.mk-geo__status[hidden] {
  display: none;
}

/* ── Sugerencias de sitio ─────────────────────────────────────────────
   Panel SÓLIDO sobre el vidrio: si fuera translúcido se vería el mapa por
   debajo de los nombres de ciudad y no se leería ninguno. */
.mk-places {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  right: 0;
  z-index: 60;
  max-height: 22rem;
  overflow-y: auto;
  padding: 0.4rem;
  border-radius: 1.25rem;
  list-style: none;
}

.mk-places[hidden] {
  display: none;
}

.mk-place {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.6rem 0.7rem;
  border-radius: 0.9rem;
  cursor: pointer;
}

.mk-place.is-active {
  background: var(--pill);
}

.mk-place__cc {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 1.75rem;
  flex-shrink: 0;
  border-radius: 0.5rem;
  border: 1px solid var(--hairline);
  background: var(--pill);
  color: rgb(var(--c-body));
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.06em;
}

.mk-place__text {
  min-width: 0;
}

.mk-place__name {
  display: block;
  color: rgb(var(--c-ink));
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mk-place__admin {
  display: block;
  color: rgb(var(--c-subtle));
  font-size: 0.75rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── El mapa ──────────────────────────────────────────────────────────
   `isolation: isolate` no es un adorno: Leaflet reparte z-index hasta 1000
   entre sus paneles y controles, y sin un contexto de apilamiento propio los
   mandos del mapa se subirían por encima de la cabecera. Con esto, todo lo
   suyo se queda dentro de su caja. */
.mk-mapwrap {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

/* Nace OCULTO y lo enciende js/market.js cuando hay algo que enseñar. Un
   mapamundi vacío encima de «todavía no hay ninguno» no informa de nada: es
   un hueco con aspecto de avería. */
.mk-mapwrap[hidden] {
  display: none;
}

.mk-mapshell {
  position: relative;
  isolation: isolate;
  z-index: 0;
  overflow: hidden;
  border-radius: 1.25rem;
  height: clamp(280px, 40vh, 420px);
  box-shadow: var(--glass-shadow);
}

/* `position: relative` + `z-index: 0` NO son decoración: Leaflet reparte
   z-index hasta 1000 entre sus paneles (400) y sus controles (1000), y el
   contenedor del mapa nace con `z-index: auto`, que NO abre contexto de
   apilamiento. Sin estas dos líneas, esos 400 y esos 1000 compiten con los
   hermanos del mapa —el botón de pantalla completa, el rótulo del punto, el
   aviso de «ninguno dice dónde está»— y los tapan con los mosaicos. Con
   ellas, todo lo de Leaflet se queda dentro de su caja y basta un `z-index`
   de 2 para pintar encima. */
#mkMap {
  position: relative;
  z-index: 0;
  width: 100%;
  height: 100%;
  background: rgb(var(--c-chip));
}

/* Pantalla completa: el MISMO contenedor llevado a `fixed`, no un segundo
   mapa dentro de una ventana modal. Un segundo mapa significaría descargar
   otra vez todos los mosaicos y mantener dos encuadres sincronizados. */
.mk-mapshell.is-fullscreen {
  position: fixed;
  inset: 0;
  z-index: 300;
  height: 100dvh;
  border-radius: 0;
  box-shadow: none;
}

body.mk-mapopen {
  overflow: hidden;
}

.mk-map__expand {
  position: absolute;
  z-index: 2;
  top: 0.75rem;
  /* `inset-inline-end` y no `right`: en árabe la página entera se refleja
     (js/i18n.js pone `dir="rtl"`), y un botón clavado a la derecha física se
     quedaría en el lado equivocado de su propio mapa. */
  inset-inline-end: 0.75rem;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 36px;
  padding: 0 0.8rem;
  border-radius: 9999px;
  color: var(--dock-ink-hover);
  background: linear-gradient(180deg, var(--dock-top), var(--dock-bottom));
  -webkit-backdrop-filter: blur(7px) saturate(170%);
  backdrop-filter: blur(7px) saturate(170%);
  box-shadow: var(--dock-shadow);
  font-family: inherit;
  font-size: 0.75rem;
  font-weight: 700;
  transition: box-shadow 0.25s var(--lg-ease);
}

.mk-map__expand:hover {
  box-shadow: var(--dock-hover-shadow);
}

.mk-map__expand svg {
  width: 14px;
  height: 14px;
}

/* Con el mapa abierto el botón dice «cerrar»: el icono se cruza y el rótulo
   lo cambia el CSS, no el JavaScript. */
.mk-mapshell.is-fullscreen .mk-map__open,
.mk-mapshell:not(.is-fullscreen) .mk-map__shut {
  display: none;
}

/* Desde dónde se está midiendo, en el canto de arriba a la izquierda. Sobre
   el mapa y no encima del campo porque es una consecuencia de lo que se ha
   elegido, no otro mando. */
.mk-map__centre {
  position: absolute;
  z-index: 2;
  top: 0.75rem;
  inset-inline-start: 0.75rem;
  max-width: calc(100% - 12rem);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  height: 36px;
  padding: 0 0.85rem;
  border-radius: 9999px;
  color: var(--dock-ink-hover);
  background: linear-gradient(180deg, var(--dock-top), var(--dock-bottom));
  -webkit-backdrop-filter: blur(7px) saturate(170%);
  backdrop-filter: blur(7px) saturate(170%);
  box-shadow: var(--dock-shadow);
  font-size: 0.75rem;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.mk-map__centre[hidden] {
  display: none;
}

.mk-map__centre svg {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
}

/* «aproximada» no es un adorno: dice que ese punto lo ha deducido una IP y
   puede estar a cincuenta kilómetros. Sin ese aviso, una lista acotada desde
   el sitio equivocado parece una lista mal hecha. */
.mk-map__approx {
  opacity: 0.7;
  font-weight: 600;
}

.mk-map__approx[hidden] {
  display: none;
}

.mk-map__empty {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: 1.25rem;
  transform: translateX(-50%);
  max-width: min(28rem, calc(100% - 2rem));
  padding: 0.6rem 1rem;
  border-radius: 1rem;
  background: rgb(var(--c-elevated) / 0.92);
  -webkit-backdrop-filter: blur(7px);
  backdrop-filter: blur(7px);
  box-shadow: var(--dock-shadow);
  color: rgb(var(--c-body));
  font-size: 0.78rem;
  text-align: center;
}

.mk-map__empty[hidden] {
  display: none;
}

.mk-map__notice[hidden] {
  display: none;
}

/* ── Chinchetas ───────────────────────────────────────────────────────
   El icono de Leaflet es una caja de tamaño CERO anclada exactamente en la
   coordenada; la pastilla de dentro se centra sola con un `transform`. Es el
   mismo truco que las etiquetas de precio de penny.flights: darle a Leaflet
   un tamaño real obligaría a medir el texto antes de pintar. */
.mk-pin {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  height: 25px;
  padding: 0 0.5rem;
  border-radius: 9999px;
  background: var(--accent);
  color: var(--accent-on);
  font-family: 'Inter', sans-serif;
  font-size: 0.72rem;
  font-weight: 800;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  box-shadow:
    0 2px 8px rgb(var(--accent-rgb) / 0.35),
    0 0 0 2px rgb(var(--c-elevated));
  transition: transform 0.3s var(--lg-spring), box-shadow 0.25s var(--lg-ease);
}

.mk-pin:hover,
.mk-pin--active {
  transform: translate(-50%, -50%) scale(1.14);
  box-shadow:
    0 6px 16px rgb(var(--accent-rgb) / 0.45),
    0 0 0 3px rgb(var(--c-elevated));
}

/* Sin precio, la SILUETA. Un disco liso se confundiría con el punto de
   «estás aquí», que también es un disco liso del mismo color: dos cosas
   distintas no pueden leerse igual en el mismo mapa. */
.mk-pin--dot {
  width: 23px;
  height: 23px;
  min-width: 0;
  padding: 0;
  justify-content: center;
}

.mk-pin__plane {
  width: 14px;
  height: 14px;
  color: var(--accent-on);
}

/* Varios en el mismo sitio. Un pelo más grande y con el número: es la
   diferencia entre «un avión aquí» y «aquí hay una flota». */
.mk-pin--many {
  height: 27px;
  font-size: 0.75rem;
}

.mk-pin__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 15px;
  height: 15px;
  padding: 0 0.2rem;
  border-radius: 9999px;
  background: rgb(var(--c-elevated) / 0.28);
  font-size: 0.62rem;
  font-weight: 800;
}

/* ── El punto de partida ──────────────────────────────────────────────
   Tinta con anillo del color de la superficie, para que se despegue del mapa
   en los dos temas, y un halo que late despacio: es lo único del mapa que no
   es un avión, y tiene que leerse como «tú estás aquí» sin rótulo. */
.mk-here {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(-50%, -50%);
  display: block;
  width: 14px;
  height: 14px;
  border-radius: 9999px;
  background: var(--accent);
  box-shadow:
    0 0 0 2.5px rgb(var(--c-elevated)),
    0 2px 6px rgba(0, 0, 0, 0.3);
}

.mk-here__pulse {
  position: absolute;
  inset: -6px;
  border-radius: 9999px;
  background: rgb(var(--accent-rgb) / 0.18);
  animation: mk-here-pulse 2.6s var(--lg-ease) infinite;
}

@keyframes mk-here-pulse {
  0%   { transform: scale(0.6); opacity: 0.9; }
  70%  { transform: scale(1.9); opacity: 0; }
  100% { transform: scale(1.9); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .mk-here__pulse {
    animation: none;
    opacity: 0.35;
  }
}

/* ── La ventanita de un grupo ─────────────────────────────────────────
   Sólo sale cuando en una coordenada hay más de uno: con uno solo, pulsar la
   chincheta abre la ficha directamente, que es a lo que se venía. */
.mk-pop {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  max-height: 15rem;
  overflow-y: auto;
  margin: -0.15rem;
}

.mk-pop__head {
  padding: 0.15rem 0.35rem 0.35rem;
  color: rgb(var(--c-subtle));
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.mk-pop__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.9rem;
  width: 100%;
  padding: 0.45rem 0.55rem;
  border-radius: 0.7rem;
  text-align: start;
  font-family: inherit;
  transition: background 0.2s var(--lg-ease);
}

.mk-pop__item:hover {
  background: var(--pill);
}

.mk-pop__text {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.mk-pop__name {
  color: rgb(var(--c-ink));
  font-size: 0.82rem;
  font-weight: 600;
}

.mk-pop__where {
  color: rgb(var(--c-subtle));
  font-size: 0.7rem;
  font-weight: 500;
}

.mk-pop__price {
  color: rgb(var(--c-muted));
  font-size: 0.78rem;
  font-weight: 700;
  white-space: nowrap;
}

/* ── Revestimiento de Leaflet ─────────────────────────────────────────
   Su hoja se deja intacta (así se puede actualizar la carpeta de vendor sin
   revisar nada); lo que cambia son los controles, que vienen con el gris de
   2011 y no saben nada de modo oscuro. */
.leaflet-container {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: rgb(var(--c-chip));
}

.leaflet-bar {
  border: none;
  border-radius: 0.75rem;
  overflow: hidden;
  box-shadow: var(--dock-shadow);
}

.leaflet-bar a,
.leaflet-bar a:hover {
  width: 32px;
  height: 32px;
  line-height: 32px;
  color: rgb(var(--c-body));
  background: rgb(var(--c-elevated));
  border-bottom-color: var(--hairline);
}

.leaflet-bar a:hover {
  background: rgb(var(--c-elevated-hover));
}

.leaflet-bar a:first-child { border-radius: 0.75rem 0.75rem 0 0; }
.leaflet-bar a:last-child  { border-radius: 0 0 0.75rem 0.75rem; }

.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
  background: rgb(var(--c-elevated));
  color: rgb(var(--c-ink));
  box-shadow: var(--dock-shadow);
}

.leaflet-popup-content-wrapper {
  border-radius: 1rem;
}

.leaflet-popup-content {
  margin: 0.6rem 0.7rem;
  min-width: 12rem;
}

.leaflet-container a.leaflet-popup-close-button {
  color: rgb(var(--c-subtle));
}

.leaflet-container a.leaflet-popup-close-button:hover {
  color: rgb(var(--c-ink));
}

/* La atribución de OpenStreetMap y CARTO se queda SIEMPRE: los mosaicos son
   suyos y su licencia la exige. Lo que se hace es vestirla —pequeña, en el
   canto, con el vidrio de la casa— en vez de esconderla. */
.leaflet-control-attribution {
  padding: 0.15rem 0.5rem;
  border-radius: 0.6rem 0 0 0;
  background: rgb(var(--c-elevated) / 0.82);
  color: rgb(var(--c-subtle));
  font-size: 0.62rem;
}

.leaflet-control-attribution a {
  color: rgb(var(--c-muted));
  text-decoration: underline;
}

/* La distancia, en la tarjeta. Sólo se pinta cuando hay un punto desde el
   que medir; sin él, la línea del sitio queda como estaba. */
.mk-card__km {
  color: rgb(var(--c-muted));
  font-weight: 700;
}

@media (max-width: 640px) {
  /* En un móvil el icono y la frase se quedan juntos en la primera línea
     —caben, y separarlos dejaba el icono solo en un renglón para él— y el
     botón se va a la segunda ocupando el ancho. `flex-basis: 100 %` es lo
     que fuerza ese salto sin tener que apilar la baldosa entera. */
  .mk-sell__cta {
    flex-basis: 100%;
    margin-inline-start: 0;
  }

  /* En un móvil, «Mi ubicación» pierde el rótulo y se queda en la diana: el
     campo de texto necesita todo el ancho que pueda tener, y una diana
     redonda dentro de un campo de sitio no se confunde con nada. */
  .mk-geo {
    padding-left: 0.9rem;
  }

  .mk-geo__locate span {
    display: none;
  }

  .mk-geo__locate {
    width: 40px;
    padding: 0;
    justify-content: center;
  }

  .mk-geo__region {
    max-width: 8.5rem;
  }

  /* El botón de pantalla completa, sin rótulo: «Mapa a pantalla completa» se
     come media anchura del mapa en un teléfono, y las cuatro flechas dicen
     lo mismo. El nombre sigue estando para quien no lo ve — el `<span>` se
     esconde con `clip`, no con `display: none`, así que el lector de
     pantalla lo lee igual. */
  .mk-map__expand .mk-map__open,
  .mk-map__expand .mk-map__shut {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .mk-map__expand {
    width: 36px;
    padding: 0;
    justify-content: center;
  }

  .mk-map__centre {
    max-width: calc(100% - 4.5rem);
  }
}

/* ══════════════════════════════════════════════════════════════════════
   2 · LA REJILLA
   ══════════════════════════════════════════════════════════════════════ */

/* La tarjeta entera es el botón que abre la ficha. Es un `<article>` con
   `role="button"` y no un `<button>` porque dentro hay un titular, una foto
   y un pie —un botón con estructura dentro no lo lee bien ningún lector— y
   por eso el cursor y el aro de foco hay que ponerlos a mano. */
.mk-card {
  cursor: pointer;
}

.mk-card:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
}

.mk-card__cat {
  position: absolute;
  z-index: 2;
  top: 0.75rem;
  left: 0.75rem;
}

.mk-badge--verified {
  gap: 0.3rem;
}

.mk-badge__icon {
  width: 12px;
  height: 12px;
}

/* ── Las fichas indexadas de otros portales ────────────────────────────
   Se pintan en la MISMA rejilla que las nuestras a propósito: quien busca
   un Bonanza quiere ver los Bonanza que hay, no elegir antes en qué
   pestaña buscarlos. Lo que tienen que hacer estos estilos es que no se
   confundan con las de la casa ni por un momento.

   Tres diferencias y ninguna es decorativa:

     · El distintivo con el nombre del portal, arriba, siempre visible.
       Es la atribución, y va en la tarjeta porque la mayoría no abre
       ninguna ficha.
     · La silueta en vez de la foto. De un anuncio ajeno no se guarda ni
       una imagen, así que el hueco tiene que leerse como «aquí no hay
       foto» y no como «la foto no ha cargado».
     · El canto sin color de marca. Lo destacado —la posición de pago— es
       de las fichas de la casa, y una externa no puede parecerse a una
       destacada ni de lejos.

   La tarjeta NO se atenúa. Se probó y era peor: un avión atenuado se lee
   como un avión que ya no está, y estos están todos a la venta. Lo que
   los separa es de quién son, no si valen. */
/* ── EL DISTINTIVO DE ORIGEN SE TIENE QUE LEER ─────────────────────────
   Nació con la tinta apagada, con la idea de que el color de marca es de
   la casa y lo de fuera va discreto. Puesto sobre la placa de la silueta
   —que es clara— quedó gris sobre gris: el nombre del portal no se leía a
   tamaño normal.

   Y eso no es un detalle estético. La atribución ES la contrapartida de
   indexar el anuncio de otro; un distintivo que no se lee es lo mismo que
   no ponerlo. Así que va en la tinta plena del tema, que sigue sin ser el
   color de marca: lo de fuera no se destaca, pero se lee. */
.mk-badge--ext {
  gap: 0.3rem;
  color: rgb(var(--c-ink));
  font-weight: 700;
  /* La placa de debajo es clara y de un solo tono; el vidrio a secas no
     separa lo suficiente. Un velo propio, del mismo material que el resto
     de las chapas de la casa. */
  background: rgb(var(--c-elevated) / 0.92);
}

.mk-card--ext {
  /* Un canto de un pelo más apagado que el de una ficha nuestra. A la
     vista casi no está; junto a una nativa, se nota. */
  border-color: var(--hairline);
}

.mk-card__media--ext .product-card__placeholder-icon {
  /* La silueta, más grande que la etiqueta de «sin foto»: aquí no es una
     ausencia que disimular, es lo que hay. */
  width: 44px;
  height: 44px;
  opacity: 0.55;
}

/* El bloque que ocupa el sitio de la descripción en una ficha externa.
   Enmarcado y no suelto, porque no es el texto del vendedor —ese no se
   copia— sino una nota de la casa explicando de quién es el anuncio. */
.mk-detail__block--ext {
  padding: 0.85rem 1rem;
  border: 1px solid var(--hairline);
  border-radius: 0.75rem;
  background: rgb(var(--c-ink) / 0.03);
}

.mk-detail__block--ext .mk-detail__text {
  margin: 0;
  color: rgb(var(--c-muted));
  font-size: 0.9rem;
  line-height: 1.55;
}

/* ── Vendido ───────────────────────────────────────────────────────────
   La foto se apaga y se le pone una banda encima. Las dos cosas: la banda
   dice qué pasa, y el apagado es lo que hace que un vendido no compita por
   la atención con los que sí se pueden comprar mientras se recorre la
   rejilla. Al pasar por encima recupera el color — sigue siendo una ficha
   que se abre y se mira. */
.mk-card--sold .product-card__media img {
  filter: grayscale(1);
  opacity: 0.6;
  transition: filter 0.35s var(--lg-ease), opacity 0.35s var(--lg-ease);
}

.mk-card--sold:hover .product-card__media img {
  filter: grayscale(0);
  opacity: 0.85;
}

.mk-card__sold,
.mk-detail__sold {
  position: absolute;
  z-index: 3;
  top: 0.75rem;
  right: 0.75rem;
  padding: 0.35rem 0.75rem;
  border-radius: 2.5rem;
  background: var(--accent);
  color: var(--accent-on);
  font-size: 0.68rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.mk-card__place {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin-bottom: 0.55rem;
  color: rgb(var(--c-muted));
  font-size: 0.78rem;
  font-weight: 600;
}

/* Horas, plazas y las siglas del IFR: los datos cortos, con icono, en una
   sola línea. Van como iconos y no como una lista de definición porque son
   cifras y no una ficha técnica — para la ficha técnica está la ficha. */
.mk-card__facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  margin-bottom: 1.1rem;
  color: rgb(var(--c-body));
  font-size: 0.8rem;
  font-weight: 600;
  min-height: 1.2rem;
}

.mk-fact {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.mk-fact__icon {
  width: 14px;
  height: 14px;
  color: rgb(var(--c-subtle));
  flex-shrink: 0;
}

/* «IFR» no lleva icono: son tres letras que ya son un símbolo, y un icono
   delante de una sigla es un dibujo que no añade nada. */
.mk-fact--flag {
  padding: 0.1rem 0.5rem;
  border-radius: 2.5rem;
  border: 1px solid var(--hairline);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
}

.mk-card__footer {
  gap: 0.6rem;
}

/* El precio va en la tinta plena y en negrita: es el dato por el que se
   compara un avión con otro, y en una tarjeta con seis datos tiene que ganar
   sin necesidad de un rótulo que diga «precio». */
.mk-card__price {
  color: rgb(var(--c-ink));
  font-size: 1.05rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

/* El pie de la tarjeta NO es un enlace: la tarjeta entera abre la ficha, y
   un enlace dentro de otro sería un objetivo de pulsación dentro de otro.
   Se pinta como el botón de la tienda porque es el mismo gesto. */
.mk-card__cta {
  pointer-events: none;
}

.mk-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
  padding: clamp(1.5rem, 4vw, 2.5rem);
}

.mk-empty[hidden] {
  display: none;
}

.mk-empty__title {
  font-size: 1.15rem;
  font-weight: 800;
}

.mk-empty__text {
  color: rgb(var(--c-muted));
  font-size: 0.9rem;
  line-height: 1.6;
  max-width: 52ch;
}

.mk-empty__cta {
  margin-top: 0.35rem;
}

/* ══════════════════════════════════════════════════════════════════════
   3 · LA FICHA
   ──────────────────────────────────────────────────────────────────────
   Una hoja centrada sobre un velo, no una página. El velo se pulsa para
   cerrar y la hoja se desplaza por dentro: lo de debajo está `inert` desde
   JavaScript, así que el tabulador no sale de aquí.
   ══════════════════════════════════════════════════════════════════════ */

.mk-detail {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(0rem, 3vw, 2.5rem);
}

.mk-detail[hidden] {
  display: none;
}

/* El velo es el MISMO que el de la ventana de la cuenta
   (`.acct-modal__veil` en css/account.css), valor por valor. Es la única
   pieza de este archivo con un color escrito a mano, y lo lleva por lo
   mismo que allí: no hay token de velo porque un velo no es una superficie
   del tema —no se lee nada encima de él—, es la oscuridad que separa una
   ventana de lo que hay debajo. Si algún día se hace token, se hacen los
   dos a la vez. */
.mk-detail__scrim {
  position: absolute;
  inset: 0;
  background: rgba(6, 9, 16, 0.55);
  -webkit-backdrop-filter: blur(10px) saturate(120%);
  backdrop-filter: blur(10px) saturate(120%);
}

/* ── QUIÉN SE DESPLAZA ────────────────────────────────────────────────
   En pantalla ancha, la HOJA no se desplaza: se desplaza solo la columna
   de la derecha. Son tres cosas a cambio de una línea:

     · la foto se queda quieta — en una ficha de un metro de alto (doce
       fotos, aviónica y cuatrocientas palabras de historia) es la
       referencia de qué avión se está mirando, y perderla obliga a subir
       para comprobarlo;
     · el aspa de cerrar, que va posicionada contra la hoja, no se va
       nunca arriba;
     · y la columna de la izquierda mide lo que mide su contenido en vez de
       estirarse hasta el alto de la otra y dejar medio metro de blanco
       debajo de la foto.

   En pantalla estrecha se invierte: ahí las dos columnas son una sola y lo
   que tiene que desplazarse es la hoja entera (ver el bloque de 900 px). */
.mk-detail__sheet {
  position: relative;
  z-index: 1;
  width: min(64rem, 100%);
  max-height: 100%;
  overflow: hidden;
  border-radius: clamp(0rem, 2vw, 1.75rem);
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
}

.mk-detail__sheet:focus {
  outline: none;
}

/* Cerrar, arriba a la derecha y SIEMPRE encima de la foto. El disco de
   vidrio es lo que lo hace visible sobre una foto clara y sobre una
   oscura — sin él, una X blanca sobre el fuselaje blanco de un Cessna
   desaparece. */
.mk-detail__close {
  position: absolute;
  z-index: 5;
  top: 0.85rem;
  right: 0.85rem;
  width: 2.4rem;
  height: 2.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  color: rgb(var(--c-ink));
  background: var(--panel-solid);
  border: 1px solid var(--hairline);
  transition: background 0.25s var(--lg-ease);
}

.mk-detail__close:hover {
  background: var(--hover-soft);
}

.mk-detail__closeIcon {
  width: 16px;
  height: 16px;
}

/* `align-self: start` para que la columna mida su contenido y no el alto de
   la otra: estirada, deja un blanco enorme debajo de la foto que se lee
   como que falta algo. Quien se desplaza es `.mk-detail__body`, no esto. */
.mk-detail__gallery {
  position: relative;
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.5rem;
  min-width: 0;
}

.mk-detail__shot {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 1.25rem;
  background: var(--pill);
}

.mk-detail__shot--empty {
  display: flex;
  align-items: center;
  justify-content: center;
}

.mk-detail__emptyIcon {
  width: 42px;
  height: 42px;
  color: rgb(var(--c-subtle));
}

/* Las miniaturas se desplazan en horizontal en vez de envolverse: doce
   fotos en tres renglones empujarían el precio y el botón por debajo del
   pliegue en cuanto el anuncio tenga galería completa. */
.mk-detail__thumbs {
  display: flex;
  gap: 0.4rem;
  overflow-x: auto;
  scrollbar-width: none;
  padding-bottom: 0.15rem;
}

.mk-detail__thumbs::-webkit-scrollbar {
  display: none;
}

.mk-detail__thumb {
  flex-shrink: 0;
  width: 4.5rem;
  height: 3.4rem;
  border-radius: 0.7rem;
  overflow: hidden;
  opacity: 0.55;
  transition: opacity 0.2s var(--lg-ease), box-shadow 0.2s var(--lg-ease);
}

.mk-detail__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mk-detail__thumb:hover {
  opacity: 0.85;
}

.mk-detail__thumb.is-on {
  opacity: 1;
  box-shadow: 0 0 0 2px var(--accent);
}

/* La columna que SÍ se desplaza (ver `.mk-detail__sheet`). El hueco de la
   derecha deja sitio al aspa de cerrar, que va pegada a esa esquina: sin él
   el titular de un avión con nombre largo se le mete por debajo. */
.mk-detail__body {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: clamp(1.1rem, 2.5vw, 1.75rem);
  padding-right: clamp(3.4rem, 5vw, 4rem);
  min-width: 0;
  overflow-y: auto;
  max-height: 100%;
  overscroll-behavior: contain;
}

.mk-detail__eyebrow {
  color: rgb(var(--c-muted));
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.mk-detail__title {
  font-size: clamp(1.3rem, 2.6vw, 1.75rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.mk-detail__price {
  color: rgb(var(--c-ink));
  font-size: clamp(1.15rem, 2.2vw, 1.45rem);
  font-weight: 800;
  letter-spacing: -0.01em;
}

/* La ficha técnica es una lista de definición de verdad: cada dato es un
   par «qué» y «cuánto», y así lo lee también quien no ve la pantalla. Las
   dos columnas son de ancho fijo para que las cifras queden alineadas — es
   una tabla de comparar, y una tabla desalineada no se compara. */
.mk-detail__specs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
  gap: 0.5rem 1.25rem;
  margin: 0.35rem 0;
  padding: 0.9rem 0;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
}

.mk-spec {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.mk-spec dt {
  color: rgb(var(--c-muted));
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.mk-spec dd {
  color: rgb(var(--c-ink));
  font-size: 0.92rem;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.mk-detail__block {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.mk-detail__h3 {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--c-muted));
}

.mk-detail__text {
  color: rgb(var(--c-body));
  font-size: 0.88rem;
  line-height: 1.65;
  overflow-wrap: anywhere;
}

/* La descripción respeta los saltos de línea de quien la escribió: un
   anuncio de un avión se escribe por bloques —historia, mantenimiento,
   aviónica— y aplastarlos en un párrafo de cuatrocientas palabras es
   quitarle al texto la única estructura que tenía. */
.mk-detail__text--long {
  white-space: pre-wrap;
}

.mk-detail__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 0.35rem;
}

.mk-detail__cta--inert {
  opacity: 0.55;
  cursor: default;
}

/* El aviso de que la casa no está en medio de la compra. Va pequeño y al
   final, que es donde se lee lo que hay que saber antes de coger el
   teléfono — y va SIEMPRE, no solo en los caros. */
.mk-detail__disclaimer {
  color: rgb(var(--c-subtle));
  font-size: 0.74rem;
  line-height: 1.55;
}

/* Los atajos del vendedor —su página y su teléfono— al lado del botón
   principal. Van en `btn-ghost` y no en `btn-primary` porque el camino que
   esta casa recomienda es la hoja de contacto: sólo puede haber un botón
   que parezca EL botón. */
.mk-detail__link {
  font-size: 0.85rem;
  white-space: nowrap;
}

/* ══════════════════════════════════════════════════════════════════════
   3 ter · LA HOJA DE CONTACTO
   ──────────────────────────────────────────────────────────────────────
   El formulario que manda la pregunta al vendedor, dentro de la propia
   ficha. Va SEPARADO del resto por una línea y un poco de aire, y ese
   detalle es la mitad de que funcione: lo de arriba es información que se
   lee, esto es una acción que se hace, y las dos cosas seguidas sin un
   corte se leen como un solo bloque que nadie termina.

   No lleva marco ni fondo propio: está dentro de la hoja de la ficha, que
   ya es un panel de cristal, y un panel dentro de otro panel es la forma
   más rápida de que una ventana parezca un formulario de una web de 2011.
   ══════════════════════════════════════════════════════════════════════ */

.mk-ask {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.6rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--hairline);
}

.mk-ask__form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-top: 0.5rem;
}

/* La casilla de la copia: la marca y su texto en la misma línea, alineados
   por arriba para que un texto que se parta en dos líneas no deje la
   casilla flotando en el medio. */
.mk-ask__check {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  color: rgb(var(--c-body));
  font-size: 0.85rem;
  line-height: 1.5;
  cursor: pointer;
}

.mk-ask__check input {
  margin-top: 0.15rem;
  accent-color: rgb(var(--c-ink));
  flex: none;
}

/* ── EL CEBO ──────────────────────────────────────────────────────────
   Fuera de la pantalla, no `display: none`. Un `display: none` lo ven los
   robots que leen el CSS y lo saltan; sacarlo del lienzo con posición
   absoluta lo esconde igual para una persona y no se distingue tan rápido.

   `aria-hidden` y `tabindex="-1"` van en el HTML, que es lo que impide que
   un lector de pantalla lo anuncie o que el tabulador caiga dentro. Esto es
   sólo la mitad visual. */
.mk-ask__pot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.mk-ask__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
}

/* El aviso de la hoja. En `bad` se pone rojo; sin tono, es el color del
   texto normal — que es lo que hace falta para «enviando». */
.mk-ask__status {
  font-size: 0.86rem;
  font-weight: 600;
  line-height: 1.5;
  color: rgb(var(--c-body));
}

.mk-ask__status[hidden] {
  display: none;
}

.mk-ask__status.is-bad {
  color: var(--c-danger);
}

/* Lo que se hace con el mensaje, en pequeño y debajo del botón. Va DESPUÉS
   del botón a propósito: es la letra pequeña, y ponerla antes de la acción
   la convierte en un obstáculo que hay que leer para llegar a pulsar. */
.mk-ask__note {
  color: rgb(var(--c-subtle));
  font-size: 0.72rem;
  line-height: 1.55;
}

/* Enviado: se queda el titular y una frase, sin formulario. El aire de
   arriba es el mismo para que la ficha no dé un salto al sustituirlo. */
.mk-ask.is-done {
  gap: 0.4rem;
}

/* ══════════════════════════════════════════════════════════════════════
   3 bis · EL NAVEGADOR DE MODELOS
   ──────────────────────────────────────────────────────────────────────
   La misma hoja sobre velo que la ficha —mismo velo, mismo material, misma
   aspa— con otra cosa dentro: dos columnas de listas que se desplazan cada
   una por su lado.

   ── POR QUÉ DOS COLUMNAS Y NO UN ACORDEÓN DE TRES NIVELES ────────────
   Porque el tercer nivel llegaría a un cuarto de pantalla de sangrado. Con
   marca › serie › modelo en una sola columna, un Cessna Citation CJ3 queda
   a tres sangrados del borde, y en un móvil de 360 px eso es la mitad del
   ancho gastada en blanco. Repartido —la marca a la izquierda, sus series
   a la derecha— solo hay UN sangrado, el de los modelos dentro de su serie.

   ── Y EN EL MÓVIL, LAS MISMAS DOS ────────────────────────────────────
   Por debajo de 860 px las dos columnas ocupan la misma casilla de la
   rejilla y se ve la de encima: elegir una marca desliza la de modelos, y
   el botón de volver la retira. No es una segunda maqueta, es la misma con
   `is-drilled` puesto.
   ══════════════════════════════════════════════════════════════════════ */

.mk-browse {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(0rem, 3vw, 2.5rem);
}

.mk-browse[hidden] {
  display: none;
}

/* El MISMO velo que la ficha, valor por valor. El porqué de que sea un color
   escrito a mano y no un token, en el bloque de `.mk-detail__scrim`. */
.mk-browse__scrim {
  position: absolute;
  inset: 0;
  background: rgba(6, 9, 16, 0.55);
  -webkit-backdrop-filter: blur(10px) saturate(120%);
  backdrop-filter: blur(10px) saturate(120%);
}

/* La hoja NO se desplaza: se desplazan las columnas. Así la cabecera —con el
   buscador dentro— se queda quieta mientras se recorren doscientas marcas,
   que es justo cuando hace falta poder escribir. */
.mk-browse__sheet {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: min(62rem, 100%);
  height: min(46rem, 100%);
  overflow: hidden;
  border-radius: clamp(0rem, 2vw, 1.75rem);
}

.mk-browse__sheet:focus {
  outline: none;
}

/* ── La cabecera ───────────────────────────────────────────────────── */

.mk-browse__head {
  flex-shrink: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.75rem 1rem;
  padding: clamp(1.1rem, 2.5vw, 1.6rem) clamp(1.1rem, 2.5vw, 1.6rem) 0.9rem;
  border-bottom: 1px solid var(--hairline);
}

.mk-browse__heading {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

.mk-browse__title {
  font-size: clamp(1.05rem, 2.2vw, 1.3rem);
  font-weight: 800;
  letter-spacing: -0.015em;
  line-height: 1.2;
}

.mk-browse__sub {
  color: rgb(var(--c-muted));
  font-size: 0.8rem;
  line-height: 1.45;
}

/* El aspa reutiliza `.mk-detail__close` entera y solo se le quita el
   posicionamiento: aquí no flota sobre una foto, vive en la cabecera. */
.mk-browse__close {
  position: static;
  align-self: start;
  flex-shrink: 0;
}

.mk-browse__search {
  grid-column: 1 / -1;
  max-width: none;
}

/* ── Las dos columnas ──────────────────────────────────────────────── */

.mk-browse__panes {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 17rem) minmax(0, 1fr);
}

.mk-browse__pane {
  min-width: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0.6rem 0.5rem 1.4rem;
}

.mk-browse__pane--makes {
  border-right: 1px solid var(--hairline);
}

/* Buscando no hay dos columnas: hay UNA lista de resultados. Mezclar marcas,
   series y modelos en dos columnas obligaría a decidir cuál va en cuál, y
   quien teclea «bonanza» no está preguntando por una marca ni por una serie,
   está preguntando por lo que se llame así. */
.mk-browse__panes.is-searching {
  grid-template-columns: minmax(0, 1fr);
}

.mk-browse__panes.is-searching .mk-browse__pane--makes {
  display: none;
}

/* El rótulo de cada columna: se queda pegado arriba al desplazar, porque a
   la altura del Cessna 172 ya no se ve de qué marca son las series que se
   están mirando. */
.mk-browse__paneHead {
  position: sticky;
  top: -0.6rem;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: -0.6rem -0.5rem 0.35rem;
  padding: 0.7rem 1rem 0.55rem;
  background: var(--panel-solid);
  border-bottom: 1px solid var(--hairline);
  color: rgb(var(--c-muted));
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.mk-browse__makeName {
  color: rgb(var(--c-ink));
  font-size: 0.82rem;
  letter-spacing: 0;
  text-transform: none;
}

.mk-browse__paneNote {
  margin-left: auto;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  white-space: nowrap;
}

/* Volver a las marcas. Solo existe en pantalla estrecha: con las dos
   columnas a la vista no hay a dónde volver, la lista de marcas está ahí. */
.mk-browse__back {
  display: none;
  align-items: center;
  gap: 0.3rem;
  margin-left: -0.35rem;
  padding: 0.25rem 0.5rem 0.25rem 0.25rem;
  border-radius: 2rem;
  color: rgb(var(--c-body));
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.mk-browse__back:hover {
  background: var(--hover-soft);
  color: rgb(var(--c-ink));
}

.mk-browse__backIcon {
  width: 14px;
  height: 14px;
  transform: rotate(180deg);
}

.mk-browse__empty {
  padding: 2.5rem 1.25rem;
  color: rgb(var(--c-muted));
  font-size: 0.85rem;
  line-height: 1.6;
  text-align: center;
}

.mk-browse__rows {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* ── La fila ───────────────────────────────────────────────────────────
   Una sola pieza para marcas, series y modelos: cambia el sangrado, el
   peso y si lleva galón, pero el alto y la zona de pulsación son los
   mismos en las tres. Dos mil setecientas filas con tres alturas distintas
   se leen como tres listas pegadas. */
.mk-brow {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  width: 100%;
  padding: 0.55rem 0.75rem;
  border-radius: 0.7rem;
  color: rgb(var(--c-body));
  font-size: 0.85rem;
  font-weight: 500;
  text-align: left;
  line-height: 1.35;
  transition:
    background 0.18s var(--lg-ease),
    color 0.18s var(--lg-ease);
}

.mk-brow:hover {
  background: var(--hover-soft);
  color: rgb(var(--c-ink));
}

.mk-brow:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: -2px;
}

.mk-brow__name {
  flex: 1;
  min-width: 0;
}

/* De qué marca es, en los resultados de la búsqueda. Va DEBAJO del nombre y
   no detrás: «F33A Bonanza · Beechcraft» en una línea se parte por donde no
   debe en cuanto la pantalla es estrecha. */
.mk-brow__of {
  display: block;
  color: rgb(var(--c-muted));
  font-size: 0.72rem;
  font-weight: 600;
}

/* La cuenta de anuncios. Solo sale cuando hay alguno: un catálogo entero
   sembrado de ceros dice «aquí no hay nada» de dos mil setecientas maneras
   distintas, cuando lo que hay es un catálogo. */
.mk-brow__n {
  flex-shrink: 0;
  min-width: 1.4rem;
  padding: 0.1rem 0.4rem;
  border-radius: 2rem;
  background: var(--pill);
  color: rgb(var(--c-ink));
  font-size: 0.7rem;
  font-weight: 700;
  text-align: center;
}

.mk-brow__tick {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
}

/* El galón gira al abrir. Es la única señal de que una serie tiene algo
   dentro, y por eso la transición es lo primero que se nota al pulsar. */
.mk-brow__chevron {
  flex-shrink: 0;
  width: 13px;
  height: 13px;
  color: rgb(var(--c-muted));
  transition: transform 0.2s var(--lg-ease);
}

.mk-brow[aria-expanded='true'] .mk-brow__chevron {
  transform: rotate(90deg);
}

/* `--solo` es un avión suelto de la marca, sin serie: el C23 Sundowner 180
   de Beechcraft o el 162 Skycatcher de Cessna. Va en el primer nivel, así
   que pesa como una serie aunque no despliegue nada. */
.mk-brow--all,
.mk-brow--series,
.mk-brow--solo {
  font-weight: 700;
  color: rgb(var(--c-ink));
}

.mk-brow--all {
  margin-bottom: 0.3rem;
}

/* Lo elegido va en la tinta del tema, sólido, igual que la pastilla de
   categoría encendida: en una paleta sin color de marca, el contraste pleno
   es lo único que separa «esto está puesto» de «esto se puede poner». */
.mk-brow.is-on,
.mk-brow.is-on:hover {
  background: var(--accent);
  color: var(--accent-on);
}

.mk-brow.is-on .mk-brow__n {
  background: rgb(var(--c-canvas) / 0.22);
  color: var(--accent-on);
}

.mk-brow.is-on .mk-brow__of,
.mk-brow.is-on .mk-brow__chevron {
  color: inherit;
  opacity: 0.75;
}

/* Los modelos de una serie: UN sangrado y una guía vertical. La guía es lo
   que dice dónde acaba la serie cuando hay veintidós modelos abiertos y el
   encabezado se ha ido por arriba. */
.mk-brow__models {
  margin: 1px 0 0.35rem 0.9rem;
  padding-left: 0.55rem;
  border-left: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.mk-brow__models[hidden] {
  display: none;
}

.mk-brow--whole {
  font-weight: 700;
  color: rgb(var(--c-ink));
}

.mk-brow--model {
  font-size: 0.82rem;
}

/* ── El botón que abre todo esto ───────────────────────────────────── */

.mk-browseBtn {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding-right: 0.75rem;
  background-image: none;
  text-align: left;
  cursor: pointer;
}

.mk-browseBtn__text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mk-browseBtn__icon {
  flex-shrink: 0;
  width: 13px;
  height: 13px;
  color: rgb(var(--c-muted));
}

/* Con marca puesta, el botón se enciende. Es el mismo aviso que da el
   `mkClear` de abajo, pero en el sitio donde se puso el filtro. */
.mk-browseBtn.is-on {
  color: rgb(var(--c-ink));
  box-shadow: var(--fieldgroup-shadow), inset 0 0 0 1.5px var(--accent);
  font-weight: 700;
}

.mk-browseBtn:focus-visible {
  outline: none;
  box-shadow: var(--fieldgroup-shadow), var(--accent-ring);
}

/* ══════════════════════════════════════════════════════════════════════
   4 · LA GUÍA
   ══════════════════════════════════════════════════════════════════════ */

.mk-guide {
  display: flex;
  flex-direction: column;
  gap: clamp(1.25rem, 3vw, 2rem);
  padding: clamp(1.5rem, 4vw, 2.75rem);
}

.mk-guide__head {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  max-width: 60ch;
}

.mk-guide__title {
  font-size: clamp(1.3rem, 2.6vw, 1.8rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.mk-guide__intro {
  color: rgb(var(--c-muted));
  font-size: 0.92rem;
  line-height: 1.65;
}

.mk-guide__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}

.mk-guide__item h3 {
  margin-bottom: 0.45rem;
  font-size: 0.98rem;
  font-weight: 700;
}

.mk-guide__item p {
  color: rgb(var(--c-muted));
  font-size: 0.87rem;
  line-height: 1.65;
}

/* La línea de los canales, al pie de la guía. Va separada por un filete y
   en cuerpo pequeño: es un apunte al margen, no una cuarta columna — si
   compartiera peso con las tres de arriba, se leería como si los canales
   fueran una parte de cómo se compra un avión, y no lo son. */
.mk-guide__aside {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding-top: clamp(0.9rem, 2vw, 1.25rem);
  border-top: 1px solid var(--hairline);
  color: rgb(var(--c-subtle));
  font-size: 0.82rem;
  line-height: 1.6;
}

.mk-guide__link {
  color: rgb(var(--c-ink));
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

.mk-guide__link:hover {
  text-decoration-thickness: 2px;
}

/* ══════════════════════════════════════════════════════════════════════
   5 · EL PANEL
   ══════════════════════════════════════════════════════════════════════ */

.mk-publish {
  display: flex;
  flex-direction: column;
  gap: clamp(1.25rem, 3vw, 1.75rem);
  padding: clamp(1.5rem, 4vw, 2.75rem);
  /* Ancla del enlace de la cabecera. El desplazamiento deja aire por arriba
     para que el titular de la sección no quede pegado al canto: caer justo
     encima de un <h2> se lee como que la página está cortada. */
  scroll-margin-top: 1.5rem;
}

.mk-publish__head {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  max-width: 60ch;
}

.mk-publish__title {
  font-size: clamp(1.3rem, 2.6vw, 1.8rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.2;
}

.mk-publish__text {
  color: rgb(var(--c-muted));
  font-size: 0.92rem;
  line-height: 1.65;
}

.mk-loading {
  color: rgb(var(--c-muted));
  font-size: 0.86rem;
}

.mk-loading[hidden],
.mk-gate[hidden],
.mk-panel[hidden] {
  display: none;
}

/* Las tres puertas —sin sesión, sin confirmar y sin base de datos— se ven
   igual: un párrafo y, como mucho, un botón. Que la de «entra» y la de
   «confirma tu correo» no se distingan por el color es deliberado: ninguna
   de las dos es un error, son dos pasos que faltan. */
.mk-gate {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
  padding: 1.15rem 1.35rem;
  border-radius: 1.25rem;
  border: 1px solid var(--hairline);
  background: var(--pill);
}

.mk-gate__text {
  color: rgb(var(--c-body));
  font-size: 0.88rem;
  line-height: 1.6;
  max-width: 58ch;
}

.mk-panel {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

/* ── Avisos ────────────────────────────────────────────────────────────
   Dos tonos y ningún icono de color a secas: el color NO es la única señal
   —el texto dice qué pasa— porque uno de cada doce hombres no distingue el
   rojo del verde. */
.mk-flash {
  padding: 0.85rem 1.15rem;
  border-radius: 1rem;
  border: 1px solid var(--hairline);
  background: var(--pill);
  color: rgb(var(--c-body));
  font-size: 0.86rem;
  line-height: 1.55;
}

.mk-flash[hidden] {
  display: none;
}

.mk-flash--ok {
  border-color: rgb(var(--c-ok-rgb) / 0.35);
  background: rgb(var(--c-ok-rgb) / 0.10);
}

.mk-flash--error {
  border-color: rgb(var(--c-danger-rgb) / 0.35);
  background: rgb(var(--c-danger-rgb) / 0.10);
}

/* ── Los tuyos ── */
.mk-mine {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.mk-mine__title {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--c-muted));
}

.mk-mine__empty {
  color: rgb(var(--c-muted));
  font-size: 0.86rem;
}

.mk-mine__empty[hidden] {
  display: none;
}

.mk-mine__list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.mk-mine__item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem 0.85rem;
  padding: 0.75rem 0.85rem 0.75rem 1.1rem;
  border-radius: 1rem;
  background: var(--pill);
}

/* El que se está editando lleva una barra de tinta a la izquierda. Con el
   formulario justo debajo, sin esta marca no se sabe cuál de las cinco filas
   es la que hay abierta. */
.mk-mine__item.is-editing {
  box-shadow: inset 3px 0 0 var(--accent);
}

.mk-mine__main {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  flex: 1;
  min-width: 12rem;
}

.mk-mine__name {
  color: rgb(var(--c-ink));
  font-size: 0.9rem;
  font-weight: 700;
}

.mk-mine__meta {
  color: rgb(var(--c-muted));
  font-size: 0.76rem;
}

/* El estado, con su punto de color delante. El punto acompaña a la palabra;
   nunca la sustituye. */
.mk-mine__status {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: rgb(var(--c-body));
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.mk-mine__status::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 9999px;
  background: rgb(var(--c-subtle));
}

.mk-mine__status[data-status='published']::before { background: var(--c-ok); }
.mk-mine__status[data-status='pending']::before   { background: var(--c-warn); }
.mk-mine__status[data-status='rejected']::before  { background: var(--c-danger); }
/* Vendido va en la tinta plena y no en verde: no es «todo bien», es «esto ya
   no está a la venta», que es un estado final y no un éxito de trámite. */
.mk-mine__status[data-status='sold']::before      { background: var(--accent); }

.mk-mine__note {
  flex-basis: 100%;
  color: rgb(var(--c-body));
  font-size: 0.82rem;
  line-height: 1.55;
}

.mk-mine__new {
  align-self: flex-start;
}

/* ── El formulario ── */
.mk-form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--hairline);
}

.mk-form[hidden] {
  display: none;
}

.mk-form__title {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--c-muted));
}

.mk-form__intro {
  color: rgb(var(--c-muted));
  font-size: 0.82rem;
  line-height: 1.55;
  max-width: 62ch;
}

.mk-form__grid {
  display: grid;
  gap: 1rem;
}

.mk-form__grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.mk-form__grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.mk-form__grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Una casilla dentro de una rejilla de campos se alinea con la CAJA de los
   demás, no con su rótulo: puesta arriba quedaría flotando a la altura de
   los rótulos y parecería otra cosa. */
.mk-form__toggle {
  justify-content: flex-end;
  padding-bottom: 0.85rem;
}

.mk-form__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding-top: 0.35rem;
}

/* El aviso de que editar uno publicado lo retira del tablón. Va con el tono
   de advertencia y encima del formulario, no al lado del botón: quien lo lee
   después de escribir ya ha decidido. */
.mk-warn {
  padding: 0.8rem 1.1rem;
  border-radius: 1rem;
  border: 1px solid rgb(var(--c-warn-rgb) / 0.35);
  background: rgb(var(--c-warn-rgb) / 0.10);
  color: rgb(var(--c-body));
  font-size: 0.84rem;
  line-height: 1.55;
}

.mk-warn[hidden] {
  display: none;
}

.mk-hint {
  color: rgb(var(--c-muted));
  font-size: 0.78rem;
  line-height: 1.5;
  padding-left: 0.2rem;
}

.mk-hint[hidden] {
  display: none;
}

.mk-hint--status {
  color: rgb(var(--c-body));
  font-weight: 600;
}

/* ── CUÁNTOS HAN PREGUNTADO ───────────────────────────────────────────
   Es el único número de este panel que dice si el anuncio funciona, y es un
   BOTÓN: al pulsarlo se despliegan los mensajes. Un número que no se puede
   abrir sería peor que no ponerlo — «3 preguntas» junto a un correo que
   cayó en no deseado deja a quien vende sin nada que mirar.

   Se viste como un enlace y no como un botón —subrayado de puntos, sin
   marco— porque va DENTRO de la línea de datos del anuncio, y un botón con
   su cápsula ahí dentro pesa más que la ficha entera. */
.mk-mine__leads {
  align-self: flex-start;
  border: none;
  background: none;
  padding: 0.1rem 0;
  color: rgb(var(--c-ink));
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  text-decoration: underline dotted;
  text-underline-offset: 0.2em;
  cursor: pointer;
}

.mk-mine__leads:hover {
  text-decoration-style: solid;
}

.mk-mine__leads:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: 0.35rem;
}

/* Mientras se piden, cuando no hay ninguna, y cuando la petición falla. Es
   el mismo hueco para los tres estados: lo que cambia es la frase. */
.mk-mine__asking {
  flex-basis: 100%;
  color: rgb(var(--c-muted));
  font-size: 0.8rem;
  padding-top: 0.5rem;
}

.mk-mine__asking--bad {
  color: var(--c-danger);
}

/* ── LA BANDEJA ───────────────────────────────────────────────────────
   Las preguntas de un anuncio, debajo de su ficha en la lista. `flex-basis:
   100%` porque la ficha de «los míos» es una fila flexible y esto tiene que
   ocupar un renglón entero por debajo de todo lo demás, no meterse entre el
   estado y el botón de editar. */
.mk-asks {
  flex-basis: 100%;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--hairline);
  list-style: none;
}

.mk-ask-item {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.7rem 0.85rem;
  border-radius: 0.9rem;
  background: rgb(var(--c-elevated));
}

.mk-ask-item__who {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.7rem;
  color: rgb(var(--c-ink));
  font-size: 0.85rem;
}

.mk-ask-item__who a {
  color: rgb(var(--c-body));
  text-decoration: underline;
  text-underline-offset: 0.15em;
  overflow-wrap: anywhere;
}

.mk-ask-item__when {
  color: rgb(var(--c-subtle));
  font-size: 0.72rem;
}

/* El texto tal cual lo escribió quien preguntó, con sus saltos de línea:
   una pregunta de tres párrafos aplastada en uno se lee peor y parece que
   la hayamos manipulado. */
.mk-ask-item__text {
  color: rgb(var(--c-body));
  font-size: 0.85rem;
  line-height: 1.6;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin-top: 0.25rem;
}

.mk-gaps {
  color: var(--c-danger);
  font-size: 0.84rem;
  font-weight: 600;
  padding-left: 0.2rem;
}

.mk-gaps[hidden] {
  display: none;
}

/* Los códigos son códigos: monoespaciados, separados y en mayúsculas. Una
   matrícula o un OACI en la misma tipografía que el nombre de la ciudad se
   leen como una palabra rara; así se leen como lo que son. */
.mk-code {
  font-family: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* Lo que falta para poder publicar: aro rojo en el campo. La lista de arriba
   dice qué es; las dos cosas, porque el aro solo se ve si el campo está en
   pantalla. */
/* El mismo aro para el campo que la hoja de contacto marca al validar. Allí
   no se puede usar `.is-missing` —esa clase la pone el formulario de
   PUBLICAR sobre el `.form-group` entero, y la hoja marca UN campo, el
   primero que falta— así que se marca con `aria-invalid`, que además es lo
   que un lector de pantalla anuncia. Un atributo que ya hay que poner por
   accesibilidad haciendo también de gancho del estilo: una cosa y no dos
   que se puedan descuadrar. */
.is-missing input,
.is-missing textarea,
input[aria-invalid='true'],
textarea[aria-invalid='true'] {
  box-shadow: var(--fieldgroup-shadow), 0 0 0 2px rgb(var(--c-danger-rgb) / 0.55);
}

/* Sin bloque de modo oscuro: `--c-danger` ya se aclara solo en la capa de
   tokens (liquid-glass.css), que es donde se decide una vez para toda la
   casa. */
.form-group.is-missing > label {
  color: var(--c-danger);
}

/* Las fotos no son un `<input>`, así que el aro no les llega: cuando lo que
   falta es una fotografía, lo que se marca es el bloque entero. */
.mk-photos.is-missing {
  border-color: rgb(var(--c-danger-rgb) / 0.55);
}

/* ── El `<select>` del formulario ──────────────────────────────────────
   La tienda no tiene ninguno, así que styles.css no lo viste. Es el mismo
   que el del panel (css/portal.css), copiado por lo que dice la cabecera de
   este archivo. La flecha va dibujada con dos degradados en vez de con una
   imagen: son dos líneas y no una petición más, y hereda el color del texto
   en oscuro. */
.form-group select {
  appearance: none;
  -webkit-appearance: none;
  border: none;
  border-radius: 2.5rem;
  padding: 0.95rem 2.6rem 0.95rem 1.25rem;
  background-color: rgb(var(--c-elevated));
  color: rgb(var(--c-ink));
  font-size: 0.95rem;
  font-family: inherit;
  box-shadow: var(--fieldgroup-shadow);
  transition: box-shadow 0.25s var(--lg-ease);
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.25rem) 55%, calc(100% - 1rem) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

.form-group select:focus {
  outline: none;
  box-shadow: var(--fieldgroup-shadow), var(--accent-ring);
}

/* ── Las fotos ─────────────────────────────────────────────────────────
   Un bloque con su propio marco: es la única parte del formulario que no
   son campos, y sin el marco las miniaturas parecerían flotar entre dos
   preguntas. Además es la zona donde se sueltan archivos, y una zona de
   soltar tiene que tener bordes visibles antes de que nadie arrastre nada. */
.mk-photos {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 1.1rem;
  border-radius: 1.25rem;
  border: 1px dashed var(--hairline);
  transition: border-color 0.2s var(--lg-ease), background 0.2s var(--lg-ease);
}

.mk-photos.is-over {
  border-color: var(--accent);
  background: var(--hover-soft);
}

.mk-photos__head {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.mk-photos__title {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgb(var(--c-muted));
}

.mk-photos__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7.5rem, 1fr));
  gap: 0.6rem;
}

.mk-photo {
  position: relative;
  border-radius: 0.9rem;
  overflow: hidden;
  background: var(--pill);
  aspect-ratio: 4 / 3;
}

.mk-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* La portada lleva aro de tinta y rótulo. Es la foto que sale en la rejilla
   —o sea, la que decide si alguien entra— y quien está subiendo doce tiene
   que ver cuál es sin contar posiciones. */
.mk-photo--cover {
  box-shadow: 0 0 0 2px var(--accent);
}

.mk-photo__flag {
  position: absolute;
  left: 0.4rem;
  bottom: 0.4rem;
  padding: 0.2rem 0.55rem;
  border-radius: 2.5rem;
  background: var(--accent);
  color: var(--accent-on);
  font-size: 0.62rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.mk-photo__tools {
  position: absolute;
  top: 0.35rem;
  right: 0.35rem;
  display: flex;
  gap: 0.3rem;
}

.mk-photo__btn {
  width: 1.85rem;
  height: 1.85rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  color: rgb(var(--c-ink));
  background: var(--panel-solid);
  border: 1px solid var(--hairline);
  transition: background 0.2s var(--lg-ease), color 0.2s var(--lg-ease);
}

.mk-photo__btn:hover {
  background: var(--hover-soft);
}

.mk-photo__btn--danger:hover {
  color: var(--c-danger-on);
  background: var(--c-danger);
}

.mk-photo__icon {
  width: 13px;
  height: 13px;
}

.mk-photos__status {
  color: var(--c-danger);
  font-size: 0.8rem;
  font-weight: 600;
}

.mk-photos__status[hidden] {
  display: none;
}

/* El botón de añadir es un `<label>` con el `<input type=file>` dentro: es
   lo que permite que se vea como los demás botones de la casa en vez de
   como el «Examinar…» del navegador, que no se puede vestir. */
.mk-photos__add {
  align-self: flex-start;
  cursor: pointer;
}

.mk-photos__add svg {
  width: 15px;
  height: 15px;
}

.mk-photos__add.is-busy,
.mk-photos__add.is-full {
  opacity: 0.55;
  pointer-events: none;
}

/* ── Botones ──────────────────────────────────────────────────────────
   `.btn-primary` viene de styles.css. `.btn-ghost` hay que traerlo porque
   esta página no carga schools.css ni portal.css. */

.btn-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  padding: 0.6rem 1.05rem;
  border-radius: 2.5rem;
  color: rgb(var(--c-body));
  background: var(--pill);
  font-size: 0.79rem;
  font-weight: 700;
  white-space: nowrap;
  transition: background 0.25s var(--lg-ease), color 0.25s var(--lg-ease);
}

.btn-ghost:hover {
  color: rgb(var(--c-ink));
  background: var(--hover-soft);
}

.btn-ghost[hidden] {
  display: none;
}

/* Lo que borra no se pinta de rojo en reposo: una fila de botones rojos deja
   de avisar de nada. Se enciende al pasar por encima, que es el momento en
   el que hace falta. */
.btn-ghost--danger:hover {
  color: var(--c-danger-on);
  background: var(--c-danger);
}

/* Un botón trabajando: apagado y sin cursor de mano. La opacidad es la señal
   de que la pulsación ya se ha registrado — sin ella se pulsa tres veces, y
   tres envíos son tres filas en la cola de revisión. */
button.is-busy,
button:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.mk-clear {
  margin-left: auto;
}

/* ── El combo del aeródromo ───────────────────────────────────────────
   Panel SÓLIDO sobre el vidrio (`.glass-panel-solid`): si fuera translúcido
   se transparentaría el formulario de debajo y la lista de aeródromos sería
   ilegible justo mientras se elige uno. */
.mk-combo {
  position: relative;
}

.mk-combo input {
  width: 100%;
}

.mk-combo__list {
  position: absolute;
  z-index: 40;
  top: calc(100% + 0.4rem);
  left: 0;
  right: 0;
  max-height: 17rem;
  overflow-y: auto;
  padding: 0.35rem;
  border-radius: 1.25rem;
}

.mk-combo__list[hidden] {
  display: none;
}

.mk-combo__option {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.6rem 0.85rem;
  border-radius: 0.9rem;
  cursor: pointer;
}

.mk-combo__option.is-active,
.mk-combo__option:hover {
  background: var(--hover-soft);
}

.mk-combo__name {
  color: rgb(var(--c-ink));
  font-size: 0.88rem;
  font-weight: 600;
}

.mk-combo__sub {
  color: rgb(var(--c-muted));
  font-size: 0.75rem;
}

/* ══════════════════════════════════════════════════════════════════════
   PANTALLAS ESTRECHAS
   ──────────────────────────────────────────────────────────────────────
   La ficha se deshace ANTES que el formulario: dos columnas de 300 px
   dejarían la ficha técnica en tiras de una palabra por renglón, y ahí es
   donde están las cifras que se comparan.
   ══════════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
  .mk-detail__sheet {
    grid-template-columns: 1fr;
    /* A una columna la hoja ocupa la pantalla entera: un margen alrededor de
       algo que ya llega arriba y abajo solo quita sitio a la foto. */
    border-radius: 0;
    max-height: 100%;
    /* Y aquí se desplaza la HOJA, no la columna: con una sola columna, dos
       zonas de desplazamiento —el cuerpo dentro de la hoja— se pelean por el
       dedo y el resultado es una ficha que a veces no baja. */
    overflow-y: auto;
  }

  .mk-detail__body {
    overflow: visible;
    max-height: none;
    padding-right: clamp(1.1rem, 2.5vw, 1.75rem);
  }

  /* Con la hoja ocupando la pantalla entera, `fixed` y la esquina de la hoja
     son el mismo sitio — y así el aspa no se va arriba al desplazar. */
  .mk-detail__close {
    position: fixed;
  }

  .mk-detail {
    padding: 0;
  }
}

/* ── EL NAVEGADOR, A UNA COLUMNA ──────────────────────────────────────
   Las dos columnas caen en la MISMA casilla de la rejilla y se decide cuál
   se ve. No hay `display: none` en la de modelos: se apila encima con
   `grid-area`, así conserva su desplazamiento al volver de las marcas. */
@media (max-width: 860px) {
  .mk-browse__panes {
    grid-template-columns: minmax(0, 1fr);
  }

  .mk-browse__pane {
    grid-area: 1 / 1;
  }

  .mk-browse__pane--makes {
    border-right: none;
  }

  .mk-browse__pane--models {
    display: none;
  }

  .mk-browse__panes.is-drilled .mk-browse__pane--makes {
    display: none;
  }

  .mk-browse__panes.is-drilled .mk-browse__pane--models,
  .mk-browse__panes.is-searching .mk-browse__pane--models {
    display: block;
  }

  /* Aquí SÍ hay a dónde volver: la lista de marcas ya no está a la vista. */
  .mk-browse__back {
    display: inline-flex;
  }

  /* La hoja ocupa la pantalla entera, igual que la ficha: un margen
     alrededor de una lista que ya llega arriba y abajo solo le quita filas. */
  .mk-browse__sheet {
    height: 100%;
    border-radius: 0;
  }
}

@media (max-width: 720px) {
  .mk-form__grid--3,
  .mk-form__grid--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .mk-form__toggle {
    padding-bottom: 0;
  }
}

@media (max-width: 480px) {
  .mk-form__grid--2,
  .mk-form__grid--3,
  .mk-form__grid--4 {
    grid-template-columns: 1fr;
  }

  .mk-mine__item {
    align-items: flex-start;
  }

  /* El botón de editar salta de renglón: apretado contra el estado en una
     pantalla de 360 px, los dos objetivos de pulsación quedan a menos de
     8 px y se pulsa el que no era. */
  .mk-mine__edit {
    flex-basis: 100%;
    justify-content: center;
  }

  .mk-clear {
    margin-left: 0;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   MODO OSCURO
   ──────────────────────────────────────────────────────────────────────
   Una sola regla, y es la del velo: todo lo demás sale de los tokens, que
   ya se invierten solos en liquid-glass.css. Sobre el lienzo negro un velo
   del 55 % apenas se nota —lo que hay debajo ya es oscuro— y la ficha
   dejaría de leerse como una ventana. Es exactamente el mismo ajuste, y el
   mismo valor, que hace css/account.css con el suyo.
   ══════════════════════════════════════════════════════════════════════ */

@media (prefers-color-scheme: dark) {
  .mk-detail__scrim,
  .mk-browse__scrim {
    background: rgba(0, 0, 0, 0.66);
  }
}
