/*
 Theme Name:   WP Rentals Child - Puerto Morelos Life
 Theme URI:    https://rentals.puertomoreloslife.com
 Description:  Child theme for WP Rentals, customized for Puerto Morelos Life vacation rental directory.
 Author:       Chuy (JesusLpz30)
 Author URI:   https://github.com/JesusLpz30
 Template:     wprentals
 Version:      1.0.7
 License:      Private
 Text Domain:  wprentals-child
*/

/* !!! VERSION HEADER KILL SWITCH — DO NOT BUMP TO 1.1+ !!!
   The PARENT theme (wprentals/functions.php, wprentals_deactivate_21_plugin on
   admin_init) reads THIS file's "Version:" header via wp_get_theme() and
   FORCE-DEACTIVATES the wprentals-core plugin (singles 404, home/about 500)
   whenever floatval(Version) lands in [1.1, 2.2). This caused the S17 and S43
   incidents (Version 2.0.0 and 1.1.x respectively). Safe values: 1.0.x ONLY
   (floatval == 1 is the vendor's child-theme exemption). Bump the PATCH digit
   for cache busting (1.0.1, 1.0.2, ...). Watchdog: mu-plugins/pml-watchdog.php.
   Runbook: docs repo custom-code-registry.md "Single property 404". */

/* Parent theme folder verified 2026-04-09 in Local pull from Production:
   wp-content/themes/wprentals/ — child theme correctly references it. */

/* ==========================================================================
   PML Design System Variables
   CT-55 (2026-06-06) — TOTAL MIGRATION to the Showit-extracted flat system.
   Old system (coral #E45E4C + Jost + glassmorphism) SUPERSEDED.
   ========================================================================== */

:root {
    /* ==========================================================================
       LAYER 0 — NEW DESIGN SYSTEM PRIMITIVES (CT-55, 2026-06-06)
       Source of truth: docs/governance/design-system/ (extracted from Showit).
       Decision: Chuy 2026-06-06 — total brand switch to the flat Showit system
       (coral #FA4E24, cream, Outfit/Poppins, zero shadow/glass, square inputs,
       pill buttons). Strategy "break-nothing": these new --color-*/--font-*/
       --radius-* names are canonical for NEW code; the legacy --pml-* names in
       Layer 1 are KEPT and re-pointed here (153+ refs depend on the --pml-*
       names, so we re-map values instead of renaming). Fonts are Google-Fonts-
       only / OFL (Outfit + Poppins); Showit-CDN + the Marlide trial font are
       intentionally NOT used (100% license-clean — Chuy decision).
       ========================================================================== */

    /* Backgrounds */
    --color-bg-page:        #fcf9f5;   /* cream — global page background */
    --color-bg-dark:        #2e0a16;   /* burgundy — dark section / footer */
    --color-bg-lavender:    #ead8f5;   /* lavender accent */
    --color-bg-sky:         #d0eaf0;   /* sky — soft blue accent / UI button */
    --color-bg-chartreuse:  #e9f29c;   /* chartreuse accent */
    --color-bg-white:       #ffffff;
    --color-bg-black:       #000000;

    /* Brand / accent */
    --color-primary:        #fa4e24;   /* coral — CTA, logo, nav */
    --color-secondary:      #eca27a;   /* peach — secondary button (NOTE: white text on
                                          peach = 2.1:1, fails AA — use dark text on peach) */
    --color-coral-dark:     #c63d18;   /* WCAG AA coral for body links — 5.14:1 on white
                                          (new #fa4e24 is only 3.4:1 = AA-large/buttons only) */

    /* Text */
    --color-text-default:   #000000;
    --color-text-white:     #ffffff;
    --color-text-dark:      #2e0a16;   /* burgundy display text */
    --color-text-gray:      #333333;   /* inputs / body */
    --color-text-accent:    #fa4e24;

    /* Borders */
    --color-border-gray:    #b8b8b8;   /* input / structural borders (flat system) */

    /* UI */
    --color-dot-indicator:  #ead8f5;   /* decorative nav dot */

    /* Fonts — Google Fonts only (OFL). Outfit ≈ Google Sans; Poppins = UI.
       --font-display-serif (Fraunces) is RESERVED but NOT enqueued unless an
       in-scope serif heading needs it (search + user pages use sans only). */
    --font-body:            'Outfit', sans-serif;     /* body, headings */
    --font-ui:              'Poppins', sans-serif;     /* inputs, controls, small labels */
    --font-display-serif:   'Fraunces', serif;         /* reserved — not loaded by default */
    --font-system:          'Times', serif;            /* nav (system serif) */

    /* Radius — new flat scale (canonical). Per-component application is CT-56;
       legacy --pml-radius-* below stay at old values until CT-56 remaps them. */
    --radius-none:    0px;
    --radius-sm:      30px;     /* image / property cards */
    --radius-md:      40px;     /* containers, modals, dropdowns */
    --radius-pill:    100px;    /* primary buttons, nav pills */
    --radius-circle:  50%;

    /* ==========================================================================
       LAYER 1 — LEGACY PRIMITIVES (--pml-*) — REMAPPED to Layer 0 (CT-55)
       Names preserved for cascade safety. Values now point at the new system.
       Old Kim WhatsApp palette superseded by docs/governance/design-system/
       (brand-source-kim/ kept as historical provenance only).
       ========================================================================== */

    /* Primary */
    --pml-coral:      var(--color-primary);      /* now #fa4e24 */
    --pml-coral-dark: var(--color-coral-dark);   /* now #c63d18 — AA body links */
    --pml-black:      var(--color-bg-black);
    --pml-white:      var(--color-bg-white);

    /* Secondary — remapped to new accents; gold/pink RETAINED as functional */
    --pml-off-white:  var(--color-bg-page);      /* now cream #fcf9f5 */
    --pml-light-blue: var(--color-bg-sky);       /* now sky #d0eaf0 */
    --pml-pink:       #f7cbcb;                    /* RETAINED functional — calendar booked days */
    --pml-blue:       var(--color-bg-sky);       /* now sky (was secondary accent) */
    --pml-gold:       #e8bb5c;                    /* RETAINED functional — star ratings */

    /* Text hierarchy (neutral grays — work in both systems) */
    --pml-text:       var(--color-text-gray);    /* #333 body */
    --pml-text-secondary: #666666;               /* Captions, metadata */
    --pml-text-tertiary:  #999999;               /* Placeholders, disabled */

    /* Utilities */
    --pml-border:     var(--color-border-gray);  /* now #b8b8b8 — flat structural border */
    --pml-hover-bg:   #f5f0ec;                    /* RETAINED — warm hover bg (cream family) */

    /* Typography family — remapped to Outfit/Poppins (was Jost) */
    --pml-font-heading: var(--font-body);        /* Outfit — headings, titles */
    --pml-font-accent:  var(--font-ui);          /* Poppins — UI: dropdowns, buttons, cards, inputs */
    --pml-font-body:    var(--font-body);        /* Outfit — body text */

    /* ==========================================================================
       LAYER 1.5 — TYPOGRAPHY PRIMITIVES (sizes, weights, line-heights, tracking)
       Source of truth: docs/governance/typography-system.md
       Decision S25: 12 sizes, 5 weights, 9 line-heights, 6 letter-spacings.
       Anything outside this set in CSS = drift.
       ========================================================================== */

    /* Sizes (12 total) */
    --pml-fs-display:  36px;         /* Hero / display headlines */
    --pml-fs-h1:       28px;         /* Page titles, single property name */
    --pml-fs-h2:       24px;         /* Section headings (Description, Amenities) */
    --pml-fs-h3:       20px;         /* Card group headings, subsections */
    --pml-fs-h4:       18px;         /* Tertiary headings, nav menu items */
    --pml-fs-body-lg:  16px;         /* Lead paragraphs, prices */
    --pml-fs-body:     15px;         /* Standard body, card titles */
    --pml-fs-button:   15px;         /* Button labels */
    --pml-fs-body-sm:  14px;         /* Inputs, captions, secondary content */
    --pml-fs-label:    13px;         /* Form labels, badges, metadata */
    --pml-fs-helper:   12px;         /* Helper text, disclaimers, small print */
    --pml-fs-overline: 11px;         /* Badges, pill labels, tiny tags (UPPERCASE) */

    /* Weights (5 total — 300 reserved but currently unused) */
    --pml-fw-light:    300;          /* Reserved (not currently applied) */
    --pml-fw-regular:  400;          /* Body text default */
    --pml-fw-medium:   500;          /* Form labels, nav items */
    --pml-fw-semibold: 600;          /* Headings h2-h4, card titles, primary buttons */
    --pml-fw-bold:     700;          /* H1, prices, hero, strong emphasis */

    /* Line-heights (9 total) */
    --pml-lh-tight:        1;        /* Icons, single-line buttons */
    --pml-lh-display:      1.1;      /* Display headlines (36px+) */
    --pml-lh-heading-h1:   1.2;
    --pml-lh-heading-h2:   1.25;
    --pml-lh-heading-h3:   1.3;
    --pml-lh-heading-h4:   1.35;
    --pml-lh-tight-body:   1.4;      /* Card titles, dense UI text */
    --pml-lh-body:         1.5;      /* Body paragraphs, normal */
    --pml-lh-relaxed:      1.6;      /* Long-form content (terms, blog) */

    /* Letter-spacing (6 total) */
    --pml-ls-tight:       -0.5px;    /* Display headlines */
    --pml-ls-tight-h:     -0.3px;    /* H1 */
    --pml-ls-tight-soft:  -0.2px;    /* H2 */
    --pml-ls-normal:       0;        /* Default body, h3, h4, inputs */
    --pml-ls-wide:         0.3px;    /* Button labels */
    --pml-ls-wider:        0.5px;    /* Overline / uppercase badges */

    /* ==========================================================================
       LAYER 2 — SEMANTIC TOKENS (decision S25, Chuy approved)
       Source of truth: docs/governance/brand-guidelines.md §1.5
       New code uses these. Existing primitive references stay valid.
       ========================================================================== */

    /* Backgrounds */
    --pml-bg-page:          var(--pml-off-white);     /* Page-level background */
    --pml-bg-card:          var(--pml-white);         /* Cards, modals, content surfaces */
    --pml-bg-hover:         var(--pml-hover-bg);      /* Hover state on dropdowns/menu items */
    --pml-bg-glass-strong:  var(--pml-white);         /* FLAT (CT-55) — glass removed, solid surface */

    /* Text (semantic) */
    --pml-text-heading:     var(--pml-black);         /* Headings h1-h4 */
    --pml-text-body:        var(--pml-text);          /* Body paragraphs */
    --pml-text-on-coral:    var(--pml-white);         /* Text on coral backgrounds (buttons) */
    --pml-text-link:        var(--pml-coral-dark);    /* Inline links in body — WCAG AA 5.4:1 */
    /* --pml-text-secondary and --pml-text-tertiary already defined above as primitives */

    /* Borders (semantic) */
    --pml-border-accent:    var(--pml-light-blue);    /* Accent borders, alternating dividers */

    /* Action / interactive */
    --pml-action:           var(--pml-coral);         /* Primary CTA buttons, action color */
    --pml-action-hover:     var(--color-coral-dark);  /* Darken of coral on hover (CT-55) */
    --pml-action-text:      var(--pml-white);         /* Text on --pml-action */

    /* Semantic states — Strong Universal (decision S25)
       Universal recognition (red/green/amber) overrides strict Kim-adherence
       in functional UI feedback. WCAG AA verified for text-on-bg per token. */
    --pml-error-bg:         #fee2e2;
    --pml-error-text:       #dc2626;
    --pml-error-border:     #f87171;
    --pml-success-bg:       #dcfce7;
    --pml-success-text:     #16a34a;
    --pml-success-border:   #4ade80;
    --pml-warning-bg:       #fef3c7;
    --pml-warning-text:     #b45309;
    --pml-warning-border:   #fbbf24;

    /* Premium / accent */
    --pml-rating:           var(--pml-gold);          /* Stars, premium badges */
    --pml-accent-pink:      var(--pml-pink);          /* Calendar booked days */
    --pml-accent-blue:      var(--pml-blue);          /* Footer links, secondary accent */

    /* ==========================================================================
       LAYER 2.1 — BORDER-RADIUS SCALE (decision S25 Fase 2B)
       Source of truth: docs/governance/brand-guidelines.md §3 + §4
       Anything outside this scale = drift. Special asymmetric cases
       (e.g., `2px 0 0 0`) stay as inline values, intentional.
       ========================================================================== */
    /* CT-56: remapped to the flat Showit scale (0 / 30 / 40 / pill / circle).
       lg=40px → pill on short buttons (radius ≥ half-height) AND 40px on
       dropdown/panel surfaces, resolving the shared-token conflict. */
    --pml-radius-xs:      0;         /* was 4px — flat badges/tags */
    --pml-radius-sm:      0;         /* was 6px — flat notices */
    --pml-radius:         0;         /* was 8px — square secondary buttons / small cards */
    --pml-radius-md:      0;         /* was 10px — SQUARE INPUTS */
    --pml-radius-lg:      40px;      /* was 12px — pill buttons + 40px panels/dropdowns */
    --pml-radius-card:    30px;      /* was 14px — image / property cards */
    --pml-radius-xl:      40px;      /* was 16px — modals, popups, containers */
    --pml-radius-pill:    100px;     /* was 9999px — pill (same effect) */
    --pml-radius-circle:  50%;       /* circular elements */

    /* ==========================================================================
       LAYER 2.2 — GLASS / SHADOW TOKENS — FLATTENED (CT-55)
       The new Showit system uses NO box-shadow and NO glassmorphism. Hierarchy
       is built from color, shape, and typography. These tokens are flattened to
       none/solid so every component that references them flattens automatically
       (the per-component pass CT-56 cleans up any hardcoded shadow/glass left).
       ========================================================================== */

    /* Backdrop-filter blur — FLATTENED: no glassmorphism */
    --pml-blur-light:     none;
    --pml-blur-standard:  none;
    --pml-blur-strong:    none;

    /* Glass surfaces — FLATTENED to solid */
    --pml-glass-strong:   var(--pml-white);
    --pml-glass-medium:   var(--pml-white);
    --pml-glass-edge:     var(--color-border-gray);        /* CT-58: flat panel border #b8b8b8 (defines edges without shadow) */

    /* Box-shadow scale — FLATTENED to none */
    --pml-shadow-card:        none;
    --pml-shadow-card-hover:  none;
    --pml-shadow-floating:    none;
    --pml-shadow-subtle:      none;
}

/* ==========================================================================
   S31 — Focus rings, tap highlight, back-to-top (global resets)
   --------------------------------------------------------------------------
   Reset transversal:

   1) Outline default del browser (azul/morado/negro) en click/focus →
      reportado por Chuy "borde feo azul oscuro al click". Solución
      moderna usa :focus-visible para mostrar outline SOLO en keyboard
      navigation. Click/tap del mouse/dedo no muestra outline. WCAG SC
      2.4.7 (Focus Visible) sigue satisfecho — keyboard users ven el
      outline coral brand.

      @supports gate evita romper accesibilidad en browsers ancestrales
      que no soportan :focus-visible (Chrome <86, Safari <15.4) — esos
      mantienen el outline default del browser por fallback. Hoy son
      <0.5% del tráfico pero la regla es no degradar a11y.

   2) -webkit-tap-highlight-color (flash overlay azul/gris al tap en
      mobile) → transparente. Sin esto cada tap muestra un overlay
      momentáneo encima del elemento.

   3) Back-to-top button del parent theme (.backtop). CT-14 lo
      redesignó coral 36px en S13 pero Chuy ya no lo quiere visible
      en ninguna parte ("no me gusta que aparezca"). Hide global con
      display: none. El FAB de Rentals (S31 Bug 2/3) ocupará esa esquina
      en property-list/advanced-search; el resto del sitio no necesita
      scroll-to-top porque las páginas son cortas. Si en el futuro se
      quiere recuperar, basta quitar esta regla — los estilos de CT-14
      siguen vivos pero inactivos por display:none.
   ========================================================================== */

* {
    -webkit-tap-highlight-color: transparent;
}

@supports selector(:focus-visible) {
    *:focus {
        outline: none;
    }
    *:focus-visible {
        outline: 2px solid var(--pml-coral);
        outline-offset: 2px;
    }

    /* CT-61 (S44) — kill the BLUE focus ring on click/tap.
       Bootstrap 3 (parent theme) sets `outline: 5px auto -webkit-focus-ring-color`
       (the browser's blue ring) with `outline-offset:-2px` on a:focus, .btn:focus,
       and radio/checkbox/file:focus. Its class-level specificity (e.g. .btn:focus
       = 0,2,0) BEAT the global `*:focus` reset above (0,1,0), so the blue inset
       ring survived every prior attempt to remove it. These selectors restore the
       win for pointer interaction; keyboard users still get the coral
       :focus-visible ring above (a11y preserved). Text inputs keep their own coral
       focus (rules further down) — not touched here. */
    a:focus:not(:focus-visible),
    .btn:focus:not(:focus-visible),
    button:focus:not(:focus-visible),
    input[type="file"]:focus:not(:focus-visible),
    input[type="radio"]:focus:not(:focus-visible),
    input[type="checkbox"]:focus:not(:focus-visible),
    [tabindex]:focus:not(:focus-visible) {
        outline: none;
    }
}

/* S31 Bug #4 — Proxy invisible para el handler de #topbarlogin del parent.
   El parent inyecta un <div id="topbarlogin"> en su header.php; templates
   custom del child que no llaman get_header() pierden ese elemento. El JS
   del parent no encuentra el target → modal de login nunca se dispara.
   Inyectamos un proxy en CT-16 (visualmente oculto pero presente en DOM)
   para que el listener del parent y mi pml-header.js lo encuentren.
   Patrón visually-hidden (a11y) — sin display:none que rompería listeners. */
.pml-login-modal-proxy {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
    padding: 0;
    margin: -1px;
}

/* Defensive selectors para back-to-top — el parent theme y plugins
   comunes usan varias convenciones. Cubrimos las más típicas para que
   ninguna variante se cuele. */
.backtop,
#backtotop,
#back-to-top,
.back-to-top,
.scrolltop,
.scroll-top,
.scrolltotop,
.scroll-to-top,
[class*="backtotop"],
[id*="backtotop"] {
    display: none !important;
    visibility: hidden !important;
}

