:root {
  --panel: rgba(10, 14, 24, 0.72);
  --edge: rgba(140, 170, 220, 0.16);
  --ink: #e8edf7;
  --dim: #8f9db8;
  --accent: #7fb2ff;
  --warm: #ffd9a0;
  --radius: 14px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  background: #000;
  color: var(--ink);
  font: 13px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
  -webkit-text-size-adjust: 100%;
}

/* ------------------------- collapsible panels -------------------------- */
.panelHead {
  display: none;                 /* desktop keeps panels always open */
  width: 100%;
  align-items: center;
  gap: 7px;
  padding: 9px 11px;
  background: none;
  border: 0;
  font: 600 11.5px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
  text-align: left;
  cursor: pointer;
}
.panelHead .chev { transition: transform 0.2s; font-size: 10px; }
.collapsed .panelHead { color: var(--ink); }
.collapsed .panelHead .chev { transform: rotate(-90deg); }
/* NB: hiding a collapsed body is deliberately NOT declared here. On desktop
   the headers are hidden, so a panel left collapsed by a narrow viewport
   would have no way to reopen and its content would be unreachable. The
   rule lives in the touch block, where a header exists to undo it. */

#sky {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  cursor: grab;
  touch-action: none;
}
#sky.dragging { cursor: grabbing; }

#radar {
  position: fixed;
  right: 14px;
  bottom: 96px;
  width: 132px;
  height: 132px;
  z-index: 9;                 /* below the panels, never floating over them */
  cursor: crosshair;
  border-radius: 50%;
  background: rgba(8, 12, 20, 0.62);
  border: 1px solid var(--edge);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: opacity 0.28s;
}
body.clean #radar { opacity: 0; pointer-events: none; }

button.wide { width: 100%; }

/* what you just tapped */
#idCard {
  position: fixed;
  z-index: 28;
  width: 200px;
  padding: 8px 11px;
  border-radius: 10px;
  background: rgba(10, 14, 24, 0.86);
  border: 1px solid rgba(140, 170, 220, 0.28);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
  opacity: 0;
  pointer-events: none;
  transform: translateY(4px);
  transition: opacity 0.18s, transform 0.18s;
}
#idCard.show { opacity: 1; transform: translateY(0); }
#idCard b { display: block; font-size: 13px; font-weight: 600; color: #f0f5ff; }
#idCard span { display: block; margin-top: 2px; font-size: 11px; color: var(--dim); }
#idCard span:first-of-type { color: #a8c4ee; }
body.clean #idCard, body.titleMode #idCard { opacity: 0; }

#loading {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--dim);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 11px;
  background: #000;
  z-index: 50;
  transition: opacity 0.5s;
}
#loading.gone { opacity: 0; pointer-events: none; }
/* Start-up died. Say why, and stop swallowing taps - an opaque overlay at
   z-index 50 sits above every escape hatch in the app. */
#loading.failed {
  background: rgba(0, 0, 0, 0.86);
  color: #ff9d7a;
  pointer-events: none;
  text-transform: none;
  letter-spacing: 0.02em;
  font-size: 13px;
  padding: 24px;
  text-align: center;
}

/* ------------------------------- title -------------------------------- */
/* Sits over the live scene: Earth keeps spinning and cycling phase behind
   it, so the menu is the simulation rather than a picture of one. Only the
   text and buttons take pointer events. */
#title {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  padding: clamp(14px, 5vh, 46px) 18px calc(clamp(14px, 5vh, 46px) + env(safe-area-inset-bottom));
  pointer-events: none;
  text-align: center;
  background:
    radial-gradient(ellipse at 50% 45%, transparent 30%, rgba(0, 0, 0, 0.55) 78%),
    linear-gradient(180deg, rgba(0, 0, 0, 0.65) 0%, transparent 26%, transparent 68%, rgba(0, 0, 0, 0.75) 100%);
  transition: opacity 0.55s ease, padding 0.4s ease;
}
#title.gone { opacity: 0; pointer-events: none; }
/* With the sheet open, recentre the wordmark and buttons in what is left of
   the screen instead of leaving them centred on the viewport and half hidden. */
body.infoOpen #title { padding-right: calc(18px + min(430px, 45vw)); }
body.titleMode #topbar,
body.titleMode #left,
body.titleMode #right,
body.titleMode #transport,
body.titleMode #radar,
body.titleMode #hint { opacity: 0; pointer-events: none; }

.bigTitle {
  margin: 0;
  font-weight: 600;
  font-size: clamp(23px, 5.6vh, 52px);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #f2f6ff;
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.8);
}
.tagline {
  margin: clamp(5px, 1.4vh, 13px) 0 0;
  font-weight: 500;
  font-size: clamp(10.5px, 1.7vh, 14px);
  letter-spacing: 0.04em;
  color: rgba(198, 214, 240, 0.82);
  max-width: 34em;
  /* On a narrow phone this wraps to two lines and the second crosses Earth's
     top limb. The wordmark already carried a shadow for exactly that reason;
     this line did not, and went grey-on-blue over the daylit side. */
  text-shadow: 0 1px 16px rgba(0, 0, 0, 0.95), 0 0 4px rgba(0, 0, 0, 0.7);
}
.titleBottom { display: flex; gap: 11px; align-items: center; flex-wrap: wrap; justify-content: center; }
#title button, #infoPanel button { pointer-events: auto; }

