/**
 * VibeLocal — Componentes
 * ============================================================================
 *
 * Todo va bajo `:where(.vl-redesign)`. `:where()` no aporta especificidad, así
 * que `.vl-btn` sigue valiendo (0,1,0) y el CSS se mantiene plano y fácil de
 * sobreescribir. Efecto secundario buscado: clases que ya existen en style.css
 * (.vl-badge, .vl-pill, .vl-empty-state) se reestilizan DENTRO del rediseño y
 * se quedan intactas fuera, así que las plantillas nuevas pueden reutilizar
 * shortcodes que ya funcionan —[vibelocal_place_badges], [vibelocal_event_date]—
 * en vez de duplicarlos.
 *
 * EL COMPONENTE FIRMA: .vl-vibe
 * Es la etiqueta con emoji que sale de la IA (vl_review_tags / vl_talk_about,
 * que ya guardan el emoji separado del texto). No es decoración: cada una está
 * respaldada por un número de reseñas reales. Aparece a tres escalas —chip,
 * medallón y rail— y es lo único del sistema que se permite ser llamativo.
 * El resto se mantiene callado a propósito.
 */

/* ══ 1. BOTONES ════════════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--vl-space-2);
  min-height: var(--vl-tap-min);
  padding: var(--vl-space-3) var(--vl-space-5);
  border-radius: var(--vl-radius-pill);
  font-family: var(--vl-font-ui);
  font-size: var(--vl-text-base);
  font-weight: var(--vl-fw-semibold);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  border: 1.5px solid transparent;
  cursor: pointer;
}

:where(.vl-redesign) .vl-btn:hover {
  text-decoration: none;
}

@media (prefers-reduced-motion: no-preference) {
  :where(.vl-redesign) .vl-btn {
    transition: background-color var(--vl-duration) var(--vl-ease),
                border-color var(--vl-duration) var(--vl-ease),
                color var(--vl-duration) var(--vl-ease);
  }
}

/*
 * ═══ EL COLOR DE LOS BOTONES VA SIN `:where()` ═══════════════════════════════
 *
 * Y no es un detalle de estilo: era un fallo de accesibilidad en producción.
 *
 * `:where()` vale especificidad CERO, así que `:where(.vl-redesign)
 * .vl-btn--primary` puntúa (0,1,0) y pierde contra cualquier regla de enlace de
 * style.css con un elemento de más. Como casi todos nuestros botones son
 * `<a>`, el resultado medido fue:
 *
 *   .vl-btn--primary  →  color rgb(32,38,47) sobre fondo rgb(19,126,136)
 *                        = 2.46:1. El mínimo del sistema es 4.5:1.
 *   .vl-btn--outline  →  tinta oscura en vez del teal de acción.
 *
 * O sea: texto casi negro sobre teal en el botón principal de cada pantalla
 * vacía. El FONDO sí se aplicaba —nadie pelea por `background`—, y por eso
 * parecía correcto de lejos.
 *
 * Todo lo demás (tamaños, forma, transiciones) se queda en `:where()` a
 * propósito: ahí la especificidad baja es útil porque permite ajustar un botón
 * concreto desde su contexto sin pelear. El color es lo único que no puede
 * quedar a merced de una hoja ajena.
 */

/* Primario: la acción principal de la pantalla. Blanco sobre teal-600, 4.81:1. */
:where(.vl-redesign) .vl-btn--primary { background: var(--vl-action); }
:where(.vl-redesign) .vl-btn--primary:hover { background: var(--vl-action-hover); }

.vl-redesign .vl-btn--primary,
.vl-redesign .vl-btn--primary:hover,
.vl-redesign .vl-btn--primary:focus,
.vl-redesign .vl-btn--accent,
.vl-redesign .vl-btn--accent:hover,
.vl-redesign .vl-btn--accent:focus,
.vl-redesign .vl-btn--accent-sm,
.vl-redesign .vl-btn--accent-sm:hover,
.vl-redesign .vl-btn--accent-sm:focus {
  color: var(--vl-text-on-dark);
}

.vl-redesign .vl-btn--outline,
.vl-redesign .vl-btn--outline:focus { color: var(--vl-action); }
.vl-redesign .vl-btn--outline:hover { color: var(--vl-action-hover); }

.vl-redesign .vl-btn--quiet { color: var(--vl-text-muted); }
.vl-redesign .vl-btn--quiet:hover { color: var(--vl-text); }

.vl-redesign .vl-btn[aria-disabled='true'],
.vl-redesign .vl-btn:disabled { color: var(--vl-text-faint); }

/*
 * Acento: la acción comercial (reservar, comprar).
 * El tamaño va EN el componente, no en la documentación. Blanco sobre
 * orange-600 da 4.10:1, que cumple AA solo a partir de 18.66px en negrita.
 * Fijando aquí 1.0625rem/700 el componente no puede usarse mal. Para acentos
 * más pequeños está .vl-btn--accent-sm, que baja a orange-700 (6.03:1).
 */
:where(.vl-redesign) .vl-btn--accent {
  background: var(--vl-accent);
  color: var(--vl-text-on-dark);
  font-size: 1.0625rem;
  font-weight: var(--vl-fw-bold);
}
:where(.vl-redesign) .vl-btn--accent:hover {
  background: var(--vl-accent-strong);
  color: var(--vl-text-on-dark);
}

:where(.vl-redesign) .vl-btn--accent-sm {
  background: var(--vl-accent-strong);
  color: var(--vl-text-on-dark);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  min-height: 36px;
  padding: var(--vl-space-2) var(--vl-space-4);
}

/* Contorno: acción terciaria (llamar). */
:where(.vl-redesign) .vl-btn--outline {
  background: var(--vl-white);
  color: var(--vl-action);
  border-color: var(--vl-teal-200);
}
:where(.vl-redesign) .vl-btn--outline:hover {
  background: var(--vl-action-tint);
  color: var(--vl-action-hover);
  border-color: var(--vl-teal-300);
}

:where(.vl-redesign) .vl-btn--quiet {
  color: var(--vl-text-muted);
  padding-inline: var(--vl-space-3);
}
:where(.vl-redesign) .vl-btn--quiet:hover {
  background: var(--vl-ink-100);
  color: var(--vl-text);
}

/* Ancho completo y tamaño grande: el CTA final de la ficha. */
:where(.vl-redesign) .vl-btn--block { width: 100%; }
:where(.vl-redesign) .vl-btn--lg {
  min-height: 56px;
  font-size: var(--vl-text-lg);
  font-weight: var(--vl-fw-bold);
  padding-inline: var(--vl-space-6);
}

:where(.vl-redesign) .vl-btn[aria-disabled='true'],
:where(.vl-redesign) .vl-btn:disabled {
  background: var(--vl-ink-100);
  color: var(--vl-text-faint);
  border-color: transparent;
  cursor: not-allowed;
}

/* Fila de CTAs: apilada en móvil, en línea a partir de tablet. */
:where(.vl-redesign) .vl-btn-row {
  display: grid;
  gap: var(--vl-space-3);
}
@media (min-width: 768px) {
  :where(.vl-redesign) .vl-btn-row {
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
  }
}

/* ══ 2. VIBE — EL COMPONENTE FIRMA ═════════════════════════════════════════ */
/*
 * El emoji vive en un disco blanco embutido en la píldora tintada, como una
 * ficha encajada. Es el gesto que se repite en las tres escalas y lo que hace
 * reconocible una tarjeta de VibeLocal de un vistazo.
 */

:where(.vl-redesign) .vl-vibe {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  padding: 2px var(--vl-space-3) 2px 2px;
  border-radius: var(--vl-radius-pill);
  background: var(--vl-bg-tint);
  color: var(--vl-teal-800);              /* 8.50:1 sobre teal-50 */
  font-size: var(--vl-text-xs);
  font-weight: var(--vl-fw-semibold);
  line-height: 1.3;
  white-space: nowrap;
  max-width: 100%;
}

:where(.vl-redesign) .vl-vibe__token {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 1.375rem;
  height: 1.375rem;
  border-radius: 50%;
  background: var(--vl-white);
  font-size: 0.75rem;
  line-height: 1;
  box-shadow: var(--vl-shadow-sm);
}

:where(.vl-redesign) .vl-vibe__label {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Variante naranja, para alternar en listas largas de chips. */
:where(.vl-redesign) .vl-vibe--accent {
  background: var(--vl-bg-tint-accent);
  color: var(--vl-orange-800);            /* 7.67:1 sobre orange-50 */
}

/* ── Rail: los chips en scroll horizontal, con degradado en los bordes ────── */
/*
 * Los chips ENVUELVEN, no se desplazan.
 *
 * Esto era un carril horizontal con degradado. En la tarjeta a una sola
 * columna eso significaba 709px de chips dentro de 362 visibles: el último
 * simplemente no existía para quien no supiera que aquello se arrastraba.
 * Medido en producción. Envolviendo se ven los tres siempre.
 */
:where(.vl-redesign) .vl-vibe-rail {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vl-space-2);
  padding-block: var(--vl-space-1);
}


:where(.vl-redesign) .vl-vibe-rail::-webkit-scrollbar { display: none; }
:where(.vl-redesign) .vl-vibe-rail > * { scroll-snap-align: start; }

/* Cuando caben todos, no hay que enmascarar nada. */
:where(.vl-redesign) .vl-vibe-rail--wrap {
  flex-wrap: wrap;
  overflow: visible;
  -webkit-mask-image: none;
          mask-image: none;
  margin-inline: 0;
  padding-inline: 0;
}

/* ── Medallón: la escala grande, los 3 highlights de la ficha ─────────────── */
/*
 * Sale de vl_talk_about: icono + frase de 3-8 palabras, ya respaldada por
 * reseñas. Tres columnas fijas en móvil; con dos elementos, se centran.
 */
:where(.vl-redesign) .vl-medallions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  gap: var(--vl-space-3);
  padding-block: var(--vl-space-5);
  border-block: 1px solid var(--vl-border);
}

:where(.vl-redesign) .vl-medallion {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vl-space-2);
  text-align: center;
  padding-inline: var(--vl-space-2);
}

:where(.vl-redesign) .vl-medallion + .vl-medallion {
  border-inline-start: 1px solid var(--vl-border);
}

/*
 * REGLA DEL SISTEMA: el emoji SIEMPRE va sobre blanco.
 *
 * Los emoji son glifos multicolor y no obedecen a `color`, así que ponerlos
 * sobre un círculo saturado no da un icono blanco: da un emoji de colores
 * sobre un fondo fuerte, ilegible y sucio. El color de marca entra como aro
 * alrededor del disco blanco, que es además el mismo gesto del chip a mayor
 * escala: el disco embutido se repite en las tres escalas y es lo que hace
 * reconocible el sistema.
 */
:where(.vl-redesign) .vl-medallion__token {
  display: grid;
  place-items: center;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  font-size: 1.375rem;
  line-height: 1;
  background: var(--vl-white);
  box-shadow: 0 0 0 3px var(--vl-teal-500), var(--vl-shadow-sm);
}

:where(.vl-redesign) .vl-medallion:nth-child(2) .vl-medallion__token {
  box-shadow: 0 0 0 3px var(--vl-orange-600), var(--vl-shadow-sm);
}
:where(.vl-redesign) .vl-medallion:nth-child(3) .vl-medallion__token {
  box-shadow: 0 0 0 3px var(--vl-fav), var(--vl-shadow-sm);
}

:where(.vl-redesign) .vl-medallion__text {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-snug);
  color: var(--vl-text);
  text-wrap: balance;
}

/* ══ 3. BADGES Y PÍLDORAS ══════════════════════════════════════════════════ */
/* Reestiliza el markup que ya emite [vibelocal_place_badges]. */

:where(.vl-redesign) .vl-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vl-space-2);
}

:where(.vl-redesign) .vl-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-1);
  padding: 0.25rem var(--vl-space-3);
  border-radius: var(--vl-radius-pill);
  font-family: var(--vl-font-ui);
  font-size: var(--vl-text-2xs);
  font-weight: var(--vl-fw-bold);
  letter-spacing: var(--vl-tracking-wide);
  text-transform: uppercase;
  line-height: 1.4;
  white-space: nowrap;
}

/* ink-900 sobre gold: 7.96:1. Por eso el badge Featured no lleva texto blanco. */
:where(.vl-redesign) .vl-badge--featured {
  background: var(--vl-gold);
  color: var(--vl-ink-900);
}
:where(.vl-redesign) .vl-badge--promoted {
  background: var(--vl-orange-100);
  color: var(--vl-orange-800);
}
:where(.vl-redesign) .vl-badge--verified {
  background: var(--vl-teal-100);
  color: var(--vl-teal-800);
}

/* Badge flotante sobre una imagen: necesita fondo sólido para ser legible
   pase lo que pase debajo. */
:where(.vl-redesign) .vl-badge--float {
  position: absolute;
  inset-block-start: var(--vl-space-3);
  inset-inline-start: var(--vl-space-3);
  z-index: var(--vl-z-base);
  box-shadow: var(--vl-shadow-md);
}

/* ══ 4. TARJETA DE NEGOCIO ═════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-placecard {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--vl-bg-raised);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-xl);
  overflow: hidden;
}

@media (prefers-reduced-motion: no-preference) {
  :where(.vl-redesign) .vl-placecard {
    transition: box-shadow var(--vl-duration) var(--vl-ease),
                border-color var(--vl-duration) var(--vl-ease);
  }
}

:where(.vl-redesign) .vl-placecard:hover,
:where(.vl-redesign) .vl-placecard:focus-within,
:where(.vl-redesign) .vl-placecard.is-mapfocus {
  box-shadow: var(--vl-shadow-lg);
  border-color: var(--vl-teal-200);
}

/*
 * SEÑALADA DESDE EL MAPA.
 *
 * La pone el JS al pasar el ratón por su marcador (ver assets/js/vl-redesign.js,
 * «Hover cruzado»). Comparte el realce del hover normal y añade un filete: el
 * cursor está en la otra columna, así que sin algo más marcado no se distingue
 * de la tarjeta que tienes debajo del ratón. `outline` y no `border` a propósito
 * —el borde ya lo usa el estado de arriba y cambiarle el grosor movería el
 * contenido un píxel.
 *
 * `teal-500` y no `400`: un filete es un componente de interfaz y necesita 3:1
 * contra el fondo (WCAG 1.4.11). El 400 se queda en 2.47:1 y el 500 llega a
 * 3.34:1 — está anotado en design-tokens.css.
 */
:where(.vl-redesign) .vl-placecard.is-mapfocus {
  outline: 2px solid var(--vl-teal-500);
  outline-offset: 1px;
}

:where(.vl-redesign) .vl-placecard__media {
  position: relative;
  aspect-ratio: 20 / 9;
  background: var(--vl-ink-100);
  overflow: hidden;
}

:where(.vl-redesign) .vl-placecard__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

:where(.vl-redesign) .vl-placecard__body {
  display: flex;
  flex-direction: column;
  gap: var(--vl-space-2);
  padding: var(--vl-space-4);
}

:where(.vl-redesign) .vl-placecard__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-xl);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-snug);
  letter-spacing: var(--vl-tracking-tight);
  color: var(--vl-text);
}

/* El enlace cubre toda la tarjeta, pero los controles interiores (favorito,
   llamar) quedan por encima y siguen siendo clicables por separado. */
:where(.vl-redesign) .vl-placecard__link::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: var(--vl-z-base);
}

:where(.vl-redesign) .vl-placecard__link {
  color: inherit;
  text-decoration: none;
}
:where(.vl-redesign) .vl-placecard__link:hover { color: inherit; text-decoration: none; }

/*
 * EL TITULAR, PEGADO AL NOMBRE Y UN PUNTO MÁS GRANDE.
 *
 * Pedido por el cliente el 03/09/2026: «the headline text should be slightly
 * larger and closer to the business name», y en el mismo correo «less blank
 * space in between».
 *
 * Va pegado al nombre —margen negativo contra el `gap` de la columna— porque
 * son una sola idea: el negocio y la frase que lo describe. El resto de la
 * tarjeta (estado, distancia, etiquetas) son datos sueltos y conservan su aire.
 */
:where(.vl-redesign) .vl-placecard__desc {
  font-size: var(--vl-text-base);
  line-height: var(--vl-leading-snug);
  color: var(--vl-text-body);
  margin-block-start: calc(var(--vl-space-2) * -1 + 2px);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

:where(.vl-redesign) .vl-placecard__actions {
  position: relative;
  z-index: calc(var(--vl-z-base) + 1);
}

/* ══ 5. FAVORITO ═══════════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-fav-btn {
  position: absolute;
  inset-block-start: var(--vl-space-3);
  inset-inline-end: var(--vl-space-3);
  z-index: calc(var(--vl-z-base) + 1);
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--vl-white);
  color: var(--vl-ink-600);
  box-shadow: var(--vl-shadow-md);
  font-size: 1rem;
}

:where(.vl-redesign) .vl-fav-btn:hover,
:where(.vl-redesign) .vl-fav-btn[aria-pressed='true'] {
  color: var(--vl-fav);
}

/* ══ 6. RECOMENDACIÓN Y ESTADO ═════════════════════════════════════════════ */

:where(.vl-redesign) .vl-recommend {
  display: inline-flex;
  align-items: baseline;
  gap: var(--vl-space-2);
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
}

:where(.vl-redesign) .vl-recommend__pct {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-xl);
  font-weight: var(--vl-fw-black);
  color: var(--vl-teal-700);            /* 6.85:1 */
  font-variant-numeric: tabular-nums;
}

/* Cuando no hay reseñas propias suficientes se cae a Google, y se dice.
   Nunca se presenta un dato de terceros como si fuera nuestro. */
:where(.vl-redesign) .vl-recommend--google .vl-recommend__pct {
  color: var(--vl-ink-800);
}

:where(.vl-redesign) .vl-status {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
}

:where(.vl-redesign) .vl-status::before {
  content: '';
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: currentColor;
}

:where(.vl-redesign) .vl-status--open   { color: var(--vl-open); }
:where(.vl-redesign) .vl-status--closed { color: var(--vl-closed); }

/* Fila de datos separados por líneas verticales (Open now · 2 min · €€). */
:where(.vl-redesign) .vl-metarow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vl-space-3);
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
}

:where(.vl-redesign) .vl-metarow > * {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
}

:where(.vl-redesign) .vl-metarow > * + *::before {
  content: '';
  width: 1px;
  height: 1em;
  margin-inline-end: var(--vl-space-1);
  background: var(--vl-border);
}

:where(.vl-redesign) .vl-metarow .vl-icon { color: var(--vl-ink-600); }

:where(.vl-redesign) .vl-price {
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text-body);
  letter-spacing: 0.06em;
}

/* ══ 7. CABECERA DE SECCIÓN ════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-sectionhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vl-space-4);
  margin-block-end: var(--vl-space-4);
}

:where(.vl-redesign) .vl-sectionhead__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-2xl);
  font-weight: var(--vl-fw-bold);
  letter-spacing: var(--vl-tracking-tight);
  color: var(--vl-text);
}

:where(.vl-redesign) .vl-sectionhead__link {
  flex: 0 0 auto;
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-action);
}

/* ══ 8. GRID DE RESULTADOS ═════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-grid {
  display: grid;
  gap: var(--vl-space-4);
  grid-template-columns: 1fr;
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1280px) {
  :where(.vl-redesign) .vl-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ══ 9. FILA DE EVENTO ═════════════════════════════════════════════════════ */
/* La lista "Happening near me" de la landing. Icono grande + datos apilados. */

:where(.vl-redesign) .vl-eventrow {
  position: relative;
  display: grid;
  grid-template-columns: 4rem 1fr auto;
  align-items: center;
  gap: var(--vl-space-3);
  padding: var(--vl-space-3);
  background: var(--vl-bg-raised);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-lg);
}

/* Misma regla que el medallón: emoji sobre blanco, color de marca en el aro. */
:where(.vl-redesign) .vl-eventrow__icon {
  display: grid;
  place-items: center;
  width: 4rem;
  height: 4rem;
  border-radius: var(--vl-radius-md);
  background: var(--vl-white);
  box-shadow: inset 0 0 0 2px var(--vl-teal-300);
  font-size: 1.625rem;
}

:where(.vl-redesign) .vl-eventrow__when {
  font-size: var(--vl-text-2xs);
  font-weight: var(--vl-fw-bold);
  letter-spacing: var(--vl-tracking-wide);
  text-transform: uppercase;
  color: var(--vl-orange-700);          /* 6.03:1 */
}

:where(.vl-redesign) .vl-eventrow__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-base);
  font-weight: var(--vl-fw-bold);
  color: var(--vl-text);
  line-height: var(--vl-leading-snug);
}

:where(.vl-redesign) .vl-eventrow__meta {
  font-size: var(--vl-text-xs);
  color: var(--vl-text-muted);
}

/* ══ 10. TARJETA DE CATEGORÍA ══════════════════════════════════════════════ */
/*
 * Los mosaicos de la landing. El texto va sobre un degradado opaco por abajo,
 * nunca sobre la foto desnuda: así el contraste no depende de qué imagen suba
 * el editor.
 */

:where(.vl-redesign) .vl-cattile {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 10.5rem;
  padding: var(--vl-space-4);
  border-radius: var(--vl-radius-lg);
  overflow: hidden;
  color: var(--vl-white);
  background: var(--vl-tile, var(--vl-cat-see));
  isolation: isolate;
}

:where(.vl-redesign) .vl-cattile__img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
 * EL VELO VA TEÑIDO DEL COLOR DE LA CATEGORÍA, NO EN GRIS.
 *
 * Lo pidió el cliente el 03/09/2026: «the home page is still showing the old
 * generic photos on the categorys that dont match the colorfull category
 * colours from the mock up». Y era exacto: el color de cada categoría sólo se
 * usaba como fondo de respaldo, para cuando el término no tenía foto. Con foto
 * —o sea, siempre— encima iba un degradado de tinta neutra, así que los cuatro
 * mosaicos salían del mismo gris apagado y la portada perdía el código de color
 * que sostiene todo el mockup.
 *
 * ES UN DEGRADADO, DE ABAJO ARRIBA, Y ARRIBA TRANSPARENTE DEL TODO. Lo único
 * que cambia respecto a lo que había es el color: donde iba tinta neutra ahora
 * va el tono de la categoría. La foto sigue viéndose limpia en la parte de
 * arriba, que es donde tiene que verse.
 *
 * (Se intentó teñir el mosaico entero con una capa plana. Mal: quedaba una
 * lámina de color sólido translúcido sobre la foto, no un degradado. Queda
 * escrito para no repetirlo.)
 *
 * Los cuatro tonos se quedan como están (`--vl-cat-*` en design-tokens.css):
 * están elegidos con su contraste medido —de 5.2:1 el naranja a 9.1:1 el
 * verdeazulado contra blanco—, y al pie del degradado van casi a fondo, así que
 * el título se lee sobre el color y no sobre la fotografía.
 */
:where(.vl-redesign) .vl-cattile::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--vl-tile, var(--vl-ink-900)) 88%, transparent) 0%,
    color-mix(in srgb, var(--vl-tile, var(--vl-ink-900)) 48%, transparent) 45%,
    transparent 100%
  );
}

/*
 * EL TEXTO SE SOSTIENE CON SOMBRA, NO CON MÁS VELO.
 *
 * El velo se ha aflojado a petición del cliente («un poquito menos agresivo»),
 * y en los mosaicos de subcategoría —que llevan descripción, así que el texto
 * sube— eso dejaba el título por debajo de 4.5:1 sobre una foto clara.
 *
 * La alternativa era volver a cargar el color, que es justo lo que se acaba de
 * quitar. Una sombra corta hace el mismo trabajo detrás de las letras y no toca
 * el resto de la fotografía: es lo que permite tener el velo suave Y el texto
 * legible, en vez de elegir.
 */
:where(.vl-redesign) .vl-cattile__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-lg);
  font-weight: var(--vl-fw-black);
  line-height: var(--vl-leading-tight);
  color: var(--vl-white);
  text-shadow: 0 1px 4px rgb(0 0 0 / 0.5);
}

:where(.vl-redesign) .vl-cattile__sub {
  font-size: var(--vl-text-xs);
  color: color-mix(in srgb, var(--vl-white) 88%, transparent);
  text-shadow: 0 1px 3px rgb(0 0 0 / 0.45);
}

/*
 * SIN `:where()`, y no es un descuido.
 * `:where()` vale especificidad CERO, así que `:where(.vl-redesign)
 * .vl-cattile__link` puntúa (0,1,0) y cualquier regla de enlace de style.css
 * con un elemento de más le gana. Medido en producción: el <h3> salía blanco
 * y el <a> de dentro en rgb(32,38,47), o sea el nombre de la categoría en
 * tinta oscura sobre una foto oscura. Ilegible.
 *
 * Con `.vl-redesign` de verdad puntúa (0,2,0) y el color lo decidimos aquí.
 */
.vl-redesign .vl-cattile__title,
.vl-redesign .vl-cattile__link,
.vl-redesign .vl-cattile__link:hover,
.vl-redesign .vl-cattile__link:focus {
  color: var(--vl-white);
  text-decoration: none;
}

:where(.vl-redesign) .vl-cattile__link::after {
  content: '';
  position: absolute;
  inset: 0;
}

/* Tono por categoría, como respaldo cuando no hay imagen de término. */
:where(.vl-redesign) .vl-cattile--food  { background: var(--vl-cat-food); }
:where(.vl-redesign) .vl-cattile--see   { background: var(--vl-cat-see); }
:where(.vl-redesign) .vl-cattile--do    { background: var(--vl-cat-do); }
:where(.vl-redesign) .vl-cattile--deals { background: var(--vl-cat-deals); }

/* ══ 11. OFERTA ════════════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-offer {
  position: relative;
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  align-items: center;
  gap: var(--vl-space-4);
  padding: var(--vl-space-3);
  border-radius: var(--vl-radius-lg);
  background: var(--vl-bg-tint);
  border: 1px solid var(--vl-teal-100);
}

:where(.vl-redesign) .vl-offer__img {
  width: 4.5rem;
  height: 4.5rem;
  border-radius: var(--vl-radius-md);
  object-fit: cover;
}

:where(.vl-redesign) .vl-offer__label {
  font-size: var(--vl-text-2xs);
  font-weight: var(--vl-fw-bold);
  letter-spacing: var(--vl-tracking-wide);
  text-transform: uppercase;
  color: var(--vl-teal-700);
}

:where(.vl-redesign) .vl-offer__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-base);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-snug);
  color: var(--vl-text);
}

/* ══ 12. CONSEJO VIBELOCAL ═════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-tip {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--vl-space-3);
  padding: var(--vl-space-4);
  border-radius: var(--vl-radius-lg);
  background: var(--vl-bg-tint-accent);
  border: 1px solid var(--vl-orange-100);
}

@media (min-width: 480px) {
  :where(.vl-redesign) .vl-tip { grid-template-columns: 1fr 6rem; align-items: center; }
}

:where(.vl-redesign) .vl-tip__title {
  display: flex;
  align-items: center;
  gap: var(--vl-space-2);
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-base);
  font-weight: var(--vl-fw-bold);
  color: var(--vl-orange-800);          /* 7.67:1 sobre orange-50 */
  margin-block-end: var(--vl-space-1);
}

:where(.vl-redesign) .vl-tip__body {
  font-size: var(--vl-text-sm);
  line-height: var(--vl-leading-normal);
  color: var(--vl-ink-800);
}

:where(.vl-redesign) .vl-tip__img {
  width: 100%;
  height: 5rem;
  object-fit: cover;
  border-radius: var(--vl-radius-md);
}

/* ══ 13. TITULAR IA ════════════════════════════════════════════════════════ */
/* vl_headline. Se marca como generado para no hacerlo pasar por editorial. */

:where(.vl-redesign) .vl-headline {
  display: flex;
  align-items: flex-start;
  gap: var(--vl-space-3);
  padding: var(--vl-space-4);
  border-radius: var(--vl-radius-lg);
  background: var(--vl-bg-tint);
}

:where(.vl-redesign) .vl-headline__text {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-lg);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-snug);
  color: var(--vl-teal-800);
  text-wrap: balance;
}

/* ══ 14. BUSCADOR ══════════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-searchbar {
  display: flex;
  align-items: center;
  gap: var(--vl-space-3);
  width: 100%;
  /* El lado derecho lleva space-2, no space-3: ahí va el botón circular y el
     aire tiene que ser el mismo por arriba, por abajo y por fuera. Con 56px de
     alto y un botón de 40px, space-2 (8px) cierra el círculo concéntrico. */
  padding: var(--vl-space-2) var(--vl-space-2) var(--vl-space-2) var(--vl-space-5);
  background: var(--vl-white);
  /* Sin borde: la sombra ya separa la barra del fondo, y el filo gris encima
     de ella ensuciaba el contorno de la píldora. */
  border: 0;
  border-radius: var(--vl-radius-pill);
  box-shadow: var(--vl-shadow-lg);
  min-height: 56px;
}

