*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --bg: #faf8f4;
  --text: #1a1714;
  --text-sub: #7a6f64;
  --border: #d9d0c6;
  /* Single restrained accent — deep muted oxblood. Used only on interaction
     (hover / active underlines, the ↗ arrow, text selection). */
  --accent: #7d3531;

  --font-en: "Space Grotesk", sans-serif;
  /* JP face listed before the generic so Japanese glyphs resolve to Shippori
     Mincho (not a device-dependent system serif) in serif contexts. */
  --font-serif: "Cormorant Garamond", "Shippori Mincho", serif;
  --font-jp: "Shippori Mincho", serif;
}

::selection {
  background: var(--accent);
  color: var(--bg);
}

html {
  scroll-behavior: auto; /* Lenis handles smooth scroll */
  /* Stop iOS / in-app browsers (LINE WKWebView etc.) from auto-inflating text,
     which can push long unbreakable lines past the viewport edge. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* ─── HORIZONTAL-OVERFLOW GUARD ───
   Final safety net: no device should ever scroll sideways. `clip` (not
   `hidden`) avoids creating a scroll container, so position:fixed nav and
   Lenis/ScrollTrigger keep working. The real fixes (text wrapping, fluid
   layout) come first; this only catches unforeseen overflow. */
html,
body {
  overflow-x: clip;
}

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

body {
  background-color: var(--bg);
  color: var(--text);
  font-family: var(--font-en);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* ─── NAV ─── */
#nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.6rem 3rem;
  background: rgba(250, 248, 244, 0.94);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.4s;
}

#nav.scrolled {
  border-bottom-color: var(--border);
}

.nav-logo {
  font-family: var(--font-serif);
  font-size: 1rem;
  font-weight: 400;
  letter-spacing: 0.25em;
  text-decoration: none;
  color: var(--text);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 2.8rem;
}

.nav-links a {
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--text-sub);
  transition: color 0.4s;
  position: relative;
}

.nav-links a::after {
  content: "";
  position: absolute;
  bottom: -3px;
  left: 0;
  width: 0;
  height: 1px;
  background: var(--accent);
  transition: width 0.4s ease;
}

.nav-links a:hover {
  color: var(--text);
}

.nav-links a:hover::after,
.nav-links a.active::after {
  width: 100%;
}

/* Scroll-spy: current section */
.nav-links a.active {
  color: var(--text);
}

/* ─── NAV: mobile menu toggle (hamburger) ─── */
.nav-toggle {
  display: none; /* shown only on narrow screens via media query */
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 28px;
  height: 28px;
  padding: 0;
  background: none;
  border: none;
  cursor: pointer;
  z-index: 110;
}

.nav-toggle span {
  display: block;
  width: 22px;
  height: 1px;
  background: var(--text);
  transition: transform 0.35s ease, opacity 0.35s ease;
}

/* Open state: morph the two bars into an X */
#nav.menu-open .nav-toggle span:first-child {
  transform: translateY(3px) rotate(45deg);
}

#nav.menu-open .nav-toggle span:last-child {
  transform: translateY(-3px) rotate(-45deg);
}

/* ─── HERO ─── */
#hero {
  height: 100vh;
  height: calc(var(--vh, 1vh) * 100);
  display: grid;
  grid-template-columns: 1fr 1fr;
  position: relative;
  overflow: hidden;
}

.hero-image {
  position: relative;
  overflow: hidden;
}

/* Cinematic vignette — grounds the portrait, adds depth without noise. */
.hero-image::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
  background: linear-gradient(to bottom, transparent 52%, rgba(17, 16, 9, 0.3) 100%),
    radial-gradient(120% 90% at 50% 38%, transparent 58%, rgba(17, 16, 9, 0.22) 100%);
}

.hero-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  filter: grayscale(100%) brightness(0.96);
  display: block;
  transition: filter 1.2s ease;
  /* Slow, near-imperceptible Ken Burns drift — the portrait "breathes". */
  animation: heroKenBurns 32s ease-in-out infinite alternate;
  transform-origin: 50% 35%;
  will-change: transform;
}

@keyframes heroKenBurns {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.07);
  }
}

.hero-image:hover img {
  filter: grayscale(60%) brightness(0.98);
}

.hero-text {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 5rem 0 4.5rem;
}

.hero-name {
  font-family: var(--font-serif);
  font-size: clamp(4rem, 7vw, 8.5rem);
  font-weight: 300;
  letter-spacing: 0.08em;
  line-height: 1;
  margin-bottom: 2.2rem;
  color: var(--text);
}

