/* Background carousel: cycles the Pi3X reconstruction scans behind the
   existing page content. Purely additive -- does not modify any existing
   selector or the gallery/card styling. */

#bg-carousel {
  position: fixed;
  inset: 0;
  /* Negative, not 0: several existing elements (the bare <h1>, the
     draggable status window) are non-positioned, and non-positioned
     siblings always paint *below* any positioned sibling with z-index
     0 or higher, regardless of DOM order -- z-index 0 here silently
     washed them out. Negative pins this behind literally everything. */
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
}

#bg-carousel .bg-scan-wrap {
  position: absolute;
  /* inset alone doesn't stretch a replaced element (<img>, and by
     extension the model-viewer canvas inside this) without explicit
     width/height -- it falls back to intrinsic size. Set both
     explicitly so the gaps (left/right 10px, top 20%) actually take
     effect. Height keeps the bottom edge pinned at 2/3 screen height
     (66.667vh) regardless of the top offset: 66.667vh - 20vh = 46.667vh. */
  top: 20%;
  right: 10px;
  left: 10px;
  width: calc(100% - 20px);
  height: 46.667vh;
  --sun-filter: none;
  opacity: 0;
  /* blur (crossfade) composes with the sun-tint custom property here,
     rather than each fighting over the filter property separately */
  filter: var(--sun-filter) blur(16px);
  transition: opacity 1100ms ease, filter 1100ms ease;
  will-change: opacity, filter;
}

#bg-carousel .bg-scan-wrap.is-current {
  opacity: 0.5;
  filter: var(--sun-filter) blur(0);
}

.bg-scan-wrap .bg-scan {
  width: 100%;
  height: 100%;
  display: block;
  /* Real transparency, not just a color that happens to match the page:
     the poster (models/bg_scans/*.png) is now rendered with alpha too
     (see render_bg_posters.py), and the model-viewer canvas itself has
     no background fill, so the sparse point cloud is the only opaque
     content -- nothing behind it (page, other stacked scans) shows
     through as a solid rectangle the way the old flat-color JPG posters
     used to. */
  --poster-color: transparent;
  background-color: transparent;
  /* The default progress bar (shown while a GLB streams in) is a real
     element inside model-viewer's own shadow DOM, sized to 100% of this
     host element -- which is already exactly the window's own width, so
     explicitly styling it here (rather than leaving it at model-viewer's
     own default height/mask) just makes that confinement deliberate
     instead of incidental. */
  --progress-bar-height: 3px;
  --progress-bar-color: #6b95c9;
  --progress-mask: transparent;
}

#bg-carousel::after {
  /* keep page text/nav legible over the busiest parts of the image */
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 38%, rgba(240, 242, 245, 0.25) 0%, rgba(240, 242, 245, 0.72) 68%, rgba(240, 242, 245, 0.92) 100%);
}

#bg-carousel .bg-label {
  /* anchored under the top-left branding rather than the viewport
     bottom -- "bottom" tracked the current viewport, which on shorter
     windows landed on top of the timeline section below the fold */
  position: absolute;
  left: 18px;
  top: 130px;
  font-family: ui-monospace, "SF Mono", "Roboto Mono", Consolas, monospace;
  font-size: 11px;
  color: #4a5560;
  background: rgba(255, 255, 255, 0.72);
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 7px;
  padding: 6px 10px;
  opacity: 0;
  transition: opacity 1100ms ease;
}

#bg-carousel .bg-label.is-current { opacity: 1; }

/* ---- controls overlay: the only place a button reliably clickable can
   live. #bg-carousel sits at z-index:-1 (needed so it paints behind the
   bare non-positioned <h1>/status-window -- see above), which per the
   CSS stacking spec puts its *entire subtree* in the layer BELOW normal
   static content, not just visually but for hit-testing too -- a button
   nested in there is not reliably clickable no matter its own z-index,
   because non-positioned siblings elsewhere on the page (like that bare
   <h1>, whose invisible full-width box extends well past its visible
   text) sit in a higher hit-test layer and silently swallow the click
   first. Confirmed via elementFromPoint() while debugging this: the h1
   was resolving as the hit target at the button's own coordinates. ---- */

#bg-scan-overlay-root {
  position: fixed;
  inset: 0;
  z-index: 2000;
  pointer-events: none; /* only children that opt back in receive clicks */
}

/* One frame matching .bg-scan-wrap's own box exactly (same top/right/
   left/height values above) -- the enlarge/prev/next/download buttons
   are positioned relative to *this*, not the viewport, so they're
   structurally part of the window rather than independently-fixed
   elements that merely lined up with its corner via matching arithmetic. */
#bg-scan-controls {
  position: fixed;
  top: 20%;
  right: 10px;
  left: 10px;
  height: 46.667vh;
  pointer-events: none;
}

#bg-scan-trigger,
#bg-scan-nav,
#bg-scan-download {
  position: absolute;
  right: 8px;
  pointer-events: auto;
}

#bg-scan-trigger {
  top: 8px;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  background: rgba(255, 255, 255, 0.85);
  color: #333;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 150ms ease, transform 150ms ease;
}

#bg-scan-trigger:hover { background: #fff; transform: scale(1.06); }
#bg-scan-trigger:focus-visible { outline: 2px solid #2554d1; outline-offset: 2px; }

/* Manual prev/next, directly below the enlarge trigger */
#bg-scan-nav {
  top: 48px; /* trigger's top(8) + height(32) + gap(8) */
  display: flex;
  gap: 4px;
}

.bg-scan-nav-btn {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  background: rgba(255, 255, 255, 0.85);
  color: #333;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 150ms ease, transform 150ms ease;
}

.bg-scan-nav-btn:hover { background: #fff; transform: scale(1.06); }
.bg-scan-nav-btn:focus-visible { outline: 2px solid #2554d1; outline-offset: 2px; }

/* Download, below the prev/next row */
#bg-scan-download {
  top: 88px; /* trigger(8+32) + nav row(32) + gaps(8+8) */
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid rgba(0, 0, 0, 0.08);
  background: rgba(255, 255, 255, 0.85);
  color: #333;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  text-decoration: none;
  transition: background 150ms ease, transform 150ms ease;
}

#bg-scan-download:hover { background: #fff; transform: scale(1.06); }
#bg-scan-download:focus-visible { outline: 2px solid #2554d1; outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  #bg-carousel .bg-scan-wrap,
  #bg-carousel .bg-label { transition: none; }
}
