/* ===========================================================================
   UNWIND GALLERY — static stylesheet
   Ported from the approved React build (app/globals.css). Class names, layout
   measurements, breakpoints, sticky offsets, keyframes and timings are
   unchanged; only the framework couplings were removed.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   1. Base reset
   The React build imported Tailwind solely for its Preflight reset — no utility
   class was ever used in the markup. Preflight was therefore load-bearing: the
   rest of this stylesheet has no element-level margin reset for headings, p,
   dl, dd or figure, and no border reset for buttons. The block below reproduces
   the parts this design actually relies on, so the file is self-contained.
   --------------------------------------------------------------------------- */

*,
*::before,
*::after {
  border: 0 solid;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: inherit;
}

blockquote,
dd,
dl,
figure,
h1,
h2,
h3,
h4,
h5,
h6,
p,
pre {
  margin: 0;
}

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

button,
input,
optgroup,
select,
textarea {
  margin: 0;
  padding: 0;
  color: inherit;
  border-radius: 0;
  background-color: transparent;
  font: inherit;
  letter-spacing: inherit;
}

button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
  appearance: button;
  background-image: none;
}

::placeholder {
  opacity: 1;
}

textarea {
  resize: vertical;
}

img,
svg,
video,
canvas {
  display: block;
  vertical-align: middle;
}

img,
video {
  max-width: 100%;
  height: auto;
}

/* Author-level [hidden] so it beats component display rules. Without this,
   `.archive-item { display: block }` and `.archive-modal { display: grid }`
   would each override the attribute and render hidden content — keeping it
   visible and, worse, keyboard-focusable. */
[hidden] {
  display: none !important;
}

/* ---------------------------------------------------------------------------
   1b. Brand faces
   Centaur MT ships in the client's brand kit (02_FONTS) and is the face the
   identity was drawn for; V1 fell back to Baskerville on machines without it.
   Bundled here so every visitor sees the same serif. The kit carries no
   Centaur italic, so italics render as a synthesized slant — consistent
   everywhere, and closer to the identity than dropping to another family.
   Confirm the webfont licence covers embedding before production deploy.
   --------------------------------------------------------------------------- */

