/* ACD · The Questionable Observatory — landing page styles.

   Contents
     1. Base
     2. Atmosphere and header
     3. The orb, its icons and the section text
     4. First-visit opening (loader, story, spotlight)
     5. Terminal handoff and archive loader
     6. Small screens
     7. Reduced motion
*/

/* ---------------------------------------------------------------- 1. Base */

:root {
  --ink: #e2e6df;
  --muted: #96aaa9;
  --gold: #d8bf87;
  --line: #acc0b02b;
  --night: #071014;
  /* the same faces as the terminal: serif for the story, mono for labels */
  --mono: 'IBM Plex Mono', 'SF Mono', 'Cascadia Mono', ui-monospace, Menlo, Consolas, monospace;
  --serif: 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
}

* {
  box-sizing: border-box;
}
body {
  margin: 0;
  height: 100svh;
  overflow: hidden;
  background: var(--night);
  color: var(--ink);
  font-family: var(--serif);
}
a {
  color: inherit;
  text-decoration: none;
}
button,
a {
  -webkit-tap-highlight-color: transparent;
}
button {
  cursor: pointer;
}
button:focus-visible,
a:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 6px;
}
[hidden] {
  display: none !important;
}

/* ------------------------------------------------ 2. Atmosphere and header */

#storm,
.vignette {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.vignette {
  background: radial-gradient(ellipse at 50% 53%, #22403922, #06101455 70%, #03090caf 100%);
}
header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 8;
  padding: 20px 4vw;
  text-align: center;
}
.brand {
  display: inline-flex;
  gap: 12px;
  align-items: center;
  font: 16px var(--mono);
}
.brand img {
  width: 32px;
}
.brand span {
  font-size: 12px;
  letter-spacing: 0.13em;
  color: var(--ink);
}
main {
  position: relative;
  height: 100svh;
}
.eyebrow {
  position: absolute;
  z-index: 2;
  top: 69px;
  left: 0;
  right: 0;
  margin: 0;
  text-align: center;
  font: 11px var(--mono);
  color: var(--gold);
  letter-spacing: 0.14em;
  pointer-events: none;
  transition: opacity 0.5s;
}
.lede {
  position: fixed;
  bottom: 18px;
  left: 0;
  right: 0;
  z-index: 5;
  margin: 0;
  padding: 8px 0;
  text-align: center;
  font: 12px/1.4 var(--mono);
  color: var(--muted);
  pointer-events: none;
  transition: opacity 0.5s;
}
#replay-opening {
  position: fixed;
  right: 24px;
  top: 25px;
  z-index: 12;
  border: 0;
  background: transparent;
  color: #aabcb7;
  font: 12px var(--mono);
  padding: 10px;
  transition: color 0.2s;
}
#replay-opening:hover,
#replay-opening:focus-visible {
  color: var(--gold);
}
body.opened #replay-opening {
  display: none;
}

/* ------------------------- 3. The orb, its icons and the section text */

.globe-zone {
  position: absolute;
  inset: 0;
}
/* Three stacked canvases make up the orb (see js/opening.js). They are grouped so
   the soft-focus effect behind an open section is applied once, to the group. */
#globe-stage {
  position: absolute;
  inset: 0;
  transition:
    filter 0.5s,
    opacity 0.5s,
    transform 1.2s;
}
#globe-stage canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
#globe-under,
#globe-dots {
  pointer-events: none;
}
#globe {
  touch-action: none;
  cursor: grab;
}
#globe:active {
  cursor: grabbing;
}
#storm {
  transition:
    filter 1s,
    opacity 1s;
}

/* The icons are invisible hit targets: the visible icon is drawn dot by dot on the
   canvas, bent onto the orb. The script moves each target with `transform`. */
#nodes {
  position: absolute;
  inset: 0;
  pointer-events: none;
}
#nodes button,
.terminal {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: #d2cba8;
  pointer-events: auto;
  transform: translate(-50%, -50%);
}
#nodes button svg,
.terminal svg {
  width: 29px;
  height: 29px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-dasharray: 0.2 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
}
#nodes button:hover,
.terminal:hover {
  color: #ffe4aa;
}
.terminal {
  z-index: 5;
  width: 65px;
  height: 65px;
}
.terminal svg {
  width: 44px;
  height: 44px;
}
/* Visible lettering is drawn per letter on the canvas; the real text stays in the
   page for screen readers. */
#globe-name,
#nodes button span {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  margin: 0;
  pointer-events: none;
}

