* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
  --fg: #fff;
  --shadow: 0 1px 3px rgba(0,0,0,.8);
  --chrome: rgba(0,0,0,.55);
  --line: rgba(255,255,255,.3);
  --accent: #2f81f7;
  /* Safe-area insets, one per side (iPhone Duo home-screen app: right 84,
     bottom 34; rotated poses move the column to another edge). Controls
     stay inside them; the camera, sky and labels still run edge to edge. */
  --in-t: env(safe-area-inset-top, 0px);
  --in-r: env(safe-area-inset-right, 0px);
  --in-b: env(safe-area-inset-bottom, 0px);
  --in-l: env(safe-area-inset-left, 0px);
  /* 8px of extra corner room when nothing sits above (Duo, Mac), 0 under a
     slab phone's status bar. */
  --corner: clamp(0px, 24px - var(--in-t), 8px);
  --hud-t: max(var(--in-t), 24px);
  --hud-r: calc(var(--in-r) + 12px + var(--corner));
  --hud-l: calc(var(--in-l) + 12px + var(--corner));
  /* horizontal centre and width of the safe area, for centred chrome */
  --cx: calc(50% + (var(--in-l) - var(--in-r)) / 2);
  --safe-w: calc(100vw - var(--in-l) - var(--in-r));
}
html, body { height: 100%; overflow: hidden; background: #000;
  font-family: -apple-system, system-ui, sans-serif; }

#cam { position: fixed; inset: 0; width: 100%; height: 100%;
  object-fit: cover; }
#sky { position: fixed; inset: 0; display: none;
  background: linear-gradient(#3a6ea5 0 54%, #1b4f72 54% 56%, #0b2e4f 56% 100%); }
body.debug #sky { display: block; }
body.debug #cam { display: none; }

#hud { position: fixed; inset: 0; color: var(--fg); display: none;
  touch-action: none; }
body.running #hud { display: block; }
body.running #gate { display: none; }

/* startup narration: user-facing, so it lives by the pill, not in the
   debug corner */
#status { position: absolute; left: var(--cx); transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 62px);
  max-width: calc(var(--safe-w) - 24px); padding: 8px 16px; font-size: 13px;
  background: var(--chrome); border-radius: 999px;
  text-shadow: var(--shadow); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }

/* wider than the screen so it still spans corner to corner when rolled;
   top + rotate() set per frame from the projected world horizon */
#horizon { position: absolute; left: calc(50% - 100vw); width: 200vw;
  height: 0; border-top: 1px dashed rgba(255,255,255,.35); }

#labels { position: absolute; inset: 0; overflow: hidden; }
/* --tilt (set per frame) keeps text level with the world horizon; the
   rotation pivots on the anchor tip so the dot stays on the feature */
.label { position: absolute;
  transform: translate(-50%, 0) rotate(var(--tilt, 0deg));
  transform-origin: 50% 100%;
  text-align: center; font-size: 13px; line-height: 1.25;
  text-shadow: var(--shadow); pointer-events: none; white-space: nowrap; }
.label .nm { font-weight: 600; }
.label .meta { font-size: 11px; opacity: .85; }
.label::after { content: ""; display: block; width: 1px; margin: 2px auto 0;
  background: rgba(255,255,255,.7); height: var(--lead, 18px); }
