:root {
  --bg: #f8f3ec;
  --paper: #fffaf3;
  --ink: #1f1b18;
  --muted: #766c63;
  --line: rgba(31,27,24,.12);
  --accent: #9b5f44;
  --soft: #eadccc;
  --glow: #b9776a; /* warm dusty pink-brown — the Travel Globe's visited-location glow (rgb(185, 119, 106)) */
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: 'Inter', sans-serif;
  background: var(--bg);
  color: var(--ink);
  line-height: 1.7;
}

.grain {
  pointer-events: none;
  position: fixed;
  inset: 0;
  opacity: .2;
  background-image: radial-gradient(#6d5b4c 0.5px, transparent 0.5px);
  background-size: 18px 18px;
  z-index: 10;
}

.nav {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  padding: 22px 7vw;
  backdrop-filter: blur(16px);
  background: rgba(248,243,236,.78);
  border-bottom: 1px solid var(--line);
}

/* Was "justify-content: space-between" with exactly two children
   (logo, nav-links). Now that the music toggle also lives in this
   same header on desktop (immediately after the nav links), space-
   between would spread the two apart instead of keeping them grouped
   tightly on the right — so instead the header just flows left-to-
   right, and <nav> gets pushed flush right with an auto margin.
   Visually this reproduces the original space-between result exactly
   for logo/nav — nothing about their positions actually changes. On
   mobile the music toggle reverts to its own fixed bottom-left
   position (see "AMBIENT MUSIC BUTTON" below) and is no longer part
   of this flex row at all, so nothing here needs a mobile-specific
   handoff for it. */
.nav nav {
  margin-left: auto;
}

.logo{
    width:58px;
    height:58px;
    display:flex;
    align-items:center;
    justify-content:center;
    text-decoration:none;
}
.logo img{
    width:100%;
    height:100%;
    object-fit:contain;
}
.nav a {
  margin-left: 24px;
  color: var(--ink);
  text-decoration: none;
  font-size: 14px;
}


/* ========================================
   MOBILE SITE MENU
   A hamburger toggle (top-right, mobile only) that opens a quiet
   full-screen index of every section on the page. The sticky header
   itself stays on top of the overlay (rather than being covered by
   it) so the toggle — morphed into an × — remains reachable to close
   it again. Explore's four destinations (Essays, Field Notes, Map,
   Gallery) are nested underneath it as smaller, indented rows, so the
   hierarchy of the page reads at a glance without needing a
   click-to-expand accordion.
======================================== */

.nav-menu-toggle {
  display: none;

  width: 26px;
  height: 16px;
  padding: 0;

  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 5px;

  background: none;
  border: none;
  cursor: pointer;

  -webkit-tap-highlight-color: transparent;
}

.nav-menu-toggle-bar {
  display: block;
  width: 100%;
  height: 1.5px;

  background: var(--ink);

  transition:
    transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.3s ease;
}

.nav-menu-toggle[aria-expanded="true"] .nav-menu-toggle-bar:nth-child(1) {
  transform: translateY(6.5px) rotate(45deg);
}

.nav-menu-toggle[aria-expanded="true"] .nav-menu-toggle-bar:nth-child(2) {
  opacity: 0;
}

.nav-menu-toggle[aria-expanded="true"] .nav-menu-toggle-bar:nth-child(3) {
  transform: translateY(-6.5px) rotate(-45deg);
}

.site-menu {
  position: fixed;
  inset: 0;
  z-index: 4;

  display: none;
  flex-direction: column;

  padding-top: 102px;

  background: rgba(248, 243, 236, 0.97);
  backdrop-filter: blur(20px);

  opacity: 0;
  visibility: hidden;
  pointer-events: none;

  transition:
    opacity 0.45s ease,
    visibility 0s linear 0.45s;
}

.site-menu[aria-hidden="false"] {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;

  transition:
    opacity 0.45s ease,
    visibility 0s linear 0s;
}

.site-menu-list {
  flex: 1;

  display: flex;
  flex-direction: column;
  justify-content: center;

  width: 100%;
  max-width: 480px;
  margin: 0 auto;
  padding: 0 8vw 40px;
}

.site-menu-item {
  position: relative;
  z-index: 1;

  display: flex;
  align-items: center;
  gap: 16px;

  padding: 15px 0;

  color: var(--ink);
  text-decoration: none;

  border-bottom: 1px solid var(--line);

  opacity: 0;
  transform: translateY(14px);

  transition:
    opacity 0.5s ease,
    transform 0.5s cubic-bezier(0.22, 1, 0.36, 1),
    color 0.3s ease;
}

.site-menu-number {
  flex-shrink: 0;
  width: 30px;

  color: var(--accent);

  font-family: "Inter", sans-serif;
  font-size: 11px;
  letter-spacing: 0.14em;

  opacity: 0.55;
}

.site-menu-title {
  flex: 1;
  min-width: 0;

  font-family: "Cormorant Garamond", serif;
  font-size: clamp(26px, 7vw, 32px);
  font-weight: 500;
}

.site-menu-arrow {
  flex-shrink: 0;
  width: 17px;
  height: 17px;

  color: var(--accent);
  opacity: 0.5;

  transition:
    transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.3s ease;
}

.site-menu-item:active .site-menu-title,
.site-menu-item:hover .site-menu-title {
  color: var(--accent);
}

.site-menu-item:active .site-menu-arrow,
.site-menu-item:hover .site-menu-arrow {
  opacity: 1;
  transform: translate(4px, -4px) rotate(8deg);
}


/* Explore's sub-destinations — quieter, indented, no number/arrow */

.site-menu-item--sub {
  padding: 10px 0 10px 46px;

  border-bottom-color: transparent;
}

.site-menu-item--sub .site-menu-title {
  font-size: clamp(17px, 4.4vw, 19px);
  font-weight: 400;

  color: var(--muted);
}

.site-menu-item--sub:active .site-menu-title,
.site-menu-item--sub:hover .site-menu-title {
  color: var(--accent);
}

.site-menu-item:last-child {
  border-bottom: none;
}


/* Staggered reveal as the menu opens */

.site-menu[aria-hidden="false"] .site-menu-item {
  opacity: 1;
  transform: translateY(0);
}

.site-menu-item:nth-child(1)  { transition-delay: 0.04s; }
.site-menu-item:nth-child(2)  { transition-delay: 0.08s; }
.site-menu-item:nth-child(3)  { transition-delay: 0.11s; }
.site-menu-item:nth-child(4)  { transition-delay: 0.14s; }
.site-menu-item:nth-child(5)  { transition-delay: 0.17s; }
.site-menu-item:nth-child(6)  { transition-delay: 0.2s; }
.site-menu-item:nth-child(7)  { transition-delay: 0.23s; }
.site-menu-item:nth-child(8)  { transition-delay: 0.26s; }
.site-menu-item:nth-child(9)  { transition-delay: 0.29s; }

html.site-menu-open,
html.site-menu-open body {
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .nav-menu-toggle-bar,
  .site-menu,
  .site-menu-item,
  .site-menu-arrow {
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
}

@media (max-width: 760px) {
  .nav-menu-toggle {
    display: flex;
    /* At this width <nav> is hidden and the music toggle has moved
       out to <body> (see audio.js), so the hamburger is left as the
       only item after the logo in the header's flex row — without
       this it just sits flush-left next to the logo instead of in
       its usual top-right corner. */
    margin-left: auto;
  }

  .site-menu {
    display: flex;
  }
}

main { padding: 0 7vw; }
.hero {
  min-height: 82vh;
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  align-items: center;
  gap: 48px;
  padding: 70px 0 40px;
  overflow-x: hidden; /* contains the ambient glow's soft bleed past .hero-right's edge */
}

.hero-left {
    position: relative;
    z-index: 2;
    padding-top: 55px;
}

.hero-left {
    padding-left: 28px;
}

.hero-right {
  position: relative;
  min-height: 700px;
  margin-right: -5vw;
}

.handwriting {
  font-family: "Cormorant Garamond", serif;
  font-style: italic;
  font-size: 26px;
  font-weight: 500;
  color: var(--accent);
  opacity: 0.75;
  letter-spacing: 0.02em;
  margin-bottom: 34px;
}

.handwriting{
    position:relative;
    top:20px;
}

.hero h1 {
  font-size: clamp(68px, 7.6vw, 104px);
  line-height: 0.88;
  max-width: 520px;
}

.hero h1 em {
  display: block;
  font-style: italic;
  font-weight: 500;
}

.short-line {
  width: 54px;
  height: 1px;
  background: var(--accent);
  margin: 32px 0 26px;
}

.hero-text {
  max-width: 420px;
  color: var(--muted);
  font-size: 17px;
  line-height: 1.7;
}

.hero-copy {
    max-width: 180px;
    line-height: 1.8;
}

.hero-photo {
  position: absolute;
  inset: 0;
  border-radius: 0 0 0 120px;

  background-image:
    linear-gradient(rgba(248,243,236,.12), rgba(248,243,236,.08)),
    url("images/hero.jpeg");

  background-size: 100%;
  background-position: center 45%;
}

/* ========================================
   HERO ENTRANCE — "the page breathes in"
   Pure CSS, no loading screen, no JS: the
   page is already fully laid out on first
   paint, and these elements simply ease
   into their resting state via animation-
   delay. Order: photo → handwriting → body
   copy → title (deliberately a touch slower
   and heavier than the copy) → line → Begin
   button, which settles in last, like a
   held breath finishing. A faint ambient
   glow behind the photo and a near-
   imperceptible drift on the grain texture
   keep things quietly alive afterwards,
   rather than the page going still the
   moment the entrance finishes.
======================================== */

.hero-photo {
  opacity: 0;
  animation: hero-photo-in .85s cubic-bezier(.16,1,.3,1) forwards;
}

.hero-right::before {
  content: "";
  position: absolute;
  inset: -6%;
  border-radius: 0 0 0 140px;
  background: radial-gradient(circle at 60% 35%, rgba(185,119,106,.4), rgba(185,119,106,0) 65%);
  filter: blur(40px);
  opacity: 0;
  pointer-events: none;
  animation:
    hero-glow-in .9s ease-out .1s forwards,
    hero-glow-breathe 9s ease-in-out 1s infinite;
}

.handwriting {
  opacity: 0;
  animation: hero-rise-in .5s ease-out .05s forwards;
}

.hero-copy {
  opacity: 0;
  animation: hero-rise-in .5s ease-out .12s forwards;
}

.hero h1 {
  opacity: 0;
  animation: hero-rise-in-title .65s cubic-bezier(.19,1,.22,1) .2s forwards;
}

.short-line {
  opacity: 0;
  transform-origin: left center;
  animation: hero-line-in .5s ease-out .5s forwards;
}

.begin-button {
  opacity: 0;
  animation: hero-rise-in .5s ease-out .62s forwards;
}

@keyframes hero-photo-in {
  from { opacity: 0; transform: scale(1.035); }
  to   { opacity: 1; transform: scale(1); }
}

@keyframes hero-glow-in {
  from { opacity: 0; }
  to   { opacity: .22; }
}

@keyframes hero-glow-breathe {
  0%, 100% { opacity: .16; transform: scale(1); }
  50%      { opacity: .3; transform: scale(1.04); }
}

@keyframes hero-rise-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes hero-rise-in-title {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes hero-line-in {
  from { opacity: 0; transform: scaleX(0); }
  to   { opacity: 1; transform: scaleX(1); }
}

@keyframes grain-drift {
  0%, 100% { background-position: 0 0; }
  50%      { background-position: 7px 11px; }
}

.grain {
  animation: grain-drift 48s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .hero-photo,
  .hero-right::before,
  .handwriting,
  .hero-copy,
  .hero h1,
  .short-line,
  .begin-button,
  .grain {
    animation: none !important;
  }

  .hero-photo,
  .handwriting,
  .hero-copy,
  .hero h1,
  .short-line,
  .begin-button {
    opacity: 1 !important;
    transform: none !important;
  }

  .hero-right::before {
    opacity: .22;
  }
}

.eyebrow, .section-label {
  text-transform: uppercase;
  letter-spacing: .16em;
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
}
h1, h2, h3 {
  font-family: 'Cormorant Garamond', serif;
  line-height: 1.05;
  margin: 0;
}
h1 {
  font-size: clamp(72px, 12vw, 150px);
  letter-spacing: -0.05em;
}
h2 { font-size: clamp(40px, 6vw, 76px); letter-spacing: -0.035em; }
h3 { font-size: 28px; }
.hero-text {
  max-width: 720px;
  font-size: clamp(19px, 2vw, 25px);
  color: var(--muted);
}
.button {
    display: inline-flex;
    align-items: center;
    gap: 8px;

    padding: 0;
    margin-top: 36px;

    font-size: 17px;
    font-weight: 500;
    letter-spacing: 0.03em;

    text-decoration: none;

    color: var(--accent);

    transition: all .35s ease;
}
.primary{
    background:none;
    color:var(--accent);

    border:none;

    border-bottom:1px solid rgba(153,113,84,.35);
    padding-bottom:6px;
}
.secondary{
    display:none;
}
.button:hover{
    gap:16px;
    color:#7f543b;
}

.primary:hover{
    border-bottom-color:#7f543b;
}

/* Explore */

.explore-section {
  display: block;

  padding: 120px 0 110px;

  border-top: 1px solid var(--line);
}


/* Explore introduction */

.explore-intro {
  max-width: 820px;
  min-height: calc(100vh - 190px);

  display: flex;
  flex-direction: column;
  justify-content: center;

  padding-bottom: 12vh;
  margin-bottom: 0;
}

.explore-intro h2 {
  max-width: 780px;
  margin-top: 24px;

  font-size: clamp(58px, 6vw, 92px);
  line-height: 0.96;
}

.explore-intro h2 em {
  color: var(--accent);
  font-weight: 500;
}

.explore-copy {
  max-width: 620px;
  margin: 38px 0 0;

  color: var(--muted);

  font-size: 16px;
  line-height: 1.8;
}


/* Explore list */

.explore-list {
  border-top: 1px solid rgba(31, 27, 24, 0.3);
}

.explore-item {
  position: relative;

  display: grid;
  grid-template-columns: 54px minmax(260px, 1fr) 260px 40px;
  align-items: center;
  gap: 24px;

  min-height: 148px;
  padding: 0px 8px;

  color: var(--ink);
  text-decoration: none;

  border-bottom: 1px solid var(--line);

  overflow: hidden;

  transition:
    padding 0.4s ease,
    background-color 0.4s ease,
    color 0.4s ease;
}

.explore-item::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;

  background:
    radial-gradient(
      ellipse at 28% 50%,
      rgba(155, 95, 68, 0.09) 0%,
      rgba(181, 135, 102, 0.045) 38%,
      transparent 72%
    ),
    linear-gradient(
      90deg,
      rgba(255, 250, 243, 0.28),
      rgba(234, 220, 204, 0.12),
      transparent 82%
    );

  opacity: 0;
  transition: opacity 0.55s ease;
}

.explore-item::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;

  background:
    linear-gradient(
      90deg,
      rgba(255, 250, 243, 0.62) 0%,
      rgba(247, 238, 228, 0.48) 48%,
      rgba(248, 243, 236, 0.18) 100%
    );

  opacity: 0;
  transition: opacity 0.45s ease;
}

.explore-item:hover::before {
  opacity: 1;
}

/* Number */

.explore-number {
  position: relative;
  z-index: 2;
  align-self: start;

  padding-top: 18px;

  color: var(--accent);

  font-size: 11px;
  letter-spacing: 0.14em;

  opacity: 0.48;

  transition:
    opacity 0.4s ease,
    transform 0.4s ease,
    letter-spacing 0.4s ease;
}

.explore-item:hover .explore-number {
  opacity: 1;
  transform: translateY(-3px);
  letter-spacing: 0.22em;
}


/* Title */

.explore-title {
  position: relative;
  z-index: 2;

  transition: transform 0.4s ease;
}

.explore-title h3 {
  font-size: clamp(36px, 3.3vw, 52px);
  font-weight: 500;

  transition:
    letter-spacing 0.45s ease,
    transform 0.45s ease;
}

.explore-item:hover .explore-title h3 {
  letter-spacing: 0.018em;
  transform: translateY(-2px);
}

.explore-title p {
  margin: 8px 0 0;

  color: var(--muted);

  font-size: 14px;

  transition: color 0.4s ease;
}


/* Preview image */

.explore-preview {
  position: relative;
  z-index: 2;
  align-self: stretch;

  width: 300px;
  height: 100%;
  min-height: 148px;

  overflow: visible;

  opacity: 0;
  transform:
    translateX(46px)
    translateY(4px)
    rotate(-1.5deg)
    scale(0.96);

  transition:
    opacity 0.5s ease,
    transform 0.65s cubic-bezier(0.22, 1, 0.36, 1);
}

.explore-preview img {
  position: absolute;
  top: 0;
  right: 0;

  display: block;

  width: auto;
  max-width: none;
  height: 100%;

  object-fit: contain;

  filter: saturate(0.72) contrast(0.94);

  transition:
    transform 0.7s ease,
    filter 0.5s ease;
}


/* Arrow */

.explore-arrow {
  position: relative;
  z-index: 2;

  justify-self: end;

  display: block;
  width: 21px;
  height: 21px;

  color: var(--accent);

  transition: transform 0.4s ease;
}

.explore-arrow svg,
.essay-arrow svg {
  display: block;
  width: 100%;
  height: 100%;
}


/* Hover */
.explore-item:hover {
  padding-left: 18px;
  padding-right: 18px;

  color: var(--accent);

  background: rgba(234, 220, 204, 0.22);
}

.explore-item:hover .explore-title {
  transform: translateX(6px);
}

.explore-item:hover .explore-preview {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.explore-item:hover .explore-preview img {
  transform: scale(1.05);

  filter: saturate(0.9) contrast(0.98);
}

.explore-item:hover .explore-arrow {
  transform: translate(6px, -6px) rotate(8deg);
}

/* 进入 Explore 后，在用户真正移动鼠标前强制保持默认状态 */
.explore-section.explore-entering .explore-item:hover {
  padding-left: 8px;
  padding-right: 8px;
  color: var(--ink);
  background: transparent;
}

.explore-section.explore-entering .explore-item:hover::before {
  opacity: 0;
}

.explore-section.explore-entering .explore-item:hover .explore-title {
  transform: none;
}

.explore-section.explore-entering .explore-item:hover .explore-title h3 {
  letter-spacing: normal;
  transform: none;
}

.explore-section.explore-entering .explore-item:hover .explore-number {
  opacity: 0.48;
  transform: none;
  letter-spacing: 0.14em;
}

.explore-section.explore-entering .explore-item:hover .explore-preview {
  opacity: 0;
  transform:
    translateX(46px)
    translateY(4px)
    rotate(-1.5deg)
    scale(0.96);
}

.explore-section.explore-entering .explore-item:hover .explore-preview img {
  transform: none;
  filter: saturate(0.72) contrast(0.94);
}

.explore-section.explore-entering .explore-item:hover .explore-arrow {
  transform: none;
}

/* ========================================
   HERO → EXPLORE TRANSITION
======================================== */

#explore {
  scroll-margin-top: 86px;
}

/* ----------------------------------------
   INTRO REVEAL
---------------------------------------- */
.explore-reveal {
  opacity: 0;
  visibility: hidden;

  transform: translate3d(0, 18px, 0);

  will-change: opacity, transform;

  transition:
    opacity 1.45s cubic-bezier(0.22, 1, 0.36, 1),
    transform 1.45s cubic-bezier(0.22, 1, 0.36, 1),
    visibility 0s linear 1.15s;
}

.explore-section.intro-reset .explore-reveal {
  opacity: 0 !important;
  visibility: hidden !important;
  transform: translate3d(0, 10px, 0) !important;

  transition: none !important;
}

.explore-section.intro-visible .explore-reveal {
  opacity: 1;
  visibility: visible;

  transform: translate3d(0, 0, 0);

  transition:
    opacity 1.15s cubic-bezier(0.16, 1, 0.3, 1),
    transform 1.15s cubic-bezier(0.16, 1, 0.3, 1),
    visibility 0s;
}

.explore-section.intro-visible .explore-reveal-1 {
  transition-delay: 0.04s;
}

.explore-section.intro-visible .explore-reveal-2 {
  transition-delay: 0.14s;
}

.explore-section.intro-visible .explore-reveal-3 {
  transition-delay: 0.32s;
}

/* ----------------------------------------
   LIST REVEAL
---------------------------------------- */

.explore-item {
  opacity: 0;
  transform: translate3d(0, 38px, 0);

  will-change: opacity, transform;

  transition:
    opacity 1.15s cubic-bezier(0.16, 1, 0.3, 1),
    transform 1.15s cubic-bezier(0.16, 1, 0.3, 1),
    padding 0.4s ease,
    background-color 0.4s ease,
    color 0.4s ease;
}

.explore-item.item-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}