.hero-title {
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.45em;
  text-transform: uppercase;
  color: var(--text-sub);
}

/* ─── SHARED SECTION STYLES ─── */
#about,
#works,
#schedule,
#connect {
  max-width: 860px;
  margin: 0 auto;
  padding: 9rem 3rem;
}

.section-label {
  font-family: var(--font-en);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.35em;
  text-transform: uppercase;
  color: var(--text-sub);
  margin-bottom: 3.8rem;
  padding-bottom: 1.2rem;
  border-bottom: 1px solid var(--border);
  opacity: 1;
  display: flex;
  align-items: baseline;
  gap: 1.3rem;
}

/* ─── ABOUT ─── */
.lang-toggle {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  flex-shrink: 0;
  margin-left: auto; /* push toggle to the right of the "01 ABOUT" label row */
}

.lang-btn {
  position: relative;
  font-family: var(--font-en);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-sub);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: color 0.35s ease;
}

.lang-btn:hover {
  color: var(--text);
}

.lang-btn[aria-pressed="true"] {
  color: var(--text);
}

.lang-btn[aria-pressed="true"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 1px;
  background: var(--accent);
}

.lang-btn:focus-visible {
  outline: 1px solid var(--text);
  outline-offset: 4px;
}

.lang-sep {
  font-size: 0.68rem;
  color: var(--text-sub);
  opacity: 0.5;
}

.bio {
  display: none;
}

.bio.active {
  display: block;
}

.bio p {
  font-size: 1.02rem;
  line-height: 1.85;
  color: var(--text);
  margin-bottom: 2rem;
  font-weight: 400;
}

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

.bio.en {
  font-family: var(--font-serif);
}

.bio.en p {
  font-size: 1.12rem;
  font-weight: 500;
}

.bio.jp {
  font-family: var(--font-serif), var(--font-jp);
}

.bio.jp p {
  font-size: 0.97rem;
  line-height: 2.0;
  font-weight: 300;
}

/* ─── RESONANCE ─── */
#resonance {
  max-width: 860px;
  margin: 0 auto;
  padding: 11rem 3rem;
}

.resonance-inner {
  text-align: center;
}

.resonance-word {
  font-family: var(--font-serif);
  font-size: clamp(3rem, 9vw, 6rem);
  font-weight: 400;
  font-style: italic;
  letter-spacing: 0.02em;
  line-height: 1;
  color: var(--text-sub);
  opacity: 0.22;
  margin-bottom: 3.5rem;
}

.resonance-poem {
  display: none;
}

.resonance-poem.active {
  display: block;
}

.resonance-poem.jp p.resonance-title,
.resonance-poem.en p.resonance-title {
  font-size: 1.05rem;
  line-height: 1.5;
  letter-spacing: 0.12em;
  color: #55576c; /* 勝色（かちいろ）: ごく暗い紫みの青 */
  margin-bottom: 2.4rem;
  font-weight: 400;
  font-style: normal;
}

/* EN: the faint "Resonance" watermark already serves as the heading,
   so hide the EN title to avoid the word appearing twice. */
.resonance-poem.en .resonance-title {
  display: none;
}

.resonance-poem p {
  color: var(--text);
  margin-bottom: 2.2rem;
  text-wrap: balance; /* even out centered, ragged poem lines */
}

.resonance-poem p:last-child {
  margin-bottom: 0;
}

.resonance-poem.jp {
  font-family: var(--font-jp);
}

.resonance-poem.jp p {
  font-size: 1.02rem;
  line-height: 2.4;
  font-weight: 300;
  word-break: keep-all; /* break at 、。 boundaries — avoids orphaned single kanji */
  /* Safety net: WebKit's stricter keep-all keeps a whole <br>-line unbroken, so
     a long line overflowed the viewport in iOS Safari / LINE's in-app browser.
     `anywhere` permits an emergency break only when no 、。 break is taken. */
  overflow-wrap: anywhere;
}

.resonance-poem.en {
  font-family: var(--font-serif);
}

.resonance-poem.en p {
  font-size: 1.18rem;
  line-height: 2.1;
  font-weight: 500;
  font-style: italic;
}

/* ─── WORKS ─── */
.works-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 3.5rem 3rem;
  align-items: center;
}

.works-logo-item {
  display: flex;
  align-items: center;
  justify-content: center;
}

.works-logo-item img {
  width: auto;
  max-width: 100%;
  max-height: 30px;
  object-fit: contain;
  filter: grayscale(100%);
  transition: filter 0.5s ease;
}