button.enter {
  width: auto;
  padding: clamp(8px, 1.6vh, 13px) clamp(26px, 5vw, 46px);
  border-radius: 999px;
  font-size: clamp(12px, 1.8vh, 14px);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  background: rgba(127, 178, 255, 0.17);
  border-color: rgba(127, 178, 255, 0.55);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
button.enter:hover { background: rgba(127, 178, 255, 0.3); }
button.info {
  width: auto;
  padding: clamp(8px, 1.6vh, 13px) clamp(16px, 3vw, 24px);
  border-radius: 999px;
  font-size: clamp(11px, 1.6vh, 13px);
  background: rgba(255, 255, 255, 0.05);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* A sheet BESIDE the title, not over it. As a full-screen scrim this hid the
   one thing it was describing - Earth turning through its phases behind the
   wordmark - so opening "What is this?" replaced the view with a wall of text
   about the view. Down one side on a wide screen, across the bottom on a
   phone; either way the sky stays visible while you read. */
#infoPanel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(430px, 45vw);
  z-index: 45;
  display: none;
  padding: 20px 20px calc(20px + env(safe-area-inset-bottom));
  background: rgba(6, 9, 16, 0.9);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-left: 1px solid var(--edge);
  overflow-y: auto;
  overscroll-behavior: contain;
}
#infoPanel.open { display: block; }
.infoInner {
  max-width: none;
  width: 100%;
  overflow: visible;
  padding: 0;
}
.infoInner h2 {
  color: var(--accent);
  margin: 18px 0 7px;
  font-size: 10px;
}
.infoInner h2:first-child { margin-top: 0; }
.infoInner p, .infoInner li { font-size: 13px; line-height: 1.55; color: #d7e0f2; margin: 0 0 9px; }
.infoInner ul { padding-left: 18px; margin: 0 0 9px; }
.infoInner b { color: #fff; font-weight: 600; }
.infoInner button { margin-top: 14px; }

/* ------------------------------- panels -------------------------------- */
.panel {
  position: fixed;
  background: linear-gradient(145deg, rgba(28, 39, 57, 0.78), var(--panel));
  border: 1px solid var(--edge);
  border-radius: var(--radius);
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  box-shadow: inset 0 1px 0 rgba(210, 230, 255, 0.05), 0 8px 40px rgba(0, 0, 0, 0.55);
  z-index: 10;
  transition: opacity 0.28s, transform 0.28s;
}
body.clean .panel, body.clean #hint { opacity: 0; pointer-events: none; transform: translateY(-6px); }
body.clean #topbar { transform: translateY(-16px); }

/* The only way back out of clean mode by pointer. Deliberately not inside any
   panel, since clean mode fades those to zero opacity and a child cannot
   escape a transparent parent. */
#showUI {
  position: fixed;
  top: max(14px, env(safe-area-inset-top));
  right: max(14px, env(safe-area-inset-right));
  z-index: 30;
  width: auto;
  padding: 9px 12px;
  border-radius: 11px;
  font-size: 14px;
  line-height: 1;
  opacity: 0;
  pointer-events: none;
  background: rgba(10, 14, 24, 0.6);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: opacity 0.28s;
}
body.clean #showUI { opacity: 0.5; pointer-events: auto; }
body.clean #showUI:hover, body.clean #showUI:active { opacity: 1; }
body.titleMode #showUI { opacity: 0; pointer-events: none; }

#topbar {
  top: 14px; left: 14px; right: 14px;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 14px;
}
.brand { display: flex; align-items: center; gap: 11px; flex: 1; min-width: 0; }
.brand .dot {
  width: 26px; height: 26px; border-radius: 50%;
  background: radial-gradient(circle at 34% 32%, #f2f2ee 0 38%, #b9bcc0 55%, #6d7176 100%);
  box-shadow: 0 0 18px rgba(200, 215, 255, 0.35);
  flex: none;
}
h1 { font-size: 14px; margin: 0; font-weight: 600; letter-spacing: 0.01em; }
.brand p { margin: 1px 0 0; font-size: 11.5px; color: var(--dim); }

.clock { text-align: right; }
.clockMain { font: 600 15px/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
.clockSub { font: 11px/1.3 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--dim); }

#left  { top: 76px; left: 14px;  width: 244px; padding: 4px 14px 14px; }
#right { top: 76px; right: 14px; width: 244px; padding: 4px 14px 14px; }
#left, #right {
  max-height: calc(100vh - 160px);
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(140, 170, 220, 0.35) transparent;
}

h2 {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--dim);
  margin: 15px 0 8px;
  font-weight: 600;
}

.kv {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding: 2.5px 0;
  font-size: 12px;
}
.kv span { color: var(--dim); }
.kv b { font: 500 12.5px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }

.hint {
  color: var(--dim);
  font-size: 11px;
  line-height: 1.4;
  margin: 9px 0 0;
}

/* Keyboard shortcuts in the info panel. They were live but written down
   nowhere the user could read them. */
.infoInner .keys { line-height: 2.1; }
kbd {
  display: inline-block;
  min-width: 1.35em;
  padding: 1px 5px;
  margin: 0 1px;
  text-align: center;
  font: 600 11px/1.5 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.09);
  border: 1px solid var(--edge);
  border-bottom-width: 2px;
  border-radius: 5px;
}

