/* ==========================================================================
   Reset & Base
   ========================================================================== */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
}

:root {
  --color-ink: #f5f2ea;
  --color-blood: #b3122e;
  --color-letter-ink: #2c2418;
  --color-gold: #c8a24a;
  --font-serif: "Noto Serif JP", serif;
  --font-sans: "Hiragino Kaku Gothic ProN", "Yu Gothic", sans-serif;
  --vh100: 100dvh;
}

html, body {
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overscroll-behavior: none;
  background: #000;
  font-family: var(--font-sans);
  color: var(--color-ink);
}

button {
  font-family: inherit;
  border: none;
  background: none;
  cursor: pointer;
}

img {
  -webkit-user-drag: none;
  user-select: none;
  pointer-events: none;
}

#app {
  position: relative;
  width: 100%;
  height: var(--vh100);
  overflow: hidden;
}

/* ==========================================================================
   Screens (common)
   ========================================================================== */
.screen {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.6s ease;
  overflow: hidden;
}

.screen--active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  z-index: 2;
}

.screen-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.screen-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.35) 0%, rgba(0, 0, 0, 0.15) 40%, rgba(0, 0, 0, 0.55) 100%);
}

.screen-overlay--venue {
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.25) 0%, rgba(0, 0, 0, 0.05) 30%, rgba(0, 0, 0, 0.4) 100%);
}

.tap-hint {
  position: absolute;
  left: 50%;
  bottom: 6%;
  transform: translateX(-50%);
  font-size: 0.85rem;
  letter-spacing: 0.15em;
  color: var(--color-ink);
  opacity: 0;
  animation: hint-blink 2.4s ease-in-out 2.2s infinite;
  white-space: nowrap;
  z-index: 3;
}

@keyframes hint-blink {
  0%, 100% { opacity: 0.15; }
  50% { opacity: 0.9; }
}

/* ==========================================================================
   1. Opening
   ========================================================================== */
.opening-content {
  position: relative;
  z-index: 3;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 6vw;
}

/* メインタイトル「蘇る罪と亡き友との再会」。
   スマートフォンの縦画面で不自然に折り返さないよう、
   .title-line で「蘇る罪と」/「亡き友との再会」の2行に固定して改行位置を制御し、
   長い方の行(7文字 + letter-spacing 0.12em ≒ 7.84em)が
   .opening-content の左右padding(6vw)の内側に収まるサイズにしている */
.opening-title {
  font-family: var(--font-serif);
  font-weight: 900;
  font-size: clamp(1.75rem, 9vw, 3.2rem);
  color: var(--color-ink);
  line-height: 1.45;
  letter-spacing: 0.7em;
  opacity: 0;
  filter: blur(2px);
  animation: title-in 1.8s cubic-bezier(0.19, 1, 0.22, 1) forwards;
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.6);
}

.title-line {
  display: block;
}

/* タイトル内で赤アクセントにしたい文字(.title-char)に付与する */
.title-char--accent {
  color: var(--color-blood);
}

@keyframes title-in {
  0% {
    opacity: 0;
    letter-spacing: 0.7em;
    filter: blur(2px);
  }
  100% {
    opacity: 1;
    letter-spacing: 0.12em;
    filter: blur(0);
  }
}

.opening-subtitle {
  margin-top: 1.6em;
  font-size: clamp(0.85rem, 3vw, 1.05rem);
  letter-spacing: 0.35em;
  color: var(--color-ink);
  opacity: 0;
  animation: fade-in-simple 1.4s ease-out 1.4s forwards;
}

@keyframes fade-in-simple {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ==========================================================================
   2. Envelope
   ========================================================================== */
/* 背景色は envelope-open.mp4 自体の背景(暗い紺〜黒)に合わせてあり、
   動画の四角い枠が画面から浮いて見えないようにしている */
#screen-envelope {
  background: #0a0e10;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 動画(1376x768)を画面いっぱいに大きく表示。タップ待ちの間は1フレーム目
   (封筒が閉じた状態)で一時停止しており、静止画のように見える */
.envelope-wrap {
  position: relative;
  width: min(92vw, calc(92vh * 1.791666), 1280px);
  aspect-ratio: 1376 / 768;
  animation: envelope-float 3.6s ease-in-out infinite;
}

.envelope-wrap.is-open {
  animation: none;
}

@keyframes envelope-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-14px); }
}

.envelope-open-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
  pointer-events: none;
}

/* 動画の四辺を背景色へフェードさせ、四角い枠の境界を馴染ませる */
.envelope-wrap::after {
  content: "";
  position: absolute;
  inset: 0;
  box-shadow: inset 0 0 min(6vw, 60px) min(2vw, 20px) #0a0e10;
  pointer-events: none;
}