.label .dot { width: 5px; height: 5px; border-radius: 50%;
  background: #fff; margin: 0 auto; box-shadow: var(--shadow); }
.label.city .dot { background: #ffd54a; }
.label.city .nm { color: #ffe9a8; }
/* landmarks: a distinct cool accent so they read apart from peaks/cities */
.label.lm .dot { background: #62d2e6; width: 6px; height: 6px;
  box-shadow: 0 0 6px rgba(98,210,230,.9), var(--shadow); }
.label.lm .nm { color: #a9e8f3; }
.label.bh { opacity: .55; }
.label.bh::after { background: transparent;
  border-left: 1px dashed rgba(255,255,255,.6); }
/* sun/moon anchors: open-ring reticle with four inward ticks. Centering a
   bright body in a ring is a hyperacuity task (concentric gap judgment)
   and the ring never occludes the target the way a dot does. */
.label.sun, .label.moon { transform-origin: 50% 22px; } /* pivot: ring center */
.label.sun .nm, .label.moon .nm { font-size: 14px; }
.label.sun .nm, .label.sun .meta, .label.sun .ret { color: #ffe066; }
.label.moon .nm, .label.moon .meta, .label.moon .ret { color: #dfe8f3; }
.label.sun::after, .label.moon::after { display: none; }
.ret { position: relative; width: 44px; height: 44px; margin: 0 auto 2px;
  border: 1.5px solid currentColor; border-radius: 50%;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,.7)); }
.ret::before, .ret::after { content: ""; position: absolute; }
.ret::before { left: 3px; right: 3px; top: 50%; height: 1.5px;
  margin-top: -0.75px;
  background: linear-gradient(90deg, currentColor 0 8px,
    transparent 8px calc(100% - 8px), currentColor calc(100% - 8px)); }
.ret::after { top: 3px; bottom: 3px; left: 50%; width: 1.5px;
  margin-left: -0.75px;
  background: linear-gradient(180deg, currentColor 0 8px,
    transparent 8px calc(100% - 8px), currentColor calc(100% - 8px)); }
.label.sun.locked .ret { border-width: 2.5px; }

#dbgbtn { position: absolute; top: var(--hud-t);
  right: var(--hud-r); height: 28px; padding: 0 12px; display: inline-flex;
  align-items: center; justify-content: center; background: var(--chrome);
  color: var(--fg); border: none; border-radius: 999px; font-size: 12px;
  font-family: ui-monospace, Menlo, monospace; cursor: pointer; }
#fsbtn { position: absolute; top: var(--hud-t);
  right: calc(var(--hud-r) + 42px); height: 28px; width: 34px; display: inline-flex;
  align-items: center; justify-content: center; background: var(--chrome);
  color: var(--fg); border: none; border-radius: 999px; font-size: 15px;
  cursor: pointer; }
#fsbtn[hidden] { display: none; }
#slbtn { position: absolute; top: var(--hud-t);
  right: calc(var(--hud-r) + 84px); height: 28px; width: 34px; display: inline-flex;
  align-items: center; justify-content: center; background: var(--chrome);
  color: var(--fg); border: none; border-radius: 999px; font-size: 15px;
  cursor: pointer; opacity: .65; }
#slbtn.on { color: #ffe066; opacity: 1; }
#slbtn.locked { background: rgba(255,224,102,.3); }
#slbtn[hidden] { display: none; }
#console { position: absolute;
  top: var(--hud-t); left: var(--hud-l);
  width: min(236px, 64vw); background: rgba(0,0,0,.42);
  max-height: calc(100% - var(--hud-t) - var(--in-b) - 8px); overflow: hidden;
  border-radius: 12px; padding: 5px; color: var(--fg);
  font-family: ui-monospace, Menlo, monospace; font-size: 10px;
  pointer-events: none; text-shadow: 0 1px 2px rgba(0,0,0,.9);
  display: flex; flex-direction: column; gap: 4px;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
#console[hidden] { display: none; }
#console .sec { background: rgba(255,255,255,.06); border-radius: 6px;
  padding: 3px 7px 4px; }
#console .hd { font-size: 8.5px; letter-spacing: .14em;
  text-transform: uppercase; opacity: .5; margin-bottom: 1px; }
#console .kv { display: flex; justify-content: space-between; gap: 10px;
  line-height: 1.35; }
#console .kv span { opacity: .55; flex: none; }
#console .kv b { font-weight: 400; text-align: right; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  font-variant-numeric: tabular-nums; }

