/* Astrowise — liquid glass over a slow-moving starfield. Dark only. */

:root {
  --bg: #04050a;
  /* text greys, readable on the dark panels: about 13:1, 9:1, 6.5:1 and 4:1 */
  --ink: #f3f6ff;
  --ink-2: rgba(232, 238, 255, 0.8);
  --ink-3: rgba(222, 230, 255, 0.65);
  --ink-4: rgba(222, 230, 255, 0.48);
  --line: rgba(255, 255, 255, 0.1);
  --line-2: rgba(255, 255, 255, 0.16);
  --tint: rgba(16, 20, 38, 0.38);
  --tint-strong: rgba(12, 15, 30, 0.6);
  --tile: rgba(255, 255, 255, 0.055);
  --tile-hover: rgba(255, 255, 255, 0.095);
  --accent: #a9cbff;
  --accent-ink: #cfe2ff;
  --accent-glow: rgba(120, 170, 255, 0.32);
  /* one status scale, from great to bad, for verdicts, scores and badges on every page */
  --st-1: #8ef0b5;
  --st-2: #c4ee9c;
  --st-3: #ffd59e;
  --st-4: #ffbf91;
  --st-5: #ffb3b3;
  /* "probably cloudy" (a clear-sky chance under 20%): a red-orange, set apart from the amber of
     "clear spells possible" */
  --cloudy: #ff9d76;
  --good: var(--st-1);
  --warn: var(--st-3);
  --bad: var(--st-5);
  /* one type scale; --text is the text size setting (Me), which reading text follows */
  --text: 1;
  --fs-1: calc(11px * var(--text));
  --fs-2: calc(12px * var(--text));
  --fs-3: calc(13px * var(--text));
  --fs-4: calc(14px * var(--text));
  --fs-5: calc(15px * var(--text));
  --fs-6: calc(17px * var(--text));
  --fs-7: calc(20px * var(--text));
  --fs-8: calc(25px * var(--text));
  --fs-9: calc(30px * var(--text));
  /* spacing steps */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --r-xl: 30px;
  --r-lg: 22px;
  --r-md: 16px;
  --r-sm: 12px;
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);
  --spring: cubic-bezier(0.34, 1.4, 0.64, 1);
  --font: ui-sans-serif, -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --card-h: 260px;
  --top-h: 72px;
  --bottom-h: 0px; /* the phone's tab bar */
  color-scheme: dark;
}
/* Reading settings from Me, set on <html> by the page's head before the first frame (sf-boot):
   larger text, and solid panels instead of glass (easier to read, and lighter on the graphics). */
html[data-text="1.15"] { --text: 1.15; }
html[data-text="1.3"] { --text: 1.3; }
html[data-panels="solid"] { --tint: rgba(14, 17, 32, 0.94); --tint-strong: rgba(10, 12, 24, 0.97); }
html[data-panels="solid"] .glass { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; }
html[data-panels="solid"] .glass::after { display: none; }

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }
/* no blue flash where a finger taps (Android draws one by default); buttons show their own pressed state */
html { -webkit-tap-highlight-color: transparent; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: var(--fs-5)/1.45 var(--font);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
  overscroll-behavior: none;
}