/* ------------------------------- inputs -------------------------------- */
select, input[type=number], input[type=datetime-local], button {
  font: inherit;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--edge);
  border-radius: 9px;
  padding: 7px 9px;
  width: 100%;
  outline: none;
}
input[type=datetime-local] { font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 12px; }
select:focus, input:focus { border-color: var(--accent); }
/* `outline: none` above stripped the focus ring from BUTTONS too, and the
   rule that put it back only covered select and input - so tabbing round the
   app showed nothing at all. :focus-visible keeps it off mouse clicks. */
select:focus-visible, input:focus-visible, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 9px;
}
select option { background: #0c1220; }

.row2 { display: flex; gap: 8px; margin-top: 8px; }
.row2 label { flex: 1; font-size: 10.5px; color: var(--dim); }
.row2 input { margin-top: 3px; }

.btnRow { display: flex; gap: 7px; margin-top: 8px; }
button {
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s;
}
button:hover { background: rgba(255, 255, 255, 0.12); }
button:active { background: rgba(255, 255, 255, 0.18); }
button.on { background: rgba(127, 178, 255, 0.22); border-color: rgba(127, 178, 255, 0.5); }

.ghost {
  width: auto;
  padding: 5px 9px;
  background: transparent;
  color: var(--dim);
  flex: none;
}

.slider { display: block; margin-top: 12px; font-size: 11px; color: var(--dim); }
.slider b { color: var(--ink); font-weight: 500; }
input[type=range] {
  width: 100%;
  margin-top: 6px;
  accent-color: var(--accent);
  background: transparent;
}
.check { display: flex; align-items: center; gap: 7px; margin-top: 11px; font-size: 11.5px; color: var(--dim); }
.check input { accent-color: var(--accent); }

/* ------------------------------ day bar -------------------------------- */
.daybar {
  position: relative;
  height: 9px;
  border-radius: 5px;
  overflow: hidden;
  margin: 4px 0 9px;
  border: 1px solid var(--edge);
}
.daybar .fill {
  position: absolute; inset: 0;
  background: linear-gradient(90deg,
    #05070d 0%, #05070d 20%, #6b6255 25%, #d8d2c4 33%,
    #f2eee4 50%, #d8d2c4 67%, #6b6255 75%, #05070d 80%, #05070d 100%);
}
.daybar i {
  position: absolute;
  top: -2px; bottom: -2px;
  width: 2px;
  background: var(--accent);
  box-shadow: 0 0 7px var(--accent);
  transform: translateX(-1px);
}

/* ----------------------------- transport ------------------------------- */
/* Centred with auto margins rather than left:50% + translateX. With only
   `left` set, the available width is the space from the 50% mark to the
   right edge - half the viewport - so on a phone the speed chips wrapped
   onto a second row and ate a third of the screen. */
#transport {
  bottom: 14px;
  left: 0;
  right: 0;
  margin-inline: auto;
  width: max-content;
  max-width: calc(100vw - 28px);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 9px 12px;
}
.tRow { display: flex; align-items: center; gap: 7px; }
.chips { justify-content: center; flex-wrap: wrap; }
#transport .chips button {
  width: auto;
  height: 26px;
  padding: 0 11px;
  font-size: 11.5px;
  letter-spacing: 0.01em;
  border-radius: 13px;
}
body.clean #transport { transform: translateY(10px); }
#transport button {
  width: 38px; height: 34px;
  padding: 0;
  display: grid;
  place-items: center;
  font-size: 13px;
  flex: none;
}
#transport button.primary {
  width: 46px;
  background: rgba(127, 178, 255, 0.2);
  border-color: rgba(127, 178, 255, 0.45);
}
.speedBox { padding: 0 10px; min-width: 168px; }
.speedBox b { display: block; font: 600 12.5px ui-monospace, Menlo, Consolas, monospace; }
.speedBox span { display: block; font-size: 10.5px; color: var(--dim); }

/* The first-run nudge. #hint is display:none on touch and in standalone, so a
   phone user has never had any indication that the view can be looked around
   at all - the opening frame reads as a picture of Earth rather than a place
   you are standing. This one shows everywhere, in the strip below the top bar
   that is clear of the side panels and the transport. */
#lookHint {
  position: fixed;
  top: calc(var(--topbarH, 47px) + 20px + env(safe-area-inset-top));
  left: 50%;
  transform: translate(-50%, -6px);
  margin: 0;
  z-index: 30;
  max-width: min(88vw, 30em);
  padding: 8px 15px;
  border-radius: 999px;
  background: rgba(8, 12, 20, 0.72);
  border: 1px solid var(--edge);
  backdrop-filter: blur(9px);
  -webkit-backdrop-filter: blur(9px);
  color: #dbe4f5;
  font-size: 12px;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s ease, transform 0.45s ease;
}
#lookHint.show { opacity: 1; transform: translate(-50%, 0); }
body.titleMode #lookHint { opacity: 0; }

/* Sat at bottom:62px on z-index 9, which is UNDER the transport bar
   (z-index 10, ~88px tall) - the line was there but never once visible.
   Lifted clear of the transport and raised above it. */
#hint {
  position: fixed;
  bottom: calc(var(--transportH, 72px) + 18px + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  color: rgba(160, 175, 200, 0.62);
  font-size: 11px;
  z-index: 12;
  pointer-events: none;
  transition: opacity 0.3s;
}

/* ======================================================================
   TOUCH / PHONE
   Landscape on a phone gives roughly 850x390 css px, so vertical space is
   the scarce resource: panels collapse to a single tappable strip and the
   sky keeps the rest. Zoom moves from a slider to a pinch gesture.
   ====================================================================== */