@font-face {
  font-family: "Centaur MT";
  src: url("../fonts/centaur-mt-regular.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Centaur MT";
  src: url("../fonts/centaur-mt-bold.otf") format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Small caps with oldstyle figures — used for the large standalone numerals
   (1931, exhibition numbers, the concept dates), where non-lining digits sit
   more naturally in the editorial setting. */
@font-face {
  font-family: "Centaur MT SC";
  src: url("../fonts/centaur-mt-sc-osf.otf") format("opentype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* ---------------------------------------------------------------------------
   2. Design tokens
   --------------------------------------------------------------------------- */

:root {
  --paper: #fcfbf6;
  --paper-deep: #f1eee5;
  --blush: #f3e3de;
  --wine: #570b0f;
  /* Dark grounds stay inside the brand wine range #2B0D09–#3C100D — never
     black (client direction, 2026-08). */
  --wine-dark: #2b0d09;
  --room: #3c100d;
  --deep: #2b0d09;
  --brass: #9e6d25;
  --brass-lit: #c1974e; /* brand gold, lifted for small text on wine grounds */
  --almond: #f2b8b0;
  --almond-deep: #dd9f9f;
  --ink: #32140f;
  --paper-dim: rgba(252, 251, 246, 0.78);
  --ink-dim: rgba(50, 20, 15, 0.66);
  --line: rgba(87, 11, 15, 0.23);
  --line-dark: rgba(158, 109, 37, 0.32);
  --serif: "Centaur MT", "Baskerville", "Iowan Old Style", "Times New Roman",
    serif;
  --serif-sc: "Centaur MT SC", "Centaur MT", "Baskerville", "Iowan Old Style",
    "Times New Roman", serif;
  --mincho: "Hiragino Mincho ProN", "Hiragino Mincho Pro", "Yu Mincho",
    "YuMincho", "Noto Serif JP", serif;
  --grotesk: "Berthold Akzidenz Grotesk", "Akzidenz-Grotesk",
    "Helvetica Neue", Arial, sans-serif;
  --page: min(92vw, 1540px);
  /* The spine rail (V3): its width participates in the desktop page maths;
     below 1101px it collapses to zero and the rail is hidden. */
  --rail-w: 76px;
  --gutter: clamp(24px, 6vw, 110px);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* On desktop the spine is lateral, so only a breathing offset; below
     1100px the fixed topbar owns the top of the viewport (V3). */
  scroll-padding-top: 24px;
  background: var(--paper);
  /* The entrance, the mobile menu and the modal all lock scrolling with
     overflow:hidden. Without a reserved gutter the scrollbar disappears with
     the lock and the whole page jumps sideways as it returns — most visibly
     when the entrance hands over to the hero. Reserving it means the layout
     never changes width. */
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  color: var(--ink);
  background: var(--paper);
  font-family: var(--mincho);
  font-size: 16px;
  line-height: 1.8;
  -webkit-font-smoothing: antialiased;
  /* The ground crossfades between rooms and leaves as the visitor moves;
     main.js writes the current section's theme to <html data-theme>. */
  transition: background-color 1s ease;
}

html[data-theme="night"] body,
html[data-theme="deep"] body {
  background: var(--deep);
}

html[data-theme="room"] body {
  background: var(--room);
}

html[data-theme="blush"] body {
  background: var(--blush);
}

html[data-theme="paper"] body {
  background: var(--paper);
}

/* Locked on <html>, not <body>: overflow on the body propagates up to the
   viewport, which discards the reserved scrollbar gutter and reintroduces the
   sideways jump the gutter exists to prevent. */
html.modal-open,
html.intro-open,
html.menu-open {
  overflow: hidden;
}

button,
input,
textarea {
  font: inherit;
}

button,
a {
  -webkit-tap-highlight-color: transparent;
}

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

img {
  display: block;
  width: 100%;
}

button {
  color: inherit;
}

::selection {
  color: var(--paper);
  background: var(--wine);
}

:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 5px;
}

.skip-link {
  position: fixed;
  z-index: 1200;
  top: 12px;
  left: 12px;
  padding: 13px 20px;
  color: var(--paper);
  background: var(--wine);
  font-family: var(--grotesk);
  font-size: 10px;
  letter-spacing: 0.14em;
  transform: translateY(-180%);
  transition: transform 0.3s var(--ease);
}

.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
}

/* ---------------------------------------------------------------------------
   Reveal motion
   The default state is fully visible so the page is complete and readable with
   JavaScript unavailable or blocked. The hidden start state is applied only
   under `.js`, which main.js (and the inline bootstrap in index.html) sets on
   <html> before first paint.
   --------------------------------------------------------------------------- */

[data-reveal] {
  transition:
    opacity 1s var(--ease),
    transform 1s var(--ease),
    clip-path 1.15s var(--ease);
}

.js [data-reveal] {
  opacity: 0;
  transform: translateY(28px);
}

.js [data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}





.jp-display {
  word-break: auto-phrase;
  text-wrap: balance;
}

.heading-line {
  display: block;
  white-space: nowrap;
}

.section-shell {
  width: var(--page);
  margin-inline: auto;
}

/* ---------------------------------------------------------------------------
   The topbar (V3)
   Transparent always; the ink flips with the room colour. On desktop it
   keeps only the MENU control at the right — the rail carries the brand.
   --------------------------------------------------------------------------- */

.topbar {
  position: fixed;
  z-index: 950;
  top: 0;
  right: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 64px;
  padding: 0 clamp(20px, 3vw, 40px);
  pointer-events: none;
  color: var(--paper);
  transition: color 0.5s ease;
}

.topbar-mark,
.menu-button {
  pointer-events: auto;
}

.topbar-mark img {
  display: block;
  width: auto;
  height: 32px;
  filter: brightness(0) invert(1);
  transition: filter 0.5s ease;
}

.menu-button {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 0;
  cursor: pointer;
  font-family: var(--grotesk);
  font-size: 10px;
  letter-spacing: 0.22em;
}

.menu-button i {
  display: block;
  width: 26px;
  height: 1px;
  background: currentColor;
  box-shadow: 0 5px currentColor;
  transition:
    transform 0.35s var(--ease),
    box-shadow 0.35s ease;
}

.menu-open .menu-button i {
  transform: translateY(3px) rotate(45deg);
  box-shadow: 0 0 currentColor;
}

/* Light leaves flip the chrome to ink. */
html[data-theme="paper"] .topbar,
html[data-theme="blush"] .topbar {
  color: var(--ink);
}

html[data-theme="paper"] .topbar-mark img,
html[data-theme="blush"] .topbar-mark img {
  filter: none;
}

/* Without JavaScript the veil below is a plain list, so its trigger is
   pointless chrome. */
html:not(.js) .menu-button {
  display: none;
}

/* ---------------------------------------------------------------------------
   The spine (V3) — desktop only
   A fixed catalogue edge on the left: the mark as a home link, the vertical
   word, plate index 01–07 with the current plate marked, and a brass thread
   drawing in with scroll progress.
   --------------------------------------------------------------------------- */

.rail {
  position: fixed;
  z-index: 940;
  top: 0;
  bottom: 0;
  left: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: var(--rail-w);
  padding: 26px 0 30px;
  color: var(--paper-dim);
  border-right: 1px solid var(--line-dark);
  transition: color 0.5s ease, border-color 0.5s ease;
}

.rail-mark {
  display: block;
  width: 30px;
}

.rail-mark img {
  filter: brightness(0) invert(1);
  opacity: 0.9;
  transition: filter 0.5s ease;
}

/* The spine wordmark carries the hero's face (client direction, 2026-08):
   Centaur MT, not the grotesk. Centaur's small x-height needs a couple of
   pixels more and a little less tracking to hold the same optical weight
   running vertically. */
.rail-word {
  display: flex;
  flex: 1;
  align-items: center;
  margin: 26px 0;
  font-family: var(--serif);
  font-size: 12px;
  letter-spacing: 0.34em;
  writing-mode: vertical-rl;
  opacity: 0.72;
}

.rail-index {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.rail-index a {
  position: relative;
  display: grid;
  min-width: 44px;
  min-height: 38px;
  place-items: center;
  font-family: var(--serif-sc);
  font-size: 13px;
  letter-spacing: 0.08em;
  opacity: 0.55;
  transition:
    opacity 0.3s ease,
    color 0.3s ease;
}

.rail-index a:hover {
  opacity: 1;
}

.rail-index a[aria-current] {
  color: var(--brass-lit);
  opacity: 1;
}

.rail-index a[aria-current]::before {
  position: absolute;
  top: 50%;
  left: 4px;
  width: 10px;
  height: 1px;
  content: "";
  background: currentColor;
}

/* Section name surfaces on hover/focus, reading from the aria-label. */
.rail-index a::after {
  position: absolute;
  top: 50%;
  left: calc(100% + 2px);
  padding: 8px 12px;
  content: attr(aria-label);
  white-space: nowrap;
  pointer-events: none;
  color: var(--paper);
  opacity: 0;
  transform: translate(-6px, -50%);
  background: var(--deep);
  border: 1px solid var(--line-dark);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.16em;
  transition:
    opacity 0.25s ease,
    transform 0.3s var(--ease);
}

.rail-index a:hover::after,
.rail-index a:focus-visible::after {
  opacity: 1;
  transform: translate(0, -50%);
}

.rail-thread {
  position: absolute;
  top: 0;
  right: -1px;
  bottom: 0;
  width: 1px;
  overflow: hidden;
}

.rail-thread i {
  display: block;
  width: 100%;
  height: 100%;
  transform: scaleY(0);
  transform-origin: top;
  background: var(--brass);
}

/* Light leaves flip the rail to ink. */
html[data-theme="paper"] .rail,
html[data-theme="blush"] .rail {
  color: var(--ink-dim);
  border-right-color: var(--line);
}

html[data-theme="paper"] .rail-mark img,
html[data-theme="blush"] .rail-mark img {
  filter: none;
}

html[data-theme="paper"] .rail-index a[aria-current],
html[data-theme="blush"] .rail-index a[aria-current] {
  color: var(--wine);
}

/* Desktop: the rail is the identity; the topbar keeps only MENU, right.
   The page column re-centres between symmetric gutters at least as deep as
   the rail. */
@media (min-width: 1101px) {
  :root {
    --page: min(100vw - 2 * (var(--rail-w) + 26px), 1540px);
  }

  .topbar {
    justify-content: flex-end;
  }

  .topbar-mark {
    display: none;
  }

  .colophon {
    padding-inline: max(4vw, calc(var(--rail-w) + 26px));
  }
}

@media (max-width: 1100px) {
  :root {
    --rail-w: 0px;
  }

  .rail {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
   The veil (from V3) — the mobile menu
   Without JavaScript it is a plain list under the header; with it, a full
   overlay whose closed state is removed from the tab order. Desktop keeps
   the inline header nav, so past the mobile breakpoint the veil is gone.
   --------------------------------------------------------------------------- */

.veil {
  padding: 76px clamp(20px, 3vw, 40px) 12px;
  font-family: var(--grotesk);
}

.veil-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

html:not(.js) .veil-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
}

html:not(.js) .veil-list a {
  display: inline-flex;
  gap: 6px;
  font-size: 10px;
  letter-spacing: 0.14em;
}

html:not(.js) .veil-list small {
  display: none;
}

.js .veil {
  position: fixed;
  z-index: 1100;
  inset: 0;
  display: flex;
  flex-direction: column;
  /* flex-start + auto margins on the list: centred when there is room,
     scrollable from the top if anything ever outgrows the viewport
     (justify-content: center would clip the first items unreachably). */
  justify-content: flex-start;
  /* V3's 96/48 frame, giving way on short viewports so the whole index
     always fits one screen — no scrolling to reach ACCESS. */
  padding: min(96px, 11.5vh) var(--gutter) min(48px, 5.8vh);
  overflow-y: auto;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  background: rgba(43, 13, 9, 0.97);
  transition:
    opacity 0.45s ease,
    visibility 0s 0.45s;
}

.js .veil--open {
  pointer-events: auto;
  visibility: visible;
  opacity: 1;
  transition:
    opacity 0.45s ease,
    visibility 0s;
}

.js .veil-list {
  width: min(760px, 100%);
  margin-block: auto;
}

.js .veil-list li {
  border-bottom: 1px solid var(--line-dark);
}

.js .veil-list li:first-child {
  border-top: 1px solid var(--line-dark);
}

/* V3's single row: numeral, name, JP at the right baseline. */
.js .veil-list a {
  position: relative;
  display: grid;
  grid-template-columns: 64px 1fr auto;
  align-items: baseline;
  padding: clamp(10px, 2.2vh, 26px) 0;
  color: var(--paper);
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity 0.55s var(--ease),
    transform 0.55s var(--ease),
    color 0.3s ease,
    padding-left 0.4s var(--ease);
}

.js .veil--open .veil-list a {
  opacity: 1;
  transform: translateY(0);
}

.js .veil--open .veil-list li:nth-child(1) a { transition-delay: 0.06s; }
.js .veil--open .veil-list li:nth-child(2) a { transition-delay: 0.1s; }
.js .veil--open .veil-list li:nth-child(3) a { transition-delay: 0.14s; }
.js .veil--open .veil-list li:nth-child(4) a { transition-delay: 0.18s; }
.js .veil--open .veil-list li:nth-child(5) a { transition-delay: 0.22s; }
.js .veil--open .veil-list li:nth-child(6) a { transition-delay: 0.26s; }
.js .veil--open .veil-list li:nth-child(7) a { transition-delay: 0.3s; }

.js .veil-list a:hover,
.js .veil-list a[aria-current] {
  padding-left: 14px;
  color: var(--brass-lit);
}

.veil-list i {
  font-family: var(--serif-sc);
  font-size: 15px;
  font-style: normal;
  color: var(--brass-lit);
}

.veil-list span {
  font-family: var(--serif);
  /* V3's 5.6vh scale, width-guarded so the longest name + its JP label
     always share one row on narrow phones. */
  font-size: clamp(28px, min(5.6vh, 8.4vw), 62px);
  letter-spacing: 0.01em;
  line-height: 1;
}

.veil-list small {
  font-family: var(--mincho);
  font-size: 10px;
  letter-spacing: 0.12em;
  opacity: 0.6;
}

.veil-language {
  margin-top: 5vh;
  padding: 10px 0;
  cursor: help;
  align-self: flex-start;
  color: var(--paper-dim);
  font-size: 10px;
  letter-spacing: 0.18em;
}

.js .veil-language {
  opacity: 0;
  transition: opacity 0.5s 0.34s ease;
}

.js .veil--open .veil-language {
  opacity: 1;
}

.veil-language span {
  opacity: 0.5;
}

/* The hero sits inside the rail's margin, exactly as V3's main column does:
   on desktop the photography starts at the rail's edge and the rail rests on
   the wine ground beside it. */
.hero {
  position: relative;
  overflow: hidden;
  min-height: 100vh;
  min-height: 100svh;
  margin-left: var(--rail-w);
  color: var(--paper);
  background: var(--wine-dark);
}

/* Film grain over the whole catalogue — one static texture, never animated
   (the V3 material feel; replaces V1/V2's hero-only grain). */
body::after {
  position: fixed;
  z-index: 2000;
  inset: 0;
  pointer-events: none;
  content: "";
  opacity: 0.09;
  background:
    repeating-radial-gradient(
      circle at 20% 30%,
      rgba(252, 251, 246, 0.28) 0 0.35px,
      transparent 0.7px 3px
    );
  mix-blend-mode: soft-light;
}

.hero-media,
.hero-slide,
.hero-wash {
  position: absolute;
  inset: 0;
}

/* The slow zoom runs only while a slide is the active one, and always from
   the same starting scale. The resting rule snaps the transform back with a
   delay equal to the cross-fade, so the reset happens after the slide has
   already faded out — invisible, and independent of how many slides exist
   (an earlier version transitioned back over 8s, which left short carousels
   starting their zoom part-way through). */
.hero-slide {
  margin: 0;
  opacity: 0;
  transform: scale(1.05);
  transition:
    opacity 1.6s ease,
    transform 0s linear 1.6s;
}

/* Without JavaScript nothing ever gets `is-active`, so the first slide stands
   in as a plain static hero image. */
.hero-slide:first-child {
  opacity: 1;
  transform: scale(1);
}

.js .hero-slide:first-child {
  opacity: 0;
  transform: scale(1.05);
}

/* 9s of travel against a 5s slide, so the movement is still underway when
   the next plate takes over — the zoom must never reach its end and sit
   still while the visitor is looking at it. */
.js .hero-slide.is-active,
.hero-slide.is-active {
  opacity: 1;
  transform: scale(1);
  transition:
    opacity 1.6s ease,
    transform 9s ease-out;
}

.hero-slide img {
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.hero-wash {
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(43, 13, 9, 0.55) 0%, rgba(43, 13, 9, 0.08) 32%),
    linear-gradient(0deg, rgba(43, 13, 9, 0.62) 0%, transparent 46%),
    radial-gradient(130% 100% at 72% 38%, transparent 55%, rgba(43, 13, 9, 0.42) 100%);
}

/* V3's composition: the wordmark stacks huge upper-left, each line rising
   out of its own mask. */
.hero-title {
  position: absolute;
  z-index: 3;
  top: clamp(88px, 15vh, 170px);
  left: var(--gutter);
  right: var(--gutter);
}

.hero-eyebrow {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 0 0 30px;
  font-family: var(--grotesk);
  font-size: 10px;
  letter-spacing: 0.3em;
  color: var(--brass-lit);
}

.hero-eyebrow i {
  display: block;
  width: 52px;
  height: 1px;
  background: currentColor;
}

.hero-word {
  margin: 0;
  font-family: var(--serif);
  font-size: clamp(78px, 12.5vw, 220px);
  font-weight: 400;
  line-height: 0.84;
  letter-spacing: -0.04em;
}

.hero-word .line--italic {
  padding-left: 0.55em;
}

.hero-word .line--italic > span {
  font-style: italic;
}

/* Cover-first choreography: the hero's own reveals wait for the lift. */
.intro-visible .hero .line > span {
  transition-delay: 2.5s;
}

.intro-visible .hero .line:nth-child(2) > span {
  transition-delay: 2.6s;
}

.intro-visible .hero-eyebrow,
.intro-visible .hero-foot {
  transition-delay: 2.7s;
}

.js .hero-eyebrow,
.js .hero-foot {
  opacity: 0;
  transition: opacity 1.1s ease;
}

.js .is-visible .hero-eyebrow,
.js .hero.is-visible .hero-foot {
  opacity: 1;
}

/* V3's foot: one bottom row — the scroll thread where V3's plate index sat
   (the numerals stay deleted, per direction), the thesis at the right. */
.hero-foot {
  position: absolute;
  z-index: 3;
  right: var(--gutter);
  bottom: 0;
  left: var(--gutter);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 30px;
  padding-bottom: 42px;
}

.hero-thesis {
  max-width: 400px;
  text-align: left;
}

.hero-jp {
  margin: 0;
  font-size: clamp(13px, 1.15vw, 16px);
  line-height: 2.1;
  letter-spacing: 0.09em;
  word-break: auto-phrase;
  text-wrap: pretty;
}

/* V3's underline link. Colour and arrow respond on hover; the control itself
   stays put (no magnetic drift — client direction). */
.hero-exhibition-link {
  display: inline-flex;
  align-items: baseline;
  gap: 14px;
  margin-top: 22px;
  padding: 12px 2px;
  border-bottom: 1px solid rgba(252, 251, 246, 0.5);
  font-family: var(--grotesk);
  font-size: 10px;
  letter-spacing: 0.2em;
  transition: color 0.3s ease, border-color 0.3s ease;
}

.hero-exhibition-link small {
  margin-left: 10px;
  font-family: var(--mincho);
  font-size: 10px;
  letter-spacing: 0.1em;
  opacity: 0.75;
}

.hero-exhibition-link i {
  display: inline-block;
  font-size: 15px;
  font-style: normal;
}

.hero-exhibition-link:hover,
.hero-exhibition-link:focus-visible {
  color: var(--brass-lit);
  border-color: currentColor;
}

/* SCROLL TO ENTER (V3): a thread of light running down a hairline. */
.scroll-cue {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  color: var(--paper-dim);
  font-family: var(--grotesk);
  font-size: 8px;
  letter-spacing: 0.3em;
}

.scroll-cue i {
  position: relative;
  display: block;
  overflow: hidden;
  width: 1px;
  height: 64px;
  background: rgba(252, 251, 246, 0.28);
}

.scroll-cue i::after {
  position: absolute;
  inset: 0;
  content: "";
  transform: translateY(-100%);
  background: var(--brass-lit);
  animation: cue 2.4s infinite ease-in-out;
}

@keyframes cue {
  0% {
    transform: translateY(-100%);
  }
  70%,
  100% {
    transform: translateY(100%);
  }
}

/* Active state is carried by fill *and* size, never colour alone. */

.modal-controls button {
  display: grid;
  width: 34px;
  height: 34px;
  padding: 0;
  cursor: pointer;
  color: inherit;
  border: 1px solid currentColor;
  border-radius: 50%;
  background: transparent;
  place-items: center;
  transition:
    color 0.25s ease,
    background 0.25s ease;
}

.concept {
  padding: 140px 0 220px;
}

.concept-intro {
  display: grid;
  grid-template-columns: 35% 65%;
  margin: 150px 0 80px;
}

.concept-kicker {
  margin: 24px 0 0;
  color: var(--brass);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.21em;
}

.concept-intro h2,
.experience-heading h2,
.archive-heading h2 {
  margin: 0;
  color: var(--wine);
  font-size: clamp(48px, 6.2vw, 104px);
  font-weight: 400;
  line-height: 1.42;
  letter-spacing: 0.02em;
}

/* Gilt emphasis — one voice for <em> in JP display type (from V3). */
.concept-intro h2 em,
.experience-heading h2 em,
.archive-heading h2 em {
  font-style: normal;
  border-bottom: 2px solid var(--brass);
  padding-bottom: 0.06em;
}

.concept-grid {
  position: relative;
  display: grid;
  grid-template-columns: 18% 42% 1fr;
  align-items: start;
  gap: 6%;
}

.concept-year {
  display: flex;
  flex-direction: column;
  margin-top: 70px;
  color: var(--wine);
  font-family: var(--serif-sc);
  font-size: clamp(92px, 13vw, 198px);
  font-weight: 400;
  line-height: 0.55;
  letter-spacing: -0.09em;
}

.concept-year span:last-child {
  margin-left: 0.3em;
  color: var(--brass);
  font-style: italic;
}

.concept-copy {
  padding-top: 28%;
}

.jp-lead {
  margin: 0 0 56px;
  color: var(--wine);
  font-size: clamp(19px, 1.7vw, 27px);
  line-height: 2.05;
  letter-spacing: 0.06em;
}

.concept-copy > p:not(.jp-lead) {
  max-width: 470px;
  margin: 0;
  font-size: 14px;
  line-height: 2.2;
  letter-spacing: 0.045em;
}

.concept-copy dl {
  margin: 68px 0 0;
}

.concept-copy dl div {
  display: grid;
  grid-template-columns: 80px 1fr;
  align-items: baseline;
  padding: 13px 0;
  border-top: 1px solid var(--line);
}

.concept-copy dt {
  color: var(--brass);
  font-family: var(--serif-sc);
  font-size: 25px;
}

.concept-copy dd {
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.07em;
}

/* The experience plates live in the dark room, as in V1/V2 — V3's weight
   with V2's sticky cards. */
.experience {
  overflow: clip;
  padding: 150px 0 0;
  color: var(--paper);
}

html:not(.js) .experience {
  background: var(--wine-dark);
}

.experience-heading {
  display: grid;
  grid-template-columns: 26% 1fr;
  margin: 140px 0 120px;
}

.experience-heading > p {
  margin: 30px 0 0;
  color: var(--brass-lit);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.2em;
}

.experience-heading h2 {
  color: var(--paper);
}

.experience-heading h2 em {
  border-bottom-color: var(--brass-lit);
}

.experience-stack {
  width: var(--page);
  margin: 0 auto;
  padding-bottom: 170px;
}

/* The three ways as cinematic plates: photography edge to edge, the reading
   column set into a wine scrim, a gilt hairline frame inset like the menu
   card, and the plate numeral anchoring the copy. As the next plate arrives,
   the one beneath recedes — scaled, tilted and veiled through --stack,
   written per frame by the scroll engine (0 = on top, 1 = fully covered). */
.experience-card {
  position: sticky;
  height: min(620px, calc(100svh - 140px));
  margin-bottom: 14vh;
  overflow: hidden;
  background: var(--deep);
  box-shadow: 0 34px 90px rgba(22, 5, 4, 0.4);
  transform: scale(calc(1 - 0.055 * var(--stack, 0)))
    rotate(calc(var(--tilt, 0deg) * var(--stack, 0)));
  transform-origin: 50% 14%;
  will-change: transform;
}

.experience-card:nth-child(1) {
  z-index: 1;
  top: 96px;
  --tilt: -1.5deg;
}

.experience-card:nth-child(2) {
  z-index: 2;
  top: 106px;
  --tilt: 1.8deg;
}

.experience-card:nth-child(3) {
  z-index: 3;
  top: 116px;
  margin-bottom: 0;
}

/* The veil that settles over a receding plate. */
.experience-card::before {
  position: absolute;
  z-index: 4;
  inset: 0;
  pointer-events: none;
  content: "";
  background: var(--deep);
  opacity: calc(0.55 * var(--stack, 0));
}

/* Gilt hairline, inset like the engraved menu frame. */
.experience-card::after {
  position: absolute;
  z-index: 3;
  inset: 14px;
  pointer-events: none;
  content: "";
  border: 1px solid rgba(158, 109, 37, 0.35);
}

.experience-card figure {
  position: absolute;
  inset: 0;
  margin: 0;
}

.experience-card figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The reading side's wine scrim. Odd plates read on the right, even on the
   left; the gradient follows. */
.experience-card figure::after {
  position: absolute;
  inset: 0;
  content: "";
  background: linear-gradient(
    270deg,
    rgba(43, 13, 9, 0.97) 0%,
    rgba(43, 13, 9, 0.88) 40%,
    rgba(43, 13, 9, 0.42) 64%,
    transparent 85%
  );
}

.experience-card:nth-child(even) figure::after {
  background: linear-gradient(
    90deg,
    rgba(43, 13, 9, 0.97) 0%,
    rgba(43, 13, 9, 0.88) 40%,
    rgba(43, 13, 9, 0.42) 64%,
    transparent 85%
  );
}

.experience-card__copy {
  position: absolute;
  z-index: 2;
  inset-block: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  width: min(46%, 560px);
  padding: clamp(36px, 4.5vw, 76px);
  color: var(--paper);
}

.experience-card:nth-child(even) .experience-card__copy {
  right: auto;
  left: 0;
}

/* The plate numeral — oldstyle figures, gilt, quiet. */
.experience-card__no {
  display: block;
  margin-bottom: 14px;
  color: var(--brass-lit);
  opacity: 0.6;
  font-family: var(--serif-sc);
  font-size: clamp(60px, 5.6vw, 96px);
  line-height: 0.8;
  letter-spacing: 0.02em;
}

.experience-card__copy > p:first-of-type {
  margin: 0;
  color: var(--brass-lit);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.2em;
}

.experience-card__copy h3 {
  margin: 22px 0 26px;
  font-size: clamp(28px, 2.8vw, 46px);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0.035em;
}

.body-copy {
  max-width: 390px;
  margin: 0;
  font-size: 12px;
  line-height: 2.05;
  letter-spacing: 0.05em;
}

.experience-card .body-copy {
  max-width: 26em;
  color: rgba(252, 251, 246, 0.86);
  font-size: 13px;
  line-height: 2.1;
}


.current {
  position: relative;
  overflow: clip;
  padding: 155px 0 200px;
  color: var(--paper);
}

html:not(.js) .current {
  background: var(--room);
}

.current-layout {
  display: grid;
  grid-template-columns: minmax(250px, 0.72fr) minmax(0, 1.75fr);
  align-items: start;
  gap: clamp(60px, 8vw, 140px);
  margin-top: 120px;
}

.current-index {
  position: sticky;
  top: 108px;
  align-self: start;
}

.exhibition-number {
  margin: 0 0 38px;
  color: var(--brass-lit);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.2em;
}

.current-index h2 {
  margin: 0;
  color: var(--paper);
  font-family: var(--serif);
  font-size: clamp(60px, 7.2vw, 128px);
  font-weight: 400;
  line-height: 0.82;
  letter-spacing: -0.045em;
}

.current-index h2 .line--italic {
  padding-left: 0.4em;
}

.current-index h2 .line--italic > span {
  font-style: italic;
}

.current-index h2 em {
  color: var(--almond);
  font-weight: 400;
}

.current-index-jp {
  margin: 34px 0 42px;
  color: var(--brass-lit);
  font-size: 11px;
  letter-spacing: 0.08em;
}

.current-index dl {
  margin: 0;
}

.current-index dl div {
  display: grid;
  grid-template-columns: 92px 1fr;
  padding: 11px 0;
  border-top: 1px solid var(--line-dark);
}

.current-index dt,
.current-index dd {
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.12em;
}

.current-index dd {
  margin: 0;
}

.current-index .text-link {
  margin-top: 38px;
}

.current-scroll {
  min-width: 0;
}

.current-lead-image {
  position: relative;
  margin: 0;
  overflow: hidden;
  background: var(--deep);
}

.current-lead-image {
  aspect-ratio: 1.38;
}

.current-lead-image img {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: scale(1.025);
  transition:
    opacity 0.8s ease,
    transform 1.2s var(--ease);
}

.current-lead-image img.is-active {
  z-index: 1;
  opacity: 1;
  transform: scale(1);
}

.current-lead-image img {
  height: 100%;
  object-fit: cover;
}

.current-lead-image figcaption {
  position: absolute;
  z-index: 2;
  left: 14px;
  bottom: 12px;
  padding: 7px 9px;
  color: var(--paper);
  background: rgba(43, 13, 9, 0.76);
  font-family: var(--grotesk);
  font-size: 8px;
  letter-spacing: 0.14em;
}

.current-carousel-controls {
  position: absolute;
  z-index: 3;
  right: 14px;
  bottom: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 9px;
  color: var(--paper);
  background: rgba(43, 13, 9, 0.76);
  font-family: var(--grotesk);
  font-size: 8px;
  letter-spacing: 0.14em;
}

.current-carousel-controls button {
  display: grid;
  width: 23px;
  height: 23px;
  padding: 0;
  cursor: pointer;
  color: inherit;
  border: 1px solid rgba(252, 251, 246, 0.55);
  border-radius: 50%;
  background: transparent;
  place-items: center;
}

.current-story {
  display: grid;
  grid-template-columns: minmax(220px, 0.8fr) minmax(0, 1fr);
  gap: clamp(36px, 6vw, 90px);
  padding: 100px 0 120px;
  border-bottom: 1px solid var(--line-dark);
}

.current-quote {
  margin: 0;
  color: var(--paper);
  font-size: clamp(25px, 2.4vw, 38px);
  line-height: 1.75;
  letter-spacing: 0.06em;
}

.current-story > p:not(.current-quote) {
  max-width: 480px;
  margin: 0;
  color: rgba(252, 251, 246, 0.82);
  font-size: 13px;
  line-height: 2.3;
  letter-spacing: 0.05em;
}

.artist-profile {
  display: grid;
  grid-template-columns: minmax(210px, 0.72fr) minmax(0, 1fr);
  gap: clamp(36px, 5vw, 72px);
  align-items: center;
  padding-top: 100px;
  border-top: 1px solid var(--line-dark);
}

.artist-profile figure {
  aspect-ratio: 1.2;
  margin: 0;
  overflow: hidden;
  background: var(--deep);
}

.artist-profile figure img {
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.artist-profile__label {
  margin: 0 0 24px;
  color: var(--brass-lit);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.2em;
}

.artist-profile h3 {
  margin: 0 0 30px;
  color: var(--paper);
  font-family: var(--serif);
  font-size: clamp(40px, 5vw, 70px);
  font-weight: 400;
  line-height: 0.9;
  letter-spacing: -0.035em;
}

.artist-profile h3 small {
  display: block;
  margin-top: 16px;
  font-family: var(--mincho);
  font-size: 10px;
  letter-spacing: 0.12em;
}

.artist-profile div > p:last-child {
  max-width: 520px;
  margin: 0;
  color: rgba(252, 251, 246, 0.82);
  font-size: 13px;
  line-height: 2.25;
  letter-spacing: 0.045em;
}

.text-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: min(100%, 410px);
  margin-top: 55px;
  padding: 17px 0;
  color: var(--brass-lit);
  border-top: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.18em;
  transition:
    padding 0.3s var(--ease),
    color 0.3s ease,
    background 0.3s ease;
}

.text-link:hover {
  padding-inline: 14px;
  color: var(--wine-dark);
  background: var(--paper);
}

.text-link i {
  font-style: normal;
  font-size: 16px;
}

.pairing {
  padding: 135px 0 150px;
  color: var(--paper);
}

html:not(.js) .pairing {
  background: var(--room);
}

.pairing-layout {
  display: grid;
  grid-template-columns: minmax(340px, 0.82fr) minmax(0, 1.18fr);
  align-items: center;
  gap: clamp(60px, 7vw, 130px);
  margin-top: 105px;
}

.pairing-kicker {
  margin: 0 0 38px;
  color: var(--brass);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.2em;
}

.archive {
  position: relative;
  padding: 145px 0 190px;
}

html:not(.js) .archive {
  background: var(--blush);
  box-shadow: 0 0 0 100vmax var(--blush);
  clip-path: inset(0 -100vmax);
}

.archive-heading {
  display: grid;
  grid-template-columns: 75% 1fr;
  align-items: end;
  margin: 130px 0 120px;
}

.archive-heading h2 {
  font-size: clamp(48px, 5.9vw, 92px);
}

.archive-heading > p {
  margin: 0 0 17px;
  color: var(--brass);
  font-family: var(--grotesk);
  font-size: 9px;
  line-height: 1.8;
  letter-spacing: 0.17em;
}

/* Holds the grid and the decorative thread drawn behind it. */
.archive-flow {
  position: relative;
}

/* A single brass hairline tracing the chronology from one exhibition to the
   next. The geometry is measured and drawn by main.js, since it depends on
   where the cards actually land; this only describes how it looks. Purely
   decorative — it is hidden from assistive technology and simply absent when
   JavaScript is unavailable. */
.archive-thread {
  position: absolute;
  z-index: 0;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

.archive-thread path {
  fill: none;
  stroke: var(--brass);
  stroke-width: 1;
  stroke-linecap: round;
  opacity: 0.42;
}

.archive-thread circle {
  fill: var(--brass);
  opacity: 0.6;
}

/* Drawn in once, as the section is reached. */
.js .archive-thread.is-drawing path {
  transition: stroke-dashoffset 2.4s var(--ease);
}

.js .archive-thread.is-drawing circle {
  opacity: 0;
  transition: opacity 0.5s ease;
}

.js .archive-thread.is-drawn circle {
  opacity: 0.6;
}

.archive-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  align-items: start;
  gap: 100px 2.3vw;
}

.archive-item {
  display: block;
  padding: 0;
  cursor: pointer;
  text-align: left;
  border: 0;
  background: transparent;
}

.archive-item[data-reveal]:nth-child(even) {
  transition-delay: 0.1s;
}

.archive-item[data-reveal]:nth-child(3n) {
  transition-delay: 0.18s;
}

/* Placement is driven by position in the list, not by the card's modifier
   class. That guarantees the chronology always reads left, right, left, right
   however many entries exist, while the exact column and drop still vary so
   the grid keeps its editorial irregularity. Every card is the same size: an
   identical 4-column span sharing one image ratio.

   The cycle repeats every six cards. Odd positions sit left, even positions
   right, and the connecting thread is drawn between them by main.js. */
.archive-item {
  position: relative;
  z-index: 1;
}

.archive-item:nth-child(6n + 1) {
  grid-column: 1 / span 4;
}

.archive-item:nth-child(6n + 2) {
  grid-column: 8 / span 4;
  margin-top: 170px;
}

.archive-item:nth-child(6n + 3) {
  grid-column: 3 / span 4;
  margin-top: 40px;
}

.archive-item:nth-child(6n + 4) {
  grid-column: 9 / span 4;
  margin-top: 200px;
}

.archive-item:nth-child(6n + 5) {
  grid-column: 2 / span 4;
  margin-top: 80px;
}

.archive-item:nth-child(6n + 6) {
  grid-column: 8 / span 4;
  margin-top: 230px;
}

.archive-item figure {
  position: relative;
  overflow: hidden;
  margin: 0;
  background: rgba(252, 251, 246, 0.55);
}

.archive-item figure {
  aspect-ratio: 1.36;
}

.archive-item figure img {
  height: 100%;
  object-fit: cover;
  filter: saturate(0.78);
  transition:
    transform 0.8s var(--ease),
    filter 0.5s ease;
}

.archive-item:hover figure img,
.archive-item:focus-visible figure img {
  transform: scale(1.04);
  filter: saturate(1.05);
}

.archive-open {
  position: absolute;
  right: 0;
  bottom: 0;
  padding: 12px 16px;
  color: var(--paper);
  opacity: 0;
  transform: translateY(100%);
  background: var(--wine);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.14em;
  transition:
    opacity 0.35s ease,
    transform 0.35s var(--ease);
}

.archive-item:hover .archive-open,
.archive-item:focus-visible .archive-open {
  opacity: 1;
  transform: translateY(0);
}

/* Two rows rather than four columns. The cards are now a uniform four-column
   span, which left the old title column too narrow — Japanese titles were
   breaking into two- and three-character stacks. Giving the title its own full
   row keeps it on one line at every card width. */
.archive-item > .archive-meta {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: clamp(10px, 1.5vw, 22px);
  row-gap: 7px;
  padding: 20px 0 4px;
  border-top: 1px solid var(--line);
}

.archive-item > .archive-meta > p {
  grid-column: 1;
  grid-row: 1 / span 2;
}

.archive-item > .archive-meta > span {
  grid-column: 2;
  grid-row: 1;
}

.archive-item .archive-meta h3 {
  grid-column: 2 / span 2;
  grid-row: 2;
}

.archive-item > .archive-meta > small {
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
}

.archive-item > .archive-meta > p {
  margin: 0;
  color: rgba(87, 11, 15, 0.5);
  font-family: var(--serif-sc);
  font-size: 28px;
  letter-spacing: 0.02em;
  transition: color 0.3s ease;
}

.archive-item:hover > .archive-meta > p,
.archive-item:focus-visible > .archive-meta > p {
  color: var(--brass);
}

.archive-item .archive-meta h3 {
  margin: 0;
  color: var(--wine);
  font-family: var(--serif);
  font-size: clamp(22px, 2vw, 32px);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: 0.04em;
}

.archive-item > .archive-meta > span {
  color: var(--wine);
  font-size: clamp(15px, 1.25vw, 20px);
  letter-spacing: 0.05em;
}

.archive-item > .archive-meta > small {
  color: rgba(87, 11, 15, 0.58);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.09em;
  white-space: nowrap;
}

.contact {
  overflow: hidden;
  padding: 105px 0 120px;
  color: var(--paper);
}

html:not(.js) .contact {
  background: var(--room);
}

.contact-layout {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(560px, 1.1fr);
  align-items: start;
  gap: clamp(48px, 6vw, 110px);
  margin-top: 72px;
}

.contact-story {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 20px 0 0;
}

.contact-kicker,
.form-heading > p {
  margin: 0;
  color: var(--brass);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.22em;
}

.contact-story h2 {
  margin: 38px 0 34px;
  color: var(--almond);
  font-size: clamp(34px, 3.2vw, 52px);
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: 0.04em;
}

.contact-description {
  position: relative;
  z-index: 1;
  max-width: 470px;
  margin: 0 0 18px;
  font-size: 13px;
  line-height: 2.1;
  letter-spacing: 0.045em;
}

.contact-conditions {
  position: relative;
  z-index: 1;
  max-width: 590px;
  margin: 42px 0 0;
  border-top: 1px solid rgba(158, 109, 37, 0.55);
}

.contact-conditions div {
  display: grid;
  grid-template-columns: 150px 1fr;
  gap: 24px;
  padding: 13px 0;
  border-bottom: 1px solid rgba(252, 251, 246, 0.16);
}

.contact-conditions dt {
  color: var(--brass);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.18em;
}

.contact-conditions dd {
  margin: 0;
  font-size: 12px;
  letter-spacing: 0.05em;
}

.contact-form-panel {
  min-width: 0;
  padding: clamp(36px, 3.6vw, 56px);
  color: var(--wine);
  border-top: 5px solid var(--brass);
  background: var(--paper);
  box-shadow: 0 30px 80px rgba(25, 4, 3, 0.2);
}

.form-heading {
  padding-bottom: 30px;
  border-bottom: 1px solid rgba(87, 11, 15, 0.22);
}

.form-heading h3 {
  margin: 14px 0 10px;
  font-size: clamp(20px, 2.15vw, 34px);
  font-weight: 400;
  line-height: 1.5;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.form-heading > span {
  display: block;
  max-width: 450px;
  font-size: 11px;
  line-height: 1.9;
  letter-spacing: 0.04em;
}

.artist-form {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding-top: 30px;
}

.artist-form label {
  display: flex;
  flex-direction: column;
}

.artist-form label > span {
  margin-bottom: 7px;
  font-family: var(--grotesk);
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.14em;
}

.artist-form label > span i {
  margin-left: 8px;
  color: var(--brass);
  font-size: 8px;
  font-style: normal;
}

.artist-form input:not([type="checkbox"]),
.artist-form textarea {
  width: 100%;
  padding: 8px 0 10px;
  color: var(--wine);
  border: 0;
  border-bottom: 1px solid rgba(87, 11, 15, 0.36);
  border-radius: 0;
  outline: none;
  background: transparent;
  font-family: var(--mincho);
  font-size: 15px;
  transition: border 0.2s ease;
}

.artist-form input::placeholder,
.artist-form textarea::placeholder {
  color: rgba(87, 11, 15, 0.46);
  opacity: 1;
}

.artist-form input:focus,
.artist-form textarea:focus {
  border-bottom-color: var(--wine);
}

.artist-form textarea {
  resize: vertical;
}

/* Out-specifies `.artist-form label` / `label > span` without !important. */
.artist-form label.privacy {
  flex-direction: row;
  align-items: center;
  gap: 12px;
  margin-top: 4px;
}

.artist-form label.privacy input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--wine);
}

.artist-form label.privacy > span {
  margin: 0;
  font-family: var(--mincho);
  font-size: 10px;
  font-weight: 400;
  letter-spacing: 0.04em;
}

.submit-button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  margin-top: 6px;
  padding: 16px 20px;
  cursor: pointer;
  color: var(--paper);
  border: 1px solid var(--wine);
  background: var(--wine);
  font-family: var(--grotesk);
  font-size: 11px;
  letter-spacing: 0.14em;
  transition:
    color 0.35s ease,
    background 0.35s ease,
    transform 0.35s var(--ease);
}

.submit-button:hover {
  color: var(--wine);
  background: var(--paper);
  transform: translateY(-2px);
}

.submit-button i {
  font-size: 21px;
  font-style: normal;
}

/* Field-level validity feedback once the visitor has actually interacted with
   a field — :user-invalid never fires on pristine forms, so nothing shouts on
   arrival. */
.artist-form input:user-invalid,
.artist-form textarea:user-invalid {
  border-bottom-color: #a1352a;
}

/* States plainly that the form is a front-end prototype. The React build only
   revealed this after submitting; saying it up front is more honest. */
.form-note {
  margin: 2px 0 0;
  color: rgba(87, 11, 15, 0.62);
  font-family: var(--grotesk);
  font-size: 9px;
  line-height: 1.95;
  letter-spacing: 0.08em;
}

.form-success {
  margin-top: 42px;
  padding: 78px 3vw;
  text-align: center;
  border: 1px solid rgba(87, 11, 15, 0.28);
}

.form-success > p {
  margin: 0 0 25px;
  color: var(--brass);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.2em;
}

.form-success h3 {
  margin: 0 0 20px;
  font-size: clamp(26px, 3vw, 44px);
  font-weight: 400;
}

.form-success span {
  display: block;
  font-size: 11px;
}

.form-success button {
  margin-top: 40px;
  padding: 10px 20px;
  cursor: pointer;
  color: var(--wine);
  border: 1px solid currentColor;
  background: transparent;
}

.access {
  padding: 150px 0 180px;
}

.access-hotel {
  display: grid;
  grid-template-columns: minmax(0, 0.92fr) minmax(440px, 1.08fr);
  align-items: start;
  gap: clamp(60px, 8vw, 140px);
  margin-top: 130px;
}

.hotel-kicker {
  margin: 0 0 38px;
  color: var(--brass);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.18em;
}

.hotel-story h2 {
  margin: 0;
  color: var(--wine);
  font-size: clamp(32px, 3.3vw, 50px);
  font-weight: 400;
  line-height: 1.6;
  letter-spacing: 0.035em;
}

.hotel-description {
  max-width: 620px;
  margin: 38px 0 0;
  font-size: 13px;
  line-height: 2.15;
  letter-spacing: 0.045em;
}

.access-facts {
  margin: 58px 0 0;
}

.access-facts div {
  display: grid;
  grid-template-columns: 140px 1fr;
  gap: 20px;
  padding: 15px 0;
  border-top: 1px solid var(--line);
}

.access-facts dt,
.access-facts dd {
  font-family: var(--grotesk);
  font-size: 9px;
  line-height: 1.8;
  letter-spacing: 0.11em;
}

.access-facts dd {
  margin: 0;
}

.access-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-top: 34px;
}

.access-actions a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 17px 20px;
  color: var(--wine);
  border: 1px solid currentColor;
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.14em;
  transition:
    color 0.3s ease,
    background 0.3s ease;
}