/* ==========================================================================
   WCAG 2.2 AA — Coral contrast fix
   --------------------------------------------------------------------------
   The brand coral #e45e4c has only 3.3:1 contrast on white, which fails
   WCAG 2.2 AA for body text (needs 4.5:1). Real legal exposure: ADA US,
   AODA Canada. The brand color is preserved on solid coral backgrounds
   (where text is white) and on large headings (where the WCAG threshold
   for "large text" is 3:1, which #e45e4c just meets).

   Strategy:
     - Body text → #333 (was already mostly the case)
     - Inline links inside content → coral-dark #b5440f
     - Coral text on white anywhere it appears as small text → coral-dark
     - Buttons / hero coral backgrounds with white text → untouched

   Audit reference: docs/research/wprentals-audit-2026-04-09.md (P0 #1)
   ========================================================================== */

/* Inline content links — replace pure coral with accessible variant */
.entry-content a:not(.btn):not(.button):not([class*="wpestate"]),
.listing_wrapper a:not(.btn):not(.button),
.property_listing a:not(.btn):not(.button),
.single-estate_property .listing_main_wrapper a:not(.btn):not(.button),
.post-content a:not(.btn):not(.button),
.widget a:not(.btn):not(.button) {
    color: var(--pml-coral-dark);
}

/* Common WP Rentals text elements where #e45e4c was applied as foreground */
.listing_main_image_price,
.property_listing_price,
.price_label,
.price,
.listing-unit-price-wrap,
.property-meta .meta-price,
.estate_breadcrumbs a,
.entry-meta a,
.post-meta a,
.read-more,
.more-link {
    color: var(--pml-coral-dark);
}

/* Hover state — keep coral-dark, slightly darker on hover */
.entry-content a:not(.btn):not(.button):not([class*="wpestate"]):hover,
.listing_wrapper a:not(.btn):not(.button):hover,
.property_listing a:not(.btn):not(.button):hover,
.single-estate_property .listing_main_wrapper a:not(.btn):not(.button):hover,
.post-content a:not(.btn):not(.button):hover,
.widget a:not(.btn):not(.button):hover {
    /* S25: was #8a3308 (undocumented brown). Use coral-dark token — same WCAG AA, in-palette. */
    color: var(--pml-coral-dark);
    text-decoration: underline;
}

/* Body text default — guarantee #333 even if parent overrides */
body,
.entry-content,
.entry-content p,
.post-content,
.post-content p,
.widget,
.listing_wrapper p,
.property_description {
    color: var(--pml-text);
}

/* ==========================================================================
   CT-2 companion: dimensions for full-width featured image
   --------------------------------------------------------------------------
   Parent CSS defines min-height for col-md-6 (515px) and col-md-3 (258px)
   but NOT for col-md-12. When CT-2 outputs col-md-12 for listings with
   <4 photos, the background-image div collapses without explicit height.

   References:
     Parent style.css:7863  .header_masonry .col-md-6.image_gallery { min-height: 515px }
     Parent style.css:7867  .header_masonry .col-md-3.image_gallery { min-height: 258px }
     Parent my_media.css:2803  @media ≤768px  .header_masonry .image_gallery { 150px }
   ========================================================================== */

.header_masonry .col-md-12.image_gallery {
    min-height: 515px;
}

@media only screen and (max-width: 768px) {
    .header_masonry .col-md-12.image_gallery {
        min-height: 300px !important;
        height: 300px;
        width: 100% !important;
    }
}

@media only screen and (max-width: 667px) {
    .header_masonry .col-md-12.image_gallery {
        min-height: 250px !important;
        height: 250px;
        width: 100% !important;
    }
}

/* ==========================================================================
   Icon content fix — fontello pseudo-elements
   --------------------------------------------------------------------------
   Parent theme style.css defines `content` multiple times in the same rule
   (Font Awesome fallback → fontello override). WP Engine's CSS optimization
   or browser parsing strips duplicate content declarations, leaving
   content: "" (empty). This makes all form icons invisible.

   Fix: explicitly re-declare the correct fontello content values.

   Parent references:
     style.css:8821-8834  .calendar_icon:after  content: "\e801"
     style.css:8976-8999  .guest_icon ...        content: "\e80c"
     style.css:9164-9171  .map_icon:after        content: "\e800"
   ========================================================================== */

/* Fontello icon fix — content + position
   Parent's triple content declaration breaks in CSSOM (content: "" computed).
   Icons also need vertical centering within 34px-high inputs. */
body .calendar_icon::after {
    content: "\e801" !important;
    font-family: "fontello" !important;
    top: 7px !important;
    font-size: 18px;
}

body .guest_icon .wpestate_guest_no_control_wraper::after,
body .guest_no_drop::after,
body #guest_no_drop::after,
body #guest_no_shortcode::after,
body #guest_no_mobile::after,
body #booking_guest_no_wrapper::after,
body #guest_no_widget::after,
body #guest_no::after {
    content: "\e80c" !important;
    font-family: "fontello" !important;
    top: 5px !important;
    font-size: 22px;
}

/* Align Guests field padding with calendar fields */
.guest_icon .wpestate_guest_no_control_info,
.guest_no_drop .wpestate_guest_no_control_info {
    padding-left: 45px !important;
}

body .map_icon::after {
    content: "\e800" !important;
    font-family: "fontello" !important;
    top: 7px !important;
    font-size: 17px;
}

/* ==========================================================================
   Search form icon positioning fix
   --------------------------------------------------------------------------
   The search form fields (Location, Check-In, Check-Out, Select Guests,
   Rental Type, etc.) use .custom_icon_class_icon with position:absolute,
   but the parent containers (col-md-4, col-md-8) lack position:relative.
   Icons position relative to a distant ancestor instead of their field.

   Also, parent CSS has `top` commented out (style.css:3938 /*top: 18px;*/),
   relying on line-height:48px which doesn't center properly in 39px inputs.

   Fix: add position:relative to field containers + explicit top for icons +
   padding-left for inputs inside those containers.
   ========================================================================== */

/* Ensure field containers are positioning context for absolute icons */
.advanced_search_form_wrapper [class*="col-md-"] {
    position: relative;
}

/* Center icon vertically within the input */
.advanced_search_form_wrapper .custom_icon_class_icon {
    top: 50% !important;
    transform: translateY(-50%);
    line-height: normal !important;
}

/* Ensure all inputs next to icons have left padding for the icon */
.advanced_search_form_wrapper .form-control,
.advanced_search_form_wrapper .wpestate_guest_no_control_info {
    padding-left: 45px !important;
}

/* ==========================================================================
   Font Awesome icon content fix
   --------------------------------------------------------------------------
   Same CSSOM bug as fontello: FA6 all.min.css and fontawesome.min.css have
   correct content values in the raw file, but browser CSSOM parses them as
   content: "" (empty) for all ::before pseudo-elements.

   Fix: re-declare content for all FA icons used on the site.
   Values sourced from: themes/wprentals/css/fontawesome/css/all.min.css
   ========================================================================== */

/* Search form icons (custom_icon_class_icon) */
body .fa-calendar-alt::before,
body .fa-calendar-days::before {
    content: "\f073" !important;
}

body .fa-globe::before {
    content: "\f0ac" !important;
}

body .fa-users::before {
    content: "\f0c0" !important;
}

body .fa-home::before,
body .fa-house::before {
    content: "\f015" !important;
}

body .fa-bed::before {
    content: "\f236" !important;
}

body .fa-dollar-sign::before,
body .fa-dollar::before,
body .fa-usd::before {
    content: "\24" !important;
}

body .fa-hospital::before {
    content: "\f0f8" !important;
}

body .fa-eye-slash::before {
    content: "\f070" !important;
}

body .fa-heart::before {
    content: "\f004" !important;
}

body .fa-times::before,
body .fa-xmark::before {
    content: "\f00d" !important;
}

body .fa-chevron-up::before {
    content: "\f077" !important;
}

body .fa-chevron-left::before {
    content: "\f053" !important;
}

body .fa-chevron-right::before {
    content: "\f054" !important;
}

body .fa-chevron-down::before {
    content: "\f078" !important;
}

/* ==========================================================================
   Caret fix — Bootstrap vs parent theme conflict
   --------------------------------------------------------------------------
   Parent theme sets .caret { border: none } to hide Bootstrap's CSS
   triangles and replace with FA chevron via .caret::after. But Bootstrap
   loads AFTER parent (line 104 vs 102) and re-applies border-top/bottom,
   making two triangles visible. Meanwhile FA chevron ::after has empty
   content (CSSOM bug).

   Fix: hide Bootstrap caret borders + restore FA chevron content.
   ========================================================================== */

.caret,
.caret_filter,
.caret_sidebar {
    border: none !important;
    width: auto !important;
    height: auto !important;
}

.caret::after {
    content: "\f078" !important;
    font-family: "Font Awesome 6 Free" !important;
    font-weight: 900;
    font-size: 11px;
    color: var(--pml-text-tertiary);
}

/* ==========================================================================
   Mobile header fix — compact + solid background
   --------------------------------------------------------------------------
   On half-map pages, the header is position:fixed with transparent
   background and 241px height (announcement bar + search form).
   This eats ~50% of mobile viewport. Fix: solid background, hide
   search form on mobile (accessible via filter button instead),
   keep header compact.
   ========================================================================== */

/* ==========================================================================
   Mobile/Tablet header — PLACEHOLDER
   --------------------------------------------------------------------------
   PENDIENTE: Diseño responsive del header planificado por breakpoints.
   Requiere mapear TODOS los breakpoints del parent theme + Elementor +
   Bootstrap antes de implementar. Ver plan en resumen-para-continuar.md.

   Breakpoints identificados que necesitan atención:
     >1155px  = desktop (funciona bien)
     1155-1007px = nav desaparece, solo Login/SignUp/Submit
     1007-691px  = hamburger aparece pero en posición incorrecta
     <691px   = mobile (Login/SignUp en fila extra, ocupa mucho espacio)

   NO IMPLEMENTAR sin plan completo. Feedback S12: no trial-and-error.
   ========================================================================== */

/* ==========================================================================
   Back to top button — redesign
   --------------------------------------------------------------------------
   Parent: 50px circle, black bg, asymmetric padding, oversized.
   Fix: 36px circle, PML coral bg, centered icon, subtle shadow.
   ========================================================================== */

/* ==========================================================================
   Mobile menu fixes — scrollable + Login/Sign Up styling
   ========================================================================== */

/* Make mobile menu scrollable when it exceeds viewport height */
.snap-drawer,
.wpestate-elementor-menu-mobile-container .mobilex-menu {
    max-height: 80vh;
    overflow-y: auto !important;
    -webkit-overflow-scrolling: touch;
}

/* Back-to-top: hidden on desktop, visible on mobile only */
.backtop {
    display: none !important;
}

@media (max-width: 768px) {
    .backtop {
        width: 36px !important;
        height: 36px !important;
        font-size: 14px !important;
        padding: 0 !important;
        display: flex !important;
        align-items: center;
        justify-content: center;
        background-color: var(--pml-coral) !important;
        border-radius: var(--pml-radius-circle) !important;
        bottom: 20px !important;
        right: 16px !important;
        box-shadow: none; /* CT-56 flat */
        opacity: 0.85 !important;
        z-index: 999 !important;
    }

    .backtop:hover {
        opacity: 1 !important;
        background-color: var(--pml-coral-dark) !important;
    }

    .backtop i,
    .backtop::before {
        color: var(--pml-white) !important;
        font-size: 14px;
        line-height: 1;
    }
}

/* ==========================================================================
   Uniform property card image height
   --------------------------------------------------------------------------
   Property cards use background-image which renders at different heights
   depending on the original image aspect ratio. Forces consistent height
   across all cards for visual uniformity.
   ========================================================================== */

.listing-unit-img-wrapper,
.listing-unit-img-wrapper .carousel,
.listing-unit-img-wrapper .carousel-inner,
.listing-unit-img-wrapper .carousel-inner .item,
.listing-unit-img-wrapper .carousel-inner .item a {
    min-height: 280px;
}

.listing-unit-img-wrapper img {
    width: 100%;
    height: 280px;
    object-fit: cover;
}

/* ==========================================================================
   Migrated from Theme Options Custom CSS (was in DB, now version-controlled)
   --------------------------------------------------------------------------
   CSS #0: Sliding Box + Testimonials (pre-existing, author unknown)
   CSS #1: Polylang Language Switcher Dropdown (Chuy, 2026-03-10)

   After migrating, enable `wp_estate_on_child_theme` toggle in Theme Options
   to stop WP Rentals from outputting the duplicate inline CSS.
   Registry: docs/governance/custom-code-registry.md
   ========================================================================== */

/* --- CSS #0 — Sliding Box + Testimonials --- */
.wpestate_sliding_box .sliding-content-wrapper {
    /* S25: was #fdf8f4 (orphan near-off-white). Use off-white token — virtually identical visual, in-palette. */
    background: var(--pml-off-white);
}

.testimonial_type_2 .testimonial-text,
.testimonial-container.testimonial_type_2 {
    background-color: #FFFFFF;
    box-shadow: none;
}

/* --- CSS #1 — Polylang Language Switcher Dropdown --- */

/* Dropdown menu container */
ul.sub-menu:has(.lang-item) {
    background-color: var(--pml-white) !important;
    border: 1px solid var(--pml-light-blue) !important;
    box-shadow: none !important; /* CT-58 flat */
    padding: 4px 0 !important;
}

/* Items de idioma */
.lang-item {
    background-color: var(--pml-white) !important;
}

/* Enlaces dentro del dropdown */
.lang-item a.menu-item-link {
    color: var(--pml-black) !important;
    background-color: var(--pml-white) !important;
    padding: 8px 16px !important;
    display: block !important;
}

/* Hover sobre items */
.lang-item a.menu-item-link:hover {
    background-color: var(--pml-off-white) !important;
    color: var(--pml-coral) !important;
}

/* Ocultar idioma activo del dropdown */
.sub-menu .lang-item.current-lang {
    display: none !important;
}

/* ==========================================================================
   Layout centering fix — Bootstrap .row override
   --------------------------------------------------------------------------
   The site structure uses <main class="content_wrapper row">.
   Parent theme sets .content_wrapper { margin: 0 auto } (style.css:516),
   but Bootstrap loads AFTER the parent theme (bootstrap-css enqueued after
   wprentals-parent-style-css) and overrides with:
     .row { margin-left: -15px; margin-right: -15px }
   Same specificity (0,1,0), later source order wins → content is NOT
   centered, sits flush-left on wide viewports.

   Fix: restore auto margins with higher specificity (0,3,0).
   Does not affect other .row elements (scoped to .main_wrapper).

   Audit reference: S13 investigation — CSS cascade analysis of 46 stylesheets
   ========================================================================== */

/* Centering: let WP Rentals Theme Options "Main Grid Width" control
   the max-width globally. We only force auto margins on the content
   wrapper to fix the Bootstrap .row negative-margin override. */
.main_wrapper .content_wrapper.row {
    margin-left: auto;
    margin-right: auto;
}

/* Single listing pages: constrain the outer container on wide screens.
   Parent theme's .wide class sets width:100%/max-width:100% which removes
   centering. This scoped rule restores it for single property pages only.
   Does NOT affect half-map pages (they use .is_half_map body class). */
.single-estate_property .container.main_wrapper {
    max-width: 1400px;
    margin-left: auto;
    margin-right: auto;
}

/* CI/CD verification — first deploy via GitHub Actions to puertomoreldev (2026-04-09) */

/* ==========================================================================
   CT-16 — Hide parent theme's native headers (so CT-16 custom header wins)
   ==========================================================================
   PROBLEM:
   WP Rentals parent theme emits its own header markup on every page load —
   multiple variants depending on device/page (desktop `.master_header`,
   mobile `.mobile_header`, Snap.js mobile drawer `.mobilewrapper`/`.snap-drawers`).
   Additionally, an Elementor Studio Template (post ID 41777) may render a
   theme-level Elementor header on any page that uses Elementor.

   If we simply added our custom header without hiding the natives, the user
   would see DUPLICATE headers stacked on top of each other.

   ROOT CAUSE (why we don't edit the parent instead):
   Modifying the parent theme would break WP Rentals updates. The parent's
   header PHP is deeply intertwined with booking forms, login modals, menu
   trees, Polylang integration, etc. — hundreds of lines we don't want to
   own. Overriding select pieces via pluggable functions would still leave
   layout/CSS conflicts. The cleanest decoupling is: let the parent render
   its header invisibly (PHP still executes, hooks still fire, no errors),
   then hide it with CSS.

   WHY `!important` and 4 layered properties (display/height/overflow/visibility):
   WP Rentals' own stylesheets use `!important` in places and sometimes
   re-apply `display: block` via JavaScript on scroll/resize. Layering
   `display: none`, `height: 0`, `overflow: hidden`, and `visibility: hidden`
   ensures the native header is invisible even if one of them is overridden
   by a late-loading rule. Defensive belt-and-suspenders by design.

   SCOPE:
   Applies globally — all pages that would otherwise render these classes.
   Our CT-16 custom header is injected via `wp_body_open` hook, which fires
   BEFORE the parent's `get_header()` output, so our header renders first
   in the DOM but both exist. This rule makes the parent one invisible.

   MAINTENANCE:
   If WP Rentals publishes a theme update that renames these classes
   (e.g., `.master_header` → `.wpe-master-header`), this rule goes stale
   and the old-classname native header reappears. Audit after each parent
   theme update by opening any page with DevTools and searching for
   visible header-like elements outside `.pml-header`. */
.master_header,
.mobile_header,
.mobilewrapper,
.mobilewrapper-user,
.snap-drawers {
    display: none !important;
    height: 0 !important;
    overflow: hidden !important;
    visibility: hidden !important;
}

/* Hide ANY Elementor-rendered header/footer template globally.
   WP Rentals ships "Studio Templates" — Elementor templates for header/footer
   that can be published and assigned via Elementor Theme Builder or WP Rentals
   Studio settings. Any such template renders in addition to our CT-16 custom
   header, causing DOUBLE NAVBAR / DOUBLE FOOTER.

   HISTORICAL IDs SEEN (documented for future audits):
     - 41777 — original Studio Template header, Kim set to Draft in S17 (2026-04-13)
     - 41970 — original Studio Template footer, Kim set to Draft in S17
     - 42634 — discovered S19 (2026-04-20) on homepage; origin unknown, possibly
       auto-created when Chuy experimented with Elementor Canvas templates

   STRATEGY (defensive, template-ID-agnostic):
   Instead of enumerating every known template ID (brittle — new IDs can appear),
   we hide ANY element with `data-elementor-type="header"` or
   `data-elementor-type="footer"`. These data attributes are emitted by
   Elementor Pro Theme Builder for ALL header/footer location templates.

   Result: no matter how many Elementor-rendered header/footer templates
   exist or get created, they all stay hidden while our CT-16/CT-17 custom
   ones remain the only visible header/footer.

   `position: absolute` is belt-and-suspenders: if Elementor's own JS
   re-applies `display: block`, `position: absolute` still removes the element
   from normal flow so it doesn't push content around.

   TRADE-OFF:
   If we ever WANT to use Elementor Pro Theme Builder for header/footer
   (alternative to CT-16/17), we'd need to remove this rule. Currently (S19)
   decision is: keep CT-16/17, hide any accidental Elementor templates. */