.works-logo-item img:hover {
  filter: grayscale(0%);
}

/* Optical size balancing: equalize perceived size by AREA within a safe box.
   Wide wordmarks get a width cap (a % of the cell, so they keep a consistent
   inset at every breakpoint instead of bleeding edge-to-edge); narrow / stacked
   lock-ups are lifted in height. */
.works-logo-item--mutek img {
  max-height: 24px;
  max-width: min(140px, 86%);
}
.works-logo-item--keisuke img {
  max-height: 24px;
  max-width: min(140px, 86%);
}
.works-logo-item--malakai img {
  max-width: min(150px, 88%);
}
.works-logo-item--tokyonode img {
  max-width: min(140px, 86%);
}
.works-logo-item--sibtv img {
  max-width: min(134px, 84%);
}
.works-logo-item--alphatheta img {
  max-height: 30px;
  max-width: min(132px, 84%);
}
.works-logo-item--ignite img {
  max-height: 28px;
  max-width: min(128px, 82%);
}
.works-logo-item--parco img {
  max-height: 30px;
}
.works-logo-item--mori img {
  max-height: 38px;
}
.works-logo-item--shogakukan img {
  max-height: 38px;
}
.works-logo-item--shibuyaradio img {
  max-height: 32px;
}
/* Qosmo: the oversized Q inflates the box height, so the lowercase reads small
   at a 30px cap — lift the height instead of widening. */
.works-logo-item--qosmo img {
  max-height: 34px;
  max-width: min(138px, 86%);
}
/* SALT / Quinto: all-cap-height and cap-plus-descender wordmarks; hold them to
   the same width band as the other wide marks so they don't overpower the row. */
.works-logo-item--salt img {
  max-height: 26px;
  max-width: min(120px, 76%);
}
.works-logo-item--quinto img {
  max-height: 24px;
  max-width: min(128px, 82%);
}
/* ドイツ大使館: 3行ロックアップで横幅 5:1。文字が最小サイズなので、
   他ロゴより幅の上限を緩めて可読性を確保する。
   国旗（黒赤金）はグレースケールにすると金が地色に沈んで判別できなくなる
   ため、DOMMUNE と同じく常時カラー（ホバーでの変化なし）。 */
.works-logo-item--germanembassy img {
  max-height: 34px;
  max-width: min(172px, 96%);
  filter: none;
}
/* syouryu: 紋章＋細いセリフのワードマークで約 5:1。 */
.works-logo-item--syouryu img {
  max-height: 28px;
  max-width: min(140px, 88%);
}

.works-logo-item--dommune {
  flex-direction: row;
  gap: 0.25rem;
}

.works-logo-item--dommune img {
  width: auto;
  max-height: none;
  filter: none;
}

.dommune-icon {
  height: 36px;
  flex-shrink: 0;
}

.dommune-text {
  height: 40px;
}

/* ─── SCHEDULE ─── */
/* Works と Gallery のあいだに置く出演予定リスト。中身は schedule.json から
   script.js が組み立てる。公開中のイベントが1件も無いあいだはセクションごと
   hidden のままにし、ナビリンクも出さない（空の見出しだけが残らないように）。 */

/* ラベル右の UPCOMING / PAST 切り替え。About の言語トグルと同じ作法で
   セクションラベル行の右端に置く。 */
.sched-filter {
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  flex-shrink: 0;
  margin-left: auto;
}

.sched-fbtn {
  position: relative;
  font-family: var(--font-en);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-sub);
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  transition: color 0.35s ease;
}

.sched-fbtn:hover {
  color: var(--text);
}

.sched-fbtn[aria-pressed="true"] {
  color: var(--text);
}

.sched-fbtn[aria-pressed="true"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -4px;
  height: 1px;
  background: var(--accent);
}

.sched-fsep {
  font-size: 0.68rem;
  color: var(--text-sub);
  opacity: 0.5;
}

.sched-list {
  list-style: none;
}

/* 日付 / 本文 / （ラベル＋矢印）の3カラム。ホバーで左に寄せる。
   罫線は引かない（クライアント要望。行の区切りは余白だけで見せる）。 */
.sched-item {
  display: grid;
  grid-template-columns: 7.6rem 1fr auto;
  align-items: baseline;
  gap: 1.4rem;
  padding: 1.7rem 0;
  text-decoration: none;
  color: var(--text);
  transition: padding-left 0.4s ease, opacity 0.4s ease;
}

a.sched-item:hover {
  padding-left: 1rem;
}

