/* ==========================================================================
   HomesSection — "Homes we'd send our friends to."

   Figma `Homes` (157:1392), leído en Dev Mode el 2026-09-08. Cada número lleva
   al lado el nodo de donde salió.

   El ancho lo pone `.tgl-container`: caja 1240, contenido 1144. Esta sección es
   —junto con `Islands`— una de las dos que CONFIRMAN ese modelo: cuatro cards
   de 265 con 26 de gap son 1144 exactos.
   ========================================================================== */

.tgl-homes {
    /* 120 y no los 141 del archivo (157:1393). Es la misma llamada que el ancho
       de container: `Islands` mide 120 y `Step-by-step` también, así que 141 en
       una sola sección es deriva del auto-layout y no una decisión — y deja las
       tres secciones con ritmos distintos entre sí, que es exactamente lo que
       el usuario pidió normalizar el 2026-09-08. */
    padding-block: 7.5rem;
    background: var(--tgl-bg-primary);
}

.tgl-homes .tgl-homes__inner {
    display: flex;
    flex-direction: column;
    gap: 2.375rem;                    /* 38 — 157:1393 */
}

/* ── Encabezado centrado ──────────────────────────────────────────────── */

.tgl-homes .tgl-homes__head {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;                        /* 16 — 157:1394 */
    /* 472 y centrado (157:1394). Es más angosto que el 680 de `Islands` porque
       el título es una sola línea corta; sin el tope se estira a 1144 y deja de
       leerse como un título centrado. */
    max-width: 29.5rem;
    margin-inline: auto;
    text-align: center;
}

.tgl-homes .tgl-homes__title {
    margin: 0;
    font-family: var(--tgl-font-heading);
    /* 44px Medium (500), idéntico al de `Islands` (157:1143): mismo tamaño,
       mismo tracking, mismo line-height. Los dos h2 de 44 de la página son el
       mismo h2. */
    font-size: 2.75rem;               /* 44 — 157:1396 */
    font-weight: 500;
    letter-spacing: -0.02em;          /* -0.88 / 44 */
    line-height: 1.12;                /* 49.28 / 44 */
    color: var(--tgl-heading-color);
}

/* El archivo deja este slot VACÍO (157:1397 es un container de 31px sin texto).
   La regla existe igual porque la sección se va a reutilizar, y un h2 sin lugar
   para una bajada abajo es una reutilización que cuesta un cambio de código. */
.tgl-homes .tgl-homes__lead {
    margin: 0;
    font-family: var(--tgl-font-body);
    font-size: 1.1875rem;             /* 19 — el mismo lead centrado de Islands */
    line-height: 1.6;
    color: var(--tgl-lead-centered-color);
}

/* ── Los pills ────────────────────────────────────────────────────────── */

.tgl-homes .tgl-homes__filters {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    /* El archivo dice `0px 10px` — row-gap 0. A 1144 los cinco pills no
       envuelven nunca, así que ese 0 no se ve; en cuanto envuelven quedan dos
       filas pegadas. 10 en los dos ejes. */
    gap: 0.625rem;                    /* 10 — 157:1399 */
}

.tgl-homes .tgl-homes__pill {
    /* `appearance: none` y el reset de fuente porque en modo filtro esto es un
       `<button>`: sin esto hereda la tipografía del UA y aparece en Arial 13.3
       al lado de sus hermanos `<a>`. */
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.625rem 1.3125rem;      /* 10 / 21 — 157:1403 */
    border: 1px solid var(--tgl-pill-border);
    border-radius: 6.25rem;           /* 100 — 157:1403 */
    background: transparent;
    font-family: var(--tgl-font-body);
    font-size: 0.875rem;              /* 14 — 157:1405 */
    font-weight: 400;
    line-height: normal;
    text-align: center;
    text-decoration: none;
    white-space: nowrap;
    /* El mismo gris que el lead centrado (#57534b). No es casualidad: es el
       texto secundario de esta familia de secciones. */
    color: var(--tgl-lead-centered-color);
    cursor: pointer;
    /* Sin esto, en iOS un tap deja un rectángulo gris sobre el pill redondeado.
       Ya nos pasó en el trip search. */
    -webkit-tap-highlight-color: transparent;
}