:where(.vl-redesign) .vl-searchbar__icon {
  flex: 0 0 auto;
  color: var(--vl-ink-500);
}

/*
 * Sin `:where()` a propósito. El reset de base.css pone `border: 0` a los
 * `button` dentro de `:where()`, que vale especificidad CERO, así que
 * cualquier regla suelta de style.css o de un plugin le gana y le repinta el
 * borde. Ya pasó con el conmutador de mapa. Aquí se escribe con especificidad
 * real para que no vuelva a pasar.
 */
.vl-redesign .vl-searchbar__go {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: var(--vl-radius-pill);
  background: var(--vl-action);
  color: var(--vl-text-on-dark);
  cursor: pointer;
  transition: background var(--vl-duration) var(--vl-ease);
}

.vl-redesign .vl-searchbar__go:hover { background: var(--vl-action-hover); }

/* El foco iba en border-color, pero la barra ya no tiene borde. Se marca con un
   anillo sobre la propia sombra: el input lleva outline:none, así que sin esto
   quien navega con teclado no vería dónde está. */
:where(.vl-redesign) .vl-searchbar:focus-within {
  box-shadow: var(--vl-shadow-lg), 0 0 0 2px var(--vl-action);
}

:where(.vl-redesign) .vl-searchbar__input {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--vl-text-base);
  color: var(--vl-text);
}

/*
 * EL BORDE VA CON ESPECIFICIDAD REAL, NO EN `:where()`.
 *
 * El tema padre estiliza los inputs por selector de elemento
 * (hello-elementor/assets/css/theme.css) con `1px solid #666` y radio 3px. Un
 * `:where()` tiene especificidad CERO, así que nuestro `border: 0` perdía y el
 * input salía con la cajita gris del tema dentro de la píldora del buscador.
 *
 * No se veía hasta el corte del 2026-08-21: el kit de Elementor pisaba al tema
 * padre y tapaba el problema. Al apagar Elementor, el tema padre volvió a
 * ganar. Medido: `1px solid rgb(102,102,102)`, radio 3px.
 *
 * Auditados el resto de campos del rediseño en portada, listado y acceso: éste
 * era el único.
 */
.vl-redesign .vl-searchbar__input,
.vl-redesign .vl-searchbar__input:focus,
.vl-redesign .vl-searchbar__input:hover {
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  outline: none;
}

:where(.vl-redesign) .vl-searchbar__input::placeholder {
  color: var(--vl-text-faint);   /* 4.65:1, el mínimo para placeholder */
}

/* ══ 15. HERO DE ZONA ══════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--vl-space-5);
  min-height: 22rem;
  padding: var(--vl-space-8) var(--vl-gutter) var(--vl-space-10);
  color: var(--vl-white);
  background: var(--vl-teal-800);
  isolation: isolate;
  overflow: hidden;
}

:where(.vl-redesign) .vl-hero__img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Velo oscuro: el hero lleva texto blanco encima de una foto que cambia por
   zona, así que el contraste no puede depender de la foto. */
:where(.vl-redesign) .vl-hero::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--vl-ink-900) 82%, transparent) 0%,
    color-mix(in srgb, var(--vl-ink-900) 42%, transparent) 55%,
    color-mix(in srgb, var(--vl-ink-900) 30%, transparent) 100%
  );
}

:where(.vl-redesign) .vl-hero__inner {
  width: 100%;
  max-width: var(--vl-container);
  margin-inline: auto;
}

:where(.vl-redesign) .vl-hero__place {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-white);
}

/*
 * EL TITULAR DEL HERO VA EN LEAGUE SPARTAN.
 *
 * La pidió el cliente con el mockup delante: «(To Next?) League Spartan font
 * with yellow ?». Es una grotesca geométrica de caja alta muy cerrada —de ahí
 * el aire de cartel— frente a Plus Jakarta, que es más redonda y ahí se quedaba
 * blanda.
 *
 * Afecta sólo a «to next?»: la palabra manuscrita de al lado tiene su propia
 * familia y no la hereda. El resto de titulares del sitio siguen en la display
 * de siempre.
 *
 * Con `letter-spacing` a cero: League Spartan ya viene apretada de origen y el
 * ajuste que necesitaba Plus Jakarta aquí le juntaba las letras de más.
 */
:where(.vl-redesign) .vl-hero__title {
  font-family: var(--vl-font-hero);
  font-size: var(--vl-text-4xl);
  font-weight: var(--vl-fw-black);
  line-height: var(--vl-leading-tight);
  letter-spacing: 0;
  color: var(--vl-white);
  margin-block: var(--vl-space-2) var(--vl-space-3);
}

/* La única palabra manuscrita de la página. El subrayado teal la ancla al
   sistema y evita que parezca pegada de otro sitio. */
:where(.vl-redesign) .vl-hero__script {
  display: block;
  font-family: var(--vl-font-script);
  font-size: var(--vl-text-script);
  font-weight: var(--vl-fw-regular);
  letter-spacing: 0;
  line-height: 0.9;
  padding-inline: 0.06em;
  text-shadow: 0 2px 16px rgba(19, 28, 33, 0.35);
}

:where(.vl-redesign) .vl-hero__rule {
  display: block;
  width: 4.5rem;
  height: 3px;
  margin-block: var(--vl-space-2);
  border-radius: var(--vl-radius-pill);
  background: var(--vl-teal-400);
}

:where(.vl-redesign) .vl-hero__sub {
  font-size: var(--vl-text-base);
  color: color-mix(in srgb, var(--vl-white) 88%, transparent);
}

/* ══ 16. GALERÍA ═══════════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-gallery {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--vl-ink-100);
  overflow: hidden;
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-gallery { aspect-ratio: 16 / 10; border-radius: var(--vl-radius-xl); }
}

:where(.vl-redesign) .vl-gallery__count {
  position: absolute;
  inset-block-end: var(--vl-space-3);
  inset-inline-end: var(--vl-space-3);
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  padding: var(--vl-space-1) var(--vl-space-3);
  border-radius: var(--vl-radius-pill);
  /* Fondo sólido y oscuro: encima puede haber cualquier foto. */
  background: color-mix(in srgb, var(--vl-ink-900) 78%, transparent);
  color: var(--vl-white);
  font-size: var(--vl-text-xs);
  font-weight: var(--vl-fw-semibold);
  font-variant-numeric: tabular-nums;
  backdrop-filter: blur(6px);
}

:where(.vl-redesign) .vl-gallery__dots {
  position: absolute;
  inset-block-end: var(--vl-space-3);
  inset-inline: 0;
  display: flex;
  justify-content: center;
  gap: var(--vl-space-2);
}

:where(.vl-redesign) .vl-gallery__dot {
  width: 0.4375rem;
  height: 0.4375rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--vl-white) 55%, transparent);
}

/* Los puntos son botones: hay que apagarles el aspecto de botón y darles un
   área de pulsación mayor que el propio punto, que mide 7px. */
:where(.vl-redesign) .vl-gallery__dot {
  padding: 0;
  border: 0;
  cursor: pointer;
  transition: width var(--vl-duration) var(--vl-ease), background var(--vl-duration) var(--vl-ease);
}

:where(.vl-redesign) .vl-gallery__dot::after {
  content: '';
  position: absolute;
  inset: -0.5rem;
}

:where(.vl-redesign) .vl-gallery__dot[aria-current='true'] {
  background: var(--vl-white);
  width: 1.25rem;
  border-radius: var(--vl-radius-pill);
}

/* ── Flechas, expandir y visor a pantalla completa ──────────────────────────
   Las flechas existen porque la pista lleva la barra de desplazamiento oculta:
   con el dedo o el trackpad se pasa de foto, pero con un ratón corriente no
   había ninguna forma de hacerlo. Por eso sólo se muestran donde el puntero es
   fino — en táctil estorban y tapan la imagen. */

:where(.vl-redesign) .vl-gallery__nav,
:where(.vl-redesign) .vl-gallery__expand {
  position: absolute;
  z-index: 1;
  display: none;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--vl-ink-900) 55%, transparent);
  color: var(--vl-white);
  cursor: pointer;
  backdrop-filter: blur(6px);
  transition: background var(--vl-duration) var(--vl-ease),
              opacity var(--vl-duration) var(--vl-ease);
}

:where(.vl-redesign) .vl-gallery__nav {
  inset-block-start: 50%;
  translate: 0 -50%;
  width: 2.75rem;
  height: 2.75rem;
  font-size: var(--vl-text-base);
  /* Semitransparentes en reposo para no competir con la foto, opacas al
     acercar el ratón. Nunca del todo invisibles: si no se ven, nadie descubre
     que la galería se puede pasar. */
  opacity: 0.75;
}

:where(.vl-redesign) .vl-gallery__nav--prev { inset-inline-start: var(--vl-space-3); }
:where(.vl-redesign) .vl-gallery__nav--next { inset-inline-end: var(--vl-space-3); }

:where(.vl-redesign) .vl-gallery__expand {
  inset-block-start: var(--vl-space-3);
  inset-inline-end: var(--vl-space-3);
  width: 2.25rem;
  height: 2.25rem;
  font-size: var(--vl-text-sm);
  opacity: 0.75;
}

@media (hover: hover) and (pointer: fine) {
  :where(.vl-redesign) .vl-gallery__nav,
  :where(.vl-redesign) .vl-gallery__expand { display: inline-flex; }

  :where(.vl-redesign) .vl-gallery:hover .vl-gallery__nav,
  :where(.vl-redesign) .vl-gallery:hover .vl-gallery__expand { opacity: 1; }

  :where(.vl-redesign) .vl-gallery__nav:hover,
  :where(.vl-redesign) .vl-gallery__expand:hover {
    background: color-mix(in srgb, var(--vl-ink-900) 78%, transparent);
    opacity: 1;
  }

  /* La foto abre el visor con el ratón; el botón de expandir es la vía para
     el teclado. */
  :where(.vl-redesign) .vl-gallery__img { cursor: zoom-in; }
}

/* Siempre visibles al tabular, aunque el puntero no esté encima. */
:where(.vl-redesign) .vl-gallery__nav:focus-visible,
:where(.vl-redesign) .vl-gallery__expand:focus-visible {
  display: inline-flex;
  opacity: 1;
  outline: 2px solid var(--vl-white);
  outline-offset: 2px;
}

:where(.vl-redesign) .vl-gallery__nav[hidden] { display: none; }

/* El visor. Lo crea el JS al abrirlo, así que no hay markup de más en cada
   ficha esperando a que alguien pulse. */
:where(.vl-redesign) .vl-lightbox {
  position: fixed;
  inset: 0;
  z-index: var(--vl-z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--vl-ink-900) 94%, transparent);
}

:where(.vl-redesign) .vl-lightbox__img {
  max-width: min(92vw, 84rem);
  max-height: 88vh;
  object-fit: contain;
  border-radius: var(--vl-radius-lg);
}

:where(.vl-redesign) .vl-lightbox__nav,
:where(.vl-redesign) .vl-lightbox__close {
  position: absolute;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--vl-white) 14%, transparent);
  color: var(--vl-white);
  font-size: var(--vl-text-lg);
  cursor: pointer;
  transition: background var(--vl-duration) var(--vl-ease);
}

:where(.vl-redesign) .vl-lightbox__nav:hover,
:where(.vl-redesign) .vl-lightbox__close:hover {
  background: color-mix(in srgb, var(--vl-white) 26%, transparent);
}

:where(.vl-redesign) .vl-lightbox__nav:focus-visible,
:where(.vl-redesign) .vl-lightbox__close:focus-visible {
  outline: 2px solid var(--vl-white);
  outline-offset: 2px;
}

:where(.vl-redesign) .vl-lightbox__nav--prev { inset-inline-start: var(--vl-space-4); }
:where(.vl-redesign) .vl-lightbox__nav--next { inset-inline-end: var(--vl-space-4); }

:where(.vl-redesign) .vl-lightbox__close {
  inset-block-start: var(--vl-space-4);
  inset-inline-end: var(--vl-space-4);
}

:where(.vl-redesign) .vl-lightbox__count {
  position: absolute;
  inset-block-end: var(--vl-space-5);
  inset-inline: 0;
  text-align: center;
  color: color-mix(in srgb, var(--vl-white) 82%, transparent);
  font-size: var(--vl-text-sm);
  font-variant-numeric: tabular-nums;
}

/* Con el visor abierto, la página de detrás no debe moverse. La clase
   .vl-redesign vive en el propio <body>, así que van juntas y no anidadas. */
.vl-redesign.vl-lightbox-open { overflow: hidden; }


/* ══ 17. BOTTOM NAV ════════════════════════════════════════════════════════ */
/* Nombre .vl-bottomnav, NO .vl-nav: esa clase ya es el menú del dashboard. */

:where(.vl-redesign) .vl-bottomnav {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: var(--vl-z-bottomnav);
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  height: calc(var(--vl-bottom-nav-h) + env(safe-area-inset-bottom, 0px));
  padding-block-end: env(safe-area-inset-bottom, 0px);
  background: var(--vl-white);
  border-block-start: 1px solid var(--vl-border);
  box-shadow: var(--vl-shadow-nav);
}

:where(.vl-redesign) .vl-bottomnav__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.1875rem;
  min-height: var(--vl-tap-min);
  color: var(--vl-text-muted);
  font-size: var(--vl-text-2xs);
  font-weight: var(--vl-fw-semibold);
  text-decoration: none;
}

:where(.vl-redesign) .vl-bottomnav__item:hover { text-decoration: none; color: var(--vl-action); }
:where(.vl-redesign) .vl-bottomnav__item[aria-current='page'] { color: var(--vl-action); }
:where(.vl-redesign) .vl-bottomnav__icon { font-size: 1.1875rem; line-height: 1; }

/*
 * «LANG» LLEVABA UN RECUADRO ROSA, Y NO ERA NUESTRO.
 *
 * El reset del tema PADRE (hello-elementor/assets/css/reset.css) pinta
 * `[type=button],[type=submit],button` con `border:1px solid #c36`,
 * `border-radius:3px`, `padding:.5rem 1rem` y, al pasar el ratón,
 * `background-color:#c36`. Ese magenta no está en la paleta.
 *
 * Se cuela por lo mismo que ya pasó en el alternador lista/mapa (sección 24):
 * el reset de base.css declara `border:0` para `button` dentro de `:where()`,
 * o sea con especificidad CERO, y el `button` pelado del padre (0,0,1) le gana.
 * La solución es la de siempre: declararlo en el componente y sin `:where()`.
 *
 * Salía en una sola pestaña porque «Lang» es el único <button> de la barra
 * —las otras tres son <a>—, así que parecía un adorno suyo y no un fallo.
 */
.vl-redesign .vl-bottomnav__item {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;   /* también mata el fondo magenta del :hover del padre */
  white-space: normal;
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-bottomnav { display: none; }
}

/* ══ 18. CABECERA ══════════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-topbar {
  position: sticky;
  inset-block-start: 0;
  z-index: var(--vl-z-header);
  min-height: var(--vl-header-h);
  background: color-mix(in srgb, var(--vl-white) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-block-end: 1px solid var(--vl-border);
}

/* El contenido de la cabecera se alinea con el de la página, no con el borde
   de la pantalla: en un monitor ancho el logo se iba a tomar por culo. */
/*
 * Se alinea con el contenido del listado, que es el que manda el ancho hoy.
 * (Aquí había una regla `.vl-archive .vl-topbar__inner` que NO podía funcionar
 * nunca: `.vl-archive` es el <main> y la cabecera es su hermana, no su hija.
 * Se veía a simple vista — el logo empezaba 150px a la derecha del título.)
 */
:where(.vl-redesign) .vl-topbar__inner {
  display: flex;
  align-items: center;
  gap: var(--vl-space-4);
  width: 100%;
  max-width: var(--vl-container-wide);
  min-height: var(--vl-header-h);
  margin-inline: auto;
  padding-inline: var(--vl-gutter);
}

@media (min-width: 1280px) {
  :where(.vl-redesign) .vl-topbar__inner { padding-inline: var(--vl-space-6); }
}

/* Navegación: sólo escritorio. En móvil la lleva la bottom-nav. */
:where(.vl-redesign) .vl-topbar__nav { display: none; }

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-topbar__nav {
    display: flex;
    align-items: center;
    gap: var(--vl-space-1);
    margin-inline-start: var(--vl-space-6);
  }

  :where(.vl-redesign) .vl-topbar__navlink {
    padding: var(--vl-space-2) var(--vl-space-4);
    border-radius: var(--vl-radius-pill);
    font-size: var(--vl-text-sm);
    font-weight: var(--vl-fw-semibold);
    color: var(--vl-text-muted);
    transition: color var(--vl-duration-fast) var(--vl-ease),
                background var(--vl-duration-fast) var(--vl-ease);
  }

  :where(.vl-redesign) .vl-topbar__navlink:hover {
    background: var(--vl-ink-100);
    color: var(--vl-text);
    text-decoration: none;
  }

  :where(.vl-redesign) .vl-topbar__navlink[aria-current='page'] {
    background: var(--vl-action-tint);
    color: var(--vl-teal-800);
  }

  /* Con sitio de sobra, la cabecera respira. */
  :where(.vl-redesign) .vl-topbar__inner { min-height: 80px; }
}

:where(.vl-redesign) .vl-topbar__logo {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
}

:where(.vl-redesign) .vl-topbar__logo img { height: 32px; width: auto; }

/* El logo es un SVG (mockup_logo.svg, 135x47), así que crece sin empastarse.
   En una cabecera de 80px, 42 se quedaba corto. */
@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-topbar__logo img { height: 54px; }
}

:where(.vl-redesign) .vl-topbar__actions {
  display: flex;
  align-items: center;
  gap: var(--vl-space-1);
  margin-inline-start: auto;
}

:where(.vl-redesign) .vl-iconbtn {
  display: grid;
  place-items: center;
  width: var(--vl-tap-min);
  height: var(--vl-tap-min);
  border-radius: 50%;
  color: var(--vl-ink-700);
  font-size: 1.0625rem;
}

:where(.vl-redesign) .vl-iconbtn:hover {
  background: var(--vl-ink-100);
  color: var(--vl-text);
}

/*
 * El mismo recuadro rosa del reset del padre que se explica en la sección 17:
 * la «×» que cierra el panel de idiomas es un <button> y lo llevaba igual.
 * Aquí sólo se corrige `border`: el `background` NO puede tocarse en esta regla
 * porque (0,2,0) le ganaría a `:where(.vl-redesign) .vl-iconbtn:hover` (0,1,1)
 * y se quedaría sin el fondo del hover.
 */
.vl-redesign .vl-iconbtn { border: 0; }

/* Hero a pantalla completa: la cabecera flota encima sin fondo hasta scrollear. */
:where(.vl-redesign) .vl-topbar--over {
  position: absolute;
  inset-inline: 0;
  background: transparent;
  border-block-end: 0;
}

/*
 * VELO PROPIO DE LA CABECERA FLOTANTE.
 *
 * El velo del hero se aclara hacia arriba (30% en el borde superior) porque
 * ahí no hay texto... salvo que la cabecera flote encima. Medido sobre la foto
 * de la playa de Fuengirola, el fondo detrás del nav daba rgb(130,149,167):
 * blanco sobre eso son 3.09:1, por debajo del mínimo de 4.5:1 del sistema.
 *
 * Este degradado corto arregla sólo esa franja sin oscurecer el resto del
 * hero, y viaja con la cabecera, así que sirve en cualquier pantalla que la
 * use flotando. Va en el ::before de la propia cabecera —que ya es contexto de
 * apilado por su z-index— para no depender de qué haya debajo.
 */
.vl-redesign .vl-topbar--over::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-start: 0;
  z-index: -1;
  height: calc(100% + var(--vl-space-10));
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    color-mix(in srgb, var(--vl-ink-900) 55%, transparent) 0%,
    color-mix(in srgb, var(--vl-ink-900) 28%, transparent) 55%,
    transparent 100%
  );
}

/*
 * Sin foto el hero ya es un degradado oscuro: el velo sobraría y sólo dejaría
 * una banda más negra arriba. Quién lleva foto lo sabe la plantilla, no el
 * CSS: la cabecera va ANTES que <main> en el HTML, así que ningún selector
 * puede mirar hacia abajo para averiguarlo.
 */
.vl-redesign .vl-topbar--noscrim::before { display: none; }

/*
 * Sobre el hero TODO va en blanco, no sólo los iconos: el logo de texto y los
 * enlaces de sección estaban quedando en tinta oscura sobre la foto.
 */
:where(.vl-redesign) .vl-topbar--over .vl-iconbtn,
:where(.vl-redesign) .vl-topbar--over .vl-topbar__navlink,
:where(.vl-redesign) .vl-topbar--over .vl-topbar__wordmark {
  color: var(--vl-white);
}

/*
 * EL LOGO DE VERDAD NO SE BLANQUEA CON `color`.
 *
 * La regla de arriba sólo alcanza a `.vl-topbar__wordmark`, que es el respaldo
 * de TEXTO que se pinta cuando el sitio no tiene logo subido. En producción sí
 * lo hay (mockup_logo.svg), así que `the_custom_logo()` emite un <img> y
 * `color` no le hace nada: sobre la foto del hero seguía saliendo en sus
 * colores de marca, teal y naranja, que es lo que reportó James.
 *
 * `brightness(0)` aplasta la imagen a negro puro y `invert(1)` la pasa a
 * blanco. Sirve igual para un SVG que para un PNG y no depende de cómo esté
 * hecho el fichero por dentro, que es justo lo que hace falta aquí: el logo lo
 * sube el cliente desde el personalizador y puede cambiar cualquier día.
 */
:where(.vl-redesign) .vl-topbar--over .vl-topbar__logo img {
  filter: brightness(0) invert(1);
}

:where(.vl-redesign) .vl-topbar--over .vl-iconbtn:hover,
:where(.vl-redesign) .vl-topbar--over .vl-topbar__navlink:hover {
  background: color-mix(in srgb, var(--vl-white) 18%, transparent);
  color: var(--vl-white);
}

/* ══ 19. ESTADO VACÍO ══════════════════════════════════════════════════════ */
/*
 * Una pantalla vacía es una invitación a actuar, no una disculpa.
 * Siempre lleva una salida.
 */

:where(.vl-redesign) .vl-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vl-space-3);
  padding: var(--vl-space-12) var(--vl-space-4);
  text-align: center;
}

:where(.vl-redesign) .vl-empty-state__icon {
  display: grid;
  place-items: center;
  width: 4rem;
  height: 4rem;
  border-radius: 50%;
  background: var(--vl-bg-tint);
  color: var(--vl-teal-600);
  font-size: 1.5rem;
}

:where(.vl-redesign) .vl-empty-state__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-xl);
  font-weight: var(--vl-fw-bold);
  color: var(--vl-text);
}

:where(.vl-redesign) .vl-empty-state__text {
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
  max-width: 34ch;
}

/* ══ 20. PANEL DE IDIOMA ═══════════════════════════════════════════════════ */
/* La vista propia que dispara el motor de GTranslate. */

:where(.vl-redesign) .vl-langsheet {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: var(--vl-z-drawer);
  padding: var(--vl-space-5) var(--vl-gutter)
           calc(var(--vl-space-5) + env(safe-area-inset-bottom, 0px));
  background: var(--vl-white);
  border-start-start-radius: var(--vl-radius-2xl);
  border-start-end-radius: var(--vl-radius-2xl);
  box-shadow: var(--vl-shadow-lg);
}

:where(.vl-redesign) .vl-langsheet[hidden] { display: none; }

:where(.vl-redesign) .vl-langsheet__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
  gap: var(--vl-space-2);
  margin-block-start: var(--vl-space-4);
}

:where(.vl-redesign) .vl-langsheet__btn {
  display: flex;
  align-items: center;
  gap: var(--vl-space-3);
  width: 100%;
  min-height: var(--vl-tap-min);
  padding: var(--vl-space-2) var(--vl-space-3);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-md);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-medium);
  color: var(--vl-text-body);
  text-align: start;
}

:where(.vl-redesign) .vl-langsheet__btn[aria-current='true'] {
  border-color: var(--vl-action);
  background: var(--vl-action-tint);
  color: var(--vl-teal-800);
  font-weight: var(--vl-fw-semibold);
}

:where(.vl-redesign) .vl-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--vl-z-backdrop);
  background: color-mix(in srgb, var(--vl-ink-900) 45%, transparent);
}

:where(.vl-redesign) .vl-backdrop[hidden] { display: none; }

/* ══ 21. LOGO DE TEXTO (respaldo) ══════════════════════════════════════════ */
/* Si no hay custom logo en WordPress, la marca se compone con tipografía. */

:where(.vl-redesign) .vl-topbar__wordmark {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-lg);
  font-weight: var(--vl-fw-black);
  letter-spacing: var(--vl-tracking-tight);
  color: var(--vl-teal-700);
}

:where(.vl-redesign) .vl-topbar__wordmark span { color: var(--vl-orange-700); }
:where(.vl-redesign) .vl-topbar__wordmark:hover { text-decoration: none; }

/* ══ 22. CABECERA DEL PANEL DE IDIOMA ══════════════════════════════════════ */

:where(.vl-redesign) .vl-langsheet__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vl-space-3);
}

:where(.vl-redesign) .vl-langsheet__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-lg);
  font-weight: var(--vl-fw-bold);
  color: var(--vl-text);
}

:where(.vl-redesign) .vl-langsheet__tick {
  margin-inline-start: auto;
  color: var(--vl-action);
  font-weight: var(--vl-fw-bold);
}

/*
 * El widget real de GTranslate. Tiene que seguir en el DOM —es lo que carga
 * base.js e inicializa doGTranslate()— pero no debe verse. Por eso se oculta
 * con la técnica de recorte y NO con `display:none`, que impediría al widget
 * de Google medirse e inicializarse en algunos navegadores.
 */
:where(.vl-redesign) .vl-langsheet__engine {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  pointer-events: none;
}

/* ══ 23. PIE ═══════════════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-footer {
  margin-block-start: var(--vl-space-12);
  padding-block: var(--vl-space-8);
  background: var(--vl-bg-sunken);
  border-block-start: 1px solid var(--vl-border);
}

:where(.vl-redesign) .vl-footer__inner {
  display: grid;
  gap: var(--vl-space-5);
  width: 100%;
  max-width: var(--vl-container);
  margin-inline: auto;
  padding-inline: var(--vl-gutter);
  justify-items: start;
}

:where(.vl-redesign) .vl-footer__logo img { height: 34px; width: auto; }

:where(.vl-redesign) .vl-footer__tagline {
  max-width: 42ch;
  margin-block-start: var(--vl-space-3);
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
}

:where(.vl-redesign) .vl-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vl-space-4);
}

:where(.vl-redesign) .vl-footer__links a {
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-medium);
  color: var(--vl-text-body);
}

:where(.vl-redesign) .vl-footer__links a:hover { color: var(--vl-action); }

:where(.vl-redesign) .vl-footer__social {
  display: grid;
  place-items: center;
  width: var(--vl-tap-min);
  height: var(--vl-tap-min);
  border-radius: 50%;
  background: var(--vl-action);
  color: var(--vl-text-on-dark);
  font-family: var(--vl-font-display);
  font-weight: var(--vl-fw-black);
  font-size: var(--vl-text-lg);
}

:where(.vl-redesign) .vl-footer__social:hover {
  background: var(--vl-action-hover);
  color: var(--vl-text-on-dark);
  text-decoration: none;
}

:where(.vl-redesign) .vl-footer__legal { color: var(--vl-text-faint); }

/* Columnas del pie: título pequeño en mayúsculas y enlaces apilados. */
:where(.vl-redesign) .vl-footer__col {
  display: flex;
  flex-direction: column;
  align-items: start;
  gap: var(--vl-space-3);
}

:where(.vl-redesign) .vl-footer__coltitle {
  font-family: var(--vl-font-ui);
  font-size: var(--vl-text-xs);
  font-weight: var(--vl-fw-bold);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--vl-text-faint);
}

:where(.vl-redesign) .vl-footer__col a {
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-medium);
  color: var(--vl-text-body);
}

:where(.vl-redesign) .vl-footer__col a:hover { color: var(--vl-action); }