/* Reading mode: keep the text sharp, soften the surrounding atmosphere. */
article {
  position: absolute;
  z-index: 4;
  top: 52%;
  left: 50%;
  width: min(370px, 70vw);
  padding: 0;
  margin: 0;
  text-align: center;
  transform: translate(-50%, -50%);
}
#number {
  margin: 0 0 16px;
  font: 11px var(--mono);
  letter-spacing: 0.12em;
  color: var(--gold);
}
h2 {
  margin: 0 0 18px;
  font-size: clamp(25px, 3vw, 37px);
  line-height: 1.15;
  font-weight: 400;
}
#description {
  margin: 0 0 17px;
  color: #b6c3be;
  font-size: 16px;
  line-height: 1.7;
}
#detail {
  display: block;
  font: 11px/1.6 var(--mono);
  color: #a1b4af;
}
#close {
  position: absolute;
  top: 100%;
  left: 50%;
  margin-top: 17px;
  padding: 12px;
  border: 0;
  background: none;
  color: var(--gold);
  font: 12px var(--mono);
  transform: translateX(-50%);
}
/* While a section opens the orb is still moving, so it is only dimmed (cheap). The blur
   arrives once it has come to rest (body.rested), when it costs a single frame. */
.opened #globe-stage {
  opacity: 0.55 !important;
  transform: scale(1.015);
}
.opened.rested #globe-stage {
  filter: blur(2px);
}
.opened #globe {
  cursor: default;
}
.opened #storm {
  opacity: 0.35;
}
.opened.rested #storm {
  filter: blur(2px);
}
.opened .eyebrow,
.opened .lede {
  opacity: 0;
}
.opened #nodes button[aria-pressed='true'] {
  z-index: 6;
  pointer-events: none;
}
.opened #nodes button[aria-pressed='true'] svg {
  opacity: 1;
  transition: opacity 0.8s;
}
.opened article {
  animation: words-arrive 0.85s both;
}
@keyframes words-arrive {
  0%,
  35% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

/* --------------- 4. First-visit opening (loader, story, spotlight) */

/* A short arrival, followed by one clear destination. */
#arrival {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: grid;
  place-items: center;
  background: var(--night);
  transition:
    background 1s,
    opacity 0.6s;
}
#arrival.sweeping {
  background: transparent;
  pointer-events: none;
}
#arrival-loading,
.archive-loading-content {
  width: min(310px, 75vw);
  text-align: center;
  font: 12px var(--mono);
  color: var(--gold);
}
#arrival-loading img,
.archive-loading-content img {
  width: 62px;
  margin-bottom: 22px;
}
#arrival-loading p,
.archive-loading-content p {
  letter-spacing: 0.12em;
  line-height: 1.7;
}
.load-track {
  height: 3px;
  background: #b4d3c523;
  margin: 24px 0 12px;
}
#load-fill,
#archive-load-fill {
  display: block;
  height: 100%;
  width: 0;
  background: var(--gold);
}
#load-fill {
  box-shadow: 0 0 14px #dec89365;
}
#skip-arrival {
  position: absolute;
  bottom: 28px;
  right: 30px;
  border: 0;
  background: none;
  color: var(--muted);
  padding: 12px;
  font: 12px var(--mono);
  pointer-events: auto;
}

/* Fixed story geometry keeps the game title steady through changing line wraps. */
#arrival-story {
  width: min(780px, 95vw);
  height: 330px;
  padding: 20px;
  text-align: center;
  font:
    clamp(21px, 3vw, 34px) / 1.7 var(--serif);
  color: var(--ink);
  text-shadow: 0 2px 30px var(--night);
  isolation: isolate;
}
/* An unboxed shadow field protects the story from bright moving particles. */
#arrival-story::before {
  content: '';
  position: absolute;
  inset: -75px -10vw;
  z-index: -1;
  background: radial-gradient(ellipse, #02090ff5 12%, #02090fc9 42%, #02090f00 72%);
  opacity: var(--shade-opacity, 1);
  pointer-events: none;
}
#story-chapter {
  display: block;
  margin-bottom: 22px;
  font: 12px/1.6 var(--mono);
  letter-spacing: 0.18em;
  color: #f0d895;
}
#story-line {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 126px;
  margin: 0 0 24px;
  color: #ffffff;
  font-size: clamp(28px, 4vw, 46px);
  line-height: 1.35;
  text-shadow: 0 2px 8px #000;
}
#story-note {
  display: block;
  min-height: 66px;
  font-size: clamp(16px, 2vw, 20px);
  font-style: normal;
  line-height: 1.65;
  color: #e8eee9;
}
/* Letters of the story are redrawn here as dots while they are pulled into the ring. */
#word-particles {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 21;
  pointer-events: none;
}

