/* =========================================================================
   Casermeiro - design system
   Loaded after Bootstrap 5.3, and it is the only stylesheet allowed to
   override it. The legacy style.css is no longer loaded by any page.

   The visual identity is unchanged from the previous site: firebrick red
   headings set in EB Garamond over white, body copy in Raleway.
   ========================================================================= */

:root {
    /* Brand ---------------------------------------------------------- */
    --brand:            #b22222;
    --brand-dark:       #8c1b1b;
    --brand-light:      #d94a4a;
    --brand-tint:       #fbf0f0;

    /* Neutrals ------------------------------------------------------- */
    --ink:              #1f1f20;
    --body:             #666666;
    --muted:            #8a8a8a;
    --line:             #e4e4e4;
    --surface:          #ffffff;
    --surface-alt:      #faf8f7;

    /* Type -----------------------------------------------------------
       The wordmark in the logo is set in Roman inscriptional small caps - a
       large initial followed by smaller capitals, with fine flat serifs. Cinzel
       descends from the same Trajan lettering, so headings and the menu now
       read as the same family as the logo instead of merely "a serif".

       Cinzel has no true lowercase: it draws small caps instead. That suits the
       headings, which are uppercase anyway, but anything that must stay
       readable as ordinary text - an e-mail address, a property description -
       has to use the body font. Those exceptions are marked where they occur. */
    --font-display:     "Cinzel", "Trajan Pro", Georgia, "Times New Roman", serif;
    --font-body:        "Raleway", system-ui, -apple-system, "Segoe UI", sans-serif;

    /* A modular scale, in rem so it stays predictable in every container.
       Bootstrap's own .small is in em and drifts; .nota below replaces it. */
    --step--1:          0.875rem;   /* 14px */
    --step-0:           1rem;       /* 16px */
    --step-1:           1.25rem;    /* 20px */
    --step-2:           1.5625rem;  /* 25px - navbar links */
    --step-3:           1.953rem;   /* 31px */
    --step-4:           2.5rem;     /* 40px - section headings */

    /* Space ---------------------------------------------------------- */
    --gap-xs:           0.5rem;
    --gap-sm:           1rem;
    --gap-md:           1.5rem;
    --gap-lg:           2.5rem;
    --gap-xl:           4rem;

    /* Shape ---------------------------------------------------------- */
    --radius:           8px;
    --radius-sm:        4px;
    --radius-pill:      999px;
    --shadow:           0 2px 12px rgba(0, 0, 0, .08);
    --shadow-lift:      0 10px 28px rgba(0, 0, 0, .14);
    --ring:             0 0 0 .25rem rgba(178, 34, 34, .25);

    --transition:       180ms ease;

    /* Bootstrap's own variables, repointed at the brand so components we
       do not restyle by hand still come out in the right colour. */
    --bs-primary:       #b22222;
    --bs-primary-rgb:   178, 34, 34;
    --bs-link-color:    #b22222;
    --bs-link-hover-color: #8c1b1b;
    --bs-body-font-family: var(--font-body);
    --bs-body-color:    #666666;
    --bs-border-color:  #e4e4e4;
}

/* Bootstrap sets [hidden] via display, and any component rule that declares
   display:flex or display:grid wins over it. Without this, an element toggled
   with the hidden attribute stays on screen - which is how a contact form ends
   up showing its success and error messages at the same time, from page load. */
[hidden] {
    display: none !important;
}

/* -------------------------------------------------------------------------
   Base
   ------------------------------------------------------------------------- */

