/* ==========================================================================
   Guía Los Reyes — hoja de estilos
   Mobile-first. Sin dependencias externas.
   ========================================================================== */

:root {
  /* Neutros (modo claro) */
  --bg:            #f7f7f5;
  --surface:       #ffffff;
  --surface-2:     #f1f1ee;
  --line:          #e4e4e0;
  --line-strong:   #d3d3ce;
  --ink:           #191917;
  --ink-2:         #57574f;
  --ink-3:         #66665e;   /* 5.4:1 sobre blanco; el de antes no llegaba a 4.5 */

  /* Acentos */
  --accent:        #0f766e;   /* teal profundo */
  --accent-ink:    #0b5a54;
  --accent-soft:   #e6f2f0;
  --gold:          #b45309;   /* ámbar para destacados */
  --gold-soft:     #fdf3e3;
  --abierto:       #15803d;   /* verde del aviso de abierto */
  --wa:            #25d366;
  --wa-ink:        #128c3f;

  /* Colores de marca de los botones de contacto */
  --brand-web:     #2563eb;
  --brand-fb:      #1877f2;
  --brand-ig:      #d62976;
  --brand-mail:    #7c3aed;   /* morado: el sobre no es de ninguna red */

  --radius:        14px;
  --radius-lg:     20px;
  --shadow-sm:     0 1px 2px rgba(25,25,23,.06), 0 1px 3px rgba(25,25,23,.05);
  --shadow-md:     0 4px 12px rgba(25,25,23,.07), 0 2px 4px rgba(25,25,23,.04);
  --shadow-lg:     0 12px 32px rgba(25,25,23,.10);

  --header-h:      64px;
  --catbar-h:      0px;
  /* Cuánto tapa la parte de arriba de la ventana: el encabezado siempre, y la
     barra de categorías sólo mientras va pegada (arriba de 900px se queda
     quieta). Lo usa el `scroll-margin-top` de las fichas. */
  --pegado:        var(--header-h);
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* ---- Paleta oscura ----------------------------------------------------
     Los valores viven aquí una sola vez. Más abajo se asignan por dos
     caminos —la preferencia del sistema y el selector manual— que deben
     listar las mismas variables; si agregas una, agrégala en los dos. */
  --d-bg:          #141414;
  --d-surface:     #1e1e1e;   /* tarjetas, con contraste claro sobre el fondo */
  --d-surface-2:   #262626;
  --d-line:        #2f2f2f;
  --d-line-strong: #3f3f3f;
  --d-ink:         #f2f2f2;
  --d-ink-2:       #b4b4b4;
  --d-ink-3:       #8a8a8a;
  --d-accent:      #2dd4bf;   /* verde brillante para botones y enlaces */
  --d-accent-ink:  #5eead4;
  --d-accent-soft: #14312e;
  --d-abierto:     #4ade80;
  --d-gold:        #fbbf24;
  --d-gold-soft:   #332711;
  --d-brand-web:   #60a5fa;   /* los azules y el rosa se aclaran para que */
  --d-brand-fb:    #4a9bff;   /* sigan siendo legibles sobre el fondo      */
  --d-brand-ig:    #f472b6;
  --d-brand-mail:  #a78bfa;
  --d-shadow-sm:   0 1px 2px rgba(0,0,0,.5);
  --d-shadow-md:   0 4px 12px rgba(0,0,0,.55);
  --d-shadow-lg:   0 12px 32px rgba(0,0,0,.6);
}

/* Modo oscuro por preferencia del sistema, salvo que el usuario haya
   elegido el claro a mano. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: var(--d-bg);                 --surface: var(--d-surface);
    --surface-2: var(--d-surface-2);   --line: var(--d-line);
    --line-strong: var(--d-line-strong);
    --ink: var(--d-ink);               --ink-2: var(--d-ink-2);
    --ink-3: var(--d-ink-3);
    --accent: var(--d-accent);         --accent-ink: var(--d-accent-ink);
    --accent-soft: var(--d-accent-soft);
    --gold: var(--d-gold);             --gold-soft: var(--d-gold-soft);
    --brand-web: var(--d-brand-web);   --brand-fb: var(--d-brand-fb);
    --brand-ig: var(--d-brand-ig); --brand-mail: var(--d-brand-mail);
    --abierto: var(--d-abierto);
    --shadow-sm: var(--d-shadow-sm);   --shadow-md: var(--d-shadow-md);
    --shadow-lg: var(--d-shadow-lg);
  }
}

/* Modo oscuro elegido a mano con el selector del encabezado. */
:root[data-theme="dark"] {
  --bg: var(--d-bg);                 --surface: var(--d-surface);
  --surface-2: var(--d-surface-2);   --line: var(--d-line);
  --line-strong: var(--d-line-strong);
  --ink: var(--d-ink);               --ink-2: var(--d-ink-2);
  --ink-3: var(--d-ink-3);
  --accent: var(--d-accent);         --accent-ink: var(--d-accent-ink);
  --accent-soft: var(--d-accent-soft);
  --gold: var(--d-gold);             --gold-soft: var(--d-gold-soft);
  --brand-web: var(--d-brand-web);   --brand-fb: var(--d-brand-fb);
  --brand-ig: var(--d-brand-ig); --brand-mail: var(--d-brand-mail);
  --abierto: var(--d-abierto);
  --shadow-sm: var(--d-shadow-sm);   --shadow-md: var(--d-shadow-md);
  --shadow-lg: var(--d-shadow-lg);
}

/* Le dice al navegador de qué tono son los controles nativos (scrollbars,
   campos de formulario) en cada modo. */
:root { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { color-scheme: dark; }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
svg { width: 100%; height: 100%; display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

.container { width: 100%; max-width: 1180px; margin-inline: auto; padding-inline: 16px; }
@media (min-width: 768px) { .container { padding-inline: 28px; } }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 100;
  background: var(--accent); color: #fff; padding: 10px 16px; border-radius: 8px;
  transition: top .15s;
}
.skip-link:focus { top: 12px; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }

/* ==========================================================================
   HEADER
   ========================================================================== */

.header {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line);
}

.header__inner {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "brand cta" "search search";
  align-items: center;
  gap: 10px 16px;
  padding-block: 10px 12px;
}

@media (min-width: 900px) {
  .header__inner {
    grid-template-columns: minmax(190px, 1fr) minmax(280px, 520px) minmax(190px, 1fr);
    grid-template-areas: "brand search cta";
    padding-block: 12px;
    gap: 20px;
  }
}

/* --- Marca --- */
.brand { grid-area: brand; display: inline-flex; align-items: center; gap: 10px; min-width: 0; }

.brand__mark {
  flex: none; width: 38px; height: 38px; display: grid; place-items: center;
  border-radius: 11px;
  background: linear-gradient(145deg, var(--accent), var(--accent-ink));
  color: #fff; box-shadow: var(--shadow-sm);
}
.brand__mark svg { width: 20px; height: 20px; }

