/* =============================================================================
   Casa Graziella — Virtual Tour 360°
   Added in v2.7.0. Supersedes the "v1.8.0 — Virtual Tour Page" block that
   used to live in style.css (moved here wholesale, see HISTORY v2.7.0).

   WHY THIS FILE EXISTS — CSS LOAD ORDER
   -------------------------------------
   The vendor stylesheet lives OUTSIDE the theme, at
       wp-content/uploads/virtual-tours/lib/pannellum.css
   and is enqueued at wp_enqueue_scripts priority 20, while the theme's own
   style.css goes out at priority 10. Overriding a vendor rule from style.css
   would therefore lose on source order at equal specificity.

   This file is enqueued with ['pannellum'] as a dependency, so WordPress
   always emits it AFTER the vendor stylesheet. That is what lets every rule
   below win with plain, honest specificity — there is not one !important or
   padded selector in here, and there should never need to be.

   NEVER EDIT uploads/virtual-tours/lib/pannellum.css. It is vendor code and
   gets overwritten whenever Pannellum is updated, silently taking any local
   edit with it. All Pannellum styling belongs in this file.

   Loaded on both surfaces that render a viewer (functions.php):
     - page-virtual-tour.php  — hero viewer + card grid + modal
     - single-apartment.php   — #cg-pannellum-viewer (apartment tours)
   The hotspot/tooltip rules matter on both; the hero/card/modal rules are
   inert on apartment singles, which is cheaper than maintaining two files.
   ============================================================================= */

/* Quick bar geometry, mirrored from css/quick-bar.css: 56px .cg-qbar__link
   min-height + its 1px top border + the home-indicator inset. Kept as a
   variable so the hero cap below reads as intent rather than arithmetic. */
:root {
    --cg-qbar-total: calc(57px + env(safe-area-inset-bottom, 0px));

    /* --- Panorama overlay palette — deliberately absolute, not themed -------
       These colours sit on top of PHOTOGRAPHS, not on the page background, so
       they must stay dark-scrim/light-ink in every palette.

       They cannot be expressed with the --cg-* names, because those invert.
       The Customizer emits an inline :root block that overrides style.css, and
       on the live light palette it resolves --cg-black to #f9f6f1 and
       --cg-cream to #2a2420 — i.e. "black" is near-white and "cream" is near-
       black. Trusting those names is what made the old
       `.pnlm-hotspot-base span` rule paint cream text on a cream background
       (removed from style.css in v2.7.0); the same mistake here would make
       every hotspot label invisible again.

       --cg-white is used as-is below because it is #ffffff in both palettes.
       ---------------------------------------------------------------------- */
    --cg-tour-ink:      #2a2420;              /* glyph on a gold hotspot */
    --cg-tour-scrim:    rgba(10, 9, 8, 0.88); /* bubble over a photo */
    --cg-tour-on-scrim: #f5f0e8;              /* text on that scrim */
}

/* =============================================================================
   1. Hero viewer — the first tour, live and interactive on page load
   ============================================================================= */

/* Full-bleed: rendered as its own section OUTSIDE .container in the template. */
.cg-tour-hero {
    position: relative;
    width: 100%;
    background: var(--cg-black);
    border-top: 1px solid var(--cg-border);
    border-bottom: 1px solid var(--cg-border);
}

/* Explicit height, never a percentage: Pannellum measures its container on
   init and a 0-height container yields a blank canvas with no error. */
.cg-tour-hero__viewer {
    width: 100%;
    height: 70vh;        /* fallback for browsers without dvh */
    height: 70dvh;
    min-height: 320px;
    max-height: 820px;
    background: var(--cg-dark);
    display: block;
}

.cg-tour-hero__caption {
    padding: 1rem var(--cg-space-sm) 1.25rem;
    max-width: var(--cg-max-width);
    margin: 0 auto;
}

.cg-tour-hero__title {
    font-family: var(--cg-font-heading);
    font-size: clamp(1.35rem, 3vw, 1.9rem);
    color: var(--cg-text);
    margin: 0 0 0.35rem;
}

