/* ---- The sky dome (client/seo/build.js, dome()) ----------------------------
   The landing page's horizon arc with the bodies on it. The SVG and the
   bodies share one frame, 100 units wide: 1 unit is 1cqw. Each body sits at
   the arc's centre and turns out to its angle, upright again. Its label sits
   outside the arc along the same radius, so a label never lands on a
   neighbour's dot; labels of close bodies step further out (--l).
   The sky pages and the landing's hero both load this file; colours come
   from the page's tokens (--ink, --cocoa, --cream, --paper, --line…). */
@property --a { syntax: '<angle>'; inherits: true; initial-value: 0deg; }
.dome-fig { margin: 4rem 0 1.5rem; }
/* The caption keeps room for its longest readout, so the next heading comes in closer. */
.dome-fig + h2 { margin-top: 2.5rem; }
.dome-sky {
  position: relative;
  container-type: inline-size;
  aspect-ratio: 100 / 60;
  max-width: 560px;
  margin: 0 auto;
}
.dome-sky svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 14%, #000 86%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 14%, #000 86%, transparent 100%);
}
.arc, .shadow, .chord { fill: none; vector-effect: non-scaling-stroke; }
.arc { stroke: var(--line); stroke-width: 1; stroke-dasharray: 139cqw; }
.chord { stroke: var(--line); stroke-width: 1; }
.shadow { stroke: var(--cocoa); stroke-width: 3; stroke-linecap: round; }
.body {
  position: absolute;
  left: 50cqw;
  top: 52cqw;
  transform: rotate(calc(-1 * var(--a))) translateX(44cqw) rotate(var(--a));
}
.body i {
  position: absolute;
  width: 7px;
  height: 7px;
  margin: -3.5px;
  border-radius: 50%;
  background: var(--ink);
}
.body .name {
  --r: calc(var(--out, 1) * (1rem + var(--l) * 1.125rem));
  position: absolute;
  left: calc(cos(var(--a)) * var(--r));
  top: calc(sin(var(--a)) * -1 * var(--r));
  translate: calc(-50% + cos(var(--a)) * var(--out, 1) * 50%) calc(-50% - sin(var(--a)) * var(--out, 1) * 50%);
  white-space: nowrap;
  font-size: 0.8125rem;
  line-height: 1.25;
  text-align: center;
  color: var(--ink-muted);
}
/* Near the horizon labels hang under it in a column, inside the frame. */
.inside { --out: -1; }
.body[data-side] .name { left: 0; top: calc(sin(var(--a)) * 44cqw + 0.625rem + var(--l) * 1.125rem); }
.body[data-side="east"] .name { translate: -0.5rem 0; text-align: left; }
.body[data-side="west"] .name { translate: calc(-100% + 0.5rem) 0; text-align: right; }
.body .name small { display: block; font-size: inherit; color: var(--ink-muted); }
.sun .name, .moon .name, .natal .name { color: var(--ink); font-weight: 500; }
/* ☉: a ring with a dot. A natal point is a ring alone. */
.sun i, .natal i { width: 13px; height: 13px; margin: -6.5px; background: var(--cream); border: 1.5px solid var(--cocoa); }
.sun i::after { content: ''; position: absolute; inset: 3px; border-radius: 50%; background: var(--cocoa); }
.natal i { width: 11px; height: 11px; margin: -5.5px; }
.moon i { z-index: 1; width: 12px; height: 12px; margin: -6px; background: var(--paper); border: 1.5px solid var(--cocoa-dark); }
.moon.new i { width: 9px; height: 9px; margin: -4.5px; background: var(--cocoa-dark); border: 0; }
.mover i, .loop i { z-index: 1; width: 7px; height: 7px; margin: -3.5px; background: var(--cocoa); }
.loop .name { color: var(--cocoa); font-weight: 500; }
.dome-fig figcaption { max-width: 34rem; margin: 1.25rem auto 0; font-size: 0.9375rem; color: var(--ink-muted); text-align: center; text-wrap: pretty; }

/* Hover, tap or focus a body to read about it, as on the profile's chart
   wheel: the others dim and the caption gives way to the body's own text.
   The caption and every readout share one grid cell, so the figure keeps
   one height whichever is shown. */
.body { transition: opacity 160ms ease; }
.body[tabindex] { cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; }
.body[tabindex]::before { content: ''; position: absolute; width: 36px; height: 36px; margin: -18px; border-radius: 50%; }
.body:focus-visible i { outline: 1.5px solid var(--cocoa); outline-offset: 3px; }
.has-focus .body:not(.is-focus) { opacity: 0.3; }
.is-focus .name { color: var(--ink); }
.dome-fig figcaption { display: grid; }
.dome-fig figcaption > * { grid-area: 1 / 1; transition: opacity 160ms ease, visibility 160ms; }
.about { display: none; }
.js .about { display: block; visibility: hidden; opacity: 0; }
.about strong { font-weight: 500; color: var(--ink); }
.about span { display: block; margin-top: 0.25rem; }
.has-focus .rest { visibility: hidden; opacity: 0; }
.about.on { visibility: visible; opacity: 1; }

/* The intro: the arc draws from the east, each body lights as the line
   reaches it, then the movers travel. Played once, by sky-figure.js. */
.js .dome-fig:not(.play) .dome-sky { visibility: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .play .arc { animation: draw 1100ms var(--ease-in-out) both; }
  .play .body > * { animation: light 520ms var(--ease-out) var(--d) both; }
  .play .body > .name { animation-delay: calc(var(--d) + 120ms); }
  .play .shadow { animation: fade 500ms ease 900ms both; }
  .play .chord { animation: fade 500ms ease 2500ms both; }
  .play .mover { animation: glide 1500ms var(--ease-in-out) 1000ms both; }
  .play .loop { animation: loop 5600ms var(--ease-in-out) 1100ms both; }
}
@media (prefers-reduced-motion: reduce) {
  .play .dome-sky { animation: fade 400ms ease both; }
}
@keyframes draw { from { stroke-dashoffset: 139cqw; } to { stroke-dashoffset: 0; } }
@keyframes light { from { opacity: 0; scale: 0.4; } }
@keyframes fade { from { opacity: 0; } }
@keyframes glide { from { --a: var(--from); } }
/* Forward to the retrograde station, a pause, back to the direct station,
   a pause, forward again. Each leg eases in and out like the planet does. */
@keyframes loop {
  0% { --a: var(--k0); }
  34%, 44% { --a: var(--k1); }
  70%, 78% { --a: var(--k2); }
  100% { --a: var(--k3); }
}

/* On a touch screen a readout opens on a tap, so the caption needs no room
   held for it: the readout takes the caption's place. */
@media not ((hover: hover) and (pointer: fine)) {
  .js .about:not(.on), .has-focus .rest { display: none; }
}
