/* =============================================================================
 * home.css — Hierophant 首頁
 * ============================================================================= */

:root {
  --gold: #c9a961;
  --ink: #0b0a14;
  --parchment: #e8e0cf;

  /* 由 JS 寫入：極緩慢的大氣亮度呼吸 */
  --breath: 1;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--ink);
  overflow: hidden;
}

body {
  font-family: 'Noto Serif TC', 'Cormorant Garamond', Georgia, serif;
  color: var(--parchment);
  /* 前景 master 解碼完成前 body 是透明的（opacity: 0），這段時間看到的
     其實是它底下的背景。html,body 已經在上面設了 var(--ink)，這裡再
     明講一次是為了保險：body 不透明時打的底色必須是場景的暗色，
     不能是瀏覽器預設的白（S3：避免載入期間閃白）。 */
  background: var(--ink);
  opacity: 0;
  transition: opacity 1.6s ease;
  cursor: pointer;
  -webkit-font-smoothing: antialiased;
}

body.ready { opacity: 1; }
/* A failed boot must be visible: lift the fade so #environmentStatus shows. */
body.boot-error { opacity: 1; transition: none; }

/* -----------------------------------------------------------------------------
 * 場景
 * -------------------------------------------------------------------------- */

.scene {
  position: fixed;
  inset: 0;
  overflow: hidden;
  /* 進場時的推進感；平時完全靜止 */
  transform: scale(1);
  transition: transform 1.6s cubic-bezier(.4, 0, .2, 1);
}

/*
 * 核准的前景 master（instrc F021 / F022）。
 *
 * 位置與尺寸由 JS 寫入（World.resize），不交給 object-fit。
 * 原因是 03_SCENE_GRAPH/mobile_crop_math.md 的二等分法則：直式畫面的左右
 * 邊緣必須正好切過兩根柱子的中線，同時王座維持在 source x=2560。
 * object-fit: cover 只會置中裁切，做不到那個垂直錨定；contain 則會把柱子
 * 縮進畫面內，同樣不符合法則。所以尺寸由 view.js 解出的裁切框決定，
 * 這裡的 object-fit: fill 是因為元素已經被設成精確的縮放尺寸。
 *
 * ⚠ 這個元素只在 GL 建立失敗時看得到。GL 路徑把同一張圖以預乘 alpha
 * 上傳成貼圖（見 gl.js），並不讀這個 <img>。
 */
.foreground {
  position: absolute;
  left: 0;
  top: 0;
  object-fit: fill;
  filter: brightness(var(--breath));
  user-select: none;
  -webkit-user-drag: none;
}

/*
 * GL 路徑。成功建立時 .scene 會被加上 .gl，DOM 路徑的三個圖層就收起來 ——
 * 它們的工作全部由 shader 接手。失敗時這個 canvas 是空的且在最底層，
 * 上面的 DOM 圖層照常顯示。
 */
#gl {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/*
 * GL 模式下前景與雲影都由 shader 接手，但 #fx 留著 —— 星表、星座連線、
 * 流星、燭火跳動都還在那一層，它用 screen 混合疊在 GL 畫布上。
 */
.scene.gl .foreground,
.scene.gl #clouds { display: none; }

/*
 * 兩層演員畫布，差別只在混合模式，而這個差別是必要的：
 *
 *   #actors  normal —— 實體。貓、蝙蝠、鳥、蛾都是遮住背景的深色剪影。
 *   #fx      screen —— 光。星星、燭火、螢火蟲、流星、角色輝光。
 *
 * 早期版本把兩者都畫在 screen 那一層，結果 screen(base, 近黑) ≈ base：
 * 近黑的貓不但看不見，還會把背景稍微「提亮」成一團淡斑，
 * 正好是黑貓的反面。實測 #6a7a8a 的背景上，#0d0c0f 的貓合成後是 #728091。
 */
#actors {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

#fx {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  mix-blend-mode: screen;
}

/*
 * 雲影層用 soft-light：它是「調亮／調暗既有的雲」，
 * 而不是蓋一層新的雲上去，因此原畫的筆觸會被保留。
 */
#clouds {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  mix-blend-mode: soft-light;
  opacity: .85;
}

.vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 120% 85% at 50% 42%,
      transparent 40%,
      rgba(6, 5, 12, .30) 78%,
      rgba(6, 5, 12, .62) 100%),
    linear-gradient(to bottom,
      rgba(6, 5, 12, .16) 0%,
      transparent 22%,
      transparent 52%,
      rgba(6, 5, 12, .30) 80%,
      rgba(6, 5, 12, .58) 100%);
}

/* -----------------------------------------------------------------------------
 * 進場層。畫面上不放任何文字，所以這一層幾乎是空的。
 * -------------------------------------------------------------------------- */

.gate {
  position: absolute;
  inset: auto 0 0 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 0 24px clamp(32px, 6vh, 64px);
  pointer-events: none;
}

/*
 * 唯一的介面元素：一條會緩慢呼吸的細線。
 * 它是「這裡可以進去」的暗示，但不是文字 —— 畫面上不出現任何字。
 * 不需要暗示的話，把 .enter-hint 整段刪掉即可，互動不受影響。
 */
.enter-hint {
  margin: 0;
  height: 1px;
}

.enter-hint span {
  display: block;
  width: clamp(48px, 9vw, 104px);
  height: 1px;
  margin: 0 auto;
  background: linear-gradient(to right,
    transparent, rgba(201, 169, 97, .55), transparent);
  animation: pulse 4.2s ease-in-out infinite;
}

/* 給輔助技術與搜尋引擎的標題，視覺上完全不存在。 */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

@keyframes pulse {
  0%, 100% { opacity: .45; }
  50%      { opacity: .95; }
}

/* -----------------------------------------------------------------------------
 * 進場轉場：向王座推進並淡出
 * -------------------------------------------------------------------------- */

body.entering .scene { transform: scale(1.14); }
body.entering .gate  { opacity: 0; transition: opacity .6s ease; }
body.entering        { opacity: 0; transition: opacity 1.2s ease .45s; }

/* -----------------------------------------------------------------------------
 * 除錯面板
 * -------------------------------------------------------------------------- */

.debug {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 99;
  padding: 10px 14px;
  font: 11px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace;
  letter-spacing: 0;
  white-space: pre;
  color: #9fe8c0;
  background: rgba(0, 0, 0, .72);
  border: 1px solid rgba(159, 232, 192, .25);
  border-radius: 4px;
  pointer-events: none;
}

/* -----------------------------------------------------------------------------
 * 直式螢幕
 *
 * 裁切本身已經由 view.js 的 solveCrop 處理（左右邊緣二等分兩根柱子），
 * 這裡只剩下版面上的調整。舊版在這裡用 object-fit: contain 把整張圖縮進畫面，
 * 那違反二等分法則，已經移除 —— 不要加回來。
 * -------------------------------------------------------------------------- */

@media (max-aspect-ratio: 21/20) {
  .gate { padding-bottom: clamp(24px, 5vh, 48px); }

  .vignette {
    background:
      radial-gradient(ellipse 130% 60% at 50% 50%,
        transparent 45%,
        rgba(6, 5, 12, .35) 85%,
        rgba(6, 5, 12, .70) 100%),
      linear-gradient(to bottom,
        rgba(6, 5, 12, .48) 0%,
        transparent 26%,
        transparent 64%,
        rgba(6, 5, 12, .55) 100%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .scene, body { transition: none; }
  .enter-hint span { animation: none; opacity: .8; }
}

#environment{position:absolute;inset:0;display:block;z-index:1;pointer-events:none;}#environmentStatus{position:fixed;bottom:20px;left:20px;right:20px;background:#1c1524;color:#eee;padding:16px;z-index:99;font:16px system-ui;}
/* Boot errors must be readable on a phone: top of the screen inside the safe area, above every canvas, high contrast. */
body.boot-error #environmentStatus{top:max(16px,env(safe-area-inset-top));bottom:auto;left:max(16px,env(safe-area-inset-left));right:max(16px,env(safe-area-inset-right));z-index:2147483647;background:#000;color:#fff;border:2px solid #fff;border-radius:6px;font:600 17px/1.45 system-ui,-apple-system,sans-serif;overflow-wrap:anywhere;max-height:80vh;overflow:auto;}