/* ----------------------------------------
   LOCK ACCIDENTAL HOVER
---------------------------------------- */

.explore-section.explore-entering .explore-item {
  pointer-events: none;
}

.explore-section.explore-entering .explore-item:hover {
  padding-left: 8px;
  padding-right: 8px;

  color: var(--ink);
  background: transparent;
}

.explore-section.explore-entering .explore-item:hover::before {
  opacity: 0;
}

.explore-section.explore-entering .explore-item:hover .explore-title {
  transform: none;
}

.explore-section.explore-entering .explore-item:hover .explore-title h3 {
  letter-spacing: normal;
  transform: none;
}

.explore-section.explore-entering .explore-item:hover .explore-number {
  opacity: 0.48;
  transform: none;
  letter-spacing: 0.14em;
}

.explore-section.explore-entering .explore-item:hover .explore-preview {
  opacity: 0;
  filter: blur(2px);

  transform:
    translateX(46px)
    translateY(4px)
    rotate(-1.5deg)
    scale(0.96);
}

.explore-section.explore-entering .explore-item:hover .explore-preview img {
  transform: none;
  filter: saturate(0.72) contrast(0.94);
}

.explore-section.explore-entering .explore-item:hover .explore-arrow {
  transform: none;
}


/* ----------------------------------------
   PREVIEW IMAGE REVEAL
---------------------------------------- */

.explore-preview {
  filter: blur(2px);

  transition:
    opacity 0.65s ease 0.06s,
    transform 0.76s cubic-bezier(0.22, 1, 0.36, 1),
    filter 0.65s ease 0.06s;
}

.explore-item:hover .explore-preview {
  opacity: 1;
  filter: blur(0);

  transform:
    translateX(0)
    translateY(0)
    rotate(0)
    scale(1);
}


/* ----------------------------------------
   ACCESSIBILITY
---------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .explore-reveal,
  .explore-item,
  .explore-preview {
    transition-duration: 0.01ms;
    transition-delay: 0s;
  }
}

/* ========================================
   SCROLL REVEAL — page-wide
   Generalises the Explore section's own fade
   + gentle-rise (above) to every section below
   it — Essays, Field Notes, Map, Gallery,
   Projects, About Me, Contact — so scrolling
   down never pops content in; each piece
   eases into place once, the first time it
   crosses into view (see script.js "SCROLL
   REVEAL"). `--reveal-delay` lets a handful of
   side-by-side elements (a heading next to its
   copy, three gallery panels, two project
   cards) stagger slightly rather than arriving
   in a single flat beat — set per-element
   below, right next to what it's staggering.
   Reduced-motion users still get the reveal,
   just instantly, matching the Explore
   section's own convention above.
======================================== */

.reveal-up {
  opacity: 0;
  transform: translate3d(0, 26px, 0);

  will-change: opacity, transform;

  transition:
    opacity 1.1s cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay, 0s),
    transform 1.1s cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay, 0s);
}

.reveal-up.is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

.reveal-d1 { --reveal-delay: 0.05s; }
.reveal-d2 { --reveal-delay: 0.15s; }
.reveal-d3 { --reveal-delay: 0.27s; }
.reveal-d4 { --reveal-delay: 0.38s; }

@media (prefers-reduced-motion: reduce) {
  .reveal-up {
    transition-duration: 0.01ms;
  }
}

.section, .split-section, .contact {
  padding: 90px 0;
  border-top: 1px solid var(--line);
}
.split-section {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: 60px;
}
.split-section p:last-child {
  font-size: 22px;
  color: var(--muted);
  margin: 40px 0 0;
}
.section-heading { margin-bottom: 34px; }

.map-card {
  display: grid;
  grid-template-columns: 1.35fr .85fr;
  min-height: 460px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 34px;
  overflow: hidden;
}


/* ----------------------------------------
   GLOBE STAGE — a quiet, hand-drawn-feeling 3D globe rendered on
   canvas by globe.js (paper-toned sphere + faint graticule; no
   continents, no photographic texture — an atlas, not a map service).
   The ambient background behind the sphere echoes the old map's warm
   radial wash so the section keeps the same overall temperature.
---------------------------------------- */

.globe-stage {
  position: relative;
  overflow: hidden;
  cursor: grab;
  touch-action: none;

  /* Dragging/pinching happens directly on this box — without this,
     a fast drag on desktop starts highlighting text behind the
     canvas, and a press-drag on mobile can trigger the native
     callout/selection menu. Nothing inside is selectable text
     anyway (canvas + buttons), so this is safe everywhere. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;

  background:
    radial-gradient(circle at 50% 46%, rgba(234, 220, 204, 0.7) 0%, transparent 55%),
    linear-gradient(160deg, #f9efe3, #eee0d0);
}

.globe-stage:active {
  cursor: grabbing;
}

.globe-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

/* Hover warmth — a soft glow-tinted wash that fades in while any
   marker is hovered/focused, toggled by globe.js via .is-warm. */
.globe-stage::after {
  content: "";
  position: absolute;
  inset: 0;

  background: radial-gradient(circle at 50% 50%, rgba(185, 119, 106, 0.14), transparent 68%);

  opacity: 0;
  transition: opacity 0.7s ease;
  pointer-events: none;
}

.globe-stage.is-warm::after {
  opacity: 1;
}


/* ----------------------------------------
   GLOBE MARKERS — small dots, not labelled pins: a name only
   surfaces on hover/focus/selection, so eighteen real (sometimes
   geographically close) places stay legible rather than cluttered.
   Position is set every animation frame by globe.js via inline
   transform, matching the sphere's current rotation.
---------------------------------------- */

.globe-marker {
  position: absolute;
  top: 0;
  left: 0;
  width: 26px;
  height: 26px;

  display: flex;
  align-items: center;
  justify-content: center;

  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  will-change: transform;
}

.globe-marker-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--glow);
  box-shadow: 0 0 0 3px rgba(255, 250, 243, 0.75);

  transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1), box-shadow 0.35s ease;
}

