/* The rope ladder menu: a wooden trapdoor on a black page; under it, when it opens, a rope ladder. The ropes are drawn
   by the script on the canvas; the rungs are links that the script moves every frame (translate and rotate). */
:root {
  --page: #000000;          /* the page */
  --frame: #3a2516;         /* the frame of the trapdoor */
  --lid: #a8743f;           /* the boards of the lid */
  --iron: #26211d;          /* the straps and the hinges */
  --brass: #c9973f;         /* the ring pull */
  --wood: #d6a86a;          /* the rungs */
  --burn: #3a2211;          /* the names burnt into the wood */
  --rope: #c9a46c;          /* the rope */
  --rope-dark: #6e5233;     /* the twist in the rope */
  --glow: #ffb25e;          /* the warm light inside the treehouse */
  --lit: #ffcf8a;           /* a chosen rung, lit up */
  --ember: #7a2e0c;         /* the name of the section you are on */
  --focus: #ffd59c;         /* the ring of the keyboard focus */
}

* {
  box-sizing: border-box;
}

html {
  touch-action: manipulation;
}

html,
body {
  margin: 0;
  overflow-x: clip;
}

body {
  min-height: 100svh;
  background: var(--page);
  color: var(--burn);
  font-family: 'Bricolage Grotesque Variable', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

.sr {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.stage {
  min-height: 100svh;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  place-items: center;
  padding: 32px 16px;
}

/* ---------------------------------------------------------------- the frame of the whole thing */
.ladder {
  position: relative;
  width: 340px;
  height: 508px;              /* the script sets it from the length of the ladder */
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.ladder__ropes {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ---------------------------------------------------------------- the rungs */
.rung {
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 176px;
  height: 34px;
  opacity: 0;
  outline: none;
  cursor: pointer;
  will-change: transform;
  -webkit-tap-highlight-color: transparent;
  -webkit-user-drag: none;
}

/* the board: a plank of pale wood, lit from the hatch above, with its grain and the rope lashed round both ends */
.rung__wood {
  position: absolute;
  inset: 0;
  border-radius: 7px 7px 9px 9px / 9px 9px 12px 12px;
  background:
    linear-gradient(180deg, rgba(255, 244, 222, 0.5) 0, rgba(255, 244, 222, 0) 28%, rgba(0, 0, 0, 0) 58%, rgba(60, 30, 8, 0.5) 100%),
    repeating-linear-gradient(91deg, transparent 0 9px, rgba(90, 50, 20, 0.13) 9px 10px, transparent 10px 23px, rgba(90, 50, 20, 0.09) 23px 25px, transparent 25px 31px),
    var(--wood);
  box-shadow:
    inset 0 1px 0 rgba(255, 246, 228, 0.55),
    inset 0 -2px 0 rgba(70, 36, 10, 0.35),
    0 6px 10px -5px rgba(0, 0, 0, 0.9);
  transition: background-color 0.5s, box-shadow 0.5s;
}

/* the grain of the wood */
.rung__wood::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='40'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.012 .5' numOctaves='3' seed='4'/%3E%3CfeColorMatrix values='0 0 0 0 .3 0 0 0 0 .16 0 0 0 0 .05 0 0 0 .5 -.05'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: 100% 100%;
  mix-blend-mode: multiply;
  opacity: 0.8;
  pointer-events: none;
}

/* the rope goes through the board near each end and is lashed round it: a short twist of rope */
.rung__lash {
  position: absolute;
  left: 4px;
  top: -5px;
  bottom: -5px;
  width: 12px;
  border-radius: 5px;
  background:
    linear-gradient(90deg, rgba(40, 24, 8, 0.45), rgba(255, 240, 210, 0.25) 40%, rgba(40, 24, 8, 0.5)),
    repeating-linear-gradient(128deg, var(--rope) 0 2.6px, var(--rope-dark) 2.6px 4px);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
  z-index: 1;
}

.rung__lash--r {
  left: auto;
  right: 4px;
}

.rung__label {
  position: relative;
  z-index: 2;
  font-size: 15px;
  line-height: 1;
  font-weight: 640;
  font-stretch: 88%;
  letter-spacing: 0.005em;
  color: var(--burn);
  text-shadow: 0 1px 0 rgba(255, 238, 205, 0.45);
  white-space: nowrap;
  transition: font-stretch 0.35s cubic-bezier(0.3, 1.6, 0.5, 1), color 0.4s, text-shadow 0.4s;
}

/* under weight the name stretches with the rope */
.rung.is-loaded .rung__label {
  font-stretch: 100%;
}

/* the section you are on is burnt a little deeper, in the colour of embers */
.rung[aria-current='page'] .rung__label {
  color: var(--ember);
}

/* chosen: the rung lights up with the warm light of a lantern */
.rung.is-lit .rung__wood {
  background-color: var(--lit);
  box-shadow:
    inset 0 1px 0 rgba(255, 250, 235, 0.8),
    inset 0 -2px 0 rgba(140, 70, 10, 0.35),
    0 0 18px 2px rgba(255, 170, 80, 0.55),
    0 0 46px 6px rgba(255, 140, 50, 0.28);
}

.rung.is-lit .rung__label {
  color: #5a1d04;
  text-shadow: 0 0 10px rgba(255, 245, 220, 0.9);
}

.rung:focus-visible .rung__wood {
  box-shadow:
    0 0 0 2px var(--page),
    0 0 0 4px var(--focus),
    0 6px 10px -5px rgba(0, 0, 0, 0.9);
}

/* ---------------------------------------------------------------- the trapdoor */
.hatch {
  position: absolute;
  left: 50%;
  top: 8px;
  width: 216px;
  height: 60px;
  margin-left: -108px;
  padding: 0;
  border: 0;
  border-radius: 9px;
  background:
    linear-gradient(180deg, rgba(255, 230, 190, 0.18), rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0.35)),
    repeating-linear-gradient(0deg, transparent 0 5px, rgba(0, 0, 0, 0.12) 5px 6px),
    var(--frame);
  box-shadow:
    inset 0 1px 0 rgba(255, 220, 170, 0.28),
    inset 0 -1px 0 rgba(0, 0, 0, 0.6),
    0 10px 24px -8px rgba(0, 0, 0, 0.9);
  font: inherit;
  cursor: pointer;
  outline: none;
  z-index: 3;
  -webkit-tap-highlight-color: transparent;
}

.hatch:focus-visible {
  box-shadow:
    0 0 0 2px var(--page),
    0 0 0 4px var(--focus),
    inset 0 1px 0 rgba(255, 220, 170, 0.28);
}

/* the hole the lid covers: dark, with the warm light of the room above */
.hatch__hole {
  position: absolute;
  inset: 7px;
  display: grid;
  place-items: center;
  border-radius: 4px;
  overflow: hidden;
  background:
    radial-gradient(120% 140% at 50% -30%, color-mix(in oklab, var(--glow) 85%, #ffffff) 0, var(--glow) 22%, color-mix(in oklab, var(--glow) 40%, #2a1306) 58%, #120803 100%);
  box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.55), inset 0 -2px 3px rgba(0, 0, 0, 0.5);
}

.hatch__close {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: #2b1405;
  font-size: 16px;
  font-weight: 680;
  font-stretch: 92%;
  letter-spacing: 0.01em;
}

.hatch__close svg {
  width: 12px;
  height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
}

/* the hinge knuckles on the frame, on the left */
.hatch__knuckle {
  position: absolute;
  left: 4px;
  top: 10px;
  width: 7px;
  height: 13px;
  border-radius: 3px;
  background: linear-gradient(90deg, #0e0c0a, #5a524a 45%, #15120f);
  z-index: 2;
}

.hatch__knuckle--low {
  top: auto;
  bottom: 10px;
}

/* the lid turns on its left edge (GSAP sets the turn and the perspective) */
.lid {
  position: absolute;
  inset: 7px;
  transform-style: preserve-3d;
  z-index: 1;
}

.lid__face {
  position: absolute;
  inset: 0;
  border-radius: 4px;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

/* three boards side by side, with their seams, grain and worn edges */
.lid__face--front {
  display: grid;
  place-items: center;
  background:
    linear-gradient(180deg, rgba(255, 236, 205, 0.32), rgba(255, 236, 205, 0) 34%, rgba(0, 0, 0, 0) 60%, rgba(40, 18, 4, 0.42)),
    linear-gradient(90deg, transparent 0 calc(33.3% - 1px), rgba(30, 14, 4, 0.55) calc(33.3% - 1px) 33.3%, rgba(255, 230, 190, 0.18) 33.3% calc(33.3% + 1px), transparent calc(33.3% + 1px) calc(66.6% - 1px), rgba(30, 14, 4, 0.55) calc(66.6% - 1px) 66.6%, rgba(255, 230, 190, 0.18) 66.6% calc(66.6% + 1px), transparent calc(66.6% + 1px)),
    var(--lid);
  box-shadow: inset 0 0 0 1px rgba(30, 14, 4, 0.5), inset 0 1px 0 rgba(255, 236, 205, 0.35);
}

.lid__face--front::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='46'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.5 .018' numOctaves='3' seed='9'/%3E%3CfeColorMatrix values='0 0 0 0 .25 0 0 0 0 .12 0 0 0 0 .03 0 0 0 .55 -.08'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size: 100% 100%;
  mix-blend-mode: multiply;
  pointer-events: none;
}

/* the underside of the lid, seen once it has swung open: darker, with a batten across */
.lid__face--back {
  transform: rotateY(180deg);
  background:
    linear-gradient(180deg, transparent 0 40%, rgba(0, 0, 0, 0.3) 40% 42%, #6a4523 42% 58%, rgba(0, 0, 0, 0.35) 58% 60%, transparent 60%),
    linear-gradient(90deg, #4a2f18, #6e4a28);
  box-shadow: inset 0 0 0 1px rgba(20, 10, 2, 0.6);
}

/* the iron straps of the hinges, nailed across the boards */
.lid__strap {
  position: absolute;
  left: -3px;
  top: 6px;
  width: 50px;
  height: 7px;
  border-radius: 1px 4px 4px 1px;
  background:
    radial-gradient(circle at 14px 50%, #6b625a 0 1.2px, transparent 1.8px),
    radial-gradient(circle at 34px 50%, #6b625a 0 1.2px, transparent 1.8px),
    linear-gradient(180deg, #4a4239, var(--iron) 60%, #0d0b09);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
  z-index: 1;
}

.lid__strap--low {
  top: auto;
  bottom: 6px;
}

.lid__word {
  position: relative;
  z-index: 1;
  font-size: 19px;
  font-weight: 760;
  font-stretch: 80%;
  letter-spacing: 0.03em;
  color: #3d1f0a;
  text-shadow: 0 1px 0 rgba(255, 226, 180, 0.35), 0 -1px 0 rgba(30, 12, 2, 0.35);
}

/* the brass ring pull, on the right */
.lid__ring {
  position: absolute;
  right: 8px;
  top: 50%;
  width: 26px;
  height: 26px;
  margin-top: -14px;
  overflow: visible;
  z-index: 1;
}

.lid__plate {
  fill: #2a2420;
}

.lid__loop {
  fill: none;
  stroke: var(--brass);
  stroke-width: 2.6;
  filter: drop-shadow(0 1.5px 1px rgba(0, 0, 0, 0.55));
}

.lid__glint {
  fill: none;
  stroke: rgba(255, 244, 210, 0.85);
  stroke-width: 1.1;
  stroke-linecap: round;
}

@media (hover: hover) {
  .hatch:hover .lid__word {
    color: #2e1505;
  }
}

/* reduced motion: the weight on a rung shows as warmer wood instead of a stretch */
@media (prefers-reduced-motion: reduce) {
  .rung.is-loaded .rung__label {
    font-stretch: 88%;
    color: var(--ember);
  }

  .rung.is-loaded .rung__wood {
    background-color: #e6bb7d;
  }
}