/*
 * Escritorio: marca a la izquierda con su medida de lectura y las columnas
 * pegadas a la derecha. Antes era todo una pila contra el margen izquierdo, que
 * en una pantalla de 1500px deja dos tercios de pie vacíos.
 */
@media (min-width: 768px) {
  :where(.vl-redesign) .vl-footer__inner {
    grid-template-columns: minmax(0, 1.6fr) repeat(3, auto);
    column-gap: var(--vl-space-10);
    align-items: start;
  }

  :where(.vl-redesign) .vl-footer__brand { grid-row: 1; }
  :where(.vl-redesign) .vl-footer__col { grid-row: 1; }

  /* La línea legal cruza todo el ancho, separada por un filete. */
  :where(.vl-redesign) .vl-footer__legal {
    grid-row: 2;
    grid-column: 1 / -1;
    width: 100%;
    margin-block-start: var(--vl-space-6);
    padding-block-start: var(--vl-space-5);
    border-block-start: 1px solid var(--vl-border);
  }
}

/* ══ 24. LISTADO ═══════════════════════════════════════════════════════════ */

/*
 * GANAR ALTO POR ARRIBA.
 *
 * Medido en un móvil de 844px: la primera tarjeta empezaba en y=415. La mitad
 * de la pantalla gastada en cabecera, pestañas, buscador y filtros antes de
 * enseñar un solo negocio. Cada margen de aquí abajo está recortado a
 * conciencia, no por gusto.
 */
:where(.vl-redesign) .vl-archive { padding-block: var(--vl-space-3) var(--vl-space-10); }

/* El encabezado ya sólo contiene el h1 oculto: no debe ocupar ni margen. */
:where(.vl-redesign) .vl-archive__head { margin: 0; }

:where(.vl-redesign) .vl-archive__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--vl-space-3);
  margin-block-end: var(--vl-space-5);
}

:where(.vl-redesign) .vl-archive__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-3xl);
  font-weight: var(--vl-fw-black);
  letter-spacing: var(--vl-tracking-tight);
  color: var(--vl-text);
}

:where(.vl-redesign) .vl-results__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vl-space-4);
  margin-block-end: var(--vl-space-3);
}

/* El alternador ya no necesita margen propio: lo pone la barra. */
.vl-redesign .vl-results--toggle .vl-viewtoggle { margin-block-end: 0; }

:where(.vl-redesign) .vl-results__count {
  margin-block-end: 0;
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text-muted);
}

:where(.vl-redesign) .vl-archive__count {
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text-muted);
}

:where(.vl-redesign) .vl-archive__search { margin-block-end: var(--vl-space-3); }

/*
 * El buscador es el widget de GeoDirectory (los filtros avanzados se enganchan
 * a él, así que no se puede reimplementar) y viene con markup de Bootstrap
 * dentro de `.bsui`. Aquí sólo se le da aire y se redondea: pelearse regla a
 * regla con AyeCode UI se pierde. La armonización de verdad va en la
 * sobreescritura de search-bar/form.php.
 */
:where(.vl-redesign) .vl-archive__search .geodir-search-form,
:where(.vl-redesign) .vl-archive__search form {
  border-radius: var(--vl-radius-lg);
}

/*
 * TRES CAMPOS SE OCULTAN, PERO NO SE QUITAN.
 *
 * El tipo de contenido lo llevan ahora las pestañas y la categoría los chips,
 * así que dentro del formulario sobraban: eran los dos controles que lo hacían
 * parecer un panel de administración.
 *
 * El tercero es «Near», y ése sobra por un motivo más serio: NO FILTRA.
 * Comprobado contra producción con la misma búsqueda: Fuengirola, Marbella,
 * Tokyo y `asdfghjkl` devuelven los mismos 896 resultados. GeoDirectory sólo
 * aplica la ubicación cuando el autocompletado de Google rellena
 * sgeo_lat/sgeo_lon al elegir una sugerencia; el texto escrito a mano se ignora
 * en silencio. Un campo que promete filtrar y no filtra es peor que no tenerlo,
 * y para «cerca de mí» ya está el chip, que sí funciona.
 *
 * Se ocultan con `visually-hidden` en vez de borrarlos porque siguen
 * enviándose con el formulario —el `stype` decide en qué CPT busca GeoDirectory—
 * y vl-redesign.js sincroniza categoría y ubicación con el estado activo, para
 * que buscar dentro de un filtro no lo pierda.
 *
 * Quitarlos del HTML exigiría sobreescribir search-bar/form.php, y eso deja
 * fuera cualquier filtro avanzado que se configure más adelante.
 */
/*
 * ── EL BUSCADOR, EN UNA SOLA PÍLDORA ─────────────────────────────────────────
 *
 * El formulario de GeoDirectory es un `row` de Bootstrap: cada campo es una
 * columna que envuelve cuando no cabe, y el botón lleva `w-100`. En móvil eso
 * mandaba el botón a una línea entera, una barra naranja de lado a lado que no
 * significa nada. Con `flex-wrap: nowrap` todo se queda en una línea a
 * cualquier ancho, y el botón pasa a ser un círculo del tamaño de un pulgar.
 *
 * Estas reglas van SIN `:where()` a propósito: compiten con utilidades de
 * Bootstrap que llevan `!important` (`w-100`, `px-0`, `mb-3`), así que
 * necesitan subir de especificidad además de llevar el suyo.
 */
.vl-redesign .vl-archive__search .geodir-search {
  display: flex !important;
  flex-wrap: nowrap !important;
  align-items: center;
  gap: var(--vl-space-2);
  margin: 0 !important;
  padding: var(--vl-space-1) !important;
  background: var(--vl-white);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-pill);
  box-shadow: var(--vl-shadow-sm);
  transition: border-color var(--vl-duration-fast) var(--vl-ease),
              box-shadow var(--vl-duration-fast) var(--vl-ease);
}

/* El foco se marca en la píldora entera, no en el input de dentro: la píldora
   es lo que el ojo lee como "el buscador". */
.vl-redesign .vl-archive__search .geodir-search:focus-within {
  border-color: var(--vl-teal-400);
  box-shadow: 0 0 0 4px var(--vl-action-tint);
}

.vl-redesign .vl-archive__search .geodir-search-form-wrapper { margin-bottom: 0 !important; }

/* Un buscador de 1.500px de ancho no es un buscador, es una raya. Se le pone
   medida y se queda a la izquierda, alineado con el resto de la columna. */
@media (min-width: 768px) {
  .vl-redesign .vl-archive__search .geodir-search { max-width: 46rem; }
}

/*
 * `gy-2` de Bootstrap le mete `margin-top: 8px` a cada hijo del row. Dentro de
 * la píldora eso empujaba todo 8px hacia abajo: la píldora crecía a 66px con
 * 48 de contenido y el botón quedaba descentrado, con 13px arriba y 5 abajo.
 * Medido con getBoundingClientRect, no a ojo.
 */
.vl-redesign .vl-archive__search .geodir-search > * { margin-top: 0 !important; }

/*
 * El icono de la lupa va `position: absolute; top: 0` y mide menos que el
 * campo (38,4 frente a 48), así que su centro caía 4,8px por encima del centro
 * del texto. Se ancla al centro en vez de al borde superior.
 */
.vl-redesign .vl-archive__search .input-group-inside > .input-group-text {
  inset-block-start: 50%;
  transform: translateY(-50%);
  padding-block: 0;
  align-items: center;
}

/* El input pierde su caja: la caja ya es la píldora. */
.vl-redesign .vl-archive__search .form-control {
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  min-height: 44px;
  font-size: var(--vl-text-base);
}

/* El botón: círculo, no barra. 44px es el objetivo táctil mínimo. */
.vl-redesign .vl-archive__search .geodir_submit_search {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 44px !important;
  height: 44px;
  padding: 0 !important;
  border: 0;
  border-radius: 50% !important;
  background: var(--vl-orange-600);
  color: var(--vl-white);
  box-shadow: var(--vl-shadow-sm);
}

.vl-redesign .vl-archive__search .geodir_submit_search:hover {
  background: var(--vl-orange-700);
}

/* Su envoltorio no debe reclamar espacio: todo el ancho es para el texto. */
.vl-redesign .vl-archive__search .geodir-search > .gd-search-field-search:last-of-type {
  flex: 0 0 auto !important;
}

/* Los filtros avanzados cuelgan del mismo row; que caigan debajo y no partan
   la píldora si algún día se configura alguno. */
.vl-redesign .vl-archive__search .geodir-filter-container {
  flex: 0 0 100%;
  order: 99;
}

@media (min-width: 1024px) {
  .vl-redesign .vl-archive__search .geodir_submit_search {
    width: 48px !important;
    height: 48px;
  }

  .vl-redesign .vl-archive__search .form-control { min-height: 48px; }
}

:where(.vl-redesign) .vl-archive__search .gd-search-field-cpt,
:where(.vl-redesign) .vl-archive__search .gd-search-field-near,
:where(.vl-redesign) .vl-archive__search .gd-search-field-categories {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── Pestañas de tipo ─────────────────────────────────────────────────────── */
/* Subrayado, no píldoras: así no compiten con los chips de filtro, que sí son
 * píldoras. Dos jerarquías distintas, dos formas distintas. */

/*
 * Sólo hasta 1024px. A partir de ahí los mismos tres enlaces están en la
 * cabecera, y tenerlos dos veces seguidas —«Places Events Offers» sobre
 * «Places Events Offers»— era ruido. Por debajo, la cabecera no lleva nav
 * (esa la hace la bottom-nav), así que estas pestañas son el único selector
 * de tipo y tienen que estar.
 */
:where(.vl-redesign) .vl-cpttabs {
  display: flex;
  gap: var(--vl-space-5);
  border-block-end: 1px solid var(--vl-border);
  margin-block-end: var(--vl-space-5);
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-cpttabs { display: none; }
}

:where(.vl-redesign) .vl-cpttabs__item {
  padding-block: var(--vl-space-3);
  border-block-end: 2px solid transparent;
  margin-block-end: -1px;
  /*
   * Estas pestañas son el título de la página, no un menú secundario: desde
   * que el h1 dejó de pintarse son lo único que dice dónde estás. Por eso van
   * en la tipografía display y con la activa en tinta plena; el resto,
   * apagadas. Se lee como un encabezado y funciona como navegación.
   */
  font-family: var(--vl-font-display);
  font-size: 1.0625rem;
  font-weight: var(--vl-fw-bold);
  color: var(--vl-text-faint);
  white-space: nowrap;
}

:where(.vl-redesign) .vl-cpttabs__item:hover {
  color: var(--vl-action);
  text-decoration: none;
}

:where(.vl-redesign) .vl-cpttabs__item[aria-current='page'] {
  color: var(--vl-text);
  border-block-end-color: var(--vl-action);
  border-block-end-width: 3px;
}

/* ── Barra de filtros ─────────────────────────────────────────────────────── */
/*
 * Una sola fila desplazable: cercanía primero, luego categorías. Se sale del
 * contenedor a los lados con márgenes negativos para que el desplazamiento
 * llegue hasta el borde de la pantalla en móvil —cortar un chip contra un
 * padding es la señal de "aquí hay más", y con el padding no se ve.
 */
:where(.vl-redesign) .vl-filterbar {
  display: grid;
  gap: var(--vl-space-2);
  margin-block-end: var(--vl-space-3);
}

/*
 * Cada fila se desplaza por su cuenta y se sale del contenedor a los lados con
 * márgenes negativos: cortar un chip contra el borde de la pantalla es la señal
 * de «aquí hay más», y con el padding del contenedor no se ve.
 */
:where(.vl-redesign) .vl-filterbar__row {
  display: flex;
  align-items: center;
  gap: var(--vl-space-2);
  overflow-x: auto;
  scrollbar-width: none;
  margin-inline: calc(var(--vl-gutter) * -1);
  padding-inline: var(--vl-gutter);
  padding-block-end: 2px;
}

:where(.vl-redesign) .vl-filterbar__row::-webkit-scrollbar { display: none; }

/* Con sitio, las dos vuelven a una sola línea separadas por un filete. */
@media (min-width: 768px) {
  :where(.vl-redesign) .vl-filterbar {
    display: flex;
    align-items: center;
    gap: var(--vl-space-3);
  }

  :where(.vl-redesign) .vl-filterbar__row { margin-inline: 0; padding-inline: 0; }
  :where(.vl-redesign) .vl-filterbar__row--geo { flex: 0 0 auto; }
  :where(.vl-redesign) .vl-filterbar__row--cats {
    flex: 1 1 auto;
    min-width: 0;
    padding-inline-start: var(--vl-space-3);
    border-inline-start: 1px solid var(--vl-border);
  }
}

:where(.vl-redesign) .vl-chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  /* 32px en móvil: dos filas de chips grandes se comían la pantalla antes de
     llegar a la primera tarjeta. Sigue por encima del mínimo cómodo para el
     pulgar en una lista horizontal. */
  min-height: 32px;
  padding: var(--vl-space-1) var(--vl-space-3);
  font-size: var(--vl-text-xs);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-pill);
  background: var(--vl-white);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text-body);
  white-space: nowrap;
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-chip {
    min-height: 38px;
    padding: var(--vl-space-2) var(--vl-space-4);
    font-size: var(--vl-text-sm);
  }
}

:where(.vl-redesign) .vl-chip:hover {
  border-color: var(--vl-teal-300);
  background: var(--vl-action-tint);
  color: var(--vl-teal-800);
  text-decoration: none;
}

:where(.vl-redesign) .vl-chip[aria-current='true'] {
  background: var(--vl-action);
  border-color: var(--vl-action);
  color: var(--vl-text-on-dark);
}

/* La cercanía se distingue del resto: es una acción, no un filtro más. */
:where(.vl-redesign) .vl-chip--geo {
  border-color: var(--vl-teal-300);
  background: var(--vl-bg-tint);
  color: var(--vl-teal-800);
}

:where(.vl-redesign) .vl-chip--up {
  border-style: dashed;
  color: var(--vl-text-muted);
}

:where(.vl-redesign) .vl-chip--clear {
  border-color: transparent;
  background: none;
  color: var(--vl-text-muted);
  text-decoration: underline;
}

:where(.vl-redesign) .vl-chip--waiting {
  border-style: dashed;
  color: var(--vl-text-faint);
  font-weight: var(--vl-fw-regular);
}

/* ── Paginación ───────────────────────────────────────────────────────────── */
/* paginate_links(type=array) emite <a|span class="page-numbers">. */

:where(.vl-redesign) .vl-pagination {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--vl-space-2);
  margin-block-start: var(--vl-space-8);
}

:where(.vl-redesign) .vl-pagination .page-numbers {
  display: grid;
  place-items: center;
  min-width: var(--vl-tap-min);
  min-height: var(--vl-tap-min);
  padding-inline: var(--vl-space-3);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-md);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--vl-text-body);
}

:where(.vl-redesign) .vl-pagination a.page-numbers:hover {
  border-color: var(--vl-teal-300);
  background: var(--vl-action-tint);
  color: var(--vl-teal-800);
  text-decoration: none;
}

:where(.vl-redesign) .vl-pagination .page-numbers.current {
  background: var(--vl-action);
  border-color: var(--vl-action);
  color: var(--vl-text-on-dark);
}

:where(.vl-redesign) .vl-pagination .page-numbers.dots {
  border-color: transparent;
  color: var(--vl-text-faint);
}

/* ══ 25. PIEZAS DE LA TARJETA SOBRE LA IMAGEN ══════════════════════════════ */

:where(.vl-redesign) .vl-placecard__badges {
  position: absolute;
  inset-block-start: var(--vl-space-3);
  inset-inline-start: var(--vl-space-3);
  z-index: calc(var(--vl-z-base) + 1);
}

:where(.vl-redesign) .vl-placecard__badges .vl-badge { box-shadow: var(--vl-shadow-md); }

:where(.vl-redesign) .vl-placecard__noimg {
  display: block;
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, var(--vl-teal-200), var(--vl-teal-500));
}

/*
 * Favorito: el markup lo emite [gd_post_fav] de GeoDirectory y su JS
 * (geodirectory.js:970) alterna la clase `geodir-removetofav-icon` sobre el
 * `<a>`. Aquí sólo se le da la forma del mockup; el AJAX es el suyo.
 *
 * El `!important` del color no es pereza: GD escribe el color en un atributo
 * `style` inline sobre el icono, y sin él el corazón queda fuera del sistema.
 */
:where(.vl-redesign) .vl-placecard__fav {
  position: absolute;
  inset-block-start: var(--vl-space-3);
  inset-inline-end: var(--vl-space-3);
  z-index: calc(var(--vl-z-base) + 2);
}

/*
 * El clicable NO es un <a> ni un .badge: GeoDirectory emite
 *   .gd-fav-info-wrap > .gd-list-favorite > .geodir-addtofav.favorite_property_<id>
 *     > span.geodir-addtofav-icon[onclick] > i.fas.fa-heart
 * Es un <span> con `onclick`. El primer intento apuntó a `> a` y no casaba con
 * nada, así que el corazón salía desnudo sobre la foto.
 *
 * `.h5` que GD añade al contenedor es una clase de Bootstrap y trae font-size y
 * margen propios: hay que neutralizarla o el círculo sale descentrado.
 */
:where(.vl-redesign) .vl-placecard__fav .gd-fav-info-wrap,
:where(.vl-redesign) .vl-placecard__fav .gd-list-favorite,
:where(.vl-redesign) .vl-placecard__fav .geodir-addtofav {
  display: block;
  margin: 0 !important;
  padding: 0 !important;
  font-size: inherit !important;
  line-height: 1 !important;
}

/*
 * SE APUNTA A `.geodir-act-fav`, QUE ES LA CLASE QUE NO CAMBIA.
 *
 * Al marcar favorito, el JS de GeoDirectory intercambia las clases del mismo
 * elemento: `geodir-addtofav-icon` → `geodir-removetofav-icon`
 * (assets/aui/js/geodirectory.js:1106-1118). Estilando sólo la primera, el
 * disco blanco y su tamaño desaparecían en cuanto pulsabas: el corazón se
 * quedaba desnudo sobre la foto. `.geodir-act-fav` está en los dos estados,
 * que es justo lo que necesita un estilo de componente.
 *
 * Las otras dos se dejan como red por si algún shortcode no pone `act-fav`.
 */
:where(.vl-redesign) .vl-placecard__fav .geodir-act-fav,
:where(.vl-redesign) .vl-placecard__fav .geodir-addtofav-icon,
:where(.vl-redesign) .vl-placecard__fav .geodir-removetofav-icon {
  display: grid !important;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  margin: 0 !important;
  padding: 0 !important;
  border-radius: 50%;
  background: var(--vl-white);
  box-shadow: var(--vl-shadow-md);
  font-size: 1rem;
  line-height: 1 !important;
  cursor: pointer;
}

:where(.vl-redesign) .vl-placecard__fav .geodir-act-fav i {
  color: var(--vl-ink-600) !important;
}

/* Marcado: corazón lleno de color. El `!important` es obligatorio porque GD le
   escribe un `style="color:…"` inline al cambiar de estado. */
:where(.vl-redesign) .vl-placecard__fav .geodir-act-fav:hover i,
:where(.vl-redesign) .vl-placecard__fav .geodir-removetofav-icon i {
  color: var(--vl-fav) !important;
}

/*
 * El breadcrumb lo inyecta un filtro del tema DENTRO del formulario de
 * búsqueda de GeoDirectory. Ahí no es una miga de pan: es una línea suelta
 * entre el título y el buscador que no ayuda a nadie a volver a ningún sitio,
 * porque las pestañas y los chips ya dicen dónde estás.
 */
/* `!important` obligado: el filtro lo emite con `style="display:flex"` inline,
   y un estilo inline gana a cualquier selector de hoja sin él. */
.vl-redesign .vl-archive__search .vibelocal-breadcrumbs { display: none !important; }

/* El texto del shortcode va oculto: en la tarjeta manda el icono. */
:where(.vl-redesign) .vl-placecard__fav .geodir-fav-text { display: none; }

/* ══ 26. CORRECCIONES SOBRE MARKUP DE TERCEROS ═════════════════════════════
 * Todo lo de aquí resuelve un choque concreto con GeoDirectory o con el CSS
 * inline heredado. Cada bloque dice contra qué pelea y por qué.
 * ------------------------------------------------------------------------- */

/*
 * (a) La distancia no se pinta hasta que se conoce la posición del visitante.
 *
 * vl_render_distance() emite el hueco con un guión dentro, y script.js lo
 * rellena y quita la clase `vl-distance-pending`. Sin esto, quien no da permiso
 * de ubicación ve un «🚶 —» permanente, que parece un dato roto. Ocultarlo
 * mientras está pendiente reutiliza el mecanismo que ya existe sin tocar el JS.
 */
:where(.vl-redesign) .vl-distance-pending { display: none !important; }

/*
 * (b) Badges: aquí SÍ se sube la especificidad a propósito.
 *
 * inc/place-badges.php imprime un <style id="vl-place-badges-css"> dentro del
 * <body> con `.vl-badge--verified{background:#16a34a;color:#fff}`. Tiene la
 * misma especificidad que la regla del sistema (0,1,0) pero va DESPUÉS en el
 * documento, así que ganaba y los badges salían en verde Tailwind.
 *
 * Usar `.vl-redesign` sin `:where()` sube a (0,2,0) y gana sin `!important` ni
 * tocar place-badges.php, que sigue sirviendo al resto del sitio tal cual.
 */
.vl-redesign .vl-badge--featured { background: var(--vl-gold); color: var(--vl-ink-900); }
.vl-redesign .vl-badge--promoted { background: var(--vl-orange-100); color: var(--vl-orange-800); }
.vl-redesign .vl-badge--verified { background: var(--vl-teal-100); color: var(--vl-teal-800); }

.vl-redesign .vl-badge {
  padding: 0.25rem var(--vl-space-3);
  border-radius: var(--vl-radius-pill);
  font-family: var(--vl-font-ui);
  font-size: var(--vl-text-2xs);
  font-weight: var(--vl-fw-bold);
  letter-spacing: var(--vl-tracking-wide);
  text-transform: uppercase;
}

/*
 * (c) El formulario de búsqueda de GeoDirectory desbordaba en móvil.
 *
 * El plugin le pone `style="box-sizing:content-box"` inline al <form>, y con
 * padding propio eso se sale del viewport a 390px. Se fuerza border-box y se
 * deja que los campos se encojan (`min-width: 0`, que es lo que le falta a
 * cualquier flex/grid item con contenido).
 */
:where(.vl-redesign) .vl-archive__search form {
  box-sizing: border-box !important;
  max-width: 100%;
}

:where(.vl-redesign) .vl-archive__search .geodir-search-container,
:where(.vl-redesign) .vl-archive__search [class*='col-'],
:where(.vl-redesign) .vl-archive__search .form-control,
:where(.vl-redesign) .vl-archive__search .input-group {
  min-width: 0;
  max-width: 100%;
}

:where(.vl-redesign) .vl-archive__search img { display: inline; }

/*
 * (d) El breadcrumb de [vibe_breadcrumbs] se inyecta DENTRO del formulario de
 * búsqueda. No se mueve de sitio (lo coloca un hook de GD), pero se le baja el
 * tono para que no compita con el buscador.
 */
:where(.vl-redesign) .vl-archive__search .vibelocal-breadcrumbs {
  font-size: var(--vl-text-xs) !important;
  color: var(--vl-text-faint);
}

:where(.vl-redesign) .vl-archive__search .vibelocal-breadcrumbs a { color: var(--vl-text-muted); }
:where(.vl-redesign) .vl-archive__search .vibelocal-breadcrumbs a:hover { color: var(--vl-action); }

/* ══ 27. ALTERNADOR Y MAPA ═════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-btn--sm {
  min-height: 38px;
  padding: var(--vl-space-2) var(--vl-space-4);
  font-size: var(--vl-text-sm);
}

/* ── Alternador lista / mapa ───────────────────────────────────────────────── */
/*
 * Sin JavaScript la lista y el mapa salen apilados: los dos son útiles, así que
 * el estado por defecto es funcional. El JS añade `vl-results--toggle` y a partir
 * de ahí se comportan como pestañas. A 1280px se ven los dos en paralelo y el
 * alternador desaparece, porque ahí sobra espacio para ambos.
 */
.vl-redesign .vl-viewtoggle { display: none; }

/*
 * Control segmentado. Los botones llevan su propia píldora dentro de la del
 * contenedor, con un carril de 3px alrededor.
 *
 * Antes el contenedor era una píldora con `overflow: hidden` y los botones
 * cuadrados: las esquinas se recortaban contra el óvalo y se veía el corte. Y
 * encima los botones heredaban de fuera `border: 1px solid #CC3366` y
 * `border-radius: 3px`, un magenta que no es de la paleta.
 *
 * Se escapaba porque el reset de base.css pone `border: 0` en `button` dentro
 * de `:where()`, o sea con especificidad CERO: cualquier regla ajena le gana.
 * Aquí se declara explícitamente y sin `:where()` en el propio componente, que
 * es donde debe estar.
 */
.vl-redesign .vl-results--toggle .vl-viewtoggle {
  display: inline-flex;
  gap: 0;
  padding: 3px;
  margin-block-end: var(--vl-space-4);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-pill);
  background: var(--vl-white);
}

.vl-redesign .vl-viewtoggle__btn {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  min-height: 30px;
  padding: var(--vl-space-1) var(--vl-space-4);
  border: 0;
  border-radius: var(--vl-radius-pill);
  background: none;
  font-size: var(--vl-text-xs);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text-muted);
  transition: background var(--vl-duration-fast) var(--vl-ease),
              color var(--vl-duration-fast) var(--vl-ease);
}

@media (min-width: 768px) {
  .vl-redesign .vl-viewtoggle__btn {
    min-height: 34px;
    padding: var(--vl-space-2) var(--vl-space-5);
    font-size: var(--vl-text-sm);
  }
}

.vl-redesign .vl-viewtoggle__btn[aria-pressed='true'] {
  background: var(--vl-action);
  color: var(--vl-text-on-dark);
  box-shadow: var(--vl-shadow-sm);
}

:where(.vl-redesign) .vl-results--toggle[data-vl-view='list'] .vl-results__map { display: none; }
:where(.vl-redesign) .vl-results--toggle[data-vl-view='map'] .vl-results__list { display: none; }

/* ── El mapa ──────────────────────────────────────────────────────────────── */
/*
 * EL ALTO LO MANDA ESTA HOJA, NO EL SHORTCODE.
 * Al mapa se le pasa `height="100%"` y aquí se propaga ese 100% por toda la
 * cadena de envoltorios de GeoDirectory. Es la única manera de que el mismo
 * mapa mida media pantalla en móvil y una pantalla entera en escritorio: lo que
 * imprime el plugin son estilos inline, y un estilo inline no atiende a media
 * queries.
 *
 * Efecto lateral buscado: con `100%` GD no imprime el JS que fija el alto en
 * píxeles (class-geodir-widget-map.php:886-910 sólo actúa si el valor trae `vh`
 * o `px`), así que nadie pelea por la altura.
 */
:where(.vl-redesign) .vl-results__map {
  height: 65vh;
  min-height: 22rem;
  margin-block-start: var(--vl-space-6);
  border-radius: var(--vl-radius-lg);
  overflow: hidden;
  border: 1px solid var(--vl-border);
}

/*
 * `.geodir_map_container` sólo trae `min-height` inline, y un `height: 100%`
 * hijo no resuelve contra un padre de alto automático: por eso entra aquí
 * también `height`. El `margin: 0` es porque el shortcode le cuelga el `mb-3`
 * de Bootstrap.
 */
:where(.vl-redesign) .vl-results__map .geodir-wgt-map,
:where(.vl-redesign) .vl-results__map .cmplz-blocked-content-container,
:where(.vl-redesign) .vl-results__map .geodir-map-wrap,
:where(.vl-redesign) .vl-results__map .stick_trigger_container,
:where(.vl-redesign) .vl-results__map .geodir_map_container,
:where(.vl-redesign) .vl-results__map .map_background,
:where(.vl-redesign) .vl-results__map .top_banner_section_in,
:where(.vl-redesign) .vl-results__map .iprelative {
  height: 100%;
  max-width: 100%;
  margin: 0;
}

:where(.vl-redesign) .vl-results__map img { max-width: none; }

/*
 * ── EL MAPA A PANTALLA COMPLETA EN MÓVIL ─────────────────────────────────────
 *
 * Al pulsar «Map» el mapa no ocupa un hueco entre la cabecera y la nav: se
 * come la pantalla entera, como un modal. Un mapa recortado en un móvil no se
 * puede explorar —cada arrastre se sale del marco— y además arrastraba la
 * página de debajo.
 *
 * El alternador se queda flotando abajo como píldora: es la única salida
 * visible, así que tiene que estar por encima del mapa y a la vista.
 */