button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; }
a { color: inherit; }
img { display: block; max-width: 100%; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

:focus { outline: none; }
:focus-visible {
  outline: 2px solid rgba(170, 205, 255, 0.95);
  outline-offset: 3px;
}

.ico { width: 20px; height: 20px; flex: none; }

/* ---------- sky ---------- */

.sky { position: fixed; inset: 0; z-index: 0; overflow: hidden; background: radial-gradient(ellipse 120% 90% at 50% 38%, #0b1126 0%, #070a16 45%, #03040a 100%); }
.sky canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.nebula {
  position: absolute; inset: -12%;
  background:
    radial-gradient(ellipse 38% 30% at 72% 22%, rgba(110, 76, 190, 0.22), transparent 70%),
    radial-gradient(ellipse 32% 26% at 22% 70%, rgba(32, 120, 150, 0.18), transparent 70%),
    radial-gradient(ellipse 28% 20% at 58% 78%, rgba(160, 60, 120, 0.12), transparent 72%),
    radial-gradient(ellipse 60% 16% at 46% 46%, rgba(120, 140, 220, 0.08), transparent 75%);
  /* in small steps, twice a second: smooth to the eye at this pace, while the glass over it (whose
     blur is worked out again whenever what's behind changes) isn't redrawn 120 times a second;
     the gradients are soft enough without a blur filter of their own */
  animation: drift 160s steps(320) infinite alternate;
}
@keyframes drift {
  from { transform: scale(1) rotate(0deg); }
  to { transform: scale(1.12) rotate(4deg); }
}
.vignette { position: absolute; inset: 0; background: radial-gradient(ellipse 85% 75% at 50% 45%, transparent 55%, rgba(0, 0, 0, 0.55) 100%); pointer-events: none; }
/* background scenes (backdrops.js): the drawn scene fades in over the CSS glow */
#backdrop { opacity: 0; }
body[data-backdrop]:not([data-backdrop="drift"]) #backdrop { opacity: 1; }
.sky.ready #backdrop, .sky.ready .nebula, .sky.ready #stars { transition: opacity 1.6s ease; }
body[data-backdrop]:not([data-backdrop="drift"]) .nebula { opacity: 0; }
#stars { opacity: var(--stars-opacity, 1); }

/* ---------- glass ---------- */

.glass {
  position: relative;
  isolation: isolate;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.085), rgba(255, 255, 255, 0.025) 60%, rgba(255, 255, 255, 0.04)), var(--tint);
  -webkit-backdrop-filter: blur(20px) saturate(175%);
  backdrop-filter: blur(20px) saturate(175%);
  border-radius: var(--r-xl);
  box-shadow:
    inset 0 1px 0.5px rgba(255, 255, 255, 0.42),
    inset 0 -1px 0.5px rgba(255, 255, 255, 0.08),
    inset 0 0 0 0.5px rgba(255, 255, 255, 0.1),
    inset 0 22px 34px -26px rgba(255, 255, 255, 0.22),
    0 28px 70px rgba(0, 0, 0, 0.5),
    0 6px 20px rgba(0, 0, 0, 0.3);
}
.glass::before {
  content: "";
  position: absolute; inset: 0; z-index: 3;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.1) 26%, rgba(255, 255, 255, 0) 48%, rgba(255, 255, 255, 0.06) 70%, rgba(255, 255, 255, 0.42));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
}
.glass::after {
  content: "";
  position: absolute; inset: 0; z-index: 0;
  border-radius: inherit;
  background: radial-gradient(520px circle at var(--lx, 22%) var(--ly, -30%), rgba(255, 255, 255, 0.09), transparent 62%);
  pointer-events: none;
}
.glass > * { position: relative; z-index: 2; }

/* ---------- top bar ---------- */

.topbar {
  position: fixed; inset: 0 0 auto; z-index: 30;
  padding: 14px max(20px, env(safe-area-inset-right)) 0 max(20px, env(safe-area-inset-left));
  display: flex; flex-direction: column; gap: 12px;
  pointer-events: none;
  container: topbar / inline-size;
}
.topbar-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 12px; }
.subnav { display: none; justify-content: center; }
.topbar-row > *, .subnav > *, .cats-menu { pointer-events: auto; }
.top-start { justify-self: start; display: flex; align-items: center; gap: 10px; min-width: 0; }

/* A section with more than one page shows them in a second row (Home and Me have none). */
body:is([data-section="tonight"], [data-section="sky"], [data-section="learn"], [data-section="gear"]) { --top-h: 132px; }
body:is([data-section="tonight"], [data-section="sky"], [data-section="learn"], [data-section="gear"]) .subnav { display: flex; }

.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; justify-self: start; color: var(--ink); }
.brand-mark { width: 30px; height: 30px; color: #dce8ff; filter: drop-shadow(0 0 10px rgba(150, 190, 255, 0.45)); }
.brand-name { font-weight: 600; font-size: 17px; letter-spacing: -0.01em; }

.cats, .mainnav { display: flex; padding: 5px; gap: 2px; border-radius: 999px; }
.cats a, .mainnav a {
  position: relative; z-index: 2;
  display: inline-flex; align-items: center; gap: 8px;
  height: 38px; padding: 0 16px 0 13px;
  border-radius: 999px;
  text-decoration: none;
  color: var(--ink-2);
  font-size: 14px; font-weight: 500;
  transition: color 0.3s var(--ease);
}
@media (hover: hover) { .cats a:hover, .mainnav a:hover { color: var(--ink); } }
.cats a[aria-current="page"], .mainnav a[aria-current="page"] { color: #fff; }
.cats a .ico, .mainnav a .ico { width: 19px; height: 19px; }
.cats-blob {
  position: absolute; z-index: 1; top: 5px; left: 0;
  height: 38px; width: 40px;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0.08));
  box-shadow: inset 0 1px 0.5px rgba(255, 255, 255, 0.55), inset 0 -1px 0.5px rgba(255, 255, 255, 0.12), 0 4px 14px rgba(0, 0, 0, 0.25), 0 0 18px rgba(140, 180, 255, 0.18);
  transform-origin: center;
  pointer-events: none;
}