/* After the opening: everything but the terminal icon is softened. */
#terminal-spotlight {
  position: fixed;
  inset: 0;
  z-index: 9;
  pointer-events: none;
  backdrop-filter: blur(5px);
  background: #07101445;
  --hole: radial-gradient(circle 160px at var(--spot-x, 50%) var(--spot-y, 53%), transparent 78%, #000 100%);
  -webkit-mask-image: var(--hole);
  mask-image: var(--hole);
}
#terminal-guide {
  position: fixed;
  top: calc(53% + 180px);
  left: 50%;
  z-index: 10;
  width: min(400px, 85vw);
  text-align: center;
  font: 12px/1.6 var(--mono);
  color: var(--muted);
  transform: translateX(-50%);
}
#terminal-guide p {
  margin: 0 0 9px;
}
#terminal-guide strong {
  display: block;
  color: var(--gold);
  font-weight: normal;
  font-size: 14px;
}
#explore-orb {
  padding: 14px;
  margin-top: 13px;
  border: 0;
  background: none;
  color: var(--muted);
  font: 12px var(--mono);
}
#terminal-spotlight,
#terminal-guide {
  animation: guide-emerge 1.2s both;
}
@keyframes guide-emerge {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.onboarding header,
.onboarding .eyebrow,
.onboarding .lede,
.guided .lede {
  opacity: 0;
}
.guided #globe {
  cursor: default;
}
.guided #nodes button {
  pointer-events: none;
}

/* ---------------------- 5. Terminal handoff and archive loader */

/* The archive is revealed through a circle growing out of the terminal icon. */
#terminal-reveal {
  position: fixed;
  inset: 0;
  z-index: 30;
  background: #061014;
  clip-path: circle(0px at var(--reveal-x, 50%) var(--reveal-y, 50%));
  transition: clip-path 2.4s cubic-bezier(0.22, 0.65, 0.2, 1);
}
#terminal-reveal.revealing {
  clip-path: circle(150vmax at var(--reveal-x, 50%) var(--reveal-y, 50%));
}
#terminal-reveal.returning {
  transition: clip-path 1.8s cubic-bezier(0.45, 0, 0.25, 1);
}
#terminal-screen {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  opacity: 0;
  background: #061014;
  transition: opacity 2s ease 0.15s;
}
#terminal-reveal.ready #terminal-screen {
  opacity: 1;
}
/* Archive entry reuses the opening's calibration visual language. */
#archive-loader {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  background: var(--night);
}

/* ------------------------------------------------------- 6. Small screens */

@media (max-width: 650px) {
  header {
    padding: 18px 6vw;
  }
  .brand {
    gap: 7px;
    font-size: 14px;
  }
  .brand span {
    display: inline;
    max-width: 190px;
    font-size: 9px;
  }
  .eyebrow {
    font-size: 10px;
  }
  .lede {
    font-size: 11px;
  }
  .terminal {
    width: 62px;
    height: 62px;
  }
  .terminal svg {
    width: 40px;
    height: 40px;
  }
  article {
    width: 64vw;
  }
  h2 {
    font-size: 28px;
  }
  #description {
    font-size: 15px;
    line-height: 1.6;
  }
  #number {
    font-size: 10px;
  }
  #close {
    margin-top: 10px;
  }
  #arrival-story {
    height: 370px;
    padding: 28px;
  }
  #arrival-story::before {
    inset: -80px -20vw;
  }
  #story-line {
    min-height: 150px;
  }
  #terminal-spotlight {
    --hole: radial-gradient(circle 140px at var(--spot-x, 50%) var(--spot-y, 53%), transparent 80%, #000 100%);
  }
  #terminal-guide {
    top: calc(53% + 150px);
  }
  /* On a phone the replay link sits centred under the hint instead of on top of it. */
  .lede {
    bottom: 34px;
  }
  #replay-opening {
    top: auto;
    bottom: 4px;
    left: 0;
    right: 0;
    width: 100%;
    font-size: 11px;
  }
}
@media (max-height: 650px) {
  .eyebrow {
    top: 55px;
  }
  article {
    width: min(430px, 70vw);
  }
  h2 {
    margin-bottom: 10px;
    font-size: 25px;
  }
  #description {
    font-size: 14px;
    line-height: 1.5;
  }
  #number {
    margin-bottom: 9px;
  }
  #detail {
    font-size: 10px;
  }
  #close {
    margin-top: 0;
  }
  #terminal-guide {
    top: calc(53% + 145px);
  }
  #terminal-guide p {
    display: none;
  }
  #terminal-guide #explore-orb {
    margin-top: 0;
    padding: 8px;
  }
}