.globe-marker:hover .globe-marker-dot,
.globe-marker:focus-visible .globe-marker-dot {
  transform: scale(1.35);
}

.globe-marker:focus-visible {
  outline: none;
}

.globe-marker:focus-visible .globe-marker-dot {
  box-shadow: 0 0 0 3px rgba(255, 250, 243, 0.9), 0 0 0 5px rgba(185, 119, 106, 0.35);
}

/* Subtle glow on the locked selection — a warm dusty pink-brown
   shadow, not a pulsing effect; restraint over spectacle. */
.globe-marker.is-selected .globe-marker-dot {
  box-shadow: 0 0 0 3px rgba(255, 250, 243, 0.9), 0 0 14px rgba(185, 119, 106, 0.5);
}

.globe-marker-label {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%) translateY(2px);

  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255, 250, 243, 0.92);
  border: 1px solid var(--line);
  backdrop-filter: blur(6px);

  color: var(--ink);
  font-family: "Inter", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  white-space: nowrap;

  opacity: 0;
  pointer-events: none;

  transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.globe-marker:hover .globe-marker-label,
.globe-marker:focus-visible .globe-marker-label,
.globe-marker.is-selected .globe-marker-label {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}


/* ----------------------------------------
   NOTE PANEL
---------------------------------------- */

.map-note {
  display: flex;
  flex-direction: column;
  justify-content: center;

  padding: 50px;

  transition: opacity 0.35s ease, transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.map-note.is-fading {
  opacity: 0;
  transform: translate3d(0, 10px, 0);
}

.map-note h3 {
  margin-top: 14px;

  font-size: clamp(34px, 4vw, 50px);
}

.map-note-meta {
  margin: 8px 0 0;

  color: var(--muted);

  font-family: "Inter", sans-serif;
  font-size: 12px;
  letter-spacing: 0.04em;
}

.map-note p {
  margin: 20px 0 0;

  color: var(--muted);
  font-size: 18px;
}

.map-note .text-link {
  margin-top: 24px;
}

.text-link { color: var(--accent); text-decoration: none; font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
  .globe-marker-dot,
  .globe-marker-label,
  .map-note {
    transition-duration: 0.01ms;
  }
}

.cards {
  display: grid;
  gap: 18px;
}
.three { grid-template-columns: repeat(3, 1fr); }
.two { grid-template-columns: repeat(2, 1fr); }
.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 28px;
  padding: 30px;
  min-height: 220px;
}
.card span { color: var(--accent); font-size: 13px; }
.card p { color: var(--muted); }
.large { min-height: 260px; }

/* Scroll reveal stagger — the two project cards sit side by side, so
   without this they'd enter together in one flat beat. See "SCROLL
   REVEAL" further up for the shared .reveal-up recipe. */
.two .card:nth-child(2) { --reveal-delay: 0.12s; }

/* ========================================
   FIELD NOTES — SCATTERED ARCHIVE
======================================== */

.field-notes-section {
  overflow: hidden;
}

.field-notes-copy {
  max-width: 420px;
  margin: 18px 0 0;

  color: var(--muted);

  font-size: 15px;
  line-height: 1.8;
}


/* Horizontal row */

.field-notes-row {
  display: flex;
  gap: 30px;

  width: 100vw;
  margin-left: calc(-50vw + 50%);
  margin-top: 54px;
  padding: 10px 7vw 34px;

  overflow-x: auto;
  overflow-y: visible;

  -webkit-overflow-scrolling: touch;
  scroll-behavior: smooth;

  scrollbar-width: thin;
  scrollbar-color: rgba(155, 95, 68, 0.28) transparent;
}

.field-notes-row::-webkit-scrollbar {
  height: 3px;
}

.field-notes-row::-webkit-scrollbar-track {
  background: transparent;
}

.field-notes-row::-webkit-scrollbar-thumb {
  background: rgba(155, 95, 68, 0.28);
  border-radius: 999px;
}


/* Card */

.field-note-card {
  position: relative;
  flex: 0 0 auto;

  display: flex;
  flex-direction: column;

  width: 258px;
  min-height: 232px;
  padding: 26px 26px 22px;

  color: var(--ink);
  text-decoration: none;

  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 4px;

  box-shadow: 0 1px 0 rgba(31, 27, 24, 0.02);

  transform: translateY(0) rotate(0deg);

  transition:
    transform 0.5s cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 0.5s ease,
    border-color 0.4s ease;
}

.field-note-card:nth-child(3n+1) { transform: rotate(-0.6deg); }
.field-note-card:nth-child(3n+2) { transform: rotate(0.5deg); }
.field-note-card:nth-child(3n)   { transform: rotate(-0.3deg); }

.field-note-card:hover,
.field-note-card:focus-visible {
  transform: translateY(-6px) rotate(0deg);

  border-color: rgba(155, 95, 68, 0.3);

  box-shadow:
    0 18px 34px rgba(31, 27, 24, 0.07),
    0 4px 10px rgba(31, 27, 24, 0.04);
}

.field-note-card:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 4px;
}


/* Number */

.field-note-number {
  display: block;

  margin-bottom: 20px;

  color: var(--accent);

  font-family: "Inter", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;

  opacity: 0.55;

  transition: opacity 0.4s ease;
}

.field-note-card:hover .field-note-number {
  opacity: 0.9;
}


/* Title / hook crossfade */

.field-note-face {
  position: relative;
  display: grid;

  flex: 1;
  align-content: start;
}

.field-note-title,
.field-note-reveal {
  grid-area: 1 / 1;
}

.field-note-title {
  margin: 0;

  font-size: 25px;
  font-weight: 500;
  line-height: 1.22;

  transition:
    opacity 0.4s ease,
    transform 0.4s ease;
}

.field-note-reveal {
  display: flex;
  flex-direction: column;
  gap: 12px;

  opacity: 0;
  transform: translateY(6px);

  transition:
    opacity 0.45s ease,
    transform 0.45s ease;
}

.field-note-hook {
  margin: 0;

  color: #8d5942;

  font-family: "Cormorant Garamond", serif;
  font-size: 21px;
  font-style: italic;
  font-weight: 500;
  line-height: 1.4;
}

.field-note-read {
  color: var(--accent);

  font-family: "Inter", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.field-note-card:hover .field-note-title,
.field-note-card:focus-visible .field-note-title {
  opacity: 0;
  transform: translateY(-6px);
}

.field-note-card:hover .field-note-reveal,
.field-note-card:focus-visible .field-note-reveal {
  opacity: 1;
  transform: translateY(0);
}


/* Meta */

.field-note-meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;

  margin-top: 20px;
  padding-top: 16px;

  border-top: 1px solid var(--line);
}

.field-note-tags,
.field-note-date {
  color: var(--muted);

  font-family: "Inter", sans-serif;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
}

.field-note-tags {
  color: var(--accent);
  opacity: 0.85;
}

@media (prefers-reduced-motion: reduce) {
  .field-notes-row {
    scroll-behavior: auto;
  }

  .field-note-card,
  .field-note-title,
  .field-note-reveal {
    transition-duration: 0.01ms;
  }
}

@media (max-width: 760px) {
  .field-notes-row {
    gap: 18px;
    margin-top: 40px;
    padding: 8px 6vw 26px;
  }

  .field-note-card {
    width: 218px;
    min-height: 208px;
    padding: 22px 22px 18px;
  }

  .field-note-title {
    font-size: 22px;
  }

  .field-note-hook {
    font-size: 19px;
  }
}

/* ========================================
   ESSAYS — BOOK SPINE
======================================== */

.essays-section {
  padding-top: 140px;
  padding-bottom: 130px;
}


/* Essays introduction */

.essays-intro {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(260px, 0.55fr);
  align-items: end;
  gap: 72px;

  margin-bottom: 88px;
}

.essays-heading h2 {
  margin-top: 22px;

  font-size: clamp(58px, 6.2vw, 92px);
  line-height: 0.94;
}

.essays-heading h2 em {
  color: var(--accent);
  font-weight: 500;
}

.essays-intro-copy {
  max-width: 360px;
  margin: 0 0 8px;

  color: var(--muted);

  font-size: 15px;
  line-height: 1.85;
}


/* Shelf */

.essay-shelf {
  position: relative;

  border-top: 1px solid rgba(31, 27, 24, 0.28);
}


/* Individual book spine */

.essay-spine {
  position: relative;

  display: grid;
  grid-template-columns:
  34px
  minmax(310px, 1fr)
  minmax(260px, 360px)
  30px;

  align-items: center;
  gap: 28px;

  min-height: 132px;
  padding: 22px 12px 22px 18px;

  color: var(--ink);
  text-decoration: none;

  border-bottom: 1px solid var(--line);

  overflow: hidden;

  opacity: 0;
  transform: translateX(0);

  transition:
    opacity 1s cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay, 0s),
    transform 0.62s cubic-bezier(0.22, 1, 0.36, 1),
    padding 0.62s cubic-bezier(0.22, 1, 0.36, 1),
    background-color 0.5s ease,
    box-shadow 0.55s ease;
}

/* Scroll reveal — opacity only (not the shared .reveal-up recipe),
   since this element's own `transform` is already spoken for by its
   hover slide-right above; animating both from the same property
   would fight each other. Staggered per spine via --reveal-delay,
   same mechanism as everywhere else — see "SCROLL REVEAL" above. */
.essay-spine.is-visible {
  opacity: 1;
}

.essay-spine:nth-of-type(2) { --reveal-delay: 0.12s; }
.essay-spine:nth-of-type(3) { --reveal-delay: 0.24s; }

@media (prefers-reduced-motion: reduce) {
  .essay-spine {
    transition-duration: 0.01ms;
  }
}


/* Book-spine line */

.essay-spine::after {
  content: "";

  position: absolute;
  left: 0;
  top: 18px;
  bottom: 18px;

  width: 2px;

  background: rgba(155, 95, 68, 0.25);

  transform: scaleY(0.72);
  transform-origin: center;

  transition:
    background-color 0.45s ease,
    transform 0.55s cubic-bezier(0.22, 1, 0.36, 1);
}


/* Soft paper layer */

.essay-spine::before {
  content: "";

  position: absolute;
  inset: 0;
  z-index: 0;

  pointer-events: none;

  background:
    linear-gradient(
      90deg,
      rgba(255, 250, 243, 0.78) 0%,
      rgba(244, 232, 219, 0.42) 52%,
      rgba(248, 243, 236, 0.08) 100%
    );

  opacity: 0;

  transition: opacity 0.55s ease;
}


/* Keep all content above background */

.essay-dot,
.essay-title,
.essay-quote,
.essay-arrow {
  position: relative;
  z-index: 1;
}

/* Small shelf marker */

.essay-dot {
  align-self: center;
  justify-self: center;

  width: 6px;
  height: 6px;

  border-radius: 50%;

  background: var(--accent);

  opacity: 0.38;

  transform: scale(1);

  transition:
    opacity 0.45s ease,
    transform 0.55s cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 0.45s ease;
}

/* Essay title */

.essay-title {
  min-width: 0;

  transition:
    transform 0.58s cubic-bezier(0.22, 1, 0.36, 1);
}

.essay-title h3 {
  margin: 0;

  font-size: clamp(29px, 2.8vw, 44px);
  font-weight: 500;
  line-height: 1;

  transition:
    color 0.45s ease,
    letter-spacing 0.5s ease;
}

.essay-type {
  display: block;

  margin-top: 12px;

  color: var(--muted);

  font-family: "Inter", sans-serif;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;

  transition:
    color 0.45s ease,
    transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}


/* Quote */

.essay-quote {
  max-width: 340px;
  margin: 0;

  color: var(--muted);

  font-family: "Cormorant Garamond", serif;
  font-size: 18px;
  font-style: italic;
  line-height: 1.42;

  opacity: 0;
  transform: translateX(22px);

  transition:
    opacity 0.55s ease 0.04s,
    transform 0.68s cubic-bezier(0.22, 1, 0.36, 1);
}


/* Arrow */

.essay-arrow {
  justify-self: end;

  display: block;
  width: 19px;
  height: 19px;

  color: var(--accent);

  opacity: 0.38;

  transition:
    opacity 0.45s ease,
    transform 0.56s cubic-bezier(0.22, 1, 0.36, 1);
}


/* Hover — pull the book from the shelf */

.essay-spine:hover {
  transform: translateX(14px);

  padding-left: 26px;
  padding-right: 18px;

  background: rgba(255, 250, 243, 0.48);

  box-shadow:
    -14px 0 22px rgba(31, 27, 24, 0.045),
    0 13px 28px rgba(31, 27, 24, 0.035);
}