header[data-elementor-type="header"],
footer[data-elementor-type="footer"],
[data-elementor-type="header"],
[data-elementor-type="footer"],
.elementor-location-header,
.elementor-location-footer,
.elementor-41777,
.elementor-41970,
.elementor-42634 {
    display: none !important;
    position: absolute !important;
}

/* ==========================================================================
   CT-24 — Announcement Banner (above header)
   Renders only when widget area "PML Announcement Banner" has content.
   Kim edits text from wp-admin → Appearance → Widgets.
   ========================================================================== */

.pml-banner {
    position: relative;
    width: 100%;
    background: var(--pml-coral);
    color: #fff;
    font-family: var(--pml-font-accent);
    font-size: 14px;
    font-weight: 500;
    text-align: center;
    padding: 8px 40px;
    z-index: 10001; /* above header */
}

.pml-banner__inner {
    max-width: 1200px;
    margin: 0 auto;
}

.pml-banner__inner p {
    margin: 0;
    line-height: 1.4;
}

.pml-banner__inner a {
    color: #fff;
    text-decoration: underline;
    font-weight: 600;
}

.pml-banner__inner a:hover {
    opacity: 0.85;
}

.pml-banner__close {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: #fff;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    padding: 4px 8px;
    opacity: 0.8;
    transition: opacity 0.2s;
}

.pml-banner__close:hover {
    opacity: 1;
}

/* Hide banner on dashboard pages */
.is_dashboard_page .pml-banner {
    display: none;
}

@media (max-width: 767px) {
    .pml-banner {
        font-size: 12px;
        padding: 6px 32px 6px 12px;
    }

    .pml-banner__close {
        right: 4px;
        font-size: 18px;
    }
}

/* ==========================================================================
   CT-16 — Custom Header: Base styles (desktop >1200px)
   ========================================================================== */

/* S31 — Altura del header en estado FIXED (post-scroll, position:fixed),
   expuesta como variable CSS global para que componentes con sticky
   descendants (CT-37 Rentals search bar, CT-36 Zones, etc.) puedan
   offsetearse sin hardcodear ni desincronizarse cuando cambia la altura
   del header en otro breakpoint. Una sola fuente de verdad: aquí.

   Valores deben coincidir con `.pml-header--fixed { height }` + sus
   media queries más abajo (líneas 859-893, 1681-1683, 1795-1797, 1840-1842).
   Si cambia uno, cambia el otro. */
:root {
    --pml-header-h-fixed: 64px;
}
@media (max-width: 768px) {
    :root {
        --pml-header-h-fixed: 56px;
    }
}
@media (max-width: 375px) {
    :root {
        --pml-header-h-fixed: 48px;
    }
}

.pml-header {
    position: relative;
    top: 0;
    left: 0;
    right: 0;
    z-index: 9999;
    height: 84px;
    padding-top: 10px;
    padding-bottom: 10px;
    background-color: var(--pml-off-white);
    box-shadow: none;
    font-family: var(--pml-font-accent);
}

/* Fixed state: slides down from -100% via CSS transition */
.pml-header--fixed {
    position: fixed;
    /* CT-71 PASO 2 (S51): sticky = BANDA BLANCA full-width (tapa las tarjetas que
       antes se asomaban en los huecos del floating) + la CÁPSULA CORAL flota
       dentro (ver .pml-header--fixed .pml-header__inner abajo). */
    top: 0;
    left: 0;
    right: 0;
    height: 76px;
    padding: 0;
    /* CT-71 (Chuy): banda TRANSPARENTE por defecto (la cápsula flota sobre el
       contenido); solo BLANCA en el buscador (property-list, ver regla :has abajo)
       donde las tarjetas se asomaban en los huecos. pointer-events:none para que
       la banda transparente NO bloquee clicks del contenido de la página. */
    background-color: transparent;
    pointer-events: none;
    box-shadow: none; /* flat system — no shadow */
    border-bottom: none;
    border-radius: 0;
    transform: translateY(-100%);
    will-change: transform;
    transition: transform 550ms cubic-bezier(0.22, 1, 0.36, 1); /* smooth ease-out */
}
/* La cápsula coral = el inner, flotando dentro de la banda blanca con margen */
.pml-header--fixed .pml-header__inner {
    background: var(--pml-coral);
    border-radius: 999px;
    height: 60px;
    max-width: none;
    margin: 8px 16px;
    padding: 0 22px;
    pointer-events: auto; /* la cápsula sí es clickeable (la banda es pointer-events:none) */
}
/* Banda blanca SOLO en el buscador: property-list / advanced-search renderean
   el contenedor .pml-rentals (CT-37). En el resto de páginas la banda queda
   transparente y la cápsula flota sobre el contenido (Chuy). */
body:has(.pml-rentals) .pml-header--fixed {
    background-color: var(--pml-white);
}

/* Visible: slid into view */
.pml-header--visible {
    transform: translateY(0);
}

/* Hidden: slid out of view (scroll-down) */
.pml-header--hidden {
    transform: translateY(-100%);
}

/* CT-71 PASO 2b (S51): se RETIRÓ el override "desktop siempre visible" para que
   el header se oculte-al-bajar / aparezca-al-subir también en desktop (paridad
   Showit). Ahora las clases --visible/--hidden (desde pml-header.js) controlan el
   transform en todos los tamaños. La página /properties-list/ se adapta sola vía
   body.pml-header-hidden → --pml-header-fixed-h:0 (rentals-page.css). */

/* Background color fix (overscroll bounce + consistency) */
html,
body {
    background-color: var(--pml-off-white) !important;
}

/* WCAG SC 2.4.11 — focused elements must not hide behind sticky header */
html {
    scroll-padding-top: 92px;
}

/* Placeholder handles the space — no body padding needed */

/* WordPress admin bar offset — only when header is fixed */
body.admin-bar .pml-header--fixed {
    top: 32px;
}

/* CT-73 (S52) — Admin-bar relative-state gap fix (desktop).
   PROBLEM (logged-in only): a ~32px white gap appears between the admin bar and
   the banner/header. MEASURED via getBoundingClientRect on /login/: banner top =
   64px while the admin bar occupies only 0–32px → 32px empty gap.
   CAUSE: WP core already offsets content with `html { margin-top: 32px }` for the
   fixed admin bar. The WP Rentals PARENT theme ALSO sets `body { margin-top: 32px }`
   (confirmed in the computed cascade — not present in this child), double-counting
   the offset: 32 (html) + 32 (body) = 64.
   FIX: neutralize the parent's redundant body offset so only WP core's html offset
   applies → first element sits flush under the bar. Scoped to WP's own admin-bar
   desktop breakpoint (≥783px); mobile keeps its existing handling (see l.~2252,
   pending its own measured pass). Does NOT touch the fixed-header rule above
   (fixed elements clear the bar via `top`, unaffected by body margin). */
@media screen and (min-width: 783px) {
    body.admin-bar {
        margin-top: 0 !important;
    }
}

/* Admin bar dropdowns must appear above our header */
#wpadminbar {
    z-index: 100000 !important;
}

#wpadminbar .ab-sub-wrapper {
    z-index: 100001 !important;
}


.pml-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    max-width: 1400px;
    margin: 0 auto;
    padding: 0 40px;
    height: 100%;
}

/* --- Zone 1: Logo --- */

.pml-header__logo {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    text-decoration: none;
}

.pml-header__logo img {
    height: 58px;
    width: auto;
    display: block;
    transition: height 200ms ease;
}

/* Smaller logo in sticky header */
.pml-header--fixed .pml-header__logo img {
    height: 42px;
}

/* CT-70: wordmark de texto "Puerto Morelos Life" (sin ícono), igual que el
   navbar de Showit. En Showit el wordmark va OSCURO (no coral) — burgundy
   display (--color-text-dark #2e0a16); el coral es solo para la pill/acentos.
   Reemplaza el PNG en el header. */
.pml-header__logo-text {
    font-family: Georgia, 'Times New Roman', Times, serif; /* CT-71: wordmark serif como Showit */
    font-weight: 500;
    font-size: 26px;
    line-height: 1;
    letter-spacing: 0;
    color: var(--color-text-dark);
    white-space: nowrap;
    transition: font-size 200ms ease, color 200ms ease;
}

.pml-header--fixed .pml-header__logo-text {
    font-size: 21px;
}

/* CT-75b (S52): Chuy pidió el wordmark COMPLETO también en móvil (antes ≤600px se
   abreviaba a "PML"). Se muestra "Puerto Morelos Life" en todo ancho y se reduce el
   tamaño en móvil para que quepa junto a la hamburguesa + el pill compacto. */
.pml-header__logo-text--short {
    display: none; /* ya no se usa el abreviado; --full se queda visible siempre */
}

@media (max-width: 768px) {
    .pml-header__logo-text {
        font-size: 17px;
    }
    .pml-header--fixed .pml-header__logo-text {
        font-size: 15px;
    }
}

@media (max-width: 375px) {
    .pml-header__logo-text {
        font-size: 14px;
    }
    .pml-header--fixed .pml-header__logo-text {
        font-size: 13px;
    }
}

/* ==========================================================================
   CT-71 (S51) — Navbar match Showit · PASO 1: top state colapsado
   Hamburguesa coral (círculo) a la IZQUIERDA en todos los tamaños + nav
   horizontal oculto + login/user/lang fuera de la barra (van al menú) + pill
   "Search Rentals" clara. El sticky = cápsula coral (PASO 2) y el menú overlay
   coral (PASO 3) son pasos aparte.
   ========================================================================== */

.pml-header__hamburger {
    display: flex !important;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 4px;
    width: 44px;
    height: 44px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: var(--pml-coral);
    cursor: pointer;
    flex-shrink: 0;
}

.pml-header__hamburger-line {
    display: block;
    width: 24px;          /* CT-71 fix: la línea central = la más LARGA (match Showit) */
    height: 2.5px;        /* un poco más gruesa */
    border-radius: 3px;   /* puntas redondeadas */
    background-color: var(--pml-white);
    transition: transform 0.3s ease, opacity 0.3s ease;
}
/* Las externas más cortas → solo la central larga */
.pml-header__hamburger-line:nth-child(1),
.pml-header__hamburger-line:nth-child(3) {
    width: 16px;
}

.pml-header__hamburger[aria-expanded="true"] .pml-header__hamburger-line:nth-child(1) {
    transform: rotate(45deg) translate(4px, 4px);
}
.pml-header__hamburger[aria-expanded="true"] .pml-header__hamburger-line:nth-child(2) {
    opacity: 0;
}
.pml-header__hamburger[aria-expanded="true"] .pml-header__hamburger-line:nth-child(3) {
    transform: rotate(-45deg) translate(4px, -4px);
}

/* Ocultar nav horizontal + lang de la barra (el nav va al menú expandible).
   El Login / User SÍ se quedan en la barra (Chuy: el botón de login va en el
   navbar, igual que el que pondrá en Showit). */
.pml-header__nav,
.pml-header__lang {
    display: none !important;
}

/* Layout: [hamburguesa][wordmark] izquierda, pill a la derecha */
.pml-header__inner {
    justify-content: flex-start;
    gap: 16px;
}
.pml-header__actions {
    margin-left: auto;
}

/* Pill "Search Rentals" CLARA (top state): fondo blanco + texto oscuro + dot lavanda */
.pml-header__search-pill {
    background: var(--pml-white);
    color: var(--color-text-dark);
    border: 1px solid var(--pml-border); /* definición sobre el header cream */
    display: inline-flex !important; /* visible también en móvil (override del display:none) */
}
/* Hover: NO usar off-white (= fondo del header → se desvanecía). Acento coral. */
.pml-header__search-pill:hover {
    background: var(--pml-white);
    border-color: var(--pml-coral);
    color: var(--pml-coral);
}

/* ── CT-71 PASO 2: contenido en BLANCO sobre la cápsula coral (estado sticky) ── */
.pml-header--fixed .pml-header__inner {
    padding: 0 22px;
}
.pml-header--fixed .pml-header__hamburger {
    background: transparent;
}
.pml-header--fixed .pml-header__logo-text {
    color: var(--pml-white);
}
.pml-header--fixed .pml-header__search-pill,
.pml-header--fixed .pml-header__search-pill:hover {
    background: transparent;
    border-color: transparent;
    color: var(--pml-white);
}
.pml-header--fixed .pml-header__login {
    border-color: rgba(255, 255, 255, 0.6);
    color: var(--pml-white);
}
.pml-header--fixed .pml-header__login:hover {
    border-color: var(--pml-white);
    color: var(--pml-white);
}

/* --- Zone 2: Nav center --- */

.pml-header__nav {
    flex: 1;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    min-width: 0;
}

.pml-nav-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    gap: 32px;
}

.pml-nav-list li {
    margin: 0;
    padding: 0;
}

.pml-nav-list li a {
    color: var(--color-text-default); /* CT-58: Showit nav — black */
    text-decoration: none;
    font-family: var(--font-system); /* CT-58: Showit nav — Times serif */
    font-size: 16px;
    font-weight: 400;
    padding: 8px 0;
    position: relative;
    transition: color 0.2s ease;
    white-space: nowrap;
}

.pml-nav-list li a:hover,
.pml-nav-list li.current-menu-item > a,
.pml-nav-list li.current_page_item > a {
    color: var(--pml-coral);
}

/* Polylang language items in nav — transparent background */
.pml-nav-list .pll-parent-menu-item,
.pml-nav-list .lang-item,
.pml-nav-list .lang-item a {
    background: transparent !important;
}

/* Active page underline */
.pml-nav-list li.current-menu-item > a::after,
.pml-nav-list li.current_page_item > a::after {
    content: '';
    position: absolute;
    bottom: -2px;
    left: 0;
    right: 0;
    height: 2px;
    background-color: var(--pml-coral);
    border-radius: 1px;
}

/* "More" dropdown button — hidden on desktop */
.pml-header__more-btn {
    display: none;
    align-items: center;
    gap: 4px;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--pml-text);
    font-size: 15px;
    font-weight: 500;
    padding: 8px 0;
    white-space: nowrap;
}

.pml-header__more-btn:hover {
    color: var(--pml-coral);
}

.pml-header__caret {
    /* S25: was 10px (drift, below typography-system minimum 11px). Use overline token. */
    font-size: var(--pml-fs-overline);
}

/* "More" dropdown panel */
.pml-header__more-dropdown {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    background: var(--pml-glass-strong);
    backdrop-filter: var(--pml-blur-standard);
    -webkit-backdrop-filter: var(--pml-blur-standard);
    border: 1px solid var(--pml-glass-edge);
    border-radius: var(--pml-radius-lg);
    box-shadow: none; /* CT-58 flat */
    padding: 6px 0;
    min-width: 180px;
    z-index: 100;
    list-style: none;
    margin: 0;
    font-family: var(--pml-font-accent);
}

.pml-header__more-dropdown[hidden] {
    display: none;
}

.pml-header__more-dropdown li {
    margin: 0;
    padding: 0;
}

.pml-header__more-dropdown li a {
    display: block;
    padding: 10px 20px;
    color: var(--pml-text);
    text-decoration: none;
    font-size: 14px;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.pml-header__more-dropdown li a:hover {
    background-color: var(--pml-off-white);
    color: var(--pml-coral);
}

/* --- Zone 3: Actions --- */

.pml-header__actions {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 16px;
}

/* Language switcher */
.pml-header__lang {
    position: relative;
}

.pml-lang__trigger {
    display: flex;
    align-items: center;
    gap: 4px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 8px;
    color: var(--pml-text);
    font-size: 14px;
    font-weight: 500;
}

.pml-lang__trigger:hover {
    color: var(--pml-coral);
}

.pml-lang__globe {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

.pml-lang__dropdown {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    background: var(--pml-glass-strong);
    backdrop-filter: var(--pml-blur-standard);
    -webkit-backdrop-filter: var(--pml-blur-standard);
    border: 1px solid var(--pml-glass-edge);
    border-radius: var(--pml-radius-lg);
    box-shadow: none; /* CT-58 flat */
    padding: 6px 0;
    min-width: 140px;
    display: none;
    list-style: none;
    margin: 0;
    z-index: 101;
    font-family: var(--pml-font-accent);
}

.pml-lang__dropdown--open {
    display: block;
}

/* ── Shared dropdown animation + caret indicator ── */

/* Bubble-in keyframes */
@keyframes pml-bubble-in {
    0% {
        opacity: 0;
        transform: scale(0.95) translateY(-4px);
    }
    100% {
        opacity: 1;
        transform: scale(1) translateY(0);
    }
}

/* Transition for scroll-fade + animation base */
.pml-lang__dropdown,
.pml-user-dropdown,
.pml-header__more-dropdown {
    transition: opacity 200ms ease;
    transform-origin: top right;
}

/* Bubble-in on open */
.pml-lang__dropdown--open,
.pml-user-dropdown:not([hidden]),
.pml-header__more-dropdown:not([hidden]) {
    animation: pml-bubble-in 300ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Caret arrow — pure CSS triangle (no background fill = no diamond) */
.pml-lang__dropdown::before,
.pml-user-dropdown::before,
.pml-header__more-dropdown::before {
    content: '';
    position: absolute;
    top: -6px;
    right: 18px;
    width: 12px;
    height: 12px;
    background: inherit;
    border-top: 1px solid rgba(0, 0, 0, 0.06);
    border-left: 1px solid rgba(0, 0, 0, 0.06);
    border-bottom: none;
    border-right: none;
    transform: rotate(45deg);
    z-index: 1;
    border-radius: 2px 0 0 0;
}

/* User dropdown caret — aligned to avatar area */
.pml-user-dropdown::before {
    right: 24px;
}

.pml-lang__dropdown li,
.pml-lang__dropdown .lang-item {
    margin: 0;
    padding: 0;
    background: transparent !important;
}

.pml-lang__dropdown li a,
.pml-lang__dropdown .lang-item a,
.pml-lang__dropdown .lang-item a.menu-item-link {
    display: block;
    padding: 10px 18px !important;
    color: var(--pml-text) !important;
    background: transparent !important;
    text-decoration: none;
    font-family: var(--pml-font-accent);
    font-size: 14px;
    font-weight: 400;
    letter-spacing: 0.3px;
    border-radius: var(--pml-radius);
    transition: background 0.2s ease, color 0.2s ease;
}

.pml-lang__dropdown li a:hover,
.pml-lang__dropdown .lang-item a:hover,
.pml-lang__dropdown .lang-item a.menu-item-link:hover {
    background: rgba(245, 240, 236, 0.6) !important;
    color: var(--pml-coral) !important;
}

/* Login — CT-71: botón outline en la barra (junto a "Search Rentals").
   Top state = borde + texto oscuros, fondo transparente (no compite con la pill
   clara). El sticky lo invierte a blanco en el PASO 2. */
.pml-header__login {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    color: var(--color-text-dark);
    border: 1px solid var(--pml-border);
    text-decoration: none;
    font-size: 14px;
    font-weight: 600;
    padding: 8px 18px;
    border-radius: var(--pml-radius-pill);
    transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
}

.pml-header__login:hover {
    border-color: var(--color-text-dark);
    background: transparent;
    color: var(--color-text-dark);
}

.pml-header__login-icon {
    display: none;
}

/* CT-58 — Showit "Search Rentals" coral pill + lavender dot (entry to the search engine) */
.pml-header__search-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: var(--pml-coral);
    color: var(--pml-white);
    font-family: var(--font-ui);
    font-size: 14px;
    font-weight: 600;
    padding: 9px 20px;
    border-radius: var(--pml-radius-pill);
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.2s ease;
}

.pml-header__search-pill:hover {
    background: var(--color-coral-dark);
    color: var(--pml-white);
}

.pml-header__search-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--color-bg-lavender); /* Showit lavender dot */
    flex-shrink: 0;
}

