/*
 * Virgo CMS - Hotspot Image module styles.
 *
 * Clickable points over a single image. The stage holds one main image and N
 * percentage-positioned pins; each pin dispatches an action on click (popup /
 * menu_link / url / image / video). The image is shown at its ORIGINAL aspect
 * ratio (uncropped): the stage pins the image height (--hi-height) and derives
 * its width from the image's own ratio (--hi-aspect), so the stage is exactly
 * as wide as the image — no letterbox gap. Pins (positioned by percentage on
 * the stage) therefore always land on the image, and stay correct when the
 * height changes. Pin positions are applied at runtime by the engine
 * (element.style.left/top) from data-x / data-y.
 *
 * Runtime values come from CSS custom properties set inline by the renderer
 * (the only sanctioned inline-style use): --hi-pin-size, --hi-height,
 * --hi-aspect, --hi-radius, --hi-popup-max.
 *
 * Colors/radii/shadows draw from the design-system tokens defined in
 * template.css :root (--primary-color, --text-color, --text-ink, --bg-color,
 * --border-color, --shadow-*). No literal brand colors are authored here.
 *
 * This stylesheet also covers the ADMIN editor (admin/modules.php edit page)
 * because the editor reuses the same .hotspot-pin / stage vocabulary on the
 * .hotspot-editor canvas. Admin-only rules are scoped under .hotspot-editor.
 */

/* ============================================
   FRONTEND ROOT + STAGE
   ============================================ */

