/*
  The scene layer stack, back to front:
  background → sun disc + glow → orbs + point light → haze → sun glare →
  film grain → tint → drawing canvas → labels.
  Lighting is driven by custom properties that js/scene.js updates every frame.
*/

.stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  isolation: isolate;
  background: var(--page);
  color: var(--ink);
  font-family: var(--font-main);
  text-transform: uppercase;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;

  /* Scene look */
  --contrast: .9;
  --brightness: .55;
  --haze: .22;
  --lift: 12;
  --glow: .12;
  --grain-opacity: .40;
  --tint-opacity: .25;

  /* Lighting defaults, overwritten per orb by JS */
  --lx: 80%;
  --ly: 32%;
  --k: 1;
  --sx: .18;
  --sy: -.04;
  --rx: -.015;
  --ry: 0;
  --rim-a: .55;

  /* Sun, overwritten by JS */
  --sun-x: 120%;
  --sun-y: -20%;
  --sun-r: 0px;
  --sun-opacity: 1;
  --sun-glow: .7;
  --sun-glare: .35;
}

.scene-background {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 60% 45% at 50% 85%, rgba(62, 62, 62, .55), transparent 70%),
    radial-gradient(ellipse 40% 60% at 15% 20%, rgba(42, 42, 42, .35), transparent 70%),
    radial-gradient(ellipse 90% 80% at 50% 50%, transparent 40%, rgba(0, 0, 0, .6)),
    linear-gradient(170deg, #1a1a1a, #121212 55%, #161616);
}

/* ---------- Sun ---------- */

.sun {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 0;
  width: calc(var(--sun-r) * 2);
  height: calc(var(--sun-r) * 2);
  border-radius: 50%;
  pointer-events: none;
  opacity: var(--sun-opacity);
  transform: translate(calc(var(--sun-x) - var(--sun-r)), calc(var(--sun-y) - var(--sun-r)));
  background:
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='400' height='400'><filter id='g'><feTurbulence type='fractalNoise' baseFrequency='.045' numOctaves='3' seed='9'/><feColorMatrix type='saturate' values='0'/></filter><rect width='100%' height='100%' filter='url(%23g)'/></svg>"),
    radial-gradient(circle closest-side, #ffffff 0, #fbfbfb 78%, #e6e6e6 93%, #d2d2d2 98.5%, #c4c4c4 100%);
  background-size: var(--texture-size, 200px) var(--texture-size, 200px), 100% 100%;
  background-blend-mode: soft-light, normal;
}

.sun-glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(circle at var(--sun-x) var(--sun-y),
    rgb(255 255 255 / 0) calc(var(--sun-r) - 2px),
    rgb(255 255 255 / calc(var(--sun-glow) * .75)) var(--sun-r),
    rgb(240 240 240 / calc(var(--sun-glow) * .3)) calc(var(--sun-r) + 4vmin),
    rgb(220 220 220 / calc(var(--sun-glow) * .1)) calc(var(--sun-r) + 14vmin),
    transparent calc(var(--sun-r) + 30vmin));
}

.sun-glare {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  mix-blend-mode: screen;
  background: radial-gradient(circle at var(--sun-x) var(--sun-y),
    rgb(255 255 255 / calc(var(--sun-glare) * .55)) var(--sun-r),
    rgb(230 230 230 / calc(var(--sun-glare) * .22)) calc(var(--sun-r) + 12vmin),
    rgb(200 200 200 / calc(var(--sun-glare) * .07)) calc(var(--sun-r) + 40vmin),
    transparent calc(var(--sun-r) + 75vmin));
}

/* ---------- Orbs ---------- */

.orbs {
  position: absolute;
  inset: 0;
  z-index: 1;
  filter: contrast(var(--contrast)) brightness(var(--brightness));
}

.point-light {
  position: absolute;
  left: 0;
  top: 0;
  z-index: var(--z, 1000);
  width: 6px;
  height: 6px;
  margin: -3px 0 0 -3px;
  border-radius: 50%;
  background: #ffffff;
  opacity: var(--opacity, 0);
  transform: translate(var(--x, -9999px), var(--y, -9999px)) scale(var(--scale, 1));
  will-change: transform;
  box-shadow:
    0 0 4px 2px #f4f4f4,
    0 0 30px 10px rgb(236 236 236 / .45),
    0 0 180px 70px rgb(230 230 230 / var(--glow, .12));
}