body {
    font-family: var(--font-body);
    font-size: var(--step-0);
    line-height: 1.65;
    color: var(--body);
    background: var(--surface);
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6,
.display-title {
    font-family: var(--font-display);
    font-weight: 500;
    color: var(--brand);
    line-height: 1.2;
}

/* Capped below the old 40px for the same reason as .section-title: this is a
   capitals-only face, and capitals carry at a smaller size than lowercase. */
h1 { font-size: clamp(1.5rem, 1.2rem + 1.5vw, 2rem);    letter-spacing: .04em; }
h2 { font-size: clamp(1.3rem, 1.1rem + 1.1vw, 1.65rem); letter-spacing: .05em; }
h3 { font-size: clamp(1.15rem, 1rem + .8vw, 1.35rem);   letter-spacing: .05em; }

a {
    color: var(--brand);
    text-decoration: none;
    transition: color var(--transition);
}

a:hover,
a:focus-visible {
    color: var(--brand-dark);
}

/* A visible focus ring on every interactive element. The legacy theme removed
   outlines entirely, which left keyboard users with no position indicator. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

img {
    max-width: 100%;
    height: auto;
}

/* Replaces Bootstrap's .small, which is sized in em and therefore renders at a
   different size depending on what it sits inside. */
.nota {
    font-size: var(--step--1);
    color: var(--muted);
}

/* -------------------------------------------------------------------------
   Section heading - the red serif band used across the site
   ------------------------------------------------------------------------- */

.section {
    padding-block: var(--gap-xl);
}

.section--alt {
    background: var(--surface-alt);
}

/* The page-level band heading. Capped well below the old 40px: Cinzel is set in
   capitals, and capitals at that size read as a poster rather than a heading -
   especially with several of them down one page. */
.section-title {
    font-family: var(--font-display);
    font-size: clamp(1.35rem, 1.15rem + 1vw, 1.75rem);
    font-weight: 600;
    letter-spacing: .08em;
    color: var(--brand);
    text-align: center;
    text-transform: uppercase;
    margin-bottom: var(--gap-lg);
}

.section-title::after {
    content: "";
    display: block;
    width: 56px;
    height: 2px;
    margin: var(--gap-sm) auto 0;
    background: var(--brand);
    opacity: .5;
}

/* -------------------------------------------------------------------------
   Navbar
   ------------------------------------------------------------------------- */

.site-header {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    position: sticky;
    top: 0;
    z-index: 1030;
}

.site-header__logo img {
    height: 60px;
    width: auto;
}

/* Bootstrap targets these links as .navbar-expand-lg .navbar-nav .nav-link,
   a three-class selector. A two-class rule of ours would lose on specificity
   and fail silently, so the class count is matched here deliberately. */
.site-header .navbar-nav .nav-link {
    font-family: var(--font-display);
    /* Inscriptional capitals carry at a smaller size than lowercase text, and
       they need room to breathe rather than scale: the previous 25px made the
       menu shout over the logo, and six labels at that size did not fit beside
       it - the longest broke onto a second line and pushed the sticky header
       from 70px to 115px. Smaller, letterspaced and on one line reads calmer
       and matches the spacing of the wordmark. */
    font-size: 1rem;
    letter-spacing: .08em;
    font-weight: 400;
    color: var(--brand);
    text-transform: uppercase;
    padding-inline: .75rem;
    position: relative;
    transition: color var(--transition);
    white-space: nowrap;
}

@media (min-width: 1400px) {
    .site-header .navbar-nav .nav-link {
        font-size: 1.05rem;
        padding-inline: .9rem;
    }
}

.site-header .navbar-nav .nav-link:hover,
.site-header .navbar-nav .nav-link:focus-visible {
    color: var(--brand-dark);
}

.site-header .navbar-nav .nav-link::after {
    content: "";
    position: absolute;
    left: var(--gap-sm);
    right: var(--gap-sm);
    bottom: .35rem;
    height: 1px;
    background: var(--brand);
    transform: scaleX(0);
    transition: transform var(--transition);
}

.site-header .navbar-nav .nav-link:hover::after,
.site-header .navbar-nav .nav-link[aria-current="page"]::after {
    transform: scaleX(1);
}

.navbar-toggler {
    border-color: var(--line);
}

.navbar-toggler:focus {
    box-shadow: var(--ring);
}

/* -------------------------------------------------------------------------
   Hero
   ------------------------------------------------------------------------- */

.hero {
    position: relative;
    min-height: min(78vh, 640px);
    display: grid;
    place-items: center;
    overflow: hidden;
    background: var(--ink);
}

.hero__media {
    position: absolute;
    inset: 0;
    object-fit: cover;
    width: 100%;
    height: 100%;
}

.hero__scrim {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(0, 0, 0, .28) 0%, rgba(0, 0, 0, .45) 100%);
}

.hero__inner {
    position: relative;
    text-align: center;
    padding: var(--gap-lg) var(--gap-sm);
}

.hero__title {
    color: #fff;
    text-shadow: 0 2px 18px rgba(0, 0, 0, .5);
    margin-bottom: var(--gap-md);
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap-sm);
    justify-content: center;
}