.essay-spine:hover::before {
  opacity: 1;
}

.essay-spine:hover::after {
  background: var(--accent);

  transform: scaleY(1);
}

.essay-spine:hover .essay-dot {
  opacity: 1;

  transform: scale(1.45);

  box-shadow:
    0 0 0 5px rgba(155, 95, 68, 0.08);
}

.essay-spine:hover .essay-title {
  transform: translateX(6px);
}

.essay-spine:hover .essay-title h3 {
  color: var(--accent);

  letter-spacing: 0.008em;
}

.essay-spine:hover .essay-type {
  color: var(--ink);

  transform: translateX(2px);
}

.essay-spine:hover .essay-quote {
  opacity: 1;

  transform: translateX(0);
}

.essay-spine:hover .essay-arrow {
  opacity: 1;

  transform: translate(5px, -5px) rotate(7deg);
}


/* Ending */

.essays-ending {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 18px;

  padding-top: 32px;
}

.essays-ending-line {
  width: 36px;
  height: 1px;

  background: rgba(155, 95, 68, 0.45);
}

.essays-ending p {
  margin: 0;

  color: var(--muted);

  font-family: "Cormorant Garamond", serif;
  font-size: 19px;
  font-style: italic;
}


/* Keyboard accessibility */

.essay-spine:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 6px;
}

/* ----------------------------------------
   ABOUT ME
---------------------------------------- */

.about-me-heading {
  max-width: 620px;
}

.about-me-heading h2 em {
  color: var(--accent);
  font-weight: 500;
}

.about-me-content {
  display: grid;
  grid-template-columns: minmax(280px, 460px) 1fr;
  align-items: start;
  gap: 64px;

  max-width: 1180px;
}

.about-photo {
  display: block;
  width: 100%;
  max-width: 460px;
  height: auto;
}

.about-me-bio {
  max-width: 480px;
  padding-top: 4px;
}

.about-me-bio p {
  margin: 0 0 20px;

  color: var(--muted);

  font-size: 16px;
  line-height: 1.8;
}

/* Higher specificity than ".about-me-bio p" above (two classes beat
   one class + one type selector) so this genuinely overrides it,
   rather than losing the cascade despite coming later in the file. */
.about-me-bio .about-me-greeting {
  margin: 0 0 20px;

  font-family: "Cormorant Garamond", serif;
  font-size: clamp(22px, 2.2vw, 26px);
  font-weight: 500;
  color: var(--ink);
}

.about-me-bio p:last-of-type {
  margin-bottom: 0;
}

.about-me-bio .text-link {
  display: inline-block;
  margin-top: 8px;
}

.about-me-currently {
  margin-top: 56px;
  padding-top: 32px;
  max-width: 1180px;

  border-top: 1px solid var(--line);
}

.about-me-currently ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 22px;

  margin: 14px 0 0;
  padding: 0;

  list-style: none;
}

.about-me-currently li {
  position: relative;
  padding-left: 14px;

  color: var(--muted);

  font-size: 14px;
  line-height: 1.6;
}

.about-me-currently li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.65em;

  width: 4px;
  height: 4px;
  border-radius: 50%;

  background: var(--accent);
}

@media (max-width: 760px) {
  .about-me-content {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  .about-photo {
    max-width: 320px;
  }

  .about-me-bio {
    max-width: none;
  }

  .about-me-currently ul {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
}


.contact {
  text-align: center;
  max-width: 760px;
  margin: auto;
}
.contact h2 { margin-bottom: 20px; }
footer {
  padding: 35px 7vw;
  color: var(--muted);
  border-top: 1px solid var(--line);
}

/* Gallery entrance panels live further down in this file — see
   "GALLERY — MUSEUM ENTRANCE" near the end of the stylesheet. */

@media (max-width: 760px) {

  .nav {
    align-items: flex-start;
  }

  .nav nav {
    display: none;
  }

  .split-section,
  .map-card,
  .three,
  .two {
    grid-template-columns: 1fr;
  }

  .map-card {
    min-height: auto;
  }

  /* The globe stays a real, draggable sphere on mobile (touch drag
     works via the same pointer-event handlers as desktop) — it just
     gets a shorter stage and a slightly larger marker hit area, since
     fingers are less precise than a cursor. */
  .globe-stage {
    min-height: 320px;
  }

  .globe-marker {
    width: 32px;
    height: 32px;
  }

  .map-note {
    padding: 40px 28px;
  }

  h1 {
    font-size: 72px;
  }


  /* Hero mobile — stack into one column; the tall hero photo gets its
     own aspect-ratio box (rather than the desktop's fixed 700px height)
     so it always shows a full, uncropped-feeling slice of the image at
     any phone width. Fixes the previous bug where a narrow single-column
     width made `background-size: 100%` render the image shorter than
     its container, causing the browser to tile (repeat) it vertically —
     the "重影" ghosting. `cover` + `no-repeat` + a tuned vertical
     position keep it to one clean, elegant crop instead. */

  .hero {
    grid-template-columns: 1fr;
    min-height: auto;
    gap: 36px;
    padding: 20px 0 56px;
  }

  .hero-left {
    padding-top: 12px;
    padding-left: 0;
  }

  .hero-copy {
    max-width: 300px;
  }

  .hero-right {
    min-height: auto;
    margin-right: 0;
    aspect-ratio: 2 / 3;
  }

  .hero-photo {
    border-radius: 0 0 0 56px;

    background-size: cover;
    background-repeat: no-repeat;
    background-position: center 64%;
  }


  /* Explore mobile */

  .explore-section {
    padding: 90px 0;
  }

  .explore-intro {
    margin-bottom: 55px;
  }

  .explore-intro h2 {
    font-size: 54px;
  }

  .explore-copy {
    max-width: 34rem;
    margin-top: 28px;
  }

  .explore-item {
    grid-template-columns: 36px 1fr 30px;
    gap: 12px;

    min-height: 116px;
    padding: 18px 4px;
  }

  .explore-title h3 {
    font-size: 36px;
  }

  .explore-title p {
    max-width: 230px;

    font-size: 12px;
    line-height: 1.5;
  }

  .explore-preview {
    display: none;
  }

  .explore-item:hover {
    padding-left: 4px;
    padding-right: 4px;
  }

  .explore-item:hover .explore-title {
    transform: none;
  }


  /* Gallery mobile rules live in "GALLERY — MUSEUM ENTRANCE" near
     the end of this file. */

    /* Essays mobile */

  .essays-section {
    padding-top: 95px;
    padding-bottom: 95px;
  }

  .essays-intro {
    grid-template-columns: 1fr;
    gap: 28px;

    margin-bottom: 58px;
  }

  .essays-heading h2 {
    font-size: 53px;
  }

  .essays-intro-copy {
    max-width: 310px;
  }

 .essay-spine {
    grid-template-columns: 22px minmax(0, 1fr) 23px;
    gap: 12px;

    min-height: 145px;
    padding: 22px 4px 22px 12px;

    transform: none;
  }

  .essay-spine::after {
    top: 16px;
    bottom: 16px;
  }

  .essay-title h3 {
    font-size: 28px;
    line-height: 1.02;
  }

  .essay-type {
    margin-top: 9px;

    font-size: 9px;
  }

  .essay-quote {
    grid-column: 2 / 3;

    max-width: 285px;
    margin-top: -4px;

    font-size: 16px;

    opacity: 0.72;
    transform: none;
  }

  .essay-arrow {
    grid-column: 3;
    grid-row: 1 / 3;

    align-self: center;

    width: 17px;
    height: 17px;
    opacity: 0.65;
  }

  .essay-spine:hover {
    transform: none;

    padding-left: 12px;
    padding-right: 4px;

    box-shadow: none;
  }

  .essay-spine:hover .essay-title {
    transform: none;
  }

 .essay-spine:hover .essay-dot {
  transform: scale(1);
  box-shadow: none;
  }

  .essay-spine:hover .essay-arrow {
    transform: none;
  }

  .essays-ending {
    justify-content: flex-start;
  }
}


/* ========================================
   LONGFORM ESSAY — EDITORIAL LAYOUT
======================================== */


/* ----------------------------------------
   READING PROGRESS
---------------------------------------- */

.essay-page .reading-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;

  z-index: 30;

  height: 2px;

  pointer-events: none;
}

.essay-page .reading-progress-bar {
  display: block;

  width: 100%;
  height: 100%;

  background: var(--accent);

  transform: scaleX(0);
  transform-origin: left center;

  will-change: transform;
}


/* ----------------------------------------
   PAGE STRUCTURE
---------------------------------------- */

.essay-page,
.field-note-page {
  background: var(--bg);
}

.article-main {
  padding: 0 7vw;
}

.longform-essay {
  width: 100%;
  max-width: 1120px;

  margin: 0 auto;
}


/* ----------------------------------------
   ARTICLE NAVIGATION
---------------------------------------- */

.essay-page-nav .logo {
  color: var(--ink);
  text-decoration: none;
}

.article-back {
  display: inline-block;

  margin-bottom: 76px;

  color: var(--muted);

  font-family: "Inter", sans-serif;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  line-height: 1;
  text-decoration: none;
  text-transform: uppercase;

  transition:
    color 0.3s ease,
    transform 0.3s ease;
}

.article-back:hover {
  color: var(--accent);
  transform: translateX(-3px);
}


/* ----------------------------------------
   ARTICLE HEADER
---------------------------------------- */

.article-header {
  display: block;

  width: 100%;
  max-width: 920px;

  padding: 105px 0 118px;
}

.article-header .section-label {
  margin: 0 0 25px;
}


/* Main title */

.article-header h1 {
  max-width: 920px;
  margin: 0;

  color: #26211e;

  font-family: "Cormorant Garamond", serif;
  font-size: clamp(56px, 6.3vw, 91px);
  font-weight: 500;
  letter-spacing: -0.045em;
  line-height: 0.98;
}

.article-header h1 em {
  display: block;

  margin-top: 6px;

  color: var(--accent);

  font-style: italic;
  font-weight: 500;
}


/* Subtitle */

.article-subtitle {
  max-width: 570px;

  margin: 43px 0 0;

  color: var(--muted);

  font-family: "Cormorant Garamond", serif;
  font-size: clamp(21px, 1.8vw, 27px);
  font-weight: 500;
  letter-spacing: -0.005em;
  line-height: 1.48;
}


/* Author, date and reading time */

.article-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 11px;

  margin-top: 36px;

  color: rgba(31, 27, 24, 0.56);

  font-family: "Inter", sans-serif;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.12em;
  line-height: 1;
  text-transform: uppercase;
}

.article-meta-dot {
  display: block;
  flex: 0 0 auto;

  width: 3px;
  height: 3px;

  border-radius: 50%;

  background: var(--accent);

  opacity: 0.55;
}


/* ----------------------------------------
   ARTICLE BODY
---------------------------------------- */

.article-body {
  position: relative;

  width: min(100%, 680px);

  margin: 0 auto;
  padding: 116px 0 155px;

  border-top: 1px solid var(--line);
}

.article-body::before {
  content: "";

  position: absolute;
  top: -1px;
  left: 0;

  width: 72px;
  height: 1px;

  background: var(--accent);

  opacity: 0.62;
}


/* Normal paragraphs */

.article-body p {
  margin: 0 0 1.85em;

  color: rgba(31, 27, 24, 0.8);

  font-family: "Inter", sans-serif;
  font-size: 16px;
  font-weight: 300;
  letter-spacing: 0.005em;
  line-height: 1.92;
}

.article-body p:last-child {
  margin-bottom: 0;
}


/* ----------------------------------------
   LEAD PARAGRAPH
---------------------------------------- */

.article-body .article-lead {
  margin-bottom: 1.55em;

  color: #302925;

  font-family: "Cormorant Garamond", serif;
  font-size: clamp(25px, 2.4vw, 32px);
  font-weight: 500;
  letter-spacing: -0.012em;
  line-height: 1.5;
}


/* Drop cap */

.drop-cap {
  float: left;

  margin: 0.075em 0.13em 0 0;

  color: var(--accent);

  font-family: "Cormorant Garamond", serif;
  font-size: 3.5em;
  font-style: normal;
  font-weight: 500;
  line-height: 0.75;
}


/* Hidden replacement letter for screen readers */

.visually-hidden {
  position: absolute;

  width: 1px;
  height: 1px;

  padding: 0;
  margin: -1px;

  overflow: hidden;

  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);

  white-space: nowrap;

  border: 0;
}


/* Opening pause */

.article-bridge {
  margin-top: 49px !important;
  margin-bottom: 27px !important;

  color: #6e4b3b !important;

  font-family: "Cormorant Garamond", serif !important;
  font-size: 23px !important;
  font-style: italic;
  font-weight: 500 !important;
  letter-spacing: -0.01em !important;
  line-height: 1.5 !important;
}


/* ----------------------------------------
   ARTICLE SECTIONS
---------------------------------------- */

.article-section {
  margin: 0;
  padding: 0;
}

.article-section + .article-section {
  margin-top: 0;
}


/* Section headings */

