:root {
  --paper: #fbf6ea;
  --ink: #3b342c;
  --accent: #e2583e;
  --backdrop: #efe6d6;
  --type: 'American Typewriter', 'Courier New', Courier, monospace;
  --hand: 'Bradley Hand', 'Segoe Print', 'Noteworthy', 'Marker Felt', 'Comic Sans MS', cursive;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--backdrop);
  color: var(--ink);
  font-family: var(--type);
  -webkit-user-select: none;
  user-select: none;
}

#scene {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
  outline: none;
}

/* Paper tags: a cut corner and a soft drop shadow, like a luggage label. */
.tag {
  position: fixed;
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  filter: drop-shadow(0 3px 5px rgba(60, 40, 20, 0.28));
  clip-path: polygon(0 0, calc(100% - 16px) 0, 100% 16px, 100% 100%, 0 100%);
}

.title {
  top: max(18px, env(safe-area-inset-top));
  left: max(18px, env(safe-area-inset-left));
  padding: 12px 30px 12px 18px;
  transform: rotate(-1.6deg);
  pointer-events: none;
  transition: opacity 0.6s;
}

.title h1 {
  margin: 0;
  font-size: clamp(18px, 2.2vw, 26px);
  font-weight: 700;
  letter-spacing: 0.04em;
}

.title p {
  margin: 2px 0 0;
  font-family: var(--hand);
  font-size: clamp(14px, 1.5vw, 18px);
  opacity: 0.75;
}

/* Hint: a torn strip of paper along the bottom. */
.strip {
  position: fixed;
  left: 50%;
  bottom: max(20px, env(safe-area-inset-bottom));
  margin: 0;
  padding: 9px 22px;
  max-width: calc(100vw - 32px);
  background: var(--paper);
  font-size: clamp(13px, 1.4vw, 16px);
  text-align: center;
  transform: translateX(-50%) rotate(0.6deg);
  filter: drop-shadow(0 3px 5px rgba(60, 40, 20, 0.25));
  clip-path: polygon(0 12%, 3% 0, 7% 10%, 12% 2%, 100% 0, 99% 100%, 93% 92%, 88% 100%, 1% 100%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s;
}

.strip.show {
  opacity: 1;
}

.viewer {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.7s;
}

.caption {
  left: 50%;
  bottom: max(22px, env(safe-area-inset-bottom));
  padding: 10px 30px 10px 20px;
  max-width: calc(100vw - 32px);
  font-family: var(--hand);
  font-size: clamp(16px, 1.9vw, 22px);
  text-align: center;
  transform: translateX(-50%) rotate(-0.8deg);
}

.caption small {
  display: block;
  font-family: var(--type);
  font-size: 0.6em;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.7;
}

.stop {
  top: max(18px, env(safe-area-inset-top));
  right: max(18px, env(safe-area-inset-right));
  padding: 12px 30px 12px 20px;
  border: 0;
  font: 700 clamp(14px, 1.5vw, 17px) var(--type);
  letter-spacing: 0.04em;
  cursor: pointer;
  transform: rotate(1.4deg);
  transition: transform 0.15s, background 0.15s;
}

.stop::before {
  content: '';
  display: inline-block;
  width: 0.7em;
  height: 0.7em;
  margin-right: 0.6em;
  background: var(--accent);
}

.stop:hover {
  transform: rotate(0deg) scale(1.05);
  background: #fff;
}

.stop:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

body.viewing .viewer {
  opacity: 1;
}

body.viewing .stop {
  pointer-events: auto;
}

body.viewing .title,
body.viewing .shelves {
  opacity: 0;
  pointer-events: none;
}

/* While a picture is up, the hint moves to the top so the caption has the bottom. */
body.viewing .hint {
  bottom: auto;
  top: max(20px, env(safe-area-inset-top));
}

/* Shelf arrows are pinned to the ends of the 3D shelf by script. */
.shelves {
  transition: opacity 0.5s;
}

.shelves[hidden] {
  display: none;
}

.arrow {
  top: 0;
  left: 0;
  width: 46px;
  height: 54px;
  padding: 0 0 4px;
  border: 0;
  font: 700 34px/1 var(--type);
  cursor: pointer;
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
  transition: background 0.15s, opacity 0.3s, scale 0.15s;
}

.arrow:hover:not(:disabled) {
  background: #fff;
  scale: 1.12;
}

.arrow:disabled {
  opacity: 0.35;
  cursor: default;
}

.arrow:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

.shelf-label {
  top: max(22px, env(safe-area-inset-top));
  left: 50%;
  padding: 7px 24px 7px 16px;
  font-size: clamp(12px, 1.2vw, 15px);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transform: translateX(-50%) rotate(0.8deg);
  pointer-events: none;
}

.sound {
  left: max(18px, env(safe-area-inset-left));
  bottom: max(20px, env(safe-area-inset-bottom));
  padding: 8px 24px 8px 14px;
  border: 0;
  font: 700 clamp(11px, 1.1vw, 14px) var(--type);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transform: rotate(-1.2deg);
  clip-path: polygon(0 0, calc(100% - 12px) 0, 100% 12px, 100% 100%, 0 100%);
  transition: background 0.15s;
}

.sound:hover {
  background: #fff;
}

.sound[aria-pressed='false'] {
  opacity: 0.6;
}

.sound:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
}

/* Loading screen: a sheet of paper over everything until the photos are in. */
.loader {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: grid;
  place-items: center;
  background: var(--backdrop);
  transition: opacity 0.7s, visibility 0.7s;
}

.loader.done {
  opacity: 0;
  visibility: hidden;
}

.loader-card {
  width: min(340px, calc(100vw - 48px));
  padding: 26px 30px 28px;
  background: var(--paper);
  transform: rotate(-1.2deg);
  filter: drop-shadow(0 6px 10px rgba(60, 40, 20, 0.25));
  clip-path: polygon(0 0, calc(100% - 22px) 0, 100% 22px, 100% 100%, 0 100%);
}

.loader-card h2 {
  margin: 0;
  font-size: 26px;
  letter-spacing: 0.04em;
}

.loader-card p {
  margin: 6px 0 18px;
  font-family: var(--hand);
  font-size: 18px;
  opacity: 0.8;
}

.loader-bar {
  height: 10px;
  background: rgba(59, 52, 44, 0.14);
}

.loader-bar i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
  transition: width 0.25s;
}

@media (max-width: 700px) {
  .shelf-label {
    left: auto;
    right: max(14px, env(safe-area-inset-right));
    transform: rotate(0.8deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .tag,
  .strip,
  .viewer {
    transition: none;
  }
}