/* El pill activo. `aria-current` y no una clase: el estado tiene que existir
   para el lector de pantalla, no solo para el ojo, y un atributo que ya
   comunica no necesita una clase al lado que pueda desincronizarse. */
.tgl-homes .tgl-homes__pill[aria-current="true"] {
    border-color: var(--tgl-primitive-teal-500);
    background: var(--tgl-primitive-teal-500);
    /* `!important` por lo mismo que `.tgl-cta`: el kit de Elementor emite
       `.elementor-kit-6 a { color: var(--e-global-color-text) }` con
       especificidad (0,1,1). Acá el selector es (0,2,0) y gana solo, pero el
       kit también trae reglas CON `!important` sobre `a`, y ese caso ya costó
       una release. Medido, no deducido. */
    color: var(--tgl-primitive-white) !important;
}

@media (hover: hover) {
    /* Guardado tras `(hover: hover)`: sin la guarda WebKit deja el estado
       pegado al último elemento tocado. Ese bug costó la v3.26.4. */
    .tgl-homes .tgl-homes__pill:hover {
        border-color: var(--tgl-lead-centered-color);
    }

    .tgl-homes .tgl-homes__pill[aria-current="true"]:hover {
        border-color: var(--tgl-primitive-teal-700);
        background: var(--tgl-primitive-teal-700);
    }
}

.tgl-homes .tgl-homes__pill:active {
    /* Hundido, no movido: `transform` sobre un elemento de una fila que envuelve
       le mueve los hermanos. */
    box-shadow: inset 0 1px 2px rgba(31, 29, 26, 0.16);
}

.tgl-homes .tgl-homes__pill:focus-visible {
    outline: 2px solid var(--tgl-primitive-teal-700);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: no-preference) {
    .tgl-homes .tgl-homes__pill {
        /* `color` va en la lista, y no es de adorno: sin él el texto SALTA a
           blanco mientras el fondo teal todavía se está desvaneciendo, así que
           durante 150ms hay blanco sobre casi-transparente. Medido el
           2026-09-09 en el harness. Los tres se mueven juntos o ninguno. */
        transition:
            background var(--tgl-transition-fast),
            border-color var(--tgl-transition-fast),
            color var(--tgl-transition-fast);
    }
}

/* El spinner que el script mete en el pill mientras el filtro va y vuelve.
   Reportado: bajar la opacidad de la grilla era demasiado silencioso solo. Va
   en el PILL porque es donde ya está el ojo —el visitante recién lo apretó— y
   un spinner en el medio de la grilla sería un salto de layout. */
.tgl-homes .tgl-homes__spinner {
    display: inline-block;
    width: 0.75rem;
    height: 0.75rem;
    margin-left: 0.4375rem;
    border: 2px solid currentColor;
    /* El cuarto transparente es lo que hace que la rotación se vea. */
    border-top-color: transparent;
    border-radius: 50%;
    vertical-align: -1px;
    animation: tgl-homes-spin 0.6s linear infinite;
}

@keyframes tgl-homes-spin {
    to { transform: rotate(360deg); }
}

/* Con movimiento reducido el spinner no gira: late. Un elemento que no da
   ninguna señal sería peor que no ponerlo. */
@media (prefers-reduced-motion: reduce) {
    .tgl-homes .tgl-homes__spinner {
        animation: tgl-homes-pulse 1.2s ease-in-out infinite;
    }
}

@keyframes tgl-homes-pulse {
    50% { opacity: 0.35; }
}

/* La foto mientras carga. Reportado: al filtrar, las cards llegan antes que sus
   imágenes y quedaba un rectángulo gris que no dice nada — se lee como una card
   que falló. El brillo que barre dice "viene en camino", y el script saca el
   atributo cuando la primera foto decodificó de verdad. */