@media (max-width: 768px) {
    /* On mobile the hamburger + slide-in menu handle navigation */
    .pml-header__search-pill { display: none; }
}


/* --- User dropdown (logged-in) --- */

.pml-header__user-wrap {
    position: relative;
}

.pml-header__user {
    display: flex;
    align-items: center;
    gap: 8px;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--pml-text);
    font-size: 14px;
    font-weight: 500;
    padding: 6px 10px;
    /* S25: 24px is intentional — soft-pill on a ~36px-tall trigger.
       --pml-radius-pill (9999px) would change visual appearance with
       different heights. Single use case, kept inline. */
    border-radius: 24px;
    transition: background-color 0.2s ease;
}

.pml-header__user:hover {
    background-color: var(--pml-off-white);
}

.pml-header__avatar {
    width: 32px;
    height: 32px;
    border-radius: var(--pml-radius-circle);
    flex-shrink: 0;
}

.pml-header__user-caret {
    transition: transform 0.2s ease;
    flex-shrink: 0;
}

.pml-header__user[aria-expanded="true"] .pml-header__user-caret {
    transform: rotate(180deg);
}

.pml-user-dropdown {
    position: absolute;
    top: calc(100% + 12px);
    right: 0;
    width: 280px;
    background: var(--pml-glass-strong);
    backdrop-filter: var(--pml-blur-standard);
    -webkit-backdrop-filter: var(--pml-blur-standard);
    border: 1px solid var(--pml-glass-edge);
    border-radius: var(--pml-radius-xl);
    box-shadow: none; /* CT-58 flat */
    padding: 8px 0;
    z-index: 200;
    font-family: var(--pml-font-accent);
}

.pml-user-dropdown[hidden] {
    display: none;
}

.pml-user-dropdown__header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 16px 12px;
}

.pml-user-dropdown__avatar {
    width: 48px;
    height: 48px;
    border-radius: var(--pml-radius-circle);
    flex-shrink: 0;
}

.pml-user-dropdown__name {
    font-weight: 600;
    font-size: 15px;
    color: var(--pml-text);
}

.pml-user-dropdown__email {
    font-size: 13px;
    color: var(--pml-text-secondary);
    margin-top: 2px;
    word-break: break-all;
}

.pml-user-dropdown__divider {
    height: 1px;
    background: var(--pml-border);
    margin: 4px 0;
}

.pml-user-dropdown__nav a,
.pml-user-dropdown__logout {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
    color: var(--pml-text);
    text-decoration: none;
    font-size: 14px;
    font-weight: 500;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.pml-user-dropdown__nav a:hover,
.pml-user-dropdown__logout:hover {
    background-color: rgba(245, 240, 236, 0.6);
    color: var(--pml-coral);
}

.pml-user-dropdown__nav a svg,
.pml-user-dropdown__logout svg {
    flex-shrink: 0;
    color: var(--pml-text-tertiary);
}

.pml-user-dropdown__nav a:hover svg,
.pml-user-dropdown__logout:hover svg {
    color: var(--pml-coral);
}

.pml-user-dropdown__badge {
    background: var(--pml-coral);
    color: var(--pml-white);
    font-size: 11px;
    font-weight: 700;
    padding: 2px 7px;
    border-radius: var(--pml-radius-md);
    margin-left: auto;
}

.pml-user-dropdown__logout {
    color: var(--pml-text-tertiary);
}

/* Mobile menu — logged-in user section */
.pml-mobile-menu__user-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-top: 16px;
}

.pml-mobile-menu__avatar-lg {
    width: 40px;
    height: 40px;
    border-radius: var(--pml-radius-circle);
    flex-shrink: 0;
}

.pml-mobile-menu__user-name {
    font-weight: 600;
    font-size: 15px;
    color: var(--pml-text);
}

.pml-mobile-menu__user-email {
    font-size: 13px;
    color: var(--pml-text-secondary);
    margin-top: 2px;
}

.pml-mobile-menu__user-links {
    margin-top: 16px;
}

.pml-mobile-menu__user-links a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 0;
    color: var(--pml-text);
    text-decoration: none;
    font-size: 15px;
    font-weight: 500;
    border-bottom: 1px solid var(--pml-border);
}

.pml-mobile-menu__user-links a:last-child {
    border-bottom: none;
}

.pml-mobile-menu__user-links a:hover {
    color: var(--pml-coral);
}

.pml-mobile-menu__logout {
    color: var(--pml-text-tertiary) !important;
}

/* WP Rentals login/register modal fix — our header (z-index 9999)
   must hide behind the modal overlay and content.
   Two selectors for redundancy:
   1. body.modal-open = Bootstrap adds this to <body> on ANY modal (CSS-only, no JS needed)
   2. .pml-header--modal-open = our JS class via shown.bs.modal event (backup) */
body.modal-open .pml-header,
.pml-header.pml-header--modal-open {
    z-index: 1 !important;
}

body.modal-open .pml-mobile-menu__overlay,
body.modal-open .pml-mobile-menu__panel {
    z-index: 1 !important;
}

/* ==========================================================================
   CT-20 REMOVED (2026-04-20, S19)
   ==========================================================================
   Originally CT-20 was ~340 lines of CSS styling the login/signup/forgot
   password modal with glassmorphism, Jost typography, coral buttons, and
   responsive mobile layout.

   Why removed:
   1. Pure cosmetic styling — NOT a WCAG/SEO/functional fix. Violates ADR-0005
      "child theme as last resort": styling should live in Theme Options,
      Elementor, or parent theme — not in child theme.
   2. Caused repeated regressions 2026-04-19/20: generic Bootstrap selectors
      leaked to booking modals (misdiagnosed as KIM-08 root cause), then
      scope fix exposed conflicts with parent theme's `position: absolute`
      image wrapper (register/forgot forms overlapping image), then every
      iteration introduced a new breakage.
   3. The modal still works without CT-20 — it just looks like default
      WP Rentals styling (simple, functional). If PML brand styling on login
      is desired in future, best path is Elementor Pro Popup Builder (clean
      UI to style, no CSS cascade conflicts) OR Theme Options → Design →
      Custom CSS (single source Kim can see and edit).

   What WAS kept from this section:
   - Modal backdrop defensive rules (see below) — generic, prevents parent
     theme's rogue backdrop appearing on pages without a visible modal.
     These are bug-fixes for the parent theme, not styling.
   - CT-24 banner hide on modal-open (later in file) — also generic.
   - CT-25 modal positioning fix (later in file) — fixes parent theme bug.

   Git history: full CT-20 code preserved in commits prior to removal. */

/* Modal backdrop defensive rules — parent theme sometimes injects
   `.modal-backdrop` on pages without a visible modal (properties-list,
   advanced-search) creating a grey overlay that blocks all interaction.
   Fix: hide backdrop by default, re-enable only when `.modal.in` / `.modal.show`
   exists as sibling. This is a parent-theme bug fix, NOT CT-20 styling. */
.modal-backdrop {
    display: none !important;
}

.modal.in ~ .modal-backdrop,
.modal.show ~ .modal-backdrop {
    display: block !important;
    opacity: 0.4;
}

/* Hide announcement banner (CT-24) when ANY modal is open.
   Why: the banner is position: fixed with z-index: 10001, which is higher than
   Bootstrap modal z-index (1050). Without this rule, the banner renders OVER
   the top of the modal, cutting off modal titles and headers.
   Alternative considered: lower banner z-index below modal (1050). Rejected
   because banner would then render below the site header (z-index 9999) too,
   and be invisible while scrolling. Hiding on modal-open is the cleanest UX
   — banner is a non-essential announcement, safe to hide briefly.
   Bootstrap adds `.modal-open` class to <body> automatically when any modal
   is displayed. Reported by Chuy post CT-25 deploy 2026-04-20. */
body.modal-open .pml-banner {
    display: none !important;
}

/* ==========================================================================
   CT-25 — Fix Bootstrap modal positioning (KIM-08)
   ==========================================================================
   PROBLEM (user-visible symptom):
   Modales de "Custom Price", "Reserve a period" (booking), login modal, y
   otros modales del sitio salen desplazados ~428px a la derecha (o en otros
   casos al lado izquierdo) del centro y se cortan fuera del viewport.
   Reportado por Kim en junta 2026-04-13.

   ROOT CAUSE:
   WP Rentals v3.16.2 parent theme (`wprentals/style.css`) usa una técnica
   pre-flexbox de centrado que combina DOS declaraciones:
       .modal-dialog { left: 50%; margin-left: -235px; }     (genérico 470px)
       #loginmodal .modal-dialog { margin-left: -375px; }    (login 750px)
       (y probablemente variantes similares para otros modal IDs específicos)
   La lógica: `left: 50%` empuja al centro y `margin-left: -half-width`
   compensa con menos-mitad-del-ancho para centrar el dialog.

   EL BUG (dos bugs coexistentes):
   (a) Para `.modal-dialog` genérico: Bootstrap 3 `@media (min-width: 768px)`
       sobrescribe `margin: 30px auto` que pisa `margin-left: -235px`
       reseteándolo a `auto`. Queda solo `left: 50%` sin compensación,
       empujando el dialog a la mitad derecha del viewport.
   (b) Para `#loginmodal .modal-dialog` (y otros IDs específicos): Bootstrap
       `@media` NO puede sobrescribir porque el selector del parent tiene
       mayor especificidad (ID > clase). El `margin-left: -375px` persiste,
       empujando el dialog a la izquierda.
   En ambos casos el centrado se rompe — por caminos opuestos pero con el
   mismo root cause (intención de centrado pre-flexbox rota por interacción
   con Bootstrap).

   Bug pre-existente del parent theme, NO introducido por el child theme
   (confirmado 2026-04-20 con scan de cascada CSS vía `document.styleSheets`
   enumeration: el child theme no tiene ninguna regla afectando `.modal-dialog`
   fuera del scope CT-20 del login modal).

   WHY THIS APPROACH (vs alternativas):
   1. Theme Options NO expone setting para esto — es CSS hardcoded del parent.
   2. Elementor NO controla modales del dashboard de WP Rentals.
   3. WP core NO aplica (Bootstrap 3 + WP Rentals manejan modales custom).
   4. Opción descartada: setear `transform: translateX(-50%)` — funcionaría
      pero podría conflictar con animación `.modal.fade/.modal.in` de Bootstrap
      que ya usa `transform: translate(0, -25%)` / `translate(0, 0)`.
   5. Opción elegida: forzar `left: auto` + `margin-left: auto` + `margin-right: auto`
      en TODOS los modales. Esto neutraliza ambos bugs del parent (el `left: 50%`
      Y el `margin-left: -X`) y deja que el default de Bootstrap (`margin: 30px auto`
      vía @media) haga el centrado correcto. Simple, sin efectos colaterales,
      cero conflicto con animación Bootstrap.

   SCOPE: Afecta a TODOS los modales del sitio (login, signup, booking,
   custom price, reserve period, etc.). El login modal sigue funcionando
   porque CT-20 (scopeado con :has()) aplica glassmorphism SOBRE este centrado,
   y el `max-width: 860px` de CT-20 no conflicta con auto-centering.

   Mobile override: el block mobile de CT-20 (`@media max-width: 768px`)
   tiene `.modal:has(...) .modal-dialog { margin: 0 !important; width: 100% }`
   con especificidad (0,0,3,0) !important que gana sobre CT-25's (0,0,2,0)
   !important — por eso en mobile el login modal sigue full-screen como se
   diseñó originalmente.

   VERIFICATION: Si WP Rentals actualiza a una versión que arregla este bug
   (retirando `.modal-dialog { left: 50% }` y los `margin-left: -X` de su
   stylesheet), esta regla se vuelve redundante pero no dañina — se puede
   retirar en ese momento. Checar en cada update del parent theme buscando
   los selectores en wprentals/style.css. */
.modal .modal-dialog {
    left: auto !important;
    margin-left: auto !important;
    margin-right: auto !important;
}

/* S31 Bug #4 v2 — Modal de login fullscreen en mobile.
   Reportes Chuy: "en celular parte del modal sale bajo la pantalla" → fix v1.
   Después: "es tan pequeño que no se puede usar, debe adaptarse al alto y
   ancho de la pantalla del celular" → fix v2 (este).

   Causa: el Bootstrap 3 modal del parent tiene styles `.modal-dialog
   { width: 600px }` y `#loginmodal .modal-dialog { width: 750px }` con
   inline `style="height:620px"`. En mobile el width: 750px excede el
   viewport, pero adicionalmente los media queries del parent reducen
   el width a algo pequeño (descubrimos que el v1 con max-width:95vw
   no era suficiente porque la regla width específica del parent ganaba).

   Solución v2: override TOTAL en mobile. Modal ocupa 100% del viewport
   (100vw × 100dvh), sin margin, content full-height con scroll interno.
   Los selectores son maximum specificity con !important para vencer
   todos los overrides del parent y las media queries de Bootstrap. */
@media (max-width: 768px) {
    body .modal#loginmodal,
    body.modal-open .modal#loginmodal {
        padding: 0 !important;
    }
    body .modal#loginmodal .modal-dialog,
    body.modal-open .modal#loginmodal .modal-dialog {
        width: 100% !important;
        max-width: 100% !important;
        min-width: 0 !important;
        height: 100dvh !important;
        max-height: 100dvh !important;
        min-height: 100dvh !important;
        margin: 0 !important;
        padding: 0 !important;
        left: 0 !important;
        right: 0 !important;
        top: 0 !important;
        transform: none !important;
        display: flex !important;
        flex-direction: column !important;
    }
    body .modal#loginmodal .modal-content {
        width: 100% !important;
        max-width: 100% !important;
        height: 100dvh !important;
        min-height: 100dvh !important;
        max-height: 100dvh !important;
        margin: 0 !important;
        border-radius: 0 !important;
        border: none !important;
        overflow-y: auto !important;
        -webkit-overflow-scrolling: touch !important;
        flex: 1 1 auto;
        display: block;
    }
    /* Reset todo lo que pueda heredar height del parent inline styles */
    body .modal#loginmodal .modal-content > *,
    body .modal#loginmodal #loginmodal_top_part,
    body .modal#loginmodal #ajax_login_div,
    body .modal#loginmodal #ajax_register_div,
    body .modal#loginmodal #lostpasswordform_wrapper {
        height: auto !important;
        max-height: none !important;
        min-height: 0 !important;
        width: auto !important;
        max-width: 100% !important;
    }
    /* Padding interno para que el contenido no toque los bordes */
    body .modal#loginmodal .modal-body,
    body .modal#loginmodal #login-content,
    body .modal#loginmodal #register-content {
        padding: 16px !important;
    }
}

/* ==========================================================================
   CT-27 — Hide duplicate YouTube iframe on single property pages
   ==========================================================================
   PROBLEM (user-visible symptom):
   When a listing has BOTH a YouTube video AND photo gallery, the single
   property page renders the video iframe TWICE:
     1. Standalone in a `.panel-wrapper.imagebody_wrapper` (video only, no images)
     2. Inside the gallery `.panel-wrapper.imagebody_wrapper` (images + video appended)
   Both iframes carry `id="player_2"` (invalid HTML — IDs must be unique) and
   the same YouTube URL. Reported by Chuy 2026-04-20 on new listing "Casa de Chuy".

   ROOT CAUSE:
   Parent theme WP Rentals v3.16.2 template
   `templates/property_page_templates/property_page_templates_section/masonary_gallery_property_page.php`
   (or similar variant) has two code paths emitting the video block:
     - Top-of-page standalone video panel
     - Bottom of images gallery panel appending video
   Both paths run when video + images are both present, producing the duplicate.
   Pre-existing parent theme bug, not caused by child theme (confirmed: child
   theme has no video-related CSS or template override for this section).

   WHY CSS vs TEMPLATE OVERRIDE:
   We already have a child theme template override for this area (CT-2,
   `masonary_gallery_property_page.php` full-width fallback for <4 photos).
   Adding more template logic would couple the override to upstream changes —
   higher maintenance burden. A surgical CSS rule that hides the redundant
   wrapper is lower-risk and self-documenting.

   SELECTOR LOGIC:
   `.imagebody_wrapper:has(~ .imagebody_wrapper .imagebody_new)` matches an
   `.imagebody_wrapper` that has a following-sibling `.imagebody_wrapper`
   containing `.imagebody_new` (images). That identifies the FIRST (video-only)
   wrapper when a SECOND wrapper with images also exists. We hide that first
   one — leaving only the gallery-with-video version visible.

   EDGE CASES HANDLED:
   - Video only, no images: no following sibling match → not hidden, video shows
   - Images only, no video: first wrapper has imagebody_new, no second wrapper → not hidden
   - Both present: first wrapper (video-only) hidden, second wrapper (gallery+video) shown
   - No video, no images: no wrappers → nothing to hide

   BROWSER SUPPORT:
   `:has()` requires Chrome 105+, Safari 15.4+, Firefox 121+ (mid-2023+).
   Same support level already assumed by CT-20 / CT-25. Graceful degradation:
   in unsupported browsers, users see duplicate video — not ideal but functional.

   VERIFICATION AFTER PARENT THEME UPDATES:
   If WP Rentals publishes a version that fixes the duplicate rendering, this
   rule becomes redundant (no duplicates to hide) but harmless. Audit by
   opening a listing with both video and gallery and checking DOM — if only
   one iframe present, CT-27 can be removed. */