.access-actions a:first-child,
.access-actions a:hover,
.access-actions a:focus-visible {
  color: var(--paper);
  background: var(--wine);
}

.archive-modal {
  position: fixed;
  z-index: 100;
  inset: 0;
  display: grid;
  grid-template-columns: 63% 37%;
  color: var(--paper);
  background: var(--wine-dark);
  animation: modal-in 0.55s var(--ease) both;
}

@keyframes modal-in {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
}

.modal-close {
  position: absolute;
  z-index: 4;
  top: 28px;
  right: 31px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0;
  cursor: pointer;
  color: var(--paper);
  border: 0;
  background: transparent;
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.18em;
}

.modal-close span {
  font-family: var(--serif);
  font-size: 32px;
  font-weight: 300;
  line-height: 1;
}

.modal-gallery {
  position: relative;
  overflow: hidden;
  background: #130706;
}

.modal-gallery img {
  position: absolute;
  inset: 0;
  height: 100%;
  opacity: 0;
  object-fit: cover;
  transform: scale(1.02);
  transition:
    opacity 0.65s ease,
    transform 0.9s var(--ease);
}

.modal-gallery img.is-active {
  opacity: 1;
  transform: scale(1);
}

.modal-controls {
  position: absolute;
  z-index: 3;
  right: 25px;
  bottom: 25px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px;
  background: rgba(43, 13, 9, 0.82);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.12em;
}