.top-actions { justify-self: end; display: flex; align-items: center; gap: 8px; }
.icon-btn {
  width: 42px; height: 42px; border-radius: 999px;
  display: inline-grid; place-items: center;
  color: var(--ink-2);
  transition: color 0.2s, transform 0.3s var(--spring);
}
@media (hover: hover) { .icon-btn:hover { color: var(--ink); transform: scale(1.06); } }
.icon-btn:active { transform: scale(0.96); }
.icon-btn[aria-pressed="true"] { color: var(--accent-ink); }
.icon-btn[hidden] { display: none; }
/* The assistant's buttons wait until it's connected (main.js sets ask-off until then). */
html.ask-off :is(.sky-ask, .uni-ask, .tg-ask, .ln-ask, [data-ask-home]) { display: none; }
a.icon-btn { text-decoration: none; }
.me-btn[aria-current="page"] { color: var(--accent-ink); box-shadow: inset 0 0 0 1.5px rgba(176, 210, 255, 0.55), 0 0 18px rgba(140, 180, 255, 0.22); }

/* The section pills shed their icons as the row narrows. The query measures the topbar's content
   box (the viewport less 40px), so iOS safe-area insets in landscape count too. Below 760px the
   sections are the tab bar instead. */
@container topbar (max-width: 739px) {
  .mainnav a { padding: 0 15px; }
  .mainnav a .ico { display: none; }
}

/* ---------- the phone's tab bar ----------
   Nearly solid rather than glass: a blur over the moving stars would be worked out again every
   frame. Over the full-screen sky map, 3D universe and cloud map it steps aside, and the Menu pill
   by the logo brings it back. */
.tabbar, .sections-btn { display: none; }
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  height: var(--bottom-h);
  padding: 0 max(4px, env(safe-area-inset-right)) env(safe-area-inset-bottom) max(4px, env(safe-area-inset-left));
  background: rgba(8, 10, 20, 0.96);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09), 0 -10px 30px rgba(0, 0, 0, 0.35);
  transition: transform 0.32s var(--ease), visibility 0s;
}
.tabbar a {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  min-width: 0; text-decoration: none;
  color: var(--ink-3); font-size: 11.5px; font-weight: 600; letter-spacing: 0.01em;
  -webkit-tap-highlight-color: transparent;
}
.tab-ico { width: 54px; height: 30px; border-radius: 999px; display: grid; place-items: center; transition: background 0.25s var(--ease); }
.tab-ico .ico { width: 22px; height: 22px; }
.tabbar a[aria-current="page"] { color: var(--ink); }
.tabbar a[aria-current="page"] .tab-ico { background: rgba(160, 200, 255, 0.17); color: var(--accent-ink); }
.tabbar a:active .tab-ico { background: rgba(255, 255, 255, 0.1); }

.sections-btn {
  align-items: center; gap: 6px; height: 38px; padding: 0 13px 0 11px; border-radius: 999px;
  color: var(--ink-2); font-size: 13.5px; font-weight: 600;
}
.sections-btn .ico { width: 18px; height: 18px; }
.sections-btn[aria-expanded="true"] { color: var(--accent-ink); }

/* ---------- product field ---------- */

main { position: relative; z-index: 2; height: 100dvh; overflow: hidden; }
.field { position: absolute; inset: 0; z-index: 4; overflow: hidden; }