.cg-tour-hero__desc {
    font-size: 0.9rem;
    color: var(--cg-muted);
    margin: 0;
    line-height: 1.55;
    max-width: 60ch;
}

/* Shown only if the hero panorama fails to load; the viewer div is reused as
   the message container, matching the modal's error path. */
.cg-tour-hero__viewer .cg-tour-error {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    margin: 0;
}

/* --- Quick bar collision ---------------------------------------------------
   The quick bar is position:fixed over the bottom ~57px of the viewport on
   <=768px. What is actually guaranteed, and what is not:

   GUARANTEED — the controls. Pannellum's interactive chrome (zoom in/out,
   fullscreen, orientation) lives in .pnlm-controls-container at
   `top: 0; left: 4px`. It is top-anchored inside the viewer, so a bottom bar
   cannot reach it, and scrolling moves it further away rather than closer.
   Measured on iPhone 13 (390x664): controls occupy y 236-326, quick bar
   starts at y 603 — clear by 277px. This is structural, not a tuned number:
   it holds as long as the controls stay top-left, which is why §7 themes them
   without repositioning them.

   NOT GUARANTEED — the viewer's bottom edge. The hero does not start at the
   top of the viewport; the .page-hero title block sits above it, and how far
   down it pushes the viewer depends on the page title and the font. No static
   calc() can know that offset, so the height below is a sensible fit rather
   than a proof. Once the page is scrolled, the lower edge passes under the bar
   regardless. That costs panorama pixels, never a control.

   The two rules below handle the parts that can be handled: a height that
   clears the bar at rest for the current content (52dvh -> bottom at y 581 vs
   bar top 603), and a lift for the vendor UI that genuinely IS bottom-anchored.
   .pnlm-panorama-info is not hypothetical — it renders whenever a scene
   carries a `title`, which the tours do; it shows "Accoglienza" on the hero.
   -------------------------------------------------------------------------- */
@media (max-width: 768px) {
    .cg-tour-hero__viewer {
        height: 52dvh;
        max-height: calc(
            100dvh - var(--cg-header-height) - var(--cg-qbar-total) - 1rem
        );
    }

    .cg-tour-hero__viewer .pnlm-panorama-info,
    .cg-tour-hero__viewer .pnlm-compass {
        bottom: calc(4px + var(--cg-qbar-total));
    }
}

/* =============================================================================
   2. Tour grid — the remaining tours, as modal triggers
   ============================================================================= */

.cg-tour-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--cg-space-md);
}

@media (max-width: 900px) {
    .cg-tour-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 600px) {
    .cg-tour-grid {
        grid-template-columns: 1fr;
    }
}

/* =============================================================================
   3. Tour card — the WHOLE card is the control, and now looks like it
   ============================================================================= */

/* The card has always been a <button> wrapping media + body, so all of it was
   already clickable; the 360° badge just made it look as though only the badge
   was. The overlay below is a visibility fix, not a behaviour change. */
.cg-tour-card {
    font: inherit;
    padding: 0;
    cursor: pointer;
    text-align: left;
    background: transparent;
    border: 1px solid var(--cg-border);
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
}

.cg-tour-card:hover,
.cg-tour-card:focus-visible {
    border-color: var(--cg-gold);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
    outline: none;
}

/* Keyboard users get a real focus ring, not just the hover treatment. */
.cg-tour-card:focus-visible {
    outline: 2px solid var(--cg-gold);
    outline-offset: 2px;
}

.cg-tour-card__media {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--cg-dark);
    overflow: hidden;
}

.cg-tour-card__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.4s ease;
}

.cg-tour-card:hover .cg-tour-card__media img,
.cg-tour-card:focus-visible .cg-tour-card__media img {
    transform: scale(1.04);
}

.cg-tour-card__badge {
    position: absolute;
    bottom: 8px;
    right: 8px;
    background: transparent;
    border: 1px solid var(--cg-gold);
    color: var(--cg-gold);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    padding: 2px 6px;
    border-radius: 3px;
    pointer-events: none;
    z-index: 2;
}

