/* 360 walkaround — a bare stage holding a bright studio plate.
   The trailer is charcoal, so the plate stays light to keep it legible; the
   accent is lifted from the DOT reflective tape on the trailer itself.

   This is embedded in an iframe on muckagtrailers.com, which supplies the
   heading and the framing ring, so the viewer carries no chrome of its own:
   no title block, no footer, no padding, and a stage that runs flush to the
   edge. A 16:9 iframe therefore holds a 16:9 stage exactly, with no bars. */

:root {
  --shell: oklch(17% 0.008 260);
  --shell-raised: oklch(22% 0.01 260);
  --hairline: oklch(32% 0.012 260);
  --text: oklch(96% 0.004 260);
  --text-dim: oklch(72% 0.012 260);
  --text-faint: oklch(58% 0.012 260);
  --accent: oklch(70% 0.19 45);
  --accent-soft: oklch(70% 0.19 45 / 0.16);
  --plate: oklch(97% 0.002 260);

  --text-body: clamp(0.9rem, 0.86rem + 0.2vw, 1rem);


  --duration-fast: 140ms;
  --duration-normal: 320ms;
  --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);

  color-scheme: dark;
}

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

/* `hidden` has to beat the `display` rules below, or a hidden element still lays
   itself out -- an off-screen hotspot stays clickable, and the error message sits
   invisibly over the whole stage swallowing every click. */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  min-height: 100vh;
  background:
    radial-gradient(120% 80% at 50% 0%, oklch(24% 0.014 260) 0%, var(--shell) 62%);
  color: var(--text);
  font-family: "Inter", "Helvetica Neue", system-ui, sans-serif;
  font-size: var(--text-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

.viewer {
  max-width: 1280px;
  margin: 0 auto;
  display: grid;
}

/* The heading and the hotspot instruction are kept for assistive tech and for
   anyone opening this page directly. `position: absolute` also takes them out
   of the grid, so they add no row and no gap above the stage. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- stage ---------- */

.stage {
  position: relative;
  margin: 0;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--plate);
  touch-action: pan-y;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  outline: none;
}

.stage:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.stage.is-grabbing {
  cursor: grabbing;
}

.stage.is-inert {
  pointer-events: none;
}

.stage__canvas,
.stage__poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
}

.stage__poster {
  transition: opacity var(--duration-normal) var(--ease-out-expo);
}

.stage__poster.is-hidden {
  opacity: 0;
}

.stage__hotspots {
  position: absolute;
  inset: 0;
}

/* Loading bar: a hairline that fills, not a spinner. */
.stage__progress {
  --progress: 0;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: oklch(50% 0.01 260 / 0.2);
  transform-origin: left;
  transition: opacity var(--duration-normal) var(--ease-out-expo);
}

.stage__progress::after {
  content: "";
  display: block;
  height: 100%;
  background: var(--accent);
  transform: scaleX(var(--progress));
  transform-origin: left;
  transition: transform var(--duration-fast) linear;
}

.stage__progress.is-done {
  opacity: 0;
}

.stage__hint {
  position: absolute;
  left: 50%;
  bottom: 6%;
  translate: -50% 0;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin: 0;
  padding: 0.5rem 0.9rem 0.5rem 0.7rem;
  border-radius: 999px;
  background: oklch(20% 0.01 260 / 0.82);
  color: var(--text);
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  backdrop-filter: blur(6px);
  transition: opacity var(--duration-normal) var(--ease-out-expo);
  pointer-events: none;
}

.stage__hint.is-hidden {
  opacity: 0;
}

.stage__hint-icon {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1.5px solid var(--accent);
  position: relative;
}

.stage__hint-icon::before,
.stage__hint-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 4px;
  height: 4px;
  border-top: 1.5px solid var(--accent);
  border-right: 1.5px solid var(--accent);
  translate: 0 -50%;
}

.stage__hint-icon::before {
  left: 2px;
  rotate: -135deg;
}

.stage__hint-icon::after {
  right: 2px;
  rotate: 45deg;
}

/* Orbit position dial. */
.dial {
  position: absolute;
  right: 1rem;
  top: 1rem;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
}

/* Sits on the light plate, so it is drawn as a faint engraved ring rather than a
   dark chip: an instrument reading out orbit position, not a button. */
.dial__face {
  width: 100%;
  height: 100%;
  fill: oklch(100% 0 0 / 0.5);
  stroke: oklch(45% 0.01 260 / 0.3);
  stroke-width: 1;
}

.dial__needle {
  --angle: 0deg;
  position: absolute;
  inset: 0;
  rotate: var(--angle);
}

.dial__needle::before {
  content: "";
  position: absolute;
  top: 4px;
  left: 50%;
  width: 4px;
  height: 8px;
  translate: -50% 0;
  border-radius: 2px;
  background: var(--accent);
}

.stage__error {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  margin: 0;
  padding: 2rem;
  text-align: center;
  color: oklch(30% 0.01 260);
}

/* ---------- hotspots ---------- */

.hotspot {
  --x: 50%;
  --y: 50%;
  --opacity: 1;
  position: absolute;
  left: var(--x);
  top: var(--y);
  translate: -50% -50%;
  opacity: var(--opacity);
  display: flex;
  align-items: center;
  gap: 0;
  /* 44px hit area regardless of the mark's visual size. */
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  cursor: pointer;
  transition: opacity var(--duration-fast) linear;
}