.tgl-homes .tgl-homes__media[data-tgl-media="loading"] {
    background:
        linear-gradient(
            90deg,
            var(--tgl-card-border) 0%,
            rgba(31, 29, 26, 0.02) 50%,
            var(--tgl-card-border) 100%
        )
        var(--tgl-card-border);
    background-size: 200% 100%;
}

@media (prefers-reduced-motion: no-preference) {
    .tgl-homes .tgl-homes__media[data-tgl-media="loading"] {
        animation: tgl-homes-shimmer 1.4s ease-in-out infinite;
    }
}

@keyframes tgl-homes-shimmer {
    from { background-position: 200% 0; }
    to   { background-position: -200% 0; }
}

/* El conteo que anuncia el filtro. Visible solo para el lector de pantalla: en
   el diseño no hay ninguna línea de texto acá, y agregarla sería inventar
   diseño. Pero un control que cambia el contenido y no dice nada es un control
   silencioso, y eso sí es un bug. */
.tgl-homes .tgl-homes__status {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    border: 0;
    /* `inset(50%)` y no `display: none`: un live region oculto con `display` no
       se anuncia. */
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ── La grilla ────────────────────────────────────────────────────────── */

.tgl-homes .tgl-homes__grid {
    /* `!important`: el kit de Elementor emite `.elementor-kit-6 ul` con
       `list-style` y `padding`, algunas con `!important`. Sin esto son ocho
       cards con bullet y 40px de sangría. */
    list-style: none !important;
    margin: 0 !important;
    padding: 0 !important;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1.625rem;                    /* 26 — 157:1415 */
}

.tgl-homes .tgl-homes__card {
    /* `relative` para el anillo de foco y el hover. **Ya NO ancla el `::after`
       del link** — eso pasó a `.tgl-homes__body` cuando la foto se volvió un
       carrusel. Si alguien saca el `relative` del cuerpo, el pseudo vuelve a
       encontrar este ancestro y se estira sobre la card entera, y el track deja
       de deslizarse en touch sin dar ningún error. */
    position: relative;
    /* Contenedor de consulta, para que la fila del precio pueda encogerse
       según el ancho de SU card y no del viewport. Es lo que arregla el footer
       partido en dos líneas en las cards angostas sin tocar las de 266.5.
       Seguro sobre un item de grilla: el ancho lo fija la pista, no el
       contenido. */
    container-type: inline-size;
    /* Dice "esto se puede clickear" antes de cualquier hover, y en toda la
       card — no solo sobre el nombre. */
    cursor: pointer;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--tgl-card-border);
    border-radius: 0.5rem;            /* 8 — 157:1416 */
    background: var(--tgl-bg-primary);
}

/* Lo que el JS pone al filtrar. Explícito porque `.tgl-homes__card` declara
   `display: flex`, y una clase con `display` le gana al `display: none` que el
   UA aplica a `[hidden]`: sin esta regla el atributo no hace nada. */
/* Mientras el filtro va y vuelve. Bajar la opacidad y cortar los clicks y
   nada más: la grilla ya ocupa su lugar, así que no hay nada que reservar y
   nada que se mueva. Un spinner acá sería un salto de layout a cambio de
   información que el atributo ya da. */
.tgl-homes .tgl-homes__grid[aria-busy="true"] {
    opacity: 0.55;
    pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
    .tgl-homes .tgl-homes__grid {
        transition: opacity var(--tgl-transition-fast);
    }
}

/* ── La foto ── */

.tgl-homes .tgl-homes__media {
    /* 264.5 / 198.38 = 1.3332, o sea 4:3. Como ratio y no como alto fijo: al
       pasar a dos y a una columna el ancho manda y el alto lo sigue. Y reserva
       la caja antes de que cargue la foto — sin eso la grilla salta cuando
       aterrizan las ocho, y eso es CLS. */
    aspect-ratio: 4 / 3;
    /* Ancla las flechas y los dots, que van absolutos adentro. */
    position: relative;
    overflow: hidden;
    background: var(--tgl-card-border);
}

/* ── El carrusel ──────────────────────────────────────────────────────

   Un track nativo con scroll-snap. **Se desliza sin una línea de JavaScript**,
   que es la razón de construirlo así en una página que es 80% mobile: el gesto
   principal es el que no necesita nada. Las flechas y los dots los revela el
   script, porque sin un listener de scroll no podrían decir dónde estás. */

