/*
 * Force the root font-size to the browser default (16px) on AeroIDX-rendered
 * pages only. The `components.js` widget bundle sizes its internals in `rem`,
 * so a theme that has changed the root font-size will misrender the widget.
 *
 * Selector escalation: started as plain `html` (lost to themes using `:root`),
 * then `html, :root !important` (lost to Bricks injecting inline CSS in <head>
 * AFTER our stylesheet — same specificity, later cascade wins). Settled on
 * `html[lang]` because:
 *   - specificity 0,0,1,1 beats `:root !important` (0,0,1,0) regardless of
 *     cascade order, so we win even if Bricks injects later in <head>;
 *   - WordPress sets the `lang` attribute on every <html> via `language_attributes()`
 *     in the theme's get_header(), so the selector always matches.
 *
 * This file is only enqueued on AeroIDX pages (see Widgets\WidgetLoader), so
 * the blast radius is scoped — the rest of the site is untouched.
 */
html[lang] {
    font-size: 16px !important;
}

/*
 * Full-width IDX pages: clear a fixed/sticky theme header. The offset value is
 * measured at runtime by assets/js/page-layout.js and published as
 * --aeroidx-header-offset on <body>. Defaults to 0 so this is inert when the
 * script is absent (e.g. /details/).
 *
 * HOW AN AUTHOR OVERRIDES THIS, and why the old advice here was wrong.
 *
 * This comment used to say admins could override padding-top from "the Theme
 * Integration Custom CSS box, which loads after this stylesheet". That box was
 * removed — the plugin no longer stores or outputs custom CSS — so the
 * load-order guarantee it relied on went with it. An author's rule now lives in
 * their theme or in WordPress' Additional CSS, and whether it beats this
 * declaration depends on enqueue order nobody promises.
 *
 * So point them at the value instead of the property: setting
 * --aeroidx-header-offset overrides the number this rule reads, at any
 * specificity, with no cascade race. The Appearance screen and README.md both
 * say so, and Settings\ThemePanelMarkupTest pins that they keep saying it.
 */
body.aeroidx-page {
    padding-top: var(--aeroidx-header-offset, 0px);
}

/**
 * The server-rendered listing heading, description, details and photos
 * (Seo\ListingSeoBody), emitted as light-DOM children of <listing-details>
 * (Template\ListingDetailsMarkup).
 *
 * VISIBLE, and no longer clipped. Through 1.5.0 this was a 1px clipped,
 * aria-hidden box; a GEO audit flagged that as "aria-hidden injection". The
 * block is now the page's real content until the widget takes over, and it
 * disappears by itself then: the element renders into its own shadow root and
 * has no <slot>, so its light-DOM children stop being rendered on upgrade.
 *
 * The cap exists for that one moment. UndefinedElementStyles already reserves
 * `min-height: 100vh` for the undefined element; capping the child at the same
 * 100vh keeps the pre-upgrade box at exactly the height it reserved, so the
 * upgrade adds no layout shift (anything taller would grow the box, then
 * collapse). A long description is clipped, not scrolled: it is a placeholder
 * for the widget, and the full text is in the HTML for readers that parse it.
 *
 * `:not(:defined)` scopes the cap to before the upgrade. Without scripting the
 * element is never upgraded, so there the cap is lifted and the visitor reads
 * the whole block.
 */
listing-details:not(:defined) > .aeroidx-listing-seo {
    max-height: 100vh;
    overflow: hidden;
}

/**
 * Transparent while the widget is on its way, when scripting is on.
 *
 * WHY. Visible, the block flashed: plain text and two photos showed until the
 * bundle booted, then the widget replaced them with a different layout, which
 * read as the page jumping. Tested in Local without throttling and judged
 * annoying. This is the platform's own answer to that (`:not(:defined)` exists
 * for exactly this flash of undefined custom elements).
 *
 * WHY THIS IS NOT THE OLD HIDING. Nothing in the HTML hides the block any more:
 * no aria-hidden, no clip. A reader of the raw response, which is what the GEO
 * audit and most AI crawlers are, sees ordinary visible content. Only a browser
 * that is about to draw the same content through the widget holds it back, and
 * only until the element is defined. opacity, not visibility or display, so the
 * block keeps its box (the reserved 100vh does not change) and stays in the
 * accessibility tree.
 *
 * THE ANIMATION IS THE SAFETY NET. If the bundle never boots (blocked, failed,
 * a CDN outage), the element stays undefined and the block would stay
 * invisible. After 3s it snaps to opaque, so the visitor gets the listing as
 * plain content instead of an empty page. 0s duration: no motion, so nothing
 * for prefers-reduced-motion to object to.
 *
 * Without scripting the media query does not match and the block is shown at
 * once, uncapped by the rule below.
 */
@media (scripting: enabled) {
    listing-details:not(:defined) > .aeroidx-listing-seo {
        opacity: 0;
        animation: aeroidx-listing-seo-reveal 0s 3s forwards;
    }
}

@keyframes aeroidx-listing-seo-reveal {
    to {
        opacity: 1;
    }
}

@media (scripting: none) {
    listing-details > .aeroidx-listing-seo {
        max-height: none;
        overflow: visible;
    }
}