/* フォールバック時(動画読み込み/再生に失敗した場合): フェードアウトして便箋へ */
.envelope-wrap.fallback-open {
  transition: opacity 0.4s ease;
  opacity: 0;
  pointer-events: none;
}

/* ==========================================================================
   3. Letter
   ========================================================================== */
#screen-letter {
  background: #1c1712;
  display: flex;
  align-items: center;
  justify-content: center;
}

.letter-wrap {
  position: relative;
  /* letter.png (1024x1024) content bbox: x 216-808, y 109-911 -> aspect 592:802.
     Cap by vh too so wide PC screens don't stretch the letter to fill the width.
     便箋の中の文字サイズ・余白はすべてこの実寸を基準に算出する */
  --letter-w: min(88vw, calc(70vh * 0.7382), 480px);
  width: var(--letter-w);
  aspect-ratio: 592 / 802;
  opacity: 0;
  transform: translateY(40px) scale(0.85);
}

#screen-letter.screen--active .letter-wrap {
  animation: letter-in 0.9s cubic-bezier(0.19, 1, 0.22, 1) forwards;
}

@keyframes letter-in {
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.letter-frame {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 2px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
}

.letter-img {
  /* crop out the dark padding baked into the square source image so the
     paper itself fills .letter-frame edge-to-edge */
  position: absolute;
  left: -36.49%;
  top: -13.59%;
  width: 172.97%;
  height: 127.67%;
  max-width: none;
  display: block;
}

/* 本文の行数が13行に増えたため、フォントサイズ・行間・余白はすべて
   便箋の実寸(--letter-w)に対する比率で指定し、画面サイズが変わっても
   .letter-text の表示エリアからはみ出さないようにしている。
   vw基準だと、便箋幅が480pxで頭打ちになるPC widescreen で文字だけが
   大きくなり溢れてしまうため、あえて --letter-w 基準にしている */
.letter-text {
  position: absolute;
  /* 便箋の左上/右下には紙のめくれ(カール)が描かれているため、
     上下は少し内側に。ボタンを便箋の中に収めるため下側の余白は広め */
  inset: 12% 6.5% 21% 6.5%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  /* 段落ブロック(本文 / 同窓会名 / 日時・会場 / 結び)の間隔 */
  gap: calc(var(--letter-w) * 0.028);
}

/* ブロック内の行間は詰め、ブロック同士だけ .letter-text の gap で空ける */
.letter-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--letter-w) * 0.008);
}

.letter-line {
  color: var(--color-letter-ink);
  font-family: var(--font-serif);
  opacity: 0;
  transform: translateY(6px);
  line-height: 1.42;
}

/* 1行ずつ時間差でフェードインさせる。行数が7→13行に増えたぶん
   1行あたりの間隔を詰め(本文は0.12s刻み)、最終行の表示完了を
   3.05s前後に抑えてテンポが間延びしないようにしている */
#screen-letter.screen--active .letter-anim-1 {
  animation: letter-line-in 0.5s ease-out 0.6s forwards;
}
#screen-letter.screen--active .letter-anim-2 {
  animation: letter-line-in 0.5s ease-out 0.78s forwards;
}
#screen-letter.screen--active .letter-anim-3 {
  animation: letter-line-in 0.5s ease-out 0.9s forwards;
}
#screen-letter.screen--active .letter-anim-4 {
  animation: letter-line-in 0.5s ease-out 1.02s forwards;
}
#screen-letter.screen--active .letter-anim-5 {
  animation: letter-line-in 0.5s ease-out 1.14s forwards;
}
#screen-letter.screen--active .letter-anim-6 {
  animation: letter-line-in 0.5s ease-out 1.26s forwards;
}
#screen-letter.screen--active .letter-anim-7 {
  animation: letter-line-in 0.5s ease-out 1.38s forwards;
}
#screen-letter.screen--active .letter-anim-8 {
  animation: letter-line-in 0.5s ease-out 1.5s forwards;
}
#screen-letter.screen--active .letter-anim-9 {
  animation: letter-line-in 0.5s ease-out 1.75s forwards;
}
#screen-letter.screen--active .letter-anim-10 {
  animation: letter-line-in 0.5s ease-out 1.9s forwards;
}
#screen-letter.screen--active .letter-anim-11 {
  animation: letter-line-in 0.5s ease-out 2.1s forwards;
}
#screen-letter.screen--active .letter-anim-12 {
  animation: letter-line-in 0.5s ease-out 2.25s forwards;
}
#screen-letter.screen--active .letter-anim-13 {
  animation: letter-line-in 0.5s ease-out 2.55s forwards;
}