.brand__text { display: flex; flex-direction: column; min-width: 0; }
.brand__name { font-size: 17px; font-weight: 500; letter-spacing: -.02em; line-height: 1.15; }
.brand__name strong { font-weight: 700; }
.brand__sub {
  font-size: 11px; color: var(--ink-3); letter-spacing: .01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* --- Buscador --- */
.search {
  grid-area: search;
  position: relative; display: flex; align-items: center;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.search:focus-within {
  background: var(--surface);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.search__icon {
  position: absolute; left: 14px; width: 17px; height: 17px;
  color: var(--ink-3); pointer-events: none;
}
.search__input {
  width: 100%; border: 0; background: transparent; outline: none;
  padding: 11px 40px 11px 41px;
  font-size: 15px; color: var(--ink); border-radius: 999px;
}
.search__input::placeholder { color: var(--ink-3); }
.search__input::-webkit-search-cancel-button { display: none; }
.search__clear {
  position: absolute; right: 8px; width: 26px; height: 26px; padding: 5px;
  border: 0; background: var(--line); color: var(--ink-2);
  border-radius: 50%; cursor: pointer;
}
.search__clear:hover { background: var(--line-strong); }

/* --- CTA y selector de tema del encabezado --- */
.header__acciones {
  grid-area: cta; justify-self: end;
  display: flex; align-items: center; gap: 8px;
}
.header__cta span { display: none; }
@media (min-width: 900px) {
  .header__cta span { display: inline; }
}

.theme-toggle {
  width: 38px; height: 38px; flex: none; padding: 9px;
  display: grid; place-items: center; border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--surface); color: var(--ink-2);
  cursor: pointer; transition: all .2s ease;
}
.theme-toggle svg { width: 100%; height: 100%; }
.theme-toggle:active { transform: scale(.94); }
@media (hover: hover) {
  .theme-toggle:hover { border-color: var(--accent); color: var(--accent); }
}

/* Se muestra el icono del modo al que se cambiaría: luna estando en claro,
   sol estando en oscuro. Sigue los mismos dos caminos que la paleta. */
.theme-toggle__sol { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle__sol  { display: block; }
  :root:not([data-theme="light"]) .theme-toggle__luna { display: none; }
}
:root[data-theme="dark"] .theme-toggle__sol  { display: block; }
:root[data-theme="dark"] .theme-toggle__luna { display: none; }

/* ==========================================================================
   BOTONES
   ========================================================================== */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 10px 16px; border-radius: 999px; border: 1px solid transparent;
  font-size: 14px; font-weight: 600; letter-spacing: -.01em;
  cursor: pointer; transition: transform .12s, background .15s, border-color .15s, box-shadow .15s;
  white-space: nowrap;
}
.btn:active { transform: scale(.975); }
.btn svg { width: 17px; height: 17px; flex: none; }

.btn--ghost { background: var(--surface); border-color: var(--line-strong); color: var(--ink); }
.btn--ghost:hover { border-color: var(--accent); color: var(--accent); }

.btn--wa {
  background: var(--wa); color: #06301a; border-color: transparent;
  box-shadow: 0 1px 2px rgba(18,140,63,.3);
}
.btn--wa:hover { background: #1fbe5a; }

.btn--block { width: 100%; }

.wa-ico {
  width: 18px; height: 18px; flex: none;
  background: currentColor;
  -webkit-mask: var(--wa-mask) center / contain no-repeat;
          mask: var(--wa-mask) center / contain no-repeat;
}
:root {
  --wa-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a12.8 12.8 0 0 0-.57-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.872.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.29.173-1.414-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0 0 12.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 0 0 5.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 0 0-3.48-8.413'/%3E%3C/svg%3E");
}

/* ==========================================================================
   HERO
   ========================================================================== */

.hero {
  padding: 24px 0 22px;
  background:
    radial-gradient(120% 120% at 85% -10%, color-mix(in srgb, var(--accent) 14%, transparent) 0%, transparent 55%),
    linear-gradient(180deg, var(--surface) 0%, var(--bg) 100%);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 768px) { .hero { padding: 36px 0 30px; } }

/* Dos columnas en escritorio: el texto a la izquierda y el carrusel VIP a la
   derecha. Debajo de 940px la retícula cae a una sola columna y el carrusel
   pasa abajo por orden del documento, sin reglas extra. */
.hero__inner {
  display: grid; gap: 20px;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
}
@media (min-width: 940px) {
  /* Las dos columnas son flexibles y el carrusel se lleva un poco más, en
     vez de tener un ancho tope: con un tope fijo la columna del texto
     quedaba más ancha que el propio texto y sobraba un hueco en medio. */
  .hero__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 40px; }
}

.hero__eyebrow {
  margin: 0 0 8px; font-size: 11px; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase; color: var(--accent);
}
/* Sin tope de ancho: el título ocupa toda la columna. El tope de 15ch que
   tenía antes lo dejaba en una franja angosta a la izquierda, con un hueco
   a la derecha y una línea de más que empujaba el banner Premium fuera de
   la pantalla del teléfono. En dos columnas el tope tampoco hacía falta:
   la propia columna limita la línea. */
.hero__title {
  margin: 0; font-size: clamp(26px, 6.2vw, 44px); line-height: 1.12;
  letter-spacing: -.03em; font-weight: 700;
}

.hero__title span {
  background: linear-gradient(100deg, var(--accent), color-mix(in srgb, var(--accent) 55%, var(--gold)));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero__lead {
  margin: 10px 0 0; color: var(--ink-2); font-size: 15px; max-width: 52ch;
}
@media (min-width: 768px) { .hero__lead { margin-top: 14px; font-size: 16.5px; } }

.hero__stats { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 14px; }
@media (min-width: 768px) { .hero__stats { margin-top: 20px; } }
/* Sin píldora: son promesas de la portada, no botones. Encerradas en un óvalo
   con fondo y borde se leían como algo en lo que se puede tocar, así que se
   quedan en texto con su palomita. */
.stat {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 13px; font-weight: 550; color: var(--ink-2);
}
.stat__ico { width: 14px; height: 14px; flex: none; color: var(--accent); }

/* El renglón de "¿Tienes un negocio?" sólo hace falta en el teléfono, donde el
   botón de registrar del encabezado se queda en un "+". En escritorio ese
   botón ya dice "Registrar negocio". */
.hero__alta {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 12px; font-size: 13.5px; color: var(--ink-2);
  text-decoration: none;
}
.hero__alta b { color: var(--accent); font-weight: 650; }
.hero__alta svg { width: 15px; height: 15px; flex: none; color: var(--accent); }
@media (hover: hover) {
  .hero__alta:hover b { text-decoration: underline; text-underline-offset: 3px; }
}
@media (min-width: 900px) { .hero__alta { display: none; } }

/* ==========================================================================
   BANNER VIP  (rotación de los negocios con plan Premium, en la portada)
   ========================================================================== */

/* El aire lo pone la retícula del hero, no un margen propio. */
.vip { min-width: 0; }

/* La ventana recorta y la pista es lo único que se mueve: las páginas van en
   fila y el JS la corre de una a la siguiente. Cada página es una columna del
   ancho de la ventana; en escritorio lleva dos negocios, uno encima del otro,
   y en el teléfono uno. El recorrido entre páginas siempre es horizontal. El
   relleno de abajo es para que la sombra de las tarjetas no se corte contra el
   borde de la ventana. */
.vip__slides {
  overflow: hidden; padding-block: 2px 8px;
  /* El dedo se lleva el banner de lado; el movimiento vertical sigue siendo de
     la página, si no el usuario quedaría atorado al querer bajar. */
  touch-action: pan-y;
  cursor: grab;
}
.vip__slides.is-agarrada { cursor: grabbing; }
/* El manto y los botones traen su propio cursor de mano; la manita de arrastrar
   es para los huecos entre tarjetas. */
.vip__slides a { cursor: pointer; }
.vip__pista {
  display: flex; align-items: stretch; gap: 14px;
  will-change: transform;
  /* Los .45s van de la mano con `VIP_DESLIZ` en el JS: al dar la vuelta, ése
     es el tiempo que espera antes de cambiar la copia del final por el
     original. Si se cambia aquí, se cambia allá. */
  transition: transform .45s cubic-bezier(.2,.8,.3,1);
}
/* Sin animaciones no hay deslizamiento: el cambio de página es instantáneo. */
.vip--quieto .vip__pista { transition: none; }

/* Una página. El ancho lo calcula el JS con el de la ventana para que caiga
   justo, y los negocios se reparten a lo alto. Si el último grupo queda impar,
   su única tarjeta se centra en la columna en vez de pegarse arriba. */
/* `min-width: 0`: sin él, el renglón de la zona —que no se parte— ensanchaba
   la página más allá de la ventana. */
.vip__grupo {
  flex: 0 0 var(--vip-w, 100%); min-width: 0;
  display: flex; flex-direction: column; justify-content: center; gap: 14px;
}

/* La tarjeta es apaisada en cualquier pantalla: el texto y la foto van lado a
   lado y la barra de contacto cruza abajo. Así dos de ellas caben una encima
   de la otra en la columna del hero sin verse como torres. */
.vip__slide {
  position: relative;
  display: flex; flex-direction: column; justify-content: space-between; gap: 6px;
  padding: 13px 14px;
  background: var(--banner, linear-gradient(135deg, #0f766e, #115e59));
  color: #fff;
  border-radius: var(--radius-lg);
  /* El marco del plan: el mismo anillo de acento que llevan las fichas
     Premium en los listados, para que el banner de la portada se reconozca
     como del mismo plan y no como una tarjeta más. Va por dentro (`border`)
     y no como anillo exterior, porque la ventana del carrusel recorta lo que
     se salga de la caja. El filo blanco por dentro lo despega del degradado
     de la categoría, que cambia de color en cada negocio. */
  border: 2px solid var(--accent);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.24), var(--shadow-md);
  overflow: hidden;
}
.vip__slide::before {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(80% 120% at 12% 0%, rgba(255,255,255,.18), transparent 62%),
    linear-gradient(180deg, transparent 40%, rgba(0,0,0,.3));
}
/* El manto: un enlace transparente tendido sobre toda la tarjeta, que la lleva
   entera a la ficha del negocio dentro de su categoría. Va por debajo del
   contenido para no taparlo, y el contenido deja pasar el clic —salvo lo que
   de verdad es otro enlace, que lo dice él mismo—. Envolverlo todo en un solo
   enlace no se puede: dentro hay otros, y un enlace dentro de otro no vale. */
.vip__manto {
  position: absolute; inset: 0; z-index: 1;
  border-radius: inherit; cursor: pointer;
}
/* Con cursor, la tarjeta se levanta un poco al pasar por encima: es lo que
   avisa de que lleva a algún lado. En táctil no hay `hover` que valga. */
@media (hover: hover) {
  .vip__slide:has(.vip__manto:hover) {
    box-shadow: inset 0 0 0 1px rgba(255,255,255,.3), var(--shadow-lg);
  }
}
.vip__cuerpo, .vip__acciones { position: relative; z-index: 2; }
.vip__cuerpo { pointer-events: none; }
.vip__mapa   { pointer-events: auto; }

/* Fila superior: texto a la izquierda, foto a la derecha. */
.vip__cuerpo { display: flex; flex-direction: row; align-items: center; gap: 12px; }
@media (min-width: 560px) { .vip__cuerpo { gap: 14px; } }

/* `min-width: 0` deja que el texto largo se corte en vez de estirar la
   diapositiva y desbordar la columna del hero. */
.vip__texto { flex: 1; min-width: 0; }

/* El nombre y la descripción van a dos renglones fijos —ni más, ni menos— para
   que todas las tarjetas midan exactamente lo mismo: en la columna del hero se
   apilan de dos en dos, y una más alta que la otra se nota de inmediato. */
.vip__nombre {
  overflow-wrap: break-word;
  margin: 6px 0 4px; font-size: 18px; font-weight: 700; letter-spacing: -.025em;
  line-height: 1.2;
  min-height: 2.4em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.vip__desc {
  margin: 0; max-width: 56ch; font-size: 12.5px; line-height: 1.4;
  color: rgba(255,255,255,.92);
  min-height: 2.8em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.vip__meta {
  margin: 7px 0 0; display: flex; align-items: center; gap: 6px;
  font-size: 11.5px; color: rgba(255,255,255,.85);
  white-space: nowrap; min-width: 0;
}
/* En un solo renglón, como el nombre y la descripción en los suyos: en los
   teléfonos angostos la categoría bajaba de renglón y esa tarjeta salía 24px
   más alta que las otras —y que el anuncio, que mide lo de las demás—. Si no
   cabe, la que se corta es la categoría, que el visitante ya conoce; la zona
   no, que es a donde tiene que ir. */
.vip__mapa { flex: none; }
.vip__cat { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.vip__meta svg { width: 13px; height: 13px; flex: none; }
/* La dirección lleva a la aplicación de mapas del aparato, así que se comporta
   como enlace: subraya al pasar el cursor. Sin color propio, que sobre el
   degradado de la categoría cualquiera desentona. */
/* Sobre el color del banner, el mismo subrayado de rayitas de las fichas,
   en blanco: aquí el enlace no puede cambiar de color. */
.vip__mapa {
  display: inline-flex; align-items: center; gap: 4px;
  color: inherit; font-weight: 600;
  text-decoration: underline dashed rgba(255,255,255,.7);
  text-decoration-thickness: 1px; text-underline-offset: 3px;
  transition: text-decoration-color .15s;
}
@media (hover: hover) {
  .vip__mapa:hover { text-decoration-style: solid; text-decoration-color: currentColor; }
}
.vip__mapa:focus-visible { text-decoration-style: solid; text-decoration-color: currentColor; }
.vip__sep { color: rgba(255,255,255,.5); }

/* Foto o logotipo del negocio, a la derecha del texto. Cuadrada, con
   `object-fit: cover` para que una imagen de cualquier proporción llene el
   recuadro sin deformarse. Sin `foto`, el mismo recurso que las tarjetas: las
   iniciales sobre el glifo de la categoría. */
.vip__foto {
  position: relative; flex: none;
  width: 88px; aspect-ratio: 1;
  align-self: center;
  border-radius: 12px; overflow: hidden;
  background: rgba(255,255,255,.13);
  border: 1px solid rgba(255,255,255,.22);
  display: grid; place-items: center;
}
@media (min-width: 560px) { .vip__foto { width: 104px; } }
.vip__foto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.vip__foto-ini {
  position: relative; z-index: 1;
  font-size: 23px; font-weight: 700; letter-spacing: -.04em;
  color: rgba(255,255,255,.95); text-shadow: 0 2px 10px rgba(0,0,0,.25);
}
.vip__foto-glifo {
  position: absolute; right: -10px; bottom: -12px; width: 62px; height: 62px;
  color: rgba(255,255,255,.16);
}

/* Fila inferior: barra de contacto a todo lo ancho de la tarjeta. Los
   márgenes negativos cancelan el relleno de la diapositiva para que llegue
   a los bordes, y se reutiliza `.act` tal cual, para que el color de marca
   al pasar el cursor y el atenuado táctil se comporten igual en toda la
   página. Alineados a la derecha y no repartidos: con `space-between` un
   negocio de dos enlaces los dejaría en las esquinas opuestas. */
.vip__acciones {
  margin: 2px -14px -13px; padding: 9px 14px;
  background: rgba(0,0,0,.2);
  border-top: 1px solid rgba(255,255,255,.14);
  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px;
}
.vip__acciones .act { width: 34px; height: 34px; padding: 8px; }

/* El botón es de 22px para que el dedo lo alcance; el punto visible va
   dentro, así el área táctil no depende del tamaño del indicador. */
.vip__dots { display: flex; justify-content: center; gap: 4px; margin-top: 8px; }
.vip__dot {
  width: 22px; height: 22px; padding: 0; border: 0; background: none;
  display: grid; place-items: center; cursor: pointer;
}
.vip__dot::before {
  content: ""; width: 8px; height: 8px; border-radius: 999px;
  background: var(--line-strong); transition: all .2s ease;
}
.vip__dot.is-active::before { width: 20px; background: var(--accent); }
/* Con el dedo el punto se queda chico para atinarle: el botón crece aunque el
   punto se vea igual. De todos modos el banner se puede arrastrar. */
@media (pointer: coarse) { .vip__dot { width: 34px; height: 30px; } }
@media (hover: hover) {
  .vip__dot:hover::before { background: var(--ink-3); }
  .vip__dot.is-active:hover::before { background: var(--accent); }
}

/* ==========================================================================
   CARRUSEL DE DESTACADOS  (portada, arriba de las categorías)
   ========================================================================== */
/* El marco sostiene la pista y las dos flechas. Las flechas son hermanas de la
   pista y no hijas: adentro las recortaría el `overflow`. */
.dest__marco { position: relative; }

/* La pista es la ventana por la que pasa el desfile, y mide exactamente lo
   mismo que la caja de contenido: empieza y termina donde el título de la
   sección y la cuadrícula de categorías. En los costados los banners se
   desvanecen en vez de cortarse en seco: así entran y salen del desfile sin
   que se vea el filo de la ventana, y el marco ámbar no aparece de golpe a
   media tarjeta. */
.dest__pista {
  position: relative;
  overflow: hidden;
  padding-block: 6px 12px;
  /* El dedo se lleva el carrusel de lado; el movimiento vertical sigue siendo
     de la página, si no el usuario quedaría atorado al querer bajar. */
  touch-action: pan-y;
  cursor: grab;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 24px,
                                      #000 calc(100% - 24px), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 24px,
                                      #000 calc(100% - 24px), transparent);
}
/* Con animaciones reducidas el carrusel no arranca solo; queda quieto en la
   primera tarjeta hasta que el usuario lo mueva. Y sin movimiento el
   desvanecido de la izquierda parecería un defecto, así que ahí se apaga. */
.dest__pista.is-manual { -webkit-mask-image: none; mask-image: none; }
.dest__pista.is-agarrada { cursor: grabbing; }
/* Los enlaces traen su propio cursor de mano; la manita de arrastrar es para
   los huecos entre tarjetas. */
.dest__pista a { cursor: pointer; }

/* La cinta lleva las tandas y es lo único que se mueve. `max-content` la deja
   crecer todo lo que necesite en vez de encogerse a la pista. El recorrido lo
   escribe el JS cuadro a cuadro: así el desfile automático, las flechas y el
   arrastre mueven todos la misma posición y ninguno pelea con el otro. */
.dest__cinta {
  display: flex; gap: 10px; width: max-content;
  will-change: transform;
}
.dest__grupo { display: flex; gap: 10px; }
/* Las mismas separaciones y los mismos cortes que la cuadrícula de categorías:
   2 tarjetas por pantalla en móvil, 3 desde 560px y 4 desde 900px. El ancho
   de cada una lo calcula el JS con esa cuenta, así el carrusel cae en la misma
   retícula que la cuadrícula de abajo. */
@media (min-width: 560px) { .dest__cinta, .dest__grupo { gap: 12px; } }
@media (min-width: 900px) { .dest__cinta, .dest__grupo { gap: 14px; } }

/* El banner es toda la tarjeta: la imagen del negocio, el sello de Destacado
   encima y nada más. Es un enlace a la ficha completa dentro de su categoría,
   así que lo que aquí se gana en limpieza se recupera de un toque. El ancho lo
   calcula el JS; el alto sale de la proporción, más apaisada en escritorio que
   en el teléfono, donde el banner es angosto y aplastarlo lo dejaría en una
   tira. */
.dest__card {
  flex: 0 0 var(--dest-w, 260px);
  position: relative;
  display: grid; place-items: center;
  aspect-ratio: 4 / 3;
  background: var(--banner, linear-gradient(135deg, #0f766e, #115e59));
  /* El marco del plan, del mismo grosor que el de los Premium de la portada:
     dos píxeles macizos, ahí del acento y aquí del ámbar de Destacado, para
     que los dos banners se lean como marcos de plan y no uno como marco y el
     otro como un filo. El filo blanco por dentro lo despega de la imagen o del
     degradado de la categoría, que cambia de color en cada negocio. */
  border: 2px solid var(--gold);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.24), var(--shadow-sm);
  transition: box-shadow .16s, transform .16s cubic-bezier(.2,.8,.3,1);
}
@media (min-width: 560px) { .dest__card { aspect-ratio: 3 / 2; } }

@media (hover: hover) {
  .dest__card:hover {
    transform: translateY(-2px);
    box-shadow: inset 0 0 0 1px rgba(255,255,255,.3), var(--shadow-md);
  }
}

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

/* Un velo para que el sello se lea sobre cualquier imagen. */
.dest__card::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(90% 130% at 15% 0%, rgba(255,255,255,.20), transparent 60%),
    linear-gradient(180deg, rgba(0,0,0,.22) 22%, transparent 55%);
}

/* Sin `foto`: las iniciales sobre el glifo de la categoría, para que el banner
   no sea un rectángulo de color a secas. Centradas de verdad: el sello vive
   sobre ellas, en su propia capa, y no les quita el medio. */
.dest__ini {
  position: relative; z-index: 1;
  font-size: 21px; font-weight: 700; letter-spacing: -.04em;
  color: rgba(255,255,255,.94); text-shadow: 0 2px 10px rgba(0,0,0,.28);
}
.dest__glifo {
  position: absolute; right: -9px; bottom: -12px; width: 60px; height: 60px;
  color: rgba(255,255,255,.16); z-index: 1;
}

/* Flechas flotantes sobre los costados. Sólo en pantallas grandes: en el
   teléfono taparían media tarjeta, y ahí el carrusel se lleva con el dedo. */
.dest__flecha { display: none; }

@media (min-width: 768px) {
  .dest__flecha {
    position: absolute; top: 50%; z-index: 2;
    display: grid; place-items: center;
    width: 40px; height: 40px; padding: 0;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    /* Traslúcida sobre la tarjeta que pasa por detrás: en oscuro cae en el
       mismo gris de las tarjetas, en claro en blanco. */
    background: color-mix(in srgb, var(--surface) 84%, transparent);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    color: var(--ink-2);
    box-shadow: var(--shadow-md);
    cursor: pointer;
    transform: translateY(-50%);
    transition: background .16s, color .16s, border-color .16s;
  }
  /* Gana al `display: grid` de arriba mientras el JS no las haya encendido. */
  .dest__flecha[hidden] { display: none; }
  .dest__flecha svg { width: 20px; height: 20px; }
  .dest__flecha--izq { left: 8px; }
  .dest__flecha--der { right: 8px; }

  /* Al apuntarles se encienden en el verde de la marca, con el mismo tinte
     oscuro que llevan los botones de WhatsApp para que el ícono se lea. */
  .dest__flecha:hover,
  .dest__flecha:focus-visible {
    background: var(--wa); border-color: transparent; color: #06301a;
  }
  .dest__flecha:active { transform: translateY(-50%) scale(.94); }
}

/* ==========================================================================
   ENCABEZADOS DE SECCIÓN
   ========================================================================== */

.section-head { margin: 24px 0 14px; }
.section-head--mt { margin-top: 22px; }
.section-head__title {
  margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -.025em;
}
@media (min-width: 768px) { .section-head__title { font-size: 22px; } }
.section-head__sub { margin: 4px 0 0; font-size: 14px; color: var(--ink-3); }

/* --- El embudo del buscador y de las categorías ---
   A la derecha de lo que se encontró, a la altura del texto. Abre un menú
   corto debajo de él; por ahora trae una sola opción, ordenar por cercanía.
   Prendida, el botón se pinta del color de la guía y dice qué orden lleva la
   lista, para que no se olvide que no es el de siempre. */
.busca-meta {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 6px;
}
.busca-meta .section-head__sub { margin: 0; }
.orden { position: relative; flex: none; }
.orden__btn {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 38px; padding: 0 14px; border-radius: 999px; cursor: pointer;
  font-size: 13.5px; font-weight: 600; letter-spacing: -.01em;
  background: var(--surface); color: var(--ink-2);
  border: 1px solid var(--line-strong);
  transition: background .15s, color .15s, border-color .15s, transform .12s;
}
.orden__btn svg { width: 15px; height: 15px; flex: none; }
.orden__btn:hover { color: var(--ink); border-color: var(--ink-3); }
.orden__btn:active { transform: scale(.96); }
.orden__btn:disabled { cursor: progress; opacity: .7; }
.orden__btn.is-activo { background: var(--accent); border-color: var(--accent); color: var(--surface); }
.orden__btn.is-activo svg { fill: currentColor; }
.orden__menu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 25;
  width: min(300px, calc(100vw - 32px));
  padding: 6px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-md);
}
.orden__opcion {
  display: flex; align-items: flex-start; gap: 10px; width: 100%;
  padding: 10px; border: 0; border-radius: 10px; cursor: pointer;
  background: none; color: var(--ink); text-align: left;
}
.orden__opcion:hover { background: var(--surface-2); }
.orden__opcion > svg { width: 18px; height: 18px; flex: none; margin-top: 1px; color: var(--accent); }
.orden__texto { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; }
.orden__texto strong { font-size: 14px; font-weight: 650; }
.orden__texto small { font-size: 12.5px; line-height: 1.4; color: var(--ink-3); }
.orden__check { visibility: hidden; }
.orden__opcion[aria-pressed="true"] .orden__check { visibility: visible; }

/* Los metros hasta el negocio, junto a su dirección, cuando la lista va por
   cercanía. En pastilla, para que se lea de un vistazo bajando la lista. */
.distancia {
  flex: none; white-space: nowrap;
  padding: 1px 8px; border-radius: 999px;
  font-size: 11.5px; font-weight: 650; font-variant-numeric: tabular-nums;
  background: var(--accent-soft); color: var(--accent-ink);
}

/* ==========================================================================
   CUADRÍCULA DE CATEGORÍAS  (2 col móvil → 4 col escritorio)
   ========================================================================== */

.grid {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
@media (min-width: 560px) { .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; } }
@media (min-width: 900px) { .grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; } }

.cat {
  position: relative; width: 100%; height: 100%; text-align: left;
  display: flex; flex-direction: column; gap: 10px; justify-content: flex-start;
  padding: 14px; cursor: pointer;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  transition: transform .16s cubic-bezier(.2,.8,.3,1), box-shadow .16s, border-color .16s;
}
@media (min-width: 768px) { .cat { padding: 18px; } }

/* Invitación a registrarse, al final de la portada. */
.alta {
  margin: 20px 0 0; padding: 20px;
  display: flex; flex-direction: column; gap: 14px;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: var(--radius-lg);
}
.alta__titulo { margin: 0; font-size: 18px; font-weight: 700; letter-spacing: -.02em; }
.alta__sub { margin: 6px 0 0; font-size: 14px; color: var(--ink-2); max-width: 56ch; }
.alta__btn {
  align-self: flex-start;
  /* El texto toma el color de la superficie: blanco sobre el verde oscuro
     del modo claro y oscuro sobre el verde brillante del modo oscuro. */
  background: var(--accent); color: var(--surface); padding: 11px 18px;
}
.alta__btn:hover { background: var(--accent-ink); }
@media (min-width: 768px) {
  .alta { flex-direction: row; align-items: center; justify-content: space-between; padding: 24px 28px; }
  .alta__btn { align-self: center; }
}

.cat:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--line-strong); }
.cat:active { transform: translateY(-1px); }

.cat__icon {
  width: 40px; height: 40px; flex: none; padding: 9px;
  border-radius: 11px;
  background: var(--cat-soft, var(--accent-soft));
  color: var(--cat-color, var(--accent));
  transition: transform .16s;
}
.cat:hover .cat__icon { transform: scale(1.06) rotate(-3deg); }
@media (min-width: 768px) { .cat__icon { width: 44px; height: 44px; padding: 10px; } }

/* El nombre y las especialidades van seguidos y comparten cuatro renglones:
   si el nombre cabe en uno, las especialidades usan tres; si ocupa dos, usan
   dos. Así todas las tarjetas miden lo mismo y no queda el hueco que dejaba
   un nombre corto junto a uno largo, con las especialidades empujadas hasta
   abajo. Los dos llevan el mismo alto de renglón para que la cuenta salga. */
.cat__texto {
  --renglon: 18.2px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4;
  overflow: hidden;
  min-height: calc(var(--renglon) * 4);
}
.cat__name {
  display: block;
  margin: 0; font-size: 14px; font-weight: 650; line-height: var(--renglon);
  letter-spacing: -.015em;
}
@media (min-width: 768px) {
  .cat__texto { --renglon: 19px; }
  .cat__name { font-size: 15px; }
}

.cat__meta {
  display: block; margin: 0;
  font-size: 13px; line-height: var(--renglon); color: var(--ink-3);
}
.cat__dot {
  display: inline-block; width: 5px; height: 5px; border-radius: 50%;
  margin-right: 5px; vertical-align: 2px;
  background: var(--cat-color, var(--accent)); flex: none;
}

/* ==========================================================================
   VISTA CATEGORÍA — cabecera + filtros
   ========================================================================== */

.catbar {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding-top: 16px;
}
/* En el teléfono, dentro de una categoría, sólo los filtros se quedan pegados
   arriba. El encabezado de la guía y la cabecera de la categoría —el regreso,
   el ícono y el título— se van con la página al bajar y no vuelven con
   cualquier subida: reaparecen al llegar otra vez hasta arriba, en su lugar
   de siempre. Antes iban pegados los dos, se recogían al bajar y regresaban
   en cuanto el dedo subía un poco, y juntos se comían casi la mitad de la
   pantalla. Para volver a las categorías también está el "atrás" del
   teléfono.

   El truco es que la barra entera va pegada, pero con el tope en negativo: se
   pega cuando ya subió todo lo que tiene arriba de los filtros
   (`--catbar-arriba`, lo mide app.js), así que eso sale de la pantalla y los
   filtros se quedan en el borde. Lo único que tapan son ellos mismos. */
@media (max-width: 899.98px) {
  [data-vista="category"] .header { position: relative; }
  .catbar { position: sticky; top: calc(-1 * var(--catbar-arriba, 0px)); z-index: 30; }
  :root[data-vista="category"] { --pegado: calc(var(--catbar-h, 0px) - var(--catbar-arriba, 0px)); }
}

.backlink {
  display: inline-flex; align-items: center; gap: 4px;
  background: none; border: 0; padding: 0 0 12px; cursor: pointer;
  font-size: 13px; font-weight: 600; color: var(--ink-3);
}
.backlink:hover { color: var(--accent); }
.backlink svg { width: 15px; height: 15px; }

.catbar__head { display: flex; align-items: center; gap: 13px; padding-bottom: 14px; }
.catbar__icon {
  width: 46px; height: 46px; flex: none; padding: 11px; border-radius: 13px;
  background: var(--cat-soft, var(--accent-soft)); color: var(--cat-color, var(--accent));
}
.catbar__title { margin: 0; font-size: 20px; font-weight: 700; letter-spacing: -.025em; }
@media (min-width: 768px) { .catbar__title { font-size: 26px; } }
.catbar__sub { margin: 2px 0 0; font-size: 13px; color: var(--ink-3); }

/* --- Barra de filtros / tags --- */
.filters { border-top: 1px solid var(--line); }
.filters__scroll {
  display: flex; gap: 8px; overflow-x: auto; padding-block: 12px;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
}
.filters__scroll::-webkit-scrollbar { display: none; }

.chip {
  flex: none; scroll-snap-align: start;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: 999px; cursor: pointer;
  font-size: 13.5px; font-weight: 600; letter-spacing: -.01em;
  background: var(--surface-2); color: var(--ink-2);
  border: 1px solid var(--line);
  transition: background .15s, color .15s, border-color .15s, transform .12s;
}
.chip:hover { border-color: var(--line-strong); color: var(--ink); }
.chip:active { transform: scale(.96); }
.chip[aria-selected="true"] {
  background: var(--ink); color: var(--bg); border-color: var(--ink);
}

.results-meta {
  padding: 18px 0 12px; font-size: 13px; color: var(--ink-3); font-weight: 500;
  /* Lo que se está viendo a la izquierda y el embudo a la derecha, como en
     el buscador. */
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}

/* ==========================================================================
   TARJETAS DE NEGOCIO
   ========================================================================== */

.cards { display: grid; gap: 14px; padding-bottom: 8px; }
@media (min-width: 700px) { .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1080px) { .cards { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* Por cercanía la lista es un escalafón —el primero es el más cercano, luego
   el que sigue—, y un escalafón se lee en una sola columna. En dos o tres
   columnas no se sabía si el orden iba por renglón o por columna, y una ficha
   gratuita al lado de una tarjeta dejaba un hueco del alto de la tarjeta. */
.cards.cards--cercania { grid-template-columns: minmax(0, 680px); }

.card {
  /* Al llegar desde un banner del carrusel, la página abre desde arriba y sólo
     baja si la ficha no cabe entera —en el teléfono, donde las fichas van en
     una columna—. Este margen es el que evita que, cuando baja, quede metida
     debajo del encabezado pegado. */
  scroll-margin-top: calc(var(--pegado) + 12px);
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform .16s cubic-bezier(.2,.8,.3,1), box-shadow .16s;
  animation: rise .3s cubic-bezier(.2,.8,.3,1) backwards;
}
.card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }

@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .card { animation: none; }
  *, *::before, *::after { transition-duration: .01ms !important; }
}

/* La ficha gratuita: un renglón, no una tarjeta. Ocupa el ancho completo de la
   retícula —abajo de las que pagan, que es donde las deja el orden— y mide lo
   que mide su contenido: nombre, dónde está, a qué hora abre y el botón de
   llamar. En un teléfono caben diez donde antes cabía una tarjeta. */
/* El bloque de las fichas gratuitas, debajo de las tarjetas y aparte de ellas.
   Aparte porque un renglón no cabe en una columna de tarjeta: tenía que ocupar
   el ancho entero de la retícula y en una pantalla grande quedaba como una
   tira larguísima, con el nombre pegado a la izquierda y el botón de llamar
   perdido en la otra orilla. En dos columnas se lee como lo que es, un listado
   debajo de las tarjetas, y de paso la última fila de tarjetas deja de parecer
   una tarjeta faltante: el filo de arriba dice dónde termina una cosa y
   empieza la otra. */
.filas {
  grid-column: 1 / -1;
  display: grid; gap: 10px;
}
/* Cada pila son hasta tres fichas gratuitas, una encima de otra, ocupando el
   lugar de una tarjeta. La pila se estira a lo alto de la fila —o sea, a lo
   que mide la tarjeta de al lado— y las fichas se quedan pegadas arriba: el
   espacio de abajo queda apartado de antemano, así que al desplegar un horario
   crece dentro de lo que ya tenía y no empuja nada. */
.pila { display: flex; flex-direction: column; gap: 10px; }
/* La pila llena se reparte el alto de la tarjeta, pero el sobrante se lo
   quedan las fichas, no los huecos: cada una crece un poco y su contenido
   queda centrado, así que el aire va por dentro —donde se lee como holgura de
   la ficha— y no por fuera, donde se leía como un espacio olvidado. Al
   desplegar un horario esa ficha pide más y las otras devuelven su parte, así
   que el conjunto sigue midiendo lo mismo que la tarjeta de al lado.

   Sólo la pila completa: si el último grupo trae una o dos fichas, estirarlas
   las dejaría como dos cajones enormes medio vacíos, y ahí es mejor que se
   queden de su tamaño, juntas arriba. */
.pila:has(> :nth-child(3)) > .card--fila { flex: 1 1 auto; }

/* Dentro de una pila el renglón va en una columna angosta, así que se aprieta:
   el nombre y el aviso se quedan en una sola línea —el nombre largo se corta
   con puntos suspensivos, y completo sigue en el `title` del enlace del mapa—
   y la tabla del horario baja de tamaño. Es lo que hace que tres fichas más un
   horario desplegado quepan en el alto de una tarjeta, que es el trato: la
   pila no crece más que la tarjeta de al lado. En el teléfono no aplica, ahí
   el renglón tiene el ancho entero y no le falta lugar. */
@media (min-width: 700px) {
  .pila .fila__nombre { flex-wrap: nowrap; }
  .pila .fila__rotulo {
    min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  .pila .horario__semana { font-size: 11.5px; margin-top: 5px; }
  .pila .horario__semana th { padding: 1px 10px 1px 0; }
  .pila .horario__semana td { padding: 1px 0; }
}
/* El filo sólo cuando hay tarjetas arriba de qué separarse. */
.card + .filas { margin-top: 6px; padding-top: 16px; border-top: 1px solid var(--line); }

/* --- El bloque se mete en el hueco de la última fila de tarjetas ---

   Si hay cuatro tarjetas en tres columnas sobran dos lugares, y el bloque
   abriendo renglón nuevo dejaba ese espacio vacío como si faltara una tarjeta.
   Aquí, en vez de abrir renglón, el bloque se acomoda en los lugares que
   sobraron.

   Se sabe cuántos sobran sin una línea de JS: el bloque es el último hijo, así
   que su número de hijo dice cuántas tarjetas van antes. Con tres columnas, si
   le toca el 3n+2 es que quedaron 3n+1 tarjetas —una sola en la última fila— y
   sobran dos lugares; si le toca el 3n+3, sobra uno. Al ser CSS y no JS, la
   cuenta se rehace sola cuando cambia el ancho de la ventana.

   El `:not(:has(…))` es el freno: sólo se mete al hueco si hay pilas para los
   lugares que sobraron, ni una más. Si sobrara una pila el bloque crecería más
   que la tarjeta de al lado, la estiraría y dejaría un hueco peor del que
   veníamos a quitar. Pasado ese número —o en un navegador viejo, sin `:has()`—
   cae de vuelta al renglón completo de abajo, que siempre se ve bien. */

/* Dos columnas */
@media (min-width: 700px) and (max-width: 1079.98px) {
  .filas { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Sobra un lugar: cabe una pila. */
  .filas:nth-child(2n + 2):not(:has(> :nth-child(2))) {
    grid-column: 2 / -1;
    grid-template-columns: minmax(0, 1fr);
    margin-top: 0; padding-top: 0; border-top: 0;
  }
}

/* Tres columnas */
@media (min-width: 1080px) {
  .filas { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  /* Sobran dos lugares: caben dos pilas. */
  .filas:nth-child(3n + 2):not(:has(> :nth-child(3))) {
    grid-column: 2 / -1;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-top: 0; padding-top: 0; border-top: 0;
  }
  /* Sobra uno: cabe una pila. */
  .filas:nth-child(3n + 3):not(:has(> :nth-child(2))) {
    grid-column: 3 / -1;
    grid-template-columns: minmax(0, 1fr);
    margin-top: 0; padding-top: 0; border-top: 0;
  }
}

.card--fila {
  flex-direction: row; align-items: center; gap: 12px;
  padding: 10px 12px;
}
.fila__sello {
  flex: none; width: 44px; height: 44px; border-radius: 11px;
  background: var(--banner, var(--surface-2));
  display: grid; place-items: center; position: relative; overflow: hidden;
}
/* Sin iniciales: el icono de la categoría al centro y a plena luz. Dos letras
   sobre un cuadro de 44px no se leen y no dicen nada —"CM" no es nadie—;
   el icono, en cambio, dice de qué es el negocio de un vistazo, y es el mismo
   dibujo con el que la persona acaba de entrar a la categoría. */
.fila__glifo {
  width: 22px; height: 22px;
  color: rgba(255,255,255,.95);
}
.fila__texto { flex: 1 1 auto; min-width: 0; }
.fila__nombre {
  margin: 0; font-size: 15px; font-weight: 600; letter-spacing: -.01em;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.fila__estado {
  font-size: 10.5px; font-weight: 600; letter-spacing: .02em;
  padding: 2px 7px; border-radius: 999px; white-space: nowrap;
}
.fila__estado--abierto { background: color-mix(in srgb, var(--abierto) 15%, transparent); color: var(--abierto); }
.fila__estado--cita    { background: color-mix(in srgb, var(--brand-web) 14%, transparent); color: var(--brand-web); }
.fila__estado--cerrado { background: var(--surface-2); color: var(--ink-3); }
/* La zona y el horario van uno al lado del otro y bajan de renglón si no
   caben. Sin punto separador a propósito: al envolverse quedaría colgando al
   principio de la segunda línea. */
.fila__meta {
  margin: 2px 0 0; font-size: 12.5px; color: var(--ink-3);
  display: flex; align-items: center; gap: 2px 14px; flex-wrap: wrap;
}
.fila__meta svg { width: 13px; height: 13px; }
.fila__horario { display: inline-flex; align-items: center; gap: 4px; }
/* Un solo botón: no necesita el aire que separa a los siete de una ficha de
   pago, ni el borde de arriba que los despega del cuerpo de la tarjeta. */
.card__actions.fila__accion { margin: 0; padding: 0; border: 0; }
/* El teléfono a la vista en los aparatos que no llaman: escrito igual que la
   zona —icono y texto, al hilo del renglón—, no en pastilla. En una
   computadora el número no está para apretarlo, está para leerlo y copiarlo,
   así que no necesita cuerpo de botón; lo que sí necesita es que se note, y
   por eso va con el color de acento y en negritas mientras los demás datos van
   en tinta apagada. Al hacerle clic se copia, igual que la pastilla. */
.card--fila .fila__tel {
  height: auto; padding: 0; border: 0; border-radius: 0; background: none;
  gap: 5px; font-size: 12.5px; font-weight: 650;
  color: var(--accent);
  border-bottom: 1px dashed transparent;
}
/* Renglón propio, no al hilo de la zona: pegado a ella el número no ocuparía
   nada y el espacio entre una ficha y otra volvería a quedar en blanco. El
   ancho completo lo toma el envoltorio, no el enlace, para que el subrayado
   del cursor se quede debajo de las cifras y no cruce la ficha entera. */
.card--fila .fila__contacto { flex: 0 0 100%; }
.card--fila .fila__sin-tel { font-size: 12.5px; color: var(--ink-3); }
/* Con la semana desplegada el número se quita: los dos se turnan el renglón,
   así la tabla entra donde estaba el número en vez de empujar a la tarjeta de
   al lado. Al cerrar el horario, el número vuelve. */
.card--fila:has(.horario--fila[open]) .fila__contacto { display: none; }
.card--fila .fila__tel svg { width: 13px; height: 13px; opacity: 1; }
.card--fila .fila__tel:hover { color: var(--accent-ink); border-bottom-color: currentColor; }
.card--fila .fila__tel:active { transform: none; }
.card--fila .fila__tel.is-copiado { color: var(--abierto); border-bottom-color: transparent; }

/* En el teléfono la columna del texto es angosta: el sello y el relleno ceden
   unos píxeles para que el nombre y la zona quepan en menos renglones. */
@media (max-width: 559.98px) {
  .card--fila { padding: 9px 10px; gap: 10px; }
  .fila__sello { width: 40px; height: 40px; border-radius: 10px; }
  .fila__glifo { width: 20px; height: 20px; }
}

/* Anillos por plan: dorado para el destacado, del color de acento para el
   premium. Las fichas completas se quedan con el borde neutro de `.card`. */
.card--featured {
  border-color: color-mix(in srgb, var(--gold) 38%, var(--line));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--gold) 18%, transparent), var(--shadow-md);
}
.card--vip {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--line));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 20%, transparent), var(--shadow-md);
}