.modal-dossier {
  overflow-y: auto;
  padding: 14vh 5vw 8vh;
  border-left: 1px solid rgba(252, 251, 246, 0.2);
}

.modal-dossier > p:first-child {
  display: flex;
  justify-content: space-between;
  margin: 0 0 10vh;
  color: var(--almond);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.15em;
}

.modal-dossier h2 {
  margin: 0;
  font-size: clamp(43px, 4.7vw, 78px);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: 0.04em;
}

.modal-dossier h3 {
  margin: 18px 0 65px;
  color: var(--almond);
  font-family: var(--serif);
  font-size: clamp(27px, 2.7vw, 43px);
  font-style: italic;
  font-weight: 400;
}

.modal-dossier dl {
  margin: 0 0 55px;
}

.modal-dossier dl div {
  display: grid;
  grid-template-columns: 95px 1fr;
  padding: 12px 0;
  border-top: 1px solid rgba(252, 251, 246, 0.24);
}

.modal-dossier dt,
.modal-dossier dd {
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.1em;
}

.modal-dossier dd {
  margin: 0;
}

.modal-description {
  margin: 0;
  font-size: 13px;
  line-height: 2.2;
  letter-spacing: 0.05em;
}

.modal-link {
  display: flex;
  justify-content: space-between;
  margin-top: 50px;
  padding: 18px 0;
  border-top: 1px solid var(--paper);
  border-bottom: 1px solid var(--paper);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.17em;
}