.hotspot__ring {
  position: relative;
  display: block;
  width: 22px;
  height: 22px;
  flex: none;
  border-radius: 50%;
  border: 2px solid var(--accent);
  background: oklch(20% 0.01 260 / 0.55);
  box-shadow: 0 2px 10px oklch(0% 0 0 / 0.35);
  transition:
    scale var(--duration-fast) var(--ease-out-expo),
    background-color var(--duration-fast) linear;
}

/* Crosshair, not a dot — it reads as an instrument, and stays legible on a
   light plate as well as on the dark trailer body. */
.hotspot__ring::before,
.hotspot__ring::after {
  content: "";
  position: absolute;
  background: var(--accent);
}

.hotspot__ring::before {
  left: 50%;
  top: 4px;
  bottom: 4px;
  width: 2px;
  translate: -50% 0;
}

.hotspot__ring::after {
  top: 50%;
  left: 4px;
  right: 4px;
  height: 2px;
  translate: 0 -50%;
}

/* The pulse only draws attention before the first interaction. */
.hotspot__ring {
  animation: hotspot-pulse 2.6s var(--ease-out-expo) infinite;
}

@keyframes hotspot-pulse {
  0%,
  70%,
  100% {
    box-shadow: 0 0 0 0 var(--accent-soft), 0 2px 10px oklch(0% 0 0 / 0.35);
  }
  35% {
    box-shadow: 0 0 0 8px oklch(70% 0.19 45 / 0), 0 2px 10px oklch(0% 0 0 / 0.35);
  }
}

.hotspot__label {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  background: oklch(20% 0.01 260 / 0.9);
  border-radius: 0 999px 999px 0;
  line-height: 1;
  padding: 0.5rem 0;
  opacity: 0;
  transition:
    max-width var(--duration-normal) var(--ease-out-expo),
    opacity var(--duration-fast) linear,
    padding var(--duration-normal) var(--ease-out-expo);
}

.hotspot:hover .hotspot__ring,
.hotspot:focus-visible .hotspot__ring {
  scale: 1.15;
  background: var(--accent);
}

.hotspot:hover .hotspot__label,
.hotspot:focus-visible .hotspot__label {
  max-width: 24ch;
  opacity: 1;
  padding: 0.5rem 0.75rem 0.5rem 0.85rem;
  margin-left: -0.6rem;
}

.hotspot.is-flipped {
  flex-direction: row-reverse;
}

.hotspot.is-flipped .hotspot__label {
  border-radius: 999px 0 0 999px;
  text-align: right;
}

.hotspot.is-flipped:hover .hotspot__label,
.hotspot.is-flipped:focus-visible .hotspot__label {
  padding: 0.5rem 0.85rem 0.5rem 0.75rem;
  margin-left: 0;
  margin-right: -0.6rem;
}

.hotspot:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 999px;
}

/* ---------- detail dialog ---------- */

.detail {
  width: min(920px, calc(100vw - 2rem));
  padding: 0;
  border: 1px solid var(--hairline);
  border-radius: 14px;
  background: var(--shell-raised);
  color: var(--text);
  overflow: hidden;
}

.detail::backdrop {
  background: oklch(8% 0.01 260 / 0.72);
  backdrop-filter: blur(3px);
}

.detail[open] {
  animation: detail-in var(--duration-normal) var(--ease-out-expo);
}

@keyframes detail-in {
  from {
    opacity: 0;
    scale: 0.97;
  }
}

.detail__panel {
  position: relative;
  display: grid;
  grid-template-columns: 1.15fr 1fr;
}

.detail__media {
  margin: 0;
  background: var(--plate);
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
}

.detail__media.is-empty::after {
  content: "Image coming soon";
  color: oklch(55% 0.01 260);
  font-size: 0.85rem;
}

.detail__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity var(--duration-normal) var(--ease-out-expo);
}

.detail__media.is-empty .detail__image {
  display: none;
}

.detail__image.is-loaded {
  opacity: 1;
}

.detail__body {
  padding: clamp(1.25rem, 1rem + 1vw, 2rem);
  display: grid;
  align-content: start;
  gap: 0.75rem;
}

.detail__title {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.detail__description {
  margin: 0;
  color: var(--text-dim);
}

.detail__spec {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.35rem 1rem;
  margin: 0.5rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--hairline);
  font-size: 0.85rem;
}

.detail__spec dt {
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.7rem;
  align-self: center;
}

.detail__spec dd {
  margin: 0;
  color: var(--text);
  font-weight: 500;
}

.detail__close {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  z-index: 1;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: 1px solid var(--hairline);
  border-radius: 50%;
  background: oklch(20% 0.01 260 / 0.85);
  color: var(--text);
  cursor: pointer;
  transition:
    background-color var(--duration-fast) linear,
    border-color var(--duration-fast) linear;
}

.detail__close svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  fill: none;
}

.detail__close:hover,
.detail__close:focus-visible {
  background: var(--accent);
  border-color: var(--accent);
  color: oklch(18% 0.02 45);
}

@media (max-width: 720px) {
  .detail__panel {
    grid-template-columns: 1fr;
  }

  .dial {
    display: none;
  }

  /* The stage is short here; keep the hint clear of the trailer's wheels. */
  .stage__hint {
    bottom: 3%;
    padding: 0.4rem 0.75rem 0.4rem 0.55rem;
    font-size: 0.72rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}