/* La ficha a la que llevó un banner —el del carrusel de destacados o el de la
   portada de un Premium—. La página abre desde arriba, como cualquier
   categoría, así que lo primero que se ve es de qué categoría se trata; para no
   perder de vista cuál era el negocio, su ficha late tres veces al llegar. El
   anillo se queda después de los latidos: el banner no traía nombre y sin esa
   marca habría que adivinar.

   El color del aro es el del plan del negocio: dorado para un destacado, el de
   acento para un Premium. Marcarlos a todos de dorado le quitaría al Premium
   justo lo que lo distingue en el listado. */
.card.is-resaltada {
  --aro: var(--gold);
  border-color: color-mix(in srgb, var(--aro) 70%, var(--line));
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--aro) 45%, transparent), var(--shadow-lg);
  /* Se repite `rise` porque el atajo `animation` de `.card` se pierde al
     redeclararlo aquí, y sin él la tarjeta no haría su entrada. */
  animation: rise .3s cubic-bezier(.2,.8,.3,1) backwards,
             latido .85s ease-out 3;
}
.card--vip.is-resaltada { --aro: var(--accent); }
/* Tres aros que salen de la ficha y se desvanecen. Sólo mueven la sombra: el
   `transform` es de `rise`, que corre a la vez —las tarjetas llevan su retraso
   de entrada en el atributo `style`, y ese retraso pisa cualquiera que se ponga
   aquí, así que las dos animaciones se solapan por fuerza—. */