/* 「拝啓」: 本文の書き出しとして少し強めに */
.letter-salutation {
  font-weight: 700;
  font-size: calc(var(--letter-w) * 0.04);
  letter-spacing: 0.15em;
}

/* 本文(挨拶文)は通常の太さ・控えめなサイズ。
   最長行「皆様には〜申し上げます。」(25文字)が
   表示エリア幅(0.87 * --letter-w)に収まるサイズにしてある */
.letter-body {
  font-weight: 400;
  font-size: calc(var(--letter-w) * 0.0325);
}

/* 「同窓会」「平成23年度卒 滝ヶ丘高校 3年A組」は本文よりやや強調(太字) */
.letter-info-title {
  font-weight: 700;
  font-size: calc(var(--letter-w) * 0.042);
  letter-spacing: 0.05em;
}

.letter-info-school {
  font-weight: 700;
  font-size: calc(var(--letter-w) * 0.033);
  letter-spacing: 0.03em;
}

/* 「日時」「会場」は読みやすく揃える */
.letter-info {
  font-weight: 400;
  font-size: calc(var(--letter-w) * 0.032);
}

/* 結びの一文は落ち着いたトーン(薄い色・やや小さめ) */
.letter-closing {
  font-weight: 400;
  font-size: calc(var(--letter-w) * 0.032);
  color: #6b5f4f;
}

@keyframes letter-line-in {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 便箋の文言(letter-anim-7: delay 2.2s + duration 0.6s = 2.8sで表示完了)が
   出そろってから、少し間を置いてボタンをフェード表示する。
   .letter-wrap(= .letter-frameと同じ箱)の子要素として、便箋の中の下部
   左右の余白に「参加する」/「不参加」をそれぞれ配置する */
.letter-choice {
  position: absolute;
  left: 11%;
  right: 11%;
  bottom: 7%;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1em;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.7s ease;
}

#screen-letter.screen--active .letter-choice {
  transition-delay: 3.4s;
  opacity: 1;
  pointer-events: auto;
}

/* 便箋の上にはっきり浮かび上がるピル型ボタン(位置変更前のデザインに戻したもの) */
.letter-choice-btn {
  font-family: var(--font-serif);
  font-size: clamp(0.78rem, 3vw, 0.95rem);
  letter-spacing: 0.12em;
  padding: 0.7em 1.5em;
  border-radius: 999px;
  background: rgba(10, 8, 6, 0.55);
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.35);
  transition: background 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
  white-space: nowrap;
}

.letter-choice-btn:active {
  transform: scale(0.96);
}

.letter-choice-btn--join {
  font-weight: 700;
  color: #e8c98a;
  border: 1px solid rgba(232, 201, 138, 0.6);
}

.letter-choice-btn--decline {
  font-weight: 400;
  color: rgba(245, 242, 234, 0.65);
  border: 1px solid rgba(245, 242, 234, 0.25);
}

@media (hover: hover) {
  .letter-choice-btn--join:hover {
    background: rgba(232, 201, 138, 0.2);
  }
  .letter-choice-btn--decline:hover {
    background: rgba(245, 242, 234, 0.12);
  }
}

/* ==========================================================================
   4. Venue / Characters
   ========================================================================== */
#screen-venue {
  background: #000;
}