.modal-dossier > small {
  display: block;
  margin-top: 35px;
  opacity: 0.45;
  font-family: var(--grotesk);
  font-size: 8px;
  letter-spacing: 0.15em;
}

.modal-scroll-hint {
  position: absolute;
  z-index: 5;
  right: 2.4vw;
  bottom: 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
  color: var(--almond);
  opacity: 1;
  font-family: var(--grotesk);
  font-size: 8px;
  letter-spacing: 0.16em;
  writing-mode: vertical-rl;
  transition: opacity 0.35s ease;
}

.modal-scroll-hint.is-hidden {
  opacity: 0;
}

.modal-scroll-hint i {
  position: relative;
  display: block;
  width: 1px;
  height: 54px;
  overflow: hidden;
  background: rgba(242, 184, 176, 0.3);
}

.modal-scroll-hint i::after {
  position: absolute;
  inset: 0;
  content: "";
  transform: translateY(-100%);
  background: var(--almond);
  animation: modal-scroll-line 1.8s var(--ease) infinite;
}

@keyframes modal-scroll-line {
  55% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(100%);
  }
}

/* ---------------------------------------------------------------------------
   Interaction refinements
   Hit areas, focus colour on dark surfaces, current-section marker, and the
   directional nudge every arrow shares. One motion vocabulary: arrows travel
   the way they point, on the same ease as everything else.
   --------------------------------------------------------------------------- */

/* The drawn controls stay small; the touchable area does not. Pseudo-elements
   extend each hit box to ~25-44px without changing the composition. */

.current-carousel-controls button,
.modal-controls button {
  position: relative;
}

.current-carousel-controls button::after {
  position: absolute;
  inset: -9px;
  content: "";
}

.modal-controls button::after {
  position: absolute;
  inset: -5px;
  content: "";
}

/* Swipe surfaces: vertical panning stays with the browser, horizontal flicks
   reach the carousel's pointer handlers. */
.hero-media,
.current-lead-image {
  touch-action: pan-y;
}

/* Brass reads ~3:1 on the dark surfaces; almond keeps the focus ring clearly
   visible there. */
.hero :focus-visible,
.experience :focus-visible,
.pairing :focus-visible,
.contact :focus-visible,
.archive-modal :focus-visible,
.veil :focus-visible {
  outline-color: var(--almond);
}

/* The topbar and rail float over whichever ground is current, so their
   rings follow the room. */
html[data-theme="night"] :is(.rail, .topbar) :focus-visible,
html[data-theme="room"] :is(.rail, .topbar) :focus-visible,
html[data-theme="deep"] :is(.rail, .topbar) :focus-visible {
  outline-color: var(--almond);
}

/* Arrows nudge in their pointing direction. */
.text-link i,
.hero-exhibition-link i,
.access-actions a span,
.modal-link span,
.submit-button i {
  transition: transform 0.3s var(--ease);
}

.text-link:hover i,
.text-link:focus-visible i,
.access-actions a:hover span,
.access-actions a:focus-visible span,
.modal-link:hover span,
.submit-button:hover i {
  transform: translate(3px, -3px);
}

.hero-exhibition-link:hover i,
.hero-exhibition-link:focus-visible i {
  transform: translateY(3px);
}

@keyframes editorial-image-drift {
  from {
    transform: scale(1.045) translateY(-1.5%);
  }
  to {
    transform: scale(1.015) translateY(1.5%);
  }
}

@media (max-width: 1100px) {
  html {
    scroll-padding-top: 76px;
  }

  .concept-grid {
    grid-template-columns: 15% 42% 1fr;
    gap: 4%;
  }

  .concept-year {
    font-size: 10vw;
  }

  .contact-layout {
    grid-template-columns: minmax(0, 0.82fr) minmax(500px, 1.18fr);
    gap: 4vw;
  }

  .contact-form-panel {
    padding: 48px;
  }


  .experience-card__copy {
    width: min(52%, 520px);
  }

  .current-layout {
    grid-template-columns: minmax(230px, 0.68fr) minmax(0, 1.4fr);
    gap: 6vw;
  }

  .pairing-layout {
    grid-template-columns: minmax(300px, 0.8fr) minmax(0, 1.2fr);
    gap: 5vw;
  }

  .access-hotel {
    grid-template-columns: minmax(0, 1fr) minmax(380px, 1fr);
    gap: 5vw;
  }
}