.single-estate_property .imagebody_wrapper:has(~ .imagebody_wrapper .imagebody_new) {
    display: none !important;
}

/* Submit Property CTA */
.pml-header__submit {
    display: inline-flex;
    align-items: center;
    padding: 10px 20px;
    background-color: var(--pml-coral);
    color: var(--pml-white) !important;
    text-decoration: none;
    font-size: 14px;
    font-weight: 600;
    border-radius: var(--pml-radius-sm);
    transition: background-color 0.2s ease;
    white-space: nowrap;
}

.pml-header__submit:hover {
    background-color: var(--pml-coral-dark);
    color: var(--pml-white) !important;
}

.pml-header__submit-short {
    display: none;
}

/* Hamburger — hidden on desktop */
.pml-header__hamburger {
    display: none;
}

/* ==========================================================================
   CT-16 — Tablet breakpoint (769px – 1200px)
   ========================================================================== */

@media (max-width: 1200px) {
    html {
        scroll-padding-top: 72px;
    }

    .pml-header {
        height: 64px;
    }


    .pml-header__logo img {
        height: 44px;
    }

    .pml-header__logo-text {
        font-size: 19px;
    }

    .pml-nav-list {
        gap: 20px;
    }

    /* Hide nav items beyond 3rd — JS clones them into "More" dropdown */
    .pml-nav-list li:nth-child(n+4) {
        display: none;
    }

    /* Show "More" button */
    .pml-header__more-btn {
        display: flex;
    }

    /* Switch login to icon, hide username + caret on tablet */
    .pml-header__login-text,
    .pml-header__username,
    .pml-header__user-caret {
        display: none;
    }

    .pml-header__login-icon {
        display: flex;
        align-items: center;
    }

    .pml-header__login {
        padding: 8px;
    }

    /* Shorter CTA text */
    .pml-header__submit-text {
        display: none;
    }

    .pml-header__submit-short {
        display: inline;
    }

    .pml-header__submit {
        padding: 8px 16px;
    }

    /* Show hamburger */
    .pml-header__hamburger {
        display: flex;
        flex-direction: column;
        justify-content: center;
        gap: 5px;
        background: none;
        border: none;
        cursor: pointer;
        padding: 8px;
        width: 40px;
        height: 40px;
    }

    .pml-header__hamburger-line {
        display: block;
        width: 22px;
        height: 2px;
        background-color: var(--pml-text);
        border-radius: 1px;
        transition: transform 0.3s ease, opacity 0.3s ease;
    }

    /* Hamburger X animation when open */
    .pml-header__hamburger[aria-expanded="true"] .pml-header__hamburger-line:nth-child(1) {
        transform: rotate(45deg) translate(5px, 5px);
    }

    .pml-header__hamburger[aria-expanded="true"] .pml-header__hamburger-line:nth-child(2) {
        opacity: 0;
    }

    .pml-header__hamburger[aria-expanded="true"] .pml-header__hamburger-line:nth-child(3) {
        transform: rotate(-45deg) translate(5px, -5px);
    }
}

/* ==========================================================================
   CT-16 — Mobile breakpoint (<768px)
   ========================================================================== */

/* WordPress admin bar is 46px on mobile (<783px) instead of 32px */
@media (max-width: 782px) {
    /* CT-73 (S52): el header RELATIVO ya NO se offsetea aquí. Medido en móvil
       logueado (vw 403): html{margin-top:46px} (WP reserva el top para la barra)
       y body margin-top = 0 (en móvil el parent NO mete el margin redundante que
       sí mete en desktop). Con eso el header en flujo cae flush bajo la barra; el
       viejo `top:46px` sobre el relativo doble-contaba → 46px de gap (header medido
       en top:91 ≈ 46+46). Se retira. El header FIXED sí conserva su top:46px: es
       position:fixed y el html margin no lo mueve, así que debe librar la barra. */
    body.admin-bar .pml-header--fixed {
        top: 46px;
    }
}

@media (max-width: 768px) {
    html {
        scroll-padding-top: 64px;
    }

    .pml-header {
        height: 56px;
        padding-top: 0; /* reset desktop padding */
    }

    .pml-header--fixed {
        height: 56px; /* same as static on mobile */
    }

    .pml-header__logo img {
        height: 40px;
    }

    /* Fixed logo same size as static on mobile */
    .pml-header--fixed .pml-header__logo img {
        height: 40px;
    }

    .pml-header__inner {
        padding: 0 16px;
    }

    /* Hide desktop/tablet nav entirely */
    .pml-header__nav {
        display: none;
    }

    /* Hide login/user and submit — they go in hamburger menu */
    .pml-header__login,
    .pml-header__user-wrap,
    .pml-header__submit {
        display: none;
    }

    /* Language: show only globe icon, no text */
    .pml-lang__current {
        display: none;
    }

}

/* ==========================================================================
   CT-16 — Small mobile breakpoint (<375px)
   ========================================================================== */

@media (max-width: 375px) {
    .pml-header {
        height: 48px;
    }

    .pml-header--fixed {
        height: 48px;
    }

    .pml-header__logo img {
        height: 36px;
    }

    .pml-header--fixed .pml-header__logo img {
        height: 36px;
    }

    .pml-header__inner {
        padding: 0 12px;
    }
}

/* ==========================================================================
   CT-16 — Mobile slide-in menu
   ========================================================================== */

.pml-mobile-menu__overlay {
    position: fixed;
    inset: 0;
    /* CT-71 (S51, Chuy): backdrop BLANCO sólido (antes rgba negro semi-transp).
       Con el modal coral inset, el fondo transparente dejaba ver las tarjetas de
       property-list por detrás — se veía feo. Blanco = limpio en todas las páginas. */
    background: var(--pml-white);
    z-index: 10000;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0.3s ease;
}

.pml-mobile-menu--open .pml-mobile-menu__overlay {
    opacity: 1;
    visibility: visible;
}

.pml-mobile-menu__panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 85vw;
    max-width: 360px;
    background: var(--pml-white);
    font-family: var(--pml-font-accent);
    z-index: 10001;
    transform: translateX(100%);
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 24px;
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.pml-mobile-menu--open .pml-mobile-menu__panel {
    transform: translateX(0);
}

.pml-mobile-menu__close {
    position: absolute;
    top: 16px;
    right: 16px;
    background: none;
    border: none;
    font-size: 28px;
    color: var(--pml-text);
    cursor: pointer;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

.pml-mobile-menu__close:hover {
    color: var(--pml-coral);
}

/* Auth section */
.pml-mobile-menu__auth {
    padding-top: 24px;
}

.pml-mobile-menu__login-btn {
    display: block;
    text-align: center;
    padding: 12px 24px;
    background: var(--pml-coral);
    color: var(--pml-white);
    border: none;
    border-radius: var(--pml-radius-lg);
    text-decoration: none;
    font-weight: 600;
    font-size: 15px;
    transition: background 0.2s ease;
}

.pml-mobile-menu__login-btn:hover {
    /* S25: formalized as --pml-action-hover token */
    background: var(--pml-action-hover);
}

/* Mobile nav list */
.pml-mobile-nav-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.pml-mobile-nav-list li {
    margin: 0;
    padding: 0;
}

.pml-mobile-nav-list li a {
    display: block;
    padding: 14px 0;
    color: var(--pml-text);
    text-decoration: none;
    font-size: 16px;
    font-weight: 500;
}

.pml-mobile-nav-list li a:hover,
.pml-mobile-nav-list li.current-menu-item > a {
    color: var(--pml-coral);
}

/* Submit CTA in mobile menu */
.pml-mobile-menu__submit {
    display: block;
    text-align: center;
    padding: 14px 24px;
    background-color: var(--pml-coral);
    color: var(--pml-white) !important;
    text-decoration: none;
    font-weight: 600;
    font-size: 15px;
    border-radius: var(--pml-radius-lg);
    transition: background-color 0.2s ease;
}

.pml-mobile-menu__submit:hover {
    background-color: var(--pml-coral-dark);
}

/* Language toggle in mobile menu */
.pml-mobile-menu__lang {
    display: flex;
    gap: 12px;
    justify-content: center;
    padding-top: 8px;
}

.pml-mobile-lang__link {
    padding: 8px 16px;
    color: var(--pml-text-secondary);
    text-decoration: none;
    font-size: 14px;
    font-weight: 600;
    border-radius: var(--pml-radius-xs);
    transition: color 0.2s ease, background-color 0.2s ease;
}

.pml-mobile-lang__link:hover {
    color: var(--pml-coral);
}

.pml-mobile-lang--active {
    color: var(--pml-coral);
    background-color: var(--pml-off-white);
}

/* Body scroll lock when menu is open */
body.pml-menu-open {
    overflow: hidden !important;
}

/* ==========================================================================
   CT-71 PASO 3 (S51) — Menú del toggle = overlay CORAL full-screen (match Showit)
   Convierte el panel lateral blanco en un modal coral a pantalla completa: X
   arriba-izq, wordmark serif, e items grandes en blanco. Items = producto
   (Home/Stays/Neighborhoods) + login. (No replicamos el marketing de Showit.)
   ========================================================================== */
.pml-mobile-menu__panel {
    inset: 14px;
    width: auto;
    max-width: none;
    background: var(--pml-coral);
    color: var(--pml-white);
    border-radius: 28px;
    padding: 24px clamp(24px, 6vw, 80px) 48px;
    gap: 28px;
    transform: translateY(-14px);
    opacity: 0;
    visibility: hidden;
    transition: opacity .32s ease, transform .32s ease, visibility .32s ease;
}
.pml-mobile-menu--open .pml-mobile-menu__panel {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
}

/* CT-71 fix: el banner CT-24 tiene z-index 10001 (= el panel) y es fixed arriba,
   así que se asomaba un sliver cuando el menú abría. Lo ocultamos mientras el
   menú está abierto (igual que body.modal-open hace con los modales Bootstrap). */
body.pml-menu-open .pml-banner {
    display: none !important;
}

/* Más margen del modal en DESKTOP (Chuy: "le falta más margin en escritorio") */
@media (min-width: 1024px) {
    .pml-mobile-menu__panel {
        inset: 40px;
        border-radius: 32px;
    }
}

/* X arriba a la IZQUIERDA, blanca */
.pml-mobile-menu__close {
    left: clamp(18px, 5vw, 72px);
    right: auto;
    top: 22px;
    width: 48px;
    height: 48px;
    font-size: 34px;
    color: var(--pml-white);
}
.pml-mobile-menu__close:hover {
    color: var(--pml-white);
    opacity: .8;
}

/* Wordmark del menú (serif blanco, debajo de la X) */
.pml-mobile-menu__brand {
    display: block;
    font-family: Georgia, 'Times New Roman', Times, serif;
    font-size: clamp(22px, 3vw, 30px);
    color: var(--pml-white);
    margin: 52px 0 4px;
}

/* Items GRANDES en blanco */
.pml-mobile-nav-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.pml-mobile-nav-list li a {
    color: var(--pml-white);
    font-family: var(--font-ui);
    font-size: clamp(28px, 5vw, 44px);
    font-weight: 500;
    padding: 8px 0;
    transition: opacity .15s ease;
}
.pml-mobile-nav-list li a:hover,
.pml-mobile-nav-list li.current-menu-item > a {
    color: var(--pml-white);
    opacity: .72;
}

/* Login / Submit: blanco sobre coral (visibles) */
.pml-mobile-menu__login-btn,
.pml-mobile-menu__submit {
    background: var(--pml-white) !important;
    color: var(--pml-coral) !important;
    border-radius: var(--pml-radius-pill);
}
.pml-mobile-menu__login-btn:hover,
.pml-mobile-menu__submit:hover {
    background: var(--pml-white) !important; /* MANTENER blanco (nunca se funde con el coral) */
    color: var(--pml-coral-dark) !important;
}
.pml-mobile-menu__auth { padding-top: 4px; }

/* Estados logged-in + lang: texto blanco sobre coral */
.pml-mobile-menu__user-name,
.pml-mobile-menu__user-email,
.pml-mobile-menu__user-links a,
.pml-mobile-menu__logout {
    color: var(--pml-white) !important;
}
.pml-mobile-menu__user-links a { border-color: rgba(255, 255, 255, 0.22); }
.pml-mobile-lang__link { color: rgba(255, 255, 255, 0.85); }
.pml-mobile-lang__link:hover,
.pml-mobile-lang--active { color: var(--pml-white); background: transparent; }

/* ==========================================================================
   CT-74 (S52) — Overlay logueado: arreglar distribución
   --------------------------------------------------------------------------
   PROBLEM (Chuy: "no está bien distribuido una vez logueado"): los items del
   dashboard (.pml-mobile-menu__user-links a) usan justify-content: space-between
   → icono al borde izq, label al borde der. Tolerable en el panel angosto
   original de móvil, pero en el overlay coral full-width de desktop (CT-71)
   estira icono y texto a los extremos dejando un hueco enorme; además el nav de
   producto (44px) queda huérfano abajo.
   FIX:
   1. Agrupar icono+label a la izquierda (flex-start + gap) en TODOS los tamaños.
   2. Desktop (≥1024px) y SOLO logueado (body.logged-in): dos columnas — cuenta
      (dashboard) a la izq, producto (Home/Stays/Neighborhoods) a la der — y bajar
      el tamaño del nav de producto para que armonice con la lista de al lado.
   El overlay del GUEST (aprobado, palabras grandes tipo Showit) queda intacto:
   todo lo de dos columnas está scopeado a body.logged-in. */

/* 1. Icono + label juntos a la izquierda (antes: space-between → hueco). */
.pml-mobile-menu__user-links a {
    justify-content: flex-start;
    gap: 12px;
}
.pml-mobile-menu__user-links a i {
    width: 22px;
    text-align: center;
    flex-shrink: 0;
    font-size: 16px;
}
/* Badge de no-leídos (Inbox): al extremo derecho de su fila. */
.pml-mobile-menu__user-links a .pml-user-dropdown__badge {
    margin-left: auto;
}

/* 2. Dos columnas en desktop, solo logueado. */
@media (min-width: 1024px) {
    body.logged-in .pml-mobile-menu__panel {
        display: grid;
        grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
        grid-template-areas:
            "brand brand"
            "auth  nav";
        align-content: start;
        column-gap: clamp(48px, 8vw, 120px);
        row-gap: 24px;
    }
    body.logged-in .pml-mobile-menu__brand { grid-area: brand; }
    body.logged-in .pml-mobile-menu__auth  { grid-area: auth; align-self: start; }
    body.logged-in .pml-mobile-menu__nav   { grid-area: nav;  align-self: start; }

    /* Lista de cuenta: un poco más grande en el modal full-screen. */
    body.logged-in .pml-mobile-menu__user-links a {
        font-size: 17px;
        padding: 13px 0;
    }
    /* Nav de producto: bajar de 44px para armonizar con la lista de al lado. */
    body.logged-in .pml-mobile-nav-list li a {
        font-size: clamp(22px, 2.2vw, 30px);
    }
}

/* ==========================================================================
   CT-75 (S52) — Header móvil: pill, cápsula sticky y hamburguesa
   --------------------------------------------------------------------------
   Reportado por Chuy (screenshots, móvil, sin sesión):
   1/2. El pill "Search Rentals" se ve muy grande: se encima con el banner y se
        corta contra el borde superior (desbordaba la altura del header móvil).
   3.   Al hacer scroll-down queda una "pestaña coral" asomada arriba: en móvil
        la banda fixed mide 56px (48px <375px) pero el inner conservaba su tamaño
        desktop (60px + 8px de margen top = 68px de fondo) → sobresalía de la banda
        y al ocultarse (translateY -100%) su parte baja quedaba visible.
   4.   En el sticky la hamburguesa salía OSCURA (var(--pml-text) del bloque móvil)
        e invisible sobre la cápsula coral.
   ========================================================================== */

/* 4. Hamburguesa blanca en estado fixed (cápsula coral). Especificidad (0,0,2,0)
   gana al override oscuro del bloque móvil (0,0,1,0). No toca el top state. */
.pml-header--fixed .pml-header__hamburger-line {
    background-color: var(--pml-white);
}

@media (max-width: 768px) {
    /* 1/2. Chuy (S52): el pill "Search Rentals" es innecesario en móvil — se
       ocultaba mal (se encimaba con el banner / se cortaba). La búsqueda ya está
       accesible por "Stays" en el menú overlay + el FAB coral en property-list, y
       sin el pill el wordmark completo tiene más espacio. Se oculta del navbar
       móvil. !important para ganar al display:inline-flex !important del top-state
       (l.~1295). */
    .pml-header__search-pill {
        display: none !important;
    }
    /* 3. Cápsula sticky más baja: 40 + 8 (margen top) = 48 ≤ banda (56/48) → se
       oculta completa sin dejar la pestaña coral asomada. */
    .pml-header--fixed .pml-header__inner {
        height: 40px;
        margin: 8px 12px;
    }
}

/* ==========================================================================
   CT-17 — Hide parent theme's native footer(s) (so CT-17 custom footer wins)
   ==========================================================================
   PROBLEM:
   WP Rentals parent theme emits its own footer on every page through several
   possible mechanisms depending on configuration:
     - `#colophon` — WordPress classic footer ID
     - `.wpestate_elementor_footer_custom` — WP Rentals' Elementor footer wrapper
     - `#footer-widget-area` — parent theme's widget-based footer
     - `.sub_footer` / `.sub_footer_wrapper` — sub-footer (copyright/social bar)
     - Any other `<footer>` tag not matching our custom `#pml-footer`

   Without hiding these, a user sees DUPLICATE footers stacked when both our
   custom CT-17 footer AND the native one render on the same page.

   ROOT CAUSE (why we don't edit the parent instead):
   Same rationale as CT-16 (see earlier in file): parent footer PHP is tied
   into Polylang, mega-menu drops, WP Rentals branding, booking widgets, etc.
   Clean decoupling = let parent render invisibly, hide with CSS, inject our
   own via `wp_footer` hook at priority 1.

   THE `footer:not(#pml-footer)` CATCH-ALL:
   A defensive selector that hides ANY `<footer>` element in the DOM that
   isn't our own `#pml-footer`. Protects against future parent theme updates
   that might introduce new footer wrappers we haven't enumerated. Without
   this catch-all, a theme update could silently start showing a duplicate
   footer until we add its class to this list.

   SCOPE:
   Applies globally. Our CT-17 custom footer is injected via `wp_footer` hook
   at priority 1, so it renders in the same DOM position as the native one
   would. This rule removes the visual duplicate.

   MAINTENANCE:
   - If WP Rentals adds new footer classes in an update, audit by opening
     any page with DevTools and searching for visible footer-like elements
     outside `#pml-footer`.
   - If we ever WANT the parent footer back (e.g., for one specific page),
     scope this rule with `:not(body.specific-page-class)` instead of
     removing it entirely. */
#colophon,
.wpestate_elementor_footer_custom,
#footer-widget-area,
.sub_footer,
.sub_footer_wrapper,
footer:not(#pml-footer) {
    display: none !important;
}

/* ==========================================================================
   CT-17 v2 — Custom Footer styles (S28: dark refresh + 5-col + i18n)
   --------------------------------------------------------------------------
   What changed vs v1:
     - Background #1a1a1a (true dark) instead of var(--pml-text) #333
     - Body text #cfcfcf (neutral gray) instead of light-blue tint
     - Headings 13px UPPERCASE letter-spacing 0.12em (was 15px regular)
     - Grid 5 cols (was 4) — added Contact column with widget + fallback
     - Social pills 38px subtle bg (was 36px outline)
     - Sub-footer border neutral white-alpha (was light-blue tint)

   Why neutral grays #1a1a1a / #cfcfcf instead of Kim palette tokens:
     The footer is a "neutral chrome" surface — true dark + neutral gray
     reads more premium across all hero/content backgrounds, and avoids
     the light-blue tint coloring everything blueish. Kim's palette stays
     the dominant brand on content surfaces (headers, cards, CTAs).
     Coral accent is preserved for hover states + the Contact CTA.

   Removal conditions: keep until/unless Kim requests a different footer
   palette. v1 left in git history if rollback ever needed.
   ========================================================================== */

.pml-footer {
    /* CT-17 v3 (S53): footer CORAL para paridad con Showit. El screenshot del footer real
       de Showit (dado por Chuy) es coral #FA4E24 con texto blanco — NO burgundy. El token
       #2e0a16 del design-system estaba glosado como "footer" pero es otra sección oscura,
       no este footer. Texto blanco sobre coral; acentos/botones en azul cielo #D0EAF0. */
    background-color: var(--pml-coral); /* #fa4e24 (was burgundy #2e0a16) */
    color: #ffffff;
    padding: 0;
    position: relative;
    z-index: 100;
    font-family: var(--pml-font-accent);
}

/* Half-map pages (properties-list, advanced-search):
   Body has class .is_half_map on these pages. The map is position:fixed,
   creating an app-like layout. Hide banner + footer, force header fixed. */
body.is_half_map .pml-banner {
    display: none !important;
}

body.is_half_map .pml-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 10000;
    background-color: var(--color-bg-page); /* CT-58: solid cream (flat) */
    backdrop-filter: var(--pml-blur-strong);
    -webkit-backdrop-filter: var(--pml-blur-strong);
    box-shadow: none; /* CT-58 flat */
    /* Keep same height/padding as static header so content stays centered */
}