/* ------------------------------------------------------ 7. Reduced motion */

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
  }
  .opened article,
  #terminal-spotlight,
  #terminal-guide {
    animation: none;
  }
  .opened #globe-stage {
    transform: none;
  }
}

/* buttons take the label face unless a rule says otherwise */
:where(button) {
  font-family: var(--mono);
}

/* ---- first-visit notice on the archive loading screen ---- */
#archive-loader.with-notice .archive-loading-content {
  width: min(520px, 90vw);
}
#archive-loader.with-notice .archive-loading-content img {
  width: 46px;
  margin-bottom: 12px;
}
#archive-loader {
  overflow-y: auto;
  padding: 20px 0;
}
#archive-notice {
  margin-top: 26px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
  font-family: var(--serif);
}
#archive-notice .notice-tag {
  font: 11px var(--mono);
  letter-spacing: 0.16em;
  color: var(--gold);
}
#archive-notice ul {
  margin: 12px 0 20px;
  padding: 0;
  list-style: none;
  text-align: left;
}
#archive-notice li {
  padding: 10px 0;
  border-top: 1px solid var(--line);
  font-size: 15px;
  line-height: 1.6;
  letter-spacing: 0;
  color: #b6c3be;
}
#archive-notice li:first-child {
  border-top: 0;
}
#archive-notice li b {
  display: block;
  color: var(--ink);
  font-weight: 600;
}
#archive-notice-accept {
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--gold);
  border-radius: 8px;
  background: #d8bf871f;
  color: #ffe4aa;
  font: 13px var(--mono);
  letter-spacing: 0.06em;
  transition: background 0.2s;
}
#archive-notice-accept:hover,
#archive-notice-accept:focus-visible {
  background: #d8bf8740;
}
#archive-notice-back {
  margin-top: 6px;
  padding: 10px;
  border: 0;
  background: none;
  color: var(--muted);
  font: 12px var(--mono);
}
#archive-notice-back:hover {
  color: var(--gold);
}
#archive-notice .notice-fine {
  margin: 4px 0 0;
  font: 11px var(--mono);
  letter-spacing: 0.04em;
  color: var(--muted);
}

/* ---- the terminal did not arrive: say so, offer another try ---- */
#archive-trouble {
  margin-top: 26px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}
#archive-trouble .notice-tag {
  font: 11px var(--mono);
  letter-spacing: 0.16em;
  color: var(--gold);
}
#archive-trouble p {
  margin: 12px 0 18px;
  font: 15px/1.6 var(--serif);
  letter-spacing: 0;
  color: #b6c3be;
}
#archive-trouble .notice-fine {
  margin: 4px 0 0;
  font: 11px var(--mono);
  color: var(--muted);
}
#archive-trouble a {
  color: var(--gold);
  text-decoration: underline;
}
#archive-retry {
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--gold);
  border-radius: 8px;
  background: #d8bf871f;
  color: #ffe4aa;
  font: 13px var(--mono);
  letter-spacing: 0.06em;
}
#archive-retry:hover,
#archive-retry:focus-visible {
  background: #d8bf8740;
}
#archive-trouble-back {
  margin-top: 6px;
  padding: 10px;
  border: 0;
  background: none;
  color: var(--muted);
  font: 12px var(--mono);
}
#archive-loader.with-trouble .archive-loading-content {
  width: min(520px, 90vw);
}
#archive-loader.with-trouble #archive-notice,
#archive-loader.with-trouble .load-track,
#archive-loader.with-trouble #archive-load-percent {
  display: none;
}

/* ---- scripting switched off: a plain door instead of an empty loading screen ---- */
.nojs-door {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 4px;
  padding: 24px;
  background: var(--night);
  text-align: center;
}
.nojs-door img {
  width: 62px;
  margin-bottom: 14px;
}
.nojs-door .nojs-tag {
  font: 11px var(--mono);
  letter-spacing: 0.14em;
  color: var(--gold);
}
.nojs-door h1 {
  margin: 6px 0 14px;
  font: 400 32px/1.15 var(--serif);
}
.nojs-door p {
  max-width: 420px;
  margin: 0 0 10px;
  font: 15px/1.6 var(--serif);
  color: #b6c3be;
}
.nojs-door a {
  color: var(--gold);
  text-decoration: underline;
}
