/* oomoo -- the wall. Same construction as css/graphics/graphics.css: this file is the page,
 * and the imports are the whole dependency list.
 *
 * Unlike the reading pages this one is a fixed viewport: the room (.room) is a horizontal
 * scroll container pinned to the screen, the track inside it is as wide as the four walls
 * need, and the floor runs along the bottom. Everything else -- the note and the
 * lightbox -- is fixed chrome over the top.
 *
 * Cork doesn't change with the theme, so the palette here is the room's own (paper, wood,
 * pins). Tokens are still loaded for the lightbox chrome and the type roles.
 */

@import url('../tokens.css');
@import url('../reset.css');
@import url('../utilities.css');
@import url('../home/fonts.css');

:root {
  --floor: 14vh; /* the strip the guy walks on */
  --gutter: clamp(40px, 6vw, 120px); /* space at each end of a wall */
  --gap: clamp(28px, 4vw, 72px); /* between things on a wall */

  --paper: #f6efdc;
  --paper-rule: #9fb7d9;
  --paper-head: #d9534f;
  --paper-ink: #2b2420;
  --wood: #6b4a2b;
  --wood-dark: #3d2a17;
  --baseboard: #2a1a10;
}

/* ------------------------------------------------------------------- Page */

html,
body {
  height: 100%;
  overflow: hidden;
}

body {
  background: var(--wood-dark);
  color: var(--paper-ink);
  font-family: 'National Park', system-ui, sans-serif;
  line-height: 1.45;
}

.label {
  text-transform: uppercase;
  font-family: var(--chrome-face);
  letter-spacing: 0.04em;
}

a {
  color: inherit;
}

/* ------------------------------------------------------------------- Room */

.room {
  position: fixed;
  inset: 0;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  outline: none;
}

.room::-webkit-scrollbar {
  display: none;
}

.track {
  position: relative;
  display: flex;
  align-items: stretch;
  width: max-content;
  min-width: 100%;
  height: 100%;
  padding-bottom: var(--floor);

  background: url('/media/backgrounds/cork.jpg') repeat;
  background-size: 512px;
}

/* The floor: ruled paper (backgrounds/paper.png, tiled), a baseboard along the top edge,
   and the wall's shadow falling onto it. Absolutely placed so it stretches the whole
   track, however wide that ends up. */
.track::after {
  content: '';
  position: absolute;
  inset: auto 0 0 0;
  height: var(--floor);
  border-top: 6px solid var(--baseboard);
  background:
    linear-gradient(180deg, rgb(0 0 0 / 35%), transparent 45%),
    url('/media/backgrounds/paper.png') repeat #fff;
  pointer-events: none;
}

/* ------------------------------------------------------------------- Wall */

.wall {
  display: flex;
  align-items: flex-start;
  gap: var(--gap);
  padding: 9vh var(--gutter) 0;
}

/* Hanging sign at the start of each wall: a small plaque on a string. */
.sign {
  position: relative;
  flex: none;
  align-self: flex-start;
  margin-top: 13vh; /* clear of the sticky note in the corner */
  padding: 0.35em 0.8em 0.3em;
  border: 2px solid var(--baseboard);
  border-radius: 3px;
  background: var(--wood);
  color: var(--paper);
  font-family: 'Terminal Grotesque', 'National Park', sans-serif;
  font-size: clamp(1rem, 2.4vh, 1.4rem);
  line-height: 1;
  text-transform: lowercase;
  white-space: nowrap;
  box-shadow: 0 6px 12px rgb(0 0 0 / 40%);
  transform: rotate(-3deg);
}

.sign::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 100%;
  width: 2px;
  height: 24vh; /* up through the wall's top padding to the ceiling */
  background: rgb(0 0 0 / 60%);
  transform: translateX(-50%);
}

/* The corner where two walls meet: a seam of shadow. */
.corner {
  flex: none;
  width: clamp(60px, 8vw, 140px);
  background: linear-gradient(
    90deg,
    rgb(0 0 0 / 55%),
    rgb(0 0 0 / 10%) 46%,
    rgb(0 0 0 / 75%) 50%,
    rgb(0 0 0 / 10%) 54%,
    rgb(0 0 0 / 55%)
  );
}

/* ----------------------------------------------------------------- Poster */

/* Sized by what the thing is, not by how many pixels the scan has: a ticket stub and a
   tour poster were both photographed to fill the frame. The four steps leave room for the
   rise above and the index card below inside the wall's height -- small things get to
   hang lower (a bigger share of --rise), big ones stay near the top. */