body.is_half_map .full_map_container {
    top: 84px !important;
    height: calc(100vh - 84px) !important;
}

body.is_half_map #google_map_prop_list_sidebar {
    top: 84px !important;
    height: calc(100vh - 84px) !important;
}

body.is_half_map #google_map_prop_list_wrapper {
    top: 84px !important;
    height: calc(100vh - 84px) !important;
}

body.is_half_map #pml-footer {
    display: none;
}

/* Main footer: 5-column grid (CT-17 v2)
   1.4fr (about) + 1fr × 3 (Explore / Quick Links / Legal) + 1.2fr (Contact) */
#pml-footer .pml-footer__main {
    max-width: 1400px;
    margin: 0 auto;
    padding: 56px 24px 32px;
    display: grid !important;
    grid-template-columns: 1.4fr 1fr 1fr 1fr 1.2fr !important;
    gap: 48px;
}

/* Column base */
#pml-footer .pml-footer__col {
    min-width: 0;
    float: none !important;
    width: auto !important;
}

/* CT-17 v3 (S53): tira de fotos lifestyle (match Showit) — fila horizontal de cuadros.
   Vacía por default (ver inc/footer.php $pml_photostrip); solo aparece cuando Kim provee fotos.
   Desktop: N columnas iguales edge-to-edge. Móvil: scroll horizontal con snap. */
.pml-footer__photostrip {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 12px;
    max-width: 1400px;
    margin: 0 auto;
    padding: 8px 24px;
}

.pml-footer__photostrip-item {
    aspect-ratio: 1 / 1;
    overflow: hidden;
    border-radius: 0;
    background: rgba(255, 255, 255, 0.08);
}

.pml-footer__photostrip-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

@media (max-width: 900px) {
    .pml-footer__photostrip {
        grid-auto-columns: 42%;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        padding-bottom: 12px;
    }
    .pml-footer__photostrip-item {
        scroll-snap-align: start;
    }
}

/* Logo in footer — invert PNG to white via filter (logo is dark on transparent) */
.pml-footer__logo {
    display: inline-block;
    margin-bottom: 18px;
}

.pml-footer__logo img {
    height: 50px;
    width: auto;
    filter: brightness(0) invert(1);
    opacity: 0.92;
}

/* CT-70 → CT-17 v3 (S53): wordmark de texto en el footer.
   Cambiado de Outfit (sans) al MISMO serif del header (CT-71, .pml-header__logo-text:
   Georgia/Times, weight 500, 26px, line-height 1) para consistencia con el navbar ya
   emparejado a Showit + eco del display serif del footer de Showit. Blanco sobre coral. */
.pml-footer__logo-text {
    font-family: Georgia, 'Times New Roman', Times, serif;
    font-weight: 500;
    font-size: 26px;
    line-height: 1;
    letter-spacing: 0;
    color: #ffffff;
}

/* About text (widget or fallback) — CT-17 v3: soft white on coral */
.pml-footer__about-text,
.pml-footer__widget {
    font-size: 14px;
    line-height: 1.7;
    color: rgba(255, 255, 255, 0.88);
    margin: 0 0 16px;
}

/* Language toggle in footer */
.pml-footer__lang {
    margin-top: 16px;
}

.pml-footer__lang .pml-mobile-lang__link {
    color: #ffffff;
    font-size: 13px;
    padding: 6px 14px;
    border: 1px solid rgba(255, 255, 255, 0.4);
    border-radius: var(--pml-radius-xs);
    margin-right: 8px;
    transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
}

.pml-footer__lang .pml-mobile-lang__link:hover {
    color: #ffffff;
    border-color: rgba(255, 255, 255, 0.75);
}

/* CT-17 v3: activo = relleno blanco + texto coral (el coral-sobre-coral era invisible) */
.pml-footer__lang .pml-mobile-lang--active {
    color: var(--pml-coral);
    background-color: #ffffff;
    border-color: #ffffff;
}

/* Column headings — uppercase tracked label style (mockup-aligned) */
#pml-footer .pml-footer__heading {
    font-size: 13px;
    font-weight: 600;
    color: #ffffff !important;
    margin: 0 0 18px;
    padding: 0;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    border: none;
}

/* Footer menu lists */
#pml-footer .pml-footer__menu {
    list-style: none !important;
    margin: 0 !important;
    padding: 0 !important;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

#pml-footer .pml-footer__menu li {
    margin: 0;
    padding: 0;
    list-style: none;
    background: none;
}

#pml-footer .pml-footer__menu li::before,
#pml-footer .pml-footer__menu li::marker {
    content: none !important;
    display: none !important;
}

#pml-footer .pml-footer__menu li a {
    display: block;
    padding: 6px 0;
    color: #ffffff !important;
    text-decoration: none;
    font-size: 14px;
    transition: color 0.18s ease;
    background: none !important;
}

/* CT-17 v3: hover azul cielo (Showit accent) — el coral sobre coral no se veía */
#pml-footer .pml-footer__menu li a:hover {
    color: var(--color-bg-sky) !important;
}

/* Contact column CTA (fallback when widget area is empty) */
/* CT-17 v3: botón azul cielo #D0EAF0 con texto oscuro (igual que el "Submit" de Showit;
   un botón coral sobre el footer coral desaparecería). */
.pml-footer__col--contact .pml-footer__cta {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 11px 22px;
    background: var(--color-bg-sky);
    color: var(--color-text-dark) !important;
    font-size: 14px;
    font-weight: 600;
    border-radius: var(--pml-radius-md);
    text-decoration: none;
    transition: background-color 0.18s ease, transform 0.18s ease;
}

.pml-footer__col--contact .pml-footer__cta:hover {
    background: #ffffff;
    transform: translateY(-1px);
    text-decoration: none;
}

/* Sub-footer bar */
#pml-footer .pml-footer__sub {
    max-width: 1400px;
    margin: 0 auto;
    padding: 22px 24px;
    border-top: 1px solid rgba(255, 255, 255, 0.22);
    display: flex !important;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
}

.pml-footer__copy {
    font-size: 12px;
    color: rgba(255, 255, 255, 0.8);
    margin: 0;
    letter-spacing: 0.02em;
}

/* Social links — subtle filled pills (mockup pattern) */
.pml-footer__social {
    display: flex;
    gap: 10px;
}

.pml-footer__social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    border-radius: var(--pml-radius-circle);
    background-color: rgba(255, 255, 255, 0.16);
    color: #ffffff;
    transition: background-color 0.2s ease, color 0.2s ease;
}

/* CT-17 v3: hover = pastilla blanca + icono coral (inverso; el coral sobre coral no se veía) */
.pml-footer__social-link:hover {
    background-color: #ffffff;
    color: var(--pml-coral);
}

.pml-footer__social-link svg {
    width: 18px;
    height: 18px;
}

/* CT-17 v3 (S53): banda MARQUEE al fondo — wordmark gigante en serif blanco scrolleando
   horizontal (match del footer de Showit). Pura CSS (sin JS) + respeta prefers-reduced-motion.
   overflow:hidden en el contenedor evita scroll horizontal de la pagina; el track es
   width:max-content y el texto se repite 8 veces (2 mitades iguales) → translateX(-50%) loop. */
.pml-footer__marquee {
    overflow: hidden;
    width: 100%;
    padding: 6px 0 20px;
}

.pml-footer__marquee-track {
    display: flex;
    width: max-content;
    white-space: nowrap;
    animation: pml-footer-marquee 45s linear infinite;
    will-change: transform;
}

.pml-footer__marquee-item {
    font-family: Georgia, 'Times New Roman', Times, serif;
    font-weight: 500;
    font-size: clamp(44px, 11vw, 150px);
    line-height: 1.02;
    color: #ffffff;
    padding-right: 0.35em;
    letter-spacing: 0;
}

@keyframes pml-footer-marquee {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
    .pml-footer__marquee-track {
        animation: none;
        transform: none;
    }
}

/* --- Footer responsive (CT-17 v2) ---
   1024px: collapse to 2 cols, About spans full width
   600px:  single column, sub-footer stacks center */

@media (max-width: 1280px) {
    #pml-footer .pml-footer__main {
        grid-template-columns: 1.4fr 1fr 1fr 1fr !important;
        gap: 36px;
    }
    /* Push Contact below as a full-width row to keep cols readable */
    #pml-footer .pml-footer__col--contact {
        grid-column: 1 / -1;
        padding-top: 28px;
        border-top: 1px solid rgba(255, 255, 255, 0.06);
    }
}

@media (max-width: 1024px) {
    #pml-footer .pml-footer__main {
        grid-template-columns: 1fr 1fr !important;
        gap: 32px;
    }

    #pml-footer .pml-footer__col--about,
    #pml-footer .pml-footer__col--contact {
        grid-column: 1 / -1;
    }

    #pml-footer .pml-footer__col--contact {
        border-top: 1px solid rgba(255, 255, 255, 0.06);
        padding-top: 28px;
    }
}

@media (max-width: 600px) {
    #pml-footer .pml-footer__main {
        grid-template-columns: 1fr !important;
        gap: 28px;
        padding: 36px 16px 24px;
    }

    #pml-footer .pml-footer__sub {
        flex-direction: column;
        text-align: center;
        padding: 18px 16px;
    }
}


/* ==========================================================================
   CT-19 — Full Width Elementor Page Template
   Strips all parent theme layout constraints so Elementor sections
   render at 100% viewport width (edge-to-edge).
   ========================================================================== */

.pml-full-width {
    background-color: var(--pml-white, #fff);
}

/* Force parent theme wrappers to full width */
.pml-full-width .main_wrapper,
.pml-full-width .content_wrapper,
.pml-full-width .content_wrapper.row,
.pml-full-width .container.main_wrapper {
    max-width: 100% !important;
    width: 100% !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}

.pml-full-width__content {
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0;
    /* overflow-x: clip (no hidden) — `hidden` crea bloque de formato y
       rompe `position: sticky` en descendants. `clip` previene scroll
       horizontal igual que `hidden` PERO sin establecer contexto de
       contenedor sticky. Soporte: Chrome 90+, Firefox 102+, Safari 15.4+
       (~98% coverage 2026). Browsers viejos hacen fallback al default
       `visible` (puede mostrar scroll horizontal en algún edge case
       mobile, pero NO es crítico). Bug original: CT-37 sidebar y mapa
       quedaban como elementos normales sin sticky pegándose en pantalla. */
    overflow-x: clip;
}

/* Force ALL Elementor containers to full width on pages using CT-19 template.
   This is global — every section, container, column gets unconstrained. */
.pml-full-width .elementor-section,
.pml-full-width .elementor-section > .elementor-container,
.pml-full-width .elementor-section-boxed > .elementor-container,
.pml-full-width .elementor-column-wrap,
.pml-full-width .elementor-widget-wrap,
.pml-full-width .e-con,
.pml-full-width .e-child,
.pml-full-width [data-elementor-type="wp-page"] {
    max-width: 100% !important;
    width: 100% !important;
    --container-max-width: 100% !important;
    --content-width: 100% !important;
}

/* Stretched sections go full viewport */
.pml-full-width .elementor-section.elementor-section-stretched {
    width: 100vw !important;
    left: 0 !important;
}

/* Reset Bootstrap .row gutters */
.pml-full-width .row {
    margin-left: 0;
    margin-right: 0;
}

/* Individual sections can set their own inner max-width via Elementor editor */



/* CT-22 Properties Grid styles moved to css/components/properties-grid.css
   (S35 refactor — extracted from monolith). The shortcode lazy-enqueues it. */

/* ==========================================================================
   CT-21 — Cookie Consent Banner (WPConsent)
   WPConsent uses Shadow DOM, so we style via ::part() selectors.
   ========================================================================== */

wpconsent-banner::part(wpconsent-banner) {
    font-family: var(--pml-font-body) !important;
    background: var(--pml-glass-strong) !important;
    backdrop-filter: var(--pml-blur-standard) !important;
    -webkit-backdrop-filter: var(--pml-blur-standard) !important;
    border: 1px solid rgba(255, 255, 255, 0.4) !important;
    border-radius: var(--pml-radius-xl) !important;
    box-shadow: none !important; /* CT-58 flat */
    padding: 20px 24px !important;
    max-width: 480px !important;
    margin: 0 0 16px 16px !important;
}

wpconsent-banner::part(wpconsent-banner-body) {
    font-family: var(--pml-font-body) !important;
    font-size: 13px !important;
    color: #333 !important;
    line-height: 1.5 !important;
}

wpconsent-banner::part(wpconsent-banner-footer) {
    gap: 8px !important;
    margin-top: 14px !important;
}

/* Accept All — coral primary */
wpconsent-banner::part(wpconsent-button-accept) {
    font-family: var(--pml-font-body) !important;
    font-weight: 600 !important;
    font-size: 13px !important;
    background: #e45e4c !important;
    color: #fff !important;
    border: none !important;
    border-radius: var(--pml-radius) !important;
    padding: 10px 20px !important;
    cursor: pointer !important;
    transition: background 0.2s ease !important;
}

wpconsent-banner::part(wpconsent-button-accept):hover {
    /* S25: formalized as --pml-action-hover token */
    background: var(--pml-action-hover) !important;
}

/* Reject — subtle outline */
wpconsent-banner::part(wpconsent-button-cancel) {
    font-family: var(--pml-font-body) !important;
    font-weight: 500 !important;
    font-size: 13px !important;
    background: transparent !important;
    color: #666 !important;
    border: 1px solid #e8e8e8 !important;
    border-radius: var(--pml-radius) !important;
    padding: 10px 16px !important;
    cursor: pointer !important;
    transition: border-color 0.2s ease, color 0.2s ease !important;
}

wpconsent-banner::part(wpconsent-button-cancel):hover {
    border-color: #999 !important;
    color: #333 !important;
}

/* Preferences — text-only */
wpconsent-banner::part(wpconsent-button-preferences) {
    font-family: var(--pml-font-body) !important;
    font-weight: 500 !important;
    font-size: 13px !important;
    background: transparent !important;
    color: #999 !important;
    border: none !important;
    padding: 10px 12px !important;
    cursor: pointer !important;
    transition: color 0.2s ease !important;
}

wpconsent-banner::part(wpconsent-button-preferences):hover {
    color: #e45e4c !important;
}


/* ==========================================================================
   CT-23 — Dashboard & User Pages: Brand PML + Mobile Responsive
   Applies to ALL pages with .is_dashboard_page (Dashboard, My Profile,
   My Listings, Add New Listing, All in One Calendar, Favorites,
   My Bookings, My Reservations, My Reviews, My Inbox, Invoices).
   ========================================================================== */

/* ── 1. Hide redundant elements ── */

#user_tab_menu_trigger,
.user_tab_menu_close {
    display: none !important;
}

.is_dashboard_page header[itemscope],
.is_dashboard_page .header_media {
    display: none !important;
}

/* ── 2. Typography: Parent defaults → PML brand (Jost) ── */

.wprentals_dashboard_page,
.dashboard_chapter_label,
.property_dashboard_location_wrapper,
.user_dashboard_panel,
.user_dashboard_links,
.user_tab_menu,
.dashboard-header,
.profile_wellcome,
.user_profile_div,
.wprentals_allinone_wrapper,
.inbox-wrapper,
.invoices-wrapper,
.dashboard_property_list {
    font-family: var(--pml-font-body) !important;
}

/* ── 3. Sidebar — Brand PML ── */

.user_tab_menu {
    background: var(--pml-off-white) !important;
    border-radius: var(--pml-radius-lg) !important;
    padding: 20px 0 !important;
}

.profile-image-wrapper {
    text-align: center;
    padding: 0 16px 16px !important;
    border-bottom: 1px solid var(--pml-border) !important;
    margin-bottom: 8px !important;
}

#profile-image-menu {
    width: 64px !important;
    height: 64px !important;
    border-radius: var(--pml-radius-circle) !important;
    margin: 0 auto 8px !important;
    background-size: cover !important;
}