.venue-scroll {
  position: absolute;
  inset: 0;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.venue-scroll::-webkit-scrollbar {
  display: none;
}

/* 初期表示のズームイン演出中は、スクロール位置と見た目の縮尺が食い違わないよう
   横スクロールを一時的に止めておく(演出終了時にscript.jsがこのクラスを外す) */
.venue-scroll--intro-zoom {
  overflow-x: hidden;
}

/* 初期表示の「引き」演出中、縦長画面などでキャンバス上下にできる黒い余白に
   一時的に重ねるタイトル/招待状文言。#screen-venue 直下(.venue-scroll の
   兄弟要素)に配置し、余白の高さは script.js が --venue-intro-margin に
   実測px値をセットする。余白が無い/狭い画面(横長のPCなど)では
   script.js が venue-intro-band--visible を付与しないため非表示のまま。
   ズームイン開始と同時にこのクラスが外れ、フェードアウトする */
.venue-intro-band {
  position: absolute;
  left: 0;
  right: 0;
  height: var(--venue-intro-margin, 0px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.35em;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.venue-intro-band--visible {
  opacity: 1;
}

.venue-intro-band--top {
  top: 0;
}

.venue-intro-band--bottom {
  bottom: 0;
}

.venue-intro-title-text {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: clamp(1rem, 4.6vw, 1.5rem);
  letter-spacing: 0.15em;
  color: var(--color-ink);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.85), 0 0 22px rgba(0, 0, 0, 0.5);
}

/* オープニング画面のタイトル配色ルール(.title-char--accent)と揃える。
   現在のタイトルには赤アクセントを付ける単語が無いため未使用 */
.venue-intro-title-accent {
  color: var(--color-blood);
}

.venue-intro-invite-line {
  /* letter-line(便箋画面)と同じくletter-spacingは指定せずnormalのまま揃える */
  font-family: var(--font-serif);
  text-align: center;
  color: rgba(245, 242, 234, 0.8);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.8);
}

.venue-intro-invite-line--main {
  /* letter-info-title(便箋の「同窓会」)と同じ font-weight で揃える */
  font-weight: 700;
  font-size: clamp(0.95rem, 3.8vw, 1.15rem);
}

/* 日時・会場の2行。3行構成になったぶん、余白の中に収まるよう
   .venue-intro-band の gap とあわせて少し小さめにしている */
.venue-intro-invite-line--sub {
  font-size: clamp(0.72rem, 2.6vw, 0.85rem);
  line-height: 1.5;
  color: rgba(245, 242, 234, 0.5);
}

/* 背景画像の実ピクセルサイズ(1536x768, bg2.png)に固定したキャンバスを用意し、
   キャラクターや入口はすべてこの固定サイズを基準に配置する。
   .venue-scale の width/height は script.js が画面サイズに応じて算出した
   スケール後のpx値を設定し、.venue-canvas はそのスケールで
   transform: scale() されるので、画面サイズ/向きが変わっても
   背景とキャラクターの相対位置は常に一致する */
.venue-scale {
  position: relative;
  height: 100%;
}

.venue-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 1536px;
  height: 768px;
  transform: scale(var(--venue-scale, 1));
  transform-origin: top left;
}

.venue-canvas .screen-bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

#character-layer {
  position: absolute;
  inset: 0;
  z-index: 2;
}

/* 建物上部、星空を背にしたエリアに重ねる会場名表示。
   bg2.png(1536x768)上の固定座標(キャラクター配置と同じ考え方)で配置し、
   .venue-canvas ごと transform: scale() されるため、引き/ズームイン
   いずれの表示状態でも建物とのずれが生じない。
   font-sizeはキャンバス実寸の高さに比例させてある(旧34px * 759/624) */
.venue-signboard {
  position: absolute;
  left: 46%;
  top: 7%;
  transform: translateX(-50%);
  z-index: 1;
  font-family: var(--font-serif);
  font-size: 41px;
  letter-spacing: 0.16em;
  white-space: nowrap;
  color: rgba(255, 240, 218, 0.95);
  text-shadow:
    0 0 10px rgba(255, 196, 120, 0.6),
    0 0 24px rgba(255, 160, 70, 0.35),
    0 2px 6px rgba(0, 0, 0, 0.9);
  pointer-events: none;
}

.scroll-hint {
  /* 端が切れている印象を出す常時表示のグラデーション(スクロール後も残す) */
  position: absolute;
  top: 0;
  bottom: 0;
  width: 30px;
  z-index: 4;
  pointer-events: none;
  display: flex;
  align-items: center;
}

.scroll-hint--left {
  left: 0;
  justify-content: flex-start;
  background: linear-gradient(to right, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0));
}

.scroll-hint--right {
  right: 0;
  justify-content: flex-end;
  background: linear-gradient(to left, rgba(0, 0, 0, 0.55), rgba(0, 0, 0, 0));
}

/* 横スクロール操作ボタン: 常時薄く表示される、実際にタップできる大きな円形ボタン */
.venue-scroll-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: clamp(56px, 16vw, 76px);
  height: clamp(56px, 16vw, 76px);
  border: none;
  border-radius: 50%;
  background: rgba(10, 8, 6, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.2s ease, opacity 0.25s ease, transform 0.15s ease;
}

.venue-scroll-btn--left {
  left: clamp(10px, 3vw, 20px);
}

.venue-scroll-btn--right {
  right: clamp(10px, 3vw, 20px);
}

.venue-scroll-btn-arrow {
  color: rgba(245, 242, 234, 0.92);
  font-size: clamp(1.6rem, 5.5vw, 2.2rem);
  line-height: 1;
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

@media (hover: hover) {
  .venue-scroll-btn:hover {
    background: rgba(20, 16, 12, 0.65);
  }
}

.venue-scroll-btn:active {
  transform: translateY(-50%) scale(0.92);
}

/* スクロール端に達したら、その方向のボタンを隠す */
.venue-scroll-btn:disabled {
  opacity: 0;
  pointer-events: none;
}

.character-marker {
  position: absolute;
  left: var(--left-pc);
  bottom: var(--bottom-pc);
  height: calc(var(--h) * 1%);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  transform: translateX(-50%);
  cursor: pointer;
  pointer-events: auto;
  transition: transform 0.25s ease, filter 0.25s ease;
}

.character-marker-img {
  height: 100%;
  width: auto;
  max-width: none;
  object-fit: contain;
  display: block;
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.45));
}

