/* World tab. Almost everything here is one canvas over the stage; this file
   holds that canvas, the pixel hand, and the page around them. */

html[data-page="world"],
html[data-page="world"] body {
  height: 100%;
  overflow: hidden;
  /* a sideways trackpad swipe spins the world, it must not go back a page */
  overscroll-behavior: none;
  background: #06070b;
}

/* The void covers the flight, and page changes pass through black, not blue. */
html[data-page="world"] #stage { visibility: hidden; }
html[data-page="world"] body::before { background: #06070b; }

/* Near-black from the first paint, before three.js has arrived. */
.world-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  background: #06070b;
  outline: 0;
  cursor: grab;
  /* one finger belongs to the world, two still zoom the page */
  touch-action: pinch-zoom;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.world-canvas.has-hand,
.world-canvas.has-hand:active { cursor: none; }
.world-canvas:active { cursor: grabbing; }

/* The pixel hand. Whole-number sizes only, or the pixels stop being square. */
.world-hand {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 11;
  width: 48px;
  height: 60px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 180ms ease-out;
  will-change: transform;
}

.world-hand.is-on { opacity: 1; }

.world-hand svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  visibility: hidden;
}

.world-hand [data-hand="point"],
.world-hand.is-down [data-hand="grip"] { visibility: visible; }
.world-hand.is-down [data-hand="point"] { visibility: hidden; }

/* No cursor on a phone, so the hand shows once what the screen wants. */
.world-hand.is-hint {
  left: 50%;
  top: 58%;
  margin-left: -24px;
  opacity: 1;
  animation: world-hint 2.8s steps(14, end) 3 forwards, world-hint-out .3s ease-out 8.4s forwards;
}

.world-hand.is-hint.is-gone {
  opacity: 0;
  animation: none;
}

@keyframes world-hint {
  0%, 100% { transform: translateX(-28px); }
  50% { transform: translateX(28px); }
}

@keyframes world-hint-out {
  to { opacity: 0; }
}

/* What each picture is. Real text in the page, unseen while the world can show it. */
.world-list {
  position: fixed;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  list-style: none;
}

/* The caption under a card. A dark chip, because a card can pass behind it. */
.world-tag {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 10;
  width: max-content;
  max-width: min(300px, calc(100vw - 32px));
  padding: 10px 13px 11px;
  border-radius: 10px;
  background: rgba(6, 7, 11, .72);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  pointer-events: none;
  opacity: 0;
  transition: opacity .16s ease-out;
  will-change: transform;
}

.world-tag.is-on { opacity: 1; }

.world-tag b {
  display: block;
  font-family: var(--serif);
  font-size: 18px;
  font-weight: 400;
  line-height: 1.15;
  letter-spacing: -.01em;
}

.world-tag span {
  display: block;
  margin-top: 3px;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.3;
  color: var(--ink-2);
}

/* The note beside a chosen card. It holds its place while hidden: the card measures it. */
.world-note {
  position: fixed;
  z-index: 10;
  right: max(var(--gutter), 7vw);
  top: 50%;
  width: min(32vw, 440px);
  transform: translateY(calc(-50% + 10px));
  opacity: 0;
  visibility: hidden;
  transition: opacity .25s ease-out, transform .5s var(--ease), visibility 0s .25s;
}

.world-note.is-on {
  transform: translateY(-50%);
  opacity: 1;
  visibility: visible;
  transition: opacity .35s ease-out .15s, transform .6s var(--ease) .15s, visibility 0s;
}

.world-note b {
  display: block;
  font-family: var(--serif);
  font-size: clamp(32px, 3.3vw, 58px);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -.02em;
  text-wrap: balance;
}

.world-note p {
  margin-top: 14px;
  font-size: clamp(16px, 1.25vw, 21px);
  font-weight: 400;
  color: var(--ink-2);
  text-wrap: pretty;
}

.world-note .pill { margin-top: 22px; }
.world-note a[hidden] { display: none; }
.world-note.is-link .pill { outline: 2px solid var(--ink); outline-offset: 3px; }

.world-back {
  display: block;
  margin-top: 13px;
  padding: 11px 0;
  border: 0;
  background: none;
  color: var(--ink-2);
  font-size: 14px;
  font-weight: 400;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

@media (hover: hover) {
  .world-back:hover { color: var(--ink); }
}

/* The line frameCard draws in world.js. */
@media (max-aspect-ratio: 11/10) {
  .world-note {
    left: var(--gutter);
    right: var(--gutter);
    top: auto;
    bottom: var(--foot-h);
    width: auto;
    transform: translateY(10px);
  }
  .world-note.is-on { transform: none; }
  .world-note b { font-size: clamp(28px, 8vw, 44px); }
}

.world-hint {
  position: fixed;
  z-index: 10;
  left: 50%;
  bottom: calc(var(--foot-h) * .36);
  transform: translateX(-50%);
  font-size: 13px;
  font-weight: 400;
  white-space: nowrap;
  color: var(--ink-2);
  pointer-events: none;
  opacity: 0;
  animation: world-word 1s ease-out 3.4s forwards;
}

.world-hint.is-gone { display: none; }

@keyframes world-word {
  to { opacity: 1; }
}

/* Without WebGL: the same images and words, in a row that scrolls. */
html .world-list.is-flat {
  inset: 0;
  display: flex;
  align-items: center;
  gap: 24px;
  width: auto;
  height: auto;
  padding: 0 var(--gutter);
  overflow: auto hidden;
  clip-path: none;
  white-space: normal;
  scroll-snap-type: x proximity;
}

.world-list.is-flat:focus-visible { outline-offset: -6px; }

.is-flat li {
  flex: none;
  width: min(74vw, 380px);
  scroll-snap-align: center;
}

.is-flat img {
  width: 100%;
  height: min(50vh, 340px);
  margin-bottom: 14px;
  object-fit: contain;
  object-position: left center;
}

.world-list h2 {
  font-family: var(--serif);
  font-size: 22px;
  font-weight: 400;
  line-height: 1.15;
}

.world-list p {
  margin-top: 4px;
  font-size: 15px;
  font-weight: 400;
  color: var(--ink-2);
}

.world-list a {
  display: inline-block;
  margin-top: 6px;
  font-size: 15px;
  font-weight: 400;
  color: var(--ink);
}

/* The script never ran: the list is the page. */
html.calm #page:not(.world-live) .world-list:not(.is-flat) {
  position: static;
  width: auto;
  height: auto;
  max-width: 640px;
  padding: calc(var(--nav-h) + 16px) var(--gutter) calc(var(--foot-h) + 16px);
  overflow: visible;
  clip-path: none;
  white-space: normal;
}
html.calm #page:not(.world-live) .world-list:not(.is-flat) li { margin-top: 20px; }
html.calm:has(#page:not(.world-live)):has(.world-list:not(.is-flat)),
html.calm:has(#page:not(.world-live)):has(.world-list:not(.is-flat)) body {
  height: auto;
  overflow: auto;
}

@media (scripting: none) {
  html[data-page="world"],
  html[data-page="world"] body {
    height: auto;
    overflow: auto;
  }
  .world-list {
    position: static;
    width: auto;
    height: auto;
    max-width: 640px;
    padding: calc(var(--nav-h) + 16px) var(--gutter) calc(var(--foot-h) + 16px);
    overflow: visible;
    clip-path: none;
    white-space: normal;
  }
  .world-list li { margin-top: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .world-hand.is-hint { animation: none; }
  .world-hint { opacity: 1; }
}
