#gate {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2rem;
  padding: 2rem;
  text-align: center;
}

#gate[hidden] {
  display: none;
}

/* The source file is a square with a white background, so it is cropped to a
   circle here — what remains reads as the round sticker itself rather than a
   white box sitting on the black page. */
.gate-stamp {
  width: min(52vw, 300px);
  height: auto;
  aspect-ratio: 1;
  border-radius: 50%;
  object-fit: cover;
}

.gate-text {
  font-family: 'Noto Serif JP', serif;
  font-size: clamp(1.1rem, 3vw, 1.5rem);
  font-weight: 300;
  color: rgba(240,235,227,0.75);
  letter-spacing: 0.05em;
}

.gate-prompt {
  background: none;
  border: 0;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
  font-size: clamp(0.8rem, 2.2vw, 0.9rem);
  color: rgba(240,235,227,0.4);
  letter-spacing: 0.1em;
  text-align: center;
}

#landing {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Scoped here (not on body) so it only ever clips the landing page's own
     content, the thing it was originally protecting before the scrollable
     6-chapter experience existed — body-level overflow:hidden would block
     native document scrolling entirely once Lenis is unavailable (reduced
     motion / no JS smooth-scroll), since Lenis just intercepts wheel events
     on top of native scroll rather than replacing it. */
  overflow: hidden;
}

#landing[hidden] {
  display: none;
}

button#reveal-trigger {
  /* A targeted reset instead of `all: unset` — `all: unset` also wiped every
     inherited `.message` typography rule (color, letter-spacing, line-height,
     font-weight) because `button#reveal-trigger` (an id+type selector) outranks
     `.message` (a class selector) on specificity, and `unset`/`inherit` on an
     inherited property pulls from THIS element's own parent (#landing/body),
     not from the `.message` rule matching the same element — so even
     `font: inherit; color: inherit;` here would silently reproduce the same
     regression (button parent has plain white text, not the dimmed
     letter-spaced `.message` look). Only browser button-chrome properties
     that `.message` never declares are reset here; every typography property
     `.message` sets (color, letter-spacing, line-height, font-weight,
     font-size, text-align) is left alone so `.message`'s declaration is the
     sole source for it. `font-family: inherit` is the one exception worth
     resetting explicitly, since the UA stylesheet's `button` default font
     family isn't overridden by inheritance otherwise. */
  background: none;
  border: 0;
  padding: 0;
  font-family: inherit;
  cursor: pointer;
}

#experience {
  min-height: 100vh;
  /* Explicit width so this resolves to a definite value against `body`
     (which is itself full viewport width) rather than shrink-to-fit —
     `body` sets `align-items: center`, so as a flex item `#experience`
     would otherwise size to its widest descendant's content (e.g. Tokyo's
     horizontal-hijack image track), and every `.chapter--*`'s `width: 100%`
     would then resolve against that inflated size instead of the viewport,
     reintroducing the shrink-wrap bug those chapter rules exist to fix. */
  width: 100%;
}

#experience[hidden] {
  display: none;
}

.chapter {
  min-height: 100vh;
  position: relative;
  overflow: hidden;
}

.audio-mute-toggle {
  /* Fixed so it's always reachable regardless of scroll position — audio
     starts crossfading once Tokyo is entered, so this is the only mute
     control for the rest of the experience. Previously unstyled: it rendered
     as a raw browser-default button in normal document flow near the top of
     #experience, scrolling out of view after ~22px and never returning. */
  position: fixed;
  top: 1.5rem;
  right: 1.5rem;
  z-index: 10000;
  width: 2.75rem;
  height: 2.75rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(10, 10, 10, 0.5);
  border: 1px solid rgba(240, 235, 227, 0.2);
  border-radius: 50%;
  color: #f0ebe3;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: background 0.2s ease, border-color 0.2s ease;
}

.audio-mute-toggle:hover,
.audio-mute-toggle:focus-visible {
  background: rgba(10, 10, 10, 0.75);
  border-color: rgba(240, 235, 227, 0.4);
}

.custom-cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 1px solid rgba(240,235,227,0.6);
  transform: translate(-50%, -50%);
  pointer-events: none;
  mix-blend-mode: difference;
  z-index: 9998;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.65rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  transition: width 0.2s ease, height 0.2s ease;
}

.custom-cursor.is-active {
  width: 64px;
  height: 64px;
  background: rgba(240,235,227,0.9);
  color: #0a0a0a;
  mix-blend-mode: normal;
}

.grain-overlay {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  mix-blend-mode: overlay;
  z-index: 9999;
}