html.vl-mapopen,
html.vl-mapopen body {
  overflow: hidden;
  touch-action: none;
}

html.vl-mapopen .vl-results__map {
  position: fixed;
  inset: 0;
  z-index: var(--vl-z-modal);
  height: 100vh;
  height: 100dvh;
  margin: 0;
  border: 0;
  border-radius: 0;
}

html.vl-mapopen .vl-results--toggle .vl-viewtoggle {
  position: fixed;
  z-index: calc(var(--vl-z-modal) + 1);
  inset-inline: 0;
  /* Por encima de la franja de atribución de Google (Terms, Map Data…), que
     ocupa los ~28px de abajo y se comía media píldora. */
  inset-block-end: calc(2.5rem + env(safe-area-inset-bottom, 0px));
  width: fit-content;
  margin-inline: auto;
  margin-block-end: 0;
  box-shadow: var(--vl-shadow-lg);
}

/* La barra de preview se aparta: caía justo encima del alternador. */
html.vl-mapopen .vl-previewbar {
  inset-block-end: calc(6.5rem + env(safe-area-inset-bottom, 0px));
  z-index: calc(var(--vl-z-modal) + 1);
}

/*
 * Escritorio: manda el mapa.
 * La lista baja a UNA columna de tarjetas y el mapa se lleva dos tercios,
 * pegado mientras se recorre la lista. La tarjeta se lee en vertical y el mapa
 * sostiene el contexto; una grilla de tres columnas al lado de un mapa
 * estrecho no era ninguna de las dos cosas.
 */
@media (min-width: 1280px) {
  /* El listado pide más ancho que una página de texto: aquí no hay medida de
     lectura que respetar, hay un mapa que cuanto más grande, mejor lee. */
  /* Se redefine `--vl-gutter`, no sólo el padding: la barra de filtros se sale
     del contenedor con márgenes negativos de esa misma medida, y si cada una
     usa un valor distinto los chips quedan descuadrados respecto al contenido. */
  :where(.vl-redesign) .vl-archive .vl-container {
    --vl-gutter: var(--vl-space-6);
    max-width: var(--vl-container-wide);
    padding-inline: var(--vl-gutter);
  }

  /*
   * La lista tiene ancho propio y el mapa se queda con TODO lo que sobre.
   * Con fracciones (1fr/2fr) la tarjeta crecía con la pantalla y a ancho
   * completo acababa midiendo 800px: una tarjeta estirada y ridícula. Así la
   * tarjeta se queda entre 22 y 28rem —que es donde se lee bien— y el mapa
   * pasa de dos tercios a 1280px a cuatro quintos en un monitor grande.
   */
  :where(.vl-redesign) .vl-results {
    display: grid;
    grid-template-columns: minmax(0, clamp(22rem, 26vw, 28rem)) minmax(0, 1fr);
    gap: var(--vl-space-6);
    align-items: start;
  }

  :where(.vl-redesign) .vl-results__list .vl-grid { grid-template-columns: minmax(0, 1fr); }

  /*
   * Colocación a mano. La barra es un hijo más de la rejilla y con
   * autoposicionamiento se habría metido en la celda del mapa. El mapa abarca
   * las dos filas para quedar a la altura de la barra y de la lista.
   */
  :where(.vl-redesign) .vl-results__bar  { grid-column: 1; grid-row: 1; }
  :where(.vl-redesign) .vl-results__list { grid-column: 1; grid-row: 2; }
  :where(.vl-redesign) .vl-results__map  { grid-column: 2; grid-row: 1 / span 2; }

  /* Con sitio para los dos, el alternador no aporta. */
  /* Sin `:where()`: la regla base del componente subió de especificidad para
     ganarle al borde magenta heredado, y con `:where()` esta ya no la tapaba.
     El alternador se colaba como primera celda de la rejilla y descolocaba
     lista y mapa. */
  .vl-redesign .vl-results--toggle .vl-viewtoggle { display: none; }
  :where(.vl-redesign) .vl-results--toggle[data-vl-view] .vl-results__list,
  :where(.vl-redesign) .vl-results--toggle[data-vl-view] .vl-results__map { display: block; }

  :where(.vl-redesign) .vl-results__map,
  :where(.vl-redesign) .vl-results--toggle[data-vl-view] .vl-results__map {
    position: sticky;
    inset-block-start: calc(var(--vl-header-h) + var(--vl-space-4));
    height: calc(100vh - var(--vl-header-h) - var(--vl-space-8));
    height: calc(100dvh - var(--vl-header-h) - var(--vl-space-8));
    margin-block-start: 0;
  }
}


/* ══ 28. BURBUJA DEL MAPA ══════════════════════════════════════════════════ */
/*
 * Lo que sale al pulsar un marcador. Escrito contra el markup REAL, medido
 * abriendo una burbuja en el navegador — el primer intento lo escribí de
 * memoria y fallaba en las tres cosas que importaban:
 *
 *   1. El aspa de cerrar NO cuelga de `.gm-style-iw-c`, sino de una cabecera
 *      propia `.gm-style-iw-chr` que se comía 48px de alto ella sola.
 *   2. El contenido medía 466px dentro de una ventana de 163: recortado.
 *   3. `.gd-bubble` salía 4px más ancho que la ventana de Google.
 *
 * Sin `:where()`: hay que ganarle a los estilos inline de Google.
 */

.vl-redesign .gm-style .gm-style-iw-c {
  padding: 0 !important;
  border-radius: var(--vl-radius-lg) !important;
  box-shadow: var(--vl-shadow-lg) !important;
  overflow: hidden;
}

.vl-redesign .gm-style .gm-style-iw-d {
  padding: 0 !important;
  overflow: hidden !important;
  /* Google calcula un max-height propio y dejaba el título cortado con barra
     de scroll. El contenido de aquí es corto por diseño, así que se libera y
     la ventana crece hasta caber entera. */
  max-height: none !important;
}

/*
 * La cabecera de Google pasa a flotar sobre la imagen en vez de ocupar su
 * propia franja. Son 48px recuperados en una tarjeta de 230.
 */
.vl-redesign .gm-style .gm-style-iw-chr {
  position: absolute;
  inset-block-start: 0;
  inset-inline-end: 0;
  z-index: 3;
  height: auto !important;
  padding: 0 !important;
}

.vl-redesign .gm-style .gm-style-iw-ch { display: none !important; }

/* El aspa, como el corazón de las tarjetas: disco blanco con sombra. */
.vl-redesign .gm-style .gm-style-iw-chr button.gm-ui-hover-effect {
  width: 2rem !important;
  height: 2rem !important;
  margin: var(--vl-space-2) !important;
  padding: 0 !important;
  border-radius: 50% !important;
  background: transparent !important;
  opacity: 1 !important;
}

.vl-redesign .gm-style .gm-style-iw-chr button.gm-ui-hover-effect:hover {
  background: var(--vl-ink-100) !important;
}

.vl-redesign .gm-style .gm-style-iw-chr button.gm-ui-hover-effect > span {
  width: 13px !important;
  height: 13px !important;
  margin: 0 !important;
  background-color: var(--vl-text-muted) !important;
}

/* El pico de la burbuja, sin el gris de serie. */
.vl-redesign .gm-style .gm-style-iw-tc::after { background: var(--vl-white); }

.vl-redesign .gd-bubble {
  /* La ventana de Google topa en 260px por mucho que se le pida más: con 292
     la tarjeta se salía 32px por el lado. Se ajusta a lo que hay. */
  width: 256px;
  box-sizing: border-box;
  font-family: var(--vl-font-ui);
}

/*
 * FUERA EL VOLCADO DE CAMPOS.
 *
 * `[gd_output_location location="mapbubble"]` imprimía 244px de pares
 * etiqueta/valor en crudo —«Place Title: Fuengirola Train Station»,
 * «Business Owner/Associate?: Yes»— que es configuración del plugin asomando
 * por la interfaz. En una tarjeta de 250px de ancho no cabe y no aporta: la
 * burbuja es un adelanto, y para el detalle está la ficha.
 *
 * Esto lo tapa sólo en el rediseño. El arreglo de fondo es destildar esos
 * campos en GeoDirectory → Campos personalizados → «mostrar en la burbuja».
 */
.vl-redesign .gd-bubble .geodir-bubble-meta-side { display: none; }

/*
 * HORIZONTAL, Y EL TÍTULO MANDA.
 *
 * En vertical con la foto en 16/9 el contenido pedía 236px y la ventana daba
 * 175: el nombre salía cortado, que es justo lo único que no puede faltar.
 * Con la miniatura a un lado, todo cabe en ~100px de alto y no hay que
 * scrollear. `grid-template-areas` coloca cada bloque donde toca sin depender
 * del orden del HTML (que es título, imagen, meta) ni tocar la plantilla del
 * plugin.
 */
.vl-redesign .gd-bubble .geodir-bubble_desc {
  display: grid;
  grid-template-columns: 60px minmax(0, 1fr);
  grid-template-areas:
    'img titulo'
    'img meta';
  align-content: start;
  gap: 2px var(--vl-space-3);
  padding: var(--vl-space-3);
  /* Hueco para el aspa de Google, que flota en la esquina: sin reservarlo se
     montaba encima del título. */
  padding-inline-end: 2.25rem;
}

.vl-redesign .gd-bubble .geodir-post-title { grid-area: titulo; }
.vl-redesign .gd-bubble .geodir-bubble-meta-top { grid-area: meta; }

/* La imagen manda: arriba, a sangre y en 16/9. En el HTML el título va primero,
   así que se reordena con flex en vez de tocar la plantilla del plugin. */
.vl-redesign .gd-bubble .geodir-bubble_image {
  grid-area: img;
  width: 60px;
  height: 60px;
  margin: 0 !important;
  padding: 0 !important;
  overflow: hidden;
  border-radius: var(--vl-radius-md);
  background: var(--vl-ink-100);
}

/*
 * La foto no es un <img> suelto: GeoDirectory monta un carrusel completo
 * (slider → container → images → carousel-item → a.ratio → img) y el enlace
 * lleva `.ratio` de Bootstrap, que impone 16:9 por `::before`. Dentro de una
 * caja cuadrada de 60px eso dejaba la foto en 60x34 y medio hueco gris debajo.
 * Se estira toda la cadena y se anula el truco del ratio.
 */
.vl-redesign .gd-bubble .geodir-bubble_image .geodir-post-slider,
.vl-redesign .gd-bubble .geodir-bubble_image .geodir-image-container,
.vl-redesign .gd-bubble .geodir-bubble_image .geodir-images,
.vl-redesign .gd-bubble .geodir-bubble_image .carousel-inner,
.vl-redesign .gd-bubble .geodir-bubble_image .carousel-item,
.vl-redesign .gd-bubble .geodir-bubble_image a {
  height: 100% !important;
  width: 100% !important;
}

.vl-redesign .gd-bubble .geodir-bubble_image .ratio::before { padding-top: 0 !important; }

.vl-redesign .gd-bubble .geodir-bubble_image img {
  display: block;
  width: 100% !important;
  height: 100% !important;
  object-fit: cover;
}

/* El iconito de "esto es un enlace" no aporta en una miniatura de 60px. */
.vl-redesign .gd-bubble .geodir-bubble_image .fa-link { display: none !important; }

.vl-redesign .gd-bubble h4 {
  margin: 0;
  padding: 0;
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-base);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-tight);
  color: var(--vl-text);
  /* Dos líneas como mucho: un nombre largo no puede dictar el alto. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.vl-redesign .gd-bubble h4 a { color: inherit; }
.vl-redesign .gd-bubble h4 a:hover { color: var(--vl-action); }

.vl-redesign .gd-bubble .geodir-bubble-meta-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vl-space-2);
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
}

/* El corazón, igual que en la tarjeta. */
.vl-redesign .gd-bubble .geodir-act-fav,
.vl-redesign .gd-bubble .geodir-addtofav-icon,
.vl-redesign .gd-bubble .geodir-removetofav-icon {
  display: inline-grid !important;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  background: var(--vl-white);
  box-shadow: var(--vl-shadow-sm);
  font-size: 0.875rem !important;
}

/* La fecha del evento, sacada del título y tratada como lo que es. */
:where(.vl-redesign) .vl-placecard__date {
  display: flex;
  align-items: center;
  gap: var(--vl-space-2);
  margin-block-start: var(--vl-space-1);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-accent-strong);
}

/*
 * Un evento que está pasando AHORA se lee en rojo.
 *
 * Se pintó primero en verde, el del «Open now» de un negocio abierto, por
 * consistencia. El cliente lo pidió en rojo el 03/09/2026 y tiene su lógica:
 * un negocio abierto lo estará mañana también, mientras que un evento en marcha
 * se acaba hoy. El rojo dice «se te escapa», no «está bien».
 */
:where(.vl-redesign) .vl-placecard__date--now {
  color: var(--vl-closed);
}

/* Y la misma etiqueta en la fila de la portada. */
:where(.vl-redesign) .vl-eventrow__when--now {
  color: var(--vl-closed);
}

/*
 * El interruptor «Open now» del directorio. Encendido se lee en el verde de
 * «abierto», el mismo que usa la ficha y la tarjeta: el color ya significa eso
 * en este sitio.
 */
:where(.vl-redesign) .vl-chip--open-on {
  border-color: var(--vl-open);
  color: var(--vl-open);
  font-weight: var(--vl-fw-semibold);
}

/*
 * EL INTERROGANTE DEL HERO, EN DORADO.
 *
 * Está así en el mockup del cliente, y no es capricho: el signo es lo único de
 * ese titular que no es una palabra, y en dorado deja de leerse como parte de
 * «next» para leerse como lo que es, el gesto de la pregunta.
 *
 * `--vl-gold` y no un amarillo nuevo: es el mismo dorado del distintivo
 * Featured, así que el sitio sigue teniendo un solo amarillo. Sobre la foto del
 * hero, que siempre lleva velo oscuro, contrasta 7.9:1 contra ink-900.
 */
:where(.vl-redesign) .vl-hero__q {
  color: var(--vl-gold);
}

/*
 * LOS TRES DATOS DE SITIO, EN COLUMNAS.
 *
 * Distancia, precio y dirección iban en la misma fila flexible que el
 * porcentaje y el horario, y en un móvil eso no es una fila: son cinco líneas,
 * una por dato. El cliente lo pidió corregido contra su mockup —«move all the
 * text up, reduce scrolling time»— y ahí van en tres columnas.
 *
 * `auto-fit` y no `repeat(3, …)`: no todas las fichas tienen los tres. Con tres
 * columnas fijas, una sin precio dejaba un hueco en medio; así los que hay se
 * reparten el ancho.
 */
/*
 * Un trozo que no se parte. Lo usa el título de la ficha para que el tic de
 * verificado baje con la última palabra en vez de quedarse solo en una línea.
 */
:where(.vl-redesign) .vl-nowrap {
  white-space: nowrap;
}

/*
 * «Cancel reply», fuera de las reseñas.
 *
 * Sirve para cancelar la respuesta a un comentario concreto, y aquí no se
 * responde a nadie: se dice si te gustó el sitio con un pulgar. Se quita por
 * CSS y no por argumentos del formulario porque GeoDirectory lo imprime por su
 * cuenta, fuera de los que acepta `comment_form()`.
 */
:where(.vl-redesign) #comments #cancel-comment-reply-link {
  display: none;
}

/*
 * Compartir: confirmación de que el enlace se ha copiado, sin mover nada. El
 * icono se cambia por un tic desde CSS, así el JS sólo pone y quita una clase.
 */
:where(.vl-redesign) .vl-share--done {
  color: var(--vl-open);
}

:where(.vl-redesign) .vl-share--done > i::before {
  content: '\f00c'; /* fa-check */
}

:where(.vl-redesign) .vl-single__facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  gap: var(--vl-space-3);
  align-items: start;
  margin-block-start: var(--vl-space-3);
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
}

:where(.vl-redesign) .vl-fact {
  display: inline-flex;
  align-items: flex-start;
  gap: .4em;
  min-width: 0;
  line-height: var(--vl-leading-snug);
}

/* El icono no se encoge ni se sube con la primera línea del texto. */
:where(.vl-redesign) .vl-fact > i {
  flex: 0 0 auto;
  margin-block-start: .15em;
}

/* ── «Cómo llegar» ────────────────────────────────────────────────────────── */
/*
 * En la tarjeta va fuera del enlace que abre la ficha: un <a> dentro de otro <a>
 * no es HTML válido y el navegador parte el árbol donde le parece.
 */
/*
 * Sólo el icono: la etiqueta ocupaba 133px de una fila de 330 para una acción
 * secundaria. El nombre accesible lo pone `aria-label` en el propio enlace.
 *
 * Y NADA MÁS DENTRO. Aquí hubo un `<span class="vl-sr-only">` con el texto, y
 * aunque va en `position: absolute` el icono se iba 14px por debajo del centro
 * del botón —medido: centro del botón 764, centro del icono 778—. Con un único
 * hijo y `inline-flex`, el icono queda donde tiene que estar.
 */
/*
 * CENTRADO A PRUEBA DE SANGRADO.
 *
 * El icono salía 6,4 px a la derecha del centro. No era el `justify-content`:
 * el <a> tenía TRES hijos —salto de línea, <i>, salto de línea— y esos nodos de
 * texto se vuelven elementos flex anónimos que ocupan la mitad izquierda y
 * empujan el icono contra el borde. El icono estaba centrado, sí… entre los dos
 * espacios en blanco.
 *
 * El HTML ya va sin saltos (vl-templates/parts/card-place.php), pero eso
 * depende de cómo esté escrita la plantilla y un sangrado inocente lo rompe
 * otra vez. Con el icono en posición absoluta cubriendo el botón, el centrado
 * deja de depender de que no haya hermanos: da igual lo que entre en el <a>.
 */
:where(.vl-redesign) .vl-placecard__directions {
  position: relative;
  display: inline-block;
  flex: 0 0 auto;
  margin-inline-start: auto;
  width: 1.75rem;
  height: 1.75rem;
  line-height: 1;
  /* El texto suelto que pudiera colarse no ocupa: el icono recupera su tamaño
     en su propia regla. */
  font-size: 0;
  border: 1px solid var(--vl-border);
  border-radius: 50%;
  background: var(--vl-white);
}

/* El color va aparte y CON especificidad: dentro de `:where()` puntúa (0,1,0) y
   se lo comía una regla suelta de `a` de style.css, así que el icono salía en
   tinta oscura (medido: rgb(32,38,47)) en vez del teal de acción. */
.vl-redesign .vl-placecard__directions,
.vl-redesign .vl-placecard__directions i {
  color: var(--vl-action);
}

/*
 * `width: auto` con `!important` porque Font Awesome le pone `width: 1.25em` a
 * los iconos. Con un ancho explícito, `inset: 0` deja de estirar la caja —manda
 * `left` y se ignora `right`—, así que el icono quedaba pegado a la izquierda:
 * 16,3 px de caja dentro de 26, o sea 4,9 px descentrado. Medido.
 *
 * Especificidad real (sin `:where`) para ganarle a la hoja de Font Awesome.
 */
.vl-redesign .vl-placecard__directions i {
  position: absolute;
  inset: 0;
  width: auto !important;
  height: auto !important;
  display: grid;
  place-items: center;
  font-size: 0.8125rem;
  line-height: 1;
}



.vl-redesign .vl-placecard__directions:hover,
.vl-redesign .vl-placecard__directions:hover i {
  border-color: var(--vl-teal-300);
  background: var(--vl-action-tint);
  color: var(--vl-teal-800);
  text-decoration: none;
}

/* El icono no lleva fondo propio: si lo heredase taparía el círculo. */
.vl-redesign .vl-placecard__directions i { background: none; border: 0; }

/* En la burbuja ocupa el ancho: es la acción de la tarjeta, no un adorno. */
.vl-redesign .gd-bubble .vl-bubble-directions {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--vl-space-2);
  min-height: 36px;
  margin-block-start: var(--vl-space-1);
  border-radius: var(--vl-radius-pill);
  background: var(--vl-action);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text-on-dark);
}

.vl-redesign .gd-bubble .vl-bubble-directions:hover {
  background: var(--vl-action-hover);
  color: var(--vl-text-on-dark);
  text-decoration: none;
}

/* ══ 29. LANDING DE ZONA ═══════════════════════════════════════════════════ */
/*
 * Aquí NO hay componentes nuevos. El hero, los mosaicos, las filas de evento y
 * las ofertas son los de las secciones 9, 10, 11 y 15, tal cual salen en
 * `?vl_styleguide=1`. Lo único que se añade son las rejillas que los colocan y
 * los enlaces estirados, que son maquetación y no diseño.
 */

/*
 * El hero de la landing es a sangre y la cabecera flota encima
 * (.vl-topbar--over es `position:absolute`), así que hay que reservarle sitio
 * arriba o el titular se mete debajo del logo.
 */
:where(.vl-redesign) .vl-zone .vl-hero {
  padding-block-start: calc(var(--vl-header-h) + var(--vl-space-8));
  min-height: min(80vh, 34rem);
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-zone .vl-hero {
    padding-inline: var(--vl-space-8);
    min-height: min(72vh, 42rem);
  }
}

/*
 * Zona sin foto de portada.
 * Hoy ninguna de las siete páginas de zona tiene imagen destacada, y un hero de
 * 42rem en teal plano con el titular abajo del todo se lee como una página a
 * medio cargar. Mientras no haya foto se recorta el alto y el fondo pasa a ser
 * un degradado de la propia paleta, para que sea una decisión y no un hueco.
 * En cuanto se suba una imagen destacada, esta clase deja de ponerse sola.
 */
:where(.vl-redesign) .vl-hero--flat {
  min-height: 0;
  background: linear-gradient(155deg,
    var(--vl-teal-900) 0%,
    var(--vl-teal-700) 58%,
    var(--vl-teal-800) 100%);
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-zone .vl-hero--flat { min-height: 0; }
}

/* Sin foto no hace falta velo: el degradado ya es opaco y ya contrasta. */
:where(.vl-redesign) .vl-hero--flat::before { display: none; }

/*
 * Hero del paso de subcategorías.
 * Es una pantalla de paso, no un destino: la mitad de alto que el de la zona y
 * sin la palabra manuscrita, que sigue siendo UNA por página y le toca al hero
 * de la landing. Aquí el protagonista es el nombre de la categoría.
 */
:where(.vl-redesign) .vl-zone .vl-hero--step {
  min-height: 0;
  padding-block-end: var(--vl-space-8);
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-zone .vl-hero--step { min-height: 0; }
}

:where(.vl-redesign) .vl-hero__title--step {
  font-size: var(--vl-text-3xl);
  margin-block: var(--vl-space-3) var(--vl-space-2);
}

:where(.vl-redesign) .vl-hero__crumbs {
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
}

/* Especificidad real: el color del enlace sobre el hero no lo puede decidir
   una regla suelta de `a` de style.css. Mismo motivo que .vl-cattile__link. */
.vl-redesign .vl-hero__crumbs a {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  color: var(--vl-white);
  text-decoration: none;
  opacity: 0.85;
}

.vl-redesign .vl-hero__crumbs a:hover {
  color: var(--vl-white);
  opacity: 1;
  text-decoration: none;
}

/* Aire entre secciones. Generoso: la landing se lee de un vistazo bajando, y
   apretarlas convierte cinco bloques distintos en una sola mancha. */
:where(.vl-redesign) .vl-zone__section {
  margin-block: var(--vl-space-10);
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-zone__section { margin-block: var(--vl-space-16); }
}

/* ── Rejilla de mosaicos ──────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-tilegrid {
  display: grid;
  gap: var(--vl-space-3);
  grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-tilegrid { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-tilegrid {
    gap: var(--vl-space-4);
    grid-template-columns: repeat(4, 1fr);
  }
}

/* Las zonas son nombres cortos y no necesitan tanto alto ni tanto ancho. */
:where(.vl-redesign) .vl-tilegrid--tight .vl-cattile { min-height: 7.5rem; }

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-tilegrid--tight { grid-template-columns: repeat(4, 1fr); }
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-tilegrid--tight { grid-template-columns: repeat(6, 1fr); }
}

/* ── Listas de filas (eventos y ofertas) ──────────────────────────────────── */

:where(.vl-redesign) .vl-rowlist {
  display: grid;
  gap: var(--vl-space-3);
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-rowlist--split { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1280px) {
  :where(.vl-redesign) .vl-rowlist        { grid-template-columns: repeat(2, 1fr); }
  :where(.vl-redesign) .vl-rowlist--split { grid-template-columns: repeat(3, 1fr); }
}

/*
 * Enlace estirado: el <a> está en el titular —que es donde debe estar para un
 * lector de pantalla— pero la zona pulsable es la fila entera. Mismo recurso
 * que ya usa .vl-cattile__link. Funciona porque .vl-eventrow y .vl-offer son
 * `position: relative`.
 */
/* Especificidad real por lo mismo que .vl-cattile__link: con `:where()` el
   color del enlace lo acababa decidiendo style.css. */
.vl-redesign .vl-eventrow__link,
.vl-redesign .vl-offer__link {
  color: var(--vl-text);
  text-decoration: none;
}

.vl-redesign .vl-eventrow__link:hover,
.vl-redesign .vl-offer__link:hover {
  color: var(--vl-action);
  text-decoration: none;
}

:where(.vl-redesign) .vl-eventrow__link::after,
:where(.vl-redesign) .vl-offer__link::after {
  content: '';
  position: absolute;
  inset: 0;
}

/* Galón decorativo: no es un enlace aparte, sólo indica que la fila lleva a
   algún sitio. ink-400 está permitido justo para esto. */
:where(.vl-redesign) .vl-eventrow__go {
  color: var(--vl-ink-400);
  font-size: var(--vl-text-sm);
}

/* Hueco de la oferta sin foto: un bloque de tinte, no una imagen genérica. */
:where(.vl-redesign) span.vl-offer__img {
  display: block;
  background: var(--vl-teal-100);
}

/* ══ 30. FICHA ═════════════════════════════════════════════════════════════ */
/*
 * Negocio, evento y oferta. Casi todo son componentes ya definidos —galería,
 * medallones, vibe, tip, headline, offer, eventrow—; aquí va la columna que los
 * coloca y las piezas que sólo existen en la ficha.
 */

/* Medida de lectura. La ficha es texto y datos en una columna: a 1200px de
   ancho una descripción se lee fatal. */
:where(.vl-redesign) .vl-container--reading {
  max-width: 60rem;
}

:where(.vl-redesign) .vl-single__section {
  margin-block: var(--vl-space-10);
}

/* ── Cabecera ─────────────────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-single__head {
  margin-block: var(--vl-space-6) var(--vl-space-8);
}

/*
 * PRIMERA LÍNEA DE LA FICHA: INSIGNIAS A LA IZQUIERDA, ACCIONES A LA DERECHA.
 *
 * Antes las insignias vivían dentro de la columna del texto y los botones en
 * una columna a su derecha. En un móvil eso salía como cuatro cosas apiladas:
 * PROMOTED, debajo VERIFIED, y el título partido en dos porque su columna había
 * perdido el ancho de los botones. Reportado con El Camarote, que se leía «El /
 * Camarote».
 *
 * `nowrap` en la fila y `wrap` sólo dentro de las insignias: si algún día hay
 * tres, que caigan ellas y no los botones, que son el objetivo táctil.
 */
:where(.vl-redesign) .vl-single__headbar {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--vl-space-3);
  margin-block-end: var(--vl-space-2);
}

:where(.vl-redesign) .vl-single__badges {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vl-space-2);
  min-width: 0;
}

/*
 * EL FAVORITO, UN ICONO Y NADA MÁS.
 *
 * GeoDirectory le pone `visually-hidden` al texto mientras no está marcado,
 * pero al marcarlo su JS lo destapa y el botón crece hasta «Unfavorite»: una
 * píldora de 200px que en el móvil se comía media fila. Aquí el texto sobra
 * —hay `title` y `aria-label` para quien los necesita— y lo que hace falta es
 * que el botón mida siempre lo mismo, marcado o no.
 */
:where(.vl-redesign) .vl-single__fav .geodir-fav-text {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
}

:where(.vl-redesign) .vl-single__fav .geodir-act-fav {
  gap: 0 !important;
  justify-content: center;
  min-width: var(--vl-tap-min);
  padding: var(--vl-space-2) !important;
}