.sched-date {
  font-family: var(--font-en);
  font-size: 0.78rem;
  letter-spacing: 0.13em;
  color: var(--text-sub);
  white-space: nowrap;
}

.sched-dow {
  margin-left: 0.4em;
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  opacity: 0.62;
}

.sched-body {
  display: block;
  min-width: 0;
}

.sched-title {
  display: block;
  font-family: var(--font-serif), var(--font-jp);
  font-size: 1.1rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  line-height: 1.45;
}

.sched-venue {
  display: block;
  margin-top: 0.5rem;
  font-family: var(--font-en), var(--font-jp);
  font-size: 0.72rem;
  font-weight: 300;
  letter-spacing: 0.11em;
  color: var(--text-sub);
}

.sched-tail {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  flex-shrink: 0;
}

.sched-tag {
  font-family: var(--font-en);
  font-size: 0.58rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-sub);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 0.28rem 0.6rem;
  line-height: 1;
  white-space: nowrap;
}

/* 完売のみアクセント色。他ラベルと差がつきすぎないよう opacity で落とす */
.sched-tag--sold {
  color: var(--accent);
  border-color: var(--accent);
  opacity: 0.75;
}

.sched-arrow {
  font-family: var(--font-en);
  font-size: 0.72rem;
  color: var(--text-sub);
  opacity: 0;
  line-height: 1;
  transform: translate(-4px, 4px);
  transition: opacity 0.35s ease, transform 0.35s ease;
}

a.sched-item:hover .sched-arrow {
  opacity: 0.9;
  transform: translate(0, 0);
  color: var(--accent);
}

/* 終了したイベント（PAST 表示）は一段落とす */
.sched-item.is-past {
  opacity: 0.42;
}

/* ─── CONNECT ─── */
.connect-category {
  display: flex;
  flex-direction: column;
}

.connect-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 1.7rem 0;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: var(--text);
  transition: padding-left 0.4s ease, border-color 0.4s ease;
}

.connect-category:first-child .connect-item:first-child {
  border-top: 1px solid var(--border);
}

.connect-item:hover {
  padding-left: 1rem;
  border-bottom-color: var(--accent);
}

.connect-item::after {
  content: "↗";
  font-family: var(--font-en);
  font-size: 0.72rem;
  color: var(--text-sub);
  opacity: 0;
  transform: translate(-4px, 4px);
  transition: opacity 0.35s ease, transform 0.35s ease;
  line-height: 1;
  flex-shrink: 0;
}

.connect-item:hover::after {
  opacity: 0.9;
  transform: translate(0, 0);
  color: var(--accent);
}

.connect-category-label {
  font-family: var(--font-en);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--text-sub);
  padding-bottom: 0.5rem;
}

.connect-category + .connect-category {
  margin-top: 2.8rem;
}

.connect-name {
  font-family: var(--font-serif), var(--font-jp);
  font-size: 1.1rem;
  font-weight: 400;
  letter-spacing: 0.08em;
}

/* Works: 最終行の端数を中央に寄せる（4列）。
   ずらし量の一般式: （空きセル数 ÷ 2）×（カラム幅 + 列ギャップ）
   セル幅＝1カラムなので「カラム幅」は `100%`、列ギャップは `3rem`。
     ・1個余り（空き3）… `grid-column` で中央2セルにまたがせる方が素直
     ・2個余り（空き2）… 1 ×（100% + 3rem）
     ・3個余り（空き1）… 0.5 ×（50% + 1.5rem）※現状18社では発生しない
   `:nth-child()` は DOM 順で判定されカラム数を見ないため、3列・2列側で必ず打ち消すこと。 */
.works-logo-item:last-child:nth-child(4n + 1) {
  grid-column: 2 / 4;
}

.works-logo-item:nth-last-child(2):nth-child(4n + 1),
.works-logo-item:last-child:nth-child(4n + 2) {
  transform: translateX(calc(100% + 3rem));
}

/* ─── FOOTER ─── */
footer {
  border-top: 1px solid var(--border);
  padding: 3rem;
  text-align: center;
}

footer p {
  font-family: var(--font-serif);
  font-size: 0.8rem;
  letter-spacing: 0.18em;
  color: var(--text-sub);
  opacity: 0.8;
}

footer .footer-note {
  font-family: var(--font-en);
  font-size: 0.6rem;
  letter-spacing: 0.06em;
  line-height: 1.7;
  opacity: 0.5;
  margin-top: 0.9rem;
}