/* 奥行き演出: B・Cなど奥側に配置するキャラクター(サイズ縮小・Y位置を
   上げるのに加え、明度・彩度をわずかに落として空気遠近感を出す) */
.character-marker--back .character-marker-img {
  filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.45)) brightness(0.88) saturate(0.82);
}

.character-marker-dot {
  position: absolute;
  /* 足元の接地点(画像内の透明余白を除いた実際の足の中心)にちょうど
     来るよう、キャラクターごとの --dot-bottom-pc / --dot-left-pc
     (data/characters.json の dotBottomPercent/dotLeftPercent、marker
     の高さ・幅=画像全体サイズに対する%) で接地点そのものを指定し、
     translate(-50%, 50%) で光の中心をその点に合わせる
     (bottom/leftはボックスの端の位置指定のため、50%ずらして中心を点に一致させる)。
     未指定時は旧来の中央下寄せ(-4%)にフォールバック。 */
  bottom: var(--dot-bottom-pc, -4%);
  left: var(--dot-left-pc, 50%);
  width: 34%;
  aspect-ratio: 1 / 1;
  max-width: 46px;
  transform: translate(-50%, 50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(245, 242, 234, 0.55) 0%, rgba(245, 242, 234, 0) 70%);
  animation: dot-pulse 2.6s ease-in-out infinite;
  pointer-events: none;
}

@keyframes dot-pulse {
  0%, 100% { opacity: 0.35; transform: translate(-50%, 50%) scale(0.9); }
  50% { opacity: 0.75; transform: translate(-50%, 50%) scale(1.05); }
}

@media (hover: hover) {
  .character-marker:hover {
    transform: translateX(-50%) scale(1.06);
  }
  .character-marker:hover .character-marker-img {
    filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.45)) drop-shadow(0 0 18px rgba(245, 242, 234, 0.55));
  }
  .character-marker--back:hover .character-marker-img {
    filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.45)) drop-shadow(0 0 18px rgba(245, 242, 234, 0.55)) brightness(0.88) saturate(0.82);
  }
}

/* 位置は bg2.png(1536x768)上の実際の玄関(黄色いドア、x≈300-390、
   床面y≈660、中心約22%/bottom≈14%)に合わせてある */
.entrance-hotspot {
  position: absolute;
  left: 22%;
  bottom: 14%;
  transform: translateX(-50%);
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  pointer-events: auto;
}

.entrance-hotspot .entrance-marker {
  width: 15vw;
  height: 15vw;
  max-width: 76px;
  max-height: 76px;
}

@media (max-width: 700px) {
  .entrance-hotspot .entrance-marker {
    width: 18vw;
    height: 18vw;
  }
}

.entrance-label {
  font-family: var(--font-serif);
  font-size: clamp(0.7rem, 2.6vw, 0.85rem);
  letter-spacing: 0.12em;
  color: var(--color-gold);
  white-space: nowrap;
  padding: 0.35em 0.9em;
  border-radius: 999px;
  background: rgba(10, 8, 6, 0.45);
  border: 1px solid rgba(200, 162, 74, 0.4);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

.entrance-marker {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(200, 162, 74, 0.55) 0%, rgba(200, 162, 74, 0.08) 70%);
  border: 1px solid rgba(200, 162, 74, 0.6);
  animation: entrance-pulse 2.2s ease-in-out infinite;
}

@keyframes entrance-pulse {
  0%, 100% { opacity: 0.55; transform: scale(0.92); }
  50% { opacity: 1; transform: scale(1.04); }
}

@media (hover: hover) {
  .entrance-hotspot:hover .entrance-marker {
    opacity: 1;
    transform: scale(1.1);
  }
}

/* 会場キャンバス右上(建物の上、夜空の部分)に置かれたミニゲームへの導線。
   横スクロールしないと見つからない位置にあるため、他のタップ領域より
   控えめな見た目にしてあり、「見つけた人へのご褒美」程度の扱いにしている */
.minigame-hotspot {
  position: absolute;
  right: 4%;
  top: 9%;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  pointer-events: auto;
}

.minigame-hotspot .minigame-hotspot-marker {
  width: 11vw;
  height: 11vw;
  max-width: 52px;
  max-height: 52px;
}