.tgl-homes .tgl-homes__slides {
    /* `!important` por lo mismo que la grilla: el kit de Elementor emite
       `.elementor-kit-6 ul` con `list-style` y `padding`, algunas con
       `!important`. Sin esto cada foto lleva un bullet. */
    list-style: none !important;
    margin: 0 !important;
    padding: 0 !important;
    display: flex;
    height: 100%;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    /* Sin esto queda una barra de scroll gris debajo de cada foto, ocho veces
       por página. */
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}

.tgl-homes .tgl-homes__slides::-webkit-scrollbar {
    display: none;
}

.tgl-homes .tgl-homes__slide {
    /* `0 0 100%`: una foto por vista, y `flex-shrink: 0` es lo que evita que
       las cinco se apachurren en el ancho de una. */
    flex: 0 0 100%;
    height: 100%;
    /* `start` y no `center`, y es la segunda causa del pedacito de foto vecina
       que se reportó. El slide mide 264.5 —fraccional, porque la card mide
       266.5 menos los bordes— así que la posición de snap centrada de cada
       slide cae en un no-entero y el navegador redondea, dejando un borde
       subpíxel del de al lado. `start` se calcula desde el borde izquierdo, que
       es múltiplo exacto del ancho del slide. Con slides del ancho justo del
       scrollport las dos alineaciones se ven igual; ésta redondea mejor. */
    scroll-snap-align: start;
    /* Reportado: al hacer hover se veía un pedacito de la foto siguiente. El
       zoom escala el `<img>` un 4%, y sin esto el excedente se derrama sobre el
       slide vecino — que en un track de scroll está justo al lado, no fuera de
       la vista. El recorte va acá y no en el track: el track TIENE que
       desbordar, es su función. */
    overflow: hidden;
}

.tgl-homes .tgl-homes__slide img,
.tgl-homes .tgl-homes__media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Las flechas. Solo con puntero fino y solo al pasar por la card: en touch el
   gesto es el swipe, y dos botones tapando la foto en 335px de ancho es peor
   que no tenerlos. */
.tgl-homes .tgl-homes__nav {
    appearance: none;
    position: absolute;
    top: 50%;
    /* z-index por encima del `::after` del link — aunque hoy ese pseudo cubre
       solo el cuerpo, dejarlo dicho es lo que evita que el día que alguien lo
       vuelva a estirar sobre la card entera las flechas dejen de recibir
       clicks en silencio. */
    z-index: 2;
    display: none;
    place-content: center;
    width: 1.875rem;
    height: 1.875rem;
    padding: 0;
    transform: translateY(-50%);
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
    box-shadow: 0 1px 4px rgba(31, 29, 26, 0.24);
    /* `currentColor` lo hereda el `stroke` del SVG, así que el estado
       deshabilitado tiñe el chevron gratis. */
    color: var(--tgl-heading-color);
    line-height: 0;
    cursor: pointer;
    opacity: 0;
    -webkit-tap-highlight-color: transparent;
}

.tgl-homes .tgl-homes__nav--prev { left: 0.5rem; }
.tgl-homes .tgl-homes__nav--next { right: 0.5rem; }

.tgl-homes .tgl-homes__nav:disabled {
    /* Deshabilitada y no oculta: que la flecha esté ahí y apagada dice "no hay
       más fotos", que es información. Desaparecer dice "esta card es
       distinta". */
    opacity: 0.35 !important;
    cursor: default;
}

@media (hover: hover) and (pointer: fine) {
    .tgl-homes .tgl-homes__nav {
        display: grid;
    }

    .tgl-homes .tgl-homes__card:hover .tgl-homes__nav {
        opacity: 1;
    }
}

/* El anillo de foco tiene que verse aunque el botón esté en opacidad 0: si no,
   un usuario de teclado tabula a un control invisible. */