body:has(#detail:not([hidden]), #about:not([hidden]), .gear-modal:not([hidden])) :is(.pf-float, .nebula) { animation-play-state: paused; }

.status {
  position: absolute; left: 50%; z-index: 6;
  bottom: calc(var(--card-h) + 34px);
  transform: translateX(-50%) translateY(var(--lift, 0px));
  width: min(820px, calc(100% - 32px));
  margin: 0; text-align: center;
  font-size: var(--fs-3); color: var(--ink-2);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.9);
  pointer-events: none;
}
.status b { color: var(--ink); font-weight: 600; }

/* ---------- wizard card ---------- */

.wizard {
  position: absolute; left: 50%; z-index: 10;
  bottom: max(22px, env(safe-area-inset-bottom));
  transform: translateX(-50%) translateY(var(--lift, 0px));
  width: min(860px, calc(100% - 32px));
  padding: 16px 18px 18px;
  border-radius: var(--r-xl);
  overflow: hidden;
}
/* a change of size slides the card and the status line above it (wizard.js fit) */
.wizard.lifting, .status.lifting { transition: transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1); }
.btn-primary {
  flex: 1; height: 50px; border-radius: 16px;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.94), rgba(222, 232, 255, 0.86));
  color: #0b1226; font-weight: 600; font-size: var(--fs-5);
  box-shadow: inset 0 1px 0 #fff, inset 0 -1px 0 rgba(0, 0, 40, 0.15), 0 8px 26px rgba(120, 170, 255, 0.25);
  transition: transform 0.35s var(--spring), box-shadow 0.3s, opacity 0.3s;
}
@media (hover: hover) { .btn-primary:hover:not(:disabled) { transform: translateY(-1px); box-shadow: inset 0 1px 0 #fff, 0 12px 34px rgba(120, 170, 255, 0.35); } }
.btn-primary:active:not(:disabled) { transform: scale(0.985); }
.btn-primary:disabled { opacity: 0.35; cursor: default; }
.btn-primary .ico { width: 18px; height: 18px; }
.btn-ghost {
  height: 50px; padding: 0 18px; border-radius: 16px;
  background: rgba(255, 255, 255, 0.07); color: var(--ink);
  font-weight: 600;
  box-shadow: inset 0 0.5px 0 rgba(255, 255, 255, 0.25);
  transition: background 0.2s;
}
@media (hover: hover) { .btn-ghost:hover { background: rgba(255, 255, 255, 0.12); } }

/* ---------- modal sheet ---------- */

.modal { position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: 24px; }
.modal[hidden] { display: none; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(2, 3, 9, 0.5); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); animation: fade 0.35s var(--ease); }
@keyframes fade { from { opacity: 0; } }
@keyframes unfrost { to { -webkit-backdrop-filter: none; backdrop-filter: none; } }
@keyframes rise { from { opacity: 0; transform: translateY(18px) scale(0.985); } }

.sheet-close { position: absolute !important; top: 14px; right: 14px; z-index: 6 !important; background: rgba(255, 255, 255, 0.07); }
.fineprint { margin: 14px 0 0; font-size: var(--fs-2); color: var(--ink-4); }

/* ---------- palette ---------- */

.palette { align-items: start; padding-top: 12vh; }
.palette-box { width: min(660px, 100%); border-radius: 26px; --tint: var(--tint-strong); animation: rise 0.35s var(--ease); overflow: hidden; }
.palette-field { display: flex; align-items: center; gap: 12px; padding: 0 18px; height: 62px; border-bottom: 1px solid var(--line); }
.palette-icon { color: var(--ink-3); display: grid; }
.palette-field input { flex: 1; height: 100%; background: transparent; border: 0; font-size: var(--fs-6); color: var(--ink); }
.palette-field input::placeholder { color: var(--ink-4); }
.palette-field input::-webkit-search-cancel-button { display: none; }
kbd { font: 600 11px var(--font); color: var(--ink-3); padding: 3px 7px; border-radius: 6px; background: rgba(255, 255, 255, 0.08); }
.palette-results { list-style: none; margin: 0; padding: 8px; max-height: min(58vh, 520px); overflow-y: auto; }
.palette-results li { border-radius: 14px; }
.palette-results button { width: 100%; display: grid; grid-template-columns: 44px 1fr auto; gap: 12px; align-items: center; padding: 7px 10px; border-radius: 14px; text-align: left; }
@media (hover: hover) { .palette-results button:hover { background: rgba(255, 255, 255, 0.08); } }
.palette-results li[aria-selected="true"] button { background: rgba(255, 255, 255, 0.08); }
.palette-results img { width: 44px; height: 44px; object-fit: contain; }
.palette-results button > span:nth-child(2) { min-width: 0; }
.palette-results .pr-ico { width: 44px; height: 44px; display: grid; place-items: center; border-radius: 13px; background: rgba(160, 200, 255, 0.1); color: var(--accent-ink); }
.palette-results .pr-ico .ico { width: 20px; height: 20px; }
.palette-results .pr-name { font-weight: 600; font-size: var(--fs-4); }
.palette-results .pr-meta { display: inline-block; max-width: 100%; font-size: var(--fs-2); color: var(--ink-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; vertical-align: top; }
.palette-results .pr-cat { font-size: var(--fs-2); color: var(--ink-3); padding: 3px 8px; border-radius: 99px; background: rgba(255, 255, 255, 0.06); }
.palette-empty { padding: 26px; text-align: center; color: var(--ink-3); font-size: var(--fs-4); }

/* ---------- about ---------- */

.about-box { width: min(580px, 100%); max-height: calc(100dvh - 48px); overflow-y: auto; padding: 30px 32px 26px; border-radius: 28px; --tint: var(--tint-strong); animation: rise 0.4s var(--ease); }
.about-box h2 { margin: 0 0 10px; font-size: var(--fs-7); letter-spacing: -0.015em; }
.about-box h3 { margin: 18px 0 4px; font-size: var(--fs-3); text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-3); }
.about-box p { margin: 0 0 8px; color: var(--ink-2); font-size: var(--fs-5); }
.about-prefs { margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line); display: flex; gap: 16px; }
.about-prefs label { display: flex; align-items: center; gap: 10px; font-size: var(--fs-4); color: var(--ink-2); }
.about-prefs select { height: 36px; padding: 0 10px; border-radius: 10px; background: rgba(255, 255, 255, 0.08); border: 1px solid var(--line-2); color: var(--ink); }