@keyframes latido {
  0% {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--aro) 45%, transparent),
                0 0 0 0 color-mix(in srgb, var(--aro) 55%, transparent);
  }
  55% {
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--aro) 80%, transparent),
                0 0 0 20px color-mix(in srgb, var(--aro) 0%, transparent);
  }
  100% {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--aro) 45%, transparent),
                0 0 0 0 transparent;
  }
}
@media (prefers-reduced-motion: reduce) {
  .card.is-resaltada { animation: none; }
}

/* --- Banner --- */
.card__banner {
  position: relative; aspect-ratio: 16 / 6;
  display: grid; place-items: center;
  background: var(--banner, linear-gradient(135deg, #0f766e, #115e59));
  overflow: hidden;
}
.card__banner::after {
  content: ""; position: absolute; inset: 0;
  background:
    radial-gradient(90% 130% at 15% 0%, rgba(255,255,255,.22), transparent 60%),
    linear-gradient(180deg, transparent 45%, rgba(0,0,0,.28));
}
.card__initials {
  position: relative; z-index: 1;
  font-size: 30px; font-weight: 700; letter-spacing: -.04em;
  color: rgba(255,255,255,.94);
  text-shadow: 0 2px 10px rgba(0,0,0,.28);
}
.card__glyph {
  position: absolute; right: -14px; bottom: -18px; width: 96px; height: 96px;
  color: rgba(255,255,255,.16); z-index: 1;
}

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: .01em;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.badge svg { width: 12px; height: 12px; }

.badge--featured {
  background: linear-gradient(135deg, #fbbf24, #f59e0b);
  color: #422006;
  box-shadow: 0 2px 8px rgba(180,83,9,.35);
}
.badge--vip {
  background: linear-gradient(135deg, var(--accent), var(--accent-ink));
  color: #ffffff;
  box-shadow: 0 2px 8px color-mix(in srgb, var(--accent) 38%, transparent);
}
/* En oscuro el acento se aclara: el texto del badge pasa a tinta oscura. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .badge--vip { color: #06302c; }
}
:root[data-theme="dark"] .badge--vip { color: #06302c; }
/* --- Cuerpo --- */
.card__body { display: flex; flex-direction: column; gap: 9px; padding: 14px 15px 15px; flex: 1; }

.card__title { margin: 0; font-size: 16.5px; font-weight: 700; letter-spacing: -.025em; line-height: 1.25; }
/* El nombre y, a su derecha, si está abierto. El nombre largo baja de renglón;
   el sello no se parte. */
.card__cabeza { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.card__cabeza .fila__estado { flex: none; margin-top: 1px; font-size: 11.5px; padding: 3px 9px; }

.card__line {
  display: flex; align-items: center; gap: 6px;
  font-size: 12.5px; color: var(--ink-3); margin: 0;
}
.card__line svg { width: 13px; height: 13px; flex: none; }

/* --- Horario desplegable ---
   A la vista queda sólo lo de hoy; la semana entera vive detrás del "Ver
   horario". Los negocios que cierran a comer necesitan cuatro renglones para
   decir su horario, y cuatro renglones en cada tarjeta dejarían la lista
   ilegible. Es un <details>, así que abre y cierra sin una línea de JS y el
   lector de pantalla lo anuncia solo. */
.horario { font-size: 12.5px; color: var(--ink-3); }
.horario__hoy {
  display: flex; align-items: center; gap: 6px;
  cursor: pointer; list-style: none;
}
/* El triangulito que trae el navegador estorba: hay uno propio a la derecha. */
.horario__hoy::-webkit-details-marker { display: none; }
.horario__hoy svg { width: 13px; height: 13px; flex: none; }
.horario__hoy:hover .horario__ver { color: var(--accent-ink); }
.horario__ver {
  margin-left: auto; flex: none;
  font-size: 11.5px; font-weight: 600; color: var(--accent);
}
.horario__ver::after {
  content: '▾'; display: inline-block; margin-left: 4px;
  transition: transform .18s ease;
}
.horario[open] .horario__ver::after { transform: rotate(180deg); }
.horario[open] .horario__ver { font-size: 0; }        /* abierto ya no hay qué decir */
.horario[open] .horario__ver::after { font-size: 11.5px; }

.horario__semana {
  width: 100%; margin: 7px 0 0; border-collapse: collapse;
  font-size: 12px; font-variant-numeric: tabular-nums;
}
.horario__semana th {
  text-align: left; font-weight: 600; color: var(--ink-2);
  padding: 4px 12px 4px 0; white-space: nowrap;
}
.horario__semana td { text-align: right; color: var(--ink-3); padding: 4px 0; }
.horario__semana tr + tr th,
.horario__semana tr + tr td { border-top: 1px solid var(--line); }
/* El día de hoy se marca: es el renglón que la persona vino a buscar. */
.horario__semana .es-hoy th,
.horario__semana .es-hoy td { color: var(--ink); font-weight: 650; }

/* En el renglón gratuito el horario va al lado de la zona, no en su propio
   párrafo, así que el "Ver horario" se queda en el puro triangulito: ahí no
   hay ancho para la palabra. Cerrado no ocupa alto, o sea que el renglón mide
   exactamente lo que medía antes. */
.horario--fila .horario__hoy { gap: 4px; display: inline-flex; }
.horario--fila .horario__ver { margin-left: 3px; font-size: 0; }
.horario--fila .horario__ver::after { font-size: 10px; margin-left: 0; }
/* Al abrirse se lleva su propio renglón para que la tabla salga a lo ancho;
   cerrado se acomoda en la misma línea que la zona. */
.fila__meta .horario--fila[open] { flex: 1 1 100%; margin-top: 2px; }


.card__desc {
  margin: 0; font-size: 13.5px; color: var(--ink-2); line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 0; padding: 0; list-style: none; }
.tag {
  font-size: 12.5px; font-weight: 600; color: var(--ink-2);
  background: var(--surface-2); border: 1px solid var(--line);
  padding: 3px 9px; border-radius: 7px;
  display: block; text-decoration: none; transition: border-color .15s, color .15s;
}
.tag:hover, .tag:focus-visible { border-color: currentColor; color: var(--ink); }
.card--featured .tag { background: var(--gold-soft); border-color: color-mix(in srgb, var(--gold) 22%, transparent); color: var(--gold); }
.card--vip .tag { background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 22%, transparent); color: var(--accent-ink); }

/* --- Dirección enlazada a Google Maps ---
   En gris y sin subrayar se leía como un dato más y nadie la tocaba. Va en el
   color de los enlaces de la guía y subrayada con rayitas: la forma de decir
   "esto se toca" sin que pese como un botón. El subrayado va en el texto y no
   debajo del pin. Al pasar el cursor el subrayado se vuelve línea entera. */
.card__mapa {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--accent-ink); font-weight: 550;
  text-decoration: underline dashed color-mix(in srgb, currentColor 55%, transparent);
  text-decoration-thickness: 1px; text-underline-offset: 3px;
  transition: color .15s, text-decoration-color .15s;
}
.card__mapa svg { color: var(--accent); }
.card__mapa:hover, .card__mapa:focus-visible {
  color: var(--accent); text-decoration-style: solid; text-decoration-color: currentColor;
}

/* --- Fila de botones circulares de contacto --- */
.card__actions {
  margin-top: auto; padding-top: 14px;
  display: flex; flex-wrap: wrap; gap: 9px;
}

.act {
  width: 42px; height: 42px; flex: none; padding: 10px;
  display: grid; place-items: center; border-radius: 50%;
  border: 1px solid var(--line-strong);
  background: var(--surface); color: var(--ink-2);
  transition: all .2s ease;
}
.act svg { width: 100%; height: 100%; }
.act:active { transform: translateY(0) scale(.94); }

/* Color oficial de cada botón, en una variable para no repetir las reglas
   entre el modo con cursor y el táctil. */
.act--wa        { --marca: var(--wa); }
.act--tel       { --marca: var(--accent); }
.act--mapa      { --marca: var(--accent); }
.act--correo    { --marca: var(--brand-mail); }
.act--web       { --marca: var(--brand-web); }
.act--facebook  { --marca: var(--brand-fb); }
.act--instagram { --marca: var(--brand-ig); }
.act--tiktok    { --marca: var(--ink); }

/* Con cursor: gris en reposo y color de marca al pasar por encima. El
   levantamiento vive aquí porque en táctil el :hover se queda pegado
   después de tocar. */
@media (hover: hover) {
  .act:hover {
    transform: translateY(-2px); box-shadow: var(--shadow-sm);
    border-color: var(--marca, var(--line-strong)); color: var(--marca, var(--ink-2));
  }
}

/* Táctil: la marca se reconoce de un vistazo y el aro se enciende mientras el
   dedo la mantiene pulsada. Antes iba al 50% de opacidad para no saturar la
   tarjeta, y en el teléfono —donde entra casi toda la gente— los botones se
   veían apagados, como si no sirvieran. */
@media (hover: none) {
  .act { color: var(--marca, var(--ink-2)); }
  .act:active { border-color: var(--marca, var(--line-strong)); }
}

/* --- WhatsApp y Llamar, grandes y con su nombre ---
   Son los que traen clientes, así que van en su propio renglón a lo ancho de
   la tarjeta y con letra, no como un círculo más entre las redes. WhatsApp es
   el principal: el verde de la marca con la tinta oscura de los otros botones
   de WhatsApp de la guía, que en blanco sobre ese verde no se leería. Llamar
   es el segundo, en el tono de la guía y más quieto, para que no compitan. */
/* Dos columnas de rejilla y no `flex: 1`: con flex el botón de WhatsApp, que
   trae relleno, se quedaba con más ancho que el del teléfono, que va envuelto
   en una caja sin relleno. La rejilla las deja iguales al píxel. Si el negocio
   no tiene WhatsApp, el de llamar se queda con el renglón entero. */
.act-principal {
  flex: 1 1 100%;
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px;
}
/* Con las dos clases, para ganarle al `.act` de 40px de la computadora. El
   icono va pegado a la orilla izquierda, en su disco, y el nombre se centra
   en lo que queda: centrados los dos juntos dejaban las orillas vacías. */
.act.act--grande {
  width: 100%; height: 50px; padding: 0 12px 0 6px;
  display: flex; align-items: center; gap: 6px;
  border-radius: 999px;
  font-size: 16.5px; font-weight: 700; letter-spacing: -.01em; white-space: nowrap;
}
.act__ico {
  width: 38px; height: 38px; flex: none; padding: 9px;
  display: grid; place-items: center; border-radius: 50%;
}
.act__ico svg { width: 100%; height: 100%; }
.act__texto { overflow: hidden; text-overflow: ellipsis; }
.act--grande .act__texto { flex: 1 1 auto; text-align: center; }
.act--grande.act--wa {
  background: linear-gradient(180deg, #2fdc70, var(--wa));
  border-color: transparent; color: #06301a;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 4px 12px -5px rgba(18,140,63,.6);
}
.act--wa .act__ico { background: rgba(255,255,255,.4); }
.act--grande.act--tel {
  background: var(--accent-soft); color: var(--accent-ink);
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}
.act--tel .act__ico { background: var(--accent); color: var(--surface); }
/* "Cómo llegar" en el lugar de Llamar, para el negocio que no tiene ni
   teléfono ni WhatsApp: el mismo tono quieto que el de llamar. */
.act--grande.act--mapa {
  background: var(--accent-soft); color: var(--accent-ink);
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}
.act--mapa .act__ico { background: var(--accent); color: var(--surface); }
.act--grande:active { transform: scale(.97); }
@media (hover: hover) {
  .act--grande.act--wa:hover {
    background: linear-gradient(180deg, #3ae57a, #20c95e); color: #06301a;
    box-shadow: inset 0 1px 0 rgba(255,255,255,.35), 0 8px 18px -6px rgba(18,140,63,.6);
  }
  .act--grande.act--tel:hover,
  .act--grande.act--mapa:hover { border-color: var(--accent); color: var(--accent-ink); }
}
/* El número destapado ocupa el lugar del botón, del mismo alto y ancho. Sin
   el auricular, que ya lo traía el botón: con él, el número no cabía en media
   tarjeta de la computadora. */
.tel--grande .tel__num {
  width: 100%; height: 50px; padding: 0 10px; justify-content: center;
  border-color: var(--accent); background: var(--accent-soft);
  font-size: 14px;
}
.tel--grande .tel__num svg { display: none; }

/* El correo y las redes, en el renglón de abajo y repartidos a lo ancho: con
   círculos fijos sobraba un hueco a la derecha aunque el negocio tuviera
   todas sus redes. Cada uno se estira a la parte que le toca. */
.act-enlaces {
  flex: 1 1 100%;
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px;
}
.act-enlaces .act {
  width: auto; height: 44px; padding: 0 10px;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  border-radius: 999px;
}
.act-enlaces .act svg { width: 21px; height: 21px; flex: none; }
.act-enlaces--nombre .act__texto { font-size: 14.5px; font-weight: 600; color: var(--ink-2); }
@media (min-width: 768px) {
  .act-enlaces .act { height: 42px; }
}

/* La ficha gratuita, en el teléfono: su único botón es el mismo Llamar de las
   demás fichas, en la esquina de abajo a la derecha. Va en rejilla para que
   el ancho del botón sólo lo pague el renglón de la zona y el horario, que es
   corto, y no el del nombre: el nombre llega hasta guardar y compartir, y el
   botón se mete debajo de ellos.

     sello  nombre nombre  esquinas
     sello  datos  llamar  llamar

   `display: contents` en `.fila__texto` suelta al nombre y a los datos para
   que cada uno tome su lugar en la rejilla. */
.card--fila:has(> .fila__accion) {
  display: grid; align-items: center; gap: 6px 8px;
  grid-template-columns: auto minmax(0, 1fr) auto auto;
  grid-template-areas: "sello nombre nombre lado" "sello datos accion accion";
}
.card--fila:has(> .fila__accion) .fila__texto  { display: contents; }
.card--fila:has(> .fila__accion) .fila__sello  { grid-area: sello; }
.card--fila:has(> .fila__accion) .fila__nombre { grid-area: nombre; }
.card--fila:has(> .fila__accion) .fila__meta   { grid-area: datos; align-self: end; }
.card--fila:has(> .fila__accion) .fila__lado   { grid-area: lado; align-self: start; }
.card--fila:has(> .fila__accion) .fila__esquinas { flex-direction: row; }
/* El horario no se parte: "Hoy" arriba y la hora abajo no se lee de corrido. */
.card--fila:has(> .fila__accion) .fila__horario { white-space: nowrap; }
.fila__accion { grid-area: accion; align-self: end; justify-self: end; }
.fila__accion .act.act--grande { width: 130px; height: 46px; font-size: 16px; padding-left: 5px; }
/* "Cómo llegar", del negocio sin teléfono, no cabe en el ancho de "Llamar". */
.fila__accion .act.act--grande.act--mapa { width: 168px; }
/* En los teléfonos chicos no cabe junto a la zona y el horario: baja a su
   propio renglón, debajo de ellos. */
@media (max-width: 389px) {
  .card--fila:has(> .fila__accion .act--mapa) {
    grid-template-areas: "sello nombre nombre lado" "sello datos datos datos" "sello accion accion accion";
  }
}
.fila__accion .act__ico { width: 36px; height: 36px; }

/* --- El número a la vista, en lo que no es teléfono ---
   En una tablet o en una computadora `tel:` no marca nada, así que el botón se
   abre y deja ver el número: se puede leer en voz alta, teclearlo en el
   teléfono de a de veras o copiarlo de un toque. Con la pastilla abierta el
   botón redondo se esconde, así que ocupa el lugar de uno solo y la fila de
   contacto no se descuadra. */
.tel { display: inline-flex; align-items: center; }
/* El `display` de la regla `[hidden]` que trae el navegador no lleva clase, así
   que cualquier `.clase { display: … }` le gana y el elemento escondido se
   sigue dibujando: se veían el botón y la pastilla al mismo tiempo. Aquí se
   dice con clase, para que el atributo `hidden` mande de verdad. */
.tel__ver[hidden], .tel__num[hidden] { display: none; }
.tel__num {
  display: inline-flex; align-items: center; gap: 8px;
  height: 42px; padding: 0 14px 0 12px;
  border: 1px solid var(--line-strong); border-radius: 999px;
  background: var(--surface); color: var(--accent-ink);
  font-size: 13.5px; font-weight: 650; letter-spacing: .01em;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  text-decoration: none; cursor: pointer;
  transition: border-color .2s ease, color .2s ease;
}
.tel__num svg { width: 15px; height: 15px; flex: none; opacity: .7; }
.tel__num:hover  { border-color: var(--accent); color: var(--accent); }
.tel__num:active { transform: scale(.97); }
/* Copiado: el mismo verde del aviso de abierto, que ya quiere decir "listo". */
.tel__num.is-copiado { border-color: var(--abierto); color: var(--abierto); }
/* En el banner Premium los botones son más chicos; la pastilla los sigue. */
.vip__acciones .tel__num { height: 34px; padding: 0 11px 0 9px; font-size: 12.5px; }

@media (min-width: 768px) {
  .act { width: 40px; height: 40px; padding: 9px; }
  .card__actions { gap: 8px; }
  .tel__num { height: 40px; }
}

/* ==========================================================================
   ESTADOS VACÍOS / REGISTRO / FOOTER
   ========================================================================== */

.empty {
  text-align: center; padding: 46px 20px; color: var(--ink-3); font-size: 14px;
  background: var(--surface); border: 1px dashed var(--line-strong); border-radius: var(--radius-lg);
}
.empty a { color: var(--accent); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }

/* "¿Es tu negocio o algo está mal?" al pie de cada tarjeta, y "Recomiéndanos
   un negocio" debajo de la lista. Discretos: están para quien los busca, no
   para competir con los botones de contacto. */
.card__aviso {
  align-self: flex-start; margin-top: -2px;
  font-size: 12px; color: var(--ink-3); text-decoration: none;
  border-bottom: 1px dashed transparent;
}
.card__aviso:hover { color: var(--accent); border-bottom-color: currentColor; }
.lista-aviso { margin: 22px 0 0; text-align: center; font-size: 13.5px; color: var(--ink-3); }
.lista-aviso a { color: var(--accent); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }

.panel {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 22px; margin: 24px 0 0;
  box-shadow: var(--shadow-sm); max-width: 1040px;
}
@media (min-width: 768px) { .panel { padding: 32px; } }
.panel__title { margin: 6px 0 0; font-size: 23px; font-weight: 700; letter-spacing: -.03em; }
.panel__lead { margin: 8px 0 22px; color: var(--ink-2); font-size: 15px; }

.lanzamiento {
  margin: -8px 0 22px; padding: 14px 16px;
  background: var(--gold-soft);
  border: 1px solid color-mix(in srgb, var(--gold) 28%, transparent);
  border-radius: var(--radius);
}
.lanzamiento__titulo {
  margin: 0 0 6px; font-size: 12px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--gold);
}
.lanzamiento__lista { margin: 0; padding-left: 18px; font-size: 14px; color: var(--ink-2); }
.lanzamiento__lista li + li { margin-top: 4px; }
.lanzamiento__lista b { color: var(--ink); font-weight: 650; }

/* "Facturamos": debajo de los planes, en el mismo tono que los precios de
   lanzamiento pero sin el dorado, que es de la promoción. */
.factura {
  margin: 22px 0 0; padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.factura__titulo { margin: 0 0 4px; font-size: 15px; font-weight: 700; color: var(--ink); }
.factura__texto { margin: 0; font-size: 14px; color: var(--ink-2); }
.factura__texto b { color: var(--ink); font-weight: 650; }

/* --- Planes --- */
/* Los badges sobresalen del borde superior: el padding evita que se recorten. */
.plans { display: grid; gap: 12px; padding-top: 11px; margin-bottom: 22px; }

/* Cuatro planes: en dos columnas caen parejos, dos y dos. Las cuatro de un
   tirón sólo cuando hay ancho de sobra; abajo de eso las listas de beneficios
   se harían tiras. */
@media (min-width: 640px) { .plans { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1100px) { .plans { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

.plan {
  position: relative; min-width: 0; padding: 18px; border-radius: var(--radius);
  border: 1px solid var(--line); background: var(--surface-2);
  /* Columna para que el botón se pegue al fondo aunque las listas de
     beneficios tengan distinto largo. */
  display: flex; flex-direction: column;
}
.plan--featured {
  background: var(--surface);
  border-color: color-mix(in srgb, var(--gold) 40%, var(--line));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--gold) 16%, transparent), var(--shadow-md);
}
.plan--premium {
  background: var(--surface);
  border-color: color-mix(in srgb, var(--accent) 40%, var(--line));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 16%, transparent), var(--shadow-md);
}
.plan .badge { position: absolute; top: -11px; right: 14px; max-width: calc(100% - 28px); }

.plan__name { margin: 0; font-size: 14px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3); }
.plan__price { margin: 6px 0 2px; font-size: 27px; font-weight: 700; letter-spacing: -.03em; }
.plan__price small { font-size: 13px; font-weight: 500; color: var(--ink-3); letter-spacing: 0; }
/* El precio anual va pegado al mensual, no en la lista de beneficios: es la
   misma cifra vista de otro modo, y es la que conviene que se lea. */
.plan__anual { margin: 0 0 12px; font-size: 12.5px; color: var(--ink-3); }
.plan__anual b { color: var(--ink-2); font-weight: 600; }
.plan__incluye { margin: -4px 0 11px; font-size: 12.5px; font-weight: 600; color: var(--ink-2); }
.plan__list { margin: 0 0 16px; padding: 0; list-style: none; display: grid; gap: 7px; font-size: 13.5px; color: var(--ink-2); }
.plan__list li { position: relative; padding-left: 20px; overflow-wrap: break-word; }
.plan__list li::before {
  content: ""; position: absolute; left: 0; top: 6px; width: 13px; height: 9px;
  border-left: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg); border-radius: 1px;
}
.plan--featured .plan__list li::before { border-color: var(--gold); }

/* El margen automático empuja el botón al fondo de la tarjeta, para que los
   tres queden alineados aunque las listas tengan distinto largo. El aire
   mínimo lo pone el margen inferior de la lista. */
.plan__cta { margin-top: auto; padding-block: 11px; white-space: normal; }

.fineprint { margin: 10px 0 0; text-align: center; font-size: 12px; color: var(--ink-3); }

.footer { border-top: 1px solid var(--line); background: var(--surface); margin-top: 28px; }
.footer__inner { padding-block: 22px 28px; }
.footer__brand { margin: 0; font-size: 16px; font-weight: 500; letter-spacing: -.02em; }
.footer__note { margin: 4px 0 0; font-size: 13.5px; color: var(--ink-3); }
.footer__demo {
  margin: 14px 0 0; font-size: 13.5px; color: var(--ink-3);
  padding: 10px 12px; background: var(--surface-2); border-radius: 10px;
  border: 1px solid var(--line); max-width: 62ch;
}

.footer__links { margin: 12px 0 0; font-size: 13px; }
.footer__links a { color: var(--ink-2); text-decoration: none; border-bottom: 1px dashed var(--line-strong); }
.footer__links a:hover { color: var(--accent); border-bottom-color: currentColor; }

/* --- Documentos legales -------------------------------------------------
   Texto largo para leer, no para hojear: renglón corto (66ch, que es donde
   el ojo alcanza a saltar de una línea a la siguiente sin perderse), altura
   de línea holgada, y los títulos con más aire arriba que abajo para que se
   lean pegados a lo que anuncian y no a lo que termina. */
.legal { max-width: 66ch; color: var(--ink-2); font-size: 14.5px; line-height: 1.65; }
.legal h2 {
  margin: 32px 0 10px; font-size: 17px; font-weight: 700;
  letter-spacing: -.02em; color: var(--ink);
  padding-top: 18px; border-top: 1px solid var(--line);
}
.legal h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.legal h3 { margin: 22px 0 6px; font-size: 14.5px; font-weight: 700; color: var(--ink); }
.legal p  { margin: 0 0 12px; }
.legal ul { margin: 0 0 12px; padding-left: 20px; }
.legal li { margin-bottom: 7px; }
.legal strong { color: var(--ink); font-weight: 650; }
.legal a { color: var(--accent); }
.legal__fecha { margin-top: 20px; font-size: 13px; color: var(--ink-3); }

/* Los huecos por llenar van en amarillo de marcatextos, no en gris: un hueco
   discreto se publica sin que nadie lo note, y un aviso de privacidad con el
   nombre del responsable en blanco no es un aviso de privacidad. Que estorbe
   a la vista es la función. */
.falta {
  background: #fef08a; color: #422006; border-radius: 4px;
  padding: 1px 5px; font-weight: 600; box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
}
.falta--grande {
  display: block; margin: 0 0 24px; padding: 12px 14px;
  border-radius: 10px; border: 1px solid #ca8a04; font-weight: 400; line-height: 1.55;
}
.falta--grande strong { display: block; margin-bottom: 4px; }

/* --- El arte del negocio de fondo ---------------------------------------
   Cuando el negocio manda su lona o su tarjeta, va de fondo del banner pero
   borrosa: el `backdrop-filter` del velo difumina lo que quedó detrás —la
   imagen— sin tocar lo que va encima, que es el logotipo y los sellos. Así el
   recuadro toma los colores de la marca sin pelearse con el texto de la lona,
   que a ese tamaño no se lee de todos modos.

   Si el navegador no sabe de `backdrop-filter`, la imagen se ve nítida bajo el
   mismo velo oscuro: menos bonito, igual de legible. */
/* La imagen la pone el atributo `style` de cada ficha; aquí sólo se le dice
   cómo acomodarse. */
.vip__slide--arte {
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}
.vip__slide--arte::before {
  backdrop-filter: blur(14px) saturate(130%);
  -webkit-backdrop-filter: blur(14px) saturate(130%);
}
/* Con una foto debajo hace falta más sombra que sobre un degradado liso: el
   blanco del texto tiene que ganarle a lo que haya salido borroso ahí abajo. */
.vip__slide--arte::before {
  background:
    radial-gradient(80% 120% at 12% 0%, rgba(255,255,255,.12), transparent 62%),
    linear-gradient(180deg, rgba(0,0,0,.40), rgba(0,0,0,.60));
}

/* El logotipo ocupa el lugar de las iniciales: entero y sin recortar
   —`contain`, no `cover`—, porque a una marca se le respeta la forma. */
.card__logo {
  position: relative; z-index: 1;
  width: 54px; height: 54px;
  object-fit: contain;
  border-radius: 10px;
  box-shadow: 0 2px 12px rgba(0,0,0,.3);
}
@media (min-width: 560px) { .card__logo { width: 60px; height: 60px; } }

/* --- El logotipo en el carrusel de destacados --------------------------- */
.dest__card--arte { background-size: cover; background-position: center; }
.dest__card--arte::after { backdrop-filter: blur(16px) saturate(130%); -webkit-backdrop-filter: blur(16px) saturate(130%); }
/* El logotipo no se recorta: `contain`. Va con la tarjeta por delante en el
   selector porque `.dest__card img` —que lo estira a todo el banner y lo
   recorta— pesa más que una sola clase, y ganaría aunque esté más arriba. */
.dest__card .dest__logo {
  position: relative; z-index: 1;
  width: 52%; height: auto; max-height: 66%;
  object-fit: contain;
  border-radius: 12px;
  box-shadow: 0 3px 16px rgba(0,0,0,.34);
}

/* --- El Premium que es su propio anuncio -------------------------------- */
/* Sin relleno y sin degradado: la tarjeta es la imagen y nada más. El alto
   se lo da el propio anuncio, así que sale completo, sin recortes. */
/* Mide lo mismo que las tarjetas Premium de al lado: se estira al alto de su
   página (`flex: 1`), que la dan las tarjetas, y el anuncio la llena. Si el
   alto o el ancho de la pantalla no dan justo la forma del archivo, se recorta
   un poco por las orillas (`cover`): por eso la captura pide dejar el texto
   y el logo lejos de ellas. Sin tarjetas al lado que le den el alto, se queda
   con el suyo, el mismo que miden ellas. */
.vip__slide--anuncio {
  display: block; padding: 0;
  flex: 1 1 auto; min-height: 191px;
  background: var(--surface);
}
.vip__slide--anuncio::before { content: none; }
.vip__anuncio {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  border-radius: inherit;
}

/* ==========================================================================
   COMPARTIR Y GUARDAR
   ========================================================================== */

/* Las dos esquinas de arriba del banner: guardar a la izquierda y compartir a
   la derecha. El contenedor no recibe clics, sólo los botones, para que el
   espacio de en medio siga siendo banner. */
.card__esquinas {
  position: absolute; top: 8px; left: 8px; right: 8px; z-index: 3;
  display: flex; justify-content: space-between;
  pointer-events: none;
}
.esq {
  pointer-events: auto;
  width: 36px; height: 36px; flex: none; padding: 8px;
  display: grid; place-items: center; border-radius: 50%;
  border: 0; cursor: pointer;
  /* Vidrio oscuro: se lee igual sobre el degradado de la categoría que sobre
     la foto de un negocio, sea clara u oscura. */
  background: rgba(0,0,0,.34); color: #fff;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  transition: background .15s ease, transform .12s ease;
}
.esq svg { width: 100%; height: 100%; }
.esq:active { transform: scale(.9); }
@media (hover: hover) {
  .esq:hover { background: rgba(0,0,0,.52); }
}
/* Guardado: el separador se rellena, como en cualquier aplicación que la gente
   ya usa. Con eso basta para leerlo; no hace falta otro color. */
.esq--guardar[aria-pressed="true"] svg { fill: currentColor; }
.esq.is-latido { animation: esq-latido .38s ease; }
@keyframes esq-latido {
  40% { transform: scale(1.22); }
}
@media (prefers-reduced-motion: reduce) {
  .esq.is-latido { animation: none; }
}

/* En el renglón gratuito no hay banner sobre el cual flotar: sin fondo, los
   dos iconos se veían sueltos, como dibujos y no como botones. Van en un
   círculo chico del mismo gris de las etiquetas, con su filo, y al quedar
   guardado se pinta del acento. */
.esq--fila {
  width: 34px; height: 34px; padding: 8px;
  background: var(--surface-2); color: var(--ink-2);
  border: 1px solid var(--line);
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
.esq--fila[aria-pressed="true"] {
  color: var(--accent); background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
}
@media (hover: hover) {
  .esq--fila:hover { background: var(--surface-2); border-color: var(--line-strong); color: var(--ink); }
}

/* El botón de guardados del encabezado usa el cuerpo del selector de tema.
   Su `display` le gana al `[hidden]` del navegador, que no lleva clase, así
   que aquí se dice con clase para que esconderlo funcione. */
.guardados-btn[hidden] { display: none; }

.empty__icono {
  width: 16px; height: 16px; vertical-align: -3px; display: inline-block;
}

/* El aviso pasajero: una pastilla abajo al centro, encima de todo. */
.aviso {
  position: fixed; left: 50%; bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  /* `max-content`: con `left: 50%` el navegador le da de ancho sólo la mitad
     de la pantalla que queda a la derecha, y el aviso salía en tres renglones. */
  z-index: 80; width: max-content; max-width: calc(100vw - 32px);
  transform: translate(-50%, 12px); opacity: 0;
  padding: 11px 18px; border-radius: 14px;
  background: var(--ink); color: var(--surface);
  font-size: 14px; font-weight: 600; text-align: center;
  box-shadow: 0 8px 28px rgba(0,0,0,.28);
  transition: opacity .2s ease, transform .2s ease;
  pointer-events: none;
}
.aviso.is-visible { opacity: 1; transform: translate(-50%, 0); }
.aviso[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .aviso { transition: none; }
}

/* El costado derecho del renglón. En pantalla ancha sólo lleva guardar y
   compartir, uno encima del otro: lado a lado le quitaban al nombre 40px, y en
   una pila el nombre ya sale cortado; a lo alto caben sin estirar el renglón.

   En el teléfono van lado a lado, arriba, y el botón de llamar en la esquina
   de abajo (`.fila__accion`). */
.fila__lado {
  flex: none; align-self: stretch;
  display: flex; flex-direction: column; align-items: flex-end;
  justify-content: center; gap: 6px;
}
.fila__esquinas { display: flex; flex-direction: column; gap: 6px; }


/* Las fotos de los negocios traen una versión por aparato (app.js,
   `imagen()`). El `<picture>` no hace caja: el `<img>` se acomoda solo. */
picture { display: contents; }

/* La vista previa en el banner de la tarjeta: nítida, a lo ancho, sin
   logotipo encima. Viene hecha en 16:6; si no, se recorta dejando ver un poco
   más la parte de arriba, donde suele ir el letrero. El velo cambia por uno
   que sólo oscurece las dos orillas, donde van los botones, y deja el centro
   de la foto como es. */
.card__previa {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 30%;
}
.card__banner--previa::after {
  background: linear-gradient(180deg,
    rgba(0,0,0,.28), transparent 32%, transparent 62%, rgba(0,0,0,.38));
}

/* --- Galería de fotos ------------------------------------------------------
   El botón transparente tendido sobre la imagen de la tarjeta la abre. Va
   debajo de las esquinas, que conservan sus botones de guardar y compartir. */
.card__ver {
  position: absolute; inset: 0; z-index: 2;
  margin: 0; padding: 0; border: 0; background: none;
  cursor: zoom-in;
}
.card__ver:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }
/* Cuántas fotos trae, chiquito en la esquina de abajo: sin él nadie sabría
   que la imagen se abre. */
.card__fotos {
  position: absolute; right: 8px; bottom: 8px;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 7px; border-radius: 999px;
  background: rgba(0,0,0,.5); color: #fff;
  font-size: 11px; font-weight: 700; font-family: var(--font);
}
.card__fotos svg { width: 12px; height: 12px; }

html.con-galeria { overflow: hidden; }

.galeria {
  width: 100%; height: 100%; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0;
  background: var(--surface); color: var(--ink);
}
.galeria::backdrop { background: rgba(0,0,0,.72); }
.galeria__caja { position: relative; height: 100%; overflow-y: auto; overscroll-behavior: contain; }

.galeria__fotos { position: relative; background: #0b0b0b; }
.galeria__pista {
  display: flex; aspect-ratio: 4 / 3; max-height: 62vh;
  overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
}
.galeria__pista::-webkit-scrollbar { display: none; }
/* La foto va tendida sobre su cuadro: con el alto en porcentaje de una
   celda, una foto cuadrada o vertical se salía por abajo. */
.galeria__foto { position: relative; flex: 0 0 100%; margin: 0; scroll-snap-align: center; }
.galeria__foto img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; }
/* El logo, sobre blanco: muchos traen fondo transparente y letras oscuras. */
.galeria__foto--logo { background: #fff; }
.galeria__foto--logo img { padding: 6%; box-sizing: border-box; }

.galeria__flecha, .galeria__cerrar {
  position: absolute; z-index: 1;
  display: grid; place-items: center;
  width: 40px; height: 40px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(255,255,255,.9); color: #191917;
  box-shadow: 0 2px 10px rgba(0,0,0,.3); cursor: pointer;
}
.galeria__flecha svg, .galeria__cerrar svg {
  width: 22px; height: 22px; fill: none; stroke: currentColor;
  stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round;
}
.galeria__flecha { top: 50%; transform: translateY(-50%); }
.galeria__flecha--ant { left: 10px; }
.galeria__flecha--sig { right: 10px; }
.galeria__flecha[hidden] { display: none; }
.galeria__cerrar { top: 10px; right: 10px; z-index: 2; }
.galeria__cuenta {
  position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%); margin: 0;
  padding: 3px 10px; border-radius: 999px; background: rgba(0,0,0,.55); color: #fff;
  font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.galeria__cuenta:empty { display: none; }

.galeria__info { display: flex; flex-direction: column; gap: 12px; padding: 18px 16px 28px; }
.galeria__cabeza { display: flex; align-items: center; gap: 12px; }
.galeria__logo {
  width: 60px; height: 60px; flex: none; object-fit: contain;
  border-radius: 12px; background: #fff; border: 1px solid var(--line);
}
.galeria__cat { margin: 0; font-size: 12.5px; color: var(--ink-3); }
.galeria__nombre { margin: 2px 0 0; font-size: 21px; font-weight: 700; letter-spacing: -.025em; line-height: 1.2; }
.galeria__linea { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin: 0; font-size: 13.5px; }
.galeria__linea .fila__estado { font-size: 11.5px; padding: 3px 9px; }
.galeria__linea svg { width: 13px; height: 13px; flex: none; }
.galeria__desc { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--ink-2); }
.galeria__info .horario__semana { font-size: 13px; margin: 0; }
.galeria__info .card__actions { margin-top: 4px; }

/* PC y tableta: la ventana al centro, las fotos a la izquierda y el negocio a
   la derecha, con su propia barra si no cabe. */
@media (min-width: 768px) {
  .galeria {
    width: min(1080px, calc(100% - 48px)); height: fit-content; max-height: calc(100dvh - 48px);
    margin: auto; border-radius: var(--radius-lg); overflow: hidden;
    box-shadow: var(--shadow-lg);
  }
  .galeria__caja {
    display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(300px, 1fr);
    height: auto; max-height: calc(100dvh - 48px); overflow: hidden;
  }
  .galeria__fotos { display: grid; align-items: center; }
  .galeria__pista { max-height: calc(100dvh - 48px); }
  .galeria__flecha--ant { left: 14px; }
  .galeria__flecha--sig { right: 14px; }
  .galeria__info { overflow-y: auto; padding: 28px 24px 24px; min-height: 0; }
  .galeria__cerrar { background: var(--surface-2); color: var(--ink); box-shadow: none; }
}

/* --- Escoger a qué número -------------------------------------------------
   La lista que abre "Llamar" cuando el negocio tiene más de un número. En el
   teléfono sale desde abajo, donde alcanza el pulgar, con renglones altos para
   el dedo; en la computadora, al centro. Cada renglón es el enlace que marca
   (o copia, en la computadora). */
.llamar {
  width: min(420px, calc(100vw - 32px)); max-width: none;
  padding: 0; border: 0; border-radius: var(--radius-lg);
  background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-md);
}
.llamar::backdrop { background: rgba(0,0,0,.5); }
@media (max-width: 559.98px) {
  .llamar {
    width: 100%; max-width: 100%; margin: auto 0 0;
    border-radius: 18px 18px 0 0;
  }
  @media (prefers-reduced-motion: no-preference) {
    .llamar[open] { animation: llamar-sube .22s cubic-bezier(.2, .8, .3, 1); }
  }
}
@keyframes llamar-sube { from { transform: translateY(24px); opacity: 0; } }
/* Con muchos números la lista se recorre por dentro y el título y "Cancelar"
   se quedan a la vista. */
.llamar { max-height: 88vh; }
.llamar__caja {
  display: flex; flex-direction: column; max-height: 88vh;
  padding: 18px 16px calc(16px + env(safe-area-inset-bottom, 0px));
}
.llamar__titulo { margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -.02em; }
.llamar__negocio { margin: 2px 0 14px; font-size: 13.5px; color: var(--ink-3); }
.llamar__lista {
  list-style: none; margin: 0; padding: 0; display: grid; gap: 8px;
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
}
.llamar__opcion {
  display: flex; align-items: center; gap: 12px;
  min-height: 58px; padding: 10px 14px;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--surface-2); color: var(--ink); text-decoration: none;
  transition: border-color .15s, background .15s;
}
.llamar__opcion:hover, .llamar__opcion:focus-visible { border-color: var(--accent); }
.llamar__opcion:active { background: var(--accent-soft); }
.llamar__opcion > svg { width: 20px; height: 20px; flex: none; color: var(--accent); }
.llamar__texto { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.llamar__texto strong { font-size: 15px; font-weight: 650; }
.llamar__numero { font-size: 13.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
strong.llamar__numero { font-size: 15px; color: var(--ink); }
.llamar__opcion.is-copiado .llamar__numero { color: var(--abierto); }
.llamar__cancelar {
  width: 100%; min-height: 46px; margin-top: 12px; cursor: pointer;
  border: 1px solid var(--line-strong); border-radius: 999px; background: none;
  font-size: 14.5px; font-weight: 600; color: var(--ink-2);
}
.llamar__cancelar:hover { color: var(--ink); border-color: var(--ink-3); }
