/* Hotspot size, look and theme: the single stylesheet every hotspot type shares (nav link, info,
   video, audio; the Hotspots editor and the Design preview use it too).

   Structure (built by hotspot-core.js):
     .hs-anchor          shifts the badge onto the yaw/pitch
       .hs-marker        the hotspot; scaled by size; carries the type class (.hs-info, .hs-nav ...)
         .hs-badge       the visible circle: background, border, blur, icon colour, hover
         popup/tooltip   type specific, positioned beside the badge, not part of the size

   Options arrive as CSS variables and data attributes on <html>, written by TourComponents.hotspot
   .applyTheme() (engine) or hotspotLook() (editor). Nothing here uses !important. */

:root {
  --hs-badge: 40px;
  --hs-size-mult: 1.5;
  --hs-user-scale: 1;
  --hs-opacity: 1;
  --hs-bg-opacity: 1;
  --hs-border: 0;
  --hs-blur-px: 0px;
  /* The smallest tap target a hotspot gets on screen, however small the tour scales its badge. */
  --hs-hit: 44px;
  /* The glyph box as a fraction of the badge (its outer size, so a border never shrinks the glyph). */
  --hs-glyph-ratio: 0.7;
  /* Property list badges animate for hover effects; info popups append their own width/radius. */
  --hs-transition:
    scale 0.2s ease, translate 0.2s ease, rotate 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease,
    background-color 0.2s ease, border-color 0.2s ease, outline-color 0.2s ease;
}
.mobile {
  --hs-badge: 50px;
}

.hs-anchor {
  position: relative;
  display: inline-block;
  transform: translate(calc(var(--hs-badge) / -2), calc(var(--hs-badge) / -2));
}

/* A hotspot's hover text (a link's "go to" label, an info tooltip) is drawn inside its own .hs-root, which
   is a layer of its own, so it cannot rise above the next hotspot by a z-index of its own. The hotspot that
   is showing its text, hovered or reached with the keyboard, is raised above the others instead: one more
   than the 1000 that hotspot-core.js gives the root of an open popup, so the text is not under a popup either.
   Hover-capable pointers only, like the hover effects. */
@media (hover: hover) {
  .hs-root:hover {
    z-index: 1001;
  }
}
.hs-root:has(:focus-visible) {
  z-index: 1001;
}

.hs-marker {
  position: relative;
  pointer-events: auto;
  scale: calc(var(--hs-size-mult) * var(--hs-user-scale));
  transform-origin: calc(var(--hs-badge) / 2) calc(var(--hs-badge) / 2);
  opacity: var(--hs-opacity);
}
/* The transparent hit area around the badge (a tap there activates the hotspot): 4px all round, or
   more when the tour scales the badge down. It is measured before the marker's scale is applied, so
   the 44px minimum is divided by that scale. */
.hs-marker::before {
  content: '';
  position: absolute;
  inset: min(
    -4px,
    calc((var(--hs-badge) - var(--hs-hit) / (var(--hs-size-mult) * var(--hs-user-scale))) / 2)
  );
}

.hs-badge {
  --hs-fill: var(--hs-bg-color, var(--accent));
  --hs-border-color: rgba(255, 255, 255, 0.9);
  position: relative;
  box-sizing: border-box;
  width: var(--hs-badge);
  height: var(--hs-badge);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--hs-icon-color, #ffffff);
  background-color: color-mix(in srgb, var(--hs-fill) calc(var(--hs-bg-opacity) * 100%), transparent);
  border: calc(var(--hs-border) * 2px) solid var(--hs-border-color);
  box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.2);
  transition: var(--hs-transition);
}

/* Blur only exists when it is on: blur(0px) still creates a backdrop layer per hotspot. */
[data-hs-blur='1'] .hs-badge {
  backdrop-filter: blur(var(--hs-blur-px));
  -webkit-backdrop-filter: blur(var(--hs-blur-px));
}