/* --- Hover / focus overlay with the "Guarda in 360°" label ----------------- */
.cg-tour-card__overlay {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(10, 9, 8, 0.55);
    opacity: 0;
    transition: opacity 0.25s ease;
    /* The <button> ancestor owns the click; the overlay must never intercept
       it, nor appear in the a11y tree (the button carries its own label). */
    pointer-events: none;
    z-index: 1;
}

.cg-tour-card:hover .cg-tour-card__overlay,
.cg-tour-card:focus-visible .cg-tour-card__overlay {
    opacity: 1;
}

.cg-tour-card__overlay-label {
    font-family: var(--cg-font-body);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    /* gold-lt, not gold: on the dark scrim it clears 4.5:1 in both palettes,
       where --cg-gold (#a07840 on the live light palette) only reaches ~4.0. */
    color: var(--cg-gold-lt);
    background: rgba(10, 9, 8, 0.6);
    border: 1px solid var(--cg-gold-lt);
    border-radius: 4px;
    padding: 0.55rem 1.1rem;
    transform: translateY(6px);
    transition: transform 0.25s ease;
}

.cg-tour-card:hover .cg-tour-card__overlay-label,
.cg-tour-card:focus-visible .cg-tour-card__overlay-label {
    transform: none;
}

/* Touch devices never fire :hover, so a hover-only affordance is invisible to
   exactly the visitors who most need it. Pin the label over a gradient and
   leave it permanently visible instead. */
@media (hover: none) {
    .cg-tour-card__overlay {
        opacity: 1;
        align-items: flex-end;
        background: linear-gradient(
            to top,
            rgba(10, 9, 8, 0.8) 0%,
            rgba(10, 9, 8, 0) 60%
        );
    }

    .cg-tour-card__overlay-label {
        transform: none;
        margin-bottom: 0.85rem;
        font-size: 0.72rem;
    }

    /* The badge would collide with the pinned label at the same corner. */
    .cg-tour-card__badge {
        bottom: auto;
        top: 8px;
    }
}

.cg-tour-card__body {
    padding: 1rem 1.25rem 1.25rem;
    flex: 1 1 auto;
}

.cg-tour-card__title {
    font-family: var(--cg-font-heading);
    font-size: 1.1rem;
    color: var(--cg-text);
    margin: 0 0 0.4rem;
}

.cg-tour-card__desc {
    font-size: 0.85rem;
    color: var(--cg-muted);
    margin: 0;
    line-height: 1.5;
}

/* =============================================================================
   4. Modal — genuinely fullscreen native <dialog>
   ============================================================================= */