/*
 * Y EL TÍTULO, UN PUNTO MÁS PEQUEÑO EN MÓVIL.
 *
 * Con la fila de arriba liberada el título ya dispone del ancho entero, pero
 * «FOGO Restaurant Fuengirola» a 30px sigue sin caber en una pantalla de 360.
 * Dos líneas de título están bien; tres, o una palabra suelta en la segunda, no.
 */
@media (max-width: 599px) {
  :where(.vl-redesign) .vl-single__title {
    font-size: var(--vl-text-2xl);
  }
}

:where(.vl-redesign) .vl-single__headtop {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--vl-space-4);
}

:where(.vl-redesign) .vl-single__eyebrow {
  font-size: var(--vl-text-2xs);
  font-weight: var(--vl-fw-bold);
  letter-spacing: var(--vl-tracking-wide);
  text-transform: uppercase;
  color: var(--vl-orange-700);          /* 6.03:1 */
  margin-block-end: var(--vl-space-1);
}

:where(.vl-redesign) .vl-single__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-3xl);
  font-weight: var(--vl-fw-black);
  line-height: var(--vl-leading-tight);
  letter-spacing: var(--vl-tracking-tight);
  color: var(--vl-text);
  text-wrap: balance;
}

:where(.vl-redesign) .vl-single__cats {
  margin-block-start: var(--vl-space-2);
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
}

.vl-redesign .vl-single__cats a {
  color: var(--vl-action);
  text-decoration: none;
}

.vl-redesign .vl-single__cats a:hover { text-decoration: underline; }

:where(.vl-redesign) .vl-single__meta {
  margin-block-start: var(--vl-space-4);
}

:where(.vl-redesign) .vl-status__range {
  font-weight: var(--vl-fw-regular);
  opacity: 0.85;
}

:where(.vl-redesign) .vl-single__actions {
  margin-block-start: var(--vl-space-5);
}

/*
 * En móvil los botones ocupan el ancho —son el objetivo táctil principal—,
 * pero en escritorio NO. `.vl-btn-row` reparte el ancho a partes iguales, y en
 * una ficha con un solo botón eso daba un «Directions» de 60rem cruzando la
 * pantalla. Muchos negocios tienen una sola acción (Kavana no tiene ni
 * teléfono ni web), así que el caso de un botón es de los frecuentes.
 */
@media (min-width: 768px) {
  :where(.vl-redesign) .vl-single__actions {
    grid-auto-columns: max-content;
    justify-content: start;
  }
}

/* El consejo lleva un hueco de 6rem reservado para una foto que en la ficha no
   se pinta; sin esto queda una columna vacía a la derecha del texto. */
:where(.vl-redesign) .vl-single .vl-tip { grid-template-columns: 1fr; }

/* ── Guardar en favoritos ─────────────────────────────────────────────────── */
/*
 * EN LA TARJETA ES UN CÍRCULO; AQUÍ ES UN BOTÓN CON SU NOMBRE.
 * En la parrilla el corazón va sobre la foto y compite con el nombre del sitio,
 * así que ahí manda el icono solo. En la ficha hay sitio y guardar es una de
 * las tres cosas que se pueden hacer, así que se etiqueta: un corazón suelto
 * junto a un titular no dice si guarda, si le gusta o si puntúa.
 *
 * LA ETIQUETA LA PONE GEODIRECTORY, NO NOSOTROS.
 * Su JS intercambia el texto entre «Favorite» y «Unfavorite» a la vez que las
 * clases (geodirectory.js:1101-1118). Escribiendo el nuestro tendríamos dos
 * fuentes para el mismo estado y una se quedaría atrás; se deja la suya y sólo
 * se viste. De paso la traduce GTranslate como el resto de la página.
 *
 * Por qué se ve el texto y GD creía haberlo ocultado: se lo marca con
 * `.visually-hidden`, que es de Bootstrap y sólo existe dentro de `.bsui`. La
 * cabecera de la ficha no está ahí dentro, así que el texto salía visible pero
 * sin estilo, pegado al corazón.
 */
:where(.vl-redesign) .vl-single__fav { flex: 0 0 auto; }

/* `.h5` de Bootstrap la añade GD al contenedor y trae tamaño y margen propios:
   sin neutralizarla el botón sale descolocado. */
:where(.vl-redesign) .vl-single__fav .gd-fav-info-wrap,
:where(.vl-redesign) .vl-single__fav .gd-list-favorite,
:where(.vl-redesign) .vl-single__fav .geodir-addtofav {
  display: block;
  margin: 0 !important;
  padding: 0 !important;
  font-size: inherit !important;
  line-height: 1 !important;
}

/*
 * Se apunta a `.geodir-act-fav`, que es la clase que sobrevive al cambio de
 * estado. `geodir-addtofav-icon` se convierte en `geodir-removetofav-icon` al
 * pulsar, y estilar sólo la primera hace que el botón se desvista en cuanto
 * funciona. Ya pasó con la tarjeta.
 */
:where(.vl-redesign) .vl-single__fav .geodir-act-fav {
  display: inline-flex !important;
  align-items: center;
  gap: var(--vl-space-2);
  min-height: var(--vl-tap-min);
  margin: 0 !important;
  padding: var(--vl-space-2) var(--vl-space-4) !important;
  border: 1.5px solid var(--vl-border);
  border-radius: var(--vl-radius-pill);
  background: var(--vl-white);
  font-family: var(--vl-font-ui);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  line-height: 1.2 !important;
  color: var(--vl-text-body);
  cursor: pointer;
  transition: border-color var(--vl-duration) var(--vl-ease),
              background var(--vl-duration) var(--vl-ease);
}

:where(.vl-redesign) .vl-single__fav .geodir-act-fav:hover {
  border-color: var(--vl-fav);
  background: color-mix(in srgb, var(--vl-fav) 6%, var(--vl-white));
}

/* Aquí SÍ se enseña el texto, al revés que en la tarjeta. */
:where(.vl-redesign) .vl-single__fav .geodir-fav-text {
  display: inline;
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
}

/* `!important` obligado: GD le escribe un `style="color:grey"` inline al
   corazón, y un estilo inline gana a cualquier selector sin él. */
:where(.vl-redesign) .vl-single__fav .geodir-act-fav i {
  color: var(--vl-ink-500) !important;
  font-size: 1rem;
}

/*
 * GUARDADO. El corazón se llena de color y la píldora se tiñe, pero la ETIQUETA
 * se queda en tinta oscura: `--vl-fav` da 4.16:1 sobre blanco, que vale para un
 * icono (mínimo 3:1) pero no para texto (mínimo 4.5:1). El estado lo dice el
 * corazón, que es donde el color sí puede vivir.
 */
:where(.vl-redesign) .vl-single__fav .geodir-removetofav-icon {
  border-color: color-mix(in srgb, var(--vl-fav) 45%, transparent);
  background: color-mix(in srgb, var(--vl-fav) 10%, var(--vl-white));
  color: var(--vl-ink-800);
}

:where(.vl-redesign) .vl-single__fav .geodir-act-fav:hover i,
:where(.vl-redesign) .vl-single__fav .geodir-removetofav-icon i {
  color: var(--vl-fav) !important;
}

/* Foco visible: es un <span> con onclick, así que el navegador no le pone
   ninguno por su cuenta. El JS le da tabindex; el aro lo ponemos aquí. */
:where(.vl-redesign) .vl-single__fav .geodir-act-fav:focus-visible {
  outline: 2px solid var(--vl-focus);
  outline-offset: 2px;
}

/* ── Galería ──────────────────────────────────────────────────────────────── */
/*
 * Carrusel de scroll nativo. `scroll-snap` hace el encaje y el desbordamiento
 * hace el resto: cero JavaScript para que funcione, y el JS sólo mueve los
 * puntos.
 */
:where(.vl-redesign) .vl-gallery__track {
  display: flex;
  height: 100%;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

:where(.vl-redesign) .vl-gallery__track::-webkit-scrollbar { display: none; }

:where(.vl-redesign) .vl-gallery__img {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  object-fit: cover;
  scroll-snap-align: center;
}

/* En la ficha la galería va a sangre en móvil y con aire en escritorio. */
:where(.vl-redesign) .vl-single .vl-gallery {
  margin-block-end: var(--vl-space-2);
}

/*
 * LA GALERÍA SE ALINEA CON LA REJILLA DE ABAJO, no con la medida de lectura.
 *
 * Tenía un `max-width: 60rem` propio de cuando la ficha era una sola columna
 * estrecha. Al pasar a dos columnas, la rejilla creció a 1200px y la foto se
 * quedó en 960 centrados: medido a 1440px, la galería empezaba en x=240 y la
 * rejilla en x=120, así que ni el borde izquierdo cuadraba con el texto ni el
 * derecho con la tarjeta de localización. Una foto que no cuadra con nada
 * parece un fallo de maquetación aunque esté centrada.
 *
 * Se le da el ANCHO INTERIOR del contenedor —su tope menos los dos márgenes—,
 * y no `padding`, porque la galería recorta con `overflow: hidden` y un relleno
 * por dentro dejaría una banda de fondo entre la foto y su esquina redondeada.
 */
@media (min-width: 768px) {
  :where(.vl-redesign) .vl-single .vl-gallery {
    max-width: calc(var(--vl-container) - 2 * var(--vl-gutter));
    margin-inline: auto;
    margin-block-start: var(--vl-space-6);
  }
}

/* ── Titular de IA ────────────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-headline__token {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: var(--vl-white);
  box-shadow: 0 0 0 2px var(--vl-teal-300);
  font-size: 1rem;
}

/* La procedencia se dice, no se esconde: es contenido generado a partir de
   reseñas y hacerlo pasar por editorial sería mentir por omisión. */
:where(.vl-redesign) .vl-headline__note {
  margin-block-start: var(--vl-space-1);
  font-size: var(--vl-text-xs);
  color: var(--vl-teal-800);            /* 9.10:1 sobre el tinte teal */
}

/* ── Medallones y cuerpo ──────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-medallion__text {
  font-size: var(--vl-text-sm);
  line-height: var(--vl-leading-snug);
  color: var(--vl-text-body);
}

:where(.vl-redesign) .vl-single__body {
  margin-block: var(--vl-space-6);
  font-size: var(--vl-text-base);
  line-height: var(--vl-leading-relaxed);
  color: var(--vl-text-body);
}

:where(.vl-redesign) .vl-single__body > * + * { margin-block-start: var(--vl-space-4); }

/* ── Dónde está ───────────────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-where {
  display: grid;
  gap: var(--vl-space-5);
  grid-template-columns: 1fr;
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-where { grid-template-columns: 1fr 1fr; align-items: start; }
}

:where(.vl-redesign) .vl-fact {
  display: flex;
  align-items: flex-start;
  gap: var(--vl-space-3);
  padding-block: var(--vl-space-2);
  font-size: var(--vl-text-sm);
  color: var(--vl-text-body);
}

:where(.vl-redesign) .vl-fact__icon {
  flex: 0 0 1.25rem;
  margin-block-start: 0.15em;
  color: var(--vl-teal-600);            /* 4.81:1 */
  text-align: center;
}

.vl-redesign .vl-fact a { color: var(--vl-action); text-decoration: none; }
.vl-redesign .vl-fact a:hover { text-decoration: underline; }

:where(.vl-redesign) .vl-fact--socials { gap: var(--vl-space-2); flex-wrap: wrap; }

/* El mapa necesita alto explícito: sin él, el contenedor de GeoDirectory
   colapsa a cero y el mapa no llega a dibujarse. */
:where(.vl-redesign) .vl-where__map {
  min-height: 15rem;
  border-radius: var(--vl-radius-lg);
  overflow: hidden;
  background: var(--vl-ink-100);
}

:where(.vl-redesign) .vl-where__map .geodir-map-wrap,
:where(.vl-redesign) .vl-where__map .geodir-wgt-map,
:where(.vl-redesign) .vl-where__map .geodir_map_container,
:where(.vl-redesign) .vl-where__map .geodir-map-canvas {
  height: 100% !important;
  min-height: 15rem;
}

/* ── Horario ──────────────────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-hours { padding-block: var(--vl-space-2); }

:where(.vl-redesign) .vl-hours__summary {
  display: flex;
  align-items: center;
  gap: var(--vl-space-3);
  cursor: pointer;
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text-body);
  list-style: none;
}

:where(.vl-redesign) .vl-hours__summary::-webkit-details-marker { display: none; }

:where(.vl-redesign) .vl-hours__summary::after {
  content: '\f078';                      /* chevron-down */
  font-family: 'Font Awesome 7 Free', 'Font Awesome 6 Free', 'Font Awesome 5 Free';
  font-weight: 900;
  font-size: 0.7em;
  color: var(--vl-ink-500);
}

:where(.vl-redesign) .vl-hours[open] .vl-hours__summary::after { content: '\f077'; }

:where(.vl-redesign) .vl-hours__table {
  width: 100%;
  margin-block-start: var(--vl-space-3);
  border-collapse: collapse;
  font-size: var(--vl-text-sm);
}

:where(.vl-redesign) .vl-hours__table th,
:where(.vl-redesign) .vl-hours__table td {
  padding-block: var(--vl-space-2);
  text-align: start;
  font-weight: var(--vl-fw-regular);
  color: var(--vl-text-body);
  border-block-end: 1px solid var(--vl-border);
}

:where(.vl-redesign) .vl-hours__table td { text-align: end; }

:where(.vl-redesign) .vl-hours__today th,
:where(.vl-redesign) .vl-hours__today td {
  font-weight: var(--vl-fw-bold);
  color: var(--vl-text);
}

/* ── Aviso ────────────────────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-notice {
  display: flex;
  align-items: center;
  gap: var(--vl-space-3);
  margin-block-start: var(--vl-space-6);
  padding: var(--vl-space-3) var(--vl-space-4);
  border-radius: var(--vl-radius-md);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
}

:where(.vl-redesign) .vl-notice--expired {
  background: color-mix(in srgb, var(--vl-closed) 10%, var(--vl-white));
  border: 1px solid color-mix(in srgb, var(--vl-closed) 35%, transparent);
  color: var(--vl-closed);              /* 5.45:1 sobre blanco */
}

/* ── Reseñas ──────────────────────────────────────────────────────────────── */
/*
 * El bloque lo pinta GeoDirectory con su propia plantilla, envuelto en `.bsui`
 * (Bootstrap 5 prefijado). No se reescribe: se le quita el hueco de más y se
 * deja que el plugin siga siendo dueño del formulario y de las estrellas, que
 * es lo que mantiene funcionando el AJAX de enviar reseña.
 */
:where(.vl-redesign) .vl-single__reviews .comments-area { margin: 0; }
:where(.vl-redesign) .vl-single__reviews .bsui { font-size: var(--vl-text-sm); }

/* ══ 31. PUERTAS DE ENTRADA ════════════════════════════════════════════════ */
/*
 * Login, registro y contraseñas. Pantalla partida en escritorio: a la izquierda
 * por qué merece la pena tener cuenta, a la derecha el formulario. En móvil se
 * cae el panel y queda sólo el formulario, que es lo único que se ha venido a
 * hacer.
 *
 * SIN CABECERA NI PIE A PROPÓSITO. Es un embudo: cada enlace de menú que se
 * ponga aquí es una salida antes de terminar. Se deja UNA, «Volver al
 * directorio», que es la que evita que quien no quiera registrarse se sienta
 * atrapado.
 */

:where(.vl-redesign) .vl-auth {
  display: grid;
  grid-template-columns: 1fr;
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--vl-bg);
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-auth { grid-template-columns: 1fr 1fr; }
}

/* ── Panel de marca ───────────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-auth__brand {
  display: none;
  position: relative;
  padding: var(--vl-space-12) var(--vl-space-10);
  color: var(--vl-white);
  background: linear-gradient(155deg,
    var(--vl-teal-900) 0%,
    var(--vl-teal-700) 58%,
    var(--vl-teal-800) 100%);
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-auth__brand {
    display: grid;
    align-content: center;
  }
}

:where(.vl-redesign) .vl-auth__brandinner {
  max-width: 26rem;
  margin-inline: auto;
}

:where(.vl-redesign) .vl-auth__logo { display: block; margin-block-end: var(--vl-space-8); }
:where(.vl-redesign) .vl-auth__logo img { max-height: 44px; width: auto; }

:where(.vl-redesign) .vl-auth__pitch {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-2xl);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-snug);
  letter-spacing: var(--vl-tracking-tight);
  color: var(--vl-white);
  text-wrap: balance;
}

:where(.vl-redesign) .vl-auth__points {
  margin-block-start: var(--vl-space-8);
  display: grid;
  gap: var(--vl-space-4);
  list-style: none;
  padding: 0;
}

:where(.vl-redesign) .vl-auth__points li {
  display: flex;
  align-items: flex-start;
  gap: var(--vl-space-3);
  font-size: var(--vl-text-sm);
  line-height: var(--vl-leading-normal);
  /* Sobre el degradado teal, el blanco al 88 % sigue muy por encima de 4.5:1. */
  color: color-mix(in srgb, var(--vl-white) 88%, transparent);
}

:where(.vl-redesign) .vl-auth__points i {
  flex: 0 0 1.25rem;
  margin-block-start: 0.15em;
  color: var(--vl-teal-300);
  text-align: center;
}

/* ── Panel del formulario ─────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-auth__panel {
  display: grid;
  align-content: center;
  padding: var(--vl-space-8) var(--vl-gutter) var(--vl-space-12);
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-auth__panel { padding-inline: var(--vl-space-10); }
}

:where(.vl-redesign) .vl-auth__card {
  width: 100%;
  max-width: 26rem;
  margin-inline: auto;
}

:where(.vl-redesign) .vl-auth__back {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  margin-block-end: var(--vl-space-8);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
}

/* Especificidad real: si no, el color del enlace lo decide style.css. */
.vl-redesign .vl-auth__back { color: var(--vl-text-muted); text-decoration: none; }
.vl-redesign .vl-auth__back:hover { color: var(--vl-action); }

:where(.vl-redesign) .vl-auth__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-3xl);
  font-weight: var(--vl-fw-black);
  line-height: var(--vl-leading-tight);
  letter-spacing: var(--vl-tracking-tight);
  color: var(--vl-text);
  text-wrap: balance;
}

:where(.vl-redesign) .vl-auth__sub {
  margin-block: var(--vl-space-2) var(--vl-space-6);
  font-size: var(--vl-text-base);
  line-height: var(--vl-leading-normal);
  color: var(--vl-text-muted);
}

/* ── El formulario de UsersWP dentro de nuestra tarjeta ───────────────────── */
/*
 * No se reescribe: se le quita la tarjeta de Bootstrap que trae y se le dan
 * nuestros campos y nuestro botón. Todo va acotado a `.vl-auth__form` para no
 * tocar los formularios de UsersWP de ninguna otra pantalla.
 */

:where(.vl-redesign) .vl-auth__form .card,
:where(.vl-redesign) .vl-auth__form .card-body {
  border: 0;
  padding: 0;
  background: none;
  box-shadow: none;
}

:where(.vl-redesign) .vl-auth__form .row { margin: 0; }

:where(.vl-redesign) .vl-auth__form label {
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text-body);
  margin-block-end: var(--vl-space-1);
}

.vl-redesign .vl-auth__form .form-control,
.vl-redesign .vl-auth__form input[type='text'],
.vl-redesign .vl-auth__form input[type='email'],
.vl-redesign .vl-auth__form input[type='password'] {
  width: 100%;
  min-height: var(--vl-tap-min);
  padding: var(--vl-space-3) var(--vl-space-4);
  border: 1.5px solid var(--vl-border-strong);   /* 4.65:1, campo de formulario */
  border-radius: var(--vl-radius-md);
  background: var(--vl-white);
  font-family: var(--vl-font-ui);
  font-size: var(--vl-text-base);
  color: var(--vl-text);
  box-shadow: none;
}

.vl-redesign .vl-auth__form .form-control:focus,
.vl-redesign .vl-auth__form input:focus {
  border-color: var(--vl-action);
  outline: 2px solid var(--vl-focus);
  outline-offset: 1px;
}

/*
 * CAMPO DE CONTRASEÑA CON SU OJO.
 *
 * UsersWP lo emite como un `.input-group` de Bootstrap: el campo y, pegado, un
 * `.input-group-text` con el icono de mostrar/ocultar. Nuestro `width: 100%`
 * sobre `.form-control` rompía ese reparto y el ojo se caía a la línea de
 * abajo como una cajita suelta.
 *
 * En un input-group el campo va `flex: 1 1 auto` con `width: 1%` —el truco de
 * Bootstrap para que el ancho lo reparta el flex y no el contenido— y los dos
 * extremos comparten borde para que se lean como una sola pieza.
 */
:where(.vl-redesign) .vl-auth__form .input-group {
  display: flex;
  align-items: stretch;
}

.vl-redesign .vl-auth__form .input-group .form-control {
  flex: 1 1 auto;
  width: 1%;
  border-start-end-radius: 0;
  border-end-end-radius: 0;
  border-inline-end: 0;
}

.vl-redesign .vl-auth__form .input-group-text {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding-inline: var(--vl-space-4);
  border: 1.5px solid var(--vl-border-strong);
  border-inline-start: 0;
  border-start-start-radius: 0;
  border-end-start-radius: 0;
  border-start-end-radius: var(--vl-radius-md);
  border-end-end-radius: var(--vl-radius-md);
  background: var(--vl-white);
  color: var(--vl-text-muted);
  cursor: pointer;
}

.vl-redesign .vl-auth__form .input-group:focus-within .form-control,
.vl-redesign .vl-auth__form .input-group:focus-within .input-group-text {
  border-color: var(--vl-action);
}

/* El botón de enviar es de Bootstrap; se le pone la piel del sistema. */
.vl-redesign .vl-auth__form .btn-primary,
.vl-redesign .vl-auth__form input[type='submit'],
.vl-redesign .vl-auth__form button[type='submit'] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: var(--vl-tap-min);
  margin-block-start: var(--vl-space-2);
  padding: var(--vl-space-3) var(--vl-space-5);
  border: 0;
  border-radius: var(--vl-radius-pill);
  background: var(--vl-action);
  font-family: var(--vl-font-ui);
  font-size: var(--vl-text-base);
  font-weight: var(--vl-fw-semibold);
  /*
   * Sin mayúsculas. El botón salía «ACCESO» porque UsersWP le pega la clase
   * `text-uppercase` de Bootstrap, que es una utilidad y lleva `!important` de
   * serie. Por eso aquí hace falta otro: es la única forma de ganarle, y en el
   * resto del rediseño los botones van en caja normal.
   */
  text-transform: none !important;
  letter-spacing: normal;
  color: var(--vl-text-on-dark);
  cursor: pointer;
}

.vl-redesign .vl-auth__form .btn-primary:hover,
.vl-redesign .vl-auth__form input[type='submit']:hover,
.vl-redesign .vl-auth__form button[type='submit']:hover {
  background: var(--vl-action-hover);
  color: var(--vl-text-on-dark);
}

/* Enlaces de pie del formulario: «¿No tienes cuenta?», «Olvidé la contraseña». */
:where(.vl-redesign) .vl-auth__form .uwp-footer-links {
  margin-block-start: var(--vl-space-6);
  padding-block-start: var(--vl-space-5);
  border-block-start: 1px solid var(--vl-border);
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
  text-align: center;
}

.vl-redesign .vl-auth__form .uwp-footer-links a {
  color: var(--vl-action);
  font-weight: var(--vl-fw-semibold);
  text-decoration: none;
}

.vl-redesign .vl-auth__form .uwp-footer-links a:hover { text-decoration: underline; }

/* Avisos de error y de éxito: los emite UsersWP con clases de Bootstrap. */
:where(.vl-redesign) .vl-auth__form .alert {
  margin-block-end: var(--vl-space-5);
  padding: var(--vl-space-3) var(--vl-space-4);
  border-radius: var(--vl-radius-md);
  font-size: var(--vl-text-sm);
}

:where(.vl-redesign) .vl-auth__form .alert-danger,
:where(.vl-redesign) .vl-auth__form .alert-error {
  background: color-mix(in srgb, var(--vl-closed) 10%, var(--vl-white));
  border: 1px solid color-mix(in srgb, var(--vl-closed) 35%, transparent);
  color: var(--vl-closed);
}

:where(.vl-redesign) .vl-auth__form .alert-success {
  background: color-mix(in srgb, var(--vl-open) 10%, var(--vl-white));
  border: 1px solid color-mix(in srgb, var(--vl-open) 35%, transparent);
  color: var(--vl-open);
}

/* ══ 32. ÁREA PRIVADA ══════════════════════════════════════════════════════ */
/*
 * Panel y cuenta. Aquí el rediseño pone SÓLO el continente: la rejilla de dos
 * columnas y el aire. El nav lateral (`.vl-nav`) y las tarjetas del panel ya
 * tienen sus estilos en style.css y en el CSS de AyeCode UI, y se dejan en paz:
 * son piezas con lógica detrás —conteos, AJAX de aprobación, permisos por
 * plan— y repintarlas desde cero es cambiar algo probado por algo nuevo.
 */

:where(.vl-redesign) .vl-dash {
  padding-block: var(--vl-space-6) var(--vl-space-16);
  background: var(--vl-bg-sunken);
  min-height: 60vh;
}

/*
 * ANCHO COMPLETO, NO LA MEDIDA DE LECTURA.
 *
 * El panel no es un texto: son tablas de fichas, de reseñas y de pedidos, con
 * columnas de fecha, estado y acciones. Encajonarlas en los 1200 px del
 * contenedor general obliga a que cada tabla haga su propio scroll horizontal
 * mientras sobran doscientos píxeles de margen a cada lado. Aquí se aprovecha
 * la pantalla y el aire lo da el padding.
 */
:where(.vl-redesign) .vl-dash .vl-container {
  max-width: none;
  padding-inline: var(--vl-gutter);
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-dash .vl-container { padding-inline: var(--vl-space-8); }
}

/* Las tablas del panel las emite AyeCode; si una se pasa de ancho, que haga
   scroll ella y no la página entera. */
:where(.vl-redesign) .vl-dash__content .table-responsive,
:where(.vl-redesign) .vl-dash__content table {
  max-width: 100%;
}

:where(.vl-redesign) .vl-dash__content > .table-responsive { overflow-x: auto; }

:where(.vl-redesign) .vl-dash__grid {
  display: grid;
  gap: var(--vl-space-6);
  grid-template-columns: 1fr;
  align-items: start;
}

/* El nav a un lado a partir de tablet apaisada; por debajo va arriba, que es
   donde el drawer de style.css lo espera. */
@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-dash__grid {
    grid-template-columns: 17rem 1fr;
    gap: var(--vl-space-8);
  }
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-dash__side {
    position: sticky;
    inset-block-start: calc(var(--vl-header-h) + var(--vl-space-4));
  }
}

:where(.vl-redesign) .vl-dash__head { margin-block-end: var(--vl-space-5); }

:where(.vl-redesign) .vl-dash__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-2xl);
  font-weight: var(--vl-fw-black);
  letter-spacing: var(--vl-tracking-tight);
  color: var(--vl-text);
}

/* El contenido del panel va sobre una superficie propia: las tarjetas de
   AyeCode son blancas y sobre el fondo hundido se leen como bloques. */
:where(.vl-redesign) .vl-dash__content {
  background: var(--vl-bg-raised);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-lg);
  padding: var(--vl-space-5);
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-dash__content { padding: var(--vl-space-6); }
}

/* Las tarjetas de dentro ya traen su propio borde: dos marcos anidados con el
   mismo gris se leen como un error de maquetación. */
:where(.vl-redesign) .vl-dash__content > .row > [class*='col-'] > .card {
  border-color: var(--vl-border);
  border-radius: var(--vl-radius-md);
}

/* Aviso informativo del panel (por qué te hemos traído aquí). */
:where(.vl-redesign) .vl-notice--info {
  margin-block-end: var(--vl-space-5);
  background: var(--vl-bg-tint);
  border: 1px solid var(--vl-teal-200);
  color: var(--vl-teal-800);            /* 9.10:1 sobre el tinte teal */
  font-weight: var(--vl-fw-medium);
}

/* ══ 33. ALTA Y EDICIÓN DE FICHAS ══════════════════════════════════════════
 *
 * `/add-listing/`, en sus tres formas: crear, editar y la entrada sin
 * parámetros. Aquí NO se estiliza el formulario: es AyeCode UI y ya viene
 * resuelto. Lo que se pone es el marco —ancho de lectura, titular y superficie—
 * que hasta ahora ponía Elementor.
 *
 * ANCHO DE LECTURA Y NO A TODA PANTALLA: un formulario largo con los campos
 * estirados a 1400px obliga a barrer la vista de un lado a otro en cada línea.
 * El área privada sí va a todo el ancho, porque son tablas; esto son campos.
 * ------------------------------------------------------------------------- */