/* -------------------------------------------------------------------------
   Buttons
   ------------------------------------------------------------------------- */

.btn {
    font-family: var(--font-body);
    font-weight: 600;
    letter-spacing: .02em;
    border-radius: var(--radius-sm);
    padding: .65rem 1.75rem;
    transition: background-color var(--transition), border-color var(--transition),
                color var(--transition), transform var(--transition);
}

.btn-brand {
    background: var(--brand);
    border: 1px solid var(--brand);
    color: #fff;
}

.btn-brand:hover,
.btn-brand:focus-visible {
    background: var(--brand-dark);
    border-color: var(--brand-dark);
    color: #fff;
}

/* Outlined button for a LIGHT background: the border and the label carry the
   brand colour.

   This used to be a white outline, which is only legible over a photograph.
   Four of its five uses were on white panels, where the button was invisible
   until the pointer landed on it and the hover state painted it in. The white
   variant now has its own name, .btn-hero-outline, so the two cannot be
   confused by whoever reaches for "the outline button" next. */
.btn-brand-outline {
    background: transparent;
    border: 1px solid var(--brand);
    color: var(--brand);
}

.btn-brand-outline:hover,
.btn-brand-outline:focus-visible {
    background: var(--brand);
    border-color: var(--brand);
    color: #fff;
}

/* Outlined button for a DARK background - the hero, over the photograph. */
.btn-hero-outline {
    background: transparent;
    border: 1px solid #fff;
    color: #fff;
}

.btn-hero-outline:hover,
.btn-hero-outline:focus-visible {
    background: #fff;
    border-color: #fff;
    color: var(--brand);
}

.btn-lg {
    font-size: var(--step-1);
    padding: .8rem 2.25rem;
}

/* -------------------------------------------------------------------------
   Search panel
   ------------------------------------------------------------------------- */

.buscador {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: var(--gap-md);
}

.buscador--floating {
    margin-top: calc(var(--gap-xl) * -1);
    position: relative;
    z-index: 5;
}

.buscador label {
    font-size: var(--step--1);
    font-weight: 600;
    color: var(--ink);
    margin-bottom: .25rem;
}

.form-select,
.form-control {
    border-radius: var(--radius-sm);
    border-color: var(--line);
    padding: .55rem .75rem;
    color: var(--ink);
}

.form-select:focus,
.form-control:focus {
    border-color: var(--brand-light);
    box-shadow: var(--ring);
}

/* -------------------------------------------------------------------------
   Property card
   ------------------------------------------------------------------------- */

.property-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    /* Keeps the card's stacking context to itself, so a badge inside can never
       paint over the sticky header while the page scrolls. */
    isolation: isolate;
    transition: transform var(--transition), box-shadow var(--transition);
}

.property-card:hover,
.property-card:focus-within {
    transform: translateY(-4px);
    box-shadow: var(--shadow-lift);
}

/* The media wrapper is a sibling of the badge, never its parent: Bootstrap's
   .ratio stretches every direct child to the full box, which would turn a
   small badge into a full-bleed block covering the photo. */
.property-card__media {
    position: relative;
    overflow: hidden;
}

.property-card__img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    display: block;
    transition: transform 400ms ease;
}

.property-card:hover .property-card__img {
    transform: scale(1.06);
}

.property-card__badge {
    position: absolute;
    top: var(--gap-xs);
    left: var(--gap-xs);
    z-index: 2;
    background: var(--brand);
    color: #fff;
    font-size: var(--step--1);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: .25rem .7rem;
    border-radius: var(--radius-pill);
}

.property-card__body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    padding: var(--gap-sm);
    gap: .35rem;
}

.property-card__title {
    font-family: var(--font-body);
    font-size: var(--step-0);
    font-weight: 700;
    color: var(--ink);
    margin: 0;
    line-height: 1.35;
}

.property-card__meta {
    font-size: var(--step--1);
    color: var(--muted);
    margin: 0;
}

.property-card__features {
    display: flex;
    flex-wrap: wrap;
    gap: var(--gap-xs) var(--gap-sm);
    font-size: var(--step--1);
    color: var(--body);
    margin-top: auto;
    padding-top: var(--gap-xs);
}

.property-card__features:empty {
    display: none;
}

.property-card__feature {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
}

.property-card__price {
    font-family: var(--font-display);
    font-size: var(--step-1);
    font-weight: 600;
    color: var(--brand);
    margin: 0;
}