.profile_wellcome {
    font-size: 14px !important;
    font-weight: 600 !important;
    color: var(--pml-text) !important;
}

.user_dashboard_links a {
    font-size: 14px !important;
    font-weight: 500 !important;
    padding: 10px 20px !important;
    color: var(--pml-text) !important;
    border-left: 3px solid transparent !important;
    transition: all 0.2s !important;
    display: flex !important;
    align-items: center !important;
    gap: 8px !important;
}

.user_dashboard_links a:hover {
    background: var(--pml-hover-bg) !important;
    color: var(--pml-coral) !important;
}

.user_dashboard_links .user_tab_active {
    background: var(--pml-hover-bg) !important;
    border-left-color: var(--pml-coral) !important;
    color: var(--pml-coral) !important;
    font-weight: 600 !important;
}

.unread_mess_wrap_menu {
    background: var(--pml-coral) !important;
    border-radius: var(--pml-radius-md) !important;
    font-size: 11px !important;
    font-weight: 700 !important;
    color: white !important;
    padding: 1px 6px !important;
    min-width: 18px !important;
    text-align: center !important;
}

/* ── 4. Content area — Brand PML ── */

.content_wrapper_dashboard {
    padding: 0 12px !important;
}

.dashboard-header {
    border-bottom: 1px solid var(--pml-border) !important;
    padding-bottom: 16px !important;
    margin-bottom: 20px !important;
    display: flex !important;
    align-items: center !important;
    justify-content: space-between !important;
}

h1.entry-title-profile {
    font-family: var(--pml-font-heading) !important;
    font-size: 24px !important;
    font-weight: 700 !important;
    color: var(--pml-text) !important;
    margin: 0 !important;
}

.user_dashboard_panel {
    background: var(--pml-white) !important;
    border-radius: var(--pml-radius-lg) !important;
    border: 1px solid var(--pml-border) !important;
    padding: 20px !important;
    margin-bottom: 16px !important;
}

.user_dashboard_panel_title,
.user_dashboard_panel_title_widget {
    font-size: 15px !important;
    font-weight: 600 !important;
    color: var(--pml-text) !important;
    margin-bottom: 12px !important;
    font-family: var(--pml-font-heading) !important;
}

/* ==========================================================================
   FORM ELEMENTS — global defaults (S26)
   --------------------------------------------------------------------------
   Why: WP Rentals parent ships minimal form styling. Child theme had only
   bandages on the advanced search form (lines ~300-370) and dashboard rules
   below. Selects rendered as native browser chrome (looked broken next to
   PML branded UI). Placeholders had no color rule (browser default gray
   varies by engine and clashes with off-white surfaces). Text inputs had no
   global typography (Jost was set on body but not always inherited by form
   controls — Bootstrap reset wins on .form-control).

   This block establishes brand defaults for <input>, <select>, <textarea>
   using the S25 token system, plus ::placeholder color and <select> custom
   appearance. Specificity is intentionally body-prefixed where Bootstrap's
   .form-control might collide; inputs scoped by attribute selector.

   Showcased on /pml-styleguide/ (CT-34). Dashboard-specific rules below
   keep their !important and override here when they apply.
   ========================================================================== */

/* Text-style inputs + textarea + select: brand typography + radius + border.
   body prefix bumps specificity above .form-control (0,0,1,1 → 0,0,1,2). */
body input[type="text"],
body input[type="email"],
body input[type="password"],
body input[type="tel"],
body input[type="url"],
body input[type="number"],
body input[type="search"],
body input[type="date"],
body textarea,
body select {
    font-family: var(--pml-font-body);
    font-size: var(--pml-fs-body-sm);
    font-weight: var(--pml-fw-regular);
    line-height: var(--pml-lh-body);
    color: var(--pml-text-body);
    background-color: var(--pml-bg-card);
    border: 1px solid var(--pml-border);
    border-radius: var(--pml-radius-md);
    padding: 10px 14px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Focus state: coral border + soft ring (matches dashboard focus pattern) */
body input[type="text"]:focus,
body input[type="email"]:focus,
body input[type="password"]:focus,
body input[type="tel"]:focus,
body input[type="url"]:focus,
body input[type="number"]:focus,
body input[type="search"]:focus,
body input[type="date"]:focus,
body textarea:focus,
body select:focus {
    outline: 2px solid var(--pml-coral); /* CT-56 flat focus (was glow ring) */
    outline-offset: 1px;
    border-color: var(--pml-action);
    box-shadow: none;
}

/* Disabled: dim + page-bg to signal non-interactive */
body input:disabled,
body textarea:disabled,
body select:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    background-color: var(--pml-bg-page);
}

/* Placeholder: tertiary text color, full opacity (Firefox defaults to 0.54) */
body ::placeholder {
    color: var(--pml-text-tertiary);
    opacity: 1;
}

/* Select: kill native chrome, add custom coral chevron SVG.
   The dropdown arrow ships inline as a data: URI to avoid extra HTTP and
   keep the asset version-locked with the CSS. Color is --pml-coral (#e45e4c)
   so swap the hex if the brand changes. */
body select {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23e45e4c'%3E%3Cpath d='M4.146 6.146a.5.5 0 0 1 .708 0L8 9.293l3.146-3.147a.5.5 0 0 1 .708.708l-3.5 3.5a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 0 1 0-.708z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 14px center;
    background-size: 14px 14px;
    padding-right: 36px;
}

/* Textarea: vertical resize only, sensible min-height */
body textarea {
    resize: vertical;
    min-height: 96px;
}

/* Reusable input-with-icon pattern for forms outside the search bandages.
   Use: <div class="pml-input-with-icon"><i class="pml-input-icon">...</i><input/></div>
   Icon sits absolute-left, input gets padding-left to clear it. */
.pml-input-with-icon {
    position: relative;
}

.pml-input-with-icon > input,
.pml-input-with-icon > select {
    padding-left: 40px;
}

.pml-input-with-icon > .pml-input-icon {
    position: absolute;
    top: 50%;
    left: 14px;
    transform: translateY(-50%);
    color: var(--pml-text-tertiary);
    pointer-events: none;
    line-height: 1;
}

/* Checkbox + radio: scale up, tint to coral on check.
   accent-color is the modern way to brand-tint native checkboxes/radios
   without losing accessibility (focus ring, keyboard nav stay native). */
body input[type="checkbox"],
body input[type="radio"] {
    accent-color: var(--pml-action);
    width: 16px;
    height: 16px;
    cursor: pointer;
}

/* Form labels: brand typography for any <label> not inside a third-party widget */
body form label,
body .pml-form-group label {
    font-family: var(--pml-font-body);
    font-size: var(--pml-fs-label);
    font-weight: var(--pml-fw-medium);
    color: var(--pml-text-body);
    display: inline-block;
    margin-bottom: 6px;
}

/* ==========================================================================
   FORM ELEMENTS — Scope guard for WP Rentals advanced search wrapper (S26)
   --------------------------------------------------------------------------
   The "FORM ELEMENTS — global" block above intentionally does NOT apply
   inside the advanced search form. That wrapper has its own visual contract
   maintained by the bandage at lines ~354-368 (icon position, padding-left
   45px) and the parent theme's unified search-bar background. Without this
   guard, the global rule's border + border-radius + bg-color would
   double-style the inputs and visually detach the absolute-positioned icon
   from the input — see S26 regression report.

   Specificity: `.advanced_search_form_wrapper input[type="text"]` is
   (0,0,2,1) which beats the global `body input[type="text"]` (0,0,1,2).

   Applies to: /properties-list/, /advanced-search/, half-map header search.
   Does NOT apply to: login, register, single property inquiry sidebar,
   submit form — those keep the new defaults.
   ========================================================================== */

.advanced_search_form_wrapper input[type="text"],
.advanced_search_form_wrapper input[type="email"],
.advanced_search_form_wrapper input[type="search"],
.advanced_search_form_wrapper input[type="date"],
.advanced_search_form_wrapper input[type="number"],
.advanced_search_form_wrapper textarea,
.advanced_search_form_wrapper select {
    border: none;
    background-color: transparent;
    border-radius: 0;
}

.advanced_search_form_wrapper input[type="text"]:focus,
.advanced_search_form_wrapper input[type="email"]:focus,
.advanced_search_form_wrapper input[type="search"]:focus,
.advanced_search_form_wrapper input[type="date"]:focus,
.advanced_search_form_wrapper input[type="number"]:focus,
.advanced_search_form_wrapper textarea:focus,
.advanced_search_form_wrapper select:focus {
    box-shadow: none;
    border: none;
}

/* ==========================================================================
   Bootstrap-select (Type field) — brand-aligned override (S26)
   --------------------------------------------------------------------------
   The Property Type field is the only multi-select in the search form, so
   WP Rentals renders it via the bootstrap-select library
   (silviomoreto/bootstrap-select). The library hides the native <select>
   and renders a <button class="dropdown-toggle btn-default"> as the visible
   trigger. The parent theme tries to style it via .wpestate-multiselect-
   custom-style (parent style.css:24217 — `border:none; background:transparent`)
   but Bootstrap 3 .btn-default + .show-tick.form-control .btn-default win
   with their gray-gradient default. Result: Type looks broken next to the
   other PML-styled dropdowns.

   This override targets the rendered button with all three classes from
   the actual DOM (verified via view-source S26): `button` tag +
   `.wpestate-multiselect-custom-style` + `.dropdown-toggle` + `.btn-default`
   = specificity (0,0,4,1) — wins over both Bootstrap 3 and parent rules.

   We re-claim with brand tokens to match the visual of the other custom
   dropdowns (.dropdown.custom_icon_class.form-control rendered by parent
   for Area, Pets Allowed, Bedrooms).

   The internal <span class="caret"> is a CSS-triangle (border trick).
   Coloring border-top to coral makes the chevron coral without replacing
   the markup or fighting the library's positioning.

   Affects: search form on /properties-list/ + homepage Reservation widget
   + any other surface where the multi-select Type dropdown renders.
   Does NOT affect: the Bootstrap 3 .btn-default class globally — selector
   is qualified with .wpestate-multiselect-custom-style.
   ========================================================================== */

/* S26 fix C — bordering belongs on the wrapper, not the button.
   Parent style.css:24295 sets `border: 1px solid #e7e9ef` on the wrapper
   `.dropdown.bootstrap-select.show-tick.form-control` intentionally —
   the bootstrap-select library uses the wrapper as the visible field,
   with the button as the transparent click target inside.
   Earlier S26 override added border + bg to the button too, producing
   a "card-in-card" double-border visual. Reverted to transparent button;
   wrapper's parent border now provides the only visible boundary, and
   we override the wrapper color below to match brand tokens. */
button.wpestate-multiselect-custom-style.dropdown-toggle.btn-default {
    background: transparent;
    background-image: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
    color: var(--pml-text-body);
    font-family: var(--pml-font-body);
    font-size: var(--pml-fs-body-sm);
    font-weight: var(--pml-fw-regular);
    line-height: var(--pml-lh-body);
}

button.wpestate-multiselect-custom-style.dropdown-toggle.btn-default:hover,
button.wpestate-multiselect-custom-style.dropdown-toggle.btn-default:focus,
button.wpestate-multiselect-custom-style.dropdown-toggle.btn-default:active,
.open > button.wpestate-multiselect-custom-style.dropdown-toggle.btn-default {
    background: transparent;
    background-image: none;
    border: none;
    box-shadow: none;
    color: var(--pml-text-body);
    outline: none;
}

/* Wrapper-level border in brand tokens — replaces parent's #e7e9ef.
   This is the visible "card" border for the Type field. Matches the
   neutral border used by the other dropdowns in the same form
   (Area, Pets Allowed, Bedrooms via .dropdown.custom_icon_class). */
.advanced_search_form_wrapper .dropdown.bootstrap-select.show-tick.form-control {
    border-color: var(--pml-border);
    border-radius: var(--pml-radius-md);
}

/* Focus state on wrapper when dropdown is open. Bootstrap-select adds
   .open to the wrapper; we hook there instead of the button so the ring
   matches the visible boundary. */
.advanced_search_form_wrapper .dropdown.bootstrap-select.show-tick.form-control.open {
    border-color: var(--pml-action);
    outline: 2px solid var(--pml-coral); /* CT-56 flat focus (was glow ring) */
    outline-offset: 1px;
    box-shadow: none;
}

/* ==========================================================================
   Owner card "See Owner Profile" link — contrast fix on coral surface (S26)
   --------------------------------------------------------------------------
   The CT-31 owner section (themes/wprentals-child/inc/pluggable.php:293)
   wraps the panel in .owner-page-wrapper which inherits a coral background
   from the parent theme. The default link color --pml-text-link
   (= --pml-coral-dark #b5440f) fails WCAG contrast on the coral bg
   (#e45e4c) — measured ~2.6:1 vs the 4.5:1 AA threshold for body text.
   Visible symptom: "See Owner Profile" reads as faint dark-coral against
   coral, almost invisible (Chuy reported S26).

   Fix: force white + underline on this specific link so the CTA is
   legible. Underline distinguishes it from the white owner name above
   (which is bold but no underline). White on coral = ~5.0:1 contrast
   (passes AA for body text per the same WCAG audit S10).

   Scope: only the .owner_read_more link inside .owner-page-wrapper —
   doesn't change global link color or other links inside the wrapper.
   ========================================================================== */

.owner-page-wrapper .owner_read_more,
.owner-page-wrapper .owner_read_more:visited {
    color: var(--pml-white);
    text-decoration: underline;
    text-underline-offset: 3px;
    font-weight: var(--pml-fw-medium);
}

.owner-page-wrapper .owner_read_more:hover,
.owner-page-wrapper .owner_read_more:focus {
    color: var(--pml-white);
    text-decoration-thickness: 2px;
    outline: none;
}

/* Color the existing CSS-triangle caret coral. The library renders
   <span class="bs-caret"><span class="caret"></span></span>, where the
   inner span is a Bootstrap 3 caret built with border-top (the visible
   triangle). Recoloring border-top is enough — no markup replacement. */
.bootstrap-select .wpestate-multiselect-custom-style.dropdown-toggle .bs-caret .caret {
    border-top-color: var(--pml-coral);
}

/* Placeholder state when no Type selected — keep tertiary text color */
button.wpestate-multiselect-custom-style.bs-placeholder,
button.wpestate-multiselect-custom-style.bs-placeholder .filter-option-inner-inner {
    color: var(--pml-text-tertiary);
}

/* Form inputs */
.is_dashboard_page .form-control {
    border-radius: var(--pml-radius-md) !important;
    border: 1px solid var(--pml-border) !important;
    font-family: var(--pml-font-body) !important;
    font-size: 14px !important;
    padding: 10px 14px !important;
}

.is_dashboard_page .form-control:focus {
    border-color: var(--pml-coral) !important;
    border-left-width: 1px !important;
    outline: 2px solid var(--pml-coral) !important; /* CT-56 flat focus */
    outline-offset: 1px !important;
    box-shadow: none !important;
}

/* Buttons */
.is_dashboard_page .wpestate_vc_button,
.is_dashboard_page .vc_button,
.is_dashboard_page input[type="submit"],
.next_submit_page input,
#update_profile,
#form_submit_1 {
    background: var(--pml-coral) !important;
    color: white !important;
    border: none !important;
    border-radius: var(--pml-radius-lg) !important;
    font-family: var(--pml-font-accent) !important;
    font-weight: 600 !important;
    font-size: 14px !important;
    padding: 10px 24px !important;
    cursor: pointer !important;
    transition: background 0.2s !important;
}

.is_dashboard_page .wpestate_vc_button:hover,
.is_dashboard_page .vc_button:hover,
#update_profile:hover,
#form_submit_1:hover {
    /* S25: formalized as --pml-action-hover token */
    background: var(--pml-action-hover) !important;
}

/* Delete button — keep distinct */
#delete_profile {
    background: transparent !important;
    color: var(--pml-text-tertiary) !important;
    border: 1px solid var(--pml-border) !important;
}

/* Widget units */
.dashboard_widget_unit {
    padding: 10px 0 !important;
    border-bottom: 1px solid var(--pml-border) !important;
}

.dashbard_unit_title {
    font-weight: 600 !important;
    color: var(--pml-text) !important;
}

.dashbard_unit_title:hover {
    color: var(--pml-coral) !important;
}

/* Back to home */
.back_to_home a {
    color: var(--pml-coral-dark) !important;
    font-size: 13px !important;
}

/* Bell notification */
.wpestate_bell_note_unread {
    /* S25: bumped 10px (drift) → overline token (11px) */
    background: var(--pml-coral) !important;
    color: white !important;
    border-radius: var(--pml-radius-circle) !important;
    font-size: var(--pml-fs-overline) !important;
    font-weight: var(--pml-fw-bold) !important;
}

/* Status badges */
.wprentals_status {
    font-size: 12px !important;
    font-family: var(--pml-font-accent) !important;
}

/* Listing titles in tables */
.listing_title a {
    font-family: var(--pml-font-accent) !important;
    font-weight: 600 !important;
    color: var(--pml-text) !important;
}

.listing_title a:hover {
    color: var(--pml-coral) !important;
}

/* Dashboard table headers */
.wpestate_dashboard_table_list_header {
    font-family: var(--pml-font-accent) !important;
    font-size: 13px !important;
    font-weight: 600 !important;
    color: var(--pml-text-secondary) !important;
    text-transform: uppercase !important;
    letter-spacing: 0.5px !important;
    border-bottom: 1px solid var(--pml-border) !important;
    padding-bottom: 10px !important;
    margin-bottom: 10px !important;
}

/* Add New Listing form guide tabs — typography only.
   CT-23 originally also set border-radius + padding + coral bg on .active,
   but that painted the entire <a> as a coral box, hiding the parent theme's
   native wizard design (circle indicators via ::before/::after pseudos).
   Removed in S18 audit. Parent handles the active state correctly. */
.user_dashboard_panel_guide a {
    font-family: var(--pml-font-accent) !important;
    font-size: 13px !important;
    font-weight: 500 !important;
}

/* Labels */
.is_dashboard_page label {
    font-family: var(--pml-font-body) !important;
    font-size: 14px !important;
    font-weight: 500 !important;
    color: var(--pml-text) !important;
}

/* Search bar in dashboard */
.search_dashborad_header .form-control {
    font-size: 14px !important;
}

/* Messages */
.message_listing {
    border-bottom: 1px solid var(--pml-border) !important;
}

.message_header {
    font-family: var(--pml-font-accent) !important;
}

/* Invoice table */
.invoice_unit {
    border-bottom: 1px solid var(--pml-border) !important;
    padding: 10px 0 !important;
    font-size: 13px !important;
}