/* The positioned element for every orb: a plain .orb, or the wrapper around Saturn. */
.celestial-body {
  position: absolute;
  left: 0;
  top: 0;
  z-index: var(--z, 1000);
  width: var(--s);
  height: var(--s);
  opacity: var(--opacity, 1);
  clip-path: var(--clip, none);
  transform: translate(var(--x, 0px), var(--y, 0px));
  will-change: transform;
}

/*
  Greyscale noise texture blended (overlay) with three lights:
  key light from the moving point light, sun light, and the fixed fill light.
  Inset shadows give the terminator and rim lights.
*/
.orb {
  border-radius: 50%;
  width: var(--s);
  height: var(--s);
  background:
    var(--texture),
    radial-gradient(circle at var(--lx) var(--ly),
      rgb(238 238 238 / var(--ma)),
      rgb(184 184 184 / var(--ma)) calc(16% * var(--k)),
      rgb(84 84 84 / var(--ma)) calc(32% * var(--k)),
      rgb(11 11 11 / var(--ma)) calc(46% * var(--k)),
      transparent calc(54% * var(--k))),
    radial-gradient(circle at var(--ux, 90%) var(--uy, 10%),
      rgb(255 255 255 / var(--ua, 0)),
      rgb(210 210 210 / var(--ua, 0)) calc(20% * var(--uk, 1)),
      rgb(90 90 90 / calc(var(--ua, 0) * .8)) calc(40% * var(--uk, 1)),
      transparent calc(58% * var(--uk, 1))),
    radial-gradient(circle at var(--fx) var(--fy),
      rgb(200 200 200 / var(--fa)),
      rgb(110 110 110 / calc(var(--fa) * .6)) calc(22% * var(--fk)),
      rgb(40 40 40 / calc(var(--fa) * .3)) calc(38% * var(--fk)),
      transparent calc(52% * var(--fk))),
    #000;
  background-size: cover;
  background-blend-mode: overlay, screen, screen, normal;
  box-shadow:
    inset calc(var(--s) * var(--sx)) calc(var(--s) * var(--sy)) calc(var(--s) * .22) rgb(0 0 0 / var(--sa, 1)),
    inset calc(var(--s) * var(--rx)) calc(var(--s) * var(--ry)) calc(var(--s) * .035) rgb(236 236 236 / var(--rim-a)),
    inset calc(var(--s) * var(--urx, 0)) calc(var(--s) * var(--ury, 0)) calc(var(--s) * .05) rgb(255 255 255 / var(--urim, 0));
  filter: brightness(var(--lb, 1));
}

/* ---------- Saturn's rings ---------- */
/* Back ring, then the orb, then the front ring clipped to its lower half. */

.ringed-body > .orb {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
}