.poster {
  --h: 30vh;
  --rise-scale: 1;
  position: relative;
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  /* Never lower than the eye line (--hang-to), whatever the rise says: the floor is at
     86vh and a card may hang underneath. */
  margin-top: min(calc(var(--rise) * var(--rise-scale)), calc(var(--hang-to) - var(--h) - 9vh));
  --hang-to: 76vh;
  transform: rotate(var(--rot));
  transform-origin: 50% 0;
  transition: transform 220ms ease-out;
}

.poster:has(.card) {
  --hang-to: 62vh;
}

.poster[data-size='s'] {
  --h: 18vh;
  --rise-scale: 2.6;
}

.poster[data-size='m'] {
  --h: 30vh;
  --rise-scale: 1.7;
}

.poster[data-size='l'] {
  --h: 44vh;
  --rise-scale: 0.7;
}

.poster[data-size='xl'] {
  --h: 54vh;
  --rise-scale: 0.25;
}

/* Standing in front of something -- or pointing at it -- straightens it a touch and lifts
   it off the cork. */
.poster--near,
.poster:hover {
  z-index: 2;
  transform: rotate(calc(var(--rot) / 3)) scale(1.03);
}

.poster__btn {
  all: unset;
  display: block;
  position: relative;
  cursor: zoom-in;
  box-shadow: 0 10px 22px rgb(0 0 0 / 45%);
  background: white;
}

.poster__btn:focus-visible {
  outline: 3px solid var(--paper);
  outline-offset: 4px;
}

/* Sized by height, but never wider than 44vw: on a narrow screen the height comes down
   with the width (--ar is the picture's w / h, from the template) so the button's white
   never shows around the picture. */
.poster__img {
  display: block;
  height: min(var(--h), calc(44vw / var(--ar, 1)));
  width: auto;
}

/* The pin. Four colours, chosen per index in the template. */
.poster__btn::before {
  content: '';
  position: absolute;
  top: -7px;
  left: 50%;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  transform: translateX(-50%);
  background: radial-gradient(
    circle at 35% 35%,
    white 0 12%,
    var(--pin-color) 20%,
    color-mix(in srgb, var(--pin-color) 55%, black) 100%
  );
  box-shadow: 0 3px 4px rgb(0 0 0 / 50%);
  --pin-color: #d23a2a;
}

.poster[data-pin='1'] .poster__btn::before {
  --pin-color: #2f6fd2;
}

.poster[data-pin='2'] .poster__btn::before {
  --pin-color: #e0b81c;
}

.poster[data-pin='3'] .poster__btn::before {
  --pin-color: #2f9e5a;
}

/* ------------------------------------------------------------- Index card */

.card {
  position: relative;
  width: clamp(11rem, 20vw, 16rem);
  padding: 1.1em 0.9em 0.9em;
  border-radius: 2px;
  background:
    linear-gradient(
      180deg,
      transparent 0 1.05em,
      var(--paper-head) 1.05em calc(1.05em + 1px),
      transparent calc(1.05em + 1px)
    ),
    repeating-linear-gradient(
      180deg,
      transparent 0 calc(1.45em - 1px),
      var(--paper-rule) calc(1.45em - 1px) 1.45em
    ),
    var(--paper);
  background-position:
    0 0,
    0 1.35em,
    0 0;
  color: var(--paper-ink);
  font-size: clamp(0.72rem, 1.7vh, 0.9rem);
  line-height: 1.45;
  box-shadow: 0 6px 14px rgb(0 0 0 / 40%);
  transform: rotate(calc(var(--rot) * -0.6));
}

.card em {
  font-style: italic;
}

/* The hover aside inside a caption: an underlined phrase you can point at. tabindex=0 on
   the span makes it keyboard- and tap-reachable, hence :focus-within. */
.tip {
  position: relative;
  text-decoration: underline dotted;
  text-decoration-color: var(--paper-head);
  cursor: help;
}

.tip__text {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  z-index: 3;
  width: max-content;
  max-width: 16rem;
  padding: 0.4em 0.7em;
  border-radius: 3px;
  background: var(--paper-ink);
  color: var(--paper);
  font-size: 0.9em;
  line-height: 1.3;
  white-space: normal;
  transform: translateX(-50%);
  opacity: 0;
  visibility: hidden;
  transition: opacity 120ms;
  pointer-events: none;
}

.tip:hover .tip__text,
.tip:focus-within .tip__text {
  opacity: 1;
  visibility: visible;
}

/* ---------------------------------------------------------------- Penguin */

.guy {
  --x: 0px;
  --dir: 1;
  position: absolute;
  z-index: 3; /* over the floor, which is painted after him in the tree */
  left: 0;
  bottom: calc(var(--floor) * 0.3);
  height: clamp(64px, 12vh, 120px);
  aspect-ratio: 186 / 200; /* the gif's frame */
  transform: translateX(var(--x)) scaleX(var(--dir));
  transform-origin: 50% 100%;
  will-change: transform;
  pointer-events: none;
  filter: drop-shadow(0 4px 3px rgb(0 0 0 / 40%));
}