@media (max-width: 820px) {
  :root {
    --page: 90vw;
  }

  /* V3's small-screen hero: the wordmark tightens, the foot stacks with the
     thesis first, and the cue turns vertical at the right edge. */
  .hero-word {
    font-size: clamp(64px, 16.5vw, 120px);
  }

  .hero-title {
    top: clamp(84px, 13vh, 140px);
  }

  .hero-foot {
    flex-direction: column;
    align-items: flex-start;
    gap: 34px;
    padding-bottom: 34px;
  }

  .hero-thesis {
    order: 1;
  }

  .scroll-cue {
    position: absolute;
    right: 0;
    bottom: 34px;
    writing-mode: vertical-rl;
    flex-direction: row;
  }

  .scroll-cue i {
    width: 1px;
    height: 48px;
  }

  .concept {
    padding: 110px 0 140px;
  }

  .concept-intro {
    display: block;
    margin: 95px 0 70px;
  }

  .concept-kicker {
    margin: 0 0 28px;
  }

  .concept-grid {
    grid-template-columns: 1fr 1fr;
    gap: 7vw;
  }

  .concept-year {
    position: absolute;
    z-index: 3;
    top: 0;
    left: -2vw;
    margin: 0;
    color: var(--paper);
    font-size: 19vw;
    text-shadow: 0 4px 20px rgba(43, 13, 9, 0.18);
  }

  .concept-copy {
    padding-top: 16%;
  }

  .jp-lead {
    font-size: 18px;
  }

  .experience {
    padding-top: 110px;
  }

  .experience-heading {
    display: block;
    margin: 90px 0;
  }

  .experience-heading > p {
    margin: 0 0 30px;
  }

  .current {
    padding: 120px 0 140px;
  }

  .current-story {
    width: 62%;
    margin: 60px 0 0 auto;
  }

  .archive {
    padding: 110px 0 140px;
  }

  .archive-heading {
    display: block;
    margin: 95px 0 80px;
  }

  .archive-heading > p {
    margin: 35px 0 0;
  }

  .archive-grid {
    gap: 80px 3vw;
  }

  /* Same alternation, wider cards, shallower drops. */
  .archive-item:nth-child(odd) {
    grid-column: 1 / span 6;
  }

  .archive-item:nth-child(even) {
    grid-column: 7 / span 6;
  }

  .archive-item:nth-child(4n + 2) {
    margin-top: 130px;
  }

  .archive-item:nth-child(4n + 3) {
    margin-top: 40px;
  }

  .archive-item:nth-child(4n + 4) {
    margin-top: 150px;
  }

  .archive-item > .archive-meta {
    grid-template-columns: 58px minmax(0, 1fr) auto;
  }

  .contact {
    padding: 90px 0 105px;
  }

  .contact-layout {
    grid-template-columns: 1fr;
    gap: 54px;
    margin-top: 65px;
  }

  .contact-story {
    min-height: 0;
    padding-right: 12vw;
  }

  .contact-form-panel {
    width: 92%;
    margin-left: auto;
  }

  .access {
    padding: 110px 0 150px;
  }

  .archive-modal {
    grid-template-columns: 58% 42%;
  }

  .modal-dossier {
    padding-inline: 4vw;
  }


  /* Below the breakpoint the deck unbinds into V3's spreads: the plate at
     4:3 with its caption beneath, then the gilt numeral anchoring the copy.
     No sticky, no --stack transform, no scrim — a plain editorial column. */
  .experience-stack {
    padding-bottom: 110px;
  }

  .experience-card {
    position: relative;
    top: 0;
    display: flex;
    flex-direction: column;
    height: auto;
    margin-bottom: clamp(84px, 13vh, 130px);
    overflow: visible;
    background: transparent;
    box-shadow: none;
    transform: none;
    will-change: auto;
  }

  .experience-card:nth-child(1),
  .experience-card:nth-child(2),
  .experience-card:nth-child(3) {
    top: 0;
  }

  .experience-card:nth-child(3) {
    margin-bottom: 0;
  }

  .experience-card::before,
  .experience-card::after,
  .experience-card figure::after,
  .experience-card:nth-child(even) figure::after {
    content: none;
  }

  .experience-card figure {
    position: relative;
    inset: auto;
    order: 1;
  }

  .experience-card figure img {
    aspect-ratio: 4 / 3;
    height: auto;
  }

  /* The copy block dissolves; its children join the spread column in V3's
     order — caption under the plate, then numeral, title, reading text. */
  .experience-card__copy {
    display: contents;
  }

  .experience-card__copy > p:first-of-type {
    order: 2;
    margin: 14px 0 0;
  }

  .experience-card__no {
    order: 3;
    margin: 30px 0 0;
    opacity: 0.55;
    font-size: clamp(48px, 11vw, 72px);
  }

  .experience-card__copy h3 {
    order: 4;
    margin: 18px 0 0;
    font-size: clamp(26px, 5.6vw, 36px);
    line-height: 1.55;
    letter-spacing: 0.03em;
  }

  .experience-card .body-copy {
    order: 5;
    margin: 24px 0 0;
  }

  .current-layout {
    display: block;
    margin-top: 92px;
  }

  .current-index {
    position: relative;
    top: auto;
    width: min(520px, 82%);
    margin-bottom: 72px;
  }

  .current-index h2 {
    font-size: clamp(68px, 13vw, 104px);
  }

  .current-story {
    grid-template-columns: 1fr;
    padding: 72px 0 84px;
  }

  .current-story > p:not(.current-quote) {
    margin-left: auto;
  }

  .pairing {
    padding: 110px 0 120px;
  }

  .pairing-layout {
    grid-template-columns: 1fr;
    gap: 70px;
    margin-top: 82px;
  }

  .archive-item > .archive-meta {
    grid-template-columns: 58px minmax(0, 1fr) auto;
  }

  .access-hotel {
    grid-template-columns: 1fr;
    gap: 70px;
    margin-top: 92px;
  }

  .hotel-story {
    width: min(100%, 680px);
  }
}

@media (max-width: 560px) {
  body {
    font-size: 14px;
  }

  .hero-word {
    font-size: 19vw;
  }

  .hero-jp {
    font-size: 12px;
  }

  .concept {
    padding-bottom: 105px;
  }

  .concept-intro h2,
  .archive-heading h2 {
    font-size: 10.2vw;
    line-height: 1.5;
  }

  .experience-heading h2 {
    font-size: 8.6vw;
    line-height: 1.65;
  }

  .concept-grid {
    display: flex;
    flex-direction: column;
  }

  .concept-year {
    top: 8vw;
    font-size: 28vw;
  }

  .concept-copy {
    width: 88%;
    padding-top: 65px;
  }

  .jp-lead {
    margin-bottom: 42px;
    font-size: 17px;
  }

  .concept-copy dl {
    margin-top: 48px;
  }

  .current-story {
    width: 82%;
    margin: 55px 5vw 0 auto;
  }

  .archive-heading h2 {
    font-size: 9.2vw;
  }

  .archive-grid {
    display: flex;
    flex-direction: column;
    gap: 85px;
  }

  /* Equal width on mobile too; the alternating alignment keeps the rhythm. */
  .archive-item {
    width: 88%;
    margin: 0;
  }

  .archive-item:nth-child(even) {
    margin-left: auto;
  }

  .archive-item figure {
    aspect-ratio: 1.08;
  }

  .archive-open {
    opacity: 1;
    transform: translateY(0);
  }

  .contact-layout {
    gap: 42px;
    margin-top: 52px;
  }

  .contact-story {
    min-height: auto;
    padding: 12px 0 0;
  }

  .contact-story h2 {
    margin: 28px 0 28px;
    font-size: 8.8vw;
  }

  .contact-description {
    max-width: 88%;
    font-size: 12px;
  }

  .contact-conditions {
    margin-top: 34px;
  }

  .contact-conditions div {
    grid-template-columns: 94px 1fr;
    gap: 14px;
    padding: 11px 0;
  }

  .contact-conditions dt {
    font-size: 8px;
  }

  .contact-conditions dd {
    font-size: 10px;
  }

  .contact-form-panel {
    width: calc(100% + 5vw);
    margin-left: 0;
    padding: 38px 7vw 44px;
  }

  .form-heading {
    padding-bottom: 25px;
  }

  .form-heading h3 {
    font-size: 18px;
  }

  .artist-form {
    gap: 24px;
    padding-top: 28px;
  }

  .archive-modal {
    display: block;
    overflow-y: auto;
    background: var(--wine-dark);
  }

  .modal-close {
    position: fixed;
    top: 15px;
    right: 20px;
    padding: 5px 10px;
    background: rgba(43, 13, 9, 0.78);
  }

  .modal-gallery {
    height: 58svh;
  }

  .modal-dossier {
    overflow: visible;
    padding: 60px 7vw 80px;
    border-left: 0;
  }

  .modal-dossier > p:first-child {
    margin-bottom: 50px;
  }

  .modal-dossier h2 {
    font-size: 12vw;
  }

  .modal-dossier h3 {
    margin-bottom: 50px;
  }

  .modal-scroll-hint {
    position: fixed;
    right: 15px;
    bottom: 18px;
  }

  /* The spreads tighten on phones — V3's own small-screen scale. */
  .experience-stack {
    padding-bottom: 96px;
  }

  .experience-card {
    margin-bottom: 84px;
  }

  .experience-card__no {
    margin-top: 26px;
    font-size: clamp(48px, 11vw, 72px);
  }

  .experience-card__copy h3 {
    margin-top: 16px;
    font-size: 26px;
  }

  .experience-card__copy > p:first-of-type {
    font-size: 8px;
  }

  .body-copy {
    font-size: 11px;
    line-height: 1.9;
  }

  .current {
    padding-bottom: 110px;
  }

  .current-index {
    width: 100%;
    margin-bottom: 54px;
  }

  .current-index h2 {
    font-size: 20vw;
  }

  .current-lead-image {
    aspect-ratio: 0.94;
  }

  .current-lead-image figcaption {
    top: 12px;
    bottom: auto;
  }

  .current-story {
    gap: 32px;
    padding: 58px 0 68px;
  }

  .artist-profile {
    grid-template-columns: 1fr;
    gap: 34px;
    padding-top: 68px;
  }

  .artist-profile figure {
    width: 76%;
  }

  .artist-profile h3 {
    font-size: 15vw;
  }

  .archive-grid {
    gap: 72px;
  }

  .archive-item:nth-child(even) {
    width: 88%;
  }

  /* Narrowest tier: the number stays in its own column, everything else
     stacks beneath the artist name. */
  .archive-item > .archive-meta {
    grid-template-columns: 48px minmax(0, 1fr);
    column-gap: 14px;
    row-gap: 8px;
    padding-top: 16px;
  }

  .archive-item > .archive-meta > p {
    grid-column: 1;
    grid-row: 1 / span 3;
    font-size: 23px;
  }

  .archive-item > .archive-meta > span {
    grid-column: 2;
    grid-row: 1;
    font-size: 15px;
  }

  .archive-item > .archive-meta > small {
    grid-column: 2;
    grid-row: 3;
    justify-self: start;
  }

  .archive-item .archive-meta h3 {
    grid-column: 2;
    grid-row: 2;
    margin-top: 0;
    font-size: 24px;
  }

  .archive-item > .archive-meta > small {
    grid-column: 1 / -1;
  }

  .hotel-story h2 {
    font-size: 7.7vw;
  }

  .hotel-description {
    font-size: 12px;
  }

  .access-facts div {
    grid-template-columns: 104px 1fr;
    gap: 12px;
  }

  .access-actions {
    grid-template-columns: 1fr;
  }
}


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

  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  /* `.js .entrance` is what turns the overlay on, so the override has to match
     that specificity to win. It does, and this block comes later in the file. */

  /* Reveals must never latch hidden when motion is suppressed. */
  .js [data-reveal] {
    opacity: 1;
    transform: none;
  }
}