/* ---- bottom chrome ---- */
/* zoom magnifier presets, sat just above the heading pill */
#zoomrow { position: absolute; left: var(--cx); transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 58px);
  display: flex; gap: 6px; padding: 4px; border-radius: 999px;
  background: var(--chrome);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
#zoomrow[hidden] { display: none; }
#zoomrow button { min-width: 38px; height: 30px; padding: 0 8px;
  border: none; border-radius: 999px; background: transparent;
  color: var(--fg); font-size: 13px; font-weight: 600; cursor: pointer; }
#zoomrow button.on { background: var(--accent); }
#zoomrow.digital { position: absolute; }
#zoomrow.digital::before { content: "digital"; position: absolute;
  left: 0; right: 0; top: -15px; text-align: center; font-size: 10px;
  letter-spacing: .08em; color: #e8a33d; opacity: .85; }
body.land-cw #zoomrow, body.land-ccw #zoomrow { display: none; }
#pill { position: absolute; left: var(--cx); transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 14px);
  display: inline-flex; align-items: center; justify-content: center;
  gap: 7px; background: var(--chrome); color: var(--fg); border: none;
  border-radius: 999px; padding: 0 18px; height: 36px; font-size: 14px;
  cursor: pointer; line-height: 1;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
#pill .glyph { font-size: 16px; line-height: 1; }

#panel[hidden] { display: none; }
#panel { position: absolute; left: var(--cx); transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom, 0px) + 60px);
  width: min(370px, calc(var(--safe-w) - 24px));
  max-height: calc(100% - var(--hud-t) - 36px - var(--in-b) - 60px);
  overflow-y: auto; background: var(--chrome); border-radius: 14px;
  padding: 12px 14px; display: flex; flex-direction: column; gap: 8px;
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }

#panel .row { font-size: 12px; }
#panel .mono { font-family: ui-monospace, Menlo, monospace; opacity: .92;
  font-size: 11.5px; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
#panel .mono.wrap { white-space: normal; overflow: visible;
  line-height: 1.5; }
#count { opacity: .7; }

#panel .ctl { font-size: 13px; }
#panel .ctl label { display: flex; justify-content: space-between;
  align-items: baseline; margin-bottom: 2px; }
#panel input[type="range"] { width: 100%; accent-color: var(--accent); }

.btnrow { display: flex; gap: 7px; align-items: stretch; }
.btnrow button { flex: 1; display: inline-flex; align-items: center;
  justify-content: center; height: 32px; padding: 0 8px;
  background: none; color: var(--fg); border: 1px solid var(--line);
  border-radius: 8px; font-size: 12.5px; line-height: 1; cursor: pointer; }
.btnrow button.on { background: var(--accent); border-color: var(--accent); }
.btnrow button.go { flex: 0 0 56px; }

#manrow input { flex: 1; min-width: 0; height: 32px; padding: 0 9px;
  background: rgba(255,255,255,.1); border: 1px solid var(--line);
  border-radius: 8px; color: var(--fg); font-size: 13px;
  font-family: ui-monospace, Menlo, monospace; appearance: none; }
#manrow input::placeholder { color: rgba(255,255,255,.45); }

/* phone physically sideways, browser rotation-locked (still portrait):
   chrome moves to the physical bottom/top edges and reads level.
   land-cw = phone top tipped right; land-ccw = tipped left.
   translateX(calc(±(50% - height/2))) re-seats the rotated box flush
   against the edge it is anchored to. */
body.land-cw #pill { left: auto; bottom: auto; top: 50%;
  right: calc(env(safe-area-inset-right, 0px) + 14px);
  transform: translateX(calc(50% - 18px)) translateY(-50%) rotate(-90deg); }
body.land-ccw #pill { bottom: auto; top: 50%;
  left: calc(env(safe-area-inset-left, 0px) + 14px);
  transform: translateX(calc(-50% + 18px)) translateY(-50%) rotate(90deg); }