@media (pointer: coarse), (max-width: 820px), (max-height: 560px) {
  :root { --radius: 12px; }

  .desktopOnly { display: none !important; }
  #hint { display: none; }

  body.infoOpen #title {
    padding-right: 18px;
    padding-bottom: calc(64vh + 12px);
  }

  /* no room for a side sheet - sit across the bottom so the sky and the
     title stay visible above it */
  #infoPanel {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    max-height: 64vh;
    border-left: 0;
    border-top: 1px solid var(--edge);
    padding: 14px 14px calc(14px + env(safe-area-inset-bottom));
  }

  /* 44pt minimum: these were 30px tall and the ghost buttons ~26x31. */
  .panelHead { display: flex; min-height: 44px; }
  .ghost, #showUI { min-width: 44px; min-height: 44px; padding: 5px 9px; }
  .collapsed .panelBody { display: none; }
  .panelBody {
    padding: 0 12px 12px;
    max-height: min(58vh, 320px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }

  #topbar {
    top: max(8px, env(safe-area-inset-top));
    left: max(8px, env(safe-area-inset-left));
    right: max(8px, env(safe-area-inset-right));
    padding: 6px 10px;
    gap: 10px;
  }
  .brand .dot { width: 20px; height: 20px; }
  .brand h1 { font-size: 12px; }
  .brand p { font-size: 10px; }
  .clockMain { font-size: 12.5px; }
  .clockSub { display: none; }

  /* On a 375px phone the brand was the only flexible item, so it collapsed
     to 61px and wrapped BOTH lines onto three each - a 111px header eating
     14% of the screen. Neither line wraps now; the site name ellipsises,
     the app's own name is the thing worth dropping if space runs out, and
     the topbar's other children stop demanding their full width. */
  #topbar { gap: 10px; }
  .brand > div { min-width: 0; }
  .brand h1, .brand p {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .clock { flex: none; }

  /* Panels hang from the top edge, collapsed by default; the bottom strip
     belongs to the transport and the sky map, which must never collide. */
  #left, #right {
    top: calc(var(--topbarH, 47px) + 16px + env(safe-area-inset-top));
    bottom: auto;
    /* 232px cut the last character off "Tranquility Base · Apollo 11" once
       the select's own chevron took its share. */
    /* The other panel hides when this opens, so use the available width. */
    width: min(320px, calc(100vw - 16px - env(safe-area-inset-left) - env(safe-area-inset-right)));
    max-height: none;
    padding: 0;
    overflow: visible;
  }
  #left { left: max(8px, env(safe-area-inset-left)); }
  #right { right: max(8px, env(safe-area-inset-right)); }
  #left.collapsed, #right.collapsed { width: auto; }
  /* only one panel opens at a time, and the other tab steps out of the way
     so the two can never stack into each other */
  body.panelOpen .collapsible.collapsed { display: none; }

  h2 { margin: 12px 0 6px; font-size: 9.5px; }
  .kv { font-size: 11.5px; padding: 2px 0; }
  .kv b { font-size: 11.5px; }
  .hint { font-size: 10.5px; }

  /* fingers need bigger targets than a mouse does */
  select, input[type=number], input[type=datetime-local], button { padding: 9px 10px; }
  input[type=range] { height: 26px; }

  #radar {
    width: 96px; height: 96px;
    right: max(8px, env(safe-area-inset-right));
    bottom: calc(var(--transportH, 72px) + 20px + env(safe-area-inset-bottom));
  }
  /* the radar sits above the panels in stacking order, so on a small
     screen it hides rather than floating over open panel content */
  body.panelOpen #radar { opacity: 0; pointer-events: none; }

  #transport {
    bottom: max(8px, env(safe-area-inset-bottom));
    padding: 6px 8px;
    gap: 6px;
    max-width: calc(100vw - 16px);
  }
  .tRow { gap: 5px; }
  /* Apple's minimum tap target is 44pt. Everything in here was 28-34px. */
  #transport button { width: 44px; height: 44px; font-size: 13px; }
  #transport button.primary { width: 52px; }
  #transport .chips button { height: 44px; padding: 0 12px; font-size: 11px; }
  .speedBox { min-width: 0; padding: 0 6px; }
  .speedBox span { display: none; }
  .speedBox b { font-size: 11.5px; }
}

/* Under 400px there is not room for both the app's name and the site's.
   The site name is the one that changes and the one the sim is about. */
@media (max-width: 400px) {
  /* .brand h1, NOT h1 - the title screen's wordmark is an h1 as well, and a
     bare selector here wiped the app's name off the front of the app. */
  .brand h1 { display: none; }
  /* Side by side, the timestamp is 22 monospace characters and leaves the
     site name about 45px - "Tranq…". They do not both fit on a 375px phone,
     so give each its own line: place on top, clock underneath. Two tidy
     lines, and still half the height of the three-line wrap this replaced. */
  #topbar { flex-wrap: wrap; row-gap: 2px; }
  .brand { flex: 1 1 auto; order: 1; }
  .ghost { order: 2; }
  .clock {
    order: 3;
    flex: 1 1 100%;
    text-align: left;
    padding-left: 31px;                /* line up under the site name */
  }
  .brand p { font-size: 11.5px; }
  .clockMain { font-size: 12px; }
}