.article-body h2 {
  max-width: 650px;

  margin: 112px 0 43px;

  color: #302925;

  font-family: "Cormorant Garamond", serif;
  font-size: clamp(35px, 3.8vw, 48px);
  font-weight: 500;
  letter-spacing: -0.025em;
  line-height: 1.08;
}

.article-body h2::before {
  content: "";

  display: block;

  width: 32px;
  height: 1px;

  margin-bottom: 26px;

  background: rgba(155, 95, 68, 0.5);
}


/* ----------------------------------------
   PULL QUOTES
---------------------------------------- */

.article-pullquote {
  position: relative;

  width: calc(100% + 72px);

  margin: 77px 0 79px -36px;
  padding: 8px 0 8px 43px;

  color: #8d5942;

  font-family: "Cormorant Garamond", serif;
  font-size: clamp(27px, 2.75vw, 35px);
  font-style: italic;
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.42;

  border: none;
}

.article-pullquote::before {
  content: "";

  position: absolute;
  top: 4px;
  bottom: 4px;
  left: 0;

  display: block;

  width: 1px;

  background: rgba(155, 95, 68, 0.72);
}

.article-pullquote::after {
  content: "";

  position: absolute;
  top: 50%;
  left: -4px;

  width: 9px;
  height: 9px;

  border: 1px solid rgba(155, 95, 68, 0.58);
  border-radius: 50%;

  background: var(--bg);

  transform: translateY(-50%);
}


/* ----------------------------------------
   FINAL PARAGRAPH
---------------------------------------- */

.article-ending {
  position: relative;

  margin-top: 94px !important;
  margin-bottom: 0 !important;
  padding: 62px 0 0 43px;

  color: #4b3930 !important;

  font-family: "Cormorant Garamond", serif !important;
  font-size: clamp(25px, 2.65vw, 34px) !important;
  font-style: italic;
  font-weight: 500 !important;
  letter-spacing: -0.012em !important;
  line-height: 1.5 !important;

  border-top: 1px solid rgba(31, 27, 24, 0.12);
}

.article-ending::before {
  content: "—";

  position: absolute;
  top: 57px;
  left: 0;

  color: var(--accent);

  font-family: "Cormorant Garamond", serif;
  font-size: 24px;
  font-style: normal;
  font-weight: 500;
}


/* ----------------------------------------
   FURTHER READING
---------------------------------------- */

.article-references {
  margin-top: 148px;
  padding-top: 46px;

  border-top: 1px solid var(--line);
}

.article-references .section-label {
  margin: 0 0 32px;

  color: var(--accent);

  font-family: "Inter", sans-serif;
}

.article-references ol {
  margin: 0;
  padding-left: 19px;
}

.article-references li {
  margin-bottom: 17px;
  padding-left: 10px;

  color: rgba(31, 27, 24, 0.58);

  font-family: "Inter", sans-serif;
  font-size: 11px;
  font-weight: 300;
  letter-spacing: 0.002em;
  line-height: 1.75;
}

.article-references li::marker {
  color: rgba(155, 95, 68, 0.72);

  font-size: 10px;
}

.article-references em {
  font-style: italic;
}


/* ----------------------------------------
   ARTICLE FOOTER
---------------------------------------- */

.article-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 30px;

  padding: 39px 7vw;

  color: var(--muted);

  border-top: 1px solid var(--line);
}

.article-footer a {
  color: var(--muted);

  font-family: "Inter", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-decoration: none;
  text-transform: uppercase;

  transition:
    color 0.3s ease,
    transform 0.3s ease;
}

.article-footer a:hover {
  color: var(--accent);
  transform: translateX(-3px);
}

.article-footer p {
  margin: 0;

  font-size: 11px;
}


/* ----------------------------------------
   SELECTION
---------------------------------------- */

.essay-page ::selection,
.field-note-page ::selection {
  color: var(--ink);
  background: rgba(155, 95, 68, 0.18);
}


/* ----------------------------------------
   TABLET
---------------------------------------- */

@media (max-width: 960px) {

  .article-header {
    max-width: 820px;
  }

  .article-pullquote {
    width: calc(100% + 36px);

    margin-left: -18px;
    padding-left: 36px;
  }

}


/* ----------------------------------------
   MOBILE
---------------------------------------- */

@media (max-width: 760px) {

  .article-main {
    padding: 0 6vw;
  }


  /* Header */

  .article-header {
    padding: 70px 0 83px;
  }

  .article-back {
    margin-bottom: 58px;
  }

  .article-header .section-label {
    margin-bottom: 20px;
  }

  .article-header h1 {
    font-size: clamp(47px, 13.4vw, 63px);
    letter-spacing: -0.043em;
    line-height: 0.98;
  }

  .article-header h1 em {
    margin-top: 5px;
  }

  .article-subtitle {
    max-width: 330px;

    margin-top: 30px;

    font-size: 21px;
    line-height: 1.5;
  }

  .article-meta {
    gap: 8px;

    margin-top: 28px;

    font-size: 9px;
    letter-spacing: 0.1em;
    line-height: 1.5;
  }


  /* Body */

  .article-body {
    width: 100%;

    padding: 76px 0 106px;
  }

  .article-body::before {
    width: 52px;
  }

  .article-body p {
    margin-bottom: 1.58em;

    font-size: 15.5px;
    letter-spacing: 0;
    line-height: 1.84;
  }

  .article-body .article-lead {
    margin-bottom: 1.48em;

    font-size: 26px;
    line-height: 1.48;
  }


  /* Drop cap */

  .drop-cap {
    margin-top: 0.08em;
    margin-right: 0.11em;

    font-size: 3.22em;
  }


  /* Opening pause */

  .article-bridge {
    margin-top: 40px !important;
    margin-bottom: 24px !important;

    font-size: 21px !important;
  }


  /* Headings */

  .article-body h2 {
    margin: 79px 0 30px;

    font-size: 38px;
    line-height: 1.08;
  }

  .article-body h2::before {
    width: 28px;

    margin-bottom: 22px;
  }


  /* Pull quotes */

  .article-pullquote {
    width: 100%;

    margin: 59px 0 63px;
    padding: 4px 0 4px 28px;

    font-size: 27px;
    line-height: 1.42;
  }

  .article-pullquote::before {
    top: 2px;
    bottom: 2px;
  }

  .article-pullquote::after {
    left: -4px;
  }


  /* Ending */

  .article-ending {
    margin-top: 76px !important;
    padding: 49px 0 0 31px;

    font-size: 27px !important;
    line-height: 1.48 !important;
  }

  .article-ending::before {
    top: 44px;

    font-size: 22px;
  }


  /* References */

  .article-references {
    margin-top: 114px;
    padding-top: 38px;
  }

  .article-references .section-label {
    margin-bottom: 27px;
  }

  .article-references li {
    margin-bottom: 16px;

    font-size: 10.5px;
    line-height: 1.72;
  }


  /* Footer */

  .article-footer {
    align-items: flex-start;
    flex-direction: column;

    padding: 32px 6vw;
  }

}


/* ----------------------------------------
   REDUCED MOTION
---------------------------------------- */

@media (prefers-reduced-motion: reduce) {

  .article-back,
  .article-footer a {
    transition: none;
  }

}


/* ========================================
   FIELD NOTE — INTIMATE READING PAGE
   Shares the longform article system above
   (typography, width, grain, nav, body
   treatment) but with a shorter, quieter
   header — closer to a private notebook
   than a formal publication.
======================================== */

.field-note-page-nav .logo {
  color: var(--ink);
  text-decoration: none;
}

.field-note-page .article-back {
  margin-bottom: 44px;
}

.field-note-page .article-header {
  padding: 54px 0 58px;
}

.field-note-page .article-header h1 {
  max-width: 700px;

  font-size: clamp(32px, 3.4vw, 48px);
  font-weight: 500;
  letter-spacing: -0.015em;
  line-height: 1.14;
}

.field-note-page .article-meta {
  margin-top: 20px;
}


/* Dialogue speaker label — used on notes written as conversation */