.tgl-homes .tgl-homes__nav:focus-visible {
    display: grid;
    opacity: 1;
    outline: 2px solid var(--tgl-primitive-teal-700);
    outline-offset: 2px;
}

/* Los dots. Son la única señal de que HAY más fotos: sin ellos la card parece
   una imagen fija y la función no existe para quien no la busca. */
.tgl-homes .tgl-homes__dots {
    list-style: none !important;
    margin: 0 !important;
    padding: 0 !important;
    position: absolute;
    right: 0;
    bottom: 0.25rem;
    left: 0;
    z-index: 2;
    display: flex;
    justify-content: center;
    /* `none` en la LISTA y `auto` en los botones: el hueco entre dots deja
       pasar el tap a la foto, que ahora abre la casa. Sin esto la barra
       invisible de 16px de alto se come esos clicks. */
    pointer-events: none;
}

.tgl-homes .tgl-homes__dots li {
    display: flex;
}

.tgl-homes .tgl-homes__dot {
    appearance: none;
    /* `content-box` + padding: el punto se ve de 6px y el área de tap mide 16.
       Un blanco de 6px está muy por debajo del mínimo usable, y en una tira de
       cinco el de al lado está a 6px de distancia. */
    box-sizing: content-box;
    width: 0.375rem;
    height: 0.375rem;
    padding: 0.3125rem;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.55);
    background-clip: content-box;
    box-shadow: none;
    cursor: pointer;
    pointer-events: auto;
    -webkit-tap-highlight-color: transparent;
}

.tgl-homes .tgl-homes__dot[data-tgl-current="true"] {
    background: var(--tgl-primitive-white);
    background-clip: content-box;
}

@media (prefers-reduced-motion: no-preference) {
    .tgl-homes .tgl-homes__nav { transition: opacity var(--tgl-transition-fast); }
    .tgl-homes .tgl-homes__dot { transition: background var(--tgl-transition-fast); }
}

/* ── El cuerpo ── */

.tgl-homes .tgl-homes__body {
    /* `relative` acá y no en la card: es lo que ancla el `::after` del link al
       CUERPO. Antes cubría la card entera, y eso no puede convivir con un track
       deslizable — una capa con pointer events encima de un contenedor de
       scroll se come el touch que lo habría desplazado. Ver el docblock de
       `HomesGallery`. */
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.4375rem;                    /* 7.1 — 157:1420 */
    padding: 1.375rem 1.375rem 1.5rem; /* 22 / 22 / 24 — 157:1420 */
    /* Junto con el `margin-top: auto` del precio, es lo que alinea las líneas
       de todas las cards de una fila. El archivo lo intenta con un
       `min-height: 40px` sobre la bajada (157:1425), que alcanza para una y dos
       líneas y falla en la tercera: en el archivo las cards de la fila 1 miden
       395.97 y 413.97, y se ve. Esto lo resuelve para cualquier largo. */
    flex: 1;
}

.tgl-homes .tgl-homes__island {
    margin: 0;
    /* Open Sans, NO Outfit. Es el único eyebrow del rediseño que no usa la
       familia de UI (157:1422) — y es coherente: no es el eyebrow de una
       sección, es una etiqueta dentro de una card, hermana del precio, que
       también es Open Sans. */
    font-family: var(--tgl-font-body);
    font-size: 0.6875rem;             /* 11 — 157:1422 */
    font-weight: 600;
    letter-spacing: 0.12em;           /* 1.32 / 11 */
    line-height: normal;
    text-transform: uppercase;
    color: var(--tgl-eyebrow-color);
}

.tgl-homes .tgl-homes__name {
    margin: 0;
    font-family: var(--tgl-font-heading);
    font-size: 1.25rem;               /* 20 — 157:1424 */
    font-weight: 600;
    line-height: normal;
    color: var(--tgl-heading-color);
}

.tgl-homes .tgl-homes__link {
    /* `!important`, y medido en el sitio: el nombre de la casa salía NARANJA.
       El kit de Elementor pinta los links con su color de acento y lo hace con
       `!important`, así que `color: inherit` en (0,2,0) no alcanzaba. Es el
       mismo adversario que ya obligó al `!important` de `.tgl-cta` y al del
       pill activo. */
    color: var(--tgl-heading-color) !important;
    text-decoration: none;
}

