/*
 * The viewer: the sky fills the page, its name sits under it like the caption of a plate, and the one instrument
 * always on screen is the day. Everything else is summoned and dismissed.
 *
 * `--sky` and `--console` are measured by app.js: how tall the sky is depends on the view and on the page's shape,
 * and the console is as tall as its contents wrap to.
 */

:root {
  --console: 132px;
  --sky: calc(100dvh - var(--console));
  --toast-bottom: calc(var(--console) + 16px);
}

body { height: 100dvh; overflow: hidden; }

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

#gl {
  position: fixed;
  top: 0;
  left: 0;
  display: block;
  width: 100vw;
  height: var(--sky);
  background: #000;
  cursor: grab;
  touch-action: none;
}
#gl:active { cursor: grabbing; }

/* the bar floats on the sky rather than boxing it in */
.topbar {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px 26px;
  background: linear-gradient(#000c, #0000);
  pointer-events: none;
}
.topbar > * { pointer-events: auto; }
.spacer { flex: 1; }

.back {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  padding: 4px 6px 4px 2px;
  font: 400 23px/1 var(--serif);
  color: var(--ink);
  text-decoration: none;
  text-shadow: 0 1px 3px #000a;
  white-space: nowrap;
}
.back .arrow { font: 400 15px/1 var(--sans); color: var(--ink-dim); transition: translate 160ms var(--ease), color 160ms var(--ease); }
.back:hover .arrow { color: var(--lit); translate: -3px 0; }

.finder, .build, .rail {
  border: 1px solid #ffffff24;
  border-radius: 999px;
  background: #0b0d13b3;
  backdrop-filter: blur(8px);
}
.finder:hover, .build:hover, .rail:hover { border-color: #ffffff45; }
.finder {
  display: flex;
  flex: 0 1 280px;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-width: 140px;
  padding: 7px 8px 7px 14px;
  font-size: 13px;
  color: var(--ink-dim);
  text-align: left;
}
.finder:hover { color: var(--ink); }
.finder kbd { padding: 2px 6px; border: 1px solid #ffffff2e; border-radius: 4px; font: 500 11px/1 var(--mono); color: var(--ink-dim); }
.build { max-width: 230px; padding: 6px 10px; font: 12px var(--mono); text-overflow: ellipsis; }
.rail { padding: 6px 13px; font-size: 13px; color: var(--ink); white-space: nowrap; }
.menu-only { display: none; }

/* a control that only means something in one view is shown only in that view */
body.panorama [data-for="look"], body:not(.panorama) [data-for="pano"] { display: none; }

/* the view and the ground are always on screen: in the bar where it has room, and as a second row of it where not */
.view-controls { display: flex; align-items: center; gap: 8px; }
.ground, .motion { display: inline-flex; align-items: center; gap: 7px; }
.ground[aria-pressed="true"], .motion[aria-pressed="true"] { border-color: #ffffff45; background: #ffffff1a; }
.ground[aria-pressed="false"], .motion[aria-pressed="false"] { color: var(--ink-dim); }
/* the Pause motion switch carries the warning mark on a sky measured to move a lot */
.motion .motion-warning { display: none; }
.motion.extreme .motion-warning { display: inline-flex; }
.caption .motion-cell { display: inline-flex; align-items: center; gap: 0.45em; color: #ffcf8a; }
/* the mark of a sky measured to hold something below the horizon */
.below-mark { display: none; width: 7px; height: 7px; border-radius: 50%; background: var(--lit); box-shadow: 0 0 8px var(--lit); }
.ground.notable .below-mark { display: inline-block; }

@media (max-width: 960px) {
  .topbar { flex-wrap: wrap; }
  .view-controls { order: 10; flex-basis: 100%; flex-wrap: wrap; }
  body:not(.panorama) .drag-hint { top: 112px; }
}

/* ---------------------------------------------------------------- the plate */

/* over the sky in the perspective view; under a panorama the page below the sky is the plate's margin */
.plate {
  position: fixed;
  right: 28px;
  bottom: calc(var(--console) + 22px);
  left: 28px;
  z-index: 2;
  pointer-events: none;
  text-shadow: 0 2px 14px #000c, 0 1px 3px #000a;
}
body.panorama .plate {
  top: var(--sky);
  bottom: var(--console);
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-shadow: none;
}
.plate h1 { margin: 0; font: 400 clamp(34px, 5vw, 66px)/1 var(--serif); letter-spacing: -0.01em; }
/*
 * Each cell is an item of a wrapping row, so a narrow page moves a whole cell down rather than breaking its words.
 * A rule sits in the gap before every cell, and the row reaches one gap past the plate's left edge with that strip
 * clipped away, so a cell that starts a line never carries a rule in front of it.
 */
.caption {
  --gap: 1.5em;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  width: max-content;
  max-width: calc(100% + var(--gap));
  margin: 10px 0 0 calc(-1 * var(--gap));
  clip-path: inset(-12px -12px -12px var(--gap));
  font: 400 12px/1.7 var(--mono);
  color: #cdd4e2;
}
.caption > * { position: relative; margin-left: var(--gap); white-space: nowrap; }
.caption b { font-weight: 500; color: var(--lit); }
.caption > *::before {
  content: "";
  position: absolute;
  top: 50%;
  left: calc(var(--gap) / -2);
  width: 1px;
  height: 0.85em;
  background: #ffffff38;
  translate: 0 -50%;
}
.trouble { margin: 10px 0 0; font: 12px/1.5 var(--mono); color: #ffb4a2; }
/* the way under a panorama's horizon, offered only where the sky was measured to hold something there */
.look-below {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  padding: 7px 14px;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  background: transparent;
  font: 500 12px/1 var(--sans);
  color: var(--ink);
  pointer-events: auto;
}
.look-below:hover { border-color: var(--lit); color: var(--lit); }
.look-below .below-mark { display: inline-block; }

.drag-hint {
  position: fixed;
  top: calc(var(--sky) - 50px);
  left: 50%;
  z-index: 2;
  margin: 0;
  padding: 6px 14px;
  border: 1px solid #ffffff24;
  border-radius: 999px;
  background: #07080cb8;
  backdrop-filter: blur(6px);
  font: 12px/1.2 var(--sans);
  color: var(--ink);
  translate: -50% 0;
  pointer-events: none;
  animation: hint-in 600ms var(--ease) 1.2s both;
}
body:not(.panorama) .drag-hint { top: 78px; }
@keyframes hint-in { from { opacity: 0; translate: -50% 6px; } }

.waiting {
  position: fixed;
  top: calc(var(--sky) / 2);
  left: 50%;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 18px;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  background: #0b0d13e0;
  backdrop-filter: blur(10px);
  font: 13px var(--sans);
  translate: -50% -50%;
}
.spin {
  width: 15px;
  height: 15px;
  border: 2px solid #ffffff2e;
  border-top-color: var(--lit);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { rotate: 360deg; } }

/* ---------------------------------------------------------------- the console */

.console {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 3;
  display: grid;
  gap: 10px;
  padding: 10px 16px calc(12px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--rule);
  background: var(--plate);
}

.day { display: grid; grid-template-columns: auto auto minmax(0, 1fr) auto; align-items: center; gap: 12px; }

.play {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--rule-strong);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
}
.play:hover { border-color: var(--lit); color: var(--lit); }
.play[aria-pressed="true"] { border-color: var(--lit); background: var(--lit); color: var(--lit-ink); }
.play .glyph { font-size: 12px; line-height: 1; translate: 1px 0; }
.play[aria-pressed="true"] .glyph { translate: 0 0; }

#clock { min-width: 5ch; font: 500 26px/1 var(--mono); font-variant-numeric: tabular-nums; letter-spacing: -0.02em; color: var(--lit); }

/* the day: the sky's renders on a canvas drawn once per preset, and the cursor and the hours as page type over it */
.band {
  position: relative;
  display: grid;
  grid-template-rows: minmax(0, 1fr) 15px;
  height: 58px;
  cursor: ew-resize;
  touch-action: none;
}
.band:focus-visible { outline-offset: 3px; }
.band canvas {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 5px;
  background: #000;
  box-shadow: 0 0 0 1px var(--rule-strong);
}
.band-cursor {
  position: absolute;
  top: -3px;
  bottom: 12px;
  left: 50%;
  width: 2px;
  margin-left: -1px;
  border-radius: 1px;
  background: var(--lit);
  box-shadow: 0 0 0 1px #07080cb3, 0 0 12px color-mix(in srgb, var(--lit) 55%, transparent);
  pointer-events: none;
}
.band-cursor::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 50%;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--lit);
  box-shadow: 0 0 0 2px var(--plate);
  translate: -50% 0;
}
.band-scale { position: relative; }
.band-scale i, .band-scale span { position: absolute; left: calc(var(--at) * 100%); }
.band-scale i { top: 0; width: 1px; height: 3px; background: var(--rule-strong); }
.band-scale i.major { height: 5px; background: var(--ink-faint); }
.band-scale span { top: 4px; font: 500 10px/1 var(--mono); letter-spacing: 0.02em; color: var(--ink-faint); translate: -50% 0; }
.band-scale span.first { translate: 1px 0; }

.speed { display: grid; grid-template-columns: auto 110px; align-items: center; gap: 4px 8px; font: 11px var(--sans); color: var(--ink-dim); }
.speed input { width: 110px; accent-color: var(--lit); }
.speed output { grid-column: 1 / -1; font: 11px var(--mono); text-align: right; }

.strips { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 24px; min-height: 30px; }

/* what the sky does past the sky: every chip is a measured column, never a guess */
.world { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.world .group { display: flex; align-items: center; gap: 6px; }
.world .label { font: 500 10px/1 var(--sans); letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-dim); }
.world .chip { width: 26px; height: 16px; border: 1px solid #ffffff1f; border-radius: 2px; }
.world .pair { display: flex; }
.world .pair .chip:first-child { border-right: 0; border-radius: 2px 0 0 2px; }
.world .pair .chip:last-child { border-radius: 0 2px 2px 0; }
.world .bar { width: 40px; height: 6px; overflow: hidden; border-radius: 999px; background: #ffffff1f; }
.world .bar i { display: block; height: 100%; background: var(--ink); }

/* ---------------------------------------------------------------- the summoned surfaces */

dialog {
  padding: 0;
  border: 1px solid var(--rule-strong);
  border-radius: 12px;
  background: #0b0d13f5;
  backdrop-filter: blur(14px);
  box-shadow: 0 24px 60px #000b;
  color: var(--ink);
}
dialog::backdrop { background: #05060ab8; }

.find { width: min(680px, 92vw); margin-top: 12vh; }
.find input {
  width: 100%;
  padding: 16px 18px;
  border: 0;
  border-bottom: 1px solid var(--rule);
  border-radius: 12px 12px 0 0;
  background: transparent;
  font: 400 18px var(--sans);
}
.find input:focus { outline: none; }
.find .hint { margin: 0; padding: 8px 18px 12px; border-top: 1px solid var(--rule); font: 11px var(--sans); color: var(--ink-dim); }

.results { max-height: 46vh; margin: 0; padding: 6px; overflow-y: auto; list-style: none; scrollbar-width: thin; }
.results li {
  display: grid;
  grid-template-columns: 6ch minmax(0, 1fr) auto;
  align-items: baseline;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 6px;
  font: 13px var(--sans);
  cursor: pointer;
}
.results li .id { font: 12px var(--mono); color: var(--ink-dim); }
.results li .where { overflow: hidden; font: 11px var(--mono); color: var(--ink-dim); text-align: right; text-overflow: ellipsis; white-space: nowrap; }
.results li:hover { background: #ffffff0d; }
.results li[aria-selected="true"] { background: #ffffff12; }
.results li[aria-selected="true"] .id { color: var(--lit); }

.sheet { width: min(560px, 92vw); padding: 20px 22px 22px; }
.sheet h2 { margin: 0 0 14px; font: 400 27px/1.1 var(--serif); }
.sheet h3 { margin: 20px 0 8px; font: 500 10px/1 var(--sans); letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-dim); }
.sheet .row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-bottom: 10px; }
.sheet label { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-dim); }
.sheet input[type=number], .sheet input[type=search], .sheet select {
  padding: 6px 9px;
  border: 1px solid var(--rule-strong);
  border-radius: 6px;
  background: #05060a;
  font: 12px var(--mono);
}
.sheet input[type=number] { width: 76px; }
.sheet input[type=search] { width: 100%; }
.sheet .row button, .sheet > .row button {
  padding: 6px 14px;
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  background: transparent;
  font-size: 13px;
}
.sheet .row button:hover { border-color: var(--lit); color: var(--lit); }
.sheet button:disabled { opacity: 0.45; cursor: progress; }
.sheet .note { margin: 12px 0 0; font: 12px/1.6 var(--sans); color: var(--ink-dim); }
.sheet .results { max-height: 34vh; padding: 4px 0; }

.detail { width: min(720px, 94vw); }
.detail pre { max-height: 40vh; margin: 0; overflow-y: auto; font: 11px/1.65 var(--mono); color: #c8cfdd; white-space: pre-wrap; }
.layers { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px 12px; }
.layers label { font-size: 13px; color: var(--ink); }
.layers input { accent-color: var(--lit); }
.credit { margin: 18px 0 0; padding-top: 12px; border-top: 1px solid var(--rule); font: 11px/1.6 var(--sans); color: var(--ink-dim); }
.credit a { color: var(--ink); }

.menu { width: min(420px, 92vw); }
.menu-row { display: grid; gap: 8px; margin-bottom: 18px; }
.menu-label { font: 500 10px/1 var(--sans); letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); }
.menu .segmented { display: flex; }
.menu .segmented button { flex: 1; padding: 9px 12px; font-size: 14px; }
.menu .build { width: 100%; max-width: none; padding: 10px 12px; }
.menu-actions { display: grid; gap: 8px; }
.menu-actions button {
  padding: 12px 16px;
  border: 1px solid var(--rule-strong);
  border-radius: 10px;
  background: transparent;
  font-size: 15px;
  text-align: left;
}
.menu-actions button:hover { border-color: var(--lit); color: var(--lit); }

.keys {
  position: fixed;
  right: 16px;
  bottom: calc(var(--console) + 12px);
  z-index: 2;
  display: flex;
  gap: 12px;
  font: 11px var(--sans);
  color: #ffffff8c;
  text-shadow: 0 1px 3px #000a;
  pointer-events: none;
}
.keys b { font: 500 11px var(--mono); color: #ffffffd6; }

/* ---------------------------------------------------------------- narrow pages */

@media (max-width: 960px), (hover: none) {
  .keys { display: none; }
}

@media (max-width: 960px) {
  .bar-only { display: none; }
  .menu-only { display: inline-flex; }
  .finder { flex: 1 1 auto; }
}

@media (max-width: 720px) {
  .topbar { gap: 8px; padding: 10px 12px 24px; }
  .back { font-size: 21px; }
  .plate { right: 16px; left: 16px; }
  .plate h1 { font-size: clamp(28px, 8.5vw, 40px); }
  .world, .speed { display: none; }
  .day { grid-template-columns: auto auto minmax(0, 1fr); gap: 10px; }
  #clock { font-size: 22px; }
  .band { height: 46px; }
  .strips { justify-content: flex-start; }
  /* a sheet rises from the foot of the page, where a thumb already is */
  dialog.sheet {
    width: 100vw;
    max-width: 100vw;
    max-height: 86dvh;
    margin: auto 0 0;
    padding-bottom: calc(22px + env(safe-area-inset-bottom));
    overflow-y: auto;
    border-bottom: 0;
    border-radius: 16px 16px 0 0;
  }
  .find { margin-top: 64px; }
}