.cg-tour-modal {
    /* inset:0 is required alongside the explicit size: an open <dialog> is
       position:fixed with auto margins, which would otherwise centre it. */
    inset: 0;
    width: 100dvw;
    max-width: 100dvw;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: var(--cg-black);
    overflow: hidden;
    display: flex;
    flex-direction: column;

    /* Safe-area insets: notch/Dynamic Island at the top, home indicator at the
       bottom, and the left/right pair for landscape. Applied as padding on the
       dialog so the close button — absolutely positioned, i.e. offset from the
       PADDING box — lands inside the safe area automatically. */
    padding-top: env(safe-area-inset-top, 0px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
}

/* A <dialog> that is not open must stay hidden even with display:flex set
   above — display on [open] only would be the alternative, but this keeps the
   base rule readable. */
.cg-tour-modal:not([open]) {
    display: none;
}

.cg-tour-modal::backdrop {
    background: rgba(8, 7, 6, 0.95);
}

.cg-tour-modal__title {
    flex: 0 0 auto;
    font-family: var(--cg-font-heading);
    font-size: 1.1rem;
    color: var(--cg-text);
    margin: 0;
    /* Right padding clears the close button. */
    padding: 0.85rem 4rem 0.85rem 1.25rem;
    border-bottom: 1px solid var(--cg-border);
}

/* flex:1 + min-height:0 rather than a vh height — the 100vh/dvh Safari
   address-bar discrepancy never enters the calculation this way. */
.cg-tour-viewer {
    flex: 1 1 auto;
    width: 100%;
    height: auto;
    min-height: 0;
    background: var(--cg-dark);
    display: block;
}

/* --- Close button, 44x44 minimum target -----------------------------------
   z-index beats Pannellum's .pnlm-ui (1) and .pnlm-controls (2). Those cannot
   escape the viewer in any case: Pannellum sets `contain: content` on
   .pnlm-container, which makes the viewer its own stacking context.
   -------------------------------------------------------------------------- */
.cg-tour-modal__close {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 44px;
    height: 44px;
    min-width: 44px;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    /* Legible over a bright panorama, not just over the dark title bar. */
    background: rgba(10, 9, 8, 0.6);
    border: 1px solid var(--cg-border);
    border-radius: 50%;
    color: var(--cg-text);
    font-size: 1.75rem;
    line-height: 1;
    cursor: pointer;
    transition: color 0.15s, background 0.15s, border-color 0.15s;
    z-index: 3;
}

.cg-tour-modal__close:hover {
    color: var(--cg-gold);
    border-color: var(--cg-gold);
    background: rgba(10, 9, 8, 0.85);
}

.cg-tour-modal__close:focus-visible {
    outline: 2px solid var(--cg-gold);
    outline-offset: 2px;
}

.cg-tour-error {
    color: var(--cg-muted);
    text-align: center;
    padding: 2rem;
}

/* =============================================================================
   5. Pannellum scene hotspots — 44px touch target
   ============================================================================= */

/* --- Why each declaration is here ------------------------------------------
   Vendor gives .pnlm-hotspot a 26px circle, well under the 44px minimum touch
   target, with its arrow glyph supplied by a sprite background-image via the
   .pnlm-sprite class. Resizing alone is therefore not enough — the sprite
   survives and reappears mis-scaled behind the chevron, so background-image
   has to be switched off explicitly.

   box-sizing is restated because vendor sets `.pnlm-container * { box-sizing:
   content-box }`, under which 44px + the 2px border would paint as a 48px box.

   transform is deliberately NOT touched. Pannellum repositions every hotspot
   on every render frame:
       f[0] += (containerW - div.offsetWidth) / 2;
       div.style.transform = "translate(...) translateZ(9999px) rotate(...)";
   Two consequences: (a) any transform set here is overwritten ~60x/second, so
   the pulse below animates box-shadow instead; (b) the centring offset is
   recomputed from the LIVE offsetWidth, so growing the hotspot to 44px stays
   accurately centred on its yaw/pitch — the bigger target does not drift off
   the thing it points at.

   NOTE — cssClass is an EXCLUSIVE branch in pannellum.js:
       f.className = a.cssClass ? base + " " + a.cssClass
                                : base + " pnlm-hotspot pnlm-sprite pnlm-" + type;
   A hotspot that sets cssClass in its tour.json loses pnlm-hotspot,
   pnlm-sprite AND pnlm-scene in one go, and every rule in this section stops
   applying to it — silently, with no error. No tour.json uses cssClass as of
   v2.7.0 (all 8 verified: apartments/{azzurro,green,lacorte,red,terrace},
   common/{cantina,jacuzzi,reception}). Anything that starts to needs its own
   rules written here.
   -------------------------------------------------------------------------- */
.pnlm-hotspot.pnlm-scene {
    box-sizing: border-box;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background-image: none;          /* kills the inherited .pnlm-sprite arrow */
    background-color: var(--cg-gold);
    /*
     * The white ring is a box-shadow, NOT a border, and that is a correctness
     * requirement rather than a style choice — see "THE BORDER TRAP" below the
     * tooltip rules. A real border shrinks the content box, which is where an
     * absolutely positioned child takes its static position from, and that
     * shifts every tooltip off-centre by the border width.
     */
    box-shadow: 0 0 0 2px var(--cg-white),
                0 2px 8px rgba(10, 9, 8, 0.45);
}

/* Vendor's hover tint assumes the transparent sprite circle; with a solid gold
   fill it reads as a dirty smear, so replace it with a lightening of the fill. */
.pnlm-hotspot.pnlm-scene:hover {
    background-color: var(--cg-gold-lt);
}

/* Chevron. ::after positions against the hotspot, which .pnlm-hotspot-base
   already makes position:absolute. */
.pnlm-hotspot.pnlm-scene::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    box-sizing: border-box;
    width: 11px;
    height: 11px;
    border-top: 2px solid var(--cg-tour-ink);
    border-right: 2px solid var(--cg-tour-ink);
    transform: translate(-60%, -50%) rotate(45deg);
}