/* Solo para el lector de pantalla: el "(opens in a new tab)" del link. Un link
   que te manda a otra pestaña tiene que decirlo, y visualmente ya lo dice la
   flecha. */
.tgl-homes .tgl-homes__sr {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    border: 0;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Lo que hace clickeable la card entera sin que el link se coma la bajada y el
   precio como nombre accesible. Ver el docblock de `HomesHtml::name()`. */
.tgl-homes .tgl-homes__link::after {
    content: "";
    position: absolute;
    inset: 0;
}

.tgl-homes .tgl-homes__note {
    margin: 0;
    font-family: var(--tgl-font-heading);
    /* Itálica, y es Raleway — la familia del nombre, no la del cuerpo. En el
       archivo (157:1426) es la voz editorial de la card, no un párrafo. */
    font-size: 0.90625rem;            /* 14.5 — 157:1426 */
    font-style: italic;
    font-weight: 400;
    line-height: 1.4;                 /* 20.3 / 14.5 */
    color: var(--tgl-note-color);
}

/* ── El precio ── */

.tgl-homes .tgl-homes__price {
    display: flex;
    align-items: center;
    /* CENTRADO, y no es un descuido de lectura: el archivo dice `justify-center`
       (157:1427) y el render lo confirma —el precio arranca 17px más a la
       derecha que "EXUMA" y que el nombre. Es la única línea centrada de la
       card, a propósito: es el dato, no la prosa. */
    justify-content: center;
    /* Envuelve como fila, no como palabra: con `nowrap` en los spans, si los
       dos datos no entran juntos el segundo baja entero. El `0.3em` es el aire
       del `·` del diseño, ahora como gap para que no cuente cuando el
       separador no está. */
    flex-wrap: wrap;
    column-gap: 0.3em;
    /* `margin-top: auto` empuja la línea al piso de la card. Con el `flex: 1`
       del cuerpo, es lo que hace que las cuatro cards de una fila tengan la
       línea a la misma altura sin importar cuántas líneas tenga la bajada. */
    margin: auto 0 0;
    padding-top: 1.0625rem;           /* 17 — 157:1427 */
    /* El archivo dibuja esta línea a 0.09 y el borde de la card a 0.10: un
       punto de alfa sobre el mismo color, o sea la misma decisión escrita dos
       veces. Unificadas en `--tgl-card-border`. Ver DIVERGENCIA 5. */
    border-top: 1px solid var(--tgl-card-border);
    font-family: var(--tgl-font-body);
    /* El 13.5 del archivo (157:1429) llega por el `clamp` de más abajo, que lo
       pone como MÁXIMO. Declararlo también acá sería una regla que la de abajo
       pisa siempre. */
    line-height: normal;
}

/* Los tres textos de la card son `<p>`, y un tope de medida sobre párrafos es
   de las cosas más comunes que emite un tema o el kit de Elementor. Con la
   fila del precio apretada a 110px las palabras ya no se parten —eso lo
   arregla el `nowrap` de abajo— pero la fila envuelve en dos renglones donde
   el diseño tiene uno. Medido en el harness el 2026-09-09 simulando
   `.elementor-kit-6 p { max-width: 110px }`: con esta regla vuelve a 220.5 y a
   una sola línea.

   `!important` porque el adversario ya usó `!important` antes: es el mismo kit
   que pintó de naranja el nombre de la casa y de negro el texto de `.tgl-cta`.
   No está diagnosticado que hoy tope los párrafos; está puesto para que no
   importe. */
.tgl-homes .tgl-homes__island,
.tgl-homes .tgl-homes__note,
.tgl-homes .tgl-homes__price {
    max-width: none !important;
}

/* El footer partido en dos líneas, tercera y última vuelta.

   Medido el 2026-09-09 con las cadenas REALES del sitio, a 266.5 de card y
   220.5 disponibles: las ocho entran en una fila a 13.5px, y el peor caso
   —"from $12,500/night · Sleeps 24"— mide 200.14. O sea que **en el ancho del
   diseño no hay problema**, y las cards del sitio son más angostas que eso.

   Acá había dos escalones fijos (12.5px abajo de 252, padding 16 abajo de 232).
   Eran una adivinanza sobre CUÁNTO más angostas, y el usuario reportó que
   seguía rompiéndose: un umbral adivinado se puede volver a errar.

   Esto no. La fila escala con SU card. El `cqi` se mide contra la caja de
   CONTENIDO del contenedor, que son 264.5 —los 266.5 de la card menos su borde
   de 1px a cada lado— así que la proporción es 13.5 / 264.5 = 5.104%. Medido,
   no calculado de memoria: con 5.066 daba 13.3996 y no 13.5. Así
   `5.104cqi` da exactamente el tamaño del diseño en el ancho del diseño y baja
   en proporción. El texto escala con la fuente y el espacio con el ancho de la
   card, así que **si entra a un ancho, entra a todos** — no queda número que
   errar. El `clamp` fija los extremos: nunca más grande que el diseño, y un
   piso de 11px para que una card absurdamente angosta pare de encoger en vez de
   volverse ilegible. */
.tgl-homes .tgl-homes__price {
    font-size: clamp(0.6875rem, 5.104cqi, 0.84375rem);
}

/* El padding sí queda como escalón, y es el cinturón de seguridad: está fijo en
   22, así que a medida que la card se angosta se come una fracción cada vez
   mayor y la proporción de arriba se queda corta. Cederlo abajo de 232 devuelve
   12px justo donde empieza a apretar. El 22 está medido del archivo (157:1420),
   así que se toca último. */
@container (max-width: 232px) {
    .tgl-homes .tgl-homes__body {
        padding-inline: 1rem;
    }
}

/* `flex: none` + `nowrap` en los tres, y es un arreglo reportado: en el sitio
   la fila salía como "from / $1,089/night" y "Sleeps / 10", cuatro líneas
   quebradas donde el diseño tiene una. La causa es que los spans son items
   flex y `flex-shrink` vale 1 por defecto, así que cuando el texto no entra no
   se va a otra línea: se encoge y parte las palabras adentro. Con esto, si de
   verdad no entra, la fila envuelve limpia en dos renglones. */
.tgl-homes .tgl-homes__from,
.tgl-homes .tgl-homes__sep,
.tgl-homes .tgl-homes__meta {
    flex: none;
    white-space: nowrap;
}

.tgl-homes .tgl-homes__from {
    font-weight: 700;                 /* Bold — 157:1429 */
    color: var(--tgl-heading-color);
}

.tgl-homes .tgl-homes__sep {
    color: var(--tgl-meta-color);
}

.tgl-homes .tgl-homes__meta {
    font-weight: 400;
    color: var(--tgl-meta-color);
}

/* ── Hover y foco de la card ── */

/* El hover de la card entera, no solo del link: la foto también abre la casa,
   así que el estado tiene que responder desde cualquier parte de la card.

   **Es la única señal de hover que queda.** El zoom de la foto, la flecha al
   lado del nombre y el subrayado salieron en la v3.36.0 a pedido del usuario:
   el zoom porque era demasiado, y los otros dos porque son diseño que el
   archivo de Figma no tiene — esa decisión la toma el equipo cuando lo vea, no
   yo mientras arreglo un footer.

   Así que el salto pasó de 3px a 6 y la sombra se reforzó: tiene que alcanzar
   solo. */
@media (hover: hover) {
    .tgl-homes .tgl-homes__card:hover {
        border-color: var(--tgl-pill-border);
        box-shadow: 0 14px 32px rgba(31, 29, 26, 0.18);
        transform: translateY(-6px);
    }
}

/* El press. En touch no hay hover, así que esto es la ÚNICA confirmación de que
   el tap se registró. El usuario lo pesó así al sacar lo demás: "en Mobile
   imagino que la gente lo va a apretar igual y no habra drama" — de acuerdo, y
   por eso el hundido también se marcó más. */
.tgl-homes .tgl-homes__card:active {
    transform: translateY(-2px) scale(0.99);
}

.tgl-homes .tgl-homes__media {
    cursor: pointer;
}

@media (prefers-reduced-motion: no-preference) {
    .tgl-homes .tgl-homes__card {
        transition:
            border-color var(--tgl-transition-fast),
            box-shadow var(--tgl-transition-fast),
            transform var(--tgl-transition-fast);
    }
}

/* El foco va en la CARD y no en el link: el link es el nombre, pero el área
   clickeable es toda la card, y un anillo alrededor de dos palabras cuando lo
   que se activa es la caja entera miente sobre el objetivo. */
.tgl-homes .tgl-homes__card:has(.tgl-homes__link:focus-visible) {
    outline: 2px solid var(--tgl-eyebrow-color);
    outline-offset: 3px;
}

/* ── El CTA ───────────────────────────────────────────────────────────── */

.tgl-homes .tgl-homes__foot {
    display: flex;
    justify-content: center;
}

/* El botón es `.tgl-cta`, en el design system. El archivo dibuja ÉSTE más
   grande que los otros dos —36/17 de padding, radio 10, 16px SemiBold contra
   24/13.5, radio 6, 15px Medium en `Islands` (206:895) y `Step-by-step`
   (206:240)—. Dos secciones coinciden y una no, la diferencia está repartida en
   cinco propiedades sin cambio de color ni de forma, y la instrucción vigente
   es normalizar esa deriva en vez de shipearla. Si resulta ser jerarquía
   deliberada, se vuelve un modificador `--lg` de la clase compartida, en un
   solo lugar. Ver el docblock de `HomesHtml::cta()`. */

/* ==========================================================================
   Mobile — 80% del tráfico
   ========================================================================== */

@media (max-width: 1023px) {

    .tgl-homes {
        padding-block: var(--tgl-space-12);
    }

    .tgl-homes .tgl-homes__inner { gap: var(--tgl-space-8); }

    /* Dos columnas y no tres: a 1023 el container da 943 de contenido, y tres
       cards de 297 con la foto en 4:3 dejan la grilla más alta que la pantalla.
       Dos de 458 mantienen la foto protagonista. */
    .tgl-homes .tgl-homes__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .tgl-homes .tgl-homes__title { font-size: 2rem; }

    .tgl-homes .tgl-homes__lead { font-size: 1rem; }
}

/* 599 y no 767 —el corte que usan `Islands` y `Process`— porque acá la card
   tiene un ancho natural: a 600 de viewport, con los 20 de gutter, cada una de
   las dos columnas mide 270, que es el ancho de la card en el diseño. Bajar a
   una sola columna antes de eso sería dejar la mitad de la pantalla vacía. */
@media (max-width: 599px) {

    .tgl-homes .tgl-homes__grid {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--tgl-space-5);
    }

    .tgl-homes .tgl-homes__body {
        padding: var(--tgl-space-5);
    }

    /* Los pills alineados a la izquierda y en scroll horizontal: cinco pills
       centrados en 335px son tres filas, y tres filas de controles arriba de la
       grilla empujan las cards abajo del pliegue. */
    .tgl-homes .tgl-homes__filters {
        flex-wrap: nowrap;
        justify-content: flex-start;
        overflow-x: auto;
        /* Los 20 del gutter, al ras, para que el primer pill no arranque pegado
           al borde y el último tenga aire al final del scroll. */
        margin-inline: calc(var(--tgl-space-5) * -1);
        padding-inline: var(--tgl-space-5);
        /* 4 y no 2: `overflow-x: auto` fuerza `overflow-y: auto`, así que la
           fila recorta también arriba y abajo — y el anillo de foco necesita
           `outline-offset` (2) + `outline-width` (2) = 4 de despeje a cada
           lado. Con 2 se cortaba justo a la mitad. Medido a 375 el 2026-09-09. */
        padding-block: 4px;
        scrollbar-width: none;
    }

    .tgl-homes .tgl-homes__filters::-webkit-scrollbar {
        display: none;
    }
}
