/* Light Orbit — shared by Image Lab (image-tools.html) and the video relight
   studio (index.html). One design system: this file uses only tokens both
   pages already define (--accent, --line, --ink, --dim, --mono), with literal
   fallbacks so it degrades rather than disappears. Every literal here is
   achromatic (channel spread <= 8) so engine/neutralTheme.test.js stays
   green: this file is UI chrome, and chrome follows the neutral theme.

   🔴 Two rings, and depth is STYLE not occlusion. The horizontal ring is the
   azimuth orbit; the vertical one is the elevation orbit and swings to the
   light's azimuth, so both axes have a track you can drag along. An earlier
   cut buried upstage beads under the media at z 1 — over a full-bleed photo
   that made them vanish outright, so everything draws in the front layer now
   and "behind" is said with a dashed, dimmed, smaller bead. The back layer is
   kept, and empty. */

[data-orbit-host] { position: relative; }

[data-orbit-media] {
  position: relative;
  z-index: 2;
}

.light-orbit-layer {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.light-orbit-layer.is-back { z-index: 1; }
.light-orbit-layer.is-front { z-index: 3; pointer-events: auto; touch-action: none; }

/* The standalone stage, used where there is no existing figure to host the
   orbit (the video relight studio). aspect-ratio reserves the slot at a
   constant height, so adding or removing a light never moves the controls
   underneath it. */
.light-orbit-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 2;
  border: 1px solid var(--line, #3A3A3E);
  border-radius: 14px;
  background:
    radial-gradient(120% 90% at 50% 12%, rgba(208, 208, 210, .06), transparent 60%),
    var(--bg, #0B0B0C);
  overflow: hidden;
  touch-action: none;
}
.light-orbit-stage [data-orbit-media] {
  position: absolute;
  left: 50%;
  top: 50%;
  max-width: 78%;
  max-height: 66%;
  transform: translate(-50%, -50%);
  border-radius: 8px;
  object-fit: contain;
  background: #000;
}

.light-orbit-wash {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  mix-blend-mode: screen;
  pointer-events: none;
}

.light-orbit-ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}
.orbit-path {
  fill: none;
  stroke: color-mix(in srgb, var(--accent, #D0D0D2) 30%, transparent);
  stroke-width: 1;
  stroke-dasharray: 3 5;
}
/* The vertical orbit. Dimmer than the near arc so the two rings read as a
   gimbal rather than competing for attention. */
.orbit-path.is-meridian {
  stroke: color-mix(in srgb, var(--accent, #D0D0D2) 34%, transparent);
  stroke-dasharray: 2 4;
  stroke-width: 1;
}
.orbit-path.is-near {
  stroke: color-mix(in srgb, var(--accent, #D0D0D2) 62%, transparent);
  stroke-dasharray: none;
  stroke-width: 1.5;
}
.orbit-tick {
  fill: color-mix(in srgb, var(--accent, #D0D0D2) 45%, transparent);
  pointer-events: none;
}
.orbit-tick.is-upstage { fill: color-mix(in srgb, var(--accent, #D0D0D2) 22%, transparent); }
.orbit-tick-hit {
  fill: transparent;
  pointer-events: auto;
  cursor: pointer;
}
.orbit-tick-hit:hover { fill: color-mix(in srgb, var(--accent, #D0D0D2) 20%, transparent); }

.light-orbit-beads { position: absolute; inset: 0; pointer-events: none; }

.light-orbit-bead {
  position: absolute;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  margin: -15px 0 0 -15px;
  padding: 0;
  border: 1.5px solid color-mix(in srgb, var(--light-color, #fff) 70%, transparent);
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 42%, var(--light-color, #fff), transparent 72%),
    rgba(10, 14, 16, .74);
  color: var(--ink, #F3F3F2);
  font: 600 11px/1 var(--mono, ui-monospace, monospace);
  cursor: grab;
  pointer-events: auto;
  /* Only transform and opacity animate — never a layout property. */
  transform: scale(var(--bead-scale, 1));
  transition: box-shadow .16s ease, border-color .16s ease;
}
.light-orbit-bead::after {
  content: "";
  position: absolute;
  inset: -9px;
  border-radius: 50%;
  background: radial-gradient(circle, color-mix(in srgb, var(--light-color, #fff) 34%, transparent), transparent 68%);
  pointer-events: none;
}
.light-orbit-bead[data-depth="behind"] {
  opacity: .62;
  border-style: dashed;
}
.light-orbit-bead[data-depth="behind"]::after { opacity: .4; }
.light-orbit-bead.is-selected {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, #D0D0D2) 60%, transparent);
}
.light-orbit-bead:focus-visible {
  outline: 2px solid var(--accent, #D0D0D2);
  outline-offset: 3px;
}
.light-orbit-bead:active { cursor: grabbing; }
.is-dragging .light-orbit-bead { transition: none; }

.light-orbit-badge {
  position: absolute;
  right: 9px;
  bottom: 9px;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 9px;
  border: 1px solid var(--line, #3A3A3E);
  border-radius: 8px;
  background: rgba(10, 14, 16, .82);
  color: var(--dim, #A7A7AA);
  font: 500 9.5px/1 var(--mono, ui-monospace, monospace);
  pointer-events: none;
}
.light-orbit-badge b { color: var(--accent, #D0D0D2); font-weight: 600; }

.light-orbit-hint {
  position: absolute;
  left: 9px;
  bottom: 9px;
  z-index: 2;
  color: var(--dim, #A7A7AA);
  font: 500 9.5px/1 var(--mono, ui-monospace, monospace);
  pointer-events: none;
}

/* ── Light rows ────────────────────────────────────────────────────────────
   🔴 The stack always renders LIGHT_ORBIT_MAX_LIGHTS rows and empties the
   unused ones. `display: none` here would collapse the slot and shove every
   control below it — the defect this project has already been bitten by more
   than once. visibility + inert keeps the box while taking it out of the tab
   order and the accessibility tree. */
.light-row[data-empty="true"] {
  visibility: hidden;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .light-orbit-bead { transition: none; }
}