:where(.vl-redesign) .vl-form {
  padding-block: var(--vl-space-8) var(--vl-space-12);
  background: var(--vl-bg-sunken);
}

:where(.vl-redesign) .vl-form .vl-container {
  max-width: 56rem;
}

:where(.vl-redesign) .vl-form__head {
  margin-block-end: var(--vl-space-6);
}

:where(.vl-redesign) .vl-form__back {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  margin-block-end: var(--vl-space-5);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
}

/* Especificidad real, no `:where()`: el enlace hereda el color de `a` del tema
   y con cero especificidad no lo gana. Mismo motivo que en las puertas de
   entrada. */
.vl-redesign .vl-form__back { color: var(--vl-text-muted); text-decoration: none; }
.vl-redesign .vl-form__back:hover { color: var(--vl-action); }

:where(.vl-redesign) .vl-form__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-3xl);
  font-weight: var(--vl-fw-black);
  line-height: var(--vl-leading-tight);
  letter-spacing: var(--vl-tracking-tight);
  color: var(--vl-text);
  text-wrap: balance;
}

:where(.vl-redesign) .vl-form__sub {
  margin-block-start: var(--vl-space-2);
  font-size: var(--vl-text-base);
  line-height: var(--vl-leading-normal);
  color: var(--vl-text-muted);
}

/* La superficie no lleva relleno: lo lleva lo que hay dentro.
   GeoDirectory envuelve TODO el formulario en `.geodir-add-listing`, y sus
   filas son `.row` de Bootstrap, que tienen margen horizontal NEGATIVO. Con el
   relleno en el contenedor de fuera, esos −12px se lo comen por los lados y los
   campos quedan pegados al borde. Puesto en el envoltorio de GD, el margen
   negativo se resta de un relleno que está en el mismo elemento y ya no
   descuadra. */
:where(.vl-redesign) .vl-form__body {
  background: var(--vl-bg-raised);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-lg);
  padding: 0;
  overflow: hidden;            /* que el relleno de dentro respete el radio */
}

:where(.vl-redesign) .geodir-add-listing,
:where(.vl-redesign) .vl-form__body > :not(.geodir-add-listing) {
  padding: var(--vl-space-5);
}

@media (min-width: 768px) {
  :where(.vl-redesign) .geodir-add-listing,
  :where(.vl-redesign) .vl-form__body > :not(.geodir-add-listing) {
    padding: var(--vl-space-8);
  }
}

/* La tarjeta de Bootstrap que trae el formulario sobra: la nuestra ya es la
   tarjeta, y dos marcos anidados con el mismo gris se leen como un fallo. */
:where(.vl-redesign) .vl-form__body > .card,
:where(.vl-redesign) .vl-form__body > form > .card {
  border: 0;
  box-shadow: none;
  background: transparent;
}

/* Aviso de plan (cuota agotada, eventos sin Featured, edición en Free). Lo
   emite GeoDirectory como alerta de Bootstrap; se le da nuestro tono en vez de
   dejar el amarillo del framework en medio de la página. */
:where(.vl-redesign) .vl-form__body .alert-warning,
:where(.vl-redesign) .vl-form__body .alert-info {
  background: var(--vl-bg-tint);
  border-color: var(--vl-teal-200);
  color: var(--vl-teal-800);            /* 9.10:1 sobre el tinte teal */
  border-radius: var(--vl-radius-md);
}

/* ══ 34. PÁGINA DE CONTENIDO ═══════════════════════════════════════════════
 *
 * Legal, privacidad, cookies, condiciones y cualquier página normal. Lo único
 * que hay que resolver aquí es LEER TEXTO LARGO, que es un problema distinto al
 * del resto del sitio: no hay tarjetas ni rejillas, hay párrafos.
 * ------------------------------------------------------------------------- */

:where(.vl-redesign) .vl-page {
  padding-block: var(--vl-space-10) var(--vl-space-16);
}

:where(.vl-redesign) .vl-page__head {
  margin-block-end: var(--vl-space-8);
  padding-block-end: var(--vl-space-6);
  border-block-end: 1px solid var(--vl-border);
}

:where(.vl-redesign) .vl-page__title {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-4xl);
  font-weight: var(--vl-fw-black);
  line-height: var(--vl-leading-tight);
  letter-spacing: var(--vl-tracking-tight);
  color: var(--vl-text);
  text-wrap: balance;
}

:where(.vl-redesign) .vl-page__meta {
  margin-block-start: var(--vl-space-3);
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
}

/* ── Texto largo ──────────────────────────────────────────────────────────
 *
 * La medida la pone `.vl-container--reading`; aquí va el ritmo vertical. El
 * espacio entre bloques se hace con `margin-block-start` sobre el hermano y no
 * con `margin-block-end` en todos: así el primer elemento no empuja el bloque
 * hacia abajo y no hay que corregirlo con `:first-child`.
 * ----------------------------------------------------------------------- */

:where(.vl-redesign) .vl-prose {
  font-size: var(--vl-text-base);
  line-height: var(--vl-leading-relaxed);
  color: var(--vl-text);
}

:where(.vl-redesign) .vl-prose > * + * {
  margin-block-start: var(--vl-space-5);
}

:where(.vl-redesign) .vl-prose h2 {
  margin-block-start: var(--vl-space-10);
  font-size: var(--vl-text-2xl);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-snug);
  letter-spacing: var(--vl-tracking-tight);
  text-wrap: balance;
}

:where(.vl-redesign) .vl-prose h3 {
  margin-block-start: var(--vl-space-8);
  font-size: var(--vl-text-lg);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-snug);
}

:where(.vl-redesign) .vl-prose ul,
:where(.vl-redesign) .vl-prose ol {
  padding-inline-start: var(--vl-space-6);
}

:where(.vl-redesign) .vl-prose li + li {
  margin-block-start: var(--vl-space-2);
}

/* Especificidad real: los enlaces dentro del texto heredan el color de `a` del
   tema, y con `:where()` no lo ganan. Subrayados a propósito — en un párrafo,
   sólo el color no basta para distinguir un enlace. */
.vl-redesign .vl-prose a {
  color: var(--vl-action);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.vl-redesign .vl-prose a:hover { text-decoration-thickness: 2px; }

:where(.vl-redesign) .vl-prose strong { font-weight: var(--vl-fw-bold); }

:where(.vl-redesign) .vl-prose blockquote {
  padding-inline-start: var(--vl-space-5);
  border-inline-start: 3px solid var(--vl-teal-200);
  color: var(--vl-text-muted);
}

:where(.vl-redesign) .vl-prose img {
  max-width: 100%;
  height: auto;
  border-radius: var(--vl-radius-md);
}

/* Las tablas de un texto legal no caben en móvil: se dejan desplazar solas en
   vez de romper el ancho de la página. */
:where(.vl-redesign) .vl-prose table {
  display: block;
  overflow-x: auto;
  width: 100%;
  border-collapse: collapse;
}

:where(.vl-redesign) .vl-prose th,
:where(.vl-redesign) .vl-prose td {
  padding: var(--vl-space-2) var(--vl-space-3);
  border: 1px solid var(--vl-border);
  text-align: start;
}

/* ══ 35. PERFIL, BLOG Y ENTRADA ════════════════════════════════════════════ */

/* El perfil de UsersWP trae sus propias pestañas y su propia rejilla: aquí sólo
   se le da la superficie y el aire. */
:where(.vl-redesign) .vl-profile {
  padding-block: var(--vl-space-8) var(--vl-space-16);
  background: var(--vl-bg-sunken);
}

:where(.vl-redesign) .vl-profile__body {
  background: var(--vl-bg-raised);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-lg);
  padding: var(--vl-space-5);
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-profile__body { padding: var(--vl-space-8); }
}

/* ── Listado del blog ────────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-blog,
:where(.vl-redesign) .vl-post {
  padding-block: var(--vl-space-10) var(--vl-space-16);
}

:where(.vl-redesign) .vl-postlist {
  display: grid;
  gap: var(--vl-space-8);
}

/* Una entrada es una fila, no una tarjeta: con un puñado de artículos, una
   rejilla de tarjetas deja más hueco que contenido. La miniatura va al lado en
   escritorio y arriba en móvil. */
:where(.vl-redesign) .vl-postcard {
  display: grid;
  gap: var(--vl-space-4);
  padding-block-end: var(--vl-space-8);
  border-block-end: 1px solid var(--vl-border);
}

:where(.vl-redesign) .vl-postcard:last-child {
  padding-block-end: 0;
  border-block-end: 0;
}

@media (min-width: 640px) {
  :where(.vl-redesign) .vl-postcard:has(.vl-postcard__media) {
    grid-template-columns: 12rem 1fr;
    gap: var(--vl-space-6);
  }
}

:where(.vl-redesign) .vl-postcard__media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--vl-radius-md);
}

:where(.vl-redesign) .vl-postcard__meta {
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
}

:where(.vl-redesign) .vl-postcard__title {
  margin-block-start: var(--vl-space-1);
  font-size: var(--vl-text-xl);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-snug);
  text-wrap: balance;
}

.vl-redesign .vl-postcard__link { color: var(--vl-text); text-decoration: none; }
.vl-redesign .vl-postcard__link:hover { color: var(--vl-action); }

:where(.vl-redesign) .vl-postcard__excerpt {
  margin-block-start: var(--vl-space-2);
  color: var(--vl-text-muted);
  line-height: var(--vl-leading-normal);
}

/* ── Entrada ─────────────────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-post__cover {
  margin-block-end: var(--vl-space-8);
}

:where(.vl-redesign) .vl-post__cover img {
  width: 100%;
  height: auto;
  border-radius: var(--vl-radius-lg);
}

:where(.vl-redesign) .vl-post__comments {
  margin-block-start: var(--vl-space-12);
  padding-block-start: var(--vl-space-8);
  border-block-start: 1px solid var(--vl-border);
}

/* ══ 36. TIENDA ════════════════════════════════════════════════════════════
 *
 * Sólo el marco. El interior —rejilla de productos, carrito, pago y cuenta— lo
 * pinta WooCommerce con sus bloques y sus plantillas, y ahí no se entra: es un
 * flujo de pago que funciona. Lo que hay aquí es el aire alrededor y cuatro
 * arreglos para que su tipografía no desentone con la del resto.
 * ------------------------------------------------------------------------- */

:where(.vl-redesign) .vl-shop {
  padding-block: var(--vl-space-8) var(--vl-space-16);
}

/* WooCommerce trae su propio h2 para «Detalles de facturación», «Tu pedido» y
   compañía, con el tamaño del plugin. Se les da el nuestro sin tocar su
   estructura. */
:where(.vl-redesign) .vl-shop__body h2 {
  font-size: var(--vl-text-2xl);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-snug);
  letter-spacing: var(--vl-tracking-tight);
}

:where(.vl-redesign) .vl-shop__body h3 {
  font-size: var(--vl-text-lg);
  font-weight: var(--vl-fw-bold);
  line-height: var(--vl-leading-snug);
}

/* Los avisos de WooCommerce (cupón aplicado, error de pago) usan el verde y el
   rojo del plugin. El de error se deja como está —un error tiene que gritar—;
   el informativo se pasa al tinte de la marca. */
:where(.vl-redesign) .vl-shop__body .woocommerce-info,
:where(.vl-redesign) .vl-shop__body .woocommerce-message {
  background: var(--vl-bg-tint);
  border-top-color: var(--vl-teal-600);
  color: var(--vl-teal-800);            /* 9.10:1 sobre el tinte teal */
}

/* La navegación de «mi cuenta» ya la sustituye el nav del tema
   (inc/woocommerce-myaccount-nav.php): si reapareciera, saldrían dos. */
:where(.vl-redesign) .vl-shop__body .woocommerce-MyAccount-navigation {
  display: none;
}

:where(.vl-redesign) .vl-shop__body .woocommerce-MyAccount-content {
  width: 100%;
  float: none;
}

/* ══ 37. 404 ═══════════════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-404__search {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vl-space-2);
  justify-content: center;
  width: 100%;
  max-width: 28rem;
  margin-block: var(--vl-space-6) var(--vl-space-4);
}

:where(.vl-redesign) .vl-404__input {
  flex: 1 1 14rem;
  min-width: 0;                /* sin esto un flex-item no baja de su contenido */
  padding: var(--vl-space-3) var(--vl-space-4);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-pill);
  background: var(--vl-bg-raised);
  color: var(--vl-text);
  font-size: var(--vl-text-base);
}

.vl-redesign .vl-404__home { color: var(--vl-text-muted); font-size: var(--vl-text-sm); }
.vl-redesign .vl-404__home:hover { color: var(--vl-action); }

/* ══ 38. RECLAMAR UNA FICHA ════════════════════════════════════════════════ */

/*
 * Dos sitios, un mismo flujo (inc/claim-listing.php):
 *   .vl-single__claim  — la tira del final de la ficha.
 *   .vl-claimsearch    — el buscador de la tarjeta del panel.
 *
 * OJO CON LA ESPECIFICIDAD EN EL PANEL
 * El buscador se pinta dentro de `.vl-dash__content.bsui`, o sea dentro del
 * reboot de AyeCode UI: `.bsui p` y `.bsui ul` puntúan (0,1,1) y le ganan a
 * `:where(.vl-redesign) .x`, que vale (0,1,0). Por eso TODO el bloque
 * .vl-claimsearch va con selector normal (0,2,0) y no con `:where()`: si no,
 * Bootstrap nos mete su margen inferior en cada párrafo y su sangrado en la
 * lista. Es el mismo motivo que el del color de los botones, sección 1.
 */

/* ── La tira de la ficha ─────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-single__claim {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--vl-space-3);
  margin-top: var(--vl-space-10);
  padding-top: var(--vl-space-6);
  border-top: 1px solid var(--vl-border);
}

:where(.vl-redesign) .vl-single__claim-text {
  margin: 0;
  font-size: var(--vl-text-sm);
}

.vl-redesign .vl-single__claim-text { color: var(--vl-text-muted); }

/* ── El buscador del panel ───────────────────────────────────────────────── */

.vl-redesign .vl-claimsearch {
  padding: var(--vl-space-4);
}

.vl-redesign .vl-claimsearch__intro,
.vl-redesign .vl-claimsearch__note {
  margin: 0;
  font-size: var(--vl-text-sm);
  line-height: 1.45;
  color: var(--vl-text-muted);
}

.vl-redesign .vl-claimsearch__note {
  margin-top: var(--vl-space-4);
  font-size: var(--vl-text-xs);
}

.vl-redesign .vl-claimsearch__input {
  width: 100%;
  margin-top: var(--vl-space-3);
  padding: var(--vl-space-3) var(--vl-space-4);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-md);
  background: var(--vl-bg-raised);
  color: var(--vl-text);
  font-family: var(--vl-font-ui);
  font-size: var(--vl-text-base);
}

.vl-redesign .vl-claimsearch__status {
  margin: var(--vl-space-3) 0 0;
  font-size: var(--vl-text-xs);
  color: var(--vl-text-muted);
}

.vl-redesign .vl-claimsearch__list {
  margin: var(--vl-space-3) 0 0;
  padding: 0;
  list-style: none;
}

.vl-redesign .vl-claimsearch__item {
  display: flex;
  align-items: center;
  gap: var(--vl-space-3);
  padding: var(--vl-space-3) 0;
  border-bottom: 1px solid var(--vl-border);
}

.vl-redesign .vl-claimsearch__item:last-child { border-bottom: 0; }

/* min-width:0 para que el título largo pueda recortarse en vez de empujar al botón */
.vl-redesign .vl-claimsearch__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.vl-redesign .vl-claimsearch__title {
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text);
}

.vl-redesign .vl-claimsearch__meta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--vl-text-xs);
  color: var(--vl-text-muted);
}

.vl-redesign .vl-claimsearch__pending {
  flex-shrink: 0;
  padding: 2px var(--vl-space-3);
  border-radius: var(--vl-radius-pill);
  background: var(--vl-bg-sunken);
  font-size: var(--vl-text-xs);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text-muted);
}

.vl-redesign .vl-claimsearch__item .vl-btn { flex-shrink: 0; }

/* ══ 38. FICHA v2 — ADAPTACIÓN AL MOCKUP ═══════════════════════════════════
 *
 * Barra de navegación, chips de categoría, verificado junto al nombre, dos
 * columnas en escritorio y «read more». El resto de la ficha no cambia.
 * ------------------------------------------------------------------------- */

/* ── Nota 1 del mockup: volver y saltar, DENTRO de la cabecera ────────────
 *
 * El primer intento fue una barra propia debajo de la cabecera, y el resultado
 * eran dos cabeceras apiladas comiéndose la mitad de la pantalla en móvil. Va
 * todo en la misma barra: en la ficha la navegación de secciones sobra —ya
 * estás dentro de un sitio— y eso deja el sitio justo para «Back» y las
 * flechas.
 * ----------------------------------------------------------------------- */

:where(.vl-redesign) .vl-topbar__back {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  flex-shrink: 0;
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
}

.vl-redesign .vl-topbar__back { color: var(--vl-text); text-decoration: none; }
.vl-redesign .vl-topbar__back:hover { color: var(--vl-action); }

/* Sobre una foto la cabecera va en blanco: el «Back» también. */
.vl-redesign .vl-topbar--over .vl-topbar__back { color: var(--vl-text-on-dark); }

:where(.vl-redesign) .vl-topbar__skip {
  display: inline-flex;
  gap: var(--vl-space-1);
  flex-shrink: 0;
}

:where(.vl-redesign) .vl-topbar__arrow {
  border: 1px solid var(--vl-border);
  border-radius: 999px;
}

/* Sin vecino se deja el hueco, no un botón muerto: la barra no se descoloca al
   llegar a la primera o la última ficha. */
:where(.vl-redesign) .vl-topbar__arrow--empty { border-color: transparent; }

@media (max-width: 767px) {
  /*
   * LA PALABRA «BACK» SE QUEDA TAMBIÉN EN MÓVIL.
   *
   * Estuvo oculta con el argumento de que la flecha sola se entiende y el logo
   * manda. Ya no se sostiene: en móvil la botonera de la derecha no se pinta
   * —la lleva la bottom-nav—, así que sitio sobra; y una flecha suelta en la
   * esquina se confunde con el «atrás» del navegador. La palabra dice a qué
   * vuelves.
   */

  /*
   * EN MÓVIL LA CABECERA NO REPITE LA BOTTOM-NAV.
   *
   * Buscar, favoritos y cuenta ya están abajo, fijos y al alcance del pulgar.
   * Tenerlos también arriba es el mismo destino dos veces en la misma pantalla,
   * y arriba es donde peor se llega. Así la cabecera se queda con el logo
   * centrado y sobra sitio: es lo que permite meter la navegación de la ficha
   * en la misma barra en vez de apilar una segunda.
   *
   * Se ocultan los TRES ENLACES, no el grupo entero: las flechas de anterior y
   * siguiente viven dentro de él y tienen que quedarse.
   *
   * Las pantallas de acceso no montan esta cabecera, así que no se quedan sin
   * navegación por esto.
   */
  /*
   * FUERA LA BOTONERA ENTERA. Buscar, favoritos y cuenta ya están en la
   * bottom-nav, fija y al alcance del pulgar; repetirlos arriba es el mismo
   * destino dos veces en la misma pantalla. Así la cabecera se queda con el
   * logo y nada más, que es lo que pide el cliente.
   */
  :where(.vl-redesign) .vl-topbar__actions { display: none; }

  /*
   * En la ficha SÍ se conserva el grupo, porque dentro viven las flechas de
   * anterior y siguiente. Lo que se ocultan son los tres enlaces, no el
   * contenedor: ésa es la holgura que permite meter la navegación de la ficha
   * en la misma barra en vez de apilar una segunda.
   */
  :where(.vl-redesign) .vl-topbar--single .vl-topbar__actions { display: inline-flex; }
  :where(.vl-redesign) .vl-topbar--single .vl-topbar__actions > a.vl-iconbtn { display: none; }
}

/* ── La insignia de oferta de la tarjeta ───────────────────────────────────
 *
 * Abajo a la izquierda de la foto, en la esquina que queda libre: arriba a la
 * izquierda van las de plan y arriba a la derecha el favorito. No compite con
 * ninguna y se lee sin tapar la imagen.
 *
 * Naranja y no teal: el teal es el color de las acciones del sitio y esto no se
 * pulsa, es un dato. `--vl-accent-strong` es el escalón que el sistema exige
 * para texto por debajo de 18px. */
/*
 * LA OFERTA, COMO BANNER DENTRO DE LA TARJETA.
 *
 * Era un distintivo flotando sobre la foto que sólo decía «Offer». El cliente
 * pidió el 03/09/2026 que dijera QUÉ es la oferta, y un texto de una frase no
 * cabe encima de una imagen sin taparla ni volverse ilegible. Así que baja al
 * cuerpo, ocupa el ancho y se lee como lo que es: la razón para entrar.
 *
 * A una línea con puntos suspensivos: son titulares de oferta escritos por el
 * negocio y alguno vendrá largo; dos líneas aquí desplazarían el estado y la
 * distancia fuera del golpe de vista.
 */
:where(.vl-redesign) .vl-placecard__offer {
  display: flex;
  align-items: center;
  gap: .45em;
  padding: .4rem .6rem;
  border-radius: var(--vl-radius-sm, .375rem);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  line-height: 1.3;
}

:where(.vl-redesign) .vl-placecard__offer > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vl-redesign .vl-placecard__offer {
  background: color-mix(in srgb, var(--vl-accent) 12%, var(--vl-white));
  color: var(--vl-accent-strong);
}

/* ── Verificado junto al nombre ──────────────────────────────────────────── */

:where(.vl-redesign) .vl-verified {
  display: inline-block;
  margin-inline-start: 0.3em;
  color: var(--vl-teal-600);
  font-size: 0.62em;              /* relativo al h1: acompaña, no compite */
  vertical-align: middle;
}

/* Texto sólo para lectores de pantalla. `.visually-hidden` de Bootstrap sólo
   funciona dentro de `.bsui`, y aquí no lo hay. */
:where(.vl-redesign) .vl-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

:where(.vl-redesign) .vl-single__sub {
  margin-block-start: var(--vl-space-1);
  font-size: var(--vl-text-base);
  color: var(--vl-text-muted);
}

/* ── Chips de categoría ──────────────────────────────────────────────────── */

:where(.vl-redesign) .vl-chiprow {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vl-space-2);
  margin-block-start: var(--vl-space-3);
}

:where(.vl-redesign) .vl-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.34em 0.8em;
  border: 1px solid var(--vl-border);
  border-radius: 999px;
  background: var(--vl-bg-raised);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-medium);
  line-height: 1.4;
  white-space: nowrap;
}

.vl-redesign .vl-chip { color: var(--vl-text); text-decoration: none; }
.vl-redesign a.vl-chip:hover { border-color: var(--vl-action); color: var(--vl-action); }

:where(.vl-redesign) .vl-chip__icon { font-size: 0.9em; }

:where(.vl-redesign) .vl-chip--rest {
  color: var(--vl-text-muted);
  border-style: dashed;
}

/* ── Herramientas de la cabecera (favorito + compartir) ──────────────────── */

:where(.vl-redesign) .vl-single__tools {
  display: inline-flex;
  align-items: center;
  gap: var(--vl-space-2);
  flex-shrink: 0;
}

/* ── Dirección en la fila de resumen ─────────────────────────────────────── */

:where(.vl-redesign) .vl-meta-addr {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  color: var(--vl-text-muted);
  font-size: var(--vl-text-sm);
}

:where(.vl-redesign) .vl-meta-addr i { color: var(--vl-teal-600); }

/* ── Read more ───────────────────────────────────────────────────────────── */

/* Retirado el 01/09/2026: la descripción de la ficha se muestra entera, así que
   se van el `-webkit-line-clamp` de `.vl-readmore__body` y el botón que lo
   desplegaba. El recorte de las TARJETAS del listado no se toca (`.vl-placecard__desc`,
   más arriba en este mismo fichero): ahí el corte a dos líneas es deliberado. */

/* ── Dos columnas en escritorio ──────────────────────────────────────────── */

/* Móvil primero: una columna, y «dónde está» al final, que es donde estaba.
   Es un dato de confirmación, no de descubrimiento. */
:where(.vl-redesign) .vl-single__grid {
  display: grid;
  gap: var(--vl-space-8);
}

@media (min-width: 1024px) {
  :where(.vl-redesign) .vl-single__grid {
    grid-template-columns: minmax(0, 1fr) 22rem;
    align-items: start;
    gap: var(--vl-space-10);
  }

  /* La medida de lectura la pone ahora la columna, no el contenedor: con el
     contenedor estrecho la columna derecha no cabría. */
  :where(.vl-redesign) .vl-single__col { max-width: 44rem; }

  /* Se queda a la vista mientras se lee el resto. El `top` deja sitio a la
     cabecera pegajosa. */
  :where(.vl-redesign) .vl-single__aside {
    position: sticky;
    top: var(--vl-space-20);
  }

  /* Dentro del aside el bloque ya no necesita su encabezado de sección a lo
     grande: es una tarjeta lateral, no un capítulo. */
  :where(.vl-redesign) .vl-single__aside .vl-sectionhead__title { font-size: var(--vl-text-lg); }

  /* Y el mapa y los datos se apilan, que a 22rem no caben en dos columnas. */
  :where(.vl-redesign) .vl-single__aside .vl-where { grid-template-columns: 1fr; }
}

/* ── El botón redondo de icono, cuando es un <button> de verdad ────────────
 *
 * `.vl-iconbtn` nació para enlaces (`<a>`), que no traen relleno propio. Al
 * usarlo en el botón de compartir apareció descentrado 4,6px a la derecha, y no
 * era el clásico nodo de texto en blanco: el botón heredaba `padding: 8px 16px`
 * de la hoja del tema, y con `box-sizing: border-box` y 44px de ancho eso deja
 * una caja de contenido de 12px para un icono de 21,25. Lo que no cabe se
 * desborda hacia la derecha, y `place-items: center` no puede centrar algo más
 * ancho que su propia pista.
 *
 * Especificidad real y no `:where()`: la regla que mete el relleno también la
 * tiene, así que con cero no se le gana.
 * ------------------------------------------------------------------------ */
.vl-redesign .vl-iconbtn {
  padding: 0;
  border: 0;
  background: none;
  -webkit-appearance: none;
  appearance: none;
  line-height: 1;
}

.vl-redesign button.vl-iconbtn { cursor: pointer; }

/* ── El globo de idioma, sólo en escritorio ────────────────────────────────
 *
 * Es el COMPLEMENTO EXACTO de la nav inferior: ésta se oculta a partir de
 * 1024px (regla de `.vl-bottomnav`, más arriba), y con ella se iba la pestaña
 * «Lang», que hasta ahora era el único sitio desde donde se podía cambiar de
 * idioma. Por debajo de ese ancho la pestaña está, así que un globo arriba
 * sería el mismo destino dos veces en la misma pantalla.
 *
 * Empieza oculto y se enciende, y no al revés: así el punto de corte vive en un
 * solo sitio y no puede desincronizarse del de la bottom-nav.
 *
 * Nota de por qué esta regla es necesaria y no basta con lo que ya hay: en la
 * ficha, la regla que despeja la cabecera oculta `> a.vl-iconbtn` —sólo los
 * ENLACES, para dejar las flechas de anterior/siguiente—. Este disparador es un
 * `<button>`, así que se libraría de ella y aparecería suelto junto a las
 * flechas en móvil. */
:where(.vl-redesign) .vl-iconbtn--lang { display: none; }

@media (min-width: 1024px) {
  /* `grid`, el mismo valor que la regla base de `.vl-iconbtn`: si aquí se
     pusiera `inline-grid` este botón sería el único distinto de la fila. */
  :where(.vl-redesign) .vl-iconbtn--lang { display: grid; }
}

/* Mismo caso que el «Read more»: el botón de compartir nace con `hidden` y el JS
   lo enseña sólo donde existe `navigator.share`. Sin esta regla salía también en
   escritorio, donde no hay API que llamar y nadie le engancha el clic: un botón
   que no hace nada. */
.vl-redesign .vl-iconbtn[hidden] { display: none; }

/* El logo, centrado entre «Back» y las flechas.
   `margin-inline: auto` en un contenedor flex reparte TODO el hueco libre a
   partes iguales a los dos lados del logo, así que queda centrado sea cual sea
   el ancho del texto de «Back» — que cambia entre «Back» y «All in Fuengirola».
   Con `justify-content` no se puede: centraría el grupo entero, no el logo. */