footer #note-jp {
  font-family: var(--font-jp);
}

footer .lang-note {
  display: none;
}

footer .lang-note.active {
  display: inline;
}

/* ─── HERO SCROLL CUE ─── */
#hero::after {
  content: "scroll";
  position: absolute;
  bottom: 2.8rem;
  right: 3.5rem;
  font-family: var(--font-en);
  font-size: 0.58rem;
  font-weight: 400;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--text-sub);
  opacity: 0.45;
  writing-mode: vertical-rl;
  pointer-events: none;
}

/* ─── FADE IN ─── */
.fade-in {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.9s ease, transform 0.9s ease;
}

.fade-in.visible {
  opacity: 1;
  transform: translateY(0);
}

/* ─── HERO ENTRANCE: pre-hide GSAP-animated elements ───
   The hero entrance is driven by GSAP .from() (script.js). Without an initial
   opacity:0 the browser paints these elements fully, then GSAP yanks them to 0
   and fades them back — a visible "appear→vanish→fade" flash. Pre-hide them so
   only the intended fade-in shows. Scoped exactly like .fade-in's no-js guard:
   - html:not(.no-js): JS disabled → no entrance runs, keep visible.
   - no-preference: reduced-motion skips GSAP (script.js), so keep visible.
   GSAP's inline opacity overrides this once the entrance runs. */
@media (prefers-reduced-motion: no-preference) {
  html:not(.no-js) #nav,
  html:not(.no-js) .hero-image,
  html:not(.no-js) .hero-name,
  html:not(.no-js) .hero-title {
    opacity: 0;
  }
}

/* ─── RESPONSIVE ─── */
@media (max-width: 900px) {
  #hero {
    grid-template-columns: 1fr;
    height: 100vh;
    height: calc(var(--vh, 1vh) * 100);
    grid-template-rows: 65% 35%;
  }

  .hero-image {
    height: auto;
  }

  .hero-image img {
    object-position: center 20%;
  }

  .hero-text {
    height: auto;
    padding: 2.5rem 2.5rem;
    justify-content: center;
    overflow: hidden;
  }

  .hero-name {
    font-size: clamp(3.5rem, 14vw, 6rem);
    margin-bottom: 1.4rem;
  }

  #nav {
    padding: 1.2rem 1.5rem;
    /* Drop the blur on mobile — it repaints every scroll frame for no
       visible gain (background is already ~opaque). */
    background: var(--bg);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .nav-links {
    gap: 1.8rem;
  }

  #about,
  #works,
  #schedule,
  #connect {
    padding: 5.5rem 1.5rem;
  }

  #resonance {
    padding: 7rem 1.5rem;
  }

  /* 3カラムは保ったまま日付カラムだけ詰める。タブレット幅では
     タイトルに残る幅を優先する。 */
  .sched-item {
    grid-template-columns: 6.4rem 1fr auto;
    gap: 1rem;
    padding: 1.5rem 0;
  }

  .sched-date {
    font-size: 0.74rem;
    letter-spacing: 0.1em;
  }

  .sched-title {
    font-size: 1rem;
  }

  .resonance-word {
    margin-bottom: 2.5rem;
  }

  /* Narrow viewport: shrink the poem a step so hard <br> lines fit without
     wrapping into orphaned characters. On phones the longest <br>-lines still
     exceed the content width, and WebKit's keep-all won't break them at 、,
     so allow normal CJK wrapping here — guaranteeing the text fits on every
     browser. The hard <br>s still define the primary line structure; only an
     over-long line wraps. */
  .resonance-poem.jp p {
    font-size: 0.92rem;
    line-height: 2.1;
    word-break: normal;
  }

  .resonance-poem.en p {
    font-size: 1.05rem;
  }

  .works-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 2.8rem 2rem;
  }

  /* 4列用の端数ルールを打ち消してから、3列用を貼り直す */
  .works-logo-item:last-child:nth-child(4n + 1) {
    grid-column: auto;
  }

  .works-logo-item:nth-last-child(2):nth-child(4n + 1),
  .works-logo-item:last-child:nth-child(4n + 2) {
    transform: none;
  }

  .works-logo-item:last-child:nth-child(3n + 1) {
    grid-column: 2 / 3;
  }

  /* 3列で2個余る場合の中央寄せ。空きセルは1つなので
     0.5 ×（100% + 2rem）＝ 50% + 1rem（列ギャップは 2rem）。
     18社の現状では 18＝3×6 で端数が出ないため不発だが、社数が変わったときのために残す。 */
  .works-logo-item:nth-last-child(2):nth-child(3n + 1),
  .works-logo-item:last-child:nth-child(3n + 2) {
    transform: translateX(calc(50% + 1rem));
  }

  #hero::after {
    display: none;
  }
}