@media (max-width: 700px) {
  .minigame-hotspot .minigame-hotspot-marker {
    width: 13vw;
    height: 13vw;
  }
}

/* 他のタップマーカー(人物=白系、会場入口=金系)とは異なり、ミニゲームだけ
   赤(--color-blood)を差し色にして「毛色の違う要素」だと一目で分かるようにする */
.minigame-hotspot-marker {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(179, 18, 46, 0.4) 0%, rgba(179, 18, 46, 0.08) 70%);
  border: 1px solid rgba(179, 18, 46, 0.65);
  animation: minigame-pulse 3.4s ease-in-out infinite;
}

/* venue-signboardと同様、canvas座標系での固定px指定にしておくことで、
   .venue-canvasのtransform: scale()と一緒に自然に拡大縮小される
   (font-size: %指定だと親の文字サイズを継承してしまい極端に小さくなるため) */
.minigame-hotspot-icon {
  font-size: 32px;
  line-height: 1;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6));
}

@keyframes minigame-pulse {
  0%, 100% { opacity: 0.55; transform: scale(0.92); box-shadow: 0 0 8px rgba(179, 18, 46, 0.3); }
  50% { opacity: 0.95; transform: scale(1.05); box-shadow: 0 0 18px rgba(179, 18, 46, 0.55); }
}

.minigame-hotspot-label {
  font-family: var(--font-serif);
  font-size: clamp(0.58rem, 2.1vw, 0.7rem);
  letter-spacing: 0.06em;
  color: rgba(245, 242, 234, 0.85);
  white-space: nowrap;
  padding: 0.3em 0.75em;
  border-radius: 999px;
  background: rgba(10, 8, 6, 0.45);
  border: 1px solid rgba(179, 18, 46, 0.5);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
}

@media (hover: hover) {
  .minigame-hotspot:hover .minigame-hotspot-marker {
    opacity: 1;
    transform: scale(1.1);
    box-shadow: 0 0 22px rgba(179, 18, 46, 0.55);
  }
}

/* ==========================================================================
   Modals
   ========================================================================== */
.modal {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5vw;
}

.modal[hidden] {
  display: none;
}

.modal-backdrop {
  position: absolute;
  inset: 0;
}

.modal-panel {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 460px;
  max-height: 88vh;
  overflow-y: auto;
  border-radius: 10px;
  animation: modal-in 0.3s ease-out;
}