.hotspot-image {
    --hi-pin-size: 32px;
    --hi-height: 500px;
    --hi-aspect: 1 / 1;
    --hi-radius: var(--radius-md, 8px);
    --hi-popup-max: 360px;
    /* Pin opacity (admin "Nokta Opaklığı", 30–100% → 0.3–1.0). Scales every pin's
       own opacity; the pulse halo and tooltip keep their own opacity behavior. */
    --hi-pin-opacity: 1;
    /* Pin + pulse-halo share one color source. Default is the primary token; the
       engine overrides --hi-pin-glow per pin when an admin pin_color is set, so
       the halo always matches the pin fill. */
    --hi-pin-glow: var(--primary-color, var(--bs-primary, #0d6efd));
    /* Glyph (foreground) color for the pin's numeral / icon. Default is the page
       surface token so the glyph reads against the pin fill; the engine overrides
       --hi-pin-glyph per pin when an admin icon_color / number_color is set. */
    --hi-pin-glyph: var(--bg-color, #ffffff);

    box-sizing: border-box;
    width: 100%;
}

.hotspot-image *,
.hotspot-image *::before,
.hotspot-image *::after {
    box-sizing: border-box;
}

/* The stage keeps the image's original aspect ratio (uncropped) at every
   viewport. The image height is treated as a MAXIMUM (--hi-height): on wide
   containers the stage grows up to that height and derives its width from the
   ratio; on narrow containers (mobile) max-width:100% caps the stage width and
   the height scales down proportionally to keep the ratio, never cropping and
   never forcing the desktop height. The result: pins positioned by percentage
   always land on the image, never on a gap, and stay put as the stage shrinks. */
.hotspot-image__stage {
    position: relative;
    height: auto;
    max-height: var(--hi-height);
    width: auto;
    max-width: 100%;
    aspect-ratio: var(--hi-aspect);
    overflow: visible;
    border-radius: var(--hi-radius);
    background: var(--bg-color, #ffffff);
}

/* Inner frame: keeps corners clean. Pins live OUTSIDE this frame (positioned on
   the stage), so a pin placed at an edge is never clipped. */
.hotspot-image__stage-frame {
    position: absolute;
    inset: 0;
    overflow: hidden;
    border-radius: inherit;
}

/* The image fills the stage exactly (the stage already matches its ratio, so
   no cropping occurs). */
.hotspot-image__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    -webkit-user-select: none;
    user-select: none;
    -webkit-user-drag: none;
}

/* ============================================
   PINS
   ============================================ */

.hotspot-image__pin {
    position: absolute;
    transform: translate(-50%, -50%);
    width: var(--hi-pin-size);
    height: var(--hi-pin-size);
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--primary-color, var(--bs-primary, #0d6efd));
    color: var(--hi-pin-glyph, var(--bg-color, #ffffff));
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: calc(var(--hi-pin-size) * 0.5);
    font-weight: 700;
    line-height: 1;
    box-shadow: var(--shadow, 0 4px 8px rgba(26, 36, 33, 0.35));
    transition: box-shadow 0.18s ease, opacity 0.18s ease;
    opacity: var(--hi-pin-opacity, 1);
    z-index: 2;
}

/* Hover and focus do NOT scale the pin. A hover-scale transform was the
   flicker source: the pin enlarges, the cursor (still at the same screen
   point) slips off the now-shifted hit-box edge, hover drops, the pin snaps
   back, the cursor is over the pin again, hover re-enters — repeat. The
   non-scaling transform stays identical on hover, so the hit-box never moves
   relative to the cursor; hover state is stable. The only hover feedback is
   a stronger shadow + full opacity (so a dimmed pin still reads clearly when
   the user is about to click it). */
.hotspot-image__pin:hover,
.hotspot-image__pin:focus-visible {
    box-shadow: var(--shadow-lg, 0 12px 32px rgba(26, 36, 33, 0.45));
    opacity: 1;
    outline: none;
}

/* Icon variant: a slightly larger glyph so common icons read clearly. Scales
   with the pin box (--hi-pin-size) so the icon grows/shrinks with the pin. */
.hotspot-image__pin--icon {
    font-size: calc(var(--hi-pin-size) * 0.55) !important;
}

/* The numeral span (number variant). pointer-events:none so the digit never
   steals the click from the button. font-size is pinned to --hi-pin-size directly
   (mirroring the icon variant) instead of relying on inheritance, so the digit
   scales with the pin box when the pin size setting changes. */
.hotspot-image__pin-num {
    pointer-events: none;
    font-size: calc(var(--hi-pin-size) * 0.5) !important;
}

/* Pulse halo (enabled via .hotspot-image--pulse on the root). The halo expands
   via box-shadow spread, NOT transform: scale. A transform on ::before combined
   with the pin's hover-scale transition forces continuous compositing/repaint
   (visible flicker), and a scaled ::before also makes the perceived pin much
   larger than its hit box (off-center clicks miss the button). box-shadow keeps
   the halo purely visual — the clickable area stays the pin's own box — and adds
   no transform layer, so there is no flicker. The halo color tracks the pin
   color via --hi-pin-glow (set by the engine when a per-pin color is present),
   falling back to the primary token. */
/* z-index is 0 (NOT -1). The pin carries a transform (the centering
   translate), which establishes a new stacking context on the button itself.
   With z-index:-1 the ::before would be painted BEHIND the pin's own opaque
   background — and since the pin's box exactly covers the ::before, the halo
   box-shadow spread (the only part that extends past the pin) renders behind
   the stage too, so the pulse visually vanishes. z-index:0 keeps the halo
   below the pin content (the number/icon) but above the pin's own background
   layer, so the expanding spread stays visible while pulsing. */
.hotspot-image--pulse .hotspot-image__pin::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    box-shadow: 0 0 0 0 var(--hi-pin-glow);
    animation: hotspot-pulse 2s ease-out infinite;
    pointer-events: none;
    z-index: 0;
}

@keyframes hotspot-pulse {
    0%   { box-shadow: 0 0 0 0   var(--hi-pin-glow);                   opacity: 0.6; }
    70%  { box-shadow: 0 0 0 calc(var(--hi-pin-size) * 0.5) var(--hi-pin-glow); opacity: 0; }
    100% { box-shadow: 0 0 0 calc(var(--hi-pin-size) * 0.5) var(--hi-pin-glow); opacity: 0; }
}

/* ============================================
   TOOLTIP (pin hover label)
   ============================================ */

/* Tooltip surface = the page surface token (--bg-color) and label = the ink
   token (--text-ink). These two tokens are theme-aware opposites in
   template.css :root (light: white bg / dark ink; dark: dark bg / light ink),
   so the tooltip reads correctly in BOTH themes. The previous mapping swapped
   them (--text-ink on background), which inverted the colors. */
.hotspot-image__tooltip {
    position: absolute;
    left: 50%;
    background: var(--bg-color, rgba(0, 0, 0, 0.85));
    color: var(--text-ink, #ffffff);
    padding: var(--radius-sm, 4px) var(--radius-sm, 8px);
    border-radius: var(--radius-sm, 4px);
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.15s ease;
    z-index: 3;
}

.hotspot-image--tooltip-top .hotspot-image__tooltip    { bottom: calc(100% + 8px);  transform: translateX(-50%); }
.hotspot-image--tooltip-bottom .hotspot-image__tooltip { top: calc(100% + 8px);     transform: translateX(-50%); }
.hotspot-image--tooltip-left .hotspot-image__tooltip   { right: calc(100% + 8px);   top: 50%; transform: translateY(-50%); }
.hotspot-image--tooltip-right .hotspot-image__tooltip  { left: calc(100% + 8px);    top: 50%; transform: translateY(-50%); }

.hotspot-image:not(.hotspot-image--tooltip) .hotspot-image__tooltip {
    display: none;
}

.hotspot-image__pin:hover .hotspot-image__tooltip,
.hotspot-image__pin:focus-visible .hotspot-image__tooltip {
    opacity: 1;
}

/* ============================================
   POPUP MODAL (SweetAlert2 — Google Maps InfoWindow clone)
   ============================================ */

/* The popup uses this module's OWN .hotspot-image-info-* vocabulary and does
   NOT depend on google-maps.css (module CSS/JS independence rule). The popup
   markup mirrors the Google Maps InfoWindow so both modules render the same
   popup, but the styles live here under self-named classes.
   SweetAlert2 injects its own padding on .swal2-popup; reset it so the padding
   lives on the inner .hotspot-image-info-window box (matching the maps InfoWindow
   layout where the close button anchors to the padded box's corner). The card
   chrome (border-radius + box-shadow) mirrors the maps InfoWindow / Leaflet
   popup card so both popups look identical.
   Margin is zeroed here as a static default so the engine's runtime top/left
   (inline-CSS exception 1) anchor the popup to the clicked pin without fighting
   SweetAlert2's flex-centering margins; top/left/transform are applied by JS at
   open time because they depend on the live pin coordinates. */
.hotspot-image-modal__popup {
    padding: 0 !important;
    margin: 0;
    text-align: initial;
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
}

/* SweetAlert2 centers its content (.swal2-popup text-align:center + grid) and
   wraps the inner HTML in .swal2-html-container which carries its own padding
   (--swal2-html-container-padding: 1em 1.6em 0.3em). The maps InfoWindow has no
   such wrapper — content padding comes only from .hotspot-image-info-window
   (12px 14px). Zero out the SweetAlert2 wrapper's padding+margin so the single
   padded box matches the maps layout exactly, and force start alignment so
   title, image+desc row and the standalone link sit flush to the inline-start
   edge like the maps popup. */
.hotspot-image-modal .swal2-html-container {
    text-align: start;
    margin: 0;
    padding: 0;
}

/* ============================================
   POPUP INFO WINDOW CONTENT (self-contained, no google-maps.css dependency)
   ============================================ */

/* Popup content mirrors the Google Maps InfoWindow exactly (min/max width +
   padding), so the rendered box is the same size as the maps popup.
   position: relative anchors the custom close button (.hotspot-image-info-close-btn). */
.hotspot-image-info-window {
    position: relative;
    font-family: inherit !important;
    min-width: 180px;
    max-width: 300px;
    padding: 12px 14px;
    font-size: 0.875rem !important;
    text-align: start;
}

/* Popup content row: image + description side by side */
.hotspot-image-info-content-row {
    display: flex;
    flex-direction: row;
    align-items: flex-start;
    gap: 8px;
    margin-top: 6px;
}

/* RTL: image left, text right */
[dir="rtl"] .hotspot-image-info-content-row {
    flex-direction: row-reverse;
}

.hotspot-image-info-image {
    width: 100px;
    border-radius: 6px;
    flex-shrink: 0;
}

.hotspot-image-info-text {
    min-width: 0;
    flex: 1;
}

.hotspot-image-info-title {
    font-weight: 700;
    font-size: 1rem !important;
    margin-bottom: 4px;
    color: #1a1a2e;
    line-height: 1.3;
}

.hotspot-image-info-desc {
    font-size: 0.8125rem !important;
    color: #4a4a5a;
    margin-bottom: 6px;
    line-height: 1.4;
}

.hotspot-image-info-link {
    font-size: 1rem !important;
    font-weight: 600;
    color: var(--primary-color);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    outline: none;
    justify-content: flex-start;
}

.hotspot-image-info-link:hover {
    text-decoration: underline;
    color: #155046;
}

.hotspot-image-info-link:hover sup {
    opacity: 1;
}

/* ============================================
   POPUP CLOSE BUTTON (module-consistent, no google-maps.css dependency)
   ============================================ */

/* A single close button rendered inside the popup content. Sized and positioned
   identically to the maps InfoWindow / Leaflet popup close control so all three
   modules show the exact same control in the exact same place. Anchored to the
   inline-end (right in LTR) top corner of the padded .hotspot-image-info-window
   box. */
.hotspot-image-info-close-btn {
    position: absolute;
    top: 5px;
    inset-inline-end: 5px;
    width: 11px;
    height: 11px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    border-radius: 2px;
    background-color: transparent;
    color: #6b7280;
    cursor: pointer;
    line-height: 1;
    z-index: 5;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.hotspot-image-info-close-btn:hover {
    background-color: rgba(0, 0, 0, 0.06);
    color: #1a1a2e;
}

.hotspot-image-info-close-btn i {
    font-size: 0.5rem;
}

/* ============================================
   POPUP RESPONSIVE (small viewports)
   ============================================ */

/* Stack image + description vertically on narrow screens (matches the maps
   InfoWindow / Leaflet popup responsive behavior). */
@media (max-width: 767.98px) {
    .hotspot-image-info-content-row {
        flex-direction: column !important;
    }

    .hotspot-image-info-image {
        width: auto;
        max-width: 150px !important;
        max-height: 50px !important;
    }

    .hotspot-image-info-desc {
        font-size: 0.8rem !important;
    }

    .hotspot-image-info-title.hotspot-image-info-link {
        display: inline;
        background: none;
    }
}

/* ============================================
   POPUP DARK MODE
   ============================================ */

/* Dark mode — match the maps InfoWindow dark card (google-maps.css) and the
   Leaflet popup card (openstreet-maps.css): same #242830 background and deeper
   shadow. Overrides template.css's generic dark .swal2-popup for this popup. */
html[data-bs-theme="dark"] .hotspot-image-modal__popup {
    background-color: #242830 !important;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
}

html[data-bs-theme="dark"] .hotspot-image-info-title {
    color: #e2e2f0;
}

html[data-bs-theme="dark"] .hotspot-image-info-desc {
    color: #a0a0b8;
}

html[data-bs-theme="dark"] .hotspot-image-info-link {
    color: #2d8676;
}

html[data-bs-theme="dark"] .hotspot-image-info-link:hover {
    color: var(--primary-color);
}

html[data-bs-theme="dark"] .hotspot-image-info-close-btn {
    color: #a0a0b8;
}

html[data-bs-theme="dark"] .hotspot-image-info-close-btn:hover {
    background-color: rgba(255, 255, 255, 0.08);
    color: #e2e2f0;
}

/* ============================================
   ACCESSIBILITY — reduced motion
   ============================================ */

@media (prefers-reduced-motion: reduce) {
    .hotspot-image__pin,
    .hotspot-image__pin::before,
    .hotspot-image__tooltip {
        transition: none;
        animation: none;
    }

    .hotspot-image--pulse .hotspot-image__pin::before {
        animation: none;
        opacity: 0;
    }
}