/*
 * TRES COLUMNAS: «Back» | logo | acciones. Es la única forma de que el logo
 * quede en el centro REAL de la barra y no a medio camino entre los dos grupos,
 * que es lo que daba `margin-inline: auto` — medido, se desviaba 37px en móvil
 * y 168px en escritorio, porque el lado derecho pesa más que la palabra «Back».
 *
 * Con `1fr auto 1fr` las dos columnas de los lados miden lo mismo pase lo que
 * pase, así que el logo cae en el centro aunque el texto de volver cambie entre
 * «Back» y «All in Fuengirola». Por eso las flechas van DENTRO del grupo de
 * acciones: con cuatro hijos sueltos no hay tres columnas que valgan.
 */
/*
 * UNA SOLA COMPOSICIÓN PARA TODAS LAS CABECERAS: logo centrado, lo que haya a
 * los lados en las columnas de fuera. Antes esto valía sólo para la ficha y el
 * resto del sitio llevaba el logo a la izquierda; el resultado era que el logo
 * saltaba de sitio al navegar.
 *
 * `1fr auto 1fr` mantiene las dos columnas de los lados iguales pase lo que
 * pase, así que el logo cae en el centro exacto tenga o no «Back» a la
 * izquierda, y tenga dos, tres o cinco iconos a la derecha.
 */
:where(.vl-redesign) .vl-topbar__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
}

/*
 * CADA UNO EN SU COLUMNA, DICHO EXPLÍCITAMENTE.
 *
 * Sin esto la rejilla los coloca por orden de aparición, y como «Back» sólo
 * existe en la ficha, en el resto del sitio el logo caía en la PRIMERA columna:
 * medido, 97px a la izquierda del centro en la portada, el listado y las
 * páginas de contenido, mientras que en la ficha salía perfecto. Justo el
 * síntoma de «en el single bien, en el resto mal».
 */
/*
 * Y LA FILA TAMBIÉN EXPLÍCITA, no sólo la columna.
 *
 * Al devolver el nav a la cabecera salió una segunda fila: logo arriba, nav y
 * acciones 20px por debajo (medido: `grid-template-rows: 54px 44px`). El motivo
 * es que el nav va DESPUÉS del logo en el HTML pero pide la columna 1, y el
 * cursor de autocolocación no retrocede: la columna 1 de la fila 1 ya la había
 * dejado atrás, así que abrió fila nueva.
 *
 * Se podría arreglar reordenando el HTML, pero entonces el orden del documento
 * —que es el que lee un lector de pantalla— quedaría atado a la maquetación.
 * Con la fila declarada, cada cual va donde se le dice venga donde venga.
 */
/*
 * VOLVER Y SECCIONES, JUNTOS EN LA CASILLA IZQUIERDA.
 *
 * Antes cada uno pedía la celda 1/1 por su cuenta y la plantilla pintaba uno u
 * otro para que no se superpusieran. Al poner «Back» en todas las vistas
 * (pedido del cliente el 03/09/2026) eso habría dejado el sitio sin navegación
 * de secciones en escritorio, así que ahora los envuelve `.vl-topbar__lead` y
 * es el contenedor el que ocupa la casilla. Las dos reglas de abajo se quedan
 * por si algún día vuelven a ser hijos directos: sobre un elemento que no es
 * ítem de rejilla, `grid-area` no hace nada.
 */
:where(.vl-redesign) .vl-topbar__lead {
  grid-area: 1 / 1;
  justify-self: start;
  display: flex;
  align-items: center;
  gap: var(--vl-space-4);
  min-width: 0;
}

:where(.vl-redesign) .vl-topbar__back    { grid-area: 1 / 1; justify-self: start; }
:where(.vl-redesign) .vl-topbar__nav     { grid-area: 1 / 1; justify-self: start; }
:where(.vl-redesign) .vl-topbar__logo    { grid-area: 1 / 2; justify-self: center; }
:where(.vl-redesign) .vl-topbar__actions { grid-area: 1 / 3; justify-self: end; }

/*
 * El nav vuelve a la cabecera (2026-08-24) y comparte casilla con el «Back»:
 * la plantilla pinta uno u otro, nunca los dos. Con la rejilla de columnas
 * fijas ya no descentra el logo, que es lo que le pasaba cuando iba en flujo.
 *
 * `margin-inline-start: 0` anula la separación que llevaba de cuando iba pegado
 * al logo por la izquierda; ahora arranca en el borde del contenedor y ese
 * margen sólo lo metía hacia dentro sin motivo.
 */
:where(.vl-redesign) .vl-topbar__nav { margin-inline-start: 0; }

/* Los enlaces del nav necesitan especificidad real: con `:where()` puntúan
   (0,1,0) y el color lo acaba decidiendo una regla de `a` de style.css. Mismo
   caso que .vl-cattile__link y .vl-topbar__back. */
.vl-redesign .vl-topbar__navlink { text-decoration: none; }

/*
 * LA SECCIÓN ACTIVA SOBRE UNA CABECERA TRANSPARENTE.
 *
 * Estaba ilegible: blanco sobre blanco. La píldora de activo pinta el fondo en
 * `--vl-action-tint` (teal-50, casi blanco) porque está pensada para la
 * cabecera sólida, y encima ganaba la regla de «sobre el hero todo va en
 * blanco». Las dos puntúan (0,2,0) y la segunda está más abajo en el fichero,
 * así que el texto salía blanco sobre un fondo casi blanco. Se ve en
 * /subcategorias/, que lleva cabecera flotante y «Places» encendido.
 *
 * Aquí la píldora se invierte: fondo blanco al 92% y la tinta teal oscura. El
 * 92% y no el 100% para que se transparente algo de la foto y no parezca una
 * pegatina; y 92% de blanco sobre lo más oscuro que puede haber debajo deja el
 * fondo en un gris de 235, o sea 8.1:1 contra teal-800. Pase la foto que pase.
 *
 * Va después de la regla de :hover a propósito: con la misma puntuación (0,3,0)
 * manda la última, y así al pasar el ratón por encima del activo se queda
 * legible en vez de volver al velo blanco translúcido.
 */
:where(.vl-redesign) .vl-topbar--over .vl-topbar__navlink[aria-current='page'],
:where(.vl-redesign) .vl-topbar--over .vl-topbar__navlink[aria-current='page']:hover {
  background: color-mix(in srgb, var(--vl-white) 92%, transparent);
  color: var(--vl-teal-800);
}

/* Las flechas no se encogen.
   `.vl-iconbtn` fija `width: 44px`, pero un ítem flex puede encogerse POR
   DEBAJO de su ancho declarado si el contenedor va justo: medido en móvil, la
   segunda flecha quedaba en 0px y sólo se veía una. `flex-shrink: 0` es lo que
   convierte ese ancho en un mínimo de verdad. Sitio hay de sobra —34px de
   volver + 93 de logo + 88 de flechas en una barra de 390—; el problema no era
   el espacio, era que flex se lo estaba repartiendo mal. */
:where(.vl-redesign) .vl-topbar__skip,
:where(.vl-redesign) .vl-topbar__arrow { flex: 0 0 auto; }

/* ══ 39. HERO DE ZONA — AJUSTE AL MOCKUP DEL CLIENTE ═══════════════════════
 *
 * El titular, el subtítulo y el buscador van CENTRADOS. Estaban alineados a la
 * izquierda, y en el mockup la composición es simétrica: la palabra manuscrita
 * en el eje, el subrayado debajo, y el buscador centrado bajo ella.
 *
 * LA CIUDAD NO SE CENTRA. «📍 Fuengirola» se queda arriba a la izquierda, como
 * en el mockup: no es parte del titular, es la etiqueta de dónde estás, y
 * centrarla la convertiría en un antetítulo que compite con «Where».
 * ------------------------------------------------------------------------- */

:where(.vl-redesign) .vl-hero__title,
:where(.vl-redesign) .vl-hero__sub {
  text-align: center;
}

/* El subrayado teal va bajo la palabra manuscrita, así que se centra con ella
   en vez de arrancar en el borde izquierdo. */
:where(.vl-redesign) .vl-hero__rule { margin-inline: auto; }

/* El buscador, centrado y con un tope propio: a todo el ancho del contenedor en
   una pantalla grande se convierte en una barra de un kilómetro. */
:where(.vl-redesign) .vl-hero .vl-searchbar {
  margin-inline: auto;
  max-width: 42rem;
}

/* La ciudad mantiene su sitio aunque todo lo demás se centre: el bloque es
   `text-align: center` heredado, así que hay que devolverla explícitamente. */
:where(.vl-redesign) .vl-hero__place { align-self: flex-start; }

/* ══ 40. HERO DE ZONA — PROPORCIONES DEL MOCKUP ════════════════════════════
 *
 * Medido contra el mockup del cliente, tres cosas no cuadraban:
 *
 *   ALTO. El nuestro medía 544px en un móvil de 390; en el mockup el hero ocupa
 *   ~1/3 de la página, unos 300. Casi el doble de alto significa que la primera
 *   pantalla era foto y nada más: los mosaicos, que son el menú del sitio, no
 *   asomaban.
 *
 *   REPARTO. Iba con `justify-content: flex-end`, así que la ciudad, el titular
 *   y el buscador se apelmazaban en la mitad de abajo y la mitad de arriba era
 *   cielo. En el mockup el bloque está centrado en la foto.
 *
 *   ESCALA. «Where» es el gesto de la página y tiene que dominar. Estaba a
 *   52px con «to next?» a 35 —apenas vez y media—; en el mockup la manuscrita
 *   casi dobla al resto.
 * ------------------------------------------------------------------------- */

:where(.vl-redesign) .vl-hero {
  min-height: min(78vw, 30rem);
  justify-content: center;
  gap: var(--vl-space-4);
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-hero { min-height: min(46vw, 34rem); }
}

/* La manuscrita manda: se escala con la pantalla y se le da aire por abajo,
   que es donde va el subrayado. */
:where(.vl-redesign) .vl-hero__script {
  font-size: clamp(3.75rem, 17vw, 8rem);
  line-height: 0.9;
}

:where(.vl-redesign) .vl-hero__title {
  font-size: clamp(1.75rem, 8.5vw, 3.5rem);
  line-height: 1.05;
}

/* El subtítulo, una línea de apoyo y no un párrafo: en el mockup es corto y
   discreto debajo del titular. */
:where(.vl-redesign) .vl-hero__sub {
  max-width: 32rem;
  margin-inline: auto;
  font-size: var(--vl-text-base);
}


/* ══ 41. HERO — EL TRAZO Y EL PIN ══════════════════════════════════════════ */

/*
 * EL SUBRAYADO DE «WHERE» ES UN TRAZO A MANO, no una barra.
 *
 * Era un rectángulo de 3px con las esquinas redondeadas: geométrico, y por eso
 * chocaba justo debajo de una palabra manuscrita. En el mockup es un trazo de
 * lápiz —arranca fino, se comba y sube un poco al final—, y ese gesto es lo que
 * une la palabra con el resto.
 *
 * Va como SVG en línea y no como imagen: pesa cuatro líneas, escala sin
 * pixelarse y el color sale del propio archivo, así que no hay que sincronizar
 * un PNG con la paleta. `preserveAspectRatio='none'` deja que se estire al
 * ancho que le toque sin engordar el grosor de forma rara.
 */
:where(.vl-redesign) .vl-hero__rule {
  width: clamp(7rem, 24vw, 13rem);
  height: 0.75rem;
  border-radius: 0;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 14' preserveAspectRatio='none'%3E%3Cpath d='M3 9.4C28 5.6 62 3.3 99 3.1c34-.2 68 1.4 98 4.6' fill='none' stroke='%2338B5BD' stroke-width='4.2' stroke-linecap='round'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}

/*
 * El pin de la ciudad, en el naranja de la marca — el mismo del logo. En el
 * mockup es la única nota de color de todo el hero, y de ahí sale su trabajo:
 * separar «dónde estás» del titular sin necesidad de un cajetín ni una línea.
 *
 * Se usa el 500, que es el naranja de marca de la paleta: aquí va sobre foto
 * oscura y como icono, no como texto, así que no le aplica el mínimo de
 * contraste de los escalones 600/700.
 */
:where(.vl-redesign) .vl-hero__place i,
:where(.vl-redesign) .vl-hero__place svg {
  color: var(--vl-orange-500);
  fill: currentColor;
  font-size: 1.15em;
}

/* ══ 39. RECOMMEND A PLACE ═════════════════════════════════════════════════ */

/*
 * El formulario único de alta y claim (inc/recommend-a-place.php) y la tabla de
 * recomendaciones. Prefijo `.vl-reco-`, NO `.vl-recommend`: esa clase ya existe
 * y es el medallón de puntuación de reseñas de la ficha (sección 20).
 *
 * TODO va con selector normal (0,2,0) y no con `:where()`, por el mismo motivo
 * que el buscador de claims de la sección 38: esto se pinta dentro de
 * `.vl-dash__content.bsui`, y el reboot de AyeCode UI puntúa (0,1,1) con reglas
 * como `.bsui p` y `.bsui label`, que le ganarían a `:where()`.
 */

.vl-redesign .vl-reco [hidden],
.vl-redesign .vl-reco-table [hidden] { display: none !important; }

/* ── Cabecera y avisos ───────────────────────────────────────────────────── */

.vl-redesign .vl-reco { padding: var(--vl-space-4); }

.vl-redesign .vl-reco__intro {
  margin: 0 0 var(--vl-space-5);
  font-size: var(--vl-text-sm);
  line-height: 1.5;
  color: var(--vl-text-muted);
}

.vl-redesign .vl-reco__warning {
  margin: 0;
  padding: var(--vl-space-3) var(--vl-space-4);
  border: 1px solid var(--vl-orange-200);
  border-radius: var(--vl-radius-md);
  background: var(--vl-accent-tint);
  font-size: var(--vl-text-sm);
  color: var(--vl-orange-800);
}

.vl-redesign .vl-reco__form {
  display: flex;
  flex-direction: column;
  gap: var(--vl-space-5);
}

/* ── 1 · Buscador de Google ──────────────────────────────────────────────── */

/*
 * El panel gris no es decoración: separa «lo que busco en Google» de «lo que le
 * cuento a VibeLocal». Sin él, el buscador parecía un campo más del formulario y
 * la gente escribía el nombre a mano sin elegir del desplegable, que es la única
 * forma de que lleguen el place_id y la URL de Maps.
 */
.vl-redesign .vl-reco__search {
  display: flex;
  align-items: flex-start;
  gap: var(--vl-space-3);
  padding: var(--vl-space-4);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-md);
  background: var(--vl-bg-sunken);
}

.vl-redesign .vl-reco__search-icon {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--vl-radius-sm);
  background: var(--vl-white);
  border: 1px solid var(--vl-border);
  color: var(--vl-orange-500);
  font-size: 1.05rem;
}

.vl-redesign .vl-reco__search-body { flex: 1 1 auto; min-width: 0; }

.vl-redesign .vl-reco__search-body > label {
  display: block;
  margin: 0 0 var(--vl-space-2);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text);
}

.vl-redesign .vl-reco__search-input {
  position: relative;
  display: block;
}

.vl-redesign .vl-reco__search-input > i {
  position: absolute;
  top: 50%;
  left: var(--vl-space-3);
  transform: translateY(-50%);
  color: var(--vl-ink-400);
  font-size: 0.85rem;
  pointer-events: none;
}

.vl-redesign .vl-reco__search-input > input {
  width: 100%;
  padding: 0.6rem 0.75rem 0.6rem 2.25rem;
  border: 1px solid var(--vl-border-strong);
  border-radius: var(--vl-radius-sm);
  background: var(--vl-white);
  font: inherit;
  font-size: var(--vl-text-sm);
  color: var(--vl-text);
}

/* ── Confirmación del sitio elegido ──────────────────────────────────────── */

.vl-redesign .vl-reco__preview {
  display: flex;
  align-items: flex-start;
  gap: var(--vl-space-2);
  margin: 0;
  padding: var(--vl-space-3);
  border: 1px solid var(--vl-teal-200);
  border-radius: var(--vl-radius-md);
  background: var(--vl-bg-tint);
}

.vl-redesign .vl-reco__preview > i {
  margin-top: 0.15rem;
  color: var(--vl-teal-600);
}

.vl-redesign .vl-reco__preview-body {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
  font-size: var(--vl-text-sm);
}

.vl-redesign .vl-reco__preview-body > strong { color: var(--vl-teal-900); }
.vl-redesign .vl-reco__preview-body > span { color: var(--vl-text-muted); }

/* ── «Ya está en el directorio» ──────────────────────────────────────────── */

.vl-redesign .vl-reco__existing-inner {
  padding: var(--vl-space-4);
  border: 1px solid var(--vl-border);
  border-left-width: 4px;
  border-radius: var(--vl-radius-md);
  background: var(--vl-bg-sunken);
}

.vl-redesign .vl-reco__existing-inner.is-claim {
  border-color: var(--vl-teal-200);
  border-left-color: var(--vl-teal-600);
  background: var(--vl-bg-tint);
}

.vl-redesign .vl-reco__existing-inner.is-pending {
  border-color: var(--vl-orange-200);
  border-left-color: var(--vl-orange-500);
  background: var(--vl-accent-tint);
}

.vl-redesign .vl-reco__existing-title {
  margin: 0 0 var(--vl-space-1);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-bold);
  color: var(--vl-text);
}

.vl-redesign .vl-reco__existing-text {
  margin: 0;
  font-size: var(--vl-text-sm);
  line-height: 1.5;
  color: var(--vl-text-body);
}

.vl-redesign .vl-reco__existing-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vl-space-2);
  margin: var(--vl-space-3) 0 0;
}

.vl-redesign .vl-reco__existing-actions:empty { display: none; }

/* ── 2 · Quién eres ──────────────────────────────────────────────────────── */

.vl-redesign .vl-reco__who {
  margin: 0;
  padding: 0;
  border: 0;
}

.vl-redesign .vl-reco__who > legend {
  float: none;
  width: auto;
  margin: 0 0 var(--vl-space-3);
  padding: 0;
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text);
}

.vl-redesign .vl-reco__options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--vl-space-3);
}

/*
 * Cada opción es una `<label>` entera y no un radio con texto al lado: el área
 * de pulsación tiene que ser la tarjeta completa, sobre todo en móvil.
 * El radio real se esconde pero SIGUE en el DOM y recibe el foco, por eso el
 * anillo de foco se pinta con :focus-visible sobre el contenedor.
 */
.vl-redesign .vl-reco__opt {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--vl-space-3);
  margin: 0;
  padding: var(--vl-space-4);
  padding-right: var(--vl-space-8);
  border: 1.5px solid var(--vl-border);
  border-radius: var(--vl-radius-lg);
  background: var(--vl-white);
  cursor: pointer;
  transition: border-color var(--vl-duration) var(--vl-ease),
              background var(--vl-duration) var(--vl-ease);
}

.vl-redesign .vl-reco__opt input[type="radio"] {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

.vl-redesign .vl-reco__opt-icon {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--vl-radius-md);
  font-size: 1.25rem;
}

.vl-redesign .vl-reco__opt-body {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

.vl-redesign .vl-reco__opt-title {
  font-size: var(--vl-text-base);
  font-weight: var(--vl-fw-bold);
  line-height: 1.3;
  color: var(--vl-text);
}

.vl-redesign .vl-reco__opt-desc {
  font-size: var(--vl-text-sm);
  line-height: 1.45;
  color: var(--vl-text-muted);
}

/* El círculo del mockup, arriba a la derecha. */
.vl-redesign .vl-reco__opt-mark {
  position: absolute;
  top: var(--vl-space-4);
  right: var(--vl-space-4);
  width: 1.15rem;
  height: 1.15rem;
  border: 2px solid var(--vl-ink-300);
  border-radius: 50%;
  background: var(--vl-white);
}

.vl-redesign .vl-reco__opt.is-selected .vl-reco__opt-mark::after {
  content: "";
  position: absolute;
  inset: 0.2rem;
  border-radius: 50%;
}

/* Dueño = teal (el primario). Local = naranja (el acento). Es el mismo par de
   colores que usa el resto del sitio, no dos tintes elegidos aquí. */
.vl-redesign .vl-reco__opt--owner .vl-reco__opt-icon {
  background: var(--vl-teal-100);
  color: var(--vl-teal-700);
}

.vl-redesign .vl-reco__opt--owner:hover { border-color: var(--vl-teal-300); }

.vl-redesign .vl-reco__opt--owner.is-selected {
  border-color: var(--vl-teal-600);
  background: var(--vl-bg-tint);
}

.vl-redesign .vl-reco__opt--owner.is-selected .vl-reco__opt-mark {
  border-color: var(--vl-teal-600);
}

.vl-redesign .vl-reco__opt--owner.is-selected .vl-reco__opt-mark::after {
  background: var(--vl-teal-600);
}

.vl-redesign .vl-reco__opt--local .vl-reco__opt-icon {
  background: var(--vl-orange-100);
  color: var(--vl-orange-700);
}

.vl-redesign .vl-reco__opt--local:hover { border-color: var(--vl-orange-300); }

.vl-redesign .vl-reco__opt--local.is-selected {
  border-color: var(--vl-orange-600);
  background: var(--vl-accent-tint);
}

.vl-redesign .vl-reco__opt--local.is-selected .vl-reco__opt-mark {
  border-color: var(--vl-orange-600);
}

.vl-redesign .vl-reco__opt--local.is-selected .vl-reco__opt-mark::after {
  background: var(--vl-orange-600);
}

.vl-redesign .vl-reco__opt:focus-within {
  outline: 2px solid var(--vl-focus);
  outline-offset: 2px;
}

/* ── 2b · Datos de titularidad ───────────────────────────────────────────── */

.vl-redesign .vl-reco__owner {
  padding: var(--vl-space-4);
  border: 1px solid var(--vl-teal-200);
  border-radius: var(--vl-radius-md);
  background: var(--vl-bg-tint);
}

.vl-redesign .vl-reco__owner-intro {
  display: flex;
  align-items: flex-start;
  gap: var(--vl-space-2);
  margin: 0 0 var(--vl-space-3);
  font-size: var(--vl-text-sm);
  line-height: 1.45;
  color: var(--vl-teal-800);
}

.vl-redesign .vl-reco__owner-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--vl-space-3);
}

/* ── Campos ──────────────────────────────────────────────────────────────── */

.vl-redesign .vl-reco__field { position: relative; }

.vl-redesign .vl-reco__field > label {
  display: block;
  margin: 0 0 var(--vl-space-2);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-text);
}

.vl-redesign .vl-reco__field input,
.vl-redesign .vl-reco__field textarea {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--vl-border-strong);
  border-radius: var(--vl-radius-sm);
  background: var(--vl-white);
  font: inherit;
  font-size: var(--vl-text-sm);
  color: var(--vl-text);
}

.vl-redesign .vl-reco__field textarea {
  min-height: 5.5rem;
  resize: vertical;
  line-height: 1.5;
}

/* El contador va dentro del textarea, abajo a la derecha, como en el mockup.
   `pointer-events:none` para que no robe el clic al propio textarea. */
.vl-redesign .vl-reco__counter {
  position: absolute;
  right: 0.65rem;
  bottom: 0.5rem;
  font-size: var(--vl-text-2xs);
  color: var(--vl-text-faint);
  pointer-events: none;
}

/* ── Botón de envío ──────────────────────────────────────────────────────── */

/*
 * Naranja de marca (orange-600, 4.10:1). Los tokens sólo lo permiten con texto
 * >=18px/700, así que el tamaño de fuente de aquí no es decorativo: es lo que
 * hace que el botón pase AA.
 */
.vl-redesign .vl-reco__submit {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--vl-space-2);
  width: 100%;
  min-height: var(--vl-tap-min);
  padding: 0.75rem 1.25rem;
  border: 0;
  border-radius: var(--vl-radius-md);
  background: var(--vl-accent);
  color: var(--vl-white);
  font-family: var(--vl-font-ui);
  font-size: 1.125rem;
  font-weight: var(--vl-fw-bold);
  cursor: pointer;
  transition: background var(--vl-duration) var(--vl-ease);
}

.vl-redesign .vl-reco__submit:hover:not(:disabled) { background: var(--vl-accent-strong); }

.vl-redesign .vl-reco__submit:disabled {
  background: var(--vl-ink-300);
  cursor: not-allowed;
}

/* ── Mensajes ────────────────────────────────────────────────────────────── */

.vl-redesign .vl-reco__msg {
  margin: 0;
  padding: var(--vl-space-3);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-md);
  font-size: var(--vl-text-sm);
  line-height: 1.45;
}

.vl-redesign .vl-reco__msg--ok {
  border-color: var(--vl-teal-200);
  background: var(--vl-bg-tint);
  color: var(--vl-teal-800);
}

.vl-redesign .vl-reco__msg--warn {
  border-color: var(--vl-orange-200);
  background: var(--vl-accent-tint);
  color: var(--vl-orange-800);
}

.vl-redesign .vl-reco__msg--error {
  border-color: #F5C6C0;
  background: #FDF2F0;
  color: var(--vl-closed);
}

/* ── La tabla de recomendaciones ─────────────────────────────────────────── */

/*
 * Grid y no <table>: las celdas tienen que reordenarse en vertical en móvil, y
 * una tabla real no se puede reflowear sin romper la semántica. Los roles ARIA
 * (role="table"/"row"/"cell") devuelven a los lectores de pantalla lo que el
 * display grid les quita.
 */
.vl-redesign .vl-reco-table { padding: 0; }

.vl-redesign .vl-reco-table__head,
.vl-redesign .vl-reco-table__row {
  display: grid;
  grid-template-columns: minmax(0, 2.4fr) minmax(0, 2.2fr) auto auto 1.5rem;
  gap: var(--vl-space-3);
  align-items: center;
  padding: var(--vl-space-3) var(--vl-space-4);
}

.vl-redesign .vl-reco-table__head {
  border-bottom: 1px solid var(--vl-border);
  font-size: var(--vl-text-2xs);
  font-weight: var(--vl-fw-bold);
  letter-spacing: var(--vl-tracking-wide);
  text-transform: uppercase;
  color: var(--vl-text-faint);
}

.vl-redesign .vl-reco-table__row + .vl-reco-table__row {
  border-top: 1px solid var(--vl-ink-100);
}

.vl-redesign .vl-reco-row__place {
  display: flex;
  align-items: center;
  gap: var(--vl-space-3);
  min-width: 0;
}

.vl-redesign .vl-reco-row__img {
  flex: 0 0 auto;
  width: 3rem;
  height: 3rem;
  border-radius: var(--vl-radius-sm);
  object-fit: cover;
  background: var(--vl-bg-sunken);
}

.vl-redesign .vl-reco-row__img--empty {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--vl-border);
  color: var(--vl-ink-400);
}

.vl-redesign .vl-reco-row__body {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.vl-redesign .vl-reco-row__name {
  font-family: var(--vl-font-display);
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-bold);
  color: var(--vl-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vl-redesign .vl-reco-row__meta {
  font-size: var(--vl-text-xs);
  color: var(--vl-text-muted);
}

.vl-redesign .vl-reco-row__reason {
  font-size: var(--vl-text-sm);
  line-height: 1.45;
  color: var(--vl-text-body);
}

.vl-redesign .vl-reco-row__date {
  font-size: var(--vl-text-xs);
  white-space: nowrap;
  color: var(--vl-text-muted);
}

.vl-redesign .vl-reco-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.25rem 0.6rem;
  border-radius: var(--vl-radius-pill);
  font-size: var(--vl-text-xs);
  font-weight: var(--vl-fw-semibold);
  white-space: nowrap;
}

.vl-redesign .vl-reco-row__go { text-align: right; }

.vl-redesign .vl-reco-row__go a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  color: var(--vl-ink-500);
}

.vl-redesign .vl-reco-row__go a:hover { color: var(--vl-action); }

/* En móvil la fila se convierte en tarjeta: dos columnas (miniatura y todo lo
   demás) y el resto de celdas apiladas debajo. La cabecera desaparece porque
   sin columnas no encabeza nada. */
@media (max-width: 46.875rem) {
  .vl-redesign .vl-reco-table__head { display: none; }

  .vl-redesign .vl-reco-table__row {
    grid-template-columns: 1fr auto;
    row-gap: var(--vl-space-2);
    padding: var(--vl-space-4);
  }

  .vl-redesign .vl-reco-row__place { grid-column: 1 / -1; }
  .vl-redesign .vl-reco-row__reason { grid-column: 1 / -1; }
  .vl-redesign .vl-reco-row__status { grid-column: 1; }
  .vl-redesign .vl-reco-row__date { grid-column: 1; }
  .vl-redesign .vl-reco-row__go { grid-column: 2; grid-row: 3 / 5; align-self: center; }
}