@media (max-width: 480px) {
  .nav-toggle {
    display: flex;
  }

  /* Keep the logo above the open overlay */
  .nav-logo {
    position: relative;
    z-index: 110;
  }

  /* Links become a full-screen overlay menu */
  .nav-links {
    position: fixed;
    inset: 0;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 2.4rem;
    background: var(--bg);
    opacity: 0;
    pointer-events: none;
    transform: translateY(-8px);
    transition: opacity 0.4s ease, transform 0.4s ease;
  }

  #nav.menu-open .nav-links {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
  }

  .nav-links a {
    font-size: 1.4rem;
    letter-spacing: 0.2em;
    color: var(--text);
  }

  .hero-image {
    height: auto;
  }

  .works-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 2rem 1.5rem;
  }

  .works-logo-item:last-child:nth-child(3n + 1),
  .works-logo-item:last-child:nth-child(4n + 1) {
    grid-column: auto;
  }

  /* 2-col orphan: center sole item in last row */
  .works-logo-item:last-child:nth-child(2n + 1) {
    grid-column: 1 / -1;
  }

  /* 2列で余るのは最大1個。3列・4列由来のズラしはすべて打ち消す */
  .works-logo-item:nth-last-child(2):nth-child(3n + 1),
  .works-logo-item:last-child:nth-child(3n + 2),
  .works-logo-item:nth-last-child(2):nth-child(4n + 1),
  .works-logo-item:last-child:nth-child(4n + 2) {
    transform: none;
  }

  /* DOMMUNE: scale down for narrow screens */
  /* 3カラムでは幅が足りないので縦に積む。ラベルは会場の下へ回す。 */
  .sched-item {
    grid-template-columns: 1fr;
    gap: 0.45rem;
    padding: 1.5rem 0;
  }

  .sched-date {
    font-size: 0.72rem;
  }

  .sched-venue {
    margin-top: 0.35rem;
  }

  .sched-tail {
    justify-content: flex-start;
    margin-top: 0.35rem;
  }

  .dommune-icon {
    height: 28px;
  }

  .dommune-text {
    height: 32px;
  }
}

/* ─── CONNECT: ROWS WITH IMAGES ─── */
.connect-body {
  display: flex;
  flex-direction: column;
  gap: 5.5rem;
}

.connect-row {
  display: grid;
  grid-template-columns: 1fr 38%;
  gap: 4.5rem;
  align-items: center;
}

/* Reverse row: image on the left, links on the right */
.connect-row--reverse {
  grid-template-columns: 38% 1fr;
}

.connect-row--reverse .connect-category {
  grid-column: 2;
  grid-row: 1;
}

.connect-row--reverse .connect-photo {
  grid-column: 1;
  grid-row: 1;
}

.connect-photo {
  overflow: hidden;
  margin: 0 auto;
  align-self: center;
}

.connect-photo img {
  width: 100%;
  display: block;
  object-fit: cover;
}

.connect-photo--music img {
  aspect-ratio: 1 / 1;
}

.connect-photo--media img {
  aspect-ratio: 3 / 4;
  object-position: center 20%;
}

@media (max-width: 900px) {
  .connect-body {
    gap: 4rem;
  }
  .connect-row,
  .connect-row--reverse {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }
  .connect-row--reverse .connect-category {
    grid-column: 1;
    grid-row: 1;
  }
  .connect-row--reverse .connect-photo {
    grid-column: 1;
    grid-row: 2;
  }
  .connect-photo {
    max-width: 58%;
  }
}

@media (max-width: 480px) {
  .connect-photo {
    max-width: 80%;
  }
}

/* ─── CONNECT: NO ARROW ON TOUCH ─── */
@media (hover: none) {
  .connect-item::after,
  .sched-arrow {
    display: none;
  }
}

/* ─── GALLERY / LIVE (Cinematic) ─── */
#gallery {
  background: #111009;
  position: relative;
  overflow: hidden;
  /* 直前のセクション（Schedule。非表示のときは Works）の下余白に、下のグラデーション帯の
     淡い頭（ほぼ地色の区間）を重ねる。重ねないと「地色の余白」と「帯の淡い部分」が続いて
     間延びする。重ね幅は、最後の行から暗転が見え始めるまでの距離がリストの行間と同程度に
     なる量。前セクションの下余白（PC 9rem／モバイル 5.5rem）より小さく保ち、本文には被せない。 */
  margin-top: -6rem;
  /* 帯の高さ（260px）＋0.75rem。ラベルは帯が暗くなり切った直後に置く */
  padding-top: 17rem;
  padding-bottom: 8rem;
}