body.land-cw #status { left: auto; bottom: auto; top: 50%;
  right: calc(env(safe-area-inset-right, 0px) + 62px);
  transform: translateX(calc(50% - 17px)) translateY(-50%) rotate(-90deg); }
body.land-ccw #status { bottom: auto; top: 50%;
  left: calc(env(safe-area-inset-left, 0px) + 62px);
  transform: translateX(calc(-50% + 17px)) translateY(-50%) rotate(90deg); }
body.land-cw #dbgbtn { right: auto; left: var(--hud-l);
  transform: rotate(-90deg); }
body.land-ccw #dbgbtn { right: var(--hud-r); top: auto;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 6px);
  transform: rotate(90deg); }
body.land-cw #fsbtn { right: auto; left: var(--hud-l);
  top: calc(var(--hud-t) + 36px);
  transform: rotate(-90deg); }
body.land-ccw #fsbtn { right: var(--hud-r); top: auto;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 42px);
  transform: rotate(90deg); }
body.land-cw #slbtn { right: auto; left: var(--hud-l);
  top: calc(var(--hud-t) + 72px);
  transform: rotate(-90deg); }
body.land-ccw #slbtn { right: var(--hud-r); top: auto;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 78px);
  transform: rotate(90deg); }

#dbgrow { justify-content: center; }
#dbgrow button { flex: 0 0 44px; font-size: 16px; }
#dbgrow span { display: inline-flex; align-items: center;
  justify-content: center; min-width: 48px; font-size: 13px; }

#toast { position: absolute; left: var(--cx); transform: translateX(-50%);
  top: 25%; max-width: calc(var(--safe-w) - 40px); background: rgba(120,20,20,.94);
  padding: 12px 16px; border-radius: 10px; font-size: 14px;
  cursor: pointer; line-height: 1.45; }

/* The gate's backdrop sits on the body so it still fills the screen while
   the scroll box itself stays inside the safe area (text never scrolls
   under the status column or home indicator). */
body:not(.running) { background:
  radial-gradient(120% 90% at 50% 0%, #16202e 0%, #0d1117 55%) #0d1117; }
#gate { position: fixed;
  inset: var(--in-t) var(--in-r) var(--in-b) var(--in-l);
  color: #e6edf3; display: flex; align-items: safe center;
  justify-content: safe center; overflow-y: auto;
  padding: max(0px, calc(24px - var(--in-t))) 24px 24px; }
/* margin:auto centres when it fits and pins to the top when it doesn't, so
   the title stays reachable on short windows (Duo closed 382x580, open
   951x543); plain center spilled the overflow above the scroll origin. */
#gate .gwrap { margin: auto; width: min(380px, 100%); display: flex;
  flex-direction: column; align-items: center; gap: 12px;
  text-align: center; }
#gate h1 { font-size: 30px; font-weight: 700; letter-spacing: .04em; }
#gate .tag { font-size: 16px; line-height: 1.4; color: #aeb9c7; }
#gate .desc { font-size: 13.5px; line-height: 1.5; color: #8b96a5;
  margin-bottom: 4px; }
#gate .card { width: 100%; text-align: left;
  background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.09);
  border-radius: 12px; padding: 12px 14px; }
#gate .cardhd { font-size: 11px; font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: #7ee787; margin-bottom: 5px; }
#gate .card p { font-size: 13px; line-height: 1.5; color: #aeb9c7; }
#gate .card p + p { margin-top: 6px; }
#gateStatus { min-height: 18px; font-size: 12.5px; color: #7ee787;
  font-family: ui-monospace, Menlo, monospace; }
#gate .foot { font-size: 11.5px; color: #5b6675; }
#start { margin-top: 6px; width: 100%; font-size: 17px; font-weight: 600;
  padding: 14px 48px; border-radius: 12px; border: none; cursor: pointer;
  background: var(--accent); color: #fff; }