/* ===========================================================================
   V4 LAYER — "the catalogue in daylight"
   V3's editorial system carried onto V2's structure: the cover, the mask
   reveals, folio furniture, arch plates, the night pairing, and the colophon.
   Self-contained, with its own breakpoints; the reduced-motion block at the
   very end collapses everything this layer animates.
   =========================================================================== */

/* ------------------------------------------------------------------ cover */

.cover {
  display: none;
}

.js .cover {
  position: fixed;
  z-index: 1500;
  inset: 0;
  display: block;
  overflow: hidden;
  color: var(--brass-lit);
  background: var(--deep);
  animation: cover-lift 0.9s 2.35s var(--ease) forwards;
}

.cover-plate {
  position: absolute;
  top: 50%;
  left: 50%;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: min(440px, 84vw);
  transform: translate(-50%, -50%);
  text-align: center;
  animation: cover-settle 2.3s 0.1s var(--ease) both;
}

.cover-mark {
  display: block;
  width: 104px;
  height: 89px;
  clip-path: inset(0 50% 0 50%);
  animation: cover-mark 0.95s 0.2s var(--ease) forwards;
}

.cover-mark svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: currentColor;
}

.cover-rule {
  display: block;
  width: 170px;
  height: 1px;
  margin: 20px 0 16px;
  transform: scaleX(0);
  background: currentColor;
  animation: cover-rule 1.5s 0.65s var(--ease) forwards;
}

.cover-title {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  opacity: 0;
  transform: translateY(8px);
  animation: cover-copy 0.8s 0.9s var(--ease) forwards;
}

.cover-title b {
  color: var(--paper);
  font-family: var(--serif);
  font-size: 21px;
  font-weight: 400;
  letter-spacing: 0.2em;
}

.cover-title small {
  font-family: var(--grotesk);
  font-size: 8px;
  letter-spacing: 0.3em;
}

@keyframes cover-mark {
  to {
    clip-path: inset(0);
  }
}

@keyframes cover-rule {
  to {
    transform: scaleX(1);
  }
}

@keyframes cover-copy {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes cover-settle {
  0%,
  8% {
    opacity: 0;
    transform: translate(-50%, calc(-50% + 12px));
  }
  20%,
  100% {
    opacity: 1;
    transform: translate(-50%, -50%);
  }
}

@keyframes cover-lift {
  to {
    transform: translateY(-101%);
  }
}

/* --------------------------------------------------------- mask primitives */

.line,
.heading-line {
  display: block;
  overflow: hidden;
}

.line > span,
.heading-line > span {
  display: block;
}

.js :is(.line, .heading-line) > span {
  transform: translateY(115%);
  transition: transform 1.1s var(--ease);
}

.js .is-visible :is(.line, .heading-line) > span,
.js .is-visible > :is(.line, .heading-line) > span {
  transform: translateY(0);
}

.js :is(.line, .heading-line):nth-child(2) > span {
  transition-delay: 0.09s;
}

.js :is(.line, .heading-line):nth-child(3) > span {
  transition-delay: 0.18s;
}

.js .reveal-img {
  clip-path: inset(0 0 16% 0);
  transition: clip-path 1.2s var(--ease);
}

.js .reveal-img img {
  transform: scale(1.07);
  transition: transform 1.5s var(--ease);
}

.js .reveal-img.is-visible {
  clip-path: inset(0);
}

.js .reveal-img.is-visible img {
  transform: scale(1);
}

/* ------------------------------------------------------------------ folio */

.folio {
  display: flex;
  align-items: baseline;
  gap: 18px;
  padding-top: 34px;
  color: var(--ink);
  font-family: var(--grotesk);
  font-size: 10px;
  letter-spacing: 0.2em;
}

.folio-no {
  font-family: var(--serif-sc);
  font-size: 17px;
  letter-spacing: 0.06em;
  color: var(--wine);
}

.folio-rule {
  flex: 1;
  height: 1px;
  align-self: center;
  background: var(--line);
}

.folio-jp {
  font-family: var(--mincho);
  font-size: 10px;
  letter-spacing: 0.14em;
}

/* Dark rooms flip the folio to paper and gilt. */
.pairing .folio,
.contact .folio,
.experience .folio,
.current .folio {
  color: var(--paper);
}

.pairing .folio .folio-no,
.contact .folio .folio-no,
.experience .folio .folio-no,
.current .folio .folio-no {
  color: var(--brass-lit);
}

.pairing .folio .folio-rule,
.contact .folio .folio-rule,
.experience .folio .folio-rule,
.current .folio .folio-rule {
  background: var(--line-dark);
}

/* ------------------------------------------------------------- arch plates */

/* The facade under its arch, in the V1/V2 wine frame the client chose: a
   deep surround, a thin arc traced inside, the caption set into the image.
   The photograph shows the full building — no aggressive crop. */
.arch-plate {
  position: relative;
  overflow: hidden;
  margin: 0;
  padding: 7% 7% 0;
  border-radius: 48% 48% 0 0 / 26% 26% 0 0;
  background: var(--wine-dark);
}

.arch-plate::before {
  position: absolute;
  z-index: 2;
  inset: 2.4% 3.4% auto;
  height: 52%;
  pointer-events: none;
  content: "";
  border: 1px solid rgba(252, 251, 246, 0.62);
  border-bottom: 0;
  border-radius: 50% 50% 0 0;
}

.arch-plate img {
  width: 100%;
  height: 100%;
  aspect-ratio: 0.92;
  object-fit: cover;
  object-position: 50% 40%;
  border-radius: 45% 45% 0 0 / 24% 24% 0 0;
}

.arch-plate figcaption {
  position: absolute;
  z-index: 3;
  right: 20px;
  bottom: 18px;
  left: 20px;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: var(--paper);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.16em;
}

/* Thin gilt arch floating over the hero photography — the facade's ghost
   (V3's geometry). */
.hero-arch {
  position: absolute;
  z-index: 2;
  top: 12vh;
  right: 7vw;
  width: min(26vw, 380px);
  aspect-ratio: 0.6;
  pointer-events: none;
  border: 1px solid rgba(158, 109, 37, 0.42);
  border-bottom: 0;
  border-radius: 999px 999px 0 0;
}

@media (max-width: 1100px) {
  .hero-arch {
    display: none;
  }
}

/* Slow depth drift, written by main.js as a transform on the figure's img.
   The figure clips; only the photograph moves. */
[data-drift] {
  overflow: hidden;
}

[data-drift] > img {
  will-change: transform;
}

/* --------------------------------------------------------- pairing (night) */

.pairing-layout {
  display: grid;
  grid-template-columns: minmax(320px, 0.95fr) minmax(0, 1.05fr);
  gap: 7vw;
  align-items: start;
  margin-top: 105px;
}

.pairing-title {
  margin: 0 0 40px;
  font-family: var(--serif);
  font-size: clamp(56px, 6.4vw, 112px);
  font-weight: 400;
  line-height: 0.92;
  letter-spacing: -0.035em;
}

.pairing-title .line--italic {
  padding-left: 0.4em;
}

.pairing-title .line--italic > span {
  font-style: italic;
}

.pairing-title em {
  font-style: italic;
  color: var(--almond);
}

.pairing-reading .body-copy {
  max-width: 34em;
  color: rgba(252, 251, 246, 0.82);
  font-size: 13px;
  line-height: 2.2;
}

.pairing-reading .body-copy + .body-copy {
  margin-top: 20px;
}

.pairing-menu {
  max-width: 420px;
  margin: 48px 0 30px;
  padding: 36px 30px 32px;
  text-align: center;
  border: 1px solid var(--line-dark);
  outline: 1px solid var(--line-dark);
  outline-offset: 5px;
}

.pairing-menu-name {
  margin: 0;
  color: var(--paper);
  font-family: var(--serif);
  font-size: 30px;
  letter-spacing: 0.02em;
}

.pairing-menu-recipe {
  margin: 12px 0 0;
  color: var(--brass-lit);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.24em;
}

.pairing-menu-rule {
  display: block;
  width: 58px;
  height: 1px;
  margin: 22px auto;
  background: var(--brass);
}

.pairing-menu-meta {
  margin: 0;
}

.pairing-menu-meta b {
  display: block;
  font-family: var(--grotesk);
  font-size: 17px;
  font-weight: 400;
  letter-spacing: 0.12em;
}

.pairing-menu-meta small {
  display: block;
  margin-top: 8px;
  color: var(--brass-lit);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.18em;
}

.bar-link {
  display: inline-flex;
  align-items: baseline;
  gap: 12px;
  padding: 10px 0;
  color: var(--brass-lit);
  border-bottom: 1px solid currentColor;
  font-family: var(--grotesk);
  font-size: 10px;
  letter-spacing: 0.2em;
  transition: color 0.3s ease;
}

.bar-link:hover,
.bar-link:focus-visible {
  color: var(--paper);
}

.bar-link span {
  display: inline-block;
  transition: transform 0.3s var(--ease);
}

.bar-link:hover span,
.bar-link:focus-visible span {
  transform: translate(3px, -3px);
}

.pairing-plates {
  position: relative;
}

.pairing-hero {
  width: 88%;
  margin: 0 0 0 auto;
}

.pairing-hero img {
  aspect-ratio: 4 / 5;
  object-fit: cover;
}

.pairing-small {
  position: absolute;
  margin: 0;
}

.pairing-small img {
  aspect-ratio: 1;
  object-fit: cover;
}

.pairing-small--a {
  bottom: -9%;
  left: 0;
  width: 42%;
  box-shadow: 0 30px 70px rgba(24, 7, 6, 0.55);
}

.pairing-small--b {
  top: -7%;
  left: 4%;
  width: 30%;
  box-shadow: 0 24px 60px rgba(24, 7, 6, 0.5);
}

/* --------------------------------------------------------------- colophon */

html:not(.js) .colophon {
  background: var(--deep);
}

.colophon {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: clamp(120px, 18vh, 220px) 4vw 34px;
  color: var(--paper);
  text-align: center;
}

.colophon-mark {
  display: block;
  width: 58px;
  color: var(--brass-lit);
}

.colophon-mark svg {
  width: 100%;
  fill: currentColor;
}

.colophon-word {
  margin: 40px 0 0;
  font-family: var(--serif);
  font-size: clamp(44px, 6.5vw, 104px);
  line-height: 1;
  letter-spacing: -0.03em;
}

.colophon-word em {
  font-style: italic;
}

.colophon-tag {
  margin: 26px 0 0;
  color: var(--brass-lit);
  font-family: var(--grotesk);
  font-size: 9px;
  line-height: 2;
  letter-spacing: 0.3em;
}

.colophon-links {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 38px;
  justify-content: center;
  margin-top: clamp(48px, 8vh, 90px);
}

.colophon-links a,
.colophon-links button {
  padding: 10px 0;
  cursor: pointer;
  color: rgba(252, 251, 246, 0.78);
  border-bottom: 1px solid transparent;
  font-family: var(--grotesk);
  font-size: 10px;
  letter-spacing: 0.16em;
  transition: color 0.3s ease, border-color 0.3s ease;
}

.colophon-links a:hover,
.colophon-links a:focus-visible {
  color: var(--paper);
  border-bottom-color: var(--brass-lit);
}

.colophon-links button {
  cursor: help;
}

.colophon-legal {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 30px;
  align-items: baseline;
  justify-content: space-between;
  width: 100%;
  margin-top: clamp(60px, 10vh, 110px);
  padding-top: 26px;
  border-top: 1px solid var(--line-dark);
  color: rgba(252, 251, 246, 0.55);
  font-family: var(--grotesk);
  font-size: 9px;
  letter-spacing: 0.14em;
}

.colophon-legal a {
  padding: 8px 0;
  transition: color 0.3s ease;
}

.colophon-legal a:hover {
  color: var(--paper);
}

/* ------------------------------------------------------------- responsive */

@media (max-width: 1100px) {
  .pairing-layout {
    gap: 5vw;
  }
}

@media (max-width: 820px) {
  .pairing-layout {
    grid-template-columns: 1fr;
    gap: 80px;
    margin-top: 82px;
  }

  .pairing-plates {
    max-width: 560px;
  }
}

@media (max-width: 560px) {
  .folio {
    flex-wrap: wrap;
    gap: 10px 14px;
    padding-top: 24px;
  }

  .folio-rule {
    order: 4;
    flex-basis: 100%;
  }

  .cover-mark {
    width: 88px;
    height: 75px;
  }

  .cover-title b {
    font-size: 18px;
  }

  .pairing-hero {
    width: 100%;
  }

  .pairing-small--b {
    display: none;
  }

  .pairing-small--a {
    bottom: -12%;
    width: 46%;
  }

  .pairing-menu {
    padding: 30px 22px 26px;
  }

  .colophon-word {
    font-size: 13vw;
  }

  .colophon-legal {
    flex-direction: column;
    gap: 8px;
    align-items: flex-start;
    text-align: left;
  }
}

/* ------------------------------------------------- rail-width type fitting */

/* With the spine rail up, the page column is narrower than the raw viewport,
   so the display headings size against var(--page) rather than vw — nowrap
   heading-lines clip inside their masks if they outgrow the column. Late in
   the file so these win over the base clamps above. */
@media (min-width: 1101px) {
  .concept-intro h2,
  .experience-heading h2,
  .archive-heading h2 {
    font-size: clamp(48px, calc(var(--page) * 0.069), 104px);
  }

  .hotel-story h2 {
    font-size: clamp(28px, calc(var(--page) * 0.0315), 50px);
  }
}

/* -------------------------------------------- reduced motion (V4 additions) */

@media (prefers-reduced-motion: reduce) {
  .cover,
  .js .cover {
    display: none;
  }

  .js :is(.line, .heading-line) > span {
    transform: none;
    transition: none;
  }

  .js .reveal-img {
    clip-path: none;
  }

  .js .reveal-img img {
    transform: none;
  }

  [data-drift] > img {
    transform: none !important;
  }
}

/* ---------------------------------------------------------------------------
   14. English editorial labels — Centaur MT
   Client direction (2026-08): the English subtitles carry the brand serif,
   not the grotesk. Collected here rather than edited into a dozen component
   blocks so the treatment reads as one decision and can be tuned in one
   place; it sits late in the file so it wins over those base rules.

   Centaur has a small x-height and wide caps, so the same optical weight
   needs a few pixels more and noticeably less tracking than the grotesk
   settings it replaces. Utilitarian micro-type — plate captions, form
   labels, buttons, counters — deliberately stays in the grotesk, where the
   crisper face reads better at interface scale.
   --------------------------------------------------------------------------- */

.hero-eyebrow,
.concept-kicker,
.experience-heading > p,
.experience-card__copy > p:first-of-type,
.exhibition-number,
.current-index dt,
.artist-profile__label,
.pairing-kicker,
.contact-kicker,
.form-heading > p,
.contact-conditions dt,
.archive-heading > p,
.hotel-kicker,
.access-facts dt,
.colophon-tag,
.scroll-cue span {
  font-family: var(--serif);
  font-size: 12px;
  letter-spacing: 0.16em;
}

.hero-eyebrow {
  font-size: 13px;
  letter-spacing: 0.24em;
}

.colophon-tag {
  font-size: 12px;
  letter-spacing: 0.22em;
}

.archive-heading > p,
.access-facts dt {
  letter-spacing: 0.13em;
}

.scroll-cue span {
  font-size: 11px;
  letter-spacing: 0.28em;
}

/* ---------------------------------------------------------------------------
   15. ACCESS — the drawn area map
   Laid over the facade plate as a collage, in the idiom the pairing section
   already uses, but sized for reading rather than decoration: it breaks left
   into the column gutter (never far enough to reach the text) and hangs past
   the photograph's foot. Below the desktop breakpoint it stops floating and
   becomes a full-width plate, where it is larger still.
   --------------------------------------------------------------------------- */

.access-plates {
  position: relative;
}

.access-map {
  margin: 26px 0 0;
  padding: 14px 14px 0;
  border: 1px solid rgba(87, 11, 15, 0.18);
  background: var(--paper);
  box-shadow: 0 18px 44px rgba(43, 13, 9, 0.16);
}

.access-map img {
  width: 100%;
  height: auto;
}

.access-map figcaption {
  padding: 10px 2px 12px;
  color: var(--brass);
  font-family: var(--serif);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-align: center;
}

@media (min-width: 1101px) {
  .access-map {
    position: absolute;
    right: -4%;
    bottom: -13%;
    left: -17%;
    z-index: 3;
    margin: 0;
  }
}

/* ---------------------------------------------------------------------------
   16. The menu control is the close control
   The bar's button already becomes CLOSE, and its rule already turns the
   hamburger into a cross — but the veil covered it, so a separate close
   button appeared 8px higher and a little further in, and the swap read as a
   jump. The bar now rises above the veil while the menu is open, so the
   control stays exactly where it was at every breakpoint and only the word
   and the glyph change. Its ink is pinned to paper because the ground behind
   it is now the wine veil, not the section it was floating over.
   --------------------------------------------------------------------------- */

html.menu-open .topbar {
  z-index: 1200;
  color: var(--paper);
}

html.menu-open .topbar-mark img {
  filter: brightness(0) invert(1);
}

/* ---------------------------------------------------------------------------
   17. The holding page — COMING SOON / BE BACK SOON
   One page, no navigation, no content dependencies: it stands in for the site
   while the gallery is being set up, and during a deliberate pause. It shares
   this stylesheet rather than carrying its own so the wordmark, the serif and
   the wine ground are the same ones the real site uses — a visitor who lands
   here early has still met the brand. The ground stays inside the brand wine
   range and never approaches black.
   --------------------------------------------------------------------------- */

html.holding,
body.holding {
  background: var(--wine-dark);
}

body.holding {
  min-height: 100svh;
  margin: 0;
  color: var(--paper);
  font-family: var(--mincho);
  -webkit-font-smoothing: antialiased;
}

.holding-sheet {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 100svh;
  padding: clamp(40px, 9vw, 96px) var(--gutter);
  overflow: hidden;
  isolation: isolate;
}

/* The optional plate sits behind everything, dimmed far enough that the
   lettering never has to fight it. */
.holding-plate {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Held well back: a bright plate (a sky, a lit facade) must not lift the
     ground out of the brand wine, and the lettering has to stay readable
     over whatever photograph staff choose. */
  opacity: 0.5;
  filter: saturate(0.78) brightness(0.58);
}

/* A wine wash rather than a black scrim: the plate darkens into the brand
   ground instead of greying out. */
.holding-sheet::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(
      108% 78% at 50% 36%,
      rgba(60, 16, 13, 0.62),
      rgba(43, 13, 9, 0.9) 58%,
      rgba(43, 13, 9, 0.98) 100%
    );
}