.guy__walk,
.guy__idle {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Standing still is the canvas frame; walking swaps in the gif. Until the script has
   drawn the frame the canvas is blank, so the gif shows by default and the class
   .guy--ready flips the two. */
.guy__idle {
  display: none;
}

.guy--ready:not(.guy--walking) .guy__idle {
  display: block;
}

.guy--ready:not(.guy--walking) .guy__walk {
  display: none;
}

/* ----------------------------------------------------------- Sticky note */
/* By the door, at the start of the first wall. Scrolls away with it. */

.note {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 4;
  width: clamp(12rem, 22vw, 17rem);
  padding: 0.8em 1em 0.9em;
  background: #fff3a8;
  color: var(--paper-ink);
  box-shadow: 0 8px 18px rgb(0 0 0 / 40%);
  transform: rotate(-1.5deg);
}

.note__back {
  font-size: 10px;
  text-decoration: none;
  opacity: 0.7;
}

.note__back:hover {
  opacity: 1;
}

.note__title {
  margin-top: 0.15em;
  font-family: 'Terminal Grotesque', 'National Park', sans-serif;
  font-size: clamp(1.6rem, 4vh, 2.4rem);
  line-height: 1;
}

.note__where {
  margin-top: 0.45em;
  font-size: 0.78rem;
  line-height: 1.4;
}

.note__here b {
  font-weight: 700;
}

/* Short screens (phones on their side): the note shrinks to the way out and the title. */
@media (max-height: 500px) {
  .note {
    width: auto;
    padding: 0.5em 0.8em 0.6em;
  }

  .note__title {
    font-size: 1.2rem;
  }

  .note__where {
    display: none;
  }
}

/* --------------------------------------------------------------- Lightbox */

.lightbox {
  margin: 0;
  padding: 0;
  border: 0;
  width: 100%;
  height: 100%;
  max-width: 100vw;
  max-height: 100vh;
  background: transparent;
  color: var(--paper-ink);
}

.lightbox[open] {
  display: grid;
  place-items: center;
}

.lightbox::backdrop {
  background: rgb(0 0 0 / 82%);
}

.lightbox__figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  max-width: 92vw;
}

.lightbox__img {
  display: block;
  max-width: 92vw;
  max-height: 74vh;
  width: auto;
  height: auto;
  box-shadow: 0 18px 40px rgb(0 0 0 / 60%);
  background: #111;
}

.lightbox__card {
  width: clamp(14rem, 34vw, 24rem);
  font-size: clamp(0.8rem, 1.9vh, 1rem);
  transform: none;
}

/* Wide and short screens (phones in landscape): card beside the picture, not under it. */
@media (min-aspect-ratio: 16/9) and (max-height: 520px) {
  .lightbox__figure {
    flex-direction: row;
    align-items: center;
  }

  .lightbox__img {
    max-height: 86vh;
    max-width: 60vw;
  }
}

.lightbox__step,
.lightbox__close {
  position: fixed;
  z-index: 2;
  cursor: pointer;
}

.lightbox__close {
  top: 14px;
  right: 14px;
  padding: 0.5em 0.8em;
  border: 1px solid rgb(255 255 255 / 30%);
  border-radius: 999px;
  background: rgb(0 0 0 / 50%);
  color: var(--paper);
  font-size: 12px;
}

.lightbox__close:hover {
  background: rgb(255 255 255 / 15%);
}

/* The bouncing arrow gif points up; turned to face the way each button goes. */
.lightbox__step {
  top: 50%;
  padding: 6px;
  border: 0;
  background: none;
  transform: translateY(-50%);
}

.lightbox__step img {
  display: block;
  width: 48px;
  height: 48px;
  image-rendering: pixelated;
}

.lightbox__step--prev {
  left: 14px;
}

.lightbox__step--prev img {
  transform: rotate(-90deg);
}

.lightbox__step--next {
  right: 14px;
}

.lightbox__step--next img {
  transform: rotate(90deg);
}

.lightbox__step:hover img {
  filter: brightness(1.15);
}

.lightbox__step[disabled] {
  opacity: 0.25;
  cursor: default;
}

/* ------------------------------------------------------------------ Motion */

@media (prefers-reduced-motion: reduce) {
  .poster,
  .tip__text {
    transition: none;
  }

  /* No animated gif: the still frame, walking or not. */
  .guy--ready .guy__idle {
    display: block;
  }

  .guy--ready .guy__walk {
    display: none;
  }
}