/* Cinematic transition — the dark gallery emerges from the paper section
   above instead of cutting hard. The stops follow a smoothstep (ease-in-out)
   curve so both seams — paper→band and band→dark — dissolve with no visible
   edge, and the mid-tones avoid a muddy flat-grey band. */
#gallery::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 260px;
  /* 11 stops sampled on a smoothstep curve — denser stops mean the slope
     barely changes at each joint, so no Mach band appears between segments. */
  background: linear-gradient(
    to bottom,
    var(--bg) 0%,
    #f4f2ed 10%,
    #e2e0dc 20%,
    #c8c6c1 30%,
    #a8a6a1 40%,
    #86847f 50%,
    #63625c 60%,
    #43423c 70%,
    #292821 80%,
    #181710 90%,
    #111009 100%
  );
  z-index: 0;
  pointer-events: none;
}

/* Dither layer — a faint monochrome noise over the transition band. It
   decorrelates the 8-bit quantisation steps that the eye reads as banding
   in the dark region. Masked at both ends so the noise itself has no edge. */
#gallery::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 260px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
  opacity: 0.05;
  z-index: 0;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(
    to bottom,
    transparent 0%,
    #000 22%,
    #000 78%,
    transparent 100%
  );
  mask-image: linear-gradient(to bottom, transparent 0%, #000 22%, #000 78%, transparent 100%);
}

#gallery .gallery-header {
  position: relative;
  z-index: 1;
  max-width: 860px;
  margin: 0 auto 4rem;
  padding: 0 3rem;
}

#gallery .gallery-label {
  color: rgba(232, 226, 216, 0.4);
  border-bottom-color: rgba(232, 226, 216, 0.12);
  margin-bottom: 0;
}

.g-block {
  position: relative;
  width: 100%;
  overflow: hidden;
}

.g-block-1 {
  /* 動画素材は上下それぞれ約12%の黒帯が焼き込まれている（シネスコ素材を16:9に収めたもの）。
     ブロックのアスペクト比を“中身”の比率（≈2.35:1）に合わせ、video を object-fit:cover で
     敷くことで、黒帯だけが上下にクロップされて画面外に出る。比率ベースなので全ビューポート
     共通で効き、横方向のロスや歪みも無い。全幅のシネスコ帯としてリード映像を見せる。 */
  aspect-ratio: 2.35 / 1;
  /* ガターは下の .g-meta-1（このブロックのキャプション）には付けない。作品間の間隔は
     次ブロック .g-block-2 の margin-top で確保し、キャプションは直上の画像に近接させる。 */
}
.g-block-2 {
  height: 75vh;
  /* 01 のキャプション(.g-meta-1)↔02 画像 のダークなガター（#111009 が見える）。
     作品を分離しつつ、キャプションは直上の 01 画像にグルーピングさせる非対称の間。 */
  margin-top: 4.5rem;
}

.g-img-wrap {
  width: 100%;
  height: 120%;
  position: absolute;
  top: -10%;
  left: 0;
  will-change: transform;
}

.g-img-wrap img,
.g-img-wrap video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Block 1 video: wrapper pinned to the block (no parallax overflow — see script.js).
   The block is shaped to the footage's content ratio (≈2.35:1) and the video is laid
   in with `cover`, so the baked-in top/bottom letterbox is cropped off-screen on every
   viewport. */
.g-img-1 {
  height: 100%;
  top: 0;
}

.g-img-1 video {
  object-fit: cover;
}

/* Block 2（3:2 静止画）: PC は縦長コンテナ＋cover で上下がトリミングされる。主役の DJ・
   Pioneer DJ 機材・手元は画像下部にあるため、object-position を下基準にして下を切らさず、
   代わりに天井/配線（雰囲気）側を多めにトリミングする。
   ※モバイル（≤900px）は contain で 3:2 ぴったり表示のため object-position は無効（影響なし）。 */
.g-img-2 img {
  object-position: 50% 100%;
}