.ring {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--s) * var(--ring-size));
  height: calc(var(--s) * var(--ring-size));
  border-radius: 50%;
  transform: translate(-50%, -50%) rotate(var(--ring-rotation)) scaleY(var(--ring-tilt));
  background:
    linear-gradient(var(--ring-side, 90deg), rgb(255 255 255 / var(--ring-sheen, 0)), transparent 70%),
    repeating-radial-gradient(circle closest-side, rgb(0 0 0 / calc(.18 * var(--band-contrast))) 0 .5%, transparent .5% 1.3%),
    radial-gradient(circle closest-side,
      transparent 44%,
      rgb(140 140 140 / calc((.12 + .2 * var(--band-contrast)) * var(--ring-opacity))) 46%,
      rgb(160 160 160 / calc((.15 + .25 * var(--band-contrast)) * var(--ring-opacity))) 62%,
      rgb(222 222 222 / calc(.95 * var(--ring-opacity))) 63%,
      rgb(200 200 200 / calc(.9 * var(--ring-opacity))) 79%,
      rgb(40 40 40 / calc((.35 - .3 * var(--band-contrast)) * var(--ring-opacity))) 80.5%,
      rgb(40 40 40 / calc((.35 - .3 * var(--band-contrast)) * var(--ring-opacity))) 82.5%,
      rgb(188 188 188 / calc(.75 * var(--ring-opacity))) 84%,
      rgb(178 178 178 / calc(.7 * var(--ring-opacity))) 91.5%,
      rgb(50 50 50 / calc(.3 * var(--ring-opacity))) 92%,
      rgb(182 182 182 / calc(.66 * var(--ring-opacity))) 92.8%,
      rgb(165 165 165 / calc(.55 * var(--ring-opacity))) 97%,
      transparent 98.5%);
  background-blend-mode: screen, normal, normal;
  -webkit-mask: radial-gradient(circle closest-side, transparent calc(var(--ring-inner) - .6%), #000 var(--ring-inner), #000 98%, transparent 99%);
  mask: radial-gradient(circle closest-side, transparent calc(var(--ring-inner) - .6%), #000 var(--ring-inner), #000 98%, transparent 99%);
  filter: brightness(var(--ring-brightness, .5));
}

.ring-back {
  z-index: 0;
}

.ring-front {
  z-index: 2;
  clip-path: inset(50% 0 0 0);
}

/* The orb's shadow falling across the ring. */
.ring-shade {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 50%;
  height: calc(100% / var(--ring-size));
  margin-top: calc(-50% / var(--ring-size));
  transform-origin: 0 50%;
  transform: rotate(var(--shade-angle, 180deg));
  background: linear-gradient(to right, #000, #000 70%, transparent);
  opacity: var(--shade-amount, 0);
  filter: blur(3px);
}

/* The ring's shadow cast onto the orb. */
.ring-cast {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--s) * var(--ring-size));
  height: calc(var(--s) * var(--ring-size));
  border-radius: 50%;
  transform: translate(-50%, -50%) translate(var(--cast-x, 0px), var(--cast-y, 0px)) rotate(var(--ring-rotation)) scaleY(var(--ring-tilt));
  background: radial-gradient(circle closest-side,
    transparent calc(var(--ring-inner) - 1%),
    rgb(0 0 0 / calc(.25 * var(--ring-opacity))) var(--ring-inner),
    rgb(0 0 0 / calc(.3 * var(--ring-opacity))) 62%,
    rgb(0 0 0 / calc(.95 * var(--ring-opacity))) 63.5%,
    rgb(0 0 0 / calc(.9 * var(--ring-opacity))) 79%,
    rgb(0 0 0 / calc(.1 * var(--ring-opacity))) 80.5%,
    rgb(0 0 0 / calc(.1 * var(--ring-opacity))) 82.5%,
    rgb(0 0 0 / calc(.75 * var(--ring-opacity))) 84%,
    rgb(0 0 0 / calc(.7 * var(--ring-opacity))) 91.5%,
    rgb(0 0 0 / calc(.2 * var(--ring-opacity))) 92%,
    rgb(0 0 0 / calc(.66 * var(--ring-opacity))) 92.8%,
    rgb(0 0 0 / calc(.55 * var(--ring-opacity))) 97%,
    transparent 98.5%);
  opacity: var(--cast-amount, 0);
  filter: blur(1.5px);
  clip-path: inset(50% 0 0 0);
}

/* ---------- Atmosphere ---------- */

.haze {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
  opacity: var(--flicker, 1);
  background:
    radial-gradient(ellipse 60% 45% at 50% 85%, rgb(62 62 62 / var(--haze)), transparent 70%),
    linear-gradient(rgb(var(--lift) var(--lift) var(--lift)), rgb(var(--lift) var(--lift) var(--lift)));
}

.film-grain {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  pointer-events: none;
  mix-blend-mode: overlay;
  opacity: var(--grain-opacity);
}

/* Orbs are greyscale; all the warmth comes from this layer. */
.tint {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  background: var(--tint);
  opacity: var(--tint-opacity);
  mix-blend-mode: color;
}

/* ---------- Drawing and labels ---------- */

.drawing {
  position: absolute;
  inset: 0;
  z-index: 6;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.labels {
  position: absolute;
  inset: 0;
  z-index: 7;
  pointer-events: none;
}

.orb-label-mask {
  position: absolute;
  inset: 0;
  pointer-events: none;
  mask-composite: intersect;
  -webkit-mask-composite: source-in;
}

.orb-label {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  opacity: var(--opacity, 0);
  transform: translate(var(--x, 0px), var(--y, 0px));
  will-change: transform;
}

.orb-label-line {
  position: absolute;
  left: 0;
  top: 0;
  width: 52px;
  border-top: 1px dashed var(--rule-dashed);
  transform-origin: 0 0;
  transform: rotate(var(--angle, 0rad));
}

.orb-label-name {
  position: absolute;
  left: var(--name-x, 0px);
  top: var(--name-y, 0px);
  transform: var(--name-shift, none);
  color: var(--ink-muted);
  font-size: var(--label-size);
  letter-spacing: var(--wide-tracking);
  white-space: nowrap;
}