/* Look: modern line (light badge, accent outline and icon) */
[data-hs-look='modern'] .hs-badge {
  --hs-fill: var(--hs-bg-color, #ffffff);
  --hs-border-color: var(--accent);
  color: var(--accent);
}

/* The modern look's popup header is light, so its title and close button take the accent colour
   instead of the default white. */
[data-hs-look='modern'] .info-hotspot .info-hotspot-title {
  color: var(--accent);
}
[data-hs-look='modern'] .info-hotspot .info-hotspot-close-wrapper {
  color: var(--accent);
  background-color: color-mix(in srgb, var(--accent) 12%, transparent);
}
[data-hs-look='modern'] .info-hotspot svg.info-hotspot-close-icon {
  color: var(--accent);
}

/* Look: original (classic dark PNG badge; the icon is an <img>) */
[data-hs-look='original'] .hs-badge {
  --hs-fill: var(--hs-bg-color, rgb(103, 115, 131));
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
}
[data-hs-look='original'] .hs-badge img {
  filter: brightness(0) invert(1);
  pointer-events: none;
}

/* The glyph box: every glyph (built-in or custom) is drawn inside the same box, so they all get the
   same optical size. Glyphs are 24-grid line art (or solid) that take the badge's colour. */
.hs-glyph {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: calc(var(--hs-badge) * var(--hs-glyph-ratio));
  height: calc(var(--hs-badge) * var(--hs-glyph-ratio));
  color: inherit;
}
.hs-glyph > svg,
.hs-glyph > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* A few solid glyphs (info-circle-solid) fill the whole badge instead of sitting inside it. */
.hs-glyph--full {
  --hs-glyph-ratio: 1.25;
}
/* The modern look draws the same glyphs with a lighter line. */
[data-hs-look='modern'] .hs-glyph svg path,
[data-hs-look='modern'] .hs-glyph svg circle,
[data-hs-look='modern'] .hs-glyph svg rect {
  stroke-width: 1.5;
}

/* Hover effects. Applied to the badge, so glows and outlines follow the circle and a spin never
   rotates the popup. Hover-capable pointers only: touch devices never see a stuck hover. */
@media (hover: hover) {
  [data-hs-hover='enlarge'] .hs-marker:not(.visible):hover > .hs-badge,
  [data-hs-hover='enlarge-border'] .hs-marker:not(.visible):hover > .hs-badge,
  [data-hs-hover='enlarge-glow'] .hs-marker:not(.visible):hover > .hs-badge {
    scale: 1.15;
  }
  [data-hs-hover='glow'] .hs-marker:not(.visible):hover > .hs-badge,
  [data-hs-hover='enlarge-glow'] .hs-marker:not(.visible):hover > .hs-badge,
  [data-hs-hover='pulse'] .hs-marker:not(.visible):hover > .hs-badge {
    box-shadow: 0 0 12px 2px var(--accent, rgba(255, 255, 255, 0.8));
  }
  [data-hs-hover='border'] .hs-marker:not(.visible):hover > .hs-badge,
  [data-hs-hover='enlarge-border'] .hs-marker:not(.visible):hover > .hs-badge {
    outline: 2px solid var(--accent, rgba(255, 255, 255, 0.8));
  }
  [data-hs-hover='float'] .hs-marker:not(.visible):hover > .hs-badge {
    translate: 0 -5px;
  }
  [data-hs-hover='wiggle'] .hs-marker:not(.visible):hover > .hs-badge {
    rotate: 8deg;
  }
  [data-hs-hover='spin'] .hs-marker:not(.visible):hover > .hs-badge {
    rotate: 180deg;
  }
  [data-hs-hover='invert'] .hs-marker:not(.visible):hover > .hs-badge {
    filter: invert(1);
  }
  /* The modern look inverts to solid on hover */
  [data-hs-look='modern'] .hs-marker:not(.visible):hover > .hs-badge {
    --hs-fill: var(--accent);
    color: var(--hs-icon-color, #ffffff);
  }
}

/* Windows high contrast and similar: system colours replace the badge's own, so it needs a border to
   stay a visible shape. */
@media (forced-colors: active) {
  .hs-badge {
    border: 2px solid ButtonText;
  }
}

/* Editor states: the selected hotspot, and one hidden in this tour. */
.hs-badge.hs-active {
  scale: 1.1;
  box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.5);
}
.hs-marker.hs-hidden {
  opacity: 0.5;
}
.hs-marker.hs-hidden .hs-badge {
  box-shadow: 0 0 0 4px #ef4444;
}

/* ==========================================================================
   Motion
   Everything here animates transform and opacity only, so it never triggers layout or paint, and the
   animations sit inside prefers-reduced-motion: no-preference, so anyone who asks for less motion
   gets none of them.

   idle      [data-hs-idle]      pulse | float | breathe   an attention animation on every hotspot
   pulse     .hs-pulse           the same ring on a single hotspot (its "pulse" flag, the pulsing variant)
   entrance  [data-hs-entrance]  fade | pop                 plays as a room's hotspots appear (.hs-entering)
   hover     [data-hs-hover]     see above

   The engine numbers each room's hotspots (--hs-i) so they are staggered instead of moving in lockstep.
   An open popup stops its own idle animation, so the popup never drifts away from its badge.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  [data-hs-idle='pulse'] .hs-marker:not(.visible)::after,
  .hs-pulse:not(.visible)::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: var(--hs-badge);
    height: var(--hs-badge);
    border-radius: 50%;
    border: 2px solid var(--accent);
    pointer-events: none;
    animation: hs-pulse-ring 2s ease-out infinite;
    animation-delay: calc(var(--hs-i, 0) * -0.31s);
  }

  [data-hs-idle='float'] .hs-marker:not(.visible) > .hs-badge {
    animation: hs-float 2.8s ease-in-out infinite;
    animation-delay: calc(var(--hs-i, 0) * -0.43s);
  }
  [data-hs-idle='breathe'] .hs-marker:not(.visible) > .hs-badge {
    animation: hs-breathe 2.6s ease-in-out infinite;
    animation-delay: calc(var(--hs-i, 0) * -0.37s);
  }

  .hs-entering[data-hs-entrance='fade'] .hs-marker {
    animation: hs-enter-fade 0.45s ease-out backwards;
    animation-delay: calc(min(var(--hs-i, 0), 8) * 70ms);
  }
  .hs-entering[data-hs-entrance='pop'] .hs-marker {
    animation: hs-enter-pop 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) backwards;
    animation-delay: calc(min(var(--hs-i, 0), 8) * 70ms);
  }
}

@keyframes hs-pulse-ring {
  from {
    transform: scale(1);
    opacity: 0.7;
  }
  to {
    transform: scale(1.8);
    opacity: 0;
  }
}
@keyframes hs-float {
  50% {
    transform: translateY(-4px);
  }
}
@keyframes hs-breathe {
  50% {
    transform: scale(1.08);
  }
}
/* Entrance keyframes only name where the animation starts: it ends on the hotspot's normal style. */
@keyframes hs-enter-fade {
  from {
    opacity: 0;
  }
}
@keyframes hs-enter-pop {
  from {
    opacity: 0;
    transform: scale(0.3);
  }
}

/* Reduced motion: no hover transitions and no popup animation either (popups just appear). */
@media (prefers-reduced-motion: reduce) {
  html .hs-marker .hs-badge,
  html .hs-marker .info-hotspot-title-wrapper,
  html .hs-marker .info-hotspot-close-wrapper,
  html .hs-marker .info-hotspot-text,
  html .hs-marker .info-tooltip,
  html .hs-marker .simple-tooltip-label,
  html .info-hotspot-modal {
    transition: none;
  }
}