/* キャプションは画像の「外（下）」に通常フローで置く（展示の作法 — 画像に文字を被せない）。
   番号＋ラベルを左揃え（全デバイス共通・棒線なし）。直上の画像に近接させるため margin-top は
   小さく、左右はサイト標準のテキストガター(3rem)に揃える（「GALLERY」ラベルや他セクション本文と
   同じ左余白。画像は全幅だが文字には必ず余白を持たせ、画面端に張り付かせない）。scrim が無くなり
   平坦なダーク(#111009)上に乗るため、ラベルの不透明度は可読性のため僅かに上げている。 */
.g-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.8rem 0.9rem;
  margin-top: 1.1rem;
  padding: 0 3rem;
}

.g-meta-num {
  font-family: var(--font-en);
  font-size: 0.55rem;
  font-weight: 400;
  letter-spacing: 0.18em;
  color: rgba(232, 226, 216, 0.38);
  flex-shrink: 0;
}

.g-meta-label {
  font-family: var(--font-en);
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  /* scrim が無くなり平坦なダーク上に乗るため、0.55 → 0.68 へ微増して可読性を確保。
     抑制したトーンは保つ。 */
  color: rgba(232, 226, 216, 0.68);
}

@media (max-width: 900px) {
  #gallery {
    margin-top: -3rem;
    /* 狭い画面では帯が長いと「何もない区間」に見えるため 180px → 160px に詰める。
       padding-top は PC と同じく 帯＋0.75rem */
    padding-top: 10.75rem;
    padding-bottom: 5.5rem;
  }
  #gallery::before,
  #gallery::after {
    height: 160px;
  }
  #gallery .gallery-header {
    padding: 0 1.5rem;
    margin-bottom: 3rem;
  }
  .g-block-1 {
    /* PC と同じく“中身”の比率(≈2.35:1)。焼き込まれた上下の黒帯を cover でクロップする。 */
    aspect-ratio: 2.35 / 1;
    height: auto;
  }
  .g-block-2 {
    /* Match the container to the 3:2 image (like block-1's 16:9). */
    aspect-ratio: 3 / 2;
    height: auto;
    margin-top: 3rem; /* モバイルは詰めたダークガター（01キャプション↔02画像） */
  }
  .g-meta {
    /* モバイルも左右はサイト標準ガター(1.5rem)に揃える（左余白を確保）。近接は維持。 */
    padding: 0 1.5rem;
    margin-top: 0.9rem;
    /* 美術館のチェックリスト式ぶら下げインデント: 番号を単独で上に落とさず、長いタイトル（02）は
       番号と同じ行から始め、折り返した続き行はタイトル左端に揃える。01・02 で改行のされ方を統一。 */
    flex-wrap: nowrap;
    align-items: baseline;
  }
  .g-meta-label {
    min-width: 0; /* ラベルを縮めてテキスト折り返しを許可（続き行＝タイトル左端＝ぶら下げ） */
  }

  /* Disable parallax travel room on mobile — prevents unwanted crop/zoom */
  .g-img-wrap {
    height: 100%;
    top: 0;
  }

  /* Landscape media (16:9 video, 3:2 image) was cropped left/right inside the
     tall portrait containers. Show it whole instead; the letterbox space blends
     into the #111009 gallery background, reading as a clean dark margin. */
  .g-img-wrap img,
  .g-img-wrap video {
    object-fit: contain;
  }
  /* Block 1 だけは cover を維持。素材の焼き込み黒帯（上下約12%）をクロップするため、
     上の contain 一括指定を打ち消す。Block 2（静止画）は contain のまま全体を見せる。 */
  .g-img-1 video {
    object-fit: cover;
  }
}

/* .g-block-1 / .g-block-2 とも 900px クエリの aspect-ratio をそのまま継承
   （高さはメディアに追従）。≤480 専用の高さ上書きは不要。 */

/* ─── NO-JS FALLBACK ─── */
/* If JS is disabled the no-js class is never removed, so reveal fade-in content. */
.no-js .fade-in {
  opacity: 1;
  transform: none;
}

/* ─── FOCUS VISIBLE (keyboard) ─── */
a:focus-visible,
.nav-toggle:focus-visible {
  outline: 1px solid var(--text);
  outline-offset: 3px;
  border-radius: 1px;
}

/* On the dark gallery, use a light ring for contrast */
#gallery a:focus-visible {
  outline-color: var(--bg);
}

/* ─── REDUCED MOTION ─── */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* Show content without motion (JS also skips Lenis/GSAP under this setting) */
  .fade-in {
    opacity: 1 !important;
    transform: none !important;
  }

  /* Stop the Ken Burns drift and reset to a clean, unscaled portrait. */
  .hero-image img {
    animation: none !important;
    transform: none !important;
  }
}
