/* Galaxy: styles. See README.md. */
@property --fl { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --fr { syntax: "<number>"; inherits: false; initial-value: 0; }
:root { --ink: rgba(255, 255, 255, .9); --dim: rgba(255, 255, 255, .56); --faint: rgba(255, 255, 255, .32); --line: rgba(255, 255, 255, .14); --panel: rgba(16, 17, 21, .66); --hover: rgba(255, 255, 255, .08); --on: rgba(255, 255, 255, .14); }
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: #050506; color: var(--ink); font: 13px/1.4 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; }
body { overflow: hidden; }
button { font: inherit; color: var(--dim); background: none; border: 0; border-radius: 999px; padding: 6px 11px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
button { transition: color .18s ease, background-color .18s ease, box-shadow .18s ease, transform .12s ease, opacity .25s ease; }
button:hover { color: var(--ink); background: var(--hover); }
button:active { transform: scale(.96); }
button[aria-pressed="true"], button[aria-current="true"] { color: var(--ink); background: var(--on); }
button:focus-visible, [role=slider]:focus-visible { outline: 2px solid rgba(255, 255, 255, .75); outline-offset: 2px; }
.glass { background: var(--panel); border: 1px solid var(--line); backdrop-filter: blur(18px) saturate(1.2); -webkit-backdrop-filter: blur(18px) saturate(1.2); }

/* the scene. Gestures are captured here only; the rest of the page keeps normal zoom and scroll */
.frame { position: fixed; inset: 0; background: #050506; touch-action: none; cursor: grab; -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.frame.dragging { cursor: grabbing; }
.frame canvas { display: block; position: relative; }
/* a still of the first view shows at once; the live scene fades in over it when its first frame is drawn. The still is
   as tall as the window (the galaxy's size on screen follows the height); on narrow screens the eye starts further
   back, so the still is shown that much smaller */
.frame .poster { position: absolute; left: 50%; top: 50%; height: 100%; aspect-ratio: 2 / 1; transform: translate(-50%, -50%); pointer-events: none; transition: opacity .7s ease .1s; }
.frame .poster img { display: block; width: 100%; height: 100%; }
.frame > canvas:first-of-type { opacity: 0; transition: opacity .7s ease; }
.frame.live > canvas:first-of-type { opacity: 1; } .frame.live .poster { opacity: 0; }
@media (max-aspect-ratio: 3/4) { .frame .poster { height: 95%; } } @media (max-aspect-ratio: 13/20) { .frame .poster { height: 87%; } } @media (max-aspect-ratio: 9/16) { .frame .poster { height: 81%; } }
@media (max-aspect-ratio: 1/2) { .frame .poster { height: 77%; } } @media (max-aspect-ratio: 23/50) { .frame .poster { height: 75%; } }
body.ig .frame > canvas:first-of-type, body.igui .frame > canvas:first-of-type { opacity: 1; transition: none; } body.ig .poster, body.igui .poster, body.bare .where, body.bare #names, body.nonames #names { display: none; }
.frame .layer { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

/* names in the scene: real buttons, so they can be clicked and reached by keyboard */
.name { position: absolute; left: 0; top: 0; height: 24px; margin: -12px 0 0 -12px; padding: 0 8px 0 calc(12px + var(--gap, 10px)); border-radius: 12px; font-size: 11px; line-height: 24px; color: rgba(255, 255, 255, .82); pointer-events: auto; will-change: transform, opacity; }
.name { transition: color .18s ease; } .name i { transition: border-color .18s ease; }
.name:hover { background: none; color: #fff; }
.name i { position: absolute; left: 12px; top: 12px; width: calc(var(--ring, 0px) * 2); height: calc(var(--ring, 0px) * 2); margin: calc(var(--ring, 0px) * -1) 0 0 calc(var(--ring, 0px) * -1); border: 1px solid rgba(255, 255, 255, .5); border-radius: 50%; }
.name.bare i { display: none; }
.name:hover i { border-color: #fff; }
.name.on { color: #fff; } .name.on span { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(255, 255, 255, .5); }
.name[hidden] { display: none; }

/* top left: where you are */
.where { position: fixed; left: max(20px, env(safe-area-inset-left)); top: max(16px, env(safe-area-inset-top)); pointer-events: none; max-width: min(60vw, 420px); text-wrap: balance; }
.where h1 { margin: 0; font-size: 17px; font-weight: 600; letter-spacing: .01em; width: max-content; max-width: 100%; }
.where p { margin: 2px 0 0; color: var(--dim); font-variant-numeric: tabular-nums; }
.where #hint { margin-top: 10px; max-height: 60px; overflow: hidden; transition: opacity .8s ease, max-height 0s .8s, margin 0s .8s; } .where #hint.gone { opacity: 0; max-height: 0; margin: 0; }
.where, .rail .tick, .name { text-shadow: 0 0 6px rgba(0, 0, 0, .9), 0 0 2px rgba(0, 0, 0, .7); }
.where [hidden] { display: none; }
/* bottom left: where the pictures come from */
.credit { position: fixed; z-index: 4; left: max(20px, env(safe-area-inset-left)); bottom: max(16px, env(safe-area-inset-bottom)); max-width: min(24vw, 250px); margin: 0; font-size: 11px; line-height: 1.45; color: var(--faint); pointer-events: none; text-wrap: pretty; text-shadow: 0 0 6px rgba(0, 0, 0, .9); transition: opacity .5s ease, bottom .3s ease; }
.credit[hidden] { display: block; opacity: 0; visibility: hidden; transition: opacity .5s ease, bottom .3s ease, visibility 0s .5s; }
@media (max-width: 1180px) { .credit { bottom: 66px; max-width: min(70vw, 420px); } }

/* top right: time and labels */
.tools { position: fixed; z-index: 31; right: max(16px, env(safe-area-inset-right)); top: max(14px, env(safe-area-inset-top)); display: flex; align-items: center; gap: 2px; padding: 4px 5px; border-radius: 999px; }
.tools button { padding: 6px 10px; min-width: 30px; justify-content: center; }
.tools .cap { color: var(--faint); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; padding: 0 4px 0 9px; }
.tools .step { padding: 6px 8px; min-width: 26px; }
.tools output { min-width: 3.1em; text-align: center; color: var(--ink); font-variant-numeric: tabular-nums; }
.tools .sep { width: 1px; height: 16px; background: var(--line); margin: 0 5px; }
.tools svg { width: 12px; height: 12px; fill: currentColor; display: block; flex: none; }
/* line icons (minus, plus, close, chevron): drawn, not typed, so they sit exactly in the middle of their buttons */
svg.ico { width: 12px; height: 12px; display: block; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.tools .check { width: 12px; height: 12px; border-radius: 50%; border: 1.5px solid currentColor; flex: none; transition: background-color .18s ease, box-shadow .18s ease; } .tools [aria-pressed="true"] .check { background: currentColor; box-shadow: inset 0 0 0 2px rgba(16, 17, 21, .9); }

/* right edge: the scale you are at, and a way to move along it */
.rail { position: fixed; z-index: 5; right: max(18px, env(safe-area-inset-right)); top: 50%; transform: translateY(-50%); height: min(46vh, 380px); width: 150px; touch-action: none; cursor: ns-resize; border-radius: 8px; }
.rail .track { position: absolute; right: 9px; top: 0; bottom: 0; width: 2px; border-radius: 1px; background: var(--line); }
.rail .tick { position: absolute; right: 0; height: 20px; margin-top: -10px; padding: 0 22px 0 8px; font-size: 11px; line-height: 20px; color: rgba(255, 255, 255, .5); border-radius: 10px; transition: top .45s cubic-bezier(.3, .7, .2, 1), color .18s ease, opacity .25s ease; }
.rail .tick:active { transform: none; }
.rail .tick::after { content: ""; position: absolute; right: 6px; top: 9px; width: 8px; height: 2px; border-radius: 1px; background: currentColor; }
.rail .tick:hover { color: var(--ink); background: none; }
.rail .tick.near { color: var(--ink); } .rail .tick.off { opacity: .7; }
.rail .thumb { position: absolute; right: 4px; width: 12px; height: 12px; margin-top: -6px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 4px rgba(255, 255, 255, .14); pointer-events: none; }

/* bottom: places to go */
/* the dock: the scale you are at (galaxy to solar system) and the places at that scale. Side by side when there is
   room; otherwise the places drop to a second row, and the scale names shorten */
.dock { position: fixed; z-index: 6; left: 50%; bottom: max(16px, env(safe-area-inset-bottom)); transform: translateX(-50%); display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; width: max-content; max-width: calc(100vw - 24px); }
.levels, .places { padding: 5px 6px; border-radius: 999px; max-width: 100%; overflow: hidden; }
.places { transition: opacity .2s ease, transform .2s ease; } .places.leaving { opacity: 0; transform: translateY(4px); }
.places[hidden] { display: none; }
/* a row that is too long scrolls sideways. The end that has more to show fades out; how much is set from how far
   there is left to scroll (--fl, --fr: 0 to 1), so the fade comes and goes with the scrolling instead of switching */
.scroll { --fl: 0; --fr: 0; display: flex; align-items: center; gap: 1px; overflow-x: auto; scrollbar-width: none; border-radius: 999px; transition: --fl .22s ease, --fr .22s ease;
  -webkit-mask-image: linear-gradient(to right, rgba(0, 0, 0, calc(1 - var(--fl))) 0, #000 56px, #000 calc(100% - 56px), rgba(0, 0, 0, calc(1 - var(--fr))) 100%);
  mask-image: linear-gradient(to right, rgba(0, 0, 0, calc(1 - var(--fl))) 0, #000 56px, #000 calc(100% - 56px), rgba(0, 0, 0, calc(1 - var(--fr))) 100%); }
.scroll::-webkit-scrollbar { display: none; }
.dock .gt { color: var(--faint); flex: none; width: 18px; display: flex; justify-content: center; } .dock .gt svg { width: 10px; height: 10px; }
.places .div { flex: none; width: 1px; height: 16px; margin: 0 7px; background: var(--line); }
.dock .cap, .rail .cap { color: var(--faint); font-size: 11px; letter-spacing: .04em; text-transform: uppercase; flex: none; }
.dock .cap { padding: 0 6px 0 9px; } .rail .cap { position: absolute; right: 0; top: -30px; text-shadow: 0 0 6px rgba(0, 0, 0, .9); }
.dock button { flex: none; } .places button.moon { font-size: 12px; padding: 5px 9px; color: var(--faint); } .places button.moon:hover, .places button.moon[aria-current="true"] { color: var(--ink); }
.places .group { display: flex; gap: 1px; padding: 0 2px; margin: 0 2px; border-left: 1px solid var(--line); border-right: 1px solid var(--line); animation: rise .3s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }
/* (nothing that holds a glass panel may fade as a whole: a faded parent cuts its panels off from the scene behind
   them and their blur is lost. So the dock itself never animates; its two rows do) */
.tools, .rail, .where, .levels { animation: rise .6s cubic-bezier(.2, .8, .2, 1) backwards; } .rail, .levels { animation-name: fadein; }
@keyframes fadein { from { opacity: 0; } }
.levels button[aria-current="true"] { background: none; color: var(--ink); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .34); }

/* help */
.help { position: fixed; z-index: 30; right: max(16px, env(safe-area-inset-right)); top: calc(48px + max(14px, env(safe-area-inset-top))); max-height: calc(100dvh - 150px); overflow-y: auto; width: min(330px, calc(100vw - 32px)); padding: 14px 16px; border-radius: 14px; color: var(--dim); transform-origin: top right; transition: opacity .22s ease, transform .26s cubic-bezier(.2, .8, .2, 1), visibility 0s; }
.help[hidden] { display: block; opacity: 0; transform: translateY(-8px) scale(.97); visibility: hidden; pointer-events: none; transition: opacity .16s ease, transform .16s ease, visibility 0s .16s; }
.help h2 { margin: 0 0 8px; font-size: 13px; font-weight: 600; color: var(--ink); }
.help dl { margin: 0 0 10px; display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; } .help dt { color: var(--ink); white-space: nowrap; } .help dd { margin: 0; }
.help p { margin: 8px 0 0; font-size: 11px; color: var(--faint); text-wrap: pretty; }
.help a, .credit a, .page a { color: var(--dim); text-underline-offset: 3px; } .help a:hover, .credit a:hover, .page a:hover { color: var(--ink); }
.credit a { pointer-events: auto; }
.credit .short { display: none; }
#hint .touch { display: none; }
@media (pointer: coarse) { #hint .mouse { display: none; } #hint .touch { display: inline; } }
@media (max-width: 640px) { .credit .long { display: none; } .credit .short { display: inline; } }
.fps { position: fixed; left: 20px; top: 50%; color: var(--faint); font-size: 11px; font-variant-numeric: tabular-nums; pointer-events: none; }

@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; } }
body.ig * { animation: none !important; transition: none !important; }
body.ig .tools, body.ig .rail, body.ig .dock, body.ig .help, body.ig #hint, body.ig .credit, body.ig .fps { display: none; }
@media (max-width: 640px) { .rail { display: none; } .where h1 { font-size: 15px; } .tools { right: 10px; top: 10px; } .tools .wide, .tools .cap, #pauseText, .dock .cap { display: none; } .where { max-width: calc(100vw - 232px); left: 14px; } }

/* text pages (credits, not found) */
.page { max-width: 720px; margin: 0 auto; padding: 56px 24px 96px; overflow: visible; }
html.doc, html.doc body { height: auto; overflow: auto; }
.page h1 { font-size: 26px; font-weight: 600; margin: 0 0 6px; text-wrap: balance; }
.page h2 { font-size: 15px; font-weight: 600; margin: 34px 0 8px; color: var(--ink); }
.page p, .page li { color: var(--dim); font-size: 14px; line-height: 1.6; text-wrap: pretty; }
.page ul { padding-left: 18px; margin: 8px 0; } .page li { margin: 4px 0; }
.page .lead { font-size: 15px; } .page .back { display: inline-block; margin-bottom: 28px; font-size: 13px; }
.page small { color: var(--faint); font-size: 12px; }
.help .by { color: var(--dim); }

/* the credits, opened over the scene (so the place you are at is kept); the same text as credits.html */
.sheet { padding: 0; border-radius: 18px; color: var(--ink); background: rgba(13, 14, 18, .84); width: min(720px, calc(100vw - 32px)); max-height: min(840px, calc(100dvh - 48px)); overflow: hidden; }
.sheet[open] { display: flex; flex-direction: column; animation: sheet-in .28s cubic-bezier(.2, .8, .2, 1); }
.sheet::backdrop { background: rgba(0, 0, 0, .5); animation: fadein .25s ease; }
.sheet.closing { opacity: 0; transform: translateY(8px) scale(.985); transition: opacity .16s ease, transform .16s ease; }
.sheet.closing::backdrop { opacity: 0; transition: opacity .16s ease; }
@keyframes sheet-in { from { opacity: 0; transform: translateY(12px) scale(.98); } }
.sheet .body { overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.sheet .page { max-width: none; padding: 30px 30px 40px; }
.sheet .page h1 { padding-right: 40px; }
.sheet .close { position: absolute; z-index: 1; top: 12px; right: 12px; width: 34px; height: 34px; padding: 0; justify-content: center; } .sheet .close svg { width: 14px; height: 14px; }
.sheet .body:focus { outline: none; }
@media (max-width: 640px) { .sheet .page { padding: 24px 20px 32px; } }