/* The whole card is clickable, but only the title is a real link, so the
   accessible name stays meaningful.

   The overlay resolves against .property-card, which is the positioned
   ancestor. It must NOT be .property-card__body: a containing block on the
   body would clip the overlay to the text area, leaving the photograph - the
   part people actually aim at - inert. */
.property-card__link::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 3;
}

/* The badge is painted above the overlay so it stays legible, so it has to let
   clicks through - otherwise the corner carrying it is a dead spot. */
.property-card__badge {
    pointer-events: none;
}

/* -------------------------------------------------------------------------
   Detail page
   ------------------------------------------------------------------------- */

.detail-title {
    font-family: var(--font-display);
    /* The property name is a heading, not a banner. At the page-title size it
       ran to three lines of capitals and shouted over the photograph, which is
       what the visitor actually came to look at. */
    font-size: clamp(1.25rem, 1.05rem + 1vw, 1.65rem);
    line-height: 1.25;
    letter-spacing: .03em;
    color: var(--brand);
    text-transform: uppercase;
}

/* Headings for the blocks INSIDE the page - Descripción, Características,
   Comodidades, Ubicación.

   These were using .section-title, the treatment meant for a page-level band:
   40px, centred, with a rule under the middle. Four of them stacked down one
   column read as four page titles and dwarfed the text they introduced. A
   subsection only needs to be findable, so this is small, aligned with the
   content, and marked with a short rule at the start. */
.block-title {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--brand);
    margin: 0 0 var(--gap-md);
    padding-bottom: .55rem;
    border-bottom: 1px solid var(--line);
    position: relative;
}

.block-title::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: -1px;
    width: 44px;
    height: 2px;
    background: var(--brand);
}

.detail-panel {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: var(--gap-md);
}

/* The contact form partial is shared with the full-width pages, where its
   heading is a page-level title. Inside this narrow column that same size
   wrapped onto three lines and took over the panel. */
.detail-panel .section-title {
    font-size: 1rem;
    letter-spacing: .12em;
    text-align: left;
    margin-bottom: var(--gap-sm);
}

.detail-panel .section-title::after {
    margin-inline: 0;
    width: 36px;
}

.detail-price {
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 1.3rem + .8vw, 1.85rem);
    font-weight: 600;
    line-height: 1.15;
    color: var(--brand);
}

/* Specifications.

   Previously a row of narrow columns with the label and the value on one line,
   which ran together into an unreadable strip: "Tipo Casa Operación Venta
   Dormitorios 3". Stacking the pair gives each fact its own block, and the
   label can then be small and quiet without crowding the value. */
.detail-specs {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: .6rem;
}

/* Each fact carries its own border rather than the grid painting one through a
   1px gap: with a background showing through the gaps, a last row that does not
   fill its columns leaves grey blanks that read as missing data. */
.detail-specs li {
    display: flex;
    flex-direction: column;
    gap: .15rem;
    padding: .7rem .85rem;
    background: var(--surface-alt);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
}

.detail-specs .spec-label {
    display: flex;
    align-items: center;
    gap: .35rem;
    color: var(--muted);
    font-size: .8rem;
    letter-spacing: .02em;
}

.detail-specs .spec-value {
    color: var(--ink);
    font-weight: 600;
    font-size: 1.05rem;
    line-height: 1.3;
}

.detail-specs .icon {
    color: var(--brand);
    opacity: .75;
}

/* Amenities read as a set of tags. As bullets in a wide grid a single one -
   which happens often - looked like a mistake; as one tag it looks deliberate. */
.amenities {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

.amenities li {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .35rem .8rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--surface-alt);
    color: var(--ink);
    font-size: .9rem;
}

.amenities li::before {
    content: "";
    flex: 0 0 auto;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--brand);
}

/* The CRM sends the description as lines separated by <br>, so most of it is
   short single lines. Generous leading keeps that from reading as a cramped
   list, and the measure stops the paragraphs from running the full column. */
.detail-description {
    color: var(--body);
    line-height: 1.85;
    max-width: 68ch;
}

.detail-description br + br {
    line-height: 2.6;
}

.map-frame {
    width: 100%;
    aspect-ratio: 16 / 10;
    border: 0;
    border-radius: var(--radius);
    display: block;
}