.glass-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---------- accessories menu ---------- */

.cats-more {
  position: relative; z-index: 2;
  display: inline-flex; align-items: center; gap: 7px;
  height: 38px; padding: 0 10px 0 13px;
  border-radius: 999px;
  color: var(--ink-2); font-size: 14px; font-weight: 500;
  transition: color 0.3s var(--ease);
}
@media (hover: hover) { .cats-more:hover { color: var(--ink); } }
.cats-more[aria-expanded="true"] { color: var(--ink); }
.cats-more[aria-current="page"] { color: #fff; }
.cats-more .ico { width: 19px; height: 19px; }
.cats-more .chev { width: 14px; height: 14px; opacity: 0.7; transition: transform 0.3s var(--ease); }
.cats-more[aria-expanded="true"] .chev { transform: rotate(180deg); }

.cats-menu {
  position: absolute; z-index: 40;
  top: calc(var(--top-h) + 6px); left: 50%;
  transform: translateX(-50%);
  width: min(620px, calc(100% - 24px));
  display: grid; grid-template-columns: 1fr 1fr; gap: 6px; grid-auto-flow: dense;
  padding: 12px;
  border-radius: 26px;
  --tint: var(--tint-strong);
  animation: drop 0.28s var(--ease);
}
.cats-menu[hidden] { display: none; }
.cats-menu-group[data-group="Imaging"] { grid-column: 2; grid-row: span 2; }
@keyframes drop { from { opacity: 0; transform: translate(-50%, -8px) scale(0.98); } }
.cats-menu-group p { margin: 4px 10px 6px; font-size: 11.5px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-3); }
.cats-menu a {
  display: grid; grid-template-columns: 34px 1fr; gap: 10px; align-items: center;
  padding: 9px 10px; border-radius: 16px;
  text-decoration: none; color: var(--ink);
  transition: background 0.2s;
}
@media (hover: hover) { .cats-menu a:hover { background: rgba(255, 255, 255, 0.08); outline: none; } }
.cats-menu a:focus-visible { background: rgba(255, 255, 255, 0.08); outline: none; }
.cats-menu a[aria-current="page"] { background: rgba(160, 200, 255, 0.14); box-shadow: inset 0 0 0 1px rgba(176, 210, 255, 0.35); }
.cats-menu a .ico { width: 34px; height: 34px; padding: 7px; border-radius: 11px; background: rgba(255, 255, 255, 0.07); color: #dbe7ff; }
.cats-menu b { display: block; font-size: 14px; font-weight: 600; }
.cats-menu small { display: block; font-size: 12px; color: var(--ink-3); line-height: 1.3; }

/* ---------- responsive ---------- */

@media (max-width: 760px) {
  :root { --top-h: 62px; --bottom-h: calc(62px + env(safe-area-inset-bottom)); }
  body:is([data-section="tonight"], [data-section="sky"], [data-section="learn"], [data-section="gear"]) { --top-h: 120px; }
  .topbar { padding-top: 10px; gap: 12px; padding-left: 12px; padding-right: 12px; }
  .topbar-row { grid-template-columns: auto 1fr auto; gap: 8px; }
  .mainnav { display: none; }
  .tabbar { display: grid; }
  .cats a { padding: 0 12px; height: 36px; }
  .cats-more { height: 36px; padding: 0 9px 0 12px; gap: 6px; }
  .cats-menu { top: calc(var(--top-h) + 4px); max-height: calc(100dvh - var(--top-h) - var(--bottom-h) - 14px); overflow-y: auto; overscroll-behavior: contain; }
  .cats-blob { height: 36px; }
  .icon-btn { width: 38px; height: 38px; }
  /* the sky map, the 3D universe and the cloud map keep the whole screen: the tab bar waits below
     until the Menu pill calls it */
  body:is([data-view="sky"], [data-view="universe"], [data-view="clouds"]) { --bottom-h: 0px; }
  body:is([data-view="sky"], [data-view="universe"], [data-view="clouds"]) .tabbar { height: calc(62px + env(safe-area-inset-bottom)); }
  body:is([data-view="sky"], [data-view="universe"], [data-view="clouds"]) .tabbar:not(.shown) { transform: translateY(105%); visibility: hidden; transition: transform 0.32s var(--ease), visibility 0s 0.32s; }
  body:is([data-view="sky"], [data-view="universe"], [data-view="clouds"]) .sections-btn { display: inline-flex; }
  body:is([data-view="sky"], [data-view="universe"], [data-view="clouds"]) .brand-name { display: none; }
  .wizard { width: calc(100% - 16px); bottom: calc(var(--bottom-h) + 8px); padding: 12px 10px 12px; border-radius: 26px; }
  .status { font-size: var(--fs-2); bottom: calc(var(--card-h) + var(--bottom-h) + 18px); }
  .modal { padding: 0; }
  .palette { padding: 10px; }
  .about-box { padding: 24px 20px; }
}

/* ---------- the app's opening (index.html; main.js endSplash) ----------
   The galaxy swirls in, turning in its tilted plane as its core lights up and its four-point star pops
   out, among stars coming out; then it swells and fades as the page comes in: the bars from above, the
   tab bar from below, the page's parts one after another. */
#splash { display: none; }
html.booting #splash, #splash.gone { position: fixed; inset: 0; z-index: 1000; display: block; background: #05060b; color: #dce8ff; }
#splash::before { content: ""; position: absolute; inset: 0; background: radial-gradient(ellipse 80% 60% at 50% var(--sp-y, 47%), #0c1431, rgba(12, 20, 49, 0.62) 32%, rgba(12, 20, 49, 0.26) 56%, rgba(12, 20, 49, 0.08) 76%, transparent 92%); } /* (eased to nothing, so its edge doesn't show) */
#splash.gone { opacity: 0; pointer-events: none; transition: opacity 0.5s ease; }
.sp-sky i { position: absolute; left: var(--x); top: var(--y); width: var(--s); height: var(--s); border-radius: 50%; background: #fff; box-shadow: 0 0 6px rgba(200, 220, 255, 0.8); opacity: 0; animation: sp-twinkle 3.2s var(--d) ease-in-out infinite; }
/* the mark with the app icon's proportions, as Android's splash shows the icon: its 64-unit square is the
   icon's visible 72 dp, 158.6 px across (centred at --sp-y, set in the app to where that was) */
.sp-tile, .sp-mark { position: absolute; left: 50%; top: var(--sp-y, 47%); }
.sp-tile { display: none; width: 156px; height: 156px; margin: -78px 0 0 -78px; border-radius: 34%; background: radial-gradient(circle 117px at 50% 42%, #1d2a5c, #05070f); }
.sp-mark { width: 158.6px; height: 158.6px; margin: -79.3px 0 0 -79.3px; overflow: visible; filter: drop-shadow(0 0 16px rgba(150, 190, 255, 0.4)); transition: transform 0.6s var(--ease); }
/* (the galaxy and its core turn and grow about the galaxy's own middle, the origin of their group) */
.sp-gal { opacity: 0; transform-box: view-box; transform-origin: 0 0; animation: sp-swirl 1.1s 0.05s var(--ease) forwards; }
.sp-core { opacity: 0; transform-box: view-box; transform-origin: 0 0; animation: sp-core 0.7s 0.35s var(--spring) forwards; }
.sp-dots { opacity: 0; animation: sp-show 0.8s 0.5s ease forwards; }
.sp-spark { fill: #fff; opacity: 0; transform-box: fill-box; transform-origin: center; animation: sp-pop 0.55s 0.7s var(--spring) forwards, sp-glint 2.6s 1.25s ease-in-out infinite; }
#splash.gone .sp-mark { transform: scale(1.12); }
/* in the app it carries on from Android's splash: the icon as it was, whose tile fades as the glow comes
   up, the galaxy already there */
html.sp-app #splash::before { opacity: 0; animation: sp-show 0.9s 0.1s ease forwards; }
html.sp-app .sp-tile { display: block; animation: sp-hide 0.55s 0.12s ease forwards; }
html.sp-app .sp-mark { animation: sp-glow 0.9s 0.1s ease both; }
html.sp-app :is(.sp-gal, .sp-core, .sp-dots) { opacity: 1; animation: none; }
html.sp-app .sp-spark { opacity: 1; animation: sp-glint 2.6s 0.35s ease-in-out infinite; }
@keyframes sp-show { to { opacity: 1; } }
@keyframes sp-hide { to { opacity: 0; } }
@keyframes sp-glow { from { filter: drop-shadow(0 0 0 rgba(150, 190, 255, 0)); } }
@keyframes sp-swirl { from { opacity: 0; transform: rotate(-150deg) scale(0.35); } 40% { opacity: 1; } to { opacity: 1; transform: none; } }
@keyframes sp-core { 0% { opacity: 0; transform: scale(0.2); } 60% { opacity: 1; transform: scale(1.25); } 100% { opacity: 1; transform: none; } }
@keyframes sp-pop { 0% { opacity: 0; transform: scale(0.2) rotate(-60deg); } 65% { opacity: 1; transform: scale(1.3) rotate(10deg); } 100% { opacity: 1; transform: none; } }
@keyframes sp-glint { 0%, 100% { transform: none; } 50% { transform: scale(0.8) rotate(45deg); } }
@keyframes sp-twinkle { 0%, 100% { opacity: 0; transform: scale(0.4); } 50% { opacity: 0.85; transform: scale(1); } }
html.revealing .topbar-row { animation: boot-down 0.6s var(--ease) both; }
html.revealing .subnav { animation: boot-down 0.6s 0.08s var(--ease) both; }
html.revealing body:not([data-view="sky"], [data-view="universe"], [data-view="clouds"]) .tabbar { animation: boot-up 0.6s 0.12s var(--ease) both; }
html.revealing .page-wrap > * { animation: boot-up 0.65s 0.46s var(--ease) both; }
html.revealing .page-wrap > :nth-child(1) { animation-delay: 0.14s; }
html.revealing .page-wrap > :nth-child(2) { animation-delay: 0.22s; }
html.revealing .page-wrap > :nth-child(3) { animation-delay: 0.3s; }
html.revealing .page-wrap > :nth-child(4) { animation-delay: 0.38s; }
@keyframes boot-down { from { opacity: 0; transform: translateY(-16px); } }
@keyframes boot-up { from { opacity: 0; transform: translateY(26px); } }

/* The weather pictures (tonight.js's wx), from 32 px up: clouds drift, rain falls, the Sun's rays turn
   and stars twinkle, gently and out of step. Still with reduced motion, or with motion switched off. */
/* (a moving picture's still drawing and its moving layers, stacked; each layer moves as a whole) */
span.wx { position: relative; display: inline-block; flex: none; width: var(--wx); height: var(--wx); vertical-align: middle; }
span.wx > svg, span.wx > i, span.wx > i > svg { position: absolute; inset: 0; display: block; width: 100%; height: 100%; }
/* (in steps, a few a second, as the background's nebula moves: each change has the page drawn again) */
.wx-live > .wx-cloud { animation: wx-drift 7s steps(21) infinite alternate; }
.wx-live > .wx-drops { animation: wx-rain 0.9s steps(6) infinite; }
.wx-live > .wx-rays { animation: wx-turn 36s steps(108) infinite; }
.wx-live > .wx-stars { animation: wx-twinkle 3.2s steps(10) infinite; }
@keyframes wx-drift { from { transform: translateX(-3.75%); } to { transform: translateX(3.75%); } }
@keyframes wx-rain { 0% { transform: translate(2.5%, -7.8%); opacity: 0; } 25%, 75% { opacity: 1; } 100% { transform: translate(-2.5%, 7.8%); opacity: 0; } }
@keyframes wx-turn { to { transform: rotate(360deg); } }
@keyframes wx-twinkle { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
html.still .wx-live > i { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .wx-live > i { animation: none; }
  .nebula, .pf-float { animation: none; }
  .pf { transition-duration: 0.01s; }
  .wz-pane { transition-duration: 0.01s; }
}

@media (prefers-reduced-transparency: reduce) {
  :root { --tint: rgba(14, 17, 32, 0.92); --tint-strong: rgba(10, 12, 24, 0.97); }
}

@media (max-width: 430px) {
  .topbar-row { gap: 6px; }
  .top-actions { gap: 6px; }
}
/* the kinds menu on a phone: names only, two columns, all of it in view */
@media (max-width: 520px) {
  .cats-menu { padding: 10px 8px; gap: 2px 4px; }
  .cats-menu small { display: none; }
  .cats-menu a { grid-template-columns: 30px 1fr; gap: 9px; padding: 7px 8px; border-radius: 13px; }
  .cats-menu a .ico { width: 30px; height: 30px; padding: 6px; border-radius: 9px; }
  .cats-menu b { font-size: 14px; }
  .cats-menu-group p { margin: 4px 8px 4px; font-size: 11px; }
}

/* The second row on a phone: labels, which say more than the icons, keep their room; the padding
   shares what's left (four labels and the row's own padding take about 230px). */
@container topbar (max-width: 431px) {
  #secnav { gap: 0; }
  #secnav a .ico, #secnav .cats-more > .ico:first-child { display: none; }
  #secnav a, #secnav .cats-more { padding: 0 clamp(7px, (100cqw - 230px) / 8, 12px); }
  #secnav .cats-more { padding-right: clamp(5px, (100cqw - 230px) / 10, 9px); }
}

/* Night vision: the whole site in dim red, like a planetarium program's night mode, so it doesn't
   spoil eyes adapted to the dark. One layer over everything multiplies it by red, so red light is all
   that's left, as bright as the level set on the Me page (--night-level, 0.3–1). It covers the pages,
   the sky map and 3D universe, the header's stars and every photo alike. A blend like this is cheap
   to draw; the grey filter it replaced was worked out again over the moving stars every frame. */
html[data-night]::after {
  content: ""; position: fixed; inset: 0; z-index: 2147483647; pointer-events: none;
  background: rgb(calc(255 * var(--night-level, 0.7)) 0 0); mix-blend-mode: multiply;
}
html.night-in[data-night]::after { animation: night-in 1s ease-out both; }
html.night-out[data-night]::after { animation: night-out 3.5s ease-in-out both; }
@keyframes night-in { from { background: #fff; } }
@keyframes night-out { to { background: #fff; } }
@media print {
  html[data-night]::after { display: none; }
}

/* ---------- a phone on its side ----------
   Little height to spare: the top bar and a section's second row slim down, and --top-h with them. */
@media (max-height: 520px) and (orientation: landscape) {
  :root { --top-h: 50px; }
  html body:is([data-section="tonight"], [data-section="sky"], [data-section="learn"], [data-section="gear"]) { --top-h: 92px; }
  .topbar { padding-top: 6px; gap: 4px; }
  .cats, .mainnav { padding: 4px; }
  .cats a, .mainnav a { height: 32px; }
  .cats-blob { top: 4px; height: 32px; }
  .icon-btn { width: 38px; height: 38px; }
}