/* very short viewports: phone in landscape */
@media (max-height: 440px) {
  #topbar { padding: 5px 9px; }
  .brand p { display: none; }
  .panelBody { max-height: 44vh; }
  #radar { width: 82px; height: 82px; }
  #transport { padding: 5px 7px; gap: 5px; }
  #transport button { height: 30px; width: 32px; }
  #transport button.primary { width: 40px; }
  #transport .chips button { height: 25px; font-size: 10.5px; padding: 0 8px; }
}

/* portrait phone: panels span the width instead of floating narrow */
@media (pointer: coarse) and (orientation: portrait) {
  #left, #right { width: auto; }
  #left { left: 8px; right: 8px; }
  /* stacked under the left tab when both are collapsed; when either opens
     the other tab is hidden, so they cannot collide */
  #right {
    left: 8px; right: 8px;
    top: calc(var(--topbarH, 47px) + 62px + env(safe-area-inset-top));
  }
  #left.collapsed, #right.collapsed { width: auto; }
}

/* installed as an app: no browser chrome to lean on */
@media (display-mode: standalone) {
  #hint { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* The tour leaves the sky clear and keeps its controls reachable on phones. */
body.touring .panel, body.touring #radar, body.touring #showUI,
body.touring #hint, body.touring #lookHint { visibility: hidden; pointer-events: none; }
#tourCard[hidden] { display: none; }
#tourCard {
  position: fixed; z-index: 45; bottom: max(18px, env(safe-area-inset-bottom));
  left: 50%; transform: translateX(-50%); width: min(520px, calc(100% - 24px));
  padding: 18px 22px; color: #e8edf7; border: 1px solid rgba(160,190,220,.24);
  border-radius: 18px; background: linear-gradient(145deg,rgba(23,34,49,.94),rgba(7,12,21,.94));
  box-shadow: 0 12px 40px #0008; backdrop-filter: blur(16px);
}
.tourTop, .tourActions { display:flex; gap:10px; align-items:center; justify-content:space-between; }
#tourCount { font-size:10px; letter-spacing:.14em; color:#a6bdd5; }
#tourCard h2 { font-size:21px; text-transform:none; letter-spacing:-.02em; margin:12px 0 8px; }
#tourText { color:#b6c5d6; font-size:13px; line-height:1.6; margin:0 0 16px; }
#tourCard button { min-height:40px; }
#tourNext { background:#aac6e5; color:#0c1724; border-color:transparent; }
#tourCard button:disabled { opacity:.35; cursor:default; }
@media(max-height:500px) { #tourCard { left:auto; right:12px; transform:none; width:330px; bottom:12px; padding:12px 16px; } #tourCard h2 {font-size:17px;} #tourText {font-size:12px; margin-bottom:10px;} }
@media(max-width:440px) { #tourCard {padding:14px 16px;} #tourCard h2 {font-size:19px;} .titleBottom {flex-wrap:wrap;} }
#tourCard .tourTop button { flex: none; min-height:32px; padding:5px 10px; font-size:11px; }
#tourCount { white-space: nowrap; }
@media(min-width:850px) and (min-height:501px) { #tourCard {left:22px; transform:none; width:400px;} }
#tourCard .tourTop button { width:auto; }
#tourCard .tourTiming {font-size:10px; letter-spacing:.05em; color:#8ca4bf; margin:0 0 10px;}
@media (pointer:coarse), (max-width:600px) {#tourCard button,#tourCard .tourTop button {min-height:44px;}}
/* Navigation remains available when the compact header hides its wordmark. */
#homeTitle {cursor:pointer; border-radius:8px;}
#homeTitle:focus-visible {outline:2px solid var(--accent);outline-offset:5px;}
#homeTitle:hover {filter:brightness(1.2);}
#tourPractice[hidden], #tourPlay[hidden], #tourZoom[hidden] {display:none;}
#tourPractice {display:flex;gap:8px;margin:0 0 10px;}
body.touring.tourSpeed #transport {visibility:visible;pointer-events:auto;}
body.tourSpeed #tourCard {bottom:calc(var(--transportH,120px) + 28px);}
#tourCard {max-height:calc(100dvh - 24px);overflow:auto;}
body.tourSpeed #tourCard {max-height:calc(100dvh - var(--transportH,120px) - 40px);}
#idCard {z-index:48;max-height:calc(100dvh - 24px);overflow:auto;}

/* Refined mobile welcome: existing actions with a clear visual hierarchy. */
.mobileTitleBreak { display:none; }
@media(max-width:700px) and (orientation:portrait) {
  .mobileTitleBreak { display:inline; }
  #title {padding:calc(48px + env(safe-area-inset-top)) 28px calc(22px + env(safe-area-inset-bottom));}
  .titleTop {width:100%;}
  .bigTitle {font-size:clamp(26px,7.6vw,32px);font-weight:600;letter-spacing:.13em;line-height:1.35;}
  .tagline {font-size:13px;line-height:1.65;font-weight:400;letter-spacing:.015em;max-width:290px;margin:18px auto 0;text-wrap:balance;}
  .titleBottom {display:grid;width:100%;gap:12px;}
  #title button {width:100%;min-height:54px;border-radius:16px;font-size:14px;}
  #title #btnEnter {min-height:56px;background:#e3ebf5;color:#111d2c;border:1px solid #ffffff55;font-size:15px;font-weight:600;letter-spacing:.02em;text-transform:none;}
  #title #btnEnter:hover {background:#fff;}
  #title #btnTour {background:#101a2980;border:1px solid #a4b9d63b;color:#dbe6f6;}
  #title #btnInfo {min-height:44px;background:none;border-color:transparent;color:#a7b6c9;backdrop-filter:none;}
}
@media(max-width:700px) and (max-height:740px) and (orientation:portrait) {
  #title {padding-top:28px;padding-bottom:14px;}
  .bigTitle {font-size:26px;}
  .tagline {font-size:12px;margin-top:12px;}
  .titleBottom {gap:8px;}
  #title #btnEnter {min-height:52px;}
  #title #btnTour {min-height:48px;}
}
@media(max-width:700px) and (orientation:portrait) {
  .titleBottom {grid-template-columns:minmax(0,1fr);justify-content:stretch;}
}

/* Opening gesture guide. Arrows explain interaction without moving the sky. */
#lookHint.lookCue {top:55%;bottom:auto;max-width:calc(100vw - 40px);width:310px;padding:16px 20px;text-align:center;white-space:normal;line-height:1.6;background:rgba(8,16,29,.9);border:1px solid rgba(178,207,242,.28);border-radius:20px;box-shadow:0 8px 30px #0005;pointer-events:none;}
#lookHint.lookCue::before {content:'←  ↑  ↓  →';display:block;margin-bottom:8px;color:#e4efff;font-size:28px;line-height:1.2;letter-spacing:6px;}
@media(prefers-reduced-motion:no-preference){#lookHint.lookCue::before{animation:lookCueGlow 1.8s ease-in-out 3;}@keyframes lookCueGlow{50%{opacity:.45}}}

/* Approved Lunar Aspect welcome — local fonts also work in the phone APK. */
@font-face{font-family:Sora;src:url('fonts/sora-regular.ttf') format('truetype');font-weight:400;font-display:swap}
@font-face{font-family:Sora;src:url('fonts/sora-medium.ttf') format('truetype');font-weight:500 600;font-display:swap}
#title{font-family:Sora,Arial,sans-serif}
#title .bigTitle{font-weight:500;line-height:1.08;letter-spacing:.055em}
#title button{font-family:inherit}
@media(max-width:700px) and (orientation:portrait){
 #title{padding-top:calc(40px + env(safe-area-inset-top))}
 #title .bigTitle{font-size:clamp(46px,14.4vw,60px)}
 #title .tagline{font-size:12px;letter-spacing:.045em;margin-top:20px;color:#aabbd0}
 #title #btnEnter{background:linear-gradient(180deg,#eff4fb,#d5e1ef);color:#172a42;border-color:#ffffff90;border-radius:18px;box-shadow:inset 0 1px 0 #fff,0 5px 24px #0003;font-weight:500;letter-spacing:.035em}
 #title #btnTour{border-radius:18px;background:#111c2bb3;border-color:#acc4df40;box-shadow:inset 0 1px 0 #ffffff08}
 #title #btnInfo{color:#91a2b8}
}
@media(max-width:700px) and (max-height:740px) and (orientation:portrait){
 #title{padding-top:28px}#title .bigTitle{font-size:46px}#title .tagline{font-size:11px;margin-top:15px}
}

/* Separately hide the upper interface and the transport. H still hides both. */
body.topHidden #topbar,body.topHidden #left,body.topHidden #right,body.topHidden #radar{opacity:0;pointer-events:none}
body.bottomHidden #transport{opacity:0;pointer-events:none}
.restoreUI{display:none;position:fixed;z-index:42;min-height:44px;background:#101c2de6;border:1px solid #aac8ec55;border-radius:12px;color:#e3edfb;padding:8px 14px}
#showTop{top:calc(12px + env(safe-area-inset-top));right:12px}#showBottom{bottom:calc(12px + env(safe-area-inset-bottom));right:12px}
body.topHidden #showTop,body.bottomHidden #showBottom{display:block}
body.titleMode .restoreUI,body.touring .restoreUI,body.clean .restoreUI{display:none}
.bottomTools{justify-content:space-between;gap:8px}.bottomTools button{min-height:44px;font-size:12px;flex:1}
body.touring .bottomTools{display:none}
body.touring.tourSpeed #transport{opacity:1}
#tourSpeedRow{display:flex;gap:8px;margin:12px 0;flex-wrap:wrap}#tourSpeedRow[hidden]{display:none}#tourSpeedRow button{flex:1;min-height:44px;white-space:nowrap;font-size:12px}
/* CSS-drawn playback icons do not depend on Android's symbol fonts. */
#play,#stepBack,#stepFwd,#slower,#faster,#reverse{font-size:0!important;position:relative;min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center}
#play::before{content:'';width:0;height:0;border-left:13px solid currentColor;border-top:8px solid transparent;border-bottom:8px solid transparent}
#play.isPlaying::before{width:13px;height:16px;border:0;border-left:4px solid currentColor;border-right:4px solid currentColor;box-sizing:border-box}
#stepBack::before,#stepFwd::before,#slower::before,#faster::before{content:'';width:10px;height:10px;border-top:2px solid currentColor;border-right:2px solid currentColor;transform:rotate(45deg)}
#stepBack::before,#slower::before{transform:rotate(-135deg)}
#stepBack::after,#stepFwd::after{content:'';width:2px;height:16px;background:currentColor;margin-left:6px}
#stepBack::after{order:-1;margin-left:0;margin-right:6px}
#slower::after,#faster::after{content:'';width:10px;height:10px;border-top:2px solid currentColor;border-right:2px solid currentColor;transform:rotate(45deg);margin-left:-3px}
#slower::after{transform:rotate(-135deg)}
#reverse::before{content:'';width:18px;height:12px;border-top:2px solid currentColor;border-bottom:2px solid currentColor}
#reverse::after{content:'';position:absolute;width:6px;height:6px;border-top:2px solid currentColor;border-left:2px solid currentColor;transform:rotate(-45deg);left:calc(50% - 9px);top:calc(50% - 10px)}
@media(pointer:coarse),(max-width:600px){#slower.desktopOnly,#faster.desktopOnly{display:none}}
#transport #play,#transport #stepBack,#transport #stepFwd,#transport #slower,#transport #faster,#transport #reverse{display:inline-flex;flex-direction:row}
#transport .bottomTools button{width:auto;height:44px;flex:1;font-size:12px;white-space:nowrap;padding:0 10px}

/* Compact phone tour: preserve the sky above the card. */
@media(max-width:600px) and (min-height:501px){
 #tourCard{padding:10px 14px;bottom:max(8px,env(safe-area-inset-bottom));width:calc(100% - 16px);max-height:34dvh;}
 #tourCard h2{font-size:17px;margin:4px 0 5px;}
 #tourText{font-size:12px;line-height:1.35;margin:0 0 6px;}
 #tourCard .tourTiming{margin:0 0 4px;font-size:9px;}
 #tourCard .tourTiming:empty{display:none;}
 #tourSpeedRow{margin:4px 0;gap:6px;}
 #tourPractice{margin:4px 0;}
 .tourActions{gap:6px;}
 #tourCard button{padding:5px 9px;}
 #tourCard .tourTop button{min-height:32px;}
}

#tourCard[data-lesson]:not([data-lesson='']):not([data-lesson='welcome']) #tourTiming{display:none}

/* Minimal restore affordance, independent of the global full-width button rule. */
#showTop{left:calc(8px + env(safe-area-inset-left));right:auto;top:calc(8px + env(safe-area-inset-top));width:40px;height:40px;min-height:40px;padding:0;border-radius:10px;background:rgba(10,17,26,.45);border-color:rgba(170,200,236,.22);line-height:0;}
#showTop svg{display:block;margin:auto;}

#showBottom{left:calc(8px + env(safe-area-inset-left));right:auto;bottom:calc(8px + env(safe-area-inset-bottom));width:40px;height:40px;min-height:40px;padding:0;border-radius:10px;background:rgba(10,17,26,.45);border-color:rgba(170,200,236,.22);line-height:0;}
#showBottom svg{display:block;margin:auto;}
#mobileSpeed,#hideBottom svg{display:none;}
@media(max-width:600px) and (orientation:portrait){
 #topbar{display:grid;grid-template-columns:minmax(0,1fr) 40px 40px;grid-template-rows:18px 18px;gap:0 4px;padding:4px 8px;top:8px;}
 #homeTitle{grid-column:1;grid-row:1;min-width:0;}
 .brand .dot,.brand h1,#lockUI{display:none;}
 .brand p{font-size:10px;}
 .clock{grid-column:1;grid-row:2;padding:0;text-align:left;min-width:0;}
 .clockMain{font-size:10px;white-space:nowrap;}
 #helpUI{grid-column:2;grid-row:1 / 3;}#hideUI{grid-column:3;grid-row:1 / 3;}
 #topbar .ghost{width:40px;min-width:40px;height:36px;min-height:36px;padding:0;}
 #left,#right{top:60px;width:auto;bottom:auto;}
 #left,#left.collapsed{left:8px;right:auto;}#right,#right.collapsed{right:8px;left:auto;top:60px;}
 .panelHead{min-height:32px;padding:5px 10px;font-size:10px;}
 #radar{display:none;}
 #transport{width:calc(100% - 16px);max-width:none;padding:4px 6px;gap:2px;bottom:8px;}
 #transport .tRow{justify-content:space-between;gap:4px;}
 #transport #presets{display:none;}
 #transport .speedBox{padding:0 2px;min-width:0;flex:1;text-align:center;}
 #transport .speedBox b{font-size:10px;}#transport .speedBox span{display:none;}
 #transport button,#transport button.primary{width:40px;height:40px;}
 #transport .bottomTools{margin:0;gap:6px;}
 #mobileSpeed{display:block;flex:1;min-width:0;width:auto;height:40px;padding:4px 8px;font-size:12px;}
 #transport .bottomTools #lockBottom{height:40px;flex:0 0 110px;padding:0 6px;font-size:11px;}
 #transport .bottomTools #hideBottom{height:40px;width:40px;flex:0 0 40px;padding:0;}
 #hideBottom .hideBottomLabel{display:none;}#hideBottom svg{display:block;}
 body.panelOpen #topbar,body.panelOpen #transport{visibility:hidden;pointer-events:none;}
 body.panelOpen #left:not(.collapsed),body.panelOpen #right:not(.collapsed){left:8px;right:8px;top:8px;width:auto;max-height:calc(30dvh - 16px);overflow:hidden;}
 body.panelOpen .panelBody{max-height:calc(30dvh - 50px);overflow-y:auto;}
 body.topHidden #lookHint{display:none;}
}

@media(max-width:600px) and (orientation:portrait){#left,#right,#right.collapsed{top:56px;}body.panelOpen #lookHint{display:none;}#transport{bottom:max(8px,env(safe-area-inset-bottom));}}

/* Phone-only speed dialog. Tablets/desktops retain the preset button strip. */
#phoneSpeedPicker[hidden]{display:none!important;}
#phoneSpeedPicker{display:none;}
body.phoneUI #phoneSpeedPicker:not([hidden]){display:block;position:fixed;z-index:60;left:8px;right:8px;bottom:max(8px,env(safe-area-inset-bottom));padding:8px 10px;border:1px solid var(--edge);border-radius:14px;background:rgba(12,20,32,.97);box-shadow:0 8px 32px #0008;max-height:calc(30dvh - 16px);overflow:auto;}
.speedPickerHead{display:flex;align-items:center;justify-content:space-between;margin-bottom:5px;}
.speedPickerHead h2{margin:0;text-transform:none;font-size:13px;color:var(--ink);}
#phoneSpeedPicker #closePhoneSpeed{width:32px;height:32px;min-height:32px;padding:0;font-size:21px;}
#phoneSpeedOptions{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px;}
#phoneSpeedOptions button{height:38px;min-height:38px;padding:4px;font-size:12px;}
#phoneSpeedOptions button[aria-pressed=true]{background:#adc7e6;color:#0b1625;border-color:#adc7e6;}
body.phoneSpeedOpen #transport,body.phoneSpeedOpen #topbar,body.phoneSpeedOpen #left,body.phoneSpeedOpen #right,body.phoneSpeedOpen #lookHint{visibility:hidden;pointer-events:none;}
#transport .bottomTools #mobileSpeed{display:none;}
body.phoneUI #transport .bottomTools #mobileSpeed{display:block;flex:1;width:auto;min-width:0;text-align:left;font-size:12px;}
@media(pointer:coarse) and (max-height:500px) and (max-width:1000px){
 body.phoneUI #phoneSpeedPicker:not([hidden]){max-height:calc(30dvh - 8px);padding:4px 8px;}
 .speedPickerHead{margin:0;}.speedPickerHead h2{font-size:11px;}
 #phoneSpeedPicker #closePhoneSpeed{height:24px;min-height:24px;}
 #phoneSpeedOptions{grid-template-columns:repeat(5,minmax(0,1fr));gap:3px;}
 #phoneSpeedOptions button{height:28px;min-height:28px;font-size:11px;}
 body.phoneUI #presets{display:none;}body.phoneUI #transport{flex-direction:row;}
}

/* Phone sky taps provide a completely clear view, with no restore buttons. */
body.phoneUI.clean #showUI,body.phoneUI.clean #lookHint,body.phoneUI.clean #radar,body.phoneUI.clean #idCard{display:none!important;}
body.phoneUI #infoPanel .keys{display:none;}
.menuScrollHint{display:none;}
body.phoneUI .collapsible:not(.collapsed) .menuScrollHint{display:block;margin-left:auto;padding-left:14px;color:#abc4df;font-size:10px;font-weight:400;text-transform:none;letter-spacing:0;}
body.phoneUI.panelOpen #left:not(.collapsed),body.phoneUI.panelOpen #right:not(.collapsed){max-height:72dvh;}
body.phoneUI.panelOpen .panelHead{min-height:44px;}
body.phoneUI.panelOpen .panelBody{max-height:calc(72dvh - 48px);overflow-y:auto;scrollbar-width:thin;scrollbar-color:#90abc9 #172335;}
body.phoneUI .panelBody::-webkit-scrollbar{width:6px;}
body.phoneUI .panelBody::-webkit-scrollbar-thumb{background:#90abc9;border-radius:6px;}
body.phoneUI #infoPanel{max-height:72dvh;}
body.phoneUI #phoneSpeedPicker:not([hidden]){max-height:70dvh;}
body.phoneUI #phoneSpeedOptions button{min-height:44px;height:44px;}

.phoneHelp{display:none;}body.phoneUI .phoneHelp{display:block;}body.phoneUI .largeScreenHelp{display:none;}

body.phoneUI.clean #showTop,body.phoneUI.clean #showBottom{display:none!important;}

#phoneEventButton,#phoneEventPicker{display:none;}
#phoneEventPicker[hidden]{display:none!important;}
body.phoneUI #phoneEventButton{display:block;text-align:left;}
body.phoneUI #jumpSelect{display:none;}
body.phoneUI #phoneEventPicker:not([hidden]){display:block;position:fixed;z-index:61;left:8px;right:8px;bottom:max(8px,env(safe-area-inset-bottom));padding:10px;border:1px solid var(--edge);border-radius:14px;background:rgba(12,20,32,.97);box-shadow:0 8px 32px #0008;max-height:72dvh;overflow:auto;}
#phoneEventOptions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px;}
#phoneEventOptions button{min-height:44px;padding:8px;font-size:12px;text-align:left;}
#phoneEventOptions button:last-child{grid-column:1 / -1;}
#closePhoneEvent{width:32px;height:32px;padding:0;font-size:21px;}
body.phoneEventOpen #topbar,body.phoneEventOpen #left,body.phoneEventOpen #right,body.phoneEventOpen #transport,body.phoneEventOpen #lookHint{visibility:hidden;pointer-events:none;}
#hideUI svg{display:block;margin:auto;}