.map-fallback {
    background: var(--surface-alt);
    border: 1px dashed var(--line);
    border-radius: var(--radius);
    padding: var(--gap-md);
    text-align: center;
    color: var(--muted);
}

/* -------------------------------------------------------------------------
   Contact form
   ------------------------------------------------------------------------- */

.contact-form .form-label {
    font-size: var(--step--1);
    font-weight: 600;
    color: var(--ink);
}

.contact-form .invalid-feedback {
    font-size: var(--step--1);
}

/* Off-screen rather than display:none, so automated form fillers still see it
   while people using a screen reader are not sent to it. */
.hp-field {
    position: absolute !important;
    left: -9999px !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.form-status {
    border-radius: var(--radius-sm);
    padding: var(--gap-sm);
    font-size: var(--step--1);
}

.form-status--ok {
    background: #e8f5e9;
    border: 1px solid #a5d6a7;
    color: #1b5e20;
}

.form-status--err {
    background: var(--brand-tint);
    border: 1px solid var(--brand-light);
    color: var(--brand-dark);
}

/* -------------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------------- */

.site-footer {
    background: var(--surface);
    border-top: 1px solid var(--line);
    padding-block: var(--gap-lg);
}

/* The footer menu is a brand element and takes the display face. */
.site-footer__nav a {
    font-family: var(--font-display);
    font-size: 1.05rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--brand);
}

.site-footer a {
    color: var(--brand);
}

/* The contact column is not: an e-mail address set in capitals is harder to
   read and to copy, and a phone number gains nothing from the display face. */
.site-footer__contact a,
.site-footer__contact li {
    font-family: var(--font-body);
    font-size: var(--step-0);
    letter-spacing: normal;
    text-transform: none;
}

.site-footer__nav {
    list-style: none;
    padding: 0;
    margin: 0;
}

.site-footer__contact {
    list-style: none;
    padding: 0;
    margin: 0;
}

.site-footer__contact li {
    display: flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: .35rem;
}

.site-footer__credit {
    border-top: 1px solid var(--line);
    margin-top: var(--gap-md);
    padding-top: var(--gap-sm);
    font-size: var(--step--1);
    color: var(--muted);
}

/* -------------------------------------------------------------------------
   Floating WhatsApp button
   ------------------------------------------------------------------------- */

.wa-fab {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 1040;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: #25d366;
    color: #fff;
    box-shadow: var(--shadow-lift);
    transition: transform var(--transition);
}

.wa-fab:hover,
.wa-fab:focus-visible {
    transform: scale(1.08);
    color: #fff;
}

.wa-fab svg {
    width: 30px;
    height: 30px;
    fill: currentColor;
}

.to-top {
    position: fixed;
    right: 18px;
    bottom: 84px;
    z-index: 1040;
    width: 42px;
    height: 42px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--brand);
    color: #fff;
    border: 0;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--transition), transform var(--transition);
}

.to-top.is-visible {
    opacity: 1;
    pointer-events: auto;
}

.to-top:hover {
    background: var(--brand-dark);
    color: #fff;
}

/* -------------------------------------------------------------------------
   Scroll reveal

   The hidden state is applied by a class that JavaScript puts on <html>, not
   by a bare attribute selector. If the script never runs - blocked, failed,
   an old browser - the class is never added and the content is simply visible,
   instead of being stranded at opacity 0 forever.
   ------------------------------------------------------------------------- */

.js-reveal [data-animate] {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 500ms ease, transform 500ms ease;
}

.js-reveal [data-animate].is-revealed {
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }

    .js-reveal [data-animate] {
        opacity: 1;
        transform: none;
    }
}

/* -------------------------------------------------------------------------
   Utilities
   ------------------------------------------------------------------------- */

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 2000;
    background: var(--brand);
    color: #fff;
    padding: .6rem 1rem;
    border-radius: 0 0 var(--radius-sm) 0;
}

.skip-link:focus {
    left: 0;
    color: #fff;
}

.icon {
    width: 1em;
    height: 1em;
    fill: currentColor;
    flex: 0 0 auto;
    vertical-align: -.125em;
}

.text-brand   { color: var(--brand) !important; }
.bg-brand     { background: var(--brand) !important; }
.border-brand { border-color: var(--brand) !important; }

.empty-state {
    text-align: center;
    padding: var(--gap-xl) var(--gap-sm);
    color: var(--muted);
}