.holding-inner {
  position: relative;
  width: min(100%, 620px);
  text-align: center;
  /* The hairline frame the rest of the site draws its plates with. */
  padding: clamp(38px, 7vw, 68px) clamp(24px, 6vw, 60px);
  border: 1px solid var(--line-dark);
}

.holding-inner::before,
.holding-inner::after {
  content: "";
  position: absolute;
  left: 50%;
  width: 1px;
  height: clamp(18px, 4vw, 34px);
  background: var(--line-dark);
}

.holding-inner::before {
  top: calc(-1 * clamp(18px, 4vw, 34px));
}

.holding-inner::after {
  bottom: calc(-1 * clamp(18px, 4vw, 34px));
}

.holding-logo {
  width: min(78%, 340px);
  height: auto;
  margin: 0 auto clamp(26px, 5vw, 40px);
  /* The lockup is drawn in wine for paper grounds; on the wine ground it is
     the same lockup in paper, exactly as the topbar does it when the veil is
     open. */
  filter: brightness(0) invert(1);
  opacity: 0.94;
}

.holding-headline {
  font-family: var(--serif);
  font-size: clamp(26px, 5.2vw, 44px);
  line-height: 1.12;
  letter-spacing: 0.16em;
  text-indent: 0.16em; /* balances the trailing letter-space */
  text-transform: uppercase;
  text-wrap: balance;
  color: var(--paper);
}

.holding-headline::after {
  content: "";
  display: block;
  width: 44px;
  height: 1px;
  margin: clamp(20px, 4vw, 30px) auto 0;
  background: var(--brass-lit);
}

.holding-message {
  margin-top: clamp(20px, 4vw, 30px);
  font-size: clamp(13.5px, 1.5vw, 15.5px);
  line-height: 2.1;
  letter-spacing: 0.04em;
  color: var(--paper-dim);
  /* Japanese wraps anywhere by default, which splits words down the middle
     in a measure this narrow. Same treatment the hero paragraph gets. */
  word-break: auto-phrase;
  text-wrap: pretty;
}

.holding-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px clamp(20px, 4vw, 34px);
  margin-top: clamp(28px, 5vw, 42px);
}

.holding-links a {
  font-family: var(--serif);
  font-size: 12px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--brass-lit);
  padding-bottom: 4px;
  border-bottom: 1px solid rgba(158, 109, 37, 0.42);
  transition: color 0.4s var(--ease), border-color 0.4s var(--ease);
}

.holding-links a:hover,
.holding-links a:focus-visible {
  color: var(--almond);
  border-bottom-color: var(--almond);
}

.holding-foot {
  margin-top: clamp(30px, 6vw, 46px);
  font-family: var(--serif-sc);
  font-size: 11px;
  letter-spacing: 0.3em;
  color: rgba(252, 251, 246, 0.5);
}

@media (max-width: 560px) {
  .holding-inner {
    border-left: 0;
    border-right: 0;
    padding-inline: 0;
  }
}