@keyframes modal-in {
  from { opacity: 0; transform: translateY(16px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.modal-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 36px;
  height: 36px;
  font-size: 1.4rem;
  line-height: 1;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
}

/* -- Character modal: "劇の世界に入る" dark / mysterious -- */
.modal--character .modal-backdrop {
  background: rgba(8, 6, 5, 0.8);
  backdrop-filter: blur(3px);
}

.character-panel {
  background: linear-gradient(180deg, #241d18 0%, #17120f 100%);
  border: 1px solid rgba(200, 162, 74, 0.25);
  color: var(--color-ink);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
}

.character-panel .modal-close {
  color: var(--color-ink);
  background: rgba(255, 255, 255, 0.08);
}

.character-panel-image-wrap {
  width: 100%;
  height: 42vh;
  max-height: 320px;
  background: radial-gradient(ellipse at center, rgba(200, 162, 74, 0.12) 0%, transparent 70%);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.character-panel-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
}

.character-panel-body {
  padding: 1.4rem 1.6rem 1.8rem;
}

.character-panel-name {
  font-family: var(--font-serif);
  font-size: 1.4rem;
  font-weight: 700;
  margin-bottom: 0.4em;
  color: var(--color-gold);
}

.character-panel-actor {
  font-size: 0.75rem;
  color: rgba(245, 242, 234, 0.55);
  margin-bottom: 1em;
  letter-spacing: 0.02em;
}

.character-panel-profile {
  font-size: 0.92rem;
  line-height: 1.8;
  margin-bottom: 1.1em;
}

.character-panel-comment {
  font-size: 0.88rem;
  line-height: 1.8;
  font-style: italic;
  color: rgba(245, 242, 234, 0.75);
  border-top: 1px solid rgba(200, 162, 74, 0.2);
  padding-top: 1em;
}

/* -- Info modal: "現実の公演情報に入る" clean / factual -- */
.modal--info .modal-backdrop {
  background: rgba(20, 20, 22, 0.6);
  backdrop-filter: blur(2px);
}

.info-panel {
  background: #faf8f4;
  color: #262220;
  padding: 2rem 1.6rem 1.8rem;
  font-family: var(--font-sans);
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
}

.info-panel .modal-close {
  color: #262220;
  background: rgba(0, 0, 0, 0.06);
}

.info-eyebrow {
  font-size: 0.72rem;
  letter-spacing: 0.25em;
  color: #a4172f;
  margin-bottom: 0.4em;
}

.info-title {
  font-family: var(--font-serif);
  font-size: 1.5rem;
  font-weight: 900;
  margin-bottom: 0.6em;
}

.info-datetime {
  font-size: 0.85rem;
  line-height: 1.7;
  color: #4a433d;
  margin-bottom: 1.4em;
  padding-bottom: 1.2em;
  border-bottom: 1px solid #ddd5c8;
}

.info-section {
  margin-bottom: 1.3em;
}

.info-section h3 {
  font-size: 0.75rem;
  letter-spacing: 0.15em;
  color: #a4172f;
  margin-bottom: 0.5em;
}

.info-section p {
  font-size: 0.88rem;
  line-height: 1.8;
  color: #3a342f;
}

.info-actions {
  margin-top: 1.6em;
  display: flex;
  flex-direction: column;
  gap: 0.7em;
}

.ticket-button {
  display: block;
  text-align: center;
  padding: 0.9em 1em;
  background: #a4172f;
  color: #fff;
  border-radius: 6px;
  font-weight: 700;
  font-size: 0.92rem;
  text-decoration: none;
  letter-spacing: 0.05em;
}

.back-button {
  text-align: center;
  padding: 0.8em 1em;
  color: #4a433d;
  font-size: 0.88rem;
  letter-spacing: 0.05em;
  border: 1px solid #ddd5c8;
  border-radius: 6px;
  background: transparent;
}

/* ==========================================================================
   Decline overlay (便箋「不参加」演出)
   ========================================================================== */
/* モーダル(z-index:10)よりさらに手前に置き、便箋画面を覆い隠す全画面暗転。
   非表示時も transition を効かせたいので display は切り替えず、
   opacity/pointer-events のみで制御する */
.decline-overlay {
  position: fixed;
  inset: 0;
  z-index: 20;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.decline-overlay--active {
  opacity: 1;
}

/* 便箋画面へ戻る最後の一歩だけ、ゆっくりフェードで暗転を解く
   (pointer-events は script.js がフェード完了まで別途 auto を維持する) */
.decline-overlay--slow-fade {
  transition: opacity 0.6s ease;
}

.decline-message {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: var(--font-serif);
  color: #ffffff;
  font-size: clamp(1.1rem, 4.4vw, 1.5rem);
  letter-spacing: 0.14em;
  text-align: center;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.decline-message--visible {
  opacity: 1;
}

/* ==========================================================================
   5. Minigame「容疑者を、追い詰めろ。」
   クラス名は他画面と衝突しないよう mg- プレフィックスで統一する。
   ========================================================================== */
#screen-minigame {
  background: #05060a;
}

.mg-stage {
  position: relative;
  width: 100%;
  height: 100%;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 64px 16px 40px;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(40, 50, 70, 0.4) 0%, rgba(5, 6, 10, 0.95) 60%),
    #05060a;
}

.mg-back-btn {
  position: absolute;
  top: 16px;
  left: 16px;
  z-index: 3;
  font-family: var(--font-serif);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  color: var(--color-ink);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.25);
  padding: 0.55em 1.1em;
  border-radius: 999px;
  transition: background 0.2s ease;
}

@media (hover: hover) {
  .mg-back-btn:hover {
    background: rgba(255, 255, 255, 0.16);
  }
}

.mg-title {
  font-family: var(--font-serif);
  font-weight: 900;
  font-size: clamp(20px, 5vw, 28px);
  letter-spacing: 0.1em;
  margin-bottom: 6px;
  text-align: center;
  color: var(--color-ink);
}

.mg-accent {
  color: var(--color-blood);
}

.mg-subtitle {
  font-family: var(--font-serif);
  font-size: 12px;
  color: #b9b4a8;
  letter-spacing: 0.15em;
  margin-bottom: 22px;
  text-align: center;
}

.mg-status {
  font-family: var(--font-serif);
  font-size: 14px;
  color: #e8c98a;
  margin-bottom: 14px;
  min-height: 20px;
  letter-spacing: 0.05em;
  text-align: center;
}

.mg-graph-wrap {
  position: relative;
  width: min(90vw, 340px);
  height: min(90vw, 440px);
  /* 最上段の駒画像がノードの円から大きくはみ出すため、上のタイトル/
     ステータス文言と重ならないよう余白を確保する */
  margin-top: 64px;
  background: #14110c;
  border: 2px solid #3a3226;
  border-radius: 10px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.7);
  flex-shrink: 0;
}

.mg-edges {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.mg-edges line {
  stroke: #4a4030;
  stroke-width: 3;
}

.mg-node {
  position: absolute;
  width: 15%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: #241f17;
  border: 2px solid #4a4030;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: clamp(18px, 5vw, 26px);
  cursor: pointer;
  overflow: visible;
  transition: box-shadow 0.2s ease, border-color 0.2s ease, background 0.2s ease;
}

/* 容疑者が現在いるノードにのみ付与する赤いスポットライト。render()が
   選択中ノードのクラス同様、容疑者のいるノードにこのクラスを付け直すことで
   移動のたびに自然に追従する(#b3122eと同じ色調) */
.mg-node.mg-thief-spotlight {
  background: radial-gradient(circle, rgba(179, 18, 46, 0.55) 0%, rgba(179, 18, 46, 0.18) 45%, transparent 75%);
  border-color: rgba(179, 18, 46, 0.6);
  box-shadow: 0 0 30px rgba(179, 18, 46, 0.35);
}

.mg-node.mg-selected {
  border-color: #e8c98a;
  box-shadow: 0 0 0 3px rgba(232, 201, 138, 0.4);
}

.mg-node.mg-selectable {
  border-color: rgba(230, 200, 138, 0.6);
}

.mg-node.mg-selectable::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 2px dashed rgba(230, 200, 138, 0.55);
  animation: mg-spin 6s linear infinite;
}

@keyframes mg-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* 駒表示: 画像(officer.png/thief.png)はノードの円より大きく表示しつつ、
   「駒の足元 = ノードの円の中心」に来るよう配置する。
   .mg-node 自体が x,y 座標に translate(-50%,-50%) で配置され、かつ
   transform 指定により絶対配置の基準(containing block)になっているので、
   その中で left/top:50% を起点に、画像下端(足元)がノード中心に来るよう
   translateY を -100% 付近にする(基準は -100%、画像内の透明余白の分だけ
   script.js が --piece-ty としてキャラごとに微調整した値を上書きする)。
   横方向も同様に --piece-tx で画像内容の中心を調整できるようにしてある
   (未指定時は中央揃えの -50%/-100% にフォールバック)。
   画像読み込みに失敗した場合は script.js 側でノードの textContent を
   絵文字に差し替えてフォールバックする */
.mg-piece-img {
  position: absolute;
  width: 220%;
  left: 50%;
  top: 50%;
  transform: translate(var(--piece-tx, -50%), var(--piece-ty, -100%));
  filter: drop-shadow(0 3px 6px rgba(0, 0, 0, 0.6));
  z-index: 5;
  pointer-events: none;
}

.mg-controls {
  margin-top: 20px;
  display: flex;
  gap: 12px;
}

.mg-btn {
  font-family: var(--font-serif);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: var(--color-ink);
  padding: 10px 20px;
  border-radius: 24px;
  font-size: 13px;
  letter-spacing: 0.1em;
  transition: background 0.2s ease;
}

@media (hover: hover) {
  .mg-btn:hover {
    background: rgba(255, 255, 255, 0.14);
  }
}

.mg-result-overlay {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: rgba(3, 4, 6, 0.92);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.6s ease;
  text-align: center;
  padding: 24px;
}

.mg-result-overlay.mg-show {
  opacity: 1;
  pointer-events: auto;
}

.mg-result-title {
  font-family: var(--font-serif);
  font-size: clamp(22px, 6vw, 32px);
  font-weight: 900;
  letter-spacing: 0.1em;
  margin-bottom: 14px;
  white-space: pre-line;
}

.mg-result-title.mg-win {
  color: #e8c98a;
}

.mg-result-title.mg-lose {
  color: var(--color-blood);
}

.mg-result-text {
  font-family: var(--font-serif);
  font-size: 14px;
  color: #cfc9bc;
  line-height: 1.9;
  margin-bottom: 26px;
  letter-spacing: 0.05em;
  white-space: pre-line;
}

.mg-result-disclaimer {
  font-family: var(--font-serif);
  font-size: 12px;
  color: rgba(207, 201, 188, 0.45);
  letter-spacing: 0.05em;
  margin-top: -16px;
  margin-bottom: 20px;
}

.mg-rules {
  margin-top: 24px;
  font-size: 11px;
  color: #8a8578;
  line-height: 1.9;
  max-width: 360px;
  text-align: center;
  letter-spacing: 0.03em;
}

/* ==========================================================================
   Small screens fine tuning
   ========================================================================== */
/* メインタイトルは .title-line による2行固定 + clamp(1.75rem, 9vw, 3.2rem) で
   320px幅の端末でも折り返さずに収まるため、旧タイトル(1行8文字)用に
   置いていた @media (max-width: 380px) の縮小指定は不要になった */