/* -------------------------------------------------------------------------
   Narrow screens
   ------------------------------------------------------------------------- */

@media (max-width: 991.98px) {
    .site-header .navbar-nav .nav-link {
        font-size: var(--step-1);
        padding-block: .4rem;
    }

    .site-header .navbar-nav .nav-link::after {
        display: none;
    }

    .buscador--floating {
        margin-top: var(--gap-md);
    }
}

@media (max-width: 575.98px) {
    .section {
        padding-block: var(--gap-lg);
    }

    .hero {
        min-height: 60vh;
    }

    .detail-specs {
        grid-template-columns: 1fr 1fr;
    }
}

/* =========================================================================
   APPENDED - shared component layer (partials/)
   Added by the component-layer pass. Nothing above this marker is modified.
   ========================================================================= */

/* The card contract puts .property-card__badge as a SIBLING of
   .property-card__media, so that the ratio box cannot stretch it to full
   bleed. The badge is position:absolute, but nothing in the card established
   a containing block for it: .property-card__body is the only positioned
   element and the badge is not inside it. Without this rule the badge escapes
   to the nearest positioned ancestor - or the viewport - and lands somewhere
   unrelated to its own card. */
.property-card {
    position: relative;
}

/* -------------------------------------------------------------------------
   Hover gallery on the listing cards

   Resting the pointer on a card fades through its other photographs. The extra
   images are fetched on the first hover, so a grid of twenty-four cards still
   paints with twenty-four requests, not two hundred.

   The frames are stacked on top of each other inside the media box and only
   opacity changes, which the compositor can animate without relayout.
   ------------------------------------------------------------------------- */

.property-card__media {
    position: relative;
    /* Reserves the height before any image loads, so the grid does not jump. */
    aspect-ratio: 4 / 3;
    background: var(--surface-alt);
}

.property-card__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 400ms ease, transform 400ms ease;
}

.property-card__img.is-active {
    opacity: 1;
}

.property-card:hover .property-card__img.is-active {
    transform: scale(1.06);
}

/* A quiet hint that there is more than one photograph, shown only once the
   extra frames have actually arrived. */
.property-card__count {
    position: absolute;
    right: var(--gap-xs);
    bottom: var(--gap-xs);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .15rem .5rem;
    border-radius: var(--radius-pill);
    background: rgba(0, 0, 0, .55);
    color: #fff;
    font-size: .75rem;
    line-height: 1.6;
    pointer-events: none;
    opacity: 0;
    transition: opacity var(--transition);
}

.property-card.has-gallery .property-card__count {
    opacity: 1;
}

/* Touch screens have no hover to rest with, and a device that reports reduced
   motion should not be given a slideshow. In both cases the card keeps its
   cover image and never fetches the rest. */
@media (hover: none), (prefers-reduced-motion: reduce) {
    .property-card__count {
        display: none;
    }

    .property-card:hover .property-card__img.is-active {
        transform: none;
    }
}

/* -------------------------------------------------------------------------
   Checklist

   For lists whose items are sentences rather than single words. The tag
   treatment in .amenities is right for "Piscina" or "Anisacate"; a pill
   wrapped around "Superficie del terreno y superficie cubierta" only makes
   the line harder to read.
   ------------------------------------------------------------------------- */

.checklist {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: .55rem;
}

.checklist li {
    display: grid;
    grid-template-columns: 1.15rem 1fr;
    gap: .55rem;
    align-items: start;
    font-size: .95rem;
    line-height: 1.55;
    color: var(--body);
}

.checklist li::before {
    content: "";
    width: 1.15rem;
    height: 1.15rem;
    margin-top: .18rem;
    border-radius: 50%;
    background: var(--brand-tint);
    border: 1px solid var(--brand-light);
    /* A tick drawn with a background image needs no icon font and no extra
       element in the markup. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M5 10.5 8.3 14 15 6.6' fill='none' stroke='%23b22222' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    background-size: .8rem;
}

/* A button stretched to the width of its column does not need the horizontal
   padding that shapes an inline one. In the detail sidebar that padding was
   squeezing "Consultar por WhatsApp" onto two lines. */
.btn.w-100 {
    padding-inline: .75rem;
    /* One step down buys the room the label needs on a single line in the
       narrow detail sidebar, with margin to spare at the tightest breakpoint. */
    font-size: .95rem;
}