/* ── Pie «View all» y estado vacío ───────────────────────────────────────── */

.vl-redesign .vl-reco-viewall {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-action);
}

.vl-redesign .vl-reco-empty {
  padding: var(--vl-space-8) var(--vl-space-4);
  text-align: center;
}

.vl-redesign .vl-reco-empty > i {
  font-size: 1.75rem;
  color: var(--vl-ink-300);
}

.vl-redesign .vl-reco-empty > p {
  margin: var(--vl-space-3) 0 var(--vl-space-4);
  font-size: var(--vl-text-sm);
  color: var(--vl-text-muted);
}

/* ── El CTA de la tarjeta del home ───────────────────────────────────────── */

.vl-redesign .vl-reco-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--vl-space-3);
  padding: var(--vl-space-4);
}

.vl-redesign .vl-reco-cta__text {
  margin: 0;
  font-size: var(--vl-text-sm);
  line-height: 1.5;
  color: var(--vl-text-muted);
}

.vl-redesign .vl-reco-cta__link {
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
  color: var(--vl-action);
}

/* ══ 42. MOSAICOS Y FILAS DE EVENTO DE LA PORTADA ══════════════════════════ */
/*
 * 2026-08-24 · Adaptación al mockup del cliente para la home y las landings de
 * zona. Tres piezas: la rejilla de cuatro mosaicos altos, las dos tarjetas
 * anchas de debajo, y la fila de evento con badge, dirección, hora y píldora.
 */

/* ── Cuatro en fila ───────────────────────────────────────────────────────── */
/*
 * CUATRO COLUMNAS TAMBIÉN EN EL MÓVIL, que es como está dibujado. En un iPhone
 * de 390px cada mosaico mide 84px, así que el tipo tiene que empezar pequeño de
 * verdad (0.72rem) y crecer con la pantalla; con la escala normal del sistema
 * «Great food & drinks» no cabría ni en tres líneas.
 *
 * `aspect-ratio` y no `min-height`: en el mockup el mosaico es más alto que
 * ancho en una proporción fija, y con alto mínimo se deformaría al pasar de
 * cuatro columnas estrechas a cuatro anchas.
 */
:where(.vl-redesign) .vl-tilegrid--four {
  grid-template-columns: repeat(4, 1fr);
  gap: var(--vl-space-2);
}

:where(.vl-redesign) .vl-tilegrid--four .vl-cattile {
  min-height: 0;
  aspect-ratio: 5 / 8;
  padding: var(--vl-space-2);
  border-radius: var(--vl-radius-md);
}

:where(.vl-redesign) .vl-tilegrid--four .vl-cattile__title {
  font-size: clamp(0.72rem, 2.6vw, 1.0625rem);
  line-height: 1.15;
}

:where(.vl-redesign) .vl-tilegrid--four .vl-cattile__sub {
  font-size: clamp(0.625rem, 2.1vw, 0.875rem);
  line-height: 1.25;
  margin-top: 0.15rem;
  /* Deja libre la esquina del galón sin sacarlo del flujo: el ancho del
     mosaico menos el diámetro del círculo y su margen. */
  padding-right: 1.75rem;
}

/*
 * SIN SUBTÍTULO POR DEBAJO DE 600px, Y ESTO ES UNA DESVIACIÓN DEL MOCKUP.
 *
 * Medido en producción a 390px: cuatro columnas dejan el mosaico en 84px, y
 * ahí «Must-see places & experiences» ocupa 63px de alto —cinco líneas de 10px—
 * debajo de un título que ya lleva dos. No desborda, pero es un muro de letra
 * pequeña, y el mockup no está dibujado a 390px: sus mosaicos son de 193px.
 *
 * De las dos maneras de que quepa —pasar a 2×2, o quitar el subtítulo— se
 * elige la segunda porque conserva lo que hace reconocible al diseño: la fila
 * de cuatro. El subtítulo es lo más prescindible que hay en el mosaico; dice
 * «Restaurants, bars & cafés» debajo de «Great food & drinks».
 *
 * Para volver a lo literal, basta con borrar este bloque.
 */
@media (max-width: 599px) {
  :where(.vl-redesign) .vl-tilegrid--four .vl-cattile__sub { display: none; }

  /*
   * EL HUECO DEL GALÓN SE RESERVA ABAJO, NO A LA DERECHA.
   *
   * Reservarlo con `padding-right` en el título fue mi primer intento y falla
   * por una razón concreta: en un mosaico de 84px, el padding deja la caja de
   * texto en 32px y «attractions» mide 62px. Una palabra suelta no se parte, así
   * que desborda su caja y se mete igual por debajo del círculo —sólo que ahora
   * además rompe el título en cuatro líneas («Great / food / & / drinks»).
   *
   * Con hueco abajo el título dispone del ancho entero, parte por donde debe y
   * el círculo se queda en su propia banda. Deja de parecerse al mockup en que
   * allí el círculo va al lado de la última línea; a este ancho no cabe.
   */
  :where(.vl-redesign) .vl-tilegrid--four .vl-cattile { padding-bottom: 2rem; }

  /*
   * Y con el texto más arriba hay que subir también el velo, o el título se
   * queda donde el degradado ya casi no cubre.
   *
   * La cuenta: el título acaba a un 44% de la altura, y ahí el velo original
   * vale 56% de ink-900. Sobre la zona más clara que puede tener una foto
   * —blanco puro— eso deja el fondo en 4.4:1 contra el texto blanco, por
   * debajo del 4.5 que exige el sistema. Hace falta un 58.5% para llegar; se
   * pone 76% al 60% de altura, que a la altura del título da un 80% y aguanta
   * cualquier foto que suba el cliente.
   *
   * ESTA REGLA VA CON EL COLOR DE LA CATEGORÍA, igual que la de arriba. Se
   * quedó en tinta neutra cuando se tiñó el velo base, y como sólo se aplica
   * por debajo de 600px —o sea, en el móvil, que es donde mira el cliente— el
   * cambio no se veía por ninguna parte mientras la regla general sí estaba
   * bien. Dos horas de dar vueltas por no buscar los overrides primero.
   */
  :where(.vl-redesign) .vl-tilegrid--four .vl-cattile::before {
    background: linear-gradient(
      to top,
      color-mix(in srgb, var(--vl-tile, var(--vl-ink-900)) 88%, transparent) 0%,
      color-mix(in srgb, var(--vl-tile, var(--vl-ink-900)) 62%, transparent) 60%,
      transparent 100%
    );
  }
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-tilegrid--four {
    gap: var(--vl-space-3);
  }
  :where(.vl-redesign) .vl-tilegrid--four .vl-cattile {
    aspect-ratio: 3 / 4;
    padding: var(--vl-space-4);
    border-radius: var(--vl-radius-lg);
  }
  :where(.vl-redesign) .vl-tilegrid--four .vl-cattile__sub { padding-right: 3rem; }
}

/* ── El galón redondo ─────────────────────────────────────────────────────── */
/*
 * Círculo blanco con el chevron del color del mosaico. El color sale de
 * `--vl-tile`, que define cada modificador de tono, así que el galón cambia con
 * el mosaico sin una regla por cada uno.
 */
:where(.vl-redesign) .vl-cattile__go,
:where(.vl-redesign) .vl-widetile__go {
  /*
   * `pointer-events: none` o el galón se come el clic de su propia esquina: va
   * después del enlace en el HTML y los dos son absolutos sin z-index, así que
   * pinta por encima del `::after` que estira la zona pulsable.
   */
  pointer-events: none;
}

:where(.vl-redesign) .vl-cattile__go {
  position: absolute;
  right: var(--vl-space-2);
  bottom: var(--vl-space-2);
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: var(--vl-radius-pill);
  background: var(--vl-white);
  color: var(--vl-tile, var(--vl-action));
  font-size: 0.625rem;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.25);
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-cattile__go {
    right: var(--vl-space-4);
    bottom: var(--vl-space-4);
    width: 2.25rem;
    height: 2.25rem;
    font-size: 0.875rem;
  }
}

/* Cada tono expone su color como variable, además de usarlo de fondo. Así lo
   pueden leer el galón y cualquier detalle que venga después. */
:where(.vl-redesign) .vl-cattile--food  { --vl-tile: var(--vl-cat-food); }
:where(.vl-redesign) .vl-cattile--see   { --vl-tile: var(--vl-cat-see); }
:where(.vl-redesign) .vl-cattile--do    { --vl-tile: var(--vl-cat-do); }
:where(.vl-redesign) .vl-cattile--deals { --vl-tile: var(--vl-cat-deals); }

/* ── Las dos tarjetas anchas ──────────────────────────────────────────────── */
/*
 * Componente aparte y no un modificador de `.vl-cattile`: cambia todo lo que
 * define a aquél —fondo claro en vez de foto a sangre, texto en tinta en vez de
 * blanco, imagen recortada al lado en vez de de fondo—. Compartir la clase
 * habría sido apagar seis propiedades para encender otras seis.
 */
:where(.vl-redesign) .vl-tilegrid--wide {
  grid-template-columns: repeat(2, 1fr);
  gap: var(--vl-space-2);
  margin-top: var(--vl-space-2);
}

:where(.vl-redesign) .vl-widetile {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--vl-space-2);
  min-height: 5.5rem;
  padding: var(--vl-space-3) 2.25rem var(--vl-space-3) var(--vl-space-3);
  border-radius: var(--vl-radius-md);
  background: var(--vl-tile-bg);
  overflow: hidden;
}

:where(.vl-redesign) .vl-widetile__body { flex: 1 1 auto; min-width: 0; }

:where(.vl-redesign) .vl-widetile__title {
  font-family: var(--vl-font-display);
  font-size: clamp(0.8125rem, 2.8vw, 1.125rem);
  font-weight: var(--vl-fw-black);
  line-height: 1.15;
}

:where(.vl-redesign) .vl-widetile__sub {
  margin-top: 0.15rem;
  font-size: clamp(0.625rem, 2.1vw, 0.8125rem);
  line-height: 1.25;
  color: var(--vl-text-muted);
}

/*
 * Especificidad real y no `:where()`, por lo mismo que `.vl-cattile__link`:
 * con especificidad cero, una regla suelta de `a` de style.css decide el color.
 */
.vl-redesign .vl-widetile__title,
.vl-redesign .vl-widetile__link,
.vl-redesign .vl-widetile__link:hover,
.vl-redesign .vl-widetile__link:focus {
  color: var(--vl-text);
  text-decoration: none;
}

:where(.vl-redesign) .vl-widetile__link::after {
  content: '';
  position: absolute;
  inset: 0;
}

/*
 * MINIATURA RECORTADA, y no el bodegón suelto del mockup.
 * En el mockup son ilustraciones sobre fondo blanco, que se pueden posar
 * directamente sobre el color de la tarjeta. Lo que hay en la base de datos son
 * FOTOS a sangre (`ct_cat_default_img` de los términos, subidas en abril). Una
 * foto suelta sin marco sobre un fondo azul claro es un rectángulo pegado; con
 * `mix-blend-mode: multiply` —que es lo que haría falta para fundir la
 * ilustración— la foto se ensucia entera. Cuadrado redondeado, entonces.
 */
:where(.vl-redesign) .vl-widetile__img {
  flex: 0 0 auto;
  width: clamp(3rem, 13vw, 5rem);
  height: clamp(3rem, 13vw, 5rem);
  border-radius: var(--vl-radius-sm);
  object-fit: cover;
}

:where(.vl-redesign) .vl-widetile__go {
  position: absolute;
  right: var(--vl-space-2);
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: var(--vl-radius-pill);
  background: var(--vl-white);
  color: var(--vl-text-muted);
  font-size: 0.625rem;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.12);
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-tilegrid--wide { gap: var(--vl-space-3); margin-top: var(--vl-space-3); }
  :where(.vl-redesign) .vl-widetile {
    min-height: 7rem;
    padding: var(--vl-space-4) 3.5rem var(--vl-space-4) var(--vl-space-4);
    border-radius: var(--vl-radius-lg);
  }
  :where(.vl-redesign) .vl-widetile__go {
    right: var(--vl-space-4);
    width: 2.25rem;
    height: 2.25rem;
    font-size: 0.875rem;
  }
}

/*
 * Los dos fondos claros del mockup. Van escritos aquí y no derivados de la
 * paleta porque son colores de ambiente —un azul de papel y un verde de salvia—
 * que no existen en las escalas de teal y naranja. El texto que va encima es
 * `--vl-text` (ink-900): 16.4:1 sobre el azul y 16.1:1 sobre el verde.
 */
:where(.vl-redesign) .vl-widetile--shops    { --vl-tile-bg: #E4EEF6; }
:where(.vl-redesign) .vl-widetile--services { --vl-tile-bg: #E8F1E6; }

/* ── Fila de evento, versión mockup ───────────────────────────────────────── */
/*
 * Los tres colores (`--vl-ev`, `--vl-ev-ink`, `--vl-ev-tint`) los escribe la
 * plantilla en el `style` de cada fila: salen del color que el cliente le puso
 * a la categoría en GeoDirectory, ya oscurecidos hasta pasar 4.5:1
 * (inc/redesign-color.php). Aquí sólo se colocan.
 */
:where(.vl-redesign) .vl-rowlist--events .vl-eventrow {
  grid-template-columns: 4.5rem minmax(0, 1fr) auto auto;
  gap: var(--vl-space-3);
  align-items: center;
}

/* El cuadro de la izquierda: color plano con el icono de la categoría en
   blanco. Sustituye al aro de teal con emoji, que era el respaldo de antes. */
:where(.vl-redesign) .vl-rowlist--events .vl-eventrow__icon {
  width: 4.5rem;
  height: 4.5rem;
  background: var(--vl-ev, var(--vl-action));
  box-shadow: none;
  color: var(--vl-white);
  font-size: 1.75rem;
}

/* Cuando hay foto del evento, el mismo cuadro pero con la imagen recortada. */
:where(.vl-redesign) img.vl-eventrow__icon--photo {
  object-fit: cover;
  background: var(--vl-ink-100);
}

:where(.vl-redesign) .vl-eventrow__body { min-width: 0; }

/* El badge toma el color de la categoría, no un naranja fijo: así la fila
   entera —cuadro, badge y píldora— habla del mismo color y se lee de un vistazo
   a qué familia pertenece el evento. */
:where(.vl-redesign) .vl-rowlist--events .vl-eventrow__when {
  color: var(--vl-ev-ink, var(--vl-accent-strong));
}

:where(.vl-redesign) .vl-rowlist--events .vl-eventrow__title {
  margin-top: 0.1rem;
  overflow-wrap: anywhere;
}

/* Dirección y hora: cada una en su línea, con su icono delante. El icono se
   pinta en ink-400, que el sistema permite justo para esto —decorativo, nunca
   texto— y el dato en el gris de texto secundario. */
:where(.vl-redesign) .vl-rowlist--events .vl-eventrow__meta {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.2rem;
  line-height: 1.3;
}

:where(.vl-redesign) .vl-rowlist--events .vl-eventrow__meta i {
  flex: 0 0 auto;
  width: 0.75rem;
  color: var(--vl-ink-400);
  font-size: 0.6875rem;
  text-align: center;
}

/* La píldora de categoría. `nowrap` porque partir «LIVE MUSIC» en dos líneas
   dentro de una píldora queda como un error, y la columna es `auto`: si no cabe
   se estrecha el título, que sí sabe partirse. */
:where(.vl-redesign) .vl-eventrow__cat {
  align-self: center;
  padding: 0.25rem 0.5rem;
  border-radius: var(--vl-radius-sm);
  background: var(--vl-ev-tint, var(--vl-bg-tint));
  color: var(--vl-ev-ink, var(--vl-action));
  font-size: var(--vl-text-2xs);
  font-weight: var(--vl-fw-bold);
  letter-spacing: var(--vl-tracking-wide);
  text-transform: uppercase;
  white-space: nowrap;
}

/*
 * La píldora aguanta hasta los 360px: medido a 390px, la fila mide 358px y con
 * el cuadro de 72px, la píldora de «MARKETS» y el galón todavía le quedan al
 * título unos 150px, que es donde empieza a partirse feo. Por debajo de eso se
 * esconde la píldora y no el galón: el galón dice que la fila lleva a algún
 * sitio —información de uso— y la categoría ya se sabe por el color y el icono
 * del cuadro de la izquierda, que siguen ahí.
 */
@media (max-width: 359px) {
  :where(.vl-redesign) .vl-eventrow__cat { display: none; }
  :where(.vl-redesign) .vl-rowlist--events .vl-eventrow__icon {
    width: 3.5rem;
    height: 3.5rem;
    font-size: 1.375rem;
  }
  :where(.vl-redesign) .vl-rowlist--events .vl-eventrow {
    grid-template-columns: 3.5rem minmax(0, 1fr) auto;
    gap: var(--vl-space-2);
  }
}

/* ── Contador del mosaico, cuando además hay texto explicativo ────────────── */
/*
 * En el paso de subcategorías el mosaico pasa a tener tres líneas: nombre,
 * para qué sirve, y cuántas fichas hay. La tercera es de apoyo —ayuda a decidir
 * pero no explica nada— así que baja de tamaño y de peso para que la del medio,
 * que es la que se añadió para orientar, se lea antes.
 */
:where(.vl-redesign) .vl-cattile__count {
  margin-top: 0.2rem;
  font-size: var(--vl-text-2xs);
  color: color-mix(in srgb, var(--vl-white) 68%, transparent);
}

/* ── Mosaico con texto explicativo ────────────────────────────────────────── */
/*
 * El paso de subcategorías añade una línea entre el nombre y el contador, y con
 * ella el bloque de texto sube al tercio superior del mosaico: medido a 390px,
 * el título de «Cafés» arranca a 61px de un mosaico de 197.
 *
 * A esa altura —69% desde abajo— el velo normal vale un 41% de ink-900, y sobre
 * la zona clara de una foto eso deja el texto blanco en 3.4:1. Con la parada del
 * 60% al 75% de altura, a la altura del título queda un 62% y pasa de 4.5:1 con
 * cualquier fotografía.
 *
 * Sólo en `--rich`, que es la clase que pone la plantilla cuando de verdad hay
 * descripción. Los mosaicos de la portada y los de zonas no se tocan: allí el
 * texto está abajo del todo y el velo de siempre les basta.
 */
/*
 * LAS DE SUBCATEGORÍA, MUCHO MÁS FLOJAS QUE LAS DE PORTADA.
 *
 * Y no es una inconsistencia: en la portada el color ES la información —cuatro
 * mosaicos que hay que distinguir de un vistazo—, mientras que aquí dentro ya
 * sabes en qué categoría estás y las cuatro tarjetas comparten tono. Ahí el
 * color no separa nada y sólo tapa la foto, que es lo único que distingue
 * «Cafés» de «Bars & Pubs».
 *
 * El texto lo sostiene la sombra, no el velo (ver .vl-cattile__title). Por eso
 * se puede bajar tanto sin que el título deje de leerse.
 */
:where(.vl-redesign) .vl-cattile--rich::before {
  background: linear-gradient(
    to top,
    color-mix(in srgb, var(--vl-tile, var(--vl-ink-900)) 70%, transparent) 0%,
    color-mix(in srgb, var(--vl-tile, var(--vl-ink-900)) 26%, transparent) 60%,
    transparent 100%
  );
}

/* Con menos velo debajo, la sombra del texto trabaja un poco más. */
:where(.vl-redesign) .vl-cattile--rich .vl-cattile__title {
  text-shadow: 0 1px 5px rgb(0 0 0 / 0.62);
}

:where(.vl-redesign) .vl-cattile--rich .vl-cattile__sub {
  text-shadow: 0 1px 4px rgb(0 0 0 / 0.58);
}

/* ══ 43. MEDIOS DEL PLAN FEATURED ══════════════════════════════════════════ */
/*
 * Vídeo, fotos de la carta y ficheros descargables. Son ventajas de pago que
 * hasta el 2026-08-24 no se pintaban en ninguna plantilla.
 */

/* El iframe de YouTube viene con width/height fijos del oembed; se le quita el
   tamaño y se le pone la proporción, o desborda en móvil. */
:where(.vl-redesign) .vl-video {
  border-radius: var(--vl-radius-lg);
  overflow: hidden;
  background: var(--vl-ink-900);
}

:where(.vl-redesign) .vl-video iframe {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  border: 0;
}

/* Fotos de la carta: tira que se desplaza en móvil y rejilla en escritorio. No
   van al carrusel de arriba a propósito —quien mira el ambiente del local no
   quiere una lista de precios— y se abren a tamaño completo al pulsar. */
:where(.vl-redesign) .vl-menushots {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 45%;
  gap: var(--vl-space-3);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--vl-space-2);
}

:where(.vl-redesign) .vl-menushot {
  scroll-snap-align: start;
  border-radius: var(--vl-radius-md);
  overflow: hidden;
  background: var(--vl-ink-100);
}

:where(.vl-redesign) .vl-menushot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: 3 / 4;
}

@media (min-width: 768px) {
  :where(.vl-redesign) .vl-menushots {
    grid-auto-flow: row;
    grid-template-columns: repeat(4, 1fr);
    overflow: visible;
  }
}

/* Descarga: misma caja que una fila de la lista, con el tipo de fichero como
   dato secundario. El galón es de «se abre fuera», no de «lleva a otra
   pantalla», y por eso no es un chevron. */
:where(.vl-redesign) .vl-filelink {
  display: grid;
  grid-template-columns: 2.75rem minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--vl-space-3);
  padding: var(--vl-space-3);
  border: 1px solid var(--vl-border);
  border-radius: var(--vl-radius-lg);
  background: var(--vl-bg-raised);
}

.vl-redesign a.vl-filelink,
.vl-redesign a.vl-filelink:hover {
  color: var(--vl-text);
  text-decoration: none;
}

.vl-redesign a.vl-filelink:hover { border-color: var(--vl-action); }

:where(.vl-redesign) .vl-filelink__icon {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--vl-radius-md);
  background: var(--vl-bg-tint);
  color: var(--vl-action);
  font-size: 1.125rem;
}

:where(.vl-redesign) .vl-filelink__body { min-width: 0; }

:where(.vl-redesign) .vl-filelink__label {
  display: block;
  font-weight: var(--vl-fw-semibold);
}

:where(.vl-redesign) .vl-filelink__meta {
  display: block;
  font-size: var(--vl-text-xs);
  color: var(--vl-text-muted);
}

:where(.vl-redesign) .vl-filelink__go {
  color: var(--vl-ink-400);
  font-size: var(--vl-text-sm);
}

/* ══ 44. LA TIRA DEL DUEÑO ═════════════════════════════════════════════════
 *
 * `.vl-ownerbar` — «Gestionas esta ficha · Editar», debajo de la cabecera.
 * Sólo la ve quien puede editar (vl_single_manage(), inc/redesign-single.php).
 *
 * Paleta prestada de `.vl-notice--info`, que es el mismo gesto: tinte teal,
 * borde teal-200 y texto en teal-800, la pareja que los tokens documentan para
 * texto sobre tinte teal. No se reutiliza esa clase directamente porque aquí
 * hay dos hijos y un botón que colocar, y `.vl-notice` es un flex de una línea.
 *
 * EL COLOR VA SIN `:where()`, como los botones de la sección 1: `:where()` vale
 * especificidad cero y cualquier regla de enlace de style.css con un elemento
 * de más le gana. La distribución sí se queda en `:where()`, que es donde la
 * especificidad baja ayuda.
 *
 * El botón es `.vl-btn--outline`, o sea fondo BLANCO: teal-600 sobre blanco da
 * 4.81:1, mientras que el mismo teal sobre el tinte de la tira se queda en
 * 4.49:1 y no llegaría al mínimo del sistema. Por eso no se le quita el fondo
 * para «integrarlo» en la tira.
 * ════════════════════════════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-ownerbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--vl-space-3);
  margin-block-start: var(--vl-space-5);
  padding: var(--vl-space-3) var(--vl-space-4);
  border-radius: var(--vl-radius-md);
  border: 1px solid var(--vl-teal-200);
}

.vl-redesign .vl-ownerbar {
  background: var(--vl-bg-tint);
}

:where(.vl-redesign) .vl-ownerbar__body {
  /* Que la frase larga del estado no empuje al botón fuera de la tira. */
  flex: 1 1 14rem;
  min-width: 0;
}

:where(.vl-redesign) .vl-ownerbar__title {
  display: flex;
  align-items: center;
  gap: var(--vl-space-2);
  margin: 0;
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-semibold);
}

:where(.vl-redesign) .vl-ownerbar__note {
  margin: var(--vl-space-1) 0 0;
  font-size: var(--vl-text-xs);
  font-weight: var(--vl-fw-regular);
}

.vl-redesign .vl-ownerbar__title,
.vl-redesign .vl-ownerbar__note {
  color: var(--vl-teal-800);          /* la pareja documentada con el tinte teal */
}

:where(.vl-redesign) .vl-ownerbar__btn {
  flex: 0 0 auto;
}

/* Los dos botones juntos, y juntos se van a la línea de abajo cuando la frase
   de estado ocupa el ancho. Sin este envoltorio, «Delete» se separaba de
   «Edit listing» y acababa al otro extremo de la tira por el
   `justify-content: space-between` de arriba. */
:where(.vl-redesign) .vl-ownerbar__actions {
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  gap: var(--vl-space-2);
}

/* Borrar es irreversible, así que se dice con el color, pero sin gritar: el
   botón sigue siendo `--outline` —fondo blanco— y sólo cambian el texto, el
   icono y el borde. Un botón rojo macizo al lado de «Edit listing» pesaría más
   que la acción que la gente viene a hacer aquí.
   `--vl-closed` es el rojo que el sistema ya reserva para «cerrado y errores»
   (5.45:1 sobre blanco), no uno nuevo. */
.vl-redesign .vl-ownerbar__btn--danger {
  color: var(--vl-closed);
  border-color: color-mix(in srgb, var(--vl-closed) 45%, transparent);
}

.vl-redesign .vl-ownerbar__btn--danger:hover,
.vl-redesign .vl-ownerbar__btn--danger:focus-visible {
  color: var(--vl-white);
  background: var(--vl-closed);
  border-color: var(--vl-closed);
}

/* ══ 45. MÉTRICAS DE LA FICHA ══════════════════════════════════════════════
 *
 * Casi nada, y eso es la intención: las métricas las pinta el add-on de
 * GeoDirectory con su propio markup de Bootstrap, dentro de `.bsui`. Aquí sólo
 * está el hueco alrededor, el aviso que ve el equipo cuando falta algo, y la
 * lista de enlaces del panel.
 *
 * Sustituye a DOS bloques `<style>` en línea idénticos que había en
 * inc/pricing-plan-cards.php y en inc/geodir-dashboard-links.php, escritos con
 * colores a pelo (#6b7280, #111827, #9ca3af) en vez de con los tokens.
 * ════════════════════════════════════════════════════════════════════════════ */

:where(.vl-redesign) .vl-analytics {
  margin-block-start: var(--vl-space-4);
}

/* La gráfica del add-on viene envuelta en una tarjeta de Bootstrap. Se le quita
   el borde para que no haya una caja dentro de otra. */
:where(.vl-redesign) .vl-analytics .gdga-analytics-box.card {
  border: 0;
  background: transparent;
}

/* En el panel la tarjeta trae su propio hueco a cero (`card_body_class = p-0`),
   así que el aire lo pone esto. */
.vl-analytics__off,
.vl-analytics__intro,
.vl-analytics__list {
  padding-inline: var(--vl-space-4);
}

:where(.vl-redesign) .vl-analytics__off,
:where(.vl-redesign) .vl-analytics__intro {
  margin: 0 0 var(--vl-space-2);
  font-size: var(--vl-text-sm);
}

/* El aviso de que falta algo sólo lo lee el equipo: es un diagnóstico, no una
   alarma para el visitante, así que va en gris y no en rojo. */
.vl-redesign .vl-analytics__off,
.vl-redesign .vl-analytics__intro { color: var(--vl-text-muted); }   /* 6.93:1 */

:where(.vl-redesign) .vl-analytics__list {
  margin: 0;
  padding-block-end: var(--vl-space-4);
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--vl-space-1);
}

:where(.vl-redesign) .vl-analytics__list a {
  font-size: var(--vl-text-sm);
  font-weight: var(--vl-fw-medium);
}