/* Gentle pulse — box-shadow only, for the frame-by-frame transform reason
   above, and opt-in on no-preference rather than opt-out on reduce. */
@media (prefers-reduced-motion: no-preference) {
    .pnlm-hotspot.pnlm-scene {
        animation: cg-hotspot-pulse 2.4s ease-in-out infinite;
    }

    /* The white ring is repeated in every frame: box-shadow animates as a
       whole list, so omitting it here would blink the ring out. */
    @keyframes cg-hotspot-pulse {
        0%,
        100% {
            box-shadow: 0 0 0 2px var(--cg-white),
                        0 2px 8px rgba(10, 9, 8, 0.45),
                        0 0 0 2px rgba(201, 169, 110, 0.55);
        }
        50% {
            box-shadow: 0 0 0 2px var(--cg-white),
                        0 2px 8px rgba(10, 9, 8, 0.45),
                        0 0 0 14px rgba(201, 169, 110, 0);
        }
    }

    /* Pausing on hover keeps the halo from fighting the tooltip underneath. */
    .pnlm-hotspot.pnlm-scene:hover {
        animation-play-state: paused;
    }
}

/* =============================================================================
   6. Pannellum tooltips — readable, and visible on touch
   ============================================================================= */

/* --- The padding constraint, which is not optional -------------------------
   Pannellum hard-codes the tooltip's geometry as inline styles, once, at
   hotspot creation:
       c.style.width      = c.scrollWidth - 20 + "px";
       c.style.marginLeft = -(c.scrollWidth - f.offsetWidth) / 2 + "px";
       c.style.marginTop  = -c.scrollHeight - 12 + "px";
   The `- 20` is the vendor's own `padding: 5px 10px` double-counted back out
   under content-box. Change the tooltip's HORIZONTAL PADDING here and that
   constant becomes wrong, shifting every label off-centre by the difference.
   So: font-size and line-height are safe to change (they are measured, since
   this stylesheet is in <head> long before any viewer is constructed), and
   left/right padding must stay 10px. Vertical padding is free — marginTop is
   derived from the measured scrollHeight.

   marginLeft centres the tooltip on f.offsetWidth, the hotspot's width at
   creation time — which the 44px rule above has already applied. Verified
   empirically, see HISTORY v2.7.0.
   -------------------------------------------------------------------------- */
div.pnlm-tooltip span {
    font-family: var(--cg-font-body);
    font-size: 0.95rem;              /* vendor inherits the 14-15px default */
    line-height: 1.35;
    padding: 6px 10px;               /* 10px horizontal is load-bearing */
    background-color: var(--cg-tour-scrim);
    color: var(--cg-tour-on-scrim);
    /* box-shadow, not border — see THE BORDER TRAP below. */
    box-shadow: 0 0 0 1px var(--cg-border);
}