.invoice_unit_title {
    font-family: var(--pml-font-accent) !important;
}

/* Calendar all-in-one */
.wprentals_allinone_wrapper {
    overflow-x: auto !important;
    -webkit-overflow-scrolling: touch !important;
}

/* ── 5. Mobile ≤768px ── */

@media (max-width: 768px) {
    .user_tab_menu.col-md-3 {
        width: 100% !important;
        float: none !important;
        margin-bottom: 16px !important;
    }

    .dashboard-margin {
        width: 100% !important;
        float: none !important;
        padding: 0 !important;
    }

    .is_dashboard_page .col-md-8,
    .is_dashboard_page .col-md-9,
    .is_dashboard_page .col-md-4,
    .is_dashboard_page .col-md-3:not(.user_tab_menu),
    .is_dashboard_page .col-md-6,
    .is_dashboard_page .col-md-12 {
        width: 100% !important;
        float: none !important;
        padding-left: 0 !important;
        padding-right: 0 !important;
    }

    .content_wrapper_dashboard {
        padding: 0 8px !important;
    }

    .dashboard-header {
        flex-wrap: wrap !important;
        gap: 8px !important;
    }

    h1.entry-title-profile {
        font-size: 20px !important;
    }

    .user_dashboard_panel {
        padding: 14px !important;
    }

    .is_dashboard_page .form-control {
        width: 100% !important;
        font-size: 16px !important;
    }

    .is_dashboard_page .wpestate_vc_button,
    .is_dashboard_page input[type="submit"] {
        width: 100% !important;
    }

    /* Listing rows: stack on mobile */
    .dasboard-prop-listing {
        display: flex !important;
        flex-wrap: wrap !important;
        gap: 8px !important;
        padding: 12px 0 !important;
    }

    .dasboard-prop-listing .blog_listing_image {
        width: 100% !important;
    }

    .dasboard-prop-listing .property_dashboard_reviews,
    .dasboard-prop-listing .property_dashboard_price,
    .dasboard-prop-listing .property_dashboard_status,
    .dasboard-prop-listing .property_dashboard_actions {
        width: auto !important;
        float: none !important;
    }

    /* Hide table column headers on mobile */
    .wpestate_dashboard_table_list_header {
        display: none !important;
    }

    /* Booking/reservation rows */
    .booking_unit_status,
    .booking_unit_period,
    .booking_unit_owner {
        width: auto !important;
        float: none !important;
    }

    /* Messages: stack header columns */
    .message_header .col-md-4,
    .message_header .col-md-2 {
        width: 100% !important;
        float: none !important;
        padding: 2px 0 !important;
    }

    /* Invoices: horizontal scroll for the table */
    .invoices-wrapper {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch !important;
    }

    .invoice_unit,
    .invoice_unit_title {
        min-width: 600px !important;
    }

    /* Invoice filters: stack */
    .invoice_filters .col-md-3 {
        width: 100% !important;
        float: none !important;
        margin-bottom: 8px !important;
    }

    /* Profile upload image */
    .profile_upload_image_wrapper {
        width: 100% !important;
        float: none !important;
    }

    .dashbard_unit_image img {
        border-radius: var(--pml-radius) !important;
    }
}

/* ── 6. Small mobile ≤480px ── */

@media (max-width: 480px) {
    .content_wrapper_dashboard {
        padding: 0 4px !important;
    }

    .user_dashboard_panel {
        padding: 10px !important;
        border-radius: var(--pml-radius) !important;
    }

    h1.entry-title-profile {
        font-size: 18px !important;
    }
}

/* ==========================================================================
   CT-28 — Preventive photo upload message (KIM-16 complement)
   ==========================================================================
   PROBLEM (user-visible symptom):
   Before CT-28, the submit form's image uploader widget had only the two
   hardcoded helper lines from the parent theme ("Double click to select
   featured", "Drag & Drop to reorder"). There was NO mention of accepted
   file formats. iPhone owners would upload HEIC photos (default iOS format)
   and either get silent failure (the bug path fixed by CT-28 PHP filter) or
   get a raw rejection error without context, confusing them. 80%+ of PML's
   target owners use iPhone.

   ROOT CAUSE:
   WP Rentals provides no native Theme Options field to inject an
   instructional message above the upload widget. The parent template
   wprentals/templates/submit_templates/property_images.php:78-112 renders
   the Plupload dropzone with no hook or filter around it.

   WHY CSS ::before vs OTHER APPROACHES:
   Per ADR-0005 (child theme last resort) we evaluated:
     - Theme Options native field: does not exist (verified S20 audit).
     - Override the parent template: template-level override adds
       maintenance burden on every theme update — overkill for one text line.
     - JS injection from a child theme script: extra file, extra enqueue,
       traducible but overhead. The message is English-first and matches the
       audience (80%+ US/Canada); Polylang translation not critical here.
     - PHP hook: no suitable action runs at the right position within
       property_images.php.
   CSS ::before on the existing .rh_drag_and_drop_wrapper is zero-JS,
   zero-PHP, scoped to the submit page context, and self-documenting.

   HOW IT WORKS:
   The parent theme renders the Plupload machinery inside #new_post2 →
   #upload-container → #aaiu-upload-container → #drag-and-drop (which has
   the .rh_drag_and_drop_wrapper class). The drop zone internally uses an
   absolutely-positioned cloud icon (.drag-drop-msg > .fa-cloud-upload-alt)
   that overlaps anything placed inside the wrapper. Initial attempt to
   place ::before on .rh_drag_and_drop_wrapper caused the icon to overlap
   the guidance text (tested S20 — screenshot confirmed).
   Fix: attach ::before to #upload-container instead, which sits ABOVE the
   drop zone in the DOM but still inside #new_post2. This renders the text
   as a block before any Plupload internals, with no overlap. Scoped to
   #new_post2 to avoid affecting other Plupload reuse points (admin media
   library, user avatar, etc.).

   MAINTENANCE / REMOVAL CONDITIONS:
   - If WP Rentals adds a native "Submit Form Instructions" field, migrate
     the text there and remove this rule.
   - If we ever install server-side HEIC conversion, soften the message
     (remove iPhone-specific advice).
   - If the bilingual requirement expands, replace with a JS/PHP approach
     that respects Polylang language switching. */
#new_post2 #upload-container::before {
    /* S25: refactored hardcoded hex + 'Jost' to PML tokens.
       Visual unchanged (#FBF7F5 → off-white, #E45E4C → coral, #333 → text body, Jost → font-body). */
    content: "Accepted formats: JPG, PNG, WebP  ·  Max 25 photos  ·  iPhone users: export as JPG from the Photos app, or enable Settings → Camera → Formats → Most Compatible before taking photos.";
    display: block;
    padding: 12px 16px;
    margin-bottom: 16px;
    background: var(--pml-off-white);
    border-left: 3px solid var(--pml-coral);
    border-radius: var(--pml-radius-sm);
    font-family: var(--pml-font-body);
    font-size: var(--pml-fs-label);
    line-height: var(--pml-lh-body);
    color: var(--pml-text-body);
    text-align: left;
    white-space: normal;
}

@media (max-width: 480px) {
    #new_post2 #upload-container::before {
        font-size: 12px;
        padding: 10px 12px;
    }
}

/* ==========================================================================
   CT-28b — Error notice for HEIC rejections (js/pml-upload-validator.js)
   ==========================================================================
   PROBLEM:
   The client-side validator (js/pml-upload-validator.js) removes HEIC
   files from Plupload's queue BEFORE they upload. It needs a visible UI
   notice to tell the user why the file was rejected — otherwise users
   see the preview flash then disappear with no explanation (that's the
   exact bug behavior we discovered when only the PHP filter was active,
   because the parent theme's AJAX handler swallows $file['error']).

   ROOT CAUSE:
   Parent theme's native error handler (ajax-upload.js:140-148) only
   renders errors for server-side Plupload codes (like -601 "File
   extension error"). For our custom client-side rejection we inject
   a div.pml-upload-heic-error into the same container Plupload uses
   (#aaiu-upload-imagelist), which means styling it alongside the
   native error pattern is a natural fit.

   WHY THIS STYLING:
   - Coral border-left matches CT-28's preventive ::before message and
     the PML brand system — same visual language = reinforces the
     "formatos aceptados" communication.
   - Red-tinted background signals rejection without being alarming.
   - Auto-dismissed after 15s by JS, but the CSS keeps it prominent
     while visible. */
.pml-upload-heic-error {
    /* S25: was Material Google red hex (#fdecea/#d93025/#5f1711). Replaced
       with --pml-error-* tokens — universal recognition + WCAG AA + token-aligned. */
    display: block;
    padding: 12px 16px;
    margin-bottom: 12px;
    background: var(--pml-error-bg);
    border-left: 3px solid var(--pml-error-border);
    border-radius: var(--pml-radius-sm);
    font-family: var(--pml-font-body);
    font-size: var(--pml-fs-label);
    line-height: var(--pml-lh-body);
    color: var(--pml-error-text);
    text-align: left;
    animation: pmlUploadErrorIn 0.2s ease-out;
}

@keyframes pmlUploadErrorIn {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ==========================================================================
   CT-29 — Hide empty duplicate map on single property pages (parent bug)
   ==========================================================================
   PROBLEM (user-visible symptom):
   On single property pages, two <div id="google_map_on_list"> elements
   render into the DOM:
     1. An EMPTY one with `data-cur_long=""` (no longitude value), rendered
        standalone with no title/wrapper → Leaflet fails to initialize,
        leaves a zero-height empty div somewhere in the page flow.
     2. The CORRECT one inside `.property_page_container.google_map_type1
        > .google_map_on_list_wrapper`, with valid lat/long/post_id data
        and the `leaflet-container` class added after Leaflet bootstraps,
        rendering the actual interactive map.
   Both carry the same `id="google_map_on_list"` — invalid HTML (IDs must
   be unique) and a risk vector for any JS that queries by ID
   (document.getElementById picks only the first match, which is the
   broken empty one). Reported by Chuy 2026-04-20 on listing "Casa de
   Chuy" (property ID 42648).

   ROOT CAUSE (parent theme bug, same family as CT-27):
   WP Rentals v3.16.2 has two template paths emitting the map div in
   certain `Listing Page Design Type` + Layout Manager combinations.
   One path fires with a fully-populated data attribute set, the other
   fires before the data is ready (or under a layout state where the
   data hasn't been passed through), producing the empty duplicate.
   The pattern mirrors CT-27's duplicate video rendering — same Layout
   Manager vs legacy template conflict. Confirmed parent-side bug, not
   child theme (our CT-2 masonry override doesn't touch map markup).

   WHY CSS vs TEMPLATE OVERRIDE:
   Override of the template introducing the dup would require locating
   both emission paths (still not fully mapped) and keeping the override
   in sync with WP Rentals updates. CSS attribute match on the empty
   `data-cur_long` is lower-risk: only hides the broken one, leaves the
   working one untouched, survives parent updates transparently.

   SELECTOR LOGIC:
   Match `#google_map_on_list` with an EMPTY `data-cur_long` attribute.
   The working map always has a valid longitude string in that attribute,
   so this selector cannot falsely match a valid map. The `.single-
   estate_property` scope restricts the rule to single property pages,
   so the same ID used in half-map views (search results, properties
   list) is never affected.

   EDGE CASES HANDLED:
   - Valid map only (property with real lat/long set): broken dup still
     emits per the parent bug → CSS hides the empty, user sees the
     working one → normal UX.
   - Property without location set (both maps would be empty): rare in
     real listings; the Layout Manager normally skips the section when
     no location is set. If it does happen, both divs get hidden — no
     regression (user sees no map either way).
   - Parent theme fixes the dup: selector stops matching (nothing to
     hide) → rule becomes a no-op, safe to leave until the audit.

   BROWSER SUPPORT:
   `[attr=""]` attribute selector is universally supported (all browsers
   since CSS 2.1, 2001).

   MAINTENANCE / REMOVAL CONDITIONS:
   - If WP Rentals publishes a version where only one map div emits,
     audit: open a listing with location set and inspect DOM for
     `#google_map_on_list` count. If 1, remove this rule.
   - Related: CT-27 (duplicate video) shares the same Layout Manager
     pattern. Retiring either without the other may leave half the
     cleanup pending.
   - If we migrate the property page layout to Elementor Pro Theme
     Builder, this rule may become obsolete (custom markup path). */
.single-estate_property #google_map_on_list[data-cur_long=""] {
    display: none !important;
}

/* ==========================================================================
   .pml-btn — generic button (S26)
   --------------------------------------------------------------------------
   Reusable button class for use outside the dashboard scope. Dashboard
   buttons (.is_dashboard_page .wpestate_vc_button etc., line ~2920) keep
   their own selector. This class is what the styleguide showcases and what
   Elementor HTML widgets should use for primary actions.

   Variants: primary (coral), secondary (outline), disabled.
   ========================================================================== */

.pml-btn {
    display: inline-block;
    font-family: var(--pml-font-accent);
    font-size: var(--pml-fs-button);
    font-weight: var(--pml-fw-semibold);
    letter-spacing: var(--pml-ls-wide);
    line-height: var(--pml-lh-tight-body);
    padding: 12px 24px;
    border: 1px solid transparent;
    border-radius: var(--pml-radius-lg);
    cursor: pointer;
    text-decoration: none;
    transition: background 0.18s ease, color 0.18s ease, border-color 0.18s ease, transform 0.06s ease;
    user-select: none;
}

.pml-btn:focus-visible {
    outline: 2px solid var(--pml-coral); /* CT-56 flat focus (was glow ring) */
    outline-offset: 2px;
    box-shadow: none;
}

.pml-btn:active {
    transform: translateY(1px);
}

.pml-btn--primary {
    background: var(--pml-action);
    color: var(--pml-action-text);
}

.pml-btn--primary:hover {
    background: var(--pml-action-hover);
    color: var(--pml-action-text);
}

.pml-btn--secondary {
    background: transparent;
    color: var(--pml-text-body);
    border-color: var(--pml-border);
}

.pml-btn--secondary:hover {
    background: var(--pml-bg-hover);
    border-color: var(--pml-text-tertiary);
    color: var(--pml-text-body);
}

.pml-btn[disabled],
.pml-btn--disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

/* ==========================================================================
   /pml-styleguide/ page layout (S26 — CT-34)
   --------------------------------------------------------------------------
   Layout for the component reference page. Sections render with a label
   on top (small uppercase) and a content area showing the component +
   a <details> block exposing the markup for copy-paste into Elementor.

   Hidden via robots meta tag in the page template. Not in nav.
   ========================================================================== */

.pml-styleguide {
    max-width: 960px;
    margin: 0 auto;
    padding: 48px 24px 96px;
    background: var(--pml-bg-page);
    font-family: var(--pml-font-body);
    color: var(--pml-text-body);
}

.pml-styleguide h1 {
    font-family: var(--pml-font-heading);
    font-size: var(--pml-fs-display);
    font-weight: var(--pml-fw-bold);
    line-height: var(--pml-lh-display);
    letter-spacing: var(--pml-ls-tight);
    color: var(--pml-text-heading);
    margin: 0 0 8px;
}

.pml-styleguide__intro {
    font-size: var(--pml-fs-body-lg);
    color: var(--pml-text-secondary);
    margin: 0 0 48px;
    line-height: var(--pml-lh-body);
}

.pml-styleguide__group {
    margin-bottom: 48px;
    padding: 32px;
    background: var(--pml-bg-card);
    border: 1px solid var(--pml-border);
    border-radius: var(--pml-radius-card);
    box-shadow: var(--pml-shadow-subtle);
}

.pml-styleguide__group-label {
    font-size: var(--pml-fs-overline);
    font-weight: var(--pml-fw-semibold);
    letter-spacing: var(--pml-ls-wider);
    text-transform: uppercase;
    color: var(--pml-text-tertiary);
    margin: 0 0 12px;
}

.pml-styleguide__group-title {
    font-family: var(--pml-font-heading);
    font-size: var(--pml-fs-h2);
    font-weight: var(--pml-fw-semibold);
    line-height: var(--pml-lh-heading-h2);
    letter-spacing: var(--pml-ls-tight-soft);
    color: var(--pml-text-heading);
    margin: 0 0 24px;
}

.pml-styleguide__item {
    padding: 20px 0;
    border-bottom: 1px solid var(--pml-border);
}

.pml-styleguide__item:last-child {
    border-bottom: none;
}

.pml-styleguide__item-name {
    font-size: var(--pml-fs-label);
    font-weight: var(--pml-fw-medium);
    color: var(--pml-text-secondary);
    margin: 0 0 12px;
}

.pml-styleguide__demo {
    padding: 16px 0;
}

.pml-styleguide__demo > * + * {
    margin-top: 12px;
}

.pml-styleguide__code {
    margin-top: 12px;
    background: var(--pml-bg-page);
    border: 1px solid var(--pml-border);
    border-radius: var(--pml-radius);
    padding: 0;
    overflow: hidden;
}

.pml-styleguide__code summary {
    cursor: pointer;
    padding: 10px 14px;
    font-size: var(--pml-fs-helper);
    font-weight: var(--pml-fw-medium);
    color: var(--pml-text-secondary);
    user-select: none;
}

.pml-styleguide__code summary:hover {
    color: var(--pml-action-hover);
}

.pml-styleguide__code pre {
    margin: 0;
    padding: 14px 16px;
    background: var(--pml-black);
    color: var(--pml-white);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: var(--pml-fs-helper);
    line-height: var(--pml-lh-body);
    overflow-x: auto;
    white-space: pre;
    border-radius: 0;
}

/* Specs panel — design tokens en valores explícitos para configurar
   widgets nativos de Elementor (Button, Form, Heading) sin inspeccionar
   CSS. Renderea como definition list dt/dd en grid 2 columnas. */
.pml-styleguide__specs {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 4px 16px;
    margin-top: 12px;
    padding: 12px 14px;
    background: var(--pml-bg-page);
    border-left: 3px solid var(--pml-action);
    border-radius: var(--pml-radius);
    font-size: var(--pml-fs-helper);
    line-height: var(--pml-lh-tight-body);
}

.pml-styleguide__specs dt {
    font-weight: var(--pml-fw-semibold);
    color: var(--pml-text-secondary);
    margin: 0;
}

.pml-styleguide__specs dd {
    margin: 0;
    color: var(--pml-text-body);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    word-break: break-word;
}

.pml-styleguide__form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}

@media (max-width: 640px) {
    .pml-styleguide__form-row {
        grid-template-columns: 1fr;
    }

    .pml-styleguide {
        padding: 32px 16px 64px;
    }

    .pml-styleguide__group {
        padding: 20px;
    }
}