.field-note-page .dialogue-speaker {
  display: inline-block;

  margin-right: 10px;

  color: var(--accent);

  font-family: "Inter", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

@media (max-width: 760px) {

  .field-note-page .article-back {
    margin-bottom: 34px;
  }

  .field-note-page .article-header {
    padding: 46px 0 50px;
  }

  .field-note-page .article-header h1 {
    font-size: clamp(28px, 8.6vw, 38px);
    letter-spacing: -0.008em;
    line-height: 1.18;
  }

  .field-note-page .article-meta {
    margin-top: 16px;
  }

}


/* ========================================
   GALLERY — MUSEUM ENTRANCE
   Two independent modules (Photographs,
   Drawings) reached through a single pair
   of full-bleed entrance panels. Not a
   portfolio grid — every image gets room
   to breathe. See CLAUDE.md → "Gallery
   architecture" for the file structure.
======================================== */


/* ----------------------------------------
   LANDING ENTRANCE (index.html #gallery)
---------------------------------------- */

.gallery-entrance {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 32px;

  margin-top: 64px;
}

.gallery-panel {
  position: relative;

  display: block;

  height: 640px;

  overflow: hidden;

  color: #fffaf3;
  text-decoration: none;

  cursor: pointer;
}

/* Scroll reveal stagger — three panels side by side; see "SCROLL
   REVEAL" further up for the shared .reveal-up recipe. */
.gallery-panel:nth-child(2) { --reveal-delay: 0.12s; }
.gallery-panel:nth-child(3) { --reveal-delay: 0.24s; }

.gallery-panel-image {
  position: absolute;
  inset: 0;

  background-size: cover;
  background-position: center;

  filter: saturate(0.85);

  transform: scale(1);

  transition: transform 1.2s cubic-bezier(0.22, 1, 0.36, 1);
}

.gallery-panel-image--placeholder {
  background-image:
    linear-gradient(
      150deg,
      rgba(234, 220, 204, 0.9),
      rgba(248, 243, 236, 0.9)
    );
}

.gallery-panel:hover .gallery-panel-image {
  transform: scale(1.03);
}

.gallery-panel::after {
  content: "";

  position: absolute;
  inset: 0;
  z-index: 1;

  pointer-events: none;

  background: linear-gradient(
    180deg,
    transparent 38%,
    rgba(31, 27, 24, 0.6) 100%
  );
}

.gallery-panel-content {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;

  padding: 40px 40px 36px;
}

.gallery-panel-title {
  display: block;

  font-family: "Cormorant Garamond", serif;
  font-size: clamp(34px, 3vw, 46px);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1;

  color: rgba(255, 250, 243, 0.88);

  transition: color 0.7s ease;
}

.gallery-panel:hover .gallery-panel-title {
  color: #fffaf3;
}

.gallery-panel-copy {
  display: block;

  margin-top: 12px;
  max-width: 260px;

  font-family: "Inter", sans-serif;
  font-size: 14px;
  line-height: 1.65;

  color: rgba(255, 250, 243, 0.72);
}

.gallery-panel-count {
  display: block;

  margin-top: 20px;

  font-family: "Inter", sans-serif;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;

  color: rgba(255, 250, 243, 0.5);
}

.gallery-panel:focus-visible {
  outline: 1px solid rgba(255, 250, 243, 0.7);
  outline-offset: -8px;
}


/* ----------------------------------------
   EXHIBITION PAGE CHROME
   (gallery/photographs.html, gallery/drawings.html)
---------------------------------------- */

.gallery-page {
  background: #f8f7f4;
}

.gallery-page ::selection {
  color: var(--ink);
  background: rgba(155, 95, 68, 0.18);
}

.gallery-page-nav .logo {
  color: var(--ink);
  text-decoration: none;
}

.gallery-exhibition {
  padding: 0 7vw;
}

.exhibit-header {
  max-width: 900px;
  margin: 0 auto;
  padding: 100px 0 90px;
}

.exhibit-back {
  display: inline-block;

  margin-bottom: 64px;

  color: var(--muted);

  font-family: "Inter", sans-serif;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  line-height: 1;
  text-decoration: none;
  text-transform: uppercase;

  transition: color 0.3s ease, transform 0.3s ease;
}

.exhibit-back:hover {
  color: var(--accent);
  transform: translateX(-3px);
}

.exhibit-breadcrumb {
  margin: 0 0 22px;

  color: var(--accent);

  font-family: "Inter", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.exhibit-header h1 {
  margin: 0;

  color: #26211e;

  font-family: "Cormorant Garamond", serif;
  font-size: clamp(56px, 7vw, 100px);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 0.96;
}

.exhibit-subtitle {
  max-width: 520px;
  margin: 26px 0 0;

  color: var(--muted);

  font-family: "Cormorant Garamond", serif;
  font-style: italic;
  font-size: clamp(20px, 1.8vw, 26px);
  line-height: 1.55;
}


/* ----------------------------------------
   COLLECTIONS
---------------------------------------- */

.exhibit-collections {
  max-width: 1500px;
  margin: 0 auto;
}

.exhibit-collection {
  padding: 120px 0;

  border-top: 1px solid var(--line);
}

.exhibit-collection:first-child {
  padding-top: 0;
  border-top: none;
}

.exhibit-collection-intro {
  max-width: 620px;
  margin: 0 auto 72px;

  text-align: center;
}

.exhibit-collection-title {
  margin: 0;

  color: #26211e;

  font-family: "Cormorant Garamond", serif;
  font-weight: 500;
  font-size: clamp(32px, 3.4vw, 50px);
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.exhibit-collection--featured .exhibit-collection-title {
  font-size: clamp(42px, 4.4vw, 64px);
}

.exhibit-collection-sentence {
  margin: 18px 0 0;

  color: var(--muted);

  font-family: "Inter", sans-serif;
  font-size: 15px;
  line-height: 1.75;
}

.exhibit-coming-soon {
  margin: 0;
  padding-bottom: 20px;

  color: var(--muted);

  font-family: "Cormorant Garamond", serif;
  font-style: italic;
  font-size: 19px;
  text-align: center;
}

.exhibit-collection-count {
  margin: 14px 0 0;

  color: rgba(155, 95, 68, 0.6);

  font-family: "Inter", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}


/* ----------------------------------------
   MASONRY (Photographs)
---------------------------------------- */

.exhibit-grid--masonry {
  column-count: 3;
  column-gap: 28px;
}

.exhibit-collection--featured .exhibit-grid--masonry {
  column-count: 2;
  column-gap: 40px;
}

.exhibit-grid--masonry .exhibit-tile {
  margin-bottom: 28px;
}


/* ----------------------------------------
   EDITORIAL GRID (Drawings)

   Unlike the Photographs masonry, drawings keep their natural
   proportions — no forced cropping. A calmer, more structured grid:
   fixed columns with row alignment, each tile's own aspect-ratio set
   inline from its data (see gallery.js createTile), generous gaps so
   every piece reads as an individual work rather than a photo stream.
---------------------------------------- */

.exhibit-grid--editorial {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  align-items: start;
  gap: 56px 40px;
}

.exhibit-tile--span2 {
  grid-column: span 2;
}


/* ----------------------------------------
   TILES
---------------------------------------- */

.exhibit-tile {
  position: relative;

  display: block;
  width: 100%;

  padding: 0;

  background: none;
  border: none;

  overflow: hidden;
  cursor: pointer;

  opacity: 0;
  transform: translateY(18px);

  transition: opacity 0.9s ease, transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

.exhibit-tile.is-revealed {
  opacity: 1;
  transform: none;
}

.exhibit-tile--portrait { aspect-ratio: 3 / 4; }
.exhibit-tile--square   { aspect-ratio: 1 / 1; }
.exhibit-tile--landscape{ aspect-ratio: 4 / 3; }
.exhibit-tile--tall     { aspect-ratio: 2 / 3; }
.exhibit-tile--wide     { aspect-ratio: 16 / 9; }

.exhibit-tile img {
  display: block;

  width: 100%;
  height: 100%;

  object-fit: cover;

  filter: saturate(0.85);

  transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1), filter 0.6s ease;
}

/* Real photographs (see .exhibit-tile--natural in gallery.js) sit in
   a tile already sized to their own measured aspect ratio, so
   object-fit: contain here fills the box exactly with zero
   letterboxing — this is a safety net against ever cropping real
   content, not a visual change from `cover`, since the two produce
   an identical result once the box ratio equals the image ratio. */
.exhibit-tile--natural img {
  object-fit: contain;
}

.exhibit-tile:hover img,
.exhibit-tile:focus-visible img {
  transform: scale(1.03);
  filter: saturate(0.95);
}

.exhibit-tile-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;

  width: 100%;
  height: 100%;

  background: linear-gradient(160deg, #eee3d3, #f6efe4);

  transition: background 0.6s ease;
}

.exhibit-tile:hover .exhibit-tile-placeholder,
.exhibit-tile:focus-visible .exhibit-tile-placeholder {
  background: linear-gradient(160deg, #e8dac6, #f3ece0);
}


/* Editorial tiles (Drawings) — contained, not cropped: each work
   sits on its own quiet mat instead of bleeding to the tile edge. */

.exhibit-tile--editorial {
  overflow: visible;

  background: #fcfbf9;
  padding: 14px;

  border: 1px solid var(--line);
}

.exhibit-tile--editorial img {
  object-fit: contain;

  filter: none;
}

.exhibit-tile--editorial:hover img,
.exhibit-tile--editorial:focus-visible img {
  transform: scale(1.015);
  filter: none;
}

.exhibit-tile--editorial .exhibit-tile-placeholder {
  background: linear-gradient(160deg, #f1ede4, #f8f6f1);
}

.exhibit-tile--editorial:hover .exhibit-tile-placeholder,
.exhibit-tile--editorial:focus-visible .exhibit-tile-placeholder {
  background: linear-gradient(160deg, #ece5d6, #f5f2ea);
}

.exhibit-tile--comics {
  grid-column: span 2;
}

.exhibit-tile-index {
  font-family: "Inter", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;

  color: rgba(155, 95, 68, 0.55);
}

.exhibit-tile:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 4px;
}


/* ----------------------------------------
   LIGHTBOX
---------------------------------------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;

  display: flex;
  align-items: center;
  justify-content: center;

  background: rgba(20, 17, 15, 0.94);

  opacity: 0;
  visibility: hidden;

  transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}

.lightbox.is-open {
  visibility: visible;
}

.lightbox.is-visible {
  opacity: 1;
  transition: opacity 0.5s ease, visibility 0s linear 0s;
}

.lightbox-stage {
  position: relative;

  display: flex;
  align-items: center;
  justify-content: center;

  max-width: 88vw;
  max-height: 82vh;
}

.lightbox-image {
  display: block;

  max-width: 88vw;
  max-height: 82vh;

  object-fit: contain;

  opacity: 0;
  transform: scale(0.98);

  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.lightbox.is-visible .lightbox-image {
  opacity: 1;
  transform: scale(1);
}

.lightbox-placeholder {
  display: none;
  align-items: center;
  justify-content: center;

  width: 60vw;
  max-width: 640px;
  aspect-ratio: 4 / 5;

  background: linear-gradient(160deg, #2a2420, #171310);
}

.lightbox-placeholder-index {
  color: rgba(248, 243, 236, 0.35);

  font-family: "Inter", sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.2em;
}

.lightbox-close,
.lightbox-prev,
.lightbox-next {
  position: absolute;

  background: none;
  border: none;

  color: rgba(248, 243, 236, 0.72);

  font-family: "Inter", sans-serif;
  font-weight: 300;

  cursor: pointer;

  transition: color 0.35s ease, opacity 0.35s ease;
}

.lightbox-close:hover,
.lightbox-prev:hover,
.lightbox-next:hover {
  color: #fffaf3;
}

.lightbox-close {
  top: 24px;
  right: 28px;

  font-size: 28px;
  line-height: 1;
}

.lightbox-prev,
.lightbox-next {
  top: 50%;

  padding: 18px;

  font-size: 22px;

  transform: translateY(-50%);
}

.lightbox-prev { left: 12px; }
.lightbox-next { right: 12px; }

.lightbox-meta {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 48px;

  margin: 0;

  color: rgba(248, 243, 236, 0.72);

  font-family: "Cormorant Garamond", serif;
  font-style: italic;
  font-size: 16px;
  text-align: center;
}

.lightbox-meta:empty {
  display: none;
}

.lightbox-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 26px;

  margin: 0;

  color: rgba(248, 243, 236, 0.5);

  font-family: "Inter", sans-serif;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-align: center;
}

body.lightbox-open {
  overflow: hidden;
}


/* ----------------------------------------
   ROOM SWITCHER (Photographs page only)

   One collection ("room") visible at a time.
   Vertical scroll browses photographs inside
   the active room; horizontal click / arrow
   keys / swipe / trackpad gesture changes
   rooms. drawings.html does not use this —
   it keeps the plain vertical stack above.
---------------------------------------- */

.exhibit-header--rooms {
  padding-bottom: 44px;
}

.room-nav {
  position: sticky;
  top: 86px;
  z-index: 4;

  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 36px;

  margin: 0 auto 64px;
  padding: 26px 0;

  background: rgba(248, 247, 244, 0.86);
  backdrop-filter: blur(10px);

  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);

  animation: room-nav-settle 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes room-nav-settle {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.room-nav-prev,
.room-nav-next {
  display: inline-flex;
  align-items: baseline;
  gap: 9px;

  padding: 0;

  background: none;
  border: none;

  color: rgba(31, 27, 24, 0.38);
  cursor: pointer;

  font-family: "Inter", sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.03em;
  white-space: nowrap;

  transition: color 0.4s ease;
}

.room-nav-prev:hover,
.room-nav-next:hover {
  color: rgba(31, 27, 24, 0.7);
}

.room-nav-arrow {
  display: inline-block;

  color: var(--accent);
  opacity: 0.55;

  transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s ease;
}

.room-nav-prev:hover .room-nav-arrow {
  opacity: 1;
  transform: translateX(-4px);
}

.room-nav-next:hover .room-nav-arrow {
  opacity: 1;
  transform: translateX(4px);
}

.room-nav-current {
  color: var(--accent);

  font-family: "Inter", sans-serif;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.room-nav-prev:focus-visible,
.room-nav-next:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 6px;
}

.room-stage {
  position: relative;

  max-width: 1500px;
  margin: 0 auto;

  overflow-x: hidden;

  touch-action: pan-y;
}

.room-stage-edge {
  position: fixed;
  top: 96px;
  bottom: 0;

  width: 56px;
  z-index: 3;

  pointer-events: none;
}

.room-stage-edge--left {
  left: 0;
  background: linear-gradient(
    90deg,
    #f8f7f4 0%,
    rgba(248, 247, 244, 0) 100%
  );
}

.room-stage-edge--right {
  right: 0;
  background: linear-gradient(
    270deg,
    #f8f7f4 0%,
    rgba(248, 247, 244, 0) 100%
  );
}

.room-panel {
  display: none;

  transform: none;
  opacity: 1;
}

.room-panel.is-active {
  display: block;
}

.room-panel .exhibit-collection {
  padding: 8px 0 60px;
  border-top: none;
}

.room-panel.is-transitioning {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;

  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.5s ease;
}

.room-panel.is-entering-from-right { transform: translateX(36px); opacity: 0; }
.room-panel.is-entering-from-left  { transform: translateX(-36px); opacity: 0; }
.room-panel.is-leaving-to-left     { transform: translateX(-36px); opacity: 0; }
.room-panel.is-leaving-to-right    { transform: translateX(36px); opacity: 0; }


/* ----------------------------------------
   REDUCED MOTION
---------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .gallery-panel-image,
  .gallery-panel-title,
  .exhibit-tile,
  .exhibit-tile img,
  .exhibit-tile-placeholder,
  .lightbox,
  .lightbox-image,
  .room-nav-arrow,
  .room-panel.is-transitioning {
    transition-duration: 0.01ms;
  }

  .room-nav {
    animation: none;
  }
}


/* ----------------------------------------
   TABLET
---------------------------------------- */

@media (max-width: 960px) {

  .gallery-entrance {
    grid-template-columns: 1fr 1fr;
  }

  .gallery-entrance .gallery-panel:nth-child(3) {
    grid-column: 1 / -1;
  }

  .exhibit-grid--masonry {
    column-count: 2;
    column-gap: 22px;
  }

  .exhibit-collection--featured .exhibit-grid--masonry {
    column-count: 1;
    max-width: 560px;
    margin: 0 auto;
  }

  .exhibit-grid--editorial {
    grid-template-columns: repeat(2, 1fr);
    gap: 44px 28px;
  }

}


/* ----------------------------------------
   MOBILE
---------------------------------------- */

@media (max-width: 760px) {

  .gallery-entrance {
    grid-template-columns: 1fr;
    gap: 20px;

    margin-top: 44px;
  }

  .gallery-panel {
    height: 460px;
  }

  .gallery-panel-content {
    padding: 30px 26px 28px;
  }

  .gallery-exhibition {
    padding: 0 6vw;
  }

  .exhibit-header {
    padding: 70px 0 64px;
  }

  .exhibit-back {
    margin-bottom: 46px;
  }

  .exhibit-header h1 {
    font-size: clamp(44px, 13vw, 64px);
  }

  .exhibit-subtitle {
    font-size: 20px;
  }

  .exhibit-collection {
    padding: 76px 0;
  }

  .exhibit-collection-intro {
    margin-bottom: 48px;
  }

  .exhibit-grid--masonry {
    column-count: 1;
  }

  .exhibit-collection--featured .exhibit-grid--masonry {
    max-width: none;
  }

  .exhibit-grid--editorial {
    grid-template-columns: 1fr;
    gap: 40px;
  }

  .exhibit-tile--span2,
  .exhibit-tile--comics {
    grid-column: span 1;
  }

  .exhibit-collection-count {
    margin-top: 10px;
  }

  .lightbox-prev,
  .lightbox-next {
    padding: 10px;
    font-size: 18px;
  }

  .lightbox-close {
    top: 14px;
    right: 16px;
  }

  .lightbox-caption {
    bottom: 16px;
  }

  .exhibit-header--rooms {
    padding-bottom: 34px;
  }

  .room-nav {
    top: 76px;

    gap: 16px;

    margin-bottom: 44px;
    padding: 18px 0;
  }

  .room-nav-prev,
  .room-nav-next {
    gap: 5px;

    font-size: 11px;
  }

  .room-nav-prev .room-nav-label,
  .room-nav-next .room-nav-label {
    display: none;
  }

  .room-nav-current {
    font-size: 13px;
  }

  .room-stage-edge {
    top: 86px;

    width: 28px;
  }

  .room-panel .exhibit-collection {
    padding: 4px 0 44px;
  }

}


/* ========================================
   CUSTOM CURSOR

   Site-wide (see cursor.js — included on every page). Reuses the
   existing palette (--accent) rather than inventing a new colour;
   the values below are the only things cursor.js expects to find
   here, and are the ones to tune first.
======================================== */

/* EDIT POINT — size, colour, opacity and easing.
   --cursor-rest-scale is --cursor-size ÷ --cursor-hover-size, kept
   as a plain number because CSS calc() cannot divide two lengths —
   update it together with either size if you change them. */
:root {
  --cursor-size: 11px;
  --cursor-hover-size: 32px;
  --cursor-rest-scale: 0.25;

  --cursor-color-rgb: 155, 95, 68; /* matches --accent (#9b5f44) */
  --cursor-rest-opacity: 0.6;
  --cursor-hover-opacity: 0.38;
  --cursor-press-scale: 0.7;

  --cursor-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --cursor-ease-duration: 0.5s;
}

/* Applied to <html> by cursor.js only once it has confirmed a fine
   pointer with hover support — never on touch devices, and never if
   the script fails to load, so the native cursor is always the safe
   fallback. !important is deliberate here: it overrides the many
   individual `cursor: pointer` declarations across the site's
   buttons, links and tiles without hunting each one down. */
html.custom-cursor-active,
html.custom-cursor-active * {
  cursor: none !important;
}

/* The site has no text inputs today, but kept for robustness if one
   is ever added — typing still gets a normal caret. */
html.custom-cursor-active input,
html.custom-cursor-active textarea,
html.custom-cursor-active [contenteditable] {
  cursor: text !important;
}

.custom-cursor {
  position: fixed;
  top: 0;
  left: 0;
  width: 0;
  height: 0;

  z-index: 9999;
  pointer-events: none;

  opacity: 0;
  transition: opacity 0.3s ease;

  will-change: transform;
}

.custom-cursor.is-visible {
  opacity: 1;
}

.custom-cursor-dot {
  position: absolute;
  top: 0;
  left: 0;

  width: var(--cursor-hover-size);
  height: var(--cursor-hover-size);

  border-radius: 50%;
  background: radial-gradient(
    circle at 50% 50%,
    rgba(var(--cursor-color-rgb), 0.95) 0%,
    rgba(var(--cursor-color-rgb), 0.55) 55%,
    rgba(var(--cursor-color-rgb), 0) 100%
  );
  filter: blur(0.3px);

  opacity: var(--cursor-rest-opacity);
  transform: translate(-50%, -50%) scale(var(--cursor-rest-scale));

  transition: transform var(--cursor-ease-duration) var(--cursor-ease),
    opacity var(--cursor-ease-duration) var(--cursor-ease),
    border-radius var(--cursor-ease-duration) var(--cursor-ease);
}

.custom-cursor-dot.is-hover {
  opacity: var(--cursor-hover-opacity);
  transform: translate(-50%, -50%) scale(1);
}

/* Brief shrink on press — quicker than the hover/rest transition so
   it reads as a small "tap" rather than a slow resize. */
.custom-cursor-dot.is-pressed {
  transition: transform 0.14s ease;
}

.custom-cursor-dot.is-hover.is-pressed {
  transform: translate(-50%, -50%) scale(0.72);
}

.custom-cursor-dot.is-pressed:not(.is-hover) {
  transform: translate(-50%, -50%)
    scale(calc(var(--cursor-rest-scale) * var(--cursor-press-scale)));
}

/* Long-form reading pages (essays, field notes) — a smaller, quieter
   hover state so the cursor never competes with body text. */
.custom-cursor--restrained .custom-cursor-dot.is-hover {
  opacity: calc(var(--cursor-hover-opacity) * 0.7);
  transform: translate(-50%, -50%) scale(0.68);
}

@media (prefers-reduced-motion: reduce) {
  .custom-cursor-dot {
    transition-duration: 0.01ms;
  }
}


/* ========================================
   PIXEL FOX COMPANION (all pages)

   Markup is built entirely by fox.js (included on every page);
   nothing to add anywhere else. Colours are their own small
   palette (--fox-*), distinct from the site's --ink/--accent but
   chosen to sit quietly alongside them — warm, muted, low-contrast.
======================================== */

:root {
  /* Pixel palette — a softer, more muted take on fox-orange than a
     literal swatch match, chosen to sit quietly in this site's warm,
     low-contrast world rather than pop against it. */
  --fox-fur: #dd9a76;
  --fox-fur-light: #f0c9ab;
  --fox-fur-deep: #c9835c;
  --fox-cream: #fbf5ec;
  --fox-shadow: #96796a;
  --fox-ink: #382c26;
  --fox-ground: rgba(56, 44, 38, 0.14);

  /* EDIT POINT — rendered size (viewBox is a fixed 40 x 44). */
  --fox-width: 58px;
  --fox-height: 64px;
}

.pixel-fox {
  position: fixed;
  right: 26px;
  bottom: 20px;

  width: var(--fox-width);
  height: var(--fox-height);

  z-index: 20;
  cursor: pointer;
  pointer-events: auto;

  /* Mobile Safari/Chrome can otherwise wait ~300ms to see whether a
     tap is the start of a double-tap-zoom or scroll gesture before
     firing click — this tells it to treat a tap here as an
     immediate, unambiguous action instead. */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;

  /* Fixed positioning, out of document flow — causes no layout
     shift on any existing section, on any page. */
}

.pixel-fox-svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Clicks/hover always land on the .pixel-fox container itself, not
   individual shapes — consistent hit-testing regardless of which
   part of the silhouette the pointer happens to be over. */
.pixel-fox-svg,
.pixel-fox-svg * {
  pointer-events: none;
}

.fox-fur { fill: var(--fox-fur); }
.fox-fur-light { fill: var(--fox-fur-light); }
.fox-fur-deep { fill: var(--fox-fur-deep); }
.fox-cream { fill: var(--fox-cream); }
.fox-ink { fill: var(--fox-ink); }
.fox-shadow { fill: var(--fox-shadow); }
.fox-ground { fill: var(--fox-ground); }

.fox-envelope-flap {
  fill: none;
  stroke: var(--fox-shadow);
  stroke-width: 1;
  stroke-linecap: round;
  stroke-linejoin: round;
}


/* ---- breathing, tail sway (idle/sitting baseline) ---- */

@keyframes fox-breathe {
  0%, 100% { transform: scaleY(1); }
  50% { transform: scaleY(1.035); }
}

@keyframes fox-breathe-slow {
  0%, 100% { transform: scaleY(1); }
  50% { transform: scaleY(1.018); }
}

.fox-body {
  transform-box: fill-box;
  transform-origin: bottom center;
  animation: fox-breathe 3.2s ease-in-out infinite;
}

.pixel-fox.is-sleeping .fox-body {
  animation: fox-breathe-slow 5.4s ease-in-out infinite;
}

@keyframes fox-tail-sway {
  0%, 100% { transform: rotate(-4deg); }
  50% { transform: rotate(6deg); }
}

.fox-tail {
  transform-box: fill-box;
  transform-origin: 10% 95%;
  animation: fox-tail-sway 4.4s ease-in-out infinite;
}

.pixel-fox.is-sitting .fox-tail {
  animation-duration: 5.2s;
}

/* Lying/sleeping — the tail settles and, once fully asleep, wraps
   in around the body rather than swaying. */
.pixel-fox.is-lying .fox-tail {
  animation: none;
  transform: rotate(28deg);
  transition: transform 0.6s ease;
}

.pixel-fox.is-sleeping .fox-tail {
  animation: none;
  transform: rotate(132deg) scale(0.96);
  transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

.pixel-fox.is-waking .fox-tail {
  animation: none;
  transform: rotate(-16deg) scale(1.06);
  transition: transform 0.5s ease;
}


/* ---- whole-body pose (sit / lie / sleep / wake / hop) ---- */

.fox-rig {
  transform-box: fill-box;
  transform-origin: bottom center;
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

.pixel-fox.is-sitting .fox-rig {
  transform: translateY(2px) scaleY(0.95);
}

/* Lying/sleeping — deliberately no scaleX/scaleY squash here: size
   stays constant, only position (settling lower) and a gentle tilt
   change, matching a real curled-up posture rather than a flattened
   one. The tail wrap (above), closed eyes, and slow breathing carry
   the rest of the "asleep" read. */
.pixel-fox.is-lying .fox-rig {
  transform: translateY(4px) rotate(-6deg);
}

.pixel-fox.is-sleeping .fox-rig {
  transform: translateY(5px) rotate(-7deg);
  transition: transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

/* The one place a brief scale change is appropriate: the stretch
   itself is motion, not a resting pose, so elongating low then
   rising back to full size at 100% is exactly the "stretch first,
   then stand" read — it just settles at the same size it started
   the sleep cycle at, never staying squashed. */
@keyframes fox-stretch {
  0% { transform: translateY(5px) rotate(-7deg); }
  35% { transform: translateY(2px) scaleY(0.82) scaleX(1.2) rotate(-2deg); }
  70% { transform: translateY(-1px) scaleY(1.06) scaleX(0.97) rotate(0deg); }
  100% { transform: translateY(0) scaleY(1) scaleX(1) rotate(0deg); }
}

.pixel-fox.is-waking .fox-rig {
  animation: fox-stretch 0.82s cubic-bezier(0.34, 1.2, 0.4, 1);
}

@keyframes fox-hop {
  0%, 100% { transform: translateY(0); }
  35% { transform: translateY(-7px); }
  60% { transform: translateY(0.5px); }
}

.pixel-fox.is-hopping .fox-rig {
  animation: fox-hop 0.42s ease;
}


/* ---- head: hover look-up, autonomous look-around, fluffy tilt ---- */

.fox-head {
  transform-box: fill-box;
  transform-origin: bottom center;
  transition: transform 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

/* Default hover look — home/about (no accessory): a plain curious
   look-up. Overridden per accessory below (EDIT POINT — each of the
   four accessory contexts gets its own small, bespoke hover
   reaction rather than sharing this one). */
.pixel-fox.is-looking .fox-head {
  transform: translateY(-2px) rotate(-3deg);
}

/* Gallery — camera does the lifting (see .fox-accessory below); the
   head barely moves, as if steadying a shot. */
.pixel-fox[data-accessory="camera"].is-looking .fox-head {
  transform: translateY(-1px) rotate(-2deg);
}

/* Essays/Field Notes — a persistent slight head-bow at rest, not
   just on hover, so the fox reads as genuinely mid-page rather than
   idly holding a closed book. Hovering (below) deepens the same
   bow further. */
.pixel-fox[data-accessory="book"] .fox-head {
  transform: translateY(1px) rotate(3deg);
}

.pixel-fox[data-accessory="book"].is-looking .fox-head {
  transform: translateY(2px) rotate(5deg);
}

/* Map — looks down toward the compass tucked at its paw. */
.pixel-fox[data-accessory="compass"].is-looking .fox-head {
  transform: translateY(1.5px) rotate(7deg);
}

/* Contact — a small alert lift, as the envelope itself is raised
   to show it (see .fox-accessory below). */
.pixel-fox[data-accessory="envelope"].is-looking .fox-head {
  transform: translateY(-1.5px) rotate(-2deg);
}

.pixel-fox.is-fluffy .fox-head {
  transform: rotate(9deg);
  transition: transform 0.5s ease;
}

@keyframes fox-look-around {
  0% { transform: rotate(0); }
  22% { transform: rotate(-11deg); }
  55% { transform: rotate(9deg); }
  80% { transform: rotate(-4deg); }
  100% { transform: rotate(0); }
}

.fox-head.is-looking-around {
  animation: fox-look-around 1.8s ease-in-out;
}


/* ---- eyes (blink) and ears (twitch) ---- */

.fox-eyes rect {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 0.09s ease, y 0.3s ease, height 0.3s ease;
}

/* Essays/Field Notes — eyes sit a little lower and noticeably
   thinner, like a focused, slightly narrowed reading gaze. Adjusts
   the actual SVG geometry (y/height) rather than `transform`, so it
   layers cleanly under the blink/sleep transforms above and below
   without fighting their own scaleY. */
.pixel-fox[data-accessory="book"] .fox-eyes rect {
  y: 17px;
  height: 2px;
}

.fox-eyes.is-blinking rect {
  transform: scaleY(0.12);
}

.pixel-fox.is-sleeping .fox-eyes rect {
  transform: scaleY(0.16);
  transition: transform 0.4s ease;
}

.fox-ear-left,
.fox-ear-right {
  transform-box: fill-box;
  transform-origin: bottom center;
  transition: transform 0.3s ease;
}

.fox-ear-left.is-twitching {
  transform: rotate(-14deg);
}

.fox-ear-right.is-twitching {
  transform: rotate(14deg);
}

.pixel-fox.is-lying .fox-ear-left { transform: rotate(-8deg); }
.pixel-fox.is-lying .fox-ear-right { transform: rotate(8deg); }

.pixel-fox.is-sleeping .fox-ear-left,
.pixel-fox.is-sleeping .fox-ear-right {
  transform: rotate(0) scaleY(0.9);
}


/* ---- Projects/About Me: round glasses + a tilted head ----
   Hidden/untilted by default, shown together only via .is-about (set
   on scroll into #projects or #about-me) — a quiet, quizzical
   "pausing to think" pose, replacing both the earlier squash/tail-
   curl attempt and the chin-propped paw that followed it. */

.fox-glasses {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transition: opacity 0.4s ease;
}

.pixel-fox.is-about .fox-glasses {
  opacity: 1;
}

.fox-glasses-lens {
  fill: none;
  stroke: var(--fox-ink);
  stroke-width: 0.8;
}

/* Resting head tilt — kept, unchanged, through hover too (see the
   combined selector below), so hovering nudges the glasses (see the
   push keyframe below) without the head itself snapping to the
   plain look-up every other context uses. */

.pixel-fox.is-about.fox-head {
  transform: rotate(12deg);
}
.pixel-fox.is-about.is-looking .fox-head {
  transform: rotate(-16deg);
}

/* Hover — a quick, snappy "push the glasses back up the nose"
   nudge, distinct from the head's own hover reactions elsewhere. */
@keyframes fox-glasses-push {
  0% { transform: translateY(0); }
  30% { transform: translateY(-1.4px); }
  60% { transform: translateY(0.3px); }
  100% { transform: translateY(0); }
}

.pixel-fox.is-about.is-looking .fox-glasses {
  animation: fox-glasses-push 0.5s ease-out;
}

.fox-bowtie {
  opacity: 0;
  transition: opacity 0.4s ease;
}

.pixel-fox[data-accessory="envelope"] .fox-bowtie {
  opacity: 1;
}


/* ---- fluffy/confused reaction: fur tufts + a small pixel "?" ---- */

.fox-fluff circle {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transform: scale(0.4);
  transition: opacity 0.4s ease, transform 0.4s ease;
}

.pixel-fox.is-fluffy .fox-fluff circle {
  opacity: 1;
  transform: scale(1);
}

.fox-question {
  font-family: "Courier New", monospace;
  font-weight: 700;
  font-size: 9px;
  fill: var(--fox-shadow);
  text-anchor: middle;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
}

@keyframes fox-question-bob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-2.5px); }
}

.pixel-fox.is-fluffy .fox-question {
  opacity: 1;
  animation: fox-question-bob 1.3s ease-in-out infinite;
}


/* ---- sleep "z"s ---- */

.fox-zzz text {
  opacity: 0;
  font-family: "Courier New", monospace;
  font-weight: 700;
  fill: var(--fox-shadow);
  text-anchor: middle;
}

@keyframes fox-zzz-rise {
  0% { opacity: 0; transform: translateY(2px) scale(0.8); }
  25% { opacity: 0.85; }
  75% { opacity: 0.6; }
  100% { opacity: 0; transform: translateY(-9px) scale(1.1); }
}

.pixel-fox.is-sleeping .fox-zzz text {
  animation: fox-zzz-rise 2.6s ease-in-out infinite;
}

.pixel-fox.is-sleeping .fox-zzz text:nth-child(2) { animation-delay: 0.5s; }
.pixel-fox.is-sleeping .fox-zzz text:nth-child(3) { animation-delay: 1s; }


/* ---- click sparkles ---- */

.fox-sparkle {
  opacity: 0;
  font-family: "Courier New", monospace;
  font-weight: 700;
  font-size: 6px;
  fill: var(--fox-fur);
  transform-box: fill-box;
  transform-origin: center;
}

@keyframes fox-sparkle-pop {
  0% { opacity: 0; transform: translateY(0) scale(0.4); }
  35% { opacity: 1; transform: translateY(-4px) scale(1); }
  100% { opacity: 0; transform: translateY(-9px) scale(0.7); }
}

.pixel-fox.is-hopping .fox-sparkle-a {
  animation: fox-sparkle-pop 0.5s ease-out;
}

.pixel-fox.is-hopping .fox-sparkle-b {
  animation: fox-sparkle-pop 0.5s ease-out 0.06s;
}


/* ---- accessory (per page/section context) ---- */

.fox-accessory {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 0.4s ease, opacity 0.5s ease;
}

/* Default hover reaction — subtle lift. Overridden per accessory
   below so each reads as its own small gesture rather than one
   generic nudge (see the matching .fox-head reactions above). */
.pixel-fox.is-looking .fox-accessory {
  transform: translateY(-1.5px);
}

/* Gallery — the camera is what lifts, up toward eye level. */
.pixel-fox[data-accessory="camera"].is-looking .fox-accessory {
  transform: translateY(-3.5px) rotate(-6deg);
}

/* Essays/Field Notes — the book stays put; the head looks down at
   it instead (see .fox-head above). */
.pixel-fox[data-accessory="book"].is-looking .fox-accessory {
  transform: translateY(0.5px);
}

/* Map — a small curious tilt, as if being consulted. */
.pixel-fox[data-accessory="compass"].is-looking .fox-accessory {
  transform: translateY(-1px) rotate(-8deg);
}

/* Contact — raised to show it. */
.pixel-fox[data-accessory="envelope"].is-looking .fox-accessory {
  transform: translateY(-3px) rotate(4deg);
}

.fox-accessory-camera,
.fox-accessory-book,
.fox-accessory-compass,
.fox-accessory-envelope {
  opacity: 0;
  transition: opacity 0.5s ease;
}

.pixel-fox[data-accessory="camera"] .fox-accessory-camera,
.pixel-fox[data-accessory="book"] .fox-accessory-book,
.pixel-fox[data-accessory="compass"] .fox-accessory-compass,
.pixel-fox[data-accessory="envelope"] .fox-accessory-envelope {
  opacity: 1;
}

/* Accessory is hidden (never mid-page/hover-reactive) once the fox
   is actually asleep or mid-stretch waking up — "placed aside"
   rather than staying visible on a curled-up, eyes-closed fox. It
   fades back in on its own once .is-idle resumes and the context's
   opacity rule above re-applies. */
.pixel-fox.is-sleeping .fox-accessory,
.pixel-fox.is-waking .fox-accessory {
  opacity: 0;
}


/* ---- speech / thought bubble ---- */

.fox-message {
  position: absolute;
  left: 50%;
  bottom: 100%;

  margin: 0 0 10px;
  padding: 6px 12px;

  width: max-content;
  max-width: 150px;

  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 3px;

  color: var(--ink);
  font-family: "Cormorant Garamond", serif;
  font-style: italic;
  font-size: 14px;
  line-height: 1.4;
  text-align: center;

  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 6px);

  transition: opacity 0.4s ease, transform 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}

.fox-message.is-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, 0);
}

/* The autonomous thought bubble — same element, quieter: smaller,
   slightly translucent, so it reads as a passing thought rather
   than a greeting aimed at the visitor. */
.fox-message.is-thought {
  font-size: 12px;
  padding: 4px 10px;
  max-width: 120px;
}

.fox-message.is-thought.is-visible {
  opacity: 0.92;
}


/* ---- reduced motion ---- */

@media (prefers-reduced-motion: reduce) {
  .fox-body,
  .fox-tail,
  .fox-head,
  .fox-question,
  .fox-zzz text,
  .fox-sparkle-a,
  .fox-sparkle-b,
  .pixel-fox.is-hopping .fox-rig,
  .pixel-fox.is-waking .fox-rig,
  .pixel-fox.is-about.is-looking .fox-glasses {
    animation: none !important;
  }

  .fox-rig,
  .fox-head,
  .fox-eyes rect,
  .fox-ear-left,
  .fox-ear-right,
  .fox-tail,
  .fox-message,
  .fox-accessory,
  .fox-glasses,
  .fox-fluff circle {
    transition-duration: 0.01ms !important;
  }
}


/* ---- mobile ---- */

@media (max-width: 760px) {
  .pixel-fox {
    right: 14px;
    /* max() keeps it clear of a phone's home-indicator gesture strip
       (env(safe-area-inset-bottom)) — without this, a tap here can
       get swallowed by the OS's own swipe-up gesture instead of
       ever reaching the page. */
    bottom: max(14px, env(safe-area-inset-bottom, 0px) + 8px);

    --fox-width: 42px;
    --fox-height: 46px;
  }

  .fox-message {
    max-width: 130px;
    font-size: 12px;
  }

  .fox-message.is-thought {
    max-width: 105px;
    font-size: 11px;
  }
}


/* ========================================
   AMBIENT MUSIC BUTTON (all pages)

   Built by audio.js — nothing hand-written into any page for it,
   same pattern as the fox and cursor. Two different layouts for two
   breakpoints, same <button> element throughout (audio.js never
   creates or moves it in the DOM based on screen size — this is CSS
   only, via the max-width query below):

   - Desktop: lives inside the top <header class="nav ...">, not a
     fixed corner — a plain icon sitting on the same row as the nav
     links, right after the last one (Contact, on the homepage), with
     the hamburger toggle immediately after it in turn on index.html.
     See ".nav nav" further up for how that row stays grouped flush
     right. No circle, no border, no fill — the note icon sits at the
     same visual weight as the plain-text links beside it.
   - Mobile: reverts to its own fixed bottom-left circle (Elvira's
     original placement, kept unchanged rather than following the nav
     — she asked for the desktop nav-icon treatment without carrying
     it over to mobile), independent of the header entirely.

   While playing, it "breathes" on both breakpoints — the same slow-
   pulse language as the hero's entrance and the scroll reveals
   elsewhere on the site — rather than an equalizer or spinner, so the
   active state reads as calm rather than busy. The two breakpoints
   use different keyframes (scale+opacity on desktop, since there's no
   background to glow against; scale+box-shadow ring on mobile, where
   the circle gives it something to glow against) — see
   music-toggle-breathe vs. music-toggle-breathe-fixed below.
======================================== */

.music-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;

  margin-left: 24px;
  padding: 2px;

  background: none;
  border: none;

  color: var(--ink);
  cursor: pointer;

  /* Same reasoning as .pixel-fox: skips the ~300ms tap-ambiguity
     delay some mobile browsers otherwise apply, and removes the
     grey tap-highlight flash. */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;

  transition:
    color 0.35s ease,
    transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.music-toggle:hover,
.music-toggle:focus-visible {
  color: var(--accent);
}

.music-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
  border-radius: 3px;
}

.music-toggle:active {
  transform: scale(0.92);
}

.music-toggle-icon {
  width: 17px;
  height: 17px;
}

/* Playing state — quiet breathing pulse, not an equalizer. */

.music-toggle.is-playing {
  color: var(--accent);
  animation: music-toggle-breathe 3.6s ease-in-out infinite;
}

@keyframes music-toggle-breathe {
  0%, 100% {
    transform: scale(1);
    opacity: 0.82;
  }
  50% {
    transform: scale(1.14);
    opacity: 1;
  }
}

/* ---- mobile: back to the original fixed bottom-left circle ---- */

@media (max-width: 760px) {
  .music-toggle {
    position: fixed;
    left: 14px;
    bottom: max(14px, env(safe-area-inset-bottom, 0px) + 8px);
    z-index: 20;

    margin: 0;

    width: 42px;
    height: 42px;
    padding: 0;

    background: rgba(255, 250, 243, 0.72);
    border: 1px solid var(--line);
    border-radius: 50%;

    color: var(--muted);

    backdrop-filter: blur(6px);

    transition:
      color 0.4s ease,
      border-color 0.4s ease,
      background-color 0.4s ease,
      transform 0.4s cubic-bezier(0.22, 1, 0.36, 1),
      box-shadow 0.6s ease;
  }

  .music-toggle:hover,
  .music-toggle:focus-visible {
    color: var(--accent);
    border-color: rgba(155, 95, 68, 0.4);
    transform: scale(1.06);
  }

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

  .music-toggle:active {
    transform: scale(0.96);
  }

  .music-toggle-icon {
    width: 16px;
    height: 16px;
  }

  .music-toggle.is-playing {
    color: var(--accent);
    border-color: rgba(155, 95, 68, 0.45);
    background: rgba(255, 250, 243, 0.85);

    animation: music-toggle-breathe-fixed 4.2s ease-in-out infinite;
  }
}

@keyframes music-toggle-breathe-fixed {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(185, 119, 106, 0.28);
  }
  50% {
    transform: scale(1.045);
    box-shadow: 0 0 0 7px rgba(185, 119, 106, 0);
  }
}

/* Placed after the max-width query above (not merged into it) so
   that reduced-motion always wins on top of it when both apply —
   otherwise a mobile device with reduced motion enabled would have
   the box-shadow-ring animation re-enabled by the later, equally-
   specific mobile rule. */
@media (prefers-reduced-motion: reduce) {
  .music-toggle {
    transition-duration: 0.01ms;
  }

  .music-toggle.is-playing {
    animation: none;
  }
}