/* --- THE BORDER TRAP -------------------------------------------------------
   Neither the hotspot nor the tooltip may carry a real `border`, and the
   reason is arithmetic rather than taste. Measured before the fix: every
   tooltip sat exactly 3px right of its hotspot's centre, on both desktop and
   iPhone emulation, identically for all hotspots.

   Pannellum centres the label with
       marginLeft = -(scrollWidth - hotspot.offsetWidth) / 2
   which is only correct if two things hold: the span's visual width equals its
   scrollWidth, and the span's static position starts at the hotspot's left
   edge. A border breaks both.

     +2px  a 2px border on the hotspot (with box-sizing: border-box) shrinks
           its content box to 40px, and the content box is where an
           absolutely positioned child takes its static position from — so the
           span starts 2px in.
     +1px  scrollWidth excludes borders, so a 1px border each side on the span
           makes it 2px wider than Pannellum believes; half of that is 1px of
           centring error.

   Rendering both rings as box-shadow is visually identical and contributes
   nothing to layout, which takes the error to 0px. Verified: worst |dx| 3px
   -> 0px, see HISTORY v2.7.0. If you ever reintroduce a border here, you will
   reintroduce the skew.
   -------------------------------------------------------------------------- */

/* Touch devices never fire :hover, so vendor's hover-only tooltip means every
   hotspot label is invisible on phones — where most guests are. Show them
   unconditionally there, including the arrow, which vendor also gates on
   :hover. visibility/opacity only: neither affects layout, so the inline
   geometry computed at creation stays valid. */
@media (hover: none) {
    div.pnlm-tooltip span {
        /*
         * `inherit`, emphatically NOT `visible`. Pannellum rewrites the
         * HOTSPOT div's own visibility on every render frame:
         *     a.div.style.visibility = <behind the camera> ? "hidden" : "visible"
         * A child set to `visible` overrides an inherited `hidden`, so
         * `visibility: visible` here would leave labels hanging over the
         * panorama for every hotspot currently behind the viewer. Inheriting
         * makes each label track its own hotspot instead.
         */
        visibility: inherit;
    }

    div.pnlm-tooltip span:after {
        content: "";
        position: absolute;
        width: 0;
        height: 0;
        border-width: 10px;
        border-style: solid;
        border-color: var(--cg-tour-scrim) transparent transparent transparent;
        bottom: -20px;
        left: -10px;
        margin: 0 50%;
    }
}

/* Match the arrow to the restyled bubble on pointer devices too. */
div.pnlm-tooltip:hover span:after {
    border-color: var(--cg-tour-scrim) transparent transparent transparent;
}

/* =============================================================================
   7. Pannellum chrome on the new surfaces
   -----------------------------------------------------------------------------
   Not a redesign: this is the same treatment style.css already applies to
   `.virtual-tour-viewer` on apartment singles, extended to the hero and the
   modal so all three viewers look alike. Without it the new surfaces show
   vendor's default white control chrome against the dark palette.

   Only the top-left control cluster is touched. It stays top-left on purpose —
   that is what keeps it clear of the fixed bottom quick bar (see §1).
   ============================================================================= */

.cg-tour-hero__viewer.pnlm-container,
.cg-tour-viewer.pnlm-container {
    background: var(--cg-dark);
    font-family: var(--cg-font-body);
}

.cg-tour-hero__viewer .pnlm-controls,
.cg-tour-viewer .pnlm-controls {
    background-color: rgba(26, 23, 20, 0.85);
    border: 1px solid var(--cg-gold);
    border-radius: 4px;
}

.cg-tour-hero__viewer .pnlm-control:hover,
.cg-tour-viewer .pnlm-control:hover {
    background-color: rgba(201, 169, 110, 0.35);
}

.cg-tour-hero__viewer .pnlm-load-box,
.cg-tour-viewer .pnlm-load-box {
    background: rgba(10, 9, 8, 0.9);
    color: var(--cg-gold-lt);
    border: 1px solid rgba(201, 169, 110, 0.3);
    border-radius: 4px;
}

.cg-tour-hero__viewer .pnlm-lbar,
.cg-tour-viewer .pnlm-lbar {
    background: rgba(201, 169, 110, 0.2);
    border: 1px solid rgba(201, 169, 110, 0.3);
}

.cg-tour-hero__viewer .pnlm-lbar-fill,
.cg-tour-viewer .pnlm-lbar-fill {
    background: var(--cg-gold);
}
